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,562 @@
|
|
|
1
|
+
---
|
|
2
|
+
recipe: nmi-timer-tick
|
|
3
|
+
toolchain: kickassembler
|
|
4
|
+
output_format: PRG
|
|
5
|
+
region: both
|
|
6
|
+
techniques: [nmi_handler_and_restore_key]
|
|
7
|
+
file_formats: [PRG]
|
|
8
|
+
uses_registers: [D011, D020, DC04, DC05, DC06, DC07, DC0D, DC0E, DC0F, DD04, DD05, DD0D, DD0E]
|
|
9
|
+
uses_kernal: []
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
<!-- doc-type: recipe -->
|
|
13
|
+
|
|
14
|
+
# KickAssembler — NMI Handler Driven by a CIA2 Timer Tick
|
|
15
|
+
|
|
16
|
+
## Synopsis
|
|
17
|
+
|
|
18
|
+
Installs an NMI handler through the `$0318` vector and drives it from
|
|
19
|
+
CIA2 Timer A at a period of 10,000 cycles. The timer stands in for the
|
|
20
|
+
RESTORE key: a headless VICE run cannot press RESTORE, and the key was
|
|
21
|
+
not pressed in this run. The program measures three windows of 1,005,000
|
|
22
|
+
cycles on CIA1 and counts the NMIs taken in each: a handler that reads
|
|
23
|
+
`$DD0D` takes 100, a handler that never reads it takes 1 and then locks
|
|
24
|
+
`/NMI` low, and one `LDA $DD0D` from the main loop re-arms the edge for
|
|
25
|
+
exactly one more. It then measures the cost of a bare `RTI` stub and of
|
|
26
|
+
the count-and-acknowledge handler, and leaves the tick running with a
|
|
27
|
+
live count on screen, so the picture shows the main program still going
|
|
28
|
+
under a stream of NMIs. This is the `nmi_handler_and_restore_key`
|
|
29
|
+
technique; use it when a program needs RESTORE disarmed, a timer tick
|
|
30
|
+
that does not depend on the raster, or an NMI-driven sample player.
|
|
31
|
+
|
|
32
|
+
Verified in VICE x64sc 3.10 on both models: the counts, the two costs
|
|
33
|
+
and the verdict are identical on PAL and NTSC; the poll and live-tick
|
|
34
|
+
figures differ by model, as the "Expected output" section explains.
|
|
35
|
+
|
|
36
|
+
## Source
|
|
37
|
+
|
|
38
|
+
```asm
|
|
39
|
+
// nmi-timer-tick.asm
|
|
40
|
+
// Installs an NMI handler through $0318 and drives it from CIA2 Timer A,
|
|
41
|
+
// which stands in for the RESTORE key (a headless VICE run cannot press
|
|
42
|
+
// RESTORE; the key was not pressed in this run). Three windows of
|
|
43
|
+
// 1,005,000 phi2 cycles, each timed by CIA1 Timer A (period 10,050) with
|
|
44
|
+
// Timer B counting its underflows:
|
|
45
|
+
// ACK : handler counts and reads $DD0D; tick every 10,000 cycles;
|
|
46
|
+
// expect 100 NMIs while the main loop keeps polling.
|
|
47
|
+
// LOCK : same tick, handler never reads $DD0D; expect 1 NMI (/NMI
|
|
48
|
+
// stays low, the 6510 takes NMI on the falling edge only).
|
|
49
|
+
// READ : one LDA $DD0D from the main loop re-arms the edge; expect 1.
|
|
50
|
+
// Then the cost of a handler, measured as CIA1 Timer A across a block of
|
|
51
|
+
// 200 NOPs with a one-shot NMI inside it minus the same block with the
|
|
52
|
+
// NMI masked: the bare RTI stub and the count-and-acknowledge handler.
|
|
53
|
+
// Finally a live tick: the handler counts for ever and the main loop
|
|
54
|
+
// prints the count, so the picture shows the program still running.
|
|
55
|
+
// Verdict: $02FF = $01 and a green border when the three windows give
|
|
56
|
+
// 100, 1 and 1; $02FF = $02 and a red border otherwise.
|
|
57
|
+
|
|
58
|
+
BasicUpstart2(start)
|
|
59
|
+
.encoding "screencode_upper"
|
|
60
|
+
|
|
61
|
+
.const SCREEN = $0400
|
|
62
|
+
.const RESULT = $02ff // verdict byte read by the harness
|
|
63
|
+
.const BORDER = $d020
|
|
64
|
+
.const CODE_PASS = $01
|
|
65
|
+
.const CODE_FAIL = $02
|
|
66
|
+
.const GREEN = $05
|
|
67
|
+
.const RED = $02
|
|
68
|
+
.const NMIVEC = $0318
|
|
69
|
+
|
|
70
|
+
.const TICK = 10000 // CIA2 Timer A period in cycles (latch + 1)
|
|
71
|
+
.const WIN_PERIOD = 10050 // CIA1 Timer A period in cycles
|
|
72
|
+
.const WIN_COUNT = 100 // Timer B underflows per window
|
|
73
|
+
// window = 100 * 10,050 = 1,005,000 cycles
|
|
74
|
+
.const WIN_TB = $ffff - WIN_COUNT // Timer B value at the window's end
|
|
75
|
+
|
|
76
|
+
.const dst = $fb // zero-page pointer: screen destination
|
|
77
|
+
.const src = $fd // zero-page pointer: text source
|
|
78
|
+
.const num = $02 // 16-bit value for putdec
|
|
79
|
+
.const tmp = $04
|
|
80
|
+
.const digit = $05
|
|
81
|
+
|
|
82
|
+
// Puts(row, col, label): copy a screen-code string ($ff-terminated)
|
|
83
|
+
.macro Puts(row, col, label) {
|
|
84
|
+
lda #<(SCREEN + row * 40 + col)
|
|
85
|
+
sta dst
|
|
86
|
+
lda #>(SCREEN + row * 40 + col)
|
|
87
|
+
sta dst + 1
|
|
88
|
+
lda #<label
|
|
89
|
+
sta src
|
|
90
|
+
lda #>label
|
|
91
|
+
sta src + 1
|
|
92
|
+
jsr puts
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Dec(row, col, lo, hi): print the 16-bit value at lo/hi as five digits
|
|
96
|
+
.macro Dec(row, col, lo, hi) {
|
|
97
|
+
lda #<(SCREEN + row * 40 + col)
|
|
98
|
+
sta dst
|
|
99
|
+
lda #>(SCREEN + row * 40 + col)
|
|
100
|
+
sta dst + 1
|
|
101
|
+
lda lo
|
|
102
|
+
sta num
|
|
103
|
+
lda hi
|
|
104
|
+
sta num + 1
|
|
105
|
+
jsr putdec
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Vector(handler): point $0318 at handler
|
|
109
|
+
.macro Vector(handler) {
|
|
110
|
+
lda #<handler
|
|
111
|
+
sta NMIVEC
|
|
112
|
+
lda #>handler
|
|
113
|
+
sta NMIVEC + 1
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Quiet(): mask every CIA2 source and drop a pending flag
|
|
117
|
+
.macro Quiet() {
|
|
118
|
+
lda #$00
|
|
119
|
+
sta $dd0e // stop Timer A
|
|
120
|
+
lda #$7f
|
|
121
|
+
sta $dd0d
|
|
122
|
+
lda $dd0d
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Window(): run one 1,005,000-cycle window on CIA1 while polling; count
|
|
126
|
+
// the polls in polls/polls+1
|
|
127
|
+
.macro Window() {
|
|
128
|
+
lda #$00
|
|
129
|
+
sta polls
|
|
130
|
+
sta polls + 1
|
|
131
|
+
lda #$51 // CRB: start, force load, count A underflows
|
|
132
|
+
sta $dc0f
|
|
133
|
+
lda #$11 // CRA: start, force load, count phi2
|
|
134
|
+
sta $dc0e
|
|
135
|
+
!: inc polls
|
|
136
|
+
bne !+
|
|
137
|
+
inc polls + 1
|
|
138
|
+
!: lda $dc06 // Timer B low byte
|
|
139
|
+
cmp #<WIN_TB
|
|
140
|
+
bne !--
|
|
141
|
+
lda #$00
|
|
142
|
+
sta $dc0e // stop both CIA1 timers
|
|
143
|
+
sta $dc0f
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Tick(): arm CIA2 Timer A as a continuous NMI source, period TICK
|
|
147
|
+
.macro Tick() {
|
|
148
|
+
lda #<(TICK - 1)
|
|
149
|
+
sta $dd04
|
|
150
|
+
lda #>(TICK - 1)
|
|
151
|
+
sta $dd05
|
|
152
|
+
lda #$81 // set Timer A -> /NMI
|
|
153
|
+
sta $dd0d
|
|
154
|
+
lda #$11 // CRA: start, force load, continuous
|
|
155
|
+
sta $dd0e
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Cost(slot): CIA1 Timer A across 200 NOPs (400 cycles) with a CIA2
|
|
159
|
+
// one-shot NMI armed to land inside the block; leaves $FFFF - reading
|
|
160
|
+
// in slot/slot+1
|
|
161
|
+
.macro Cost(slot) {
|
|
162
|
+
lda #100
|
|
163
|
+
sta $dd04
|
|
164
|
+
lda #$00
|
|
165
|
+
sta $dd05 // Timer A latch 100: underflow ~101 cycles in
|
|
166
|
+
lda #$19 // CRA: start, force load, one-shot
|
|
167
|
+
sta $dd0e
|
|
168
|
+
lda #$11
|
|
169
|
+
sta $dc0e // CIA1 Timer A from $FFFF, counting phi2
|
|
170
|
+
.fill 200, $ea // 200 x NOP = 400 cycles
|
|
171
|
+
lda #$00
|
|
172
|
+
sta $dc0e
|
|
173
|
+
sec
|
|
174
|
+
lda #$ff
|
|
175
|
+
sbc $dc04
|
|
176
|
+
sta slot
|
|
177
|
+
lda #$ff
|
|
178
|
+
sbc $dc05
|
|
179
|
+
sta slot + 1
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
start:
|
|
183
|
+
sei
|
|
184
|
+
lda #$7f // CIA1: no IRQ sources, flags dropped
|
|
185
|
+
sta $dc0d
|
|
186
|
+
lda $dc0d
|
|
187
|
+
lda #$00
|
|
188
|
+
sta $dc0e
|
|
189
|
+
sta $dc0f
|
|
190
|
+
lda #<(WIN_PERIOD - 1)
|
|
191
|
+
sta $dc04
|
|
192
|
+
lda #>(WIN_PERIOD - 1)
|
|
193
|
+
sta $dc05
|
|
194
|
+
lda #$ff
|
|
195
|
+
sta $dc06
|
|
196
|
+
sta $dc07
|
|
197
|
+
Quiet()
|
|
198
|
+
|
|
199
|
+
ldx #$00 // clear the screen
|
|
200
|
+
lda #$20
|
|
201
|
+
!: sta SCREEN, x
|
|
202
|
+
sta SCREEN + $100, x
|
|
203
|
+
sta SCREEN + $200, x
|
|
204
|
+
sta SCREEN + $300, x
|
|
205
|
+
inx
|
|
206
|
+
bne !-
|
|
207
|
+
|
|
208
|
+
Puts(0, 0, t_title)
|
|
209
|
+
Puts(2, 0, t_tick)
|
|
210
|
+
Puts(3, 0, t_ack)
|
|
211
|
+
Puts(4, 0, t_lock)
|
|
212
|
+
Puts(5, 0, t_read)
|
|
213
|
+
Puts(6, 0, t_polls)
|
|
214
|
+
Puts(8, 0, t_cost)
|
|
215
|
+
Puts(10, 0, t_live)
|
|
216
|
+
Puts(12, 0, t_note1)
|
|
217
|
+
Puts(13, 0, t_note2)
|
|
218
|
+
|
|
219
|
+
// ACK: count-and-acknowledge handler, 100 ticks in the window
|
|
220
|
+
lda #$00
|
|
221
|
+
sta count
|
|
222
|
+
Vector(nmi_ack)
|
|
223
|
+
Tick()
|
|
224
|
+
Window()
|
|
225
|
+
lda count
|
|
226
|
+
sta ack_n
|
|
227
|
+
Quiet()
|
|
228
|
+
Dec(3, 10, ack_n, zero)
|
|
229
|
+
Dec(6, 11, polls, polls + 1)
|
|
230
|
+
|
|
231
|
+
// LOCK: handler never reads $DD0D, so the first tick locks /NMI low
|
|
232
|
+
lda #$00
|
|
233
|
+
sta count
|
|
234
|
+
Vector(nmi_lock)
|
|
235
|
+
Tick()
|
|
236
|
+
Window()
|
|
237
|
+
lda count
|
|
238
|
+
sta lock_n
|
|
239
|
+
Dec(4, 10, lock_n, zero)
|
|
240
|
+
|
|
241
|
+
// READ: one read from the main loop re-arms the edge; the timer is
|
|
242
|
+
// still running and the handler still never acknowledges
|
|
243
|
+
lda #$00
|
|
244
|
+
sta count
|
|
245
|
+
lda $dd0d // the unlock
|
|
246
|
+
Window()
|
|
247
|
+
lda count
|
|
248
|
+
sta read_n
|
|
249
|
+
Quiet()
|
|
250
|
+
Dec(5, 10, read_n, zero)
|
|
251
|
+
|
|
252
|
+
// Costs: control (NMI masked), bare RTI stub, count-and-acknowledge.
|
|
253
|
+
// Screen off first, so no badline steals cycles inside a block; DEN
|
|
254
|
+
// is sampled on line $30, so wait for the next frame before timing.
|
|
255
|
+
lda $d011
|
|
256
|
+
and #$ef
|
|
257
|
+
sta $d011
|
|
258
|
+
!: lda $d011 // wait until raster line >= 256
|
|
259
|
+
bpl !-
|
|
260
|
+
!: lda $d011 // then until it wraps to line 0
|
|
261
|
+
bmi !-
|
|
262
|
+
Cost(c_ctrl) // CIA2 NMI still masked: control run
|
|
263
|
+
Quiet()
|
|
264
|
+
Vector(nmi_stub)
|
|
265
|
+
lda #$81
|
|
266
|
+
sta $dd0d
|
|
267
|
+
Cost(c_stub)
|
|
268
|
+
Quiet() // the stub left /NMI low; this read frees it
|
|
269
|
+
Vector(nmi_ack)
|
|
270
|
+
lda #$81
|
|
271
|
+
sta $dd0d
|
|
272
|
+
Cost(c_ack)
|
|
273
|
+
Quiet()
|
|
274
|
+
lda $d011
|
|
275
|
+
ora #$10
|
|
276
|
+
sta $d011 // screen back on
|
|
277
|
+
sec // stub cost = stub reading - control
|
|
278
|
+
lda c_stub
|
|
279
|
+
sbc c_ctrl
|
|
280
|
+
sta c_stub
|
|
281
|
+
lda c_stub + 1
|
|
282
|
+
sbc c_ctrl + 1
|
|
283
|
+
sta c_stub + 1
|
|
284
|
+
sec
|
|
285
|
+
lda c_ack
|
|
286
|
+
sbc c_ctrl
|
|
287
|
+
sta c_ack
|
|
288
|
+
lda c_ack + 1
|
|
289
|
+
sbc c_ctrl + 1
|
|
290
|
+
sta c_ack + 1
|
|
291
|
+
Dec(8, 5, c_stub, c_stub + 1)
|
|
292
|
+
Dec(8, 15, c_ack, c_ack + 1)
|
|
293
|
+
|
|
294
|
+
// Verdict
|
|
295
|
+
ldx #CODE_PASS
|
|
296
|
+
ldy #GREEN
|
|
297
|
+
lda ack_n
|
|
298
|
+
cmp #100
|
|
299
|
+
bne fail
|
|
300
|
+
lda lock_n
|
|
301
|
+
cmp #1
|
|
302
|
+
bne fail
|
|
303
|
+
lda read_n
|
|
304
|
+
cmp #1
|
|
305
|
+
beq verdict
|
|
306
|
+
fail:
|
|
307
|
+
ldx #CODE_FAIL
|
|
308
|
+
ldy #RED
|
|
309
|
+
verdict:
|
|
310
|
+
stx RESULT
|
|
311
|
+
sty BORDER
|
|
312
|
+
txa
|
|
313
|
+
cmp #CODE_PASS
|
|
314
|
+
bne !+
|
|
315
|
+
Puts(3, 30, t_pass)
|
|
316
|
+
Puts(4, 30, t_pass)
|
|
317
|
+
Puts(5, 30, t_pass)
|
|
318
|
+
jmp live
|
|
319
|
+
!: Puts(3, 30, t_fail)
|
|
320
|
+
Puts(4, 30, t_fail)
|
|
321
|
+
Puts(5, 30, t_fail)
|
|
322
|
+
|
|
323
|
+
// Live tick: the handler counts for ever, the main loop prints
|
|
324
|
+
live:
|
|
325
|
+
lda #$00
|
|
326
|
+
sta live_n
|
|
327
|
+
sta live_n + 1
|
|
328
|
+
Vector(nmi_live)
|
|
329
|
+
Tick()
|
|
330
|
+
!: Dec(10, 5, live_n, live_n + 1)
|
|
331
|
+
jmp !-
|
|
332
|
+
|
|
333
|
+
// --- NMI handlers. $FE43 runs SEI then JMP ($0318); nothing is pushed
|
|
334
|
+
// before the vector, so a handler that touches no register needs no
|
|
335
|
+
// saves and a bare RTI is a complete handler. BIT reads $DD0D without
|
|
336
|
+
// disturbing A, X or Y; RTI puts P back.
|
|
337
|
+
|
|
338
|
+
nmi_stub:
|
|
339
|
+
rti // disarms RESTORE; does not acknowledge CIA2
|
|
340
|
+
|
|
341
|
+
nmi_ack:
|
|
342
|
+
inc count
|
|
343
|
+
bit $dd0d // acknowledge: /NMI returns high
|
|
344
|
+
rti
|
|
345
|
+
|
|
346
|
+
nmi_lock:
|
|
347
|
+
inc count
|
|
348
|
+
rti // no read: /NMI stays low, no further edge
|
|
349
|
+
|
|
350
|
+
nmi_live:
|
|
351
|
+
inc live_n
|
|
352
|
+
bne !+
|
|
353
|
+
inc live_n + 1
|
|
354
|
+
!: bit $dd0d
|
|
355
|
+
rti
|
|
356
|
+
|
|
357
|
+
// --- helpers
|
|
358
|
+
|
|
359
|
+
// puts: copy the $ff-terminated screen-code string at (src) to (dst)
|
|
360
|
+
puts:
|
|
361
|
+
ldy #$00
|
|
362
|
+
!: lda (src), y
|
|
363
|
+
cmp #$ff
|
|
364
|
+
beq !+
|
|
365
|
+
sta (dst), y
|
|
366
|
+
iny
|
|
367
|
+
bne !-
|
|
368
|
+
!: rts
|
|
369
|
+
|
|
370
|
+
// putdec: write num (16-bit) at (dst) as five decimal digits
|
|
371
|
+
putdec:
|
|
372
|
+
ldx #$00
|
|
373
|
+
ldy #$00
|
|
374
|
+
pd_digit:
|
|
375
|
+
lda #$30 // screen code '0'
|
|
376
|
+
sta digit
|
|
377
|
+
pd_sub:
|
|
378
|
+
sec
|
|
379
|
+
lda num
|
|
380
|
+
sbc pow_lo, x
|
|
381
|
+
sta tmp
|
|
382
|
+
lda num + 1
|
|
383
|
+
sbc pow_hi, x
|
|
384
|
+
bcc pd_done
|
|
385
|
+
sta num + 1
|
|
386
|
+
lda tmp
|
|
387
|
+
sta num
|
|
388
|
+
inc digit
|
|
389
|
+
jmp pd_sub
|
|
390
|
+
pd_done:
|
|
391
|
+
lda digit
|
|
392
|
+
sta (dst), y
|
|
393
|
+
iny
|
|
394
|
+
inx
|
|
395
|
+
cpx #$05
|
|
396
|
+
bne pd_digit
|
|
397
|
+
rts
|
|
398
|
+
|
|
399
|
+
pow_lo: .byte <10000, <1000, <100, <10, <1
|
|
400
|
+
pow_hi: .byte >10000, >1000, >100, >10, >1
|
|
401
|
+
|
|
402
|
+
zero: .byte $00
|
|
403
|
+
count: .byte $00
|
|
404
|
+
ack_n: .byte $00
|
|
405
|
+
lock_n: .byte $00
|
|
406
|
+
read_n: .byte $00
|
|
407
|
+
polls: .word $0000
|
|
408
|
+
c_ctrl: .word $0000
|
|
409
|
+
c_stub: .word $0000
|
|
410
|
+
c_ack: .word $0000
|
|
411
|
+
live_n: .word $0000
|
|
412
|
+
|
|
413
|
+
t_title: .text "NMI HANDLER AND RESTORE KEY"
|
|
414
|
+
.byte $ff
|
|
415
|
+
t_tick: .text "TICK 10000 CYCLES WINDOW 1005000 CYCLES"
|
|
416
|
+
.byte $ff
|
|
417
|
+
t_ack: .text "ACK NMIS EXPECT 00100"
|
|
418
|
+
.byte $ff
|
|
419
|
+
t_lock: .text "LOCK NMIS EXPECT 00001"
|
|
420
|
+
.byte $ff
|
|
421
|
+
t_read: .text "READ NMIS EXPECT 00001"
|
|
422
|
+
.byte $ff
|
|
423
|
+
t_polls: .text "MAIN POLLS IN THE ACK WINDOW"
|
|
424
|
+
.byte $ff
|
|
425
|
+
t_cost: .text "STUB ACK CYCLES PER NMI"
|
|
426
|
+
.byte $ff
|
|
427
|
+
t_live: .text "LIVE TICKS AND COUNTING"
|
|
428
|
+
.byte $ff
|
|
429
|
+
t_note1: .text "RESTORE WAS NOT PRESSED IN THIS RUN."
|
|
430
|
+
.byte $ff
|
|
431
|
+
t_note2: .text "CIA2 TIMER A STANDS IN FOR THE KEY."
|
|
432
|
+
.byte $ff
|
|
433
|
+
t_pass: .text "PASS"
|
|
434
|
+
.byte $ff
|
|
435
|
+
t_fail: .text "FAIL"
|
|
436
|
+
.byte $ff
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
## Build
|
|
440
|
+
|
|
441
|
+
```bash
|
|
442
|
+
java -jar KickAss.jar nmi-timer-tick.asm -o nmi-timer-tick.prg
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
Produces `nmi-timer-tick.prg`, `$0801` to `$1077`.
|
|
446
|
+
|
|
447
|
+
## Expected output
|
|
448
|
+
|
|
449
|
+
Border green, text area the power-on blue, the whole screen ours (the
|
|
450
|
+
program never returns to BASIC). On PAL, at the pinned 8,000,000 cycles:
|
|
451
|
+
|
|
452
|
+
```
|
|
453
|
+
NMI HANDLER AND RESTORE KEY
|
|
454
|
+
|
|
455
|
+
TICK 10000 CYCLES WINDOW 1005000 CYCLES
|
|
456
|
+
ACK NMIS 00100 EXPECT 00100 PASS
|
|
457
|
+
LOCK NMIS 00001 EXPECT 00001 PASS
|
|
458
|
+
READ NMIS 00001 EXPECT 00001 PASS
|
|
459
|
+
MAIN POLLS 52574 IN THE ACK WINDOW
|
|
460
|
+
|
|
461
|
+
STUB 00020 ACK 00030 CYCLES PER NMI
|
|
462
|
+
|
|
463
|
+
LIVE 00196 TICKS AND COUNTING
|
|
464
|
+
|
|
465
|
+
RESTORE WAS NOT PRESSED IN THIS RUN.
|
|
466
|
+
CIA2 TIMER A STANDS IN FOR THE KEY.
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
NTSC shows the same screen with `MAIN POLLS 52092` and `LIVE 00186`.
|
|
470
|
+
|
|
471
|
+
Screenshots from the pinned run, 8,000,000 cycles:
|
|
472
|
+
`screenshots/nmi-timer-tick.png` (PAL) and
|
|
473
|
+
`screenshots/nmi-timer-tick-ntsc.png` (NTSC). Both decoded against the
|
|
474
|
+
character ROM give the text above; border pixel (2, 100) = (98, 213, 50)
|
|
475
|
+
on PAL and (114, 189, 103) on NTSC, index 5 in both palettes of
|
|
476
|
+
`runtime/vice-reference.md`. The pinned command was run twice per model
|
|
477
|
+
and the two PNGs were identical bytes. `$02FF` is `$01`.
|
|
478
|
+
|
|
479
|
+
The arithmetic behind each line:
|
|
480
|
+
|
|
481
|
+
- **ACK.** CIA2 Timer A is latched with 9,999 and runs continuously, so
|
|
482
|
+
it underflows every 10,000 cycles (a 6526 timer's period is latch + 1;
|
|
483
|
+
`hardware/cia-reference.md`, `$DC04`). The window is CIA1 Timer A at
|
|
484
|
+
a period of 10,050 with Timer B counting 100 of its underflows:
|
|
485
|
+
1,005,000 cycles. 1,005,000 / 10,000 = 100.5, so 100 ticks fall inside
|
|
486
|
+
the window with a 5,000-cycle margin at each end, whatever the few
|
|
487
|
+
cycles between the two timers' starts. Both timers count phi2, so the
|
|
488
|
+
figure is the same on PAL and NTSC. In seconds, PAL: a 98.5 Hz tick
|
|
489
|
+
over 1.020 s; NTSC: a 102.3 Hz tick over 0.983 s (arithmetic from
|
|
490
|
+
985,248 Hz and 1,022,727 Hz).
|
|
491
|
+
- **LOCK.** The handler increments the count and returns without reading
|
|
492
|
+
`$DD0D`. The first underflow sets ICR bit 0, CIA2 pulls `/NMI` low and
|
|
493
|
+
the CPU takes one NMI. The flag is never cleared, `/NMI` never goes
|
|
494
|
+
high again, and the 6510's NMI input is edge-triggered, so the other
|
|
495
|
+
99 underflows in the window produce no NMI. Count 1.
|
|
496
|
+
- **READ.** With the timer still running and the same handler in place,
|
|
497
|
+
the main loop reads `$DD0D` once. That clears the flag and `/NMI` rises.
|
|
498
|
+
The next underflow, within 10,000 cycles, makes a fresh falling edge,
|
|
499
|
+
one NMI is taken, and the handler locks the line again. Count 1.
|
|
500
|
+
- **MAIN POLLS.** How many times the main loop's poll of `$DC06` ran
|
|
501
|
+
during the ACK window: the program was running the whole time the
|
|
502
|
+
NMIs were being taken. The figure differs by model because the
|
|
503
|
+
screen was on and the badlines in a PAL frame and an NTSC frame steal
|
|
504
|
+
different totals over 1,005,000 cycles; it is stated as measured, not
|
|
505
|
+
derived.
|
|
506
|
+
- **STUB and ACK.** CIA1 Timer A counts phi2 across 200 `NOP`s (400
|
|
507
|
+
cycles) with a CIA2 one-shot armed to underflow about 100 cycles in;
|
|
508
|
+
the reading with the NMI masked is subtracted from the reading with
|
|
509
|
+
it taken. The screen is off for these three blocks so no badline
|
|
510
|
+
lands inside one (an earlier run with the screen on read 63 and 73:
|
|
511
|
+
20 and 30 plus one 43-cycle badline). Bare `RTI`: 20 = the NMI
|
|
512
|
+
sequence (7) + the KERNAL's `SEI` at `$FE43` (2) + its `JMP ($0318)`
|
|
513
|
+
(5) + `RTI` (6). Count and acknowledge: 30 = 20 + `INC abs` (6) +
|
|
514
|
+
`BIT abs` (4). The instruction table is `hardware/6510-cpu-reference.md`;
|
|
515
|
+
the 20 agrees with the figure in `pitfalls/kernal-and-io.md`,
|
|
516
|
+
`restore_nmi_not_maskable`.
|
|
517
|
+
- **LIVE.** The tick keeps running with a 16-bit count-and-acknowledge
|
|
518
|
+
handler and the main loop prints the count for ever. At the pinned
|
|
519
|
+
cycle count it reads 196 on PAL and 186 on NTSC; the two differ
|
|
520
|
+
because the autostart and the three windows leave different amounts of
|
|
521
|
+
the 8,000,000 cycles for the live phase on each model. A different
|
|
522
|
+
`-limitcycles` gives a different number here and nowhere else.
|
|
523
|
+
|
|
524
|
+
## Why this works
|
|
525
|
+
|
|
526
|
+
`$FFFA` holds `$FE43`, which is `SEI` and then `JMP ($0318)`. Nothing is
|
|
527
|
+
pushed before that jump, so a handler at `$0318` gets control with the
|
|
528
|
+
interrupted program's A, X and Y intact and the CPU's own push of PC and
|
|
529
|
+
P already done. A handler that touches no register needs no saves, which
|
|
530
|
+
is why one `RTI` is a complete handler and why the counting handler uses
|
|
531
|
+
`BIT $DD0D` rather than `LDA`: `BIT` reads the register and only sets
|
|
532
|
+
flags, and `RTI` restores P. `$0318` is only consulted while the KERNAL
|
|
533
|
+
ROM is mapped in; with HIRAM clear the CPU fetches `$FFFA` from RAM and
|
|
534
|
+
the vector is yours to supply there.
|
|
535
|
+
|
|
536
|
+
Reading `$DD0D` is the acknowledge. The CIA clears every flag in the ICR
|
|
537
|
+
on a read and drops its interrupt output, which is the 6510's `/NMI`
|
|
538
|
+
pin. Until that read the pin stays low, and the 6510 takes an NMI on the
|
|
539
|
+
high-to-low transition only, so nothing can raise another NMI, not
|
|
540
|
+
another underflow and not RESTORE. The LOCK and READ lines are that rule
|
|
541
|
+
seen twice: once locked, and once unlocked by a single read from outside
|
|
542
|
+
the handler. A program that uses CIA2 NMIs on purpose reads `$DD0D` in
|
|
543
|
+
every handler; a program that wants RESTORE dead can either point
|
|
544
|
+
`$0318` at `RTI`, which costs 20 cycles per press and nothing otherwise,
|
|
545
|
+
or hold the lock, which costs every CIA2 interrupt for as long as it
|
|
546
|
+
holds.
|
|
547
|
+
|
|
548
|
+
The KERNAL's own handler at `$FE47` is what the vector replaces. It
|
|
549
|
+
pushes the registers, masks and reads `$DD0D`, and if no CIA2 flag was
|
|
550
|
+
set it treats the NMI as a RESTORE press: it samples the keyboard for
|
|
551
|
+
RUN/STOP and, if that key is down, warm-starts BASIC through `$FE66`.
|
|
552
|
+
A game that leaves `$0318` alone therefore hands RUN/STOP+RESTORE to
|
|
553
|
+
BASIC; the details of that path, from the ROM bytes, are in
|
|
554
|
+
`pitfalls/kernal-and-io.md` under `restore_nmi_not_maskable`, and the
|
|
555
|
+
pitfall `kernal_nmi_handler_runs_stop_check` in `pitfalls/cia.md` is the
|
|
556
|
+
short form.
|
|
557
|
+
|
|
558
|
+
The three windows are timed on CIA1 rather than the raster so that the
|
|
559
|
+
count does not depend on the model. CIA1's own IRQ sources are masked
|
|
560
|
+
and the program runs under `SEI`, so the KERNAL's jiffy interrupt is not
|
|
561
|
+
part of the picture; only the NMIs interrupt the main loop, and the
|
|
562
|
+
`MAIN POLLS` figure shows that it kept running between them.
|