get byte(){return -1;} | get byte(){return -1;} | ||||
set byte(b){} | set byte(b){} | ||||
// Shorthand method for accessing an address and returning a byte. | |||||
// Same as... | |||||
// | |||||
// mem.address = <16 bit value> | |||||
// let res = mem.byte | |||||
// | |||||
// NOTE: This will trigger read listeners. | |||||
read(a){ | read(a){ | ||||
this.address = a; | this.address = a; | ||||
return this.byte; | return this.byte; | ||||
} | } | ||||
// Shorthand method for accessing an address and setting it's byte. | |||||
// Same as... | |||||
// | |||||
// mem.address = <16 bit value> | |||||
// mem.byte = <1 byte value> | |||||
// | |||||
// NOTE: This will trigger write listeners. | |||||
write(a, b){ | write(a, b){ | ||||
if (this.writable){ | if (this.writable){ | ||||
this.address = a; | this.address = a; | ||||
return this; | return this; | ||||
} | } | ||||
// Same as .read() but will NOT trigger read listeners. | |||||
peek(a){return 0;} | |||||
// Same as .write() but will NOT trigger write listeners. | |||||
poke(a, b){return this;} | |||||
// Starting at <address> will fill memory (regardless of whether | |||||
// it's ROM or RAM) with the values in <data> | |||||
// NOTE: <data> is assumed to only contain byte values. | |||||
load(address, data){ | load(address, data){ | ||||
return this; | return this; | ||||
} | } | ||||
// Clears 256 bytes of memory starting from <page> * 256 | |||||
// NOTE: This affects both RAM and ROM. | |||||
clearPage(page){ | clearPage(page){ | ||||
return this; | return this; | ||||
} | } | ||||
// Clears all memory | |||||
// NOTE: This affects both RAM and ROM. | |||||
clear(){ | clear(){ | ||||
return this; | return this; | ||||
} | } |
} | } | ||||
peek(a){ | |||||
a = Math.min(this.__map.length - 1, Math.max(0, a)); | |||||
return this.__map[a]; | |||||
} | |||||
load(address, data){ | load(address, data){ | ||||
let dc = data; | let dc = data; | ||||
if (address < 0 || address >= this.__map.length) | if (address < 0 || address >= this.__map.length) | ||||
this.__wlisteners.on(addr, fn); | this.__wlisteners.on(addr, fn); | ||||
return this; | return this; | ||||
} | } | ||||
poke(a, b){ | |||||
a = Math.min(this.__map.length - 1, Math.max(0, a)); | |||||
this.__map[a] = b & 0xFF; | |||||
return this; | |||||
} | |||||
} | } | ||||
return this; | return this; | ||||
} | } | ||||
peek(a){ | |||||
a = Math.min(this.__size - 1, Math.max(0, a)) % this.__map.length; | |||||
return this.__map[a]; | |||||
} | |||||
poke(a, b){ | |||||
if (a >= 0 && a < this.__map.length) | |||||
this.__map[a] = b & 0xFF; | |||||
return this; | |||||
} | |||||
load(addr, data){ | load(addr, data){ | ||||
let dc = data; | let dc = data; | ||||
if (addr < 0 || addr >= this.__size) | if (addr < 0 || addr >= this.__size) |
} | } | ||||
} | } | ||||
peek(a){ | |||||
let v = 0; | |||||
if (this.__switches.length > 0){ | |||||
let oa = this.address; | |||||
this.address = a; // Let this do ALL the work for me. | |||||
a = this.__switches[this.__sidx].mem.address; | |||||
v = this.__switches[this.__sidx].mem.peek(a); | |||||
this.address = oa; | |||||
} | |||||
return v; | |||||
} | |||||
poke(a, b){ | |||||
if (this.__switches.length > 0){ | |||||
let oa = this.address; | |||||
this.address = a; | |||||
a = this.__switches[this.__sidx].mem.address; | |||||
this.__switches[this.__sidx].mem.poke(a, b); | |||||
this.address = oa; | |||||
} | |||||
return this; | |||||
} | |||||
load(addr, data){ | load(addr, data){ | ||||
if (addr < 0 || addr > this.size) | if (addr < 0 || addr > this.size) | ||||
throw new RangeError("Memory address out of range."); | throw new RangeError("Memory address out of range."); |
expect(cb.callCount).to.equal(2); | expect(cb.callCount).to.equal(2); | ||||
}); | }); | ||||
it("Peek", function(){ | |||||
var cb = sinon.fake(); | |||||
m2.onAddressRead(0x0101, cb); | |||||
expect(m2.peek(0x0101)).to.equal(0x77); | |||||
expect(cb.callCount).to.equal(0); | |||||
expect(m2.read(0x0101)).to.equal(0x77); | |||||
expect(cb.callCount).to.equal(1); | |||||
m2.peek(0x0101); | |||||
expect(cb.callCount).to.equal(1); | |||||
}); | |||||
it("Clear Page", function(){ | it("Clear Page", function(){ | ||||
m2.clearPage(2); | m2.clearPage(2); | ||||
expect(m2.read(0x0200)).to.equal(0x00); | expect(m2.read(0x0200)).to.equal(0x00); | ||||
expect(cb.callCount).to.equal(2); | expect(cb.callCount).to.equal(2); | ||||
}); | }); | ||||
it("Peek", function(){ | |||||
var cb = sinon.fake(); | |||||
m2.onAddressRead(0x0101, cb); | |||||
expect(m2.peek(0x0101)).to.equal(0x77); | |||||
expect(cb.callCount).to.equal(0); | |||||
expect(m2.read(0x0101)).to.equal(0x77); | |||||
expect(cb.callCount).to.equal(1); | |||||
m2.peek(0x0101); | |||||
expect(cb.callCount).to.equal(1); | |||||
}); | |||||
it("Poke", function(){ | |||||
var cb = sinon.fake(); | |||||
m2.onAddressWrite(0x0130, cb); | |||||
m2.poke(0x0130, 0x42); | |||||
expect(cb.callCount).to.equal(0); | |||||
expect(m2.peek(0x0130)).to.equal(0x42); | |||||
m2.write(0x0130, 0x46); | |||||
expect(cb.callCount).to.equal(1); | |||||
expect(m2.peek(0x0130)).to.equal(0x46); | |||||
m2.poke(0x0130, 0x42); | |||||
expect(cb.callCount).to.equal(1); | |||||
}); | |||||
it("Clear Page", function(){ | it("Clear Page", function(){ | ||||
m2.clearPage(2); | m2.clearPage(2); | ||||
expect(m2.read(0x0200)).to.equal(0x00); | expect(m2.read(0x0200)).to.equal(0x00); | ||||
expect(cb1.lastArg).to.equal(0x22); | expect(cb1.lastArg).to.equal(0x22); | ||||
}); | }); | ||||
it("Peek"); | |||||
it("Poke"); | |||||
it("Clear Page", function(){ | it("Clear Page", function(){ | ||||
sm.clearPage(0); | sm.clearPage(0); | ||||
expect(sm.read(0x00)).to.equal(0x00); | expect(sm.read(0x00)).to.equal(0x00); | ||||
describe("Memory Management Controller (MMC) Class", function(){ | describe("Memory Management Controller (MMC) Class", function(){ | ||||
var mmc = new Mem.MMC(); | var mmc = new Mem.MMC(); | ||||
mmc.connectMemory(new Mem.Memory.RAM(1)); | |||||
var rcb = sinon.fake(); | |||||
var wcb = sinon.fake(); | |||||
let m1 = new Mem.Memory.RAM(1); | |||||
m1.onAddressRead(0x31, rcb); | |||||
m1.onAddressWrite(0x31, wcb); | |||||
mmc.connectMemory(m1); | |||||
mmc.connectMemory(new Mem.Memory.RAM(2)); | mmc.connectMemory(new Mem.Memory.RAM(2)); | ||||
mmc.connectMemory(new Mem.Memory.RAM(1)); | mmc.connectMemory(new Mem.Memory.RAM(1)); | ||||
expect(mmc.address).to.equal(0x03FF); | expect(mmc.address).to.equal(0x03FF); | ||||
}); | }); | ||||
it("Peek"); | |||||
it("Poke"); | |||||
it("Clear Page", function(){ | it("Clear Page", function(){ | ||||
expect(mmc.read(0x0200)).to.equal(0x11); | expect(mmc.read(0x0200)).to.equal(0x11); | ||||
expect(mmc.read(0x0201)).to.equal(0x22); | expect(mmc.read(0x0201)).to.equal(0x22); |