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,670 @@
|
|
|
1
|
+
---
|
|
2
|
+
recipe: logic-rate-decoupling
|
|
3
|
+
toolchain: kickassembler
|
|
4
|
+
output_format: PRG
|
|
5
|
+
region: both
|
|
6
|
+
techniques: [logic_rate_decoupling]
|
|
7
|
+
file_formats: [PRG]
|
|
8
|
+
uses_registers: [D000, D001, D010, D011, D012, D015, D019, D01A, D020, D021, D027, DC0D]
|
|
9
|
+
uses_kernal: []
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
<!-- doc-type: recipe -->
|
|
13
|
+
|
|
14
|
+
# KickAssembler — Game logic at half the display rate, sprites interpolated
|
|
15
|
+
|
|
16
|
+
## Synopsis
|
|
17
|
+
|
|
18
|
+
Eight sprites moved by game logic that runs once every two display
|
|
19
|
+
frames, drawn every frame with the position on the in-between frame
|
|
20
|
+
interpolated. The logic runs in the main loop and carries an artificial
|
|
21
|
+
load: every eighth tick runs a 40-page delay, about 51,440 cycles or 2.6
|
|
22
|
+
PAL frames by the instruction table before badlines and sprite DMA take
|
|
23
|
+
their share. A raster interrupt
|
|
24
|
+
below the display counts frames, owes the logic one tick every second
|
|
25
|
+
frame, and runs the display update with interrupts re-enabled behind a
|
|
26
|
+
re-entrancy guard; one display update is made to overrun on purpose so the
|
|
27
|
+
guard trips. The logic hands positions to the display through a
|
|
28
|
+
double-buffered table flipped by one byte. The screen shows display
|
|
29
|
+
frames, logic ticks, loop passes, skipped frames, guard trips, input
|
|
30
|
+
latency for two events, sprite 0's step on 32 consecutive frames, and a
|
|
31
|
+
PASS/FAIL check that game time kept to half the display frame count. The
|
|
32
|
+
technique is `logic_rate_decoupling` in `techniques/logic.md`.
|
|
33
|
+
|
|
34
|
+
## Source
|
|
35
|
+
|
|
36
|
+
```asm
|
|
37
|
+
// logic-rate-decoupling.asm: game logic at half the display rate.
|
|
38
|
+
// Main loop: the game logic, one tick per two display frames, with an
|
|
39
|
+
// artificial load that overruns on every eighth tick. Raster IRQ at line
|
|
40
|
+
// 251: counts display frames, owes the logic one tick every second frame,
|
|
41
|
+
// and runs the display update with interrupts re-enabled, guarded so a
|
|
42
|
+
// nested entry skips it. The update shows the midpoint between the last
|
|
43
|
+
// two logic positions on the frame after a publish and the newer position
|
|
44
|
+
// on the frames after that. The screen shows the counters, the input
|
|
45
|
+
// latency, sprite 0's per-frame step, and a PASS/FAIL check on game speed.
|
|
46
|
+
// Build: java -jar KickAss.jar logic-rate-decoupling.asm -o logic-rate-decoupling.prg
|
|
47
|
+
|
|
48
|
+
BasicUpstart2(start)
|
|
49
|
+
|
|
50
|
+
.encoding "screencode_upper"
|
|
51
|
+
|
|
52
|
+
.const SCREEN = $0400
|
|
53
|
+
.const IRQLINE = 251 // below the lowest sprite (y 226, 21 lines)
|
|
54
|
+
.const NSPR = 8
|
|
55
|
+
.const LIGHT = 3 // delay pages for an ordinary logic tick
|
|
56
|
+
.const HEAVY = 40 // delay pages for every eighth tick
|
|
57
|
+
.const SPIKE = 60 // display frame whose update overruns once
|
|
58
|
+
.const SPIKEPG = 20 // delay pages in that update
|
|
59
|
+
.const EVT_A = 100 // input event on an even frame: sprite 6 starts
|
|
60
|
+
.const EVT_B = 131 // input event on an odd frame: sprite 7 starts
|
|
61
|
+
.const DSTART = 160 // first frame of the sprite-0 step record
|
|
62
|
+
.const REST6 = 40 // rest x of sprite 6 before its event
|
|
63
|
+
.const REST7 = 140 // rest x of sprite 7 before its event
|
|
64
|
+
|
|
65
|
+
* = $0810
|
|
66
|
+
|
|
67
|
+
start:
|
|
68
|
+
sei
|
|
69
|
+
lda #$7f
|
|
70
|
+
sta $dc0d // CIA1 timer IRQ off: only the raster reaches $0314
|
|
71
|
+
lda $dc0d
|
|
72
|
+
lda #0
|
|
73
|
+
sta $d020
|
|
74
|
+
sta $d021
|
|
75
|
+
ldx #0
|
|
76
|
+
!: lda #$20
|
|
77
|
+
sta SCREEN,x
|
|
78
|
+
sta SCREEN + $100,x
|
|
79
|
+
sta SCREEN + $200,x
|
|
80
|
+
sta SCREEN + $2e8,x
|
|
81
|
+
lda #1
|
|
82
|
+
sta $d800,x
|
|
83
|
+
sta $d900,x
|
|
84
|
+
sta $da00,x
|
|
85
|
+
sta $dae8,x
|
|
86
|
+
inx
|
|
87
|
+
bne !-
|
|
88
|
+
ldx #0 // labels, rows 0 to 12
|
|
89
|
+
!: lda labels,x
|
|
90
|
+
sta SCREEN,x
|
|
91
|
+
lda labels + $100,x
|
|
92
|
+
sta SCREEN + $100,x
|
|
93
|
+
inx
|
|
94
|
+
bne !-
|
|
95
|
+
|
|
96
|
+
ldx #62 // one solid sprite shape at $2000, block $80
|
|
97
|
+
lda #$ff
|
|
98
|
+
!: sta $2000,x
|
|
99
|
+
dex
|
|
100
|
+
bpl !-
|
|
101
|
+
ldx #NSPR - 1
|
|
102
|
+
!: lda #$80
|
|
103
|
+
sta SCREEN + $3f8,x
|
|
104
|
+
lda colours,x
|
|
105
|
+
sta $d027,x
|
|
106
|
+
lda lx,x // both table halves start at the start position
|
|
107
|
+
sta fromx,x
|
|
108
|
+
sta fromx + 8,x
|
|
109
|
+
sta tox,x
|
|
110
|
+
sta tox + 8,x
|
|
111
|
+
dex
|
|
112
|
+
bpl !-
|
|
113
|
+
ldx #0
|
|
114
|
+
ldy #0
|
|
115
|
+
!: lda ypos,x
|
|
116
|
+
sta $d001,y
|
|
117
|
+
lda lx,x
|
|
118
|
+
sta $d000,y
|
|
119
|
+
iny
|
|
120
|
+
iny
|
|
121
|
+
inx
|
|
122
|
+
cpx #NSPR
|
|
123
|
+
bne !-
|
|
124
|
+
lda #0
|
|
125
|
+
sta $d010
|
|
126
|
+
lda #$ff
|
|
127
|
+
sta $d015
|
|
128
|
+
|
|
129
|
+
lda #<irq
|
|
130
|
+
sta $0314
|
|
131
|
+
lda #>irq
|
|
132
|
+
sta $0315
|
|
133
|
+
lda #IRQLINE
|
|
134
|
+
sta $d012
|
|
135
|
+
lda $d011
|
|
136
|
+
and #$7f
|
|
137
|
+
sta $d011
|
|
138
|
+
lda #1
|
|
139
|
+
sta $d01a
|
|
140
|
+
lda #$ff
|
|
141
|
+
sta $d019
|
|
142
|
+
cli
|
|
143
|
+
|
|
144
|
+
// ---------------------------------------------------------------------------
|
|
145
|
+
// Main loop: the game logic. Runs every tick it is owed, publishes once.
|
|
146
|
+
// ---------------------------------------------------------------------------
|
|
147
|
+
mainloop:
|
|
148
|
+
!: lda owed // wait until the IRQ owes a tick
|
|
149
|
+
beq !-
|
|
150
|
+
lda #0
|
|
151
|
+
sta batch
|
|
152
|
+
runtick:
|
|
153
|
+
dec owed // one RMW instruction: the IRQ cannot split it
|
|
154
|
+
jsr logic_tick
|
|
155
|
+
inc ticks
|
|
156
|
+
bne !+
|
|
157
|
+
inc ticks + 1
|
|
158
|
+
!: inc batch
|
|
159
|
+
lda owed // still owed: run again before publishing,
|
|
160
|
+
bne runtick // so game speed holds while the display skips
|
|
161
|
+
inc passes
|
|
162
|
+
bne !+
|
|
163
|
+
inc passes + 1
|
|
164
|
+
!: ldx batch // every tick past the first went undisplayed
|
|
165
|
+
dex
|
|
166
|
+
txa
|
|
167
|
+
clc
|
|
168
|
+
adc skipped
|
|
169
|
+
sta skipped
|
|
170
|
+
bcc !+
|
|
171
|
+
inc skipped + 1
|
|
172
|
+
|
|
173
|
+
// Publish: write the half the IRQ is not reading, then flip one byte.
|
|
174
|
+
!: lda fresh // the IRQ has not taken the last table yet
|
|
175
|
+
bne !-
|
|
176
|
+
lda front
|
|
177
|
+
eor #1
|
|
178
|
+
asl
|
|
179
|
+
asl
|
|
180
|
+
asl
|
|
181
|
+
tay // Y = back half * 8
|
|
182
|
+
ldx #0
|
|
183
|
+
!: lda prevx,x
|
|
184
|
+
sta fromx,y
|
|
185
|
+
lda lx,x
|
|
186
|
+
sta tox,y
|
|
187
|
+
iny
|
|
188
|
+
inx
|
|
189
|
+
cpx #NSPR
|
|
190
|
+
bne !-
|
|
191
|
+
lda front
|
|
192
|
+
eor #1
|
|
193
|
+
sta ready
|
|
194
|
+
lda #1
|
|
195
|
+
sta fresh // one store hands the table over
|
|
196
|
+
|
|
197
|
+
jsr show_counters
|
|
198
|
+
lda checked
|
|
199
|
+
bne !+
|
|
200
|
+
jsr check_speed
|
|
201
|
+
!: jmp mainloop
|
|
202
|
+
|
|
203
|
+
// One logic tick: input, movement with bounce, and the artificial load.
|
|
204
|
+
logic_tick:
|
|
205
|
+
lda joyA // an input event starts sprite 6
|
|
206
|
+
cmp #1
|
|
207
|
+
bne !+
|
|
208
|
+
lda #2
|
|
209
|
+
sta vx + 6
|
|
210
|
+
sta joyA
|
|
211
|
+
!: lda joyB // and another starts sprite 7
|
|
212
|
+
cmp #1
|
|
213
|
+
bne !+
|
|
214
|
+
lda #2
|
|
215
|
+
sta vx + 7
|
|
216
|
+
sta joyB
|
|
217
|
+
!: ldx #NSPR - 1
|
|
218
|
+
tickspr:
|
|
219
|
+
lda lx,x
|
|
220
|
+
sta prevx,x // the position before this tick, for interpolation
|
|
221
|
+
lda vx,x
|
|
222
|
+
beq nextspr
|
|
223
|
+
bmi goleft
|
|
224
|
+
lda lx,x
|
|
225
|
+
cmp #236
|
|
226
|
+
bcc !+
|
|
227
|
+
lda #$fe
|
|
228
|
+
sta vx,x
|
|
229
|
+
jmp nextspr
|
|
230
|
+
!: clc
|
|
231
|
+
adc #2
|
|
232
|
+
sta lx,x
|
|
233
|
+
jmp nextspr
|
|
234
|
+
goleft:
|
|
235
|
+
lda lx,x
|
|
236
|
+
cmp #26
|
|
237
|
+
bcs !+
|
|
238
|
+
lda #2
|
|
239
|
+
sta vx,x
|
|
240
|
+
jmp nextspr
|
|
241
|
+
!: sec
|
|
242
|
+
sbc #2
|
|
243
|
+
sta lx,x
|
|
244
|
+
nextspr:
|
|
245
|
+
dex
|
|
246
|
+
bpl tickspr
|
|
247
|
+
lda ticks // the artificial load
|
|
248
|
+
and #7
|
|
249
|
+
cmp #7
|
|
250
|
+
bne !+
|
|
251
|
+
lda #HEAVY
|
|
252
|
+
jmp delay
|
|
253
|
+
!: lda #LIGHT
|
|
254
|
+
// fall through
|
|
255
|
+
|
|
256
|
+
// Delay: A pages of 256 DEY/BNE loops, about 1,286 cycles a page.
|
|
257
|
+
delay:
|
|
258
|
+
tax
|
|
259
|
+
d1: ldy #0
|
|
260
|
+
!: dey
|
|
261
|
+
bne !-
|
|
262
|
+
dex
|
|
263
|
+
bne d1
|
|
264
|
+
rts
|
|
265
|
+
|
|
266
|
+
// ---------------------------------------------------------------------------
|
|
267
|
+
// Raster IRQ, entered through the KERNAL at $0314 (A, X, Y already stacked).
|
|
268
|
+
// ---------------------------------------------------------------------------
|
|
269
|
+
irq:
|
|
270
|
+
lda #$ff
|
|
271
|
+
sta $d019 // acknowledge before CLI, or it re-enters at once
|
|
272
|
+
inc frames // timekeeping runs on every entry, nested or not
|
|
273
|
+
bne !+
|
|
274
|
+
inc frames + 1
|
|
275
|
+
!: lda half
|
|
276
|
+
eor #1
|
|
277
|
+
sta half
|
|
278
|
+
bne !+
|
|
279
|
+
inc owed // the speed counter: one tick per two frames
|
|
280
|
+
!: lda frames + 1
|
|
281
|
+
bne noevt
|
|
282
|
+
lda frames
|
|
283
|
+
cmp #EVT_A
|
|
284
|
+
bne !+
|
|
285
|
+
lda #1
|
|
286
|
+
sta joyA
|
|
287
|
+
!: cmp #EVT_B
|
|
288
|
+
bne noevt
|
|
289
|
+
lda #1
|
|
290
|
+
sta joyB
|
|
291
|
+
noevt:
|
|
292
|
+
inc busy // re-entrancy guard
|
|
293
|
+
lda busy
|
|
294
|
+
cmp #2
|
|
295
|
+
bcs nested
|
|
296
|
+
cli // lower-level raster IRQs could now run
|
|
297
|
+
jsr frame_update
|
|
298
|
+
sei
|
|
299
|
+
dec busy
|
|
300
|
+
jmp $ea81
|
|
301
|
+
nested:
|
|
302
|
+
inc guard
|
|
303
|
+
dec busy
|
|
304
|
+
jmp $ea81
|
|
305
|
+
|
|
306
|
+
// Display update: pick the table, write interpolated x to the VIC-II.
|
|
307
|
+
frame_update:
|
|
308
|
+
lda fresh
|
|
309
|
+
beq holdto
|
|
310
|
+
lda ready
|
|
311
|
+
sta front
|
|
312
|
+
lda #0
|
|
313
|
+
sta fresh
|
|
314
|
+
lda #1 // first frame of a new table: midpoint
|
|
315
|
+
bne setmid
|
|
316
|
+
holdto:
|
|
317
|
+
lda #0 // later frames: the newer position
|
|
318
|
+
setmid:
|
|
319
|
+
sta mid
|
|
320
|
+
lda front
|
|
321
|
+
asl
|
|
322
|
+
asl
|
|
323
|
+
asl
|
|
324
|
+
tax // X = front half * 8
|
|
325
|
+
ldy #0
|
|
326
|
+
fuloop:
|
|
327
|
+
lda mid
|
|
328
|
+
beq !+
|
|
329
|
+
lda tox,x
|
|
330
|
+
clc
|
|
331
|
+
adc fromx,x // (from + to) / 2: the carry holds bit 8
|
|
332
|
+
ror
|
|
333
|
+
jmp !++
|
|
334
|
+
!: lda tox,x
|
|
335
|
+
!: sta $d000,y
|
|
336
|
+
sta shown,y
|
|
337
|
+
inx
|
|
338
|
+
iny
|
|
339
|
+
iny
|
|
340
|
+
cpy #NSPR * 2
|
|
341
|
+
bne fuloop
|
|
342
|
+
|
|
343
|
+
lda frames + 1 // one deliberate overrun of the update
|
|
344
|
+
bne !+
|
|
345
|
+
lda frames
|
|
346
|
+
cmp #SPIKE
|
|
347
|
+
bne !+
|
|
348
|
+
lda #SPIKEPG
|
|
349
|
+
jsr delay
|
|
350
|
+
|
|
351
|
+
!: lda latA // latency: frames from event to first motion
|
|
352
|
+
bne !+
|
|
353
|
+
lda joyA
|
|
354
|
+
beq !+
|
|
355
|
+
lda shown + 12
|
|
356
|
+
cmp #REST6
|
|
357
|
+
beq !+
|
|
358
|
+
lda frames
|
|
359
|
+
sec
|
|
360
|
+
sbc #EVT_A
|
|
361
|
+
sta latA
|
|
362
|
+
!: lda latB
|
|
363
|
+
bne !+
|
|
364
|
+
lda joyB
|
|
365
|
+
beq !+
|
|
366
|
+
lda shown + 14
|
|
367
|
+
cmp #REST7
|
|
368
|
+
beq !+
|
|
369
|
+
lda frames
|
|
370
|
+
sec
|
|
371
|
+
sbc #EVT_B
|
|
372
|
+
sta latB
|
|
373
|
+
|
|
374
|
+
!: lda shown // sprite 0 step this frame, |x - last x|
|
|
375
|
+
sec
|
|
376
|
+
sbc last0
|
|
377
|
+
bcs !+
|
|
378
|
+
eor #$ff
|
|
379
|
+
adc #1
|
|
380
|
+
!: cmp #10
|
|
381
|
+
bcc !+
|
|
382
|
+
lda #9
|
|
383
|
+
!: tay
|
|
384
|
+
lda shown
|
|
385
|
+
sta last0
|
|
386
|
+
lda frames + 1
|
|
387
|
+
bne fudone
|
|
388
|
+
lda frames
|
|
389
|
+
sec
|
|
390
|
+
sbc #DSTART
|
|
391
|
+
cmp #32
|
|
392
|
+
bcs fudone
|
|
393
|
+
tax
|
|
394
|
+
lda hexdig,y
|
|
395
|
+
sta SCREEN + 7 * 40 + 8,x
|
|
396
|
+
fudone:
|
|
397
|
+
rts
|
|
398
|
+
|
|
399
|
+
// ---------------------------------------------------------------------------
|
|
400
|
+
// Screen output.
|
|
401
|
+
// ---------------------------------------------------------------------------
|
|
402
|
+
.macro print16(src, dst) {
|
|
403
|
+
lda src + 1
|
|
404
|
+
lsr
|
|
405
|
+
lsr
|
|
406
|
+
lsr
|
|
407
|
+
lsr
|
|
408
|
+
tax
|
|
409
|
+
lda hexdig,x
|
|
410
|
+
sta dst
|
|
411
|
+
lda src + 1
|
|
412
|
+
and #15
|
|
413
|
+
tax
|
|
414
|
+
lda hexdig,x
|
|
415
|
+
sta dst + 1
|
|
416
|
+
lda src
|
|
417
|
+
lsr
|
|
418
|
+
lsr
|
|
419
|
+
lsr
|
|
420
|
+
lsr
|
|
421
|
+
tax
|
|
422
|
+
lda hexdig,x
|
|
423
|
+
sta dst + 2
|
|
424
|
+
lda src
|
|
425
|
+
and #15
|
|
426
|
+
tax
|
|
427
|
+
lda hexdig,x
|
|
428
|
+
sta dst + 3
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
show_counters:
|
|
432
|
+
sei // frames is two bytes the IRQ writes
|
|
433
|
+
lda frames
|
|
434
|
+
sta fcopy
|
|
435
|
+
lda frames + 1
|
|
436
|
+
sta fcopy + 1
|
|
437
|
+
cli
|
|
438
|
+
print16(fcopy, SCREEN + 1 * 40 + 8)
|
|
439
|
+
print16(ticks, SCREEN + 2 * 40 + 8)
|
|
440
|
+
print16(passes, SCREEN + 3 * 40 + 8)
|
|
441
|
+
print16(skipped, SCREEN + 4 * 40 + 8)
|
|
442
|
+
lda guard
|
|
443
|
+
sta gcopy
|
|
444
|
+
print16(gcopy, SCREEN + 5 * 40 + 8)
|
|
445
|
+
lda latA
|
|
446
|
+
sta lcopy
|
|
447
|
+
lda latB
|
|
448
|
+
sta lcopy2
|
|
449
|
+
print16(lcopy, SCREEN + 6 * 40 + 8)
|
|
450
|
+
print16(lcopy2, SCREEN + 6 * 40 + 13)
|
|
451
|
+
rts
|
|
452
|
+
|
|
453
|
+
// At the first publish on or after frame 256: game time must equal half
|
|
454
|
+
// the display frames, less at most one owed tick, and the load must have
|
|
455
|
+
// forced at least one frame skip and one guard trip.
|
|
456
|
+
check_speed:
|
|
457
|
+
lda fcopy + 1
|
|
458
|
+
bne !+
|
|
459
|
+
rts
|
|
460
|
+
!: lda #1
|
|
461
|
+
sta checked
|
|
462
|
+
print16(fcopy, SCREEN + 8 * 40 + 9)
|
|
463
|
+
print16(ticks, SCREEN + 8 * 40 + 20)
|
|
464
|
+
lda fcopy + 1 // want = frames / 2
|
|
465
|
+
lsr
|
|
466
|
+
sta want + 1
|
|
467
|
+
lda fcopy
|
|
468
|
+
ror
|
|
469
|
+
sta want
|
|
470
|
+
sec // lag = want - ticks
|
|
471
|
+
lda want
|
|
472
|
+
sbc ticks
|
|
473
|
+
sta lag
|
|
474
|
+
lda want + 1
|
|
475
|
+
sbc ticks + 1
|
|
476
|
+
bne fail // negative, or 256 or more
|
|
477
|
+
lda lag
|
|
478
|
+
cmp #2
|
|
479
|
+
bcs fail
|
|
480
|
+
lda skipped
|
|
481
|
+
ora skipped + 1
|
|
482
|
+
beq fail
|
|
483
|
+
lda guard
|
|
484
|
+
beq fail
|
|
485
|
+
ldx #3
|
|
486
|
+
!: lda passtxt,x
|
|
487
|
+
sta SCREEN + 8 * 40 + 25,x
|
|
488
|
+
dex
|
|
489
|
+
bpl !-
|
|
490
|
+
lda #5 // green border
|
|
491
|
+
sta $d020
|
|
492
|
+
rts
|
|
493
|
+
fail:
|
|
494
|
+
ldx #3
|
|
495
|
+
!: lda failtxt,x
|
|
496
|
+
sta SCREEN + 8 * 40 + 25,x
|
|
497
|
+
dex
|
|
498
|
+
bpl !-
|
|
499
|
+
lda #2 // red border
|
|
500
|
+
sta $d020
|
|
501
|
+
rts
|
|
502
|
+
|
|
503
|
+
// ---------------------------------------------------------------------------
|
|
504
|
+
// Data.
|
|
505
|
+
// ---------------------------------------------------------------------------
|
|
506
|
+
hexdig: .text "0123456789ABCDEF"
|
|
507
|
+
passtxt: .text "PASS"
|
|
508
|
+
failtxt: .text "FAIL"
|
|
509
|
+
colours: .byte 1, 7, 3, 5, 14, 10, 13, 15
|
|
510
|
+
ypos: .byte 124, 140, 156, 172, 188, 204, 226, 226
|
|
511
|
+
lx: .byte 24, 54, 84, 114, 144, 174, REST6, REST7
|
|
512
|
+
vx: .byte 2, 2, $fe, 2, $fe, 2, 0, 0
|
|
513
|
+
prevx: .fill NSPR, 0
|
|
514
|
+
fromx: .fill 16, 0
|
|
515
|
+
tox: .fill 16, 0
|
|
516
|
+
shown: .fill 16, 0
|
|
517
|
+
frames: .word 0
|
|
518
|
+
ticks: .word 0
|
|
519
|
+
passes: .word 0
|
|
520
|
+
skipped: .word 0
|
|
521
|
+
fcopy: .word 0
|
|
522
|
+
gcopy: .word 0
|
|
523
|
+
lcopy: .word 0
|
|
524
|
+
lcopy2: .word 0
|
|
525
|
+
want: .word 0
|
|
526
|
+
owed: .byte 0
|
|
527
|
+
half: .byte 0
|
|
528
|
+
batch: .byte 0
|
|
529
|
+
busy: .byte 0
|
|
530
|
+
guard: .byte 0
|
|
531
|
+
fresh: .byte 0
|
|
532
|
+
ready: .byte 0
|
|
533
|
+
front: .byte 0
|
|
534
|
+
mid: .byte 0
|
|
535
|
+
joyA: .byte 0
|
|
536
|
+
joyB: .byte 0
|
|
537
|
+
latA: .byte 0
|
|
538
|
+
latB: .byte 0
|
|
539
|
+
last0: .byte 24
|
|
540
|
+
checked: .byte 0
|
|
541
|
+
lag: .byte 0
|
|
542
|
+
|
|
543
|
+
labels:
|
|
544
|
+
.text "LOGIC AT HALF RATE, SPRITES INTERPOLATED" // row 0
|
|
545
|
+
.text "FRAMES " // row 1
|
|
546
|
+
.text "TICKS " // row 2
|
|
547
|
+
.text "PASSES " // row 3
|
|
548
|
+
.text "SKIPPED " // row 4
|
|
549
|
+
.text "GUARD " // row 5
|
|
550
|
+
.text "LATENCY " // row 6
|
|
551
|
+
.text "STEP " // row 7
|
|
552
|
+
.text "AT FRAME TICKS " // row 8
|
|
553
|
+
.text " " // row 9
|
|
554
|
+
.fill 512 - 400, $20
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+
## Build
|
|
558
|
+
|
|
559
|
+
```bash
|
|
560
|
+
java -jar KickAss.jar logic-rate-decoupling.asm -o logic-rate-decoupling.prg
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
Built with KickAssembler 5.25. Code and data occupy `$0810`-`$0F9D`; the
|
|
564
|
+
labels block is 512 bytes of that.
|
|
565
|
+
|
|
566
|
+
## Expected output
|
|
567
|
+
|
|
568
|
+
Every figure below was measured in VICE x64sc 3.10 (rung 1) from the exit
|
|
569
|
+
screenshot of the pinned run at 10,000,000 cycles, text decoded against
|
|
570
|
+
the `chargen-901225-01.bin` glyphs and sprites located by colour with PIL.
|
|
571
|
+
Two runs per model gave byte-identical PNGs.
|
|
572
|
+
|
|
573
|
+
```text
|
|
574
|
+
x64sc -default -warp +sound +autostart-delay-random -autostartprgmode 1 \
|
|
575
|
+
-limitcycles 10000000 [-model ntsc] -exitscreenshot out.png \
|
|
576
|
+
-autostart logic-rate-decoupling.prg
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
| Row | PAL (`screenshots/logic-rate-decoupling.png`) | NTSC (`screenshots/logic-rate-decoupling-ntsc.png`) |
|
|
580
|
+
|---|---|---|
|
|
581
|
+
| `FRAMES` | `0164` (356) | `018E` (398) |
|
|
582
|
+
| `TICKS` | `00B2` (178) | `00C7` (199) |
|
|
583
|
+
| `PASSES` | `009C` (156) | `00AF` (175) |
|
|
584
|
+
| `SKIPPED` | `0016` (22) | `0018` (24) |
|
|
585
|
+
| `GUARD` | `0001` | `0001` |
|
|
586
|
+
| `LATENCY` | `0001 0002` | `0001 0001` |
|
|
587
|
+
| `STEP` | `10003211111111111000321111111111` | the same |
|
|
588
|
+
| check row | `AT FRAME 0103 TICKS0081 PASS` | the same |
|
|
589
|
+
|
|
590
|
+
The border is green on both (PASS; red would be FAIL). Eight solid
|
|
591
|
+
24-pixel sprites sit below the text. On PAL sprite 0 is at X 97, an odd
|
|
592
|
+
number, so the shot caught a midpoint frame: every logic position is even.
|
|
593
|
+
On NTSC it is at X 52, a logic position.
|
|
594
|
+
|
|
595
|
+
What the rows show:
|
|
596
|
+
|
|
597
|
+
- **Game speed held.** `TICKS` is exactly half `FRAMES` on both models, and
|
|
598
|
+
the check at frame 259 found 129 ticks against the 129 owed. `PASSES`
|
|
599
|
+
counts trips round the main loop: 22 fewer than the ticks on PAL. A loop
|
|
600
|
+
that ran one tick per pass, the one-step-per-frame form of
|
|
601
|
+
`frame_sync_loop`, would have fallen 22 ticks behind, about 12% slow.
|
|
602
|
+
- **Skipped frames.** `SKIPPED` is `TICKS - PASSES`: ticks run back to back
|
|
603
|
+
with no display in between.
|
|
604
|
+
- **Guard.** Display frame 60's update carries a 20-page delay, longer than
|
|
605
|
+
a frame. The next raster interrupt arrived while it ran, counted its
|
|
606
|
+
frame and owed its tick, found the guard set and returned. `GUARD` counts
|
|
607
|
+
that one nested entry.
|
|
608
|
+
- **Latency.** Frames from an input event, raised by the interrupt at
|
|
609
|
+
frames 100 and 131, to the first frame the responding sprite (6, then 7)
|
|
610
|
+
was drawn moved. On PAL the event on the even frame, which is the frame
|
|
611
|
+
that owes a tick, showed after 1 frame; the event on the odd frame waited
|
|
612
|
+
for the next tick and showed after 2. On NTSC both showed after 1; why the
|
|
613
|
+
odd event was quick there was not traced.
|
|
614
|
+
- **STEP.** Sprite 0's movement in pixels on frames 160 to 191. The logic
|
|
615
|
+
moves it 2 pixels a tick; interpolation turns that into 1 pixel every
|
|
616
|
+
frame. Frames 161 to 163 and 177 to 179 are 0: a heavy tick is running
|
|
617
|
+
and the display holds the last table. Then 3 and 2 as the owed ticks run
|
|
618
|
+
back to back and publish. The 32 steps sum to 32 pixels, 16 ticks of 2.
|
|
619
|
+
Without interpolation the row would alternate 2 and 0.
|
|
620
|
+
|
|
621
|
+
The display update's own cost, the table pick and the interpolation loop
|
|
622
|
+
over eight sprites, was measured with CIA1 timer B around it in a harness
|
|
623
|
+
build (not this listing): 384 cycles on the midpoint frame, identical on
|
|
624
|
+
PAL and NTSC because line 251 onwards has no badline and no sprite DMA. The
|
|
625
|
+
same count comes from the instruction table: 49 cycles for the call and the
|
|
626
|
+
pick, 42 per sprite, one less for the last branch.
|
|
627
|
+
|
|
628
|
+
## Why this works
|
|
629
|
+
|
|
630
|
+
**Two clocks, one owner each.** The interrupt owns `frames` and `owed`,
|
|
631
|
+
the main loop owns `ticks`. The interrupt adds one to `owed` every second
|
|
632
|
+
frame whatever the logic is doing, and the logic takes one off with `DEC`,
|
|
633
|
+
which the interrupt cannot split. When a tick ends and `owed` is still not
|
|
634
|
+
zero the loop runs the next tick at once without publishing. That is the
|
|
635
|
+
frame skip, and it is why `TICKS` equals `FRAMES / 2` however long a tick
|
|
636
|
+
takes. The check at the first publish past frame 255 compares `frames / 2`
|
|
637
|
+
with `ticks`, allows one owed tick, and also requires a skip and a guard
|
|
638
|
+
trip so that a run where the load never overran cannot pass.
|
|
639
|
+
|
|
640
|
+
**Positions, not state.** The logic keeps `lx`, `vx` and everything else.
|
|
641
|
+
Before moving a sprite it copies `lx` to `prevx`. Publishing copies `prevx`
|
|
642
|
+
and `lx` into the half of the table the display is not reading, then sets
|
|
643
|
+
`ready` and, last, `fresh`. The display update takes a fresh table on the
|
|
644
|
+
next frame and shows `(from + to) / 2`: `ADC` leaves bit 8 in the carry and
|
|
645
|
+
`ROR` brings it back, so the average of two unsigned bytes is exact. On the
|
|
646
|
+
frames after that it shows `to`. The logic never writes the half in use,
|
|
647
|
+
because it waits for `fresh` to clear before writing, so a half-written
|
|
648
|
+
table is never drawn.
|
|
649
|
+
|
|
650
|
+
**The re-entrant update.** The interrupt acknowledges `$D019` first, does
|
|
651
|
+
the timekeeping, then increments `busy`. At 1 it runs `CLI` and calls the
|
|
652
|
+
update, so any lower-level raster interrupt (a split, a multiplexer) would
|
|
653
|
+
still be taken on time. At 2 it is a nested entry: it counts a guard trip
|
|
654
|
+
and leaves. The KERNAL's entry at `$FF48` has already pushed A, X and Y on
|
|
655
|
+
the stack and `$EA81` pulls them, so the nested entry corrupts nothing.
|
|
656
|
+
The interrupt line is 251, below the lowest sprite (Y 226 plus 21 lines),
|
|
657
|
+
so the sprite registers change after the beam has drawn every sprite. Bit 7
|
|
658
|
+
of `$D011` is cleared because 251 is below 256 (`d012_wrap_around`).
|
|
659
|
+
|
|
660
|
+
**What the listing leaves out.** Every X stays between 24 and 238, so
|
|
661
|
+
`$D010` stays 0; a game using the full width interpolates nine bits and
|
|
662
|
+
writes `$D010` in the same pass (`sprite_x_high_bit_wrong_register`). The
|
|
663
|
+
update uses `ADC` and `SBC` without `CLD` because nothing here sets decimal
|
|
664
|
+
mode; a program that does needs `CLD` at the top of the handler
|
|
665
|
+
(`decimal_mode_in_irq_handler`). The delay loop's cost in frames is
|
|
666
|
+
stretched by badlines and by the eight sprites' DMA, which is why the
|
|
667
|
+
heavy tick is given in pages, not frames. On NTSC the same listing runs the
|
|
668
|
+
logic at 30 Hz, so the sprites move 20% faster in real time
|
|
669
|
+
(`pal_ntsc_tempo_mismatch`); a game that must keep its speed on both
|
|
670
|
+
scales the movement per tick by region.
|