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,679 @@
1
+ ---
2
+ recipe: tech-tech
3
+ toolchain: kickassembler
4
+ output_format: PRG
5
+ region: both
6
+ techniques: [tech_tech_wobbler, stable_raster_irq, pal_ntsc_detection]
7
+ file_formats: [PRG]
8
+ uses_registers: [D011, D012, D016, D018, D019, D01A, D020, D021, DC04, DC05, DC06, DC07, DC0E, DC0F]
9
+ uses_kernal: []
10
+ ---
11
+
12
+ <!-- doc-type: recipe -->
13
+
14
+ # KickAssembler recipe: a tech-tech, a character logo on a 63-pixel per-line sine through eight video matrices and XSCROLL
15
+
16
+ ## Synopsis
17
+
18
+ Puts the word WOBBLE, drawn in 3 by 5 block cells with a rule under it,
19
+ into eight 1 KB video matrices at `$2000` to `$3FFF`, each holding the
20
+ logo one cell further right than the last, and shows character rows 8 to
21
+ 13 (raster lines 115 to 162) with a different horizontal shift on every
22
+ line. The shift s for a line is 32 + round(31 sin) from a 256-entry
23
+ table, 1 to 63; s >> 3 picks the matrix through `$D018` and s & 7 goes
24
+ into XSCROLL. Because the VIC-II reads character codes only on a badline,
25
+ the code forces one on every line of the band the way FLI does: a stable
26
+ raster IRQ reaches a known cycle, and from there one unrolled block per
27
+ line writes `$D018`, `$D016` and then `$D011` with YSCROLL = line & 7,
28
+ timed so the badline condition arises after the cycle-14 row counter
29
+ check and before the c-accesses. The VIC then fetches the 40 codes again
30
+ on that line from the matrix just named. The first three cells of each
31
+ forced line get no fetch and show screen code 255 (the FLI bug), so the
32
+ logo lives in cells 3 to 39. The two register tables for the band are
33
+ rebuilt in the vertical blank each frame with the phase advanced by one;
34
+ after 300 frames the phase stops and the picture is static. CIA1 timer A
35
+ measures the band interrupt and timer B the table build. Built with
36
+ `:seven=1` the `$D018` table is a constant, so XSCROLL alone moves the
37
+ logo: the seven-pixel control. Built with `:pad=N` the per-line padding
38
+ is N instead of 3: the sweep. The technique is `tech_tech_wobbler` in
39
+ `techniques/effects-vector-3d.md`.
40
+
41
+ ## Source
42
+
43
+ ```asm
44
+ // tech-tech.asm
45
+ // A tech-tech: a character logo pushed sideways by a per-line sine of up
46
+ // to 63 pixels, which is eight character cells more than XSCROLL alone can
47
+ // move it. The VIC-II reads character codes (the c-accesses) only on a
48
+ // badline, into a 40-entry buffer it reuses for the next seven lines, so a
49
+ // text row cannot normally change its codes line by line. This program
50
+ // forces a badline on every line of the logo band the FLI way: on each
51
+ // line it writes YSCROLL = line & 7 into $D011 after cycle 14, so the row
52
+ // counter is not reset and rows still advance, and before the c-accesses,
53
+ // so the VIC fetches the 40 codes again on that line from whichever video
54
+ // matrix $D018 names at that moment. Eight matrices hold the same logo
55
+ // shifted right by 0 to 7 cells; the line's shift s in 0..63 selects the
56
+ // matrix s >> 3 and puts s & 7 into XSCROLL. The first three cells of each
57
+ // forced line keep no fetch (the FLI bug), so the logo lives in cells
58
+ // 3 to 39 and the strip at the left is measured on the page.
59
+ //
60
+ // The eight matrices sit at $2000 + k * $400, k = 0..7, in VIC bank 0.
61
+ // They cannot sit at $0400 + k * $400: the VIC sees the character ROM,
62
+ // not RAM, at $1000-$1FFF of banks 0 and 2, for every kind of access.
63
+ //
64
+ // Region: both. Separate unrolled bands for PAL (63-cycle line) and NTSC
65
+ // (65-cycle line), chosen at boot by detect_region. The per-line padding
66
+ // is a command line variable for the sweep: :pad=N sets the PAL block
67
+ // padding, the NTSC block gets two more. Default 3, the measured value.
68
+ // :seven=1 builds the control that keeps $D018 fixed and moves the logo
69
+ // with XSCROLL only.
70
+
71
+ .const D011 = $d011
72
+ .const D012 = $d012
73
+ .const D016 = $d016
74
+ .const D018 = $d018
75
+ .const D019 = $d019
76
+ .const D01A = $d01a
77
+ .const D020 = $d020
78
+ .const D021 = $d021
79
+ .const CIA_TALO = $dc04
80
+ .const CIA_TAHI = $dc05
81
+ .const CIA_TBLO = $dc06
82
+ .const CIA_TBHI = $dc07
83
+ .const CIA_CRA = $dc0e
84
+ .const CIA_CRB = $dc0f
85
+
86
+ // Band geometry: character rows 8 to 13, raster lines 115 to 162.
87
+ .const FIRST_LINE = 115 // row 8, line 0: a natural badline (115 & 7 = 3)
88
+ .const LAST_LINE = 162 // row 13, line 7
89
+ .const NLINES = LAST_LINE - FIRST_LINE + 1 // 48
90
+ .const SYNC_LINE = 112 // stable raster here; 112 & 7 = 0, not a badline
91
+ .const SYNC_PAD = 11 // as measured for stable-raster-irq and fli-image
92
+
93
+ // Padding, measured in VICE (see page). The block for line l is
94
+ // Delay(LINE_PAD) + 20 cycles of writes; its $D011 write is the block's
95
+ // last cycle. With LINE_PAD 3 the block is 23 cycles from the end of the
96
+ // previous line's stall, the same 23 as fli-image's LINE_PAD 11 + 12.
97
+ .var padVar = cmdLineVars.get("pad")
98
+ .const LINE_PAD_PAL = (padVar == null) ? 3 : padVar.asNumber()
99
+ .const LINE_PAD_NTSC = LINE_PAD_PAL + 2
100
+ .var sevenVar = cmdLineVars.get("seven")
101
+ .const SEVENONLY = (sevenVar != null)
102
+
103
+ // From the sync point to cycle 55 of FIRST_LINE, after its natural
104
+ // badline stall: fli-image's 197 (PAL) and 204 (NTSC), less the 14
105
+ // cycles of line 115's own two writes placed before the delay. Measured:
106
+ // 205 - 14 on NTSC put line 116's write one cycle late (four cells lost).
107
+ .const ENTRY_PAD_PAL = 197 - 14
108
+ .const ENTRY_PAD_NTSC = 204 - 14
109
+
110
+ .const MATRIX0 = $2000 // matrix k at MATRIX0 + k * $400
111
+ .const D016_BASE = $c8 // 40 columns, hires, XSCROLL 0
112
+ .function d018k(k) { .return ((8 + k) << 4) | $04 } // VM = 8 + k, CB = 2: ROM font at $1000
113
+ .function d011l(l) { .return $18 | (l & 7) } // text mode, DEN, RSEL, YSCROLL = l & 7
114
+
115
+ // Per-line register tables, rebuilt each frame in the vertical blank.
116
+ // Both in zero page so a block's loads take 3 cycles each.
117
+ .const D016_ZP = $02 // 48 bytes: $D016 value per band line
118
+ .const D018_ZP = $32 // 48 bytes: $D018 value per band line
119
+ .const ZP_PH = $fb // sine phase while building
120
+
121
+ .const SAVED_SP = $02e0
122
+ .const REG_FLAG = $02e1 // 0 = PAL, 1 = NTSC
123
+ .const FRAME_LO = $02e2 // frames advanced
124
+ .const FRAME_HI = $02e3
125
+ .const T = $02e4 // wave phase, +1 a frame until DONE
126
+ .const BAND_LO = $02e6 // CIA1 timer A: irq1 entry to band exit, last frame
127
+ .const BAND_HI = $02e7
128
+ .const TAB_LO = $02e8 // CIA1 timer B: one table build, last frame
129
+ .const TAB_HI = $02e9
130
+ .const DONE = $02ff // 1 once 300 frames have advanced
131
+
132
+ .macro Delay(n) {
133
+ .if (n < 2) .error "Delay needs >= 2 cycles"
134
+ .if ((n & 1) != 0) { bit $ea }
135
+ .for (var i = 0; i < ((n & 1) != 0 ? n - 3 : n) / 2; i++) { nop }
136
+ }
137
+
138
+ // ---------------------------------------------------------------------------
139
+ // The logo: the word WOBBLE in 3 by 5 block letters with one blank cell
140
+ // between letters, 23 cells wide, and a 23-cell rule under it as row 6.
141
+ // Cell $A0 is the reversed space, a solid block in the cell's colour.
142
+ // ---------------------------------------------------------------------------
143
+ .const WORD = "WOBBLE"
144
+ .const LOGO_W = 23
145
+ .var font = Hashtable()
146
+ .eval font.put("W", List().add("X.X", "X.X", "X.X", "XXX", "X.X"))
147
+ .eval font.put("O", List().add("XXX", "X.X", "X.X", "X.X", "XXX"))
148
+ .eval font.put("B", List().add("XX.", "X.X", "XX.", "X.X", "XX."))
149
+ .eval font.put("L", List().add("X..", "X..", "X..", "X..", "XXX"))
150
+ .eval font.put("E", List().add("XXX", "X..", "XX.", "X..", "XXX"))
151
+
152
+ .function logoCell(r, c) {
153
+ .if (r == 5) .return $a0
154
+ .var lc = mod(c, 4)
155
+ .if (lc == 3) .return $20
156
+ .var glyph = font.get(WORD.substring(floor(c / 4), floor(c / 4) + 1))
157
+ .return (glyph.get(r).charAt(lc) == 'X') ? $a0 : $20
158
+ }
159
+
160
+ // Matrix k, cell i: the logo in rows 8..13 from column 3 + k.
161
+ .function matrixCell(k, i) {
162
+ .var r = floor(i / 40)
163
+ .var c = mod(i, 40) - 3 - k
164
+ .if (r < 8 || r > 13 || c < 0 || c >= LOGO_W) .return $20
165
+ .return logoCell(r - 8, c)
166
+ }
167
+
168
+ .for (var k = 0; k < 8; k++) {
169
+ * = MATRIX0 + k * $400
170
+ .fill 1000, matrixCell(k, i)
171
+ }
172
+
173
+ // ---------------------------------------------------------------------------
174
+ // Tables
175
+ // ---------------------------------------------------------------------------
176
+ * = $1c00
177
+ // s(i) = 32 + round(31 sin(2 pi i / 256)), 1..63. Amplitude 31 so that no
178
+ // entry reaches 64 (pitfalls/maths.md, sine_table_peak_wraps_to_zero).
179
+ sine: .fill 256, 32 + round(31 * sin(toRadians(i * 360 / 256)))
180
+ // s -> register values, s in 0..63.
181
+ s2d018: .fill 64, SEVENONLY ? d018k(4) : d018k(i >> 3)
182
+ s2d016: .fill 64, D016_BASE | (i & 7)
183
+
184
+ // ---------------------------------------------------------------------------
185
+ // Setup
186
+ // ---------------------------------------------------------------------------
187
+ BasicUpstart2(start)
188
+
189
+ * = $0900
190
+ start:
191
+ sei
192
+ lda #$7f
193
+ sta $dc0d
194
+ lda $dc0d
195
+ sta $dd0d
196
+ lda $dd0d
197
+
198
+ lda #0
199
+ sta D020
200
+ sta D021
201
+ sta FRAME_LO
202
+ sta FRAME_HI
203
+ sta T
204
+ sta DONE
205
+ lda #1 // colour RAM white everywhere
206
+ ldx #0
207
+ !: sta $d800, x
208
+ sta $d900, x
209
+ sta $da00, x
210
+ sta $dae8, x
211
+ inx
212
+ bne !-
213
+
214
+ lda #D016_BASE
215
+ sta D016
216
+ lda #d018k(0)
217
+ sta D018
218
+ lda #$1b
219
+ sta D011
220
+
221
+ jsr detect_region // returns with interrupts enabled
222
+ sei
223
+ jsr build_tables
224
+
225
+ lda #<vblank_irq
226
+ sta $0314
227
+ lda #>vblank_irq
228
+ sta $0315
229
+ lda #251
230
+ sta D012
231
+ lda #$01
232
+ sta D01A
233
+ sta D019
234
+ cli
235
+ jmp *
236
+
237
+ // detect_region: REG_FLAG = 0 (PAL) or 1 (NTSC), as in pseudo-3d-road.
238
+ // Tracks $D012 while RST8 is set; the last value is $37 on PAL, $06 or $05
239
+ // on NTSC. Call with SEI; returns with CLI.
240
+ detect_region:
241
+ sei
242
+ dr_wait_lo:
243
+ bit D011
244
+ bmi dr_wait_lo
245
+ dr_wait_hi:
246
+ bit D011
247
+ bpl dr_wait_hi
248
+ dr_track:
249
+ lda D012
250
+ bit D011
251
+ bpl dr_band_over
252
+ tax
253
+ jmp dr_track
254
+ dr_band_over:
255
+ lda #0
256
+ cpx #$10
257
+ bcs dr_set_flag
258
+ lda #1
259
+ dr_set_flag:
260
+ sta REG_FLAG
261
+ cli
262
+ rts
263
+
264
+ // build_tables: for band line l = 0..47, s = sine[(T + 3 l) & 255],
265
+ // D018_ZP[l] = s2d018[s], D016_ZP[l] = s2d016[s].
266
+ build_tables:
267
+ lda T
268
+ sta ZP_PH
269
+ ldx #0
270
+ bt_lp:
271
+ ldy ZP_PH
272
+ lda sine, y
273
+ tay
274
+ lda s2d018, y
275
+ sta D018_ZP, x
276
+ lda s2d016, y
277
+ sta D016_ZP, x
278
+ lda ZP_PH
279
+ clc
280
+ adc #3
281
+ sta ZP_PH
282
+ inx
283
+ cpx #NLINES
284
+ bne bt_lp
285
+ rts
286
+
287
+ // ---------------------------------------------------------------------------
288
+ // vblank_irq, line 251: build next frame's tables (timed), count the frame,
289
+ // arm irq1 for the band.
290
+ // ---------------------------------------------------------------------------
291
+ vblank_irq:
292
+ cld
293
+ lda #$ff
294
+ sta CIA_TBLO
295
+ sta CIA_TBHI
296
+ lda #$11
297
+ sta CIA_CRB
298
+ jsr build_tables
299
+ lda #0
300
+ sta CIA_CRB
301
+ sec
302
+ lda #$ff
303
+ sbc CIA_TBLO
304
+ sta TAB_LO
305
+ lda #$ff
306
+ sbc CIA_TBHI
307
+ sta TAB_HI
308
+
309
+ lda DONE
310
+ bne vb_arm
311
+ inc T
312
+ inc FRAME_LO
313
+ bne !+
314
+ inc FRAME_HI
315
+ !: lda FRAME_LO
316
+ cmp #<300
317
+ bne vb_arm
318
+ lda FRAME_HI
319
+ cmp #>300
320
+ bne vb_arm
321
+ lda #1
322
+ sta DONE // T stays at 300 from here: the picture is static
323
+ vb_arm:
324
+ lda #<irq1
325
+ sta $0314
326
+ lda #>irq1
327
+ sta $0315
328
+ lda #SYNC_LINE - 3
329
+ sta D012
330
+ lda #$1b
331
+ sta D011
332
+ lda #$01
333
+ sta D019
334
+ pla
335
+ tay
336
+ pla
337
+ tax
338
+ pla
339
+ rti
340
+
341
+ // ---------------------------------------------------------------------------
342
+ // Double IRQ, as in stable-raster-irq and fli-image. irq1 at SYNC_LINE - 3
343
+ // starts the band timer, picks the band for the model and arms irq2 at
344
+ // SYNC_LINE - 1; irq2 fires inside the NOP slide and returns through
345
+ // irq1's stack frame.
346
+ // ---------------------------------------------------------------------------
347
+ irq1:
348
+ cld // irq2 fires inside this handler and inherits D clear
349
+ lda #$ff
350
+ sta CIA_TALO
351
+ sta CIA_TAHI
352
+ lda #$11
353
+ sta CIA_CRA
354
+ lda REG_FLAG
355
+ bne i1_ntsc
356
+ lda #<irq2_pal
357
+ sta $0314
358
+ lda #>irq2_pal
359
+ sta $0315
360
+ jmp i1_common
361
+ i1_ntsc:
362
+ lda #<irq2_ntsc
363
+ sta $0314
364
+ lda #>irq2_ntsc
365
+ sta $0315
366
+ i1_common:
367
+ lda #SYNC_LINE - 1
368
+ sta D012
369
+ lda #$01
370
+ sta D019
371
+ tsx
372
+ stx SAVED_SP
373
+ cli
374
+ .for (var i = 0; i < 40; i++) { nop }
375
+ pla
376
+ tay
377
+ pla
378
+ tax
379
+ pla
380
+ rti
381
+
382
+ // One band: sync, line 115's own registers before its natural badline, the
383
+ // entry delay to cycle 55 of line 115, then one block per line 116..162.
384
+ // Each block starts on cycle 55 of the previous line, where the stall
385
+ // leaves the CPU, and its $D011 write is its last cycle: LINE_PAD + 20.
386
+ .macro Band(entryPad, linePad) {
387
+ lda D018_ZP + 0 // 3 line 115: matrix and XSCROLL for its natural fetch
388
+ sta D018 // 4
389
+ lda D016_ZP + 0 // 3
390
+ sta D016 // 4
391
+ Delay(entryPad)
392
+ .for (var l = 1; l < NLINES; l++) {
393
+ Delay(linePad)
394
+ lda D018_ZP + l // 3
395
+ sta D018 // 4
396
+ lda D016_ZP + l // 3
397
+ sta D016 // 4
398
+ lda #d011l(FIRST_LINE + l) // 2
399
+ sta D011 // 4 forces this line's badline
400
+ }
401
+ }
402
+
403
+ irq2_pal:
404
+ ldx SAVED_SP
405
+ txs
406
+ Delay(SYNC_PAD)
407
+ lda D012
408
+ cmp D012
409
+ beq !+
410
+ !: Band(ENTRY_PAD_PAL, LINE_PAD_PAL)
411
+ jmp band_done
412
+
413
+ irq2_ntsc:
414
+ ldx SAVED_SP
415
+ txs
416
+ Delay(SYNC_PAD)
417
+ lda D012
418
+ cmp D012
419
+ beq !+
420
+ !: Band(ENTRY_PAD_NTSC, LINE_PAD_NTSC)
421
+
422
+ // band_done: cycle 55 of LAST_LINE. Normal registers back so line 163 is
423
+ // a natural badline from matrix 0; stop the timer; arm the vertical blank.
424
+ band_done:
425
+ lda #$1b
426
+ sta D011
427
+ lda #d018k(0)
428
+ sta D018
429
+ lda #D016_BASE
430
+ sta D016
431
+ lda #0
432
+ sta CIA_CRA
433
+ cld
434
+ sec
435
+ lda #$ff
436
+ sbc CIA_TALO
437
+ sta BAND_LO
438
+ lda #$ff
439
+ sbc CIA_TAHI
440
+ sta BAND_HI
441
+ lda #<vblank_irq
442
+ sta $0314
443
+ lda #>vblank_irq
444
+ sta $0315
445
+ lda #251
446
+ sta D012
447
+ lda #$01
448
+ sta D019
449
+ pla
450
+ tay
451
+ pla
452
+ tax
453
+ pla
454
+ rti
455
+ ```
456
+
457
+ ## Build
458
+
459
+ ```bash
460
+ java -jar KickAss.jar tech-tech.asm -o tech-tech.prg
461
+ ```
462
+
463
+ For the seven-pixel control, in which `$D018` is the same on every line:
464
+
465
+ ```bash
466
+ java -jar KickAss.jar tech-tech.asm :seven=1 -o tech-tech-seven.prg
467
+ ```
468
+
469
+ For the placement sweep, N from 2 to 6:
470
+
471
+ ```bash
472
+ java -jar KickAss.jar tech-tech.asm :pad=N -o tech-tech-padN.prg
473
+ ```
474
+
475
+ `-showmem` reports the code at `$0900` to `$1221` (2,338 bytes, most of
476
+ it the two unrolled bands), the tables at `$1C00` to `$1D7F` (384 bytes)
477
+ and the eight matrices at `$2000`, `$2400`, ... `$3C00`, 1,000 bytes each.
478
+ The PRG is 14,313 bytes.
479
+
480
+ ## Expected output
481
+
482
+ A black screen. From raster line 115 to 162 the word WOBBLE in white
483
+ block cells, 23 cells wide and six rows tall including the rule under it,
484
+ each raster line of it shifted right by its own s between 1 and 63
485
+ pixels, so that the letters shear across the band; the phase steps by
486
+ three table entries a line, so the 48 lines cover about half a wave and
487
+ the shear runs one way. Down the left of the band, on lines 116 to 162,
488
+ three cells of screen code 255 in a colour that is not the logo's white:
489
+ the FLI bug strip, see below. Line 115 has no strip. The rest of the
490
+ screen is empty. After 300 frames the wave stops moving.
491
+
492
+ Measured in VICE x64sc 3.10 with the pinned command at 12,000,000
493
+ cycles on both models: `$02E2` and `$02E3` read 300 (frames advanced),
494
+ `$02FF` read `01`, and the picture is byte-identical across two runs on
495
+ each model (PAL MD5 `001c304d…`, NTSC `f61dcf58…`). The PAL picture has
496
+ 5,312 white pixels in PNG rows 99 to 146 (raster 115 to 162) and columns
497
+ 57 to 302; the NTSC picture the same 5,312 in rows 87 to 134, the same
498
+ columns.
499
+
500
+ With the phase held at 300, band line l (raster 115 + l) shows s =
501
+ sine[(300 + 3 l) & 255], matrix k = s >> 3 and XSCROLL = s & 7, so the
502
+ logo's left edge sits at display pixel 24 + s, PNG column 56 + s. Five
503
+ lines, measured with PIL against the table the listing builds:
504
+
505
+ | Raster line | s | k | XSCROLL | Edge from the table (56 + s) | First white pixel, PAL | First white pixel, NTSC | First white pixel, `:seven=1` |
506
+ |---|---|---|---|---|---|---|---|
507
+ | 116 | 60 | 7 | 4 | 116 | 116 | 116 | 92 |
508
+ | 131 | 56 | 7 | 0 | 112 | 112 | 112 | 88 |
509
+ | 143 | 32 | 4 | 0 | 88 | 88 | 88 | 88 |
510
+ | 156 | 7 | 0 | 7 | 63 | 63 | 63 | 95 |
511
+ | 162 | 1 | 0 | 1 | 57 | 57 | 57 | 89 |
512
+
513
+ All 48 lines agree with the table on both models, not only these five.
514
+ The `:seven=1` control holds k at 4 (the logo from cell 7, pixel 88) and
515
+ its edge is 88 + XSCROLL: the same XSCROLL values, an amplitude of seven
516
+ pixels instead of 63. Its picture is `figures/tech-tech-seven-12000000.png`.
517
+
518
+ **The FLI bug strip.** Classifying every band line's first twelve cells
519
+ in the PAL pin: line 115 has cells 0 to 2 black and the logo from cell
520
+ 10; lines 116 to 162 have cells 0 to 2 filled with one glyph whose rows
521
+ are `$0F $0F $0F $0F $F0 $F0 $F0 $F0`, which is screen code 255 in the
522
+ uppercase ROM (read from the VICE `chargen` image), and the logo from
523
+ cell 3 + k. The strip's colour is not the cell's colour RAM (white): it
524
+ is purple (index 4) on lines 116 to 161 and medium grey (12) on line 162
525
+ in the PAL picture, purple on 116 to 161 and brown (9) on line 162 in the
526
+ NTSC picture, and light red (10) on lines 116 to 161 in the `:pad=2` and
527
+ `:pad=4` builds. In each case the low nibble matches the opcode byte the
528
+ CPU fetches next after the `$D011` write (`bit $ea` is `$24`, `nop` is
529
+ `$EA`, the code after the last block begins `lda #`, `$A9`), except the
530
+ PAL line 162, where it does not; how VICE chooses the byte was not read
531
+ for this page, and nothing here says what a 6569 or 6567 shows.
532
+
533
+ **The placement sweep.** `:pad=N` makes each block N + 20 cycles from
534
+ the end of the previous line's stall. PAL, 12,000,000 cycles, one run
535
+ each:
536
+
537
+ | pad | Block, cycles | `$D011` write, model cycle | Cells with no fetch | What the picture shows |
538
+ |---|---|---|---|---|
539
+ | 2 | 22 | 14 | cells 0 and 1 show code 255 | The row counter is reset every line: the band shows only the top pixel row of the letters, sheared, and the whole logo is drawn again unshifted from line 163 to 210. 10,304 white pixels in rows 99 to 194. `figures/tech-tech-pad2-12000000.png` |
540
+ | 3 | 23 | 15 | cells 0 to 2 show code 255 | Correct: the pinned picture |
541
+ | 4 | 24 | 16 | cell 0 keeps the last full fetch (a space), cells 1 to 3 show code 255 | Lines with k = 0 lose the logo's first cell: line 162 first white at 65, not 57. `figures/tech-tech-pad4-12000000.png` |
542
+ | 5 | 25 | 17 | cells 0 and 1 stale, 2 to 4 code 255 | Line 162 first white at 73 |
543
+ | 6 | 26 | 18 | cells 0 to 2 stale, 3 to 5 code 255 | Line 162 first white at 81 |
544
+
545
+ The model cycle is the block length less eight, the numbering
546
+ `fli-image` uses for its own 23-cycle block; the padding is the
547
+ measurement. One cycle early loses one cell fewer and resets the row
548
+ counter; each cycle late loses one cell more, and the cells that miss
549
+ their fetch on the early side of the three are not code 255 but whatever
550
+ the buffer held from the last complete fetch, here line 115's spaces.
551
+ Nothing in the sweep produced a plain, unwobbled logo: a write late
552
+ enough to miss the badline window altogether was not tried.
553
+
554
+ On NTSC the block is `LINE_PAD_NTSC` = 5, 25 cycles of a 65-cycle line,
555
+ and the entry delay 204 - 14. With 205 - 14, which `fli-image` suggested
556
+ would be right for the 6567R8, line 116 came out one cycle late (cell 0
557
+ stale, 1 to 3 code 255) and lines 117 to 162 correct; with 204 - 14 all
558
+ 47 forced lines are correct. The remaining lines of both models were
559
+ identical in the two settings, because from the first block onwards each
560
+ line is timed by its own stall.
561
+
562
+ Screenshots from the VICE runs this page describes:
563
+ `screenshots/tech-tech.png` (PAL) and `screenshots/tech-tech-ntsc.png`.
564
+
565
+ The timer figures, read from the running machine with a `-moncommands`
566
+ file that traces the store to `$02FF` and dumps `$02E0` to `$02FF` at
567
+ the 300th frame, no overhead removed (the timer's own start and stop
568
+ instructions are inside the count, 16 cycles at the start and the stop
569
+ sequence after the last write):
570
+
571
+ | | PAL | NTSC |
572
+ |---|---|---|
573
+ | Band interrupt, `irq1` entry on line 109 to the register restore after line 162, CIA1 timer A | 3,405 | 3,508 |
574
+ | Table build in the vertical blank, 48 lines, CIA1 timer B | 2,041 | 2,041 |
575
+
576
+ Per band line, 63 cycles elapse on PAL and 65 on NTSC; the CPU sees 23
577
+ of them (cycles 55 to 63 of the previous line and 1 to 15 of its own on
578
+ PAL, 25 on NTSC) and every one is spent in the block. The band interrupt
579
+ is 54 raster lines, 109 to 162, of which the first three are the double
580
+ IRQ's entry and the sync (arithmetic from the listing; the timer figure
581
+ is the measurement).
582
+
583
+ ## Why this works
584
+
585
+ ### Why the matrix can change per line at all
586
+
587
+ `hardware/vic-ii-reference.md` states the constraint and the lever: "The
588
+ chip fetches one character pointer (c-access) per cell during the badline
589
+ of each text row, caches it in an internal 40x12-bit row buffer, and then
590
+ performs eight g-accesses per cell over the next eight raster lines", and
591
+ the badline condition is "($30 <= raster <= $F7) AND (raster & 7 ==
592
+ YSCROLL) AND DEN was set on $30", evaluated every cycle. Writing YSCROLL
593
+ = line & 7 on a line makes the condition true on that line; the VIC then
594
+ performs the 40 c-accesses on cycles 15 to 54 from the matrix `$D018`
595
+ names, and the g-accesses that follow on the same line read the new
596
+ buffer. `fli-image` uses this to change colours per line in bitmap mode;
597
+ here the same fetch changes the character codes, so the row of cells that
598
+ the line draws is a different row of a differently shifted logo.
599
+
600
+ The two timing constraints are `fli-image`'s. The write must land after
601
+ the cycle-14 check, where the VIC resets the row counter RC to 0 if the
602
+ condition already holds, or the band displays pixel row 0 of every cell
603
+ on every line and never advances: that is the `:pad=2` picture, with the
604
+ logo drawn again below the band because VCBASE was never moved on. And
605
+ the write must land before the c-accesses' slots have passed: the three
606
+ cells whose slot is over when BA falls read screen code 255 with a colour
607
+ nibble from the data bus. That is the strip, and three cells is the least
608
+ the trick costs; each cycle later costs one more, as the sweep shows.
609
+
610
+ ### The stall is the loop counter
611
+
612
+ After the `$D011` write the CPU's next cycle is an instruction fetch, a
613
+ read, and the VIC holds BA low until cycle 54, so the CPU stands still
614
+ until cycle 55 whatever it was about to do. Every block therefore begins
615
+ on cycle 55 of the previous line and only the 23 cycles from there to the
616
+ write need counting: `Delay(3)`, then three loads and three stores. Both
617
+ tables are in zero page so the loads take three cycles; with absolute
618
+ loads the block would be 25 cycles and the write two cycles late. There
619
+ is no room for an index register or a branch inside the block, so the
620
+ band is unrolled, 47 blocks per model, and the per-line values are
621
+ tables rather than code.
622
+
623
+ Line 115 is different: it is row 8's natural badline (115 & 7 = 3 with
624
+ YSCROLL 3 from the exit of the previous frame), so its fetch is complete
625
+ and it has no strip. Its two register values are written before the
626
+ entry delay, on line 112, and the natural stall on line 115 leaves the
627
+ CPU at cycle 55 for the first block, line 116. The exit after line 162
628
+ restores YSCROLL 3, matrix 0 and XSCROLL 0 in the right border of line
629
+ 162, so line 163 is row 14's natural badline, from an empty matrix.
630
+
631
+ ### Eight matrices, and where they cannot go
632
+
633
+ Matrix k holds the logo from cell 3 + k, so the pair (matrix s >> 3,
634
+ XSCROLL s & 7) puts the left edge at pixel 24 + s for every s from 0 to
635
+ 63; the table's amplitude is 31 about 32 so no entry reaches 64
636
+ (`pitfalls/maths.md`, `sine_table_peak_wraps_to_zero`). The matrices are
637
+ in VIC bank 0 at `$2000` to `$3FFF`, not at `$0400` to `$23FF`: the VIC
638
+ sees the character ROM in place of RAM at `$1000` to `$1FFF` of banks 0
639
+ and 2 for every kind of access, so four matrices there would fetch codes
640
+ from the font, not from the logo. The `$D018` value for matrix k is
641
+ `((8 + k) << 4) | $04`: VM nibble 8 + k, CB 2 for the ROM font at
642
+ `$1000`.
643
+
644
+ ### Where the work runs
645
+
646
+ The band takes 54 raster lines a frame and the table build about 2,041
647
+ cycles in the vertical blank; the rest of the frame is free. A second
648
+ sine, a colour wash through `$D021` in the same blocks, or a taller band
649
+ all fit; a taller band costs 63 cycles a line and nothing else, until the
650
+ tables outgrow zero page.
651
+
652
+ ### Region
653
+
654
+ `detect_region` sets a flag at boot and `irq1` picks the PAL or NTSC band
655
+ from it, as `pseudo-3d-road` does. The NTSC band's blocks have two more
656
+ cycles of padding for the 65-cycle line of the 6567R8, which is VICE's
657
+ `-model ntsc`, and a different entry delay; the c-accesses still occupy
658
+ cycles 15 to 54 and the stall still ends on cycle 55, so the block
659
+ structure is the same. The 64-cycle 6567R56A was not run.
660
+
661
+ ## What it does not establish
662
+
663
+ **Real hardware.** Every figure above is VICE 3.10. The strip's colour in
664
+ particular is whatever the emulator puts on the data bus during the three
665
+ missed fetches; a 6569 or 6567 may show another colour, or a colour that
666
+ changes with what the CPU is doing.
667
+
668
+ **More than 64 pixels.** Eight matrices give eight cells of shift plus
669
+ seven pixels; a wider wave needs more matrices in the same bank or a
670
+ smaller logo moved by both matrix and code. Neither was built.
671
+
672
+ **NTSC beyond the pin.** The NTSC picture and the two timer figures are
673
+ one build at one cycle count; the 6567R56A and the entry delay's exact
674
+ cycle on NTSC were not settled here.
675
+
676
+ **The old-fetch cells.** The sweep shows that the cells lost on the early
677
+ side of a late write keep the last complete fetch; which fetch that is
678
+ when the band starts on a forced line rather than a natural one was not
679
+ measured.