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,583 @@
1
+ ---
2
+ tool: oscar64-headers
3
+ tool_kind: c-library
4
+ maintainer: drmortalwombat
5
+ license: GPL-3.0
6
+ home_url: https://github.com/drmortalwombat/oscar64/tree/main/include/c64
7
+ ---
8
+
9
+ <!-- doc-type: toolchain-reference -->
10
+
11
+ # Oscar64 Headers Reference
12
+
13
+ ## Tool
14
+
15
+ The `include/c64/` directory in the Oscar64 source tree contains a suite of C headers that give Oscar64 programs structured, type-safe access to C64 hardware and operating-system services. Each header declares structs that map directly to the hardware register layout, named constants for all bit flags and enumerations, and helper functions that encapsulate common sequences. Every header with an implementation file uses a `#pragma compile("filename.c")` directive to automatically pull in its implementation (`types.h` and `easyflash.h` are header-only; an earlier version of this page said every header carries the pragma). Including the header is sufficient to link the library, with no separate link step — but a header does not re-export the `vic.h`/`rasterirq.h` names its own API uses, so a fence that calls `vic_waitLine()` or `rirq_wait()` still needs those headers included (see the fences below).
16
+
17
+ This document is the per-header API reference. For broader context on when to reach for these headers, see [oscar64-reference.md](oscar64-reference.md). The rule of thumb: whenever an Oscar64 recipe needs to touch a hardware register, there is almost certainly a header that makes it cleaner, safer, and more portable between PAL and NTSC builds than direct POKE/PEEK patterns.
18
+
19
+ ## types.h — Fundamental C64 type aliases
20
+
21
+ Every other C64 header includes `types.h`. It defines four type aliases that appear throughout Oscar64 C64 code:
22
+
23
+ - `byte` — `unsigned char` (8-bit, used for all hardware register accesses)
24
+ - `word` — `unsigned int` (16-bit)
25
+ - `dword` — `unsigned long` (32-bit)
26
+ - `sbyte` — `signed char` (8-bit signed)
27
+
28
+ Using `byte` instead of `unsigned char` throughout hardware-access code makes intent clear and avoids accidental signed-extension bugs on values read from registers.
29
+
30
+ ```c
31
+ #include <c64/types.h>
32
+
33
+ byte color = 0x0E; // light blue
34
+ word address = 0xD400; // SID base address
35
+ ```
36
+
37
+ ## vic.h — VIC-II chip access
38
+
39
+ `vic.h` provides the `VIC` struct that maps directly to the VIC-II register file at `$D000`. The macro `vic` dereferences a pointer to that address, so `vic.color_border` is a volatile byte write to `$D020`. The header also declares the `VICColors` enum (sixteen named palette entries from `VCOL_BLACK` to `VCOL_LT_GREY`), bit-flag constants for `ctrl1`, `ctrl2`, and `intr_enable`/`intr_ctrl`, and a `VicMode` enum for `vic_setmode`.
40
+
41
+ Public functions and macros:
42
+
43
+ - `vic` — macro reference to the VIC-II struct at `$D000`
44
+ - `VICColors` — enum: `VCOL_BLACK`, `VCOL_WHITE`, ..., `VCOL_LT_GREY`
45
+ - `vic_setbank(char bank)` — selects one of four 16 KB VIC banks (0–3)
46
+ - `vic_setmode(VicMode mode, const char * text, const char * font)` — sets display mode and base addresses
47
+ - `vic_sprxy(byte s, int x, int y)` — moves sprite `s` to `(x, y)`, handles the MSB X bit
48
+ - `vic_sprgetx(byte s)` — reads the full 9-bit X position of sprite `s`
49
+ - `vic_waitBottom()` / `vic_waitTop()` — waits for raster beam to reach bottom/top of frame
50
+ - `vic_waitFrame()` — waits for top then bottom (one full frame)
51
+ - `vic_isBottom()` — returns true if beam is below the visible area
52
+ - `vic_waitFrames(char n)` — busy-waits `n` full frames
53
+ - `vic_waitLine(int line)` — busy-waits until beam reaches a specific raster line
54
+ - `vic_waitBelow(int line)` / `vic_waitRange(char below, char above)` — positional raster waits
55
+
56
+ ```c
57
+ #include <c64/vic.h>
58
+
59
+ vic.color_border = VCOL_BLACK;
60
+ vic.color_back = VCOL_BLACK;
61
+ vic_waitFrame(); // sync to vertical blank
62
+ ```
63
+
64
+ ### The raster waits, line by line
65
+
66
+ The one-line summaries above are the header's own comments (`vic.h` lines
67
+ 106 to 128, comments and declarations; the declarations themselves are
68
+ lines 107 to 128). What each routine actually waits for is in `vic.c` (Oscar64
69
+ build 2026-05-19; line numbers are that file's, read here). All of them
70
+ poll; none installs an interrupt or touches `$D019`. "RST8" is bit 7 of
71
+ `$D011` (`VIC_CTRL1_RST8`, `vic.h` line 10), the ninth bit of the raster
72
+ counter, set for raster lines 256 and up on every VIC-II.
73
+
74
+ - `vic_isBottom()` (`vic.c` 56 to 59): returns true if RST8 is set, that is,
75
+ if the beam is on line 256 or later. No wait.
76
+ - `vic_waitBottom()` (62 to 66): spins while RST8 is clear. Returns on line
77
+ 256 if the beam was above it, and at once if it was already at or past
78
+ 256. The header's "bottom of the visual area" means line 256, six lines
79
+ below the 25-row display window's last line, 250.
80
+ - `vic_waitTop()` (68 to 72): spins while RST8 is set. Returns on line 0 if
81
+ the beam was in the RST8 band, and at once if it was anywhere in lines 0
82
+ to 255. "Top of the frame" means line 0.
83
+ - `vic_waitFrame()` (74 to 80): `vic_waitTop()` then `vic_waitBottom()` in
84
+ one function: spins until RST8 is clear, then until it is set. Always
85
+ returns on line 256 of a frame that had not yet reached 256 when the call
86
+ was made, so consecutive calls are exactly one frame apart. It is not
87
+ "one full frame" from an arbitrary call, as the bullet above says: called
88
+ from line 100 it returns 156 lines later. `vic_waitBottom()` alone does
89
+ not give this guarantee: called twice inside the band it returns twice in
90
+ the same frame, and the band is only 7 lines on the 6567R8 (256 to 262;
91
+ settled frame length, arithmetic).
92
+ - `vic_waitFrames(char n)` (82 to 89): `vic_waitFrame()` `n` times. With
93
+ `n == 0` it returns immediately.
94
+ - `vic_waitLine(int line)` (91 to 101; compiled native by the `#pragma` on
95
+ line 140): splits the target into a low byte and bit 8 shifted into the
96
+ RST8 position, spins until `$D012` equals the low byte, then checks RST8
97
+ against the target's bit 8 and goes round again if they differ. So it
98
+ distinguishes line 20 from line 276. It is an equality wait: if the
99
+ target line passes while something else holds the CPU for longer than a
100
+ line, it waits for the next frame, and a line the chip does not have (312
101
+ and up on PAL, 263 and up on the 6567R8) never returns.
102
+ - `vic_waitBelow(int line)` (103 to 121): waits until the beam is past the
103
+ line. For a target below 256 it spins while `$D012 <= low byte` and
104
+ returns as soon as the raster reads greater, so it cannot miss the line,
105
+ only end late. It compares the low byte alone and never reads RST8 in
106
+ this case, so a call made from inside the RST8 band with a target below
107
+ the band's low-byte range (below 56 on PAL, below 7 on the 6567R8) returns
108
+ inside the band: target 20, called on PAL line 260, returns on line 277,
109
+ whose low byte 21 is the first greater than 20, not on line 21 of the
110
+ next frame (arithmetic from the source, not run here). A target of 100
111
+ from the same place behaves: the band's low bytes are all at most 55, the
112
+ spin continues through line 0, and it returns on line 101. For a target
113
+ of 256 or more it spins on the low byte and then requires RST8 to be set,
114
+ repeating if it is not.
115
+ - `vic_waitRange(char below, char above)` (123 to 138): both arguments are
116
+ low bytes, so the range is within lines 0 to 255. It first spins while
117
+ RST8 is set (gets out of the band), then, if `$D012` is already at or
118
+ past `above`, waits through the next band (RST8 set, then clear) to reach
119
+ the following frame, and finally spins while `$D012 < below`. It returns
120
+ with the beam at or after `below` and, on entry, before `above`. The
121
+ header's comment says "in a given range on screen"; the order of the
122
+ arguments is `(below, above)`, lower line first.
123
+
124
+ For a loop that must run once a frame, `vic_waitFrame()` is the one to call
125
+ from the wait-only form; `techniques/raster.md` `frame_sync_loop` covers it,
126
+ with the interrupt-driven form and its dropped-frame counter, and
127
+ `recipes/oscar64/frame-sync-loop.md` measures both the fitting and the
128
+ overrunning case.
129
+
130
+ ## sid.h — SID sound chip access
131
+
132
+ `sid.h` maps the SID chip at `$D400` to a `SID` struct with three nested `Voice` structs. It provides named constants for all attack, decay, sustain, release, waveform control, and filter mode bits, plus frequency calculation macros for PAL and NTSC clock rates.
133
+
134
+ Public functions and macros:
135
+
136
+ - `sid` — macro reference to the SID struct at `$D400`
137
+ - `NOTE_C(octave)` through `NOTE_B(octave)` — the note's frequency in **Hz**, not a SID register value: `NOTE_A(o)` is `28160U >> (10 - o)`, so `NOTE_A(4)` = 440 (header-read; measured in VICE). Pass the result through `SID_FREQ_PAL()` / `SID_FREQ_NTSC()` before writing it to `freq`; written raw on PAL, 440 plays 440 × 985248 / 2^24 ≈ 25.8 Hz. The values are integer-truncated (`NOTE_C(4)` = 261, not 261.63) and the octave argument must be 0..10 (the macro shifts right by 10 − octave). An earlier version of this page called them PAL-precomputed register values.
138
+ - `SID_FREQ_PAL(hz)` / `SID_FREQ_NTSC(hz)` — convert Hz to frequency register value for the respective clock
139
+ - `SID_CLOCK_PAL` (985248), `SID_CLOCK_NTSC` (1022727) — clock constants in Hz
140
+ - `SID_CTRL_*` constants — `GATE`, `SYNC`, `RING`, `TEST`, `TRI`, `SAW`, `RECT`, `NOISE`
141
+ - `SID_ATK_*` / `SID_DKY_*` constants — named attack/decay times in milliseconds
142
+ - `SID_FILTER_*` / `SID_FMODE_*` constants — filter routing and mode bits
143
+
144
+ ```c
145
+ #include <c64/sid.h>
146
+
147
+ sid.voices[0].freq = SID_FREQ_PAL(NOTE_A(4)); // 440 Hz, octave 4 -> register 7492
148
+ sid.voices[0].ctrl = SID_CTRL_SAW | SID_CTRL_GATE;
149
+ sid.voices[0].attdec = SID_ATK_8 | SID_DKY_24;
150
+ sid.voices[0].susrel = 0xA0;
151
+ ```
152
+
153
+ ## cia.h — CIA timer and I/O chip access
154
+
155
+ `cia.h` maps CIA1 at `$DC00` and CIA2 at `$DD00` to `CIA` structs. CIA1 handles the keyboard matrix and joystick port 2; CIA2 handles the serial port, user port, and VIC bank select. The most common use of this header from Oscar64 code is `cia_init()`, which stops CIA timers and clears pending interrupts so that raster IRQs can take over cleanly.
156
+
157
+ Public API:
158
+
159
+ - `cia1` — macro reference to CIA1 struct at `$DC00`
160
+ - `cia2` — macro reference to CIA2 struct at `$DD00`
161
+ - `CIA` struct fields — `pra`, `prb` (port data), `ddra`, `ddrb` (direction), `ta`/`tb` (timers), `todt`/`tods`/`todm`/`todh` (TOD clock), `sdr` (serial shift), `icr` (interrupt control), `cra`/`crb` (control)
162
+ - `ciaa_pra_def` — default value for CIA1 port A (used by `cia_init`)
163
+ - `cia_init()` — disables CIA timer interrupts; required before using `rasterirq.h`
164
+
165
+ ```c
166
+ #include <c64/cia.h>
167
+ #include <c64/memmap.h>
168
+
169
+ mmap_set(MMAP_NO_ROM); // disable kernal
170
+ cia_init(); // kill CIA IRQs; raster IRQs take over
171
+ ```
172
+
173
+ ## rasterirq.h — Raster interrupt system
174
+
175
+ `rasterirq.h` is the demo-development backbone. It manages up to 16 simultaneous raster interrupt slots (configurable with `-dNUM_IRQS=n`). Each slot fires at a specified raster line and executes up to five memory writes in hand-optimized assembly. The system handles IRQ vector installation and slot sorting so that slots always fire in scanline order even when moved between frames. It does not disable the CIAs: no `rirq_init_*` variant writes `$DC0D`/`$DD0D` (header-read, `rasterirq.c`), so call `cia_init()` first when using `rirq_init_crt`, `rirq_init_crt_noio`, `rirq_init_io` or `rirq_init_memmap` (the variants whose handler does not fall through to the kernal), otherwise the CIA1 timer IRQ keeps entering a handler that never acknowledges it and the splits break up. The two kernal-routed variants (`rirq_init_kernal`, `rirq_init_kernal_noio`, i.e. `rirq_init(true)`) acknowledge `$DC0D` and continue into `$EA31`, so they run without `cia_init()`. It is also not cycle-exact: each slot busy-polls `CMP $D012`, so its writes land at the start of the line below `row`, inside horizontal blanking with a few cycles of jitter — a clean full-line colour split, but not a base for FLI, side-border or other cycle-exact effects. An earlier version of this page claimed CIA disabling and stable-raster timing.
176
+
177
+ `RIRQCode` is 32 bytes: a `size` byte plus a 31-byte code area (`RIRQ_SIZE`), holding up to five operations (address + data pairs). `RIRQCode10` (62 bytes, 61-byte code area) and `RIRQCode20` (107 bytes, 106-byte code area) hold up to 10 and 20 operations. `sizeof(RIRQCode)` measured in VICE = 32; an earlier version of this page said 31. The `size` byte is the number of operations (0–25; `rirq_build` asserts `size < 26`, larger counts need `RIRQCode10`/`RIRQCode20`). A delay is not a sixth slot: an `RIRQCode` carries either five writes or one delay plus four writes, because `rirq_delay()` re-uses write slot 0 — its data byte becomes the loop count and its STY is overwritten with a DEY/BNE loop (about 5 cycles per count; the header comment's own words). The earlier text described the `size` field as a wait value, a misreading of the header's "size (wait + #ops)" comment.
178
+
179
+ Public API:
180
+
181
+ - `rirq_build(RIRQCode * ic, byte size)` — initialises the code for `size` operations; the implementation accepts 0–25 (`__assume(size < 26)`, and the setters index 26-entry tables) but only as much room as the caller supplied: the RTS lands at code offset 12 for size 1 and 15+5·(size−2) above that, so size 5 ends at byte 30 (fits `RIRQCode`), size 10 at 55 (fits `RIRQCode10`), size 20 at 105 (exactly fills `RIRQCode20`); sizes 21–25 overflow every declared struct and are only safe in a `rirq_alloc()` block (`malloc(1 + 31 + 5*size)`) or a caller's own larger buffer. `size` = 0 builds a bare RTS. An earlier version of this page gave the range as 1–5.
182
+ - `rirq_alloc(byte size)` — heap-allocates an `RIRQCode`
183
+ - `rirq_write(RIRQCode * ic, byte n, void * addr, byte data)` — sets write slot `n` to store `data` at `addr`
184
+ - `rirq_call(RIRQCode * ic, byte n, void * addr)` — sets slot `n` to JSR `addr` (calls a C function from within the IRQ)
185
+ - `rirq_addr(RIRQCode * ic, byte n, void * addr)` — changes the target address of write slot `n` at runtime
186
+ - `rirq_addrhi(RIRQCode * ic, byte n, byte hi)` — changes only the high byte of the address (fast path for moving through memory pages)
187
+ - `rirq_data(RIRQCode * ic, byte n, byte data)` — changes the data byte of write slot `n` at runtime
188
+ - `rirq_delay(RIRQCode * ic, byte cycles)` — converts write slot 0 into a delay of roughly 5 × `cycles` before the remaining writes, for horizontal positioning. Call it after `rirq_build()` (which rebuilds slot 0 as a write) and then only use `rirq_write`/`rirq_data`/`rirq_addr` on slots 1..4 — slot 0's data byte IS the delay count, so `rirq_data(ic, 0, x)` changes the delay. Measured from the emitted bytes in VICE: after `rirq_build(&rc, 2)`, two `rirq_write`, `rirq_delay(&rc, 3)` the code is `A0 03 A2 02 CD 12 D0 B0 FB 88 D0 FD 8E 20 D0 60` with `size` still 2 — write 0 is gone. An earlier version of this page said the delay was added before the first write at no cost to a slot.
189
+ - `rirq_set(byte n, byte row, RIRQCode * write)` — installs `write` into slot `n` to fire one line below `row`
190
+ - `rirq_clear(byte n)` — removes slot `n`
191
+ - `rirq_move(byte n, byte row)` — changes the trigger line of slot `n` without rebuilding the code
192
+ - `rirq_init(bool kernalIRQ)` — `true` = `rirq_init_kernal()` (routes via `$0314`, works with the KERNAL ROM in, chains to the KERNAL handler); `false` = `rirq_init_io()`, which writes only the RAM copy of `$FFFE` and does not change `$01`. With the KERNAL ROM in (the default map) the CPU reads `$FFFE` from ROM and the handler never runs — the header's own wording is "if the kernal ROM is turned off". To use `false`: call `cia_init()` (the RAM-vector ISRs do not test `$D019`, so a live CIA timer IRQ would also enter them and misplace the writes), then `mmap_set(MMAP_NO_ROM)`, then `rirq_init(false)` — the order `sprmux32.c` uses. If the ROM may be in or out, use `rirq_init_crt()` / `rirq_init_crt_noio()`, which write both `$0314` and `$FFFE`. An earlier version of this page described `false` as a drop-in "install hardware vector directly".
193
+ - `rirq_init_kernal()` / `rirq_init_kernal_noio()` — kernal-routed variants
194
+ - `rirq_init_crt()` / `rirq_init_crt_noio()` — cartridge-safe variants
195
+ - `rirq_init_io()` / `rirq_init_memmap()` — RAM vector variants
196
+ - `rirq_start()` — enables the raster IRQ system
197
+ - `rirq_stop()` — a bare `sei` (`rasterirq.c`); it does not clear `$D01A`, so the KERNAL's own `cli` inside serial I/O re-enables the raster IRQ, and measured in VICE a file write with `rirq_stop()` around it behaved the same as one with the IRQ left armed (`recipes/oscar64/high-score-persist.md`). To keep the raster IRQ out of a transfer, clear `$D01A` and acknowledge `$D019`, then restore them
198
+ - `rirq_sort(bool inirq)` — sorts the slots by scanline and builds the dispatch schedule (`rasterIRQNext[]`); call once after the initial `rirq_set()` calls and before `rirq_start()`, and again after any `rirq_set`/`rirq_move`/`rirq_clear`; pass `true` when calling from within an interrupt
199
+ - `rirq_wait_done()` — blocks until the last slot of the current frame has fired; call before `rirq_sort`
200
+ - `rirq_wait()` — blocks until the raster IRQ chain has completed one more pass (end of frame), i.e. until `rirq_count` changes; an earlier version of this page said "the next IRQ tick"
201
+ - `rirq_count` — volatile byte incremented once per frame, by the ISR after the last active slot has run (not once per slot: with two slots it advances by 1 per frame, not 2 — header-read, `inc rirq_count` sits only at the "no more interrupts" exit of each ISR variant). `rirq_wait()` returns when it has changed since the last `rirq_wait()`/`rirq_sort()`, which is why `vspr_update()`/`rirq_sort()` are placed after it. With no slots set it never advances and `rirq_wait()` will not return.
202
+
203
+ ```c
204
+ #include <c64/vic.h>
205
+ #include <c64/rasterirq.h>
206
+
207
+ RIRQCode topBar, botBar;
208
+
209
+ void setup_raster(void) {
210
+ rirq_init(true);
211
+
212
+ rirq_build(&topBar, 2);
213
+ rirq_write(&topBar, 0, &vic.color_back, VCOL_RED);
214
+ rirq_write(&topBar, 1, &vic.color_border, VCOL_RED);
215
+ rirq_set(0, 50, &topBar);
216
+
217
+ rirq_build(&botBar, 2);
218
+ rirq_write(&botBar, 0, &vic.color_back, VCOL_BLACK);
219
+ rirq_write(&botBar, 1, &vic.color_border, VCOL_BLACK);
220
+ rirq_set(1, 150, &botBar);
221
+
222
+ rirq_sort(false);
223
+ rirq_start();
224
+ }
225
+ ```
226
+
227
+ This sets up two color splits: a red band from raster 51 to 151, and black above and below it. The order matters: `rirq_init()` resets every slot's row to 255, so it must come before any `rirq_set()`; and `rirq_sort()` is the only routine that builds the dispatch schedule (`rasterIRQNext[]`) and programs the first `$D012` line — `rirq_start()` only enables the raster IRQ. Without `rirq_sort()` the IRQ fires but no slot ever runs. Measured in VICE: with set-before-init, or with init-first but no sort, no band appears at all; with init → set → sort → start the text area is red from raster 51 through 150 and black from 151 (x64sc PAL exit PNG, rows 35–134 red and row 135 black at x = 200, row = line − 16), i.e. the slot set at `row` 150 fires on line 151, as the `rirq_set` bullet says. An earlier version of this fence called `rirq_set()` before `rirq_init()` and never called `rirq_sort()`, and it also lacked `#include <c64/vic.h>` (`rasterirq.h` includes only `types.h`, so `vic` and `VCOL_RED` were undefined).
228
+
229
+ ## sprites.h — Hardware and multiplexed sprite control
230
+
231
+ `sprites.h` provides two layers of sprite management. The hardware layer (`spr_*`) operates directly on the eight VIC-II hardware sprites. The virtual layer (`vspr_*`) uses `rasterirq.h` slots 0–8 to multiplex 16 virtual sprites onto the eight physical sprites, repositioning them mid-screen as the beam passes.
232
+
233
+ Public API — hardware sprites:
234
+
235
+ - `spr_init(char * screen)` — initializes the sprite system for a given screen RAM address
236
+ - `spr_set(char sp, bool show, int x, int y, char image, char color, bool multi, bool xexpand, bool yexpand)` — fully configures sprite `sp`
237
+ - `spr_show(char sp, bool show)` — shows or hides sprite `sp`
238
+ - `spr_move(char sp, int x, int y)` — moves sprite to `(x, y)` with 8-bit Y and 9-bit X
239
+ - `spr_move16(char sp, int x, int y)` — moves sprite with 16-bit coordinates, hides when off-screen
240
+ - `spr_posx(char sp)` / `spr_posy(char sp)` — read current sprite position
241
+ - `spr_image(char sp, char image)` — changes the sprite data block
242
+ - `spr_color(char sp, char color)` — changes sprite color
243
+ - `spr_expand(char sp, bool xexpand, bool yexpand)` — sets double-size flags
244
+
245
+ Public API — virtual (multiplexed) sprites:
246
+
247
+ - `vspr_init(char * screen)` — initializes the multiplexer (occupies rirq slots 0–8)
248
+ - `vspr_shutdown()` — releases rirq slots
249
+ - `vspr_set(char sp, int x, int y, char image, char color)` — configures virtual sprite `sp` (0–15)
250
+ - `vspr_move(char sp, int x, int y)` — moves a virtual sprite
251
+ - `vspr_movex(char sp, int x)` / `vspr_movey(char sp, int y)` — single-axis moves
252
+ - `vspr_image(char sp, char image)` / `vspr_color(char sp, char color)` — attribute changes
253
+ - `vspr_hide(char sp)` — moves sprite off-screen
254
+ - `vspr_sort()` — sorts virtual sprites by Y position (call before `vspr_update`)
255
+ - `vspr_update()` — reprograms the hardware sprite slots based on sorted order; call at frame bottom after `rirq_wait()`
256
+ - `VSPRITES_MAX` define — default 16; override with `-dVSPRITES_MAX=32` for more slots (requires more rirq slots too)
257
+
258
+ ```c
259
+ #include <c64/sprites.h>
260
+ #include <c64/rasterirq.h> // rirq_wait / rirq_sort; sprites.h does not include it
261
+
262
+ vspr_init((char *)0x0400);
263
+ vspr_set(0, 160, 100, 1, VCOL_YELLOW);
264
+
265
+ // In main loop:
266
+ vic_waitBottom();
267
+ vspr_sort();
268
+ rirq_wait();
269
+ vspr_update();
270
+ rirq_sort();
271
+ ```
272
+
273
+ ## joystick.h — Joystick input
274
+
275
+ `joystick.h` provides polling-based joystick input. A single call to `joy_poll(n)` reads `$DC00+n` on CIA1 and populates three global arrays. Port numbering (verified against `include/c64/joystick.c`):
276
+
277
+ - `joy_poll(0)` reads **`$DC00`** = CIA1 port A = **physical joystick port 2** (the standard "game" port for single-player games).
278
+ - `joy_poll(1)` reads **`$DC01`** = CIA1 port B = **physical joystick port 1**.
279
+
280
+ Public API:
281
+
282
+ - `joy_poll(char n)` — polls joystick `n` (0 or 1) and updates globals
283
+ - `joyx[n]` — `sbyte`: -1 (left), 0 (center), +1 (right)
284
+ - `joyy[n]` — `sbyte`: -1 (up), 0 (center), +1 (down)
285
+ - `joyb[n]` — `bool`: true when fire button is pressed
286
+
287
+ ```c
288
+ #include <c64/joystick.h>
289
+
290
+ joy_poll(0); // port 2 — most common for single-player
291
+ player.x += joyx[0];
292
+ player.y += joyy[0];
293
+ if (joyb[0]) fire();
294
+ ```
295
+
296
+ Note: `joy_poll` must be called once per frame (typically at the start of the game loop) to get a fresh snapshot. Multiple reads within one frame all see the same snapshot from the last `joy_poll` call.
297
+
298
+ **Note — port 2 and the keyboard column drive share `$DC00`, but a main-loop `joy_poll(0)` cannot see the scan.** SCNKEY is called from inside the KERNAL jiffy IRQ handler (`JSR $EA87` at `$EA7B`) and restores `$7F` before the handler's RTI, so the main loop is never running while the columns are driven (measured in VICE x64sc: 0 of 76,144 main-loop samples caught the `$00` window — `pitfalls/input.md`, joystick2_scan_phantom_press). Only an NMI handler, or an IRQ handler that `cli`s before chaining to `$EA31`, can read the all-pressed phantom value; if you poll from such a context, treat `$00` as "scan in progress" and re-read, or take over the IRQ. An earlier version of this page blamed the main loop and advised `sei`/`cli` around the poll, which changes nothing there. Port 1 (`joy_poll(1)`) has no timing hazard either, but a held `1`, LEFT-ARROW, CTRL, `2` or SPACE reads as joystick 1 continuously because the KERNAL leaves column 7 selected.
299
+
300
+ ## keyboard.h — Keyboard matrix scan
301
+
302
+ `keyboard.h` provides matrix-level keyboard scanning. The hardware keyboard on the C64 is an 8x8 matrix read via CIA1 ports A and B; `keyb_poll()` scans the full matrix and records the result. The `KeyScanCode` enum covers all physical keys including shifted variants.
303
+
304
+ Public API:
305
+
306
+ - `keyb_poll()` — scans the full 8x8 keyboard matrix and updates `keyb_matrix` and `keyb_key`
307
+ - `keyb_matrix[8]` — raw scan results, one byte per column
308
+ - `keyb_key` — `KeyScanCode`: the scan code of the most recently detected key, with `KSCAN_QUAL_DOWN` (bit 7) set while pressed
309
+ - `keyb_codes[128]` — lookup table mapping scan codes to PETSCII values (first 64 unshifted, next 64 shifted)
310
+ - `key_pressed(KeyScanCode code)` — returns true if `code` is currently held down
311
+ - `key_shift()` — returns true if either shift key is pressed
312
+ - `KEY_F1`–`KEY_F8`, `KEY_RETURN`, `KEY_DEL`, `KEY_HOME`, `KEY_CLR`, `KEY_CSR_*` — PETSCII code constants
313
+ - `KSCAN_*` — scan code constants for every key
314
+
315
+ ```c
316
+ #include <c64/keyboard.h>
317
+
318
+ keyb_poll();
319
+ if (key_pressed(KSCAN_SPACE)) { jump(); }
320
+ if (key_pressed(KSCAN_F1)) { pause_game(); }
321
+ ```
322
+
323
+ `keyb_poll` is a full-matrix scan and is relatively expensive. For games that only need joystick input, prefer `joystick.h` and skip `keyb_poll` entirely.
324
+
325
+ ## charwin.h — Character-mode windowed text rendering
326
+
327
+ `charwin.h` implements a cursor-based text window over a rectangular region of screen RAM. It wraps all screen writes with bounds checking, handles PETSCII versus screen-code distinction through `_raw` variants, and provides scrolling, editing, and console-style I/O within the window bounds.
328
+
329
+ The `CharWin` struct records the window geometry (`sx`, `sy` — top-left origin; `wx`, `wy` — width and height), the cursor position (`cx`, `cy`), and pointers to the screen and color RAM.
330
+
331
+ Public API highlights:
332
+
333
+ - `cwin_init(CharWin * win, char * screen, char sx, char sy, char wx, char wy)` — initialize without clearing
334
+ - `cwin_clear(CharWin * win)` — fill with spaces
335
+ - `cwin_fill(CharWin * win, char ch, char color)` — fill with character and color
336
+ - `cwin_cursor_move(CharWin * win, char cx, char cy)` — position cursor
337
+ - `cwin_cursor_show(CharWin * win, bool show)` — show/hide cursor (toggles MSB of char at cursor)
338
+ - `cwin_put_char(win, ch, color)` / `cwin_put_string(win, str, color)` — write at cursor, advance
339
+ - `cwin_putat_char(win, x, y, ch, color)` / `cwin_putat_string(win, x, y, str, color)` — write at absolute position
340
+ - `cwin_put_rect(win, x, y, w, h, chars, color)` — fill a rectangle
341
+ - `cwin_scroll_left/right/up/down(win, by)` — scroll the window contents
342
+ - `cwin_edit(CharWin * win)` — interactive edit: reads keystrokes, returns when RETURN or STOP is pressed
343
+ - `cwin_console_printf(win, color, fmt, ...)` — `printf`-style output to the window
344
+
345
+ `_raw` variants (`cwin_put_char_raw`, `cwin_putat_string_raw`, etc.) write screen codes directly without PETSCII translation. Use `_raw` when your data is already in screen-code format (e.g. tile indices).
346
+
347
+ ```c
348
+ #include <c64/vic.h> // VCOL_* — charwin.h does not include vic.h
349
+ #include <c64/charwin.h>
350
+
351
+ CharWin win;
352
+ cwin_init(&win, (char *)0x0400, 2, 2, 36, 21);
353
+ cwin_clear(&win);
354
+ cwin_put_string(&win, "SCORE:", VCOL_WHITE);
355
+ cwin_console_printf(&win, VCOL_YELLOW, "%d", score);
356
+ ```
357
+
358
+ ## mouse.h — 1351 mouse input
359
+
360
+ `mouse.h` reads a Commodore 1351 proportional mouse connected to a joystick port. The 1351 encodes movement in the SID potentiometer registers. `mouse_arm` primes the potentiometer circuit (needs ~4 ms to stabilize before reading) and `mouse_poll` reads the relative displacement.
361
+
362
+ Public API:
363
+
364
+ - `mouse_init()` — initializes mouse state
365
+ - `mouse_arm(char n)` — arms potentiometer input for port `n` (0 or 1); call ~4 ms before `mouse_poll`
366
+ - `mouse_poll()` — reads delta movement into `mouse_dx`/`mouse_dy` and button state
367
+ - `mouse_dx` / `mouse_dy` — `sbyte`: signed relative movement since last poll
368
+ - `mouse_lb` / `mouse_rb` — `bool`: left and right button state
369
+
370
+ ```c
371
+ #include <c64/vic.h> // vic_waitLine — mouse.h includes only types.h
372
+ #include <c64/mouse.h>
373
+
374
+ mouse_init();
375
+ // in frame loop:
376
+ mouse_arm(0);
377
+ vic_waitLine(200); // busy-waits until raster line 200: 0-20 ms after arming,
378
+ // depending on beam position. The pot needs ~4 ms, so either
379
+ // frame-sync the loop (vic_waitBottom() before mouse_arm) or
380
+ // wait a fixed line only when mouse_arm ran at a known beam position.
381
+ mouse_poll();
382
+ cursor_x += mouse_dx;
383
+ cursor_y += mouse_dy;
384
+ ```
385
+
386
+ ## kernalio.h — KERNAL file I/O wrappers
387
+
388
+ `kernalio.h` wraps the C64 KERNAL file I/O routines (SETNAM, OPEN, CLOSE, CHKIN, CHKOUT, CLRCHN, CHRIN, CHROUT, LOAD, SAVE) in a C-callable interface. It uses logical file numbers (0–15) as handles and returns `krnioerr` status codes. A measured write, read-back, status-check and provoked-error run is `../recipes/oscar64/save-load-seq-file.md`; the call sequences as techniques are `../techniques/file-io.md`.
389
+
390
+ Public API:
391
+
392
+ - `krnio_setnam(const char * name)` — sets the filename for the next OPEN
393
+ - `krnio_setnam_n(const char * name, char len)` — sets filename with explicit length
394
+ - `krnio_open(char fnum, char device, char channel)` — opens a channel; returns true on success
395
+ - `krnio_close(char fnum)` — closes the channel
396
+ - `krnio_chkout(char fnum)` / `krnio_chkin(char fnum)` — redirect output/input to file
397
+ - `krnio_clrchn()` — restore default input/output channels
398
+ - `krnio_chrout(char ch)` / `krnio_chrin()` — byte-level I/O to current channel
399
+ - `krnio_getch(char fnum)` — read byte from file; returns negative on error, sets bit 8 on EOF
400
+ - `krnio_putch(char fnum, char ch)` — write byte to file
401
+ - `krnio_read(char fnum, char * data, int num)` — read `num` bytes; returns bytes read or negative
402
+ - `krnio_write(char fnum, const char * data, int num)` — write `num` bytes
403
+ - `krnio_gets(char fnum, char * data, int num)` — read until CR/LF and append zero
404
+ - `krnio_puts(char fnum, const char * data)` — write zero-terminated string
405
+ - `krnio_load(char fnum, char device, char channel)` — LOAD with KERNAL
406
+ - `krnio_save(char device, const char * start, const char * end)` — SAVE range to device
407
+ - `krnio_status()` — returns status of last I/O operation as `krnioerr`
408
+ - `krnio_read_lzo(char fnum, char * data)` — read and decompress LZO-compressed data from file
409
+ - `krnio_pstatus[16]` — per-file-number status array
410
+
411
+ ```c
412
+ #include <c64/kernalio.h>
413
+
414
+ krnio_setnam("SCORES");
415
+ krnio_open(2, 8, 2); // open file 2 on drive 8, channel 2
416
+ krnio_write(2, (char *)&hiscores, sizeof(hiscores));
417
+ krnio_close(2);
418
+ ```
419
+
420
+ Note: string literals passed to `krnio_setnam` should use the `P` prefix (`P"SCORES"`) to ensure PETSCII encoding, since the KERNAL expects PETSCII filenames.
421
+
422
+ ## iecbus.h — Low-level IEC serial bus
423
+
424
+ `iecbus.h` gives direct access to the IEC serial bus at a lower level than the KERNAL wrappers in `kernalio.h`. Use when implementing custom serial protocols or when the KERNAL overhead is unacceptable. `iec_status` holds the last operation result.
425
+
426
+ Public API:
427
+
428
+ - `iec_write(char b)` / `iec_read()` — byte-level bus read/write
429
+ - `iec_atn(char dev, char sec)` — ATN sequence to address a device
430
+ - `iec_talk(char dev, char sec)` / `iec_untalk()` — put device into talk mode
431
+ - `iec_listen(char dev, char sec)` / `iec_unlisten()` — put device into listen mode
432
+ - `iec_open(char dev, char sec, const char * fname)` — open a named file on the bus
433
+ - `iec_close(char dev, char sec)` — close
434
+ - `iec_write_bytes(const char * data, int num)` / `iec_read_bytes(char * data, int num)` — bulk transfer
435
+ - `iec_status` — `IEC_STATUS` enum: `IEC_OK`, `IEC_EOF`, `IEC_QUEUED`, `IEC_ERROR`, `IEC_TIMEOUT`, `IEC_DATA_CHECK`
436
+
437
+ ```c
438
+ #include <c64/iecbus.h>
439
+
440
+ iec_listen(8, 15); // open command channel on drive 8
441
+ iec_write_bytes("I0\r", 3); // initialize disk
442
+ iec_unlisten();
443
+ ```
444
+
445
+ Prefer `kernalio.h` for standard file operations. Use `iecbus.h` only when you need protocol-level control, such as implementing fast loaders or non-standard device protocols.
446
+
447
+ ## easyflash.h — EasyFlash cartridge banking
448
+
449
+ `easyflash.h` provides access to the EasyFlash cartridge bank register at `$DE00` and a C++ template wrapper (`EFlashCall<fn>`) that automates bank switching when calling functions in different ROM banks.
450
+
451
+ The `EasyFlash` struct at `$DE00` has three fields: `bank` (volatile `__memmap byte`) which selects the active 16 KB bank (0–63), `pad1` (unused), and `control` (EasyFlash control flags). The `__memmap` qualifier on `bank` prevents any memory access from being reordered across a bank switch — critical for correctness.
452
+
453
+ Public API:
454
+
455
+ - `eflash` — macro reference to `EasyFlash` struct at `$DE00`
456
+ - `EFCTRL_GAME` / `EFCTRL_EXROM` / `EFCTRL_MODE` / `EFCTRL_LED` — control register flags
457
+ - `ef_call_p<back, fn, P...>(p...)` — switches to `fn`'s bank, calls it, switches back to bank `back`
458
+ - `EFlashCall<fn>` — C++ wrapper class; `operator()` resolves the current bank and calls `ef_call_p`
459
+ - `EF_CALL(fn)` — declares an `EFlashCall<fn_p>` variable named `fn` for clean call syntax
460
+
461
+ The template wrapper and `EF_CALL` are only defined under `__cplusplus`, so this must be compiled in C++ mode — either a `.cpp` source file or a `.c` file built with `-pp`. Compiled as plain C it fails with `Identifier not defined 'EF_CALL'` (build, Oscar64 2026-05-19 with `-tf=crt`; the same text as `.cpp` builds). `EF_CALL(render_level)` declares an `EFlashCall<render_level_p>` object named `render_level`, so you must have defined the real function as `render_level_p`. An earlier version of this page tagged the fence as C and omitted the `_p` definition.
462
+
463
+ ```cpp
464
+ #include <c64/easyflash.h>
465
+
466
+ // The real function, placed in bank 2, carries the _p suffix:
467
+ int render_level_p(const char *data) { /* lives in bank 2 */ return 0; }
468
+
469
+ // Declare the cross-bank callable wrapper (EFlashCall<render_level_p> named render_level):
470
+ EF_CALL(render_level);
471
+
472
+ // At call site (works from any bank):
473
+ render_level(level_data);
474
+ ```
475
+
476
+ `easyflash.h` is only relevant when building with `-tf=crt` targeting EasyFlash hardware. For stock-C64 programs (the primary c64-kb target), this header is not needed.
477
+
478
+ ## memmap.h — Memory map control
479
+
480
+ `memmap.h` exposes the C64's memory banking register at `$01` and provides constants for common configurations. The C64's PLA interprets three bits of the CPU port to select which combination of BASIC ROM, KERNAL ROM, character ROM, and I/O area is visible at `$A000`–`$FFFF` and `$D000`–`$DFFF`.
481
+
482
+ Public API:
483
+
484
+ - `mmap_set(char pla)` — writes `pla` to `$01`; returns previous value; uses `__memmap` to prevent reordering
485
+ - `mmap_trampoline()` — installs an IRQ/NMI trampoline that keeps KERNAL interrupts working when the KERNAL ROM is paged out; call before `mmap_set(MMAP_NO_ROM)`
486
+
487
+ Memory map constants:
488
+
489
+ | Constant | Value | Configuration |
490
+ |----------|-------|---------------|
491
+ | `MMAP_ROM` | `$37` | BASIC + I/O + KERNAL (default power-on state) |
492
+ | `MMAP_NO_BASIC` | `$36` | I/O + KERNAL only (frees `$A000`–`$BFFF` as RAM) |
493
+ | `MMAP_NO_ROM` | `$35` | I/O only (frees `$A000`–`$BFFF` and `$E000`–`$FFFF`) |
494
+ | `MMAP_RAM` | `$30` | All RAM, no ROM, no I/O |
495
+ | `MMAP_CHAR_ROM` | `$31` | Character ROM visible (for copying glyphs) |
496
+ | `MMAP_ALL_ROM` | `$33` | All ROM, no I/O (disables hardware register access) |
497
+
498
+ ```c
499
+ #include <c64/memmap.h>
500
+
501
+ mmap_trampoline(); // keep IRQs working
502
+ mmap_set(MMAP_NO_ROM); // extra 28 KB of code+data space
503
+ // Now $A000–$BFFF and $E000–$FFFF are RAM
504
+ ```
505
+
506
+ After `mmap_set(MMAP_NO_ROM)` or `mmap_set(MMAP_RAM)` the KERNAL is gone, and every KERNAL call crashes — including the `krnio_*` wrappers, which are plain `JSR $FFxx` calls into the jump table and never touch `$01` (header-read, `kernalio.c`: on the C64 their `BANKIN`/`BANKOUT` macros are empty; only the Plus/4 build banks the ROM in). `mmap_trampoline()` covers only the IRQ/NMI entry path; it does nothing for a `JSR` from your own code. An earlier version of this page said the `krnio_*` wrappers handle the memory map; they do not. To do KERNAL I/O while running with the ROM out, bank it back in around the call and restore the previous map afterwards:
507
+
508
+ ```c
509
+ #include <c64/memmap.h>
510
+ #include <c64/kernalio.h>
511
+
512
+ char old = mmap_set(MMAP_ROM);
513
+ krnio_setnam(P"SCORES");
514
+ krnio_open(2, 8, 2);
515
+ /* ... krnio_read / krnio_write ... */
516
+ krnio_close(2);
517
+ mmap_set(old);
518
+ ```
519
+
520
+ `MMAP_NO_BASIC` (`$36`) keeps the KERNAL in, so `krnio_*` works unchanged under it. While the ROM is banked in, a buffer that lives under `$A000–$BFFF` or `$E000–$FFFF` reads back as ROM bytes, so keep I/O buffers below `$A000` or in `$C000–$CFFF`.
521
+
522
+ ## reu.h — RAM Expansion Unit DMA
523
+
524
+ `reu.h` provides access to the 1700/1764/1750 RAM Expansion Unit connected at `$DF00`. The REU adds 128 KB, 256 KB, or 512 KB of battery-backed RAM accessible via DMA. The header maps the REU control registers to a `REU` struct and provides inline helpers for common transfer operations.
525
+
526
+ Note: REU support is listed in Oscar64 headers for completeness. The c64-kb scope is stock C64 hardware; REU recipes are out of scope for this KB. This header is documented here so agents know it exists.
527
+
528
+ Public API:
529
+
530
+ - `reu` — macro reference to `REU` struct at `$DF00`
531
+ - `reu_count_pages()` — tests how many 64 KB pages of REU are present (destructive test)
532
+ - `reu_store(unsigned long raddr, const volatile char * sp, unsigned length)` — copy from C64 RAM to REU
533
+ - `reu_load(unsigned long raddr, volatile char * dp, unsigned length)` — copy from REU to C64 RAM
534
+ - `reu_fill(unsigned long raddr, char c, unsigned length)` — fill REU memory with a value
535
+ - `reu_load2d(unsigned long raddr, volatile char * dp, char height, unsigned width, unsigned stride)` — 2D DMA transfer (e.g. for tile blitting from REU)
536
+
537
+ ```c
538
+ #include <c64/reu.h>
539
+
540
+ // Save current screen to REU bank 0
541
+ reu_store(0UL, (volatile char *)0x0400, 1000);
542
+ // Later, restore it
543
+ reu_load(0UL, (volatile char *)0x0400, 1000);
544
+ ```
545
+
546
+ ## asm6502.h — Runtime 6502 code emitter
547
+
548
+ `asm6502.h` provides a set of inline functions that write raw 6502 machine instructions into a byte buffer at runtime. This is used to generate self-modifying code, JIT-compiled routines, or custom IRQ stubs that must live at specific addresses. Each `asm_*` function emits one instruction and returns the instruction size in bytes.
549
+
550
+ The `AsmIns` enum lists all standard 6502 opcodes in their base (implied or zero-page) form. Addressing mode wrappers encode the full instruction.
551
+
552
+ Public API — addressing mode wrappers (each returns instruction size):
553
+
554
+ - `asm_np(byte * ip, AsmIns ins)` — implied (e.g. `NOP`, `RTS`, `SEI`)
555
+ - `asm_ac(byte * ip, AsmIns ins)` — accumulator (e.g. `ROL`)
556
+ - `asm_im(byte * ip, AsmIns ins, byte value)` — immediate
557
+ - `asm_zp(byte * ip, AsmIns ins, byte addr)` — zero page
558
+ - `asm_zx(byte * ip, AsmIns ins, byte addr)` — zero page indexed X
559
+ - `asm_zy(byte * ip, AsmIns ins, byte addr)` — zero page indexed Y
560
+ - `asm_ab(byte * ip, AsmIns ins, unsigned addr)` — absolute
561
+ - `asm_ax(byte * ip, AsmIns ins, unsigned addr)` — absolute indexed X
562
+ - `asm_ay(byte * ip, AsmIns ins, unsigned addr)` — absolute indexed Y
563
+ - `asm_in(byte * ip, AsmIns ins, unsigned addr)` — indirect (JMP only)
564
+ - `asm_ix(byte * ip, AsmIns ins, byte addr)` — (zp,X) indirect pre-indexed
565
+ - `asm_iy(byte * ip, AsmIns ins, byte addr)` — (zp),Y indirect post-indexed
566
+ - `asm_rl(byte * ip, AsmIns ins, sbyte addr)` — relative branch
567
+
568
+ ```c
569
+ #include <c64/asm6502.h>
570
+
571
+ // Emit a short routine into a RAM buffer (static: see the note below)
572
+ static byte codebuf[16];
573
+ byte * p = codebuf;
574
+ p += asm_im(p, ASM_LDA, 0x0E); // LDA #$0E
575
+ p += asm_ab(p, ASM_STA, 0xD020); // STA $D020
576
+ p += asm_np(p, ASM_RTS); // RTS
577
+ // codebuf now holds a 6-byte routine (A9 0E 8D 20 D0 60) that sets the border to light blue
578
+ __asm { jsr codebuf } // call it
579
+ ```
580
+
581
+ As of the 2026-05-19 build, calling a byte buffer through a cast function pointer (`((void (*)(void))codebuf)();`) crashes the compiler — exit 139, no `.prg`, no diagnostic — when the buffer is a local, whether the call is direct or through a pointer variable (build; the same class as the `const` function-pointer segfault in the project gotchas). With a global buffer the same cast call compiles, but at `-O2` the stores into the buffer are dead-store-eliminated and the JSR lands on zeroed BSS, so use the inline-asm `jsr`. And `__asm { jsr codebuf }` on a LOCAL (stack) buffer assembles to `JSR $0000` with only a "nullptr dereferenced" warning, which is why the buffer must be `static` or file-scope. The routine is 6 bytes (`asm_im` 2 + `asm_ab` 3 + `asm_np` 1; bytes measured in VICE); an earlier version of this page said 7 and showed the crashing cast call.
582
+
583
+ Use `asm6502.h` as a last resort — it bypasses all compiler optimizations and type checking. Prefer `__asm { }` inline blocks for most performance-critical code.