c64-kb 0.17.0

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 (970) hide show
  1. package/CHANGELOG.md +2082 -0
  2. package/LICENSE +29 -0
  3. package/README.md +559 -0
  4. package/VERSION +25 -0
  5. package/dist/cli/setup.js +66 -0
  6. package/dist/cli/setup.js.map +1 -0
  7. package/dist/cli-memorize-audit.js +97 -0
  8. package/dist/cli-memorize-audit.js.map +1 -0
  9. package/dist/cli.js +335 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/config.js +83 -0
  12. package/dist/config.js.map +1 -0
  13. package/dist/context.js +53 -0
  14. package/dist/context.js.map +1 -0
  15. package/dist/domain/budget-notes.js +104 -0
  16. package/dist/domain/budget-notes.js.map +1 -0
  17. package/dist/domain/budget.js +417 -0
  18. package/dist/domain/budget.js.map +1 -0
  19. package/dist/domain/game-design.js +77 -0
  20. package/dist/domain/game-design.js.map +1 -0
  21. package/dist/domain/timing.js +39 -0
  22. package/dist/domain/timing.js.map +1 -0
  23. package/dist/graph/apply.js +132 -0
  24. package/dist/graph/apply.js.map +1 -0
  25. package/dist/graph/claims.js +231 -0
  26. package/dist/graph/claims.js.map +1 -0
  27. package/dist/graph/extract/archetype.js +118 -0
  28. package/dist/graph/extract/archetype.js.map +1 -0
  29. package/dist/graph/extract/common.js +69 -0
  30. package/dist/graph/extract/common.js.map +1 -0
  31. package/dist/graph/extract/failure.js +37 -0
  32. package/dist/graph/extract/failure.js.map +1 -0
  33. package/dist/graph/extract/game-design.js +189 -0
  34. package/dist/graph/extract/game-design.js.map +1 -0
  35. package/dist/graph/extract/hardware.js +124 -0
  36. package/dist/graph/extract/hardware.js.map +1 -0
  37. package/dist/graph/extract/pitfall.js +62 -0
  38. package/dist/graph/extract/pitfall.js.map +1 -0
  39. package/dist/graph/extract/raster-band.js +56 -0
  40. package/dist/graph/extract/raster-band.js.map +1 -0
  41. package/dist/graph/extract/recipe.js +71 -0
  42. package/dist/graph/extract/recipe.js.map +1 -0
  43. package/dist/graph/extract/technique-entities.js +180 -0
  44. package/dist/graph/extract/technique-entities.js.map +1 -0
  45. package/dist/graph/extract/technique.js +179 -0
  46. package/dist/graph/extract/technique.js.map +1 -0
  47. package/dist/graph/extract/toolchain.js +67 -0
  48. package/dist/graph/extract/toolchain.js.map +1 -0
  49. package/dist/graph/extract/types.js +3 -0
  50. package/dist/graph/extract/types.js.map +1 -0
  51. package/dist/graph/extract/vocabulary.js +65 -0
  52. package/dist/graph/extract/vocabulary.js.map +1 -0
  53. package/dist/graph/extract.js +43 -0
  54. package/dist/graph/extract.js.map +1 -0
  55. package/dist/graph/kernal-clobbers.js +64 -0
  56. package/dist/graph/kernal-clobbers.js.map +1 -0
  57. package/dist/graph/machine-variants.js +208 -0
  58. package/dist/graph/machine-variants.js.map +1 -0
  59. package/dist/ingest/files.js +99 -0
  60. package/dist/ingest/files.js.map +1 -0
  61. package/dist/ingest/passes.js +104 -0
  62. package/dist/ingest/passes.js.map +1 -0
  63. package/dist/ingest/points.js +50 -0
  64. package/dist/ingest/points.js.map +1 -0
  65. package/dist/ingest/report.js +140 -0
  66. package/dist/ingest/report.js.map +1 -0
  67. package/dist/ingest/tally.js +81 -0
  68. package/dist/ingest/tally.js.map +1 -0
  69. package/dist/ingest/verified-on.js +43 -0
  70. package/dist/ingest/verified-on.js.map +1 -0
  71. package/dist/ingest.js +135 -0
  72. package/dist/ingest.js.map +1 -0
  73. package/dist/schemas/cost-basis.js +5 -0
  74. package/dist/schemas/cost-basis.js.map +1 -0
  75. package/dist/schemas/machine-variant.js +25 -0
  76. package/dist/schemas/machine-variant.js.map +1 -0
  77. package/dist/schemas/plan-budget.js +121 -0
  78. package/dist/schemas/plan-budget.js.map +1 -0
  79. package/dist/schemas/tool-outputs.js +526 -0
  80. package/dist/schemas/tool-outputs.js.map +1 -0
  81. package/dist/server/define-tool.js +52 -0
  82. package/dist/server/define-tool.js.map +1 -0
  83. package/dist/server/defined-only.js +9 -0
  84. package/dist/server/defined-only.js.map +1 -0
  85. package/dist/server/tools-briefings.js +70 -0
  86. package/dist/server/tools-briefings.js.map +1 -0
  87. package/dist/server/tools-lookup.js +180 -0
  88. package/dist/server/tools-lookup.js.map +1 -0
  89. package/dist/server/tools-maintenance.js +116 -0
  90. package/dist/server/tools-maintenance.js.map +1 -0
  91. package/dist/server/tools-pitfalls.js +89 -0
  92. package/dist/server/tools-pitfalls.js.map +1 -0
  93. package/dist/server/tools-recipes.js +296 -0
  94. package/dist/server/tools-recipes.js.map +1 -0
  95. package/dist/server/tools-runtime.js +48 -0
  96. package/dist/server/tools-runtime.js.map +1 -0
  97. package/dist/server/tools.js +43 -0
  98. package/dist/server/tools.js.map +1 -0
  99. package/dist/server.js +95 -0
  100. package/dist/server.js.map +1 -0
  101. package/dist/services/analytics/schema.js +78 -0
  102. package/dist/services/analytics/schema.js.map +1 -0
  103. package/dist/services/analytics/statements.js +99 -0
  104. package/dist/services/analytics/statements.js.map +1 -0
  105. package/dist/services/analytics.js +195 -0
  106. package/dist/services/analytics.js.map +1 -0
  107. package/dist/services/bm25.js +158 -0
  108. package/dist/services/bm25.js.map +1 -0
  109. package/dist/services/chunker.js +81 -0
  110. package/dist/services/chunker.js.map +1 -0
  111. package/dist/services/embeddings.js +58 -0
  112. package/dist/services/embeddings.js.map +1 -0
  113. package/dist/services/falkor/base.js +85 -0
  114. package/dist/services/falkor/base.js.map +1 -0
  115. package/dist/services/falkor/links.js +361 -0
  116. package/dist/services/falkor/links.js.map +1 -0
  117. package/dist/services/falkor/nodes.js +183 -0
  118. package/dist/services/falkor/nodes.js.map +1 -0
  119. package/dist/services/falkor/params.js +45 -0
  120. package/dist/services/falkor/params.js.map +1 -0
  121. package/dist/services/falkor/schema.js +77 -0
  122. package/dist/services/falkor/schema.js.map +1 -0
  123. package/dist/services/falkor.js +100 -0
  124. package/dist/services/falkor.js.map +1 -0
  125. package/dist/services/qdrant.js +238 -0
  126. package/dist/services/qdrant.js.map +1 -0
  127. package/dist/services/versions.js +73 -0
  128. package/dist/services/versions.js.map +1 -0
  129. package/dist/services/vice-bin.js +51 -0
  130. package/dist/services/vice-bin.js.map +1 -0
  131. package/dist/tools/briefings/archetype.js +174 -0
  132. package/dist/tools/briefings/archetype.js.map +1 -0
  133. package/dist/tools/briefings/budget.js +177 -0
  134. package/dist/tools/briefings/budget.js.map +1 -0
  135. package/dist/tools/briefings/build-order.js +135 -0
  136. package/dist/tools/briefings/build-order.js.map +1 -0
  137. package/dist/tools/briefings/build.js +185 -0
  138. package/dist/tools/briefings/build.js.map +1 -0
  139. package/dist/tools/briefings/discovery.js +290 -0
  140. package/dist/tools/briefings/discovery.js.map +1 -0
  141. package/dist/tools/briefings/plan-pitfalls.js +69 -0
  142. package/dist/tools/briefings/plan-pitfalls.js.map +1 -0
  143. package/dist/tools/briefings/render.js +151 -0
  144. package/dist/tools/briefings/render.js.map +1 -0
  145. package/dist/tools/briefings/rows.js +41 -0
  146. package/dist/tools/briefings/rows.js.map +1 -0
  147. package/dist/tools/briefings/toolchain.js +63 -0
  148. package/dist/tools/briefings/toolchain.js.map +1 -0
  149. package/dist/tools/briefings/why-proposed.js +69 -0
  150. package/dist/tools/briefings/why-proposed.js.map +1 -0
  151. package/dist/tools/briefings.js +44 -0
  152. package/dist/tools/briefings.js.map +1 -0
  153. package/dist/tools/feedback.js +97 -0
  154. package/dist/tools/feedback.js.map +1 -0
  155. package/dist/tools/hydrate.js +75 -0
  156. package/dist/tools/hydrate.js.map +1 -0
  157. package/dist/tools/intelligence.js +67 -0
  158. package/dist/tools/intelligence.js.map +1 -0
  159. package/dist/tools/lint/asm-decimal.js +86 -0
  160. package/dist/tools/lint/asm-decimal.js.map +1 -0
  161. package/dist/tools/lint/asm-rules.js +221 -0
  162. package/dist/tools/lint/asm-rules.js.map +1 -0
  163. package/dist/tools/lint/asm-shared.js +3 -0
  164. package/dist/tools/lint/asm-shared.js.map +1 -0
  165. package/dist/tools/lint/c-rules.js +215 -0
  166. package/dist/tools/lint/c-rules.js.map +1 -0
  167. package/dist/tools/lint/text.js +122 -0
  168. package/dist/tools/lint/text.js.map +1 -0
  169. package/dist/tools/lint/types.js +40 -0
  170. package/dist/tools/lint/types.js.map +1 -0
  171. package/dist/tools/lint.js +76 -0
  172. package/dist/tools/lint.js.map +1 -0
  173. package/dist/tools/memorization-mcp.js +111 -0
  174. package/dist/tools/memorization-mcp.js.map +1 -0
  175. package/dist/tools/pitfalls/bm25.js +53 -0
  176. package/dist/tools/pitfalls/bm25.js.map +1 -0
  177. package/dist/tools/pitfalls/format.js +58 -0
  178. package/dist/tools/pitfalls/format.js.map +1 -0
  179. package/dist/tools/pitfalls/graph.js +124 -0
  180. package/dist/tools/pitfalls/graph.js.map +1 -0
  181. package/dist/tools/pitfalls.js +134 -0
  182. package/dist/tools/pitfalls.js.map +1 -0
  183. package/dist/tools/prompts.js +81 -0
  184. package/dist/tools/prompts.js.map +1 -0
  185. package/dist/tools/query/compatibility/closure.js +62 -0
  186. package/dist/tools/query/compatibility/closure.js.map +1 -0
  187. package/dist/tools/query/compatibility/facts.js +28 -0
  188. package/dist/tools/query/compatibility/facts.js.map +1 -0
  189. package/dist/tools/query/compatibility/fetch.js +164 -0
  190. package/dist/tools/query/compatibility/fetch.js.map +1 -0
  191. package/dist/tools/query/compatibility/hard-rules.js +159 -0
  192. package/dist/tools/query/compatibility/hard-rules.js.map +1 -0
  193. package/dist/tools/query/compatibility/index.js +27 -0
  194. package/dist/tools/query/compatibility/index.js.map +1 -0
  195. package/dist/tools/query/compatibility/kernal-zp-rule.js +90 -0
  196. package/dist/tools/query/compatibility/kernal-zp-rule.js.map +1 -0
  197. package/dist/tools/query/compatibility/render.js +106 -0
  198. package/dist/tools/query/compatibility/render.js.map +1 -0
  199. package/dist/tools/query/compatibility/rules.js +337 -0
  200. package/dist/tools/query/compatibility/rules.js.map +1 -0
  201. package/dist/tools/query/compatibility/unit-rules.js +253 -0
  202. package/dist/tools/query/compatibility/unit-rules.js.map +1 -0
  203. package/dist/tools/query/game-design.js +83 -0
  204. package/dist/tools/query/game-design.js.map +1 -0
  205. package/dist/tools/query/lookups.js +220 -0
  206. package/dist/tools/query/lookups.js.map +1 -0
  207. package/dist/tools/query/plan-budget.js +266 -0
  208. package/dist/tools/query/plan-budget.js.map +1 -0
  209. package/dist/tools/query/recipes.js +214 -0
  210. package/dist/tools/query/recipes.js.map +1 -0
  211. package/dist/tools/query/retrieval.js +128 -0
  212. package/dist/tools/query/retrieval.js.map +1 -0
  213. package/dist/tools/query/shared.js +121 -0
  214. package/dist/tools/query/shared.js.map +1 -0
  215. package/dist/tools/query/techniques.js +331 -0
  216. package/dist/tools/query/techniques.js.map +1 -0
  217. package/dist/tools/query/timing.js +106 -0
  218. package/dist/tools/query/timing.js.map +1 -0
  219. package/dist/tools/query/types.js +11 -0
  220. package/dist/tools/query/types.js.map +1 -0
  221. package/dist/tools/query.js +21 -0
  222. package/dist/tools/query.js.map +1 -0
  223. package/dist/tools/resources.js +186 -0
  224. package/dist/tools/resources.js.map +1 -0
  225. package/dist/tools/run-game.js +249 -0
  226. package/dist/tools/run-game.js.map +1 -0
  227. package/dist/tools/selfimprovement.js +367 -0
  228. package/dist/tools/selfimprovement.js.map +1 -0
  229. package/docker-compose.yml +35 -0
  230. package/docs/ARCHITECTURE.md +164 -0
  231. package/docs/CONVENTIONS-archetypes.md +158 -0
  232. package/docs/CONVENTIONS-failures.md +46 -0
  233. package/docs/CONVENTIONS-game-designs.md +75 -0
  234. package/docs/CONVENTIONS-hardware-reference.md +184 -0
  235. package/docs/CONVENTIONS-pitfalls.md +91 -0
  236. package/docs/CONVENTIONS-recipes.md +106 -0
  237. package/docs/CONVENTIONS-techniques.md +309 -0
  238. package/docs/CONVENTIONS-toolchain-reference.md +89 -0
  239. package/docs/ONTOLOGY.md +655 -0
  240. package/docs/art/art-production-reference.md +157 -0
  241. package/docs/art/asset-pipelines.md +586 -0
  242. package/docs/c64-failure-patterns.md +693 -0
  243. package/docs/demo-design/demo-composition.md +349 -0
  244. package/docs/demo-design/demo-design-philosophy.md +320 -0
  245. package/docs/demo-design/intro-cracktro-patterns.md +435 -0
  246. package/docs/figures/ctm-spd-embed-probe.png +0 -0
  247. package/docs/figures/dot-flag-mid-5000000.png +0 -0
  248. package/docs/figures/dot-flag-no-erase-12000000.png +0 -0
  249. package/docs/figures/edges.json +1 -0
  250. package/docs/figures/fig6-architecture.png +0 -0
  251. package/docs/figures/fig7-ontology.png +0 -0
  252. package/docs/figures/screen-dissolve-mid-frame25.png +0 -0
  253. package/docs/figures/screen-dissolve-wipe-frame25.png +0 -0
  254. package/docs/figures/spindle-two-parts-part1.png +0 -0
  255. package/docs/figures/spindle-two-parts-part2.png +0 -0
  256. package/docs/figures/starters/action-puzzle.png +0 -0
  257. package/docs/figures/starters/adventure.png +0 -0
  258. package/docs/figures/starters/beat-em-up.png +0 -0
  259. package/docs/figures/starters/demo.png +0 -0
  260. package/docs/figures/starters/platformer.png +0 -0
  261. package/docs/figures/starters/shmup-vertical.png +0 -0
  262. package/docs/figures/tape-kernal-master-ntsc.png +0 -0
  263. package/docs/figures/tape-kernal-master-pal.png +0 -0
  264. package/docs/figures/tape-turbo-loader-ntsc.png +0 -0
  265. package/docs/figures/tape-turbo-loader-pal.png +0 -0
  266. package/docs/figures/tape-turbo-master-ntsc.png +0 -0
  267. package/docs/figures/tape-turbo-master-pal.png +0 -0
  268. package/docs/figures/tech-tech-pad2-12000000.png +0 -0
  269. package/docs/figures/tech-tech-pad4-12000000.png +0 -0
  270. package/docs/figures/tech-tech-seven-12000000.png +0 -0
  271. package/docs/figures/twister-mid-5000000.png +0 -0
  272. package/docs/figures/twister-straight-12000000.png +0 -0
  273. package/docs/figures/vector-balls-nosort-ntsc.png +0 -0
  274. package/docs/figures/vector-balls-nosort.png +0 -0
  275. package/docs/formats/c64-file-formats.md +1212 -0
  276. package/docs/formats/iec-disk-reference.md +754 -0
  277. package/docs/game-design/c64-game-archetypes.md +273 -0
  278. package/docs/game-design/designs/falling-blocks.md +54 -0
  279. package/docs/game-design/designs/platformer-scaffold.md +48 -0
  280. package/docs/game-design/designs/simple-shmup.md +27 -0
  281. package/docs/game-design/enemy-behaviour-and-difficulty.md +349 -0
  282. package/docs/game-design/game-design-patterns.md +1189 -0
  283. package/docs/game-design/game-structure.md +354 -0
  284. package/docs/game-design/production-planning.md +349 -0
  285. package/docs/game-design/reference-game-sources.md +90 -0
  286. package/docs/hardware/6502-illegal-opcodes.md +1353 -0
  287. package/docs/hardware/6510-cpu-reference.md +2112 -0
  288. package/docs/hardware/c64-memory-map.md +3184 -0
  289. package/docs/hardware/c64-registers-reference.md +996 -0
  290. package/docs/hardware/cia-reference.md +1281 -0
  291. package/docs/hardware/kernal-routines-reference.md +1836 -0
  292. package/docs/hardware/pal-ntsc-reference.md +813 -0
  293. package/docs/hardware/sid-reference.md +1137 -0
  294. package/docs/hardware/vic-ii-reference.md +1714 -0
  295. package/docs/music/music-production-reference.md +403 -0
  296. package/docs/pitfalls/banking.md +1067 -0
  297. package/docs/pitfalls/cia.md +1147 -0
  298. package/docs/pitfalls/cpu.md +874 -0
  299. package/docs/pitfalls/input.md +282 -0
  300. package/docs/pitfalls/kernal-and-io.md +1615 -0
  301. package/docs/pitfalls/loader.md +1191 -0
  302. package/docs/pitfalls/logic.md +94 -0
  303. package/docs/pitfalls/maths.md +187 -0
  304. package/docs/pitfalls/raster-and-badline.md +721 -0
  305. package/docs/pitfalls/region-timing.md +660 -0
  306. package/docs/pitfalls/scroll.md +207 -0
  307. package/docs/pitfalls/sid.md +738 -0
  308. package/docs/pitfalls/sprite.md +979 -0
  309. package/docs/pitfalls/text-mode-render.md +1172 -0
  310. package/docs/recipes/cc65/cartridge-8k.md +398 -0
  311. package/docs/recipes/cc65/hello-world-conio.md +76 -0
  312. package/docs/recipes/cc65/memory-layout.md +312 -0
  313. package/docs/recipes/cc65/screenshots/README.md +14 -0
  314. package/docs/recipes/cc65/screenshots/cartridge-8k-ntsc.png +0 -0
  315. package/docs/recipes/cc65/screenshots/cartridge-8k.png +0 -0
  316. package/docs/recipes/cc65/screenshots/hello-world-conio.png +0 -0
  317. package/docs/recipes/cc65/screenshots/memory-layout-ntsc.png +0 -0
  318. package/docs/recipes/cc65/screenshots/memory-layout.png +0 -0
  319. package/docs/recipes/kickassembler/basic-float-calls.md +578 -0
  320. package/docs/recipes/kickassembler/basic-wedge.md +398 -0
  321. package/docs/recipes/kickassembler/big-font-scroller.md +620 -0
  322. package/docs/recipes/kickassembler/charset-copy-rom-to-ram.md +623 -0
  323. package/docs/recipes/kickassembler/cia-revision-detect.md +366 -0
  324. package/docs/recipes/kickassembler/colour-cycling.md +343 -0
  325. package/docs/recipes/kickassembler/colour-fade.md +303 -0
  326. package/docs/recipes/kickassembler/compare-16bit-signed.md +1007 -0
  327. package/docs/recipes/kickassembler/cracktro-template.md +526 -0
  328. package/docs/recipes/kickassembler/crt-banked.md +276 -0
  329. package/docs/recipes/kickassembler/dos-error-codes.md +466 -0
  330. package/docs/recipes/kickassembler/dot-flag.md +576 -0
  331. package/docs/recipes/kickassembler/drive-job-queue.md +667 -0
  332. package/docs/recipes/kickassembler/drive-via-probe.md +690 -0
  333. package/docs/recipes/kickassembler/dycp-scroller.md +568 -0
  334. package/docs/recipes/kickassembler/dypp-sprite-scroller.md +681 -0
  335. package/docs/recipes/kickassembler/dysp.md +670 -0
  336. package/docs/recipes/kickassembler/easyflash-save.md +800 -0
  337. package/docs/recipes/kickassembler/eight-way-scroll.md +1484 -0
  338. package/docs/recipes/kickassembler/file-io-roundtrip.md +546 -0
  339. package/docs/recipes/kickassembler/fire-effect.md +420 -0
  340. package/docs/recipes/kickassembler/fld.md +414 -0
  341. package/docs/recipes/kickassembler/fli-image.md +336 -0
  342. package/docs/recipes/kickassembler/four-player-read.md +672 -0
  343. package/docs/recipes/kickassembler/headless-verify.md +228 -0
  344. package/docs/recipes/kickassembler/hello-world.md +98 -0
  345. package/docs/recipes/kickassembler/high-score-insert.md +660 -0
  346. package/docs/recipes/kickassembler/hires-plot-line.md +723 -0
  347. package/docs/recipes/kickassembler/irq-chain.md +316 -0
  348. package/docs/recipes/kickassembler/irq-owns-port.md +668 -0
  349. package/docs/recipes/kickassembler/isometric-room.md +1145 -0
  350. package/docs/recipes/kickassembler/light-pen-read.md +926 -0
  351. package/docs/recipes/kickassembler/logic-rate-decoupling.md +670 -0
  352. package/docs/recipes/kickassembler/mci-interlace.md +543 -0
  353. package/docs/recipes/kickassembler/memory-layout.md +277 -0
  354. package/docs/recipes/kickassembler/mouse-1351-read.md +801 -0
  355. package/docs/recipes/kickassembler/nmi-timer-tick.md +562 -0
  356. package/docs/recipes/kickassembler/own-keyscan.md +881 -0
  357. package/docs/recipes/kickassembler/paddle-read.md +751 -0
  358. package/docs/recipes/kickassembler/palette-cells.md +219 -0
  359. package/docs/recipes/kickassembler/pseudo-3d-road.md +930 -0
  360. package/docs/recipes/kickassembler/pwm-digi.md +463 -0
  361. package/docs/recipes/kickassembler/raster-bars.md +264 -0
  362. package/docs/recipes/kickassembler/reu-dma.md +1019 -0
  363. package/docs/recipes/kickassembler/runtime-relocation.md +743 -0
  364. package/docs/recipes/kickassembler/screen-dissolve.md +545 -0
  365. package/docs/recipes/kickassembler/screen-wipe.md +408 -0
  366. package/docs/recipes/kickassembler/screenshots/README.md +72 -0
  367. package/docs/recipes/kickassembler/screenshots/basic-float-calls-ntsc.png +0 -0
  368. package/docs/recipes/kickassembler/screenshots/basic-float-calls.png +0 -0
  369. package/docs/recipes/kickassembler/screenshots/basic-wedge-ntsc.png +0 -0
  370. package/docs/recipes/kickassembler/screenshots/basic-wedge.png +0 -0
  371. package/docs/recipes/kickassembler/screenshots/big-font-scroller-ntsc.png +0 -0
  372. package/docs/recipes/kickassembler/screenshots/big-font-scroller.png +0 -0
  373. package/docs/recipes/kickassembler/screenshots/charset-copy-rom-to-ram-ntsc.png +0 -0
  374. package/docs/recipes/kickassembler/screenshots/charset-copy-rom-to-ram.png +0 -0
  375. package/docs/recipes/kickassembler/screenshots/cia-revision-detect-ntsc.png +0 -0
  376. package/docs/recipes/kickassembler/screenshots/cia-revision-detect.png +0 -0
  377. package/docs/recipes/kickassembler/screenshots/colour-cycling-ntsc.png +0 -0
  378. package/docs/recipes/kickassembler/screenshots/colour-cycling.png +0 -0
  379. package/docs/recipes/kickassembler/screenshots/colour-fade-ntsc.png +0 -0
  380. package/docs/recipes/kickassembler/screenshots/colour-fade.png +0 -0
  381. package/docs/recipes/kickassembler/screenshots/compare-16bit-signed-ntsc.png +0 -0
  382. package/docs/recipes/kickassembler/screenshots/compare-16bit-signed.png +0 -0
  383. package/docs/recipes/kickassembler/screenshots/cracktro-template.png +0 -0
  384. package/docs/recipes/kickassembler/screenshots/crt-banked-ntsc.png +0 -0
  385. package/docs/recipes/kickassembler/screenshots/crt-banked.png +0 -0
  386. package/docs/recipes/kickassembler/screenshots/dos-error-codes-ntsc.png +0 -0
  387. package/docs/recipes/kickassembler/screenshots/dos-error-codes.png +0 -0
  388. package/docs/recipes/kickassembler/screenshots/dot-flag-ntsc.png +0 -0
  389. package/docs/recipes/kickassembler/screenshots/dot-flag.png +0 -0
  390. package/docs/recipes/kickassembler/screenshots/drive-job-queue-ntsc.png +0 -0
  391. package/docs/recipes/kickassembler/screenshots/drive-job-queue.png +0 -0
  392. package/docs/recipes/kickassembler/screenshots/drive-via-probe-ntsc.png +0 -0
  393. package/docs/recipes/kickassembler/screenshots/drive-via-probe.png +0 -0
  394. package/docs/recipes/kickassembler/screenshots/dycp-scroller-ntsc.png +0 -0
  395. package/docs/recipes/kickassembler/screenshots/dycp-scroller.png +0 -0
  396. package/docs/recipes/kickassembler/screenshots/dypp-sprite-scroller-ntsc.png +0 -0
  397. package/docs/recipes/kickassembler/screenshots/dypp-sprite-scroller.png +0 -0
  398. package/docs/recipes/kickassembler/screenshots/dysp-ntsc.png +0 -0
  399. package/docs/recipes/kickassembler/screenshots/dysp.png +0 -0
  400. package/docs/recipes/kickassembler/screenshots/easyflash-save-ntsc-run2.png +0 -0
  401. package/docs/recipes/kickassembler/screenshots/easyflash-save-ntsc.png +0 -0
  402. package/docs/recipes/kickassembler/screenshots/easyflash-save-run2.png +0 -0
  403. package/docs/recipes/kickassembler/screenshots/easyflash-save.png +0 -0
  404. package/docs/recipes/kickassembler/screenshots/eight-way-scroll-ntsc.png +0 -0
  405. package/docs/recipes/kickassembler/screenshots/eight-way-scroll.png +0 -0
  406. package/docs/recipes/kickassembler/screenshots/file-io-roundtrip-ntsc.png +0 -0
  407. package/docs/recipes/kickassembler/screenshots/file-io-roundtrip.png +0 -0
  408. package/docs/recipes/kickassembler/screenshots/fire-effect-ntsc.png +0 -0
  409. package/docs/recipes/kickassembler/screenshots/fire-effect.png +0 -0
  410. package/docs/recipes/kickassembler/screenshots/fld-ntsc.png +0 -0
  411. package/docs/recipes/kickassembler/screenshots/fld.png +0 -0
  412. package/docs/recipes/kickassembler/screenshots/fli-image.png +0 -0
  413. package/docs/recipes/kickassembler/screenshots/four-player-read-ntsc.png +0 -0
  414. package/docs/recipes/kickassembler/screenshots/four-player-read.png +0 -0
  415. package/docs/recipes/kickassembler/screenshots/headless-verify-ntsc.png +0 -0
  416. package/docs/recipes/kickassembler/screenshots/headless-verify.png +0 -0
  417. package/docs/recipes/kickassembler/screenshots/hello-world.png +0 -0
  418. package/docs/recipes/kickassembler/screenshots/high-score-insert-ntsc.png +0 -0
  419. package/docs/recipes/kickassembler/screenshots/high-score-insert.png +0 -0
  420. package/docs/recipes/kickassembler/screenshots/hires-plot-line-ntsc.png +0 -0
  421. package/docs/recipes/kickassembler/screenshots/hires-plot-line.png +0 -0
  422. package/docs/recipes/kickassembler/screenshots/irq-chain-ntsc.png +0 -0
  423. package/docs/recipes/kickassembler/screenshots/irq-chain.png +0 -0
  424. package/docs/recipes/kickassembler/screenshots/irq-owns-port-ntsc.png +0 -0
  425. package/docs/recipes/kickassembler/screenshots/irq-owns-port.png +0 -0
  426. package/docs/recipes/kickassembler/screenshots/isometric-room-ntsc.png +0 -0
  427. package/docs/recipes/kickassembler/screenshots/isometric-room.png +0 -0
  428. package/docs/recipes/kickassembler/screenshots/light-pen-read-ntsc.png +0 -0
  429. package/docs/recipes/kickassembler/screenshots/light-pen-read.png +0 -0
  430. package/docs/recipes/kickassembler/screenshots/logic-rate-decoupling-ntsc.png +0 -0
  431. package/docs/recipes/kickassembler/screenshots/logic-rate-decoupling.png +0 -0
  432. package/docs/recipes/kickassembler/screenshots/mci-interlace-average.png +0 -0
  433. package/docs/recipes/kickassembler/screenshots/mci-interlace-frame-b.png +0 -0
  434. package/docs/recipes/kickassembler/screenshots/mci-interlace-ntsc.png +0 -0
  435. package/docs/recipes/kickassembler/screenshots/mci-interlace.png +0 -0
  436. package/docs/recipes/kickassembler/screenshots/memory-layout-ntsc.png +0 -0
  437. package/docs/recipes/kickassembler/screenshots/memory-layout.png +0 -0
  438. package/docs/recipes/kickassembler/screenshots/mouse-1351-read-ntsc.png +0 -0
  439. package/docs/recipes/kickassembler/screenshots/mouse-1351-read.png +0 -0
  440. package/docs/recipes/kickassembler/screenshots/nmi-timer-tick-ntsc.png +0 -0
  441. package/docs/recipes/kickassembler/screenshots/nmi-timer-tick.png +0 -0
  442. package/docs/recipes/kickassembler/screenshots/own-keyscan-ntsc.png +0 -0
  443. package/docs/recipes/kickassembler/screenshots/own-keyscan.png +0 -0
  444. package/docs/recipes/kickassembler/screenshots/paddle-read-ntsc.png +0 -0
  445. package/docs/recipes/kickassembler/screenshots/paddle-read.png +0 -0
  446. package/docs/recipes/kickassembler/screenshots/palette-cells-ntsc.png +0 -0
  447. package/docs/recipes/kickassembler/screenshots/palette-cells.png +0 -0
  448. package/docs/recipes/kickassembler/screenshots/pseudo-3d-road-ntsc.png +0 -0
  449. package/docs/recipes/kickassembler/screenshots/pseudo-3d-road.png +0 -0
  450. package/docs/recipes/kickassembler/screenshots/pwm-digi-ntsc.png +0 -0
  451. package/docs/recipes/kickassembler/screenshots/pwm-digi.png +0 -0
  452. package/docs/recipes/kickassembler/screenshots/raster-bars.png +0 -0
  453. package/docs/recipes/kickassembler/screenshots/reu-dma-ntsc.png +0 -0
  454. package/docs/recipes/kickassembler/screenshots/reu-dma.png +0 -0
  455. package/docs/recipes/kickassembler/screenshots/runtime-relocation-ntsc.png +0 -0
  456. package/docs/recipes/kickassembler/screenshots/runtime-relocation.png +0 -0
  457. package/docs/recipes/kickassembler/screenshots/screen-dissolve-ntsc.png +0 -0
  458. package/docs/recipes/kickassembler/screenshots/screen-dissolve.png +0 -0
  459. package/docs/recipes/kickassembler/screenshots/screen-wipe-ntsc.png +0 -0
  460. package/docs/recipes/kickassembler/screenshots/screen-wipe.png +0 -0
  461. package/docs/recipes/kickassembler/screenshots/scroll-panel-split-ntsc.png +0 -0
  462. package/docs/recipes/kickassembler/screenshots/scroll-panel-split.png +0 -0
  463. package/docs/recipes/kickassembler/screenshots/sfx-in-player-ntsc.png +0 -0
  464. package/docs/recipes/kickassembler/screenshots/sfx-in-player.png +0 -0
  465. package/docs/recipes/kickassembler/screenshots/shadebobs-ntsc.png +0 -0
  466. package/docs/recipes/kickassembler/screenshots/shadebobs.png +0 -0
  467. package/docs/recipes/kickassembler/screenshots/sideborder-open.png +0 -0
  468. package/docs/recipes/kickassembler/screenshots/sine-scroller.png +0 -0
  469. package/docs/recipes/kickassembler/screenshots/sine-table-runtime-ntsc.png +0 -0
  470. package/docs/recipes/kickassembler/screenshots/sine-table-runtime.png +0 -0
  471. package/docs/recipes/kickassembler/screenshots/software-sprite-preshifted-ntsc.png +0 -0
  472. package/docs/recipes/kickassembler/screenshots/software-sprite-preshifted.png +0 -0
  473. package/docs/recipes/kickassembler/screenshots/speedcode-generator-ntsc.png +0 -0
  474. package/docs/recipes/kickassembler/screenshots/speedcode-generator.png +0 -0
  475. package/docs/recipes/kickassembler/screenshots/sprite-border-scroller-ntsc.png +0 -0
  476. package/docs/recipes/kickassembler/screenshots/sprite-border-scroller.png +0 -0
  477. package/docs/recipes/kickassembler/screenshots/sprite-cache-flip-ntsc.png +0 -0
  478. package/docs/recipes/kickassembler/screenshots/sprite-cache-flip.png +0 -0
  479. package/docs/recipes/kickassembler/screenshots/sprite-multiplex-24.png +0 -0
  480. package/docs/recipes/kickassembler/screenshots/sprite-multiplex-game-ntsc.png +0 -0
  481. package/docs/recipes/kickassembler/screenshots/sprite-multiplex-game.png +0 -0
  482. package/docs/recipes/kickassembler/screenshots/sprite-priority-classes-ntsc.png +0 -0
  483. package/docs/recipes/kickassembler/screenshots/sprite-priority-classes.png +0 -0
  484. package/docs/recipes/kickassembler/screenshots/sprite-sine-chain-ntsc.png +0 -0
  485. package/docs/recipes/kickassembler/screenshots/sprite-sine-chain.png +0 -0
  486. package/docs/recipes/kickassembler/screenshots/sprite-stretcher-ntsc.png +0 -0
  487. package/docs/recipes/kickassembler/screenshots/sprite-stretcher.png +0 -0
  488. package/docs/recipes/kickassembler/screenshots/sprites-only-screen-ntsc.png +0 -0
  489. package/docs/recipes/kickassembler/screenshots/sprites-only-screen.png +0 -0
  490. package/docs/recipes/kickassembler/screenshots/sqrt-atan2-ntsc.png +0 -0
  491. package/docs/recipes/kickassembler/screenshots/sqrt-atan2.png +0 -0
  492. package/docs/recipes/kickassembler/screenshots/stable-raster-irq-control.png +0 -0
  493. package/docs/recipes/kickassembler/screenshots/stable-raster-irq.png +0 -0
  494. package/docs/recipes/kickassembler/screenshots/tech-tech-ntsc.png +0 -0
  495. package/docs/recipes/kickassembler/screenshots/tech-tech.png +0 -0
  496. package/docs/recipes/kickassembler/screenshots/tod-alarm-ntsc.png +0 -0
  497. package/docs/recipes/kickassembler/screenshots/tod-alarm.png +0 -0
  498. package/docs/recipes/kickassembler/screenshots/topbottom-border-open.png +0 -0
  499. package/docs/recipes/kickassembler/screenshots/twister-ntsc.png +0 -0
  500. package/docs/recipes/kickassembler/screenshots/twister.png +0 -0
  501. package/docs/recipes/kickassembler/screenshots/unit-test-driver-ntsc.png +0 -0
  502. package/docs/recipes/kickassembler/screenshots/unit-test-driver.png +0 -0
  503. package/docs/recipes/kickassembler/screenshots/vector-balls-ntsc.png +0 -0
  504. package/docs/recipes/kickassembler/screenshots/vector-balls.png +0 -0
  505. package/docs/recipes/kickassembler/screenshots/wireframe-ships-ntsc.png +0 -0
  506. package/docs/recipes/kickassembler/screenshots/wireframe-ships.png +0 -0
  507. package/docs/recipes/kickassembler/scroll-panel-split.md +381 -0
  508. package/docs/recipes/kickassembler/sfx-in-player.md +907 -0
  509. package/docs/recipes/kickassembler/shadebobs.md +522 -0
  510. package/docs/recipes/kickassembler/sideborder-open.md +338 -0
  511. package/docs/recipes/kickassembler/sine-scroller.md +321 -0
  512. package/docs/recipes/kickassembler/sine-table-runtime.md +815 -0
  513. package/docs/recipes/kickassembler/software-sprite-preshifted.md +725 -0
  514. package/docs/recipes/kickassembler/speedcode-generator.md +606 -0
  515. package/docs/recipes/kickassembler/sprite-border-scroller.md +696 -0
  516. package/docs/recipes/kickassembler/sprite-cache-flip.md +1071 -0
  517. package/docs/recipes/kickassembler/sprite-multiplex-24.md +326 -0
  518. package/docs/recipes/kickassembler/sprite-multiplex-game.md +986 -0
  519. package/docs/recipes/kickassembler/sprite-priority-classes.md +463 -0
  520. package/docs/recipes/kickassembler/sprite-sine-chain.md +338 -0
  521. package/docs/recipes/kickassembler/sprite-stretcher.md +501 -0
  522. package/docs/recipes/kickassembler/sprites-only-screen.md +550 -0
  523. package/docs/recipes/kickassembler/sqrt-atan2.md +1014 -0
  524. package/docs/recipes/kickassembler/stable-raster-irq.md +360 -0
  525. package/docs/recipes/kickassembler/tape-turbo-loader.md +875 -0
  526. package/docs/recipes/kickassembler/tech-tech.md +679 -0
  527. package/docs/recipes/kickassembler/tod-alarm.md +754 -0
  528. package/docs/recipes/kickassembler/topbottom-border-open.md +407 -0
  529. package/docs/recipes/kickassembler/twister.md +518 -0
  530. package/docs/recipes/kickassembler/unit-test-driver.md +314 -0
  531. package/docs/recipes/kickassembler/vector-balls.md +545 -0
  532. package/docs/recipes/kickassembler/wireframe-ships.md +2324 -0
  533. package/docs/recipes/oscar64/actor-activation-window.md +807 -0
  534. package/docs/recipes/oscar64/adventure-engine.md +1094 -0
  535. package/docs/recipes/oscar64/attract-replay.md +465 -0
  536. package/docs/recipes/oscar64/beat-em-up-lanes.md +563 -0
  537. package/docs/recipes/oscar64/bfs-distance-map.md +723 -0
  538. package/docs/recipes/oscar64/bitmap-koala-viewer.md +355 -0
  539. package/docs/recipes/oscar64/car-contact.md +950 -0
  540. package/docs/recipes/oscar64/cave-scan.md +609 -0
  541. package/docs/recipes/oscar64/char-bullets.md +477 -0
  542. package/docs/recipes/oscar64/charset-animation.md +383 -0
  543. package/docs/recipes/oscar64/charset-parallax.md +401 -0
  544. package/docs/recipes/oscar64/destructible-terrain.md +1099 -0
  545. package/docs/recipes/oscar64/difficulty-tables.md +654 -0
  546. package/docs/recipes/oscar64/dig-and-guards.md +975 -0
  547. package/docs/recipes/oscar64/directory-reader.md +535 -0
  548. package/docs/recipes/oscar64/divide-check.md +581 -0
  549. package/docs/recipes/oscar64/double-buffer-nomirror.md +205 -0
  550. package/docs/recipes/oscar64/double-buffer.md +255 -0
  551. package/docs/recipes/oscar64/falling-blocks.md +874 -0
  552. package/docs/recipes/oscar64/fixed-point-jump-velocity.md +289 -0
  553. package/docs/recipes/oscar64/fixed-point-jump.md +210 -0
  554. package/docs/recipes/oscar64/flip-screen-rooms.md +793 -0
  555. package/docs/recipes/oscar64/frame-sync-loop-overrun.md +214 -0
  556. package/docs/recipes/oscar64/frame-sync-loop.md +254 -0
  557. package/docs/recipes/oscar64/game-tree-search.md +743 -0
  558. package/docs/recipes/oscar64/ghost-targeting.md +867 -0
  559. package/docs/recipes/oscar64/headless-verify.md +345 -0
  560. package/docs/recipes/oscar64/hello-world.md +83 -0
  561. package/docs/recipes/oscar64/high-score-persist.md +772 -0
  562. package/docs/recipes/oscar64/iffl-kernal-skip.md +421 -0
  563. package/docs/recipes/oscar64/joystick-input.md +358 -0
  564. package/docs/recipes/oscar64/lane-pursuit.md +1028 -0
  565. package/docs/recipes/oscar64/level-rle-decoder.md +620 -0
  566. package/docs/recipes/oscar64/lfsr-random-seed2.md +338 -0
  567. package/docs/recipes/oscar64/lfsr-random.md +403 -0
  568. package/docs/recipes/oscar64/load-asset-runtime.md +492 -0
  569. package/docs/recipes/oscar64/memory-layout.md +232 -0
  570. package/docs/recipes/oscar64/mixed-fighters.md +781 -0
  571. package/docs/recipes/oscar64/multi-sprite-object.md +533 -0
  572. package/docs/recipes/oscar64/nav-area-pathfinding.md +881 -0
  573. package/docs/recipes/oscar64/object-pool.md +572 -0
  574. package/docs/recipes/oscar64/pal-ntsc-detect.md +257 -0
  575. package/docs/recipes/oscar64/password-state.md +532 -0
  576. package/docs/recipes/oscar64/per-frame-hitbox.md +651 -0
  577. package/docs/recipes/oscar64/petscii-screen-codes.md +428 -0
  578. package/docs/recipes/oscar64/platformer-scaffold.md +1467 -0
  579. package/docs/recipes/oscar64/print-number.md +367 -0
  580. package/docs/recipes/oscar64/raster-bars.md +239 -0
  581. package/docs/recipes/oscar64/raster-profile-bars.md +404 -0
  582. package/docs/recipes/oscar64/rel-side-sectors.md +391 -0
  583. package/docs/recipes/oscar64/relative-file-records.md +378 -0
  584. package/docs/recipes/oscar64/save-load-seq-file.md +365 -0
  585. package/docs/recipes/oscar64/screenshots/README.md +99 -0
  586. package/docs/recipes/oscar64/screenshots/actor-activation-window-ntsc.png +0 -0
  587. package/docs/recipes/oscar64/screenshots/actor-activation-window.png +0 -0
  588. package/docs/recipes/oscar64/screenshots/adventure-engine-ntsc.png +0 -0
  589. package/docs/recipes/oscar64/screenshots/adventure-engine.png +0 -0
  590. package/docs/recipes/oscar64/screenshots/attract-replay-ntsc.png +0 -0
  591. package/docs/recipes/oscar64/screenshots/attract-replay.png +0 -0
  592. package/docs/recipes/oscar64/screenshots/beat-em-up-lanes-ntsc.png +0 -0
  593. package/docs/recipes/oscar64/screenshots/beat-em-up-lanes.png +0 -0
  594. package/docs/recipes/oscar64/screenshots/bfs-distance-map-ntsc.png +0 -0
  595. package/docs/recipes/oscar64/screenshots/bfs-distance-map.png +0 -0
  596. package/docs/recipes/oscar64/screenshots/bitmap-koala-viewer.png +0 -0
  597. package/docs/recipes/oscar64/screenshots/car-contact-ntsc.png +0 -0
  598. package/docs/recipes/oscar64/screenshots/car-contact.png +0 -0
  599. package/docs/recipes/oscar64/screenshots/cave-scan-ntsc.png +0 -0
  600. package/docs/recipes/oscar64/screenshots/cave-scan.png +0 -0
  601. package/docs/recipes/oscar64/screenshots/char-bullets-ntsc.png +0 -0
  602. package/docs/recipes/oscar64/screenshots/char-bullets.png +0 -0
  603. package/docs/recipes/oscar64/screenshots/charset-animation-ntsc.png +0 -0
  604. package/docs/recipes/oscar64/screenshots/charset-animation.png +0 -0
  605. package/docs/recipes/oscar64/screenshots/charset-parallax-ntsc.png +0 -0
  606. package/docs/recipes/oscar64/screenshots/charset-parallax.png +0 -0
  607. package/docs/recipes/oscar64/screenshots/destructible-terrain-ntsc.png +0 -0
  608. package/docs/recipes/oscar64/screenshots/destructible-terrain.png +0 -0
  609. package/docs/recipes/oscar64/screenshots/difficulty-tables-ntsc.png +0 -0
  610. package/docs/recipes/oscar64/screenshots/difficulty-tables.png +0 -0
  611. package/docs/recipes/oscar64/screenshots/dig-and-guards-ntsc.png +0 -0
  612. package/docs/recipes/oscar64/screenshots/dig-and-guards.png +0 -0
  613. package/docs/recipes/oscar64/screenshots/directory-reader-ntsc.png +0 -0
  614. package/docs/recipes/oscar64/screenshots/directory-reader.png +0 -0
  615. package/docs/recipes/oscar64/screenshots/divide-check-ntsc.png +0 -0
  616. package/docs/recipes/oscar64/screenshots/divide-check.png +0 -0
  617. package/docs/recipes/oscar64/screenshots/double-buffer-nomirror.png +0 -0
  618. package/docs/recipes/oscar64/screenshots/double-buffer-ntsc.png +0 -0
  619. package/docs/recipes/oscar64/screenshots/double-buffer.png +0 -0
  620. package/docs/recipes/oscar64/screenshots/falling-blocks-ntsc.png +0 -0
  621. package/docs/recipes/oscar64/screenshots/falling-blocks.png +0 -0
  622. package/docs/recipes/oscar64/screenshots/fixed-point-jump-ntsc.png +0 -0
  623. package/docs/recipes/oscar64/screenshots/fixed-point-jump-velocity-ntsc.png +0 -0
  624. package/docs/recipes/oscar64/screenshots/fixed-point-jump-velocity.png +0 -0
  625. package/docs/recipes/oscar64/screenshots/fixed-point-jump.png +0 -0
  626. package/docs/recipes/oscar64/screenshots/flip-screen-rooms-ntsc.png +0 -0
  627. package/docs/recipes/oscar64/screenshots/flip-screen-rooms.png +0 -0
  628. package/docs/recipes/oscar64/screenshots/frame-sync-loop-ntsc.png +0 -0
  629. package/docs/recipes/oscar64/screenshots/frame-sync-loop-overrun.png +0 -0
  630. package/docs/recipes/oscar64/screenshots/frame-sync-loop.png +0 -0
  631. package/docs/recipes/oscar64/screenshots/game-tree-search-ntsc.png +0 -0
  632. package/docs/recipes/oscar64/screenshots/game-tree-search.png +0 -0
  633. package/docs/recipes/oscar64/screenshots/ghost-targeting-ntsc.png +0 -0
  634. package/docs/recipes/oscar64/screenshots/ghost-targeting.png +0 -0
  635. package/docs/recipes/oscar64/screenshots/headless-verify-ntsc.png +0 -0
  636. package/docs/recipes/oscar64/screenshots/headless-verify.png +0 -0
  637. package/docs/recipes/oscar64/screenshots/hello-world.png +0 -0
  638. package/docs/recipes/oscar64/screenshots/high-score-persist-ntsc.png +0 -0
  639. package/docs/recipes/oscar64/screenshots/high-score-persist.png +0 -0
  640. package/docs/recipes/oscar64/screenshots/iffl-kernal-skip-ntsc.png +0 -0
  641. package/docs/recipes/oscar64/screenshots/iffl-kernal-skip.png +0 -0
  642. package/docs/recipes/oscar64/screenshots/joystick-input-ntsc.png +0 -0
  643. package/docs/recipes/oscar64/screenshots/joystick-input.png +0 -0
  644. package/docs/recipes/oscar64/screenshots/lane-pursuit-ntsc.png +0 -0
  645. package/docs/recipes/oscar64/screenshots/lane-pursuit.png +0 -0
  646. package/docs/recipes/oscar64/screenshots/level-rle-decoder-ntsc.png +0 -0
  647. package/docs/recipes/oscar64/screenshots/level-rle-decoder.png +0 -0
  648. package/docs/recipes/oscar64/screenshots/lfsr-random-ntsc.png +0 -0
  649. package/docs/recipes/oscar64/screenshots/lfsr-random-seed2.png +0 -0
  650. package/docs/recipes/oscar64/screenshots/lfsr-random.png +0 -0
  651. package/docs/recipes/oscar64/screenshots/load-asset-runtime-ntsc.png +0 -0
  652. package/docs/recipes/oscar64/screenshots/load-asset-runtime.png +0 -0
  653. package/docs/recipes/oscar64/screenshots/memory-layout-ntsc.png +0 -0
  654. package/docs/recipes/oscar64/screenshots/memory-layout.png +0 -0
  655. package/docs/recipes/oscar64/screenshots/mixed-fighters-ntsc.png +0 -0
  656. package/docs/recipes/oscar64/screenshots/mixed-fighters.png +0 -0
  657. package/docs/recipes/oscar64/screenshots/multi-sprite-object-ntsc.png +0 -0
  658. package/docs/recipes/oscar64/screenshots/multi-sprite-object.png +0 -0
  659. package/docs/recipes/oscar64/screenshots/nav-area-pathfinding-ntsc.png +0 -0
  660. package/docs/recipes/oscar64/screenshots/nav-area-pathfinding.png +0 -0
  661. package/docs/recipes/oscar64/screenshots/object-pool-ntsc.png +0 -0
  662. package/docs/recipes/oscar64/screenshots/object-pool.png +0 -0
  663. package/docs/recipes/oscar64/screenshots/pal-ntsc-detect-ntsc.png +0 -0
  664. package/docs/recipes/oscar64/screenshots/pal-ntsc-detect-oldntsc.png +0 -0
  665. package/docs/recipes/oscar64/screenshots/pal-ntsc-detect-pal.png +0 -0
  666. package/docs/recipes/oscar64/screenshots/password-state-ntsc.png +0 -0
  667. package/docs/recipes/oscar64/screenshots/password-state.png +0 -0
  668. package/docs/recipes/oscar64/screenshots/per-frame-hitbox-ntsc.png +0 -0
  669. package/docs/recipes/oscar64/screenshots/per-frame-hitbox.png +0 -0
  670. package/docs/recipes/oscar64/screenshots/petscii-screen-codes-ntsc.png +0 -0
  671. package/docs/recipes/oscar64/screenshots/petscii-screen-codes.png +0 -0
  672. package/docs/recipes/oscar64/screenshots/platformer-scaffold-d64-ntsc.png +0 -0
  673. package/docs/recipes/oscar64/screenshots/platformer-scaffold-d64.png +0 -0
  674. package/docs/recipes/oscar64/screenshots/platformer-scaffold-ntsc.png +0 -0
  675. package/docs/recipes/oscar64/screenshots/platformer-scaffold.png +0 -0
  676. package/docs/recipes/oscar64/screenshots/print-number-ntsc.png +0 -0
  677. package/docs/recipes/oscar64/screenshots/print-number.png +0 -0
  678. package/docs/recipes/oscar64/screenshots/raster-bars.png +0 -0
  679. package/docs/recipes/oscar64/screenshots/raster-profile-bars-ntsc.png +0 -0
  680. package/docs/recipes/oscar64/screenshots/raster-profile-bars.png +0 -0
  681. package/docs/recipes/oscar64/screenshots/rel-side-sectors-ntsc.png +0 -0
  682. package/docs/recipes/oscar64/screenshots/rel-side-sectors.png +0 -0
  683. package/docs/recipes/oscar64/screenshots/relative-file-records-ntsc.png +0 -0
  684. package/docs/recipes/oscar64/screenshots/relative-file-records.png +0 -0
  685. package/docs/recipes/oscar64/screenshots/save-load-seq-file-ntsc.png +0 -0
  686. package/docs/recipes/oscar64/screenshots/save-load-seq-file.png +0 -0
  687. package/docs/recipes/oscar64/screenshots/seeded-level-fill-ntsc.png +0 -0
  688. package/docs/recipes/oscar64/screenshots/seeded-level-fill.png +0 -0
  689. package/docs/recipes/oscar64/screenshots/sfx-engine-ntsc.png +0 -0
  690. package/docs/recipes/oscar64/screenshots/sfx-engine.png +0 -0
  691. package/docs/recipes/oscar64/screenshots/sid-music-player.png +0 -0
  692. package/docs/recipes/oscar64/screenshots/simple-shmup.png +0 -0
  693. package/docs/recipes/oscar64/screenshots/slope-collision-ntsc.png +0 -0
  694. package/docs/recipes/oscar64/screenshots/slope-collision.png +0 -0
  695. package/docs/recipes/oscar64/screenshots/soft-scroll-h.png +0 -0
  696. package/docs/recipes/oscar64/screenshots/sprite-animation-table-ntsc.png +0 -0
  697. package/docs/recipes/oscar64/screenshots/sprite-animation-table.png +0 -0
  698. package/docs/recipes/oscar64/screenshots/sprite-multiplex-8.png +0 -0
  699. package/docs/recipes/oscar64/screenshots/stable-raster-irq.png +0 -0
  700. package/docs/recipes/oscar64/screenshots/text-input-ntsc.png +0 -0
  701. package/docs/recipes/oscar64/screenshots/text-input.png +0 -0
  702. package/docs/recipes/oscar64/screenshots/text-overlay-playfield-gameover.png +0 -0
  703. package/docs/recipes/oscar64/screenshots/text-overlay-playfield-notrail-control.png +0 -0
  704. package/docs/recipes/oscar64/screenshots/text-overlay-playfield-ntsc.png +0 -0
  705. package/docs/recipes/oscar64/screenshots/text-overlay-playfield-ungated-control.png +0 -0
  706. package/docs/recipes/oscar64/screenshots/text-overlay-playfield.png +0 -0
  707. package/docs/recipes/oscar64/screenshots/text-window-menu-ntsc.png +0 -0
  708. package/docs/recipes/oscar64/screenshots/text-window-menu.png +0 -0
  709. package/docs/recipes/oscar64/screenshots/tile-grid-collision-ntsc.png +0 -0
  710. package/docs/recipes/oscar64/screenshots/tile-grid-collision.png +0 -0
  711. package/docs/recipes/oscar64/screenshots/tile-map-render-ntsc.png +0 -0
  712. package/docs/recipes/oscar64/screenshots/tile-map-render.png +0 -0
  713. package/docs/recipes/oscar64/screenshots/two-player-ntsc.png +0 -0
  714. package/docs/recipes/oscar64/screenshots/two-player.png +0 -0
  715. package/docs/recipes/oscar64/screenshots/two-word-parser-ntsc.png +0 -0
  716. package/docs/recipes/oscar64/screenshots/two-word-parser.png +0 -0
  717. package/docs/recipes/oscar64/screenshots/vehicle-control-ntsc.png +0 -0
  718. package/docs/recipes/oscar64/screenshots/vehicle-control.png +0 -0
  719. package/docs/recipes/oscar64/screenshots/wave-director-ntsc.png +0 -0
  720. package/docs/recipes/oscar64/screenshots/wave-director.png +0 -0
  721. package/docs/recipes/oscar64/seeded-level-fill.md +364 -0
  722. package/docs/recipes/oscar64/sfx-engine.md +514 -0
  723. package/docs/recipes/oscar64/sid-music-player.md +441 -0
  724. package/docs/recipes/oscar64/simple-shmup.md +1000 -0
  725. package/docs/recipes/oscar64/slope-collision.md +610 -0
  726. package/docs/recipes/oscar64/soft-scroll-h.md +261 -0
  727. package/docs/recipes/oscar64/sprite-animation-table.md +671 -0
  728. package/docs/recipes/oscar64/sprite-multiplex-8.md +314 -0
  729. package/docs/recipes/oscar64/stable-raster-irq.md +236 -0
  730. package/docs/recipes/oscar64/text-input.md +274 -0
  731. package/docs/recipes/oscar64/text-overlay-playfield.md +617 -0
  732. package/docs/recipes/oscar64/text-window-menu.md +551 -0
  733. package/docs/recipes/oscar64/tile-grid-collision.md +563 -0
  734. package/docs/recipes/oscar64/tile-map-render.md +395 -0
  735. package/docs/recipes/oscar64/two-player.md +528 -0
  736. package/docs/recipes/oscar64/two-word-parser.md +510 -0
  737. package/docs/recipes/oscar64/vehicle-control.md +771 -0
  738. package/docs/recipes/oscar64/wave-director.md +787 -0
  739. package/docs/recipes/runs.json +1606 -0
  740. package/docs/runtime/sim6502-reference.md +466 -0
  741. package/docs/runtime/vice-mcp-reference.md +351 -0
  742. package/docs/runtime/vice-reference.md +1393 -0
  743. package/docs/techniques/bitmap-modes.md +685 -0
  744. package/docs/techniques/cpu-cycle-tricks.md +1570 -0
  745. package/docs/techniques/effects-vector-3d.md +1431 -0
  746. package/docs/techniques/file-io.md +1427 -0
  747. package/docs/techniques/input.md +1072 -0
  748. package/docs/techniques/loaders-packers.md +768 -0
  749. package/docs/techniques/logic.md +3091 -0
  750. package/docs/techniques/maths.md +1524 -0
  751. package/docs/techniques/memory-banking.md +1686 -0
  752. package/docs/techniques/music-sid.md +1144 -0
  753. package/docs/techniques/raster.md +1543 -0
  754. package/docs/techniques/scroll.md +1292 -0
  755. package/docs/techniques/sprite.md +2566 -0
  756. package/docs/techniques/text-mode-render.md +717 -0
  757. package/docs/techniques/text.md +1095 -0
  758. package/docs/techniques/transitions.md +405 -0
  759. package/docs/toolchains/cartconv-reference.md +262 -0
  760. package/docs/toolchains/cc1541-reference.md +316 -0
  761. package/docs/toolchains/cc65-reference.md +667 -0
  762. package/docs/toolchains/error-sources/cc65/README.md +1 -0
  763. package/docs/toolchains/error-sources/cc65/missing-setcpu.s +4 -0
  764. package/docs/toolchains/error-sources/cc65/range-error.s +4 -0
  765. package/docs/toolchains/error-sources/cc65/segment-overflow.c +6 -0
  766. package/docs/toolchains/error-sources/cc65/unresolved-external.c +6 -0
  767. package/docs/toolchains/error-sources/kickassembler/README.md +1 -0
  768. package/docs/toolchains/error-sources/kickassembler/branch-out-of-range.asm +4 -0
  769. package/docs/toolchains/error-sources/kickassembler/failed-assert.asm +3 -0
  770. package/docs/toolchains/error-sources/kickassembler/flat-lib.asm +4 -0
  771. package/docs/toolchains/error-sources/kickassembler/import-source-no-namespace.asm +5 -0
  772. package/docs/toolchains/error-sources/kickassembler/macro-without-parentheses.asm +6 -0
  773. package/docs/toolchains/error-sources/kickassembler/memory-block-overlap.asm +4 -0
  774. package/docs/toolchains/error-sources/kickassembler/symbol-clash-lib.asm +5 -0
  775. package/docs/toolchains/error-sources/kickassembler/symbol-clash-main.asm +6 -0
  776. package/docs/toolchains/error-sources/kickassembler/unknown-symbol.asm +4 -0
  777. package/docs/toolchains/error-sources/oscar64/README.md +1 -0
  778. package/docs/toolchains/error-sources/oscar64/asm-addressing-mode.c +7 -0
  779. package/docs/toolchains/error-sources/oscar64/region-overflow.c +6 -0
  780. package/docs/toolchains/error-sources/oscar64/undefined-extern-var.c +5 -0
  781. package/docs/toolchains/error-sources/oscar64/undefined-extern.c +6 -0
  782. package/docs/toolchains/error-sources/oscar64/unknown-vic-field.c +6 -0
  783. package/docs/toolchains/error-sources/oscar64/void-main.c +3 -0
  784. package/docs/toolchains/kickassembler-reference.md +1020 -0
  785. package/docs/toolchains/memory-layout-planning.md +362 -0
  786. package/docs/toolchains/oscar64-headers-reference.md +583 -0
  787. package/docs/toolchains/oscar64-reference.md +892 -0
  788. package/docs/toolchains/petcat-reference.md +290 -0
  789. package/docs/toolchains/png2prg.md +188 -0
  790. package/docs/toolchains/release-disk.md +314 -0
  791. package/docs/toolchains/sidreloc.md +236 -0
  792. package/docs/toolchains/spindle-reference.md +487 -0
  793. package/docs/toolchains/tape-mastering.md +592 -0
  794. package/docs/toolchains/unit-testing-6502.md +281 -0
  795. package/docs/workflow/agent-harness.md +478 -0
  796. package/package.json +105 -0
  797. package/templates/_harness/CLAUDE.md.template +91 -0
  798. package/templates/_harness/PLAN.md.template +72 -0
  799. package/templates/_harness/check.py +442 -0
  800. package/templates/_harness/claude/settings.json +17 -0
  801. package/templates/_harness/gen-asm-header.py +96 -0
  802. package/templates/_harness/harness.mk +273 -0
  803. package/templates/_harness/hooks/plan-gate.py +185 -0
  804. package/templates/_harness/meter/frame_meter.asm +311 -0
  805. package/templates/_harness/meter/frame_meter.c +155 -0
  806. package/templates/_harness/meter/frame_meter.h +80 -0
  807. package/templates/_harness/zp-used.py +104 -0
  808. package/templates/action-puzzle/.claude/settings.json +17 -0
  809. package/templates/action-puzzle/.mcp.json +10 -0
  810. package/templates/action-puzzle/CLAUDE.md +120 -0
  811. package/templates/action-puzzle/Makefile +125 -0
  812. package/templates/action-puzzle/PLAN.md +388 -0
  813. package/templates/action-puzzle/README.md +240 -0
  814. package/templates/action-puzzle/expect.json +25 -0
  815. package/templates/action-puzzle/src/cave.c +280 -0
  816. package/templates/action-puzzle/src/cave.h +80 -0
  817. package/templates/action-puzzle/src/gen_autopilot.h +20 -0
  818. package/templates/action-puzzle/src/gen_caves.h +59 -0
  819. package/templates/action-puzzle/src/gen_notes.h +16 -0
  820. package/templates/action-puzzle/src/hiscore.c +152 -0
  821. package/templates/action-puzzle/src/hiscore.h +41 -0
  822. package/templates/action-puzzle/src/level.c +64 -0
  823. package/templates/action-puzzle/src/level.h +24 -0
  824. package/templates/action-puzzle/src/main.c +599 -0
  825. package/templates/action-puzzle/src/render.c +239 -0
  826. package/templates/action-puzzle/src/render.h +31 -0
  827. package/templates/action-puzzle/src/sound.c +158 -0
  828. package/templates/action-puzzle/src/sound.h +22 -0
  829. package/templates/action-puzzle/tools/disk_check.py +77 -0
  830. package/templates/action-puzzle/tools/drive.py +106 -0
  831. package/templates/action-puzzle/tools/gen.py +454 -0
  832. package/templates/action-puzzle/tools/model_check.py +49 -0
  833. package/templates/action-puzzle/tools/verdict_codes.py +24 -0
  834. package/templates/adventure/.claude/settings.json +17 -0
  835. package/templates/adventure/.mcp.json +10 -0
  836. package/templates/adventure/CLAUDE.md +118 -0
  837. package/templates/adventure/Makefile +113 -0
  838. package/templates/adventure/PLAN.md +396 -0
  839. package/templates/adventure/README.md +277 -0
  840. package/templates/adventure/expect.json +25 -0
  841. package/templates/adventure/src/engine.c +543 -0
  842. package/templates/adventure/src/engine.h +48 -0
  843. package/templates/adventure/src/gen_script.h +141 -0
  844. package/templates/adventure/src/gen_world.h +511 -0
  845. package/templates/adventure/src/main.c +439 -0
  846. package/templates/adventure/src/picture.c +83 -0
  847. package/templates/adventure/src/picture.h +16 -0
  848. package/templates/adventure/src/save.c +159 -0
  849. package/templates/adventure/src/save.h +25 -0
  850. package/templates/adventure/src/sound.c +71 -0
  851. package/templates/adventure/src/sound.h +16 -0
  852. package/templates/adventure/src/text.c +349 -0
  853. package/templates/adventure/src/text.h +40 -0
  854. package/templates/adventure/tools/disk_check.py +128 -0
  855. package/templates/adventure/tools/drive.py +119 -0
  856. package/templates/adventure/tools/gen.py +1033 -0
  857. package/templates/adventure/tools/world.py +356 -0
  858. package/templates/beat-em-up/.claude/settings.json +17 -0
  859. package/templates/beat-em-up/.mcp.json +10 -0
  860. package/templates/beat-em-up/CLAUDE.md +136 -0
  861. package/templates/beat-em-up/Makefile +96 -0
  862. package/templates/beat-em-up/PLAN.md +502 -0
  863. package/templates/beat-em-up/README.md +315 -0
  864. package/templates/beat-em-up/expect-gameover.json +8 -0
  865. package/templates/beat-em-up/expect.json +29 -0
  866. package/templates/beat-em-up/src/anim.c +70 -0
  867. package/templates/beat-em-up/src/art.c +344 -0
  868. package/templates/beat-em-up/src/autopilot.h +154 -0
  869. package/templates/beat-em-up/src/brute.c +273 -0
  870. package/templates/beat-em-up/src/enemy.c +281 -0
  871. package/templates/beat-em-up/src/engine.asm +512 -0
  872. package/templates/beat-em-up/src/fighter.c +384 -0
  873. package/templates/beat-em-up/src/game.h +269 -0
  874. package/templates/beat-em-up/src/hud.c +135 -0
  875. package/templates/beat-em-up/src/main.c +341 -0
  876. package/templates/beat-em-up/src/sound.c +44 -0
  877. package/templates/beat-em-up/src/street.c +93 -0
  878. package/templates/beat-em-up/src/verdict.h +523 -0
  879. package/templates/beat-em-up/src/view.c +362 -0
  880. package/templates/beat-em-up/tools/drive.py +105 -0
  881. package/templates/beat-em-up/tools/flickercheck.py +273 -0
  882. package/templates/demo/.claude/settings.json +17 -0
  883. package/templates/demo/.mcp.json +10 -0
  884. package/templates/demo/CLAUDE.md +129 -0
  885. package/templates/demo/Makefile +66 -0
  886. package/templates/demo/PLAN.md +401 -0
  887. package/templates/demo/README.md +322 -0
  888. package/templates/demo/expect.json +945 -0
  889. package/templates/demo/src/config.asm +80 -0
  890. package/templates/demo/src/framework.asm +390 -0
  891. package/templates/demo/src/main.asm +139 -0
  892. package/templates/demo/src/music.asm +197 -0
  893. package/templates/demo/src/part_main.asm +279 -0
  894. package/templates/demo/src/part_title.asm +79 -0
  895. package/templates/demo/src/parts.asm +43 -0
  896. package/templates/demo/src/tables.asm +73 -0
  897. package/templates/demo/src/verdict.asm +179 -0
  898. package/templates/demo/tools/audio.py +80 -0
  899. package/templates/demo/tools/gen_expect.py +167 -0
  900. package/templates/demo/tools/probe.py +95 -0
  901. package/templates/hello/.claude/settings.json +17 -0
  902. package/templates/hello/.mcp.json +10 -0
  903. package/templates/hello/CLAUDE.md +100 -0
  904. package/templates/hello/Makefile +38 -0
  905. package/templates/hello/PLAN.md +200 -0
  906. package/templates/hello/expect.json +20 -0
  907. package/templates/hello/src/main.c +161 -0
  908. package/templates/hello/src/sprite.asm +27 -0
  909. package/templates/hello-kick/.claude/settings.json +17 -0
  910. package/templates/hello-kick/.mcp.json +10 -0
  911. package/templates/hello-kick/CLAUDE.md +100 -0
  912. package/templates/hello-kick/Makefile +17 -0
  913. package/templates/hello-kick/PLAN.md +199 -0
  914. package/templates/hello-kick/expect.json +20 -0
  915. package/templates/hello-kick/src/main.asm +233 -0
  916. package/templates/platformer/.claude/settings.json +17 -0
  917. package/templates/platformer/.mcp.json +10 -0
  918. package/templates/platformer/CLAUDE.md +125 -0
  919. package/templates/platformer/Makefile +86 -0
  920. package/templates/platformer/PLAN.md +360 -0
  921. package/templates/platformer/README.md +277 -0
  922. package/templates/platformer/expect.json +32 -0
  923. package/templates/platformer/src/actors.c +289 -0
  924. package/templates/platformer/src/anim.c +51 -0
  925. package/templates/platformer/src/art.c +212 -0
  926. package/templates/platformer/src/autopilot.h +30 -0
  927. package/templates/platformer/src/engine.asm +253 -0
  928. package/templates/platformer/src/game.h +248 -0
  929. package/templates/platformer/src/hud.c +90 -0
  930. package/templates/platformer/src/level.c +184 -0
  931. package/templates/platformer/src/main.c +306 -0
  932. package/templates/platformer/src/player.c +268 -0
  933. package/templates/platformer/src/sound.c +42 -0
  934. package/templates/platformer/src/verdict.h +206 -0
  935. package/templates/platformer/src/view.c +331 -0
  936. package/templates/platformer/stage-expect.json +6 -0
  937. package/templates/platformer/tools/drive.py +112 -0
  938. package/templates/platformer/tools/tearcheck.py +229 -0
  939. package/templates/shmup-vertical/.claude/settings.json +17 -0
  940. package/templates/shmup-vertical/.mcp.json +10 -0
  941. package/templates/shmup-vertical/CLAUDE.md +137 -0
  942. package/templates/shmup-vertical/Makefile +131 -0
  943. package/templates/shmup-vertical/PLAN.md +569 -0
  944. package/templates/shmup-vertical/README.md +189 -0
  945. package/templates/shmup-vertical/expect.json +38 -0
  946. package/templates/shmup-vertical/src/bullets.c +158 -0
  947. package/templates/shmup-vertical/src/bullets.h +35 -0
  948. package/templates/shmup-vertical/src/display.c +239 -0
  949. package/templates/shmup-vertical/src/display.h +40 -0
  950. package/templates/shmup-vertical/src/game.h +85 -0
  951. package/templates/shmup-vertical/src/glyph.asm +358 -0
  952. package/templates/shmup-vertical/src/hiscore.c +141 -0
  953. package/templates/shmup-vertical/src/hiscore.h +16 -0
  954. package/templates/shmup-vertical/src/hit.asm +180 -0
  955. package/templates/shmup-vertical/src/hitbox.c +59 -0
  956. package/templates/shmup-vertical/src/hitbox.h +25 -0
  957. package/templates/shmup-vertical/src/kernel.asm +330 -0
  958. package/templates/shmup-vertical/src/level.c +174 -0
  959. package/templates/shmup-vertical/src/level.h +27 -0
  960. package/templates/shmup-vertical/src/main.c +824 -0
  961. package/templates/shmup-vertical/src/mux.asm +321 -0
  962. package/templates/shmup-vertical/src/sound.asm +255 -0
  963. package/templates/shmup-vertical/src/step.asm +169 -0
  964. package/templates/shmup-vertical/src/waves.c +195 -0
  965. package/templates/shmup-vertical/src/waves.h +33 -0
  966. package/templates/shmup-vertical/stage-expect.json +6 -0
  967. package/templates/shmup-vertical/tools/drive.py +152 -0
  968. package/templates/shmup-vertical/tools/joytest.py +159 -0
  969. package/templates/shmup-vertical/tools/meter.py +15 -0
  970. package/templates/shmup-vertical/tools/phases.py +73 -0
@@ -0,0 +1,693 @@
1
+ <!-- doc-type: failure-reference -->
2
+
3
+ # C64 Failure Patterns
4
+
5
+ Symptom-keyed catalog of common C64 failure modes. Each entry is a
6
+ CrashPattern node. Likely-causes tags are free-form searchable strings;
7
+ graph edges are emitted by the `Caused by …` lines.
8
+
9
+ ---
10
+
11
+ ## black_screen — Display goes solid color or stays $00
12
+
13
+ **Likely causes:** vic_bank_misconfigured, screen_pointer_outside_bank, d011_blanked
14
+ **Diagnosis steps:** Read $D011 and check bit 4 (BLANK); read $D018 and verify the screen-RAM pointer nibble points to RAM inside the active VIC bank; read $DD00 bits 0-1 to confirm which 16 KB bank the VIC is addressing; confirm the CPU data bus reaches VIC-II by reading $D012 (raster counter should not be stuck at $FF).
15
+ **Caused by registers:** D011, D018, DD00
16
+ **Caused by techniques:** vic_bank_select
17
+
18
+ The display is completely dark — either a single solid color (usually
19
+ black border plus black background) or a frame that never shows any
20
+ characters or bitmap data. The machine is not frozen; it is actively
21
+ drawing nothing.
22
+
23
+ The most common root cause is a VIC bank mismatch introduced by
24
+ incorrectly writing $DD00 (CIA2 Port A). The VIC-II fetches screen RAM,
25
+ charset or bitmap data, and sprite bitmaps from a 16 KB window selected
26
+ by bits 0–1 of $DD00. Four banks are available (bank 0 at $0000,
27
+ bank 1 at $4000, bank 2 at $8000, bank 3 at $C000). If the bank is
28
+ switched without also updating $D018 to point screen RAM and
29
+ character/bitmap data inside the new bank, the VIC reads from the wrong
30
+ addresses — usually all-zero ROM or garbage — and draws a blank field.
31
+ A second cause is leaving bit 4 of $D011 (DEN, Display Enable) clear;
32
+ the chip blanks the display entirely when this bit is 0. A third cause
33
+ is a $D018 video-matrix pointer that falls outside the active bank
34
+ because the offset nibble was set before the bank was switched.
35
+
36
+ **Diagnosis steps:**
37
+ 1. Via vice-mcp, read memory at $D011. If bit 4 is 0 the screen is
38
+ intentionally blanked — set it to re-enable.
39
+ 2. Read $DD00 bits 0–1. Bank = 3 − (bits 0–1). Verify this matches
40
+ where your screen RAM and charset/bitmap data live.
41
+ 3. Read $D018. High nibble = screen-RAM offset (×$0400 within bank).
42
+ Low nibble = charset pointer (×$0800) or bitmap pointer ($08 = bitmap
43
+ at bank base, $18 = bitmap at bank_base+$2000). Confirm the resolved
44
+ addresses fall inside the bank.
45
+ 4. Attempt to write a known character code to screen RAM and read it
46
+ back. If the read returns the written value, the RAM is visible but
47
+ the VIC is looking elsewhere.
48
+
49
+ Correct the VIC bank by writing the right 2-bit value to $DD00 (keep
50
+ bits 2–7 unchanged). Then update $D018 so both the screen pointer and
51
+ the charset/bitmap pointer resolve to addresses inside that 16 KB window.
52
+ Set $DD00 first, then $D018, and keep screen RAM at the canonical offset
53
+ ($0400 within bank 0, i.e., $D018 = $14 in default mode). If code sets
54
+ the BLANK bit as part of a display-off effect, ensure the re-enable
55
+ write cannot be skipped by an IRQ handler that returns early.
56
+
57
+ ---
58
+
59
+ ## garbled_bitmap — Bitmap mode shows random characters or noise
60
+
61
+ **Likely causes:** bitmap_mode_not_set, charset_pointer_wrong, screen_ram_collision
62
+ **Diagnosis steps:** Read $D011 bit 5 (BMM) — must be 1 for bitmap mode; read $D016 bit 4 (MCM) for multicolor; check $D018 low nibble: bit 3 must be set (bitmap at +$2000 relative to VIC bank base) or clear (bitmap at bank base); verify screen RAM in $D018 high nibble is inside the same VIC bank as the bitmap.
63
+ **Caused by registers:** D011, D016, D018
64
+
65
+ The display shows a chaotic pattern of random character glyphs or
66
+ high-frequency color noise instead of the intended image. Bitmap mode
67
+ was selected but the content looks like character-mode garbage.
68
+
69
+ Three distinct configurations must align for bitmap mode to work: $D011
70
+ bit 5 (BMM) must be set; $D018 bit 3 selects whether the bitmap data
71
+ lives at the VIC bank base or at +$2000 within the bank; and $D018 high
72
+ nibble places screen RAM (which holds the foreground/background color
73
+ for each 8×8 cell) at the correct offset. A common mistake is leaving
74
+ $D018 in its power-on value of $14, which places screen RAM at $0400
75
+ and the charset pointer at $1000 — fine for character mode but
76
+ incorrect for bitmap if the bitmap data was loaded to $2000. Another
77
+ mistake is copying a koala or hires image to the right address but
78
+ forgetting to set BMM, so the VIC still reads character pointers. A
79
+ collision between screen RAM and bitmap data (when both are assigned to
80
+ overlapping ranges inside a bank) causes half the visible area to show
81
+ the wrong colors or scrambled shapes.
82
+
83
+ **Diagnosis steps:**
84
+ 1. Read $D011. Bit 5 must be 1. If it is 0, the chip is in character
85
+ mode despite the image data being loaded.
86
+ 2. Read $D018. For a hires bitmap at $2000 in bank 0: screen RAM at
87
+ $0400 → high nibble = $1, bitmap → low nibble = $8; combined $18.
88
+ For a koala at $2000 with screen RAM at $0400: $D018 = $18, plus
89
+ $D016 bit 4 = 1 for multicolor.
90
+ 3. Confirm the VIC bank (via $DD00) encompasses both the bitmap and
91
+ screen RAM addresses.
92
+ 4. Use vice-mcp to read 8 bytes from the resolved bitmap base address
93
+ and verify they match the first row of pixel data from the image.
94
+
95
+ Set $D011 bit 5 to enable bitmap mode and bit 4 to enable the display.
96
+ For hires, $D016 bit 4 = 0; for multicolor bitmap (Koala) it = 1.
97
+ Load the 8000-byte bitmap to the address the $D018 low nibble selects,
98
+ and the 1000-byte screen RAM to the address the high nibble selects.
99
+ The two ranges must not overlap within the VIC bank.
100
+
101
+ ---
102
+
103
+ ## sprite_flicker_random — Sprites flicker randomly across the frame
104
+
105
+ **Likely causes:** dma_timing_violation, sprite_register_write_during_active
106
+ **Diagnosis steps:** Read $D015 (sprite enable); count enabled sprites; use vice-mcp raster breakpoint to pause mid-frame and inspect $D000-$D00E; check whether sprite register writes occur inside VIC DMA windows (cycles 58-61 on each sprite-active scanline); look for writes to $D015 that toggle bits during visible raster.
107
+ **Caused by registers:** D015, D000
108
+ **Caused by techniques:** sprite_multiplex_8
109
+
110
+ Sprites blink on and off in an apparently random pattern — appearing
111
+ correct on some frames and vanishing or shifting position on others.
112
+ The effect is not consistent across runs, which points to a race between
113
+ CPU writes and VIC DMA reads.
114
+
115
+ The VIC-II reads sprite data from 64-byte blocks in the VIC bank during
116
+ specific DMA windows — typically cycles 58–61 per sprite per active
117
+ scanline. If the CPU writes sprite X/Y position or enable-bit registers
118
+ during one of those windows, the VIC may see a torn value: the high
119
+ byte of a new position combined with the low byte of the old, or a
120
+ sprite-enable bit that transitions mid-DMA. The result is a sprite that
121
+ appears one pixel-row too high or low on one frame, or one that
122
+ disappears entirely when the enable bit clears at exactly the wrong
123
+ moment. Random patterns emerge because the relative phase between CPU
124
+ and VIC shifts each frame unless the raster IRQ is stabilised.
125
+
126
+ **Diagnosis steps:**
127
+ 1. Set a vice-mcp raster breakpoint at the first sprite-active line and
128
+ dump $D000-$D017 to verify they match intended values.
129
+ 2. Instrument your sprite-update routine to log the value of $D012
130
+ (raster line) at the moment of each write. Writes occurring in
131
+ the DMA window of an active sprite are unsafe.
132
+ 3. Enable VICE's raster-beam display and single-step through the
133
+ sprite-update loop to identify which write collides with DMA.
134
+ 4. Check whether $D015 is written inside the visible frame with bits
135
+ that affect currently-active sprites.
136
+
137
+ Move all sprite register writes to the vertical blank region or to
138
+ raster lines immediately above the sprite's Y position, before VIC
139
+ DMA begins for that sprite. In a multiplexer, split the sorting phase
140
+ (during visible frame) from the register-commit phase (at or near VBI).
141
+ If $D015 must be toggled mid-frame, do so at a stable raster position
142
+ with interrupts disabled for the critical write window.
143
+
144
+ ---
145
+
146
+ ## sprite_flicker_periodic — Sprites flicker on every N-th frame
147
+
148
+ **Likely causes:** sprite_multiplex_miscount, raster_irq_overrun
149
+ **Diagnosis steps:** Measure IRQ handler execution time in cycles via vice-mcp; check if the IRQ handler takes more cycles than the gap between the raster line it fires on and the next VIC DMA window for the topmost sprite; verify the sprite-sort routine does not run over its budget on frames with many active sprites.
150
+ **Caused by registers:** D012
151
+ **Caused by techniques:** stable_raster_irq, sprite_multiplex_8
152
+
153
+ Sprites are correct on most frames but flicker predictably on every
154
+ second, fourth, or Nth frame. Unlike random flicker, the period is
155
+ consistent, which points to a cyclic resource overrun rather than a
156
+ timing race.
157
+
158
+ The most common cause is a sprite multiplexer whose sort-and-commit
159
+ phase runs past the raster position where VIC DMA begins for the top
160
+ sprite. On light frames (few sprites) the handler finishes in time; on
161
+ heavy frames (eight or more logical sprites, complex sorting network)
162
+ it overruns by a handful of cycles, and the VIC begins DMA before the
163
+ CPU finishes writing the new Y positions. Because the overrun happens
164
+ only when the sort list reaches a certain length, the period of the
165
+ flicker matches the period of the heaviest frame in the animation. A
166
+ secondary cause is a raster IRQ that fires too late — either because
167
+ the D012 target line was miscounted or because a badline stole the
168
+ extra cycles that a tight timing routine relied on.
169
+
170
+ **Diagnosis steps:**
171
+ 1. Add a cycle counter (read $DC04/$DC05 CIA1 timer) at entry and exit
172
+ of your IRQ handler. Log the delta over 60 frames and look for
173
+ frames where the count spikes above your budget.
174
+ 2. Set a vice-mcp breakpoint at the known flicker line and inspect
175
+ $D012 to confirm the raster IRQ is actually firing on the intended
176
+ line.
177
+ 3. Count the number of active sprites on each frame class and compare
178
+ against the sprite-sort worst-case cycle estimate.
179
+ 4. Introduce a temporary `STA $D020` probe at the IRQ exit to see a
180
+ visible color stripe when the handler is still running as sprites
181
+ become active.
182
+
183
+ Reduce the sort routine's worst case: use counting sort instead of
184
+ bubble sort; cap the active sprite count at eight (hardware limit);
185
+ or split the sort across two frames with a double-buffered sprite
186
+ table. If the raster IRQ fires late due to badlines, advance the
187
+ trigger line by the number of stolen cycles.
188
+
189
+ ---
190
+
191
+ ## sprite_disappears — Sprite vanishes when crossing a screen position
192
+
193
+ **Likely causes:** sprite_x_high_bit_lost, sprite_y_off_screen
194
+ **Diagnosis steps:** Read $D010 (MSB of X for all sprites); when sprite X crosses 255→256 the corresponding bit in $D010 must flip from 0 to 1 or the sprite jumps back to the left edge; inspect $D001/$D003/… Y registers — values 0-7 and 248-255 place the sprite partially or fully off-screen.
195
+ **Caused by registers:** D010, D000
196
+
197
+ A sprite that tracks a moving game object or scroll position suddenly
198
+ becomes invisible at a specific horizontal or vertical position, then
199
+ reappears after passing through a narrow dead zone.
200
+
201
+ Sprite X is a 9-bit value: the low 8 bits live in $D000/$D002/… and
202
+ the 9th (MSB) lives as a single bit in $D010 for each of the eight
203
+ sprites. Software that stores sprite X as a single byte and writes only
204
+ the low register will leave the MSB stale. When the sprite crosses
205
+ X=255 the displayed position wraps to 0 instead of advancing to 256,
206
+ making the sprite appear to teleport to the left edge and immediately
207
+ leave the visible area. For Y, values 255 (and 0–7) place the sprite
208
+ above or on the top border; values above 230 (approximately, depending
209
+ on PAL/NTSC) push it below the visible area. A sprite at Y=255 is never
210
+ drawn — it simply disappears.
211
+
212
+ **Diagnosis steps:**
213
+ 1. In vice-mcp, set a watch on the sprite's X register ($D000 + 2×N)
214
+ and $D010 bit N. Step through the movement code and confirm that
215
+ when X_low rolls over from 255 to 0, the corresponding $D010 bit
216
+ also toggles.
217
+ 2. Read the sprite's Y register. Values near 0 or 255 on PAL place the
218
+ sprite in the border/blanking region.
219
+ 3. On NTSC, the visible Y window is different (41–300 raster lines;
220
+ sprite Y range 0–249 active). Confirm the Y value is valid for the
221
+ target region.
222
+ 4. Check whether the sprite's priority bit ($D01B) is set, which causes
223
+ it to appear behind the background bitmap, making it effectively
224
+ invisible on non-$D021 pixels.
225
+
226
+ Store sprite X as a 16-bit value internally. Derive the low byte as
227
+ `x & 0xFF` and the MSB contribution as `(x >> 8) & 1`. Before writing
228
+ to hardware, compute the new $D010 value: clear the bit for this sprite,
229
+ then OR in the MSB. A common idiom is to build the full $D010 byte from
230
+ all eight sprite MSBs each frame in the commit phase. For Y, clamp the
231
+ stored position to 230 on PAL or use the off-screen sentinel $FF only
232
+ when intentionally hiding a sprite via the enable bit ($D015) instead.
233
+
234
+ ---
235
+
236
+ ## screen_jumps_y_axis — Display jumps vertically each frame
237
+
238
+ **Likely causes:** raster_irq_late, badline_overrun
239
+ **Diagnosis steps:** Check $D012 IRQ trigger line vs actual raster position at handler entry using CIA1 timer delta; count cycles consumed in the IRQ handler path; verify $D011 bits 0-2 (Y scroll) are not being written on different lines each frame; use vice-mcp raster breakpoint to compare actual vs expected raster position at scroll register write.
240
+ **Caused by registers:** D011, D012
241
+
242
+ The entire display shakes or jerks vertically — typically by one or
243
+ two pixel rows — once per frame. The jitter is usually consistent in
244
+ magnitude but may vary by one raster line between frames.
245
+
246
+ The root cause is nearly always a scroll-register write ($D011 bits
247
+ 2–0, Y-scroll) that arrives at a different raster line on different
248
+ frames. The VIC-II displays a character row eight lines tall; writing Y-
249
+ scroll mid-row shifts which pixel row the VIC outputs, causing the
250
+ display to jump. If the raster IRQ that performs this write fires late
251
+ on some frames (due to a badline, an NMI, or a variable-length preceding
252
+ handler), the write reaches the chip one raster line later and the
253
+ visible pixel shift differs by one scanline. Over multiple frames this
254
+ produces a flickering, unstable image. Badlines steal 40 CPU cycles;
255
+ if the IRQ fires on or just before a badline, the handler's timing
256
+ budget is silently consumed and the critical write is delayed.
257
+
258
+ **Diagnosis steps:**
259
+ 1. Read the CIA1 timer ($DC04) at the first instruction of the IRQ
260
+ handler and again just before the $D011 scroll write. If the delta
261
+ varies by more than one or two cycles between frames, the IRQ is
262
+ not arriving at a stable raster position.
263
+ 2. Use vice-mcp to set a raster breakpoint at the intended trigger line
264
+ and confirm it fires before any badline between trigger and write.
265
+ 3. Instrument the code: temporarily write a distinctive value to $D020
266
+ (border color) immediately at IRQ entry and at the scroll write to
267
+ produce a color stripe. Measure its position on a frame grabber or
268
+ VICE's raster display — if it wobbles, the IRQ is unstable.
269
+ 4. Count cycles between IRQ trigger and D011 write and verify the line
270
+ falls in a non-badline region.
271
+
272
+ Use the stable double-IRQ technique to eliminate jitter: fire the first
273
+ IRQ above the target line, set D012 to the exact target line and exit;
274
+ the second IRQ writes the scroll register with cycle precision. If
275
+ badlines are unavoidable between the IRQ and the write, advance the
276
+ trigger line by the number of stolen cycles and verify with a CIA1
277
+ timer delta measurement.
278
+
279
+ ---
280
+
281
+ ## hang_no_irq — Program freezes with no IRQ activity
282
+
283
+ **Likely causes:** sei_never_cleared, irq_vector_corrupt, stack_overflow_in_irq
284
+ **Diagnosis steps:** Attach vice-mcp and read the CPU status register P — if bit 2 (I flag) is set, interrupts are globally masked; read $0314-$0315 (IRQ vector) and confirm they point to a valid handler; read the stack pointer and top-of-stack bytes to detect overflow; read $D01A (VIC IRQ enable) and $DC0D (CIA1 ICR) to confirm interrupt sources are enabled.
285
+ **Caused by kernal:** CHKIN, CHKOUT
286
+
287
+ The program halts — it neither crashes to BASIC nor responds to any
288
+ input. The border color does not change, no music plays, and no raster
289
+ effects occur. The STOP key may or may not respond depending on whether
290
+ KERNAL interrupt handling is still active.
291
+
292
+ Three distinct failure modes produce this symptom. First: `SEI` was
293
+ executed to protect a critical section and the matching `CLI` never
294
+ ran, leaving interrupts permanently masked — timers, raster IRQs, and
295
+ keyboard scans all silently fail. Second: the IRQ vector at $0314–$0315
296
+ was overwritten with a corrupt address; the CPU vectors there on the
297
+ next interrupt, executes garbage, and loops or crashes. Third: a
298
+ runaway IRQ handler overflows the 6510's hardware stack (page $01,
299
+ $0100–$01FF). Each IRQ entry pushes 3 bytes (PC + P); a handler that
300
+ never returns or a cascade of nested IRQs fills the stack, wraps to
301
+ $01FF, and corrupts CPU state.
302
+
303
+ **Diagnosis steps:**
304
+ 1. Attach vice-mcp, halt execution, and read the CPU P register. If
305
+ bit 2 is set, interrupts are masked; look for the last `SEI` in
306
+ the instruction stream.
307
+ 2. Read $0314 (low byte) and $0315 (high byte) of the IRQ vector. Jump
308
+ to that address in the disassembler and confirm it contains a
309
+ plausible handler sequence ending in `RTI`.
310
+ 3. Read the CPU stack pointer (S register) and inspect $0100 + S
311
+ through $01FF. If S is close to $00 the stack is near overflow.
312
+ 4. Read $D01A bit 0 (VIC raster IRQ enable) and $DC0D bits 0-1
313
+ (CIA1 timer A/B IRQ enable) to confirm at least one interrupt
314
+ source is enabled.
315
+
316
+ Ensure every `SEI` is paired with a `CLI` before any blocking loop or
317
+ `RTS`. Never call KERNAL routines like `CHKIN` or `CHKOUT` with
318
+ interrupts disabled — they loop on IEC bus signals and will deadlock.
319
+ Write the IRQ vector as an atomic pair with interrupts disabled. For
320
+ stack overflow, reduce handler nesting depth and prevent IRQ re-entry.
321
+
322
+ ---
323
+
324
+ ## wrong_music_tempo — Music plays too fast or too slow
325
+
326
+ **Likely causes:** pal_ntsc_tempo_mismatch, cia_timer_misconfigured
327
+ **Diagnosis steps:** Read $DC04/$DC05 (CIA1 Timer A low/high bytes) — on PAL the canonical frame timer value is $4CC7; on NTSC it is $42C6; detect region by reading $D012 after writing known $D011 values or by measuring frame length; check $DC0E bit 0 (timer A running) and bit 3 (one-shot vs continuous).
328
+ **Caused by registers:** D012
329
+ **Caused by techniques:** sid_play_routine_pattern, sid_voice_setup
330
+
331
+ Music is audibly off-tempo — notes hold too long or too short, and the
332
+ overall BPM differs from the intended tempo by approximately 4% or by
333
+ a small fixed ratio. All three SID voices are affected equally.
334
+
335
+ The universal cause is a CIA timer value hard-coded for PAL running on
336
+ an NTSC machine (or vice versa). CIA1 Timer A drives most SID players:
337
+ a PAL timer value of $4CC7 (19,655 cycles) on an NTSC machine fires
338
+ every 19.2 ms instead of 20.1 ms — 3.8% too fast. SID players that
339
+ use the VIC raster IRQ for timing are equally affected: PAL produces
340
+ 50 frames/sec, NTSC ~60 frames/sec — a 20% difference that makes
341
+ music dramatically wrong on the wrong region.
342
+
343
+ **Diagnosis steps:**
344
+ 1. Read $DC04/$DC05 at program startup before the player init runs.
345
+ Compare against $4CC7 (PAL) or $42C6 (NTSC) to determine what the
346
+ timer was set to.
347
+ 2. Detect the running region: read $D011 with $1B, then poll $D012 and
348
+ time how many CIA1 timer ticks elapse between values $F8 and $00
349
+ (the raster wrap). PAL counts ~19656 cycles; NTSC ~17095.
350
+ 3. Confirm $DC0E bit 0 is 1 (timer running) and bit 3 is 0 (continuous
351
+ mode). One-shot mode causes the timer to stop after the first tick.
352
+ 4. Check whether the player uses the raster IRQ path vs the CIA timer
353
+ path, as the fix differs.
354
+
355
+ For a player that uses CIA1 Timer A, read the region at startup (or
356
+ accept it as a config byte) and set the timer low/high bytes
357
+ accordingly: PAL → `LDA #$C7 / STA $DC04 / LDA #$4C / STA $DC05`;
358
+ NTSC → `LDA #$C6 / STA $DC04 / LDA #$42 / STA $DC05`. For raster-
359
+ driven players, maintain two separate tempo tables and index them by
360
+ the detected region, or time all notes in absolute CPU cycles rather
361
+ than frame counts.
362
+
363
+ ---
364
+
365
+ ## music_silence — SID writes occur but no sound is produced
366
+
367
+ **Likely causes:** master_volume_zero, voice_gate_never_set, filter_routing_wrong
368
+ **Diagnosis steps:** Read $D418 low nibble — must be nonzero (typically $F for max volume); read $D404/$D40B/$D412 bit 0 (GATE) — gate must be asserted to start the ADSR envelope; read $D415-$D417 filter routing; confirm the SID chip is responding by writing $D418 = $0F and listening for a faint click on the audio output.
369
+ **Caused by registers:** D418, D404, D412
370
+ **Caused by techniques:** sid_voice_setup
371
+
372
+ All three SID voices are programmed with frequencies, waveforms, and
373
+ envelope settings, yet the audio output is completely silent. No pops,
374
+ no tones, nothing. The SID registers read back the values that were
375
+ written.
376
+
377
+ Four independent gates can silence the SID simultaneously. The most
378
+ common is $D418 low nibble = $00: the master volume DAC is at zero
379
+ and the analog output is muted regardless of what the three voices are
380
+ doing. The second is a GATE bit (bit 0 of $D404, $D40B, or $D412)
381
+ that was never set to 1 — the ADSR envelope stays at zero (attack
382
+ never starts) and the voice produces no output. The third is filter
383
+ misconfiguration: if all three voices are routed through the filter
384
+ ($D417 bits 0–2 all set) and $D418 selects only high-pass output on a
385
+ signal that has no high-frequency content, the result is silence. The
386
+ fourth possibility is a volume-register write that was intended to kick-
387
+ start a digi sample but left volume stuck at zero.
388
+
389
+ **Diagnosis steps:**
390
+ 1. Read $D418. Low nibble must be nonzero. Write $0F and check for
391
+ sound; if silence persists, suspect a hardware or wiring issue.
392
+ 2. Read $D404 (voice 1 control), $D40B (voice 2), $D412 (voice 3).
393
+ Bit 0 = GATE. It must be 1 for any note to start.
394
+ 3. Read $D405-$D406 (voice 1 ADSR). Attack nibble = $00 → instant
395
+ attack. If decay/sustain are also zero the note will start and
396
+ release immediately; increase sustain.
397
+ 4. Read $D415-$D417. If bits 0–2 of $D417 are all set (all voices
398
+ through filter) and $D418 bits 4–6 select only LP/HP/BP in an
399
+ unusual combination, bypass the filter for debugging by clearing
400
+ $D417 bits 0–2.
401
+
402
+ Set $D418 to $0F (master volume maximum). For each voice: set
403
+ frequency ($D400/$D401 etc.), set waveform and GATE bit in the
404
+ control register ($D404 = $11 for triangle+gate, for example), then
405
+ set ADSR to reasonable values ($D405 = $09 for medium attack/decay).
406
+ If using the filter, verify that at least one filter output mode is
407
+ selected in $D418 bits 4–6 and that the cutoff ($D415–$D416) is not
408
+ fully closed ($0000 on a 6581 can attenuate heavily).
409
+
410
+ ---
411
+
412
+ ## sid_pop_click — Audible click between notes
413
+
414
+ **Likely causes:** hard_restart_missing, gate_release_timing
415
+ **Diagnosis steps:** Check whether a hard restart (write $00 then $08 to control register with $0F waveform to flush the accumulator) is performed before each new note; measure time between gate-off and next gate-on — minimum ~2 ms (PAL ~2000 cycles) needed for envelope to reach zero; inspect $D404/$D40B/$D412 for transition from gate=1 to gate=0 without intermediate $08 pulse.
416
+ **Caused by registers:** D404
417
+ **Caused by techniques:** sid_play_routine_pattern
418
+
419
+ A sharp click or pop is audible at the boundary between two notes, or
420
+ at the moment a gate is asserted on a new note when the previous
421
+ envelope has not fully released.
422
+
423
+ The SID ADSR hardware has a well-documented bug: the envelope counter
424
+ is a 15-bit accumulator, and if the rate register is updated to a
425
+ value whose compare threshold the counter has already passed, the
426
+ counter must wrap the full 15-bit range (up to 32,768 cycles, roughly
427
+ 33 ms at PAL) before the new rate takes effect. When a new note's gate
428
+ is asserted before the previous release has completed, the residual
429
+ envelope level is non-zero and the new attack begins from that elevated
430
+ level, producing an audible step transient — the click. Additionally,
431
+ if the oscillator phase accumulator is not reset between notes, the new
432
+ tone starts from a random phase offset that can produce a click at the
433
+ note onset even when the envelope is clean.
434
+
435
+ **Diagnosis steps:**
436
+ 1. In vice-mcp, set a write watchpoint on $D404 (voice 1 control).
437
+ Step through the note-change sequence and verify the sequence is:
438
+ gate-off ($D404 &= ~$01) → wait release → $08 pulse → new note.
439
+ 2. Read $D41C (ENV3) if the failing voice is voice 3 — this shows the
440
+ live envelope value. A non-zero value at gate-on confirms the
441
+ release was incomplete.
442
+ 3. Count CPU cycles between gate-off and gate-on. For typical release
443
+ values the envelope needs at least 1000–6000 cycles to reach zero.
444
+ 4. Check whether the waveform bits change simultaneously with the gate
445
+ assertion (writing both waveform and gate in one byte is fine; the
446
+ issue is changing waveform to $00 which AND-mixes to zero and can
447
+ cause a transient).
448
+
449
+ Perform a hard restart before every note: gate-off with TEST bit set
450
+ (resets phase accumulator), then gate-on with TEST clear. For voice 1:
451
+ write `waveform | $08` to $D404 (gate off, test on), then write
452
+ `waveform | $01` (test off, gate on). Allow at least 2 ms (~2000 PAL
453
+ cycles) between gate-off and gate-on for the release envelope to reach
454
+ zero before the attack begins.
455
+
456
+ ---
457
+
458
+ ## scroll_jitter — Scroll moves unevenly or stutters
459
+
460
+ **Likely causes:** d016_write_late, raster_irq_late_unstable, badline_overrun
461
+ **Diagnosis steps:** Read $D016 bits 0-2 (X scroll) at the raster line where the scroll write should occur; use vice-mcp raster breakpoint to verify the write arrives before the VIC fetches the first visible character column; confirm the IRQ handler cycle count is deterministic; check whether a badline falls between IRQ trigger and scroll write.
462
+ **Caused by registers:** D016
463
+ **Caused by techniques:** soft_scroll_h, stable_raster_irq
464
+
465
+ The horizontal scroll is supposed to move at a fixed rate but the
466
+ display occasionally stutters by one pixel column, or the text appears
467
+ to vibrate back and forth by one pixel. On frames that exhibit the
468
+ jitter, the scroll position is off by exactly one step.
469
+
470
+ Horizontal smooth scrolling is controlled by bits 2–0 of $D016
471
+ (X-scroll, 0–7 pixels). The VIC reads this register at the start of
472
+ each visible character row. If the CPU writes the new X-scroll value
473
+ after the VIC has already latched it for the current row, the update
474
+ takes effect one raster line late — the first row of characters scrolls
475
+ by the old value while the remaining rows use the new value. On the
476
+ next frame the timing may be correct, producing alternating one-off and
477
+ on-target positions: the jitter. Badlines exacerbate this because they
478
+ steal 40 cycles just as the CPU needs to be writing the scroll register,
479
+ pushing the write past the VIC's sample point.
480
+
481
+ **Diagnosis steps:**
482
+ 1. Place a vice-mcp raster breakpoint on the line immediately above the
483
+ first visible character row. Confirm the scroll write happens within
484
+ the first few cycles of that line, well before cycle 16 where VIC
485
+ begins character fetch.
486
+ 2. Use a CIA1 timer delta measurement at IRQ entry and at the scroll
487
+ write to confirm the handler has a fixed cycle cost. Any variation
488
+ of more than 2 cycles is enough to cause jitter.
489
+ 3. Temporarily replace the IRQ-driven scroll write with a per-frame
490
+ spin-wait on $D012 to isolate whether the jitter is an IRQ timing
491
+ issue or a display mode issue.
492
+ 4. Check whether a badline (raster line where $D011 bits 2–0 equal the
493
+ low three bits of the raster counter) falls between IRQ trigger and
494
+ the scroll write.
495
+
496
+ Use the stable double-IRQ pattern: fire the first IRQ several lines
497
+ above the target, set D012 to the exact write line, and write $D016
498
+ in the second IRQ with cycle precision. Adjust the D016 write to
499
+ occur during the horizontal blank portion of the target raster line
500
+ (before cycle 16 on a PAL VIC-II) to guarantee the VIC samples the
501
+ new value for all visible rows. If a badline is unavoidable, add a
502
+ compensation of 40 cycles to the stable-IRQ entry wait loop.
503
+
504
+ ---
505
+
506
+ ## multicolor_wrong_color — Multicolor bitmap or sprite shows wrong palette
507
+
508
+ **Likely causes:** d020_d021_swapped, sprite_multicolor_bits_wrong
509
+ **Diagnosis steps:** For multicolor bitmap: verify $D020 (border), $D021 (background color 0), $D022 (background color 1), $D023 (background color 2), and screen-RAM high nibble (foreground) are set correctly; for multicolor sprites: read $D025 (sprite multicolor 0) and $D026 (sprite multicolor 1) and confirm $D01C bit for the sprite is set.
510
+ **Caused by registers:** D020, D021, D025, D026
511
+ **Caused by techniques:** multicolor_bitmap
512
+
513
+ Colors appear correct in terms of shape (the image is recognizable) but
514
+ the palette is shifted — what should be the background color appears
515
+ where the foreground color should be, or sprite shared colors are
516
+ swapped, or two of the four color values appear to be exchanged.
517
+
518
+ Multicolor character and bitmap modes use a fixed mapping between 2-bit
519
+ pixel values and color sources. In multicolor bitmap mode (Koala format)
520
+ the pixel-value-to-color mapping is: `%00` = $D021 (background
521
+ register), `%01` = screen RAM high nibble, `%10` = screen RAM low
522
+ nibble, `%11` = color RAM. A common mistake is writing the two screen-
523
+ RAM nybbles in reversed order (high nibble = foreground, low nibble =
524
+ background, but the values are swapped in memory). For multicolor
525
+ sprites, `%00` = transparent, `%01` = $D025 (shared color 0), `%10` =
526
+ the sprite's own color ($D027–$D02E), `%11` = $D026 (shared color 1).
527
+ Setting $D01C bit N enables multicolor for sprite N; forgetting to set
528
+ it leaves the sprite in hires mode where the 2-bit pixel values are
529
+ interpreted differently, shifting the palette.
530
+
531
+ **Diagnosis steps:**
532
+ 1. For a bitmap image: compare the intended Koala color layout with
533
+ the values at $D021, screen RAM high/low nybbles at the relevant
534
+ cell, and color RAM at $D800 + cell offset.
535
+ 2. For sprites: read $D01C. The bit for the affected sprite must be 1.
536
+ Read $D025 and $D026 and compare against the sprite's intended
537
+ shared colors.
538
+ 3. Convert the on-screen color index to decimal and look up the C64
539
+ color value table — the most common mistake is confusing the color
540
+ index (0–15) with a register address.
541
+ 4. Use vice-mcp to read a single cell's screen RAM word and color RAM
542
+ byte and trace which color value maps to which pixel pattern.
543
+
544
+ For Koala bitmaps: pack the screen RAM byte as `(color_1 << 4) | color_2`
545
+ where color_1 is the `%01` value and color_2 is the `%10` value. Use
546
+ a consistent reference (C64Wiki color chart) for the 4-bit color
547
+ indices 0–15. For multicolor sprites, ensure $D01C has the correct bit
548
+ set before the sprite appears, and load $D025/$D026 before enabling
549
+ sprites ($D015). Double-check sprite color registers: sprite 0's own
550
+ color is $D027, sprite 1's is $D028, etc. — these are separate from
551
+ $D025/$D026 which are shared across all multicolor sprites.
552
+
553
+ ---
554
+
555
+ ## dim_colors_on_8580 — Output is visibly dimmer on 8580 than on 6581
556
+
557
+ **Likely causes:** filter_chip_variation, voice_3_silent_bit_difference
558
+ **Diagnosis steps:** Read $D418 — on the 8580, bit 7 (voice 3 mute) works differently; the 8580 filter cutoff curve is linear vs 6581's sigmoidal, so verify $D415-$D416 cutoff values produce the intended open-filter response; check whether SID digi playback uses volume-register writes calibrated for the 6581's non-linear DAC response.
559
+ **Caused by registers:** D418
560
+ **Caused by techniques:** sid_8580_vs_6581_differences
561
+
562
+ Audio output is noticeably quieter on a C64C or late-model machine
563
+ (which uses the 8580 SID) than on an earlier machine (6581). The tones
564
+ are recognizable but the overall level is lower and some filter effects
565
+ sound different. On high-filter-cutoff settings the signal may
566
+ disappear entirely on the 8580.
567
+
568
+ The 6581 and 8580 differ in three measurable ways. First, the filter
569
+ cutoff curve: on the 6581 it is highly non-linear and varies between
570
+ chips; a cutoff value that opens the filter wide on one 6581 may have
571
+ almost no effect on another. The 8580 has a linear curve. A code path
572
+ tuned for 6581 filter behavior will produce a different tonal character
573
+ on the 8580. Second, the 8580 DAC for digi playback ($D418 used as a
574
+ PWM DAC) has a different step size than the 6581, making samples sound
575
+ clipped or too quiet. Third, the 8580's combined-waveform output
576
+ levels differ from the 6581's — timbres that work on one may be muted
577
+ on the other.
578
+
579
+ **Diagnosis steps:**
580
+ 1. Confirm the target SID revision: read the environment configuration
581
+ or detect heuristically by exploiting a filter-response difference
582
+ (write $D415/$D416 = $00/$00 and check audio — on 6581 this fully
583
+ closes the filter; on 8580 the cutoff minimum is different).
584
+ 2. Read $D415-$D416 and compute the cutoff frequency. If the value was
585
+ tuned for the 6581's non-linear curve, recalibrate for the 8580's
586
+ linear response.
587
+ 3. Check $D418 bit 7. On the 8580, voice 3 is not truly muted by this
588
+ bit in the same way; routing behavior differs. Verify that voice 3
589
+ is not unexpectedly contributing to or stealing from the mix.
590
+ 4. If digi playback is used, test the volume-register write range: on
591
+ the 6581 the effective range for PWM digi is ~$00–$0F with a
592
+ roughly usable midpoint around $08; on the 8580 the step size is
593
+ lower and the effective range may require different scaling.
594
+
595
+ Maintain per-chip filter-cutoff tuning tables and detect the chip at
596
+ runtime using the filter-response heuristic. For music that must sound
597
+ identical on both chips, avoid filter-heavy patches and rely on pure
598
+ waveforms (sawtooth, pulse, triangle). For digi playback, ship separate
599
+ sample scaling factors for each chip variant.
600
+
601
+ ---
602
+
603
+ ## intermittent_load_crash — Load works most of the time but crashes occasionally
604
+
605
+ **Likely causes:** fastloader_kernal_dependency, gcr_timing_drift
606
+ **Diagnosis steps:** Confirm the fastloader protocol is exiting via the KERNAL UNLISTEN/UNTALK path before returning to user code; check whether the crash occurs only at specific disk sectors (suggesting a GCR timing edge case); test with the KERNAL fastloader disabled (switch to $37 memory map) to isolate whether the crash is in the custom loader or the KERNAL I/O path; count crashes per 100 loads as a timing-sensitivity metric.
607
+ **Caused by kernal:** LOAD
608
+ **Caused by techniques:** krill_loader_integration, sparkle_irq_loader
609
+
610
+ The program loads correctly on 9 out of 10 attempts but occasionally
611
+ hangs mid-load, crashes to BASIC, or corrupts a small region of the
612
+ loaded data. The failure is not reproducible at a specific sector,
613
+ suggesting a timing-sensitive race rather than a data error.
614
+
615
+ The C64's IEC bus is software-timed: both the drive and the C64
616
+ measure bit timing in CPU cycles rather than via a hardware UART. Any
617
+ deviation in CPU availability — an NMI, a raster IRQ, or a badline —
618
+ can corrupt a bit. Fastloaders that push the bus to 3× or 4× KERNAL
619
+ speed have very narrow windows; an interrupt firing on a critical
620
+ bit edge drops the bit. GCR decoding adds further sensitivity: off-
621
+ spec drive timing from head wear can miss a sync mark and begin
622
+ decoding at the wrong byte boundary, producing exactly the sporadic
623
+ corruption observed.
624
+
625
+ **Diagnosis steps:**
626
+ 1. Disable all IRQs during the load phase (`SEI` before entering the
627
+ loader, `CLI` after) and retest. If crashes stop, an IRQ is
628
+ interfering with the timing loop.
629
+ 2. Log the C64-side byte count at crash time across 20 runs. Consistent
630
+ crash positions (within ±2 bytes) point to a specific sector or
631
+ block boundary; random positions point to an IRQ interference.
632
+ 3. Switch from the fastloader to the KERNAL LOAD routine ($FFD5) and
633
+ retest. If stability improves, the custom loader has a timing margin
634
+ issue.
635
+ 4. On a real disk setup, try a known-good diskette and compare crash
636
+ rates — GCR drift is drive-specific.
637
+
638
+ Disable the KERNAL's CIA1 interrupt by reading $DC0D (ICR acknowledge)
639
+ before entering the time-critical receive loop, and re-enable it on
640
+ exit. Widen timing windows where the protocol allows — most fastloaders
641
+ have a configurable bit-cell width. If crashes correlate with a sector
642
+ boundary, add a retry at sector level. For Krill or Sparkle (IRQs
643
+ enabled during load), verify the installed IRQ handler never calls any
644
+ KERNAL I/O routine.
645
+
646
+ ---
647
+
648
+ ## garbled_only_in_irq — Code works at top level but corrupts data inside IRQ
649
+
650
+ **Likely causes:** decimal_mode_in_irq_handler, register_not_saved
651
+ **Diagnosis steps:** Check whether the mainline code uses BCD (SED instruction); inspect the IRQ handler prologue for PHA/TXA/PHA/TYA/PHA and corresponding epilogue; look for JSR to a subroutine inside the IRQ that modifies zero-page variables shared with mainline; confirm the IRQ returns via RTI not RTS.
652
+ **Caused by techniques:** decimal_mode_pitfalls
653
+
654
+ Code that runs correctly in the main loop produces wrong results or
655
+ corrupts variables when invoked from inside an IRQ handler. The bug is
656
+ not present when interrupts are disabled, and disabling interrupts
657
+ temporarily at the point of failure makes it disappear.
658
+
659
+ Two distinct mechanisms produce this symptom. The more subtle is
660
+ decimal mode: the 6510 does not automatically clear the decimal flag (D
661
+ bit of P) on IRQ entry, unlike the 65C02. If the main program uses BCD
662
+ arithmetic (`SED` / `CLD`) and an IRQ fires while the D flag is set,
663
+ all arithmetic inside the handler operates in BCD — `ADC` and `SBC`
664
+ produce Binary Coded Decimal results rather than binary results. A
665
+ handler that adds a frame counter or adjusts a position variable will
666
+ silently produce wrong values on every frame after the first `SED` in
667
+ the main loop. The second mechanism is register contamination: a
668
+ handler that modifies A, X, Y, or zero-page variables without saving
669
+ and restoring them returns to the main loop with a corrupted CPU state.
670
+ Code that looks correct in isolation fails only when the handler fires
671
+ at a sensitive moment in the main loop.
672
+
673
+ **Diagnosis steps:**
674
+ 1. At the very start of the IRQ handler, read the CPU P register via
675
+ vice-mcp and check bit 3 (D flag). If it is set when the IRQ fires,
676
+ the main program left decimal mode active.
677
+ 2. Step through the IRQ handler prologue and confirm the sequence
678
+ `PHA / TXA / PHA / TYA / PHA` (save A, X, Y) appears before any
679
+ register modification.
680
+ 3. Check all JSR targets called from inside the handler for zero-page
681
+ side effects — any write to a ZP location that the mainline reads
682
+ is a potential corruption point.
683
+ 4. Verify the handler ends with `PLA / TAY / PLA / TAX / PLA / RTI` in
684
+ that exact order, and that it is `RTI` (not `RTS` which does not
685
+ restore P).
686
+
687
+ Add `CLD` as the first instruction of every IRQ handler before any
688
+ arithmetic — one cycle eliminates the entire decimal-mode class. Save
689
+ and restore all used registers in the prologue/epilogue. Subroutines
690
+ called from inside the handler must also preserve all registers they
691
+ use. For zero-page variables shared between main and IRQ, write to a
692
+ shadow copy inside the handler and swap buffers from the main loop at
693
+ a known-safe point.