Simplify the Bus and Memory interfaces slightly, by enabling WORDBUS, which treats all word accesses as aligned; the CPU is has sole responsibility for detecting unaligned word addresses and trapping appropriatelu

This commit is contained in:
Jeff 2016-10-06 14:17:29 -07:00 • committed by Jeff Parsons
commit 1a1614a648
12 changed files with 444 additions and 398 deletions

View file

@ -34,12 +34,12 @@
* so for normal development, you should continue using Grunt.
*
* To learn Gulp, I started with a simple concatenation task ("mktmp") that combines all the files
* required to compile a single emulation module (PCx86), and then I added a compilation task ("compile")
* required to compile a single emulation module (PDPjs), and then I added a compilation task ("compile")
* that runs the new JavaScript version of Google's Closure Compiler.
*
* Unfortunately, the JavaScript version of the Closure Compiler appears to be MUCH slower than the
* Java version. But, it did uncover a few new type-related bugs in my code, which are now fixed,
* and the PCx86 emulation module now compiles successfully (although I haven't tested it yet).
* and the PDPjs emulation module now compiles successfully (although I haven't tested it yet).
*
* Additional work is required to make Gulp skip tasks when the output file(s) are still newer
* than the input file(s). By default, every time you run Gulp, EVERYTHING is built again. Apparently,
@ -60,9 +60,9 @@ var pkg = require("./package.json");
pkg.version = pkg.version.slice(0, -1) + 'x'; // TODO: Remove this hack when we're done testing
var pcX86TmpDir = "./tmp/pcx86/" + pkg.version;
var pcX86ReleaseDir = "./versions/pcx86/" + pkg.version;
var pcX86ReleaseFile = "pcx86.js";
var pdp11TmpDir = "./tmp/pdp11/" + pkg.version;
var pdp11ReleaseDir = "./versions/pdpjs/" + pkg.version;
var pdp11ReleaseFile = "pdp11.js";
var sExterns = "";
var sSiteHost = "www.pcjs.org";
@ -86,7 +86,7 @@ if (pkg.homepage) {
}
gulp.task('mktmp', function() {
return gulp.src(pkg.pcX86Files)
return gulp.src(pkg.pdp11Files)
.pipe(foreach(function(stream, file){
return stream
.pipe(header('/* ' + file.path + ' */\n\n'))
@ -95,13 +95,13 @@ gulp.task('mktmp', function() {
.pipe(replace(/[ \t]*if\s*\(typeof\s+module\s*!==\s*(['"])undefined\1\)\s*(\{[^}]*}|[^\n]*)(\n|$)/gm, ""))
.pipe(replace(/[ \t]*[A-Za-z_][A-Za-z0-9_.]*\.assert\([^\n]*\);[^\n]*/g, ""))
}))
.pipe(concat(pcX86ReleaseFile))
.pipe(concat(pdp11ReleaseFile))
.pipe(header('"use strict";\n\n'))
.pipe(gulp.dest(pcX86TmpDir));
.pipe(gulp.dest(pdp11TmpDir));
});
gulp.task('compile', function() {
return gulp.src(path.join(pcX86TmpDir, pcX86ReleaseFile) /*, {base: './'} */)
return gulp.src(path.join(pdp11TmpDir, pdp11ReleaseFile) /*, {base: './'} */)
.pipe(compiler({
assumeFunctionWrapper: true,
compilationLevel: 'ADVANCED',
@ -117,10 +117,10 @@ gulp.task('compile', function() {
languageIn: "ES6", // this is now the default, just documenting our requirements
languageOut: "ES5", // this is also the default
outputWrapper: '(function(){%output%})()',
jsOutputFile: pcX86ReleaseFile, // TODO: This must vary according to debugger/non-debugger releases
jsOutputFile: pdp11ReleaseFile, // TODO: This must vary according to debugger/non-debugger releases
createSourceMap: false
}))
.pipe(gulp.dest(pcX86ReleaseDir));
.pipe(gulp.dest(pdp11ReleaseDir));
});
gulp.task('default', function() {

View file

@ -253,7 +253,7 @@ C1PComputer.power = function(computer)
/*
* C1PComputer.init()
*
* This function operates on every HTML element of class "computer", extracting the
* This function operates on every HTML element of class "c1pjs-computer", extracting the
* JSON-encoded parameters for the C1PComputer constructor from the element's "data-value"
* attribute, invoking the constructor to create a C1PComputer component, and then binding
* any associated HTML controls to the new component.
@ -263,7 +263,7 @@ C1PComputer.init = function()
/*
* In non-COMPILED builds, embedMachine() may have set XMLVERSION.
*/
if (!COMPILED && C1PJS.XMLVERSION) C1PJS.APPVERSION = C1PJS.XMLVERSION;
if (!COMPILED && XMLVERSION) C1PJS.APPVERSION = XMLVERSION;
var aeComputers = Component.getElementsByClass(document, C1PJS.APPCLASS, "computer");

View file

@ -1488,7 +1488,7 @@ Computer8080.prototype.updateVideo = function(fForced)
/**
* Computer8080.init()
*
* For every machine represented by an HTML element of class "pcjs-machine", this function
* For every machine represented by an HTML element of class "pc8080-machine", this function
* locates the HTML element of class "computer", extracting the JSON-encoded parameters for the
* Computer constructor from the element's "data-value" attribute, invoking the constructor to
* create a Computer component, and then binding any associated HTML controls to the new component.
@ -1498,7 +1498,7 @@ Computer8080.init = function()
/*
* In non-COMPILED builds, embedMachine() may have set XMLVERSION.
*/
if (!COMPILED && PC8080.XMLVERSION) PC8080.APPVERSION = PC8080.XMLVERSION;
if (!COMPILED && XMLVERSION) PC8080.APPVERSION = XMLVERSION;
var aeMachines = Component.getElementsByClass(document, PC8080.APPCLASS + "-machine");

View file

@ -1518,7 +1518,7 @@ Computer.prototype.updateVideo = function(fForce)
/**
* Computer.init()
*
* For every machine represented by an HTML element of class "pcjs-machine", this function
* For every machine represented by an HTML element of class "pcx86-machine", this function
* locates the HTML element of class "computer", extracting the JSON-encoded parameters for the
* Computer constructor from the element's "data-value" attribute, invoking the constructor to
* create a Computer component, and then binding any associated HTML controls to the new component.
@ -1528,7 +1528,7 @@ Computer.init = function()
/*
* In non-COMPILED builds, embedMachine() may have set XMLVERSION.
*/
if (!COMPILED && PCX86.XMLVERSION) PCX86.APPVERSION = PCX86.XMLVERSION;
if (!COMPILED && XMLVERSION) PCX86.APPVERSION = XMLVERSION;
var aeMachines = Component.getElementsByClass(document, PCX86.APPCLASS + "-machine");

View file

@ -133,7 +133,7 @@ function BusPDP11(parmsBus, cpu, dbg)
this.fIOBreakAll = false;
this.fnReset = null;
this.fnAccess = this.access;
this.fnIOAccess = this.unknownIO;
/*
* Allocate empty Memory blocks to span the entire physical address space.
@ -214,7 +214,7 @@ BusPDP11.IOController = {
}
return b;
}
b = bus.fnAccess(addr | BusPDP11.IOPAGE_22BIT, -1, 1);
b = bus.fnIOAccess(addr | BusPDP11.IOPAGE_22BIT, -1, 1);
if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.BUS)) {
this.dbg.printMessage("warning: unconverted read access to byte @" + this.dbg.toStrBase(addr) + ": " + this.dbg.toStrBase(b));
}
@ -279,7 +279,7 @@ BusPDP11.IOController = {
}
return;
}
bus.fnAccess(addr | BusPDP11.IOPAGE_22BIT, b, 1);
bus.fnIOAccess(addr | BusPDP11.IOPAGE_22BIT, b, 1);
if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.BUS)) {
this.dbg.printMessage("warning: unconverted write access to byte @" + this.dbg.toStrBase(addr) + ": " + this.dbg.toStrBase(b));
}
@ -312,7 +312,7 @@ BusPDP11.IOController = {
}
return w;
}
w = bus.fnAccess(addr | BusPDP11.IOPAGE_22BIT, -1, 0);
w = bus.fnIOAccess(addr | BusPDP11.IOPAGE_22BIT, -1, 0);
if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.BUS)) {
this.dbg.printMessage("warning: unconverted read access to word @" + this.dbg.toStrBase(addr) + ": " + this.dbg.toStrBase(w));
}
@ -349,7 +349,7 @@ BusPDP11.IOController = {
}
return;
}
bus.fnAccess(addr | BusPDP11.IOPAGE_22BIT, w, 0);
bus.fnIOAccess(addr | BusPDP11.IOPAGE_22BIT, w, 0);
if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.BUS)) {
this.dbg.printMessage("warning: unconverted write access to word @" + this.dbg.toStrBase(addr) + ": " + this.dbg.toStrBase(w));
}
@ -426,7 +426,7 @@ BusPDP11.prototype.reset = function()
};
/**
* access(addr, data, byteFlag)
* unknownIO(addr, data, byteFlag)
*
* This is our default I/O handler, called whenever there's an IOPAGE access without a corresponding entry
* in aIOHandlers; in the interim, our Device component will override this default handler with its own function
@ -438,10 +438,10 @@ BusPDP11.prototype.reset = function()
* @param {number} data (-1 if read, otherwise write)
* @param {number} byteFlag (true if byte I/O, otherwise word)
*/
BusPDP11.prototype.access = function(addr, data, byteFlag)
BusPDP11.prototype.unknownIO = function(addr, data, byteFlag)
{
if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.BUS)) {
this.dbg.printMessage("warning: unrecognized access(" + this.dbg.toStrBase(addr) + "," + this.dbg.toStrBase(data) + "," + byteFlag + ")");
this.dbg.printMessage("warning: unrecognized I/O access(" + this.dbg.toStrBase(addr) + "," + this.dbg.toStrBase(data) + "," + byteFlag + ")");
}
return 0;
};
@ -808,10 +808,10 @@ BusPDP11.prototype.getWord = function(addr)
{
var off = addr & this.nBlockLimit;
var iBlock = (addr & this.nBusMask) >>> this.nBlockShift;
if (off != this.nBlockLimit) {
return this.aMemBlocks[iBlock].readWord(off, addr);
}
if (!PDP11.WORDBUS && off == this.nBlockLimit) {
return this.aMemBlocks[iBlock++].readByte(off, addr) | (this.aMemBlocks[iBlock & this.nBlockMask].readByte(0, addr + 1) << 8);
}
return this.aMemBlocks[iBlock].readWord(off, addr);
};
/**
@ -827,10 +827,10 @@ BusPDP11.prototype.getWordDirect = function(addr)
{
var off = addr & this.nBlockLimit;
var iBlock = (addr & this.nBusMask) >>> this.nBlockShift;
if (off != this.nBlockLimit) {
return this.aMemBlocks[iBlock].readWordDirect(off, addr);
}
if (!PDP11.WORDBUS && off == this.nBlockLimit) {
return this.aMemBlocks[iBlock++].readByteDirect(off, addr) | (this.aMemBlocks[iBlock & this.nBlockMask].readByteDirect(0, addr + 1) << 8);
}
return this.aMemBlocks[iBlock].readWordDirect(off, addr);
};
/**
@ -871,12 +871,12 @@ BusPDP11.prototype.setWord = function(addr, w)
{
var off = addr & this.nBlockLimit;
var iBlock = (addr & this.nBusMask) >>> this.nBlockShift;
if (off != this.nBlockLimit) {
this.aMemBlocks[iBlock].writeWord(off, w & 0xffff, addr);
return;
}
if (!PDP11.WORDBUS && off == this.nBlockLimit) {
this.aMemBlocks[iBlock++].writeByte(off, w & 0xff, addr);
this.aMemBlocks[iBlock & this.nBlockMask].writeByte(0, (w >> 8) & 0xff, addr + 1);
return;
}
this.aMemBlocks[iBlock].writeWord(off, w & 0xffff, addr);
};
/**
@ -893,12 +893,12 @@ BusPDP11.prototype.setWordDirect = function(addr, w)
{
var off = addr & this.nBlockLimit;
var iBlock = (addr & this.nBusMask) >>> this.nBlockShift;
if (off != this.nBlockLimit) {
this.aMemBlocks[iBlock].writeWordDirect(off, w & 0xffff, addr);
return;
}
if (!PDP11.WORDBUS && off == this.nBlockLimit) {
this.aMemBlocks[iBlock++].writeByteDirect(off, w & 0xff, addr);
this.aMemBlocks[iBlock & this.nBlockMask].writeByteDirect(0, (w >> 8) & 0xff, addr + 1);
return;
}
this.aMemBlocks[iBlock].writeWordDirect(off, w & 0xffff, addr);
};
/**
@ -1072,18 +1072,18 @@ BusPDP11.prototype.addIOTable = function(component, table)
};
/**
* addIODefaultHandlers(fnReset, fnAccess)
* addIODefaultHandlers(fnReset, fnIOAccess)
*
* Add default I/O notification handlers.
*
* @this {BusPDP11}
* @param {function()} fnReset
* @param {function(number,number,number)} fnAccess
* @param {function(number,number,number)} fnIOAccess
*/
BusPDP11.prototype.addIODefaultHandlers = function(fnReset, fnAccess)
BusPDP11.prototype.addIODefaultHandlers = function(fnReset, fnIOAccess)
{
this.fnReset = fnReset;
this.fnAccess = fnAccess;
this.fnIOAccess = fnIOAccess;
};
/**

View file

@ -1448,7 +1448,7 @@ ComputerPDP11.prototype.updateStatus = function(fForce)
/**
* ComputerPDP11.init()
*
* For every machine represented by an HTML element of class "pcjs-machine", this function
* For every machine represented by an HTML element of class "pdp11-machine", this function
* locates the HTML element of class "computer", extracting the JSON-encoded parameters for the
* Computer constructor from the element's "data-value" attribute, invoking the constructor to
* create a Computer component, and then binding any associated HTML controls to the new component.

View file

@ -1094,12 +1094,18 @@ CPUStatePDP11.prototype.mapVirtualToPhysical = function(virtualAddress, accessFl
this.mmuLastVirtual = physicalAddress;
if (physicalAddress >= BusPDP11.IOPAGE_VIRT) {
physicalAddress |= BusPDP11.IOPAGE_22BIT;
} else { // no max_memory check in 16 bit mode
}
/*
* I'm moving this alignment test to the CPU->Bus interfaces that read/write physical words;
* hopefully there are no order dependencies on this test.
*
else { // no max_memory check in 16 bit mode
if ((physicalAddress & 1) && !(accessFlags & PDP11.ACCESS.BYTE)) {
this.regErr |= PDP11.CPUERR.ODDADDR;
this.trap(PDP11.TRAP.BUS_ERROR, PDP11.REASON.ODDMEMADDR);
}
}
*/
} else {
this.mmuLastVirtual = virtualAddress;
page = (virtualAddress >> 13) & this.mmuMask[this.mmuMode];
@ -1118,10 +1124,15 @@ CPUStatePDP11.prototype.mapVirtualToPhysical = function(virtualAddress, accessFl
this.regErr |= PDP11.CPUERR.NOMEMORY;
this.trap(PDP11.TRAP.BUS_ERROR, PDP11.REASON.NOMEMORY); // KB11-EM does this after ABORT handling - KB11-CM before
}
/*
* I'm moving this alignment test to the CPU->Bus interfaces that read/write physical words;
* hopefully there are no order dependencies on this test.
*
if ((physicalAddress & 1) && !(accessFlags & PDP11.ACCESS.BYTE)) {
this.regErr |= PDP11.CPUERR.ODDADDR;
this.trap(PDP11.TRAP.BUS_ERROR, PDP11.REASON.ODDMMUADDR);
}
*/
}
switch (pdr & 0x7) {
case 1: // read-only with trap
@ -1190,6 +1201,18 @@ CPUStatePDP11.prototype.mapVirtualToPhysical = function(virtualAddress, accessFl
return physicalAddress;
};
/**
* readByteFromPhysical(physicalAddress) [formerly readByteByAddr]
*
* @this {CPUStatePDP11}
* @param {number} physicalAddress
* @return {number}
*/
CPUStatePDP11.prototype.readByteFromPhysical = function(physicalAddress)
{
return this.bus.getByte(physicalAddress);
};
/**
* readWordFromPhysical(physicalAddress) [formerly readWordByAddr]
*
@ -1199,6 +1222,10 @@ CPUStatePDP11.prototype.mapVirtualToPhysical = function(virtualAddress, accessFl
*/
CPUStatePDP11.prototype.readWordFromPhysical = function(physicalAddress)
{
if (physicalAddress & 0x1) {
this.regErr |= PDP11.CPUERR.ODDADDR;
this.trap(PDP11.TRAP.BUS_ERROR, PDP11.REASON.ODDMEMADDR);
}
return this.bus.getWord(physicalAddress);
};
@ -1213,30 +1240,6 @@ CPUStatePDP11.prototype.readWordFromVirtual = function(virtualAddress)
return this.readWordFromPhysical(this.mapVirtualToPhysical(virtualAddress, PDP11.ACCESS.READ_WORD));
};
/**
* writeWordToPhysical(physicalAddress, data) [formerly writeWordByAddr]
*
* @this {CPUStatePDP11}
* @param {number} physicalAddress
* @param {number} data
*/
CPUStatePDP11.prototype.writeWordToPhysical = function(physicalAddress, data)
{
this.bus.setWord(physicalAddress, data & 0xffff);
};
/**
* readByteFromPhysical(physicalAddress) [formerly readByteByAddr]
*
* @this {CPUStatePDP11}
* @param {number} physicalAddress
* @return {number}
*/
CPUStatePDP11.prototype.readByteFromPhysical = function(physicalAddress)
{
return this.bus.getByte(physicalAddress);
};
/**
* writeByteToPhysical(physicalAddress, data) [formerly writeByteByAddr]
*
@ -1250,6 +1253,22 @@ CPUStatePDP11.prototype.writeByteToPhysical = function(physicalAddress, data)
this.bus.setByte(physicalAddress, data & 0xff);
};
/**
* writeWordToPhysical(physicalAddress, data) [formerly writeWordByAddr]
*
* @this {CPUStatePDP11}
* @param {number} physicalAddress
* @param {number} data
*/
CPUStatePDP11.prototype.writeWordToPhysical = function(physicalAddress, data)
{
if (physicalAddress & 0x1) {
this.regErr |= PDP11.CPUERR.ODDADDR;
this.trap(PDP11.TRAP.BUS_ERROR, PDP11.REASON.ODDMEMADDR);
}
this.bus.setWord(physicalAddress, data & 0xffff);
};
/**
* popWord()
*

View file

@ -590,7 +590,7 @@ if (DEBUGGER) {
if (addr !== PDP11.ADDR_INVALID) {
this.nDisableMessages++;
/*
* TODO: We also need a Bus interface to disable fnAccess() calls that could trigger a trap()
* TODO: We also need a Bus interface to disable fnIOAccess() calls that could trigger a trap().
*/
b = this.bus.getByteDirect(addr);
this.nDisableMessages--;
@ -614,7 +614,11 @@ if (DEBUGGER) {
if (addr !== PDP11.ADDR_INVALID) {
this.nDisableMessages++;
/*
* TODO: We also need a Bus interface to disable fnAccess() calls that could trigger a trap()
* TODO: We also need a Bus interface to disable fnIOAccess() calls that could trigger a trap().
*
* NOTE: We don't care if the word address is aligned, because 1) we assume the user knows what
* they're doing, and 2) the Bus simply ignores the low address bit anyway. Alignment checks are
* performed by the CPU, not the Bus.
*/
w = this.bus.getWordDirect(addr);
this.nDisableMessages--;
@ -637,7 +641,7 @@ if (DEBUGGER) {
if (addr !== PDP11.ADDR_INVALID) {
this.nDisableMessages++;
/*
* TODO: We also need a Bus interface to disable fnAccess() calls that could trigger a trap()
* TODO: We also need a Bus interface to disable fnIOAccess() calls that could trigger a trap().
*/
this.bus.setByteDirect(addr, b);
this.nDisableMessages--;
@ -660,7 +664,11 @@ if (DEBUGGER) {
if (addr !== PDP11.ADDR_INVALID) {
this.nDisableMessages++;
/*
* TODO: We also need a Bus interface to disable fnAccess() calls that could trigger a trap()
* TODO: We also need a Bus interface to disable fnIOAccess() calls that could trigger a trap().
*
* NOTE: We don't care if the word address is aligned, because 1) we assume the user knows what
* they're doing, and 2) the Bus simply ignores the low address bit anyway. Alignment checks are
* performed by the CPU, not the Bus.
*/
this.bus.setWordDirect(addr, w);
this.nDisableMessages--;
@ -2841,15 +2849,14 @@ if (DEBUGGER) {
var sData = "", sChars = "";
sAddr = this.toStrAddr(dbgAddr);
/*
* It's just coincidence that we want to dump 8 bytes per line when using base 8 and 16 bytes
* per line when using base 16, because octal requires more digits.
* Dump 8 bytes per line when using base 8, and dump 16 bytes when using base 16 (or when dumping dwords)
*/
var nBytes = (size == 4? 16 : this.nBase);
for (i = nBytes; i > 0 && cb > 0; i--) {
var b = this.getByte(dbgAddr, 1);
data |= (b << (iByte++ << 3));
if (iByte == size) {
sData += (this.nBase == 8? str.toOct(data, size * 3) : str.toHex(data, size * 2));
sData += this.toStrBase(data, size);
sData += (size == 1? (i == 9? '-' : ' ') : " ");
data = iByte = 0;
}

View file

@ -79,6 +79,21 @@ var BYTEARRAYS = false;
*/
var TYPEDARRAYS = (typeof ArrayBuffer !== 'undefined');
/**
* WORDBUS forces the Bus and Memory interfaces to assume even addresses when accessing words. Since PDPjs inherited
* its Bus component from PCx86, it originally supported both aligned and unaligned word accesses by default, but since
* the PDP-11 requires aligned (even) word addresses, we can turn off support for unaligned accesses and get some
* performance gains.
*
* When WORDBUS is true, the Bus and Memory components simply ignore the low bit of word addresses, because it is the
* CPU, not the Bus, that's responsible for validating addresses and generating the appropriate traps.
*
* Don't worry that the source code looks MORE complicated rather than LESS with the additional WORDBUS checks, because
* the Closure Compiler eliminates those checks and throws away the (unreachable) code blocks that deal with unaligned
* accesses.
*/
var WORDBUS = true;
/*
* Combine all the shared globals and machine-specific globals into one machine-specific global object,
* which all machine components should start using; eg: "if (PDP11.DEBUG) ..." instead of "if (DEBUG) ...".
@ -95,6 +110,7 @@ var PDP11 = {
MAXDEBUG: MAXDEBUG, // shared
PRIVATE: PRIVATE, // shared
TYPEDARRAYS:TYPEDARRAYS,
WORDBUS: WORDBUS,
SITEHOST: SITEHOST, // shared
XMLVERSION: XMLVERSION, // shared

View file

@ -782,10 +782,15 @@ MemoryPDP11.prototype = {
*/
readWordLE: function readWordLE(off, addr) {
/*
* TODO: It remains to be seen if there's any advantage to checking the offset for an aligned read
* vs. always reading the bytes separately.
* TODO: For non-WORDBUS machines, it remains to be seen if there's any advantage to checking the offset
* for an aligned read vs. always reading the bytes separately.
*/
var w = (off & 0x1)? (this.ab[off] | (this.ab[off+1] << 8)) : this.aw[off >> 1];
var w;
if (PDP11.WORDBUS || !(off & 0x1)) {
w = this.aw[off >> 1];
} else {
w = this.ab[off] | (this.ab[off+1] << 8);
}
if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.MEM)) {
this.dbg.printMessage("Memory.readWord(" + this.dbg.toStrBase(addr) + "): " + this.dbg.toStrBase(w), true);
}
@ -840,14 +845,14 @@ MemoryPDP11.prototype = {
*/
writeWordLE: function writeWordLE(off, w, addr) {
/*
* TODO: It remains to be seen if there's any advantage to checking the offset for an aligned write
* vs. always writing the bytes separately.
* TODO: For non-WORDBUS machines, it remains to be seen if there's any advantage to checking the offset
* for an aligned write vs. always writing the bytes separately.
*/
if (off & 0x1) {
if (PDP11.WORDBUS || !(off & 0x1)) {
this.aw[off >> 1] = w;
} else {
this.ab[off] = w;
this.ab[off+1] = w >> 8;
} else {
this.aw[off >> 1] = w;
}
this.fDirty = true;
if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.MEM)) {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long