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,813 @@
1
+ ---
2
+ region: PAL+NTSC
3
+ ---
4
+
5
+ # PAL vs NTSC Region Reference
6
+
7
+ ## Overview
8
+
9
+ The Commodore 64 shipped in two main video regions that are mostly software-
10
+ compatible but differ in clock rate, frame timing, raster geometry, and SID
11
+ audio frequency. Code that does not account for the region difference will
12
+ exhibit one or more of: music played at the wrong tempo, raster IRQs that
13
+ fire on the wrong line, sprite multiplexers that overflow the visible area,
14
+ side-border-opening tricks that fail outright, and digi playback that pitches
15
+ up or down by roughly 4%.
16
+
17
+ The two regions covered by this document are:
18
+
19
+ - **PAL** — used in Europe, Australia, parts of South America, and most of
20
+ Asia. Driven by a 17.734472 MHz crystal divided by 18 (some sources give
21
+ 17.734475 MHz, four times the PAL colour subcarrier; the 0.17 Hz that
22
+ makes on the CPU clock is below anything measured here — an earlier
23
+ version of this line paired 17.734475 with the 985,248.444 Hz quotient
24
+ below, which belongs to 17.734472), a CPU clock of approximately
25
+ 985,248 Hz. Frame rate is 50 Hz, 312 scanlines per frame,
26
+ 63 cycles per scanline.
27
+ - **NTSC** — used in the United States, Canada, Japan, and Mexico. Driven by
28
+ a 14.31818 MHz crystal, divides down to a CPU clock of approximately
29
+ 1,022,727 Hz. Frame rate is ~59.826 Hz (commonly called "60 Hz"), 263
30
+ scanlines per frame, 65 cycles per scanline.
31
+
32
+ Two minor variants — **PAL-N** (Argentina/Paraguay/Uruguay; the Drean
33
+ C64, VIC 6572) and **PAL-M** (Brazil) — are out of scope for the tables
34
+ in this reference, but they do NOT share PAL CPU timing, as an earlier
35
+ version of this page said. Measured in VICE x64sc with `-model drean`
36
+ (not on a 6572 on a bench): 312 raster lines of **65** cycles, 20,280
37
+ cycles per frame, CPU clock about 1.0234 MHz (1,023,451 cycles/s read
38
+ against the CIA TOD; VICE's own constant is 1,023,440). That is an
39
+ NTSC-length line on a PAL-length frame. Consequences: a per-frame CIA
40
+ timer needs $4F37 (20,279) there, not $4CC7; any loop padded to 63
41
+ cycles per line drifts 2 cycles per line, so PAL stable-raster and
42
+ side-border code loses sync; the SID clock follows the CPU clock, so
43
+ PAL frequency tables play about 3.9 % sharp (1,023,440 / 985,248) — use
44
+ NTSC-derived tables. Frame rate is 50.46 Hz, so per-frame music tempo
45
+ is within 1 % of PAL. All three detection methods below report PAL-N
46
+ as PAL (max raster 311, frame time $4F38 >= $4800, KERNAL $02A6 = 1).
47
+ PAL-M is unmeasured here: VICE has no PAL-M model, so do not assume it
48
+ shares PAL timing either.
49
+
50
+ Sources for this document: c64-wiki PAL article, c64-wiki NTSC article,
51
+ codebase64 PAL/NTSC compatibility wiki, and the Bauer "VIC-II Article"
52
+ (cebix mirror).
53
+
54
+ ## Quick reference
55
+
56
+ | Property | PAL (6569) | NTSC (6567R8) | NTSC-old (6567R56A) |
57
+ |-------------------------|------------------------|------------------------|------------------------|
58
+ | CPU clock | 985,248.444 Hz | 1,022,727.143 Hz | 1,022,727.143 Hz |
59
+ | Dot clock | 7,881,987 Hz | 8,181,817 Hz | 8,181,817 Hz |
60
+ | Frame rate (nominal) | 50.125 Hz | 59.826 Hz | 60.993 Hz |
61
+ | Scanlines per frame | 312 | 263 | 262 |
62
+ | Cycles per scanline | 63 | 65 | 64 |
63
+ | Cycles per frame | 19,656 | 17,095 | 16,768 |
64
+ | Visible Y range (Bauer, not measured here) | 16-299 (284 lines) | 41-262 then 0-12 (235 lines) | 41-261 then 0-12 (234 lines) |
65
+ | Visible X range (cycles)| 12-59 (approx) | 14-61 (approx) | 13-60 (approx) |
66
+ | First badline (default) | $33 (51) | $33 (51) | $33 (51) |
67
+ | Last badline (default) | $F3 (243) | $F3 (243) | $F3 (243) |
68
+ | $D012 wraps at line | 312 (back to 0) | 263 (back to 0) | 262 (back to 0) |
69
+ | Vertical blank starts | line 300 | line 13 | line 13 |
70
+ | Top border opens at | line 51 ($33) | line 51 ($33) | line 51 ($33) |
71
+ | Bottom border opens at | line 251 ($FB) | line 251 ($FB) | line 251 ($FB) |
72
+ | Side border CSEL write | cycle 56 (one cycle) | not measured here | not measured here |
73
+ | CIA timer A for frame | $4CC7 (19,655) | $42C6 (17,094) | $417F (16,767) |
74
+
75
+ Note on $D012 wrap: $D012 is only 8 bits wide. The 9th bit lives in
76
+ $D011 bit 7 (RST8). PAL frames see $D012 take values 0..255 with RST8=0
77
+ followed by 0..55 with RST8=1, then wrap; NTSC frames see 0..255 with
78
+ RST8=0 followed by 0..6 with RST8=1, then wrap. See
79
+ `d012_wrap_around` in [raster-and-badline.md](../pitfalls/raster-and-badline.md)
80
+ for the RST8 set/clear pattern, and `raster_line_count_difference` in
81
+ [region-timing.md](../pitfalls/region-timing.md) for the per-region wrap
82
+ point.
83
+
84
+ ## Timing table — detailed
85
+
86
+ ### Cycles per frame
87
+
88
+ PAL frames are 19,656 cycles long (312 lines × 63 cycles). NTSC frames
89
+ on the modern 6567R8 are 17,095 cycles (263 × 65). The older 6567R56A
90
+ NTSC chip uses 262 lines × 64 cycles = 16,768 cycles per frame; the
91
+ R56A is uncommon and is reported to have shipped only in the earliest
92
+ U.S. machines (production history from published sources, not verified
93
+ here). Any code that assumes a fixed cycle count per frame must be
94
+ parameterized per region. PAL-N (6572): 312 × 65 = 20,280 cycles per
95
+ frame, measured in VICE x64sc `-model drean`.
96
+
97
+ A PAL frame is roughly 15% longer than an NTSC frame in cycles (19,656
98
+ vs 17,095) but about 19% longer in time (19.95 ms vs 16.71 ms), because
99
+ the NTSC CPU clock is also 3.8% faster. That means:
100
+
101
+ - A music routine called once per frame plays about 19% faster on NTSC
102
+ (59.83 Hz vs 50.12 Hz frames; measured in VICE x64sc as 600 vs 502
103
+ frames per 10 s of CIA TOD time). An earlier version of this page said
104
+ 15%, which is the cycle-count ratio — it describes the CPU budget per
105
+ frame, not tempo. See [Music tempo](#music-tempo).
106
+ - A demo effect that consumes N cycles per frame has 2,561 more cycles
107
+ to work with on PAL.
108
+ - A raster split that "just barely fits" on PAL may not fit on NTSC
109
+ because each scanline is 2 cycles longer (giving more time per line)
110
+ but each frame contains 49 fewer scanlines (50 on the R56A, whose
111
+ lines are only 1 cycle longer) to work with — the cycle budget is
112
+ what matters, not the line count.
113
+
114
+ ### Visible region
115
+
116
+ The "visible region" is the rectangle of raster lines where the VIC-II
117
+ generates picture content (as opposed to vertical or horizontal blanking).
118
+ Lines outside the visible Y range still execute on the CPU, but anything
119
+ drawn there will be off-screen.
120
+
121
+ PAL picture lines are 16-299 (284 lines; vertical blank 300-15). NTSC
122
+ picture lines are 41-262 wrapping to 0-12 (235 lines on the R8, 234 on
123
+ the R56A; vertical blank 13-40). These spans are from Bauer's VIC-II
124
+ article and are not measured here; what is measured (VICE x64sc 3.10)
125
+ is the frame length: maximum raster line 311 PAL, 262 R8, 261 R56A. An
126
+ earlier revision of this page gave 16-287 (272 lines) for PAL and
127
+ 41-300 (260 lines) for NTSC — the PAL figure is VICE's default
128
+ screenshot crop (384x272, raster 16-287), not the chip's picture area,
129
+ and it left lines 288-299 unaccounted for against this page's own
130
+ "vertical blank starts line 300"; the NTSC figure ran 38 lines past the
131
+ end of a 263-line frame. VICE's default exit screenshots crop to raster
132
+ 16-287 on PAL and 28-262 then 0-11 (247 rows) on NTSC; do not read
133
+ either as the visible area.
134
+
135
+ The default 25-row text display lives at lines 51-250 in both regions,
136
+ which is centered on PAL but pushed slightly low on NTSC. Most games
137
+ work fine because they target the 200-line display, not the larger
138
+ visible area.
139
+
140
+ ### Badline range
141
+
142
+ A "badline" is a scanline on which the VIC-II steals 40-43 cycles from
143
+ the CPU to fetch character pointers. By default, badlines occur on every
144
+ 8th line starting at line 51 ($33) — lines 51, 59, 67, ..., 243 in both
145
+ regions, 25 badlines for 25 character rows (measured in VICE x64sc, PAL
146
+ and NTSC R8). An earlier revision gave 247 here and $F8 (248) in the
147
+ table; neither is a badline: 248 lies outside the $30–$F7 window the
148
+ condition tests, and 247 & 7 = 7 ≠ YSCROLL (3). The badline range
149
+ itself is region-independent because it is anchored to the fixed raster
150
+ window $30-$F7 (48-247) and to YSCROLL ($D011 bits 0-2), gated by DEN
151
+ having been set on line $30 — not to the border geometry: RSEL ($D011
152
+ bit 3) and CSEL ($D016 bit 3) move the border, not the badlines.
153
+ Measured in VICE x64sc 3.10 on the 8565 (VICE's default C64C; an earlier
154
+ version said 6569), 6567R8 and 6567R56A: clearing
155
+ RSEL or CSEL leaves the badlines on 51, 59, ..., 243; YSCROLL=4 moves
156
+ every one of them to 52, 60, ..., 244. An earlier version of this
157
+ paragraph attributed the anchor to RSEL/CSEL.
158
+
159
+ What differs by region is the number of non-badlines before and after
160
+ the display window:
161
+
162
+ - PAL has 51 lines (0-50) before the first badline and 68 lines
163
+ (244-311) after the last.
164
+ - NTSC R8 has 51 lines (0-50) before and 19 lines (244-262) after.
165
+
166
+ The narrow post-display window on NTSC is the main reason NTSC
167
+ demos struggle with effects that "open" the bottom border — there
168
+ are far fewer lines to do setup work between the last badline and
169
+ the next frame's first badline.
170
+
171
+ ## VIC-II chip differences
172
+
173
+ The PAL/NTSC split is enforced by which VIC-II chip is socketed.
174
+ There is no software register to read region directly; agents must
175
+ detect by timing or by the raster line counter (see
176
+ [Detection at runtime](#detection-at-runtime)).
177
+
178
+ ### 6569 — PAL VIC-II family
179
+
180
+ - **6569R1 / 6569R3** — early PAL VIC-II revisions with the same
181
+ timing. (An earlier version of this page said R3 "fixes a
182
+ sprite-vs-background priority bug"; nothing on this machine can check
183
+ a revision history, so that claim is withdrawn rather than repeated.)
184
+ - **6569R4 / 6569R5** — later NMOS revisions, same timing as R3.
185
+ - **8565** — HMOS-II PAL VIC-II shipped in the C64C (C64-II, 1986+).
186
+ Same timing as 6569R3 but with slightly different colour output
187
+ (brighter greys, slightly different luminance levels). All 8565
188
+ parts are timing-compatible with 6569 from a software perspective.
189
+
190
+ PAL VIC-II chips were the most-produced variant because Europe was
191
+ Commodore's largest market for the C64.
192
+
193
+ ### 6567 — NTSC VIC-II family
194
+
195
+ - **6567R56A** — the original NTSC chip. 262 scanlines per frame, 64
196
+ cycles per scanline (measured in VICE x64sc `-model oldntsc`). Its
197
+ shipping history — early U.S. machines, 1982-83 — is from published
198
+ sources and not verified here.
199
+ - **6567R8** — the standard NTSC chip from 1983 onward. 263
200
+ scanlines per frame, 65 cycles per scanline. This is what
201
+ virtually all NTSC software is written for.
202
+ - **8562** — HMOS-II NTSC VIC-II shipped in the C64C. Timing-
203
+ compatible with 6567R8.
204
+
205
+ The 6567R56A is the only common case where "NTSC" is not enough
206
+ information to write timing-exact code. Code that needs to run
207
+ on R56A machines must detect by counting raster lines in a frame
208
+ (262 vs 263) — see [Detection at runtime](#detection-at-runtime).
209
+
210
+ ### Cross-region chip swaps
211
+
212
+ Physically swapping a 6569 for a 6567 (or vice versa) in a real
213
+ machine does not work without also changing the crystal oscillator,
214
+ because the CPU and VIC-II share a clock. Emulators sidestep this
215
+ by letting you select a region independent of any physical part.
216
+
217
+ ## SID frequency table differences
218
+
219
+ The SID chip's tone generators are clocked from the CPU clock (called
220
+ phi2 — "phase 2"). A given $D400 register value therefore produces
221
+ different output frequencies on PAL vs NTSC.
222
+
223
+ The SID frequency formula is:
224
+
225
+ ```
226
+ output_hz = (freq_register * cpu_clock_hz) / 16777216
227
+ ```
228
+
229
+ where `freq_register` is the 16-bit value written to $D400/$D401
230
+ (or $D407/$D408, $D40E/$D40F) and `16777216` is 2^24.
231
+
232
+ Using the canonical clocks:
233
+
234
+ - PAL: `output_hz = freq_register * 985248 / 16777216`
235
+ - NTSC: `output_hz = freq_register * 1022727 / 16777216`
236
+
237
+ To produce the same audio pitch on both regions, the frequency
238
+ register must be scaled:
239
+
240
+ ```
241
+ freq_ntsc = freq_pal * (985248 / 1022727)
242
+ = freq_pal * 0.96334...
243
+ ```
244
+
245
+ Or in reverse:
246
+
247
+ ```
248
+ freq_pal = freq_ntsc * (1022727 / 985248)
249
+ = freq_ntsc * 1.03804...
250
+ ```
251
+
252
+ A PAL-tuned music routine played without correction on NTSC plays
253
+ roughly 0.65 semitones sharp. Conversely, an NTSC-tuned routine
254
+ played on PAL plays roughly 0.65 semitones flat.
255
+
256
+ ### Common approach: two frequency tables
257
+
258
+ The usual approach is one precomputed frequency table per region —
259
+ 96 notes × 2 bytes = 192 bytes each, so carrying both is cheap — and a
260
+ region flag read once at start-up (`pal_ntsc_detection` in
261
+ `techniques/raster.md`) to choose between them. Which named editors and
262
+ players do this, and how, is not verified here; an earlier version of
263
+ this paragraph named three and called the tables "12-note", which its
264
+ own byte count contradicted.
265
+
266
+ Example PAL-vs-NTSC frequency for middle A (A4, ~440 Hz):
267
+
268
+ - PAL: $D400/$D401 = $1D45 (7493 decimal)
269
+ - NTSC: $D400/$D401 = $1C32 (7218 decimal)
270
+
271
+ A music driver that hard-codes the PAL table and runs on NTSC plays
272
+ A4 at:
273
+
274
+ ```
275
+ 7493 * 1022727 / 16777216 = 456.8 Hz
276
+ ```
277
+
278
+ which is 65 cents sharp — clearly audible.
279
+
280
+ ### Filter cutoff and resonance
281
+
282
+ The SID filter's cutoff frequency ($D415/$D416) is also clock-
283
+ dependent, but the relationship is non-linear and varies by chip
284
+ revision (6581 vs 8580). Most code does not try to match filter
285
+ behavior precisely across regions because the per-chip variation
286
+ within a region is already larger than the cross-region drift.
287
+
288
+ ## CIA timer values
289
+
290
+ The two CIA chips ($DC00-$DCFF and $DD00-$DDFF) contain 16-bit timers
291
+ clocked from phi2 (the CPU clock). A timer loaded with value `N`
292
+ fires after `N+1` cycles (the +1 accounts for the reload itself).
293
+
294
+ For "once per frame" timing without a raster IRQ, the typical CIA
295
+ timer A latch value is:
296
+
297
+ | Region | Timer A latch | Cycles per frame |
298
+ |---------------|---------------|------------------|
299
+ | PAL | $4CC7 (19,655)| 19,656 |
300
+ | NTSC R8 | $42C6 (17,094)| 17,095 |
301
+ | NTSC R56A | $417F (16,767)| 16,768 |
302
+
303
+ (Latch = cycles - 1: a continuous timer with latch N repeats every N+1
304
+ cycles. Measured in VICE x64sc: latch $4CC7 repeats every 19,656 cycles
305
+ exactly and stays on the same PAL raster line frame after frame; $4CC6
306
+ repeats every 19,655 and drifts one cycle per frame. An earlier version
307
+ of this table said cycles - 2.)
308
+
309
+ The KERNAL's default IRQ uses CIA #1 timer A at roughly 60 Hz on BOTH
310
+ regions; it is not once per frame. At reset ($FDDD, entered from IOINIT
311
+ and again from CINT once $FF5B has set the PAL/NTSC flag at $02A6 —
312
+ 1 = PAL, 0 = NTSC) it writes the timer A latch as $4025 on PAL (16,422
313
+ cycles, 59.996 Hz) and $4295 on NTSC (17,046 cycles, 59.998 Hz) — ROM
314
+ bytes $FDE2-$FDF5. Read from the 901227-03 ROM image and confirmed in
315
+ VICE x64sc by sampling the free-running counter (maximum seen $401E on
316
+ PAL, $428E on NTSC). So TI/TI$ ticks about 60 times a second on a PAL
317
+ machine too, and on PAL the KERNAL IRQ drifts against the raster rather
318
+ than locking to it. An earlier version of this page gave $4CC6 (PAL) /
319
+ $42C5 (NTSC) and "50 Hz on PAL" for the KERNAL's defaults; those are
320
+ this page's own once-per-frame latches, which the KERNAL never writes.
321
+ Many games disable the KERNAL IRQ and reprogram timer A to
322
+ their own value (often once-per-frame, sometimes higher rates for
323
+ music routines that run faster than the frame rate).
324
+
325
+ ### Music tempo
326
+
327
+ A music driver that runs once per frame plays at:
328
+
329
+ - PAL: 50.12 Hz (one tick per ~19.95 ms)
330
+ - NTSC: 59.83 Hz (one tick per ~16.71 ms)
331
+
332
+ If the music data is authored at 50 Hz tick rate and played on NTSC
333
+ without correction, the music plays 19.4% faster — a noticeably
334
+ brighter tempo. The standard fix is to skip one call in six on NTSC —
335
+ run the driver from the frame IRQ but skip its update on every 6th
336
+ call, so it ticks on five of every six frames: 59.83 × 5/6 ≈ 49.86 Hz,
337
+ 0.54% below PAL's 50.12 Hz, inaudible. The other option is to ship
338
+ per-region tempo tables in the music data (checklist item (c) below;
339
+ region-timing.md, Approach 2). Do not force a 50 Hz tick from a CIA
340
+ timer instead — see region-timing.md, "What not to do". An earlier
341
+ revision of this sentence said "every 6th NTSC frame instead of every
342
+ 5th", which read literally is one call in six, or 9.97 Hz (measured in
343
+ VICE x64sc: 50 calls in 300 NTSC frames against 250 for five-of-six).
344
+ Most modern drivers handle this automatically given a region flag.
345
+
346
+ ## Border timing differences
347
+
348
+ The VIC-II has two famous timing windows that let demo code "open"
349
+ the screen border — turning the normally-fixed border colour region
350
+ into addressable pixels. The exact cycle window during which the
351
+ border-disable bits ($D011 bit 3 for vertical, $D016 bit 3 for
352
+ horizontal) must be toggled differs slightly between PAL and NTSC.
353
+
354
+ ### Top/bottom border (vertical) opening
355
+
356
+ To open the bottom border, code must clear $D011 bit 3 (24-row mode)
357
+ after the VIC-II has finished comparing line 247 — the bottom-border
358
+ line for 24-row mode (RSEL=0) — and before it starts comparing line
359
+ 251, the bottom-border line for 25-row mode (RSEL=1); then restore
360
+ RSEL=1 from line 252 on. RSEL must still be 1 for the whole of line 247
361
+ and already be 0 when line 251 begins, so the RSEL=0 write lands in
362
+ lines 248-250. Measured in VICE x64sc 3.10 (PAL, stable IRQ, write
363
+ cycle calibrated against the cycle-56 CSEL reference): a write on any
364
+ cycle of line 247 up to cycle 62 closes the display (from line 247 if
365
+ the write is on cycle 16 or earlier, from 248 otherwise); writes from
366
+ cycle 63 of line 247 through cycle 63 of line 250 open it; a write on
367
+ cycle 1 of line 251, or anywhere later in 251, leaves the border on
368
+ from 251. The open window is three lines plus one cycle:
369
+
370
+ - PAL: 190 cycles (measured)
371
+ - NTSC R8: 196 cycles (3 × 65 + 1, arithmetic; VICE shows the same
372
+ lines closing and opening on NTSC)
373
+ - NTSC R56A: 193 cycles (3 × 64 + 1, arithmetic)
374
+
375
+ The line range is the same in every region because the 247/251 compare
376
+ values are internal to the VIC-II; only the per-line cycle count
377
+ differs. Bauer's description (one compare at cycle 63, one at the left
378
+ edge) would also admit the first 16 cycles of line 251; x64sc latches
379
+ the compare on every cycle and does not, and it has not been measured
380
+ on a real 6569 here. An earlier version of this page gave lines
381
+ 247-251 / 5 lines / ~315 cycles, with the two modes' thresholds
382
+ swapped.
383
+
384
+ There is no separate top-border write. Once the bottom comparison has
385
+ been suppressed the flip-flop stays clear through the vertical blank
386
+ and the next frame's top border, and line 51's top comparison resets a
387
+ flip-flop that is already clear; a write near line 55 on its own opens
388
+ nothing (measured in VICE x64sc 3.10 — the two writes, the window sweep
389
+ and the controls are in `recipes/kickassembler/topbottom-border-open.md`).
390
+
391
+ ### Side border (horizontal) opening
392
+
393
+ The side-border open is a one-cycle target per scanline, not a window.
394
+ The VIC-II sets the border flip-flop when the beam reaches X=335 with
395
+ CSEL=0 or X=344 with CSEL=1; on PAL the beam is at X=335 during cycle
396
+ 55 and X=344 during cycle 56 (cycles numbered 1-63 as in VICE and
397
+ Bauer), so the write that takes CSEL ($D016 bit 3) from 1 to 0 must
398
+ land on cycle 56: a `DEC $D016` on $C8 started on cycle 51 does it. Set
399
+ CSEL back to 1 any time before cycle 55 of the next line; there is no
400
+ separate left-border or close window, because a flip-flop that was
401
+ never set has nothing to reset at X=24/31. Measured in VICE x64sc 3.10
402
+ (recipes/kickassembler/sideborder-open.md; a one-cycle sweep with a
403
+ badline anchor opens only on the cycle-56 write, and a restore on
404
+ cycle 47 of the next line still opens).
405
+
406
+ NTSC 6567R8 / R56A: not measured here. The X positions are the same,
407
+ but the cycle number and the per-line loop length (65 or 64 cycles, not
408
+ 63) have to be re-derived from the 6567 timing table.
409
+
410
+ Earlier text here gave a 1-2 cycle window at zero-indexed cycles 57-58
411
+ with a close window at 14-15 of the next line, and 58-59 for the R8;
412
+ none of those windows exist, and 57-58 in any indexing leaves the
413
+ border closed.
414
+
415
+ ## Sample rate caveats for $D418 digi
416
+
417
+ "$D418 digi" is the technique of generating pseudo-PCM audio by
418
+ rapidly writing 4-bit volume values to the SID volume register
419
+ ($D418). The output sample rate equals the rate at which $D418
420
+ is written.
421
+
422
+ A common scheme is to write $D418 once per scanline using a
423
+ raster IRQ. The resulting sample rate is:
424
+
425
+ - PAL: 985,248 Hz ÷ 63 cycles per line = 15,639 Hz
426
+ - NTSC R8: 1,022,727 Hz ÷ 65 cycles per line = 15,734 Hz
427
+ - NTSC R56A: 1,022,727 Hz ÷ 64 cycles per line = 15,980 Hz
428
+
429
+ PAL and NTSC R8 are close enough (0.6% apart, about 10 cents) that
430
+ the same digi data can play on both regions without resampling and
431
+ still sound correct. The pitch shift is below 20 cents, which is at
432
+ the limit of audibility. The rare R56A is the exception: it runs
433
+ 2.2% faster than PAL, about 37 cents, which is audible.
434
+
435
+ However, a digi played by a CIA timer at a fixed cycle interval
436
+ will drift more:
437
+
438
+ - A timer of $0080 (128+1 = 129 cycles per sample) gives
439
+ ~7,638 Hz on PAL and ~7,928 Hz on NTSC R8 — a 290 Hz / ~3.8%
440
+ difference, audible as a pitch shift.
441
+
442
+ To play a sample at the same rate on both regions, scale the
443
+ timer value by the clock ratio:
444
+
445
+ ```
446
+ timer_ntsc = timer_pal * (1022727 / 985248)
447
+ = timer_pal * 1.03804
448
+ ```
449
+
450
+ ### 8580 vs 6581 digi
451
+
452
+ The 6581 SID has a known DC-coupling quirk in $D418 that makes
453
+ $D418 digi loud and clear. The 8580 SID fixes this DC quirk, which
454
+ makes $D418 digi much quieter (some tracks are barely audible on
455
+ an 8580). This is a chip-revision issue, not a region issue —
456
+ both 6581 and 8580 ship in both PAL and NTSC machines. C64Cs from
457
+ ~1986 onward typically ship with 8580; earlier C64s ship with 6581.
458
+
459
+ ## Detection at runtime
460
+
461
+ There is no register that returns "I am PAL" or "I am NTSC". Code
462
+ must detect the region by observation. Two methods are reliable.
463
+
464
+ ### Method 1: Read $D012 + $D011 bit 7 at frame top
465
+
466
+ Wait for $D011 bit 7 to be set (raster line >= 256), then keep reading
467
+ $D012 until bit 7 clears again; the last low byte seen while bit 7 was
468
+ set is the last line of the frame: $37 (311) on PAL, $06 (262) on the
469
+ 6567R8, $05 (261) on the 6567R56A.
470
+
471
+ Maximum raster line value:
472
+ - PAL: 311 ($137 — i.e., $D012=$37 with $D011 bit 7=1)
473
+ - NTSC R8: 262 ($106 — $D012=$06 with $D011 bit 7=1)
474
+ - NTSC R56A: 261 ($105 — $D012=$05 with $D011 bit 7=1)
475
+
476
+ The routine below tracks the low byte while RST8 is set and returns
477
+ the region when RST8 falls. It works from any entry line. The earlier
478
+ listing here ended in `...`, never set A, and its loop exited on the
479
+ first pass because it was entered while the raster was still on line
480
+ 0; it also read $D011 before $D012, which lets it mistake line 256 for
481
+ line 0 about 40% of the time (measured in VICE x64sc: 24 of 72 starts).
482
+
483
+ ```kickassembler
484
+ // Region by last raster line. On exit A = 0 PAL (6569), 1 NTSC 6567R8, 2 NTSC 6567R56A.
485
+ // Trashes X, Y. Call with interrupts disabled. Measured in VICE x64sc 3.10 on all three models.
486
+ detect_region:
487
+ wait_lo:
488
+ lda $D011
489
+ bmi wait_lo // a band already in progress: let it finish (see below)
490
+ wait_hi:
491
+ lda $D011
492
+ bpl wait_hi // wait for RST8 = 1 (line >= 256)
493
+ ldy #0
494
+ track:
495
+ ldx $D012 // candidate low byte
496
+ lda $D011
497
+ bpl wrapped // RST8 fell: X may already be line 0, Y is the last good one
498
+ txa
499
+ tay // Y = last $D012 seen while RST8 = 1
500
+ jmp track // 17 cycles a pass, well under one line
501
+ wrapped:
502
+ lda #0
503
+ cpy #$10
504
+ bcs done // $37 -> PAL
505
+ lda #1
506
+ cpy #$06
507
+ beq done // $06 -> R8
508
+ lda #2 // $05 -> R56A
509
+ done:
510
+ rts
511
+ ```
512
+
513
+ The `wait_lo` loop closes a race at the end of the band, not the start.
514
+ A call landing in the last cycles of line 311 reads $D012 on that line
515
+ and $D011 on line 0, so `bpl wrapped` is taken before the first `tay`
516
+ and Y is still 0: the routine would answer R56A on a PAL machine. A call
517
+ landing mid-band needs no guard — the lines it skips are the smaller
518
+ values — but with the guard `wait_hi` can only exit at line 256.
519
+ Measured on the equivalent tracking loop (`pal_ntsc_detection` in
520
+ `techniques/raster.md`, VICE x64sc 3.10): without the guard, entered on
521
+ PAL line 311 with the entry phase swept in 4-cycle steps, 2 of 16 phases
522
+ returned the register's preloaded junk; with it, all 16 returned $37.
523
+ Runtime depends on the entry line: 57 lines at best on PAL (called from
524
+ line 255) and 368 at worst (called as RST8 rises — the rest of that
525
+ band, 256 clear lines, and a whole band again), 8 to 270 lines on the
526
+ 6567R8; that loop measured 3,575 and 23,172 cycles on PAL, 500 and
527
+ 17,535 on the R8, 432 and 17,131 on the R56A against CIA 1 timer A.
528
+
529
+ A simpler and more common approach is to time a frame:
530
+
531
+ ```
532
+ ; Time one frame in cycles using CIA timer B.
533
+ ; Returns approx 19656 (PAL) or 17095 (NTSC R8) in $FB/$FC
534
+ ; (measured in VICE x64sc: $4CC2..$4CC9 and $42C0..$42C7; the
535
+ ; spread is the 7-cycle poll loop).
536
+ ;
537
+ ; Method: let any current line 0 pass, wait for raster line 0,
538
+ ; start timer B counting down from $FFFF, wait for the next
539
+ ; line 0, read timer B, subtract from $FFFF.
540
+ ;
541
+ ; An earlier version of this listing read $D011 before $D012, so
542
+ ; a read pair straddling the 255->256 wrap passed as line 0, and
543
+ ; it re-tested for line 0 immediately after arming the timer; in
544
+ ; VICE it returned ~$0DC8 (lines 256-311 only) or ~$0011 (a few
545
+ ; cycles), never a frame.
546
+
547
+ time_frame:
548
+ sei
549
+ lda #$7F
550
+ sta $DC0D ; mask all CIA #1 IRQ sources
551
+ lda $DC0D ; ack any pending
552
+ lda #$00
553
+ sta $DC0F ; stop timer B
554
+ lda #$FF
555
+ sta $DC06 ; timer B latch low
556
+ sta $DC07 ; timer B latch high (loads the counter while stopped)
557
+ pre0:
558
+ lda $D012
559
+ beq pre0 ; already on line 0 (or 256): let it pass first
560
+ wait0a:
561
+ lda $D012 ; low byte first: a 255->256 straddle cannot pass as line 0
562
+ bne wait0a
563
+ lda $D011
564
+ bmi wait0a ; RST8 set: that was line 256, keep waiting
565
+ lda #$19 ; start + one-shot + force load, phi2 input
566
+ sta $DC0F
567
+ leave0:
568
+ lda $D012
569
+ beq leave0 ; let this line 0 go by before waiting for the next one
570
+ wait0b:
571
+ lda $D012
572
+ bne wait0b
573
+ lda $D011
574
+ bmi wait0b
575
+ lda #$00
576
+ sta $DC0F ; stop timer B
577
+ sec
578
+ lda #$FF
579
+ sbc $DC06
580
+ sta $FB
581
+ lda #$FF
582
+ sbc $DC07
583
+ sta $FC
584
+ cli
585
+ rts
586
+
587
+ ; Caller: if $FC >= $48 -> PAL ($4CC2..$4CC9; frame latch is $4CC7)
588
+ ; else -> NTSC ($42C0..$42C7)
589
+ ```
590
+
591
+ The threshold $4800 (18,432) sits comfortably between the NTSC R8
592
+ cycle count (17,095) and the PAL cycle count (19,656).
593
+
594
+ ### Method 2: Read $D012 wrap point
595
+
596
+ Wait for $D011 bit 7 to go high (i.e., raster line ≥ 256), then
597
+ poll $D012 until it stops counting up. The last value before wrap
598
+ is the discriminator:
599
+
600
+ - PAL: $D012 reaches $37 (55) then wraps -> max line 311
601
+ - NTSC R8: $D012 reaches $06 (6) then wraps -> max line 262
602
+ - NTSC R56A: $D012 reaches $05 (5) then wraps -> max line 261
603
+
604
+ Practical discriminator: read $D012 when $D011 bit 7 is 1. If
605
+ the value is ever $10 or higher, you're on PAL.
606
+
607
+ ```
608
+ ; Detect PAL vs NTSC by raster line wrap. Carry clear = NTSC,
609
+ ; carry set = PAL.
610
+ detect_pal:
611
+ sei
612
+ wait_lo:
613
+ lda $D011
614
+ bmi wait_lo ; a band already in progress: let it finish (see below)
615
+ wait_hi:
616
+ lda $D011
617
+ bpl wait_hi ; wait for RST8=1 (raster >= 256)
618
+ scan:
619
+ lda $D011
620
+ bpl is_ntsc ; RST8 fell before $D012 reached $10: 262/263-line frame
621
+ lda $D012
622
+ cmp #$10 ; >= $10 means PAL (NTSC tops at $06/$05)
623
+ bcc scan ; keep polling while the raster is below 272
624
+ sec ; line 272 exists: 312-line frame (PAL, PAL-N)
625
+ rts
626
+ is_ntsc:
627
+ clc
628
+ rts
629
+ ```
630
+
631
+ An earlier version of this listing read $D012 once, immediately after
632
+ RST8 rose — i.e. on line 256, where $D012 is 0 — and so returned NTSC
633
+ on a PAL machine from every raster phase below 272 (six of eight phases
634
+ measured in VICE x64sc); the prose above it already described polling,
635
+ the code did not. The `wait_lo` guard is the end-of-band race from
636
+ Method 1: a call in the last cycles of line 311 would pass `wait_hi`
637
+ there and take `bpl is_ntsc` on line 0. Technique: `pal_ntsc_detection`
638
+ in `techniques/raster.md`; recipe: `recipes/oscar64/pal-ntsc-detect.md`.
639
+
640
+ This is the shortest reliable detect. It does not distinguish R8 from
641
+ R56A — for that, use the Method 1 `detect_region` routine above, whose
642
+ Y register ends as $06 on the R8 and $05 on the R56A (measured in VICE
643
+ x64sc 3.10, `-model ntsc` and `-model oldntsc`, not on hardware).
644
+
645
+ ### Method 3: Read the KERNAL's own flag at $02A6
646
+
647
+ The stock C64 KERNAL does store a region byte. At reset ($FCFB ->
648
+ JSR $FF5B) it runs the screen-editor init at $E518, whose VIC register
649
+ table sets the raster compare to line 311 ($D011 = $9B, $D012 = $37)
650
+ and clears $D019; $FF5B then waits for $D012 = 0, reads $D019 bit 0
651
+ and stores it at $02A6: 0 = NTSC, 1 = PAL (also 1 on 312-line
652
+ PAL-N/Drean, which it cannot tell from PAL). It then jumps to $FDDD,
653
+ which reads $02A6 to choose the CIA #1 timer A jiffy latch; $F42C
654
+ reads it again to pick the RS-232 baud table. Read from the 901227-03
655
+ ROM image ($FF5B: `20 18 E5 AD 12 D0 D0 FB AD 19 D0 29 01 8D A6 02 4C
656
+ DD FD`). Measured in VICE x64sc after boot: $02A6 = 1 on the PAL and
657
+ Drean models, 0 on NTSC 6567R8 and 6567R56A.
658
+
659
+ It is plain RAM written once at reset, so trust it only if nothing has
660
+ overwritten it, and it cannot separate R8 from R56A. $D030 has nothing
661
+ to do with it: on a C64 the address is unmapped and reads $FF; on the
662
+ C128 it is the VIC-IIe 2 MHz/test register, read/write (bit 0 toggles
663
+ when written, measured in x128), and carries no region information. An
664
+ earlier version of this page said the stock KERNAL stores no region
665
+ byte and called $D030 a read-only C128 region flag; both statements
666
+ were wrong.
667
+
668
+ **Recommendation:** Use Method 2 (poll $D012 while RST8=1) for simple
669
+ PAL/NTSC distinction. Use Method 1's `detect_region` to distinguish R8
670
+ from R56A (Y = $06 / $05; measured in VICE x64sc 3.10, `-model ntsc`
671
+ and `-model oldntsc`, not on hardware), or `time_frame` if you want the
672
+ cycle count itself. $02A6 is a free check only when you know nothing
673
+ has touched it since reset.
674
+
675
+ ## Region-portability checklist
676
+
677
+ When writing code intended to run on both regions, parameterize
678
+ the following:
679
+
680
+ - [ ] **CPU clock constant.** Define a symbol (e.g., `CPU_CLOCK`)
681
+ and select it at startup based on detected region. Used by
682
+ anything that converts seconds -> cycles.
683
+ - [ ] **SID frequency table.** Carry two tables. Select pointer
684
+ at startup. Cost: ~192 bytes per table.
685
+ - [ ] **CIA timer values.** Any timer set to "once per frame" or
686
+ "once per N frames" must be region-scaled. Hardcoding
687
+ $4CC7 breaks NTSC; hardcoding $42C6 breaks PAL.
688
+ - [ ] **Music driver tick rate.** If the driver is authored at
689
+ 50 Hz tick rate, decide whether to (a) accept the 20% tempo
690
+ jump on NTSC, (b) skip 1 frame in 6 on NTSC to approximate
691
+ 50 Hz, or (c) ship a re-tuned NTSC version of the music data.
692
+ - [ ] **Raster IRQ line numbers.** Most line numbers are
693
+ region-independent because the display window is the same.
694
+ But anything placed below the display window must be checked
695
+ against the NTSC wrap point: lines 263-311 do not exist on the
696
+ 6567R8 (262-311 on the R56A) — a raster IRQ set there never
697
+ fires on NTSC (measured in VICE x64sc: an IRQ at line 262 fires
698
+ on both regions, one at line 263 fires only on PAL). Lines
699
+ 251-262 exist in both regions. An earlier version of this page
700
+ said lines 252-262 did not exist on NTSC; they do.
701
+ - [ ] **Sprite multiplexer schedule.** If multiplexer slots are
702
+ placed in the bottom blanking, they must be moved or
703
+ eliminated on NTSC.
704
+ - [ ] **Side-border-open timing.** Use a region-dispatch table
705
+ for the cycle offset.
706
+ - [ ] **Digi playback rate.** If using a CIA timer for the
707
+ sample rate, scale by clock ratio. If using a raster IRQ
708
+ (one sample per line), the rate auto-adjusts.
709
+ - [ ] **Visible Y range assumptions.** Don't write to $D011
710
+ bits 0-2 (vertical scroll) assuming a specific display
711
+ offset on screen.
712
+ - [ ] **Frame counter overflow.** A frame counter that wraps
713
+ every N seconds wraps at different real times on PAL vs
714
+ NTSC. If timestamps matter, compute in frames and convert
715
+ to seconds at display time.
716
+ - [ ] **Game speed.** Per-frame movement deltas must be scaled by
717
+ the frame-period ratio 50.125/59.826 = 0.838 when moving from
718
+ PAL authoring to NTSC. A delta is applied once per frame, so it
719
+ scales with the frame rate, not with the cycles in a frame; an
720
+ earlier version of this page gave the cycles-per-frame ratio
721
+ 17,095/19,656 = 0.870, which is the CPU-budget ratio and leaves
722
+ the game 3.8% fast (the NTSC/PAL clock ratio). Many ported
723
+ European games skip the scaling and play 19.4% faster on U.S.
724
+ machines (the famous "European games run too fast in the U.S."
725
+ problem).
726
+ - [ ] **Loader timing.** Custom IRQ-based loaders that bit-
727
+ bang the serial bus often depend on cycle counts; many
728
+ PAL loaders fail on NTSC because the timing windows
729
+ shift.
730
+
731
+ ## Pitfalls
732
+
733
+ - **Music tempo drift**: Hard-coding a single SID frequency table
734
+ causes 4% pitch error and 20% tempo error across regions. See
735
+ [SID frequency table differences](#sid-frequency-table-differences).
736
+ - **Raster IRQ misfire**: A raster IRQ set to fire on line 280
737
+ fires on PAL but never on NTSC (max line is 262). Always
738
+ detect region before installing IRQs that target lines above
739
+ 262. See [Detection at runtime](#detection-at-runtime).
740
+ - **Sideborder open on NTSC**: PAL side-border code assumes a
741
+ 63-cycle line; on the 6567R8 the loop must be 65 cycles (64 on the
742
+ R56A) and the sprite-stall and badline phases differ, so the write
743
+ no longer lands where it did. The cycle of the write on NTSC is not
744
+ measured here; re-derive it, do not shift it by one on faith. See
745
+ [Border timing differences](#border-timing-differences).
746
+ - **CIA timer A frame timing**: Loading $4CC7 (PAL frame) on
747
+ NTSC fires every 1.15 frames, producing slow scrolling and
748
+ off-beat music. Always set the timer based on detected region.
749
+ - **$D012 raster wrap**: Comparing $D012 against >=256 requires
750
+ combining with $D011 bit 7. The wrap point differs by region
751
+ (312 PAL, 263 NTSC). See `d012_wrap_around` in
752
+ [raster-and-badline.md](../pitfalls/raster-and-badline.md) (RST8
753
+ handling) and `raster_line_count_difference` in
754
+ [region-timing.md](../pitfalls/region-timing.md) (wrap point per
755
+ region).
756
+ - **Digi pitch shift**: A fixed CIA timer produces different
757
+ sample rates on PAL vs NTSC. For accurate cross-region digi,
758
+ scale the timer or use a raster-IRQ-driven (per-line) digi.
759
+ - **Cross-region 6567R56A**: The R56A has 262 lines / 64 cycles
760
+ rather than 263 / 65. Method 1's `detect_region` tells it from the
761
+ R8 by the frame's last line, $05 against $06; the flag-only
762
+ `detect_pal` (Method 2) cannot, and `time_frame` sees 16,768 against
763
+ 17,095 cycles.
764
+ - **PAL-N / PAL-M misdetection**: Raster-wrap, frame-timing and
765
+ KERNAL ($02A6) detection all report a PAL-N (Drean, 6572) machine
766
+ as PAL, but its lines are 65 cycles, not 63 (measured in VICE x64sc
767
+ `-model drean`; 20,280 cycles per frame). Cycle-exact PAL code and
768
+ PAL SID tables are wrong there. If you must tell them apart, time a
769
+ frame: 20,280 vs 19,656 cycles ($4F vs $4C in the high byte)
770
+ separates PAL-N from PAL; the raster wrap cannot. PAL-M is
771
+ unmeasured (no VICE model). An earlier version of this bullet said
772
+ PAL was the correct answer for CPU timing on these machines.
773
+ - **Game-speed porting**: Ported games that skip the 50.125/59.826 =
774
+ 0.838 movement-delta scaling play 19.4% too fast in the region they
775
+ weren't authored in (the ratio is the frame period, not the
776
+ 17,095/19,656 = 0.870 cycle budget this page previously gave). This
777
+ is a content issue, not a hardware issue, but it surfaces during
778
+ region porting.
779
+ - **Visible Y range vs display window**: Setting $D011 bit 3
780
+ (24 vs 25 rows) and bits 0-2 (vertical scroll) on NTSC can
781
+ push the display below the visible area; values that look
782
+ fine on PAL may clip on NTSC.
783
+
784
+ ## Cross-references
785
+
786
+ - VIC-II chip register details: [vic-ii-reference.md](vic-ii-reference.md)
787
+ - SID chip register details: [sid-reference.md](sid-reference.md)
788
+ - CIA chip register details: [cia-reference.md](cia-reference.md)
789
+ - $D012 raster-wrap handling: [raster-and-badline.md](../pitfalls/raster-and-badline.md) (`d012_wrap_around`)
790
+ - Per-region raster line count: [region-timing.md](../pitfalls/region-timing.md) (`raster_line_count_difference`)
791
+
792
+ ## Source citations
793
+
794
+ - c64-wiki, "PAL": https://www.c64-wiki.com/wiki/PAL — refresh
795
+ rates, frame structure, region geographies.
796
+ - c64-wiki, "NTSC": https://www.c64-wiki.com/wiki/NTSC — NTSC
797
+ timing and chip revisions (6567R56A vs 6567R8).
798
+ - codebase64, "PAL/NTSC compatibility":
799
+ https://codebase64.org/doku.php?id=base:pal_ntsc_compatibility —
800
+ detection routines, region-portability practices.
801
+ - Christian Bauer, "The MOS 6567/6569 video controller (VIC-II)
802
+ and its application in the Commodore 64" (cebix mirror):
803
+ https://www.cebix.net/VIC-Article.txt — per-region cycle tables,
804
+ raster geometry, border-open cycle windows.
805
+ - VICE 3.10, `x64sc`, models `default`, `ntsc`, `oldntsc` — the
806
+ instrument behind every figure marked measured under Method 2
807
+ (the three wrap bytes, the entry-line runs, the `wait_lo` race,
808
+ the CIA-timed durations). https://vice-emu.sourceforge.io/
809
+ - KickAssembler 5.25 — assembled the Method 1 and Method 2 listings.
810
+ - VICE's `kernal-901227-03.bin` — the bytes at $FF5B, $E518,
811
+ $ECB9 and $FDDD behind Method 3 and the IOINIT timer values.
812
+
813
+ <!-- doc-type: hardware-reference -->