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,623 @@
|
|
|
1
|
+
---
|
|
2
|
+
recipe: charset-copy-rom-to-ram
|
|
3
|
+
toolchain: kickassembler
|
|
4
|
+
output_format: PRG
|
|
5
|
+
region: both
|
|
6
|
+
techniques: [charset_copy_rom_to_ram]
|
|
7
|
+
file_formats: [PRG]
|
|
8
|
+
uses_registers: [D011, D012, D018, D020, DC0D, DD04, DD05, DD06, DD07, DD0D, DD0E, DD0F]
|
|
9
|
+
uses_kernal: []
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
<!-- doc-type: recipe -->
|
|
13
|
+
|
|
14
|
+
# KickAssembler — Copy the character ROM into RAM, checked, timed, and done wrong once
|
|
15
|
+
|
|
16
|
+
## Synopsis
|
|
17
|
+
|
|
18
|
+
Copies the 4 KB character ROM into RAM at `$3000` with the I/O window
|
|
19
|
+
swapped for the ROM under `SEI`, checks every byte of the copy through a
|
|
20
|
+
16-bit sum against the value the host computed from
|
|
21
|
+
`chargen-901225-01.bin`, times the 2 KB and 4 KB copies with the CIA2
|
|
22
|
+
timers (display on and display blanked), points `$D018` at the copy and
|
|
23
|
+
overwrites one glyph in it so the screen proves the VIC is reading RAM.
|
|
24
|
+
Then it does the copy once the wrong way: interrupts enabled while the
|
|
25
|
+
KERNAL IRQ is live, under a CIA2 timer NMI that acts as a watchdog. The
|
|
26
|
+
program reports how far that copy got, how many times the interrupt
|
|
27
|
+
handler ran before the watchdog fired, and how many keys the handler
|
|
28
|
+
queued from a keyboard it could not see. Verdict for a harness: `$02FF`
|
|
29
|
+
= `$01` and a green border when the checksum matches and the
|
|
30
|
+
unprotected copy was caught, `$02` and red otherwise.
|
|
31
|
+
|
|
32
|
+
## Source
|
|
33
|
+
|
|
34
|
+
```asm
|
|
35
|
+
// charset-copy-rom-to-ram.asm
|
|
36
|
+
// Copies the character ROM into RAM at $3000 with the I/O window swapped
|
|
37
|
+
// for the ROM under SEI, times the 2 KB and 4 KB copies with the CIA2
|
|
38
|
+
// timers (display on and display blanked), checks the copy against a
|
|
39
|
+
// checksum of chargen-901225-01.bin computed on the host, points $D018
|
|
40
|
+
// at the copy and alters one glyph to prove the VIC is reading it. Then
|
|
41
|
+
// it repeats the copy the wrong way, with interrupts enabled while the
|
|
42
|
+
// KERNAL IRQ is live, under a CIA2 timer NMI that acts as a watchdog,
|
|
43
|
+
// and reports how far the copy got, how many times the IRQ handler ran,
|
|
44
|
+
// and how many keys the handler queued from a keyboard it could not see.
|
|
45
|
+
// Verdict for a harness: $02FF = $01 and a green border when the
|
|
46
|
+
// checksum matches and the unprotected copy was caught, $02 and red
|
|
47
|
+
// otherwise.
|
|
48
|
+
|
|
49
|
+
BasicUpstart2(start)
|
|
50
|
+
.encoding "screencode_upper"
|
|
51
|
+
|
|
52
|
+
.const SCREEN = $0400
|
|
53
|
+
.const COLRAM = $d800
|
|
54
|
+
.const RESULT = $02ff // verdict byte read by the harness
|
|
55
|
+
.const BORDER = $d020
|
|
56
|
+
.const CODE_PASS = $01
|
|
57
|
+
.const CODE_FAIL = $02
|
|
58
|
+
.const FONT = $3000 // 4 KB copy: VIC bank 0, $D018 CB = %110
|
|
59
|
+
.const SCRATCH = $4000 // target of the unprotected copy
|
|
60
|
+
.const EXP_SUM = $f7f8 // 16-bit sum of the 4,096 ROM bytes, host-computed
|
|
61
|
+
.const KERNAL_IRQ = $ea31
|
|
62
|
+
.const KERNAL_NMI = $fe47
|
|
63
|
+
.const MARK = $66 // screen code whose glyph is replaced after the switch
|
|
64
|
+
|
|
65
|
+
.const src = $fb // zero-page pointer: string source
|
|
66
|
+
.const dst = $fd // zero-page pointer: screen destination
|
|
67
|
+
|
|
68
|
+
// ---------------------------------------------------------------- macros
|
|
69
|
+
|
|
70
|
+
// CopyRom(pages, dest): the technique. ROM in, copy, I/O back. The
|
|
71
|
+
// caller holds SEI across the whole macro: no interrupt may run while
|
|
72
|
+
// the I/O chips are out of the map.
|
|
73
|
+
.macro CopyRom(pages, dest) {
|
|
74
|
+
lda $01
|
|
75
|
+
and #$f8 // keep the datasette bits 3-5
|
|
76
|
+
ora #$03 // $33: char ROM at $D000-$DFFF
|
|
77
|
+
sta $01
|
|
78
|
+
ldx #0
|
|
79
|
+
!:
|
|
80
|
+
.for (var p = 0; p < pages; p++) {
|
|
81
|
+
lda $d000 + p * 256, x
|
|
82
|
+
sta dest + p * 256, x
|
|
83
|
+
}
|
|
84
|
+
inx
|
|
85
|
+
bne !-
|
|
86
|
+
lda $01
|
|
87
|
+
and #$f8
|
|
88
|
+
ora #$07 // $37: I/O back
|
|
89
|
+
sta $01
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Time(routine, slot): CIA2 timer A counts phi2, timer B counts A
|
|
93
|
+
// underflows; the 24-bit count lands in slot. The CIAs keep counting
|
|
94
|
+
// while the CPU cannot see them; only the start and the read need I/O.
|
|
95
|
+
// SEI is held from before the start to after the read, so the count is
|
|
96
|
+
// the routine alone: an IRQ deferred by the copy would otherwise run at
|
|
97
|
+
// the CLI, inside the window.
|
|
98
|
+
.macro Time(routine, slot) {
|
|
99
|
+
sei
|
|
100
|
+
lda #$ff
|
|
101
|
+
sta $dd04
|
|
102
|
+
sta $dd05
|
|
103
|
+
sta $dd06
|
|
104
|
+
sta $dd07
|
|
105
|
+
lda #$51
|
|
106
|
+
sta $dd0f
|
|
107
|
+
lda #$11
|
|
108
|
+
sta $dd0e
|
|
109
|
+
jsr routine
|
|
110
|
+
lda #$00
|
|
111
|
+
sta $dd0e
|
|
112
|
+
sta $dd0f
|
|
113
|
+
sec
|
|
114
|
+
lda #$ff
|
|
115
|
+
sbc $dd04
|
|
116
|
+
sta slot
|
|
117
|
+
lda #$ff
|
|
118
|
+
sbc $dd05
|
|
119
|
+
sta slot+1
|
|
120
|
+
lda #$ff
|
|
121
|
+
sbc $dd06
|
|
122
|
+
sta slot+2
|
|
123
|
+
cli
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.macro PrintAt(row, col, text) {
|
|
127
|
+
lda #<(SCREEN + row * 40 + col)
|
|
128
|
+
sta dst
|
|
129
|
+
lda #>(SCREEN + row * 40 + col)
|
|
130
|
+
sta dst+1
|
|
131
|
+
lda #<text
|
|
132
|
+
sta src
|
|
133
|
+
lda #>text
|
|
134
|
+
sta src+1
|
|
135
|
+
jsr print
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
.macro Hex24At(row, col, slot) {
|
|
139
|
+
lda #<(SCREEN + row * 40 + col)
|
|
140
|
+
sta dst
|
|
141
|
+
lda #>(SCREEN + row * 40 + col)
|
|
142
|
+
sta dst+1
|
|
143
|
+
ldy #0
|
|
144
|
+
lda slot+2
|
|
145
|
+
jsr hex_byte
|
|
146
|
+
lda slot+1
|
|
147
|
+
jsr hex_byte
|
|
148
|
+
lda slot
|
|
149
|
+
jsr hex_byte
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.macro Hex16At(row, col, slot) {
|
|
153
|
+
lda #<(SCREEN + row * 40 + col)
|
|
154
|
+
sta dst
|
|
155
|
+
lda #>(SCREEN + row * 40 + col)
|
|
156
|
+
sta dst+1
|
|
157
|
+
ldy #0
|
|
158
|
+
lda slot+1
|
|
159
|
+
jsr hex_byte
|
|
160
|
+
lda slot
|
|
161
|
+
jsr hex_byte
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.macro Hex8At(row, col, slot) {
|
|
165
|
+
lda #<(SCREEN + row * 40 + col)
|
|
166
|
+
sta dst
|
|
167
|
+
lda #>(SCREEN + row * 40 + col)
|
|
168
|
+
sta dst+1
|
|
169
|
+
ldy #0
|
|
170
|
+
lda slot
|
|
171
|
+
jsr hex_byte
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// ---------------------------------------------------------------- main
|
|
175
|
+
|
|
176
|
+
start:
|
|
177
|
+
jsr clear_screen
|
|
178
|
+
PrintAt(0, 0, t_title)
|
|
179
|
+
|
|
180
|
+
// 1. The technique, timed three ways.
|
|
181
|
+
Time(copy2k, t_2k_on)
|
|
182
|
+
jsr blank_display
|
|
183
|
+
Time(copy2k, t_2k_off)
|
|
184
|
+
jsr show_display
|
|
185
|
+
Time(copy4k, t_4k_on)
|
|
186
|
+
Time(nothing, t_empty)
|
|
187
|
+
|
|
188
|
+
// 2. Check the 4 KB copy against the host checksum.
|
|
189
|
+
jsr checksum
|
|
190
|
+
PrintAt(2, 0, t_sum)
|
|
191
|
+
Hex16At(2, 4, sum)
|
|
192
|
+
lda sum
|
|
193
|
+
cmp #<EXP_SUM
|
|
194
|
+
bne sum_bad
|
|
195
|
+
lda sum+1
|
|
196
|
+
cmp #>EXP_SUM
|
|
197
|
+
bne sum_bad
|
|
198
|
+
PrintAt(2, 14, t_pass)
|
|
199
|
+
lda #1
|
|
200
|
+
sta sum_ok
|
|
201
|
+
jmp sum_done
|
|
202
|
+
sum_bad:
|
|
203
|
+
PrintAt(2, 14, t_fail)
|
|
204
|
+
sum_done:
|
|
205
|
+
PrintAt(3, 0, t_2k_on_l)
|
|
206
|
+
Hex24At(3, 8, t_2k_on)
|
|
207
|
+
PrintAt(4, 0, t_2k_off_l)
|
|
208
|
+
Hex24At(4, 8, t_2k_off)
|
|
209
|
+
PrintAt(5, 0, t_4k_on_l)
|
|
210
|
+
Hex24At(5, 8, t_4k_on)
|
|
211
|
+
PrintAt(6, 0, t_empty_l)
|
|
212
|
+
Hex24At(6, 8, t_empty)
|
|
213
|
+
|
|
214
|
+
// 3. Point the VIC at the copy, then alter one glyph in the copy.
|
|
215
|
+
PrintAt(7, 0, t_live)
|
|
216
|
+
lda #$1c // screen $0400, charset $3000
|
|
217
|
+
sta $d018
|
|
218
|
+
ldx #7
|
|
219
|
+
lda #$ff
|
|
220
|
+
!: sta FONT + MARK * 8, x // MARK becomes a solid 8x8 block
|
|
221
|
+
dex
|
|
222
|
+
bpl !-
|
|
223
|
+
|
|
224
|
+
// 4. The mistake, caught: copy with interrupts enabled.
|
|
225
|
+
jsr bad_copy
|
|
226
|
+
PrintAt(9, 0, t_nosei)
|
|
227
|
+
lda completed
|
|
228
|
+
beq !+
|
|
229
|
+
PrintAt(9, 13, t_completed)
|
|
230
|
+
jmp !++
|
|
231
|
+
!: PrintAt(9, 13, t_caught)
|
|
232
|
+
!: PrintAt(10, 0, t_irqs)
|
|
233
|
+
Hex16At(10, 11, irq_count)
|
|
234
|
+
PrintAt(11, 0, t_iter)
|
|
235
|
+
Hex8At(11, 11, progress)
|
|
236
|
+
PrintAt(12, 0, t_keys)
|
|
237
|
+
Hex8At(12, 12, $c6)
|
|
238
|
+
|
|
239
|
+
// 5. Verdict.
|
|
240
|
+
lda sum_ok
|
|
241
|
+
beq verdict_fail
|
|
242
|
+
lda completed
|
|
243
|
+
bne verdict_fail
|
|
244
|
+
lda #CODE_PASS
|
|
245
|
+
sta RESULT
|
|
246
|
+
lda #5
|
|
247
|
+
sta BORDER
|
|
248
|
+
jmp forever
|
|
249
|
+
verdict_fail:
|
|
250
|
+
lda #CODE_FAIL
|
|
251
|
+
sta RESULT
|
|
252
|
+
lda #2
|
|
253
|
+
sta BORDER
|
|
254
|
+
forever:
|
|
255
|
+
jmp forever
|
|
256
|
+
|
|
257
|
+
// ---------------------------------------------------------------- copies
|
|
258
|
+
|
|
259
|
+
copy2k:
|
|
260
|
+
CopyRom(8, FONT)
|
|
261
|
+
rts
|
|
262
|
+
|
|
263
|
+
copy4k:
|
|
264
|
+
CopyRom(16, FONT)
|
|
265
|
+
rts
|
|
266
|
+
|
|
267
|
+
nothing: // the timing window's own overhead
|
|
268
|
+
rts
|
|
269
|
+
|
|
270
|
+
// The wrong way. Same loop, interrupts enabled, the KERNAL IRQ live. A
|
|
271
|
+
// CIA2 timer A one-shot of 65,535 cycles raises an NMI as a watchdog;
|
|
272
|
+
// the copy would take about 39,000 cycles if nothing stopped it.
|
|
273
|
+
bad_copy:
|
|
274
|
+
sei
|
|
275
|
+
lda #<irq_hook
|
|
276
|
+
sta $0314
|
|
277
|
+
lda #>irq_hook
|
|
278
|
+
sta $0315
|
|
279
|
+
lda #<nmi_catch
|
|
280
|
+
sta $0318
|
|
281
|
+
lda #>nmi_catch
|
|
282
|
+
sta $0319
|
|
283
|
+
lda #0
|
|
284
|
+
sta irq_count
|
|
285
|
+
sta irq_count+1
|
|
286
|
+
sta progress
|
|
287
|
+
sta completed
|
|
288
|
+
sta $c6 // empty the keyboard buffer
|
|
289
|
+
tsx
|
|
290
|
+
stx saved_sp
|
|
291
|
+
lda #$7f
|
|
292
|
+
sta $dd0d // mask every CIA2 source
|
|
293
|
+
lda $dd0d // and drop anything pending
|
|
294
|
+
lda #$ff
|
|
295
|
+
sta $dd04
|
|
296
|
+
sta $dd05
|
|
297
|
+
lda #$81
|
|
298
|
+
sta $dd0d // timer A may raise the NMI
|
|
299
|
+
lda #$19
|
|
300
|
+
sta $dd0e // one-shot, force load, start
|
|
301
|
+
lda $01
|
|
302
|
+
and #$f8
|
|
303
|
+
ora #$03
|
|
304
|
+
sta $01 // ROM in
|
|
305
|
+
cli // the mistake
|
|
306
|
+
ldx #0
|
|
307
|
+
bad_loop:
|
|
308
|
+
stx progress
|
|
309
|
+
.for (var p = 0; p < 16; p++) {
|
|
310
|
+
lda $d000 + p * 256, x
|
|
311
|
+
sta SCRATCH + p * 256, x
|
|
312
|
+
}
|
|
313
|
+
inx
|
|
314
|
+
bne bad_loop
|
|
315
|
+
// Only reached if no interrupt fired for the whole copy.
|
|
316
|
+
sei
|
|
317
|
+
lda $01
|
|
318
|
+
and #$f8
|
|
319
|
+
ora #$07
|
|
320
|
+
sta $01
|
|
321
|
+
lda #$7f
|
|
322
|
+
sta $dd0d
|
|
323
|
+
lda $dd0d
|
|
324
|
+
lda #0
|
|
325
|
+
sta $dd0e
|
|
326
|
+
lda #1
|
|
327
|
+
sta completed
|
|
328
|
+
jmp recovered
|
|
329
|
+
|
|
330
|
+
irq_hook:
|
|
331
|
+
inc irq_count
|
|
332
|
+
bne !+
|
|
333
|
+
inc irq_count+1
|
|
334
|
+
!: jmp KERNAL_IRQ
|
|
335
|
+
|
|
336
|
+
nmi_catch:
|
|
337
|
+
lda $01
|
|
338
|
+
and #$f8
|
|
339
|
+
ora #$07
|
|
340
|
+
sta $01 // I/O back before touching a CIA
|
|
341
|
+
lda $dd0d // acknowledge the watchdog
|
|
342
|
+
lda $dc0d // acknowledge the stuck KERNAL IRQ
|
|
343
|
+
ldx saved_sp
|
|
344
|
+
txs // unwind the nested handler frames
|
|
345
|
+
// falls through: I is set from the NMI entry
|
|
346
|
+
|
|
347
|
+
recovered:
|
|
348
|
+
lda #<KERNAL_IRQ
|
|
349
|
+
sta $0314
|
|
350
|
+
lda #>KERNAL_IRQ
|
|
351
|
+
sta $0315
|
|
352
|
+
lda #<KERNAL_NMI
|
|
353
|
+
sta $0318
|
|
354
|
+
lda #>KERNAL_NMI
|
|
355
|
+
sta $0319
|
|
356
|
+
cli
|
|
357
|
+
rts
|
|
358
|
+
|
|
359
|
+
// ---------------------------------------------------------------- support
|
|
360
|
+
|
|
361
|
+
checksum: // sum = 16-bit sum of FONT..FONT+$0FFF
|
|
362
|
+
lda #0
|
|
363
|
+
sta sum
|
|
364
|
+
sta sum+1
|
|
365
|
+
sta src
|
|
366
|
+
lda #>FONT
|
|
367
|
+
sta src+1
|
|
368
|
+
ldx #16
|
|
369
|
+
ldy #0
|
|
370
|
+
cs_loop:
|
|
371
|
+
lda (src), y
|
|
372
|
+
clc
|
|
373
|
+
adc sum
|
|
374
|
+
sta sum
|
|
375
|
+
bcc !+
|
|
376
|
+
inc sum+1
|
|
377
|
+
!: iny
|
|
378
|
+
bne cs_loop
|
|
379
|
+
inc src+1
|
|
380
|
+
dex
|
|
381
|
+
bne cs_loop
|
|
382
|
+
rts
|
|
383
|
+
|
|
384
|
+
blank_display: // DEN off, then wait past line $30 of a new frame
|
|
385
|
+
lda $d011
|
|
386
|
+
and #$ef
|
|
387
|
+
sta $d011
|
|
388
|
+
!: lda $d012
|
|
389
|
+
bne !-
|
|
390
|
+
!: lda $d012
|
|
391
|
+
cmp #100
|
|
392
|
+
bne !-
|
|
393
|
+
rts
|
|
394
|
+
|
|
395
|
+
show_display:
|
|
396
|
+
lda $d011
|
|
397
|
+
ora #$10
|
|
398
|
+
sta $d011
|
|
399
|
+
rts
|
|
400
|
+
|
|
401
|
+
clear_screen:
|
|
402
|
+
ldx #0
|
|
403
|
+
lda #$20
|
|
404
|
+
!: sta SCREEN, x
|
|
405
|
+
sta SCREEN + $100, x
|
|
406
|
+
sta SCREEN + $200, x
|
|
407
|
+
sta SCREEN + $300, x
|
|
408
|
+
inx
|
|
409
|
+
bne !-
|
|
410
|
+
lda #1
|
|
411
|
+
!: sta COLRAM, x
|
|
412
|
+
sta COLRAM + $100, x
|
|
413
|
+
sta COLRAM + $200, x
|
|
414
|
+
sta COLRAM + $300, x
|
|
415
|
+
inx
|
|
416
|
+
bne !-
|
|
417
|
+
rts
|
|
418
|
+
|
|
419
|
+
print: // (src) zero-terminated -> (dst)
|
|
420
|
+
ldy #0
|
|
421
|
+
!: lda (src), y
|
|
422
|
+
beq !+
|
|
423
|
+
sta (dst), y
|
|
424
|
+
iny
|
|
425
|
+
bne !-
|
|
426
|
+
!: rts
|
|
427
|
+
|
|
428
|
+
hex_byte: // A -> two hex digits at (dst),y; Y advances
|
|
429
|
+
pha
|
|
430
|
+
lsr
|
|
431
|
+
lsr
|
|
432
|
+
lsr
|
|
433
|
+
lsr
|
|
434
|
+
tax
|
|
435
|
+
lda hex_digits, x
|
|
436
|
+
sta (dst), y
|
|
437
|
+
iny
|
|
438
|
+
pla
|
|
439
|
+
and #$0f
|
|
440
|
+
tax
|
|
441
|
+
lda hex_digits, x
|
|
442
|
+
sta (dst), y
|
|
443
|
+
iny
|
|
444
|
+
rts
|
|
445
|
+
|
|
446
|
+
hex_digits: .text "0123456789ABCDEF"
|
|
447
|
+
|
|
448
|
+
t_title: .text "CHARSET COPY ROM TO RAM"
|
|
449
|
+
.byte 0
|
|
450
|
+
t_sum: .text "SUM"
|
|
451
|
+
.byte 0
|
|
452
|
+
t_pass: .text "PASS"
|
|
453
|
+
.byte 0
|
|
454
|
+
t_fail: .text "FAIL"
|
|
455
|
+
.byte 0
|
|
456
|
+
t_2k_on_l: .text "2K ON"
|
|
457
|
+
.byte 0
|
|
458
|
+
t_2k_off_l: .text "2K OFF"
|
|
459
|
+
.byte 0
|
|
460
|
+
t_4k_on_l: .text "4K ON"
|
|
461
|
+
.byte 0
|
|
462
|
+
t_empty_l: .text "EMPTY"
|
|
463
|
+
.byte 0
|
|
464
|
+
t_live: .text "D018=1C COPY LIVE "
|
|
465
|
+
.fill 8, MARK
|
|
466
|
+
.byte 0
|
|
467
|
+
t_nosei: .text "NO SEI COPY:"
|
|
468
|
+
.byte 0
|
|
469
|
+
t_caught: .text "CAUGHT BY NMI"
|
|
470
|
+
.byte 0
|
|
471
|
+
t_completed: .text "COMPLETED"
|
|
472
|
+
.byte 0
|
|
473
|
+
t_irqs: .text "IRQ PASSES"
|
|
474
|
+
.byte 0
|
|
475
|
+
t_iter: .text "ITERATIONS"
|
|
476
|
+
.byte 0
|
|
477
|
+
t_keys: .text "KEYS QUEUED"
|
|
478
|
+
.byte 0
|
|
479
|
+
|
|
480
|
+
t_2k_on: .byte 0, 0, 0
|
|
481
|
+
t_2k_off: .byte 0, 0, 0
|
|
482
|
+
t_4k_on: .byte 0, 0, 0
|
|
483
|
+
t_empty: .byte 0, 0, 0
|
|
484
|
+
sum: .byte 0, 0
|
|
485
|
+
sum_ok: .byte 0
|
|
486
|
+
irq_count: .byte 0, 0
|
|
487
|
+
progress: .byte 0
|
|
488
|
+
completed: .byte 0
|
|
489
|
+
saved_sp: .byte 0
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
## Build
|
|
493
|
+
|
|
494
|
+
```bash
|
|
495
|
+
java -jar KickAss.jar charset-copy-rom-to-ram.asm -o charset-copy-rom-to-ram.prg
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
Produces `charset-copy-rom-to-ram.prg`, `$0801` to `$0E53`, 1,621 bytes
|
|
499
|
+
on disk.
|
|
500
|
+
|
|
501
|
+
## Expected output
|
|
502
|
+
|
|
503
|
+
Border green, text white on the power-on blue. PAL (VICE x64sc 3.10,
|
|
504
|
+
`-limitcycles 8000000`; the screenshot is
|
|
505
|
+
`screenshots/charset-copy-rom-to-ram.png`):
|
|
506
|
+
|
|
507
|
+
```
|
|
508
|
+
CHARSET COPY ROM TO RAM
|
|
509
|
+
|
|
510
|
+
SUM F7F8 PASS
|
|
511
|
+
2K ON 005141
|
|
512
|
+
2K OFF 004D26
|
|
513
|
+
4K ON 009AAD
|
|
514
|
+
EMPTY 000011
|
|
515
|
+
D018=1C COPY LIVE ████████
|
|
516
|
+
|
|
517
|
+
NO SEI COPY: CAUGHT BY NMI
|
|
518
|
+
IRQ PASSES 001A
|
|
519
|
+
ITERATIONS 1E
|
|
520
|
+
KEYS QUEUED 01
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
The eight cells after `COPY LIVE` are screen code `$66`, a checkerboard
|
|
524
|
+
in the ROM; every pixel of them is white in the screenshot because the
|
|
525
|
+
program overwrote that glyph in the RAM copy after the `$D018` switch.
|
|
526
|
+
Measured with PIL over the 8 × 64 pixels on both models.
|
|
527
|
+
|
|
528
|
+
NTSC (`-model ntsc`, `screenshots/charset-copy-rom-to-ram-ntsc.png`)
|
|
529
|
+
differs on four lines: `2K ON 0052AF`, `4K ON 009D5C`, `IRQ PASSES 001B`,
|
|
530
|
+
`ITERATIONS 07`. `2K OFF`, `EMPTY`, the checksum and `KEYS QUEUED` are
|
|
531
|
+
the same on both models.
|
|
532
|
+
|
|
533
|
+
Each figure was produced twice per model with identical PNG bytes.
|
|
534
|
+
In decimal, with the 17-cycle window overhead (`EMPTY`) taken off:
|
|
535
|
+
|
|
536
|
+
| Measurement | PAL | NTSC | Arithmetic |
|
|
537
|
+
|---|---|---|---|
|
|
538
|
+
| 2 KB copy, display blanked | 19,733 | 19,733 | 19,733 |
|
|
539
|
+
| 2 KB copy, display on | 20,784 | 21,150 | 19,733 + badlines |
|
|
540
|
+
| 4 KB copy, display on | 39,580 | 40,267 | 38,165 + badlines |
|
|
541
|
+
| Unprotected copy: loop iterations before the first IRQ (of 256) | 30 | 7 | phase-dependent |
|
|
542
|
+
| Unprotected copy: IRQ handler passes before the watchdog | 26 | 27 | |
|
|
543
|
+
| Keyboard buffer bytes after recovery | 1 | 1 | |
|
|
544
|
+
|
|
545
|
+
The arithmetic column is the instruction table: eight `LDA abs,X` /
|
|
546
|
+
`STA abs,X` pairs at 9 cycles, `INX` and a taken `BNE` at 5, 256
|
|
547
|
+
iterations less the last branch not taken, 19,711; the bank switch in
|
|
548
|
+
(12) and out (10) make 19,733. The 4 KB loop is 16 pairs, 38,143 + 22.
|
|
549
|
+
The 4 KB copy with the display blanked was not measured here.
|
|
550
|
+
|
|
551
|
+
## Why this works
|
|
552
|
+
|
|
553
|
+
**The technique.** `CopyRom` reads `$01`, clears bits 0-2 and sets
|
|
554
|
+
`$33`: CHAREN low, HIRAM and LORAM high, so `$D000-$DFFF` reads the
|
|
555
|
+
character ROM while BASIC and KERNAL stay in place. The copy is a plain
|
|
556
|
+
indexed loop, one page per load/store pair. Then `$01` goes back to
|
|
557
|
+
`$37`. Bits 3-5 are preserved by the read-modify-write; a bare
|
|
558
|
+
`LDA #$33 / STA $01` would also work on a machine with no datasette
|
|
559
|
+
running but the habit costs nothing. The caller holds `SEI` from before
|
|
560
|
+
the switch to after the restore; `Time` does that here, and a program
|
|
561
|
+
that is not timing anything does `SEI / CopyRom / CLI`.
|
|
562
|
+
|
|
563
|
+
**Why the interrupt flag matters.** While `$01` is `$33` there is no
|
|
564
|
+
I/O in the map. The KERNAL IRQ fires from CIA1 timer A, which the
|
|
565
|
+
KERNAL latches with `$4025` on PAL and `$4295` on NTSC (the writes are
|
|
566
|
+
at `$FDE2` and `$FDEC` in the 901227-03 image), a period of about
|
|
567
|
+
16,400 and 17,000 cycles; its handler ends by reading `$DC0D` to
|
|
568
|
+
acknowledge the timer. With the ROM mapped, that read returns a font
|
|
569
|
+
byte, the CIA flag is never cleared, `/IRQ` stays low, and the handler
|
|
570
|
+
is re-entered the moment `RTI` clears the I flag. The main program never
|
|
571
|
+
gets another instruction. The recipe shows this as measured, not as a
|
|
572
|
+
warning: the unprotected copy managed 30 of 256 iterations on PAL
|
|
573
|
+
(7 on NTSC; the count depends only on where in the timer period the
|
|
574
|
+
copy started), the handler then ran 26 times in the 61,000 cycles that
|
|
575
|
+
remained before the watchdog, and the copy never advanced. Along the
|
|
576
|
+
way the KERNAL keyboard scan read its column byte from the ROM instead
|
|
577
|
+
of CIA1 port B, decoded a key nobody pressed, and left one byte in the
|
|
578
|
+
keyboard buffer (`$C6` = 1 on both models). What that key was is not
|
|
579
|
+
measured here. Pitfall `irq_during_charen_window` has the mechanism.
|
|
580
|
+
|
|
581
|
+
**How the crash is caught.** The watchdog is CIA2 timer A, one-shot,
|
|
582
|
+
65,535 cycles, with its interrupt enabled: CIA2 drives `/NMI`, and an
|
|
583
|
+
NMI cannot be masked. The KERNAL NMI entry at `$FE43` jumps through
|
|
584
|
+
`$0318`, which the recipe points at `nmi_catch`. The catcher restores
|
|
585
|
+
`$37` first, because until it does neither CIA is reachable; then it
|
|
586
|
+
reads `$DD0D` to drop the watchdog and `$DC0D` to drop the stuck IRQ,
|
|
587
|
+
reloads the stack pointer saved before the copy, and falls into the
|
|
588
|
+
same recovery code the completed path would take. The completed path
|
|
589
|
+
exists so that the assertion is real: if a future machine or a future
|
|
590
|
+
KERNAL let the copy finish, the screen would say `COMPLETED` and the
|
|
591
|
+
verdict would be `FAIL`, because the page's claim would then be wrong.
|
|
592
|
+
|
|
593
|
+
**Why the timing window holds `SEI`.** An earlier build of this program
|
|
594
|
+
put `SEI` and `CLI` inside the copy routine and measured 468 cycles too
|
|
595
|
+
many: a KERNAL IRQ falls due during any copy longer than one timer
|
|
596
|
+
period, and it ran at the `CLI`, inside the window. The pinned listing
|
|
597
|
+
holds `SEI` across the timer start and the timer read, so the figure is
|
|
598
|
+
the routine alone. A second earlier figure, 20,005 for the blanked 2 KB
|
|
599
|
+
copy, was 255 too many for a different reason: that build's loop branch
|
|
600
|
+
crossed a page boundary and paid one cycle on each of the 255 taken
|
|
601
|
+
branches (pitfall `branch_page_cross_extra_cycle`). The final layout has
|
|
602
|
+
all three loop branches on one page, checked from the symbol file. The
|
|
603
|
+
display-on figures are larger by the badlines the window spans, about
|
|
604
|
+
1,050 cycles on PAL for the 2 KB copy; blank the display (`$D011` bit 4)
|
|
605
|
+
and wait for a frame past line `$30` if the copy has to be fast, or put
|
|
606
|
+
it before the display is turned on.
|
|
607
|
+
|
|
608
|
+
**The checksum.** The host figure is one line:
|
|
609
|
+
`python3 -c "print(hex(sum(open('chargen-901225-01.bin','rb').read()) & 0xffff))"`
|
|
610
|
+
over the VICE image `/opt/homebrew/opt/vice/share/vice/C64/chargen-901225-01.bin`,
|
|
611
|
+
which gives `0xf7f8`; the program sums the 4,096 bytes at `$3000` the
|
|
612
|
+
same way. A 16-bit sum is not a strong hash, but here the alternative
|
|
613
|
+
failure is not a subtle one: a copy made with `$01` = `$37` reads VIC,
|
|
614
|
+
SID and CIA registers, and a copy that was cut short leaves whatever was
|
|
615
|
+
in RAM. Either moves the sum.
|
|
616
|
+
|
|
617
|
+
**The switch.** `$D018` = `$1C` keeps the screen at `$0400` and sets the
|
|
618
|
+
character base to `$3000` inside VIC bank 0 (CB field %110, × `$0800`).
|
|
619
|
+
The VIC reads the copy from the next character fetch; the program then
|
|
620
|
+
writes eight `$FF` bytes at `$3000 + $66 × 8`, and the eight `$66` cells
|
|
621
|
+
already on the screen turn solid. The font at `$1000-$1FFF` in the same
|
|
622
|
+
bank is the ROM shadow (technique `char_rom_under_vic`); the copy has to
|
|
623
|
+
sit outside it, and `$3000-$3FFF` does.
|