Update CPU's getLong() and setLong() interfaces
This commit is contained in:
parent
e0959dc00c
commit
7fb26846f9
4 changed files with 62 additions and 34 deletions
|
|
@ -4746,7 +4746,7 @@ if (DEBUGGER) {
|
||||||
if (this.cmp) this.cmp.reset();
|
if (this.cmp) this.cmp.reset();
|
||||||
return true;
|
return true;
|
||||||
case "ver":
|
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;
|
return true;
|
||||||
default:
|
default:
|
||||||
ch0 = sCmd.charAt(0);
|
ch0 = sCmd.charAt(0);
|
||||||
|
|
|
||||||
|
|
@ -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
|
* 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.
|
* 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.
|
* Array of numbers that stores 32 bits -- 4 consecutive bytes -- per number), so TYPEDARRAYS is completely disabled.
|
||||||
*
|
*
|
||||||
* See the Memory component for details.
|
* See the Memory component for details.
|
||||||
|
|
|
||||||
|
|
@ -80,14 +80,14 @@ if (typeof module !== 'undefined') {
|
||||||
* Because Memory blocks now allow us to have a "sparse" address space, we could choose to
|
* 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,
|
* 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
|
* 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.
|
* be faster and word accesses somewhat less faster.
|
||||||
*
|
*
|
||||||
* However, preliminary testing of that feature (FATARRAYS) did not yield significantly 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
|
* 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
|
* 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
|
* as well as LONGARRAYS; 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
|
* 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
|
* 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).
|
* 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 idw = off >> 2;
|
||||||
var nShift = (off & 0x3) << 3;
|
var nShift = (off & 0x3) << 3;
|
||||||
var dw = this.adw[idw];
|
var l = this.adw[idw];
|
||||||
if (nShift) {
|
if (nShift) {
|
||||||
dw >>>= nShift;
|
l >>>= nShift;
|
||||||
dw |= this.adw[idw + 1] << (32 - 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}
|
* @this {Memory}
|
||||||
* @param {number} off
|
* @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);
|
Component.assert(off >= 0 && off < this.cb - 3);
|
||||||
if (FATARRAYS) {
|
if (FATARRAYS) {
|
||||||
this.ab[off] = (dw & 0xff);
|
this.ab[off] = (l & 0xff);
|
||||||
this.ab[off + 1] = (dw >> 8) & 0xff;
|
this.ab[off + 1] = (l >> 8) & 0xff;
|
||||||
this.ab[off + 2] = (dw >> 16) & 0xff;
|
this.ab[off + 2] = (l >> 16) & 0xff;
|
||||||
this.ab[off + 3] = (dw >> 24) & 0xff;
|
this.ab[off + 3] = (l >> 24) & 0xff;
|
||||||
} else {
|
} else {
|
||||||
var idw = off >> 2;
|
var idw = off >> 2;
|
||||||
var nShift = (off & 0x3) << 3;
|
var nShift = (off & 0x3) << 3;
|
||||||
if (!nShift) {
|
if (!nShift) {
|
||||||
this.adw[idw] = dw;
|
this.adw[idw] = l;
|
||||||
} else {
|
} else {
|
||||||
this.adw[idw] = (this.adw[idw] & ~(0xffffffff << nShift)) | (dw << nShift);
|
this.adw[idw] = (this.adw[idw] & ~(0xffffffff << nShift)) | (l << nShift);
|
||||||
idw++;
|
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;
|
this.fDirty = true;
|
||||||
|
|
@ -449,13 +449,13 @@ Memory.writeWordChecked = function writeWordChecked(off, w)
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* writeLongChecked(off, dw)
|
* writeLongChecked(off, l)
|
||||||
*
|
*
|
||||||
* @this {Memory}
|
* @this {Memory}
|
||||||
* @param {number} off
|
* @param {number} off
|
||||||
* @param {number} dw
|
* @param {number} l
|
||||||
*/
|
*/
|
||||||
Memory.writeLongChecked = function writeLongChecked(off, dw)
|
Memory.writeLongChecked = function writeLongChecked(off, l)
|
||||||
{
|
{
|
||||||
if (DEBUGGER) {
|
if (DEBUGGER) {
|
||||||
this.dbg.checkMemoryWrite(this.addr + off) ||
|
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 + 2) ||
|
||||||
this.dbg.checkMemoryWrite(this.addr + off + 3)
|
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}
|
* @this {Memory}
|
||||||
* @param {number} off
|
* @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);
|
Component.assert(off >= 0 && off < this.cb - 3);
|
||||||
this.dv.setInt32(off, dw, true);
|
this.dv.setInt32(off, l, true);
|
||||||
this.fDirty = true;
|
this.fDirty = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1906,7 +1906,7 @@ X86CPU.prototype.getWord = function(addr)
|
||||||
*
|
*
|
||||||
* @this {X86CPU}
|
* @this {X86CPU}
|
||||||
* @param {number} addr is a physical (non-segmented) address
|
* @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)
|
X86CPU.prototype.getLong = function(addr)
|
||||||
{
|
{
|
||||||
|
|
@ -1916,13 +1916,11 @@ X86CPU.prototype.getLong = function(addr)
|
||||||
this.backTrack.btiMemLo = this.bus.readBackTrack(addr);
|
this.backTrack.btiMemLo = this.bus.readBackTrack(addr);
|
||||||
this.backTrack.btiMemHi = this.bus.readBackTrack(addr + 1);
|
this.backTrack.btiMemHi = this.bus.readBackTrack(addr + 1);
|
||||||
}
|
}
|
||||||
var nShift = (off & 0x3) << 3;
|
if (off < this.blockLimit - 2) {
|
||||||
var dw = this.aMemBlocks[iBlock].readLong(off & ~0x3);
|
return this.aMemBlocks[iBlock].readLong(off);
|
||||||
if (nShift) {
|
|
||||||
dw >>>= nShift;
|
|
||||||
dw |= (this.aMemBlocks[(iBlock + 1) & this.blockMask].readLong(0) << (32 - nShift));
|
|
||||||
}
|
}
|
||||||
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);
|
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)
|
* getEAByte(seg, off)
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue