jsbeeb 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (498) hide show
  1. package/.editorconfig +15 -0
  2. package/.git-blame-ignore-revs +3 -0
  3. package/.github/copilot-instructions.md +94 -0
  4. package/.github/workflows/claude-issue-triage.yml +105 -0
  5. package/.github/workflows/claude.yml +63 -0
  6. package/.github/workflows/release-please.yml +75 -0
  7. package/.github/workflows/test-and-deploy.yml +86 -0
  8. package/.gitmodules +6 -0
  9. package/.husky/pre-commit +1 -0
  10. package/.idea/codeStyleSettings.xml +9 -0
  11. package/.idea/codeStyles/Project.xml +62 -0
  12. package/.idea/codeStyles/codeStyleConfig.xml +5 -0
  13. package/.idea/compiler.xml +22 -0
  14. package/.idea/copyright/profiles_settings.xml +3 -0
  15. package/.idea/encodings.xml +6 -0
  16. package/.idea/inspectionProfiles/Project_Default.xml +7 -0
  17. package/.idea/jsLibraryMappings.xml +6 -0
  18. package/.idea/jsLinters/jshint.xml +85 -0
  19. package/.idea/jsLinters/jslint.xml +15 -0
  20. package/.idea/jsbeeb.iml +11 -0
  21. package/.idea/misc.xml +6 -0
  22. package/.idea/modules.xml +8 -0
  23. package/.idea/prettier.xml +7 -0
  24. package/.idea/runConfigurations/Debug.xml +5 -0
  25. package/.idea/scopes/scope_settings.xml +5 -0
  26. package/.idea/vcs.xml +8 -0
  27. package/.prettierignore +4 -0
  28. package/.prettierrc.json +1 -0
  29. package/.release-please-manifest.json +3 -0
  30. package/.vscode/launch.json +14 -0
  31. package/.vscode/settings.json +6 -0
  32. package/CHANGELOG.md +32 -0
  33. package/CLAUDE.md +136 -0
  34. package/COPYING +674 -0
  35. package/Dockerfile +22 -0
  36. package/Makefile +30 -0
  37. package/README.md +259 -0
  38. package/docker/nginx-default.conf +10 -0
  39. package/docs/pal-comb-filter-research.md +129 -0
  40. package/docs/pal-simulation-design.md +368 -0
  41. package/eslint.config.js +35 -0
  42. package/index.html +954 -0
  43. package/jsconfig.json +10 -0
  44. package/package.json +102 -0
  45. package/public/discs/README.Irq-Timing +3 -0
  46. package/public/discs/README.bcdtest +5 -0
  47. package/public/discs/README.elite +6 -0
  48. package/public/discs/README.eng_test +3 -0
  49. package/public/discs/README.protection +7 -0
  50. package/public/favicon.ico +0 -0
  51. package/public/images/botbar.png +0 -0
  52. package/public/images/cub-monitor.png +0 -0
  53. package/public/images/jsbeeb-example.png +0 -0
  54. package/public/images/placeholder.png +0 -0
  55. package/public/images/red-off-16.png +0 -0
  56. package/public/images/red-on-16.png +0 -0
  57. package/public/images/sb/CD-left.jpg +0 -0
  58. package/public/images/sb/CD-right.jpg +0 -0
  59. package/public/images/sidebar.png +0 -0
  60. package/public/images/tv.png +0 -0
  61. package/public/images/yellow-off-16.png +0 -0
  62. package/public/images/yellow-on-16.png +0 -0
  63. package/public/jsbeeb-icon.png +0 -0
  64. package/public/robots.txt +3 -0
  65. package/public/roms/ADFS1-53.rom +0 -0
  66. package/public/roms/BASIC.ROM +0 -0
  67. package/public/roms/README +4 -0
  68. package/public/roms/a01/BASIC1.rom +0 -0
  69. package/public/roms/ample.rom +0 -0
  70. package/public/roms/ats-3.0.rom +0 -0
  71. package/public/roms/b/DFS-0.9.rom +0 -0
  72. package/public/roms/b/DFS-1.2.rom +0 -0
  73. package/public/roms/b1770/dfs1770.rom +0 -0
  74. package/public/roms/b1770/zADFS.ROM +0 -0
  75. package/public/roms/bp/dfs.rom +0 -0
  76. package/public/roms/bp/zADFS.ROM +0 -0
  77. package/public/roms/bpos.rom +0 -0
  78. package/public/roms/compact/adfs210.rom +0 -0
  79. package/public/roms/compact/basic48.rom +0 -0
  80. package/public/roms/compact/basic486.rom +0 -0
  81. package/public/roms/compact/os51.rom +0 -0
  82. package/public/roms/compact/utils.rom +0 -0
  83. package/public/roms/deos.rom +0 -0
  84. package/public/roms/master/anfs-4.25.rom +0 -0
  85. package/public/roms/master/mos.txt +68819 -0
  86. package/public/roms/master/mos3.20 +0 -0
  87. package/public/roms/os.rom +0 -0
  88. package/public/roms/os01.rom +0 -0
  89. package/public/roms/tube/6502Tube.rom +0 -0
  90. package/public/roms/tube/ARMeval_100.rom +0 -0
  91. package/public/roms/tube/BIOS.ROM +0 -0
  92. package/public/roms/tube/ReCo6502ROM_816 +0 -0
  93. package/public/roms/tube/Z80_120.rom +0 -0
  94. package/public/roms/us/USBASIC.rom +0 -0
  95. package/public/roms/us/USDNFS.rom +0 -0
  96. package/public/roms/usmos.rom +0 -0
  97. package/public/sounds/disc525/motor.wav +0 -0
  98. package/public/sounds/disc525/motoroff.wav +0 -0
  99. package/public/sounds/disc525/motoron.wav +0 -0
  100. package/public/sounds/disc525/seek.wav +0 -0
  101. package/public/sounds/disc525/seek2.wav +0 -0
  102. package/public/sounds/disc525/seek3.wav +0 -0
  103. package/public/sounds/disc525/step.wav +0 -0
  104. package/public/teletext/txt0.dat +0 -0
  105. package/public/teletext/txt1.dat +0 -0
  106. package/public/teletext/txt2.dat +0 -0
  107. package/public/teletext/txt3.dat +0 -0
  108. package/release-please-config.json +13 -0
  109. package/run-container.sh +92 -0
  110. package/src/6502.js +1347 -0
  111. package/src/6502.opcodes.js +1411 -0
  112. package/src/acia.js +261 -0
  113. package/src/adc.js +149 -0
  114. package/src/analogue-source.js +21 -0
  115. package/src/app/app.js +175 -0
  116. package/src/app/electron.js +20 -0
  117. package/src/app/preload.js +8 -0
  118. package/src/app-bench.js +33 -0
  119. package/src/basic/multiline-tetris +9 -0
  120. package/src/basic-tokenise.js +104 -0
  121. package/src/canvas.js +177 -0
  122. package/src/cmos.js +141 -0
  123. package/src/config.js +165 -0
  124. package/src/ddnoise.js +138 -0
  125. package/src/disc-drive.js +371 -0
  126. package/src/disc-hfe.js +396 -0
  127. package/src/disc.js +997 -0
  128. package/src/econet/L3FS.dat +0 -0
  129. package/src/econet/scsi.dat +0 -0
  130. package/src/econet.js +714 -0
  131. package/src/fake6502.js +32 -0
  132. package/src/fdc.js +248 -0
  133. package/src/filestore.js +666 -0
  134. package/src/gamepad-source.js +59 -0
  135. package/src/gamepads.js +268 -0
  136. package/src/google-drive.js +160 -0
  137. package/src/intel-fdc.js +1717 -0
  138. package/src/jsbeeb.css +363 -0
  139. package/src/keyboard.js +411 -0
  140. package/src/lib/README +1 -0
  141. package/src/lib/webgl-debug.js +911 -0
  142. package/src/main.js +1759 -0
  143. package/src/microphone-input.js +149 -0
  144. package/src/models.js +200 -0
  145. package/src/mouse-joystick-source.js +107 -0
  146. package/src/music5000-worklet.js +43 -0
  147. package/src/music5000.js +207 -0
  148. package/src/scheduler.js +148 -0
  149. package/src/serial.js +31 -0
  150. package/src/soundchip.js +314 -0
  151. package/src/sth.js +59 -0
  152. package/src/tapes.js +265 -0
  153. package/src/teletext.js +348 -0
  154. package/src/teletext_adaptor.js +172 -0
  155. package/src/teletext_data.js +1064 -0
  156. package/src/touchscreen.js +86 -0
  157. package/src/tube.js +349 -0
  158. package/src/url-params.js +256 -0
  159. package/src/utils.js +1090 -0
  160. package/src/via.js +702 -0
  161. package/src/video-filters/pal-composite.js +94 -0
  162. package/src/video-filters/passthrough-filter.js +70 -0
  163. package/src/video-filters/shaders/pal-composite.frag.glsl +147 -0
  164. package/src/video-filters/shaders/pal-composite.vert.glsl +8 -0
  165. package/src/video-filters/shaders/passthrough.frag.glsl +6 -0
  166. package/src/video-filters/shaders/passthrough.vert.glsl +7 -0
  167. package/src/video.js +794 -0
  168. package/src/wd-fdc.js +1344 -0
  169. package/src/web/audio-handler.js +146 -0
  170. package/src/web/audio-renderer.js +115 -0
  171. package/src/web/debug.js +529 -0
  172. package/tests/integration/RmwX.asm +47 -0
  173. package/tests/integration/TestInstructionsSource +27 -0
  174. package/tests/integration/TestTimingsResults +27 -0
  175. package/tests/integration/TestTimingsSource +61 -0
  176. package/tests/integration/bcd.js +23 -0
  177. package/tests/integration/dormann.js +101 -0
  178. package/tests/integration/dp111timing.js +42 -0
  179. package/tests/integration/ensure-submodules.js +25 -0
  180. package/tests/integration/nops.bas +119 -0
  181. package/tests/integration/nops.js +24 -0
  182. package/tests/integration/protection.js +26 -0
  183. package/tests/integration/rmw.js +69 -0
  184. package/tests/integration/teletext/expected_bug_469.png +0 -0
  185. package/tests/integration/teletext/expected_flash_0.png +0 -0
  186. package/tests/integration/teletext/expected_flash_1.png +0 -0
  187. package/tests/integration/teletext/expected_hoglet_held_char.png +0 -0
  188. package/tests/integration/teletext/expected_reveal_flash_0.png +0 -0
  189. package/tests/integration/teletext/expected_reveal_flash_1.png +0 -0
  190. package/tests/integration/teletext.js +126 -0
  191. package/tests/integration/timings.js +56 -0
  192. package/tests/integration/via.js +1125 -0
  193. package/tests/suite/README.md +7 -0
  194. package/tests/suite/Test Suite 2.15.txt +373 -0
  195. package/tests/suite/bin/ start +0 -0
  196. package/tests/suite/bin/adca +0 -0
  197. package/tests/suite/bin/adcax +0 -0
  198. package/tests/suite/bin/adcay +0 -0
  199. package/tests/suite/bin/adcb +0 -0
  200. package/tests/suite/bin/adcix +0 -0
  201. package/tests/suite/bin/adciy +0 -0
  202. package/tests/suite/bin/adcz +0 -0
  203. package/tests/suite/bin/adczx +0 -0
  204. package/tests/suite/bin/alrb +0 -0
  205. package/tests/suite/bin/ancb +0 -0
  206. package/tests/suite/bin/anda +0 -0
  207. package/tests/suite/bin/andax +0 -0
  208. package/tests/suite/bin/anday +0 -0
  209. package/tests/suite/bin/andb +0 -0
  210. package/tests/suite/bin/andix +0 -0
  211. package/tests/suite/bin/andiy +0 -0
  212. package/tests/suite/bin/andz +0 -0
  213. package/tests/suite/bin/andzx +0 -0
  214. package/tests/suite/bin/aneb +0 -0
  215. package/tests/suite/bin/arrb +0 -0
  216. package/tests/suite/bin/asla +0 -0
  217. package/tests/suite/bin/aslax +0 -0
  218. package/tests/suite/bin/asln +0 -0
  219. package/tests/suite/bin/aslz +0 -0
  220. package/tests/suite/bin/aslzx +0 -0
  221. package/tests/suite/bin/asoa +0 -0
  222. package/tests/suite/bin/asoax +0 -0
  223. package/tests/suite/bin/asoay +0 -0
  224. package/tests/suite/bin/asoix +0 -0
  225. package/tests/suite/bin/asoiy +0 -0
  226. package/tests/suite/bin/asoz +0 -0
  227. package/tests/suite/bin/asozx +0 -0
  228. package/tests/suite/bin/axsa +0 -0
  229. package/tests/suite/bin/axsix +0 -0
  230. package/tests/suite/bin/axsz +0 -0
  231. package/tests/suite/bin/axszy +0 -0
  232. package/tests/suite/bin/bccr +0 -0
  233. package/tests/suite/bin/bcsr +0 -0
  234. package/tests/suite/bin/beqr +0 -0
  235. package/tests/suite/bin/bita +0 -0
  236. package/tests/suite/bin/bitz +0 -0
  237. package/tests/suite/bin/bmir +0 -0
  238. package/tests/suite/bin/bner +0 -0
  239. package/tests/suite/bin/bplr +0 -0
  240. package/tests/suite/bin/branchwrap +0 -0
  241. package/tests/suite/bin/brkn +0 -0
  242. package/tests/suite/bin/bvcr +0 -0
  243. package/tests/suite/bin/bvsr +0 -0
  244. package/tests/suite/bin/cia1pb6 +0 -0
  245. package/tests/suite/bin/cia1pb7 +0 -0
  246. package/tests/suite/bin/cia1ta +0 -0
  247. package/tests/suite/bin/cia1tab +0 -0
  248. package/tests/suite/bin/cia1tb +0 -0
  249. package/tests/suite/bin/cia1tb123 +0 -0
  250. package/tests/suite/bin/cia2pb6 +0 -0
  251. package/tests/suite/bin/cia2pb7 +0 -0
  252. package/tests/suite/bin/cia2ta +0 -0
  253. package/tests/suite/bin/cia2tb +0 -0
  254. package/tests/suite/bin/cia2tb123 +0 -0
  255. package/tests/suite/bin/clcn +0 -0
  256. package/tests/suite/bin/cldn +0 -0
  257. package/tests/suite/bin/clin +0 -0
  258. package/tests/suite/bin/clvn +0 -0
  259. package/tests/suite/bin/cmpa +0 -0
  260. package/tests/suite/bin/cmpax +0 -0
  261. package/tests/suite/bin/cmpay +0 -0
  262. package/tests/suite/bin/cmpb +0 -0
  263. package/tests/suite/bin/cmpix +0 -0
  264. package/tests/suite/bin/cmpiy +0 -0
  265. package/tests/suite/bin/cmpz +0 -0
  266. package/tests/suite/bin/cmpzx +0 -0
  267. package/tests/suite/bin/cntdef +0 -0
  268. package/tests/suite/bin/cnto2 +0 -0
  269. package/tests/suite/bin/cpuport +0 -0
  270. package/tests/suite/bin/cputiming +0 -0
  271. package/tests/suite/bin/cpxa +0 -0
  272. package/tests/suite/bin/cpxb +0 -0
  273. package/tests/suite/bin/cpxz +0 -0
  274. package/tests/suite/bin/cpya +0 -0
  275. package/tests/suite/bin/cpyb +0 -0
  276. package/tests/suite/bin/cpyz +0 -0
  277. package/tests/suite/bin/dcma +0 -0
  278. package/tests/suite/bin/dcmax +0 -0
  279. package/tests/suite/bin/dcmay +0 -0
  280. package/tests/suite/bin/dcmix +0 -0
  281. package/tests/suite/bin/dcmiy +0 -0
  282. package/tests/suite/bin/dcmz +0 -0
  283. package/tests/suite/bin/dcmzx +0 -0
  284. package/tests/suite/bin/deca +0 -0
  285. package/tests/suite/bin/decax +0 -0
  286. package/tests/suite/bin/decz +0 -0
  287. package/tests/suite/bin/deczx +0 -0
  288. package/tests/suite/bin/dexn +0 -0
  289. package/tests/suite/bin/deyn +0 -0
  290. package/tests/suite/bin/eora +0 -0
  291. package/tests/suite/bin/eorax +0 -0
  292. package/tests/suite/bin/eoray +0 -0
  293. package/tests/suite/bin/eorb +0 -0
  294. package/tests/suite/bin/eorix +0 -0
  295. package/tests/suite/bin/eoriy +0 -0
  296. package/tests/suite/bin/eorz +0 -0
  297. package/tests/suite/bin/eorzx +0 -0
  298. package/tests/suite/bin/finish +0 -0
  299. package/tests/suite/bin/flipos +0 -0
  300. package/tests/suite/bin/icr01 +0 -0
  301. package/tests/suite/bin/imr +0 -0
  302. package/tests/suite/bin/inca +0 -0
  303. package/tests/suite/bin/incax +0 -0
  304. package/tests/suite/bin/incz +0 -0
  305. package/tests/suite/bin/inczx +0 -0
  306. package/tests/suite/bin/insa +0 -0
  307. package/tests/suite/bin/insax +0 -0
  308. package/tests/suite/bin/insay +0 -0
  309. package/tests/suite/bin/insix +0 -0
  310. package/tests/suite/bin/insiy +0 -0
  311. package/tests/suite/bin/insz +0 -0
  312. package/tests/suite/bin/inszx +0 -0
  313. package/tests/suite/bin/inxn +0 -0
  314. package/tests/suite/bin/inyn +0 -0
  315. package/tests/suite/bin/irq +0 -0
  316. package/tests/suite/bin/jmpi +0 -0
  317. package/tests/suite/bin/jmpw +0 -0
  318. package/tests/suite/bin/jsrw +0 -0
  319. package/tests/suite/bin/lasay +0 -0
  320. package/tests/suite/bin/laxa +0 -0
  321. package/tests/suite/bin/laxay +0 -0
  322. package/tests/suite/bin/laxix +0 -0
  323. package/tests/suite/bin/laxiy +0 -0
  324. package/tests/suite/bin/laxz +0 -0
  325. package/tests/suite/bin/laxzy +0 -0
  326. package/tests/suite/bin/ldaa +0 -0
  327. package/tests/suite/bin/ldaax +0 -0
  328. package/tests/suite/bin/ldaay +0 -0
  329. package/tests/suite/bin/ldab +0 -0
  330. package/tests/suite/bin/ldaix +0 -0
  331. package/tests/suite/bin/ldaiy +0 -0
  332. package/tests/suite/bin/ldaz +0 -0
  333. package/tests/suite/bin/ldazx +0 -0
  334. package/tests/suite/bin/ldxa +0 -0
  335. package/tests/suite/bin/ldxay +0 -0
  336. package/tests/suite/bin/ldxb +0 -0
  337. package/tests/suite/bin/ldxz +0 -0
  338. package/tests/suite/bin/ldxzy +0 -0
  339. package/tests/suite/bin/ldya +0 -0
  340. package/tests/suite/bin/ldyax +0 -0
  341. package/tests/suite/bin/ldyb +0 -0
  342. package/tests/suite/bin/ldyz +0 -0
  343. package/tests/suite/bin/ldyzx +0 -0
  344. package/tests/suite/bin/loadth +0 -0
  345. package/tests/suite/bin/lsea +0 -0
  346. package/tests/suite/bin/lseax +0 -0
  347. package/tests/suite/bin/lseay +0 -0
  348. package/tests/suite/bin/lseix +0 -0
  349. package/tests/suite/bin/lseiy +0 -0
  350. package/tests/suite/bin/lsez +0 -0
  351. package/tests/suite/bin/lsezx +0 -0
  352. package/tests/suite/bin/lsra +0 -0
  353. package/tests/suite/bin/lsrax +0 -0
  354. package/tests/suite/bin/lsrn +0 -0
  355. package/tests/suite/bin/lsrz +0 -0
  356. package/tests/suite/bin/lsrzx +0 -0
  357. package/tests/suite/bin/lxab +0 -0
  358. package/tests/suite/bin/mmu +0 -0
  359. package/tests/suite/bin/mmufetch +0 -0
  360. package/tests/suite/bin/nmi +0 -0
  361. package/tests/suite/bin/nopa +0 -0
  362. package/tests/suite/bin/nopax +0 -0
  363. package/tests/suite/bin/nopb +0 -0
  364. package/tests/suite/bin/nopn +0 -0
  365. package/tests/suite/bin/nopz +0 -0
  366. package/tests/suite/bin/nopzx +0 -0
  367. package/tests/suite/bin/oneshot +0 -0
  368. package/tests/suite/bin/oraa +0 -0
  369. package/tests/suite/bin/oraax +0 -0
  370. package/tests/suite/bin/oraay +0 -0
  371. package/tests/suite/bin/orab +0 -0
  372. package/tests/suite/bin/oraix +0 -0
  373. package/tests/suite/bin/oraiy +0 -0
  374. package/tests/suite/bin/oraz +0 -0
  375. package/tests/suite/bin/orazx +0 -0
  376. package/tests/suite/bin/phan +0 -0
  377. package/tests/suite/bin/phpn +0 -0
  378. package/tests/suite/bin/plan +0 -0
  379. package/tests/suite/bin/plpn +0 -0
  380. package/tests/suite/bin/rlaa +0 -0
  381. package/tests/suite/bin/rlaax +0 -0
  382. package/tests/suite/bin/rlaay +0 -0
  383. package/tests/suite/bin/rlaix +0 -0
  384. package/tests/suite/bin/rlaiy +0 -0
  385. package/tests/suite/bin/rlaz +0 -0
  386. package/tests/suite/bin/rlazx +0 -0
  387. package/tests/suite/bin/rola +0 -0
  388. package/tests/suite/bin/rolax +0 -0
  389. package/tests/suite/bin/roln +0 -0
  390. package/tests/suite/bin/rolz +0 -0
  391. package/tests/suite/bin/rolzx +0 -0
  392. package/tests/suite/bin/rora +0 -0
  393. package/tests/suite/bin/rorax +0 -0
  394. package/tests/suite/bin/rorn +0 -0
  395. package/tests/suite/bin/rorz +0 -0
  396. package/tests/suite/bin/rorzx +0 -0
  397. package/tests/suite/bin/rraa +0 -0
  398. package/tests/suite/bin/rraax +0 -0
  399. package/tests/suite/bin/rraay +0 -0
  400. package/tests/suite/bin/rraix +0 -0
  401. package/tests/suite/bin/rraiy +0 -0
  402. package/tests/suite/bin/rraz +0 -0
  403. package/tests/suite/bin/rrazx +0 -0
  404. package/tests/suite/bin/rtin +0 -0
  405. package/tests/suite/bin/rtsn +0 -0
  406. package/tests/suite/bin/sbca +0 -0
  407. package/tests/suite/bin/sbcax +0 -0
  408. package/tests/suite/bin/sbcay +0 -0
  409. package/tests/suite/bin/sbcb +0 -0
  410. package/tests/suite/bin/sbcb(eb) +0 -0
  411. package/tests/suite/bin/sbcix +0 -0
  412. package/tests/suite/bin/sbciy +0 -0
  413. package/tests/suite/bin/sbcz +0 -0
  414. package/tests/suite/bin/sbczx +0 -0
  415. package/tests/suite/bin/sbxb +0 -0
  416. package/tests/suite/bin/secn +0 -0
  417. package/tests/suite/bin/sedn +0 -0
  418. package/tests/suite/bin/sein +0 -0
  419. package/tests/suite/bin/shaay +0 -0
  420. package/tests/suite/bin/shaiy +0 -0
  421. package/tests/suite/bin/shsay +0 -0
  422. package/tests/suite/bin/shxay +0 -0
  423. package/tests/suite/bin/shyax +0 -0
  424. package/tests/suite/bin/staa +0 -0
  425. package/tests/suite/bin/staax +0 -0
  426. package/tests/suite/bin/staay +0 -0
  427. package/tests/suite/bin/staix +0 -0
  428. package/tests/suite/bin/staiy +0 -0
  429. package/tests/suite/bin/staz +0 -0
  430. package/tests/suite/bin/stazx +0 -0
  431. package/tests/suite/bin/stxa +0 -0
  432. package/tests/suite/bin/stxz +0 -0
  433. package/tests/suite/bin/stxzy +0 -0
  434. package/tests/suite/bin/stya +0 -0
  435. package/tests/suite/bin/styz +0 -0
  436. package/tests/suite/bin/styzx +0 -0
  437. package/tests/suite/bin/taxn +0 -0
  438. package/tests/suite/bin/tayn +0 -0
  439. package/tests/suite/bin/trap1 +0 -0
  440. package/tests/suite/bin/trap10 +0 -0
  441. package/tests/suite/bin/trap11 +0 -0
  442. package/tests/suite/bin/trap12 +0 -0
  443. package/tests/suite/bin/trap13 +0 -0
  444. package/tests/suite/bin/trap14 +0 -0
  445. package/tests/suite/bin/trap15 +0 -0
  446. package/tests/suite/bin/trap16 +0 -0
  447. package/tests/suite/bin/trap17 +0 -0
  448. package/tests/suite/bin/trap2 +0 -0
  449. package/tests/suite/bin/trap3 +0 -0
  450. package/tests/suite/bin/trap4 +0 -0
  451. package/tests/suite/bin/trap5 +0 -0
  452. package/tests/suite/bin/trap6 +0 -0
  453. package/tests/suite/bin/trap7 +0 -0
  454. package/tests/suite/bin/trap8 +0 -0
  455. package/tests/suite/bin/trap9 +0 -0
  456. package/tests/suite/bin/tsxn +0 -0
  457. package/tests/suite/bin/txan +0 -0
  458. package/tests/suite/bin/txsn +0 -0
  459. package/tests/suite/bin/tyan +0 -0
  460. package/tests/suite/cbm-hackers-post.html +178 -0
  461. package/tests/suite/cbm-hackers-post.md +78 -0
  462. package/tests/test-machine.js +288 -0
  463. package/tests/test-suite.js +147 -0
  464. package/tests/test.css +7 -0
  465. package/tests/unit/gzip/test-1 +0 -0
  466. package/tests/unit/gzip/test-1.gz +0 -0
  467. package/tests/unit/gzip/test-2 +0 -0
  468. package/tests/unit/gzip/test-2.gz +0 -0
  469. package/tests/unit/gzip/test-3 +0 -0
  470. package/tests/unit/gzip/test-3.gz +0 -0
  471. package/tests/unit/gzip/test-4 +0 -0
  472. package/tests/unit/gzip/test-4.gz +0 -0
  473. package/tests/unit/test-adc.js +307 -0
  474. package/tests/unit/test-bcd.js +30 -0
  475. package/tests/unit/test-cmos.js +266 -0
  476. package/tests/unit/test-disc-drive.js +85 -0
  477. package/tests/unit/test-disc-hfe.js +347 -0
  478. package/tests/unit/test-disc.js +232 -0
  479. package/tests/unit/test-fifo.js +35 -0
  480. package/tests/unit/test-gamepad-source.js +67 -0
  481. package/tests/unit/test-gzip.js +22 -0
  482. package/tests/unit/test-intel-fdc.js +93 -0
  483. package/tests/unit/test-keyboard.js +410 -0
  484. package/tests/unit/test-mouse-joystick-source.js +128 -0
  485. package/tests/unit/test-scheduler.js +190 -0
  486. package/tests/unit/test-serial.js +154 -0
  487. package/tests/unit/test-teletext-adaptor.js +359 -0
  488. package/tests/unit/test-tokenise.js +65 -0
  489. package/tests/unit/test-url-params.js +398 -0
  490. package/tests/unit/test-utils.js +276 -0
  491. package/tests/unit/test-video.js +498 -0
  492. package/tests/unit/test-zip.js +56 -0
  493. package/tests/unit/zip/test-mixed.zip +0 -0
  494. package/tests/unit/zip/test-rom.zip +0 -0
  495. package/tests/unit/zip/test-ssd.zip +0 -0
  496. package/tools/fir-generator.js +80 -0
  497. package/tools/vite-plugin-fir-shader.js +131 -0
  498. package/vite.config.js +34 -0
@@ -0,0 +1,1125 @@
1
+ import { describe, it } from "vitest";
2
+ import { TestMachine } from "../test-machine.js";
3
+ import assert from "assert";
4
+
5
+ async function runViaProgram(source) {
6
+ const testMachine = new TestMachine();
7
+ await testMachine.initialise();
8
+ await testMachine.runUntilInput();
9
+ await testMachine.loadBasic(source);
10
+
11
+ testMachine.captureText((elem) => console.log(`emulator output: ${elem.text}`));
12
+ await testMachine.type("RUN");
13
+ await testMachine.runUntilInput();
14
+ return testMachine;
15
+ }
16
+
17
+ const resultAddress = 0x100;
18
+
19
+ function expectArray(testMachine, array) {
20
+ let addr = resultAddress;
21
+ for (const expected of array) {
22
+ assert.equal(testMachine.readbyte(addr), expected, `mismatch at 0x${addr.toString(16)}`);
23
+ addr++;
24
+ }
25
+ }
26
+
27
+ describe("should pass scarybeasts' VIA tests", function () {
28
+ // Code here extracted and paraphrased from the SSD zipfile from https://github.com/mattgodbolt/jsbeeb/issues/179
29
+ it("VIA.AC1 - Does ACR write restart timer?", async function () {
30
+ const testMachine = await runViaProgram(`
31
+ DIM MC% 100
32
+ R% = ${resultAddress}
33
+ P% = MC%
34
+ [
35
+ OPT 2
36
+ SEI
37
+ LDA #&FF
38
+ STA &FE62
39
+ LDA #&00
40
+ STA &FE60
41
+ LDA #&7F
42
+ STA &FE6E
43
+ LDA #&80
44
+ STA &FE6B
45
+ LDA #&04
46
+ STA &FE64
47
+ LDA #&00
48
+ STA &FE65
49
+ NOP
50
+ NOP
51
+ NOP
52
+ LDA &FE6D
53
+ STA R%
54
+ NOP
55
+ NOP
56
+ LDA #&C0
57
+ STA &FE6B
58
+ LDA &FE64
59
+ STA R%+1
60
+ LDA &FE6D
61
+ STA R%+2
62
+ LDA &FE60
63
+ STA R%+3
64
+ CLI
65
+ RTS
66
+ ]
67
+ CALL MC%
68
+ PRINT "VIA TEST: DOES ACR WRITE RESTART TIMER?"
69
+ PRINT "REAL BBC: 64, 0, 0, 128"
70
+ PRINT ?(R%)
71
+ PRINT ?(R%+1)
72
+ PRINT ?(R%+2)
73
+ PRINT ?(R%+3)`);
74
+ expectArray(testMachine, [64, 0, 0, 128]);
75
+ });
76
+ it("VIA.AC2 - Does ACR write at timer expiry affect behaviour #1?", async function () {
77
+ const testMachine = await runViaProgram(`
78
+ DIM MC% 100
79
+ R% = ${resultAddress}
80
+ P% = MC%
81
+ [
82
+ OPT 2
83
+ SEI
84
+ LDA #&7F
85
+ STA &FE6E
86
+ LDA #&00
87
+ STA &FE6B
88
+ LDA #&02
89
+ STA &FE64
90
+ LDA #&00
91
+ STA &FE65
92
+ LDA #&40
93
+ STA &FE6B
94
+ LDA &FE64
95
+ STA R%
96
+ LDA &FE6D
97
+ STA R%+1
98
+ CLI
99
+ RTS
100
+ ]
101
+ CALL MC%
102
+ PRINT "VIA TEST: DOES ACR WRITE AT TIMER EXPIRY AFFECT BEHAVIOR #1?"
103
+ PRINT "REAL BBC: 0, 0"
104
+ PRINT ?(R%)
105
+ PRINT ?(R%+1)`);
106
+ expectArray(testMachine, [0, 0]);
107
+ });
108
+ it("VIA.AC3 - Does ACR write at timer expiry affect behaviour #2?", async function () {
109
+ const testMachine = await runViaProgram(`
110
+ DIM MC% 100
111
+ R% = ${resultAddress}
112
+ P% = MC%
113
+ [
114
+ OPT 2
115
+ SEI
116
+ LDA #&7F
117
+ STA &FE6E
118
+ LDA #&40
119
+ STA &FE6B
120
+ LDA #&02
121
+ STA &FE64
122
+ LDA #&00
123
+ STA &FE65
124
+ LDA #&00
125
+ STA &FE6B
126
+ LDA &FE64
127
+ STA R%
128
+ LDA &FE6D
129
+ STA R%+1
130
+ CLI
131
+ RTS
132
+ ]
133
+ CALL MC%
134
+ PRINT "VIA TEST: DOES ACR WRITE AT TIMER EXPIRY AFFECT BEHAVIOR #2?"
135
+ PRINT "REAL BBC: 0, 0"
136
+ PRINT ?(R%)
137
+ PRINT ?(R%+1)`);
138
+ expectArray(testMachine, [0, 0]);
139
+ });
140
+ it("VIA.AC4 - flip ACR mode to one-shot after expiry, does it IRQ?", async function () {
141
+ const testMachine = await runViaProgram(`
142
+ DIM MC% 256
143
+ R% = ${resultAddress}
144
+ P% = MC%
145
+ [
146
+ OPT 2
147
+ SEI
148
+ LDA #&7F
149
+ STA &FE6E
150
+ LDA #&40
151
+ STA &FE6B
152
+ LDA #10
153
+ STA &FE64
154
+ LDA #&00
155
+ STA &FE65
156
+ LDA &FE6D
157
+ STA R%
158
+ LDA &FE64
159
+ STA R%+1
160
+ NOP
161
+ NOP
162
+ LDA &FE6D
163
+ STA R%+2
164
+ LDA &FE64
165
+ STA R%+3
166
+ NOP
167
+ NOP
168
+ LDA &FE6D
169
+ STA R%+4
170
+ LDA &FE64
171
+ STA R%+5
172
+ NOP
173
+ NOP
174
+ LDA #&00
175
+ STA &FE6B
176
+ NOP
177
+ NOP
178
+ NOP
179
+ NOP
180
+ NOP
181
+ NOP
182
+ NOP
183
+ NOP
184
+ LDA &FE6D
185
+ STA R%+6
186
+ LDA &FE64
187
+ STA R%+7
188
+ NOP
189
+ NOP
190
+ LDA &FE6D
191
+ STA R%+8
192
+ LDA &FE64
193
+ STA R%+9
194
+ CLI
195
+ RTS
196
+ ]
197
+ CALL MC%
198
+ REM REAL BBC! 0, 3, 64, 3, 64, 3, 64, 3, 0, 3
199
+ PRINT "VIA TEST: FLIP ACR MODE TO ONE-SHOT AFTER EXPIRY, DOES IT IRQ?"
200
+ PRINT "REAL BBC: 0, 3, 64, 3, 64, 3, 64, 3, 0, 3"
201
+ PRINT ?(R%)
202
+ PRINT ?(R%+1)
203
+ PRINT ?(R%+2)
204
+ PRINT ?(R%+3)
205
+ PRINT ?(R%+4)
206
+ PRINT ?(R%+5)
207
+ PRINT ?(R%+6)
208
+ PRINT ?(R%+7)
209
+ PRINT ?(R%+8)
210
+ PRINT ?(R%+9)`);
211
+ expectArray(testMachine, [0, 3, 64, 3, 64, 3, 64, 3, 0, 3]);
212
+ });
213
+ it("VIA.AC5 - flip ACR mode to continuous after expiry, does it IRQ?", async function () {
214
+ const testMachine = await runViaProgram(`
215
+ DIM MC% 256
216
+ R% = ${resultAddress}
217
+ P% = MC%
218
+ [
219
+ OPT 2
220
+ SEI
221
+ LDA #&7F
222
+ STA &FE6E
223
+ LDA #&00
224
+ STA &FE6B
225
+ LDA #10
226
+ STA &FE64
227
+ LDA #&00
228
+ STA &FE65
229
+ LDA &FE6D
230
+ STA R%
231
+ LDA &FE64
232
+ STA R%+1
233
+ NOP
234
+ NOP
235
+ LDA &FE6D
236
+ STA R%+2
237
+ LDA &FE64
238
+ STA R%+3
239
+ NOP
240
+ NOP
241
+ LDA &FE6D
242
+ STA R%+4
243
+ LDA &FE64
244
+ STA R%+5
245
+ NOP
246
+ NOP
247
+ LDA #&40
248
+ STA &FE6B
249
+ NOP
250
+ NOP
251
+ NOP
252
+ NOP
253
+ NOP
254
+ NOP
255
+ NOP
256
+ NOP
257
+ LDA &FE6D
258
+ STA R%+6
259
+ LDA &FE64
260
+ STA R%+7
261
+ NOP
262
+ NOP
263
+ LDA &FE6D
264
+ STA R%+8
265
+ LDA &FE64
266
+ STA R%+9
267
+ CLI
268
+ RTS
269
+ ]
270
+ CALL MC%
271
+ REM REAL BBC! 0, 3, 64, 3, 0, 3, 0, 3, 0, 3
272
+ PRINT "VIA TEST: FLIP ACR MODE TO CONT AFTER EXPIRY, DOES IT IRQ?"
273
+ PRINT "REAL BBC: 0, 3, 64, 3, 0, 3, 0, 3, 0, 3"
274
+ PRINT ?(R%)
275
+ PRINT ?(R%+1)
276
+ PRINT ?(R%+2)
277
+ PRINT ?(R%+3)
278
+ PRINT ?(R%+4)
279
+ PRINT ?(R%+5)
280
+ PRINT ?(R%+6)
281
+ PRINT ?(R%+7)
282
+ PRINT ?(R%+8)
283
+ PRINT ?(R%+9)`);
284
+ expectArray(testMachine, [0, 3, 64, 3, 0, 3, 0, 3, 0, 3]);
285
+ });
286
+ it("VIA.AC6 - getting to the bottom of ACR write at IRQ time #1", async function () {
287
+ const testMachine = await runViaProgram(`
288
+ DIM MC% 256
289
+ R% = ${resultAddress}
290
+ P% = MC%
291
+ [
292
+ OPT 0
293
+ SEI
294
+ LDA #&7F
295
+ STA &FE6E
296
+ LDA #6
297
+ STA &FE64
298
+
299
+ LDA #&40
300
+ STA &FE6B
301
+ LDA #&00
302
+ STA &FE65
303
+
304
+ LDA #&00
305
+ STA &FE6B
306
+ NOP : NOP : NOP : NOP
307
+ LDA &FE6D
308
+ LDY &FE64
309
+ NOP : NOP
310
+ LDX &FE6D
311
+ LDY &FE64
312
+ STA R%
313
+ STX R%+1
314
+ STY R%+2
315
+
316
+ LDA #&40
317
+ STA &FE6B
318
+ LDA #&00
319
+ STA &FE65
320
+
321
+ LDA #&00
322
+ NOP : NOP : NOP : NOP
323
+ STA &FE6B
324
+ LDA &FE6D
325
+ LDY &FE64
326
+ NOP : NOP
327
+ LDX &FE6D
328
+ LDY &FE64
329
+ STA R%+3
330
+ STX R%+4
331
+ STY R%+5
332
+
333
+ LDA #&40
334
+ STA &FE6B
335
+ LDA #&00
336
+ STA &FE65
337
+
338
+ LDA #&00
339
+ NOP : NOP : NOP
340
+ STA &FE6B
341
+ NOP
342
+ LDA &FE6D
343
+ LDY &FE64
344
+ NOP : NOP
345
+ LDX &FE6D
346
+ LDY &FE64
347
+ STA R%+6
348
+ STX R%+7
349
+ STY R%+8
350
+
351
+ LDA #&40
352
+ STA &FE6B
353
+ LDA #&00
354
+ STA &FE65
355
+
356
+ LDA #&00
357
+ LDX &00
358
+ NOP : NOP : NOP
359
+ STA &FE6B
360
+ LDA &FE6D
361
+ LDY &FE64
362
+ NOP : NOP
363
+ LDX &FE6D
364
+ LDY &FE64
365
+ STA R%+9
366
+ STX R%+10
367
+ STY R%+11
368
+
369
+ LDA #&40
370
+ STA &FE6B
371
+ LDA #&00
372
+ STA &FE65
373
+
374
+ LDA #&C0
375
+ NOP : NOP : NOP : NOP
376
+ STA &FE6B
377
+ LDA &FE6D
378
+ LDY &FE64
379
+ NOP : NOP
380
+ LDX &FE6D
381
+ LDY &FE64
382
+ STA R%+12
383
+ STX R%+13
384
+ STY R%+14
385
+ CLI
386
+ RTS
387
+ ]
388
+ CALL MC%
389
+ PRINT "VIA TEST: GETTING TO THE BOTTOM OF ACR WRITE AT IRQ TIME #1"
390
+ PRINT "REAL BBC: 64, 0, 1, 64, 0, 1, 64, 0, 1, 64, 0, 1, 64, 64, 1"
391
+ PRINT "40 -> 00 IMMEDIATE"
392
+ REM REAL BBC! 64, 0, 1
393
+ PRINT ?(R%)
394
+ PRINT ?(R%+1)
395
+ PRINT ?(R%+2)
396
+ PRINT "40 -> 00 AT -1"
397
+ REM REAL BBC! 64, 0, 1
398
+ PRINT ?(R%+3)
399
+ PRINT ?(R%+4)
400
+ PRINT ?(R%+5)
401
+ PRINT "40 -> 00 AT 0"
402
+ REM REAL BBC! 64, 0, 1
403
+ PRINT ?(R%+6)
404
+ PRINT ?(R%+7)
405
+ PRINT ?(R%+8)
406
+ PRINT "40 -> 00 AT -1, 2 CYCLE STORE"
407
+ REM REAL BBC! 64, 0, 1
408
+ PRINT ?(R%+9)
409
+ PRINT ?(R%+10)
410
+ PRINT ?(R%+11)
411
+ PRINT "40 -> C0 AT -1"
412
+ REM REAL BBC! 64, 64, 1
413
+ PRINT ?(R%+12)
414
+ PRINT ?(R%+13)
415
+ PRINT ?(R%+14)`);
416
+ expectArray(testMachine, [64, 0, 1, 64, 0, 1, 64, 0, 1, 64, 0, 1, 64, 64, 1]);
417
+ });
418
+ it("VIA.AC7 - getting to the bottom of ACR write at IRQ time #2", async function () {
419
+ const testMachine = await runViaProgram(`
420
+ DIM MC% 256
421
+ R% = ${resultAddress}
422
+ P% = MC%
423
+ [
424
+ OPT 0
425
+ SEI
426
+ LDA #&7F
427
+ STA &FE6E
428
+ LDA #6
429
+ STA &FE64
430
+
431
+ LDA #&00
432
+ STA &FE6B
433
+ LDA #&00
434
+ STA &FE65
435
+
436
+ LDA #&40
437
+ STA &FE6B
438
+ NOP : NOP : NOP : NOP
439
+ LDA &FE6D
440
+ LDY &FE64
441
+ NOP : NOP
442
+ LDX &FE6D
443
+ LDY &FE64
444
+ STA R%
445
+ STX R%+1
446
+ STY R%+2
447
+
448
+ LDA #&00
449
+ STA &FE6B
450
+ LDA #&00
451
+ STA &FE65
452
+
453
+ LDA #&40
454
+ NOP : NOP : NOP : NOP
455
+ STA &FE6B
456
+ LDA &FE6D
457
+ LDY &FE64
458
+ NOP : NOP
459
+ LDX &FE6D
460
+ LDY &FE64
461
+ STA R%+3
462
+ STX R%+4
463
+ STY R%+5
464
+
465
+ LDA #&00
466
+ STA &FE6B
467
+ LDA #&00
468
+ STA &FE65
469
+
470
+ LDA #&40
471
+ NOP : NOP : NOP
472
+ STA &FE6B
473
+ NOP
474
+ LDA &FE6D
475
+ LDY &FE64
476
+ NOP : NOP
477
+ LDX &FE6D
478
+ LDY &FE64
479
+ STA R%+6
480
+ STX R%+7
481
+ STY R%+8
482
+
483
+ LDA #&00
484
+ STA &FE6B
485
+ LDA #&00
486
+ STA &FE65
487
+
488
+ LDA #&40
489
+ LDX &00
490
+ NOP : NOP : NOP
491
+ STA &FE6B
492
+ LDA &FE6D
493
+ LDY &FE64
494
+ NOP : NOP
495
+ LDX &FE6D
496
+ LDY &FE64
497
+ STA R%+9
498
+ STX R%+10
499
+ STY R%+11
500
+
501
+ LDA #&00
502
+ STA &FE6B
503
+ LDA #&00
504
+ STA &FE65
505
+
506
+ LDA #&C0
507
+ NOP : NOP : NOP : NOP
508
+ STA &FE6B
509
+ LDA &FE6D
510
+ LDY &FE64
511
+ NOP : NOP
512
+ LDX &FE6D
513
+ LDY &FE64
514
+ STA R%+12
515
+ STX R%+13
516
+ STY R%+14
517
+ CLI
518
+ RTS
519
+ ]
520
+ CALL MC%
521
+ PRINT "VIA TEST: GETTING TO THE BOTTOM OF ACR WRITE AT IRQ TIME #2"
522
+ PRINT "REAL BBC: 64, 64, 1, 64, 0, 1, 64, 64, 1, 64, 0, 1, 64, 0, 1"
523
+ PRINT "00 -> 40 IMMEDIATE"
524
+ REM REAL BBC! 64, 64, 1
525
+ PRINT ?(R%)
526
+ PRINT ?(R%+1)
527
+ PRINT ?(R%+2)
528
+ PRINT "00 -> 40 AT -1"
529
+ REM REAL BBC! 64, 0, 1
530
+ PRINT ?(R%+3)
531
+ PRINT ?(R%+4)
532
+ PRINT ?(R%+5)
533
+ PRINT "00 -> 40 AT 0"
534
+ REM REAL BBC! 64, 64, 1
535
+ PRINT ?(R%+6)
536
+ PRINT ?(R%+7)
537
+ PRINT ?(R%+8)
538
+ PRINT "00 -> 40 AT -1, 2 CYCLE STORE"
539
+ REM REAL BBC! 64, 0, 1
540
+ PRINT ?(R%+9)
541
+ PRINT ?(R%+10)
542
+ PRINT ?(R%+11)
543
+ PRINT "00 -> C0 AT -1"
544
+ REM REAL BBC! 64, 0, 1
545
+ PRINT ?(R%+12)
546
+ PRINT ?(R%+13)
547
+ PRINT ?(R%+14)`);
548
+ expectArray(testMachine, [64, 64, 1, 64, 0, 1, 64, 64, 1, 64, 0, 1, 64, 0, 1]);
549
+ });
550
+ it("VIA.C1", async function () {
551
+ const testMachine = await runViaProgram(`
552
+ DIM MC% 256
553
+ R% = ${resultAddress}
554
+ P% = MC%
555
+ [
556
+ OPT 2
557
+ SEI
558
+ LDX #0
559
+ LDY #0
560
+ LDA #20
561
+ STA &FE64
562
+ LDA #0
563
+ STA &FE65
564
+ LDA &FE64
565
+ STA &FE6A
566
+ CLI
567
+ RTS
568
+ ]
569
+ CALL MC%
570
+ PRINT ?&FE6A
571
+ ?R% = ?&FE6A`);
572
+ expectArray(testMachine, [18]); // checked on a BBC Master
573
+ });
574
+ it("VIA.C2", async function () {
575
+ const testMachine = await runViaProgram(`
576
+ DIM MC% 256
577
+ R% = ${resultAddress}
578
+ P% = MC%
579
+ [
580
+ OPT 2
581
+ SEI
582
+ LDA #&64
583
+ STA &50
584
+ LDA #&FE
585
+ STA &51
586
+ LDX #0
587
+ LDY #0
588
+ LDA #20
589
+ STA &FE64
590
+ LDA #0
591
+ STA &FE65
592
+ LDA (&50),Y
593
+ STA &FE6A
594
+ CLI
595
+ RTS
596
+ ]
597
+ CALL MC%
598
+ PRINT ?&FE6A
599
+ ?R% = ?&FE6A`);
600
+ expectArray(testMachine, [18]); // checked on a BBC Master
601
+ });
602
+ it("VIA.C3", async function () {
603
+ const testMachine = await runViaProgram(`
604
+ DIM MC% 256
605
+ R% = ${resultAddress}
606
+ P% = MC%
607
+ [
608
+ OPT 2
609
+ SEI
610
+ LDA #&64
611
+ STA &50
612
+ LDA #&FE
613
+ STA &51
614
+ LDX #0
615
+ LDY #0
616
+ LDA #20
617
+ STA &FE64
618
+ LDA #0
619
+ STA &FE65
620
+ LDA (&50,X)
621
+ STA &FE6A
622
+ CLI
623
+ RTS
624
+ ]
625
+ CALL MC%
626
+ PRINT ?&FE6A
627
+ ?R% = ?&FE6A`);
628
+ expectArray(testMachine, [17]); // checked on a BBC Master
629
+ });
630
+ // TODO: check on a real BBC and update the `[13]` if that's not right
631
+ it.skip("VIA.C4", async function () {
632
+ const testMachine = await runViaProgram(`
633
+ DIM MC% 256
634
+ R% = ${resultAddress}
635
+ P% = MC%
636
+ [
637
+ OPT 2
638
+ SEI
639
+ LDX #0
640
+ LDY #0
641
+ LDA #20
642
+ STA &FE64
643
+ LDA #0
644
+ STA &FE65
645
+ ASL &FE64,X
646
+ LDA &FE64
647
+ STA &FE6A
648
+ CLI
649
+ RTS
650
+ ]
651
+ CALL MC%
652
+ PRINT ?&FE6A
653
+ ?R% = ?&FE6A`);
654
+ expectArray(testMachine, [13]); // checked on a BBC Master
655
+ });
656
+ it("VIA.C5", async function () {
657
+ const testMachine = await runViaProgram(`
658
+ DIM MC% 256
659
+ R% = ${resultAddress}
660
+ P% = MC%
661
+ [
662
+ OPT 2
663
+ SEI
664
+ LDA #&64
665
+ STA &50
666
+ LDA #&FE
667
+ STA &51
668
+ LDX #0
669
+ LDY #0
670
+ LDA #20
671
+ STA &FE64
672
+ LDA #0
673
+ STA &FE65
674
+ EQUB &03 \\ SLO ($50, X)
675
+ EQUB &50
676
+ LDA &FE64
677
+ STA &FE6A
678
+ CLI
679
+ RTS
680
+ ]
681
+ CALL MC%
682
+ PRINT ?&FE6A
683
+ ?R% = ?&FE6A`);
684
+ expectArray(testMachine, [12]); // TODO check this on a real BBC (opcode difference on master)
685
+ });
686
+ it("VIA.I1 - does T1LH write clear int in on-shot", async function () {
687
+ const testMachine = await runViaProgram(`
688
+ DIM MC% 256
689
+ R% = ${resultAddress}
690
+ P% = MC%
691
+ [
692
+ OPT 2
693
+ SEI
694
+ LDA #&7F
695
+ STA &FE6E
696
+ LDA #&00
697
+ STA &FE6B
698
+ STA &FE64
699
+ STA &FE65
700
+ NOP
701
+ NOP
702
+ LDA &FE6D
703
+ STA R%
704
+ LDA #&00
705
+ STA &FE67
706
+ LDA &FE6D
707
+ STA R%+1
708
+ CLI
709
+ RTS
710
+ ]
711
+ CALL MC%
712
+ PRINT "VIA TEST: DOES T1LH WRITE CLEAR INT IN ONE-SHOT?"
713
+ PRINT "REAL BBC: YES: 64, 0"
714
+ REM REAL BBC! YES: 64, 0
715
+ PRINT ?(R%)
716
+ PRINT ?(R%+1)`);
717
+ expectArray(testMachine, [64, 0]);
718
+ });
719
+ it("VIA.I2 - does timer interrupt fire if IFR cleared at the same time?", async function () {
720
+ const testMachine = await runViaProgram(`
721
+ DIM IRQ% 100
722
+ DIM MC% 256
723
+ R% = ${resultAddress}
724
+ DIM BAK% 3
725
+ P% = IRQ%
726
+ [
727
+ OPT 2
728
+ INC R%
729
+ RTI
730
+ ]
731
+ P% = MC%
732
+ [
733
+ OPT 2
734
+ SEI
735
+ LDA #&00
736
+ STA R%
737
+ LDA &0204
738
+ STA BAK%
739
+ LDA &0205
740
+ STA BAK%+1
741
+ LDA &FE4E
742
+ STA BAK%+2
743
+ LDA #(IRQ% MOD 256)
744
+ STA &0204
745
+ LDA #(IRQ% DIV 256)
746
+ STA &0205
747
+ LDA #&7F
748
+ STA &FE6E
749
+ STA &FE4E
750
+ LDA #&C0
751
+ STA &FE6E
752
+ LDA #&00
753
+ STA &FE6B
754
+ LDA #&03
755
+ STA &FE64
756
+ LDA #&00
757
+ LDX #&7F
758
+ STA &FE65
759
+ NOP
760
+ NOP
761
+ STX &FE6D
762
+ LDA &FE6D
763
+ STA R%+1
764
+ CLI
765
+ SEI
766
+ LDA BAK%
767
+ STA &0204
768
+ LDA BAK%+1
769
+ STA &0205
770
+ LDA BAK%+2
771
+ STA &FE4E
772
+ LDA #&7F
773
+ STA &FE6E
774
+ CLI
775
+ RTS
776
+ ]
777
+ PRINT ~MC%
778
+ PRINT ~IRQ%
779
+ CALL MC%
780
+ PRINT "VIA TEST: DOES TIMER INTERRUPT FIRE IF IFR CLEARED AT SAME TIME?"
781
+ PRINT "REAL BBC: YES: 1, 192"
782
+ PRINT ?(R%)
783
+ PRINT ?(R%+1)`);
784
+ expectArray(testMachine, [1, 192]);
785
+ });
786
+ it("VIA.PB2 - does pb7 toggle if ACR not in PB7 mode?", async function () {
787
+ const testMachine = await runViaProgram(`
788
+ DIM MC% 256
789
+ R% = ${resultAddress}
790
+ P% = MC%
791
+ [
792
+ OPT 3
793
+ SEI
794
+ LDA #&FF
795
+ STA &FE62
796
+ LDA #&00
797
+ STA &FE60
798
+ LDA #&7F
799
+ STA &FE6E
800
+ LDA #&80
801
+ STA &FE6B
802
+ LDA #&03
803
+ STA &FE64
804
+ LDA #&00
805
+ STA &FE65
806
+ STA &FE6B
807
+ NOP
808
+ NOP
809
+ LDA #&80
810
+ STA &FE6B
811
+ LDA &FE60
812
+ STA R%
813
+ CLI
814
+ RTS
815
+ ]
816
+ CALL MC%
817
+ REM REAL BBC! YES: 128
818
+ PRINT ?(R%)`);
819
+ expectArray(testMachine, [128]);
820
+ });
821
+ // @scarybeasts' original talks about "SYSVIA" below but this is the user VIA
822
+ it("VIA.PB7 - user via checks", async function () {
823
+ const testMachine = await runViaProgram(`
824
+ PRINT "RUN AFTER FRESH BOOT"
825
+ R% = ${resultAddress}
826
+ ?R% = 0
827
+ PROCcheck(0, ?&FE62, "SYSVIA DDRB &FE62")
828
+ PROCcheck(255, ?&FE60, "SYSVIA PORT B &FE60")
829
+ ?&FE62 = 255
830
+ PROCcheck(0, ?&FE60, "SYSVIA PORT B OUTPUT")
831
+ ?&FE62 = 0
832
+ PROCcheck(255, ?&FE60, "SYSVIA PORT B INPUT")
833
+ PROCcheck(0, ?&FE6B, "SYSVIA ACR")
834
+ ?&FE6B = 128
835
+ ?&FE60 = 0
836
+ ?&FE64 = 0
837
+ ?&FE65 = 255
838
+ REM READ QUICKLY BEFORE TIMER HITS
839
+ A% = ?&FE60
840
+ REM TIMER EXPIRES IN 65MS
841
+ T%=TIME+10:REPEAT UNTIL TIME>T%
842
+ PROCcheck(127, A%, "SYSVIA PORT B INPUT PB7 LOW")
843
+ PROCcheck(255, ?&FE60, "SYSVIA PORT B INPUT PB7 HIGH")
844
+ ?&FE62 = 255
845
+ PROCcheck(128, ?&FE60, "SYSVIA PORT B OUTPUT PB7 HIGH")
846
+ ?&FE6B = 0
847
+ PROCcheck(0, ?&FE60, "SYSVIA PORT B OUTPUT")
848
+ ?&FE60 = 0
849
+ ?&FE62 = 0
850
+ END
851
+ DEF PROCcheck(E%, A%, N$)
852
+ R$ = "OK"
853
+ IF E% <> A% THEN R$ = "FAIL!"
854
+ IF E% <> A% THEN ?R% = 255
855
+ PRINT R$ + ": " + N$ + ": " + STR$(A%) + " (expected " + STR$(E%) + ")"
856
+ ENDPROC`);
857
+ expectArray(testMachine, [0]);
858
+ });
859
+ it("VIA.T11 - How does T1 tick across expiry?", async function () {
860
+ const testMachine = await runViaProgram(`
861
+ REM RESET ACR TO DEFAULT BOOT + MOS 1.2 STATE
862
+ R% = ${resultAddress}
863
+ PRINT "VIA TEST: HOW DOES T1 TICK ACROSS EXPIRY?"
864
+ PRINT "REAL BBC: 1, 0, 255, 4, 3, 2"
865
+ ?&FE6B = 0
866
+ REM QUICK CHECKS TO SEE IF TIMERS ARE RUNNING ETC.
867
+ PRINT "USER VIA IFR: " + STR$(?&FE6D)
868
+ FOR A%=0 TO 1
869
+ PRINT "USER VIA T1CH: " + STR$(?&FE65)
870
+ PRINT "USER VIA T1CL: " + STR$(?&FE64)
871
+ NEXT
872
+ DIM MC% 100
873
+ PROCtimeit(1)
874
+ PROCtimeit(2)
875
+ PROCtimeit(3)
876
+ PROCtimeit(4)
877
+ PROCtimeit(5)
878
+ PROCtimeit(6)
879
+ END
880
+ DEF PROCtimeit(N%)
881
+ P% = MC%
882
+ [
883
+ OPT 0
884
+ SEI
885
+ LDX #0
886
+ LDY #0
887
+ LDA #4
888
+ STA &FE64
889
+ LDA #0
890
+ STA &FE65
891
+ ]
892
+ FOR A%=1 TO N%
893
+ [
894
+ OPT 0
895
+ NOP
896
+ ]
897
+ NEXT
898
+ [
899
+ OPT 0
900
+ LDA &FE64
901
+ STA &FE6A
902
+ CLI
903
+ RTS
904
+ ]
905
+ CALL MC%
906
+ PRINT "USER VIA T1CL: " + STR$(?&FE6A)
907
+ ?R% = ?&FE6A
908
+ R% = R% + 1
909
+ ENDPROC`);
910
+ expectArray(testMachine, [1, 0, 255, 4, 3, 2]);
911
+ });
912
+ it("VIA.T12 - When do T1L writes take effect vs. timer expiry?", async function () {
913
+ const testMachine = await runViaProgram(`
914
+ DIM MC% 100
915
+ R% = ${resultAddress}
916
+ P% = MC%
917
+ [
918
+ OPT 3
919
+ SEI
920
+ LDA #&00
921
+ STA &FE6B
922
+ LDA #&7F
923
+ STA &FE6E
924
+ LDA #&02
925
+ STA &FE64
926
+ LDA #&00
927
+ STA &FE65
928
+ LDA #&FF
929
+ STA &FE66
930
+ LDA &FE64
931
+ STA R%
932
+ LDA #&03
933
+ STA &FE64
934
+ LDA #&00
935
+ STA &FE65
936
+ NOP
937
+ NOP
938
+ LDA #&FF
939
+ STA &FE66
940
+ LDA &FE64
941
+ STA R%+1
942
+ CLI
943
+ RTS
944
+ ]
945
+ CALL MC%
946
+ REM REAL BBC: 253, 0
947
+ PRINT "VIA TEST: WHEN DO T1L WRITES TAKE EFFECT VS. TIMER EXPIRY?"
948
+ PRINT "REAL BBC: 253, 0"
949
+ PRINT ?(R%)
950
+ PRINT ?(R%+1)`);
951
+ expectArray(testMachine, [253, 0]);
952
+ });
953
+ it("VIA.T21 - user VIA T2 to pulse counting?", async function () {
954
+ const testMachine = await runViaProgram(`
955
+ REM USER VIA T2 TO PULSE COUNTING
956
+ REM FREEZES T2
957
+ R% = ${resultAddress}
958
+ PRINT "VIA TEST: T2 IN PULSE COUNTING MODE"
959
+ PRINT "REAL BBC: 1, 255, 255"
960
+ ?&FE6B = &20
961
+ ?&FE68 = 1
962
+ ?&FE69 = 0
963
+ R%?0 = ?&FE68
964
+ ?&FE68 = &FF
965
+ ?&FE69 = &FF
966
+ R%?1 = ?&FE68
967
+ R%?2 = ?&FE68
968
+ PRINT "USER VIA T2CL: " + STR$(R%?0)
969
+ PRINT "USER VIA T2CL: " + STR$(R%?1)
970
+ PRINT "USER VIA T2CL: " + STR$(R%?2)`);
971
+ expectArray(testMachine, [1, 255, 255]);
972
+ });
973
+ it("VIA.T22 - T2 ticking past expiry", async function () {
974
+ const testMachine = await runViaProgram(`
975
+ REM RESET ACR TO DEFAULT BOOT + MOS 1.2 STATE
976
+ R% = ${resultAddress}
977
+ PRINT "VIA TEST: T2 TICKING PAST EXPIRY"
978
+ PRINT "REAL BBC: 1, 0, 255, 254, 253, 252"
979
+ ?&FE6B = 0
980
+ REM QUICK CHECKS TO SEE IF TIMERS ARE RUNNING ETC.
981
+ PRINT "USER VIA IFR: " + STR$(?&FE6D)
982
+ FOR A%=0 TO 1
983
+ PRINT "USER VIA T2CH: " + STR$(?&FE69)
984
+ PRINT "USER VIA T2CL: " + STR$(?&FE68)
985
+ NEXT
986
+ DIM MC% 100
987
+ PROCtimeit(1)
988
+ PROCtimeit(2)
989
+ PROCtimeit(3)
990
+ PROCtimeit(4)
991
+ PROCtimeit(5)
992
+ PROCtimeit(6)
993
+ END
994
+ DEF PROCtimeit(N%)
995
+ P% = MC%
996
+ [
997
+ OPT 0
998
+ SEI
999
+ LDX #0
1000
+ LDY #0
1001
+ LDA #4
1002
+ STA &FE68
1003
+ LDA #0
1004
+ STA &FE69
1005
+ ]
1006
+ FOR A%=1 TO N%
1007
+ [
1008
+ OPT 0
1009
+ NOP
1010
+ ]
1011
+ NEXT
1012
+ [
1013
+ OPT 0
1014
+ LDA &FE68
1015
+ STA &FE6A
1016
+ CLI
1017
+ RTS
1018
+ ]
1019
+ CALL MC%
1020
+ PRINT "USER VIA T2CL: " + STR$(?&FE6A)
1021
+ ?R% = ?&FE6A
1022
+ R% = R% + 1
1023
+ ENDPROC`);
1024
+ expectArray(testMachine, [1, 0, 255, 254, 253, 252]);
1025
+ });
1026
+ // Disabled, @scarybeasts comments:
1027
+ // I fixed everything except VIA.T23, which doesn't seem important. It's tricky for code to really rely on T2
1028
+ // values after toggling ACR 0x20 because results will vary depending on what is attached and generating pulses
1029
+ // from external.
1030
+ // @mattgodbolt notes; the "real BBC" values agree with my BBC Master, so seems good to fix.
1031
+ // TODO: fix this eventually
1032
+ it.skip("VIA.T23 - what values do we get freezing and starting T2?", async function () {
1033
+ const testMachine = await runViaProgram(`
1034
+ DIM MC% 100
1035
+ R% = ${resultAddress}
1036
+ P% = MC%
1037
+ [
1038
+ OPT 3
1039
+ SEI
1040
+ LDA #&40
1041
+ STA &FE4B
1042
+ LDA #&FF
1043
+ STA &FE48
1044
+ STA &FE49
1045
+ LDA #&60
1046
+ STA &FE4B
1047
+ LDA &FE48
1048
+ STA R%
1049
+ LDA #&40
1050
+ STA &FE4B
1051
+ LDA &FE48
1052
+ STA R%+1
1053
+ LDA #&60
1054
+ STA &FE4B
1055
+ CLI
1056
+ RTS
1057
+ ]
1058
+ CALL MC%
1059
+ REM REAL BBC: 251, 249
1060
+ PRINT "VIA TEST: WHAT VALUES DO WE GET FREEZING AND STARTING T2?"
1061
+ PRINT "REAL BBC: 251, 249"
1062
+ PRINT ?(R%)
1063
+ PRINT ?(R%+1)`);
1064
+ expectArray(testMachine, [251, 249]);
1065
+ });
1066
+
1067
+ // @tom-seddon reported this one:
1068
+ it("T.VIA.PB6 - VIA T2 doesn't count manually-induced PB6 pulses", async function () {
1069
+ const testMachine = await runViaProgram(`
1070
+ REM DISABLE IRQS
1071
+ N%=0
1072
+ R%=${resultAddress}
1073
+ ?&FE6E=&7F
1074
+ ?&FE6D=&7F
1075
+ :
1076
+ REM T2 PULSE COUNTING MODE
1077
+ ?&FE6B=?&FE6B OR&20
1078
+ :
1079
+ REM RESET T2
1080
+ ?&FE68=100
1081
+ ?&FE69=0
1082
+ :
1083
+ REM PB OUTPUTS
1084
+ :
1085
+ PROCP
1086
+ PRINT"TOGGLE IN OUTPUT MODE"
1087
+ ?&FE62=0
1088
+ ?&FE6F=&40
1089
+ PROCP
1090
+ ?&FE62=&FF
1091
+ PROCP
1092
+ ?&FE6F=&40
1093
+ PROCP
1094
+ ?&FE6F=&00
1095
+ PROCP
1096
+ PRINT"TOGGLE VIA DDRB"
1097
+ ?&FE62=0
1098
+ PROCP
1099
+ ?&FE62=&FF
1100
+ PROCP
1101
+ ?&FE62=0
1102
+ PROCP
1103
+ END
1104
+ :
1105
+ DEFPROCP:LOCALT2%
1106
+ T2%=?&FE69*256+?&FE68
1107
+ R%!N%=T2%
1108
+ N%=N%+2
1109
+ PRINT"T2=";T2%" (&";~T2%")"
1110
+ ENDPROC`);
1111
+ // Expected output:
1112
+ // T2=100 (&64)
1113
+ // TOGGLE IN OUTPUT MODE
1114
+ // T2=100 (&64)
1115
+ // T2=99 (&63)
1116
+ // T2=99 (&63)
1117
+ // T2=99 (&63)
1118
+ // TOGGLE VIA DDRB
1119
+ // T2=99 (&63)
1120
+ // T2=98 (&62)
1121
+ // T2=98 (&62)
1122
+ expectArray(testMachine, [100, 0, 100, 0, 99, 0, 99, 0, 99, 0, 99, 0, 98, 0, 98, 0]);
1123
+ });
1124
+ // TODO: write more pb6 pulse tests, e.g. interrupt behaviour and underflow, and run on a real bbc.
1125
+ });