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,986 @@
|
|
|
1
|
+
---
|
|
2
|
+
recipe: sprite-multiplex-game
|
|
3
|
+
toolchain: kickassembler
|
|
4
|
+
output_format: PRG
|
|
5
|
+
region: both
|
|
6
|
+
techniques: [sprite_multiplex_game]
|
|
7
|
+
file_formats: [PRG]
|
|
8
|
+
uses_registers: [D000, D001, D010, D011, D012, D015, D017, D019, D01A, D01B, D01C, D01D, D020, D021, D027, DC0D, DD04, DD05, DD06, DD07, DD0D, DD0E, DD0F]
|
|
9
|
+
uses_kernal: []
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
<!-- doc-type: recipe -->
|
|
13
|
+
|
|
14
|
+
# KickAssembler — Game Sprite Multiplexer With Its Own Timings
|
|
15
|
+
|
|
16
|
+
## Synopsis
|
|
17
|
+
|
|
18
|
+
Twenty-four actors move on their own paths and are shown with eight
|
|
19
|
+
hardware sprites. The main loop sorts them by Y every frame with an
|
|
20
|
+
insertion sort that keeps last frame's order, builds the sorted sprite
|
|
21
|
+
table into the half the IRQs are not reading, and marks it ready. A frame
|
|
22
|
+
IRQ at line 252 swaps the halves and writes the first eight sprites; zone
|
|
23
|
+
IRQs further down reuse the slots, each zone writing every sprite whose Y
|
|
24
|
+
is within four lines of its first. When a zone ends so close to the next
|
|
25
|
+
one that the raster is already within three lines of it, the handler runs
|
|
26
|
+
the next zone at once instead of returning. The program times its own
|
|
27
|
+
sort, build and IRQs with the two CIA2 timers and prints them in the top
|
|
28
|
+
four text rows, with a count of the times and frames the late guard fired.
|
|
29
|
+
Use it as the display half of a game with more than eight moving objects.
|
|
30
|
+
The technique is `sprite_multiplex_game` in `docs/techniques/sprite.md`.
|
|
31
|
+
|
|
32
|
+
Verified in VICE x64sc 3.10 on PAL and NTSC, measured with PIL: every one
|
|
33
|
+
of the 24 actors shows in its own column in both pinned shots and all 16
|
|
34
|
+
swept shots. In the pinned shots each is one whole 21-line box. In 9
|
|
35
|
+
swept shots some boxes are split at the line where the exit screenshot
|
|
36
|
+
cut the frame.
|
|
37
|
+
|
|
38
|
+
## Source
|
|
39
|
+
|
|
40
|
+
```asm
|
|
41
|
+
// sprite-multiplex-game.asm
|
|
42
|
+
// A game-style sprite multiplexer: 24 actors on independent paths, sorted
|
|
43
|
+
// by Y every frame with a persistent insertion sort, built into one half
|
|
44
|
+
// of a double-buffered sorted table while the IRQs show the other half,
|
|
45
|
+
// and displayed through zone IRQs that each set up one or more sprites.
|
|
46
|
+
// The program times its own sort and its own IRQs with the two CIA2
|
|
47
|
+
// timers and prints the figures in the top four text rows.
|
|
48
|
+
//
|
|
49
|
+
// Each actor has its own X column (X = 24 + 13*i), so a missing actor is
|
|
50
|
+
// an empty column. Actors 18-23 are past X=255 and need $D010.
|
|
51
|
+
//
|
|
52
|
+
// Region: both. KERNAL and BASIC are banked out; the IRQ vector is $FFFE.
|
|
53
|
+
|
|
54
|
+
.const N = 24 // actors
|
|
55
|
+
.const BUF = 32 // offset of sorted buffer 1 (a multiple of 8)
|
|
56
|
+
.const MIN_GAP = 21 // a reused slot's next Y must be >= its last Y + 21
|
|
57
|
+
.const JOIN = 4 // sprites within 4 lines of a zone's first join it
|
|
58
|
+
.const LEAD = 3 // zone IRQ line = first Y - LEAD - sprites in zone
|
|
59
|
+
.const MARGIN = 3 // late guard: next line - 3 already reached? run it now
|
|
60
|
+
.const BOTTOM = 252 // frame IRQ: swap buffers, write the first eight
|
|
61
|
+
.const TOP_Y = 90 // path range 90..228; a sprite at Y draws Y+1..Y+21
|
|
62
|
+
|
|
63
|
+
.const SCREEN = $0400
|
|
64
|
+
.const PTRS = $07f8
|
|
65
|
+
|
|
66
|
+
// zero page
|
|
67
|
+
.label save_a = $02
|
|
68
|
+
.label save_x = $03
|
|
69
|
+
.label save_y = $04
|
|
70
|
+
.label cra_save = $05
|
|
71
|
+
.label next_hnd = $06 // 2 bytes: body the next IRQ runs
|
|
72
|
+
.label zidx = $08
|
|
73
|
+
.label zlast = $09
|
|
74
|
+
.label zend_tmp = $0a
|
|
75
|
+
.label front_off = $0b // 0 or BUF: the half the IRQs read
|
|
76
|
+
.label ready = $0c // main loop sets 1 when the back half is built
|
|
77
|
+
.label late_flag = $0d
|
|
78
|
+
.label late_total = $0e // 2 bytes: times the guard fell through
|
|
79
|
+
.label late_frms = $10 // 2 bytes: frames with at least one fall-through
|
|
80
|
+
.label missed = $12 // 2 bytes: frames shown twice (build not ready)
|
|
81
|
+
.label frames = $14 // 2 bytes
|
|
82
|
+
.label irq_cyc = $16 // 2 bytes: CIA2 timer B, multiplexer IRQs, one frame
|
|
83
|
+
.label sort_cyc = $18 // 2 bytes: CIA2 timer A, sort of the last frame
|
|
84
|
+
.label sort_max = $1a // 2 bytes
|
|
85
|
+
.label calib = $1c // 2 bytes: timer count of an empty start/stop
|
|
86
|
+
.label t_stable = $1e // 2 bytes: startup, sort of an already sorted order
|
|
87
|
+
.label t_shuf = $20 // 2 bytes: startup, order i*7 mod 24
|
|
88
|
+
.label t_rev = $22 // 2 bytes: startup, reversed order
|
|
89
|
+
.label bo = $24 // build: back half offset
|
|
90
|
+
.label acc = $25 // build: next accepted index (absolute)
|
|
91
|
+
.label bk = $26
|
|
92
|
+
.label by = $27
|
|
93
|
+
.label d010run = $28
|
|
94
|
+
.label rejects = $29
|
|
95
|
+
.label zw = $2a
|
|
96
|
+
.label ybase = $2b
|
|
97
|
+
.label ylim = $2c
|
|
98
|
+
.label zn = $2d
|
|
99
|
+
.label key = $2e
|
|
100
|
+
.label cand = $2f
|
|
101
|
+
.label s_i = $30
|
|
102
|
+
.label n16 = $31 // 2 bytes
|
|
103
|
+
.label tmp = $33
|
|
104
|
+
.label digit = $34
|
|
105
|
+
.label dst = $35 // 2 bytes
|
|
106
|
+
.label t_build = $37 // 2 bytes: startup, one build of the sorted half
|
|
107
|
+
.label pflip = $39
|
|
108
|
+
|
|
109
|
+
BasicUpstart2(start)
|
|
110
|
+
|
|
111
|
+
// ---------------------------------------------------------------------------
|
|
112
|
+
// Setup
|
|
113
|
+
// ---------------------------------------------------------------------------
|
|
114
|
+
* = $0820
|
|
115
|
+
start:
|
|
116
|
+
sei
|
|
117
|
+
lda #$7f
|
|
118
|
+
sta $dc0d // no CIA1 interrupts
|
|
119
|
+
sta $dd0d // no CIA2 NMIs from the timers used as counters
|
|
120
|
+
lda $dc0d
|
|
121
|
+
lda $dd0d
|
|
122
|
+
lda #$35 // KERNAL and BASIC out, I/O in
|
|
123
|
+
sta $01
|
|
124
|
+
lda #<irq_entry
|
|
125
|
+
sta $fffe
|
|
126
|
+
lda #>irq_entry
|
|
127
|
+
sta $ffff
|
|
128
|
+
lda #<nmi
|
|
129
|
+
sta $fffa
|
|
130
|
+
lda #>nmi
|
|
131
|
+
sta $fffb
|
|
132
|
+
|
|
133
|
+
ldx #0
|
|
134
|
+
!: lda #$20
|
|
135
|
+
sta SCREEN, x
|
|
136
|
+
sta SCREEN + $100, x
|
|
137
|
+
sta SCREEN + $200, x
|
|
138
|
+
sta SCREEN + $2e8, x
|
|
139
|
+
lda #1
|
|
140
|
+
sta $d800, x
|
|
141
|
+
sta $d900, x
|
|
142
|
+
sta $da00, x
|
|
143
|
+
sta $dae8, x
|
|
144
|
+
inx
|
|
145
|
+
bne !-
|
|
146
|
+
ldx #0
|
|
147
|
+
!: lda labels, x
|
|
148
|
+
sta SCREEN, x
|
|
149
|
+
inx
|
|
150
|
+
cpx #160
|
|
151
|
+
bne !-
|
|
152
|
+
|
|
153
|
+
lda #0
|
|
154
|
+
sta $d020
|
|
155
|
+
sta $d021
|
|
156
|
+
sta $d017
|
|
157
|
+
sta $d01d
|
|
158
|
+
sta $d01c
|
|
159
|
+
sta $d01b
|
|
160
|
+
|
|
161
|
+
ldx #$2f // clear the zero-page variables
|
|
162
|
+
lda #0
|
|
163
|
+
!: sta $02, x
|
|
164
|
+
dex
|
|
165
|
+
bpl !-
|
|
166
|
+
|
|
167
|
+
// CIA2 timers as cycle counters: latch $FFFF, loaded, stopped.
|
|
168
|
+
lda #$ff
|
|
169
|
+
sta $dd04
|
|
170
|
+
sta $dd05
|
|
171
|
+
sta $dd06
|
|
172
|
+
sta $dd07
|
|
173
|
+
lda #$10
|
|
174
|
+
sta $dd0e
|
|
175
|
+
sta $dd0f
|
|
176
|
+
|
|
177
|
+
// Calibration: the count of a start immediately followed by a stop.
|
|
178
|
+
lda #$11
|
|
179
|
+
sta $dd0e
|
|
180
|
+
lda #$00
|
|
181
|
+
sta $dd0e
|
|
182
|
+
jsr read_a
|
|
183
|
+
lda n16
|
|
184
|
+
sta calib
|
|
185
|
+
lda n16 + 1
|
|
186
|
+
sta calib + 1
|
|
187
|
+
|
|
188
|
+
// Startup sort timings, IRQs off, screen and sprites off: with DEN
|
|
189
|
+
// clear when line $30 passes there are no badlines, so the timer
|
|
190
|
+
// counts only the CPU's own cycles.
|
|
191
|
+
lda #$0b
|
|
192
|
+
sta $d011
|
|
193
|
+
lda #0
|
|
194
|
+
sta $d015
|
|
195
|
+
!: lda $d012
|
|
196
|
+
bne !-
|
|
197
|
+
!: lda $d012
|
|
198
|
+
cmp #60
|
|
199
|
+
bne !-
|
|
200
|
+
ldx #N - 1
|
|
201
|
+
!: txa
|
|
202
|
+
sta order, x
|
|
203
|
+
dex
|
|
204
|
+
bpl !-
|
|
205
|
+
jsr move_actors
|
|
206
|
+
jsr sort // untimed: now sorted
|
|
207
|
+
jsr timed_sort // already sorted
|
|
208
|
+
lda n16
|
|
209
|
+
sta t_stable
|
|
210
|
+
lda n16 + 1
|
|
211
|
+
sta t_stable + 1
|
|
212
|
+
|
|
213
|
+
ldx #0 // order = i*7 mod 24
|
|
214
|
+
lda #0
|
|
215
|
+
!: sta order, x
|
|
216
|
+
clc
|
|
217
|
+
adc #7
|
|
218
|
+
cmp #N
|
|
219
|
+
bcc no_wrap
|
|
220
|
+
sbc #N
|
|
221
|
+
no_wrap:
|
|
222
|
+
inx
|
|
223
|
+
cpx #N
|
|
224
|
+
bne !-
|
|
225
|
+
jsr timed_sort
|
|
226
|
+
lda n16
|
|
227
|
+
sta t_shuf
|
|
228
|
+
lda n16 + 1
|
|
229
|
+
sta t_shuf + 1
|
|
230
|
+
|
|
231
|
+
ldx #0 // reverse the sorted order
|
|
232
|
+
ldy #N - 1
|
|
233
|
+
!: lda order, y
|
|
234
|
+
sta tmp_order, x
|
|
235
|
+
dey
|
|
236
|
+
inx
|
|
237
|
+
cpx #N
|
|
238
|
+
bne !-
|
|
239
|
+
ldx #N - 1
|
|
240
|
+
!: lda tmp_order, x
|
|
241
|
+
sta order, x
|
|
242
|
+
dex
|
|
243
|
+
bpl !-
|
|
244
|
+
jsr timed_sort
|
|
245
|
+
lda n16
|
|
246
|
+
sta t_rev
|
|
247
|
+
lda n16 + 1
|
|
248
|
+
sta t_rev + 1
|
|
249
|
+
|
|
250
|
+
// First frame: build half 0, show it, arm the frame IRQ.
|
|
251
|
+
lda #BUF // so that build's back half is 0
|
|
252
|
+
sta front_off
|
|
253
|
+
lda #$11 // timed like the sorts: screen still off
|
|
254
|
+
sta $dd0e
|
|
255
|
+
jsr build
|
|
256
|
+
lda #$00
|
|
257
|
+
sta $dd0e
|
|
258
|
+
jsr read_a
|
|
259
|
+
lda n16
|
|
260
|
+
sta t_build
|
|
261
|
+
lda n16 + 1
|
|
262
|
+
sta t_build + 1
|
|
263
|
+
lda #0
|
|
264
|
+
sta front_off
|
|
265
|
+
lda #<bottom_body
|
|
266
|
+
sta next_hnd
|
|
267
|
+
lda #>bottom_body
|
|
268
|
+
sta next_hnd + 1
|
|
269
|
+
jsr print_fixed
|
|
270
|
+
lda #$ff
|
|
271
|
+
sta $d015
|
|
272
|
+
lda #$1b
|
|
273
|
+
sta $d011 // screen on; bit 8 of the raster compare = 0
|
|
274
|
+
lda #BOTTOM
|
|
275
|
+
sta $d012
|
|
276
|
+
lda #$01
|
|
277
|
+
sta $d01a
|
|
278
|
+
sta $d019
|
|
279
|
+
cli
|
|
280
|
+
|
|
281
|
+
// ---------------------------------------------------------------------------
|
|
282
|
+
// Main loop: one pass per displayed frame.
|
|
283
|
+
// ---------------------------------------------------------------------------
|
|
284
|
+
main:
|
|
285
|
+
!: lda ready // wait until the frame IRQ took the last build
|
|
286
|
+
bne !-
|
|
287
|
+
jsr move_actors
|
|
288
|
+
lda #$11 // load $FFFF and start timer A
|
|
289
|
+
sta $dd0e
|
|
290
|
+
jsr sort
|
|
291
|
+
lda #$00
|
|
292
|
+
sta $dd0e // stop
|
|
293
|
+
jsr read_a
|
|
294
|
+
lda n16
|
|
295
|
+
sta sort_cyc
|
|
296
|
+
lda n16 + 1
|
|
297
|
+
sta sort_cyc + 1
|
|
298
|
+
cmp sort_max + 1 // keep the largest
|
|
299
|
+
bcc not_max
|
|
300
|
+
bne new_max
|
|
301
|
+
lda n16
|
|
302
|
+
cmp sort_max
|
|
303
|
+
bcc not_max
|
|
304
|
+
new_max:
|
|
305
|
+
lda n16
|
|
306
|
+
sta sort_max
|
|
307
|
+
lda n16 + 1
|
|
308
|
+
sta sort_max + 1
|
|
309
|
+
not_max:
|
|
310
|
+
jsr build
|
|
311
|
+
lda #1
|
|
312
|
+
sta ready
|
|
313
|
+
jsr print_stats
|
|
314
|
+
jmp main
|
|
315
|
+
|
|
316
|
+
timed_sort:
|
|
317
|
+
lda #$11
|
|
318
|
+
sta $dd0e
|
|
319
|
+
jsr sort
|
|
320
|
+
lda #$00
|
|
321
|
+
sta $dd0e
|
|
322
|
+
// fall through
|
|
323
|
+
// read_a: n16 = $FFFF - timer A - calib, then reload the latch.
|
|
324
|
+
read_a:
|
|
325
|
+
lda #$ff
|
|
326
|
+
sec
|
|
327
|
+
sbc $dd04
|
|
328
|
+
sta n16
|
|
329
|
+
lda #$ff
|
|
330
|
+
sbc $dd05
|
|
331
|
+
sta n16 + 1
|
|
332
|
+
lda n16
|
|
333
|
+
sec
|
|
334
|
+
sbc calib
|
|
335
|
+
sta n16
|
|
336
|
+
lda n16 + 1
|
|
337
|
+
sbc calib + 1
|
|
338
|
+
sta n16 + 1
|
|
339
|
+
lda #$10
|
|
340
|
+
sta $dd0e
|
|
341
|
+
rts
|
|
342
|
+
|
|
343
|
+
// ---------------------------------------------------------------------------
|
|
344
|
+
// Actors follow a 256-entry path table at their own phase and speed.
|
|
345
|
+
// ---------------------------------------------------------------------------
|
|
346
|
+
move_actors:
|
|
347
|
+
ldx #N - 1
|
|
348
|
+
!: lda phase, x
|
|
349
|
+
clc
|
|
350
|
+
adc speed, x
|
|
351
|
+
sta phase, x
|
|
352
|
+
tay
|
|
353
|
+
lda path, y
|
|
354
|
+
sta act_y, x
|
|
355
|
+
dex
|
|
356
|
+
bpl !-
|
|
357
|
+
rts
|
|
358
|
+
|
|
359
|
+
// ---------------------------------------------------------------------------
|
|
360
|
+
// Persistent insertion sort: order[] keeps last frame's order, so an
|
|
361
|
+
// element already in place costs one compare. Ties keep their order.
|
|
362
|
+
// ---------------------------------------------------------------------------
|
|
363
|
+
.align $100 // both loop branches stay inside one page
|
|
364
|
+
sort:
|
|
365
|
+
ldx #1
|
|
366
|
+
s_loop:
|
|
367
|
+
ldy order, x
|
|
368
|
+
lda act_y, y
|
|
369
|
+
ldy order - 1, x
|
|
370
|
+
cmp act_y, y
|
|
371
|
+
bcs s_next // y[order[i]] >= y[order[i-1]]: in place
|
|
372
|
+
sta key
|
|
373
|
+
lda order, x
|
|
374
|
+
sta cand
|
|
375
|
+
stx s_i
|
|
376
|
+
s_shift:
|
|
377
|
+
lda order - 1, x
|
|
378
|
+
sta order, x
|
|
379
|
+
dex
|
|
380
|
+
beq s_place
|
|
381
|
+
ldy order - 1, x
|
|
382
|
+
lda act_y, y
|
|
383
|
+
cmp key
|
|
384
|
+
beq s_place
|
|
385
|
+
bcs s_shift // still greater than the key: keep shifting
|
|
386
|
+
s_place:
|
|
387
|
+
lda cand
|
|
388
|
+
sta order, x
|
|
389
|
+
ldx s_i
|
|
390
|
+
s_next:
|
|
391
|
+
inx
|
|
392
|
+
cpx #N
|
|
393
|
+
bne s_loop
|
|
394
|
+
rts
|
|
395
|
+
|
|
396
|
+
// ---------------------------------------------------------------------------
|
|
397
|
+
// Build the back half: accept or reject each sorted actor, precalculate
|
|
398
|
+
// $D010, then group sprites 8.. into zones.
|
|
399
|
+
// ---------------------------------------------------------------------------
|
|
400
|
+
build:
|
|
401
|
+
lda front_off
|
|
402
|
+
eor #BUF
|
|
403
|
+
sta bo
|
|
404
|
+
sta acc
|
|
405
|
+
lda #0
|
|
406
|
+
sta d010run
|
|
407
|
+
sta rejects
|
|
408
|
+
ldx #0
|
|
409
|
+
b_loop:
|
|
410
|
+
stx bk
|
|
411
|
+
ldy order, x
|
|
412
|
+
lda act_y, y
|
|
413
|
+
sta by
|
|
414
|
+
ldx acc
|
|
415
|
+
txa
|
|
416
|
+
sec
|
|
417
|
+
sbc bo
|
|
418
|
+
cmp #8
|
|
419
|
+
bcc b_accept // the first eight always fit
|
|
420
|
+
lda by
|
|
421
|
+
sec
|
|
422
|
+
sbc sy - 8, x // gap to the last sprite this slot showed
|
|
423
|
+
cmp #MIN_GAP
|
|
424
|
+
bcc b_reject
|
|
425
|
+
b_accept:
|
|
426
|
+
lda by
|
|
427
|
+
sta sy, x
|
|
428
|
+
lda act_x, y
|
|
429
|
+
sta sx, x
|
|
430
|
+
lda act_ptr, y
|
|
431
|
+
sta sptr, x
|
|
432
|
+
lda act_col, y
|
|
433
|
+
sta scol, x
|
|
434
|
+
lda act_xh, y
|
|
435
|
+
beq b_clear
|
|
436
|
+
lda d010run
|
|
437
|
+
ora bitm, x
|
|
438
|
+
jmp b_store
|
|
439
|
+
b_clear:
|
|
440
|
+
lda bitm, x
|
|
441
|
+
eor #$ff
|
|
442
|
+
and d010run
|
|
443
|
+
b_store:
|
|
444
|
+
sta d010run
|
|
445
|
+
sta sd010, x
|
|
446
|
+
inx
|
|
447
|
+
stx acc
|
|
448
|
+
jmp b_next
|
|
449
|
+
b_reject:
|
|
450
|
+
inc rejects
|
|
451
|
+
b_next:
|
|
452
|
+
ldx bk
|
|
453
|
+
inx
|
|
454
|
+
cpx #N
|
|
455
|
+
bne b_loop
|
|
456
|
+
|
|
457
|
+
lda bo // zones over accepted sprites 8..acc-1
|
|
458
|
+
sta zw
|
|
459
|
+
clc
|
|
460
|
+
adc #8
|
|
461
|
+
tax
|
|
462
|
+
z_loop:
|
|
463
|
+
cpx acc
|
|
464
|
+
bcs z_done
|
|
465
|
+
ldy zw
|
|
466
|
+
txa
|
|
467
|
+
sta zstart, y
|
|
468
|
+
lda sy, x
|
|
469
|
+
sta ybase
|
|
470
|
+
clc
|
|
471
|
+
adc #JOIN
|
|
472
|
+
sta ylim
|
|
473
|
+
lda #0
|
|
474
|
+
sta zn
|
|
475
|
+
z_in:
|
|
476
|
+
inx
|
|
477
|
+
inc zn
|
|
478
|
+
cpx acc
|
|
479
|
+
bcs z_close
|
|
480
|
+
lda sy, x
|
|
481
|
+
cmp ylim
|
|
482
|
+
bcc z_in
|
|
483
|
+
beq z_in
|
|
484
|
+
z_close:
|
|
485
|
+
txa
|
|
486
|
+
sta zend, y
|
|
487
|
+
lda ybase
|
|
488
|
+
sec
|
|
489
|
+
sbc #LEAD
|
|
490
|
+
sbc zn
|
|
491
|
+
sta zline, y
|
|
492
|
+
inc zw
|
|
493
|
+
jmp z_loop
|
|
494
|
+
z_done:
|
|
495
|
+
ldy bo
|
|
496
|
+
lda zw
|
|
497
|
+
sta zlast_b, y
|
|
498
|
+
lda rejects
|
|
499
|
+
sta rej_b, y
|
|
500
|
+
rts
|
|
501
|
+
|
|
502
|
+
// ---------------------------------------------------------------------------
|
|
503
|
+
// IRQ. Entry pauses timer A (so an IRQ during the sort is not counted as
|
|
504
|
+
// sort time, apart from the cycles before the pause) and runs timer B,
|
|
505
|
+
// which adds up the multiplexer's IRQ time over one frame.
|
|
506
|
+
// ---------------------------------------------------------------------------
|
|
507
|
+
irq_entry:
|
|
508
|
+
sta save_a
|
|
509
|
+
lda $dd0e
|
|
510
|
+
and #$01
|
|
511
|
+
sta cra_save
|
|
512
|
+
lda #$00
|
|
513
|
+
sta $dd0e // pause the sort timer
|
|
514
|
+
lda #$01
|
|
515
|
+
sta $dd0f // run the IRQ timer
|
|
516
|
+
cld // binary arithmetic below, whatever was running
|
|
517
|
+
stx save_x
|
|
518
|
+
sty save_y
|
|
519
|
+
dispatch:
|
|
520
|
+
jmp (next_hnd)
|
|
521
|
+
|
|
522
|
+
// Zone body: write every sprite of zone zidx, Y first.
|
|
523
|
+
zone_body:
|
|
524
|
+
ldx zidx
|
|
525
|
+
lda zend, x
|
|
526
|
+
sta zend_tmp
|
|
527
|
+
ldy zstart, x
|
|
528
|
+
zl:
|
|
529
|
+
ldx slot2, y
|
|
530
|
+
lda sy, y
|
|
531
|
+
sta $d001, x
|
|
532
|
+
lda sx, y
|
|
533
|
+
sta $d000, x
|
|
534
|
+
ldx slot, y
|
|
535
|
+
lda sptr, y
|
|
536
|
+
sta PTRS, x
|
|
537
|
+
lda scol, y
|
|
538
|
+
sta $d027, x
|
|
539
|
+
lda sd010, y
|
|
540
|
+
sta $d010
|
|
541
|
+
iny
|
|
542
|
+
cpy zend_tmp
|
|
543
|
+
bne zl
|
|
544
|
+
ldx zidx
|
|
545
|
+
inx
|
|
546
|
+
stx zidx
|
|
547
|
+
cpx zlast
|
|
548
|
+
beq z_to_bottom
|
|
549
|
+
lda zline, x
|
|
550
|
+
jmp schedule
|
|
551
|
+
z_to_bottom:
|
|
552
|
+
lda #<bottom_body
|
|
553
|
+
sta next_hnd
|
|
554
|
+
lda #>bottom_body
|
|
555
|
+
sta next_hnd + 1
|
|
556
|
+
lda #BOTTOM
|
|
557
|
+
// fall through
|
|
558
|
+
|
|
559
|
+
// schedule: A = next line. If the raster is already within MARGIN lines
|
|
560
|
+
// of it, run the next body now instead of returning and waiting a frame.
|
|
561
|
+
schedule:
|
|
562
|
+
sta $d012
|
|
563
|
+
sec
|
|
564
|
+
sbc #MARGIN
|
|
565
|
+
cmp $d012
|
|
566
|
+
bcs on_time
|
|
567
|
+
inc late_total
|
|
568
|
+
bne !+
|
|
569
|
+
inc late_total + 1
|
|
570
|
+
!: lda #1
|
|
571
|
+
sta late_flag
|
|
572
|
+
jmp dispatch
|
|
573
|
+
on_time:
|
|
574
|
+
lda #$01
|
|
575
|
+
sta $d019
|
|
576
|
+
irq_exit:
|
|
577
|
+
ldy save_y
|
|
578
|
+
ldx save_x
|
|
579
|
+
lda #$00
|
|
580
|
+
sta $dd0f // stop the IRQ timer
|
|
581
|
+
lda cra_save
|
|
582
|
+
sta $dd0e // resume the sort timer if it was running
|
|
583
|
+
lda save_a
|
|
584
|
+
nmi:
|
|
585
|
+
rti
|
|
586
|
+
|
|
587
|
+
// Frame body at line BOTTOM: swap halves if a build is ready, write the
|
|
588
|
+
// first eight sprites of the shown half, arm the first zone.
|
|
589
|
+
bottom_body:
|
|
590
|
+
lda ready
|
|
591
|
+
beq no_swap
|
|
592
|
+
lda front_off
|
|
593
|
+
eor #BUF
|
|
594
|
+
sta front_off
|
|
595
|
+
lda #0
|
|
596
|
+
sta ready
|
|
597
|
+
jmp swapped
|
|
598
|
+
no_swap:
|
|
599
|
+
inc missed
|
|
600
|
+
bne swapped
|
|
601
|
+
inc missed + 1
|
|
602
|
+
swapped:
|
|
603
|
+
ldy front_off
|
|
604
|
+
.for (var s = 0; s < 8; s++) {
|
|
605
|
+
lda sy + s, y
|
|
606
|
+
sta $d001 + s * 2
|
|
607
|
+
lda sx + s, y
|
|
608
|
+
sta $d000 + s * 2
|
|
609
|
+
lda sptr + s, y
|
|
610
|
+
sta PTRS + s
|
|
611
|
+
lda scol + s, y
|
|
612
|
+
sta $d027 + s
|
|
613
|
+
}
|
|
614
|
+
lda sd010 + 7, y
|
|
615
|
+
sta $d010
|
|
616
|
+
sty zidx
|
|
617
|
+
lda zlast_b, y
|
|
618
|
+
sta zlast
|
|
619
|
+
inc frames
|
|
620
|
+
bne !+
|
|
621
|
+
inc frames + 1
|
|
622
|
+
!: lda late_flag
|
|
623
|
+
beq !+
|
|
624
|
+
inc late_frms
|
|
625
|
+
bne !+
|
|
626
|
+
inc late_frms + 1
|
|
627
|
+
!: lda #0
|
|
628
|
+
sta late_flag
|
|
629
|
+
sta $dd0f // stop timer B and read one frame's IRQ time
|
|
630
|
+
lda #$ff
|
|
631
|
+
sec
|
|
632
|
+
sbc $dd06
|
|
633
|
+
sta irq_cyc
|
|
634
|
+
lda #$ff
|
|
635
|
+
sbc $dd07
|
|
636
|
+
sta irq_cyc + 1
|
|
637
|
+
lda #$10
|
|
638
|
+
sta $dd0f // reload $FFFF, stopped
|
|
639
|
+
ldx zidx
|
|
640
|
+
cpx zlast
|
|
641
|
+
beq only_eight
|
|
642
|
+
lda #<zone_body
|
|
643
|
+
sta next_hnd
|
|
644
|
+
lda #>zone_body
|
|
645
|
+
sta next_hnd + 1
|
|
646
|
+
lda zline, x
|
|
647
|
+
jmp arm
|
|
648
|
+
only_eight:
|
|
649
|
+
lda #BOTTOM
|
|
650
|
+
arm:
|
|
651
|
+
sta $d012 // next frame: no late check across the wrap
|
|
652
|
+
jmp on_time
|
|
653
|
+
|
|
654
|
+
// ---------------------------------------------------------------------------
|
|
655
|
+
// Statistics, printed by the main loop after each build.
|
|
656
|
+
// ---------------------------------------------------------------------------
|
|
657
|
+
.macro Print(v, col) {
|
|
658
|
+
lda v
|
|
659
|
+
sta n16
|
|
660
|
+
lda v + 1
|
|
661
|
+
sta n16 + 1
|
|
662
|
+
lda #<(SCREEN + col)
|
|
663
|
+
sta dst
|
|
664
|
+
lda #>(SCREEN + col)
|
|
665
|
+
sta dst + 1
|
|
666
|
+
jsr pr16
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
// The figures fixed at startup are printed once; the live ones in two
|
|
670
|
+
// halves on alternate frames, so printing does not crowd out the build.
|
|
671
|
+
print_fixed:
|
|
672
|
+
Print(t_build, 35)
|
|
673
|
+
Print(t_stable, 40 + 7)
|
|
674
|
+
Print(t_shuf, 40 + 18)
|
|
675
|
+
Print(t_rev, 40 + 28)
|
|
676
|
+
Print(calib, 120 + 30)
|
|
677
|
+
rts
|
|
678
|
+
|
|
679
|
+
print_stats:
|
|
680
|
+
inc pflip
|
|
681
|
+
lda pflip
|
|
682
|
+
and #1
|
|
683
|
+
beq print_a
|
|
684
|
+
Print(late_total, 80 + 5)
|
|
685
|
+
Print(late_frms, 80 + 16)
|
|
686
|
+
Print(frames, 120 + 7)
|
|
687
|
+
Print(missed, 120 + 20)
|
|
688
|
+
rts
|
|
689
|
+
print_a:
|
|
690
|
+
Print(sort_cyc, 5)
|
|
691
|
+
Print(sort_max, 15)
|
|
692
|
+
Print(irq_cyc, 25)
|
|
693
|
+
ldy bo // zones and rejects of the half just built
|
|
694
|
+
lda zlast_b, y
|
|
695
|
+
sec
|
|
696
|
+
sbc bo
|
|
697
|
+
sta n16
|
|
698
|
+
lda #0
|
|
699
|
+
sta n16 + 1
|
|
700
|
+
lda #<(SCREEN + 80 + 25)
|
|
701
|
+
sta dst
|
|
702
|
+
lda #>(SCREEN + 80 + 25)
|
|
703
|
+
sta dst + 1
|
|
704
|
+
jsr pr16
|
|
705
|
+
ldy bo
|
|
706
|
+
lda rej_b, y
|
|
707
|
+
sta n16
|
|
708
|
+
lda #0
|
|
709
|
+
sta n16 + 1
|
|
710
|
+
lda #<(SCREEN + 80 + 34)
|
|
711
|
+
sta dst
|
|
712
|
+
lda #>(SCREEN + 80 + 34)
|
|
713
|
+
sta dst + 1
|
|
714
|
+
// fall through
|
|
715
|
+
|
|
716
|
+
// pr16: n16 as five decimal digits at (dst).
|
|
717
|
+
pr16:
|
|
718
|
+
ldy #0
|
|
719
|
+
ldx #0
|
|
720
|
+
d_loop:
|
|
721
|
+
lda #$30 // screen code of '0'
|
|
722
|
+
sta digit
|
|
723
|
+
d_sub:
|
|
724
|
+
lda n16
|
|
725
|
+
sec
|
|
726
|
+
sbc p10lo, x
|
|
727
|
+
sta tmp
|
|
728
|
+
lda n16 + 1
|
|
729
|
+
sbc p10hi, x
|
|
730
|
+
bcc d_out
|
|
731
|
+
sta n16 + 1
|
|
732
|
+
lda tmp
|
|
733
|
+
sta n16
|
|
734
|
+
inc digit
|
|
735
|
+
jmp d_sub
|
|
736
|
+
d_out:
|
|
737
|
+
lda digit
|
|
738
|
+
sta (dst), y
|
|
739
|
+
iny
|
|
740
|
+
inx
|
|
741
|
+
cpx #5
|
|
742
|
+
bne d_loop
|
|
743
|
+
rts
|
|
744
|
+
|
|
745
|
+
p10lo: .byte <10000, <1000, <100, <10, <1
|
|
746
|
+
p10hi: .byte >10000, >1000, >100, >10, >1
|
|
747
|
+
|
|
748
|
+
labels:
|
|
749
|
+
.text "sort max irq bld "
|
|
750
|
+
.text "stable shuf rev "
|
|
751
|
+
.text "late lfrm zn rj "
|
|
752
|
+
.text "frames missed cal "
|
|
753
|
+
|
|
754
|
+
// ---------------------------------------------------------------------------
|
|
755
|
+
// Tables
|
|
756
|
+
// ---------------------------------------------------------------------------
|
|
757
|
+
* = $1000 "tables"
|
|
758
|
+
path: .fill 256, TOP_Y + round(69 + 69 * sin(toRadians(i * 360 / 256)))
|
|
759
|
+
act_y: .fill N, 0
|
|
760
|
+
act_x: .fill N, (24 + 13 * i) & $ff
|
|
761
|
+
act_xh: .fill N, (24 + 13 * i) >> 8
|
|
762
|
+
act_col: .fill N, 1 + mod(i, 15)
|
|
763
|
+
act_ptr: .fill N, $2000 / 64
|
|
764
|
+
phase: .fill N, mod(i * 45, 256)
|
|
765
|
+
speed: .fill N, (i & 3) == 3 ? $fe : 1 + (i & 3)
|
|
766
|
+
order: .fill N, i
|
|
767
|
+
tmp_order: .fill N, 0
|
|
768
|
+
|
|
769
|
+
* = $1200 "sorted halves"
|
|
770
|
+
sy: .fill 64, 0
|
|
771
|
+
sx: .fill 64, 0
|
|
772
|
+
sptr: .fill 64, 0
|
|
773
|
+
scol: .fill 64, 0
|
|
774
|
+
sd010: .fill 64, 0
|
|
775
|
+
zstart: .fill 64, 0
|
|
776
|
+
zend: .fill 64, 0
|
|
777
|
+
zline: .fill 64, 0
|
|
778
|
+
zlast_b: .fill 64, 0
|
|
779
|
+
rej_b: .fill 64, 0
|
|
780
|
+
slot: .fill 64, i & 7
|
|
781
|
+
slot2: .fill 64, (i & 7) * 2
|
|
782
|
+
bitm: .fill 64, 1 << (i & 7)
|
|
783
|
+
|
|
784
|
+
// One shape: an 8-pixel-wide, 21-line block in the sprite's left byte.
|
|
785
|
+
* = $2000 "sprite"
|
|
786
|
+
.fill 21, [$ff, $00, $00]
|
|
787
|
+
.byte 0
|
|
788
|
+
```
|
|
789
|
+
|
|
790
|
+
## Build
|
|
791
|
+
|
|
792
|
+
```bash
|
|
793
|
+
java -jar KickAss.jar sprite-multiplex-game.asm -o sprite-multiplex-game.prg -showmem
|
|
794
|
+
```
|
|
795
|
+
|
|
796
|
+
`-showmem` prints code at $0820–$0EAA, the actor and path tables at
|
|
797
|
+
$1000–$11D7, the two sorted halves and the slot tables at $1200–$153F and
|
|
798
|
+
the sprite shape at $2000. The sort is aligned to a page (`.align $100`),
|
|
799
|
+
which is why the code segment has a gap.
|
|
800
|
+
|
|
801
|
+
## Expected output
|
|
802
|
+
|
|
803
|
+
A black screen. The top four text rows, in white:
|
|
804
|
+
|
|
805
|
+
```text
|
|
806
|
+
SORT 00750 MAX 01411 IRQ 02764 BLD 03815
|
|
807
|
+
STABLE 00611 SHUF 05228 REV 08783
|
|
808
|
+
LATE 00370 LFRM 00249 ZN 00010 RJ 00000
|
|
809
|
+
FRAMES 00309 MISSED 00001 CAL 00005
|
|
810
|
+
```
|
|
811
|
+
|
|
812
|
+
That is the PAL screenshot at 9,100,000 cycles. The NTSC one reads SORT
|
|
813
|
+
815, MAX 1,411, IRQ 2,608, LATE 369, LFRM 266, ZN 10, RJ 0, FRAMES 346,
|
|
814
|
+
MISSED 0, and the same five startup figures. The fields are:
|
|
815
|
+
|
|
816
|
+
| Field | What it counts |
|
|
817
|
+
|---|---|
|
|
818
|
+
| SORT, MAX | Cycles of this frame's sort call, and the largest so far (CIA2 timer A). |
|
|
819
|
+
| IRQ | Cycles inside the multiplexer IRQs over one frame (CIA2 timer B), from the timer-start write to the timer-stop write of each IRQ. |
|
|
820
|
+
| BLD | One build of a sorted half, timed at startup. |
|
|
821
|
+
| STABLE, SHUF, REV | The sort at startup on an order already sorted, on the order i×7 mod 24, and on the sorted order reversed. |
|
|
822
|
+
| LATE, LFRM | Times the late guard ran the next zone at once, and frames in which it did so at least once. |
|
|
823
|
+
| ZN, RJ | Zones and rejected actors in the half just built. |
|
|
824
|
+
| FRAMES, MISSED | Frame IRQs so far, and frames shown twice because the build was not ready. |
|
|
825
|
+
| CAL | Timer count of a start write followed at once by a stop write; every timed figure has it subtracted. |
|
|
826
|
+
|
|
827
|
+
Below the text, 24 boxes, 8 pixels wide and 21 lines tall, one per
|
|
828
|
+
column at sprite X = 24 + 13 × i, in colours 1–15 repeating. Actors 18–23
|
|
829
|
+
sit past X = 255 and need their $D010 bit. The boxes rise and fall on a
|
|
830
|
+
sine at different speeds and phases, so they overtake one another in Y
|
|
831
|
+
and the sort has work to do.
|
|
832
|
+
|
|
833
|
+
Screenshots from the VICE runs this page describes:
|
|
834
|
+
`screenshots/sprite-multiplex-game.png` (PAL) and
|
|
835
|
+
`screenshots/sprite-multiplex-game-ntsc.png` (NTSC), both at
|
|
836
|
+
9,100,000 cycles. Each command was run twice and gave identical bytes.
|
|
837
|
+
|
|
838
|
+
## Why this works
|
|
839
|
+
|
|
840
|
+
### What was measured
|
|
841
|
+
|
|
842
|
+
The text rows were decoded from the screenshots by matching each 8×8 cell
|
|
843
|
+
against the character ROM (`chargen-901225-01.bin`). The sprite check
|
|
844
|
+
walked each actor's column at screenshot x = 35 + 13 × i and recorded each
|
|
845
|
+
lit run (PAL row = raster line − 16, NTSC row = line − 28).
|
|
846
|
+
|
|
847
|
+
| Claim | Result | Rung |
|
|
848
|
+
|---|---|---|
|
|
849
|
+
| Every actor is drawn | 24 of 24 columns hold a box in both pinned shots and in 16 swept shots (PAL and NTSC, 8.1 to 9.5 million cycles, 200,000 apart) | measured in VICE x64sc |
|
|
850
|
+
| Boxes are whole | Pinned shots: every box is 21 lines, 8 pixels, one colour. In 9 of the 16 swept shots, 2 to 4 boxes were 18 to 26 lines long or had a 1-line fragment beside them, because the exit screenshot cut the frame there (the mid-frame effect in `docs/runtime/vice-reference.md`). The beam line at exit, (cycles mod 19,656) / 63 on PAL and (cycles mod 17,095) / 65 on NTSC, lies inside the split boxes' lines in all 9 of those shots and outside sprite lines 91 to 249 in the 7 clean ones. PAL reruns at 8,519,656 and 8,539,312 cycles (beam at line 136) split boxes at 136 again; 8,509,828 and 8,529,484 (beam at line 292) were clean | measured; the cut line predicted by arithmetic and confirmed by runs one frame apart |
|
|
851
|
+
| Sort, order already sorted | 611 cycles for 24 actors, JSR and RTS included. The listing gives JSR 6 + `ldx #1` 2 + 26 per compare × 23 − 1 (the last `bne` not taken) + RTS 6 = 611, which matches the measurement | measured, and arithmetic agrees |
|
|
852
|
+
| Same sort straddling a page | 656 cycles: both loop branches crossed a page and took 28 per compare. Hence `.align $100` | measured |
|
|
853
|
+
| Sort, shuffled (i×7 mod 24) | 5,228 cycles | measured |
|
|
854
|
+
| Sort, reversed | 8,783 cycles: 276 moves, about 29.6 cycles per place an element moves | measured |
|
|
855
|
+
| Sort in the running game | 611 to 953 cycles in the 16 swept shots (PAL and NTSC, 8.1 to 9.5 million cycles); largest 1,411 in the first 257 to 370 frames of each | measured |
|
|
856
|
+
| Build of one sorted half | 3,815 cycles | measured |
|
|
857
|
+
| IRQ time per frame | 2,201 to 2,764 cycles in the same 16 shots, with 7 to 13 zones built (10 in the pinned shot) | measured |
|
|
858
|
+
| IRQ time the timer does not see | 31 cycles before the start write (7 for the interrupt, 24 of prologue) and 16 after the stop write, per IRQ taken | arithmetic from the listing |
|
|
859
|
+
| Late guard | Fired 370 times in 309 PAL frames, in 249 of them; 369 times in 346 NTSC frames, in 266 of them | measured |
|
|
860
|
+
| Late guard overshoot | A probe build recorded the raster on the fall-through path: at most 5 lines past line − 3, so at most 2 lines past the scheduled line and at least 2 lines before the zone's first Y (PAL, 309 frames). An 8-sprite zone under full sprite DMA on a badline was not measured | measured in VICE x64sc |
|
|
861
|
+
| Late guard removed | A build with `bcs on_time` changed to `jmp on_time` showed 11 of 24 boxes in 2 of the 16 swept shots (9,300,000 cycles, PAL and NTSC) and 24 in the other 14 | measured |
|
|
862
|
+
| Printing load | Printing all twelve figures every frame left MISSED at 13 of about 260 PAL frames and 66 of about 290 NTSC frames; printing the five startup figures once and the live ones half at a time brought it to 0 or 1 | measured |
|
|
863
|
+
|
|
864
|
+
The startup timings run with IRQs off, sprites off and $D011 = $0B. DEN
|
|
865
|
+
is clear when line $30 passes, so there are no badlines and the timer
|
|
866
|
+
counts only the CPU's own cycles. With the screen and sprites on, the
|
|
867
|
+
already-sorted figure read 742.
|
|
868
|
+
|
|
869
|
+
### The sort keeps last frame's order
|
|
870
|
+
|
|
871
|
+
`order[]` is never reset. Each frame starts from the order the last frame
|
|
872
|
+
ended with, so an actor that has not passed a neighbour costs one compare:
|
|
873
|
+
`ldy order,x / lda act_y,y / ldy order-1,x / cmp act_y,y / bcs`, 26
|
|
874
|
+
cycles with the loop control. An actor that has passed k neighbours is
|
|
875
|
+
shifted k places at about 29.6 cycles a place. On paths that move 1 to 3
|
|
876
|
+
lines a frame that is a few hundred cycles above the sorted figure. A
|
|
877
|
+
reversed order is the worst case, 8,783 cycles, about 45 % of a PAL frame
|
|
878
|
+
on the sort alone. Ties stop the shift (`beq s_place`), so equal Ys keep
|
|
879
|
+
their order and do not swap back and forth from frame to frame.
|
|
880
|
+
|
|
881
|
+
### Two halves, one flag
|
|
882
|
+
|
|
883
|
+
The sorted tables `sy`, `sx`, `sptr`, `scol` and `sd010` are 64 bytes
|
|
884
|
+
each: half 0 at offset 0 and half 1 at offset 32. The IRQs read the half
|
|
885
|
+
at `front_off`; the main loop builds the other. The main loop waits until
|
|
886
|
+
`ready` is 0, builds, then sets `ready`. The frame IRQ swaps only when
|
|
887
|
+
`ready` is 1. The main loop therefore never writes a half the IRQs are
|
|
888
|
+
reading, and a late build shows the old half again (MISSED) instead of a
|
|
889
|
+
half-written table. The unsorted actor tables are not doubled; only the
|
|
890
|
+
main loop touches them.
|
|
891
|
+
|
|
892
|
+
### Rejecting the ninth sprite
|
|
893
|
+
|
|
894
|
+
A sorted entry at accepted position a ≥ 8 goes to slot a mod 8, which last
|
|
895
|
+
showed entry a − 8. `build` rejects the actor when its Y is less than 21
|
|
896
|
+
lines below that entry's Y and counts it in RJ. Twenty-one is the gap the
|
|
897
|
+
hardware needs: `docs/pitfalls/sprite.md` (`sprite_dma_overflow`) measured
|
|
898
|
+
a slot at Y = 100 rewritten to Y = 120 never reappearing, while Y = 121
|
|
899
|
+
did. A variant with the path squeezed into 50 lines showed RJ = 3 and 20
|
|
900
|
+
of 24 boxes in one PAL shot.
|
|
901
|
+
|
|
902
|
+
### Zones
|
|
903
|
+
|
|
904
|
+
Sprites 8 onward are grouped: a zone starts at the first unwritten sprite
|
|
905
|
+
and takes every following sprite whose Y is at most 4 lines lower. The
|
|
906
|
+
zone's IRQ line is its first Y − 3 − n, where n is its sprite count. The
|
|
907
|
+
writes cost about 60 cycles a sprite (arithmetic from the loop), about one
|
|
908
|
+
line, and Y is written first. A zone can hold at most eight sprites:
|
|
909
|
+
two sprites within 4 lines cannot share a slot, since accepted entries in
|
|
910
|
+
one slot are at least 21 lines apart. The same fact means the slot's
|
|
911
|
+
previous sprite started at least 17 lines above the zone's first Y, so the
|
|
912
|
+
IRQ line (at most 11 lines above it) is always after that start.
|
|
913
|
+
|
|
914
|
+
What the zone does not wait for is the end of the previous sprite. If the
|
|
915
|
+
new sprite is exactly 21 lines below the old one, the new X, colour and
|
|
916
|
+
pointer land while the old sprite still has its last few lines to draw.
|
|
917
|
+
In the squeezed variant, 1- to 3-line stubs in another actor's colour
|
|
918
|
+
appeared next to some boxes; that is this effect. Writing Y last and
|
|
919
|
+
firing the IRQ just below the old sprite avoids it, at the cost of
|
|
920
|
+
dropping the new sprite when the IRQ is late (Cadaver, sprite.html,
|
|
921
|
+
section 2.4.2).
|
|
922
|
+
|
|
923
|
+
### The late guard
|
|
924
|
+
|
|
925
|
+
At the end of every zone the handler stores the next zone's line in
|
|
926
|
+
$D012, subtracts 3 and compares with $D012. If the raster has already
|
|
927
|
+
reached that point it jumps straight to the next zone's body, skipping
|
|
928
|
+
the exit, the acknowledge and the next entry. Without the guard, an IRQ
|
|
929
|
+
line written after the raster has passed it does not fire until the
|
|
930
|
+
next frame, and every zone after it that frame is lost: 11 of 24 boxes in
|
|
931
|
+
2 of the 16 swept shots of the variant above. The acknowledge ($D019 = $01) is written only on the
|
|
932
|
+
on-time path, after the guard, so a compare that matched during a
|
|
933
|
+
fall-through does not raise a second IRQ. Cadaver found that a margin of
|
|
934
|
+
2 lines still flickered in rare cases and uses 3 (not measured here).
|
|
935
|
+
The frame IRQ does not use the guard: its next line is in the next
|
|
936
|
+
frame, and any compare with the current raster would call it late.
|
|
937
|
+
|
|
938
|
+
### $D010 is precalculated
|
|
939
|
+
|
|
940
|
+
`build` keeps a running $D010 value and stores, with every sorted entry,
|
|
941
|
+
the $D010 byte as it must be after that entry is written. The IRQ writes
|
|
942
|
+
one precomputed byte instead of reading, masking and setting a bit. The
|
|
943
|
+
frame IRQ writes the byte stored with entry 7.
|
|
944
|
+
|
|
945
|
+
### The timers
|
|
946
|
+
|
|
947
|
+
CIA2 timer A times the sort and B adds up IRQ time. Both latch $FFFF.
|
|
948
|
+
Writing $11 to a control register loads $FFFF and starts the timer;
|
|
949
|
+
writing $00 stops it; the elapsed count is $FFFF minus the timer, less
|
|
950
|
+
CAL. The IRQ prologue reads timer A's control register, keeps its start
|
|
951
|
+
bit, and stops it, then starts timer B; the epilogue stops B and writes
|
|
952
|
+
A's saved start bit back. A stopped timer restarts from its current count,
|
|
953
|
+
so an IRQ that lands during the sort adds only its first 25 or so cycles
|
|
954
|
+
to SORT. In this program the sort runs in the lower border after the
|
|
955
|
+
frame IRQ, where no zone IRQ fires. CIA2's interrupt mask is cleared so
|
|
956
|
+
the timers cannot raise an NMI. The prologue clears the decimal flag
|
|
957
|
+
before any arithmetic.
|
|
958
|
+
|
|
959
|
+
### Where the time goes
|
|
960
|
+
|
|
961
|
+
Per PAL frame in the pinned shot: sort 750, build about 3,815, IRQs 2,764
|
|
962
|
+
plus about 47 per IRQ taken. The build copies five bytes for every actor
|
|
963
|
+
so the IRQ indexes one set of tables; it is the largest item. The main
|
|
964
|
+
loop also runs `move_actors` and prints, and the VIC takes its badline and
|
|
965
|
+
sprite cycles. Printing all twelve figures every frame was enough to
|
|
966
|
+
overrun on NTSC (MISSED 66 of about 290), which is why the live figures
|
|
967
|
+
are printed half at a time.
|
|
968
|
+
|
|
969
|
+
### Region
|
|
970
|
+
|
|
971
|
+
`region: both`. Every IRQ line is between 79 and 252, inside PAL's 312
|
|
972
|
+
and NTSC's 263 lines, so $D011 bit 7 stays 0. Sprite Ys run from 90 to
|
|
973
|
+
228; the last sprite line is 249, before the frame IRQ at 252. Lines 256
|
|
974
|
+
and later on PAL compare as 0 to 55 in the low byte, below every sprite Y
|
|
975
|
+
used here. The pinned run uses the same cycle count on both models.
|
|
976
|
+
|
|
977
|
+
### Sources
|
|
978
|
+
|
|
979
|
+
Facts, not code, from: Cadaver, "Sprite multiplexing",
|
|
980
|
+
https://cadaver.github.io/rants/sprite.html (continuous insertion sort,
|
|
981
|
+
the 21-line rejection, double-buffered sorted tables, precalculated
|
|
982
|
+
$D010, the late-IRQ check with a 3-line margin); Falco Paul in Cadaver's
|
|
983
|
+
"Speculative sprite sorting methods",
|
|
984
|
+
https://cadaver.github.io/rants/sorting.html (bucket and hybrid sorts);
|
|
985
|
+
cadaver/c64gameframework, https://github.com/cadaver/c64gameframework
|
|
986
|
+
(`screen.s`, `raster.s`; MIT), read for names and structure only.
|