Some Bus and Video tweaks

This commit is contained in:
Jeff Parsons 2015-01-27 15:46:22 -08:00 committed by jeffpar
commit 2637a4ca85
9 changed files with 290 additions and 168 deletions

View file

@ -98,19 +98,19 @@ function Bus(parmsBus, cpu, dbg)
*
* iBlock & this.blockMask
*
* While we *could* say that we mask addresses with this.addrMask to simulate "A20 wrap", the simple
* While we *could* say that we mask addresses with this.busMask to simulate "A20 wrap", the simple
* fact is it relieves us from bounds-checking every aMemBlocks index. Address wrapping at the 1Mb
* boundary (ie, the A20 address line) is something we'll have to deal with more carefully on the 80286.
*
* New property Old property Old hard-coded values (when nBusWidth was always 20)
* ------------ ------------ ----------------------------------------------------
* this.addrLimit Bus.ADDR.LIMIT 0xfffff
* this.addrMask N/A N/A
* this.busLimit Bus.ADDR.LIMIT 0xfffff
* this.busMask N/A N/A
* this.blockSize Bus.BLOCK.SIZE 4096
* this.blockLen Bus.BLOCK.LEN (this.blockSize >> 2)
* this.blockShift Bus.BLOCK.SHIFT 12
* this.blockLimit Bus.BLOCK.LIMIT 0xfff
* this.blockTotal Bus.BLOCK.TOTAL ((this.addrLimit + this.blockSize) / this.blockSize) | 0
* this.blockTotal Bus.BLOCK.TOTAL ((this.busLimit + this.blockSize) / this.blockSize) | 0
* this.blockMask Bus.BLOCK.MASK (this.blockTotal - 1) (ie, 0xff)
*
* Note that the blockShift calculation below chooses a 4Kb physical memory block size for a 20-bit bus
@ -123,13 +123,14 @@ function Bus(parmsBus, cpu, dbg)
* memory implementation detail, which should have no bearing on segment or page granularity of any future
* virtual memory implementation.
*/
this.addrLimit = this.addrMask = (1 << this.nBusWidth) - 1;
this.busLimit = this.busMask = (1 << this.nBusWidth) - 1;
this.blockShift = (this.nBusWidth <= 20? 12 : 14);
this.blockSize = 1 << this.blockShift;
this.blockLen = this.blockSize >> 2;
this.blockLimit = this.blockSize - 1;
this.blockTotal = ((this.addrLimit + this.blockSize) / this.blockSize) | 0;
this.blockTotal = ((this.busLimit + this.blockSize) / this.blockSize) | 0;
this.blockMask = this.blockTotal - 1;
this.assert(this.blockTotal <= Bus.BLOCK.MASK);
/*
* Lists of I/O notification functions: aPortInputNotify and aPortOutputNotify are arrays, indexed by
@ -235,6 +236,15 @@ if (BACKTRACK) {
};
}
/*
* scanMemory() records block numbers in bits 0-14, a BackTrack "mod" bit in bit 15, and the block type at bit 16.
*/
Bus.BLOCK = {
MASK: 0x7fff,
BTMOD_SHIFT: 15,
TYPE_SHIFT: 16
};
/**
* initMemory()
*
@ -250,8 +260,8 @@ Bus.prototype.initMemory = function()
var block = this.aMemBlocks[iBlock] = new Memory(addr);
if (DEBUGGER) block.setDebugInfo(this.cpu, this.dbg, addr, this.blockSize);
}
this.cpu.initMemory(this.aMemBlocks, this.addrLimit, this.blockShift, this.blockLimit, this.blockMask);
this.cpu.setAddressMask(this.addrMask);
this.cpu.initMemory(this.aMemBlocks, this.blockShift, this.blockLimit, this.blockMask);
this.cpu.setAddressMask(this.busMask);
};
/**
@ -300,7 +310,7 @@ Bus.prototype.powerUp = function(data, fRepower)
*
* @this {Bus}
* @param {number} addr is the starting physical address of the memory address range
* @param {number} size of the length in bytes of the range; must be a multiple of BLOCK_SIZE
* @param {number} size of the length in bytes of the range; must be a multiple of blockSize
* @param {number} type is one of the Memory.TYPE constants
* @param {Object} [controller] is an optional memory controller component
* @return {boolean} true if successful, false if not
@ -348,27 +358,49 @@ Bus.prototype.cleanMemory = function(addr, size)
};
/**
* scanMemory(addr, size, stats)
* scanMemory(stats, addr, size)
*
* Returns a Stats object for the specified address range with the following properties:
*
* cbTotal: total bytes allocated
* cBlocks: total Memory blocks allocated
* aBlocks: array of allocated Memory block numbers
*
* aBlocks is preallocated to its maximum size, so don't rely on its length; at any given moment,
* only the first cBlocks entries will be valid.
*
* @this {Bus}
* @param {number} [addr]
* @param {number} [size]
* @param {Object} [stats]
* @return {number} bytes allocated
* @param {Object} [stats] previous stats, if any
* @param {number} [addr] starting address of range (0 if none provided)
* @param {number} [size] size of range, in bytes (up to end of address space if none provided)
* @return {Object} updated stats (or new stats if no previous stats provided)
*/
Bus.prototype.scanMemory = function(addr, size, stats)
Bus.prototype.scanMemory = function(stats, addr, size)
{
var cbTotal = 0;
if (addr === undefined) addr = 0;
if (size === undefined) size = (this.addrLimit + 1) - addr;
if (addr == null) addr = 0;
if (size == null) size = (this.busLimit + 1) - addr;
if (stats == null) stats = {cbTotal: 0, cBlocks: 0, aBlocks: new Array(this.blockTotal)};
var iBlock = addr >>> this.blockShift;
var iBlockMax = ((addr + size - 1) >>> this.blockShift);
stats.cbTotal = 0;
stats.cBlocks = 0;
while (iBlock <= iBlockMax) {
var block = this.aMemBlocks[iBlock];
cbTotal += block.size;
stats.cbTotal += block.size;
if (block.size) {
var nBlock = iBlock;
nBlock |= (block.type << Bus.BLOCK.TYPE_SHIFT);
if (BACKTRACK) {
var fMod = block.modBackTrack(false);
if (fMod) nBlock |= (1 << Bus.BLOCK.BTMOD_SHIFT);
}
stats.aBlocks[stats.cBlocks++] = nBlock;
}
iBlock++;
}
return cbTotal;
return stats;
};
/**
@ -379,7 +411,7 @@ Bus.prototype.scanMemory = function(addr, size, stats)
*/
Bus.prototype.getA20 = function()
{
return this.addrLimit == this.addrMask;
return this.busLimit == this.busMask;
};
/**
@ -393,9 +425,9 @@ Bus.prototype.setA20 = function(fEnable)
this.assert(fEnable !== undefined);
if (fEnable !== undefined) {
if (this.nBusWidth > 20) {
var addrMask = (this.addrMask & ~0x100000) | (fEnable? 0x100000 : 0);
if (addrMask != this.addrMask) {
this.addrMask = addrMask;
var addrMask = (this.busMask & ~0x100000) | (fEnable? 0x100000 : 0);
if (addrMask != this.busMask) {
this.busMask = addrMask;
/*
* This callback is required only because the CPU "insists" on using its own memory access functions.
*/
@ -484,7 +516,7 @@ Bus.prototype.removeMemory = function(addr, size)
*/
Bus.prototype.getByte = function(addr)
{
return this.aMemBlocks[(addr & this.addrMask) >> this.blockShift].readByte(addr & this.blockLimit);
return this.aMemBlocks[(addr & this.busMask) >> this.blockShift].readByte(addr & this.blockLimit);
};
/**
@ -498,7 +530,7 @@ Bus.prototype.getByte = function(addr)
*/
Bus.prototype.getByteDirect = function(addr)
{
return this.aMemBlocks[(addr & this.addrMask) >> this.blockShift].readByteDirect(addr & this.blockLimit);
return this.aMemBlocks[(addr & this.busMask) >> this.blockShift].readByteDirect(addr & this.blockLimit);
};
/**
@ -515,9 +547,9 @@ Bus.prototype.getByteDirect = function(addr)
Bus.prototype.getShort = function(addr)
{
var off = addr & this.blockLimit;
var iBlock = (addr & this.addrMask) >> this.blockShift;
var iBlock = (addr & this.busMask) >> this.blockShift;
if (off != this.blockLimit) {
return this.aMemBlocks[iBlock].readWord(off);
return this.aMemBlocks[iBlock].readShort(off);
}
return this.aMemBlocks[iBlock++].readByte(off) | (this.aMemBlocks[iBlock & this.blockMask].readByte(0) << 8);
};
@ -534,9 +566,9 @@ Bus.prototype.getShort = function(addr)
Bus.prototype.getShortDirect = function(addr)
{
var off = addr & this.blockLimit;
var iBlock = (addr & this.addrMask) >> this.blockShift;
var iBlock = (addr & this.busMask) >> this.blockShift;
if (off != this.blockLimit) {
return this.aMemBlocks[iBlock].readWordDirect(off);
return this.aMemBlocks[iBlock].readShortDirect(off);
}
return this.aMemBlocks[iBlock++].readByteDirect(off) | (this.aMemBlocks[iBlock & this.blockMask].readByteDirect(0) << 8);
};
@ -555,7 +587,7 @@ Bus.prototype.getShortDirect = function(addr)
Bus.prototype.getLong = function(addr)
{
var off = addr & this.blockLimit;
var iBlock = (addr & this.addrMask) >> this.blockShift;
var iBlock = (addr & this.busMask) >> this.blockShift;
if (off < this.blockLimit - 2) {
return this.aMemBlocks[iBlock].readLong(off);
}
@ -575,7 +607,7 @@ Bus.prototype.getLong = function(addr)
Bus.prototype.getLongDirect = function(addr)
{
var off = addr & this.blockLimit;
var iBlock = (addr & this.addrMask) >> this.blockShift;
var iBlock = (addr & this.busMask) >> this.blockShift;
if (off < this.blockLimit - 2) {
return this.aMemBlocks[iBlock].readLongDirect(off);
}
@ -595,7 +627,7 @@ Bus.prototype.getLongDirect = function(addr)
*/
Bus.prototype.setByte = function(addr, b)
{
this.aMemBlocks[(addr & this.addrMask) >> this.blockShift].writeByte(addr & this.blockLimit, b & 0xff);
this.aMemBlocks[(addr & this.busMask) >> this.blockShift].writeByte(addr & this.blockLimit, b & 0xff);
};
/**
@ -610,7 +642,7 @@ Bus.prototype.setByte = function(addr, b)
*/
Bus.prototype.setByteDirect = function(addr, b)
{
this.aMemBlocks[(addr & this.addrMask) >> this.blockShift].writeByteDirect(addr & this.blockLimit, b & 0xff);
this.aMemBlocks[(addr & this.busMask) >> this.blockShift].writeByteDirect(addr & this.blockLimit, b & 0xff);
};
/**
@ -627,9 +659,9 @@ Bus.prototype.setByteDirect = function(addr, b)
Bus.prototype.setShort = function(addr, w)
{
var off = addr & this.blockLimit;
var iBlock = (addr & this.addrMask) >> this.blockShift;
var iBlock = (addr & this.busMask) >> this.blockShift;
if (off != this.blockLimit) {
this.aMemBlocks[iBlock].writeWord(off, w & 0xffff);
this.aMemBlocks[iBlock].writeShort(off, w & 0xffff);
return;
}
this.aMemBlocks[iBlock++].writeByte(off, w & 0xff);
@ -649,9 +681,9 @@ Bus.prototype.setShort = function(addr, w)
Bus.prototype.setShortDirect = function(addr, w)
{
var off = addr & this.blockLimit;
var iBlock = (addr & this.addrMask) >> this.blockShift;
var iBlock = (addr & this.busMask) >> this.blockShift;
if (off != this.blockLimit) {
this.aMemBlocks[iBlock].writeWordDirect(off, w & 0xffff);
this.aMemBlocks[iBlock].writeShortDirect(off, w & 0xffff);
return;
}
this.aMemBlocks[iBlock++].writeByteDirect(off, w & 0xff);
@ -672,7 +704,7 @@ Bus.prototype.setShortDirect = function(addr, w)
Bus.prototype.setLong = function(addr, l)
{
var off = addr & this.blockLimit;
var iBlock = (addr & this.addrMask) >> this.blockShift;
var iBlock = (addr & this.busMask) >> this.blockShift;
if (off < this.blockLimit - 2) {
this.aMemBlocks[iBlock].writeLong(off, l);
return;
@ -699,7 +731,7 @@ Bus.prototype.setLong = function(addr, l)
Bus.prototype.setLongDirect = function(addr, l)
{
var off = addr & this.blockLimit;
var iBlock = (addr & this.addrMask) >> this.blockShift;
var iBlock = (addr & this.busMask) >> this.blockShift;
if (off < this.blockLimit - 2) {
this.aMemBlocks[iBlock].writeLongDirect(off, l);
return;
@ -819,7 +851,7 @@ Bus.prototype.writeBackTrackObject = function(addr, bto, off)
Bus.prototype.readBackTrack = function(addr)
{
if (BACKTRACK) {
return this.aMemBlocks[(addr & this.addrMask) >> this.blockShift].readBackTrack(addr & this.blockLimit);
return this.aMemBlocks[(addr & this.busMask) >> this.blockShift].readBackTrack(addr & this.blockLimit);
}
return 0;
};
@ -835,9 +867,11 @@ Bus.prototype.writeBackTrack = function(addr, bti)
{
if (BACKTRACK) {
var slot = bti >>> Bus.BACKTRACK.SLOT_SHIFT;
var btiPrev = this.aMemBlocks[(addr & this.addrMask) >> this.blockShift].writeBackTrack(addr & this.blockLimit, bti);
var iBlock = (addr & this.busMask) >> this.blockShift;
var btiPrev = this.aMemBlocks[iBlock].writeBackTrack(addr & this.blockLimit, bti);
var slotPrev = btiPrev >>> Bus.BACKTRACK.SLOT_SHIFT;
if (slot != slotPrev) {
this.aMemBlocks[iBlock].modBackTrack(true);
if (btiPrev && slotPrev) {
var btoPrev = this.abtObjects[slotPrev-1];
if (!btoPrev) {
@ -935,7 +969,7 @@ Bus.prototype.updateBackTrackCode = function(addr, bti)
} else {
return;
}
this.aMemBlocks[(addr & this.addrMask) >> this.blockShift].writeBackTrack(addr & this.blockLimit, bti);
this.aMemBlocks[(addr & this.busMask) >> this.blockShift].writeBackTrack(addr & this.blockLimit, bti);
}
};

View file

@ -3076,7 +3076,7 @@ if (DEBUGGER) {
* done later, by getAddr(), which returns a negative result (-1) for invalid segments, out-of-range offsets,
* etc. The Debugger's low-level get/set memory functions verify all getAddr() results, but even if an
* invalid address is passed through to the Bus memory interfaces, the address will simply be masked with
* Bus.addrLimit; in the case of -1, that will generally refer to the last byte of physical address space.
* Bus.busLimit; in the case of -1, that will generally refer to the last byte of physical address space.
*
* @this {Debugger}
* @param {string|undefined} sAddr
@ -4596,7 +4596,7 @@ if (DEBUGGER) {
return;
if (n === undefined) n = 1;
var aAddrEnd = this.newAddr(0xffff, aAddr[1], this.bus.addrLimit);
var aAddrEnd = this.newAddr(0xffff, aAddr[1], this.bus.busLimit);
if (sAddrEnd !== undefined) {
aAddrEnd = this.parseAddr(sAddrEnd, Debugger.ADDR_CODE);

View file

@ -1167,7 +1167,7 @@ HDC.prototype.loadDisk = function(iDrive, sDiskName, sDiskPath, fAutoMount)
* @param {string} sDiskName
* @param {string} sDiskPath
*/
HDC.prototype.doneLoadDisk = function onHDCLoadNotify(drive, disk, sDiskName, sDiskPath)
HDC.prototype.doneLoadDisk = function(drive, disk, sDiskName, sDiskPath)
{
drive.fBusy = false;
if ((drive.disk = disk)) {

View file

@ -74,7 +74,7 @@ if (typeof module !== 'undefined') {
* The Bus allocates empty blocks for the entire address space during initialization, so that
* any reads/writes to undefined addresses will have no effect. Later, the ROM and RAM
* components will ask the Bus to allocate memory for specific ranges, and the Bus will allocate
* as many new BLOCK_SIZE Memory objects as the ranges require. Partial Memory blocks could
* as many new blockSize Memory objects as the ranges require. Partial Memory blocks could
* also be supported in theory, but in practice, they're not.
*
* Because Memory blocks now allow us to have a "sparse" address space, we could choose to
@ -105,9 +105,9 @@ if (typeof module !== 'undefined') {
function Memory(addr, size, type, controller)
{
var i;
this.cb = size || 0;
this.adw = null;
this.offset = 0;
this.size = size || 0;
this.type = type || Memory.TYPE.NONE;
this.fReadOnly = (type == Memory.TYPE.ROM);
this.controller = null;
@ -115,11 +115,15 @@ function Memory(addr, size, type, controller)
if (BACKTRACK) {
if (!size || controller) {
this.fModBackTrack = false;
this.readBackTrack = Memory.readBackTrackNone;
this.writeBackTrack = Memory.writeBackTrackNone;
this.modBackTrack = Memory.modBackTrackNone;
} else {
this.fModBackTrack = true;
this.readBackTrack = Memory.readBackTrackIndex;
this.writeBackTrack = Memory.writeBackTrackIndex;
this.modBackTrack = Memory.modBackTrackIndex;
this.abtIndexes = new Array(size);
for (i = 0; i < size; i++) this.abtIndexes[i] = 0;
}
@ -153,7 +157,7 @@ function Memory(addr, size, type, controller)
* know how to deal with this simple 1-1 mapping of addresses to bytes and words.
*
* TODO: Consider initializing the memory array to random (or pseudo-random) values in DEBUG
* mode; pseudo-random might be best, because if that uncovers a bug, it might be reproducible.
* mode; pseudo-random might be best, because if it uncovers a bug, the bug should be reproducible.
*/
if (TYPEDARRAYS) {
this.buffer = new ArrayBuffer(size);
@ -203,6 +207,10 @@ Memory.TYPE = {
VIDEO: 3
};
if (DEBUG) {
Memory.TYPE.NAMES = ["NONE", "RAM", "ROM", "VIDEO"];
}
/**
* readNone(off)
*
@ -241,7 +249,7 @@ Memory.writeNone = function writeNone(off, v)
*/
Memory.readByteMemory = function readByteMemory(off)
{
Component.assert(off >= 0 && off < this.cb);
Component.assert(off >= 0 && off < this.size);
if (FATARRAYS) {
return this.ab[off];
}
@ -249,15 +257,15 @@ Memory.readByteMemory = function readByteMemory(off)
};
/**
* readWordMemory(off)
* readShortMemory(off)
*
* @this {Memory}
* @param {number} off
* @return {number}
*/
Memory.readWordMemory = function readWordMemory(off)
Memory.readShortMemory = function readShortMemory(off)
{
Component.assert(off >= 0 && off < this.cb - 1);
Component.assert(off >= 0 && off < this.size - 1);
if (FATARRAYS) {
return this.ab[off] | (this.ab[off + 1] << 8);
}
@ -282,7 +290,7 @@ Memory.readWordMemory = function readWordMemory(off)
*/
Memory.readLongMemory = function readLongMemory(off)
{
Component.assert(off >= 0 && off < this.cb - 3);
Component.assert(off >= 0 && off < this.size - 3);
if (FATARRAYS) {
return this.ab[off] | (this.ab[off + 1] << 8) | (this.ab[off + 2] << 16) | (this.ab[off + 3] << 24);
}
@ -305,7 +313,7 @@ Memory.readLongMemory = function readLongMemory(off)
*/
Memory.writeByteMemory = function writeByteMemory(off, b)
{
Component.assert(off >= 0 && off < this.cb && (b & 0xff) == b);
Component.assert(off >= 0 && off < this.size && (b & 0xff) == b);
if (FATARRAYS) {
this.ab[off] = b;
} else {
@ -317,15 +325,15 @@ Memory.writeByteMemory = function writeByteMemory(off, b)
};
/**
* writeWordMemory(off, w)
* writeShortMemory(off, w)
*
* @this {Memory}
* @param {number} off
* @param {number} w
*/
Memory.writeWordMemory = function writeWordMemory(off, w)
Memory.writeShortMemory = function writeShortMemory(off, w)
{
Component.assert(off >= 0 && off < this.cb - 1 && (w & 0xffff) == w);
Component.assert(off >= 0 && off < this.size - 1 && (w & 0xffff) == w);
if (FATARRAYS) {
this.ab[off] = (w & 0xff);
this.ab[off + 1] = (w >> 8);
@ -352,7 +360,7 @@ Memory.writeWordMemory = function writeWordMemory(off, w)
*/
Memory.writeLongMemory = function writeLongMemory(off, l)
{
Component.assert(off >= 0 && off < this.cb - 3);
Component.assert(off >= 0 && off < this.size - 3);
if (FATARRAYS) {
this.ab[off] = (l & 0xff);
this.ab[off + 1] = (l >> 8) & 0xff;
@ -386,19 +394,19 @@ Memory.readByteChecked = function readByteChecked(off)
};
/**
* readWordChecked(off)
* readShortChecked(off)
*
* @this {Memory}
* @param {number} off
* @return {number}
*/
Memory.readWordChecked = function readWordChecked(off)
Memory.readShortChecked = function readShortChecked(off)
{
if (DEBUGGER) {
this.dbg.checkMemoryRead(this.addr + off) ||
this.dbg.checkMemoryRead(this.addr + off + 1);
}
return this.readWordDirect(off);
return this.readShortDirect(off);
};
/**
@ -433,19 +441,19 @@ Memory.writeByteChecked = function writeByteChecked(off, b)
};
/**
* writeWordChecked(off, w)
* writeShortChecked(off, w)
*
* @this {Memory}
* @param {number} off
* @param {number} w
*/
Memory.writeWordChecked = function writeWordChecked(off, w)
Memory.writeShortChecked = function writeShortChecked(off, w)
{
if (DEBUGGER) {
this.dbg.checkMemoryWrite(this.addr + off) ||
this.dbg.checkMemoryWrite(this.addr + off + 1);
}
this.writeWordDirect(off, w);
this.writeShortDirect(off, w);
};
/**
@ -475,20 +483,20 @@ Memory.writeLongChecked = function writeLongChecked(off, l)
*/
Memory.readByteTypedArray = function readByteTypedArray(off)
{
Component.assert(off >= 0 && off < this.cb);
Component.assert(off >= 0 && off < this.size);
return this.ab[off];
};
/**
* readWordTypedArray(off)
* readShortTypedArray(off)
*
* @this {Memory}
* @param {number} off
* @return {number}
*/
Memory.readWordTypedArray = function readWordTypedArray(off)
Memory.readShortTypedArray = function readShortTypedArray(off)
{
Component.assert(off >= 0 && off < this.cb - 1);
Component.assert(off >= 0 && off < this.size - 1);
return this.dv.getUint16(off, true);
};
@ -501,7 +509,7 @@ Memory.readWordTypedArray = function readWordTypedArray(off)
*/
Memory.readLongTypedArray = function readLongTypedArray(off)
{
Component.assert(off >= 0 && off < this.cb - 3);
Component.assert(off >= 0 && off < this.size - 3);
return this.dv.getInt32(off, true);
};
@ -514,21 +522,21 @@ Memory.readLongTypedArray = function readLongTypedArray(off)
*/
Memory.writeByteTypedArray = function writeByteTypedArray(off, b)
{
Component.assert(off >= 0 && off < this.cb && (b & 0xff) == b);
Component.assert(off >= 0 && off < this.size && (b & 0xff) == b);
this.ab[off] = b;
this.fDirty = true;
};
/**
* writeWordTypedArray(off, w)
* writeShortTypedArray(off, w)
*
* @this {Memory}
* @param {number} off
* @param {number} w
*/
Memory.writeWordTypedArray = function writeWordTypedArray(off, w)
Memory.writeShortTypedArray = function writeShortTypedArray(off, w)
{
Component.assert(off >= 0 && off < this.cb - 1 && (w & 0xffff) == w);
Component.assert(off >= 0 && off < this.size - 1 && (w & 0xffff) == w);
this.dv.setUint16(off, w, true);
this.fDirty = true;
};
@ -542,7 +550,7 @@ Memory.writeWordTypedArray = function writeWordTypedArray(off, w)
*/
Memory.writeLongTypedArray = function writeLongTypedArray(off, l)
{
Component.assert(off >= 0 && off < this.cb - 3);
Component.assert(off >= 0 && off < this.size - 3);
this.dv.setInt32(off, l, true);
this.fDirty = true;
};
@ -570,6 +578,17 @@ Memory.writeBackTrackNone = function writeBackTrackNone(off, bti)
{
};
/**
* modBackTrackNone(fMod)
*
* @this {Memory}
* @param {boolean} fMod
*/
Memory.modBackTrackNone = function modBackTrackNone(fMod)
{
return false;
};
/**
* readBackTrackIndex(off)
*
@ -579,7 +598,7 @@ Memory.writeBackTrackNone = function writeBackTrackNone(off, bti)
*/
Memory.readBackTrackIndex = function readBackTrackIndex(off)
{
Component.assert(off >= 0 && off < this.cb);
Component.assert(off >= 0 && off < this.size);
return this.abtIndexes[off];
};
@ -594,17 +613,31 @@ Memory.readBackTrackIndex = function readBackTrackIndex(off)
Memory.writeBackTrackIndex = function writeBackTrackIndex(off, bti)
{
var btiPrev;
Component.assert(off >= 0 && off < this.cb);
Component.assert(off >= 0 && off < this.size);
btiPrev = this.abtIndexes[off];
this.abtIndexes[off] = bti;
return btiPrev;
};
Memory.afnMemory = [Memory.readByteMemory, Memory.readWordMemory, Memory.readLongMemory, Memory.writeByteMemory, Memory.writeWordMemory, Memory.writeLongMemory];
Memory.afnChecked = [Memory.readByteChecked, Memory.readWordChecked, Memory.readLongChecked, Memory.writeByteChecked, Memory.writeWordChecked, Memory.writeLongChecked];
/**
* modBackTrackIndex(fMod)
*
* @this {Memory}
* @param {boolean} fMod
* @return {boolean} previous value
*/
Memory.modBackTrackIndex = function modBackTrackIndex(fMod)
{
var fModPrev = this.fModBackTrack;
this.fModBackTrack = fMod;
return fModPrev;
};
Memory.afnMemory = [Memory.readByteMemory, Memory.readShortMemory, Memory.readLongMemory, Memory.writeByteMemory, Memory.writeShortMemory, Memory.writeLongMemory];
Memory.afnChecked = [Memory.readByteChecked, Memory.readShortChecked, Memory.readLongChecked, Memory.writeByteChecked, Memory.writeShortChecked, Memory.writeLongChecked];
if (TYPEDARRAYS) {
Memory.afnTypedArray = [Memory.readByteTypedArray, Memory.readWordTypedArray, Memory.readLongTypedArray, Memory.writeByteTypedArray, Memory.writeWordTypedArray, Memory.writeLongTypedArray];
Memory.afnTypedArray = [Memory.readByteTypedArray, Memory.readShortTypedArray, Memory.readLongTypedArray, Memory.writeByteTypedArray, Memory.writeShortTypedArray, Memory.writeLongTypedArray];
}
Memory.prototype = {
@ -628,7 +661,7 @@ Memory.prototype = {
adw = null;
}
else if (FATARRAYS) {
adw = new Array(this.cb >> 2);
adw = new Array(this.size >> 2);
var off = 0;
for (i = 0; i < adw.length; i++) {
adw[i] = this.ab[off] | (this.ab[off + 1] << 8) | (this.ab[off + 2] << 16) | (this.ab[off + 3] << 24);
@ -637,7 +670,7 @@ Memory.prototype = {
}
else if (TYPEDARRAYS) {
/*
* It might be tempting to just return a copy of Int32Array(this.buffer, 0, this.cb >> 2),
* It might be tempting to just return a copy of Int32Array(this.buffer, 0, this.size >> 2),
* but we can't be sure of the "endianness" of an Int32Array -- which would be OK if the array
* was always saved/restored on the same machine, but there's no guarantee of that, either.
* So we use getInt32() and require little-endian values.
@ -646,7 +679,7 @@ Memory.prototype = {
* a normal array; it's serialized as an Object rather than an Array, so it lacks a "length"
* property and causes problems for State.store() and State.parse().
*/
adw = new Array(this.cb >> 2);
adw = new Array(this.size >> 2);
for (i = 0; i < adw.length; i++) {
adw[i] = this.dv.getInt32(i << 2, true);
}
@ -680,7 +713,7 @@ Memory.prototype = {
* no controller AND no data.
*/
Component.assert(adw != null);
if (adw && this.cb == adw.length << 2) {
if (adw && this.size == adw.length << 2) {
var i;
if (FATARRAYS) {
var off = 0;
@ -725,11 +758,11 @@ Memory.prototype = {
*/
setReadAccess: function(afn, fDirect) {
this.readByte = afn[0] || Memory.readNone;
this.readWord = afn[1] || Memory.readNone;
this.readShort = afn[1] || Memory.readNone;
this.readLong = afn[2] || Memory.readNone;
if (fDirect) {
this.readByteDirect = afn[0] || Memory.readNone;
this.readWordDirect = afn[1] || Memory.readNone;
this.readShortDirect = afn[1] || Memory.readNone;
this.readLongDirect = afn[2] || Memory.readNone;
}
},
@ -742,11 +775,11 @@ Memory.prototype = {
*/
setWriteAccess: function(afn, fDirect) {
this.writeByte = !this.fReadOnly && afn[3] || Memory.writeNone;
this.writeWord = !this.fReadOnly && afn[4] || Memory.writeNone;
this.writeShort = !this.fReadOnly && afn[4] || Memory.writeNone;
this.writeLong = !this.fReadOnly && afn[5] || Memory.writeNone;
if (fDirect) {
this.writeByteDirect = afn[3] || Memory.writeNone;
this.writeWordDirect = afn[4] || Memory.writeNone;
this.writeShortDirect = afn[4] || Memory.writeNone;
this.writeLongDirect = afn[5] || Memory.writeNone;
}
},
@ -757,7 +790,7 @@ Memory.prototype = {
*/
resetReadAccess: function() {
this.readByte = this.readByteDirect;
this.readWord = this.readWordDirect;
this.readShort = this.readShortDirect;
this.readLong = this.readLongDirect;
},
/**
@ -767,7 +800,7 @@ Memory.prototype = {
*/
resetWriteAccess: function() {
this.writeByte = this.fReadOnly? Memory.writeNone : this.writeByteDirect;
this.writeWord = this.fReadOnly? Memory.writeNone : this.writeWordDirect;
this.writeShort = this.fReadOnly? Memory.writeNone : this.writeShortDirect;
this.writeLong = this.fReadOnly? Memory.writeNone : this.writeLongDirect;
},
/**

View file

@ -35,6 +35,8 @@
if (typeof module !== 'undefined') {
var web = require("../../shared/lib/weblib");
var Component = require("../../shared/lib/component");
var Bus = require("./bus");
var Memory = require("./memory");
}
/**
@ -49,7 +51,10 @@ if (typeof module !== 'undefined') {
function Panel(parmsPanel) {
Component.call(this, "Panel", parmsPanel, Panel);
this.canvas = null;
if (BACKTRACK) this.fBackTrack = false;
if (BACKTRACK) {
this.stats = null;
this.fBackTrack = false;
}
}
Component.subclass(Component, Panel);
@ -82,7 +87,7 @@ Panel.prototype.setBinding = function(sHTMLType, sBinding, control)
this.canvas = control;
this.canvasContext = this.canvas.getContext("2d");
/*
* this.canvas.width and this.canvas.height contain the width and height of the canvas, in pixels
* NOTE: this.canvas.width and this.canvas.height contain the width and height of the canvas, in pixels
*/
this.fRedraw = true;
return true;
@ -121,25 +126,6 @@ Panel.prototype.powerUp = function(data, fRepower)
{
if (!fRepower) {
Panel.init();
if (this.canvas) {
if (this.fBackTrack) {
/*
* We need to calculate some parameters based on the canvas pixel dimensions. For now, we're
* going to use 100% of the canvas height, and 75% of the canvas width (starting with the left edge),
* for the live memory display.
*
* For a 640x350 canvas, that means 480x350 pixels for the live memory display, or 168,000 pixels.
* For a 16Mb (24-bit) address space, with 16,777,216 locations, the worst case would mean each pixel
* represents roughly 100 memory locations. But in a machine with only 1152Kb of RAM, 32Kb of Video RAM,
* and 128Kb of ROM, that's only 1,343,488 locations we need to worry about, because we can ignore all
* the unallocated regions.
*
* So to start, we need a function that scans the entire address space, and reports how many bytes are
* actually allocated. At the same time, we should also count how many different objects exist.
*/
this.bus.scanMemory()
}
}
}
return true;
};
@ -156,11 +142,6 @@ Panel.prototype.powerDown = function(fSave)
return true;
};
Panel.prototype.scanMemory = function()
{
};
/**
* updateAnimation()
*
@ -175,7 +156,11 @@ Panel.prototype.updateAnimation = function()
if (this.fRedraw) {
if (BACKTRACK && this.fBackTrack) {
context.font = "40px Arial";
context.fillStyle = "#FFFFFF";
/*
* Even when the canvas from whence the context came has an explicit "color" style,
* the context still defaults to "black", so we must manually propagate the canvas color.
*/
context.fillStyle = this.canvas.style.color;
context.fillText("BackTrack Panel",10,50);
}
this.fRedraw = false;
@ -194,6 +179,62 @@ Panel.prototype.updateAnimation = function()
*/
Panel.prototype.updateStatus = function()
{
if (this.canvas) {
if (this.fBackTrack) {
if (MAXDEBUG) this.log("begin scanMemory()");
this.stats = this.bus.scanMemory(this.stats);
this.findRegions();
if (MAXDEBUG) this.log("end scanMemory(): total bytes: " + this.stats.cbTotal + ", total blocks: " + this.stats.cBlocks + ", total regions: " + this.stats.cRegions);
}
}
};
/**
* findRegions()
*
* This takes the stats object produced by scanMemory() and adds the following:
*
* cRegions: number of contiguous memory regions
* aRegions: array of aBlocks indexes (bits 0-15) combined with block counts (bits 16-31)
*
* It calls addRegion() for each discrete region (set of contiguous blocks with the same type) that it finds.
*
* @this {Panel}
*/
Panel.prototype.findRegions = function()
{
this.stats.cRegions = 0;
if (!this.stats.aRegions) this.stats.aRegions = [];
var typeRegion = -1, iBlockRegion = 0, addrRegion = 0, nBlockPrev = -1;
for (var iBlock = 0; iBlock < this.stats.cBlocks; iBlock++) {
var nBlock = this.stats.aBlocks[iBlock];
var type = nBlock >>> Bus.BLOCK.TYPE_SHIFT;
var nBlockCurr = (nBlock & Bus.BLOCK.MASK);
if (type != typeRegion || nBlockCurr != nBlockPrev + 1) {
var cBlocks = iBlock - iBlockRegion;
if (cBlocks) this.addRegion(addrRegion, iBlockRegion, cBlocks, typeRegion);
typeRegion = type;
iBlockRegion = iBlock;
addrRegion = (nBlock & Bus.BLOCK.MASK) << this.bus.blockShift;
}
nBlockPrev = nBlockCurr;
}
this.addRegion(addrRegion, iBlockRegion, iBlock - iBlockRegion, typeRegion);
};
/**
* addRegion(addr, iBlock, cBlocks, type)
*
* @this {Panel}
* @param {number} addr
* @param {number} iBlock
* @param {number} cBlocks
* @param {number} type
*/
Panel.prototype.addRegion = function(addr, iBlock, cBlocks, type)
{
this.stats.aRegions[this.stats.cRegions++] = (iBlock | cBlocks << 16);
if (MAXDEBUG) this.log("region " + this.stats.cRegions + " (addr " + str.toHex(addr) + ", type " + Memory.TYPE.NAMES[type] + ") contains " + cBlocks + " blocks");
};
/**

View file

@ -710,10 +710,10 @@ Video.aCGAColorSet2 = [Video.ATTRS.FGND_CYAN, Video.ATTRS.FGND_MAGENTA, Video.A
Video.aEGAPalDef = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F];
Video.aEGAByteToDW = [
0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff,
0x00ff0000, 0x00ff00ff, 0x00ffff00, 0x00ffffff,
0xff000000, 0xff0000ff, 0xff00ff00, 0xff00ffff,
0xffff0000, 0xffff00ff, 0xffffff00, 0xffffffff
0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff,
0x00ff0000, 0x00ff00ff, 0x00ffff00, 0x00ffffff,
0xff000000|0, 0xff0000ff|0, 0xff00ff00|0, 0xff00ffff|0,
0xffff0000|0, 0xffff00ff|0, 0xffffff00|0, 0xffffffff|0
];
Video.aEGADWToByte = [];
@ -725,14 +725,14 @@ Video.aEGADWToByte[0x00800000] = 0x4;
Video.aEGADWToByte[0x00800080] = 0x5;
Video.aEGADWToByte[0x00808000] = 0x6;
Video.aEGADWToByte[0x00808080] = 0x7;
Video.aEGADWToByte[0x80000000] = 0x8;
Video.aEGADWToByte[0x80000080] = 0x9;
Video.aEGADWToByte[0x80008000] = 0xa;
Video.aEGADWToByte[0x80008080] = 0xb;
Video.aEGADWToByte[0x80800000] = 0xc;
Video.aEGADWToByte[0x80800080] = 0xd;
Video.aEGADWToByte[0x80808000] = 0xe;
Video.aEGADWToByte[0x80808080] = 0xf;
Video.aEGADWToByte[0x80000000|0] = 0x8;
Video.aEGADWToByte[0x80000080|0] = 0x9;
Video.aEGADWToByte[0x80008000|0] = 0xa;
Video.aEGADWToByte[0x80008080|0] = 0xb;
Video.aEGADWToByte[0x80800000|0] = 0xc;
Video.aEGADWToByte[0x80800080|0] = 0xd;
Video.aEGADWToByte[0x80808000|0] = 0xe;
Video.aEGADWToByte[0x80808080|0] = 0xf;
/**
* Card(video, iCard, data, cbMemory)
@ -1241,13 +1241,13 @@ Card.ACCESS.WRITE.MODE2XOR = 0xE000;
Card.ACCESS.WRITE.MASK = 0xff00;
/**
* readWord(off)
* readShort(off)
*
* @this {Memory}
* @param {number} off
* @return {number}
*/
Card.ACCESS.readWord = function readWord(off)
Card.ACCESS.readShort = function readShort(off)
{
return this.readByte(off) | (this.readByte(off + 1) << 8);
};
@ -1265,13 +1265,13 @@ Card.ACCESS.readLong = function readLong(off)
};
/**
* writeWord(off, w)
* writeShort(off, w)
*
* @this {Memory}
* @param {number} off
* @param {number} w
*/
Card.ACCESS.writeWord = function writeWord(off, w)
Card.ACCESS.writeShort = function writeShort(off, w)
{
Component.assert(!(w & ~0xffff));
this.writeByte(off, w & 0xff);
@ -1655,11 +1655,11 @@ Card.prototype.initEGA = function(data, nMonitorType)
*/
/*15*/ Card.ACCESS.READ.MODE0 | Card.ACCESS.READ.EVENODD | Card.ACCESS.WRITE.MODE0 | Card.ACCESS.WRITE.EVENODD,
/*16*/ 0,
/*17*/ 0xffffffff,
/*17*/ 0xffffffff|0,
/*18*/ 0,
/*19*/ 0xffffffff,
/*19*/ 0xffffffff|0,
/*20*/ 0,
/*21*/ 0xffffffff,
/*21*/ 0xffffffff|0,
/*22*/ 0,
/*23*/ 0,
/*24*/ 0
@ -1953,7 +1953,7 @@ Card.prototype.setMemoryAccess = function(nAccess)
}
}
if (!this.afnAccess) {
this.afnAccess = [null, Card.ACCESS.readWord, Card.ACCESS.readLong, null, Card.ACCESS.writeWord, Card.ACCESS.writeLong];
this.afnAccess = [null, Card.ACCESS.readShort, Card.ACCESS.readLong, null, Card.ACCESS.writeShort, Card.ACCESS.writeLong];
}
this.afnAccess[0] = fnReadByte;
this.afnAccess[3] = fnWriteByte;
@ -4340,8 +4340,8 @@ Video.prototype.updateScreenGraphicsEGA = function(addrScreen, addrScreenLimit)
if (x < xDirty) xDirty = x;
for (var iPixel = 0; iPixel < nPixelsPerCell; iPixel++) {
/*
* JavaScript Alert: if adwMemory contains a 32-bit value such as -1526726656, and then we mask it
* with 0x80808080, we end up with -2147483648, which in a perfect 32-bit world, would be equivalent
* JavaScript Alert: if adwMemory contains a 32-bit value such as -1526726656, and then we mask
* it with 0x80808080, we end up with -2147483648, which in a perfect 32-bit world, would be equal
* to 0x80000000, which means that when we look up "Video.aEGADWToByte[0x80000000]", we should get
* the entry containing 0x8. But no, in JavaScript, since the original value was negative, the
* masked value is still negative, because there are 52 "significand" bits in JavaScript numbers,
@ -4349,13 +4349,17 @@ Video.prototype.updateScreenGraphicsEGA = function(addrScreen, addrScreenLimit)
*
* This can be confirmed by looking at dwPixel.toString(16), which returns "-80000000". One solution
* is to add 4294967296 (0x100000000) to any negative 32-bit value for which we need the positive
* representation.
* representation. A better solution (ie, one that doesn't require 33-bit values, triggering floating
* point arithmetic) is storing negative indexes in the lookup array (aEGADWToByte). However, you CANNOT
* do that by simply writing a value like 0x80000080 as "-0x80000080", because JavaScript will interpret
* that as the negation of 2147483776, yielding -2147483776, the low 32 bits of which are 0x7FFFFFF80,
* not 0x80000080 as intended. So, the safest way to write a constant like that is "0x80000080|0".
*
* And, since assertions don't fix problems (only catch them, and only in DEBUG builds), I'm also
* ensuring that bPixel will always default to 0 if an undefined value ever slips through again.
*/
var dwPixel = data & 0x80808080;
if (dwPixel < 0) dwPixel += 0x100000000;
// if (dwPixel < 0) dwPixel += 0x100000000;
this.assert(Video.aEGADWToByte[dwPixel] !== undefined);
var bPixel = Video.aEGADWToByte[dwPixel] || 0;
this.setPixel(this.imageScreenBuffer, x++, y, aPixelColors[bPixel]);

View file

@ -167,7 +167,7 @@ function X86CPU(parmsCPU) {
* when the Bus is initialized.
*/
this.aMemBlocks = [];
this.addrMemMask = this.blockShift = this.blockLimit = this.blockMask = 0;
this.busMask = this.blockShift = this.blockLimit = this.blockMask = 0;
if (SAMPLER) {
/*
@ -442,7 +442,7 @@ X86CPU.PREFETCH = {
};
/**
* initMemory(aMemBlocks, addrLimit, blockShift, blockLimit, blockMask)
* initMemory(aMemBlocks, busMask, blockShift, blockLimit, blockMask)
*
* Notification from Bus.initMemory(), giving us direct access to the entire memory space
* (aMemBlocks).
@ -485,15 +485,13 @@ X86CPU.PREFETCH = {
*
* @this {X86CPU}
* @param {Array} aMemBlocks
* @param {number} addrLimit
* @param {number} blockShift
* @param {number} blockLimit
* @param {number} blockMask
*/
X86CPU.prototype.initMemory = function(aMemBlocks, addrLimit, blockShift, blockLimit, blockMask)
X86CPU.prototype.initMemory = function(aMemBlocks, blockShift, blockLimit, blockMask)
{
this.aMemBlocks = aMemBlocks;
this.addrMemMask = addrLimit;
this.blockShift = blockShift;
this.blockLimit = blockLimit;
this.blockMask = blockMask;
@ -508,16 +506,16 @@ X86CPU.prototype.initMemory = function(aMemBlocks, addrLimit, blockShift, blockL
};
/**
* setAddressMask(addrMask)
* setAddressMask(busMask)
*
* Notification from Bus.setA20(), called whenever the A20 line changes.
*
* @this {X86CPU}
* @param {number} addrMask
* @param {number} busMask
*/
X86CPU.prototype.setAddressMask = function(addrMask)
X86CPU.prototype.setAddressMask = function(busMask)
{
this.addrMemMask = addrMask;
this.busMask = busMask;
};
/**
@ -1879,7 +1877,7 @@ X86CPU.prototype.setBinding = function(sHTMLType, sBinding, control)
X86CPU.prototype.getByte = function(addr)
{
if (BACKTRACK) this.backTrack.btiMemLo = this.bus.readBackTrack(addr);
return this.aMemBlocks[(addr & this.addrMemMask) >> this.blockShift].readByte(addr & this.blockLimit);
return this.aMemBlocks[(addr & this.busMask) >> this.blockShift].readByte(addr & this.blockLimit);
};
/**
@ -1892,7 +1890,7 @@ X86CPU.prototype.getByte = function(addr)
X86CPU.prototype.getShort = function(addr)
{
var off = addr & this.blockLimit;
var iBlock = (addr & this.addrMemMask) >> this.blockShift;
var iBlock = (addr & this.busMask) >> this.blockShift;
/*
* On the 8088, it takes 4 cycles to read the additional byte REGARDLESS whether the address is odd or even.
* TODO: For the 8086, the penalty is actually "(addr & 0x1) << 2" (4 additional cycles only when the address is odd).
@ -1904,7 +1902,7 @@ X86CPU.prototype.getShort = function(addr)
this.backTrack.btiMemHi = this.bus.readBackTrack(addr + 1);
}
if (off < this.blockLimit) {
return this.aMemBlocks[iBlock].readWord(off);
return this.aMemBlocks[iBlock].readShort(off);
}
return this.aMemBlocks[iBlock].readByte(off) | (this.aMemBlocks[(iBlock + 1) & this.blockMask].readByte(0) << 8);
};
@ -1919,7 +1917,7 @@ X86CPU.prototype.getShort = function(addr)
X86CPU.prototype.getLong = function(addr)
{
var off = addr & this.blockLimit;
var iBlock = (addr & this.addrMemMask) >> this.blockShift;
var iBlock = (addr & this.busMask) >> this.blockShift;
if (BACKTRACK) {
this.backTrack.btiMemLo = this.bus.readBackTrack(addr);
this.backTrack.btiMemHi = this.bus.readBackTrack(addr + 1);
@ -1941,7 +1939,7 @@ X86CPU.prototype.getLong = function(addr)
X86CPU.prototype.setByte = function(addr, b)
{
if (BACKTRACK) this.bus.writeBackTrack(addr, this.backTrack.btiMemLo);
this.aMemBlocks[(addr & this.addrMemMask) >> this.blockShift].writeByte(addr & this.blockLimit, b & 0xff);
this.aMemBlocks[(addr & this.busMask) >> this.blockShift].writeByte(addr & this.blockLimit, b & 0xff);
};
/**
@ -1954,7 +1952,7 @@ X86CPU.prototype.setByte = function(addr, b)
X86CPU.prototype.setShort = function(addr, w)
{
var off = addr & this.blockLimit;
var iBlock = (addr & this.addrMemMask) >> this.blockShift;
var iBlock = (addr & this.busMask) >> this.blockShift;
/*
* On the 8088, it takes 4 cycles to write the additional byte REGARDLESS whether the address is odd or even.
* TODO: For the 8086, the penalty is actually "(addr & 0x1) << 2" (4 additional cycles only when the address is odd).
@ -1966,7 +1964,7 @@ X86CPU.prototype.setShort = function(addr, w)
this.bus.writeBackTrack(addr + 1, this.backTrack.btiMemHi);
}
if (off < this.blockLimit) {
this.aMemBlocks[iBlock].writeWord(off, w & 0xffff);
this.aMemBlocks[iBlock].writeShort(off, w & 0xffff);
return;
}
this.aMemBlocks[iBlock++].writeByte(off, w & 0xff);
@ -1983,7 +1981,7 @@ X86CPU.prototype.setShort = function(addr, w)
X86CPU.prototype.setLong = function(addr, l)
{
var off = addr & this.blockLimit;
var iBlock = (addr & this.addrMemMask) >> this.blockShift;
var iBlock = (addr & this.busMask) >> this.blockShift;
this.nStepCycles -= this.CYCLES.nWordCyclePenalty;
if (BACKTRACK) {
@ -2292,10 +2290,10 @@ X86CPU.prototype.getBytePrefetch = function(addr)
* with side-effects we may not want, and in any case, while it seemed to improve Safari's performance slightly,
* it did nothing for the oddball Chrome performance I'm seeing with PREFETCH enabled.
*
* b = this.aMemBlocks[(addr & this.addrMemMask) >> this.blockShift].readByte(addr & this.blockLimit);
* b = this.aMemBlocks[(addr & this.busMask) >> this.blockShift].readByte(addr & this.blockLimit);
* this.nBusCycles += 4;
* this.cbPrefetchValid = 0;
* this.addrPrefetchHead = (addr + 1) & this.addrMemMask;
* this.addrPrefetchHead = (addr + 1) & this.busMask;
* return b;
*/
}
@ -2342,10 +2340,10 @@ X86CPU.prototype.fillPrefetch = function(n)
{
while (n-- > 0 && this.cbPrefetchQueued < X86CPU.PREFETCH.QUEUE) {
var addr = this.addrPrefetchHead;
var b = this.aMemBlocks[(addr & this.addrMemMask) >> this.blockShift].readByte(addr & this.blockLimit);
var b = this.aMemBlocks[(addr & this.busMask) >> this.blockShift].readByte(addr & this.blockLimit);
this.aPrefetch[this.iPrefetchHead] = b | (addr << 8);
if (MAXDEBUG) this.printMessage(" fillPrefetch[" + this.iPrefetchHead + "]: " + str.toHex(addr) + ":" + str.toHexByte(b));
this.addrPrefetchHead = (addr + 1) & this.addrMemMask;
this.addrPrefetchHead = (addr + 1) & this.busMask;
this.iPrefetchHead = (this.iPrefetchHead + 1) & X86CPU.PREFETCH.MASK;
this.cbPrefetchQueued++;
/*