Browse Source

Memory now has a peek() and poke() method; like read() and write() respectively, but will not trigger listeners.

master
Bryan Miller 5 years ago
parent
commit
c1f1f23ec4
4 changed files with 119 additions and 1 deletions
  1. +26
    -0
      src/memory/imem.js
  2. +23
    -0
      src/memory/memory.js
  3. +23
    -0
      src/memory/mmc.js
  4. +47
    -1
      test/unit.src.memory.memory.spec.js

+ 26
- 0
src/memory/imem.js View File

@@ -13,11 +13,25 @@ class IMem{
get byte(){return -1;}
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){
this.address = a;
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){
if (this.writable){
this.address = a;
@@ -26,14 +40,26 @@ class IMem{
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){
return this;
}

// Clears 256 bytes of memory starting from <page> * 256
// NOTE: This affects both RAM and ROM.
clearPage(page){
return this;
}

// Clears all memory
// NOTE: This affects both RAM and ROM.
clear(){
return this;
}

+ 23
- 0
src/memory/memory.js View File

@@ -56,6 +56,12 @@ class ROM extends IMem{
}


peek(a){
a = Math.min(this.__map.length - 1, Math.max(0, a));
return this.__map[a];
}


load(address, data){
let dc = data;
if (address < 0 || address >= this.__map.length)
@@ -115,6 +121,12 @@ class RAM extends ROM {
this.__wlisteners.on(addr, fn);
return this;
}

poke(a, b){
a = Math.min(this.__map.length - 1, Math.max(0, a));
this.__map[a] = b & 0xFF;
return this;
}
}


@@ -169,6 +181,17 @@ class Shadow extends IMem {
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){
let dc = data;
if (addr < 0 || addr >= this.__size)

+ 23
- 0
src/memory/mmc.js View File

@@ -85,6 +85,29 @@ class MMC extends IMem{
}
}

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){
if (addr < 0 || addr > this.size)
throw new RangeError("Memory address out of range.");

+ 47
- 1
test/unit.src.memory.memory.spec.js View File

@@ -79,6 +79,17 @@ describe("Testing Memory Module", function(){
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(){
m2.clearPage(2);
expect(m2.read(0x0200)).to.equal(0x00);
@@ -198,6 +209,30 @@ describe("Testing Memory Module", function(){
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(){
m2.clearPage(2);
expect(m2.read(0x0200)).to.equal(0x00);
@@ -304,6 +339,9 @@ describe("Testing Memory Module", function(){
expect(cb1.lastArg).to.equal(0x22);
});

it("Peek");
it("Poke");

it("Clear Page", function(){
sm.clearPage(0);
expect(sm.read(0x00)).to.equal(0x00);
@@ -324,7 +362,12 @@ describe("Testing Memory Module", function(){

describe("Memory Management Controller (MMC) Class", function(){
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(1));

@@ -425,6 +468,9 @@ describe("Testing Memory Module", function(){
expect(mmc.address).to.equal(0x03FF);
});

it("Peek");
it("Poke");

it("Clear Page", function(){
expect(mmc.read(0x0200)).to.equal(0x11);
expect(mmc.read(0x0201)).to.equal(0x22);

Loading…
Cancel
Save