diff --git a/modules/pcjs/lib/debugger.js b/modules/pcjs/lib/debugger.js index 6bf4b073d..eb6231fab 100644 --- a/modules/pcjs/lib/debugger.js +++ b/modules/pcjs/lib/debugger.js @@ -4746,7 +4746,7 @@ if (DEBUGGER) { if (this.cmp) this.cmp.reset(); return true; case "ver": - this.println((APPNAME || "PCjs") + " version " + APPVERSION + " (" + (I386? "80386" : "80286") + (COMPILED? ",RELEASE" : (DEBUG? ",DEBUG" : ",NODEBUG")) + (PREFETCH? ",PREFETCH" : ",NOPREFETCH") + (TYPEDARRAYS? ",TYPEDARRAYS" : (FATARRAYS? ",FATARRAYS" : ",DWORDARRAYS")) + (BACKTRACK? ",BACKTRACK" : "") + ")"); + this.println((APPNAME || "PCjs") + " version " + APPVERSION + " (" + (I386? "80386" : "80286") + (COMPILED? ",RELEASE" : (DEBUG? ",DEBUG" : ",NODEBUG")) + (PREFETCH? ",PREFETCH" : ",NOPREFETCH") + (TYPEDARRAYS? ",TYPEDARRAYS" : (FATARRAYS? ",FATARRAYS" : ",LONGARRAYS")) + (BACKTRACK? ",BACKTRACK" : "") + ")"); return true; default: ch0 = sCmd.charAt(0); diff --git a/modules/pcjs/lib/defines.js b/modules/pcjs/lib/defines.js index e6a045ad1..b953afb26 100644 --- a/modules/pcjs/lib/defines.js +++ b/modules/pcjs/lib/defines.js @@ -85,7 +85,7 @@ var FATARRAYS = false; * TYPEDARRAYS enables use of typed arrays for Memory blocks. This used to be a compile-time-only option, but I've * added Memory access functions for typed arrays (see Memory.afnTypedArray), so support can be enabled dynamically. * - * However, TYPEDARRAYS has always been slightly slower than the original DWORDARRAYS implementation (which uses an + * However, TYPEDARRAYS has always been slightly slower than the original LONGARRAYS implementation (which uses an * Array of numbers that stores 32 bits -- 4 consecutive bytes -- per number), so TYPEDARRAYS is completely disabled. * * See the Memory component for details. diff --git a/modules/pcjs/lib/memory.js b/modules/pcjs/lib/memory.js index 30db021d8..20ecf0b76 100644 --- a/modules/pcjs/lib/memory.js +++ b/modules/pcjs/lib/memory.js @@ -80,14 +80,14 @@ if (typeof module !== 'undefined') { * Because Memory blocks now allow us to have a "sparse" address space, we could choose to * take the memory hit of allocating 4K arrays per block, where each element stores only one byte, * instead of the more frugal but slightly slower approach of allocating arrays of 32-bit dwords - * (DWORDARRAYS) and shifting/masking bytes/words to/from dwords; in theory, byte accesses would + * (LONGARRAYS) and shifting/masking bytes/words to/from dwords; in theory, byte accesses would * be faster and word accesses somewhat less faster. * * However, preliminary testing of that feature (FATARRAYS) did not yield significantly faster * performance, so it is OFF by default to minimize our memory consumption. Using TYPEDARRAYS * would seem best, but as discussed in defines.js, it's off by default, because it doesn't perform - * as well as DWORDARRAYS; the other advantage of TYPEDARRAYS is that it should theoretically use - * about 1/2 the memory of DWORDARRAYS (32-bit elements vs 64-bit numbers), but I value speed over + * as well as LONGARRAYS; the other advantage of TYPEDARRAYS is that it should theoretically use + * about 1/2 the memory of LONGARRAYS (32-bit elements vs 64-bit numbers), but I value speed over * size at this point. Also, not all JavaScript implementations support TYPEDARRAYS (IE9 is probably * the only real outlier: it lacks typed arrays but otherwise has all the necessary HTML5 support). * @@ -288,12 +288,12 @@ Memory.readLongMemory = function readLongMemory(off) } var idw = off >> 2; var nShift = (off & 0x3) << 3; - var dw = this.adw[idw]; + var l = this.adw[idw]; if (nShift) { - dw >>>= nShift; - dw |= this.adw[idw + 1] << (32 - nShift); + l >>>= nShift; + l |= this.adw[idw + 1] << (32 - nShift); } - return dw; + return l; }; /** @@ -344,29 +344,29 @@ Memory.writeWordMemory = function writeWordMemory(off, w) }; /** - * writeLongMemory(off, dw) + * writeLongMemory(off, l) * * @this {Memory} * @param {number} off - * @param {number} dw + * @param {number} l */ -Memory.writeLongMemory = function writeLongMemory(off, dw) +Memory.writeLongMemory = function writeLongMemory(off, l) { Component.assert(off >= 0 && off < this.cb - 3); if (FATARRAYS) { - this.ab[off] = (dw & 0xff); - this.ab[off + 1] = (dw >> 8) & 0xff; - this.ab[off + 2] = (dw >> 16) & 0xff; - this.ab[off + 3] = (dw >> 24) & 0xff; + this.ab[off] = (l & 0xff); + this.ab[off + 1] = (l >> 8) & 0xff; + this.ab[off + 2] = (l >> 16) & 0xff; + this.ab[off + 3] = (l >> 24) & 0xff; } else { var idw = off >> 2; var nShift = (off & 0x3) << 3; if (!nShift) { - this.adw[idw] = dw; + this.adw[idw] = l; } else { - this.adw[idw] = (this.adw[idw] & ~(0xffffffff << nShift)) | (dw << nShift); + this.adw[idw] = (this.adw[idw] & ~(0xffffffff << nShift)) | (l << nShift); idw++; - this.adw[idw] = (this.adw[idw] & (0xffffffff << nShift)) | (dw >>> (32 - nShift)); + this.adw[idw] = (this.adw[idw] & (0xffffffff << nShift)) | (l >>> (32 - nShift)); } } this.fDirty = true; @@ -449,13 +449,13 @@ Memory.writeWordChecked = function writeWordChecked(off, w) }; /** - * writeLongChecked(off, dw) + * writeLongChecked(off, l) * * @this {Memory} * @param {number} off - * @param {number} dw + * @param {number} l */ -Memory.writeLongChecked = function writeLongChecked(off, dw) +Memory.writeLongChecked = function writeLongChecked(off, l) { if (DEBUGGER) { this.dbg.checkMemoryWrite(this.addr + off) || @@ -463,7 +463,7 @@ Memory.writeLongChecked = function writeLongChecked(off, dw) this.dbg.checkMemoryWrite(this.addr + off + 2) || this.dbg.checkMemoryWrite(this.addr + off + 3) } - this.writeLongDirect(off, dw); + this.writeLongDirect(off, l); }; /** @@ -534,16 +534,16 @@ Memory.writeWordTypedArray = function writeWordTypedArray(off, w) }; /** - * writeLongTypedArray(off, dw) + * writeLongTypedArray(off, l) * * @this {Memory} * @param {number} off - * @param {number} dw + * @param {number} l */ -Memory.writeLongTypedArray = function writeLongTypedArray(off, dw) +Memory.writeLongTypedArray = function writeLongTypedArray(off, l) { Component.assert(off >= 0 && off < this.cb - 3); - this.dv.setInt32(off, dw, true); + this.dv.setInt32(off, l, true); this.fDirty = true; }; diff --git a/modules/pcjs/lib/x86cpu.js b/modules/pcjs/lib/x86cpu.js index 1d15a4e18..75a844dde 100644 --- a/modules/pcjs/lib/x86cpu.js +++ b/modules/pcjs/lib/x86cpu.js @@ -1906,7 +1906,7 @@ X86CPU.prototype.getWord = function(addr) * * @this {X86CPU} * @param {number} addr is a physical (non-segmented) address - * @return {number} word (32-bit) value at that address + * @return {number} long (32-bit) value at that address */ X86CPU.prototype.getLong = function(addr) { @@ -1916,13 +1916,11 @@ X86CPU.prototype.getLong = function(addr) this.backTrack.btiMemLo = this.bus.readBackTrack(addr); this.backTrack.btiMemHi = this.bus.readBackTrack(addr + 1); } - var nShift = (off & 0x3) << 3; - var dw = this.aMemBlocks[iBlock].readLong(off & ~0x3); - if (nShift) { - dw >>>= nShift; - dw |= (this.aMemBlocks[(iBlock + 1) & this.blockMask].readLong(0) << (32 - nShift)); + if (off < this.blockLimit - 2) { + return this.aMemBlocks[iBlock].readLong(off); } - return dw; + var nShift = (off & 0x3) << 3; + return (this.aMemBlocks[iBlock].readLong(off & ~0x3) >>> nShift) | (this.aMemBlocks[(iBlock + 1) & this.blockMask].readLong(0) << (32 - nShift)); }; /** @@ -1967,6 +1965,36 @@ X86CPU.prototype.setWord = function(addr, w) this.aMemBlocks[iBlock & this.blockMask].writeByte(0, (w >> 8) & 0xff); }; +/** + * setLong(addr, l) + * + * @this {X86CPU} + * @param {number} addr is a physical (non-segmented) address + * @param {number} l is the long (32-bit) value to write + */ +X86CPU.prototype.setLong = function(addr, l) +{ + var off = addr & this.blockLimit; + var iBlock = (addr & this.addrMemMask) >> this.blockShift; + this.nStepCycles -= this.CYCLES.nWordCyclePenalty; + + if (BACKTRACK) { + this.bus.writeBackTrack(addr, this.backTrack.btiMemLo); + this.bus.writeBackTrack(addr + 1, this.backTrack.btiMemHi); + } + if (off < this.blockLimit - 2) { + this.aMemBlocks[iBlock].writeLong(off, l); + return; + } + var lPrev, nShift = (off & 0x3) << 3; + off &= ~0x3; + lPrev = this.aMemBlocks[iBlock].readLong(off); + this.aMemBlocks[iBlock].writeLong(off, (lPrev & ~(0xffffffff << nShift)) | (l << nShift)); + iBlock = (iBlock + 1) & this.blockMask; + lPrev = this.aMemBlocks[iBlock].readLong(0); + this.aMemBlocks[iBlock].writeLong(0, (lPrev & (0xffffffff << nShift)) | (l >>> (32 - nShift))); +}; + /** * getEAByte(seg, off) *