Fantasy 8Bit system (F8), is a fantasy 8bit console and a set of libraries for creating fantasy 8bit consoles.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

358 lines
11KB

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