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,1137 @@
1
+ ---
2
+ chip: SID
3
+ ---
4
+
5
+ # SID Hardware Reference
6
+
7
+ The MOS 6581/8580 Sound Interface Device (SID) is the C64's three-voice
8
+ synthesizer chip, mapped at $D400-$D41F (29 registers occupy $D400-$D41C;
9
+ $D41D-$D41F are unused). The chip combines digital oscillators, ADSR
10
+ envelope generators, ring modulation, oscillator sync, a multi-mode
11
+ analog filter, two paddle A/D converters, and a 4-bit master-volume DAC.
12
+
13
+ This reference covers both the original 6581 (used 1982-1986) and the
14
+ later 8580 (1987-1992). Most software runs on both, but the two parts
15
+ differ audibly in three places that programmers care about: filter
16
+ cutoff curve, sample replay via the volume register, and combined
17
+ waveform output level.
18
+
19
+ ## Overview
20
+
21
+ The SID is a mixed-signal IC: digital control registers feed three
22
+ phase-accumulator oscillators, whose outputs pass through a digital
23
+ waveform selector, a per-voice 8-bit envelope multiplier, an optional
24
+ analog multi-mode filter, and finally a 4-bit master-volume DAC. The
25
+ chip uses a 5-bit address bus internally; the upper bits of $D4xx are
26
+ decoded by the C64's PLA. The register window is mirrored every 32
27
+ bytes throughout $D400-$D7FF on the C64. On the C128 the mirrors stop
28
+ at $D4FF: $D420-$D4FF still alias the SID, and nothing above it does —
29
+ writes to $D5xx-$D7xx never reach the chip and reads there return other
30
+ C128 I/O (the MMU at $D500, the VDC at $D600), measured in VICE x128 in
31
+ both C64 mode and native mode. An earlier revision of this page said
32
+ the C128 did not mirror at all and reserved $D420-$D4FF for a second
33
+ SID; neither is so.
34
+
35
+ ### Voice architecture
36
+
37
+ Each of the three voices contains:
38
+
39
+ - A 24-bit phase accumulator clocked at the system clock (PAL 985248 Hz
40
+ / NTSC 1022727 Hz). The accumulator is incremented by the 16-bit
41
+ frequency value in FREQLO/FREQHI every cycle.
42
+ - A waveform selector that can emit triangle, sawtooth, pulse (with
43
+ 12-bit programmable duty cycle), noise (from a 23-bit LFSR), or any
44
+ AND-combination of those four.
45
+ - An 8-bit ADSR envelope generator with 16 attack rates and 16
46
+ decay/release rates (decay and release share a rate table; sustain
47
+ is a level, not a rate).
48
+ - A control register with GATE/SYNC/RING/TEST bits in the low nibble
49
+ and the four waveform-enable bits in the high nibble.
50
+
51
+ Voice 3 is special in two ways: its oscillator output is readable at
52
+ $D41B (OSC3) and its envelope output is readable at $D41C (ENV3),
53
+ making it the C64's only built-in random-number source and a free
54
+ LFO (the noise setup for seeding, and the LFSR it should seed rather than
55
+ be read every frame, are `lfsr_random` in `../techniques/maths.md`).
56
+ Voice 3 can also be muted via $D418 bit 7 without disturbing its
57
+ oscillator, which is how OSC3/ENV3 are used as control signals without
58
+ making them audible.
59
+
60
+ ### Filter architecture
61
+
62
+ A single multi-mode analog filter operates on whichever voices have
63
+ their routing bit set in $D417. The filter has an 11-bit cutoff
64
+ ($D415-$D416), a 4-bit resonance ($D417 high nibble), and three mode
65
+ bits in $D418 selecting low-pass (12 dB/oct), band-pass (6 dB/oct),
66
+ and high-pass (12 dB/oct). Mode bits can be combined (LP+HP produces
67
+ notch; all three on produces a phase-shifted blend). Voices not routed
68
+ to the filter bypass it and go straight to the volume DAC.
69
+
70
+ ### 6581 vs 8580: what programmers care about
71
+
72
+ **Filter cutoff curve.** On the 6581 the cutoff vs register-value curve
73
+ is non-linear and looks roughly sigmoidal on a log scale; in addition
74
+ the curve varies wildly between individual chips depending on the
75
+ manufacturing batch. A cutoff value that opens the filter wide on one
76
+ 6581 may have almost no effect on another. On the 8580 the curve is
77
+ linear and consistent between chips, matching the designer's intent.
78
+ Music tuned for one chip often sounds wrong on the other; SID players
79
+ typically ship per-chip tuning data.
80
+
81
+ **ADSR bug.** Both chips have a hardware quirk where, if you reduce an
82
+ AD or SR rate to a smaller value than the envelope's internal rate
83
+ counter has already exceeded, the rate counter must wrap all the way
84
+ around its 15-bit range (up to 32768 cycles, ~33 ms at PAL) before the
85
+ envelope resumes. The bug also causes the very first cycle of attack
86
+ and decay to use the wrong rate. The standard workaround is a "hard
87
+ restart" (see Programming patterns).
88
+
89
+ **$D418 sample replay.** Writing rapidly-varying values to the lower 4
90
+ bits of the volume register modulates the master DAC and produces
91
+ audible clicks. On the 6581 this is loud enough to play 4-bit PCM
92
+ samples at multi-kHz rates and is the classic "digi" technique used
93
+ in Ghostbusters, Arkanoid, Mahoney's Musik Demo, and most C64 speech
94
+ synthesizers. On the 8580 the same writes are nearly inaudible because
95
+ the digital-to-analog stage is cleaner; the standard hardware fix is a
96
+ 330-740 kΩ resistor between SID pin 26 (EXT IN) and pin 14 (GND) or
97
+ between EXT IN and +5 V, which forces some signal into the filter and
98
+ restores the click. Software-only digi techniques on stock 8580s
99
+ include combined-waveform digi and "pulse-width DAC" (PWM).
100
+
101
+ **Combined waveforms.** Combining two or more waveform-enable bits
102
+ produces a logical AND of the waveform outputs at the bit level. The
103
+ 6581 combined waveform output is quieter and noisier; the 8580 produces
104
+ louder, cleaner combined waveforms. The specific bit-pattern depends on
105
+ the chip revision and even on individual chips. Tunes that rely on
106
+ combined waveforms (e.g. triangle+pulse for warm pad sounds) sound
107
+ distinctly different on 6581 vs 8580.
108
+
109
+ **Write-only registers.** Registers $D400-$D418 are write-only. Reading
110
+ one — or an unused address $D41D-$D41F, or any mirror through $D7FF —
111
+ does not return open bus: the SID drives the bus with the byte it last
112
+ held, which is the last value written to any address in its 32-byte
113
+ window ($D41D-$D41F included) or the last value read from $D419-$D41C,
114
+ and that byte fades to $00 after roughly 7k cycles on the 6581 and
115
+ roughly 660k cycles on the 8580 (measured in VICE 3.10 x64sc reSID:
116
+ held at 6.4k and gone at 7.7k cycles on the 6581 model, held at 658k
117
+ and gone at 669k on the 8580 model; real chips fade too, not measured
118
+ here). An earlier version of this page said the read gave the high
119
+ byte of the address or the last VIC-II fetch; neither ever appears — a
120
+ read of $D704 right after writing $A5 to $D401 returns $A5, not $D7.
121
+ Either way it is not register state: code that needs read-modify-write
122
+ must keep a software shadow. The $D419-$D41C registers are read-only;
123
+ writes to them are silently ignored.
124
+
125
+ **Voltage and capacitors.** The 6581 needs +12 V Vdd and uses 470 pF
126
+ filter capacitors. The 8580 runs on +9 V and uses 22 nF caps. Swapping
127
+ the chip without changing the caps gives wrong cutoff range. The 6582
128
+ label is an 8580 in a different package.
129
+
130
+ ## Quick reference
131
+
132
+ The full register map. Addresses $D41D-$D41F are unused; writes change
133
+ no register, and reads return the SID's held bus byte (see Write-only
134
+ registers above), not open bus.
135
+
136
+ | Address | Name | R/W | Description |
137
+ |---------|------|-----|-------------|
138
+ | $D400 | FRELO1 | W | Voice 1 frequency low byte |
139
+ | $D401 | FREHI1 | W | Voice 1 frequency high byte |
140
+ | $D402 | PWLO1 | W | Voice 1 pulse width low byte (PW7-PW0) |
141
+ | $D403 | PWHI1 | W | Voice 1 pulse width high nibble (PW11-PW8) |
142
+ | $D404 | VCREG1 | W | Voice 1 control register (waveform / GATE / SYNC / RING / TEST) |
143
+ | $D405 | ATDCY1 | W | Voice 1 attack/decay rate |
144
+ | $D406 | SUREL1 | W | Voice 1 sustain level / release rate |
145
+ | $D407 | FRELO2 | W | Voice 2 frequency low byte |
146
+ | $D408 | FREHI2 | W | Voice 2 frequency high byte |
147
+ | $D409 | PWLO2 | W | Voice 2 pulse width low byte |
148
+ | $D40A | PWHI2 | W | Voice 2 pulse width high nibble |
149
+ | $D40B | VCREG2 | W | Voice 2 control register |
150
+ | $D40C | ATDCY2 | W | Voice 2 attack/decay rate |
151
+ | $D40D | SUREL2 | W | Voice 2 sustain level / release rate |
152
+ | $D40E | FRELO3 | W | Voice 3 frequency low byte |
153
+ | $D40F | FREHI3 | W | Voice 3 frequency high byte |
154
+ | $D410 | PWLO3 | W | Voice 3 pulse width low byte |
155
+ | $D411 | PWHI3 | W | Voice 3 pulse width high nibble |
156
+ | $D412 | VCREG3 | W | Voice 3 control register |
157
+ | $D413 | ATDCY3 | W | Voice 3 attack/decay rate |
158
+ | $D414 | SUREL3 | W | Voice 3 sustain level / release rate |
159
+ | $D415 | CUTLO | W | Filter cutoff frequency low (FC2-FC0) |
160
+ | $D416 | CUTHI | W | Filter cutoff frequency high (FC10-FC3) |
161
+ | $D417 | RESON | W | Filter resonance + voice routing |
162
+ | $D418 | SIGVOL | W | Filter mode + voice-3 mute + master volume |
163
+ | $D419 | POTX | R | Paddle X A/D converter |
164
+ | $D41A | POTY | R | Paddle Y A/D converter |
165
+ | $D41B | RANDOM | R | Voice 3 oscillator output (high 8 bits of accumulator) |
166
+ | $D41C | ENV3 | R | Voice 3 envelope output |
167
+
168
+ ### Frequency formulas
169
+
170
+ Each voice's 16-bit frequency value F sets oscillator pitch by adding
171
+ F to the 24-bit phase accumulator every system clock. The audible
172
+ frequency f in Hz is:
173
+
174
+ ```
175
+ f = F * Phi2 / 2^24
176
+ ```
177
+
178
+ where `Phi2` is the system clock (985248 Hz PAL, 1022727 Hz NTSC).
179
+ Inverting:
180
+
181
+ ```
182
+ F_PAL = f * 16777216 / 985248 ~= f * 17.0284
183
+ F_NTSC = f * 16777216 / 1022727 ~= f * 16.4044
184
+ ```
185
+
186
+ (The multipliers previously read 17.0288 and 16.4046; both were
187
+ arithmetic slips. The worked values $1167 and $1D45 below were always
188
+ computed from the exact fraction and are unchanged.)
189
+
190
+ For middle C (261.626 Hz) the PAL value is $1167; for A4 (440 Hz) it
191
+ is $1D45 (PAL). Music players ship 96-entry frequency tables (8
192
+ octaves x 12 semitones) tuned to either PAL or NTSC; a PAL tune played
193
+ on an NTSC machine sounds about 3.8% sharp (roughly two-thirds of a
194
+ semitone, 65 cents).
195
+
196
+ ### ADSR rate table
197
+
198
+ All times are at a nominal 1 MHz clock; on a real C64 they are ~1.5%
199
+ longer on PAL (985,248 Hz) and ~2.2% shorter on NTSC (1,022,727 Hz).
200
+ (An earlier revision gave a single "~1.49%" for both; that was the PAL
201
+ figure only.) Decay and release share the same table; their values are
202
+ roughly 3x the matching attack value. The nominal times are the ones the
203
+ Commodore 64 Programmer's Reference Guide (1982) prints for the SID's
204
+ envelope rates; they are the chip's documented behaviour, not measured here.
205
+
206
+ | Value | Attack | Decay/Release |
207
+ |-------|--------|---------------|
208
+ | 0 | 2 ms | 6 ms |
209
+ | 1 | 8 ms | 24 ms |
210
+ | 2 | 16 ms | 48 ms |
211
+ | 3 | 24 ms | 72 ms |
212
+ | 4 | 38 ms | 114 ms |
213
+ | 5 | 56 ms | 168 ms |
214
+ | 6 | 68 ms | 204 ms |
215
+ | 7 | 80 ms | 240 ms |
216
+ | 8 | 100 ms | 300 ms |
217
+ | 9 | 250 ms | 750 ms |
218
+ | 10 | 500 ms | 1.5 s |
219
+ | 11 | 800 ms | 2.4 s |
220
+ | 12 | 1 s | 3 s |
221
+ | 13 | 3 s | 9 s |
222
+ | 14 | 5 s | 15 s |
223
+ | 15 | 8 s | 24 s |
224
+
225
+ Attack rises linearly from 0 to peak; decay and release are
226
+ exponential (the envelope counter drops in stages at 255, 93, 54, 26,
227
+ 14, 6, 0). Sustain is a 4-bit level value (0-15) where 15 holds at
228
+ peak; the envelope multiplier scales the oscillator output by a value
229
+ from 0 to 255.
230
+
231
+ ## Voice registers
232
+
233
+ Voice N (N = 1, 2, 3) occupies seven consecutive registers starting at
234
+ base address $D400 + 7*(N-1). All voice registers are write-only.
235
+
236
+ ### $D400 — FRELO1 — Voice 1 frequency low byte (W)
237
+
238
+ **Chip:** SID
239
+
240
+ Low 8 bits (F7-F0) of the 16-bit oscillator frequency value for voice 1.
241
+ The full 16-bit value is added to the 24-bit phase accumulator every
242
+ system clock cycle. See [frequency formulas](#frequency-formulas) for
243
+ conversion to Hz.
244
+
245
+ Write low byte first then high byte for atomic frequency changes; a
246
+ single-byte update to the high byte while the low byte is stale can
247
+ glitch pitch by up to one semitone for one cycle.
248
+
249
+ ### $D401 — FREHI1 — Voice 1 frequency high byte (W)
250
+
251
+ **Chip:** SID
252
+
253
+ High 8 bits (F15-F8) of the 16-bit oscillator frequency for voice 1.
254
+
255
+ | Bit | Name | Description |
256
+ |-----|------|-------------|
257
+ | 7-0 | F15-F8 | Frequency high byte |
258
+
259
+ The full frequency range 0-$FFFF maps to roughly 0-3848 Hz (PAL) or
260
+ 0-3995 Hz (NTSC). Pitch resolution is ~0.06 Hz per LSB at PAL.
261
+
262
+ ### $D402 — PWLO1 — Voice 1 pulse width low byte (W)
263
+
264
+ **Chip:** SID
265
+
266
+ Low 8 bits (PW7-PW0) of the 12-bit pulse-width value for voice 1. Only
267
+ meaningful when the pulse waveform bit is set in $D404. A value of
268
+ $000 holds the pulse output constantly high ($FFF), $800 gives a 50 %
269
+ square wave, and $FFF holds it low except for one accumulator step in
270
+ 4096 (an earlier version of this page had the two DC levels swapped;
271
+ measured in VICE x64sc/reSID on both the 6581 and 8580 models, by OSC3
272
+ read-back and by the raw audio output — a PW=$800 square wave's rails
273
+ are exactly the PW=$000 and PW=$FFF levels, and PW=$FFF sits at the
274
+ same level as a sawtooth held at accumulator zero).
275
+
276
+ ### $D403 — PWHI1 — Voice 1 pulse width high nibble (W)
277
+
278
+ **Chip:** SID
279
+
280
+ High 4 bits (PW11-PW8) of the 12-bit pulse-width value for voice 1.
281
+
282
+ | Bit | Name | Description |
283
+ |-----|------|-------------|
284
+ | 7-4 | — | Unused (writes ignored) |
285
+ | 3-0 | PW11-PW8 | Pulse width high nibble |
286
+
287
+ The 12-bit pulse width divides one oscillator period into 4096 steps.
288
+ The output is low while the accumulator's top 12 bits are below `PW`
289
+ and high for the rest of the period, so PW = $800 (= 2048) is a square
290
+ wave. Sweeping PW with a small LFO produces classic SID "pulse PWM"
291
+ pads.
292
+
293
+ ### $D404 — VCREG1 — Voice 1 control register (W)
294
+
295
+ **Chip:** SID
296
+
297
+ | Bit | Name | Description |
298
+ |-----|------|-------------|
299
+ | 7 | NOISE | Enable noise waveform |
300
+ | 6 | PULSE | Enable pulse waveform |
301
+ | 5 | SAW | Enable sawtooth waveform |
302
+ | 4 | TRI | Enable triangle waveform |
303
+ | 3 | TEST | Reset oscillator to zero (also halts noise LFSR) |
304
+ | 2 | RING | Ring-modulate with voice 3 oscillator |
305
+ | 1 | SYNC | Hard-sync this oscillator to voice 3 oscillator |
306
+ | 0 | GATE | 0 = release phase; 1 = attack-decay-sustain phase |
307
+
308
+ **GATE.** Setting GATE starts the attack phase. Clearing GATE starts
309
+ the release phase from whatever level the envelope is currently at.
310
+ The envelope generator has no separate "note off" register; gating is
311
+ the only way to trigger and end notes.
312
+
313
+ **TEST.** Setting TEST resets the phase accumulator to zero and holds
314
+ it there as long as TEST is set. The noise LFSR stops shifting and
315
+ keeps its contents; held long enough its bits drift to one, not zero —
316
+ measured in VICE x64sc 3.10 (reSID), the noise output read at $D41B is
317
+ unchanged for about 35,000 cycles on a 6581 and reads $FF by about
318
+ 38,000; on an 8580 it is unchanged for about 2.5 million cycles and
319
+ reads $FF by about 3.5 million. It never reads $00. Clearing TEST
320
+ shifts the register once, feeding the complement of bit 17 into bit 0
321
+ (an all-ones register reads $FE afterwards, an all-zero one $01), and
322
+ normal clocking resumes from that state; there is no fresh seed. An
323
+ earlier version said TEST forced the LFSR to zero and that release
324
+ started it from a fresh state; neither is so. TEST is used for
325
+ phase-locked drum sounds (so each note starts at the same accumulator
326
+ value) and for the "test-bit digi" technique on 8580s.
327
+
328
+ **RING.** Enables ring modulation between this voice's triangle and
329
+ voice 3's oscillator MSB. The triangle waveform must also be selected
330
+ (bit 4). Ring modulation XORs the triangle's MSB with voice 3's MSB,
331
+ producing inharmonic metallic tones. Voice 1 modulates against voice 3;
332
+ voice 2 against voice 1; voice 3 against voice 2 (each voice
333
+ ring-mods against the previous one cyclically).
334
+
335
+ **SYNC.** Hard-syncs this oscillator to voice 3. When voice 3's
336
+ oscillator MSB transitions high, this voice's accumulator is reset.
337
+ Sync pairing matches RING (voice 1 syncs to voice 3, voice 2 to
338
+ voice 1, voice 3 to voice 2).
339
+
340
+ **Waveform bits.** Multiple waveform bits can be set simultaneously;
341
+ the output is the bit-wise AND of each enabled waveform's 12-bit
342
+ output. Common combinations: TRI+PULSE for warm pad, SAW+PULSE for
343
+ biting lead, TRI+SAW for soft brass. Noise combined with any other
344
+ waveform shifts the noise LFSR's output bits to zero over time (a
345
+ known SID quirk) and is typically used as a one-shot effect with TEST
346
+ to restore the LFSR.
347
+
348
+ ### $D405 — ATDCY1 — Voice 1 attack/decay rate (W)
349
+
350
+ **Chip:** SID
351
+
352
+ | Bit | Name | Description |
353
+ |-----|------|-------------|
354
+ | 7-4 | ATTACK | Attack rate (0-15, see ADSR table) |
355
+ | 3-0 | DECAY | Decay rate (0-15, see ADSR table) |
356
+
357
+ Attack rises linearly from 0 to peak in the time listed in the ADSR
358
+ rate table. Decay falls exponentially from peak to the sustain level.
359
+
360
+ ### $D406 — SUREL1 — Voice 1 sustain level / release rate (W)
361
+
362
+ **Chip:** SID
363
+
364
+ | Bit | Name | Description |
365
+ |-----|------|-------------|
366
+ | 7-4 | SUSTAIN | Sustain level (0=silent, 15=peak) |
367
+ | 3-0 | RELEASE | Release rate (0-15, see ADSR table) |
368
+
369
+ Sustain is a 4-bit level; the envelope holds at `sustain * $11` — $00,
370
+ $11, $22 ... $FF — after decay completes (measured on ENV3 in VICE; an
371
+ earlier version said `sustain << 4`, which would make sustain 15 hold
372
+ at $F0, not the $FF peak). Release fires when GATE is cleared and
373
+ decays exponentially from the current envelope value to zero at the
374
+ listed rate.
375
+
376
+ ### $D407 — FRELO2 — Voice 2 frequency low byte (W)
377
+
378
+ **Chip:** SID
379
+
380
+ Low 8 bits of voice 2's 16-bit oscillator frequency. Identical to
381
+ $D400 but for voice 2.
382
+
383
+ ### $D408 — FREHI2 — Voice 2 frequency high byte (W)
384
+
385
+ **Chip:** SID
386
+
387
+ High 8 bits of voice 2's oscillator frequency.
388
+
389
+ ### $D409 — PWLO2 — Voice 2 pulse width low byte (W)
390
+
391
+ **Chip:** SID
392
+
393
+ Low 8 bits of voice 2's 12-bit pulse-width.
394
+
395
+ ### $D40A — PWHI2 — Voice 2 pulse width high nibble (W)
396
+
397
+ **Chip:** SID
398
+
399
+ High 4 bits of voice 2's pulse-width. Bits 7-4 unused.
400
+
401
+ ### $D40B — VCREG2 — Voice 2 control register (W)
402
+
403
+ **Chip:** SID
404
+
405
+ Same bit layout as $D404. RING modulates voice 2's triangle against
406
+ voice 1's oscillator MSB; SYNC syncs voice 2 to voice 1.
407
+
408
+ | Bit | Name | Description |
409
+ |-----|------|-------------|
410
+ | 7 | NOISE | Enable noise waveform |
411
+ | 6 | PULSE | Enable pulse waveform |
412
+ | 5 | SAW | Enable sawtooth waveform |
413
+ | 4 | TRI | Enable triangle waveform |
414
+ | 3 | TEST | Reset oscillator |
415
+ | 2 | RING | Ring-mod with voice 1 |
416
+ | 1 | SYNC | Sync to voice 1 |
417
+ | 0 | GATE | Envelope gate |
418
+
419
+ ### $D40C — ATDCY2 — Voice 2 attack/decay rate (W)
420
+
421
+ **Chip:** SID
422
+
423
+ | Bit | Name | Description |
424
+ |-----|------|-------------|
425
+ | 7-4 | ATTACK | Attack rate (0-15) |
426
+ | 3-0 | DECAY | Decay rate (0-15) |
427
+
428
+ ### $D40D — SUREL2 — Voice 2 sustain level / release rate (W)
429
+
430
+ **Chip:** SID
431
+
432
+ | Bit | Name | Description |
433
+ |-----|------|-------------|
434
+ | 7-4 | SUSTAIN | Sustain level (0-15) |
435
+ | 3-0 | RELEASE | Release rate (0-15) |
436
+
437
+ ### $D40E — FRELO3 — Voice 3 frequency low byte (W)
438
+
439
+ **Chip:** SID
440
+
441
+ Low 8 bits of voice 3's 16-bit oscillator frequency.
442
+
443
+ Voice 3 has a special role as the master for SYNC/RING (it is the
444
+ modulator for voice 1) and is the only voice with readable oscillator
445
+ and envelope outputs via $D41B/$D41C.
446
+
447
+ ### $D40F — FREHI3 — Voice 3 frequency high byte (W)
448
+
449
+ **Chip:** SID
450
+
451
+ High 8 bits of voice 3's oscillator frequency.
452
+
453
+ ### $D410 — PWLO3 — Voice 3 pulse width low byte (W)
454
+
455
+ **Chip:** SID
456
+
457
+ Low 8 bits of voice 3's 12-bit pulse-width.
458
+
459
+ ### $D411 — PWHI3 — Voice 3 pulse width high nibble (W)
460
+
461
+ **Chip:** SID
462
+
463
+ High 4 bits of voice 3's pulse-width. Bits 7-4 unused.
464
+
465
+ ### $D412 — VCREG3 — Voice 3 control register (W)
466
+
467
+ **Chip:** SID
468
+
469
+ Same bit layout as $D404. RING modulates voice 3's triangle against
470
+ voice 2's oscillator MSB; SYNC syncs voice 3 to voice 2.
471
+
472
+ | Bit | Name | Description |
473
+ |-----|------|-------------|
474
+ | 7 | NOISE | Enable noise waveform |
475
+ | 6 | PULSE | Enable pulse waveform |
476
+ | 5 | SAW | Enable sawtooth waveform |
477
+ | 4 | TRI | Enable triangle waveform |
478
+ | 3 | TEST | Reset oscillator |
479
+ | 2 | RING | Ring-mod with voice 2 |
480
+ | 1 | SYNC | Sync to voice 2 |
481
+ | 0 | GATE | Envelope gate |
482
+
483
+ When voice 3 is used as an LFO source (via $D41B/$D41C) it is common
484
+ to set NOISE alone (or TRI alone for a smoother LFO), set GATE, set
485
+ $D418 bit 7 (3OFF) to mute its audible output, and pick a low
486
+ frequency value so the oscillator slowly cycles.
487
+
488
+ ### $D413 — ATDCY3 — Voice 3 attack/decay rate (W)
489
+
490
+ **Chip:** SID
491
+
492
+ | Bit | Name | Description |
493
+ |-----|------|-------------|
494
+ | 7-4 | ATTACK | Attack rate (0-15) |
495
+ | 3-0 | DECAY | Decay rate (0-15) |
496
+
497
+ ### $D414 — SUREL3 — Voice 3 sustain level / release rate (W)
498
+
499
+ **Chip:** SID
500
+
501
+ | Bit | Name | Description |
502
+ |-----|------|-------------|
503
+ | 7-4 | SUSTAIN | Sustain level (0-15) |
504
+ | 3-0 | RELEASE | Release rate (0-15) |
505
+
506
+ ## Filter
507
+
508
+ The SID's single multi-mode analog filter is shared across all three
509
+ voices and an external audio input. Each voice can be individually
510
+ routed through or around the filter; the filter mode (LP/BP/HP) and
511
+ cutoff/resonance apply globally.
512
+
513
+ ### Filter signal flow
514
+
515
+ ```
516
+ Voice 1 osc -> envelope -> [filter mux] -> filter -> [volume DAC] -> audio out
517
+ Voice 2 osc -> envelope -> [filter mux] /
518
+ Voice 3 osc -> envelope -> [filter mux] / (also direct to mux)
519
+ EXT IN ----------------> [filter mux] /
520
+
521
+ Voices not routed to filter go directly to volume DAC.
522
+ Voice 3 muted by $D418 bit 7 bypasses both paths.
523
+ ```
524
+
525
+ The filter cutoff is an 11-bit value across $D415 (low 3 bits) and
526
+ $D416 (high 8 bits). On the 6581 the cutoff range is roughly
527
+ 30 Hz - 12 kHz; on the 8580 it is roughly 30 Hz - 12 kHz but with a
528
+ linear and consistent curve. Resonance ranges 0-15 across all chips;
529
+ the 8580 reaches noticeably higher Q before self-oscillation.
530
+
531
+ ### $D415 — CUTLO — Filter cutoff frequency low (W)
532
+
533
+ **Chip:** SID
534
+
535
+ | Bit | Name | Description |
536
+ |-----|------|-------------|
537
+ | 7-3 | — | Unused (writes ignored) |
538
+ | 2-0 | FC2-FC0 | Filter cutoff low 3 bits |
539
+
540
+ The low 3 bits of the 11-bit cutoff frequency. Many tunes only update
541
+ $D416 (the high 8 bits) and leave $D415 at zero, giving 8-bit cutoff
542
+ resolution; the extra 3 bits in $D415 are mostly useful for slow
543
+ sweeps.
544
+
545
+ ### $D416 — CUTHI — Filter cutoff frequency high (W)
546
+
547
+ **Chip:** SID
548
+
549
+ | Bit | Name | Description |
550
+ |-----|------|-------------|
551
+ | 7-0 | FC10-FC3 | Filter cutoff high 8 bits |
552
+
553
+ The high 8 bits of the 11-bit cutoff frequency. Combined with $D415:
554
+ cutoff = ($D416 << 3) | ($D415 & 7), giving an 11-bit value 0-2047.
555
+
556
+ On the 6581 the mapping from this value to actual cutoff Hz is
557
+ chip-dependent and non-linear (roughly sigmoid on a log scale). On
558
+ the 8580 the mapping is linear and consistent. Tunes that sweep
559
+ cutoff for filter automation will sound noticeably different across
560
+ chip revisions.
561
+
562
+ ### $D417 — RESON — Filter resonance and routing (W)
563
+
564
+ **Chip:** SID
565
+
566
+ | Bit | Name | Description |
567
+ |-----|------|-------------|
568
+ | 7-4 | RES | Filter resonance Q (0=low, 15=high) |
569
+ | 3 | FILTEX | Route external audio input through filter |
570
+ | 2 | FILT3 | Route voice 3 through filter |
571
+ | 1 | FILT2 | Route voice 2 through filter |
572
+ | 0 | FILT1 | Route voice 1 through filter |
573
+
574
+ **Resonance.** The 4-bit resonance value emphasises frequencies near
575
+ the cutoff. On the 6581 high resonance values often cause distortion
576
+ (this is musically desirable for some applications); on the 8580
577
+ resonance is cleaner and reaches higher Q before clipping.
578
+
579
+ **Routing.** Each FILT bit selects whether that voice/input passes
580
+ through the filter or bypasses it. A voice with its FILT bit clear
581
+ goes straight to the volume DAC at full bandwidth (with the envelope
582
+ still applied). A voice with its FILT bit set is subject to the LP/BP/
583
+ HP processing in $D418.
584
+
585
+ A common pattern is to route only voice 1 (FILT1=1) to the filter
586
+ for lead synth work while voices 2-3 carry unfiltered bass and pad.
587
+
588
+ ### $D418 — SIGVOL — Filter mode, voice-3 mute, master volume (W)
589
+
590
+ **Chip:** SID
591
+
592
+ | Bit | Name | Description |
593
+ |-----|------|-------------|
594
+ | 7 | 3OFF | Disconnect voice 3 from audio output (oscillator still runs) |
595
+ | 6 | HP | Enable high-pass filter mode (12 dB/oct) |
596
+ | 5 | BP | Enable band-pass filter mode (6 dB/oct) |
597
+ | 4 | LP | Enable low-pass filter mode (12 dB/oct) |
598
+ | 3-0 | VOL | Master volume (0=silent, 15=full) |
599
+
600
+ **3OFF (voice 3 mute).** Disconnects voice 3 from the final audio
601
+ output without affecting its oscillator or envelope. Used when voice 3
602
+ is configured as an LFO/random source for $D41B/$D41C and shouldn't be
603
+ audible. Note: voice 3 routed to the filter (FILT3=1 in $D417) ignores
604
+ 3OFF — the mute happens at the bypass path only.
605
+
606
+ **Filter mode bits.** LP, BP, HP can be combined: LP+HP is a notch
607
+ filter, LP+BP gives a warmer band-pass, BP+HP is also a notch.
608
+ Setting all three on simultaneously sums the three responses (rare in
609
+ practice). Setting all three off with $D417 routing bits set produces
610
+ silence for those voices (the filter output is grounded when no mode
611
+ is enabled).
612
+
613
+ **Volume DAC.** The 4-bit VOL field scales the audio output linearly.
614
+ This DAC is the entry point for the classic 4-bit sample replay
615
+ ("$D418 digi") technique: writing changing values in the low nibble
616
+ produces audible clicks at the sample rate, allowing PCM playback
617
+ mixed with regular SID music. The DAC is shared with everything so
618
+ suddenly changing VOL between non-zero values while voices are gated
619
+ produces a "pop" — this is the same artifact that makes sample replay
620
+ work, and is also why turning the SID on/off at fade time should
621
+ fade VOL gradually.
622
+
623
+ ## Read-only registers
624
+
625
+ The four read-only registers at $D419-$D41C return live state from the
626
+ chip's analog inputs and voice 3. Writes to these addresses are
627
+ silently ignored.
628
+
629
+ ### $D419 — POTX — Paddle X A/D converter (R)
630
+
631
+ **Chip:** SID
632
+
633
+ 8-bit A/D conversion of the voltage on pin POTX (control port 1 pin 9
634
+ or control port 2 pin 9, multiplexed by CIA1 port A, $DC00 bits 6-7:
635
+ %01 = control port 1, %10 = control port 2; an earlier revision said
636
+ CIA2, whose bits 6-7 are the IEC CLK IN / DATA IN lines and have no
637
+ effect on the SID). Values range $00 (full clockwise / pot maxed) to
638
+ $FF (full counter-clockwise / pot at zero), though the usable range is
639
+ typically $00-$DF.
640
+
641
+ The A/D circuit takes about 512 system cycles (~520 us PAL) to settle
642
+ after the multiplex source changes; reads made sooner return stale or
643
+ transitional values. Wait a full 512 cycles — nine PAL raster lines
644
+ (eight NTSC; eight PAL lines is 504 and still inside the window) —
645
+ after writing the selector before sampling, and in practice switch on
646
+ one frame and read on the next. An earlier revision said two raster
647
+ lines, which is 126 cycles; measured in VICE x64sc with a 1351 on
648
+ port 1, $D419 reads noise up to 508 cycles after the selector write
649
+ and the settled value from 513 on.
650
+
651
+ The 1351 mouse uses POTX/POTY in a different way: the mouse generates
652
+ its own changing voltages encoding quadrature position, which the
653
+ software samples at known intervals (typically every other frame).
654
+
655
+ ### $D41A — POTY — Paddle Y A/D converter (R)
656
+
657
+ **Chip:** SID
658
+
659
+ 8-bit A/D conversion of the voltage on pin POTY (control port 1 pin 5
660
+ or control port 2 pin 5). Same multiplexing and timing as POTX.
661
+
662
+ The two A/D converters are independent; POTX and POTY can be read in
663
+ any order. Both are tied to whichever control port CIA1 has selected
664
+ at the moment of the conversion.
665
+
666
+ ### $D41B — RANDOM — Voice 3 oscillator output high byte (R)
667
+
668
+ **Chip:** SID
669
+
670
+ Returns the upper 8 bits of voice 3's oscillator output. What appears
671
+ here depends on the waveform selected in $D412:
672
+
673
+ - **Noise selected.** Returns bits from the 23-bit LFSR — the standard
674
+ C64 random-number source. Set voice 3 to NOISE+GATE with a high
675
+ frequency value, mute it with $D418 bit 7, and read $D41B for a
676
+ fresh pseudo-random byte. Some bits move faster than others, so
677
+ combine multiple reads for whitening.
678
+ - **Triangle selected.** Returns the rising/falling triangle slope —
679
+ useful as a slow LFO if voice 3's frequency is low.
680
+ - **Sawtooth selected.** Returns the ramp value.
681
+ - **Pulse selected.** Returns $00 or $FF depending on phase
682
+ (effectively useless as a control source).
683
+
684
+ When the TEST bit ($D412 bit 3) is set, what $D41B reads depends on
685
+ the waveform (measured in VICE x64sc reSID, 6581 and 8580 models; an
686
+ earlier revision of this page said it always reads zero, which holds
687
+ only for triangle and sawtooth). Triangle and sawtooth read $00 — the
688
+ accumulator is reset and held at zero. Pulse reads $FF whatever PW
689
+ holds ($000, $800 and $FFF all give $FF; TEST forces the pulse output
690
+ high). Noise keeps returning the LFSR's current bits, and if TEST is
691
+ held the LFSR drifts to all ones: the 6581 model reads $FF within
692
+ about 77,000 cycles (still unchanged at ~31,000, partly changed at
693
+ ~36,000), the 8580 model holds its value past 77,000 cycles and reads
694
+ $FF after roughly 10 million. Combined waveforms in voice 3 produce
695
+ the same AND-of-waveforms shape that audio gets.
696
+
697
+ ### $D41C — ENV3 — Voice 3 envelope output (R)
698
+
699
+ **Chip:** SID
700
+
701
+ Returns the 8-bit current value of voice 3's envelope generator
702
+ (0-$FF). Used as a programmable ramp / LFO source. Typical pattern:
703
+
704
+ 1. Set voice 3 ATDCY3=$XY and SUREL3=$ZW for the desired slope
705
+ 2. Set $D418 bit 7 to mute voice 3
706
+ 3. Gate voice 3 by writing $D412 with GATE=1 and any waveform bit
707
+ 4. Read $D41C every frame as the controller value
708
+
709
+ The envelope value rises and falls under software control of the
710
+ gate bit. Some games (e.g. Wizball) modulate other voices' pulse
711
+ width by feeding ENV3 into the PWHI register every frame.
712
+
713
+ ## Programming patterns
714
+
715
+ ### Frequency tables
716
+
717
+ For musical tuning, ship a 96-entry frequency table indexed by MIDI
718
+ note number (or equivalent). Each entry is a 16-bit PAL- or NTSC-
719
+ calibrated value. Example (PAL, equal temperament, A4 = 440 Hz):
720
+
721
+ ```
722
+ ; PAL frequency table, semitone 0 = C-0 (~16 Hz)
723
+ ; F = round(freq * 16777216 / 985248)
724
+ freqtbl:
725
+ .word $0117, $0127, $0139, $014B ; C-0 .. D#-0
726
+ .word $015F, $0174, $018A, $01A1 ; E-0 .. G-0
727
+ ; ...
728
+ .word $1D45 ; A-4 = 440 Hz
729
+ ; 8 octaves x 12 semitones = 96 entries
730
+ ```
731
+
732
+ (Earlier revisions labelled the first eight entries C-1..G-1; they are
733
+ octave 0 in the same A4 = 440 Hz numbering as the rest of the table —
734
+ $0117 is 16.38 Hz.)
735
+
736
+ To play a note in voice 1: load the 16-bit value from `freqtbl,note`,
737
+ store low byte to $D400, high byte to $D401, then write the desired
738
+ control register value (waveform + GATE=1) to $D404.
739
+
740
+ ### Hard restart (ADSR-bug workaround)
741
+
742
+ The classic hard restart prevents the ADSR-bug rate-counter wrap
743
+ before each new note. Apply two frames before the next note's gate:
744
+
745
+ ```
746
+ ; "Classic" hard restart, applied 2 frames before next note gate
747
+ hard_restart:
748
+ lda #0
749
+ sta $D405 ; AD = 0
750
+ lda #$F0
751
+ sta $D406 ; SR = $F0 (sustain max, release 0)
752
+ lda $D404
753
+ and #$FE
754
+ sta $D404 ; clear GATE bit
755
+ ; ... 1 frame later ...
756
+ lda #$09
757
+ sta $D404 ; trigger TEST+GATE (reset oscillator, start attack)
758
+ ; ... 1 frame later (the note frame) ...
759
+ lda real_ad
760
+ sta $D405
761
+ lda real_sr
762
+ sta $D406
763
+ lda real_waveform_with_gate
764
+ sta $D404 ; release TEST, real waveform + GATE
765
+ ```
766
+
767
+ Variants include:
768
+
769
+ - **Test-bit restart:** set $D404 bit 3 (TEST) one frame before the
770
+ note, clear it on the gate frame. Locks the accumulator at zero so
771
+ the new note phase-starts cleanly.
772
+ - **Aggressive restart:** write 0 to $D405/$D406 simultaneously with
773
+ clearing GATE, forcing instant release and clamping the envelope to
774
+ zero before the new attack.
775
+ - **Light restart:** only clear GATE one frame before, then re-gate.
776
+ Avoids the worst of the ADSR bug at the cost of not fully resetting
777
+ state.
778
+
779
+ Different SID players use different strategies; GoatTracker uses
780
+ classic hard restart by default, defMON has configurable variants,
781
+ and SidFactory II ships per-instrument hard-restart parameters.
782
+
783
+ ### Ring modulation
784
+
785
+ Ring modulation produces inharmonic, bell-like, or clangy timbres.
786
+ The ring modulator XORs the carrier voice's triangle MSB with the
787
+ modulator voice's oscillator MSB.
788
+
789
+ ```
790
+ ; Voice 1 ring-mods against voice 3
791
+ lda #$10 ; mid-range freq for voice 3
792
+ sta $D40F
793
+ lda #$00
794
+ sta $D40E
795
+ lda #$10 ; voice 3: TRI, no GATE (silent modulator; the oscillator runs regardless)
796
+ sta $D412
797
+
798
+ lda #$80
799
+ sta $D401 ; voice 1 freq high
800
+ lda #$00
801
+ sta $D400
802
+ lda #$15 ; voice 1: TRI + RING + GATE
803
+ sta $D404
804
+ ```
805
+
806
+ The RING bit in $D404 must be set, the TRI waveform must be enabled,
807
+ and voice 3 must have a non-zero frequency. Voice 3's GATE state is
808
+ irrelevant — the ring-mod source is the oscillator MSB, not the
809
+ post-envelope output. (An earlier revision of this listing wrote $11
810
+ here, which is TRI + GATE; measured in VICE x64sc reSID, $10 leaves
811
+ OSC3 advancing with ENV3 at zero.) Voice 3 should typically not also
812
+ be playing audibly; either mute it via $D418 bit 7 or leave its
813
+ envelope at zero.
814
+
815
+ ### Oscillator sync
816
+
817
+ Hard sync resets the slave oscillator's accumulator whenever the
818
+ master oscillator's MSB rises. Produces aggressive, formant-like
819
+ harmonics that depend on the ratio between master and slave
820
+ frequencies.
821
+
822
+ ```
823
+ ; Voice 1 sync to voice 3
824
+ lda #$30 ; voice 3 = master, lower frequency
825
+ sta $D40F
826
+ lda #$00
827
+ sta $D40E
828
+ lda #$11 ; voice 3: TRI + GATE — GATE only makes it audible; non-zero frequency is what sync needs
829
+ sta $D412
830
+
831
+ lda #$80 ; voice 1 = slave, higher frequency
832
+ sta $D401
833
+ lda #$21 ; voice 1: SAW + SYNC + GATE
834
+ sta $D404
835
+ ```
836
+
837
+ Sync needs the master OSCILLATOR running, not the master ENVELOPE: the
838
+ accumulator advances whenever the frequency is non-zero and TEST is
839
+ clear, whatever GATE and the waveform bits say. Measured in VICE x64sc
840
+ (reSID, 6581 and 8580 models) on OSC3: a voice synced to an ungated
841
+ master read $05 and $0D where an unsynced control read $28, the same
842
+ as with the master gated; with the master at F=0 or with its TEST bit
843
+ held, no sync occurred. An earlier revision of this page said gating
844
+ was needed for the accumulator to advance reliably; it is not — GATE
845
+ drives only the envelope. Gate the master only if you want to hear it
846
+ (with the default all-zero ADSR a gated master only clicks). Sweep the
847
+ slave (voice 1) frequency for the classic sync sweep.
848
+
849
+ ### ADSR-bug delay (intentional)
850
+
851
+ You can deliberately exploit the ADSR bug as a timed delay. Set the
852
+ sustain level high, then write a smaller AD or SR value than the
853
+ current envelope-counter position; the envelope will hang at its
854
+ current level until the rate counter wraps. Some early SID composers
855
+ used this as a "stuck note" effect, though most players treat it as
856
+ something to avoid.
857
+
858
+ ### 4-bit sample replay via $D418
859
+
860
+ Stream 4-bit PCM samples by writing to the low nibble of $D418 at the
861
+ sample rate (typically 4-8 kHz). The sample rate is usually a divisor
862
+ of the system clock; an IRQ on every Nth raster line writes the next
863
+ nibble. Each byte of `sample_data` holds two consecutive samples,
864
+ first sample in the low nibble; the packer must agree, because the
865
+ unpacker below depends on it.
866
+
867
+ ```
868
+ ; ~8 kHz sample replay (PAL): IRQ every ~123 cycles
869
+ sample_irq:
870
+ ldx sample_idx
871
+ lda sample_data,x ; packed 4-bit, LOW nibble plays first
872
+ bit nibble_flag
873
+ bpl lo_nibble
874
+ lsr
875
+ lsr
876
+ lsr
877
+ lsr
878
+ inc sample_idx ; advance only after the high nibble
879
+ lo_nibble:
880
+ and #$0F
881
+ sta $D418
882
+ lda nibble_flag
883
+ eor #$80
884
+ sta nibble_flag
885
+ rti
886
+ ```
887
+
888
+ The shifts are written as bare `lsr` for portability — KickAssembler
889
+ rejects `lsr a` (Unknown symbol 'a'); ca65 accepts both. An earlier
890
+ version of this listing used `inc nibble_flag` as the toggle, which
891
+ flips bit 7 only every 128 calls, so it played the low nibble of bytes
892
+ 0-127 and the high nibble of bytes 128-255 and never alternated
893
+ (measured in VICE x64sc); the `eor #$80` flips the tested bit on every
894
+ call, and `inc sample_idx` now advances only after the high nibble has
895
+ gone out.
896
+
897
+ On a stock 8580 this produces almost no audible output. The classic
898
+ hardware fix is a 330 kΩ - 740 kΩ resistor between EXT IN (pin 26) and
899
+ GND (pin 14), or between EXT IN and +5 V. Software-only digi on 8580
900
+ typically uses:
901
+
902
+ - **Test-bit DC digi (8580).** Set PULSE+TEST+GATE ($49) on all three
903
+ voices, F=0 (any), AD=$00, SR=$F0, PW irrelevant. With TEST set the
904
+ pulse output is held HIGH whatever the pulse width (measured in VICE
905
+ x64sc reSID, both models: OSC3 reads $FF for PW=$000, $001, $800 and
906
+ $FFF; the WAV output shows no change for PW writes while TEST is
907
+ held), so each voice feeds a constant full-scale level through its
908
+ envelope. Ordinary $D418 nibble writes then scale a real signal: in
909
+ reSID's 8580 model the volume step with three such voices is about
910
+ 5x the bare-voice step, while with only one voice it is no louder
911
+ than bare (the voice DC roughly cancels the mixer's own small
912
+ offset), so use all three. The earlier text here said PWHI3 was the
913
+ DAC; it was wrong — PW has no effect on the output while TEST is set
914
+ (the value is kept and applies when TEST clears), and without TEST
915
+ the comparator output is binary ($000 or $FFF), never proportional
916
+ to PW. The scene form (Mahoney's 8580 digi, "Musik Run/Stop", 2014)
917
+ also drives the filter-mode bits in $D418 with the voices routed
918
+ through the filter and maps sample values through a per-chip lookup
919
+ table of measured $D418 bytes for ~8-bit output; that extension is
920
+ from published descriptions, not measured here. Nothing in this
921
+ bullet was measured on silicon.
922
+
923
+ ### Voice 3 as random source
924
+
925
+ ```
926
+ ; Initialize voice 3 as random-number source (one-time setup)
927
+ init_random:
928
+ lda #$FF
929
+ sta $D40E ; voice 3 freq low
930
+ sta $D40F ; voice 3 freq high (max rate)
931
+ lda #$80
932
+ sta $D412 ; voice 3: NOISE only, no GATE
933
+ ; (without GATE the LFSR still advances)
934
+ rts
935
+
936
+ ; Read a pseudo-random byte
937
+ random:
938
+ lda $D41B
939
+ rts
940
+ ```
941
+
942
+ Note: setting NOISE+GATE+TEST and then clearing TEST is sometimes
943
+ needed to seed the LFSR; on cold start the LFSR may be in a stuck
944
+ state.
945
+
946
+ ### Voice 3 as LFO
947
+
948
+ ```
949
+ ; Voice 3 as a slow triangle LFO (modulates voice 1 pulse width)
950
+ init_lfo:
951
+ lda #$10 ; slow freq
952
+ sta $D40E
953
+ lda #$00
954
+ sta $D40F
955
+ lda #$11 ; TRI + GATE
956
+ sta $D412
957
+ lda #$80
958
+ sta $D418 ; 3OFF set, volume 0 (or set as needed)
959
+ rts
960
+
961
+ ; Every frame, feed the triangle's top nibble to voice 1 pulse width high
962
+ lfo_tick:
963
+ lda $D41B
964
+ lsr
965
+ lsr
966
+ lsr
967
+ lsr ; 0-15: the slow triangle, 16 steps per half-cycle
968
+ sta $D403 ; voice 1 PWHI — only bits 3-0 are used
969
+ rts
970
+ ```
971
+
972
+ $D403 keeps only bits 3-0, so storing OSC3 unshifted (as an earlier
973
+ version of this block did) applies the triangle's LOW nibble, which
974
+ wraps 0-15 every couple of frames at this frequency — measured in VICE
975
+ x64sc (reSID) the applied values run 0,9,3,12,6,0,9,… — a jitter over
976
+ the whole pulse-width range, not the slow sweep described. Shifted,
977
+ the value steps by at most 1 per frame. For finer steps also write
978
+ OSC3<<4 to $D402 (12-bit PW = OSC3 × 16); keep the sweep away from PW
979
+ $000 and $FFF, which are silent (see Pitfalls).
980
+
981
+ ### Avoiding $D418 volume pops
982
+
983
+ When transitioning from playing to silent (e.g. end of game), don't
984
+ just drop volume to zero — that causes the loudest possible click.
985
+ Instead, gate-off all voices first and let the release phase decay,
986
+ then fade VOL down through the lower nibble values. Conversely on
987
+ startup, write filter mode bits and volume only after gating voices
988
+ to known states.
989
+
990
+ ### Initializing the SID
991
+
992
+ A clean startup sequence (e.g. after RESET, or before loading a tune):
993
+
994
+ ```
995
+ init_sid:
996
+ lda #0
997
+ ldx #$18
998
+ zero_loop:
999
+ sta $D400,x
1000
+ dex
1001
+ bpl zero_loop ; zero $D400-$D418
1002
+ lda #$0F
1003
+ sta $D418 ; volume = 15, all filter modes off
1004
+ rts
1005
+ ```
1006
+
1007
+ This zeros all 25 write-only registers and sets master volume to
1008
+ maximum with no filtering. The four read-only registers ($D419-$D41C)
1009
+ are not touched.
1010
+
1011
+ ## Pitfalls
1012
+
1013
+ - **Write-only registers.** $D400-$D418 cannot be read back. A read
1014
+ returns the SID's held bus byte — the last write to any SID address
1015
+ or the last $D419-$D41C read, fading to $00 within ~7k cycles (6581)
1016
+ / ~660k cycles (8580) in reSID — not open-bus garbage and not the
1017
+ address high byte as this page used to say. Code that needs to
1018
+ modify a single bit of a register must maintain a software shadow.
1019
+ See [sid.md](../pitfalls/sid.md) (`sid_write_only_registers`).
1020
+
1021
+ - **ADSR bug.** Reducing the AD or SR rate below the envelope's
1022
+ internal counter position causes the counter to wrap through its
1023
+ full 15-bit range before the envelope resumes — up to 33 ms at PAL.
1024
+ Mitigate with a hard restart sequence applied 1-2 frames before
1025
+ each note gate. See [sid.md](../pitfalls/sid.md) (`sid_adsr_bug_8580`;
1026
+ the entry's heading names the 8580 but its Mechanism covers both
1027
+ chips).
1028
+
1029
+ - **$D418 popping.** Sudden changes to the master-volume nibble
1030
+ generate audible clicks via the DAC. This is the same effect that
1031
+ enables 4-bit sample replay; for music playback always fade VOL
1032
+ gradually and gate voices off first to let release decay.
1033
+
1034
+ - **8580 sample replay broken.** The classic $D418 digi technique
1035
+ produces nearly silent output on 8580 SIDs because the cleaner DAC
1036
+ doesn't leak DC. Either install the 330-740 kΩ EXT-IN-to-GND
1037
+ resistor mod or use a software-only digi (the test-bit DC digi:
1038
+ three voices held at constant full-scale output with
1039
+ PULSE+TEST+GATE, $D418 as the DAC — not pulse-width modulation, see
1040
+ Programming patterns).
1041
+
1042
+ - **Filter cutoff varies across chips.** The 6581 cutoff curve varies
1043
+ drastically between individual chips of the same revision. A
1044
+ cutoff sweep tuned on one 6581 may sound completely different on
1045
+ another. The 8580 cutoff is consistent but uses a different
1046
+ (linear vs sigmoidal) curve than the 6581, so 6581-tuned music
1047
+ sounds wrong on 8580 and vice versa. Music players typically ship
1048
+ per-chip-revision tuning.
1049
+
1050
+ - **Combined waveforms are chip-dependent.** Combining waveform bits
1051
+ (e.g. TRI+PULSE) produces a bit-wise AND of the waveform outputs;
1052
+ the resulting amplitude is louder on 8580 than 6581. Some specific
1053
+ combined-waveform shapes only sound right on one chip revision.
1054
+
1055
+ - **No frequency read-back.** You cannot read the current oscillator
1056
+ frequency. You can read $D41B (OSC3) to see the upper 8 bits of
1057
+ voice 3's accumulator, but the frequency register itself is
1058
+ write-only.
1059
+
1060
+ - **Pulse width 0 and FFF give silence.** PW=$000 holds the pulse
1061
+ output high, PW=$FFF holds it (almost) constantly low (an earlier
1062
+ revision had the two swapped; measured in VICE x64sc reSID on both
1063
+ chip models). Both produce a DC level that
1064
+ is inaudible (the envelope multiplies a constant). A safe default
1065
+ pulse width is $800 (square wave); changing PW dynamically while
1066
+ pulse is enabled produces audible width changes.
1067
+
1068
+ - **TEST bit halts the noise LFSR.** Setting TEST on a voice playing
1069
+ noise freezes the LFSR where it is (its bits drift to one if TEST is
1070
+ held ~35k cycles on a 6581, ~2.5M on an 8580, measured in VICE);
1071
+ clearing TEST shifts it once and lets it run on from there. The
1072
+ output jumps at both edges, so don't toggle TEST during sustained
1073
+ noise notes unless you want a click. An earlier version said TEST
1074
+ reset the LFSR to zero; it does not.
1075
+
1076
+ - **Noise combined with other waveforms zeros the LFSR.** If you
1077
+ enable NOISE simultaneously with TRI, SAW, or PULSE, the AND-gate
1078
+ combination eventually drives all LFSR bits to zero, silencing
1079
+ the noise. Once stuck, set TEST briefly to re-seed. This is a
1080
+ well-known SID quirk and is also why "noise sweeps" usually pulse
1081
+ the TEST bit periodically. A brief pulse is enough — a few cycles of
1082
+ TEST re-seeds a zeroed LFSR, because the falling edge shifts a 1
1083
+ into bit 0 when bit 17 is 0 (measured in VICE: $D41B reads $01 right
1084
+ after the pulse and runs on). Holding TEST longer only matters if
1085
+ you want the register driven to all ones.
1086
+
1087
+ - **Voice 3 mute ($D418 bit 7) only mutes the bypass path.** If
1088
+ voice 3 has FILT3=1 in $D417, it still goes to the filter and
1089
+ through to output regardless of bit 7. To fully silence voice 3
1090
+ for use as a modulator: clear FILT3 in $D417 and set 3OFF in
1091
+ $D418.
1092
+
1093
+ - **Frequency table tuning depends on system clock.** PAL and NTSC
1094
+ clocks differ by ~3.8%. A tune tuned for PAL plays sharp on NTSC
1095
+ by roughly two-thirds of a semitone (65 cents). Some music
1096
+ players auto-detect the region and select between two tables.
1097
+
1098
+ - **Sync requires master oscillator running.** SYNC syncs to the
1099
+ previous voice's oscillator MSB. If the master voice has frequency
1100
+ zero, no MSB transitions happen and sync produces no effect. The
1101
+ master voice's GATE state is not required for sync (measured, see
1102
+ Oscillator sync), but setting a non-zero frequency is.
1103
+
1104
+ - **POTX/POTY settling time.** After $DC00 bits 6-7 switch the paddle
1105
+ source between control port 1 and 2, wait ~512 cycles before
1106
+ reading $D419/$D41A. Faster reads return stale/transitional
1107
+ values. The KERNAL keyboard scan (SCNKEY, called from the $EA31
1108
+ jiffy IRQ) rewrites $DC00 every frame and leaves it at $7F, i.e.
1109
+ %01 = control port 1, so select the pair with IRQs masked or
1110
+ re-select immediately before each read. See
1111
+ [cia-reference.md](cia-reference.md) for the CIA1 paddle multiplex
1112
+ bits. (Measured in VICE x64sc 3.10 and read from the 901227-03
1113
+ KERNAL; earlier text said CIA2.)
1114
+
1115
+ - **Mirroring at $D420-$D7FF.** The SID register window is mirrored
1116
+ every 32 bytes through $D7FF on the stock C64. Writing to $D420 is
1117
+ the same as $D400. On the C128 the mirrors stop at $D4FF: a write to
1118
+ $D512 or $D700 never reaches the SID (measured in VICE x128; an
1119
+ earlier revision said the C128 reserved this area for a second SID,
1120
+ which it does not). Don't rely on any mirror for cross-machine code
1121
+ — above $D4FF it is not the SID on a C128, and $D420 and $D500 are
1122
+ the bases add-on second-SID boards usually decode (see
1123
+ [c64-registers-reference.md](c64-registers-reference.md)), so
1124
+ portable code addresses $D400-$D41C only.
1125
+
1126
+ - **Voltage matters for chip swap.** Replacing a 6581 with an 8580
1127
+ (or vice versa) requires changing Vdd (12 V vs 9 V) and the filter
1128
+ capacitors (470 pF vs 22 nF). A naked swap often results in
1129
+ audible distortion, wrong cutoff range, or chip damage.
1130
+
1131
+ - **$D41D-$D41F are not a constant.** These addresses are unused; a
1132
+ read returns the SID's held bus byte (last write or last $D419-$D41C
1133
+ read, fading to $00), not the high byte of the address as this page
1134
+ used to say. Don't use them as a "guaranteed zero" or any other
1135
+ constant source.
1136
+
1137
+ <!-- doc-type: hardware-reference -->