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,668 @@
|
|
|
1
|
+
---
|
|
2
|
+
recipe: irq-owns-port
|
|
3
|
+
toolchain: kickassembler
|
|
4
|
+
output_format: PRG
|
|
5
|
+
region: both
|
|
6
|
+
techniques: [irq_owns_processor_port]
|
|
7
|
+
file_formats: [PRG]
|
|
8
|
+
uses_registers: [D011, D012, D019, D01A, D020, D400, D401, D404, D405, D406, D418, DC04, DC05, DC0D, DC0E, DD04, DD05, DD0D, DD0E]
|
|
9
|
+
uses_kernal: []
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
<!-- doc-type: recipe -->
|
|
13
|
+
|
|
14
|
+
# KickAssembler — IRQ and NMI handlers that own $01 while main code runs at $34
|
|
15
|
+
|
|
16
|
+
## Synopsis
|
|
17
|
+
|
|
18
|
+
Main code sets `$01` = `$34` (all RAM, no I/O) and, 32 times over,
|
|
19
|
+
copies 4 KB into the RAM under `$D000-$DFFF` and checks it by a 16-bit
|
|
20
|
+
sum, alternating a plain and an inverted copy so each pass has to write
|
|
21
|
+
every byte. Interrupts stay on throughout: a raster IRQ turns the border
|
|
22
|
+
yellow on line 120, a second one turns it back on line 200 and steps a
|
|
23
|
+
tiny SID player, and a CIA2 timer NMI fires every 5,000 cycles. Every
|
|
24
|
+
handler saves `$01` on the stack, stores `#$35`, does its work and
|
|
25
|
+
stores the saved value back. The KERNAL is banked out, so the CPU takes
|
|
26
|
+
both vectors from the RAM at `$FFFA-$FFFF`. The program prints the pass
|
|
27
|
+
count, the bad sums, how many times the line-200 handler and the NMI
|
|
28
|
+
ran, the fewest line-200 handler runs seen in any one pass, and the
|
|
29
|
+
cycles of the line-120 handler with and without the `$01` wrapper.
|
|
30
|
+
Verdict for a harness: `$02FF` = `$01` and `PASS` when every sum
|
|
31
|
+
matched and every pass saw an interrupt, `$02` and `FAIL` otherwise.
|
|
32
|
+
|
|
33
|
+
## Source
|
|
34
|
+
|
|
35
|
+
```asm
|
|
36
|
+
// irq-owns-port.asm
|
|
37
|
+
// Main code runs with $01 = $34 (all RAM, no I/O) and copies 4 KB into
|
|
38
|
+
// the RAM under $D000-$DFFF, then checks it by a 16-bit sum, 32 times,
|
|
39
|
+
// plain and inverted in turn. Meanwhile two raster IRQs change the
|
|
40
|
+
// border colour on lines 120 and 200, the second one also steps a tiny
|
|
41
|
+
// SID player, and a CIA2 timer NMI counts. Every handler saves $01,
|
|
42
|
+
// stores #$35, does its work, and puts the saved value back. The
|
|
43
|
+
// KERNAL is banked out, so the CPU takes its vectors from the RAM at
|
|
44
|
+
// $FFFA-$FFFF. The program prints the pass count, the bad sums, the
|
|
45
|
+
// IRQ and NMI counts, the fewest IRQs seen in any one pass, and the
|
|
46
|
+
// cycles of the line-120 handler with and without the $01 wrapper.
|
|
47
|
+
// Verdict for a harness: $02FF = $01 when every sum matched and every
|
|
48
|
+
// pass saw an IRQ, $02 otherwise.
|
|
49
|
+
// -define NO_SET35 builds the broken handler (it never sets $35).
|
|
50
|
+
// -define RESTORE35 builds a handler that restores #$35, not the saved value.
|
|
51
|
+
|
|
52
|
+
BasicUpstart2(start)
|
|
53
|
+
.encoding "screencode_upper"
|
|
54
|
+
|
|
55
|
+
.const SCREEN = $0400
|
|
56
|
+
.const RESULT = $02ff
|
|
57
|
+
.const BORDER = $d020
|
|
58
|
+
.const DEST = $d000 // the RAM under I/O
|
|
59
|
+
.const SRC = $4000 // 4 KB source pattern
|
|
60
|
+
.const PASSES = 32
|
|
61
|
+
.const LINE_A = 120 // border to yellow
|
|
62
|
+
.const LINE_B = 200 // border back, player, frame count
|
|
63
|
+
.const NMI_LAT = 4999 // CIA2 timer A period for the NMI
|
|
64
|
+
|
|
65
|
+
.const src = $fb
|
|
66
|
+
.const dst = $fd
|
|
67
|
+
|
|
68
|
+
// Expected sums, computed by the assembler from the same formula as the
|
|
69
|
+
// source data: the plain copy and the inverted copy.
|
|
70
|
+
.function pat(i) { .return ((i * 37) + (i >> 8) * 11 + 5) & $ff }
|
|
71
|
+
.var s_plain = 0
|
|
72
|
+
.for (var i = 0; i < 4096; i++) { .eval s_plain = s_plain + pat(i) }
|
|
73
|
+
.const SUM_PLAIN = s_plain & $ffff
|
|
74
|
+
.const SUM_INV = (4096 * 255 - s_plain) & $ffff
|
|
75
|
+
|
|
76
|
+
// ------------------------------------------------------------- wrapper
|
|
77
|
+
// Enter: save the interrupted $01 on the stack, make I/O visible.
|
|
78
|
+
.macro PortIn() {
|
|
79
|
+
lda $01
|
|
80
|
+
pha
|
|
81
|
+
#if !NO_SET35
|
|
82
|
+
lda #$35
|
|
83
|
+
sta $01
|
|
84
|
+
#endif
|
|
85
|
+
}
|
|
86
|
+
// Leave: put back exactly what the interrupted code had.
|
|
87
|
+
.macro PortOut() {
|
|
88
|
+
pla
|
|
89
|
+
#if RESTORE35
|
|
90
|
+
lda #$35
|
|
91
|
+
#endif
|
|
92
|
+
sta $01
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Handler A body: border yellow, chain to line B. wrap selects the
|
|
96
|
+
// wrapper so the same body can be timed with and without it.
|
|
97
|
+
.macro HandlerA(wrap) {
|
|
98
|
+
pha
|
|
99
|
+
.if (wrap) { PortIn() }
|
|
100
|
+
lda #7
|
|
101
|
+
sta BORDER
|
|
102
|
+
lda #LINE_B
|
|
103
|
+
sta $d012
|
|
104
|
+
lda #<irq_b
|
|
105
|
+
sta $fffe
|
|
106
|
+
lda #>irq_b
|
|
107
|
+
sta $ffff
|
|
108
|
+
lda #$01
|
|
109
|
+
sta $d019
|
|
110
|
+
.if (wrap) { PortOut() }
|
|
111
|
+
pla
|
|
112
|
+
rti
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// ---------------------------------------------------------------- main
|
|
116
|
+
start:
|
|
117
|
+
jsr $e544 // KERNAL clear screen, while it is still in
|
|
118
|
+
sei
|
|
119
|
+
lda #$7f
|
|
120
|
+
sta $dc0d // CIA1: no interrupts
|
|
121
|
+
sta $dd0d // CIA2: no NMIs yet
|
|
122
|
+
lda $dc0d
|
|
123
|
+
lda $dd0d
|
|
124
|
+
lda #0
|
|
125
|
+
sta $d01a
|
|
126
|
+
lda #$ff
|
|
127
|
+
sta $d019
|
|
128
|
+
// Vectors into the RAM under the KERNAL: writes go to RAM even now.
|
|
129
|
+
lda #<irq_a
|
|
130
|
+
sta $fffe
|
|
131
|
+
lda #>irq_a
|
|
132
|
+
sta $ffff
|
|
133
|
+
lda #<nmi
|
|
134
|
+
sta $fffa
|
|
135
|
+
lda #>nmi
|
|
136
|
+
sta $fffb
|
|
137
|
+
lda #$35 // KERNAL and BASIC out, I/O in
|
|
138
|
+
sta $01
|
|
139
|
+
|
|
140
|
+
// 1. Time handler A with and without the wrapper (CIA1 timer A).
|
|
141
|
+
lda #$34
|
|
142
|
+
sta call_port
|
|
143
|
+
lda #<bare_a
|
|
144
|
+
ldx #>bare_a
|
|
145
|
+
jsr time_call
|
|
146
|
+
stx t_bare
|
|
147
|
+
sty t_bare+1
|
|
148
|
+
lda #<irq_a
|
|
149
|
+
ldx #>irq_a
|
|
150
|
+
jsr time_call
|
|
151
|
+
stx t_full
|
|
152
|
+
sty t_full+1
|
|
153
|
+
lda #<rti_only
|
|
154
|
+
ldx #>rti_only
|
|
155
|
+
jsr time_call
|
|
156
|
+
stx t_empty
|
|
157
|
+
sty t_empty+1
|
|
158
|
+
lda #<irq_a // timing moved the chain: reset it
|
|
159
|
+
sta $fffe
|
|
160
|
+
lda #>irq_a
|
|
161
|
+
sta $ffff
|
|
162
|
+
|
|
163
|
+
// 2. Raster IRQ at LINE_A, CIA2 NMI, SID voice 1.
|
|
164
|
+
lda $d011
|
|
165
|
+
and #$7f
|
|
166
|
+
sta $d011
|
|
167
|
+
lda #LINE_A
|
|
168
|
+
sta $d012
|
|
169
|
+
lda #$ff
|
|
170
|
+
sta $d019
|
|
171
|
+
lda #$01
|
|
172
|
+
sta $d01a
|
|
173
|
+
lda #<NMI_LAT
|
|
174
|
+
sta $dd04
|
|
175
|
+
lda #>NMI_LAT
|
|
176
|
+
sta $dd05
|
|
177
|
+
lda #$81
|
|
178
|
+
sta $dd0d
|
|
179
|
+
lda #$11
|
|
180
|
+
sta $dd0e
|
|
181
|
+
lda #$0f
|
|
182
|
+
sta $d418
|
|
183
|
+
lda #$09
|
|
184
|
+
sta $d405
|
|
185
|
+
lda #$00
|
|
186
|
+
sta $d406
|
|
187
|
+
cli
|
|
188
|
+
|
|
189
|
+
// 3. The test: all RAM, interrupts live.
|
|
190
|
+
lda #$34
|
|
191
|
+
sta $01
|
|
192
|
+
lda #$ff
|
|
193
|
+
sta min_irq
|
|
194
|
+
lda #0
|
|
195
|
+
sta pass
|
|
196
|
+
sta bad
|
|
197
|
+
pass_loop:
|
|
198
|
+
lda irq_count
|
|
199
|
+
sta pass_start
|
|
200
|
+
lda pass
|
|
201
|
+
and #1
|
|
202
|
+
bne !+
|
|
203
|
+
jsr copy_plain
|
|
204
|
+
jmp !++
|
|
205
|
+
!: jsr copy_inv
|
|
206
|
+
!: jsr checksum
|
|
207
|
+
lda pass
|
|
208
|
+
and #1
|
|
209
|
+
bne !+
|
|
210
|
+
lda sum
|
|
211
|
+
cmp #<SUM_PLAIN
|
|
212
|
+
bne pass_bad
|
|
213
|
+
lda sum+1
|
|
214
|
+
cmp #>SUM_PLAIN
|
|
215
|
+
bne pass_bad
|
|
216
|
+
jmp pass_ok
|
|
217
|
+
!: lda sum
|
|
218
|
+
cmp #<SUM_INV
|
|
219
|
+
bne pass_bad
|
|
220
|
+
lda sum+1
|
|
221
|
+
cmp #>SUM_INV
|
|
222
|
+
bne pass_bad
|
|
223
|
+
jmp pass_ok
|
|
224
|
+
pass_bad:
|
|
225
|
+
inc bad
|
|
226
|
+
pass_ok:
|
|
227
|
+
lda irq_count
|
|
228
|
+
sec
|
|
229
|
+
sbc pass_start
|
|
230
|
+
cmp min_irq
|
|
231
|
+
bcs !+
|
|
232
|
+
sta min_irq
|
|
233
|
+
!: inc pass
|
|
234
|
+
lda pass
|
|
235
|
+
cmp #PASSES
|
|
236
|
+
bne pass_loop
|
|
237
|
+
lda #$35 // test over: I/O back for main code
|
|
238
|
+
sta $01
|
|
239
|
+
|
|
240
|
+
// 4. Report.
|
|
241
|
+
PrintAt(0, 0, t_title)
|
|
242
|
+
PrintAt(2, 0, t_pass_l)
|
|
243
|
+
Hex8At(2, 10, pass)
|
|
244
|
+
PrintAt(2, 16, t_bad_l)
|
|
245
|
+
Hex8At(2, 20, bad)
|
|
246
|
+
PrintAt(3, 0, t_irq_l)
|
|
247
|
+
Hex16At(3, 10, irq_count)
|
|
248
|
+
PrintAt(3, 16, t_min_l)
|
|
249
|
+
Hex8At(3, 29, min_irq)
|
|
250
|
+
PrintAt(4, 0, t_nmi_l)
|
|
251
|
+
Hex16At(4, 10, nmi_count)
|
|
252
|
+
PrintAt(5, 0, t_full_l)
|
|
253
|
+
Hex16At(5, 10, t_full)
|
|
254
|
+
PrintAt(6, 0, t_bare_l)
|
|
255
|
+
Hex16At(6, 10, t_bare)
|
|
256
|
+
sec
|
|
257
|
+
lda t_full
|
|
258
|
+
sbc t_bare
|
|
259
|
+
sta t_diff
|
|
260
|
+
lda t_full+1
|
|
261
|
+
sbc t_bare+1
|
|
262
|
+
sta t_diff+1
|
|
263
|
+
PrintAt(7, 0, t_diff_l)
|
|
264
|
+
Hex16At(7, 10, t_diff)
|
|
265
|
+
PrintAt(8, 0, t_empty_l)
|
|
266
|
+
Hex16At(8, 10, t_empty)
|
|
267
|
+
lda bad
|
|
268
|
+
bne fail
|
|
269
|
+
lda min_irq
|
|
270
|
+
beq fail
|
|
271
|
+
lda #1
|
|
272
|
+
sta RESULT
|
|
273
|
+
PrintAt(10, 0, t_ok)
|
|
274
|
+
jmp forever
|
|
275
|
+
fail:
|
|
276
|
+
lda #2
|
|
277
|
+
sta RESULT
|
|
278
|
+
PrintAt(10, 0, t_ng)
|
|
279
|
+
forever:
|
|
280
|
+
jmp forever
|
|
281
|
+
|
|
282
|
+
// ------------------------------------------------------------ handlers
|
|
283
|
+
irq_a:
|
|
284
|
+
HandlerA(true)
|
|
285
|
+
|
|
286
|
+
irq_b:
|
|
287
|
+
pha
|
|
288
|
+
PortIn()
|
|
289
|
+
txa
|
|
290
|
+
pha
|
|
291
|
+
lda #14
|
|
292
|
+
sta BORDER
|
|
293
|
+
inc irq_count
|
|
294
|
+
bne !+
|
|
295
|
+
inc irq_count+1
|
|
296
|
+
!: // Player: one note per 8 frames from an 8-note table, gate on.
|
|
297
|
+
inc frame
|
|
298
|
+
lda frame
|
|
299
|
+
lsr
|
|
300
|
+
lsr
|
|
301
|
+
lsr
|
|
302
|
+
and #7
|
|
303
|
+
tax
|
|
304
|
+
lda notes_lo, x
|
|
305
|
+
sta $d400
|
|
306
|
+
lda notes_hi, x
|
|
307
|
+
sta $d401
|
|
308
|
+
lda #$11
|
|
309
|
+
sta $d404
|
|
310
|
+
lda #LINE_A
|
|
311
|
+
sta $d012
|
|
312
|
+
lda #<irq_a
|
|
313
|
+
sta $fffe
|
|
314
|
+
lda #>irq_a
|
|
315
|
+
sta $ffff
|
|
316
|
+
lda #$01
|
|
317
|
+
sta $d019
|
|
318
|
+
pla
|
|
319
|
+
tax
|
|
320
|
+
PortOut()
|
|
321
|
+
pla
|
|
322
|
+
rti
|
|
323
|
+
|
|
324
|
+
// CIA2 timer NMI (and RESTORE): same wrapper, its own stack slot, so it
|
|
325
|
+
// is safe even when it lands inside an IRQ handler's wrapper.
|
|
326
|
+
nmi:
|
|
327
|
+
pha
|
|
328
|
+
PortIn()
|
|
329
|
+
lda $dd0d // acknowledge CIA2, or NMIs stop
|
|
330
|
+
inc nmi_count
|
|
331
|
+
bne !+
|
|
332
|
+
inc nmi_count+1
|
|
333
|
+
!: PortOut()
|
|
334
|
+
pla
|
|
335
|
+
rti
|
|
336
|
+
|
|
337
|
+
// The same body as irq_a without the wrapper, for timing only.
|
|
338
|
+
bare_a:
|
|
339
|
+
HandlerA(false)
|
|
340
|
+
|
|
341
|
+
// The framing alone: time_call's pushes, jump and exit around an RTI.
|
|
342
|
+
rti_only:
|
|
343
|
+
rti
|
|
344
|
+
|
|
345
|
+
// time_call: run the handler at A/X as an interrupt would (return
|
|
346
|
+
// address and status pushed, then RTI), with $01 = call_port during the
|
|
347
|
+
// call, timed by CIA1 timer A. Returns cycles in X (lo) / Y (hi),
|
|
348
|
+
// including the framing that rti_only measures alone.
|
|
349
|
+
time_call:
|
|
350
|
+
sta tc_jmp+1
|
|
351
|
+
stx tc_jmp+2
|
|
352
|
+
lda #252 // start in the lower border: no badline
|
|
353
|
+
!: cmp $d012 // or sprite DMA can steal from the window
|
|
354
|
+
bne !-
|
|
355
|
+
lda #$ff
|
|
356
|
+
sta $dc04
|
|
357
|
+
sta $dc05
|
|
358
|
+
lda #$19 // one-shot, force load, start
|
|
359
|
+
sta $dc0e
|
|
360
|
+
lda call_port
|
|
361
|
+
sta $01
|
|
362
|
+
lda #>tc_ret
|
|
363
|
+
pha
|
|
364
|
+
lda #<tc_ret
|
|
365
|
+
pha
|
|
366
|
+
php
|
|
367
|
+
tc_jmp:
|
|
368
|
+
jmp $ffff
|
|
369
|
+
tc_ret:
|
|
370
|
+
lda #$35
|
|
371
|
+
sta $01
|
|
372
|
+
lda #$00
|
|
373
|
+
sta $dc0e
|
|
374
|
+
sec
|
|
375
|
+
lda #$ff
|
|
376
|
+
sbc $dc04
|
|
377
|
+
tax
|
|
378
|
+
lda #$ff
|
|
379
|
+
sbc $dc05
|
|
380
|
+
tay
|
|
381
|
+
rts
|
|
382
|
+
|
|
383
|
+
// ------------------------------------------------------------- copies
|
|
384
|
+
copy_plain:
|
|
385
|
+
ldx #0
|
|
386
|
+
cp_loop:
|
|
387
|
+
.for (var p = 0; p < 16; p++) {
|
|
388
|
+
lda SRC + p * 256, x
|
|
389
|
+
sta DEST + p * 256, x
|
|
390
|
+
}
|
|
391
|
+
inx
|
|
392
|
+
beq cp_done
|
|
393
|
+
jmp cp_loop
|
|
394
|
+
cp_done:
|
|
395
|
+
rts
|
|
396
|
+
|
|
397
|
+
copy_inv:
|
|
398
|
+
ldx #0
|
|
399
|
+
ci_loop:
|
|
400
|
+
.for (var p = 0; p < 16; p++) {
|
|
401
|
+
lda SRC + p * 256, x
|
|
402
|
+
eor #$ff
|
|
403
|
+
sta DEST + p * 256, x
|
|
404
|
+
}
|
|
405
|
+
inx
|
|
406
|
+
beq ci_done
|
|
407
|
+
jmp ci_loop
|
|
408
|
+
ci_done:
|
|
409
|
+
rts
|
|
410
|
+
|
|
411
|
+
checksum:
|
|
412
|
+
lda #0
|
|
413
|
+
sta sum+1
|
|
414
|
+
ldx #0
|
|
415
|
+
clc // carry stays clear between bytes
|
|
416
|
+
cs_loop:
|
|
417
|
+
.for (var p = 0; p < 16; p++) {
|
|
418
|
+
adc DEST + p * 256, x // A holds the low byte of the sum
|
|
419
|
+
bcc skip
|
|
420
|
+
inc sum+1
|
|
421
|
+
clc
|
|
422
|
+
skip:
|
|
423
|
+
}
|
|
424
|
+
inx
|
|
425
|
+
beq cs_done
|
|
426
|
+
jmp cs_loop
|
|
427
|
+
cs_done:
|
|
428
|
+
sta sum
|
|
429
|
+
rts
|
|
430
|
+
|
|
431
|
+
// -------------------------------------------------------------- print
|
|
432
|
+
.macro PrintAt(row, col, text) {
|
|
433
|
+
lda #<(SCREEN + row * 40 + col)
|
|
434
|
+
sta dst
|
|
435
|
+
lda #>(SCREEN + row * 40 + col)
|
|
436
|
+
sta dst+1
|
|
437
|
+
lda #<text
|
|
438
|
+
sta src
|
|
439
|
+
lda #>text
|
|
440
|
+
sta src+1
|
|
441
|
+
jsr print
|
|
442
|
+
}
|
|
443
|
+
.macro Hex16At(row, col, slot) {
|
|
444
|
+
lda #<(SCREEN + row * 40 + col)
|
|
445
|
+
sta dst
|
|
446
|
+
lda #>(SCREEN + row * 40 + col)
|
|
447
|
+
sta dst+1
|
|
448
|
+
ldy #0
|
|
449
|
+
lda slot+1
|
|
450
|
+
jsr hex_byte
|
|
451
|
+
lda slot
|
|
452
|
+
jsr hex_byte
|
|
453
|
+
}
|
|
454
|
+
.macro Hex8At(row, col, slot) {
|
|
455
|
+
lda #<(SCREEN + row * 40 + col)
|
|
456
|
+
sta dst
|
|
457
|
+
lda #>(SCREEN + row * 40 + col)
|
|
458
|
+
sta dst+1
|
|
459
|
+
ldy #0
|
|
460
|
+
lda slot
|
|
461
|
+
jsr hex_byte
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
print:
|
|
465
|
+
ldy #0
|
|
466
|
+
!: lda (src), y
|
|
467
|
+
beq !+
|
|
468
|
+
sta (dst), y
|
|
469
|
+
iny
|
|
470
|
+
bne !-
|
|
471
|
+
!: rts
|
|
472
|
+
|
|
473
|
+
hex_byte:
|
|
474
|
+
pha
|
|
475
|
+
lsr
|
|
476
|
+
lsr
|
|
477
|
+
lsr
|
|
478
|
+
lsr
|
|
479
|
+
jsr hex_digit
|
|
480
|
+
pla
|
|
481
|
+
and #$0f
|
|
482
|
+
hex_digit:
|
|
483
|
+
cmp #10
|
|
484
|
+
bcc !+
|
|
485
|
+
sbc #9 // carry set: A-F are screen codes 1-6
|
|
486
|
+
jmp !++
|
|
487
|
+
!: ora #$30
|
|
488
|
+
!: sta (dst), y
|
|
489
|
+
iny
|
|
490
|
+
rts
|
|
491
|
+
|
|
492
|
+
// --------------------------------------------------------------- data
|
|
493
|
+
notes_lo: .byte $c3, $d1, $ef, $1f, $60, $b5, $1e, $87
|
|
494
|
+
notes_hi: .byte $10, $12, $14, $15, $18, $1a, $1d, $20
|
|
495
|
+
|
|
496
|
+
t_title: .text "IRQ OWNS THE PORT: MAIN RUNS AT $34"
|
|
497
|
+
.byte 0
|
|
498
|
+
t_pass_l: .text "PASSES"
|
|
499
|
+
.byte 0
|
|
500
|
+
t_bad_l: .text "BAD"
|
|
501
|
+
.byte 0
|
|
502
|
+
t_irq_l: .text "IRQS"
|
|
503
|
+
.byte 0
|
|
504
|
+
t_min_l: .text "MIN PER PASS"
|
|
505
|
+
.byte 0
|
|
506
|
+
t_nmi_l: .text "NMIS"
|
|
507
|
+
.byte 0
|
|
508
|
+
t_full_l: .text "WRAPPED"
|
|
509
|
+
.byte 0
|
|
510
|
+
t_bare_l: .text "BARE"
|
|
511
|
+
.byte 0
|
|
512
|
+
t_empty_l: .text "FRAMING"
|
|
513
|
+
.byte 0
|
|
514
|
+
t_diff_l: .text "OVERHEAD"
|
|
515
|
+
.byte 0
|
|
516
|
+
t_ok: .text "PASS"
|
|
517
|
+
.byte 0
|
|
518
|
+
t_ng: .text "FAIL"
|
|
519
|
+
.byte 0
|
|
520
|
+
|
|
521
|
+
call_port: .byte 0
|
|
522
|
+
irq_count: .word 0
|
|
523
|
+
nmi_count: .word 0
|
|
524
|
+
frame: .byte 0
|
|
525
|
+
pass: .byte 0
|
|
526
|
+
pass_start: .byte 0
|
|
527
|
+
min_irq: .byte 0
|
|
528
|
+
bad: .byte 0
|
|
529
|
+
sum: .word 0
|
|
530
|
+
t_full: .word 0
|
|
531
|
+
t_bare: .word 0
|
|
532
|
+
t_diff: .word 0
|
|
533
|
+
t_empty: .word 0
|
|
534
|
+
|
|
535
|
+
* = SRC "source pattern"
|
|
536
|
+
.for (var i = 0; i < 4096; i++) { .byte pat(i) }
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
## Build
|
|
540
|
+
|
|
541
|
+
```bash
|
|
542
|
+
java -jar $KICKASS_JAR irq-owns-port.asm -o irq-owns-port.prg
|
|
543
|
+
# the two broken handlers described under "Why this works":
|
|
544
|
+
java -jar $KICKASS_JAR irq-owns-port.asm -define NO_SET35 -o no-set35.prg
|
|
545
|
+
java -jar $KICKASS_JAR irq-owns-port.asm -define RESTORE35 -o restore35.prg
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
Run headless (pinned in `recipes/runs.json`, 8,000,000 cycles, PAL and
|
|
549
|
+
NTSC):
|
|
550
|
+
|
|
551
|
+
```bash
|
|
552
|
+
x64sc -default -warp +sound +autostart-delay-random -autostartprgmode 1 \
|
|
553
|
+
-limitcycles 8000000 [-model ntsc] -exitscreenshot out.png -autostart irq-owns-port.prg
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
## Expected output
|
|
557
|
+
|
|
558
|
+

|
|
559
|
+
|
|
560
|
+
Measured in VICE x64sc 3.10 from the exit screenshots, which were
|
|
561
|
+
identical byte for byte over two runs of each model. The numbers on
|
|
562
|
+
screen are hex.
|
|
563
|
+
|
|
564
|
+
| Line on screen | PAL | NTSC |
|
|
565
|
+
|---|---|---|
|
|
566
|
+
| `PASSES` / `BAD` | `20` / `00` (32 passes, no bad sum) | `20` / `00` |
|
|
567
|
+
| `IRQS` (line-200 handler runs) | `009A` (154) | `00B3` (179) |
|
|
568
|
+
| `MIN PER PASS` | `04` | `05` |
|
|
569
|
+
| `NMIS` | `025E` (606) | `0264` (612) |
|
|
570
|
+
| `WRAPPED` | `005E` (94) | `005E` |
|
|
571
|
+
| `BARE` | `004C` (76) | `004C` |
|
|
572
|
+
| `OVERHEAD` | `0012` (18) | `0012` |
|
|
573
|
+
| `FRAMING` | `0027` (39) | `0027` |
|
|
574
|
+
| verdict | `PASS` | `PASS` |
|
|
575
|
+
|
|
576
|
+
The counters are read once, just after the last pass. 154 PAL frames at
|
|
577
|
+
19,656 cycles is about 3.03 million cycles, which at one NMI per 5,000
|
|
578
|
+
cycles is 606 NMIs, the figure on screen (arithmetic from the counts).
|
|
579
|
+
|
|
580
|
+
The border, measured with PIL at x = 4 (left border) and x = 380
|
|
581
|
+
(right border): PAL rows 0-103 light blue, row 104 light blue on the
|
|
582
|
+
left and yellow on the right, rows 105-183 yellow, row 184 yellow on
|
|
583
|
+
the left and light blue on the right, rows 185-271 light blue. Rows 104
|
|
584
|
+
and 184 are raster lines 120 and 200 (row = line - 16): the colour
|
|
585
|
+
changes part-way along the line the IRQ was set for, because the IRQ
|
|
586
|
+
is not stabilised. NTSC is the same with rows 92 and 172 (row = line
|
|
587
|
+
- 28). The band shows the raster chain still running at exit, when main code
|
|
588
|
+
is back at `$35`. The evidence that the handlers ran while main code was
|
|
589
|
+
at `$34` is the counters: `MIN PER PASS` is non-zero and `BAD` is 00.
|
|
590
|
+
|
|
591
|
+
## Why this works
|
|
592
|
+
|
|
593
|
+
**The wrapper.** Each handler begins `PHA`, `LDA $01`, `PHA`,
|
|
594
|
+
`LDA #$35`, `STA $01` and ends `PLA`, `STA $01`, `PLA`, `RTI`. `$35`
|
|
595
|
+
keeps the ROMs out and makes I/O visible, whatever the interrupted code
|
|
596
|
+
had. The saved value goes on the stack, not in a fixed byte, so an NMI
|
|
597
|
+
that lands inside an IRQ handler's wrapper saves and restores its own
|
|
598
|
+
copy; with a shared save byte the NMI would overwrite the IRQ's saved
|
|
599
|
+
`$34` with `$35` and the IRQ would return main code into the I/O
|
|
600
|
+
window. `ORA #$01` in place of the `$35` store does not work in
|
|
601
|
+
general: from `$30` it gives `$31`, the character ROM, not I/O.
|
|
602
|
+
|
|
603
|
+
**The vectors.** `$01` = `$34` and `$35` both have HIRAM clear, so the
|
|
604
|
+
CPU fetches the IRQ and NMI vectors from the RAM at `$FFFE/$FFFF` and
|
|
605
|
+
`$FFFA/$FFFB`, not from the KERNAL. The program writes them before it
|
|
606
|
+
banks the KERNAL out; the writes reach RAM even while the ROM is in
|
|
607
|
+
(`ram_under_rom_traps`). `$0314` and `$0318` are never read. The
|
|
608
|
+
raster chain rewrites `$FFFE/$FFFF` from inside the handlers.
|
|
609
|
+
|
|
610
|
+
**The NMI.** `SEI` does not stop an NMI, and the RESTORE key or CIA2
|
|
611
|
+
can raise one while `$01` = `$34`. The NMI handler here has the same
|
|
612
|
+
wrapper and reads `$DD0D` to acknowledge CIA2; without `$35` that read
|
|
613
|
+
reaches RAM, the CIA's flag stays set, `/NMI` never goes high again,
|
|
614
|
+
and no further NMI edge can occur (pitfall
|
|
615
|
+
`kernal_nmi_handler_runs_stop_check` in `pitfalls/cia.md`).
|
|
616
|
+
|
|
617
|
+
**The timing.** `time_call` enters a handler as an interrupt would:
|
|
618
|
+
return address and status on the stack, then a jump; the handler's
|
|
619
|
+
`RTI` comes back to `time_call`. CIA1 timer A counts the window, which
|
|
620
|
+
starts on raster line 252 so no badline or sprite fetch falls in it.
|
|
621
|
+
`$01` is `$34` for the call. `rti_only` measures the framing alone (39
|
|
622
|
+
cycles, its `RTI` included). The line-120 handler is 94 − 39 + 6 = 61
|
|
623
|
+
cycles wrapped and 43 bare, each plus 7 cycles for the interrupt
|
|
624
|
+
sequence itself (arithmetic from the instruction table, not in the
|
|
625
|
+
window). The difference, 18, is the wrapper: `LDA zp` 3, `PHA` 3,
|
|
626
|
+
`LDA #` 2, `STA zp` 3, `PLA` 4, `STA zp` 3, which is also what the
|
|
627
|
+
instruction table gives. The same figures on PAL and NTSC.
|
|
628
|
+
|
|
629
|
+
**The negative runs.** Both were run in VICE x64sc 3.10 (PAL, and the
|
|
630
|
+
first also NTSC) and probed through the remote monitor after 60 to 115
|
|
631
|
+
million cycles; neither is the pinned listing.
|
|
632
|
+
|
|
633
|
+
- `-define NO_SET35`: the handlers save and restore `$01` but never
|
|
634
|
+
store `$35`. The screen stays blank blue with no yellow band and
|
|
635
|
+
nothing printed. The monitor showed the pass counter at 0, the PC
|
|
636
|
+
inside a handler, the NMI count at 1 and the line-200 count at
|
|
637
|
+
`$9A29` (PAL, 115 million cycles; NTSC `$7133` at 100 million). The
|
|
638
|
+
`$D019` acknowledge went to RAM, so the VIC's interrupt stayed
|
|
639
|
+
asserted and the two handlers re-entered each other for ever,
|
|
640
|
+
swapping the vector each time; main code never ran another pass. The
|
|
641
|
+
NMI ran once and stopped, its `$DD0D` read having gone to RAM. With
|
|
642
|
+
`$01` = `$34` the monitor showed the handlers' register writes in
|
|
643
|
+
the RAM copy: `$D012` = `$78`, `$D019` = `$01`, `$D020` = `$07`,
|
|
644
|
+
`$D400`/`$D401`/`$D404` = a note and `$11`. Had the main loop run
|
|
645
|
+
on, those bytes would have failed the sum.
|
|
646
|
+
- `-define RESTORE35`: the handlers set `$35` but restore `$35`
|
|
647
|
+
instead of the saved value. The first interrupt returns main code
|
|
648
|
+
into the I/O window mid-copy, and the copy writes its pattern into
|
|
649
|
+
the VIC, SID and CIA registers: the exit screenshot is a black screen
|
|
650
|
+
with coloured streaks and a striped border. The monitor showed the
|
|
651
|
+
pass counter at 0 and the NMI count at 1 at 95 million cycles, and
|
|
652
|
+
the PC inside a handler in both probes (60 and 95 million). That the stray pattern bytes enabled
|
|
653
|
+
a CIA1 interrupt source no handler acknowledges is the likely reason
|
|
654
|
+
the handlers never stop (`$DC0D` read `$01` in the monitor); it was
|
|
655
|
+
not traced further.
|
|
656
|
+
|
|
657
|
+
**The copy.** 16 `LDA abs,X` / `STA abs,X` pairs per `X` step, 256
|
|
658
|
+
steps; the checksum keeps the low byte of the sum in A and carries into
|
|
659
|
+
the high byte. The expected sums are computed by the assembler from the
|
|
660
|
+
same function that generates the source bytes, so the listing carries
|
|
661
|
+
no magic numbers. A 16-bit sum is weak, but every failure above is
|
|
662
|
+
gross.
|
|
663
|
+
|
|
664
|
+
Sources for the pattern: the Sparkle 3.4 user manual, section "Loading
|
|
665
|
+
to the RAM under I/O registers ($D000-$DFFF)", in
|
|
666
|
+
https://github.com/spartaomg/SparkleCPP (the loader decrunches with
|
|
667
|
+
`$01` = `$34` and requires IRQs to save, set `$35` and restore). The
|
|
668
|
+
code here is original.
|