Fantasy 8Bit system (F8), is a fantasy 8bit console and a set of libraries for creating fantasy 8bit consoles.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

453 lines
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. });