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,120 @@
|
|
|
1
|
+
# Rules for an agent working on this C64 program
|
|
2
|
+
|
|
3
|
+
This program runs on a stock Commodore 64, PAL and NTSC. It is built on the
|
|
4
|
+
c64-kb harness (`./harness`, vendored from c64-kb's `templates/_harness`).
|
|
5
|
+
c64-kb is the reference: its pages give the registers, timings, techniques,
|
|
6
|
+
pitfalls and recipes this program is built from. A wrong number becomes a torn
|
|
7
|
+
screen or a crash, so every claim here is measured or says it is not.
|
|
8
|
+
|
|
9
|
+
A new program starts in c64-kb with `npm run new-project -- <starter> <dir>`.
|
|
10
|
+
That copies the starter and the harness, points `.mcp.json` and `local.mk`
|
|
11
|
+
at the c64-kb checkout, proves the copy with `make shot check`, and leaves a
|
|
12
|
+
blank `PLAN.md`.
|
|
13
|
+
|
|
14
|
+
## This starter: action-puzzle
|
|
15
|
+
|
|
16
|
+
CAVE RUN, a Boulder Dash-style game in Oscar64 C: a cave scan split into
|
|
17
|
+
four row slices a frame, RLE caves, a tune and effects, and a high-score
|
|
18
|
+
table saved to drive 8. README.md has the file map and the measured frame.
|
|
19
|
+
Start a program from it with `npm run new-project -- action-puzzle <dir>`
|
|
20
|
+
in c64-kb. `PLAN.md` here is a plan filled from real tool output;
|
|
21
|
+
new-project keeps it as `PLAN-action-puzzle-example.md` and gives the new
|
|
22
|
+
program a blank one.
|
|
23
|
+
|
|
24
|
+
Rules this starter adds:
|
|
25
|
+
|
|
26
|
+
- The rules live twice: `src/cave.c` and the model in `tools/gen.py`. Change
|
|
27
|
+
both, run `make gen`, then `make shot check modelcheck`. The autopilot
|
|
28
|
+
verdict compares the game with the model; a rule changed on one side only
|
|
29
|
+
turns it red. A red verdict prints one letter per failed test on row 23
|
|
30
|
+
(README, "Checks"). After a change to the scan, also `make selftest-scan`.
|
|
31
|
+
- A slice fits about 20 moving objects on NTSC; the verdict counts dropped
|
|
32
|
+
frames (letter D), so a cave past that fails its own check.
|
|
33
|
+
- Caves and the autopilot script are edited in `tools/gen.py`, never in the
|
|
34
|
+
generated `src/gen_*.h`.
|
|
35
|
+
- Disk calls happen on a static screen, with the sound muted, followed by
|
|
36
|
+
`SEI` and `$DC00 = $FF`. `make disktest` proves the save and the load on a
|
|
37
|
+
true-drive 1541; run it after any change to `hiscore.c` or to what runs
|
|
38
|
+
before the first OPEN (pitfall `first_open_after_reset_hangs_on_pal`).
|
|
39
|
+
- To see the normal game (not the autopilot) headless: `make joy`, then
|
|
40
|
+
`tools/drive.py` (README, "Driving it headless"). VICE's joyport commands
|
|
41
|
+
do not reach `$DC00` in the windowless build.
|
|
42
|
+
|
|
43
|
+
## Before any code
|
|
44
|
+
|
|
45
|
+
1. Brief: `npx tsx src/cli.ts game-briefing "<concept>" --archetype <name>`
|
|
46
|
+
(or `demo-briefing`), in the c64-kb checkout. Read what it proposes.
|
|
47
|
+
2. For each technique you keep: `technique-lookup <name>` and
|
|
48
|
+
`pitfalls-for <name>`. Start from the recipe it names (`recipe-lookup`).
|
|
49
|
+
3. Fill `PLAN.md`: paste the whole output of `check-compatibility` and of
|
|
50
|
+
`plan-budget` (same techniques) into their sections, list every technique
|
|
51
|
+
in its table, and replace every `FILL:` line.
|
|
52
|
+
|
|
53
|
+
Until `PLAN.md` passes, a hook blocks Edit and Write under `src/`, and every
|
|
54
|
+
make target that builds stops (`make plan-gate` says what is missing). With
|
|
55
|
+
C64KB set, `make` re-runs `check-compatibility` and wants the pasted Verdict.
|
|
56
|
+
The gate cannot see writes made through a shell command, or outputs edited
|
|
57
|
+
into shape by hand: do neither. `make PLAN_GATE=off` overrides it; say why in
|
|
58
|
+
`PLAN.md` if you do.
|
|
59
|
+
|
|
60
|
+
## The loop
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
make # build build/<name>.prg
|
|
64
|
+
make shot check # autopilot build, headless PAL and NTSC, graded by expect.json
|
|
65
|
+
make selftest # the FORCE_FAULT build must fail the same checks
|
|
66
|
+
make disk # build/<name>.d64
|
|
67
|
+
make claims # every store the program makes, against what it declares
|
|
68
|
+
make run # windowed VICE, for a human
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Rules
|
|
72
|
+
|
|
73
|
+
- Build before claiming. Code that has not built is not done.
|
|
74
|
+
- Measure screenshots with `check.py` through `expect.json`, never by eye.
|
|
75
|
+
Every visible claim gets a check. Add one before you trust a change.
|
|
76
|
+
- PAL and NTSC: both shots pass, or it is not done.
|
|
77
|
+
- Name the rung for every number: measured here (`make shot`, the meter, the
|
|
78
|
+
VICE monitor), taken from a c64-kb page (say which), arithmetic, or not
|
|
79
|
+
measured. Never call something verified that was not run.
|
|
80
|
+
- Frame cost comes from the meter: CIA2 timer A, printed as
|
|
81
|
+
`F<frames> W<worst> T<typical>` at row 24, columns 20 to 39, in AUTOPILOT
|
|
82
|
+
builds. It records the first `hold` frames: make that the autopilot
|
|
83
|
+
script's play frames. Typical is the median of those frames, the KB's
|
|
84
|
+
`cycles_per_frame_typical`. Keep grading, logging and printing outside the
|
|
85
|
+
bracket; work split between the main loop and IRQs is summed with
|
|
86
|
+
`METER_PAUSE` / `METER_START`.
|
|
87
|
+
- Do not invent a register, routine or address. Look it up:
|
|
88
|
+
`lookup-register`, `lookup-kernal`, `memory-map`.
|
|
89
|
+
- Lint every source you change: `npx tsx src/cli.ts lint <file>`.
|
|
90
|
+
- Commit named paths only. Never `git add -A` or `git add .`. `build/`,
|
|
91
|
+
`shots/` and `local.mk` are never committed.
|
|
92
|
+
|
|
93
|
+
## Harness facts you will need
|
|
94
|
+
|
|
95
|
+
- `AUTOPILOT=1` builds read a scripted joystick byte instead of `$DC00` and
|
|
96
|
+
grade themselves: `$02FF` = `$01` and a green border on pass, `$02` and red
|
|
97
|
+
on fail. `FORCE_FAULT=1` must turn the verdict red and move something a
|
|
98
|
+
screenshot check can see.
|
|
99
|
+
- Screenshot geometry (c64-kb `docs/runtime/vice-reference.md`): PAL 384 x 272,
|
|
100
|
+
row = raster line - 16; NTSC 384 x 247, row = line - 28; x = VIC X + 8. A
|
|
101
|
+
sprite at Y register y is drawn from line y + 1.
|
|
102
|
+
- `check.py` reads text in the ROM character set unless a check names a
|
|
103
|
+
`charset` file; the meter's cells need 0-9, F, W and T in the set on screen.
|
|
104
|
+
- A KickAssembler part called from C is a raw blob at its own `* =` address,
|
|
105
|
+
`$0880` or above; `build/asm.h` gives C its labels as `ASM_<LABEL>`
|
|
106
|
+
(`ASM_<SCOPE>_<LABEL>` inside a scope). Pass arguments through bytes in the
|
|
107
|
+
blob, not Oscar64's zero page (`$02` up; the top depends on the program:
|
|
108
|
+
`make zp` lists what the build's code touches).
|
|
109
|
+
- The meter takes CIA2 timer A. Do not open RS-232 (device 2) while it runs.
|
|
110
|
+
- The KERNAL serial routines end in `CLI` (ROM bytes `58 60` / `58 18` at
|
|
111
|
+
`$EDAB`, `$EDB5`, `$EDDB`, `$EE82`). After any disk call, `SEI` again if
|
|
112
|
+
the program runs with the KERNAL IRQ off: otherwise that IRQ lands inside
|
|
113
|
+
the meter's brackets and rewrites `$DC00`.
|
|
114
|
+
|
|
115
|
+
## Calling c64-kb
|
|
116
|
+
|
|
117
|
+
- CLI, from the c64-kb checkout (`C64KB` in `local.mk`):
|
|
118
|
+
`npx tsx src/cli.ts <command>`; `npx tsx src/cli.ts --help` lists them.
|
|
119
|
+
- MCP: `.mcp.json` starts `node <c64-kb>/dist/cli.js serve` (run
|
|
120
|
+
`npm run build` in c64-kb first).
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# action-puzzle: CAVE RUN, a Boulder Dash-style starter. Harness targets:
|
|
2
|
+
# make build build/action-puzzle.prg (after the PLAN.md gate)
|
|
3
|
+
# make run windowed VICE, joystick in port 2
|
|
4
|
+
# make shot headless PAL and NTSC exit screenshots of the autopilot build
|
|
5
|
+
# make check grade shots/pal.png and shots/ntsc.png against expect.json
|
|
6
|
+
# make selftest prove check fails on the FORCE_FAULT=1 build
|
|
7
|
+
# make disk build/action-puzzle.d64
|
|
8
|
+
# make claims c64-kb's claims-watch over the autopilot build, when available
|
|
9
|
+
# and this starter's own:
|
|
10
|
+
# make gen re-run tools/gen.py (caves, script, model, note table)
|
|
11
|
+
# make disktest the high-score save on a true-drive 1541: save, save over it, cold start, load
|
|
12
|
+
# make modelcheck every visible cave cell of the shots against tools/gen.py's model
|
|
13
|
+
# make joy the normal game reading its port byte from $02FE, for tools/drive.py
|
|
14
|
+
# make clean
|
|
15
|
+
NAME := action-puzzle
|
|
16
|
+
C_MAIN := src/main.c
|
|
17
|
+
|
|
18
|
+
# Pinned after the verdict, which follows the save and its read-back on the
|
|
19
|
+
# shot's fresh disk. Measured with VICE x64sc 3.10: at 18,000,000 cycles the
|
|
20
|
+
# save is still running on both models; at 20,000,000, 24,000,000 and
|
|
21
|
+
# 30,000,000 the picture is byte-identical, PAL and NTSC.
|
|
22
|
+
SHOT_CYCLES_PAL := 24000000
|
|
23
|
+
SHOT_CYCLES_NTSC := 24000000
|
|
24
|
+
|
|
25
|
+
# Every headless shot attaches its own fresh copy of the release D64 (the
|
|
26
|
+
# harness makes it), so the autopilot saves its table and reads it back.
|
|
27
|
+
SHOT_DISK := 1
|
|
28
|
+
|
|
29
|
+
# What the program may write, for make claims (claims-watch's grammar).
|
|
30
|
+
# zero_page $02-$52 is Oscar64's register block, as in hello; $53-$55 is the
|
|
31
|
+
# start of its BC_REG_TMP_SAVED block (MachineTypes.cpp), which this
|
|
32
|
+
# program's larger functions use (claims-watch found 902 stores there on
|
|
33
|
+
# the first run). --kernal names the routines hiscore.c calls through
|
|
34
|
+
# kernalio.h and the KERNAL IRQ, which runs during those calls only.
|
|
35
|
+
# vic_raster_irq: wait_frame sets the compare line and acknowledges the
|
|
36
|
+
# $D019 latch to count dropped frames; the interrupt itself stays disabled.
|
|
37
|
+
CLAIMS_ARGS := --cycles 24000000 --kernal SETLFS,SETNAM,OPEN,CLOSE,CHKIN,CHKOUT,CLRCHN,CHRIN,CHROUT,READST,IRQ --claim 'sid_voice_1, sid_voice_2, sid_voice_3, sid_filter_volume, cia1_port_a, cia1_timer_b, vic_raster_irq, zero_page $$02-$$55' --range 'screen=$$0400-$$07FF,colour=$$D800-$$DBFF,charset=$$2000-$$27FF,result=$$02FF' --harness 'cia2_timer_a, cia2_timer_b, cia2_tod'
|
|
38
|
+
|
|
39
|
+
# The harness sits beside the starter in c64-kb (../_harness) or is vendored
|
|
40
|
+
# into ./harness when the starter is copied out on its own.
|
|
41
|
+
# Proof targets `npm run verify:templates -- --selftest` runs after selftest.
|
|
42
|
+
VERIFY_TARGETS := disktest modelcheck selftest-scan
|
|
43
|
+
|
|
44
|
+
HARNESS ?= $(firstword $(wildcard harness) ../_harness)
|
|
45
|
+
$(if $(wildcard $(HARNESS)/harness.mk),,$(error No harness at '$(HARNESS)'. Copy c64-kb's templates/_harness to ./harness, or make the project with npm run new-project in c64-kb))
|
|
46
|
+
include $(HARNESS)/harness.mk
|
|
47
|
+
|
|
48
|
+
# ---- this starter's own targets ---------------------------------------------------
|
|
49
|
+
# tools/gen.py writes the three src/gen_*.h headers; an edit to it rebuilds them.
|
|
50
|
+
GEN_OUT := src/gen_caves.h src/gen_autopilot.h src/gen_notes.h
|
|
51
|
+
$(GEN_OUT): build/gen.stamp
|
|
52
|
+
build/gen.stamp: tools/gen.py
|
|
53
|
+
@mkdir -p build
|
|
54
|
+
$(PYTHON) tools/gen.py
|
|
55
|
+
@touch $@
|
|
56
|
+
|
|
57
|
+
.PHONY: gen disktest modelcheck
|
|
58
|
+
gen:
|
|
59
|
+
$(PYTHON) tools/gen.py
|
|
60
|
+
|
|
61
|
+
# The disk test, on a true-drive 1541 (DISK_MODEL=pal or ntsc):
|
|
62
|
+
# 1. the autopilot build runs against a fresh copy of the release D64: no
|
|
63
|
+
# file (62), it plays, saves (scratch, then write) and shows SAVED (00);
|
|
64
|
+
# 2. it runs again on the same D64: it loads that file, its score ties row 4
|
|
65
|
+
# and goes in row 5, and the save must replace the file (without the
|
|
66
|
+
# scratch the drive answers 63, FILE EXISTS). Its verdict is red by
|
|
67
|
+
# design: the table it started from is not the default one;
|
|
68
|
+
# 3. a cold VICE boots the release PRG from the D64 with LOAD"*",8,1; it
|
|
69
|
+
# loads the table and shows it on the title screen.
|
|
70
|
+
# tools/disk_check.py grades the three pictures, both files c1541 read back,
|
|
71
|
+
# and the directory (one HISCORE entry).
|
|
72
|
+
DISKTEST_D64 := build/disktest.d64
|
|
73
|
+
DISK_MODEL ?= pal
|
|
74
|
+
# PAL is the -default machine: "-model pal" selects a 6569R3 whose palette
|
|
75
|
+
# differs from the one check.py matches (border green read (94, 214, 56)).
|
|
76
|
+
DISK_VICE = $(TIMEOUT) $(VICE_TIMEOUT) $(X64SC) $(VICE_FLAGS) $(if $(filter ntsc,$(DISK_MODEL)),-model ntsc) -drive8type 1541 -drive8truedrive -drive8wobbleamplitude 0 -drive8wobblefrequency 0
|
|
77
|
+
# $(1) = the picture's name, $(2) = cycles, $(3) = what to autostart, $(4) = extra flags
|
|
78
|
+
define disk_run
|
|
79
|
+
@rm -f shots/$(1).png
|
|
80
|
+
@$(DISK_VICE) -limitcycles $(2) $(4) -exitscreenshot shots/$(1).png -autostart $(3) > shots/$(1).log 2>&1 || true
|
|
81
|
+
@test -s shots/$(1).png || { echo "disktest: no picture from the $(1) run; see shots/$(1).log"; exit 1; }
|
|
82
|
+
endef
|
|
83
|
+
disktest: $(D64) $(PRG_AUTO)
|
|
84
|
+
@mkdir -p shots
|
|
85
|
+
cp $(D64) $(DISKTEST_D64)
|
|
86
|
+
$(call disk_run,disk-save,30000000,$(PRG_AUTO),-8 $(DISKTEST_D64))
|
|
87
|
+
$(C1541) -attach $(DISKTEST_D64) -read "hiscore,s" build/hiscore-1.seq > /dev/null
|
|
88
|
+
$(call disk_run,disk-save2,30000000,$(PRG_AUTO),-8 $(DISKTEST_D64))
|
|
89
|
+
$(C1541) -attach $(DISKTEST_D64) -read "hiscore,s" build/hiscore-2.seq > /dev/null
|
|
90
|
+
$(C1541) -attach $(DISKTEST_D64) -list > build/disktest-dir.txt 2>/dev/null
|
|
91
|
+
$(call disk_run,disk-load,60000000,$(DISKTEST_D64),)
|
|
92
|
+
$(PYTHON) tools/disk_check.py $(HARNESS_DIR) build $(DISK_MODEL)
|
|
93
|
+
|
|
94
|
+
# The normal game with its port byte read from $02FE instead of $DC00, so a
|
|
95
|
+
# VICE monitor can drive it headless (tools/drive.py; README "Driving it headless").
|
|
96
|
+
.PHONY: joy
|
|
97
|
+
joy: build/$(NAME)-joy.prg
|
|
98
|
+
build/$(NAME)-joy.prg: $(C_DEPS) $(METER_DEPS) | plan-gate
|
|
99
|
+
@mkdir -p build
|
|
100
|
+
$(OSCAR64_BUILD) -dJOY_SOURCE=0x02fe -o=$@ $(C_MAIN)
|
|
101
|
+
|
|
102
|
+
# The scanned bit's self-test: the autopilot built with SCAN_FLAG=0 (the
|
|
103
|
+
# cave-scan recipe's double-move bug) must fail check.py and name E in its
|
|
104
|
+
# verdict, the test that the scan meets the living player once a cave frame.
|
|
105
|
+
PRG_NOSCAN := build/$(NAME)-noscan.prg
|
|
106
|
+
$(PRG_NOSCAN): $(C_DEPS) $(METER_DEPS) | plan-gate
|
|
107
|
+
@mkdir -p build
|
|
108
|
+
$(OSCAR64_BUILD) -d$(AUTOPILOT_DEFINE)=1 -dSCAN_FLAG=0 -o=$@ $(C_MAIN)
|
|
109
|
+
shots/noscan-pal.png: $(PRG_NOSCAN) $(PIN_PAL) $(SHOT_DEPS)
|
|
110
|
+
$(call vice_shot,$(PRG_NOSCAN),$(SHOT_CYCLES_PAL),,$@)
|
|
111
|
+
shots/noscan-ntsc.png: $(PRG_NOSCAN) $(PIN_NTSC) $(SHOT_DEPS)
|
|
112
|
+
$(call vice_shot,$(PRG_NOSCAN),$(SHOT_CYCLES_NTSC),-model ntsc,$@)
|
|
113
|
+
.PHONY: selftest-scan
|
|
114
|
+
selftest-scan:
|
|
115
|
+
@rm -f shots/noscan-pal.png shots/noscan-ntsc.png
|
|
116
|
+
@$(MAKE) --no-print-directory shots/noscan-pal.png shots/noscan-ntsc.png
|
|
117
|
+
@$(PYTHON) $(HARNESS_DIR)/check.py expect.json shots/noscan-pal.png shots/noscan-ntsc.png > shots/noscan-check.txt 2>&1; st=$$?; \
|
|
118
|
+
if [ $$st -ne 1 ]; then cat shots/noscan-check.txt; echo "selftest-scan: FAIL, check.py exit $$st on the SCAN_FLAG=0 build"; exit 1; fi
|
|
119
|
+
@$(PYTHON) tools/verdict_codes.py $(HARNESS_DIR) shots/noscan-pal.png pal E
|
|
120
|
+
@$(PYTHON) tools/verdict_codes.py $(HARNESS_DIR) shots/noscan-ntsc.png ntsc E
|
|
121
|
+
@echo "selftest-scan: PASS, the SCAN_FLAG=0 build failed, E among its letters"
|
|
122
|
+
|
|
123
|
+
# Every visible cave cell of both autopilot shots against tools/gen.py's model.
|
|
124
|
+
modelcheck: $(SHOTS)
|
|
125
|
+
$(PYTHON) tools/model_check.py $(HARNESS_DIR) shots/pal.png shots/ntsc.png
|
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
# Plan: action-puzzle
|
|
2
|
+
|
|
3
|
+
A Boulder Dash-style cave game, planned from the c64-kb tools on 2026-09-23
|
|
4
|
+
(c64-kb 0.14.0, the graph on this branch). The tool output is pasted whole.
|
|
5
|
+
|
|
6
|
+
## Concept
|
|
7
|
+
|
|
8
|
+
The player digs through earth in a 40 x 22 cave of one-character cells.
|
|
9
|
+
Boulders and gems fall and roll under a cave scan; two enemy kinds follow
|
|
10
|
+
walls. Collecting the cave's quota of gems opens the exit; walking into it
|
|
11
|
+
decodes the next cave from its RLE stream. A timer, a score and three lives;
|
|
12
|
+
at game over a new high score is entered by joystick and the five-row table
|
|
13
|
+
is saved to drive 8 and loaded back at start-up. An original tune plays
|
|
14
|
+
through the game, sound effects on their own voice. PAL and NTSC, the same
|
|
15
|
+
game logic on both (one cave frame every four display frames).
|
|
16
|
+
|
|
17
|
+
## Briefing
|
|
18
|
+
|
|
19
|
+
Command: `npx tsx src/cli.ts game-briefing "Boulder Dash-style cave game: dig earth, boulders and gems fall and roll under a cave scan, enemies follow walls, enough gems open the exit; RLE-compressed caves decoded between caves; timer, score, high-score table saved to disk" --archetype action-puzzle`
|
|
20
|
+
|
|
21
|
+
Kept from its 13 proposals: cave_scan_engine, high_score_table_insert,
|
|
22
|
+
raster_profile_bars (the harness meter is its CIA half).
|
|
23
|
+
|
|
24
|
+
Dropped, and why: text_mode_overlay_render (no moving overlay: every
|
|
25
|
+
object is a cell), directory_read_and_select (the file name is fixed),
|
|
26
|
+
irq_keyboard_own_scan and keyboard_matrix_scan (joystick only),
|
|
27
|
+
text_window_and_menu (one fixed table box, drawn directly),
|
|
28
|
+
actor_activation_window and nav_area_pathfinding (enemies are cells the scan
|
|
29
|
+
moves by local rules), two_word_parser (no text input),
|
|
30
|
+
drive_code_upload_and_job_queue (KERNAL file calls are enough for a small
|
|
31
|
+
file), jump_arc_table (no jumping).
|
|
32
|
+
|
|
33
|
+
Added, which the briefing did not propose: tile_map_render (its RLE row
|
|
34
|
+
stream is the cave format), charset_animation (gems, enemies and the open
|
|
35
|
+
exit animate by glyph), sid_play_routine_pattern and sfx_engine_beside_music
|
|
36
|
+
(tune and effects), kernal_file_read_seq, kernal_file_write_seq and
|
|
37
|
+
error_channel_check (the table on disk), frame_sync_loop, joystick_edge_detect.
|
|
38
|
+
|
|
39
|
+
The briefing listed 0 pitfalls; pitfalls-for on the techniques kept found
|
|
40
|
+
the ones in the table below.
|
|
41
|
+
|
|
42
|
+
## Techniques
|
|
43
|
+
|
|
44
|
+
| Technique | Why | Recipe it starts from | Pitfalls read (`pitfalls-for`) |
|
|
45
|
+
|---|---|---|---|
|
|
46
|
+
| cave_scan_engine | falling, rolling, digging, pushing, wall-following enemies, explosions; one scan per cave frame, split into four row slices, one a display frame | oscar64-cave-scan | pal_ntsc_tempo_mismatch |
|
|
47
|
+
| tile_map_render | caves stored as the RLE row stream (run `0x80+n`, literal count, `0` ends a row), decoded between caves | oscar64-level-rle-decoder, oscar64-tile-map-render | badline_cycle_loss, colour_ram_index_past_last_cell_hits_cia1, full_field_redraw_exceeds_vblank |
|
|
48
|
+
| charset_animation | gem sparkle, enemy spin and the open exit by rewriting glyph bytes in the RAM charset (method (a)) | oscar64-charset-animation | charset_blit_overruns_grown_code, vic_bank_visibility_collision, petscii_written_to_screen_ram |
|
|
49
|
+
| sid_play_routine_pattern | an original two-voice tune, one play call a frame | oscar64-sid-music-player | pal_ntsc_tempo_mismatch, sid_write_only_registers |
|
|
50
|
+
| sfx_engine_beside_music | table-driven effects with priorities on voice 3, after the tune's play call | oscar64-sfx-engine | sid_adsr_bug_8580, sid_voice3_disable_silent_bit |
|
|
51
|
+
| high_score_table_insert | a new score into the sorted five-row table; a tie goes below | kickassembler-high-score-insert, oscar64-high-score-persist | petscii_written_to_screen_ram |
|
|
52
|
+
| kernal_file_read_seq | load the table at start-up | oscar64-high-score-persist, oscar64-save-load-seq-file | first_open_after_reset_hangs_on_pal, kernal_assumes_sei_cleared, kernal_io_mapping_dependency, c1541_uppercase_filename_petscii_shift |
|
|
53
|
+
| kernal_file_write_seq | save it after a new entry: scratch, then write | oscar64-high-score-persist | krnio_save_leaves_splat_file, raster_irq_during_serial_io |
|
|
54
|
+
| error_channel_check | the drive's reply decides first run (62), loaded (00), no disk (74) | oscar64-high-score-persist | first_open_after_reset_hangs_on_pal |
|
|
55
|
+
| frame_sync_loop | one pass a frame, polled at raster line 250 | oscar64-frame-sync-loop, templates/hello | badline_cycle_loss, d012_wrap_around, raster_line_count_difference |
|
|
56
|
+
| joystick_edge_detect | fire and name entry act once per press | oscar64-headless-verify (the autopilot) | joystick2_scan_phantom_press, cia1_ddr_cleared_kills_keyboard |
|
|
57
|
+
| raster_profile_bars | the harness frame meter (CIA2 timer A) | oscar64-raster-profile-bars | badline_cycle_loss, vic_bus_takeover_on_dma |
|
|
58
|
+
|
|
59
|
+
## Compatibility
|
|
60
|
+
|
|
61
|
+
Command: `npx tsx src/cli.ts check-compatibility cave_scan_engine tile_map_render charset_animation sfx_engine_beside_music sid_play_routine_pattern high_score_table_insert kernal_file_write_seq kernal_file_read_seq error_channel_check frame_sync_loop joystick_edge_detect raster_profile_bars`
|
|
62
|
+
|
|
63
|
+
```text
|
|
64
|
+
# Compatibility: cave_scan_engine + tile_map_render + charset_animation + sfx_engine_beside_music + sid_play_routine_pattern + high_score_table_insert + kernal_file_write_seq + kernal_file_read_seq + error_channel_check + frame_sync_loop + joystick_edge_detect + raster_profile_bars
|
|
65
|
+
|
|
66
|
+
**Verdict:** WARNINGS
|
|
67
|
+
|
|
68
|
+
Checked with 1 implied prerequisite(s): sid_voice_setup.
|
|
69
|
+
|
|
70
|
+
Unit claims are stated for 3 of 12 techniques; a unit conflict cannot be ruled out for: cave_scan_engine, tile_map_render, charset_animation, high_score_table_insert, kernal_file_write_seq, kernal_file_read_seq, error_channel_check, frame_sync_loop, raster_profile_bars, sid_voice_setup (prerequisite). The zero-page bytes and interrupt vectors a recipe chooses are not checked yet (issue #22, step 8).
|
|
71
|
+
|
|
72
|
+
## unit_shared (soft): sfx_engine_beside_music × sid_play_routine_pattern
|
|
73
|
+
**Shared:** sid_voice_2
|
|
74
|
+
sid_play_routine_pattern owns sid_voice_2; sfx_engine_beside_music writes it under sid_play_routine_pattern's protocol.
|
|
75
|
+
**Resolution:** sfx_engine_beside_music must follow sid_play_routine_pattern's protocol: write after sid_play_routine_pattern's write in the frame, or run inside sid_play_routine_pattern's interrupt chain.
|
|
76
|
+
|
|
77
|
+
## shared_register (soft): sfx_engine_beside_music × sid_play_routine_pattern
|
|
78
|
+
**Shared:** SIGVOL, SUREL3, ATDCY3, VCREG3, PWHI3, PWLO3, FREHI3, FRELO3, SUREL2, ATDCY2, VCREG2, PWHI2, PWLO2, FREHI2, FRELO2, SUREL1, ATDCY1, VCREG1, PWHI1, PWLO1, FREHI1, FRELO1
|
|
79
|
+
Both techniques touch register(s) SIGVOL, SUREL3, ATDCY3, VCREG3, PWHI3, PWLO3, FREHI3, FRELO3, SUREL2, ATDCY2, VCREG2, PWHI2, PWLO2, FREHI2, FRELO2, SUREL1, ATDCY1, VCREG1, PWHI1, PWLO1, FREHI1, FRELO1. This says they write the same registers, not that they fight: keep each one's writes in its own raster region, or have one of them own the register and the other read a shadow copy.
|
|
80
|
+
|
|
81
|
+
## shared_kernal (soft): kernal_file_write_seq × kernal_file_read_seq
|
|
82
|
+
**Shared:** CLRCHN, CLOSE, OPEN, SETNAM, SETLFS
|
|
83
|
+
Both techniques call KERNAL routine(s) CLRCHN, CLOSE, OPEN, SETNAM, SETLFS. Concurrent use may clobber KERNAL state.
|
|
84
|
+
|
|
85
|
+
## shared_kernal (soft): kernal_file_write_seq × error_channel_check
|
|
86
|
+
**Shared:** CLRCHN, CLOSE, OPEN, SETNAM, SETLFS
|
|
87
|
+
Both techniques call KERNAL routine(s) CLRCHN, CLOSE, OPEN, SETNAM, SETLFS. Concurrent use may clobber KERNAL state.
|
|
88
|
+
|
|
89
|
+
## shared_kernal (soft): kernal_file_read_seq × error_channel_check
|
|
90
|
+
**Shared:** CHRIN, CLRCHN, CHKIN, CLOSE, OPEN, SETNAM, SETLFS, READST
|
|
91
|
+
Both techniques call KERNAL routine(s) CHRIN, CLRCHN, CHKIN, CLOSE, OPEN, SETNAM, SETLFS, READST. Concurrent use may clobber KERNAL state.
|
|
92
|
+
|
|
93
|
+
## shared_register (soft): frame_sync_loop × raster_profile_bars
|
|
94
|
+
**Shared:** EXTCOL
|
|
95
|
+
Both techniques touch register(s) EXTCOL. This says they write the same registers, not that they fight: keep each one's writes in its own raster region, or have one of them own the register and the other read a shadow copy.
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
## Not covered
|
|
99
|
+
- **cave_scan_engine**: the graph has no registers, KERNAL routines or demands for it; the verdict says nothing about it.
|
|
100
|
+
- **tile_map_render**: the graph has no registers, KERNAL routines or demands for it; the verdict says nothing about it.
|
|
101
|
+
- **high_score_table_insert**: the graph has no registers, KERNAL routines or demands for it; the verdict says nothing about it.
|
|
102
|
+
|
|
103
|
+
## Shared Infrastructure (info)
|
|
104
|
+
- **sid_voice_setup** (prerequisite, not in the set): required by sfx_engine_beside_music, sid_play_routine_pattern; included in the check as implied. Set it up first.
|
|
105
|
+
- **CHRIN** (KernalRoutine) shared via recipe(s): oscar64-platformer-scaffold, kickassembler-file-io-roundtrip, oscar64-save-load-seq-file, oscar64-directory-reader, oscar64-high-score-persist
|
|
106
|
+
- **CHROUT** (KernalRoutine) shared via recipe(s): oscar64-platformer-scaffold, kickassembler-file-io-roundtrip, oscar64-save-load-seq-file, oscar64-directory-reader, oscar64-high-score-persist
|
|
107
|
+
- **CLRCHN** (KernalRoutine) shared via recipe(s): oscar64-platformer-scaffold, kickassembler-file-io-roundtrip, oscar64-save-load-seq-file, oscar64-directory-reader, oscar64-high-score-persist
|
|
108
|
+
- **CHKOUT** (KernalRoutine) shared via recipe(s): oscar64-platformer-scaffold, kickassembler-file-io-roundtrip, oscar64-save-load-seq-file, oscar64-directory-reader, oscar64-high-score-persist
|
|
109
|
+
- **CHKIN** (KernalRoutine) shared via recipe(s): oscar64-platformer-scaffold, kickassembler-file-io-roundtrip, oscar64-save-load-seq-file, oscar64-directory-reader, oscar64-high-score-persist
|
|
110
|
+
- **SP6COL** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
111
|
+
- **SP5COL** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
112
|
+
- **SP4COL** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
113
|
+
- **SP3COL** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
114
|
+
- **SP2COL** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
115
|
+
- **SP1COL** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
116
|
+
- **CLOSE** (KernalRoutine) shared via recipe(s): oscar64-platformer-scaffold, kickassembler-file-io-roundtrip, oscar64-save-load-seq-file, oscar64-directory-reader, oscar64-high-score-persist
|
|
117
|
+
- **OPEN** (KernalRoutine) shared via recipe(s): oscar64-platformer-scaffold, kickassembler-file-io-roundtrip, oscar64-save-load-seq-file, oscar64-directory-reader, oscar64-high-score-persist
|
|
118
|
+
- **SETNAM** (KernalRoutine) shared via recipe(s): oscar64-platformer-scaffold, kickassembler-file-io-roundtrip, oscar64-save-load-seq-file, oscar64-directory-reader, oscar64-high-score-persist
|
|
119
|
+
- **SETLFS** (KernalRoutine) shared via recipe(s): oscar64-platformer-scaffold, kickassembler-file-io-roundtrip, oscar64-save-load-seq-file, oscar64-directory-reader, oscar64-high-score-persist
|
|
120
|
+
- **SP0COL** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
121
|
+
- **DC0F** (Register) shared via recipe(s): oscar64-platformer-scaffold, oscar64-cave-scan
|
|
122
|
+
- **DC07** (Register) shared via recipe(s): oscar64-platformer-scaffold, oscar64-cave-scan
|
|
123
|
+
- **DC06** (Register) shared via recipe(s): oscar64-platformer-scaffold, oscar64-cave-scan
|
|
124
|
+
- **DC03** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
125
|
+
- **BGCOL0** (Register) shared via recipe(s): oscar64-platformer-scaffold, oscar64-cave-scan, oscar64-falling-blocks
|
|
126
|
+
- **EXTCOL** (Register) shared via recipe(s): oscar64-platformer-scaffold, oscar64-cave-scan, oscar64-directory-reader, oscar64-falling-blocks
|
|
127
|
+
- **IRQMSK** (Register) shared via recipe(s): oscar64-platformer-scaffold, oscar64-cave-scan
|
|
128
|
+
- **VICIRQ** (Register) shared via recipe(s): oscar64-platformer-scaffold, oscar64-cave-scan
|
|
129
|
+
- **SPENA** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
130
|
+
- **RASTER** (Register) shared via recipe(s): oscar64-platformer-scaffold, oscar64-cave-scan, oscar64-directory-reader, oscar64-falling-blocks
|
|
131
|
+
- **SCROLY** (Register) shared via recipe(s): oscar64-platformer-scaffold, oscar64-falling-blocks
|
|
132
|
+
- **MSIGX** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
133
|
+
- **M0Y** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
134
|
+
- **M0X** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
135
|
+
- **RANDOM** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
136
|
+
- **SIGVOL** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
137
|
+
- **SUREL3** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
138
|
+
- **ATDCY3** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
139
|
+
- **VCREG3** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
140
|
+
- **PWHI3** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
141
|
+
- **PWLO3** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
142
|
+
- **FREHI3** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
143
|
+
- **FRELO3** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
144
|
+
- **SUREL2** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
145
|
+
- **ATDCY2** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
146
|
+
- **VCREG2** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
147
|
+
- **PWHI2** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
148
|
+
- **PWLO2** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
149
|
+
- **FREHI2** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
150
|
+
- **FRELO2** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
151
|
+
- **SUREL1** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
152
|
+
- **ATDCY1** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
153
|
+
- **VCREG1** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
154
|
+
- **PWHI1** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
155
|
+
- **PWLO1** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
156
|
+
- **FREHI1** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
157
|
+
- **FRELO1** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
158
|
+
- **DC02** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
159
|
+
- **DC00** (Register) shared via recipe(s): oscar64-platformer-scaffold, oscar64-directory-reader, oscar64-falling-blocks
|
|
160
|
+
- **READST** (KernalRoutine) shared via recipe(s): oscar64-platformer-scaffold, kickassembler-file-io-roundtrip, oscar64-save-load-seq-file, oscar64-directory-reader, oscar64-high-score-persist
|
|
161
|
+
- **DC0E** (Register) shared via recipe(s): oscar64-cave-scan, oscar64-falling-blocks
|
|
162
|
+
- **DC05** (Register) shared via recipe(s): oscar64-cave-scan, oscar64-falling-blocks
|
|
163
|
+
- **DC04** (Register) shared via recipe(s): oscar64-cave-scan, oscar64-falling-blocks
|
|
164
|
+
- **DD0F** (Register) shared via recipe(s): kickassembler-file-io-roundtrip, oscar64-save-load-seq-file, oscar64-directory-reader
|
|
165
|
+
- **DD0E** (Register) shared via recipe(s): kickassembler-file-io-roundtrip, oscar64-save-load-seq-file, oscar64-directory-reader
|
|
166
|
+
- **DD07** (Register) shared via recipe(s): kickassembler-file-io-roundtrip, oscar64-save-load-seq-file, oscar64-directory-reader
|
|
167
|
+
- **DD06** (Register) shared via recipe(s): kickassembler-file-io-roundtrip, oscar64-save-load-seq-file, oscar64-directory-reader
|
|
168
|
+
- **DD05** (Register) shared via recipe(s): kickassembler-file-io-roundtrip, oscar64-save-load-seq-file, oscar64-directory-reader
|
|
169
|
+
- **DD04** (Register) shared via recipe(s): kickassembler-file-io-roundtrip, oscar64-save-load-seq-file, oscar64-directory-reader
|
|
170
|
+
- **raster_discipline**: Multiple raster-discipline techniques present. Verify IRQ stack ordering and timing budget.
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
What the warnings mean for this program:
|
|
174
|
+
|
|
175
|
+
- sid_voice_2 unit and the shared SID registers (sfx x tune): the tune here
|
|
176
|
+
uses voices 1 and 2 only; effects own voice 3 and run after the play call
|
|
177
|
+
in the same frame, so the resolution the tool asks for holds by layout.
|
|
178
|
+
- Shared KERNAL routines between the three file techniques: they run one
|
|
179
|
+
after another on a static screen, never at once.
|
|
180
|
+
- EXTCOL (frame_sync_loop x raster_profile_bars): no border bars; only the
|
|
181
|
+
verdict writes `$D020`.
|
|
182
|
+
|
|
183
|
+
## Budget
|
|
184
|
+
|
|
185
|
+
Command: `npx tsx src/cli.ts plan-budget cave_scan_engine:play tile_map_render:transition charset_animation:play sfx_engine_beside_music:play sid_play_routine_pattern:play high_score_table_insert:transition kernal_file_write_seq:transition kernal_file_read_seq:init error_channel_check:transition frame_sync_loop:play joystick_edge_detect:play raster_profile_bars:play --region both --screen on`
|
|
186
|
+
|
|
187
|
+
```text
|
|
188
|
+
# Budget plan: undetermined
|
|
189
|
+
|
|
190
|
+
Techniques: cave_scan_engine, tile_map_render:transition, charset_animation, sfx_engine_beside_music, sid_play_routine_pattern, high_score_table_insert:transition, kernal_file_write_seq:transition, kernal_file_read_seq:init, error_channel_check:transition, frame_sync_loop, joystick_edge_detect, raster_profile_bars
|
|
191
|
+
|
|
192
|
+
## play (PAL, 19656 cycles a frame): undetermined
|
|
193
|
+
|
|
194
|
+
Range 19599-19807 + 1075 fixed cycles; floor 0; weakest basis measured-vice; IRQ slots 2.
|
|
195
|
+
|
|
196
|
+
Summed:
|
|
197
|
+
- cave_scan_engine: 18559 (measured-vice, on oscar64-cave-scan (one scan, run every fourth frame; slowest game-cave scan, NTSC, screen on))
|
|
198
|
+
- charset_animation: 196 (measured-vice, on oscar64-charset-animation (one glyph a frame, in the vertical blank))
|
|
199
|
+
- sfx_engine_beside_music: 50-258 (measured-vice, on oscar64-sfx-engine (a frame the engine owns the voice))
|
|
200
|
+
- sid_play_routine_pattern: 327 (measured-vice, on oscar64-sfx-engine (the recipe's stub tune; a real player costs several times more))
|
|
201
|
+
- raster_profile_bars: 467 (measured-vice, on oscar64-raster-profile-bars (worst frame, screen blanked))
|
|
202
|
+
|
|
203
|
+
To measure:
|
|
204
|
+
- frame_sync_loop: the Cost line has no cycles_per_frame (nor cycles_per_line with lines_active); measure it on oscar64-frame-sync-loop
|
|
205
|
+
- joystick_edge_detect: no **Cost:** line; measure it on oscar64-attract-replay
|
|
206
|
+
|
|
207
|
+
Notes:
|
|
208
|
+
- Fixed losses 1075 cycles (badlines 25 × 43 = 1075, lines 51-243 every eighth with YSCROLL 3; arithmetic) charged because charset_animation, sfx_engine_beside_music, sid_play_routine_pattern, raster_profile_bars are not stated as measured with the screen on. A stall takes its cycles wherever the code runs, so the charge is exact unless a figure already holds stalls: cave_scan_engine was measured with the screen on and already holds the stalls that fell inside it, so the charge is too high by that much and the over test counts 0.
|
|
209
|
+
- The low end, 19599 + 1075, passes the 19656-cycle frame, but it is not a floor: the figures of cave_scan_engine, charset_animation, sfx_engine_beside_music, sid_play_routine_pattern, raster_profile_bars are a common frame or a real run's worst, and those frames need not fall together. cave_scan_engine, charset_animation, sid_play_routine_pattern, raster_profile_bars have no typical frame, so their low end is a worst frame. The floor, work every frame plus the loss no figure can hold, is 0 and fits. A frame measured whole, with every member running, would settle it.
|
|
210
|
+
- Unknown is not zero: frame_sync_loop, joystick_edge_detect have no cycles figure, so the verdict cannot be fits.
|
|
211
|
+
|
|
212
|
+
## play (NTSC, 17095 cycles a frame): undetermined
|
|
213
|
+
|
|
214
|
+
Range 1040-1248 + 1075 fixed cycles; floor 1075; weakest basis measured-vice; IRQ slots 2.
|
|
215
|
+
|
|
216
|
+
Summed:
|
|
217
|
+
- charset_animation: 196 (measured-vice, on oscar64-charset-animation (one glyph a frame, in the vertical blank))
|
|
218
|
+
- sfx_engine_beside_music: 50-258 (measured-vice, on oscar64-sfx-engine (a frame the engine owns the voice))
|
|
219
|
+
- sid_play_routine_pattern: 327 (measured-vice, on oscar64-sfx-engine (the recipe's stub tune; a real player costs several times more))
|
|
220
|
+
- raster_profile_bars: 467 (measured-vice, on oscar64-raster-profile-bars (worst frame, screen blanked))
|
|
221
|
+
|
|
222
|
+
Left out:
|
|
223
|
+
- cave_scan_engine: 18559 cycles, above one frame: a multi-frame operation, not summed (measured on oscar64-cave-scan)
|
|
224
|
+
|
|
225
|
+
To measure:
|
|
226
|
+
- frame_sync_loop: the Cost line has no cycles_per_frame (nor cycles_per_line with lines_active); measure it on oscar64-frame-sync-loop
|
|
227
|
+
- joystick_edge_detect: no **Cost:** line; measure it on oscar64-attract-replay
|
|
228
|
+
|
|
229
|
+
Notes:
|
|
230
|
+
- Fixed losses 1075 cycles (badlines 25 × 43 = 1075, lines 51-243 every eighth with YSCROLL 3; arithmetic) charged because charset_animation, sfx_engine_beside_music, sid_play_routine_pattern, raster_profile_bars are not stated as measured with the screen on. A stall takes its cycles wherever the code runs, so the charge is exact: no summed figure already holds a stall.
|
|
231
|
+
- Unknown is not zero: frame_sync_loop, joystick_edge_detect have no cycles figure, so the verdict cannot be fits.
|
|
232
|
+
- Multi-frame: cave_scan_engine (18559) is above one NTSC frame of 17095 and not summed; spread the work over frames or budget it as its own phase.
|
|
233
|
+
- Cycles per frame are the pages' figures, most measured on PAL; the same code takes about the same cycles on NTSC, against a 17,095-cycle frame.
|
|
234
|
+
|
|
235
|
+
## transition (PAL, 19656 cycles a frame): undetermined
|
|
236
|
+
|
|
237
|
+
Range 749 + 1075 fixed cycles; floor 1075; weakest basis arithmetic; IRQ slots 0.
|
|
238
|
+
|
|
239
|
+
Summed:
|
|
240
|
+
- tile_map_render: 268 (arithmetic, on oscar64-tile-map-render (one column edge, 11 metatiles))
|
|
241
|
+
- high_score_table_insert: 481 (measured-vice, on kickassembler-high-score-insert (worst insert, once a round, screen blanked))
|
|
242
|
+
|
|
243
|
+
To measure:
|
|
244
|
+
- kernal_file_write_seq: no **Cost:** line; measure it on kickassembler-file-io-roundtrip
|
|
245
|
+
- error_channel_check: no **Cost:** line; measure it on kickassembler-dos-error-codes
|
|
246
|
+
|
|
247
|
+
Notes:
|
|
248
|
+
- Fixed losses 1075 cycles (badlines 25 × 43 = 1075, lines 51-243 every eighth with YSCROLL 3; arithmetic) charged because tile_map_render, high_score_table_insert are not stated as measured with the screen on. A stall takes its cycles wherever the code runs, so the charge is exact: no summed figure already holds a stall.
|
|
249
|
+
- Unknown is not zero: kernal_file_write_seq, error_channel_check have no cycles figure, so the verdict cannot be fits.
|
|
250
|
+
- The transition phase is judged against one frame too; a transition that takes several frames drops frames, which may be acceptable there.
|
|
251
|
+
|
|
252
|
+
## transition (NTSC, 17095 cycles a frame): undetermined
|
|
253
|
+
|
|
254
|
+
Range 749 + 1075 fixed cycles; floor 1075; weakest basis arithmetic; IRQ slots 0.
|
|
255
|
+
|
|
256
|
+
Summed:
|
|
257
|
+
- tile_map_render: 268 (arithmetic, on oscar64-tile-map-render (one column edge, 11 metatiles))
|
|
258
|
+
- high_score_table_insert: 481 (measured-vice, on kickassembler-high-score-insert (worst insert, once a round, screen blanked))
|
|
259
|
+
|
|
260
|
+
To measure:
|
|
261
|
+
- kernal_file_write_seq: no **Cost:** line; measure it on kickassembler-file-io-roundtrip
|
|
262
|
+
- error_channel_check: no **Cost:** line; measure it on kickassembler-dos-error-codes
|
|
263
|
+
|
|
264
|
+
Notes:
|
|
265
|
+
- Fixed losses 1075 cycles (badlines 25 × 43 = 1075, lines 51-243 every eighth with YSCROLL 3; arithmetic) charged because tile_map_render, high_score_table_insert are not stated as measured with the screen on. A stall takes its cycles wherever the code runs, so the charge is exact: no summed figure already holds a stall.
|
|
266
|
+
- Unknown is not zero: kernal_file_write_seq, error_channel_check have no cycles figure, so the verdict cannot be fits.
|
|
267
|
+
- The transition phase is judged against one frame too; a transition that takes several frames drops frames, which may be acceptable there.
|
|
268
|
+
- Cycles per frame are the pages' figures, most measured on PAL; the same code takes about the same cycles on NTSC, against a 17,095-cycle frame.
|
|
269
|
+
|
|
270
|
+
## init (PAL, 19656 cycles a frame): undetermined
|
|
271
|
+
|
|
272
|
+
Range 0 cycles; floor 0; weakest basis (nothing summed); IRQ slots 0.
|
|
273
|
+
|
|
274
|
+
To measure:
|
|
275
|
+
- kernal_file_read_seq: no **Cost:** line; measure it on kickassembler-file-io-roundtrip
|
|
276
|
+
|
|
277
|
+
Notes:
|
|
278
|
+
- Unknown is not zero: kernal_file_read_seq has no cycles figure, so the verdict cannot be fits.
|
|
279
|
+
- The init phase is judged against one frame too; an init that takes several frames drops frames, which may be acceptable there.
|
|
280
|
+
|
|
281
|
+
## init (NTSC, 17095 cycles a frame): undetermined
|
|
282
|
+
|
|
283
|
+
Range 0 cycles; floor 0; weakest basis (nothing summed); IRQ slots 0.
|
|
284
|
+
|
|
285
|
+
To measure:
|
|
286
|
+
- kernal_file_read_seq: no **Cost:** line; measure it on kickassembler-file-io-roundtrip
|
|
287
|
+
|
|
288
|
+
Notes:
|
|
289
|
+
- Unknown is not zero: kernal_file_read_seq has no cycles figure, so the verdict cannot be fits.
|
|
290
|
+
- The init phase is judged against one frame too; an init that takes several frames drops frames, which may be acceptable there.
|
|
291
|
+
- Cycles per frame are the pages' figures, most measured on PAL; the same code takes about the same cycles on NTSC, against a 17,095-cycle frame.
|
|
292
|
+
|
|
293
|
+
## Bytes
|
|
294
|
+
|
|
295
|
+
No member states a byte figure that can be summed.
|
|
296
|
+
- frame_sync_loop: 985 bytes left out, the whole program, not the technique
|
|
297
|
+
|
|
298
|
+
## Assumptions
|
|
299
|
+
|
|
300
|
+
- Region PAL and NTSC: PAL 19656, NTSC 17095 cycles a frame.
|
|
301
|
+
- Screen on: unless every summed figure says it was measured with the screen on, the 25 badlines × 43 cycles outside any band charge are charged.
|
|
302
|
+
- Low end: each member's cycles_per_frame_typical where the page states one (a common frame, or a real run's worst frame), else its worst frame. It is not a floor. Over is judged on the floor: band and per-line charges, which run every frame, plus the badline loss no summed figure can already hold.
|
|
303
|
+
- Each figure is the technique's own Cost line, measured on the recipe it names: another implementation can cost more or less.
|
|
304
|
+
- Claims, zero page and memory are not judged here; c64_check_compatibility judges claims and zero page.
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
The frame meter measures the real figure once the loop runs: worst, and
|
|
308
|
+
typical as the median of the autopilot's play frames. Both are recorded in
|
|
309
|
+
README.md with the model and the command.
|
|
310
|
+
|
|
311
|
+
What is unknown, and how the meter settles it: the tool sums a whole cave
|
|
312
|
+
scan (18,559 cycles, the recipe's slowest scan) into one PAL play frame and
|
|
313
|
+
drops it on NTSC as multi-frame. This program splits each scan into four
|
|
314
|
+
slices of five rows, one slice a display frame, so the play frame holds a
|
|
315
|
+
quarter scan plus the redraw of the cells it changed, the tune, the effects
|
|
316
|
+
and the glyph animation. The meter over the autopilot's play frames gives
|
|
317
|
+
the real worst and typical on both models. The RLE decode (the recipe's C
|
|
318
|
+
decoder: 28,193 to 50,447 cycles a room) is a transition on a static
|
|
319
|
+
screen; it is timed once with CIA1 timer B and printed, not metered.
|
|
320
|
+
|
|
321
|
+
## Memory and screen
|
|
322
|
+
|
|
323
|
+
- `$0801`-`$087F` Oscar64 start-up; code and data `$0880`-`$1FFF`, then
|
|
324
|
+
`$2800`-`$9FFF` for the rest (`#pragma region`, the split the
|
|
325
|
+
bitmap-koala-viewer recipe uses).
|
|
326
|
+
- `$2000`-`$27FF` the RAM character set: the ROM set copied at start-up
|
|
327
|
+
(text, digits and the meter's F, W, T keep their ROM glyphs), codes
|
|
328
|
+
`$40`-`$5F` replaced by the cave's glyphs. `$D018` = `$18`.
|
|
329
|
+
- Screen `$0400`: row 0 the HUD, rows 1-22 the cave (cell x, y at row
|
|
330
|
+
y + 1), row 23 messages, row 24 columns 0-19 the cave name; columns 20-39
|
|
331
|
+
belong to the meter in AUTOPILOT builds.
|
|
332
|
+
- No sprites, no raster IRQ. The KERNAL IRQ is off (`SEI`) except during
|
|
333
|
+
disk calls, and `SEI` again after each one.
|
|
334
|
+
- CIA2 timer A is the meter's; CIA1 timer B times the RLE decode once.
|
|
335
|
+
|
|
336
|
+
## Autopilot and checks
|
|
337
|
+
|
|
338
|
+
- The script is one string of moves per cave start (L U R D, `-` still),
|
|
339
|
+
keyed to the game's own counter of starts and held on the synthetic
|
|
340
|
+
joystick byte for the four display frames of each cave frame. Start 1
|
|
341
|
+
digs, pushes a boulder, collects cave 1's quota and enters the open exit;
|
|
342
|
+
starts 2 to 4 are cave 2 after each lost life, each ending under a falling
|
|
343
|
+
boulder, so the restart path runs twice and all three lives are played.
|
|
344
|
+
The script then enters a name; the table is saved to the shot's fresh D64
|
|
345
|
+
(`SHOT_DISK := 1`), read back and compared, and shown.
|
|
346
|
+
- `tools/gen.py` holds the caves, packs them, and runs a Python model of
|
|
347
|
+
the same rules over the same script. It writes `src/gen_caves.h` (the RLE
|
|
348
|
+
streams), `src/gen_autopilot.h` (the script and the model's expected
|
|
349
|
+
values) and `src/gen_notes.h` (the note tables).
|
|
350
|
+
- Verdict, after the table is shown, outside the meter, one letter per
|
|
351
|
+
failed test: the fold chained over every cave left, score, gems, cave,
|
|
352
|
+
play frames, cave starts, the table row, the decodes, the scan meeting the
|
|
353
|
+
player once a cave frame, the screen against the cave at every cave end,
|
|
354
|
+
dropped frames (the `$D019` raster latch), and the save's read-back.
|
|
355
|
+
`$02FF` and the border. A watchdog ends a game that runs past the model's
|
|
356
|
+
play frames.
|
|
357
|
+
- FORCE_FAULT flips a byte of the save as it is read back: the verdict turns
|
|
358
|
+
red and the table shows READ BACK BAD. `make selftest-scan` builds with
|
|
359
|
+
SCAN_FLAG=0 and must fail with E.
|
|
360
|
+
- expect.json: verdict, the HUD text, the table box text, cave cells the
|
|
361
|
+
model places, the `same` area over the cave, the meter with the recorded
|
|
362
|
+
frame count.
|
|
363
|
+
- A separate `make disktest` proves the save with true drive emulation: the
|
|
364
|
+
autopilot build writes the table to a fresh D64, then saves again over
|
|
365
|
+
it; a cold VICE boots the release PRG from that D64, which loads the
|
|
366
|
+
table and shows it.
|
|
367
|
+
|
|
368
|
+
## Decisions and open questions
|
|
369
|
+
|
|
370
|
+
- One cave frame every four display frames on both models, so the game is
|
|
371
|
+
the same on PAL and NTSC and one model run serves both; NTSC plays 20 %
|
|
372
|
+
faster in real time (pal_ntsc_tempo_mismatch). The time counter ticks every
|
|
373
|
+
12 cave frames. The tune's note lengths are in frames, so it plays 20 %
|
|
374
|
+
faster on NTSC too; the note frequencies come from a PAL or NTSC table.
|
|
375
|
+
- The meter records at most 255 frames; the script is kept to fit (240).
|
|
376
|
+
- Measured (make shot check, 2026-09-23): worst 13,619 / typical 6,529
|
|
377
|
+
cycles on PAL, 13,832 / 6,786 on NTSC; the worst is the slice where 16
|
|
378
|
+
boulders fall and overflow the dirty list. About 440 cycles a moving
|
|
379
|
+
object, so about 20 a slice fit NTSC. The overflow queues rows, redrawn
|
|
380
|
+
two a frame. A first build passed the cell
|
|
381
|
+
pointer to `cell()`; Oscar64 then computed it for every cell before the
|
|
382
|
+
test and the scan loop took 42 cycles a cell (typical frame 11,812).
|
|
383
|
+
Passing row and column made it 17 (counted from the generated code).
|
|
384
|
+
- Settled: first_open_after_reset_hangs_on_pal. `DISK_WAIT` waits 50 frames
|
|
385
|
+
before the first OPEN (main.c). `make disktest` ran on PAL and NTSC with a
|
|
386
|
+
true-drive 1541: the start-up read, two saves (the second replacing the
|
|
387
|
+
file) and a cold boot that loads it, all without a hang. It is a phase
|
|
388
|
+
effect, so any change to the code before the first OPEN needs that test again.
|