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,113 @@
1
+ # adventure: STARWATCH, a two-word text adventure. Harness targets:
2
+ # make build build/adventure.prg (after the PLAN.md gate)
3
+ # make run windowed VICE: type on the keyboard, SAVE and LOAD to drive 8
4
+ # make shot headless PAL and NTSC exit screenshots of the autopilot build
5
+ # make check grade shots/pal.png and shots/ntsc.png against expect.json
6
+ # make selftest prove check fails on the FORCE_FAULT=1 build
7
+ # make disk build/adventure.d64
8
+ # make claims c64-kb's claims-watch over the autopilot build, when available
9
+ # and this starter's own:
10
+ # make gen re-run tools/gen.py (world tables, packed text, pictures, script, model)
11
+ # make disktest SAVE, a cold reset, LOAD and the same state back, on a true-drive 1541
12
+ # make clean
13
+ NAME := adventure
14
+ C_MAIN := src/main.c
15
+
16
+ # Pinned after the verdict. Measured with VICE x64sc 3.10: see README.md, "The shot pin".
17
+ SHOT_CYCLES_PAL := 18000000
18
+ SHOT_CYCLES_NTSC := 18000000
19
+
20
+ # The shot plays SAVE and LOAD for real: each headless run gets a fresh copy
21
+ # of the release D64 (the harness's SHOT_DISK), in a true-drive 1541 (the
22
+ # VICE_FLAGS line after the include).
23
+ SHOT_DISK := 1
24
+
25
+ # What the program may write, for make claims (claims-watch's grammar).
26
+ # zero_page $02-$57 is what Oscar64's code touches (make zp lists it); $C6 is
27
+ # the KERNAL's key count, which the loop and the autopilot write. keyqueue is
28
+ # the KERNAL keyboard queue; shiftmode $0291 locks SHIFT + C=. --kernal names
29
+ # SCNKEY, which the loop calls every frame, and the file routines save.c calls
30
+ # through kernalio.h.
31
+ CLAIMS_ARGS := --cycles 18000000 --kernal SCNKEY,SETLFS,SETNAM,OPEN,CLOSE,CHKIN,CHKOUT,CLRCHN,CHRIN,CHROUT,READST --claim 'sid_voice_1, sid_voice_2, sid_filter_volume, cia1_port_a, cia1_timer_a, cia1_timer_b, cia1_tod, zero_page $$02-$$57+$$C6' --range 'keyqueue=$$0277-$$0280,shiftmode=$$0291,screen=$$0400-$$07FF,colour=$$D800-$$DBFF,charset=$$3800-$$3FFF,result=$$02FF' --harness 'cia2_timer_a, cia2_timer_b, cia2_tod'
32
+
33
+ # The harness sits beside the starter in c64-kb (../_harness) or is vendored
34
+ # into ./harness when the starter is copied out on its own.
35
+ # Proof targets `npm run verify:templates -- --selftest` runs after selftest.
36
+ VERIFY_TARGETS := disktest
37
+
38
+ HARNESS ?= $(firstword $(wildcard harness) ../_harness)
39
+ $(if $(wildcard $(HARNESS)/harness.mk),,$(error No harness at '$(HARNESS)'. Copy c64-kb's templates/_harness to ./harness, or make the project with npm run new-project in c64-kb))
40
+ include $(HARNESS)/harness.mk
41
+ VICE_FLAGS += -drive8type 1541 -drive8truedrive
42
+ ZP_CLAIM := $$02-$$57,$$C6
43
+
44
+ # ---- this starter's own targets ---------------------------------------------------
45
+ # tools/gen.py writes the two src/gen_*.h headers from tools/world.py.
46
+ GEN_OUT := src/gen_world.h src/gen_script.h
47
+ $(GEN_OUT): build/gen.stamp
48
+ build/gen.stamp: tools/gen.py tools/world.py
49
+ @mkdir -p build
50
+ $(PYTHON) tools/gen.py
51
+ @touch $@
52
+
53
+ .PHONY: gen disktest joy
54
+ gen:
55
+ $(PYTHON) tools/gen.py
56
+
57
+ # The normal game with its fire button read from $02FE instead of $DC00, so
58
+ # tools/drive.py can press it headless (README, "Driving it headless").
59
+ joy: build/$(NAME)-joy.prg
60
+ build/$(NAME)-joy.prg: $(C_DEPS) $(METER_DEPS) | plan-gate
61
+ @mkdir -p build
62
+ $(OSCAR64_BUILD) -dJOY_SOURCE=0x02fe -o=$@ $(C_MAIN)
63
+
64
+ # The disk test, on a true-drive 1541 (DISK_MODEL=pal or ntsc):
65
+ # 1. DISKTEST=1 plays the script up to its SAVE on a fresh copy of the release
66
+ # D64 and grades itself: the state the model says, and the drive's 00;
67
+ # 2. c1541 reads SAVEGAME back: tools/disk_check.py compares it byte for byte
68
+ # with the record the model wrote (build/save-expected.bin);
69
+ # 3. a cold VICE (a reset) runs DISKTEST=2 on the same D64: it types LOAD
70
+ # first, then the rest of the script, which reaches the ending only from
71
+ # the saved state, and grades itself;
72
+ # 4. a cold VICE boots the release PRG from the D64 and types RETURN, LOAD,
73
+ # SCORE and I through the keyboard queue (-keybuf). Without
74
+ # -keybuf-delay the keys arrived before the program ran and were lost;
75
+ # 2500 held them past the load (measured, VICE 3.10).
76
+ # 5. the release PRG LOADs three bad saves (tools/disk_check.py --make-bad):
77
+ # a changed byte, room 200 with a good fold, another world's version with
78
+ # a good fold; each must be refused;
79
+ # 6. the release PRG types SAVE to a drive with no disk: the drive's words.
80
+ # tools/disk_check.py grades the pictures and the file against the model.
81
+ DISKTEST_D64 := build/disktest.d64
82
+ DISK_MODEL ?= pal
83
+ DISK_VICE = $(TIMEOUT) $(VICE_TIMEOUT) $(X64SC) $(VICE_FLAGS) $(if $(filter ntsc,$(DISK_MODEL)),-model ntsc) -drive8type 1541 -drive8truedrive -drive8wobbleamplitude 0 -drive8wobblefrequency 0
84
+ # $(1) = the picture's name, $(2) = cycles, $(3) = what to autostart, $(4) = extra flags
85
+ define disk_run
86
+ @rm -f shots/$(1).png
87
+ @$(DISK_VICE) -limitcycles $(2) $(4) -exitscreenshot shots/$(1).png -autostart $(3) > shots/$(1).log 2>&1 || true
88
+ @test -s shots/$(1).png || { echo "disktest: no picture from the $(1) run; see shots/$(1).log"; exit 1; }
89
+ endef
90
+ build/$(NAME)-disk1.prg: $(C_DEPS) $(METER_DEPS) | plan-gate
91
+ $(OSCAR64_BUILD) -dAUTOPILOT=1 -dDISKTEST=1 -o=$@ $(C_MAIN)
92
+ build/$(NAME)-disk2.prg: $(C_DEPS) $(METER_DEPS) | plan-gate
93
+ $(OSCAR64_BUILD) -dAUTOPILOT=1 -dDISKTEST=2 -o=$@ $(C_MAIN)
94
+ # $(1) = a bad save (tools/disk_check.py --make-bad): the release PRG LOADs it
95
+ define bad_run
96
+ cp $(D64) build/$(1).d64
97
+ $(C1541) -attach build/$(1).d64 -write build/$(1).seq "savegame,s" > /dev/null
98
+ $(call disk_run,$(1),8000000,$(PRG),-8 build/$(1).d64 -keybuf '\x0dload\x0d' -keybuf-delay 100)
99
+ endef
100
+ disktest: $(D64) $(PRG) build/$(NAME)-disk1.prg build/$(NAME)-disk2.prg
101
+ @mkdir -p shots
102
+ cp $(D64) $(DISKTEST_D64)
103
+ $(call disk_run,disk-save,20000000,build/$(NAME)-disk1.prg,-8 $(DISKTEST_D64))
104
+ $(C1541) -attach $(DISKTEST_D64) -read "savegame,s" build/savegame.seq > /dev/null
105
+ $(call disk_run,disk-load,20000000,build/$(NAME)-disk2.prg,-8 $(DISKTEST_D64))
106
+ $(call disk_run,disk-boot,60000000,$(DISKTEST_D64),-keybuf '\x0dload\x0dscore\x0di\x0d' -keybuf-delay 2500)
107
+ $(C1541) -attach $(DISKTEST_D64) -list > build/disktest-dir.txt 2>/dev/null
108
+ $(PYTHON) tools/disk_check.py --make-bad build
109
+ $(call bad_run,bad-fold)
110
+ $(call bad_run,bad-room)
111
+ $(call bad_run,bad-world)
112
+ $(call disk_run,no-disk,12000000,$(PRG),-keybuf '\x0dsave\x0d' -keybuf-delay 100)
113
+ $(PYTHON) tools/disk_check.py $(HARNESS_DIR) build $(DISK_MODEL)
@@ -0,0 +1,396 @@
1
+ # Plan: adventure
2
+
3
+ The text-adventure starter for c64-kb issue #39. The tool output below was
4
+ produced on 2026-09-23 by this checkout's c64-kb and pasted whole.
5
+
6
+ ## Concept
7
+
8
+ STARWATCH, a two-word text adventure in an original twelve-room world: an
9
+ astronomer's house on the night a comet passes. The player types commands on
10
+ an input line under a scrolling room-text window; a strip of multicolour
11
+ character pictures above the window shows the room. Objects, four containers
12
+ (chest, drawer, crate, desk), three puzzles with state (a key fished out of a
13
+ pond, a dark cellar and a lamp that needs matches, a clock that opens the
14
+ tower hatch), a scored ending, and SAVE and LOAD of the game to drive 8. The
15
+ room and message text is stored packed. PAL and NTSC.
16
+
17
+ ## Briefing
18
+
19
+ Command: `npx tsx src/cli.ts game-briefing "text adventure: original twelve-room world, two-word parser with synonyms, split screen room text window above an input line, objects and containers, stateful puzzles, scored ending, save and load game state to disk, compressed room and message text, multicolour character picture strip" --archetype text_adventure`
20
+
21
+ (`--archetype adventure` is refused: the graph's name is `text_adventure`.)
22
+
23
+ Kept from its 17 proposals: adventure_database_engine, two_word_parser,
24
+ text_input_line, sid_voice_setup (a key click and two chimes).
25
+
26
+ Dropped, and why: cpu_io_port_bank, ram_under_kernal and exomizer_basics (the
27
+ archetype's fingerprint for large games; this one fits under $A000 with the
28
+ ROMs in); text_window_and_menu (the window here is a scrolling terminal, not a
29
+ save-under box, and the technique pulls in joystick_edge_detect);
30
+ flip_screen_rooms (the room change redraws only the picture strip);
31
+ screen_dissolve_lfsr and screen_wipe (no transitions); world_state_bits (the
32
+ whole state is a few dozen bytes and is saved whole); attract_mode_input_replay
33
+ (the autopilot types into the keyboard queue instead); multi_sprite_object,
34
+ two_player_state_swap, joystick_autorepeat, joystick_edge_detect (no sprites,
35
+ one player, keyboard play; fire on port 2 only starts the game).
36
+
37
+ Added, which the briefing did not propose: kernal_file_write_seq,
38
+ kernal_file_read_seq and error_channel_check (the brief says SAVE and LOAD);
39
+ mcm_text and charset_copy_rom_to_ram (the picture strip); decimal_print
40
+ (score and turns); petscii_screen_code_conversion (typed PETSCII to the
41
+ screen); frame_sync_loop; raster_profile_bars (the harness meter).
42
+
43
+ The briefing's 38 pitfalls are mostly its sprite and joystick proposals'.
44
+ The ones this program meets are in the table below.
45
+
46
+ ## Techniques
47
+
48
+ | Technique | Why | Recipe it starts from | Pitfalls read (`pitfalls-for`) |
49
+ |---|---|---|---|
50
+ | adventure_database_engine | rooms, items, an action table with conditions and commands, occurrences, containers, packed text | oscar64-adventure-engine | petscii_written_to_screen_ram |
51
+ | two_word_parser | verb and noun stems of four letters, synonyms share an id, articles skipped | oscar64-two-word-parser | petscii_written_to_screen_ram, getchx_petscii_remaps_return, kernal_clobbers_a_x_y |
52
+ | text_input_line | the input line: echo, DEL, RETURN, a length cap, a blinking cursor | oscar64-text-input | getchx_petscii_remaps_return, badline_cycle_loss, d012_wrap_around |
53
+ | petscii_screen_code_conversion | typed PETSCII to screen codes for the echo and the unknown-word reply | oscar64-petscii-screen-codes | petscii_written_to_screen_ram |
54
+ | decimal_print | score and turns on the status bar | oscar64-print-number | petscii_written_to_screen_ram |
55
+ | mcm_text | the picture strip: colour RAM 8-15 cells are multicolour, 0-7 stay hires text | none yet (the technique says "No recipe yet"); oscar64-charset-animation for the RAM set | d016_unmasked_rmw_clobbers_csel_mcm, charset_blit_overruns_grown_code |
56
+ | charset_copy_rom_to_ram | the ROM letters and reverse glyphs copied under the picture tiles | kickassembler-charset-copy-rom-to-ram | irq_during_charen_window, charset_blit_overruns_grown_code |
57
+ | kernal_file_write_seq | SAVE: scratch, then write the state record | oscar64-save-load-seq-file, oscar64-high-score-persist | krnio_save_leaves_splat_file, kernal_assumes_sei_cleared, kernal_io_mapping_dependency |
58
+ | kernal_file_read_seq | LOAD: read the record, check size, version and checksum | oscar64-save-load-seq-file | first_open_after_reset_hangs_on_pal, kernal_assumes_sei_cleared |
59
+ | error_channel_check | the drive's two-digit reply decides what SAVE and LOAD print | oscar64-high-score-persist | first_open_after_reset_hangs_on_pal |
60
+ | frame_sync_loop | one pass a frame, polled at raster line 250 | oscar64-frame-sync-loop, templates/hello | d012_wrap_around, badline_cycle_loss, pal_ntsc_tempo_mismatch |
61
+ | sid_voice_setup | key click, score chime, ending jingle | oscar64-sid-music-player (voice setup only) | sid_write_only_registers, sid_adsr_bug_8580, sid_voice3_disable_silent_bit |
62
+ | raster_profile_bars | the harness frame meter (CIA2 timer A) | oscar64-raster-profile-bars | badline_cycle_loss |
63
+
64
+ ## Compatibility
65
+
66
+ Command: `npx tsx src/cli.ts check-compatibility adventure_database_engine two_word_parser text_input_line petscii_screen_code_conversion decimal_print mcm_text charset_copy_rom_to_ram kernal_file_write_seq kernal_file_read_seq error_channel_check frame_sync_loop sid_voice_setup raster_profile_bars`
67
+
68
+ ```text
69
+ # Compatibility: adventure_database_engine + two_word_parser + text_input_line + petscii_screen_code_conversion + decimal_print + mcm_text + charset_copy_rom_to_ram + kernal_file_write_seq + kernal_file_read_seq + error_channel_check + frame_sync_loop + sid_voice_setup + raster_profile_bars
70
+
71
+ **Verdict:** WARNINGS
72
+
73
+ Checked with 1 implied prerequisite(s): cpu_io_port_bank.
74
+
75
+ Unit claims are stated for 0 of 13 techniques; a unit conflict cannot be ruled out for: adventure_database_engine, two_word_parser, text_input_line, petscii_screen_code_conversion, decimal_print, mcm_text, charset_copy_rom_to_ram, kernal_file_write_seq, kernal_file_read_seq, error_channel_check, frame_sync_loop, sid_voice_setup, raster_profile_bars, cpu_io_port_bank (prerequisite). The zero-page bytes and interrupt vectors a recipe chooses are not checked yet (issue #22, step 8).
76
+
77
+ ## shared_kernal (soft): two_word_parser × text_input_line
78
+ **Shared:** GETIN
79
+ Both techniques call KERNAL routine(s) GETIN. Concurrent use may clobber KERNAL state.
80
+
81
+ ## shared_register (soft): text_input_line × frame_sync_loop
82
+ **Shared:** SCROLY
83
+ Both techniques touch register(s) SCROLY. This says they write the same registers, not that they fight: keep each one's writes in its own raster region, or have one of them own the register and the other read a shadow copy.
84
+
85
+ ## shared_register (soft): petscii_screen_code_conversion × mcm_text
86
+ **Shared:** VMCSB
87
+ Both techniques touch register(s) VMCSB. This says they write the same registers, not that they fight: keep each one's writes in its own raster region, or have one of them own the register and the other read a shadow copy.
88
+
89
+ ## shared_register (soft): petscii_screen_code_conversion × charset_copy_rom_to_ram
90
+ **Shared:** VMCSB
91
+ Both techniques touch register(s) VMCSB. This says they write the same registers, not that they fight: keep each one's writes in its own raster region, or have one of them own the register and the other read a shadow copy.
92
+
93
+ ## shared_kernal (soft): petscii_screen_code_conversion × kernal_file_write_seq
94
+ **Shared:** CHROUT
95
+ Both techniques call KERNAL routine(s) CHROUT. Concurrent use may clobber KERNAL state.
96
+
97
+ ## shared_register (soft): mcm_text × charset_copy_rom_to_ram
98
+ **Shared:** VMCSB
99
+ Both techniques touch register(s) VMCSB. This says they write the same registers, not that they fight: keep each one's writes in its own raster region, or have one of them own the register and the other read a shadow copy.
100
+
101
+ ## shared_kernal (soft): kernal_file_write_seq × kernal_file_read_seq
102
+ **Shared:** CLRCHN, CLOSE, OPEN, SETNAM, SETLFS
103
+ Both techniques call KERNAL routine(s) CLRCHN, CLOSE, OPEN, SETNAM, SETLFS. Concurrent use may clobber KERNAL state.
104
+
105
+ ## shared_kernal (soft): kernal_file_write_seq × error_channel_check
106
+ **Shared:** CLRCHN, CLOSE, OPEN, SETNAM, SETLFS
107
+ Both techniques call KERNAL routine(s) CLRCHN, CLOSE, OPEN, SETNAM, SETLFS. Concurrent use may clobber KERNAL state.
108
+
109
+ ## shared_kernal (soft): kernal_file_read_seq × error_channel_check
110
+ **Shared:** CHRIN, CLRCHN, CHKIN, CLOSE, OPEN, SETNAM, SETLFS, READST
111
+ Both techniques call KERNAL routine(s) CHRIN, CLRCHN, CHKIN, CLOSE, OPEN, SETNAM, SETLFS, READST. Concurrent use may clobber KERNAL state.
112
+
113
+ ## shared_register (soft): frame_sync_loop × raster_profile_bars
114
+ **Shared:** EXTCOL
115
+ Both techniques touch register(s) EXTCOL. This says they write the same registers, not that they fight: keep each one's writes in its own raster region, or have one of them own the register and the other read a shadow copy.
116
+
117
+
118
+ ## Not covered
119
+ - **adventure_database_engine**: the graph has no registers, KERNAL routines or demands for it; the verdict says nothing about it.
120
+ - **decimal_print**: the graph has no registers, KERNAL routines or demands for it; the verdict says nothing about it.
121
+ - **cpu_io_port_bank** (prerequisite of charset_copy_rom_to_ram): the graph has no registers, KERNAL routines or demands for it.
122
+
123
+ ## Shared Infrastructure (info)
124
+ - **cpu_io_port_bank** (prerequisite, not in the set): required by charset_copy_rom_to_ram; included in the check as implied. Set it up first.
125
+ - **SP6COL** (Register) shared via recipe(s): oscar64-platformer-scaffold
126
+ - **CHRIN** (KernalRoutine) shared via recipe(s): oscar64-platformer-scaffold, oscar64-save-load-seq-file, kickassembler-file-io-roundtrip, oscar64-directory-reader, oscar64-high-score-persist
127
+ - **CHROUT** (KernalRoutine) shared via recipe(s): oscar64-platformer-scaffold, oscar64-save-load-seq-file, kickassembler-file-io-roundtrip, oscar64-directory-reader, oscar64-high-score-persist
128
+ - **CLRCHN** (KernalRoutine) shared via recipe(s): oscar64-platformer-scaffold, oscar64-save-load-seq-file, kickassembler-file-io-roundtrip, oscar64-directory-reader, oscar64-high-score-persist
129
+ - **CHKOUT** (KernalRoutine) shared via recipe(s): oscar64-platformer-scaffold, oscar64-save-load-seq-file, kickassembler-file-io-roundtrip, oscar64-directory-reader, oscar64-high-score-persist
130
+ - **CHKIN** (KernalRoutine) shared via recipe(s): oscar64-platformer-scaffold, oscar64-save-load-seq-file, kickassembler-file-io-roundtrip, oscar64-directory-reader, oscar64-high-score-persist
131
+ - **CLOSE** (KernalRoutine) shared via recipe(s): oscar64-platformer-scaffold, oscar64-save-load-seq-file, kickassembler-file-io-roundtrip, oscar64-directory-reader, oscar64-high-score-persist
132
+ - **OPEN** (KernalRoutine) shared via recipe(s): oscar64-platformer-scaffold, oscar64-save-load-seq-file, kickassembler-file-io-roundtrip, oscar64-directory-reader, oscar64-high-score-persist
133
+ - **SETNAM** (KernalRoutine) shared via recipe(s): oscar64-platformer-scaffold, oscar64-save-load-seq-file, kickassembler-file-io-roundtrip, oscar64-directory-reader, oscar64-high-score-persist
134
+ - **SETLFS** (KernalRoutine) shared via recipe(s): oscar64-platformer-scaffold, oscar64-save-load-seq-file, kickassembler-file-io-roundtrip, oscar64-directory-reader, oscar64-high-score-persist
135
+ - **DC0F** (Register) shared via recipe(s): oscar64-platformer-scaffold
136
+ - **DC07** (Register) shared via recipe(s): oscar64-platformer-scaffold
137
+ - **DC06** (Register) shared via recipe(s): oscar64-platformer-scaffold
138
+ - **DC03** (Register) shared via recipe(s): oscar64-platformer-scaffold
139
+ - **SP5COL** (Register) shared via recipe(s): oscar64-platformer-scaffold
140
+ - **SP4COL** (Register) shared via recipe(s): oscar64-platformer-scaffold
141
+ - **SP3COL** (Register) shared via recipe(s): oscar64-platformer-scaffold
142
+ - **SP2COL** (Register) shared via recipe(s): oscar64-platformer-scaffold
143
+ - **SP1COL** (Register) shared via recipe(s): oscar64-platformer-scaffold
144
+ - **SP0COL** (Register) shared via recipe(s): oscar64-platformer-scaffold
145
+ - **BGCOL0** (Register) shared via recipe(s): oscar64-platformer-scaffold
146
+ - **EXTCOL** (Register) shared via recipe(s): oscar64-platformer-scaffold, oscar64-directory-reader
147
+ - **IRQMSK** (Register) shared via recipe(s): oscar64-platformer-scaffold
148
+ - **VICIRQ** (Register) shared via recipe(s): oscar64-platformer-scaffold
149
+ - **SPENA** (Register) shared via recipe(s): oscar64-platformer-scaffold
150
+ - **RASTER** (Register) shared via recipe(s): oscar64-platformer-scaffold, oscar64-directory-reader
151
+ - **SCROLY** (Register) shared via recipe(s): oscar64-platformer-scaffold
152
+ - **MSIGX** (Register) shared via recipe(s): oscar64-platformer-scaffold
153
+ - **M0Y** (Register) shared via recipe(s): oscar64-platformer-scaffold
154
+ - **M0X** (Register) shared via recipe(s): oscar64-platformer-scaffold
155
+ - **RANDOM** (Register) shared via recipe(s): oscar64-platformer-scaffold
156
+ - **DC02** (Register) shared via recipe(s): oscar64-platformer-scaffold
157
+ - **DC00** (Register) shared via recipe(s): oscar64-platformer-scaffold, oscar64-directory-reader
158
+ - **SIGVOL** (Register) shared via recipe(s): oscar64-platformer-scaffold
159
+ - **SUREL3** (Register) shared via recipe(s): oscar64-platformer-scaffold
160
+ - **ATDCY3** (Register) shared via recipe(s): oscar64-platformer-scaffold
161
+ - **VCREG3** (Register) shared via recipe(s): oscar64-platformer-scaffold
162
+ - **PWHI3** (Register) shared via recipe(s): oscar64-platformer-scaffold
163
+ - **PWLO3** (Register) shared via recipe(s): oscar64-platformer-scaffold
164
+ - **FREHI3** (Register) shared via recipe(s): oscar64-platformer-scaffold
165
+ - **FRELO3** (Register) shared via recipe(s): oscar64-platformer-scaffold
166
+ - **SUREL2** (Register) shared via recipe(s): oscar64-platformer-scaffold
167
+ - **ATDCY2** (Register) shared via recipe(s): oscar64-platformer-scaffold
168
+ - **VCREG2** (Register) shared via recipe(s): oscar64-platformer-scaffold
169
+ - **PWHI2** (Register) shared via recipe(s): oscar64-platformer-scaffold
170
+ - **PWLO2** (Register) shared via recipe(s): oscar64-platformer-scaffold
171
+ - **FREHI2** (Register) shared via recipe(s): oscar64-platformer-scaffold
172
+ - **FRELO2** (Register) shared via recipe(s): oscar64-platformer-scaffold
173
+ - **SUREL1** (Register) shared via recipe(s): oscar64-platformer-scaffold
174
+ - **ATDCY1** (Register) shared via recipe(s): oscar64-platformer-scaffold
175
+ - **VCREG1** (Register) shared via recipe(s): oscar64-platformer-scaffold
176
+ - **PWHI1** (Register) shared via recipe(s): oscar64-platformer-scaffold
177
+ - **PWLO1** (Register) shared via recipe(s): oscar64-platformer-scaffold
178
+ - **FREHI1** (Register) shared via recipe(s): oscar64-platformer-scaffold
179
+ - **FRELO1** (Register) shared via recipe(s): oscar64-platformer-scaffold
180
+ - **READST** (KernalRoutine) shared via recipe(s): oscar64-platformer-scaffold, oscar64-save-load-seq-file, kickassembler-file-io-roundtrip, oscar64-directory-reader, oscar64-high-score-persist
181
+ - **DD0F** (Register) shared via recipe(s): oscar64-save-load-seq-file, kickassembler-file-io-roundtrip, oscar64-directory-reader
182
+ - **DD0E** (Register) shared via recipe(s): oscar64-save-load-seq-file, kickassembler-file-io-roundtrip, oscar64-directory-reader
183
+ - **DD07** (Register) shared via recipe(s): oscar64-save-load-seq-file, kickassembler-file-io-roundtrip, oscar64-directory-reader
184
+ - **DD06** (Register) shared via recipe(s): oscar64-save-load-seq-file, kickassembler-file-io-roundtrip, oscar64-directory-reader
185
+ - **DD05** (Register) shared via recipe(s): oscar64-save-load-seq-file, kickassembler-file-io-roundtrip, oscar64-directory-reader
186
+ - **DD04** (Register) shared via recipe(s): oscar64-save-load-seq-file, kickassembler-file-io-roundtrip, oscar64-directory-reader
187
+ - **raster_discipline**: Multiple raster-discipline techniques present. Verify IRQ stack ordering and timing budget.
188
+
189
+ ```
190
+
191
+ What the warnings mean for this program:
192
+
193
+ - GETIN shared by two_word_parser and text_input_line: one reader. The input
194
+ line pops the KERNAL queue (the bytes GETIN's LP2 at `$E5B4` moves, without
195
+ its `CLI`); the parser only reads the finished line.
196
+ - SCROLY (text_input_line, frame_sync_loop): read only (raster bit 8 is not
197
+ used; the loop polls line 250 in `$D012`).
198
+ - VMCSB ($D018) for petscii_screen_code_conversion, mcm_text and
199
+ charset_copy_rom_to_ram: written once at start-up, `$1E` (screen `$0400`,
200
+ characters `$3800`), never again.
201
+ - CHROUT and the file routines: all disk calls are made from one place
202
+ (`save.c`) on a frame outside the meter, never while another channel is
203
+ open.
204
+ - EXTCOL (frame_sync_loop, raster_profile_bars): the border is written only
205
+ by the verdict.
206
+
207
+ ## Budget
208
+
209
+ Command: `npx tsx src/cli.ts plan-budget adventure_database_engine two_word_parser text_input_line petscii_screen_code_conversion decimal_print mcm_text charset_copy_rom_to_ram:init kernal_file_write_seq:transition kernal_file_read_seq:transition error_channel_check:transition frame_sync_loop sid_voice_setup raster_profile_bars --region both --screen on`
210
+
211
+ ```text
212
+ # Budget plan: undetermined
213
+
214
+ Techniques: adventure_database_engine, two_word_parser, text_input_line, petscii_screen_code_conversion, decimal_print, mcm_text, charset_copy_rom_to_ram:init, kernal_file_write_seq:transition, kernal_file_read_seq:transition, error_channel_check:transition, frame_sync_loop, sid_voice_setup, raster_profile_bars
215
+
216
+ ## play (PAL, 19656 cycles a frame): undetermined
217
+
218
+ Range 19004 + 1075 fixed cycles; floor 0; weakest basis estimated; IRQ slots 0.
219
+
220
+ Summed:
221
+ - adventure_database_engine: 14908 (measured-vice, on oscar64-adventure-engine (one command's parse and turn, PAL, display on))
222
+ - two_word_parser: 2036 (measured-vice, on oscar64-two-word-parser (one command's parse, worst of ten, PAL, display on))
223
+ - text_input_line: 200 (estimated, recipe not stated)
224
+ - petscii_screen_code_conversion: 32 (measured-vice, on oscar64-petscii-screen-codes (one call, longest path))
225
+ - decimal_print: 1361 (measured-vice, on oscar64-print-number (one call, worst decimal case))
226
+ - raster_profile_bars: 467 (measured-vice, on oscar64-raster-profile-bars (worst frame, screen blanked))
227
+
228
+ To measure:
229
+ - mcm_text: no **Cost:** line; no recipe yet
230
+ - frame_sync_loop: the Cost line has no cycles_per_frame (nor cycles_per_line with lines_active); measure it on oscar64-frame-sync-loop
231
+ - sid_voice_setup: no **Cost:** line; measure it on oscar64-sid-music-player
232
+
233
+ Notes:
234
+ - Fixed losses 1075 cycles (badlines 25 × 43 = 1075, lines 51-243 every eighth with YSCROLL 3; arithmetic) charged because text_input_line, petscii_screen_code_conversion, decimal_print, raster_profile_bars are not stated as measured with the screen on. A stall takes its cycles wherever the code runs, so the charge is exact unless a figure already holds stalls: adventure_database_engine, two_word_parser were measured with the screen on and already hold the stalls that fell inside them, so the charge is too high by that much and the over test counts 0.
235
+ - The low end, 19004 + 1075, passes the 19656-cycle frame, but it is not a floor: the figures of adventure_database_engine, two_word_parser, text_input_line, petscii_screen_code_conversion, decimal_print, raster_profile_bars are a common frame or a real run's worst, and those frames need not fall together. adventure_database_engine, two_word_parser, text_input_line, petscii_screen_code_conversion, decimal_print, raster_profile_bars have no typical frame, so their low end is a worst frame. The floor, work every frame plus the loss no figure can hold, is 0 and fits. A frame measured whole, with every member running, would settle it.
236
+ - Unknown is not zero: mcm_text, frame_sync_loop, sid_voice_setup have no cycles figure, so the verdict cannot be fits.
237
+
238
+ ## play (NTSC, 17095 cycles a frame): undetermined
239
+
240
+ Range 19004 + 1075 fixed cycles; floor 0; weakest basis estimated; IRQ slots 0.
241
+
242
+ Summed:
243
+ - adventure_database_engine: 14908 (measured-vice, on oscar64-adventure-engine (one command's parse and turn, PAL, display on))
244
+ - two_word_parser: 2036 (measured-vice, on oscar64-two-word-parser (one command's parse, worst of ten, PAL, display on))
245
+ - text_input_line: 200 (estimated, recipe not stated)
246
+ - petscii_screen_code_conversion: 32 (measured-vice, on oscar64-petscii-screen-codes (one call, longest path))
247
+ - decimal_print: 1361 (measured-vice, on oscar64-print-number (one call, worst decimal case))
248
+ - raster_profile_bars: 467 (measured-vice, on oscar64-raster-profile-bars (worst frame, screen blanked))
249
+
250
+ To measure:
251
+ - mcm_text: no **Cost:** line; no recipe yet
252
+ - frame_sync_loop: the Cost line has no cycles_per_frame (nor cycles_per_line with lines_active); measure it on oscar64-frame-sync-loop
253
+ - sid_voice_setup: no **Cost:** line; measure it on oscar64-sid-music-player
254
+
255
+ Notes:
256
+ - Fixed losses 1075 cycles (badlines 25 × 43 = 1075, lines 51-243 every eighth with YSCROLL 3; arithmetic) charged because text_input_line, petscii_screen_code_conversion, decimal_print, raster_profile_bars are not stated as measured with the screen on. A stall takes its cycles wherever the code runs, so the charge is exact unless a figure already holds stalls: adventure_database_engine, two_word_parser were measured with the screen on and already hold the stalls that fell inside them, so the charge is too high by that much and the over test counts 0.
257
+ - The low end, 19004 + 1075, passes the 17095-cycle frame, but it is not a floor: the figures of adventure_database_engine, two_word_parser, text_input_line, petscii_screen_code_conversion, decimal_print, raster_profile_bars are a common frame or a real run's worst, and those frames need not fall together. adventure_database_engine, two_word_parser, text_input_line, petscii_screen_code_conversion, decimal_print, raster_profile_bars have no typical frame, so their low end is a worst frame. The floor, work every frame plus the loss no figure can hold, is 0 and fits. A frame measured whole, with every member running, would settle it.
258
+ - Unknown is not zero: mcm_text, frame_sync_loop, sid_voice_setup have no cycles figure, so the verdict cannot be fits.
259
+ - Cycles per frame are the pages' figures, most measured on PAL; the same code takes about the same cycles on NTSC, against a 17,095-cycle frame.
260
+
261
+ ## transition (PAL, 19656 cycles a frame): undetermined
262
+
263
+ Range 0 cycles; floor 0; weakest basis (nothing summed); IRQ slots 0.
264
+
265
+ To measure:
266
+ - kernal_file_write_seq: no **Cost:** line; measure it on kickassembler-file-io-roundtrip
267
+ - kernal_file_read_seq: no **Cost:** line; measure it on kickassembler-file-io-roundtrip
268
+ - error_channel_check: no **Cost:** line; measure it on kickassembler-dos-error-codes
269
+
270
+ Notes:
271
+ - Unknown is not zero: kernal_file_write_seq, kernal_file_read_seq, error_channel_check have no cycles figure, so the verdict cannot be fits.
272
+ - The transition phase is judged against one frame too; a transition that takes several frames drops frames, which may be acceptable there.
273
+
274
+ ## transition (NTSC, 17095 cycles a frame): undetermined
275
+
276
+ Range 0 cycles; floor 0; weakest basis (nothing summed); IRQ slots 0.
277
+
278
+ To measure:
279
+ - kernal_file_write_seq: no **Cost:** line; measure it on kickassembler-file-io-roundtrip
280
+ - kernal_file_read_seq: no **Cost:** line; measure it on kickassembler-file-io-roundtrip
281
+ - error_channel_check: no **Cost:** line; measure it on kickassembler-dos-error-codes
282
+
283
+ Notes:
284
+ - Unknown is not zero: kernal_file_write_seq, kernal_file_read_seq, error_channel_check have no cycles figure, so the verdict cannot be fits.
285
+ - The transition phase is judged against one frame too; a transition that takes several frames drops frames, which may be acceptable there.
286
+ - Cycles per frame are the pages' figures, most measured on PAL; the same code takes about the same cycles on NTSC, against a 17,095-cycle frame.
287
+
288
+ ## init (PAL, 19656 cycles a frame): undetermined
289
+
290
+ Range 0 cycles; floor 0; weakest basis (nothing summed); IRQ slots 0.
291
+
292
+ To measure:
293
+ - charset_copy_rom_to_ram: the Cost line has no cycles_per_frame (nor cycles_per_line with lines_active); measure it on kickassembler-charset-copy-rom-to-ram
294
+
295
+ Notes:
296
+ - Unknown is not zero: charset_copy_rom_to_ram has no cycles figure, so the verdict cannot be fits.
297
+ - The init phase is judged against one frame too; an init that takes several frames drops frames, which may be acceptable there.
298
+
299
+ ## init (NTSC, 17095 cycles a frame): undetermined
300
+
301
+ Range 0 cycles; floor 0; weakest basis (nothing summed); IRQ slots 0.
302
+
303
+ To measure:
304
+ - charset_copy_rom_to_ram: the Cost line has no cycles_per_frame (nor cycles_per_line with lines_active); measure it on kickassembler-charset-copy-rom-to-ram
305
+
306
+ Notes:
307
+ - Unknown is not zero: charset_copy_rom_to_ram has no cycles figure, so the verdict cannot be fits.
308
+ - The init phase is judged against one frame too; an init that takes several frames drops frames, which may be acceptable there.
309
+ - Cycles per frame are the pages' figures, most measured on PAL; the same code takes about the same cycles on NTSC, against a 17,095-cycle frame.
310
+
311
+ ## Bytes
312
+
313
+ Sum 2118 over charset_copy_rom_to_ram; a floor, since adventure_database_engine, two_word_parser, text_input_line, petscii_screen_code_conversion, decimal_print, mcm_text, kernal_file_write_seq, kernal_file_read_seq, error_channel_check, sid_voice_setup, raster_profile_bars state no bytes.
314
+ - frame_sync_loop: 985 bytes left out, the whole program, not the technique
315
+
316
+ ## Assumptions
317
+
318
+ - Region PAL and NTSC: PAL 19656, NTSC 17095 cycles a frame.
319
+ - Screen on: unless every summed figure says it was measured with the screen on, the 25 badlines × 43 cycles outside any band charge are charged.
320
+ - Low end: each member's cycles_per_frame_typical where the page states one (a common frame, or a real run's worst frame), else its worst frame. It is not a floor. Over is judged on the floor: band and per-line charges, which run every frame, plus the badline loss no summed figure can already hold.
321
+ - Each figure is the technique's own Cost line, measured on the recipe it names: another implementation can cost more or less.
322
+ - Claims, zero page and memory are not judged here; c64_check_compatibility judges claims and zero page.
323
+
324
+ ```
325
+
326
+ The tool sums one command's parse and turn (14,908 from the recipe, which
327
+ also decoded and printed its text inside the turn) with a separate parse
328
+ (2,036) into every play frame: 19,004 + 1,075. Neither is this program's
329
+ frame. Here a frame does one bounded job: take typed keys (and, on RETURN,
330
+ parse and run the turn, which only queues message numbers); or draw the
331
+ room picture; or print one line of the window (scroll 13 rows of screen and
332
+ colour RAM, then decode and word-wrap one line). The recipe's PRINT figure
333
+ (109,866 cycles for one command's output) is why the text is printed a line
334
+ a frame. The meter settles the real figure; mcm_text, frame_sync_loop and
335
+ sid_voice_setup have no cost line and are measured only inside the whole
336
+ frame. The disk calls run on frames outside the meter's bracket (the
337
+ transition phase), as the harness allows.
338
+
339
+ ## Memory and screen
340
+
341
+ - Code and data `$0880`-`$37FF`, then `$4000`-`$9FFF` if it grows (two
342
+ Oscar64 regions). Character set `$3800`-`$3FFF`: codes 0-63 the ROM
343
+ letters, 64-127 the picture tiles (multicolour), 128-255 the ROM reverse
344
+ glyphs. `$D018` = `$1E`. Screen `$0400`.
345
+ - Rows 0-6 the picture strip (colour RAM 8-15: multicolour); row 7 the status
346
+ bar; rows 8-21 the text window; row 22 a rule; row 23 the input line; row 24
347
+ the verdict (columns 0-19) and the meter (20-39) in AUTOPILOT builds. Text
348
+ colours are 0-7 so those cells stay hires under MCM.
349
+ - `$D021` black, `$D022` grey, `$D023` brown: shared by every picture.
350
+ - The KERNAL IRQ is off (CIA1 interrupts masked), so its `CLI`s are harmless;
351
+ the loop calls SCNKEY (`$FF9F`) itself once a frame.
352
+
353
+ ## Autopilot and checks
354
+
355
+ - The script is a list of commands in `tools/world.py`. Each frame at the
356
+ input line the autopilot puts up to ten bytes of the next command and its
357
+ RETURN into the KERNAL keyboard queue (`$0277`, count `$C6`), the bytes
358
+ SCNKEY puts there for a real key; the input line reads them back the same
359
+ way it reads a typist.
360
+ - The script walks the whole game: an unknown word, synonyms, a locked door,
361
+ containers opened and emptied, the dark cellar, SAVE, a mistake, LOAD, and
362
+ the ending at 100 points.
363
+ - `tools/gen.py` runs the same script through a Python model of the engine and
364
+ printer and writes what the game must end with: room, item locations,
365
+ flags, score, turns, a fold of every printed window line, and the play
366
+ frames (one per metered frame). The verdict compares, then sets `$02FF` and
367
+ the border. FORCE_FAULT scores one point less for the lens, so the status
368
+ bar, the ending line and the verdict change.
369
+ - `expect.json`: the verdict, the ending lines in the window, the status bar,
370
+ the input line, picture-strip cells of the tower, PAL = NTSC over the text
371
+ rows, and the meter with the model's frame count.
372
+ - The shot runs with a copy of the release D64 in a true-drive 1541, so SAVE
373
+ and LOAD in the script really write and read the disk. `make disktest`
374
+ proves save, cold reset, load and the same state back.
375
+
376
+ ## Decisions and open questions
377
+
378
+ - Text is packed by `tools/gen.py` at build time; the plain text is not in
379
+ the PRG. The first plan was a dictionary of common words; see below.
380
+ - Settled: the colour scroll went. With it the worst frame was 22,000
381
+ cycles on PAL and 22,087 on NTSC (meter); the typed command now shows in
382
+ reverse video and the window's colour RAM stays fixed.
383
+ - Measured (`make shot check`, 251 play frames, after the review's fixes):
384
+ worst 15,272 and typical 8,543 cycles on PAL; 15,488 and 8,842 on NTSC.
385
+ The worst is a window line (scroll plus decode). README.md, "The measured
386
+ frame", compares it with the budget above.
387
+ - Corrected in review: the first worst figure (15,262 / 15,476) left out
388
+ the library picture, which the script never drew: 20,240 cycles, over the
389
+ frame on both models. Pictures are now coded as runs and literals row by
390
+ row (the dearest, the garden, 12,483 PAL / 12,739 NTSC), and gen.py
391
+ refuses a script that does not show every picture.
392
+ - Settled: byte-pair packing of the text, 40.2 % smaller than C strings
393
+ with pointers; a word dictionary saved 18 % (tools/gen.py, arithmetic).
394
+ - Settled: the title and the ending act on a new fire press. Found with
395
+ tools/drive.py: a held fire at the ending went to the title and started a
396
+ new game.