Added support for PDP-10 RAM images
This commit is contained in:
parent
6cf141baf9
commit
aecd943c52
23 changed files with 583 additions and 632 deletions
7
apps/pdp10/tests/optest.json
Normal file
7
apps/pdp10/tests/optest.json
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"load": 0o100,
|
||||
"exec": 0o100,
|
||||
"data": [
|
||||
0o500000000000
|
||||
]
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
{"data":[
|
||||
{"longs":[
|
||||
-13436026,-1752439855,1451819088,1611565826,72255744,18119,246465280,-1964227858,263211744,-1007926546,105993040,-1912584008,-1258114624,-402542583,-2147155945,8168192,
|
||||
-38465359,149422512,8299264,1482381575,1431458755,-980627318,4984456,12305806,130491904,-953810944,-64953,-1960379140,-50529249,-75236100,113649152,1946157056,
|
||||
5021704,350994730,1278097552,422912,-352302058,5021895,-1057046230,-524164046,1532648710,1381061571,180049750,375040,855640255,-2131494958,129380546,9672073,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{"data":[
|
||||
{"longs":[
|
||||
-1100993236,-1959854112,76230196,1947140265,-1876497661,-2145246021,-58670876,-401967808,1480327193,867898229,1921771570,4098094,512241152,1692925953,-1664917134,209500754,
|
||||
-1973295878,-2133526816,1642336484,-533065692,-5179275,-131797778,-2034000550,-771804421,1352109027,39225600,6295179,-956019063,70,-301027133,-527766462,-300961718,
|
||||
1355017282,-1207545517,-1064435640,162857649,401080752,8389888,-1325368157,-1325550320,583681,117472931,-1017619623,-1974119853,-2000319280,-1912583154,48069,509734,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{"data":[
|
||||
{"longs":[
|
||||
-215511036,-1446729497,-970077091,-889074117,-1059597233,0,0,0,4793994,-1023318392,1996700702,2122974813,-402410489,-1957560157,45351510,-1962894616,
|
||||
920847438,-1962117493,-661778362,1586212092,8290310,1007908353,1007645703,1007383560,1007121418,-1828490227,508662700,4241488,-396830578,1495203869,123392994,-167281014,
|
||||
1962999878,-402476027,-1977679793,-2013247194,1019412838,1010529287,1010267144,1010005002,-1188072435,162791425,-1275056408,2746371,372949758,343212106,-956378574,1964637824,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{"data":[
|
||||
{"longs":[
|
||||
1126701261,1866670121,1769109872,544499815,1347243843,1126191425,1970302319,544367988,1886547779,1952543343,745434985,943272224,1092627507,1914727532,1952999273,1701978227,
|
||||
1987208563,539911269,1179863594,1095651370,1279804202,1246905130,-98557910,1676057008,1642483120,-222688080,-930288125,-1141057394,45998350,-1979600896,11857431,-1979484277,
|
||||
-997588649,-297620242,-2134573494,-227208964,-92268662,1107654104,1257124016,-1912135496,-13433529,-217624693,38242987,163808238,-1329433267,-1337727372,-1337858541,-431888896,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{"data":[
|
||||
{"longs":[
|
||||
-2065284944,-1912586056,7512536,876380390,-436272523,1102112139,1642366182,270848246,-4595574,610395391,1959016976,-1141448176,414823662,-2143568640,-347608855,-431836967,
|
||||
536919684,-768348877,855638456,-2147436091,-13385074,-1412378210,-964625438,1926642448,-431771412,207742084,-352261364,610395648,-352261133,-1335761408,-2021333436,-1143852034,
|
||||
-583860223,-628177525,12187187,-741237120,843492511,1979113923,-431640529,-1469979516,1962979520,1189007651,-1314987917,-2133601528,-683994938,-142094222,-1333036467,-1199249850,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{"data":[
|
||||
{"longs":[
|
||||
-400512427,-1070398658,-990193522,637550622,1976516480,-268387576,1706804110,1112117488,168201293,136218881,1108249601,1074185984,-1945315584,-956269042,1610644486,235834421,
|
||||
201770753,-1154392063,-611450816,11144844,11011783,113639692,-77594489,-402537752,-1070450007,-398905880,28311742,-805250328,-1327494432,13756418,-536155952,8922760,
|
||||
254067846,-774337640,-1752486173,-628424485,1947256566,-2029092859,145818112,1963509494,-402345718,-355270472,-754928664,11462890,-1962882072,-754142765,10676458,-1962878488,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{"data":[
|
||||
{"longs":[
|
||||
-399463851,-303561389,46589952,-622263437,-393504768,-661733325,1075758330,1112117248,-2144975539,141938495,-1896873800,-261768256,17434252,17309321,-1912586056,199504600,
|
||||
-2147256851,-726007348,-2147241981,1622347980,-973604425,175374338,-1341934406,46891015,1235418039,-1993963520,-2028042240,-2009167872,1662421248,9168896,1912887528,53471342,
|
||||
-402479640,378143218,-85458871,60418049,8988288,-259286791,-1976640117,-805222980,201815023,72607984,-317997005,-1976695436,-1962848834,436320488,-2048335994,133922902,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{"data":[
|
||||
{"longs":[
|
||||
820532650,-386632187,-637402904,-371231997,-399310709,-655834994,-388371968,1229063324,-1653387963,-939523095,507574980,-2143354842,146329461,-1900019472,-259212443,25757194,
|
||||
28843528,-1898430464,200094436,-2134084349,-738000454,-2134069245,1622610099,-989660681,179961972,-1341672445,45580491,1224801186,-1996453850,-2030008290,-2013231042,1660979478,
|
||||
65595469,-402409726,373883530,184680680,58779831,16328329,-259286901,-1967334098,-789620479,-1949928695,-395244304,-167050189,86961524,1627491006,-1207858194,-538436986,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{"data":[
|
||||
{"longs":[
|
||||
-349132203,808728341,792014896,942617394,942746936,976236602,-1461112784,1112080384,1329799245,1413566541,1162625601,0,0,858796032,758527280,1127559216,
|
||||
1381584975,1414022985,1380012064,1397310529,1498619973,1296389203,1313415251,824192579,741816377,943208753,1279336492,1230118988,1398032455,1397051936,1163285061,1095194180,
|
||||
22845,757610496,419831562,101122588,7,1515221248,419831562,101122588,7,757610496,1678147338,66160,0,1380999424,419830031,185401881,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
<name pos="center">PDP-10 Test Machine with Debugger</name>
|
||||
<computer id="computer" busWidth="18"/>
|
||||
<cpu id="cpu" model="1001" cycles="1000000"/>
|
||||
<ram id="ram" addr="0x0000" size="0x4000"/>
|
||||
<ram id="ram" addr="0x0000" size="0x4000" file="/apps/pdp10/tests/optest.json"/>
|
||||
<device id="default" type="default"/>
|
||||
<serial id="serial" adapter="0" binding="print" upperCase="true"/>
|
||||
<panel ref="/devices/pdp10/panel/test/debugger/terminal.xml"/>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
<name pos="center">PDP-10 Test Machine</name>
|
||||
<computer id="computer" busWidth="18"/>
|
||||
<cpu id="cpu" model="1001" cycles="1000000"/>
|
||||
<ram id="ram" addr="0x0000" size="0x4000"/>
|
||||
<ram id="ram" addr="0x0000" size="0x4000" file="/apps/pdp10/tests/optest.json"/>
|
||||
<device id="default" type="default"/>
|
||||
<serial id="serial" adapter="0" binding="print" upperCase="true"/>
|
||||
<panel ref="/devices/pdp10/panel/test/terminal.xml"/>
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ var DumpAPI = require("../../shared/lib/dumpapi");
|
|||
* what the loadFile() function already does.
|
||||
*
|
||||
* @constructor
|
||||
* @param {string|undefined} sFormat should be one of "json"|"data"|"hex"|"bytes"|"rom" (see the FORMAT constants)
|
||||
* @param {string|undefined} sFormat should be one of "json"|"longs"|"hex"|"bytes"|"rom" (see the FORMAT constants)
|
||||
* @param {boolean|string|undefined} fComments enables comments and other readability enhancements in the JSON output
|
||||
* @param {boolean|string|undefined} fDecimal forces decimal output if not undefined
|
||||
* @param {number|string|undefined} offDump
|
||||
|
|
@ -82,7 +82,7 @@ function FileDump(sFormat, fComments, fDecimal, offDump, nWidthDump, sServerRoot
|
|||
FileDump.sAPIURL = "http://www.pcjs.org" + DumpAPI.ENDPOINT;
|
||||
FileDump.sCopyright = COPYRIGHT;
|
||||
FileDump.sNotice = FileDump.sAPIURL + " " + FileDump.sCopyright;
|
||||
FileDump.sUsage = "Usage: " + FileDump.sAPIURL + "?" + DumpAPI.QUERY.FILE + "=({path}|{URL})&" + DumpAPI.QUERY.FORMAT + "=(json|data|hex|octal|bytes|words|rom)";
|
||||
FileDump.sUsage = "Usage: " + FileDump.sAPIURL + "?" + DumpAPI.QUERY.FILE + "=({path}|{URL})&" + DumpAPI.QUERY.FORMAT + "=(json|longs|hex|octal|bytes|words|rom)";
|
||||
|
||||
FileDump.asBadExts = [
|
||||
"js", "log"
|
||||
|
|
@ -99,7 +99,7 @@ FileDump.asBadExts = [
|
|||
*
|
||||
* Usage
|
||||
* ---
|
||||
* filedump --file=({path}|{URL}) [--merge=({path}|{url})] [--format=(json|data|hex|octal|bytes|words|rom)]
|
||||
* filedump --file=({path}|{URL}) [--merge=({path}|{url})] [--format=(json|longs|hex|octal|bytes|words|rom)]
|
||||
* [--comments] [--decimal] [--offset={number}] [--width={number}] [--load={number}] [--exec={number}]
|
||||
* [--output={path}] [--overwrite]
|
||||
*
|
||||
|
|
@ -146,7 +146,7 @@ FileDump.CLI = function()
|
|||
var args = proc.getArgs();
|
||||
|
||||
if (!args.argc) {
|
||||
console.log("usage: filedump --file=({path}|{URL}) [--merge=({path}|{url})] [--format=(json|data|hex|octal|bytes|words|rom)] [--comments] [--decimal] [--offset={number}] [--width={number}] [--output={path}] [--overwrite]");
|
||||
console.log("usage: filedump --file=({path}|{URL}) [--merge=({path}|{url})] [--format=(json|longs|hex|octal|bytes|words|rom)] [--comments] [--decimal] [--offset={number}] [--width={number}] [--output={path}] [--overwrite]");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -752,7 +752,7 @@ FileDump.prototype.buildJSON = function()
|
|||
else if (this.sFormat == DumpAPI.FORMAT.OCTAL || this.sFormat == DumpAPI.FORMAT.WORDS) {
|
||||
this.json += this.dumpBuffer(this.sFormat, this.buf, this.buf.length, 2);
|
||||
} else {
|
||||
this.json += this.dumpBuffer("data", this.buf, this.buf.length, 4);
|
||||
this.json += this.dumpBuffer(DumpAPI.FORMAT.LONGS, this.buf, this.buf.length, 4);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -344,10 +344,10 @@ class CPUStatePDP10 extends CPUPDP10 {
|
|||
}
|
||||
|
||||
/*
|
||||
* Bits 0-22 (I,X,Y) contain what we call a "reference address" (R), which is used to calculate the
|
||||
* "effective address" (E). To determine E from R, we must extract I, X, and Y from R, set E 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 to [E]
|
||||
* and repeat the process.
|
||||
* Bits 0-22 (I,X,Y) contain what we call a "reference address" (R), which is used to calculate an
|
||||
* 18-bit "effective address" (E). To determine E from R, we must extract I, X, and Y from R, set E
|
||||
* 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
|
||||
* to [E] and repeat the process.
|
||||
*
|
||||
* However, we don't actually repeat the process immediately; we need to treat each indirection as a
|
||||
* separate decoding step, to ensure that the emulator can "breathe" periodically. So instead, we
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ class RAMPDP10 extends Component {
|
|||
{
|
||||
super("RAM", parmsRAM);
|
||||
|
||||
this.abInit = null;
|
||||
this.aData = null;
|
||||
this.aSymbols = null;
|
||||
|
||||
this.addrRAM = +parmsRAM['addr'];
|
||||
|
|
@ -71,7 +71,7 @@ class RAMPDP10 extends Component {
|
|||
if (this.addrExec != null) this.addrExec = +this.addrExec;
|
||||
|
||||
this.fInstalled = (!!this.sizeRAM); // 0 is the default value for 'size' when none is specified
|
||||
this.fAllocated = false;
|
||||
this.fAllocated = this.fReset = false;
|
||||
|
||||
this.sFilePath = parmsRAM['file'];
|
||||
this.sFileName = Str.getBaseName(this.sFilePath);
|
||||
|
|
@ -180,7 +180,7 @@ class RAMPDP10 extends Component {
|
|||
Component.addMachineResource(this.idMachine, sURL, sData);
|
||||
var resource = Web.parseMemoryResource(sURL, sData);
|
||||
if (resource) {
|
||||
this.abInit = resource.aBytes;
|
||||
this.aData = resource.aData;
|
||||
this.aSymbols = resource.aSymbols;
|
||||
if (this.addrLoad == null) this.addrLoad = resource.addrLoad;
|
||||
if (this.addrExec == null) this.addrExec = resource.addrExec;
|
||||
|
|
@ -219,9 +219,9 @@ class RAMPDP10 extends Component {
|
|||
/*
|
||||
* Too early...
|
||||
*/
|
||||
if (!this.abInit || !this.bus) return;
|
||||
if (!this.aData) return;
|
||||
|
||||
if (this.loadImage(this.abInit, this.addrLoad, this.addrExec, this.addrRAM)) {
|
||||
if (this.loadImage(this.aData, this.addrLoad, this.addrExec, this.addrRAM)) {
|
||||
this.status('Loaded image "' + this.sFileName + '"');
|
||||
} else {
|
||||
this.notice('Error loading image "' + this.sFileName + '"');
|
||||
|
|
@ -230,9 +230,10 @@ class RAMPDP10 extends Component {
|
|||
/*
|
||||
* NOTE: We now retain this data, so that reset() can return the RAM to its predefined state.
|
||||
*
|
||||
* delete this.abInit;
|
||||
* delete this.aData;
|
||||
*/
|
||||
}
|
||||
this.fReset = true;
|
||||
this.setReady();
|
||||
}
|
||||
}
|
||||
|
|
@ -244,127 +245,47 @@ class RAMPDP10 extends Component {
|
|||
*/
|
||||
reset()
|
||||
{
|
||||
if (this.fAllocated) {
|
||||
if (this.fAllocated && !this.fReset) {
|
||||
/*
|
||||
* TODO: Add a configuration parameter for selecting the byte pattern on reset?
|
||||
* Note that when memory blocks are originally created, they are currently always
|
||||
* zero-initialized, so this would only affect resets.
|
||||
*/
|
||||
this.bus.zeroMemory(this.addrRAM, this.sizeRAM, 0);
|
||||
if (this.abInit) {
|
||||
this.loadImage(this.abInit, this.addrLoad, this.addrExec, this.addrRAM, !this.dbg);
|
||||
if (this.aData) {
|
||||
this.loadImage(this.aData, this.addrLoad, this.addrExec, this.addrRAM, !this.dbg);
|
||||
}
|
||||
}
|
||||
this.fReset = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* loadImage(aBytes, addrLoad, addrExec, addrInit, fStart)
|
||||
* loadImage(aData, addrLoad, addrExec, addrInit, fStart)
|
||||
*
|
||||
* If the array contains a PAPER tape image in the "Absolute Format," load it as specified
|
||||
* by the format; otherwise, load it as-is using the address(es) supplied.
|
||||
*
|
||||
* @this {RAMPDP10}
|
||||
* @param {Array|Uint8Array} aBytes
|
||||
* @param {Array} aData
|
||||
* @param {number|null} [addrLoad]
|
||||
* @param {number|null} [addrExec] (this CAN override any starting address INSIDE the image)
|
||||
* @param {number|null} [addrInit]
|
||||
* @param {boolean} [fStart]
|
||||
* @return {boolean} (true if loaded, false if not)
|
||||
*/
|
||||
loadImage(aBytes, addrLoad, addrExec, addrInit, fStart)
|
||||
loadImage(aData, addrLoad, addrExec, addrInit, fStart)
|
||||
{
|
||||
var fStop = false;
|
||||
var fLoaded = false;
|
||||
/*
|
||||
* Data on tapes in the "Absolute Format" is organized into blocks; each block begins with
|
||||
* a 6-byte header:
|
||||
*
|
||||
* 2-byte signature (0x0001)
|
||||
* 2-byte block length (N + 6, because it includes the 6-byte header)
|
||||
* 2-byte load address
|
||||
*
|
||||
* followed by N data bytes. If N is zero, then the 2-byte load address is the exec address,
|
||||
* unless the address is odd (usually 1). DEC's Absolute Loader jumps to the exec address
|
||||
* in former case, halts in the latter.
|
||||
*
|
||||
* All values are stored "little endian" (low byte followed by high byte), just like the
|
||||
* PDP-11's memory architecture.
|
||||
*
|
||||
* After the data bytes, there is a single checksum byte. The 8-bit sum of all the bytes in
|
||||
* the block (including the header bytes and checksum byte) should be zero.
|
||||
*
|
||||
* ANOMALIES: Tape files don't always begin with a signature word, so I allow any number of
|
||||
* leading zeros before the first signature. Tape files don't always end cleanly either, so as
|
||||
* soon as I see an invalid signature, I break out of the loop without signalling an error, as
|
||||
* long as at least ONE block was successfully processed. In fact, it's possible that as
|
||||
* soon as a block with ZERO data bytes is encountered, processing is supposed to stop, but
|
||||
* I haven't examined enough tapes (or the Absolute Loader code) to know for sure.
|
||||
*/
|
||||
|
||||
if (addrLoad == null) {
|
||||
var off = 0, fError = false;
|
||||
while (off < aBytes.length - 1) {
|
||||
var w = (aBytes[off] & 0xff) | ((aBytes[off+1] & 0xff) << 8);
|
||||
if (!w) { // ignore pairs of leading zeros
|
||||
off += 2;
|
||||
continue;
|
||||
addrLoad = addrInit;
|
||||
}
|
||||
if (!(w & 0xff)) { // as well as single bytes of zero
|
||||
off++;
|
||||
continue;
|
||||
}
|
||||
var offBlock = off;
|
||||
if (w != 0x0001) {
|
||||
this.printMessage("invalid signature (" + Str.toHexWord(w) + ") at offset " + Str.toHexWord(offBlock), MessagesPDP10.PAPER);
|
||||
break;
|
||||
}
|
||||
if (off + 6 >= aBytes.length) {
|
||||
this.printMessage("invalid block at offset " + Str.toHexWord(offBlock), MessagesPDP10.PAPER);
|
||||
break;
|
||||
}
|
||||
off += 2;
|
||||
var checksum = w;
|
||||
var len = (aBytes[off++] & 0xff) | ((aBytes[off++] & 0xff) << 8);
|
||||
var addr = (aBytes[off++] & 0xff) | ((aBytes[off++] & 0xff) << 8);
|
||||
checksum += (len & 0xff) + (len >> 8) + (addr & 0xff) + (addr >> 8);
|
||||
var offData = off, cbData = len -= 6;
|
||||
while (len > 0 && off < aBytes.length) {
|
||||
checksum += aBytes[off++] & 0xff;
|
||||
len--;
|
||||
}
|
||||
if (len != 0 || off >= aBytes.length) {
|
||||
this.printMessage("insufficient data for block at offset " + Str.toHexWord(offBlock), MessagesPDP10.PAPER);
|
||||
break;
|
||||
}
|
||||
checksum += aBytes[off++] & 0xff;
|
||||
if (checksum & 0xff) {
|
||||
this.printMessage("invalid checksum (" + Str.toHexByte(checksum) + ") for block at offset " + Str.toHexWord(offBlock), MessagesPDP10.PAPER);
|
||||
break;
|
||||
}
|
||||
if (!cbData) {
|
||||
if (addr & 0x1) {
|
||||
fStop = true;
|
||||
} else {
|
||||
if (addrExec == null) addrExec = addr;
|
||||
}
|
||||
if (addrExec != null) this.printMessage("starting address: " + Str.toHexWord(addrExec), MessagesPDP10.PAPER);
|
||||
} else {
|
||||
this.printMessage("loading " + Str.toHexWord(cbData) + " bytes at " + Str.toHexWord(addr) + "-" + Str.toHexWord(addr + cbData), MessagesPDP10.PAPER);
|
||||
while (cbData--) {
|
||||
this.bus.setWordDirect(addr++, aBytes[offData++]);
|
||||
}
|
||||
}
|
||||
fLoaded = true;
|
||||
}
|
||||
}
|
||||
if (!fLoaded) {
|
||||
if (addrLoad == null) addrLoad = addrInit;
|
||||
if (addrLoad != null) {
|
||||
for (var i = 0; i < aBytes.length; i++) {
|
||||
this.bus.setWordDirect(addrLoad + i, aBytes[i]);
|
||||
for (var i = 0; i < aData.length; i++) {
|
||||
this.bus.setWordDirect(addrLoad + i, aData[i]);
|
||||
}
|
||||
fLoaded = true;
|
||||
}
|
||||
}
|
||||
if (fLoaded) {
|
||||
/*
|
||||
* Set the start address to whatever the caller provided, or failing that, whatever start
|
||||
|
|
@ -374,7 +295,7 @@ class RAMPDP10 extends Component {
|
|||
* image, but we know that the directions for that diagnostic say to "Start and Restart at 200",
|
||||
* so we have manually inserted an "exec":128 in the JSON containing the image.
|
||||
*/
|
||||
if (addrExec == null || fStop) {
|
||||
if (addrExec == null) {
|
||||
this.cpu.stopCPU();
|
||||
fStart = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ class RAMPDP11 extends Component {
|
|||
if (this.addrExec != null) this.addrExec = +this.addrExec;
|
||||
|
||||
this.fInstalled = (!!this.sizeRAM); // 0 is the default value for 'size' when none is specified
|
||||
this.fAllocated = false;
|
||||
this.fAllocated = this.fReset = false;
|
||||
|
||||
this.sFilePath = parmsRAM['file'];
|
||||
this.sFileName = Str.getBaseName(this.sFilePath);
|
||||
|
|
@ -224,7 +224,7 @@ class RAMPDP11 extends Component {
|
|||
/*
|
||||
* Too early...
|
||||
*/
|
||||
if (!this.abInit || !this.bus) return;
|
||||
if (!this.abInit) return;
|
||||
|
||||
if (this.loadImage(this.abInit, this.addrLoad, this.addrExec, this.addrRAM)) {
|
||||
this.status('Loaded image "' + this.sFileName + '"');
|
||||
|
|
@ -238,6 +238,7 @@ class RAMPDP11 extends Component {
|
|||
* delete this.abInit;
|
||||
*/
|
||||
}
|
||||
this.fReset = true;
|
||||
this.setReady();
|
||||
}
|
||||
}
|
||||
|
|
@ -249,7 +250,7 @@ class RAMPDP11 extends Component {
|
|||
*/
|
||||
reset()
|
||||
{
|
||||
if (this.fAllocated) {
|
||||
if (this.fAllocated && !this.fReset) {
|
||||
/*
|
||||
* TODO: Add a configuration parameter for selecting the byte pattern on reset?
|
||||
* Note that when memory blocks are originally created, they are currently always
|
||||
|
|
@ -260,6 +261,7 @@ class RAMPDP11 extends Component {
|
|||
this.loadImage(this.abInit, this.addrLoad, this.addrExec, this.addrRAM, !this.dbg);
|
||||
}
|
||||
}
|
||||
this.fReset = false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ var DumpAPI = {
|
|||
OCTAL: "octal", // displays data as octal words
|
||||
BYTES: "bytes", // displays data as hex bytes; normally used only when comments are enabled
|
||||
WORDS: "words", // displays data as hex words; normally used only when comments are enabled
|
||||
LONGS: "longs", // displays data as dwords
|
||||
IMG: "img", // returns the raw disk data (ie, using a Buffer object) (DiskDump only)
|
||||
ROM: "rom" // returns the raw file data (ie, using a Buffer object) (FileDump only)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -268,6 +268,23 @@ class Web {
|
|||
/**
|
||||
* parseMemoryResource(sURL, sData)
|
||||
*
|
||||
* This converts a variety of JSON-style data streams into an Object with the following properties:
|
||||
*
|
||||
* aBytes
|
||||
* aSymbols
|
||||
* addrLoad
|
||||
* addrExec
|
||||
*
|
||||
* If the source data contains a 'bytes' array, it's passed through to 'aBytes'; alternatively, if
|
||||
* it contains a 'words' array, the values are converted from 16-bit to 8-bit and stored in 'aBytes',
|
||||
* and if it contains a 'longs' array, the values are converted from 32-bit longs into bytes and
|
||||
* stored in 'aBytes'.
|
||||
*
|
||||
* Alternatively, if the source data contains a 'data' array, we simply pass that through to the output
|
||||
* object as:
|
||||
*
|
||||
* aData
|
||||
*
|
||||
* @param {string} sURL
|
||||
* @param {string} sData
|
||||
* @return {Object|null} (resource)
|
||||
|
|
@ -315,8 +332,8 @@ class Web {
|
|||
*
|
||||
* ["unrecognized disk path: test.img"]
|
||||
*/
|
||||
if (sData.indexOf("0x") < 0 && sData.substr(0, 2) != "[\"") {
|
||||
data = JSON.parse(sData.replace(/([a-z]+):/gm, "\"$1\":").replace(/\/\/[^\n]*/gm, ""));
|
||||
if (sData.indexOf("0x") < 0 && sData.indexOf("0o") < 0 && sData.substr(0, 2) != '["') {
|
||||
data = JSON.parse(sData.replace(/([a-z]+):/gm, '"$1":').replace(/\/\/[^\n]*/gm, ""));
|
||||
} else {
|
||||
data = eval("(" + sData + ")");
|
||||
}
|
||||
|
|
@ -338,7 +355,7 @@ class Web {
|
|||
Component.assert(!(a[i] & ~0xffff));
|
||||
}
|
||||
}
|
||||
else if (a = data['data']) {
|
||||
else if (a = data['longs']) {
|
||||
/*
|
||||
* Convert all dwords (longs) into bytes
|
||||
*/
|
||||
|
|
@ -350,12 +367,14 @@ class Web {
|
|||
resource.aBytes[ib++] = (a[i] >> 24) & 0xff;
|
||||
}
|
||||
}
|
||||
else if (a = data['data']) {
|
||||
resource.aData = a;
|
||||
}
|
||||
else {
|
||||
resource.aBytes = data;
|
||||
}
|
||||
|
||||
resource.aSymbols = data['symbols'];
|
||||
|
||||
if (resource.aBytes) {
|
||||
if (!resource.aBytes.length) {
|
||||
Component.error("Empty resource: " + sURL);
|
||||
resource = null;
|
||||
|
|
@ -364,6 +383,9 @@ class Web {
|
|||
Component.error(resource.aBytes[0]);
|
||||
resource = null;
|
||||
}
|
||||
}
|
||||
resource.aSymbols = data['symbols'];
|
||||
|
||||
} catch (e) {
|
||||
Component.error("Resource data error (" + sURL + "): " + e.message);
|
||||
resource = null;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{"data":[
|
||||
{"longs":[
|
||||
-2126857072,112742,-144277504,297297640,1715745570,-1184447607,-2005440939,1726084966,963047927,1602555864,-1898827382,-661887270,264275302,-376811131,-1869578132,-1869574000,
|
||||
-1869574000,-1869574000,-1869574000,-1869574000,-1869574000,-1869574000,-1869574000,-1869574000,-1869574000,-1869574000,-1869574000,-1869574000,-1869574000,-1869574000,-1869574000,-1869574000,
|
||||
-1869574000,-1869574000,-1869574000,-1869574000,-1869574000,-1869574000,-1869574000,-1869574000,-1869574000,-1869574000,-1869574000,-1869574000,-1869574000,-1869574000,-1869574000,-1869574000,
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue