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.
- package/CHANGELOG.md +2082 -0
- package/LICENSE +29 -0
- package/README.md +559 -0
- package/VERSION +25 -0
- package/dist/cli/setup.js +66 -0
- package/dist/cli/setup.js.map +1 -0
- package/dist/cli-memorize-audit.js +97 -0
- package/dist/cli-memorize-audit.js.map +1 -0
- package/dist/cli.js +335 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.js +83 -0
- package/dist/config.js.map +1 -0
- package/dist/context.js +53 -0
- package/dist/context.js.map +1 -0
- package/dist/domain/budget-notes.js +104 -0
- package/dist/domain/budget-notes.js.map +1 -0
- package/dist/domain/budget.js +417 -0
- package/dist/domain/budget.js.map +1 -0
- package/dist/domain/game-design.js +77 -0
- package/dist/domain/game-design.js.map +1 -0
- package/dist/domain/timing.js +39 -0
- package/dist/domain/timing.js.map +1 -0
- package/dist/graph/apply.js +132 -0
- package/dist/graph/apply.js.map +1 -0
- package/dist/graph/claims.js +231 -0
- package/dist/graph/claims.js.map +1 -0
- package/dist/graph/extract/archetype.js +118 -0
- package/dist/graph/extract/archetype.js.map +1 -0
- package/dist/graph/extract/common.js +69 -0
- package/dist/graph/extract/common.js.map +1 -0
- package/dist/graph/extract/failure.js +37 -0
- package/dist/graph/extract/failure.js.map +1 -0
- package/dist/graph/extract/game-design.js +189 -0
- package/dist/graph/extract/game-design.js.map +1 -0
- package/dist/graph/extract/hardware.js +124 -0
- package/dist/graph/extract/hardware.js.map +1 -0
- package/dist/graph/extract/pitfall.js +62 -0
- package/dist/graph/extract/pitfall.js.map +1 -0
- package/dist/graph/extract/raster-band.js +56 -0
- package/dist/graph/extract/raster-band.js.map +1 -0
- package/dist/graph/extract/recipe.js +71 -0
- package/dist/graph/extract/recipe.js.map +1 -0
- package/dist/graph/extract/technique-entities.js +180 -0
- package/dist/graph/extract/technique-entities.js.map +1 -0
- package/dist/graph/extract/technique.js +179 -0
- package/dist/graph/extract/technique.js.map +1 -0
- package/dist/graph/extract/toolchain.js +67 -0
- package/dist/graph/extract/toolchain.js.map +1 -0
- package/dist/graph/extract/types.js +3 -0
- package/dist/graph/extract/types.js.map +1 -0
- package/dist/graph/extract/vocabulary.js +65 -0
- package/dist/graph/extract/vocabulary.js.map +1 -0
- package/dist/graph/extract.js +43 -0
- package/dist/graph/extract.js.map +1 -0
- package/dist/graph/kernal-clobbers.js +64 -0
- package/dist/graph/kernal-clobbers.js.map +1 -0
- package/dist/graph/machine-variants.js +208 -0
- package/dist/graph/machine-variants.js.map +1 -0
- package/dist/ingest/files.js +99 -0
- package/dist/ingest/files.js.map +1 -0
- package/dist/ingest/passes.js +104 -0
- package/dist/ingest/passes.js.map +1 -0
- package/dist/ingest/points.js +50 -0
- package/dist/ingest/points.js.map +1 -0
- package/dist/ingest/report.js +140 -0
- package/dist/ingest/report.js.map +1 -0
- package/dist/ingest/tally.js +81 -0
- package/dist/ingest/tally.js.map +1 -0
- package/dist/ingest/verified-on.js +43 -0
- package/dist/ingest/verified-on.js.map +1 -0
- package/dist/ingest.js +135 -0
- package/dist/ingest.js.map +1 -0
- package/dist/schemas/cost-basis.js +5 -0
- package/dist/schemas/cost-basis.js.map +1 -0
- package/dist/schemas/machine-variant.js +25 -0
- package/dist/schemas/machine-variant.js.map +1 -0
- package/dist/schemas/plan-budget.js +121 -0
- package/dist/schemas/plan-budget.js.map +1 -0
- package/dist/schemas/tool-outputs.js +526 -0
- package/dist/schemas/tool-outputs.js.map +1 -0
- package/dist/server/define-tool.js +52 -0
- package/dist/server/define-tool.js.map +1 -0
- package/dist/server/defined-only.js +9 -0
- package/dist/server/defined-only.js.map +1 -0
- package/dist/server/tools-briefings.js +70 -0
- package/dist/server/tools-briefings.js.map +1 -0
- package/dist/server/tools-lookup.js +180 -0
- package/dist/server/tools-lookup.js.map +1 -0
- package/dist/server/tools-maintenance.js +116 -0
- package/dist/server/tools-maintenance.js.map +1 -0
- package/dist/server/tools-pitfalls.js +89 -0
- package/dist/server/tools-pitfalls.js.map +1 -0
- package/dist/server/tools-recipes.js +296 -0
- package/dist/server/tools-recipes.js.map +1 -0
- package/dist/server/tools-runtime.js +48 -0
- package/dist/server/tools-runtime.js.map +1 -0
- package/dist/server/tools.js +43 -0
- package/dist/server/tools.js.map +1 -0
- package/dist/server.js +95 -0
- package/dist/server.js.map +1 -0
- package/dist/services/analytics/schema.js +78 -0
- package/dist/services/analytics/schema.js.map +1 -0
- package/dist/services/analytics/statements.js +99 -0
- package/dist/services/analytics/statements.js.map +1 -0
- package/dist/services/analytics.js +195 -0
- package/dist/services/analytics.js.map +1 -0
- package/dist/services/bm25.js +158 -0
- package/dist/services/bm25.js.map +1 -0
- package/dist/services/chunker.js +81 -0
- package/dist/services/chunker.js.map +1 -0
- package/dist/services/embeddings.js +58 -0
- package/dist/services/embeddings.js.map +1 -0
- package/dist/services/falkor/base.js +85 -0
- package/dist/services/falkor/base.js.map +1 -0
- package/dist/services/falkor/links.js +361 -0
- package/dist/services/falkor/links.js.map +1 -0
- package/dist/services/falkor/nodes.js +183 -0
- package/dist/services/falkor/nodes.js.map +1 -0
- package/dist/services/falkor/params.js +45 -0
- package/dist/services/falkor/params.js.map +1 -0
- package/dist/services/falkor/schema.js +77 -0
- package/dist/services/falkor/schema.js.map +1 -0
- package/dist/services/falkor.js +100 -0
- package/dist/services/falkor.js.map +1 -0
- package/dist/services/qdrant.js +238 -0
- package/dist/services/qdrant.js.map +1 -0
- package/dist/services/versions.js +73 -0
- package/dist/services/versions.js.map +1 -0
- package/dist/services/vice-bin.js +51 -0
- package/dist/services/vice-bin.js.map +1 -0
- package/dist/tools/briefings/archetype.js +174 -0
- package/dist/tools/briefings/archetype.js.map +1 -0
- package/dist/tools/briefings/budget.js +177 -0
- package/dist/tools/briefings/budget.js.map +1 -0
- package/dist/tools/briefings/build-order.js +135 -0
- package/dist/tools/briefings/build-order.js.map +1 -0
- package/dist/tools/briefings/build.js +185 -0
- package/dist/tools/briefings/build.js.map +1 -0
- package/dist/tools/briefings/discovery.js +290 -0
- package/dist/tools/briefings/discovery.js.map +1 -0
- package/dist/tools/briefings/plan-pitfalls.js +69 -0
- package/dist/tools/briefings/plan-pitfalls.js.map +1 -0
- package/dist/tools/briefings/render.js +151 -0
- package/dist/tools/briefings/render.js.map +1 -0
- package/dist/tools/briefings/rows.js +41 -0
- package/dist/tools/briefings/rows.js.map +1 -0
- package/dist/tools/briefings/toolchain.js +63 -0
- package/dist/tools/briefings/toolchain.js.map +1 -0
- package/dist/tools/briefings/why-proposed.js +69 -0
- package/dist/tools/briefings/why-proposed.js.map +1 -0
- package/dist/tools/briefings.js +44 -0
- package/dist/tools/briefings.js.map +1 -0
- package/dist/tools/feedback.js +97 -0
- package/dist/tools/feedback.js.map +1 -0
- package/dist/tools/hydrate.js +75 -0
- package/dist/tools/hydrate.js.map +1 -0
- package/dist/tools/intelligence.js +67 -0
- package/dist/tools/intelligence.js.map +1 -0
- package/dist/tools/lint/asm-decimal.js +86 -0
- package/dist/tools/lint/asm-decimal.js.map +1 -0
- package/dist/tools/lint/asm-rules.js +221 -0
- package/dist/tools/lint/asm-rules.js.map +1 -0
- package/dist/tools/lint/asm-shared.js +3 -0
- package/dist/tools/lint/asm-shared.js.map +1 -0
- package/dist/tools/lint/c-rules.js +215 -0
- package/dist/tools/lint/c-rules.js.map +1 -0
- package/dist/tools/lint/text.js +122 -0
- package/dist/tools/lint/text.js.map +1 -0
- package/dist/tools/lint/types.js +40 -0
- package/dist/tools/lint/types.js.map +1 -0
- package/dist/tools/lint.js +76 -0
- package/dist/tools/lint.js.map +1 -0
- package/dist/tools/memorization-mcp.js +111 -0
- package/dist/tools/memorization-mcp.js.map +1 -0
- package/dist/tools/pitfalls/bm25.js +53 -0
- package/dist/tools/pitfalls/bm25.js.map +1 -0
- package/dist/tools/pitfalls/format.js +58 -0
- package/dist/tools/pitfalls/format.js.map +1 -0
- package/dist/tools/pitfalls/graph.js +124 -0
- package/dist/tools/pitfalls/graph.js.map +1 -0
- package/dist/tools/pitfalls.js +134 -0
- package/dist/tools/pitfalls.js.map +1 -0
- package/dist/tools/prompts.js +81 -0
- package/dist/tools/prompts.js.map +1 -0
- package/dist/tools/query/compatibility/closure.js +62 -0
- package/dist/tools/query/compatibility/closure.js.map +1 -0
- package/dist/tools/query/compatibility/facts.js +28 -0
- package/dist/tools/query/compatibility/facts.js.map +1 -0
- package/dist/tools/query/compatibility/fetch.js +164 -0
- package/dist/tools/query/compatibility/fetch.js.map +1 -0
- package/dist/tools/query/compatibility/hard-rules.js +159 -0
- package/dist/tools/query/compatibility/hard-rules.js.map +1 -0
- package/dist/tools/query/compatibility/index.js +27 -0
- package/dist/tools/query/compatibility/index.js.map +1 -0
- package/dist/tools/query/compatibility/kernal-zp-rule.js +90 -0
- package/dist/tools/query/compatibility/kernal-zp-rule.js.map +1 -0
- package/dist/tools/query/compatibility/render.js +106 -0
- package/dist/tools/query/compatibility/render.js.map +1 -0
- package/dist/tools/query/compatibility/rules.js +337 -0
- package/dist/tools/query/compatibility/rules.js.map +1 -0
- package/dist/tools/query/compatibility/unit-rules.js +253 -0
- package/dist/tools/query/compatibility/unit-rules.js.map +1 -0
- package/dist/tools/query/game-design.js +83 -0
- package/dist/tools/query/game-design.js.map +1 -0
- package/dist/tools/query/lookups.js +220 -0
- package/dist/tools/query/lookups.js.map +1 -0
- package/dist/tools/query/plan-budget.js +266 -0
- package/dist/tools/query/plan-budget.js.map +1 -0
- package/dist/tools/query/recipes.js +214 -0
- package/dist/tools/query/recipes.js.map +1 -0
- package/dist/tools/query/retrieval.js +128 -0
- package/dist/tools/query/retrieval.js.map +1 -0
- package/dist/tools/query/shared.js +121 -0
- package/dist/tools/query/shared.js.map +1 -0
- package/dist/tools/query/techniques.js +331 -0
- package/dist/tools/query/techniques.js.map +1 -0
- package/dist/tools/query/timing.js +106 -0
- package/dist/tools/query/timing.js.map +1 -0
- package/dist/tools/query/types.js +11 -0
- package/dist/tools/query/types.js.map +1 -0
- package/dist/tools/query.js +21 -0
- package/dist/tools/query.js.map +1 -0
- package/dist/tools/resources.js +186 -0
- package/dist/tools/resources.js.map +1 -0
- package/dist/tools/run-game.js +249 -0
- package/dist/tools/run-game.js.map +1 -0
- package/dist/tools/selfimprovement.js +367 -0
- package/dist/tools/selfimprovement.js.map +1 -0
- package/docker-compose.yml +35 -0
- package/docs/ARCHITECTURE.md +164 -0
- package/docs/CONVENTIONS-archetypes.md +158 -0
- package/docs/CONVENTIONS-failures.md +46 -0
- package/docs/CONVENTIONS-game-designs.md +75 -0
- package/docs/CONVENTIONS-hardware-reference.md +184 -0
- package/docs/CONVENTIONS-pitfalls.md +91 -0
- package/docs/CONVENTIONS-recipes.md +106 -0
- package/docs/CONVENTIONS-techniques.md +309 -0
- package/docs/CONVENTIONS-toolchain-reference.md +89 -0
- package/docs/ONTOLOGY.md +655 -0
- package/docs/art/art-production-reference.md +157 -0
- package/docs/art/asset-pipelines.md +586 -0
- package/docs/c64-failure-patterns.md +693 -0
- package/docs/demo-design/demo-composition.md +349 -0
- package/docs/demo-design/demo-design-philosophy.md +320 -0
- package/docs/demo-design/intro-cracktro-patterns.md +435 -0
- package/docs/figures/ctm-spd-embed-probe.png +0 -0
- package/docs/figures/dot-flag-mid-5000000.png +0 -0
- package/docs/figures/dot-flag-no-erase-12000000.png +0 -0
- package/docs/figures/edges.json +1 -0
- package/docs/figures/fig6-architecture.png +0 -0
- package/docs/figures/fig7-ontology.png +0 -0
- package/docs/figures/screen-dissolve-mid-frame25.png +0 -0
- package/docs/figures/screen-dissolve-wipe-frame25.png +0 -0
- package/docs/figures/spindle-two-parts-part1.png +0 -0
- package/docs/figures/spindle-two-parts-part2.png +0 -0
- package/docs/figures/starters/action-puzzle.png +0 -0
- package/docs/figures/starters/adventure.png +0 -0
- package/docs/figures/starters/beat-em-up.png +0 -0
- package/docs/figures/starters/demo.png +0 -0
- package/docs/figures/starters/platformer.png +0 -0
- package/docs/figures/starters/shmup-vertical.png +0 -0
- package/docs/figures/tape-kernal-master-ntsc.png +0 -0
- package/docs/figures/tape-kernal-master-pal.png +0 -0
- package/docs/figures/tape-turbo-loader-ntsc.png +0 -0
- package/docs/figures/tape-turbo-loader-pal.png +0 -0
- package/docs/figures/tape-turbo-master-ntsc.png +0 -0
- package/docs/figures/tape-turbo-master-pal.png +0 -0
- package/docs/figures/tech-tech-pad2-12000000.png +0 -0
- package/docs/figures/tech-tech-pad4-12000000.png +0 -0
- package/docs/figures/tech-tech-seven-12000000.png +0 -0
- package/docs/figures/twister-mid-5000000.png +0 -0
- package/docs/figures/twister-straight-12000000.png +0 -0
- package/docs/figures/vector-balls-nosort-ntsc.png +0 -0
- package/docs/figures/vector-balls-nosort.png +0 -0
- package/docs/formats/c64-file-formats.md +1212 -0
- package/docs/formats/iec-disk-reference.md +754 -0
- package/docs/game-design/c64-game-archetypes.md +273 -0
- package/docs/game-design/designs/falling-blocks.md +54 -0
- package/docs/game-design/designs/platformer-scaffold.md +48 -0
- package/docs/game-design/designs/simple-shmup.md +27 -0
- package/docs/game-design/enemy-behaviour-and-difficulty.md +349 -0
- package/docs/game-design/game-design-patterns.md +1189 -0
- package/docs/game-design/game-structure.md +354 -0
- package/docs/game-design/production-planning.md +349 -0
- package/docs/game-design/reference-game-sources.md +90 -0
- package/docs/hardware/6502-illegal-opcodes.md +1353 -0
- package/docs/hardware/6510-cpu-reference.md +2112 -0
- package/docs/hardware/c64-memory-map.md +3184 -0
- package/docs/hardware/c64-registers-reference.md +996 -0
- package/docs/hardware/cia-reference.md +1281 -0
- package/docs/hardware/kernal-routines-reference.md +1836 -0
- package/docs/hardware/pal-ntsc-reference.md +813 -0
- package/docs/hardware/sid-reference.md +1137 -0
- package/docs/hardware/vic-ii-reference.md +1714 -0
- package/docs/music/music-production-reference.md +403 -0
- package/docs/pitfalls/banking.md +1067 -0
- package/docs/pitfalls/cia.md +1147 -0
- package/docs/pitfalls/cpu.md +874 -0
- package/docs/pitfalls/input.md +282 -0
- package/docs/pitfalls/kernal-and-io.md +1615 -0
- package/docs/pitfalls/loader.md +1191 -0
- package/docs/pitfalls/logic.md +94 -0
- package/docs/pitfalls/maths.md +187 -0
- package/docs/pitfalls/raster-and-badline.md +721 -0
- package/docs/pitfalls/region-timing.md +660 -0
- package/docs/pitfalls/scroll.md +207 -0
- package/docs/pitfalls/sid.md +738 -0
- package/docs/pitfalls/sprite.md +979 -0
- package/docs/pitfalls/text-mode-render.md +1172 -0
- package/docs/recipes/cc65/cartridge-8k.md +398 -0
- package/docs/recipes/cc65/hello-world-conio.md +76 -0
- package/docs/recipes/cc65/memory-layout.md +312 -0
- package/docs/recipes/cc65/screenshots/README.md +14 -0
- package/docs/recipes/cc65/screenshots/cartridge-8k-ntsc.png +0 -0
- package/docs/recipes/cc65/screenshots/cartridge-8k.png +0 -0
- package/docs/recipes/cc65/screenshots/hello-world-conio.png +0 -0
- package/docs/recipes/cc65/screenshots/memory-layout-ntsc.png +0 -0
- package/docs/recipes/cc65/screenshots/memory-layout.png +0 -0
- package/docs/recipes/kickassembler/basic-float-calls.md +578 -0
- package/docs/recipes/kickassembler/basic-wedge.md +398 -0
- package/docs/recipes/kickassembler/big-font-scroller.md +620 -0
- package/docs/recipes/kickassembler/charset-copy-rom-to-ram.md +623 -0
- package/docs/recipes/kickassembler/cia-revision-detect.md +366 -0
- package/docs/recipes/kickassembler/colour-cycling.md +343 -0
- package/docs/recipes/kickassembler/colour-fade.md +303 -0
- package/docs/recipes/kickassembler/compare-16bit-signed.md +1007 -0
- package/docs/recipes/kickassembler/cracktro-template.md +526 -0
- package/docs/recipes/kickassembler/crt-banked.md +276 -0
- package/docs/recipes/kickassembler/dos-error-codes.md +466 -0
- package/docs/recipes/kickassembler/dot-flag.md +576 -0
- package/docs/recipes/kickassembler/drive-job-queue.md +667 -0
- package/docs/recipes/kickassembler/drive-via-probe.md +690 -0
- package/docs/recipes/kickassembler/dycp-scroller.md +568 -0
- package/docs/recipes/kickassembler/dypp-sprite-scroller.md +681 -0
- package/docs/recipes/kickassembler/dysp.md +670 -0
- package/docs/recipes/kickassembler/easyflash-save.md +800 -0
- package/docs/recipes/kickassembler/eight-way-scroll.md +1484 -0
- package/docs/recipes/kickassembler/file-io-roundtrip.md +546 -0
- package/docs/recipes/kickassembler/fire-effect.md +420 -0
- package/docs/recipes/kickassembler/fld.md +414 -0
- package/docs/recipes/kickassembler/fli-image.md +336 -0
- package/docs/recipes/kickassembler/four-player-read.md +672 -0
- package/docs/recipes/kickassembler/headless-verify.md +228 -0
- package/docs/recipes/kickassembler/hello-world.md +98 -0
- package/docs/recipes/kickassembler/high-score-insert.md +660 -0
- package/docs/recipes/kickassembler/hires-plot-line.md +723 -0
- package/docs/recipes/kickassembler/irq-chain.md +316 -0
- package/docs/recipes/kickassembler/irq-owns-port.md +668 -0
- package/docs/recipes/kickassembler/isometric-room.md +1145 -0
- package/docs/recipes/kickassembler/light-pen-read.md +926 -0
- package/docs/recipes/kickassembler/logic-rate-decoupling.md +670 -0
- package/docs/recipes/kickassembler/mci-interlace.md +543 -0
- package/docs/recipes/kickassembler/memory-layout.md +277 -0
- package/docs/recipes/kickassembler/mouse-1351-read.md +801 -0
- package/docs/recipes/kickassembler/nmi-timer-tick.md +562 -0
- package/docs/recipes/kickassembler/own-keyscan.md +881 -0
- package/docs/recipes/kickassembler/paddle-read.md +751 -0
- package/docs/recipes/kickassembler/palette-cells.md +219 -0
- package/docs/recipes/kickassembler/pseudo-3d-road.md +930 -0
- package/docs/recipes/kickassembler/pwm-digi.md +463 -0
- package/docs/recipes/kickassembler/raster-bars.md +264 -0
- package/docs/recipes/kickassembler/reu-dma.md +1019 -0
- package/docs/recipes/kickassembler/runtime-relocation.md +743 -0
- package/docs/recipes/kickassembler/screen-dissolve.md +545 -0
- package/docs/recipes/kickassembler/screen-wipe.md +408 -0
- package/docs/recipes/kickassembler/screenshots/README.md +72 -0
- package/docs/recipes/kickassembler/screenshots/basic-float-calls-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/basic-float-calls.png +0 -0
- package/docs/recipes/kickassembler/screenshots/basic-wedge-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/basic-wedge.png +0 -0
- package/docs/recipes/kickassembler/screenshots/big-font-scroller-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/big-font-scroller.png +0 -0
- package/docs/recipes/kickassembler/screenshots/charset-copy-rom-to-ram-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/charset-copy-rom-to-ram.png +0 -0
- package/docs/recipes/kickassembler/screenshots/cia-revision-detect-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/cia-revision-detect.png +0 -0
- package/docs/recipes/kickassembler/screenshots/colour-cycling-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/colour-cycling.png +0 -0
- package/docs/recipes/kickassembler/screenshots/colour-fade-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/colour-fade.png +0 -0
- package/docs/recipes/kickassembler/screenshots/compare-16bit-signed-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/compare-16bit-signed.png +0 -0
- package/docs/recipes/kickassembler/screenshots/cracktro-template.png +0 -0
- package/docs/recipes/kickassembler/screenshots/crt-banked-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/crt-banked.png +0 -0
- package/docs/recipes/kickassembler/screenshots/dos-error-codes-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/dos-error-codes.png +0 -0
- package/docs/recipes/kickassembler/screenshots/dot-flag-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/dot-flag.png +0 -0
- package/docs/recipes/kickassembler/screenshots/drive-job-queue-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/drive-job-queue.png +0 -0
- package/docs/recipes/kickassembler/screenshots/drive-via-probe-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/drive-via-probe.png +0 -0
- package/docs/recipes/kickassembler/screenshots/dycp-scroller-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/dycp-scroller.png +0 -0
- package/docs/recipes/kickassembler/screenshots/dypp-sprite-scroller-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/dypp-sprite-scroller.png +0 -0
- package/docs/recipes/kickassembler/screenshots/dysp-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/dysp.png +0 -0
- package/docs/recipes/kickassembler/screenshots/easyflash-save-ntsc-run2.png +0 -0
- package/docs/recipes/kickassembler/screenshots/easyflash-save-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/easyflash-save-run2.png +0 -0
- package/docs/recipes/kickassembler/screenshots/easyflash-save.png +0 -0
- package/docs/recipes/kickassembler/screenshots/eight-way-scroll-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/eight-way-scroll.png +0 -0
- package/docs/recipes/kickassembler/screenshots/file-io-roundtrip-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/file-io-roundtrip.png +0 -0
- package/docs/recipes/kickassembler/screenshots/fire-effect-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/fire-effect.png +0 -0
- package/docs/recipes/kickassembler/screenshots/fld-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/fld.png +0 -0
- package/docs/recipes/kickassembler/screenshots/fli-image.png +0 -0
- package/docs/recipes/kickassembler/screenshots/four-player-read-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/four-player-read.png +0 -0
- package/docs/recipes/kickassembler/screenshots/headless-verify-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/headless-verify.png +0 -0
- package/docs/recipes/kickassembler/screenshots/hello-world.png +0 -0
- package/docs/recipes/kickassembler/screenshots/high-score-insert-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/high-score-insert.png +0 -0
- package/docs/recipes/kickassembler/screenshots/hires-plot-line-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/hires-plot-line.png +0 -0
- package/docs/recipes/kickassembler/screenshots/irq-chain-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/irq-chain.png +0 -0
- package/docs/recipes/kickassembler/screenshots/irq-owns-port-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/irq-owns-port.png +0 -0
- package/docs/recipes/kickassembler/screenshots/isometric-room-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/isometric-room.png +0 -0
- package/docs/recipes/kickassembler/screenshots/light-pen-read-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/light-pen-read.png +0 -0
- package/docs/recipes/kickassembler/screenshots/logic-rate-decoupling-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/logic-rate-decoupling.png +0 -0
- package/docs/recipes/kickassembler/screenshots/mci-interlace-average.png +0 -0
- package/docs/recipes/kickassembler/screenshots/mci-interlace-frame-b.png +0 -0
- package/docs/recipes/kickassembler/screenshots/mci-interlace-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/mci-interlace.png +0 -0
- package/docs/recipes/kickassembler/screenshots/memory-layout-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/memory-layout.png +0 -0
- package/docs/recipes/kickassembler/screenshots/mouse-1351-read-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/mouse-1351-read.png +0 -0
- package/docs/recipes/kickassembler/screenshots/nmi-timer-tick-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/nmi-timer-tick.png +0 -0
- package/docs/recipes/kickassembler/screenshots/own-keyscan-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/own-keyscan.png +0 -0
- package/docs/recipes/kickassembler/screenshots/paddle-read-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/paddle-read.png +0 -0
- package/docs/recipes/kickassembler/screenshots/palette-cells-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/palette-cells.png +0 -0
- package/docs/recipes/kickassembler/screenshots/pseudo-3d-road-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/pseudo-3d-road.png +0 -0
- package/docs/recipes/kickassembler/screenshots/pwm-digi-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/pwm-digi.png +0 -0
- package/docs/recipes/kickassembler/screenshots/raster-bars.png +0 -0
- package/docs/recipes/kickassembler/screenshots/reu-dma-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/reu-dma.png +0 -0
- package/docs/recipes/kickassembler/screenshots/runtime-relocation-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/runtime-relocation.png +0 -0
- package/docs/recipes/kickassembler/screenshots/screen-dissolve-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/screen-dissolve.png +0 -0
- package/docs/recipes/kickassembler/screenshots/screen-wipe-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/screen-wipe.png +0 -0
- package/docs/recipes/kickassembler/screenshots/scroll-panel-split-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/scroll-panel-split.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sfx-in-player-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sfx-in-player.png +0 -0
- package/docs/recipes/kickassembler/screenshots/shadebobs-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/shadebobs.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sideborder-open.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sine-scroller.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sine-table-runtime-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sine-table-runtime.png +0 -0
- package/docs/recipes/kickassembler/screenshots/software-sprite-preshifted-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/software-sprite-preshifted.png +0 -0
- package/docs/recipes/kickassembler/screenshots/speedcode-generator-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/speedcode-generator.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sprite-border-scroller-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sprite-border-scroller.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sprite-cache-flip-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sprite-cache-flip.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sprite-multiplex-24.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sprite-multiplex-game-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sprite-multiplex-game.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sprite-priority-classes-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sprite-priority-classes.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sprite-sine-chain-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sprite-sine-chain.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sprite-stretcher-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sprite-stretcher.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sprites-only-screen-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sprites-only-screen.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sqrt-atan2-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/sqrt-atan2.png +0 -0
- package/docs/recipes/kickassembler/screenshots/stable-raster-irq-control.png +0 -0
- package/docs/recipes/kickassembler/screenshots/stable-raster-irq.png +0 -0
- package/docs/recipes/kickassembler/screenshots/tech-tech-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/tech-tech.png +0 -0
- package/docs/recipes/kickassembler/screenshots/tod-alarm-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/tod-alarm.png +0 -0
- package/docs/recipes/kickassembler/screenshots/topbottom-border-open.png +0 -0
- package/docs/recipes/kickassembler/screenshots/twister-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/twister.png +0 -0
- package/docs/recipes/kickassembler/screenshots/unit-test-driver-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/unit-test-driver.png +0 -0
- package/docs/recipes/kickassembler/screenshots/vector-balls-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/vector-balls.png +0 -0
- package/docs/recipes/kickassembler/screenshots/wireframe-ships-ntsc.png +0 -0
- package/docs/recipes/kickassembler/screenshots/wireframe-ships.png +0 -0
- package/docs/recipes/kickassembler/scroll-panel-split.md +381 -0
- package/docs/recipes/kickassembler/sfx-in-player.md +907 -0
- package/docs/recipes/kickassembler/shadebobs.md +522 -0
- package/docs/recipes/kickassembler/sideborder-open.md +338 -0
- package/docs/recipes/kickassembler/sine-scroller.md +321 -0
- package/docs/recipes/kickassembler/sine-table-runtime.md +815 -0
- package/docs/recipes/kickassembler/software-sprite-preshifted.md +725 -0
- package/docs/recipes/kickassembler/speedcode-generator.md +606 -0
- package/docs/recipes/kickassembler/sprite-border-scroller.md +696 -0
- package/docs/recipes/kickassembler/sprite-cache-flip.md +1071 -0
- package/docs/recipes/kickassembler/sprite-multiplex-24.md +326 -0
- package/docs/recipes/kickassembler/sprite-multiplex-game.md +986 -0
- package/docs/recipes/kickassembler/sprite-priority-classes.md +463 -0
- package/docs/recipes/kickassembler/sprite-sine-chain.md +338 -0
- package/docs/recipes/kickassembler/sprite-stretcher.md +501 -0
- package/docs/recipes/kickassembler/sprites-only-screen.md +550 -0
- package/docs/recipes/kickassembler/sqrt-atan2.md +1014 -0
- package/docs/recipes/kickassembler/stable-raster-irq.md +360 -0
- package/docs/recipes/kickassembler/tape-turbo-loader.md +875 -0
- package/docs/recipes/kickassembler/tech-tech.md +679 -0
- package/docs/recipes/kickassembler/tod-alarm.md +754 -0
- package/docs/recipes/kickassembler/topbottom-border-open.md +407 -0
- package/docs/recipes/kickassembler/twister.md +518 -0
- package/docs/recipes/kickassembler/unit-test-driver.md +314 -0
- package/docs/recipes/kickassembler/vector-balls.md +545 -0
- package/docs/recipes/kickassembler/wireframe-ships.md +2324 -0
- package/docs/recipes/oscar64/actor-activation-window.md +807 -0
- package/docs/recipes/oscar64/adventure-engine.md +1094 -0
- package/docs/recipes/oscar64/attract-replay.md +465 -0
- package/docs/recipes/oscar64/beat-em-up-lanes.md +563 -0
- package/docs/recipes/oscar64/bfs-distance-map.md +723 -0
- package/docs/recipes/oscar64/bitmap-koala-viewer.md +355 -0
- package/docs/recipes/oscar64/car-contact.md +950 -0
- package/docs/recipes/oscar64/cave-scan.md +609 -0
- package/docs/recipes/oscar64/char-bullets.md +477 -0
- package/docs/recipes/oscar64/charset-animation.md +383 -0
- package/docs/recipes/oscar64/charset-parallax.md +401 -0
- package/docs/recipes/oscar64/destructible-terrain.md +1099 -0
- package/docs/recipes/oscar64/difficulty-tables.md +654 -0
- package/docs/recipes/oscar64/dig-and-guards.md +975 -0
- package/docs/recipes/oscar64/directory-reader.md +535 -0
- package/docs/recipes/oscar64/divide-check.md +581 -0
- package/docs/recipes/oscar64/double-buffer-nomirror.md +205 -0
- package/docs/recipes/oscar64/double-buffer.md +255 -0
- package/docs/recipes/oscar64/falling-blocks.md +874 -0
- package/docs/recipes/oscar64/fixed-point-jump-velocity.md +289 -0
- package/docs/recipes/oscar64/fixed-point-jump.md +210 -0
- package/docs/recipes/oscar64/flip-screen-rooms.md +793 -0
- package/docs/recipes/oscar64/frame-sync-loop-overrun.md +214 -0
- package/docs/recipes/oscar64/frame-sync-loop.md +254 -0
- package/docs/recipes/oscar64/game-tree-search.md +743 -0
- package/docs/recipes/oscar64/ghost-targeting.md +867 -0
- package/docs/recipes/oscar64/headless-verify.md +345 -0
- package/docs/recipes/oscar64/hello-world.md +83 -0
- package/docs/recipes/oscar64/high-score-persist.md +772 -0
- package/docs/recipes/oscar64/iffl-kernal-skip.md +421 -0
- package/docs/recipes/oscar64/joystick-input.md +358 -0
- package/docs/recipes/oscar64/lane-pursuit.md +1028 -0
- package/docs/recipes/oscar64/level-rle-decoder.md +620 -0
- package/docs/recipes/oscar64/lfsr-random-seed2.md +338 -0
- package/docs/recipes/oscar64/lfsr-random.md +403 -0
- package/docs/recipes/oscar64/load-asset-runtime.md +492 -0
- package/docs/recipes/oscar64/memory-layout.md +232 -0
- package/docs/recipes/oscar64/mixed-fighters.md +781 -0
- package/docs/recipes/oscar64/multi-sprite-object.md +533 -0
- package/docs/recipes/oscar64/nav-area-pathfinding.md +881 -0
- package/docs/recipes/oscar64/object-pool.md +572 -0
- package/docs/recipes/oscar64/pal-ntsc-detect.md +257 -0
- package/docs/recipes/oscar64/password-state.md +532 -0
- package/docs/recipes/oscar64/per-frame-hitbox.md +651 -0
- package/docs/recipes/oscar64/petscii-screen-codes.md +428 -0
- package/docs/recipes/oscar64/platformer-scaffold.md +1467 -0
- package/docs/recipes/oscar64/print-number.md +367 -0
- package/docs/recipes/oscar64/raster-bars.md +239 -0
- package/docs/recipes/oscar64/raster-profile-bars.md +404 -0
- package/docs/recipes/oscar64/rel-side-sectors.md +391 -0
- package/docs/recipes/oscar64/relative-file-records.md +378 -0
- package/docs/recipes/oscar64/save-load-seq-file.md +365 -0
- package/docs/recipes/oscar64/screenshots/README.md +99 -0
- package/docs/recipes/oscar64/screenshots/actor-activation-window-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/actor-activation-window.png +0 -0
- package/docs/recipes/oscar64/screenshots/adventure-engine-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/adventure-engine.png +0 -0
- package/docs/recipes/oscar64/screenshots/attract-replay-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/attract-replay.png +0 -0
- package/docs/recipes/oscar64/screenshots/beat-em-up-lanes-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/beat-em-up-lanes.png +0 -0
- package/docs/recipes/oscar64/screenshots/bfs-distance-map-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/bfs-distance-map.png +0 -0
- package/docs/recipes/oscar64/screenshots/bitmap-koala-viewer.png +0 -0
- package/docs/recipes/oscar64/screenshots/car-contact-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/car-contact.png +0 -0
- package/docs/recipes/oscar64/screenshots/cave-scan-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/cave-scan.png +0 -0
- package/docs/recipes/oscar64/screenshots/char-bullets-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/char-bullets.png +0 -0
- package/docs/recipes/oscar64/screenshots/charset-animation-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/charset-animation.png +0 -0
- package/docs/recipes/oscar64/screenshots/charset-parallax-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/charset-parallax.png +0 -0
- package/docs/recipes/oscar64/screenshots/destructible-terrain-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/destructible-terrain.png +0 -0
- package/docs/recipes/oscar64/screenshots/difficulty-tables-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/difficulty-tables.png +0 -0
- package/docs/recipes/oscar64/screenshots/dig-and-guards-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/dig-and-guards.png +0 -0
- package/docs/recipes/oscar64/screenshots/directory-reader-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/directory-reader.png +0 -0
- package/docs/recipes/oscar64/screenshots/divide-check-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/divide-check.png +0 -0
- package/docs/recipes/oscar64/screenshots/double-buffer-nomirror.png +0 -0
- package/docs/recipes/oscar64/screenshots/double-buffer-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/double-buffer.png +0 -0
- package/docs/recipes/oscar64/screenshots/falling-blocks-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/falling-blocks.png +0 -0
- package/docs/recipes/oscar64/screenshots/fixed-point-jump-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/fixed-point-jump-velocity-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/fixed-point-jump-velocity.png +0 -0
- package/docs/recipes/oscar64/screenshots/fixed-point-jump.png +0 -0
- package/docs/recipes/oscar64/screenshots/flip-screen-rooms-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/flip-screen-rooms.png +0 -0
- package/docs/recipes/oscar64/screenshots/frame-sync-loop-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/frame-sync-loop-overrun.png +0 -0
- package/docs/recipes/oscar64/screenshots/frame-sync-loop.png +0 -0
- package/docs/recipes/oscar64/screenshots/game-tree-search-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/game-tree-search.png +0 -0
- package/docs/recipes/oscar64/screenshots/ghost-targeting-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/ghost-targeting.png +0 -0
- package/docs/recipes/oscar64/screenshots/headless-verify-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/headless-verify.png +0 -0
- package/docs/recipes/oscar64/screenshots/hello-world.png +0 -0
- package/docs/recipes/oscar64/screenshots/high-score-persist-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/high-score-persist.png +0 -0
- package/docs/recipes/oscar64/screenshots/iffl-kernal-skip-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/iffl-kernal-skip.png +0 -0
- package/docs/recipes/oscar64/screenshots/joystick-input-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/joystick-input.png +0 -0
- package/docs/recipes/oscar64/screenshots/lane-pursuit-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/lane-pursuit.png +0 -0
- package/docs/recipes/oscar64/screenshots/level-rle-decoder-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/level-rle-decoder.png +0 -0
- package/docs/recipes/oscar64/screenshots/lfsr-random-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/lfsr-random-seed2.png +0 -0
- package/docs/recipes/oscar64/screenshots/lfsr-random.png +0 -0
- package/docs/recipes/oscar64/screenshots/load-asset-runtime-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/load-asset-runtime.png +0 -0
- package/docs/recipes/oscar64/screenshots/memory-layout-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/memory-layout.png +0 -0
- package/docs/recipes/oscar64/screenshots/mixed-fighters-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/mixed-fighters.png +0 -0
- package/docs/recipes/oscar64/screenshots/multi-sprite-object-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/multi-sprite-object.png +0 -0
- package/docs/recipes/oscar64/screenshots/nav-area-pathfinding-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/nav-area-pathfinding.png +0 -0
- package/docs/recipes/oscar64/screenshots/object-pool-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/object-pool.png +0 -0
- package/docs/recipes/oscar64/screenshots/pal-ntsc-detect-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/pal-ntsc-detect-oldntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/pal-ntsc-detect-pal.png +0 -0
- package/docs/recipes/oscar64/screenshots/password-state-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/password-state.png +0 -0
- package/docs/recipes/oscar64/screenshots/per-frame-hitbox-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/per-frame-hitbox.png +0 -0
- package/docs/recipes/oscar64/screenshots/petscii-screen-codes-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/petscii-screen-codes.png +0 -0
- package/docs/recipes/oscar64/screenshots/platformer-scaffold-d64-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/platformer-scaffold-d64.png +0 -0
- package/docs/recipes/oscar64/screenshots/platformer-scaffold-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/platformer-scaffold.png +0 -0
- package/docs/recipes/oscar64/screenshots/print-number-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/print-number.png +0 -0
- package/docs/recipes/oscar64/screenshots/raster-bars.png +0 -0
- package/docs/recipes/oscar64/screenshots/raster-profile-bars-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/raster-profile-bars.png +0 -0
- package/docs/recipes/oscar64/screenshots/rel-side-sectors-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/rel-side-sectors.png +0 -0
- package/docs/recipes/oscar64/screenshots/relative-file-records-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/relative-file-records.png +0 -0
- package/docs/recipes/oscar64/screenshots/save-load-seq-file-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/save-load-seq-file.png +0 -0
- package/docs/recipes/oscar64/screenshots/seeded-level-fill-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/seeded-level-fill.png +0 -0
- package/docs/recipes/oscar64/screenshots/sfx-engine-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/sfx-engine.png +0 -0
- package/docs/recipes/oscar64/screenshots/sid-music-player.png +0 -0
- package/docs/recipes/oscar64/screenshots/simple-shmup.png +0 -0
- package/docs/recipes/oscar64/screenshots/slope-collision-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/slope-collision.png +0 -0
- package/docs/recipes/oscar64/screenshots/soft-scroll-h.png +0 -0
- package/docs/recipes/oscar64/screenshots/sprite-animation-table-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/sprite-animation-table.png +0 -0
- package/docs/recipes/oscar64/screenshots/sprite-multiplex-8.png +0 -0
- package/docs/recipes/oscar64/screenshots/stable-raster-irq.png +0 -0
- package/docs/recipes/oscar64/screenshots/text-input-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/text-input.png +0 -0
- package/docs/recipes/oscar64/screenshots/text-overlay-playfield-gameover.png +0 -0
- package/docs/recipes/oscar64/screenshots/text-overlay-playfield-notrail-control.png +0 -0
- package/docs/recipes/oscar64/screenshots/text-overlay-playfield-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/text-overlay-playfield-ungated-control.png +0 -0
- package/docs/recipes/oscar64/screenshots/text-overlay-playfield.png +0 -0
- package/docs/recipes/oscar64/screenshots/text-window-menu-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/text-window-menu.png +0 -0
- package/docs/recipes/oscar64/screenshots/tile-grid-collision-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/tile-grid-collision.png +0 -0
- package/docs/recipes/oscar64/screenshots/tile-map-render-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/tile-map-render.png +0 -0
- package/docs/recipes/oscar64/screenshots/two-player-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/two-player.png +0 -0
- package/docs/recipes/oscar64/screenshots/two-word-parser-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/two-word-parser.png +0 -0
- package/docs/recipes/oscar64/screenshots/vehicle-control-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/vehicle-control.png +0 -0
- package/docs/recipes/oscar64/screenshots/wave-director-ntsc.png +0 -0
- package/docs/recipes/oscar64/screenshots/wave-director.png +0 -0
- package/docs/recipes/oscar64/seeded-level-fill.md +364 -0
- package/docs/recipes/oscar64/sfx-engine.md +514 -0
- package/docs/recipes/oscar64/sid-music-player.md +441 -0
- package/docs/recipes/oscar64/simple-shmup.md +1000 -0
- package/docs/recipes/oscar64/slope-collision.md +610 -0
- package/docs/recipes/oscar64/soft-scroll-h.md +261 -0
- package/docs/recipes/oscar64/sprite-animation-table.md +671 -0
- package/docs/recipes/oscar64/sprite-multiplex-8.md +314 -0
- package/docs/recipes/oscar64/stable-raster-irq.md +236 -0
- package/docs/recipes/oscar64/text-input.md +274 -0
- package/docs/recipes/oscar64/text-overlay-playfield.md +617 -0
- package/docs/recipes/oscar64/text-window-menu.md +551 -0
- package/docs/recipes/oscar64/tile-grid-collision.md +563 -0
- package/docs/recipes/oscar64/tile-map-render.md +395 -0
- package/docs/recipes/oscar64/two-player.md +528 -0
- package/docs/recipes/oscar64/two-word-parser.md +510 -0
- package/docs/recipes/oscar64/vehicle-control.md +771 -0
- package/docs/recipes/oscar64/wave-director.md +787 -0
- package/docs/recipes/runs.json +1606 -0
- package/docs/runtime/sim6502-reference.md +466 -0
- package/docs/runtime/vice-mcp-reference.md +351 -0
- package/docs/runtime/vice-reference.md +1393 -0
- package/docs/techniques/bitmap-modes.md +685 -0
- package/docs/techniques/cpu-cycle-tricks.md +1570 -0
- package/docs/techniques/effects-vector-3d.md +1431 -0
- package/docs/techniques/file-io.md +1427 -0
- package/docs/techniques/input.md +1072 -0
- package/docs/techniques/loaders-packers.md +768 -0
- package/docs/techniques/logic.md +3091 -0
- package/docs/techniques/maths.md +1524 -0
- package/docs/techniques/memory-banking.md +1686 -0
- package/docs/techniques/music-sid.md +1144 -0
- package/docs/techniques/raster.md +1543 -0
- package/docs/techniques/scroll.md +1292 -0
- package/docs/techniques/sprite.md +2566 -0
- package/docs/techniques/text-mode-render.md +717 -0
- package/docs/techniques/text.md +1095 -0
- package/docs/techniques/transitions.md +405 -0
- package/docs/toolchains/cartconv-reference.md +262 -0
- package/docs/toolchains/cc1541-reference.md +316 -0
- package/docs/toolchains/cc65-reference.md +667 -0
- package/docs/toolchains/error-sources/cc65/README.md +1 -0
- package/docs/toolchains/error-sources/cc65/missing-setcpu.s +4 -0
- package/docs/toolchains/error-sources/cc65/range-error.s +4 -0
- package/docs/toolchains/error-sources/cc65/segment-overflow.c +6 -0
- package/docs/toolchains/error-sources/cc65/unresolved-external.c +6 -0
- package/docs/toolchains/error-sources/kickassembler/README.md +1 -0
- package/docs/toolchains/error-sources/kickassembler/branch-out-of-range.asm +4 -0
- package/docs/toolchains/error-sources/kickassembler/failed-assert.asm +3 -0
- package/docs/toolchains/error-sources/kickassembler/flat-lib.asm +4 -0
- package/docs/toolchains/error-sources/kickassembler/import-source-no-namespace.asm +5 -0
- package/docs/toolchains/error-sources/kickassembler/macro-without-parentheses.asm +6 -0
- package/docs/toolchains/error-sources/kickassembler/memory-block-overlap.asm +4 -0
- package/docs/toolchains/error-sources/kickassembler/symbol-clash-lib.asm +5 -0
- package/docs/toolchains/error-sources/kickassembler/symbol-clash-main.asm +6 -0
- package/docs/toolchains/error-sources/kickassembler/unknown-symbol.asm +4 -0
- package/docs/toolchains/error-sources/oscar64/README.md +1 -0
- package/docs/toolchains/error-sources/oscar64/asm-addressing-mode.c +7 -0
- package/docs/toolchains/error-sources/oscar64/region-overflow.c +6 -0
- package/docs/toolchains/error-sources/oscar64/undefined-extern-var.c +5 -0
- package/docs/toolchains/error-sources/oscar64/undefined-extern.c +6 -0
- package/docs/toolchains/error-sources/oscar64/unknown-vic-field.c +6 -0
- package/docs/toolchains/error-sources/oscar64/void-main.c +3 -0
- package/docs/toolchains/kickassembler-reference.md +1020 -0
- package/docs/toolchains/memory-layout-planning.md +362 -0
- package/docs/toolchains/oscar64-headers-reference.md +583 -0
- package/docs/toolchains/oscar64-reference.md +892 -0
- package/docs/toolchains/petcat-reference.md +290 -0
- package/docs/toolchains/png2prg.md +188 -0
- package/docs/toolchains/release-disk.md +314 -0
- package/docs/toolchains/sidreloc.md +236 -0
- package/docs/toolchains/spindle-reference.md +487 -0
- package/docs/toolchains/tape-mastering.md +592 -0
- package/docs/toolchains/unit-testing-6502.md +281 -0
- package/docs/workflow/agent-harness.md +478 -0
- package/package.json +105 -0
- package/templates/_harness/CLAUDE.md.template +91 -0
- package/templates/_harness/PLAN.md.template +72 -0
- package/templates/_harness/check.py +442 -0
- package/templates/_harness/claude/settings.json +17 -0
- package/templates/_harness/gen-asm-header.py +96 -0
- package/templates/_harness/harness.mk +273 -0
- package/templates/_harness/hooks/plan-gate.py +185 -0
- package/templates/_harness/meter/frame_meter.asm +311 -0
- package/templates/_harness/meter/frame_meter.c +155 -0
- package/templates/_harness/meter/frame_meter.h +80 -0
- package/templates/_harness/zp-used.py +104 -0
- package/templates/action-puzzle/.claude/settings.json +17 -0
- package/templates/action-puzzle/.mcp.json +10 -0
- package/templates/action-puzzle/CLAUDE.md +120 -0
- package/templates/action-puzzle/Makefile +125 -0
- package/templates/action-puzzle/PLAN.md +388 -0
- package/templates/action-puzzle/README.md +240 -0
- package/templates/action-puzzle/expect.json +25 -0
- package/templates/action-puzzle/src/cave.c +280 -0
- package/templates/action-puzzle/src/cave.h +80 -0
- package/templates/action-puzzle/src/gen_autopilot.h +20 -0
- package/templates/action-puzzle/src/gen_caves.h +59 -0
- package/templates/action-puzzle/src/gen_notes.h +16 -0
- package/templates/action-puzzle/src/hiscore.c +152 -0
- package/templates/action-puzzle/src/hiscore.h +41 -0
- package/templates/action-puzzle/src/level.c +64 -0
- package/templates/action-puzzle/src/level.h +24 -0
- package/templates/action-puzzle/src/main.c +599 -0
- package/templates/action-puzzle/src/render.c +239 -0
- package/templates/action-puzzle/src/render.h +31 -0
- package/templates/action-puzzle/src/sound.c +158 -0
- package/templates/action-puzzle/src/sound.h +22 -0
- package/templates/action-puzzle/tools/disk_check.py +77 -0
- package/templates/action-puzzle/tools/drive.py +106 -0
- package/templates/action-puzzle/tools/gen.py +454 -0
- package/templates/action-puzzle/tools/model_check.py +49 -0
- package/templates/action-puzzle/tools/verdict_codes.py +24 -0
- package/templates/adventure/.claude/settings.json +17 -0
- package/templates/adventure/.mcp.json +10 -0
- package/templates/adventure/CLAUDE.md +118 -0
- package/templates/adventure/Makefile +113 -0
- package/templates/adventure/PLAN.md +396 -0
- package/templates/adventure/README.md +277 -0
- package/templates/adventure/expect.json +25 -0
- package/templates/adventure/src/engine.c +543 -0
- package/templates/adventure/src/engine.h +48 -0
- package/templates/adventure/src/gen_script.h +141 -0
- package/templates/adventure/src/gen_world.h +511 -0
- package/templates/adventure/src/main.c +439 -0
- package/templates/adventure/src/picture.c +83 -0
- package/templates/adventure/src/picture.h +16 -0
- package/templates/adventure/src/save.c +159 -0
- package/templates/adventure/src/save.h +25 -0
- package/templates/adventure/src/sound.c +71 -0
- package/templates/adventure/src/sound.h +16 -0
- package/templates/adventure/src/text.c +349 -0
- package/templates/adventure/src/text.h +40 -0
- package/templates/adventure/tools/disk_check.py +128 -0
- package/templates/adventure/tools/drive.py +119 -0
- package/templates/adventure/tools/gen.py +1033 -0
- package/templates/adventure/tools/world.py +356 -0
- package/templates/beat-em-up/.claude/settings.json +17 -0
- package/templates/beat-em-up/.mcp.json +10 -0
- package/templates/beat-em-up/CLAUDE.md +136 -0
- package/templates/beat-em-up/Makefile +96 -0
- package/templates/beat-em-up/PLAN.md +502 -0
- package/templates/beat-em-up/README.md +315 -0
- package/templates/beat-em-up/expect-gameover.json +8 -0
- package/templates/beat-em-up/expect.json +29 -0
- package/templates/beat-em-up/src/anim.c +70 -0
- package/templates/beat-em-up/src/art.c +344 -0
- package/templates/beat-em-up/src/autopilot.h +154 -0
- package/templates/beat-em-up/src/brute.c +273 -0
- package/templates/beat-em-up/src/enemy.c +281 -0
- package/templates/beat-em-up/src/engine.asm +512 -0
- package/templates/beat-em-up/src/fighter.c +384 -0
- package/templates/beat-em-up/src/game.h +269 -0
- package/templates/beat-em-up/src/hud.c +135 -0
- package/templates/beat-em-up/src/main.c +341 -0
- package/templates/beat-em-up/src/sound.c +44 -0
- package/templates/beat-em-up/src/street.c +93 -0
- package/templates/beat-em-up/src/verdict.h +523 -0
- package/templates/beat-em-up/src/view.c +362 -0
- package/templates/beat-em-up/tools/drive.py +105 -0
- package/templates/beat-em-up/tools/flickercheck.py +273 -0
- package/templates/demo/.claude/settings.json +17 -0
- package/templates/demo/.mcp.json +10 -0
- package/templates/demo/CLAUDE.md +129 -0
- package/templates/demo/Makefile +66 -0
- package/templates/demo/PLAN.md +401 -0
- package/templates/demo/README.md +322 -0
- package/templates/demo/expect.json +945 -0
- package/templates/demo/src/config.asm +80 -0
- package/templates/demo/src/framework.asm +390 -0
- package/templates/demo/src/main.asm +139 -0
- package/templates/demo/src/music.asm +197 -0
- package/templates/demo/src/part_main.asm +279 -0
- package/templates/demo/src/part_title.asm +79 -0
- package/templates/demo/src/parts.asm +43 -0
- package/templates/demo/src/tables.asm +73 -0
- package/templates/demo/src/verdict.asm +179 -0
- package/templates/demo/tools/audio.py +80 -0
- package/templates/demo/tools/gen_expect.py +167 -0
- package/templates/demo/tools/probe.py +95 -0
- package/templates/hello/.claude/settings.json +17 -0
- package/templates/hello/.mcp.json +10 -0
- package/templates/hello/CLAUDE.md +100 -0
- package/templates/hello/Makefile +38 -0
- package/templates/hello/PLAN.md +200 -0
- package/templates/hello/expect.json +20 -0
- package/templates/hello/src/main.c +161 -0
- package/templates/hello/src/sprite.asm +27 -0
- package/templates/hello-kick/.claude/settings.json +17 -0
- package/templates/hello-kick/.mcp.json +10 -0
- package/templates/hello-kick/CLAUDE.md +100 -0
- package/templates/hello-kick/Makefile +17 -0
- package/templates/hello-kick/PLAN.md +199 -0
- package/templates/hello-kick/expect.json +20 -0
- package/templates/hello-kick/src/main.asm +233 -0
- package/templates/platformer/.claude/settings.json +17 -0
- package/templates/platformer/.mcp.json +10 -0
- package/templates/platformer/CLAUDE.md +125 -0
- package/templates/platformer/Makefile +86 -0
- package/templates/platformer/PLAN.md +360 -0
- package/templates/platformer/README.md +277 -0
- package/templates/platformer/expect.json +32 -0
- package/templates/platformer/src/actors.c +289 -0
- package/templates/platformer/src/anim.c +51 -0
- package/templates/platformer/src/art.c +212 -0
- package/templates/platformer/src/autopilot.h +30 -0
- package/templates/platformer/src/engine.asm +253 -0
- package/templates/platformer/src/game.h +248 -0
- package/templates/platformer/src/hud.c +90 -0
- package/templates/platformer/src/level.c +184 -0
- package/templates/platformer/src/main.c +306 -0
- package/templates/platformer/src/player.c +268 -0
- package/templates/platformer/src/sound.c +42 -0
- package/templates/platformer/src/verdict.h +206 -0
- package/templates/platformer/src/view.c +331 -0
- package/templates/platformer/stage-expect.json +6 -0
- package/templates/platformer/tools/drive.py +112 -0
- package/templates/platformer/tools/tearcheck.py +229 -0
- package/templates/shmup-vertical/.claude/settings.json +17 -0
- package/templates/shmup-vertical/.mcp.json +10 -0
- package/templates/shmup-vertical/CLAUDE.md +137 -0
- package/templates/shmup-vertical/Makefile +131 -0
- package/templates/shmup-vertical/PLAN.md +569 -0
- package/templates/shmup-vertical/README.md +189 -0
- package/templates/shmup-vertical/expect.json +38 -0
- package/templates/shmup-vertical/src/bullets.c +158 -0
- package/templates/shmup-vertical/src/bullets.h +35 -0
- package/templates/shmup-vertical/src/display.c +239 -0
- package/templates/shmup-vertical/src/display.h +40 -0
- package/templates/shmup-vertical/src/game.h +85 -0
- package/templates/shmup-vertical/src/glyph.asm +358 -0
- package/templates/shmup-vertical/src/hiscore.c +141 -0
- package/templates/shmup-vertical/src/hiscore.h +16 -0
- package/templates/shmup-vertical/src/hit.asm +180 -0
- package/templates/shmup-vertical/src/hitbox.c +59 -0
- package/templates/shmup-vertical/src/hitbox.h +25 -0
- package/templates/shmup-vertical/src/kernel.asm +330 -0
- package/templates/shmup-vertical/src/level.c +174 -0
- package/templates/shmup-vertical/src/level.h +27 -0
- package/templates/shmup-vertical/src/main.c +824 -0
- package/templates/shmup-vertical/src/mux.asm +321 -0
- package/templates/shmup-vertical/src/sound.asm +255 -0
- package/templates/shmup-vertical/src/step.asm +169 -0
- package/templates/shmup-vertical/src/waves.c +195 -0
- package/templates/shmup-vertical/src/waves.h +33 -0
- package/templates/shmup-vertical/stage-expect.json +6 -0
- package/templates/shmup-vertical/tools/drive.py +152 -0
- package/templates/shmup-vertical/tools/joytest.py +159 -0
- package/templates/shmup-vertical/tools/meter.py +15 -0
- package/templates/shmup-vertical/tools/phases.py +73 -0
|
@@ -0,0 +1,907 @@
|
|
|
1
|
+
---
|
|
2
|
+
recipe: sfx-in-player
|
|
3
|
+
toolchain: kickassembler
|
|
4
|
+
output_format: PRG
|
|
5
|
+
region: both
|
|
6
|
+
techniques: [sfx_in_player]
|
|
7
|
+
file_formats: [PRG]
|
|
8
|
+
uses_registers: [D011, D012, D020, D021, D400, D401, D402, D403, D404, D405, D406, D407, D408, D409, D40A, D40B, D40C, D40D, D40E, D40F, D410, D411, D412, D413, D414, D415, D416, D417, D418, DC04, DC05, DC0D, DC0E, DD0D]
|
|
9
|
+
uses_kernal: []
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
<!-- doc-type: recipe -->
|
|
13
|
+
|
|
14
|
+
# KickAssembler — Sound effects inside the music player, with voice stealing and hand-back
|
|
15
|
+
|
|
16
|
+
## Synopsis
|
|
17
|
+
|
|
18
|
+
A three-voice music player of its own, with a sound-effect entry point
|
|
19
|
+
built in. An effect takes one voice for its length. Requests are queued, so
|
|
20
|
+
at most one effect starts per frame and the higher effect number wins; an
|
|
21
|
+
effect cannot cut a higher-numbered one already on its voice. When an
|
|
22
|
+
effect ends, the player re-applies the music voice's instrument (AD, SR,
|
|
23
|
+
pulse width, waveform and gate) on that same frame. The player writes into
|
|
24
|
+
a 25-byte shadow of the SID and copies the whole shadow to `$D400`-`$D418`
|
|
25
|
+
once per frame ("ghost registers"). A script requests effects on fixed
|
|
26
|
+
frames, so the run needs no input. The program logs which voices an effect
|
|
27
|
+
owned on each of 120 frames, compares the log with an expected table, reads
|
|
28
|
+
the shadow on the frames around every hand-back, times each play call with
|
|
29
|
+
CIA1 timer A, and prints PASS or FAIL. The technique is `sfx_in_player` in
|
|
30
|
+
`techniques/music-sid.md`.
|
|
31
|
+
|
|
32
|
+
## Source
|
|
33
|
+
|
|
34
|
+
```asm
|
|
35
|
+
// sfx-in-player.asm: sound effects run inside a three-voice music player.
|
|
36
|
+
// The player keeps a 25-byte shadow of the SID ("ghost registers"), writes
|
|
37
|
+
// music or effect values into it per voice, and copies all 25 bytes to
|
|
38
|
+
// $D400-$D418 once per frame, $18 down to $00. An effect takes one voice for
|
|
39
|
+
// its length; a request is queued so at most one effect starts per frame and
|
|
40
|
+
// the higher effect number wins; an effect cannot cut a higher one already
|
|
41
|
+
// playing on its voice. When an effect ends the player re-applies the
|
|
42
|
+
// music voice's AD, SR, pulse width and control from its instrument.
|
|
43
|
+
// A script requests effects on fixed frames. The program logs which voices
|
|
44
|
+
// an effect owned on each of 120 frames, checks the log against an
|
|
45
|
+
// expected table, reads the shadow on the frames around each hand-back,
|
|
46
|
+
// times every play call with CIA1 timer A, and prints PASS or FAIL.
|
|
47
|
+
// Build: java -jar KickAss.jar sfx-in-player.asm -o sfx-in-player.prg
|
|
48
|
+
|
|
49
|
+
BasicUpstart2(start)
|
|
50
|
+
|
|
51
|
+
.encoding "screencode_upper"
|
|
52
|
+
|
|
53
|
+
.const SCREEN = $0400
|
|
54
|
+
.const LINE = 251 // below the display: no badlines, no sprites
|
|
55
|
+
.const NFRAMES = 120 // frames logged and checked
|
|
56
|
+
.label fxptr = $fb // zero-page pointer to the running effect
|
|
57
|
+
.label patptr = $fd // zero-page pointer to a voice's pattern
|
|
58
|
+
|
|
59
|
+
* = $0810
|
|
60
|
+
|
|
61
|
+
start:
|
|
62
|
+
sei
|
|
63
|
+
lda #$7f
|
|
64
|
+
sta $dc0d // no CIA interrupts: timer A is the stopwatch
|
|
65
|
+
sta $dd0d
|
|
66
|
+
lda $dc0d
|
|
67
|
+
lda $dd0d
|
|
68
|
+
lda #0
|
|
69
|
+
sta $d020
|
|
70
|
+
sta $d021
|
|
71
|
+
ldx #0
|
|
72
|
+
clr:
|
|
73
|
+
lda #$20
|
|
74
|
+
sta SCREEN,x
|
|
75
|
+
sta SCREEN + $100,x
|
|
76
|
+
sta SCREEN + $200,x
|
|
77
|
+
sta SCREEN + $2e8,x
|
|
78
|
+
lda #1
|
|
79
|
+
sta $d800,x
|
|
80
|
+
sta $d900,x
|
|
81
|
+
sta $da00,x
|
|
82
|
+
sta $dae8,x
|
|
83
|
+
inx
|
|
84
|
+
bne clr
|
|
85
|
+
ldx #0
|
|
86
|
+
lab:
|
|
87
|
+
lda labels,x
|
|
88
|
+
sta SCREEN,x
|
|
89
|
+
lda labels + $100,x
|
|
90
|
+
sta SCREEN + $100,x
|
|
91
|
+
inx
|
|
92
|
+
bne lab
|
|
93
|
+
|
|
94
|
+
jsr music_init
|
|
95
|
+
jsr calibrate
|
|
96
|
+
|
|
97
|
+
// ---------------------------------------------------------------------------
|
|
98
|
+
// Frame loop: script, timed play, log, checks. No interrupts.
|
|
99
|
+
// ---------------------------------------------------------------------------
|
|
100
|
+
frameloop:
|
|
101
|
+
jsr waitline
|
|
102
|
+
inc frame
|
|
103
|
+
jsr script
|
|
104
|
+
ldx #2 // mask of effect voices before play
|
|
105
|
+
jsr fxmask
|
|
106
|
+
sta maskbefore
|
|
107
|
+
jsr timed_play
|
|
108
|
+
ldx #2 // count effects on their first frame:
|
|
109
|
+
cnt1: // header and one row read, position 5
|
|
110
|
+
lda sfxnum,x
|
|
111
|
+
beq cnt2
|
|
112
|
+
lda sfxpos,x
|
|
113
|
+
cmp #5
|
|
114
|
+
bne cnt2
|
|
115
|
+
inc starts
|
|
116
|
+
cnt2:
|
|
117
|
+
dex
|
|
118
|
+
bpl cnt1
|
|
119
|
+
ldx #2
|
|
120
|
+
jsr fxmask
|
|
121
|
+
ldy frame
|
|
122
|
+
sta log - 1,y // frame 1 goes to log+0
|
|
123
|
+
ora maskbefore // an effect ran or handed back this frame
|
|
124
|
+
beq idlecat
|
|
125
|
+
lda cost + 1 // effect frame: keep the maximum
|
|
126
|
+
cmp fxmax + 1
|
|
127
|
+
bcc catdone
|
|
128
|
+
bne fxnew
|
|
129
|
+
lda cost
|
|
130
|
+
cmp fxmax
|
|
131
|
+
bcc catdone
|
|
132
|
+
fxnew:
|
|
133
|
+
lda cost
|
|
134
|
+
sta fxmax
|
|
135
|
+
lda cost + 1
|
|
136
|
+
sta fxmax + 1
|
|
137
|
+
lda frame
|
|
138
|
+
sta fxat
|
|
139
|
+
jmp catdone
|
|
140
|
+
idlecat:
|
|
141
|
+
lda cost + 1 // music-only frame: keep the maximum
|
|
142
|
+
cmp idmax + 1
|
|
143
|
+
bcc catdone
|
|
144
|
+
bne idnew
|
|
145
|
+
lda cost
|
|
146
|
+
cmp idmax
|
|
147
|
+
bcc catdone
|
|
148
|
+
idnew:
|
|
149
|
+
lda cost
|
|
150
|
+
sta idmax
|
|
151
|
+
lda cost + 1
|
|
152
|
+
sta idmax + 1
|
|
153
|
+
lda frame
|
|
154
|
+
sta idat
|
|
155
|
+
catdone:
|
|
156
|
+
lda cost + 1 // any frame: keep the minimum
|
|
157
|
+
cmp mnmin + 1
|
|
158
|
+
bcc mnnew
|
|
159
|
+
bne mndone
|
|
160
|
+
lda cost
|
|
161
|
+
cmp mnmin
|
|
162
|
+
bcs mndone
|
|
163
|
+
mnnew:
|
|
164
|
+
lda cost
|
|
165
|
+
sta mnmin
|
|
166
|
+
lda cost + 1
|
|
167
|
+
sta mnmin + 1
|
|
168
|
+
lda frame
|
|
169
|
+
sta mnat
|
|
170
|
+
mndone:
|
|
171
|
+
jsr checks
|
|
172
|
+
lda frame
|
|
173
|
+
cmp #NFRAMES
|
|
174
|
+
beq alldone
|
|
175
|
+
jmp frameloop
|
|
176
|
+
alldone:
|
|
177
|
+
jsr report
|
|
178
|
+
idle: // music keeps playing; the screen is final
|
|
179
|
+
jsr waitline
|
|
180
|
+
jsr play
|
|
181
|
+
jmp idle
|
|
182
|
+
|
|
183
|
+
waitline:
|
|
184
|
+
lda $d011
|
|
185
|
+
bmi waitline
|
|
186
|
+
lda $d012
|
|
187
|
+
cmp #LINE
|
|
188
|
+
bne waitline
|
|
189
|
+
rts
|
|
190
|
+
|
|
191
|
+
// A = mask of voices (bit 0 = voice 1) an effect owns; X = 2 on entry
|
|
192
|
+
fxmask:
|
|
193
|
+
lda #0
|
|
194
|
+
sta mtmp
|
|
195
|
+
fxm1:
|
|
196
|
+
lda sfxnum,x
|
|
197
|
+
cmp #1 // carry set if an effect owns voice X
|
|
198
|
+
rol mtmp
|
|
199
|
+
dex
|
|
200
|
+
bpl fxm1
|
|
201
|
+
lda mtmp // voice 3 rolled in first, ends in bit 2
|
|
202
|
+
rts
|
|
203
|
+
|
|
204
|
+
// ---------------------------------------------------------------------------
|
|
205
|
+
// Stopwatch: CIA1 timer A, one-shot from $FFFF.
|
|
206
|
+
// ---------------------------------------------------------------------------
|
|
207
|
+
calibrate:
|
|
208
|
+
lda #$ff
|
|
209
|
+
sta $dc04
|
|
210
|
+
sta $dc05
|
|
211
|
+
lda #%00011001 // force load, one-shot, start
|
|
212
|
+
sta $dc0e
|
|
213
|
+
lda #0
|
|
214
|
+
sta $dc0e // stop
|
|
215
|
+
sec
|
|
216
|
+
lda #$ff
|
|
217
|
+
sbc $dc04
|
|
218
|
+
sta calib
|
|
219
|
+
lda #$ff
|
|
220
|
+
sbc $dc05
|
|
221
|
+
sta calib + 1
|
|
222
|
+
rts
|
|
223
|
+
|
|
224
|
+
timed_play:
|
|
225
|
+
lda #$ff
|
|
226
|
+
sta $dc04
|
|
227
|
+
sta $dc05
|
|
228
|
+
lda #%00011001
|
|
229
|
+
sta $dc0e
|
|
230
|
+
jsr play
|
|
231
|
+
lda #0
|
|
232
|
+
sta $dc0e
|
|
233
|
+
sec
|
|
234
|
+
lda #$ff
|
|
235
|
+
sbc $dc04
|
|
236
|
+
sta cost
|
|
237
|
+
lda #$ff
|
|
238
|
+
sbc $dc05
|
|
239
|
+
sta cost + 1
|
|
240
|
+
sec // less the stopwatch's own start/stop
|
|
241
|
+
lda cost
|
|
242
|
+
sbc calib
|
|
243
|
+
sta cost
|
|
244
|
+
lda cost + 1
|
|
245
|
+
sbc calib + 1
|
|
246
|
+
sta cost + 1
|
|
247
|
+
rts
|
|
248
|
+
|
|
249
|
+
// ---------------------------------------------------------------------------
|
|
250
|
+
// Script: effect requests on fixed frames (the autopilot).
|
|
251
|
+
// ---------------------------------------------------------------------------
|
|
252
|
+
script:
|
|
253
|
+
ldx sidx
|
|
254
|
+
lda scframe,x
|
|
255
|
+
cmp frame
|
|
256
|
+
bne scdone
|
|
257
|
+
lda scfx,x
|
|
258
|
+
jsr sfx_request
|
|
259
|
+
inc sidx
|
|
260
|
+
jmp script // two requests may share a frame
|
|
261
|
+
scdone:
|
|
262
|
+
rts
|
|
263
|
+
|
|
264
|
+
// ===========================================================================
|
|
265
|
+
// The player
|
|
266
|
+
// ===========================================================================
|
|
267
|
+
|
|
268
|
+
// SFX entry point. A = effect number 1-4; a higher number wins.
|
|
269
|
+
// Only one request per frame survives to the player.
|
|
270
|
+
sfx_request:
|
|
271
|
+
cmp pending
|
|
272
|
+
bcc srdrop
|
|
273
|
+
ldy pending
|
|
274
|
+
beq srstore
|
|
275
|
+
inc dropped // a lower request queued this frame is lost
|
|
276
|
+
srstore:
|
|
277
|
+
sta pending
|
|
278
|
+
rts
|
|
279
|
+
srdrop:
|
|
280
|
+
inc dropped
|
|
281
|
+
rts
|
|
282
|
+
|
|
283
|
+
music_init:
|
|
284
|
+
ldx #2
|
|
285
|
+
mi1:
|
|
286
|
+
lda #0
|
|
287
|
+
sta mtimer,x
|
|
288
|
+
sta mseq,x
|
|
289
|
+
sta sfxnum,x
|
|
290
|
+
sta restore,x
|
|
291
|
+
dex
|
|
292
|
+
bpl mi1
|
|
293
|
+
ldx #$18
|
|
294
|
+
mi2:
|
|
295
|
+
lda #0
|
|
296
|
+
sta ghost,x
|
|
297
|
+
dex
|
|
298
|
+
bpl mi2
|
|
299
|
+
lda #$0f
|
|
300
|
+
sta ghost + $18 // volume 15, no filter
|
|
301
|
+
rts
|
|
302
|
+
|
|
303
|
+
play:
|
|
304
|
+
ldy pending // start the queued effect, if any
|
|
305
|
+
beq plvoices
|
|
306
|
+
ldx fxvoice,y
|
|
307
|
+
tya
|
|
308
|
+
cmp sfxnum,x
|
|
309
|
+
bcs pltake // same or higher than the one playing: take
|
|
310
|
+
inc refused
|
|
311
|
+
jmp plclear
|
|
312
|
+
pltake:
|
|
313
|
+
sta sfxnum,x
|
|
314
|
+
lda #0
|
|
315
|
+
sta sfxpos,x
|
|
316
|
+
plclear:
|
|
317
|
+
lda #0
|
|
318
|
+
sta pending
|
|
319
|
+
plvoices:
|
|
320
|
+
ldx #2
|
|
321
|
+
plv:
|
|
322
|
+
jsr voice
|
|
323
|
+
dex
|
|
324
|
+
bpl plv
|
|
325
|
+
ldx #$18 // ghost copy: every register, once per frame
|
|
326
|
+
plcopy:
|
|
327
|
+
lda ghost,x
|
|
328
|
+
sta $d400,x
|
|
329
|
+
dex
|
|
330
|
+
bpl plcopy
|
|
331
|
+
rts
|
|
332
|
+
|
|
333
|
+
// One voice. X = voice 0-2. The music advances every frame, owned or not.
|
|
334
|
+
voice:
|
|
335
|
+
lda voff,x
|
|
336
|
+
sta vo
|
|
337
|
+
lda #0
|
|
338
|
+
sta noteinit
|
|
339
|
+
lda mtimer,x
|
|
340
|
+
bne vgate
|
|
341
|
+
inc noteinit // first frame of a note: fetch it
|
|
342
|
+
lda patlo,x
|
|
343
|
+
sta patptr
|
|
344
|
+
lda pathi,x
|
|
345
|
+
sta patptr + 1
|
|
346
|
+
ldy mseq,x
|
|
347
|
+
lda (patptr),y
|
|
348
|
+
cmp #$ff
|
|
349
|
+
bne vnote
|
|
350
|
+
ldy #0 // end of pattern: loop
|
|
351
|
+
lda (patptr),y
|
|
352
|
+
vnote:
|
|
353
|
+
iny
|
|
354
|
+
sta ntmp
|
|
355
|
+
tya
|
|
356
|
+
sta mseq,x
|
|
357
|
+
ldy ntmp
|
|
358
|
+
lda freqlo,y
|
|
359
|
+
sta mflo,x
|
|
360
|
+
lda freqhi,y
|
|
361
|
+
sta mfhi,x
|
|
362
|
+
vgate:
|
|
363
|
+
lda mtimer,x // gate off on a note's first and last frame
|
|
364
|
+
beq vgoff
|
|
365
|
+
clc
|
|
366
|
+
adc #1
|
|
367
|
+
cmp idur,x
|
|
368
|
+
beq vgoff
|
|
369
|
+
lda iwave,x
|
|
370
|
+
ora #1
|
|
371
|
+
bne vgset
|
|
372
|
+
vgoff:
|
|
373
|
+
lda iwave,x
|
|
374
|
+
vgset:
|
|
375
|
+
sta mctrl,x
|
|
376
|
+
inc mtimer,x
|
|
377
|
+
lda mtimer,x
|
|
378
|
+
cmp idur,x
|
|
379
|
+
bne vowner
|
|
380
|
+
lda #0
|
|
381
|
+
sta mtimer,x
|
|
382
|
+
vowner:
|
|
383
|
+
lda sfxnum,x
|
|
384
|
+
bne veffect
|
|
385
|
+
vmusic:
|
|
386
|
+
ldy vo
|
|
387
|
+
lda restore,x // hand-back frame or note start: instrument
|
|
388
|
+
ora noteinit
|
|
389
|
+
beq vfc
|
|
390
|
+
lda #0
|
|
391
|
+
sta restore,x
|
|
392
|
+
lda iad,x
|
|
393
|
+
sta ghost + 5,y
|
|
394
|
+
lda isr,x
|
|
395
|
+
sta ghost + 6,y
|
|
396
|
+
lda ipw,x
|
|
397
|
+
sta ghost + 3,y
|
|
398
|
+
lda #0
|
|
399
|
+
sta ghost + 2,y
|
|
400
|
+
vfc:
|
|
401
|
+
lda mflo,x
|
|
402
|
+
sta ghost + 0,y
|
|
403
|
+
lda mfhi,x
|
|
404
|
+
sta ghost + 1,y
|
|
405
|
+
lda mctrl,x
|
|
406
|
+
sta ghost + 4,y
|
|
407
|
+
rts
|
|
408
|
+
|
|
409
|
+
// Effect data: AD, SR, pulse high, then rows of (control, freq high),
|
|
410
|
+
// one row per frame, ended by a control byte of 0.
|
|
411
|
+
veffect:
|
|
412
|
+
stx vidx
|
|
413
|
+
ldy sfxnum,x
|
|
414
|
+
lda fxlo,y
|
|
415
|
+
sta fxptr
|
|
416
|
+
lda fxhi,y
|
|
417
|
+
sta fxptr + 1
|
|
418
|
+
ldy sfxpos,x
|
|
419
|
+
ldx vo
|
|
420
|
+
cpy #0
|
|
421
|
+
bne vrow
|
|
422
|
+
lda (fxptr),y // first frame: the effect's envelope and pulse
|
|
423
|
+
sta ghost + 5,x
|
|
424
|
+
iny
|
|
425
|
+
lda (fxptr),y
|
|
426
|
+
sta ghost + 6,x
|
|
427
|
+
iny
|
|
428
|
+
lda (fxptr),y
|
|
429
|
+
sta ghost + 3,x
|
|
430
|
+
lda #0
|
|
431
|
+
sta ghost + 2,x
|
|
432
|
+
iny
|
|
433
|
+
vrow:
|
|
434
|
+
lda (fxptr),y
|
|
435
|
+
beq vend
|
|
436
|
+
sta ghost + 4,x
|
|
437
|
+
iny
|
|
438
|
+
lda (fxptr),y
|
|
439
|
+
sta ghost + 1,x
|
|
440
|
+
lda #0
|
|
441
|
+
sta ghost + 0,x
|
|
442
|
+
iny
|
|
443
|
+
tya
|
|
444
|
+
ldx vidx
|
|
445
|
+
sta sfxpos,x
|
|
446
|
+
rts
|
|
447
|
+
vend:
|
|
448
|
+
ldx vidx // effect over: hand the voice back this frame
|
|
449
|
+
lda #0
|
|
450
|
+
sta sfxnum,x
|
|
451
|
+
lda #1
|
|
452
|
+
sta restore,x
|
|
453
|
+
jmp vmusic
|
|
454
|
+
|
|
455
|
+
// ===========================================================================
|
|
456
|
+
// Checks
|
|
457
|
+
// ===========================================================================
|
|
458
|
+
|
|
459
|
+
// Around each hand-back: on the effect's last frame the shadow holds the
|
|
460
|
+
// effect's AD and SR; on the next frame it holds the instrument's AD, SR,
|
|
461
|
+
// pulse high and waveform with GATE set (the music note is mid-note).
|
|
462
|
+
checks:
|
|
463
|
+
ldx cidx
|
|
464
|
+
lda ckframe,x
|
|
465
|
+
cmp frame
|
|
466
|
+
bne ckdone
|
|
467
|
+
ldy ckvoice,x
|
|
468
|
+
lda voff,y
|
|
469
|
+
tay // Y = ghost offset
|
|
470
|
+
lda cktype,x
|
|
471
|
+
bne ckback
|
|
472
|
+
lda ckfx,x // owned: compare with the effect header
|
|
473
|
+
tax
|
|
474
|
+
lda fxlo,x
|
|
475
|
+
sta fxptr
|
|
476
|
+
lda fxhi,x
|
|
477
|
+
sta fxptr + 1
|
|
478
|
+
lda ghost + 5,y
|
|
479
|
+
sta ctmp
|
|
480
|
+
lda ghost + 6,y
|
|
481
|
+
ldy #1
|
|
482
|
+
cmp (fxptr),y
|
|
483
|
+
bne ckfail
|
|
484
|
+
lda ctmp
|
|
485
|
+
dey
|
|
486
|
+
cmp (fxptr),y
|
|
487
|
+
bne ckfail
|
|
488
|
+
jmp ckpass
|
|
489
|
+
ckback:
|
|
490
|
+
ldx cidx
|
|
491
|
+
lda ckvoice,x
|
|
492
|
+
tax // X = voice
|
|
493
|
+
lda ghost + 5,y
|
|
494
|
+
cmp iad,x
|
|
495
|
+
bne ckfail
|
|
496
|
+
lda ghost + 6,y
|
|
497
|
+
cmp isr,x
|
|
498
|
+
bne ckfail
|
|
499
|
+
lda ghost + 3,y
|
|
500
|
+
cmp ipw,x
|
|
501
|
+
bne ckfail
|
|
502
|
+
ldy cidx // type 1 wants GATE set, type 2 clear
|
|
503
|
+
lda cktype,y
|
|
504
|
+
and #1
|
|
505
|
+
ldy voff,x // Y = ghost offset again
|
|
506
|
+
ora iwave,x
|
|
507
|
+
cmp ghost + 4,y
|
|
508
|
+
bne ckfail
|
|
509
|
+
ckpass:
|
|
510
|
+
inc ckok
|
|
511
|
+
ckfail:
|
|
512
|
+
inc cidx
|
|
513
|
+
ckdone:
|
|
514
|
+
rts
|
|
515
|
+
|
|
516
|
+
// ===========================================================================
|
|
517
|
+
// Report
|
|
518
|
+
// ===========================================================================
|
|
519
|
+
report:
|
|
520
|
+
ldx #0 // mask log, rows 2 to 4
|
|
521
|
+
rp1:
|
|
522
|
+
lda log,x
|
|
523
|
+
ora #$30
|
|
524
|
+
sta SCREEN + 2 * 40,x
|
|
525
|
+
inx
|
|
526
|
+
cpx #NFRAMES
|
|
527
|
+
bne rp1
|
|
528
|
+
|
|
529
|
+
ldx #0 // compare the log with the expected runs
|
|
530
|
+
ldy #0
|
|
531
|
+
rp2:
|
|
532
|
+
lda exprun,y // run length, 0 ends
|
|
533
|
+
beq rp4
|
|
534
|
+
sta rtmp
|
|
535
|
+
lda exprun + 1,y
|
|
536
|
+
rp3:
|
|
537
|
+
cmp log,x
|
|
538
|
+
bne rpbad
|
|
539
|
+
inx
|
|
540
|
+
dec rtmp
|
|
541
|
+
bne rp3
|
|
542
|
+
iny
|
|
543
|
+
iny
|
|
544
|
+
jmp rp2
|
|
545
|
+
rpbad:
|
|
546
|
+
inc logbad
|
|
547
|
+
rp4:
|
|
548
|
+
cpx #NFRAMES
|
|
549
|
+
beq rp5
|
|
550
|
+
inc logbad
|
|
551
|
+
rp5:
|
|
552
|
+
lda #<(SCREEN + 5 * 40 + 7)
|
|
553
|
+
ldx #>(SCREEN + 5 * 40 + 7)
|
|
554
|
+
ldy starts
|
|
555
|
+
jsr puthex
|
|
556
|
+
lda #<(SCREEN + 5 * 40 + 18)
|
|
557
|
+
ldx #>(SCREEN + 5 * 40 + 18)
|
|
558
|
+
ldy refused
|
|
559
|
+
jsr puthex
|
|
560
|
+
lda #<(SCREEN + 5 * 40 + 29)
|
|
561
|
+
ldx #>(SCREEN + 5 * 40 + 29)
|
|
562
|
+
ldy dropped
|
|
563
|
+
jsr puthex
|
|
564
|
+
lda #<(SCREEN + 6 * 40 + 16)
|
|
565
|
+
ldx #>(SCREEN + 6 * 40 + 16)
|
|
566
|
+
ldy ckok
|
|
567
|
+
jsr puthex
|
|
568
|
+
lda #<(SCREEN + 7 * 40 + 16)
|
|
569
|
+
ldx #>(SCREEN + 7 * 40 + 16)
|
|
570
|
+
ldy idmax + 1
|
|
571
|
+
jsr puthex
|
|
572
|
+
lda #<(SCREEN + 7 * 40 + 18)
|
|
573
|
+
ldx #>(SCREEN + 7 * 40 + 18)
|
|
574
|
+
ldy idmax
|
|
575
|
+
jsr puthex
|
|
576
|
+
lda #<(SCREEN + 7 * 40 + 31)
|
|
577
|
+
ldx #>(SCREEN + 7 * 40 + 31)
|
|
578
|
+
ldy idat
|
|
579
|
+
jsr puthex
|
|
580
|
+
lda #<(SCREEN + 8 * 40 + 16)
|
|
581
|
+
ldx #>(SCREEN + 8 * 40 + 16)
|
|
582
|
+
ldy fxmax + 1
|
|
583
|
+
jsr puthex
|
|
584
|
+
lda #<(SCREEN + 8 * 40 + 18)
|
|
585
|
+
ldx #>(SCREEN + 8 * 40 + 18)
|
|
586
|
+
ldy fxmax
|
|
587
|
+
jsr puthex
|
|
588
|
+
lda #<(SCREEN + 8 * 40 + 31)
|
|
589
|
+
ldx #>(SCREEN + 8 * 40 + 31)
|
|
590
|
+
ldy fxat
|
|
591
|
+
jsr puthex
|
|
592
|
+
lda #<(SCREEN + 9 * 40 + 16)
|
|
593
|
+
ldx #>(SCREEN + 9 * 40 + 16)
|
|
594
|
+
ldy mnmin + 1
|
|
595
|
+
jsr puthex
|
|
596
|
+
lda #<(SCREEN + 9 * 40 + 18)
|
|
597
|
+
ldx #>(SCREEN + 9 * 40 + 18)
|
|
598
|
+
ldy mnmin
|
|
599
|
+
jsr puthex
|
|
600
|
+
lda #<(SCREEN + 9 * 40 + 31)
|
|
601
|
+
ldx #>(SCREEN + 9 * 40 + 31)
|
|
602
|
+
ldy mnat
|
|
603
|
+
jsr puthex
|
|
604
|
+
lda #<(SCREEN + 10 * 40 + 16)
|
|
605
|
+
ldx #>(SCREEN + 10 * 40 + 16)
|
|
606
|
+
ldy calib + 1
|
|
607
|
+
jsr puthex
|
|
608
|
+
lda #<(SCREEN + 10 * 40 + 18)
|
|
609
|
+
ldx #>(SCREEN + 10 * 40 + 18)
|
|
610
|
+
ldy calib
|
|
611
|
+
jsr puthex
|
|
612
|
+
|
|
613
|
+
lda logbad // verdict
|
|
614
|
+
bne rpfail
|
|
615
|
+
lda ckok
|
|
616
|
+
cmp #8
|
|
617
|
+
bne rpfail
|
|
618
|
+
lda starts
|
|
619
|
+
cmp #5
|
|
620
|
+
bne rpfail
|
|
621
|
+
lda refused
|
|
622
|
+
cmp #1
|
|
623
|
+
bne rpfail
|
|
624
|
+
lda dropped
|
|
625
|
+
cmp #1
|
|
626
|
+
bne rpfail
|
|
627
|
+
ldx #3
|
|
628
|
+
rppass:
|
|
629
|
+
lda passtxt,x
|
|
630
|
+
sta SCREEN + 11 * 40 + 7,x
|
|
631
|
+
dex
|
|
632
|
+
bpl rppass
|
|
633
|
+
lda #5 // green border: PASS
|
|
634
|
+
sta $d020
|
|
635
|
+
rts
|
|
636
|
+
rpfail:
|
|
637
|
+
ldx #3
|
|
638
|
+
rpf1:
|
|
639
|
+
lda failtxt,x
|
|
640
|
+
sta SCREEN + 11 * 40 + 7,x
|
|
641
|
+
dex
|
|
642
|
+
bpl rpf1
|
|
643
|
+
lda #2 // red border: FAIL
|
|
644
|
+
sta $d020
|
|
645
|
+
rts
|
|
646
|
+
|
|
647
|
+
// Y = byte, A/X = screen address: two hex digits
|
|
648
|
+
puthex:
|
|
649
|
+
sta patptr
|
|
650
|
+
stx patptr + 1
|
|
651
|
+
tya
|
|
652
|
+
pha
|
|
653
|
+
lsr
|
|
654
|
+
lsr
|
|
655
|
+
lsr
|
|
656
|
+
lsr
|
|
657
|
+
tax
|
|
658
|
+
lda hexdig,x
|
|
659
|
+
ldy #0
|
|
660
|
+
sta (patptr),y
|
|
661
|
+
pla
|
|
662
|
+
and #$0f
|
|
663
|
+
tax
|
|
664
|
+
lda hexdig,x
|
|
665
|
+
ldy #1
|
|
666
|
+
sta (patptr),y
|
|
667
|
+
rts
|
|
668
|
+
|
|
669
|
+
// ===========================================================================
|
|
670
|
+
// Data
|
|
671
|
+
// ===========================================================================
|
|
672
|
+
voff: .byte 0, 7, 14
|
|
673
|
+
iwave: .byte $40, $20, $40 // pulse, saw, pulse
|
|
674
|
+
iad: .byte $08, $0a, $22
|
|
675
|
+
isr: .byte $a6, $80, $b8
|
|
676
|
+
ipw: .byte $08, $04, $06 // pulse width high nybble
|
|
677
|
+
idur: .byte 8, 16, 12 // frames per note
|
|
678
|
+
patlo: .byte <pat1, <pat2, <pat3
|
|
679
|
+
pathi: .byte >pat1, >pat2, >pat3
|
|
680
|
+
pat1: .byte 12, 16, 19, 16, 14, 17, 21, 17, $ff
|
|
681
|
+
pat2: .byte 0, 0, 5, 7, $ff
|
|
682
|
+
pat3: .byte 19, 21, 23, 21, $ff
|
|
683
|
+
|
|
684
|
+
// 24 semitones from C-3, PAL clock: f * 16777216 / 985248
|
|
685
|
+
.const K = 16777216 / 985248
|
|
686
|
+
freqlo: .fill 24, <round(K * 130.81 * pow(2, i / 12))
|
|
687
|
+
freqhi: .fill 24, >round(K * 130.81 * pow(2, i / 12))
|
|
688
|
+
|
|
689
|
+
// Effect number n: voice and data. Entry 0 is unused.
|
|
690
|
+
fxvoice: .byte 0, 2, 2, 2, 0
|
|
691
|
+
fxlo: .byte 0, <fx1, <fx2, <fx3, <fx4
|
|
692
|
+
fxhi: .byte 0, >fx1, >fx2, >fx3, >fx4
|
|
693
|
+
fx1: .byte $00, $f0, $02 // 10 frames, falling blip
|
|
694
|
+
.for (var r = 0; r < 9; r++) { .byte $41, $30 - r * 3 }
|
|
695
|
+
.byte $40, $08, 0
|
|
696
|
+
fx2: .byte $0c, $00, $08 // 40 frames, noise
|
|
697
|
+
.for (var r = 0; r < 39; r++) { .byte $81, $28 - (r >> 1) }
|
|
698
|
+
.byte $80, $10, 0
|
|
699
|
+
fx3: .byte $00, $c9, $03 // 20 frames, rising
|
|
700
|
+
.for (var r = 0; r < 19; r++) { .byte $41, $10 + r * 2 }
|
|
701
|
+
.byte $40, $38, 0
|
|
702
|
+
fx4: .byte $05, $50, $0c // 10 frames, voice 1
|
|
703
|
+
.for (var r = 0; r < 9; r++) { .byte $11, $20 + r * 4 }
|
|
704
|
+
.byte $10, $40, 0
|
|
705
|
+
|
|
706
|
+
// Script: frame, effect. Frame 0 ends it.
|
|
707
|
+
scframe: .byte 20, 30, 49, 49, 81, 87, 97, 0
|
|
708
|
+
scfx: .byte 2, 1, 1, 3, 4, 1, 4, 0
|
|
709
|
+
|
|
710
|
+
// Checks: frame, voice, type, effect for type 0. Type 0: the effect owns
|
|
711
|
+
// the voice. Type 1: hand-back mid-note, GATE set. Type 2: hand-back on a
|
|
712
|
+
// note's first frame, GATE clear.
|
|
713
|
+
ckframe: .byte 68, 69, 90, 91, 96, 97, 106, 107, 0
|
|
714
|
+
ckvoice: .byte 2, 2, 0, 0, 2, 2, 0, 0
|
|
715
|
+
cktype: .byte 0, 1, 0, 1, 0, 2, 0, 1
|
|
716
|
+
ckfx: .byte 3, 0, 4, 0, 1, 0, 4, 0
|
|
717
|
+
|
|
718
|
+
// Expected mask log as runs of (length, mask), written from the script,
|
|
719
|
+
// not from the player: bit 0 voice 1, bit 2 voice 3.
|
|
720
|
+
exprun: .byte 19, 0, 49, 4, 12, 0, 6, 1, 4, 5, 6, 4, 10, 1, 14, 0, 0
|
|
721
|
+
|
|
722
|
+
hexdig: .text "0123456789ABCDEF"
|
|
723
|
+
passtxt: .text "PASS"
|
|
724
|
+
failtxt: .text "FAIL"
|
|
725
|
+
|
|
726
|
+
labels:
|
|
727
|
+
.text "SFX INSIDE THE PLAYER: VOICE STEALING " // row 0
|
|
728
|
+
.text "EFFECT VOICES PER FRAME, FRAMES 1-120: " // row 1
|
|
729
|
+
.text " " // row 2
|
|
730
|
+
.text " " // row 3
|
|
731
|
+
.text " " // row 4
|
|
732
|
+
.text "STARTS REFUSED DROPPED " // row 5
|
|
733
|
+
.text "HANDBACK CHECKS OF 08 " // row 6
|
|
734
|
+
.text "PLAY IDLE MAX $ AT FRAME $ " // row 7
|
|
735
|
+
.text "PLAY FX MAX $ AT FRAME $ " // row 8
|
|
736
|
+
.text "PLAY MIN $ AT FRAME $ " // row 9
|
|
737
|
+
.text "STOPWATCH $ " // row 10
|
|
738
|
+
.text "RESULT " // row 11
|
|
739
|
+
.fill 512 - 12 * 40, $20
|
|
740
|
+
|
|
741
|
+
// Variables
|
|
742
|
+
frame: .byte 0
|
|
743
|
+
sidx: .byte 0
|
|
744
|
+
cidx: .byte 0
|
|
745
|
+
pending: .byte 0
|
|
746
|
+
refused: .byte 0
|
|
747
|
+
dropped: .byte 0
|
|
748
|
+
starts: .byte 0
|
|
749
|
+
ckok: .byte 0
|
|
750
|
+
logbad: .byte 0
|
|
751
|
+
maskbefore: .byte 0
|
|
752
|
+
mtmp: .byte 0
|
|
753
|
+
ntmp: .byte 0
|
|
754
|
+
ctmp: .byte 0
|
|
755
|
+
rtmp: .byte 0
|
|
756
|
+
vo: .byte 0
|
|
757
|
+
vidx: .byte 0
|
|
758
|
+
noteinit: .byte 0
|
|
759
|
+
cost: .word 0
|
|
760
|
+
calib: .word 0
|
|
761
|
+
idmax: .word 0
|
|
762
|
+
idat: .byte 0
|
|
763
|
+
fxmax: .word 0
|
|
764
|
+
fxat: .byte 0
|
|
765
|
+
mnmin: .word $ffff
|
|
766
|
+
mnat: .byte 0
|
|
767
|
+
mtimer: .fill 3, 0
|
|
768
|
+
mseq: .fill 3, 0
|
|
769
|
+
mflo: .fill 3, 0
|
|
770
|
+
mfhi: .fill 3, 0
|
|
771
|
+
mctrl: .fill 3, 0
|
|
772
|
+
sfxnum: .fill 3, 0
|
|
773
|
+
sfxpos: .fill 3, 0
|
|
774
|
+
restore: .fill 3, 0
|
|
775
|
+
ghost: .fill 25, 0
|
|
776
|
+
log: .fill NFRAMES, 0
|
|
777
|
+
```
|
|
778
|
+
|
|
779
|
+
## Build
|
|
780
|
+
|
|
781
|
+
```bash
|
|
782
|
+
java -jar KickAss.jar sfx-in-player.asm -o sfx-in-player.prg
|
|
783
|
+
```
|
|
784
|
+
|
|
785
|
+
Built with KickAssembler 5.25. Code and data occupy `$0810`-`$110A`. From
|
|
786
|
+
the symbol file: the player's code (`sfx_request` to the end of `veffect`)
|
|
787
|
+
is 371 bytes, and its tables, patterns, frequency table and four effects
|
|
788
|
+
are 282 bytes. The shadow is 25 bytes and the per-voice state 24.
|
|
789
|
+
|
|
790
|
+
## Expected output
|
|
791
|
+
|
|
792
|
+
Every figure below was measured in VICE x64sc 3.10 (rung 1) from the exit
|
|
793
|
+
screenshot of the pinned run at 8,000,000 cycles, text decoded against the
|
|
794
|
+
`chargen-901225-01.bin` glyphs with PIL. Two runs per model gave
|
|
795
|
+
byte-identical PNGs. `+sound` is off: every claim is register-level, what
|
|
796
|
+
the player put in the shadow and so in the SID. Nobody has listened to it.
|
|
797
|
+
|
|
798
|
+
```text
|
|
799
|
+
x64sc -default -warp +sound +autostart-delay-random -autostartprgmode 1 \
|
|
800
|
+
-limitcycles 8000000 [-model ntsc] -exitscreenshot out.png \
|
|
801
|
+
-autostart sfx-in-player.prg
|
|
802
|
+
```
|
|
803
|
+
|
|
804
|
+
PAL (`screenshots/sfx-in-player.png`) and NTSC
|
|
805
|
+
(`screenshots/sfx-in-player-ntsc.png`) show the same text:
|
|
806
|
+
|
|
807
|
+
```text
|
|
808
|
+
SFX INSIDE THE PLAYER: VOICE STEALING
|
|
809
|
+
EFFECT VOICES PER FRAME, FRAMES 1-120:
|
|
810
|
+
0000000000000000000444444444444444444444
|
|
811
|
+
4444444444444444444444444444000000000000
|
|
812
|
+
1111115555444444111111111100000000000000
|
|
813
|
+
STARTS 05 REFUSED 01 DROPPED 01
|
|
814
|
+
HANDBACK CHECKS 08 OF 08
|
|
815
|
+
PLAY IDLE MAX $0422 AT FRAME $01
|
|
816
|
+
PLAY FX MAX $04B0 AT FRAME $61
|
|
817
|
+
PLAY MIN $0306 AT FRAME $02
|
|
818
|
+
STOPWATCH $0005
|
|
819
|
+
RESULT PASS
|
|
820
|
+
```
|
|
821
|
+
|
|
822
|
+
The border is green (PASS; red would be FAIL).
|
|
823
|
+
|
|
824
|
+
**The log.** One digit per frame, frames 1 to 120: bit 0 set means an
|
|
825
|
+
effect owns voice 1, bit 2 voice 3. The script's requests and what the log
|
|
826
|
+
shows:
|
|
827
|
+
|
|
828
|
+
| Frame | Request | Result in the log |
|
|
829
|
+
|---|---|---|
|
|
830
|
+
| 20 | effect 2 (voice 3, 40 rows) | voice 3 taken: `4` from frame 20 |
|
|
831
|
+
| 30 | effect 1 (voice 3) | refused: effect 2 is higher. `REFUSED 01` |
|
|
832
|
+
| 49 | effect 1, then effect 3, same frame | the queue keeps 3 and drops 1 (`DROPPED 01`); 3 cuts 2 |
|
|
833
|
+
| 69 | (none) | effect 3's 20 rows are over: voice 3 handed back, `0` |
|
|
834
|
+
| 81 | effect 4 (voice 1, 10 rows) | `1` |
|
|
835
|
+
| 87 | effect 1 (voice 3, 10 rows) | both voices: `5` |
|
|
836
|
+
| 91 | (none) | effect 4 ends, voice 1 handed back: `4` |
|
|
837
|
+
| 97 | effect 4 again (voice 1) | voice 3 handed back and voice 1 taken on the same frame: `1` |
|
|
838
|
+
| 107 | (none) | voice 1 handed back: `0` to frame 120 |
|
|
839
|
+
|
|
840
|
+
The program compares the log with a table of runs written from this
|
|
841
|
+
script, not from the player (`exprun`). `STARTS 05` counts effects that got
|
|
842
|
+
a voice (2, 3, 4, 1, 4), found after each call as a voice whose effect
|
|
843
|
+
position is 5, the header and one row.
|
|
844
|
+
|
|
845
|
+
**Hand-back checks.** On the last frame of each of the four effects the
|
|
846
|
+
shadow's AD and SR equal the effect's header (4 checks). On the next frame
|
|
847
|
+
they equal the instrument's AD, SR and pulse high byte, and the control
|
|
848
|
+
byte equals the instrument's waveform with GATE set (frames 69, 91 and
|
|
849
|
+
107, all mid-note) or clear (frame 97, where voice 3's next note starts
|
|
850
|
+
and the player holds GATE off for one frame).
|
|
851
|
+
|
|
852
|
+
A harness build with the one store that sets `restore` changed to store 0
|
|
853
|
+
(not this listing) ran the same way: `HANDBACK CHECKS 05 OF 08`, FAIL. The
|
|
854
|
+
three mid-note hand-backs failed and the frame-97 one passed, because the
|
|
855
|
+
player writes AD, SR and pulse on every note start anyway. Without the
|
|
856
|
+
restore, the music voice keeps the effect's envelope and pulse width until
|
|
857
|
+
its next note.
|
|
858
|
+
|
|
859
|
+
**Cycles.** Hex, net of the stopwatch's own 5 cycles; the same on PAL and
|
|
860
|
+
NTSC, because the play call runs from raster line 251, below the badlines,
|
|
861
|
+
with no sprites on.
|
|
862
|
+
|
|
863
|
+
| Row | Cycles | Frame | What ran |
|
|
864
|
+
|---|---|---|---|
|
|
865
|
+
| `PLAY IDLE MAX` | 1,058 | 1 | no effect; a note starts on all three voices |
|
|
866
|
+
| `PLAY FX MAX` | 1,200 | 97 | a note starts on all three voices, voice 3 is handed back with its instrument re-applied, and effect 4 starts on voice 1 with its header |
|
|
867
|
+
| `PLAY MIN` | 774 | 2 | no effect, no note start |
|
|
868
|
+
|
|
869
|
+
Frame 97 is the worst frame the script builds on purpose: every
|
|
870
|
+
per-voice path that costs extra, on one frame. 351 cycles of every figure
|
|
871
|
+
are the shadow copy (25 × 14 − 1 + 2, from the instruction table; `ghost`
|
|
872
|
+
does not cross a page). The demonstration's counters are outside the
|
|
873
|
+
timed call, except `inc refused` (6 cycles), which runs only on a refused
|
|
874
|
+
frame. An earlier layout of this listing, with a counter inside `play`,
|
|
875
|
+
measured 1,055, 1,203 and 773: moving code shifts page crossings in the
|
|
876
|
+
indexed loads, and the figures move by a few cycles with it.
|
|
877
|
+
|
|
878
|
+
## Why this works
|
|
879
|
+
|
|
880
|
+
**The player advances the music on every voice, every frame.** An effect
|
|
881
|
+
stops the voice's writes to the shadow, not its sequencer. `voice` fetches
|
|
882
|
+
notes and works out the gate for the music whether or not an effect owns
|
|
883
|
+
the voice; `vowner` then picks who writes. The tune stays in time, and at
|
|
884
|
+
hand-back the music's frequency and gate are already the ones for that
|
|
885
|
+
frame.
|
|
886
|
+
|
|
887
|
+
**Hand-back re-applies the instrument.** This player writes AD, SR and
|
|
888
|
+
pulse width only on a note's first frame, as most players do, to save
|
|
889
|
+
cycles. The effect overwrote them. So `vend` sets `restore` and jumps into
|
|
890
|
+
the music path, which rewrites all three from the instrument table on the
|
|
891
|
+
same frame. The effect's last row clears GATE, so the music's GATE on the
|
|
892
|
+
next frame is a 0-to-1 edge and a fresh attack with the music's envelope.
|
|
893
|
+
|
|
894
|
+
**One start per frame.** `sfx_request` only compares and stores: the
|
|
895
|
+
higher number stays in `pending`. The player takes it at the top of the
|
|
896
|
+
next `play`. Two requests in one frame cost one voice, not two.
|
|
897
|
+
|
|
898
|
+
**Ghost registers.** Nothing writes the SID but the copy loop at the end of
|
|
899
|
+
`play`, `$18` down to `$00`: for each voice SR, AD, control, pulse,
|
|
900
|
+
frequency. Every register is written every frame, in the same order, and
|
|
901
|
+
a voice's seven writes land within 98 cycles (7 × 14, arithmetic) whatever
|
|
902
|
+
path the player took. When they land in the frame still moves with the
|
|
903
|
+
player's length, 774 to 1,200 cycles here; copying first and computing
|
|
904
|
+
second fixes that too (see the technique). The SID's
|
|
905
|
+
registers are write-only (`pitfalls/sid.md`, `sid_write_only_registers`),
|
|
906
|
+
so the shadow is also the only place a program can read what it last
|
|
907
|
+
wrote; the checks read it.
|