|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508 |
- 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.ROM(1);
- var m2 = new Mem.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("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);
- 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.RAM(1);
- var m2 = new Mem.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("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);
- 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.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("Peek");
- it("Poke");
-
- 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();
- var rcb = sinon.fake();
- var wcb = sinon.fake();
- let m1 = new Mem.RAM(1);
- m1.onAddressRead(0x31, rcb);
- m1.onAddressWrite(0x31, wcb);
- mmc.connectMemory(m1);
- mmc.connectMemory(new Mem.RAM(2));
- mmc.connectMemory(new Mem.RAM(1));
-
- it("Reports 4 pages", function(){
- expect(mmc.pages).to.equal(4);
- });
-
- it("Bytes match 4 pages", function(){
- expect(mmc.size).to.equal(1024);
- });
-
- it("Load / Read Check", function(){
- mmc.load(0, [0x01, 0x02, 0x03, 0x04]);
- mmc.load(0x0200, [0x11, 0x22, 0x33, 0x44]);
- mmc.load(0x0300, [0xAA, 0xBB, 0xCC, 0xDD]);
- mmc.load(0xFE, [0x41, 0x42, 0x43, 0x44]);
-
- expect(mmc.read(0x01)).to.equal(0x02);
- expect(mmc.read(0x0202)).to.equal(0x33);
- expect(mmc.read(0x0303)).to.equal(0xDD);
- expect(mmc.read(0xFF)).to.equal(0x42);
- expect(mmc.read(0x0101)).to.equal(0x44);
- });
-
- it("Write check", function(){
- mmc.write(0x02, 0x06);
- expect(mmc.read(0x02)).to.equal(0x06);
- mmc.write(0x0115, 0x15);
- expect(mmc.read(0x0115)).to.equal(0x15);
- mmc.write(0x0207, 0x07);
- expect(mmc.read(0x0207)).to.equal(0x07);
- });
-
- it("Adding Switchable Banks", function(){
- let b2 = new Mem.ROM(1);
- expect(function(){
- mmc.connectMemory(b2, 0x0100);
- }).to.throw("Memory modules assigned to the same bank must be the same byte size.");
- expect(function(){
- mmc.connectMemory(b2, 0xEE)
- }).to.throw("Cannot align memory module to bank at address " + (0xEE));
- mmc.connectMemory(b2, 0x00);
- expect(mmc.read(0x00)).to.equal(0x01);
- expect(mmc.read(0x01)).to.equal(0x02);
- mmc.switchBank(0x01);
- expect(mmc.read(0x01)).to.equal(0x00);
- mmc.switchBank(0x00);
- expect(mmc.read(0x01)).to.equal(0x02);
-
- mmc.connectMemory(new Mem.ROM(2), 0x0100);
- expect(mmc.read(0x0115)).to.equal(0x15);
- mmc.switchBank(0x11);
- expect(mmc.read(0x0115)).to.equal(0x00);
- mmc.switchBank(0x10);
- expect(mmc.read(0x0115)).to.equal(0x15);
- });
-
- it("Write Check 2 (switch between RAM and ROM)", function(){
- // Disable memory write passthrough for the initial tests...
- mmc.writePassthrough = false;
- mmc.write(0x0115, 0x16);
- expect(mmc.read(0x0115)).to.equal(0x16);
- mmc.switchBank(0x11);
- expect(mmc.read(0x0115)).to.equal(0x00);
- mmc.write(0x0115, 0x17);
- expect(mmc.read(0x0115)).to.equal(0x00);
- mmc.switchBank(0x10);
- expect(mmc.read(0x0115)).to.equal(0x16);
-
- // Reenable write passthrough!
- mmc.writePassthrough = true;
- mmc.switchBank(0x11);
- mmc.write(0x0115, 0x17);
- expect(mmc.read(0x0115)).to.equal(0x00);
- mmc.switchBank(0x10);
- expect(mmc.read(0x0115)).to.equal(0x17);
- });
-
- it("Set Address / Get Byte", function(){
- mmc.address = 0x0200;
- expect(mmc.byte).to.equal(0x11);
- mmc.address = 0x0301;
- expect(mmc.byte).to.equal(0xBB);
- mmc.address = 0x03;
- expect(mmc.byte).to.equal(0x04);
- });
-
- it("Set Address / Set Byte", function(){
- mmc.address = 0xEE;
- mmc.byte = 0x1A;
- mmc.address = 0xEF;
- mmc.byte = 0x2B;
- mmc.address = 0xF0;
- mmc.byte = 0x3C;
- expect(mmc.read(0xEE)).to.equal(0x1A);
- expect(mmc.read(0xEF)).to.equal(0x2B);
- expect(mmc.read(0xF0)).to.equal(0x3C);
- });
-
- it("Address Within Memory Bounds", function(){
- mmc.address = 0x05;
- expect(mmc.address).to.equal(0x05);
- mmc.address = 0x0201
- expect(mmc.address).to.equal(0x0201);
- mmc.address = -1;
- expect(mmc.address).to.equal(0);
- mmc.address = 0x0400;
- 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);
- mmc.clearPage(2);
- expect(mmc.read(0x0200)).to.equal(0x00);
- expect(mmc.read(0x0201)).to.equal(0x00);
- expect(mmc.read(0xEE)).to.equal(0x1A);
- mmc.clearPage(0);
- expect(mmc.read(0x00)).to.equal(0x00);
- expect(mmc.read(0xEE)).to.equal(0x00);
- expect(mmc.read(0xEF)).to.equal(0x00);
- });
-
- it("Clear", function(){
- mmc.clear();
- for (let i=0; i < 10; i++){
- expect(mmc.read(0xF6 + i)).to.equal(0x00);
- }
- });
- });
- });
-
-
-
-
|