Fantasy 8Bit system (F8), is a fantasy 8bit console and a set of libraries for creating fantasy 8bit consoles.
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

453 linhas
14KB

  1. const expect = require('chai').expect;
  2. const sinon = require('sinon');
  3. const Mem = require('../src/memory');
  4. describe("Testing Memory Module", function(){
  5. describe("Core Memory Classes...", function(){
  6. describe("ROM Class", function(){
  7. var m1 = new Mem.Memory.ROM(1);
  8. var m2 = new Mem.Memory.ROM(4);
  9. it("Bytes match 256 byte page sizes", function(){
  10. expect(m1.size).to.equal(256);
  11. expect(m2.size).to.equal(1024);
  12. });
  13. it("Loading Bytes", function(){
  14. m1.load(0x80, [0x10, 0x44, 0xAB, 0x11, 0x9C]);
  15. expect(m1.__map[0x80]).to.equal(0x10);
  16. expect(m1.__map[0x81]).to.equal(0x44);
  17. expect(m1.__map[0x82]).to.equal(0xAB);
  18. expect(m1.__map[0x83]).to.equal(0x11);
  19. expect(m1.__map[0x84]).to.equal(0x9C);
  20. m2.load(0x0100, [0x88, 0x77, 0x66, 0x55]);
  21. m2.load(0x0200, [0xAA, 0xBB, 0xCC, 0xDD]);
  22. expect(m2.__map[0x0100]).to.equal(0x88);
  23. expect(m2.__map[0x0101]).to.equal(0x77);
  24. expect(m2.__map[0x0102]).to.equal(0x66);
  25. expect(m2.__map[0x0103]).to.equal(0x55);
  26. expect(m2.__map[0x0200]).to.equal(0xAA);
  27. expect(m2.__map[0x0201]).to.equal(0xBB);
  28. expect(m2.__map[0x0202]).to.equal(0xCC);
  29. expect(m2.__map[0x0203]).to.equal(0xDD);
  30. });
  31. it("Read Check", function(){
  32. expect(m1.read(0x81)).to.equal(0x44);
  33. expect(m1.address).to.equal(0x81);
  34. expect(m1.read(0x84)).to.equal(0x9C);
  35. expect(m1.address).to.equal(0x84);
  36. expect(m2.read(0x0102)).to.equal(0x66);
  37. expect(m2.address).to.equal(0x0102);
  38. expect(m2.read(0x0203)).to.equal(0xDD);
  39. expect(m2.address).to.equal(0x0203);
  40. });
  41. it("Address Within Memory Bounds", function(){
  42. m1.address = 0x0100;
  43. expect(m1.address).to.equal(0xFF);
  44. m2.address = -1;
  45. expect(m2.address).to.equal(0x00);
  46. m2.address = 0x0400;
  47. expect(m2.address).to.equal(0x03FF);
  48. });
  49. it("Set Address / Get Byte", function(){
  50. m1.address = 0x82;
  51. expect(m1.byte).to.equal(0xAB);
  52. m1.address = 0x83;
  53. expect(m1.byte).to.equal(0x11);
  54. m2.address = 0x0101;
  55. expect(m2.byte).to.equal(0x77);
  56. m2.address = 0x0202;
  57. expect(m2.byte).to.equal(0xCC);
  58. });
  59. it("Address Read Callback", function(){
  60. var cb = sinon.fake();
  61. m2.onAddressRead(0x0100, cb);
  62. m2.read(0x0100);
  63. m2.read(0x0201);
  64. m2.address = 0x0101;
  65. m2.byte;
  66. m2.address = 0x0100;
  67. m2.byte;
  68. expect(cb.callCount).to.equal(2);
  69. });
  70. it("Clear Page", function(){
  71. m2.clearPage(2);
  72. expect(m2.read(0x0200)).to.equal(0x00);
  73. expect(m2.read(0x0201)).to.equal(0x00);
  74. expect(m2.read(0x0202)).to.equal(0x00);
  75. expect(m2.read(0x0203)).to.equal(0x00);
  76. });
  77. it("Clear", function(){
  78. m1.clear();
  79. expect(m1.read(0x80)).to.equal(0x00);
  80. expect(m1.read(0x81)).to.equal(0x00);
  81. expect(m1.read(0x82)).to.equal(0x00);
  82. expect(m1.read(0x83)).to.equal(0x00);
  83. });
  84. });
  85. describe("RAM Class", function(){
  86. var m1 = new Mem.Memory.RAM(1);
  87. var m2 = new Mem.Memory.RAM(4);
  88. it("Bytes match 256 byte page sizes", function(){
  89. expect(m1.size).to.equal(256);
  90. expect(m2.size).to.equal(1024);
  91. });
  92. it("Loading Bytes", function(){
  93. m1.load(0x80, [0x10, 0x44, 0xAB, 0x11, 0x9C]);
  94. expect(m1.__map[0x80]).to.equal(0x10);
  95. expect(m1.__map[0x81]).to.equal(0x44);
  96. expect(m1.__map[0x82]).to.equal(0xAB);
  97. expect(m1.__map[0x83]).to.equal(0x11);
  98. expect(m1.__map[0x84]).to.equal(0x9C);
  99. m2.load(0x0100, [0x88, 0x77, 0x66, 0x55]);
  100. m2.load(0x0200, [0xAA, 0xBB, 0xCC, 0xDD]);
  101. expect(m2.__map[0x0100]).to.equal(0x88);
  102. expect(m2.__map[0x0101]).to.equal(0x77);
  103. expect(m2.__map[0x0102]).to.equal(0x66);
  104. expect(m2.__map[0x0103]).to.equal(0x55);
  105. expect(m2.__map[0x0200]).to.equal(0xAA);
  106. expect(m2.__map[0x0201]).to.equal(0xBB);
  107. expect(m2.__map[0x0202]).to.equal(0xCC);
  108. expect(m2.__map[0x0203]).to.equal(0xDD);
  109. });
  110. it("Read Check", function(){
  111. expect(m1.read(0x81)).to.equal(0x44);
  112. expect(m1.address).to.equal(0x81);
  113. expect(m1.read(0x84)).to.equal(0x9C);
  114. expect(m1.address).to.equal(0x84);
  115. expect(m2.read(0x0102)).to.equal(0x66);
  116. expect(m2.address).to.equal(0x0102);
  117. expect(m2.read(0x0203)).to.equal(0xDD);
  118. expect(m2.address).to.equal(0x0203);
  119. });
  120. it("Write Check", function(){
  121. expect(m1.read(0x85)).to.equal(0x00);
  122. m1.write(0x85, 0x12);
  123. expect(m1.read(0x85)).to.equal(0x12);
  124. m1.write(0x85, 0xDC);
  125. expect(m1.byte).to.equal(0xDC);
  126. });
  127. it("Set Address / Get Byte", function(){
  128. m1.address = 0x82;
  129. expect(m1.byte).to.equal(0xAB);
  130. m1.address = 0x83;
  131. expect(m1.byte).to.equal(0x11);
  132. m2.address = 0x0101;
  133. expect(m2.byte).to.equal(0x77);
  134. m2.address = 0x0202;
  135. expect(m2.byte).to.equal(0xCC);
  136. });
  137. it("Set Address / Set Byte", function(){
  138. m1.address = 0x86;
  139. m1.byte = 0xFE;
  140. m1.address = 0x87;
  141. m1.byte = 0xEF;
  142. expect(m1.read(0x86)).to.equal(0xFE);
  143. expect(m1.read(0x87)).to.equal(0xEF);
  144. });
  145. it("Address Within Memory Bounds", function(){
  146. m1.address = 0x0100;
  147. expect(m1.address).to.equal(0xFF);
  148. m2.address = -1;
  149. expect(m2.address).to.equal(0x00);
  150. m2.address = 0x0400;
  151. expect(m2.address).to.equal(0x03FF);
  152. });
  153. it("Address Read Callback", function(){
  154. var cb = sinon.fake();
  155. m2.onAddressRead(0x0100, cb);
  156. m2.read(0x0100);
  157. m2.read(0x0201);
  158. m2.address = 0x0101;
  159. m2.byte;
  160. m2.address = 0x0100;
  161. m2.byte;
  162. expect(cb.callCount).to.equal(2);
  163. });
  164. it("Address Write Callback", function(){
  165. var cb = sinon.fake();
  166. m1.onAddressWrite(0x86, cb);
  167. m1.write(0x86, 0x12);
  168. expect(cb.lastArg).to.equal(0x12);
  169. m1.write(0x86, 0x22);
  170. expect(cb.lastArg).to.equal(0x22);
  171. expect(cb.callCount).to.equal(2);
  172. });
  173. it("Clear Page", function(){
  174. m2.clearPage(2);
  175. expect(m2.read(0x0200)).to.equal(0x00);
  176. expect(m2.read(0x0201)).to.equal(0x00);
  177. expect(m2.read(0x0202)).to.equal(0x00);
  178. expect(m2.read(0x0203)).to.equal(0x00);
  179. });
  180. it("Clear", function(){
  181. m1.clear();
  182. expect(m1.read(0x80)).to.equal(0x00);
  183. expect(m1.read(0x81)).to.equal(0x00);
  184. expect(m1.read(0x82)).to.equal(0x00);
  185. expect(m1.read(0x83)).to.equal(0x00);
  186. });
  187. });
  188. describe("Shadow Class", function(){
  189. var sm = new Mem.Memory.Shadow(1, 4);
  190. it("Bytes Match 256 Size", function(){
  191. expect(sm.size).to.equal(256);
  192. });
  193. it("Load Bytes", function(){
  194. var stored = sm.load(0, [0x10, 0x20, 0x30, 0x40, 0x50]);
  195. expect(stored).to.equal(4);
  196. expect(sm.__map[0]).to.equal(0x10);
  197. expect(sm.__map[1]).to.equal(0x20);
  198. expect(sm.__map[2]).to.equal(0x30);
  199. expect(sm.__map[3]).to.equal(0x40);
  200. });
  201. it("Read Check", function(){
  202. expect(sm.read(0x01)).to.equal(0x20);
  203. expect(sm.read(0x05)).to.equal(0x20);
  204. expect(sm.read(0x09)).to.equal(0x20);
  205. expect(sm.read(0x0D)).to.equal(0x20);
  206. });
  207. it("Write Check", function(){
  208. sm.write(0x01, 0x11);
  209. expect(sm.read(0x01)).to.equal(0x11);
  210. expect(sm.read(0x05)).to.equal(0x11);
  211. sm.write(0x05, 0x12);
  212. expect(sm.read(0x05)).to.equal(0x11);
  213. });
  214. it("Set Address / Get Byte", function(){
  215. sm.address = 0x02;
  216. expect(sm.byte).to.equal(0x30);
  217. sm.address = 0x03;
  218. expect(sm.byte).to.equal(0x40);
  219. sm.address = 0x04;
  220. expect(sm.byte).to.equal(0x10);
  221. sm.address = 0x05;
  222. expect(sm.byte).to.equal(0x11);
  223. });
  224. it("Set Address / Set Byte", function(){
  225. sm.address = 0x02;
  226. sm.byte = 0x31;
  227. expect(sm.byte).to.equal(0x31);
  228. sm.address = 0x06;
  229. expect(sm.byte).to.equal(0x31);
  230. sm.byte = 0x32;
  231. expect(sm.byte).to.equal(0x31);
  232. });
  233. it("Address Within Memory Bounds", function(){
  234. sm.address = 0x0100;
  235. expect(sm.address).to.equal(0xFF);
  236. sm.address = -1;
  237. expect(sm.address).to.equal(0x00);
  238. });
  239. it("Address Read Callback", function(){
  240. var cb1 = sinon.fake();
  241. var cb2 = sinon.fake();
  242. sm.onAddressRead(0x01, cb1);
  243. sm.onAddressRead(0x05, cb2);
  244. sm.read(0x01);
  245. expect(cb1.callCount).to.equal(1);
  246. expect(cb2.callCount).to.equal(0);
  247. sm.read(0x05);
  248. expect(cb1.callCount).to.equal(1);
  249. expect(cb2.callCount).to.equal(1);
  250. });
  251. it("Address Write Callback", function(){
  252. var cb1 = sinon.fake();
  253. var cb2 = sinon.fake();
  254. sm.onAddressWrite(0x01, cb1);
  255. sm.write(0x01, 0x21);
  256. expect(cb1.callCount).to.equal(1);
  257. expect(cb1.lastArg).to.equal(0x21);
  258. sm.onAddressWrite(0x05, cb2);
  259. sm.write(0x05, 0x22);
  260. expect(cb2.callCount).to.equal(0);
  261. sm.write(0x01, 0x22);
  262. expect(cb2.callCount).to.equal(1);
  263. expect(cb2.lastArg).to.equal(0x22);
  264. expect(cb1.callCount).to.equal(2);
  265. expect(cb1.lastArg).to.equal(0x22);
  266. });
  267. it("Clear Page", function(){
  268. sm.clearPage(0);
  269. expect(sm.read(0x00)).to.equal(0x00);
  270. expect(sm.read(0x01)).to.equal(0x00);
  271. expect(sm.read(0x05)).to.equal(0x00);
  272. });
  273. it("Clear", function(){
  274. sm.load(0, [0x10, 0x20, 0x30, 0x40]);
  275. sm.clear();
  276. expect(sm.read(0x00)).to.equal(0x00);
  277. expect(sm.read(0x01)).to.equal(0x00);
  278. expect(sm.read(0x05)).to.equal(0x00);
  279. });
  280. });
  281. });
  282. describe("Memory Management Controller (MMC) Class", function(){
  283. var mmc = new Mem.MMC();
  284. mmc.connectMemory(new Mem.Memory.RAM(1));
  285. mmc.connectMemory(new Mem.Memory.RAM(2));
  286. mmc.connectMemory(new Mem.Memory.RAM(1));
  287. it("Reports 4 pages", function(){
  288. expect(mmc.pages).to.equal(4);
  289. });
  290. it("Bytes match 4 pages", function(){
  291. expect(mmc.size).to.equal(1024);
  292. });
  293. it("Load / Read Check", function(){
  294. mmc.load(0, [0x01, 0x02, 0x03, 0x04]);
  295. mmc.load(0x0200, [0x11, 0x22, 0x33, 0x44]);
  296. mmc.load(0x0300, [0xAA, 0xBB, 0xCC, 0xDD]);
  297. mmc.load(0xFE, [0x41, 0x42, 0x43, 0x44]);
  298. expect(mmc.read(0x01)).to.equal(0x02);
  299. expect(mmc.read(0x0202)).to.equal(0x33);
  300. expect(mmc.read(0x0303)).to.equal(0xDD);
  301. expect(mmc.read(0xFF)).to.equal(0x42);
  302. expect(mmc.read(0x0101)).to.equal(0x44);
  303. });
  304. it("Write check", function(){
  305. mmc.write(0x02, 0x06);
  306. expect(mmc.read(0x02)).to.equal(0x06);
  307. mmc.write(0x0115, 0x15);
  308. expect(mmc.read(0x0115)).to.equal(0x15);
  309. mmc.write(0x0207, 0x07);
  310. expect(mmc.read(0x0207)).to.equal(0x07);
  311. });
  312. it("Adding Switchable Banks", function(){
  313. let b2 = new Mem.Memory.ROM(1);
  314. expect(function(){
  315. mmc.connectMemory(b2, 0x0100);
  316. }).to.throw("Memory modules assigned to the same bank must be the same byte size.");
  317. expect(function(){
  318. mmc.connectMemory(b2, 0xEE)
  319. }).to.throw("Cannot align memory module to bank at address " + (0xEE));
  320. mmc.connectMemory(b2, 0x00);
  321. expect(mmc.read(0x00)).to.equal(0x01);
  322. expect(mmc.read(0x01)).to.equal(0x02);
  323. mmc.switchBank(0x01);
  324. expect(mmc.read(0x01)).to.equal(0x00);
  325. mmc.switchBank(0x00);
  326. expect(mmc.read(0x01)).to.equal(0x02);
  327. mmc.connectMemory(new Mem.Memory.ROM(2), 0x0100);
  328. expect(mmc.read(0x0115)).to.equal(0x15);
  329. mmc.switchBank(0x11);
  330. expect(mmc.read(0x0115)).to.equal(0x00);
  331. mmc.switchBank(0x10);
  332. expect(mmc.read(0x0115)).to.equal(0x15);
  333. });
  334. it("Write Check 2 (switch between RAM and ROM)", function(){
  335. mmc.write(0x0115, 0x16);
  336. expect(mmc.read(0x0115)).to.equal(0x16);
  337. mmc.switchBank(0x11);
  338. expect(mmc.read(0x0115)).to.equal(0x00);
  339. mmc.write(0x0115, 0x17);
  340. expect(mmc.read(0x0115)).to.equal(0x00);
  341. mmc.switchBank(0x10);
  342. expect(mmc.read(0x0115)).to.equal(0x16);
  343. });
  344. it("Set Address / Get Byte", function(){
  345. mmc.address = 0x0200;
  346. expect(mmc.byte).to.equal(0x11);
  347. mmc.address = 0x0301;
  348. expect(mmc.byte).to.equal(0xBB);
  349. mmc.address = 0x03;
  350. expect(mmc.byte).to.equal(0x04);
  351. });
  352. it("Set Address / Set Byte", function(){
  353. mmc.address = 0xEE;
  354. mmc.byte = 0x1A;
  355. mmc.address = 0xEF;
  356. mmc.byte = 0x2B;
  357. mmc.address = 0xF0;
  358. mmc.byte = 0x3C;
  359. expect(mmc.read(0xEE)).to.equal(0x1A);
  360. expect(mmc.read(0xEF)).to.equal(0x2B);
  361. expect(mmc.read(0xF0)).to.equal(0x3C);
  362. });
  363. it("Address Within Memory Bounds", function(){
  364. mmc.address = 0x05;
  365. expect(mmc.address).to.equal(0x05);
  366. mmc.address = 0x0201
  367. expect(mmc.address).to.equal(0x0201);
  368. mmc.address = -1;
  369. expect(mmc.address).to.equal(0);
  370. mmc.address = 0x0400;
  371. expect(mmc.address).to.equal(0x03FF);
  372. });
  373. it("Clear Page", function(){
  374. expect(mmc.read(0x0200)).to.equal(0x11);
  375. expect(mmc.read(0x0201)).to.equal(0x22);
  376. mmc.clearPage(2);
  377. expect(mmc.read(0x0200)).to.equal(0x00);
  378. expect(mmc.read(0x0201)).to.equal(0x00);
  379. expect(mmc.read(0xEE)).to.equal(0x1A);
  380. mmc.clearPage(0);
  381. expect(mmc.read(0x00)).to.equal(0x00);
  382. expect(mmc.read(0xEE)).to.equal(0x00);
  383. expect(mmc.read(0xEF)).to.equal(0x00);
  384. });
  385. it("Clear", function(){
  386. mmc.clear();
  387. for (let i=0; i < 10; i++){
  388. expect(mmc.read(0xF6 + i)).to.equal(0x00);
  389. }
  390. });
  391. });
  392. });