|
|
|
|
|
|
|
|
|
|
|
const expect = require('chai').expect; |
|
|
|
|
|
const sinon = require('sinon'); |
|
|
|
|
|
const Mem = require('../src/memory'); |
|
|
|
|
|
|
|
|
|
|
|
describe("Testing Memory Module", function(){ |
|
|
|
|
|
describe("Core Memory Classes...", function(){ |
|
|
|
|
|
describe("ROM Class", function(){ |
|
|
|
|
|
var m1 = new Mem.Memory.ROM(1); |
|
|
|
|
|
var m2 = new Mem.Memory.ROM(4); |
|
|
|
|
|
|
|
|
|
|
|
it("Bytes match 256 byte page sizes", function(){ |
|
|
|
|
|
expect(m1.size).to.equal(256); |
|
|
|
|
|
expect(m2.size).to.equal(1024); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it("Loading Bytes", function(){ |
|
|
|
|
|
m1.load(0x80, [0x10, 0x44, 0xAB, 0x11, 0x9C]); |
|
|
|
|
|
expect(m1.__map[0x80]).to.equal(0x10); |
|
|
|
|
|
expect(m1.__map[0x81]).to.equal(0x44); |
|
|
|
|
|
expect(m1.__map[0x82]).to.equal(0xAB); |
|
|
|
|
|
expect(m1.__map[0x83]).to.equal(0x11); |
|
|
|
|
|
expect(m1.__map[0x84]).to.equal(0x9C); |
|
|
|
|
|
|
|
|
|
|
|
m2.load(0x0100, [0x88, 0x77, 0x66, 0x55]); |
|
|
|
|
|
m2.load(0x0200, [0xAA, 0xBB, 0xCC, 0xDD]); |
|
|
|
|
|
expect(m2.__map[0x0100]).to.equal(0x88); |
|
|
|
|
|
expect(m2.__map[0x0101]).to.equal(0x77); |
|
|
|
|
|
expect(m2.__map[0x0102]).to.equal(0x66); |
|
|
|
|
|
expect(m2.__map[0x0103]).to.equal(0x55); |
|
|
|
|
|
|
|
|
|
|
|
expect(m2.__map[0x0200]).to.equal(0xAA); |
|
|
|
|
|
expect(m2.__map[0x0201]).to.equal(0xBB); |
|
|
|
|
|
expect(m2.__map[0x0202]).to.equal(0xCC); |
|
|
|
|
|
expect(m2.__map[0x0203]).to.equal(0xDD); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it("Read Check", function(){ |
|
|
|
|
|
expect(m1.read(0x81)).to.equal(0x44); |
|
|
|
|
|
expect(m1.address).to.equal(0x81); |
|
|
|
|
|
expect(m1.read(0x84)).to.equal(0x9C); |
|
|
|
|
|
expect(m1.address).to.equal(0x84); |
|
|
|
|
|
|
|
|
|
|
|
expect(m2.read(0x0102)).to.equal(0x66); |
|
|
|
|
|
expect(m2.address).to.equal(0x0102); |
|
|
|
|
|
expect(m2.read(0x0203)).to.equal(0xDD); |
|
|
|
|
|
expect(m2.address).to.equal(0x0203); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it("Address Within Memory Bounds", function(){ |
|
|
|
|
|
m1.address = 0x0100; |
|
|
|
|
|
expect(m1.address).to.equal(0xFF); |
|
|
|
|
|
m2.address = -1; |
|
|
|
|
|
expect(m2.address).to.equal(0x00); |
|
|
|
|
|
m2.address = 0x0400; |
|
|
|
|
|
expect(m2.address).to.equal(0x03FF); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it("Set Address / Get Byte", function(){ |
|
|
|
|
|
m1.address = 0x82; |
|
|
|
|
|
expect(m1.byte).to.equal(0xAB); |
|
|
|
|
|
m1.address = 0x83; |
|
|
|
|
|
expect(m1.byte).to.equal(0x11); |
|
|
|
|
|
|
|
|
|
|
|
m2.address = 0x0101; |
|
|
|
|
|
expect(m2.byte).to.equal(0x77); |
|
|
|
|
|
m2.address = 0x0202; |
|
|
|
|
|
expect(m2.byte).to.equal(0xCC); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it("Address Read Callback", function(){ |
|
|
|
|
|
var cb = sinon.fake(); |
|
|
|
|
|
m2.onAddressRead(0x0100, cb); |
|
|
|
|
|
m2.read(0x0100); |
|
|
|
|
|
m2.read(0x0201); |
|
|
|
|
|
m2.address = 0x0101; |
|
|
|
|
|
m2.byte; |
|
|
|
|
|
m2.address = 0x0100; |
|
|
|
|
|
m2.byte; |
|
|
|
|
|
expect(cb.callCount).to.equal(2); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it("Clear Page", function(){ |
|
|
|
|
|
m2.clearPage(2); |
|
|
|
|
|
expect(m2.read(0x0200)).to.equal(0x00); |
|
|
|
|
|
expect(m2.read(0x0201)).to.equal(0x00); |
|
|
|
|
|
expect(m2.read(0x0202)).to.equal(0x00); |
|
|
|
|
|
expect(m2.read(0x0203)).to.equal(0x00); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it("Clear", function(){ |
|
|
|
|
|
m1.clear(); |
|
|
|
|
|
expect(m1.read(0x80)).to.equal(0x00); |
|
|
|
|
|
expect(m1.read(0x81)).to.equal(0x00); |
|
|
|
|
|
expect(m1.read(0x82)).to.equal(0x00); |
|
|
|
|
|
expect(m1.read(0x83)).to.equal(0x00); |
|
|
|
|
|
}); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
describe("RAM Class", function(){ |
|
|
|
|
|
var m1 = new Mem.Memory.RAM(1); |
|
|
|
|
|
var m2 = new Mem.Memory.RAM(4); |
|
|
|
|
|
|
|
|
|
|
|
it("Bytes match 256 byte page sizes", function(){ |
|
|
|
|
|
expect(m1.size).to.equal(256); |
|
|
|
|
|
expect(m2.size).to.equal(1024); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it("Loading Bytes", function(){ |
|
|
|
|
|
m1.load(0x80, [0x10, 0x44, 0xAB, 0x11, 0x9C]); |
|
|
|
|
|
expect(m1.__map[0x80]).to.equal(0x10); |
|
|
|
|
|
expect(m1.__map[0x81]).to.equal(0x44); |
|
|
|
|
|
expect(m1.__map[0x82]).to.equal(0xAB); |
|
|
|
|
|
expect(m1.__map[0x83]).to.equal(0x11); |
|
|
|
|
|
expect(m1.__map[0x84]).to.equal(0x9C); |
|
|
|
|
|
|
|
|
|
|
|
m2.load(0x0100, [0x88, 0x77, 0x66, 0x55]); |
|
|
|
|
|
m2.load(0x0200, [0xAA, 0xBB, 0xCC, 0xDD]); |
|
|
|
|
|
expect(m2.__map[0x0100]).to.equal(0x88); |
|
|
|
|
|
expect(m2.__map[0x0101]).to.equal(0x77); |
|
|
|
|
|
expect(m2.__map[0x0102]).to.equal(0x66); |
|
|
|
|
|
expect(m2.__map[0x0103]).to.equal(0x55); |
|
|
|
|
|
|
|
|
|
|
|
expect(m2.__map[0x0200]).to.equal(0xAA); |
|
|
|
|
|
expect(m2.__map[0x0201]).to.equal(0xBB); |
|
|
|
|
|
expect(m2.__map[0x0202]).to.equal(0xCC); |
|
|
|
|
|
expect(m2.__map[0x0203]).to.equal(0xDD); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it("Read Check", function(){ |
|
|
|
|
|
expect(m1.read(0x81)).to.equal(0x44); |
|
|
|
|
|
expect(m1.address).to.equal(0x81); |
|
|
|
|
|
expect(m1.read(0x84)).to.equal(0x9C); |
|
|
|
|
|
expect(m1.address).to.equal(0x84); |
|
|
|
|
|
|
|
|
|
|
|
expect(m2.read(0x0102)).to.equal(0x66); |
|
|
|
|
|
expect(m2.address).to.equal(0x0102); |
|
|
|
|
|
expect(m2.read(0x0203)).to.equal(0xDD); |
|
|
|
|
|
expect(m2.address).to.equal(0x0203); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it("Write Check", function(){ |
|
|
|
|
|
expect(m1.read(0x85)).to.equal(0x00); |
|
|
|
|
|
m1.write(0x85, 0x12); |
|
|
|
|
|
expect(m1.read(0x85)).to.equal(0x12); |
|
|
|
|
|
m1.write(0x85, 0xDC); |
|
|
|
|
|
expect(m1.byte).to.equal(0xDC); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it("Set Address / Get Byte", function(){ |
|
|
|
|
|
m1.address = 0x82; |
|
|
|
|
|
expect(m1.byte).to.equal(0xAB); |
|
|
|
|
|
m1.address = 0x83; |
|
|
|
|
|
expect(m1.byte).to.equal(0x11); |
|
|
|
|
|
|
|
|
|
|
|
m2.address = 0x0101; |
|
|
|
|
|
expect(m2.byte).to.equal(0x77); |
|
|
|
|
|
m2.address = 0x0202; |
|
|
|
|
|
expect(m2.byte).to.equal(0xCC); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it("Set Address / Set Byte", function(){ |
|
|
|
|
|
m1.address = 0x86; |
|
|
|
|
|
m1.byte = 0xFE; |
|
|
|
|
|
m1.address = 0x87; |
|
|
|
|
|
m1.byte = 0xEF; |
|
|
|
|
|
expect(m1.read(0x86)).to.equal(0xFE); |
|
|
|
|
|
expect(m1.read(0x87)).to.equal(0xEF); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it("Address Within Memory Bounds", function(){ |
|
|
|
|
|
m1.address = 0x0100; |
|
|
|
|
|
expect(m1.address).to.equal(0xFF); |
|
|
|
|
|
m2.address = -1; |
|
|
|
|
|
expect(m2.address).to.equal(0x00); |
|
|
|
|
|
m2.address = 0x0400; |
|
|
|
|
|
expect(m2.address).to.equal(0x03FF); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it("Address Read Callback", function(){ |
|
|
|
|
|
var cb = sinon.fake(); |
|
|
|
|
|
m2.onAddressRead(0x0100, cb); |
|
|
|
|
|
m2.read(0x0100); |
|
|
|
|
|
m2.read(0x0201); |
|
|
|
|
|
m2.address = 0x0101; |
|
|
|
|
|
m2.byte; |
|
|
|
|
|
m2.address = 0x0100; |
|
|
|
|
|
m2.byte; |
|
|
|
|
|
expect(cb.callCount).to.equal(2); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it("Address Write Callback", function(){ |
|
|
|
|
|
var cb = sinon.fake(); |
|
|
|
|
|
m1.onAddressWrite(0x86, cb); |
|
|
|
|
|
m1.write(0x86, 0x12); |
|
|
|
|
|
expect(cb.lastArg).to.equal(0x12); |
|
|
|
|
|
m1.write(0x86, 0x22); |
|
|
|
|
|
expect(cb.lastArg).to.equal(0x22); |
|
|
|
|
|
expect(cb.callCount).to.equal(2); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it("Clear Page", function(){ |
|
|
|
|
|
m2.clearPage(2); |
|
|
|
|
|
expect(m2.read(0x0200)).to.equal(0x00); |
|
|
|
|
|
expect(m2.read(0x0201)).to.equal(0x00); |
|
|
|
|
|
expect(m2.read(0x0202)).to.equal(0x00); |
|
|
|
|
|
expect(m2.read(0x0203)).to.equal(0x00); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it("Clear", function(){ |
|
|
|
|
|
m1.clear(); |
|
|
|
|
|
expect(m1.read(0x80)).to.equal(0x00); |
|
|
|
|
|
expect(m1.read(0x81)).to.equal(0x00); |
|
|
|
|
|
expect(m1.read(0x82)).to.equal(0x00); |
|
|
|
|
|
expect(m1.read(0x83)).to.equal(0x00); |
|
|
|
|
|
}); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
describe("Shadow Class", function(){ |
|
|
|
|
|
var sm = new Mem.Memory.Shadow(1, 4); |
|
|
|
|
|
|
|
|
|
|
|
it("Bytes Match 256 Size", function(){ |
|
|
|
|
|
expect(sm.size).to.equal(256); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it("Load Bytes", function(){ |
|
|
|
|
|
var stored = sm.load(0, [0x10, 0x20, 0x30, 0x40, 0x50]); |
|
|
|
|
|
expect(stored).to.equal(4); |
|
|
|
|
|
expect(sm.__map[0]).to.equal(0x10); |
|
|
|
|
|
expect(sm.__map[1]).to.equal(0x20); |
|
|
|
|
|
expect(sm.__map[2]).to.equal(0x30); |
|
|
|
|
|
expect(sm.__map[3]).to.equal(0x40); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it("Read Check", function(){ |
|
|
|
|
|
expect(sm.read(0x01)).to.equal(0x20); |
|
|
|
|
|
expect(sm.read(0x05)).to.equal(0x20); |
|
|
|
|
|
expect(sm.read(0x09)).to.equal(0x20); |
|
|
|
|
|
expect(sm.read(0x0D)).to.equal(0x20); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it("Write Check", function(){ |
|
|
|
|
|
sm.write(0x01, 0x11); |
|
|
|
|
|
expect(sm.read(0x01)).to.equal(0x11); |
|
|
|
|
|
expect(sm.read(0x05)).to.equal(0x11); |
|
|
|
|
|
sm.write(0x05, 0x12); |
|
|
|
|
|
expect(sm.read(0x05)).to.equal(0x11); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it("Set Address / Get Byte", function(){ |
|
|
|
|
|
sm.address = 0x02; |
|
|
|
|
|
expect(sm.byte).to.equal(0x30); |
|
|
|
|
|
sm.address = 0x03; |
|
|
|
|
|
expect(sm.byte).to.equal(0x40); |
|
|
|
|
|
sm.address = 0x04; |
|
|
|
|
|
expect(sm.byte).to.equal(0x10); |
|
|
|
|
|
sm.address = 0x05; |
|
|
|
|
|
expect(sm.byte).to.equal(0x11); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it("Set Address / Set Byte", function(){ |
|
|
|
|
|
sm.address = 0x02; |
|
|
|
|
|
sm.byte = 0x31; |
|
|
|
|
|
expect(sm.byte).to.equal(0x31); |
|
|
|
|
|
sm.address = 0x06; |
|
|
|
|
|
expect(sm.byte).to.equal(0x31); |
|
|
|
|
|
sm.byte = 0x32; |
|
|
|
|
|
expect(sm.byte).to.equal(0x31); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it("Address Within Memory Bounds", function(){ |
|
|
|
|
|
sm.address = 0x0100; |
|
|
|
|
|
expect(sm.address).to.equal(0xFF); |
|
|
|
|
|
sm.address = -1; |
|
|
|
|
|
expect(sm.address).to.equal(0x00); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it("Address Read Callback", function(){ |
|
|
|
|
|
var cb1 = sinon.fake(); |
|
|
|
|
|
var cb2 = sinon.fake(); |
|
|
|
|
|
sm.onAddressRead(0x01, cb1); |
|
|
|
|
|
sm.onAddressRead(0x05, cb2); |
|
|
|
|
|
sm.read(0x01); |
|
|
|
|
|
expect(cb1.callCount).to.equal(1); |
|
|
|
|
|
expect(cb2.callCount).to.equal(0); |
|
|
|
|
|
sm.read(0x05); |
|
|
|
|
|
expect(cb1.callCount).to.equal(1); |
|
|
|
|
|
expect(cb2.callCount).to.equal(1); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it("Address Write Callback", function(){ |
|
|
|
|
|
var cb1 = sinon.fake(); |
|
|
|
|
|
var cb2 = sinon.fake(); |
|
|
|
|
|
sm.onAddressWrite(0x01, cb1); |
|
|
|
|
|
sm.write(0x01, 0x21); |
|
|
|
|
|
expect(cb1.callCount).to.equal(1); |
|
|
|
|
|
expect(cb1.lastArg).to.equal(0x21); |
|
|
|
|
|
sm.onAddressWrite(0x05, cb2); |
|
|
|
|
|
sm.write(0x05, 0x22); |
|
|
|
|
|
expect(cb2.callCount).to.equal(0); |
|
|
|
|
|
sm.write(0x01, 0x22); |
|
|
|
|
|
expect(cb2.callCount).to.equal(1); |
|
|
|
|
|
expect(cb2.lastArg).to.equal(0x22); |
|
|
|
|
|
expect(cb1.callCount).to.equal(2); |
|
|
|
|
|
expect(cb1.lastArg).to.equal(0x22); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it("Clear Page", function(){ |
|
|
|
|
|
sm.clearPage(0); |
|
|
|
|
|
expect(sm.read(0x00)).to.equal(0x00); |
|
|
|
|
|
expect(sm.read(0x01)).to.equal(0x00); |
|
|
|
|
|
expect(sm.read(0x05)).to.equal(0x00); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it("Clear", function(){ |
|
|
|
|
|
sm.load(0, [0x10, 0x20, 0x30, 0x40]); |
|
|
|
|
|
sm.clear(); |
|
|
|
|
|
expect(sm.read(0x00)).to.equal(0x00); |
|
|
|
|
|
expect(sm.read(0x01)).to.equal(0x00); |
|
|
|
|
|
expect(sm.read(0x05)).to.equal(0x00); |
|
|
|
|
|
}); |
|
|
|
|
|
}); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
describe("Memory Management Controller (MMC) Class", function(){ |
|
|
|
|
|
var mmc = new Mem.MMC(); |
|
|
|
|
|
mmc.connectMemory(new Mem.Memory.RAM(1)); |
|
|
|
|
|
mmc.connectMemory(new Mem.Memory.RAM(2)); |
|
|
|
|
|
mmc.connectMemory(new Mem.Memory.RAM(1)); |
|
|
|
|
|
|
|
|
|
|
|
it("Bytes match 4 pages."/*, function(){ |
|
|
|
|
|
console.log(mmc); |
|
|
|
|
|
expect(mmc.size).to.equal(1024); |
|
|
|
|
|
}*/); |
|
|
|
|
|
|
|
|
|
|
|
}); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|