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,38 @@
|
|
|
1
|
+
# hello: the minimal starter. Every target comes from the harness:
|
|
2
|
+
# make build build/hello.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/hello.d64
|
|
8
|
+
# make claims c64-kb's claims-watch over the autopilot build, when available
|
|
9
|
+
# make clean
|
|
10
|
+
NAME := hello
|
|
11
|
+
C_MAIN := src/main.c
|
|
12
|
+
KICK_SRC := src/sprite.asm
|
|
13
|
+
|
|
14
|
+
# Pinned after the script's 144 play frames and the grade at frame 150. From
|
|
15
|
+
# then on nothing on the screen changes, so the pin can land anywhere in the
|
|
16
|
+
# frame: 7,000,000 and 8,000,000 cycles gave byte-identical PAL pictures,
|
|
17
|
+
# 8,000,000 and 12,000,000 identical NTSC ones (VICE x64sc 3.10, windowless).
|
|
18
|
+
SHOT_CYCLES_PAL := 8000000
|
|
19
|
+
SHOT_CYCLES_NTSC := 8000000
|
|
20
|
+
|
|
21
|
+
# What the program may write, for make claims (claims-watch's own grammar).
|
|
22
|
+
# zero_page $02-$55: Oscar64's fixed registers start at BC_REG_WORK_Y ($02)
|
|
23
|
+
# and each function's temporaries run from BC_REG_TMP ($43) up by its own
|
|
24
|
+
# temp count, past BC_REG_TMP_SAVED ($53), so the top depends on the program.
|
|
25
|
+
# Measured, not assumed: `make zp` lists what this build's code touches ($43
|
|
26
|
+
# to $55 here), and claims-watch saw stores to $53-$55. An earlier version
|
|
27
|
+
# claimed $02-$52 and failed make claims with 309 stores to $53-$55. IRQ is
|
|
28
|
+
# declared because the KERNAL's IRQ handler runs and writes its own zero page.
|
|
29
|
+
# The meter's one $DD0D store ($01: mask timer A only) is listed under
|
|
30
|
+
# cia2_timer_b and cia2_tod too, because claims-watch maps any $DD0D store
|
|
31
|
+
# to every CIA2 source; so all three are declared as harness.
|
|
32
|
+
CLAIMS_ARGS := --claim 'sprite_0, cia1_port_a, zero_page $$02-$$55' --kernal IRQ --range 'screen=$$0400-$$07FF,colour=$$D800-$$DBFF,spritedata=$$0340-$$037F,result=$$02FF' --harness 'cia2_timer_a, cia2_timer_b, cia2_tod'
|
|
33
|
+
|
|
34
|
+
# The harness sits beside the starter in c64-kb (../_harness) or is vendored
|
|
35
|
+
# into ./harness when the starter is copied out on its own.
|
|
36
|
+
HARNESS ?= $(firstword $(wildcard harness) ../_harness)
|
|
37
|
+
$(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))
|
|
38
|
+
include $(HARNESS)/harness.mk
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
# Plan: hello
|
|
2
|
+
|
|
3
|
+
The minimal starter. It exists to prove the harness end to end, so its plan
|
|
4
|
+
is small. The tool output below was produced on 2026-09-23 by c64-kb 0.13.0
|
|
5
|
+
(KB data 756) and pasted whole.
|
|
6
|
+
|
|
7
|
+
## Concept
|
|
8
|
+
|
|
9
|
+
One hardware sprite, moved by joystick port 2, fire toggles its colour. The
|
|
10
|
+
sprite registers are written by a KickAssembler routine that C calls, and the
|
|
11
|
+
frame's work is timed by the harness meter. PAL and NTSC.
|
|
12
|
+
|
|
13
|
+
## Briefing
|
|
14
|
+
|
|
15
|
+
No briefing was run for hello: its techniques were chosen to exercise the
|
|
16
|
+
harness, not proposed by a brief. A real starter runs
|
|
17
|
+
`npx tsx src/cli.ts game-briefing "<concept>" --archetype <name>` here.
|
|
18
|
+
|
|
19
|
+
## Techniques
|
|
20
|
+
|
|
21
|
+
| Technique | Why | Recipe it starts from | Pitfalls read (`pitfalls-for`) |
|
|
22
|
+
|---|---|---|---|
|
|
23
|
+
| frame_sync_loop | one pass of the loop a frame, synced on raster line 250 | oscar64-frame-sync-loop | badline_cycle_loss, d012_wrap_around, raster_line_count_difference, vic_colour_register_upper_nibble_reads_set, and the rest of its list |
|
|
24
|
+
| joystick_edge_detect | fire toggles the colour once per press, not once per frame | oscar64-joystick-input, oscar64-headless-verify (the autopilot) | cia1_ddr_cleared_kills_keyboard, colour_ram_index_past_last_cell_hits_cia1, joystick2_scan_phantom_press |
|
|
25
|
+
| raster_profile_bars | the frame meter is its CIA-timed half, on CIA2 timer A | oscar64-raster-profile-bars | badline_cycle_loss, vic_bus_takeover_on_dma, vic_colour_register_upper_nibble_reads_set |
|
|
26
|
+
|
|
27
|
+
## Compatibility
|
|
28
|
+
|
|
29
|
+
Command: `npx tsx src/cli.ts check-compatibility frame_sync_loop joystick_edge_detect raster_profile_bars`
|
|
30
|
+
|
|
31
|
+
```text
|
|
32
|
+
# Compatibility: frame_sync_loop + joystick_edge_detect + raster_profile_bars
|
|
33
|
+
|
|
34
|
+
**Verdict:** WARNINGS
|
|
35
|
+
|
|
36
|
+
Unit claims are stated for 1 of 3 techniques; a unit conflict cannot be ruled out for: frame_sync_loop, raster_profile_bars. The zero-page bytes and interrupt vectors a recipe chooses are not checked yet (issue #22, step 8).
|
|
37
|
+
|
|
38
|
+
## shared_register (soft): frame_sync_loop × raster_profile_bars
|
|
39
|
+
**Shared:** EXTCOL
|
|
40
|
+
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.
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
## Shared Infrastructure (info)
|
|
44
|
+
- **CLRCHN** (KernalRoutine) shared via recipe(s): oscar64-platformer-scaffold
|
|
45
|
+
- **CHKOUT** (KernalRoutine) shared via recipe(s): oscar64-platformer-scaffold
|
|
46
|
+
- **CHKIN** (KernalRoutine) shared via recipe(s): oscar64-platformer-scaffold
|
|
47
|
+
- **CLOSE** (KernalRoutine) shared via recipe(s): oscar64-platformer-scaffold
|
|
48
|
+
- **OPEN** (KernalRoutine) shared via recipe(s): oscar64-platformer-scaffold
|
|
49
|
+
- **SETNAM** (KernalRoutine) shared via recipe(s): oscar64-platformer-scaffold
|
|
50
|
+
- **SETLFS** (KernalRoutine) shared via recipe(s): oscar64-platformer-scaffold
|
|
51
|
+
- **DC0F** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
52
|
+
- **DC07** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
53
|
+
- **DC06** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
54
|
+
- **SP6COL** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
55
|
+
- **SP5COL** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
56
|
+
- **SP4COL** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
57
|
+
- **SP3COL** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
58
|
+
- **SP2COL** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
59
|
+
- **SP1COL** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
60
|
+
- **SP0COL** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
61
|
+
- **BGCOL0** (Register) shared via recipe(s): oscar64-platformer-scaffold, oscar64-falling-blocks
|
|
62
|
+
- **EXTCOL** (Register) shared via recipe(s): oscar64-platformer-scaffold, oscar64-falling-blocks
|
|
63
|
+
- **IRQMSK** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
64
|
+
- **VICIRQ** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
65
|
+
- **SPENA** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
66
|
+
- **RASTER** (Register) shared via recipe(s): oscar64-platformer-scaffold, oscar64-falling-blocks
|
|
67
|
+
- **SCROLY** (Register) shared via recipe(s): oscar64-platformer-scaffold, oscar64-falling-blocks
|
|
68
|
+
- **MSIGX** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
69
|
+
- **M0Y** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
70
|
+
- **M0X** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
71
|
+
- **RANDOM** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
72
|
+
- **SIGVOL** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
73
|
+
- **SUREL3** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
74
|
+
- **ATDCY3** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
75
|
+
- **VCREG3** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
76
|
+
- **PWHI3** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
77
|
+
- **PWLO3** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
78
|
+
- **FREHI3** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
79
|
+
- **FRELO3** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
80
|
+
- **SUREL2** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
81
|
+
- **ATDCY2** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
82
|
+
- **VCREG2** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
83
|
+
- **PWHI2** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
84
|
+
- **PWLO2** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
85
|
+
- **FREHI2** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
86
|
+
- **FRELO2** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
87
|
+
- **SUREL1** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
88
|
+
- **ATDCY1** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
89
|
+
- **VCREG1** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
90
|
+
- **DC03** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
91
|
+
- **DC02** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
92
|
+
- **PWHI1** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
93
|
+
- **PWLO1** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
94
|
+
- **FREHI1** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
95
|
+
- **FRELO1** (Register) shared via recipe(s): oscar64-platformer-scaffold
|
|
96
|
+
- **READST** (KernalRoutine) shared via recipe(s): oscar64-platformer-scaffold
|
|
97
|
+
- **DC00** (Register) shared via recipe(s): oscar64-platformer-scaffold, oscar64-falling-blocks
|
|
98
|
+
- **CHRIN** (KernalRoutine) shared via recipe(s): oscar64-platformer-scaffold
|
|
99
|
+
- **CHROUT** (KernalRoutine) shared via recipe(s): oscar64-platformer-scaffold
|
|
100
|
+
- **DC0E** (Register) shared via recipe(s): oscar64-falling-blocks
|
|
101
|
+
- **DC05** (Register) shared via recipe(s): oscar64-falling-blocks
|
|
102
|
+
- **DC04** (Register) shared via recipe(s): oscar64-falling-blocks
|
|
103
|
+
- **raster_discipline**: Multiple raster-discipline techniques present. Verify IRQ stack ordering and timing budget.
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
What the warnings mean for this program:
|
|
107
|
+
|
|
108
|
+
- EXTCOL shared by frame_sync_loop and raster_profile_bars: hello uses no
|
|
109
|
+
border bars; only the verdict writes `$D020`, once.
|
|
110
|
+
- The shared-infrastructure list comes from another recipe
|
|
111
|
+
(platformer-scaffold) that uses these techniques; hello calls no KERNAL
|
|
112
|
+
routine after `SEI`.
|
|
113
|
+
|
|
114
|
+
## Budget
|
|
115
|
+
|
|
116
|
+
Command: `npx tsx src/cli.ts plan-budget frame_sync_loop joystick_edge_detect raster_profile_bars --region both --sprites 1 --sprite-lines 21`
|
|
117
|
+
|
|
118
|
+
```text
|
|
119
|
+
# Budget plan: undetermined
|
|
120
|
+
|
|
121
|
+
Techniques: frame_sync_loop, joystick_edge_detect, raster_profile_bars
|
|
122
|
+
|
|
123
|
+
## play (PAL, 19656 cycles a frame): undetermined
|
|
124
|
+
|
|
125
|
+
Range 467 + 1180 fixed cycles; floor 1180; weakest basis measured-vice; IRQ slots 0.
|
|
126
|
+
|
|
127
|
+
Summed:
|
|
128
|
+
- raster_profile_bars: 467 (measured-vice, on oscar64-raster-profile-bars (worst frame, screen blanked))
|
|
129
|
+
|
|
130
|
+
To measure:
|
|
131
|
+
- 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
|
|
132
|
+
- joystick_edge_detect: no **Cost:** line; measure it on oscar64-attract-replay
|
|
133
|
+
|
|
134
|
+
Notes:
|
|
135
|
+
- Fixed losses 1180 cycles (badlines 25 × 43 = 1075, lines 51-243 every eighth with YSCROLL 3, sprite DMA 105; arithmetic) charged because raster_profile_bars is 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.
|
|
136
|
+
- Unknown is not zero: frame_sync_loop, joystick_edge_detect have no cycles figure, so the verdict cannot be fits.
|
|
137
|
+
|
|
138
|
+
## play (NTSC, 17095 cycles a frame): undetermined
|
|
139
|
+
|
|
140
|
+
Range 467 + 1180 fixed cycles; floor 1180; weakest basis measured-vice; IRQ slots 0.
|
|
141
|
+
|
|
142
|
+
Summed:
|
|
143
|
+
- raster_profile_bars: 467 (measured-vice, on oscar64-raster-profile-bars (worst frame, screen blanked))
|
|
144
|
+
|
|
145
|
+
To measure:
|
|
146
|
+
- 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
|
|
147
|
+
- joystick_edge_detect: no **Cost:** line; measure it on oscar64-attract-replay
|
|
148
|
+
|
|
149
|
+
Notes:
|
|
150
|
+
- Fixed losses 1180 cycles (badlines 25 × 43 = 1075, lines 51-243 every eighth with YSCROLL 3, sprite DMA 105; arithmetic) charged because raster_profile_bars is 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.
|
|
151
|
+
- Unknown is not zero: frame_sync_loop, joystick_edge_detect have no cycles figure, so the verdict cannot be fits.
|
|
152
|
+
- 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.
|
|
153
|
+
|
|
154
|
+
## Bytes
|
|
155
|
+
|
|
156
|
+
No member states a byte figure that can be summed.
|
|
157
|
+
- frame_sync_loop: 985 bytes left out, the whole program, not the technique
|
|
158
|
+
|
|
159
|
+
## Assumptions
|
|
160
|
+
|
|
161
|
+
- Region PAL and NTSC: PAL 19656, NTSC 17095 cycles a frame.
|
|
162
|
+
- 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.
|
|
163
|
+
- 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.
|
|
164
|
+
- Each figure is the technique's own Cost line, measured on the recipe it names: another implementation can cost more or less.
|
|
165
|
+
- Claims, zero page and memory are not judged here; c64_check_compatibility judges claims and zero page.
|
|
166
|
+
- Sprites: 1 a line on 21 lines, (3 + 2 × 1) × 21 = 105 cycles of DMA a frame (3 + 2n measured in VICE x64sc for sprites numbered without gaps).
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Measured by the meter (`make shot check`, VICE x64sc 3.10, the script's 144
|
|
170
|
+
play frames): worst 194 cycles, typical (the median) 172, the same on PAL and
|
|
171
|
+
NTSC. The bracket starts on raster line 250, below the last badline ($F7),
|
|
172
|
+
and the sprite is on lines 117 to 137, so no badline and no sprite DMA lands
|
|
173
|
+
in it; the plan's 1,180 fixed cycles are real but fall outside the bracket.
|
|
174
|
+
The grading at frame 150 runs after the bracket and is not in either figure.
|
|
175
|
+
|
|
176
|
+
## Memory and screen
|
|
177
|
+
|
|
178
|
+
- `$0340-$037E` sprite 0's image (block 13, the tape buffer).
|
|
179
|
+
- `$0801-$0880` Oscar64 startup; `$0900-$0FFF` the KickAssembler blob
|
|
180
|
+
(`src/sprite.asm`, 31 bytes now); `$1000` up, Oscar64's code, data and stack.
|
|
181
|
+
- `$0400` screen, power-on character set. Row 24, columns 20 to 39: the meter.
|
|
182
|
+
- `$02FF` the verdict byte. CIA2 timer A: the meter.
|
|
183
|
+
|
|
184
|
+
## Autopilot and checks
|
|
185
|
+
|
|
186
|
+
Script (frames, port byte): 64 right, 40 down, 16 fire, 24 up and right: 144
|
|
187
|
+
frames, every one playing, then idle. The meter records exactly those 144.
|
|
188
|
+
End state by arithmetic: sprite X 188, Y 116, cyan. Frame 150, after the
|
|
189
|
+
meter's bracket, reads the sprite registers back, stores the verdict at
|
|
190
|
+
`$02FF` and sets the border. FORCE_FAULT starts the sprite at X 101, so it
|
|
191
|
+
ends at 189: the verdict and the sprite checks fail together. `expect.json`
|
|
192
|
+
checks the border, the title and verdict text, the sprite's bounding box and
|
|
193
|
+
that it is solid, the pixel left of it, rows 0 to 23 identical on PAL and
|
|
194
|
+
NTSC, and the meter (144 frames recorded, worst within one frame).
|
|
195
|
+
|
|
196
|
+
## Decisions and open questions
|
|
197
|
+
|
|
198
|
+
- The KickAssembler routine takes its arguments in its own bytes
|
|
199
|
+
(`ASM_SPR_X`, `ASM_SPR_Y`), not Oscar64's zero page, which the compiler owns.
|
|
200
|
+
- `SEI` at start: no KERNAL interrupt lands inside the meter's bracket.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"checks": [
|
|
3
|
+
{ "name": "own verdict (border)", "type": "verdict" },
|
|
4
|
+
{ "name": "title", "type": "text", "row": 1, "col": 1, "text": "HELLO HARNESS" },
|
|
5
|
+
{ "name": "verdict line", "type": "text", "row": 22, "col": 1, "text": "RESULT 01 PASS" },
|
|
6
|
+
{
|
|
7
|
+
"name": "sprite where the script leaves it (X 188, Y 116: lines 117 to 137)",
|
|
8
|
+
"type": "sprite",
|
|
9
|
+
"colour": 3,
|
|
10
|
+
"vic_x": 188,
|
|
11
|
+
"line": 117,
|
|
12
|
+
"width": 24,
|
|
13
|
+
"height": 21
|
|
14
|
+
},
|
|
15
|
+
{ "name": "sprite solid", "type": "rect", "colour": 3, "vic_x": 188, "line": 117, "width": 24, "height": 21 },
|
|
16
|
+
{ "name": "left of the sprite", "type": "pixel", "vic_x": 187, "line": 117, "colour": 0 },
|
|
17
|
+
{ "name": "display the same on both models", "type": "same", "cells": [0, 0, 23, 39] },
|
|
18
|
+
{ "name": "frame meter, the script's 144 play frames", "type": "meter", "row": 24, "col": 20, "frames": 144 }
|
|
19
|
+
]
|
|
20
|
+
}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
// hello: the minimal starter. One sprite moved by joystick port 2 and placed
|
|
2
|
+
// by a KickAssembler routine called from C, with the frame meter around the
|
|
3
|
+
// frame's work. AUTOPILOT=1 replaces the port with a script and grades the
|
|
4
|
+
// end position; FORCE_FAULT=1 starts the sprite one pixel off, so both the
|
|
5
|
+
// program's own grade and the screenshot checks must fail.
|
|
6
|
+
#include <c64/vic.h>
|
|
7
|
+
#include <c64/cia.h>
|
|
8
|
+
#include "asm.h" // generated from src/sprite.asm by the harness
|
|
9
|
+
#include "frame_meter.h" // templates/_harness/meter
|
|
10
|
+
|
|
11
|
+
#ifndef AUTOPILOT
|
|
12
|
+
#define AUTOPILOT 0
|
|
13
|
+
#endif
|
|
14
|
+
#ifndef FORCE_FAULT
|
|
15
|
+
#define FORCE_FAULT 0
|
|
16
|
+
#endif
|
|
17
|
+
|
|
18
|
+
// ---- the KickAssembler blob at its own address ------------------------------
|
|
19
|
+
// ASM_ORG comes from the blob; main moves up to $1000 to leave it room. A blob
|
|
20
|
+
// that outgrows $1000 fails the link with "Could not place object"; one that
|
|
21
|
+
// starts below $0880, over Oscar64's startup code, stops at the #error that
|
|
22
|
+
// asm.h carries.
|
|
23
|
+
#pragma section( asmcode, 0 )
|
|
24
|
+
#pragma region( asmreg, ASM_ORG, 0x1000, , , { asmcode } )
|
|
25
|
+
#pragma region( main, 0x1000, 0xa000, , , { code, data, bss, heap, stack } )
|
|
26
|
+
#pragma data( asmcode )
|
|
27
|
+
__export const char asm_blob[] = {
|
|
28
|
+
#embed "asm.bin"
|
|
29
|
+
};
|
|
30
|
+
#pragma data( data )
|
|
31
|
+
|
|
32
|
+
#define SPR_X (*(volatile unsigned *)ASM_SPR_X) // parameters live in the blob
|
|
33
|
+
#define SPR_Y (*(volatile char *)ASM_SPR_Y)
|
|
34
|
+
|
|
35
|
+
#define SCREEN ((char *)0x0400)
|
|
36
|
+
#define COLOUR ((char *)0xd800)
|
|
37
|
+
#define SPRITE_BLOCK 13 // $0340, the tape buffer
|
|
38
|
+
#define RESULT (*(volatile char *)0x02ff) // $01 pass, $02 fail, $00 not reached
|
|
39
|
+
|
|
40
|
+
#define JOY_UP 0x01
|
|
41
|
+
#define JOY_DOWN 0x02
|
|
42
|
+
#define JOY_LEFT 0x04
|
|
43
|
+
#define JOY_RIGHT 0x08
|
|
44
|
+
#define JOY_FIRE 0x10
|
|
45
|
+
|
|
46
|
+
#define START_X (100 + FORCE_FAULT) // the fault build ends 1 pixel off
|
|
47
|
+
#define START_Y 100
|
|
48
|
+
#define PLAY_FRAMES 144 // the script's length; the meter records these
|
|
49
|
+
#define VERDICT_FRAME 150 // after the script
|
|
50
|
+
|
|
51
|
+
#if AUTOPILOT
|
|
52
|
+
// { frames, port byte }, active low as $DC00 reads it: right 64, down 40,
|
|
53
|
+
// fire 16 (one press: yellow to cyan), up and right 24. Every frame plays.
|
|
54
|
+
static const char script[4][2] = {
|
|
55
|
+
{ 64, 0xf7 }, { 40, 0xfd }, { 16, 0xef }, { 24, 0xf6 }
|
|
56
|
+
};
|
|
57
|
+
static char ap_index, ap_used;
|
|
58
|
+
// End state by arithmetic on the script: x 100 + 64 + 24, y 100 + 40 - 24.
|
|
59
|
+
#define EXPECT_X 188
|
|
60
|
+
#define EXPECT_Y 116
|
|
61
|
+
#define EXPECT_COLOUR VCOL_CYAN
|
|
62
|
+
|
|
63
|
+
static char port_read(void)
|
|
64
|
+
{
|
|
65
|
+
char out = 0xff;
|
|
66
|
+
if (ap_index < 4) {
|
|
67
|
+
out = script[ap_index][1];
|
|
68
|
+
if (++ap_used == script[ap_index][0]) { ap_used = 0; ap_index++; }
|
|
69
|
+
}
|
|
70
|
+
return out;
|
|
71
|
+
}
|
|
72
|
+
#else
|
|
73
|
+
static char port_read(void)
|
|
74
|
+
{
|
|
75
|
+
return cia1.pra; // control port 2, active low
|
|
76
|
+
}
|
|
77
|
+
#endif
|
|
78
|
+
|
|
79
|
+
static void put_text(char row, char col, const char *s, char colour)
|
|
80
|
+
{
|
|
81
|
+
char *p = SCREEN + 40 * row + col;
|
|
82
|
+
char *q = COLOUR + 40 * row + col;
|
|
83
|
+
while (*s) {
|
|
84
|
+
char c = *s++;
|
|
85
|
+
*p++ = (c >= 'a' && c <= 'z') ? c - 'a' + 1 : c;
|
|
86
|
+
*q++ = colour;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// frame_sync_loop: line 250 is below the last badline ($F7) on PAL and NTSC
|
|
91
|
+
// and occurs once a frame, so the 8-bit compare needs no ninth bit.
|
|
92
|
+
static void wait_frame(void)
|
|
93
|
+
{
|
|
94
|
+
while (vic.raster == 250) ;
|
|
95
|
+
while (vic.raster != 250) ;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
int main(void)
|
|
99
|
+
{
|
|
100
|
+
__asm { sei } // no KERNAL IRQ inside the meter's bracket
|
|
101
|
+
cia1.pra = 0xff; // no keyboard column selected
|
|
102
|
+
|
|
103
|
+
for (unsigned i = 0; i < 1000; i++) {
|
|
104
|
+
SCREEN[i] = 0x20;
|
|
105
|
+
COLOUR[i] = VCOL_WHITE;
|
|
106
|
+
}
|
|
107
|
+
vic.color_border = VCOL_BLACK;
|
|
108
|
+
vic.color_back = VCOL_BLACK;
|
|
109
|
+
put_text(1, 1, "hello harness", VCOL_WHITE);
|
|
110
|
+
|
|
111
|
+
char *img = (char *)(SPRITE_BLOCK * 64);
|
|
112
|
+
for (char i = 0; i < 63; i++)
|
|
113
|
+
img[i] = 0xff; // a solid 24 x 21 block
|
|
114
|
+
SCREEN[0x3f8] = SPRITE_BLOCK;
|
|
115
|
+
vic.spr_color[0] = VCOL_YELLOW;
|
|
116
|
+
vic.spr_enable = 0x01;
|
|
117
|
+
|
|
118
|
+
unsigned x = START_X;
|
|
119
|
+
char y = START_Y, colour = VCOL_YELLOW, prev = 0xff;
|
|
120
|
+
unsigned frame = 0;
|
|
121
|
+
|
|
122
|
+
meter_init(0x0400, 24, 20, VCOL_WHITE, PLAY_FRAMES);
|
|
123
|
+
|
|
124
|
+
for (;;) {
|
|
125
|
+
wait_frame();
|
|
126
|
+
METER_START;
|
|
127
|
+
|
|
128
|
+
char joy = port_read();
|
|
129
|
+
if (!(joy & JOY_LEFT) && x > 24) x--;
|
|
130
|
+
if (!(joy & JOY_RIGHT) && x < 320) x++;
|
|
131
|
+
if (!(joy & JOY_UP) && y > 50) y--;
|
|
132
|
+
if (!(joy & JOY_DOWN) && y < 229) y++;
|
|
133
|
+
if (!(joy & JOY_FIRE) && (prev & JOY_FIRE)) // a new press
|
|
134
|
+
colour = colour == VCOL_YELLOW ? VCOL_CYAN : VCOL_YELLOW;
|
|
135
|
+
prev = joy;
|
|
136
|
+
|
|
137
|
+
SPR_X = x;
|
|
138
|
+
SPR_Y = y;
|
|
139
|
+
__asm { jsr ASM_PUT_SPRITE } // the KickAssembler routine
|
|
140
|
+
vic.spr_color[0] = colour;
|
|
141
|
+
|
|
142
|
+
METER_STOP; // the frame's own work ends here
|
|
143
|
+
|
|
144
|
+
#if AUTOPILOT
|
|
145
|
+
// Grading is the harness's bookkeeping, not the program's work: it
|
|
146
|
+
// runs after METER_STOP, so it is not in the worst frame.
|
|
147
|
+
if (frame == VERDICT_FRAME) {
|
|
148
|
+
char ok = vic.spr_pos[0].x == (char)EXPECT_X
|
|
149
|
+
&& (*(volatile char *)0xd010 & 1) == (EXPECT_X >> 8)
|
|
150
|
+
&& vic.spr_pos[0].y == EXPECT_Y
|
|
151
|
+
&& (vic.spr_color[0] & 15) == EXPECT_COLOUR;
|
|
152
|
+
RESULT = ok ? 0x01 : 0x02;
|
|
153
|
+
vic.color_border = ok ? VCOL_GREEN : VCOL_RED;
|
|
154
|
+
put_text(22, 1, ok ? "result 01 pass" : "result 02 fail", VCOL_WHITE);
|
|
155
|
+
}
|
|
156
|
+
#endif
|
|
157
|
+
meter_print();
|
|
158
|
+
frame++;
|
|
159
|
+
}
|
|
160
|
+
return 0;
|
|
161
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// sprite.asm: the KickAssembler half of hello. The harness assembles it to
|
|
2
|
+
// build/asm.bin (raw bytes from $0900) and build/asm.h, which gives C
|
|
3
|
+
// ASM_ORG, ASM_END and ASM_<LABEL> for every top-level label below.
|
|
4
|
+
//
|
|
5
|
+
// Calling convention (this file's own, not Oscar64's): C writes the
|
|
6
|
+
// parameters into this blob's own bytes, then `jsr ASM_PUT_SPRITE` from an
|
|
7
|
+
// __asm block. The routine uses A and X and no zero page, so it cannot
|
|
8
|
+
// collide with Oscar64's registers.
|
|
9
|
+
|
|
10
|
+
* = $0900 "asm"
|
|
11
|
+
|
|
12
|
+
// Sprite 0 to (spr_x, spr_y). spr_x is 9-bit: its high byte sets bit 0 of $D010.
|
|
13
|
+
put_sprite:
|
|
14
|
+
lda spr_x
|
|
15
|
+
sta $d000
|
|
16
|
+
lda $d010
|
|
17
|
+
and #$fe
|
|
18
|
+
ldx spr_x+1
|
|
19
|
+
beq !+
|
|
20
|
+
ora #$01
|
|
21
|
+
!: sta $d010
|
|
22
|
+
lda spr_y
|
|
23
|
+
sta $d001
|
|
24
|
+
rts
|
|
25
|
+
|
|
26
|
+
spr_x: .word 0
|
|
27
|
+
spr_y: .byte 0
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/claude-code-settings.json",
|
|
3
|
+
"hooks": {
|
|
4
|
+
"PreToolUse": [
|
|
5
|
+
{
|
|
6
|
+
"matcher": "Edit|MultiEdit|Write|NotebookEdit",
|
|
7
|
+
"hooks": [
|
|
8
|
+
{
|
|
9
|
+
"type": "command",
|
|
10
|
+
"command": "h=\"$CLAUDE_PROJECT_DIR/harness/hooks/plan-gate.py\"; [ -f \"$h\" ] || h=\"$CLAUDE_PROJECT_DIR/../_harness/hooks/plan-gate.py\"; exec python3 \"$h\"",
|
|
11
|
+
"timeout": 10
|
|
12
|
+
}
|
|
13
|
+
]
|
|
14
|
+
}
|
|
15
|
+
]
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
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: hello-kick
|
|
15
|
+
|
|
16
|
+
hello in KickAssembler alone: `src/main.asm` runs the loop, moves sprite 0
|
|
17
|
+
and uses the meter's macros (`#import "frame_meter.asm"`). Start a pure
|
|
18
|
+
KickAssembler program from it with `npm run new-project -- hello-kick <dir>`
|
|
19
|
+
in c64-kb. `PLAN.md` here is a plan filled from real tool output;
|
|
20
|
+
new-project keeps it as `PLAN-hello-kick-example.md` and gives the new
|
|
21
|
+
program a blank one.
|
|
22
|
+
|
|
23
|
+
## Before any code
|
|
24
|
+
|
|
25
|
+
1. Brief: `npx tsx src/cli.ts game-briefing "<concept>" --archetype <name>`
|
|
26
|
+
(or `demo-briefing`), in the c64-kb checkout. Read what it proposes.
|
|
27
|
+
2. For each technique you keep: `technique-lookup <name>` and
|
|
28
|
+
`pitfalls-for <name>`. Start from the recipe it names (`recipe-lookup`).
|
|
29
|
+
3. Fill `PLAN.md`: paste the whole output of `check-compatibility` and of
|
|
30
|
+
`plan-budget` (same techniques) into their sections, list every technique
|
|
31
|
+
in its table, and replace every `FILL:` line.
|
|
32
|
+
|
|
33
|
+
Until `PLAN.md` passes, a hook blocks Edit and Write under `src/`, and every
|
|
34
|
+
make target that builds stops (`make plan-gate` says what is missing). With
|
|
35
|
+
C64KB set, `make` re-runs `check-compatibility` and wants the pasted Verdict.
|
|
36
|
+
The gate cannot see writes made through a shell command, or outputs edited
|
|
37
|
+
into shape by hand: do neither. `make PLAN_GATE=off` overrides it; say why in
|
|
38
|
+
`PLAN.md` if you do.
|
|
39
|
+
|
|
40
|
+
## The loop
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
make # build build/<name>.prg
|
|
44
|
+
make shot check # autopilot build, headless PAL and NTSC, graded by expect.json
|
|
45
|
+
make selftest # the FORCE_FAULT build must fail the same checks
|
|
46
|
+
make disk # build/<name>.d64
|
|
47
|
+
make claims # every store the program makes, against what it declares
|
|
48
|
+
make run # windowed VICE, for a human
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Rules
|
|
52
|
+
|
|
53
|
+
- Build before claiming. Code that has not built is not done.
|
|
54
|
+
- Measure screenshots with `check.py` through `expect.json`, never by eye.
|
|
55
|
+
Every visible claim gets a check. Add one before you trust a change.
|
|
56
|
+
- PAL and NTSC: both shots pass, or it is not done.
|
|
57
|
+
- Name the rung for every number: measured here (`make shot`, the meter, the
|
|
58
|
+
VICE monitor), taken from a c64-kb page (say which), arithmetic, or not
|
|
59
|
+
measured. Never call something verified that was not run.
|
|
60
|
+
- Frame cost comes from the meter: CIA2 timer A, printed as
|
|
61
|
+
`F<frames> W<worst> T<typical>` at row 24, columns 20 to 39, in AUTOPILOT
|
|
62
|
+
builds. It records the first `hold` frames: make that the autopilot
|
|
63
|
+
script's play frames. Typical is the median of those frames, the KB's
|
|
64
|
+
`cycles_per_frame_typical`. Keep grading, logging and printing outside the
|
|
65
|
+
bracket; work split between the main loop and IRQs is summed with
|
|
66
|
+
`METER_PAUSE` / `METER_START`.
|
|
67
|
+
- Do not invent a register, routine or address. Look it up:
|
|
68
|
+
`lookup-register`, `lookup-kernal`, `memory-map`.
|
|
69
|
+
- Lint every source you change: `npx tsx src/cli.ts lint <file>`.
|
|
70
|
+
- Commit named paths only. Never `git add -A` or `git add .`. `build/`,
|
|
71
|
+
`shots/` and `local.mk` are never committed.
|
|
72
|
+
|
|
73
|
+
## Harness facts you will need
|
|
74
|
+
|
|
75
|
+
- `AUTOPILOT=1` builds read a scripted joystick byte instead of `$DC00` and
|
|
76
|
+
grade themselves: `$02FF` = `$01` and a green border on pass, `$02` and red
|
|
77
|
+
on fail. `FORCE_FAULT=1` must turn the verdict red and move something a
|
|
78
|
+
screenshot check can see.
|
|
79
|
+
- Screenshot geometry (c64-kb `docs/runtime/vice-reference.md`): PAL 384 x 272,
|
|
80
|
+
row = raster line - 16; NTSC 384 x 247, row = line - 28; x = VIC X + 8. A
|
|
81
|
+
sprite at Y register y is drawn from line y + 1.
|
|
82
|
+
- `check.py` reads text in the ROM character set unless a check names a
|
|
83
|
+
`charset` file; the meter's cells need 0-9, F, W and T in the set on screen.
|
|
84
|
+
- A KickAssembler part called from C is a raw blob at its own `* =` address,
|
|
85
|
+
`$0880` or above; `build/asm.h` gives C its labels as `ASM_<LABEL>`
|
|
86
|
+
(`ASM_<SCOPE>_<LABEL>` inside a scope). Pass arguments through bytes in the
|
|
87
|
+
blob, not Oscar64's zero page (`$02` up; the top depends on the program:
|
|
88
|
+
`make zp` lists what the build's code touches).
|
|
89
|
+
- The meter takes CIA2 timer A. Do not open RS-232 (device 2) while it runs.
|
|
90
|
+
- The KERNAL serial routines end in `CLI` (ROM bytes `58 60` / `58 18` at
|
|
91
|
+
`$EDAB`, `$EDB5`, `$EDDB`, `$EE82`). After any disk call, `SEI` again if
|
|
92
|
+
the program runs with the KERNAL IRQ off: otherwise that IRQ lands inside
|
|
93
|
+
the meter's brackets and rewrites `$DC00`.
|
|
94
|
+
|
|
95
|
+
## Calling c64-kb
|
|
96
|
+
|
|
97
|
+
- CLI, from the c64-kb checkout (`C64KB` in `local.mk`):
|
|
98
|
+
`npx tsx src/cli.ts <command>`; `npx tsx src/cli.ts --help` lists them.
|
|
99
|
+
- MCP: `.mcp.json` starts `node <c64-kb>/dist/cli.js serve` (run
|
|
100
|
+
`npm run build` in c64-kb first).
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# hello-kick: hello in KickAssembler alone, on the same harness targets as
|
|
2
|
+
# hello (make, run, shot, check, selftest, disk, claims, clean).
|
|
3
|
+
NAME := hello-kick
|
|
4
|
+
KICK_SRC := src/main.asm
|
|
5
|
+
|
|
6
|
+
# Pinned as in hello: 7,000,000 and 8,000,000 cycles gave identical PAL
|
|
7
|
+
# pictures, 8,000,000 and 12,000,000 identical NTSC ones.
|
|
8
|
+
SHOT_CYCLES_PAL := 8000000
|
|
9
|
+
SHOT_CYCLES_NTSC := 8000000
|
|
10
|
+
|
|
11
|
+
# What the program may write, for make claims (claims-watch's own grammar).
|
|
12
|
+
# See hello's Makefile for why cia2_timer_b and cia2_tod are listed as harness.
|
|
13
|
+
CLAIMS_ARGS := --claim 'sprite_0, cia1_port_a' --range 'screen=$$0400-$$07FF,colour=$$D800-$$DBFF,spritedata=$$0340-$$037F,result=$$02FF' --harness 'cia2_timer_a, cia2_timer_b, cia2_tod'
|
|
14
|
+
|
|
15
|
+
HARNESS ?= $(firstword $(wildcard harness) ../_harness)
|
|
16
|
+
$(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))
|
|
17
|
+
include $(HARNESS)/harness.mk
|