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,926 @@
|
|
|
1
|
+
---
|
|
2
|
+
recipe: light-pen-read
|
|
3
|
+
toolchain: kickassembler
|
|
4
|
+
output_format: PRG
|
|
5
|
+
region: both
|
|
6
|
+
techniques: [light_pen_read]
|
|
7
|
+
file_formats: [PRG]
|
|
8
|
+
uses_registers: [D013, D014, D019, D01A, D011, D012, DC00, DC01, DC0D, DD04, DD05, DD0E, D020, D021]
|
|
9
|
+
uses_kernal: []
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
<!-- doc-type: recipe -->
|
|
13
|
+
|
|
14
|
+
# KickAssembler — Read the light pen latch on control port 1, count its interrupts, and convert the latch to a text cell
|
|
15
|
+
|
|
16
|
+
## Synopsis
|
|
17
|
+
|
|
18
|
+
Enables the VIC's light pen interrupt (`$D01A` bit 3), reads the latched
|
|
19
|
+
`$D013` and `$D014` once per frame for 300 frames, counts the pen
|
|
20
|
+
interrupts and how often the latch moved, and prints the port's switch
|
|
21
|
+
byte and the interrupt flag register at the end. It then runs eight
|
|
22
|
+
synthetic latch values through the pen-delay correction and the
|
|
23
|
+
two-pixel-unit conversion to a text column and row, and times the
|
|
24
|
+
interrupt handler with a CIA2 timer. It writes `$01` to `$02FF` and turns
|
|
25
|
+
the border green when every synthetic row matches and the register
|
|
26
|
+
readings are consistent, `$02` and red otherwise. The technique is
|
|
27
|
+
`light_pen_read` in `techniques/input.md`.
|
|
28
|
+
|
|
29
|
+
A headless VICE run has no host mouse, and VICE's light pen follows the
|
|
30
|
+
host mouse, so the pen never triggers here: the run measures the resting
|
|
31
|
+
registers, the count of zero and the flag, and says so. The handler's
|
|
32
|
+
cost is measured by entering the same handler from a raster interrupt,
|
|
33
|
+
because nothing in software can pull the pen line low.
|
|
34
|
+
|
|
35
|
+
## Source
|
|
36
|
+
|
|
37
|
+
```asm
|
|
38
|
+
// light-pen-read.asm
|
|
39
|
+
// Enables the VIC's light pen interrupt, records the latched LPX/LPY
|
|
40
|
+
// ($D013/$D014) once per frame over NFRAMES frames, counts the pen
|
|
41
|
+
// interrupts, runs a table of synthetic latch values through the
|
|
42
|
+
// pen-delay correction and the two-pixel-unit conversion to a text cell,
|
|
43
|
+
// times the interrupt handler with a CIA2 timer, and reports a verdict at
|
|
44
|
+
// $02FF and in the border colour.
|
|
45
|
+
//
|
|
46
|
+
// The pen is on control port 1: its trigger is the port's FIRE line, CIA1
|
|
47
|
+
// PB4, which is also the VIC's LP input. The KERNAL IRQ is turned off so
|
|
48
|
+
// the keyboard scan cannot drive $DC00 while the port is read.
|
|
49
|
+
.encoding "screencode_upper"
|
|
50
|
+
|
|
51
|
+
.const SCREEN = $0400
|
|
52
|
+
.const RESULT = $02ff
|
|
53
|
+
.const NFRAMES = 300 // frames sampled at rest
|
|
54
|
+
.const READ_LINE = $fa // raster line 250: below the text area, inside both models' frames
|
|
55
|
+
.const PEN_DELAY = 0 // the pen's own latch delay in LPX units; per pen, 0 here
|
|
56
|
+
.const NTESTS = 8 // rows in the synthetic table
|
|
57
|
+
.const COST_LINE = 25 // the raster line that drives the handler for the cost measurement
|
|
58
|
+
.const OFF = $ff // "outside the text area" in the expected columns
|
|
59
|
+
|
|
60
|
+
.const zp_val = $fb // 16-bit value for the decimal printer
|
|
61
|
+
.const zp_row = $fd // screen pointer for the printers
|
|
62
|
+
.const zp_lbl = $f7 // pointer into the label table
|
|
63
|
+
.const zp_fail = $f9
|
|
64
|
+
.const zp_tmp = $fa
|
|
65
|
+
|
|
66
|
+
BasicUpstart2(start)
|
|
67
|
+
|
|
68
|
+
* = $0900 "code"
|
|
69
|
+
|
|
70
|
+
start:
|
|
71
|
+
sei
|
|
72
|
+
lda #$7f
|
|
73
|
+
sta $dc0d // CIA1 interrupts off: no keyboard scan on $DC00
|
|
74
|
+
lda $dc0d // drop a pending one
|
|
75
|
+
lda #$00
|
|
76
|
+
sta $d020
|
|
77
|
+
sta $d021
|
|
78
|
+
sta zp_fail
|
|
79
|
+
jsr clear_screen
|
|
80
|
+
jsr draw_labels
|
|
81
|
+
|
|
82
|
+
lda #<irq
|
|
83
|
+
sta $0314
|
|
84
|
+
lda #>irq
|
|
85
|
+
sta $0315
|
|
86
|
+
lda #$ff
|
|
87
|
+
sta $d019 // acknowledge anything pending
|
|
88
|
+
lda #$08
|
|
89
|
+
sta $d01a // ELP only: the light pen is the one VIC source
|
|
90
|
+
cli
|
|
91
|
+
|
|
92
|
+
// --- part A: NFRAMES frames at rest, the latch read once per frame ------
|
|
93
|
+
lda $d013
|
|
94
|
+
sta first_x
|
|
95
|
+
sta min_x
|
|
96
|
+
sta max_x
|
|
97
|
+
sta last_x
|
|
98
|
+
lda $d014
|
|
99
|
+
sta first_y
|
|
100
|
+
sta min_y
|
|
101
|
+
sta max_y
|
|
102
|
+
sta last_y
|
|
103
|
+
lda #0
|
|
104
|
+
sta chg_x
|
|
105
|
+
sta chg_y
|
|
106
|
+
sta frames
|
|
107
|
+
sta frames+1
|
|
108
|
+
frameloop:
|
|
109
|
+
jsr wait_read_line
|
|
110
|
+
lda $d013
|
|
111
|
+
cmp last_x
|
|
112
|
+
beq !+
|
|
113
|
+
inc chg_x
|
|
114
|
+
!: sta last_x
|
|
115
|
+
cmp min_x
|
|
116
|
+
bcs !+
|
|
117
|
+
sta min_x
|
|
118
|
+
!: lda last_x
|
|
119
|
+
cmp max_x
|
|
120
|
+
bcc !+
|
|
121
|
+
sta max_x
|
|
122
|
+
!: lda $d014
|
|
123
|
+
cmp last_y
|
|
124
|
+
beq !+
|
|
125
|
+
inc chg_y
|
|
126
|
+
!: sta last_y
|
|
127
|
+
cmp min_y
|
|
128
|
+
bcs !+
|
|
129
|
+
sta min_y
|
|
130
|
+
!: lda last_y
|
|
131
|
+
cmp max_y
|
|
132
|
+
bcc !+
|
|
133
|
+
sta max_y
|
|
134
|
+
!: inc frames
|
|
135
|
+
bne !+
|
|
136
|
+
inc frames+1
|
|
137
|
+
!: lda frames
|
|
138
|
+
cmp #<NFRAMES
|
|
139
|
+
bne frameloop
|
|
140
|
+
lda frames+1
|
|
141
|
+
cmp #>NFRAMES
|
|
142
|
+
bne frameloop
|
|
143
|
+
|
|
144
|
+
sei
|
|
145
|
+
lda #$00
|
|
146
|
+
sta $d01a // pen IRQ off; the count is final
|
|
147
|
+
lda irq_count
|
|
148
|
+
sta pen_irqs
|
|
149
|
+
lda irq_count+1
|
|
150
|
+
sta pen_irqs+1
|
|
151
|
+
lda $d019
|
|
152
|
+
sta d019_end // bit 3 set here means a trigger since the last acknowledge
|
|
153
|
+
|
|
154
|
+
lda #<NFRAMES
|
|
155
|
+
sta zp_val
|
|
156
|
+
lda #>NFRAMES
|
|
157
|
+
sta zp_val+1
|
|
158
|
+
ldy #2
|
|
159
|
+
ldx #19
|
|
160
|
+
jsr print_dec5
|
|
161
|
+
lda pen_irqs
|
|
162
|
+
sta zp_val
|
|
163
|
+
lda pen_irqs+1
|
|
164
|
+
sta zp_val+1
|
|
165
|
+
ldy #3
|
|
166
|
+
ldx #19
|
|
167
|
+
jsr print_dec5
|
|
168
|
+
lda first_x
|
|
169
|
+
ldy #4
|
|
170
|
+
ldx #19
|
|
171
|
+
jsr print_hex
|
|
172
|
+
lda min_x
|
|
173
|
+
ldy #4
|
|
174
|
+
ldx #23
|
|
175
|
+
jsr print_hex
|
|
176
|
+
lda max_x
|
|
177
|
+
ldy #4
|
|
178
|
+
ldx #27
|
|
179
|
+
jsr print_hex
|
|
180
|
+
lda first_y
|
|
181
|
+
ldy #5
|
|
182
|
+
ldx #19
|
|
183
|
+
jsr print_hex
|
|
184
|
+
lda min_y
|
|
185
|
+
ldy #5
|
|
186
|
+
ldx #23
|
|
187
|
+
jsr print_hex
|
|
188
|
+
lda max_y
|
|
189
|
+
ldy #5
|
|
190
|
+
ldx #27
|
|
191
|
+
jsr print_hex
|
|
192
|
+
lda chg_x
|
|
193
|
+
ldy #6
|
|
194
|
+
ldx #19
|
|
195
|
+
jsr print_hex
|
|
196
|
+
lda chg_y
|
|
197
|
+
ldy #6
|
|
198
|
+
ldx #27
|
|
199
|
+
jsr print_hex
|
|
200
|
+
lda d019_end
|
|
201
|
+
ldy #7
|
|
202
|
+
ldx #6
|
|
203
|
+
jsr print_hex
|
|
204
|
+
lda $dc01
|
|
205
|
+
ldy #7
|
|
206
|
+
ldx #19
|
|
207
|
+
jsr print_hex
|
|
208
|
+
lda $dc00
|
|
209
|
+
ldy #7
|
|
210
|
+
ldx #32
|
|
211
|
+
jsr print_hex
|
|
212
|
+
|
|
213
|
+
// the consistency rule: the latch does not move at rest, and the pen
|
|
214
|
+
// interrupt count is either the frame count (one trigger a frame, within
|
|
215
|
+
// one) or zero with the flag clear (no trigger at all). Anything between
|
|
216
|
+
// is a pen that triggers on some frames only, and the rule fails.
|
|
217
|
+
lda min_x
|
|
218
|
+
cmp max_x
|
|
219
|
+
bne rest_bad
|
|
220
|
+
lda min_y
|
|
221
|
+
cmp max_y
|
|
222
|
+
bne rest_bad
|
|
223
|
+
lda pen_irqs+1
|
|
224
|
+
ora pen_irqs
|
|
225
|
+
bne count_some
|
|
226
|
+
lda d019_end
|
|
227
|
+
and #$08
|
|
228
|
+
beq rest_ok // zero triggers and no flag: consistent
|
|
229
|
+
bne rest_bad
|
|
230
|
+
count_some:
|
|
231
|
+
sec
|
|
232
|
+
lda #<NFRAMES
|
|
233
|
+
sbc pen_irqs
|
|
234
|
+
sta zp_tmp
|
|
235
|
+
lda #>NFRAMES
|
|
236
|
+
sbc pen_irqs+1
|
|
237
|
+
bne rest_bad // more than 255 apart, or the count exceeds the frames
|
|
238
|
+
lda zp_tmp
|
|
239
|
+
cmp #2
|
|
240
|
+
bcc rest_ok // 0 or 1 frames short: one trigger a frame
|
|
241
|
+
rest_bad:
|
|
242
|
+
inc zp_fail
|
|
243
|
+
rest_ok:
|
|
244
|
+
|
|
245
|
+
// --- part B: synthetic latch values through the conversion ---------------
|
|
246
|
+
ldx #0
|
|
247
|
+
testloop:
|
|
248
|
+
stx tidx
|
|
249
|
+
lda test_lpx,x
|
|
250
|
+
jsr test_row_y
|
|
251
|
+
ldx #2
|
|
252
|
+
jsr print_hex
|
|
253
|
+
ldx tidx
|
|
254
|
+
lda test_lpy,x
|
|
255
|
+
jsr test_row_y
|
|
256
|
+
ldx #7
|
|
257
|
+
jsr print_hex
|
|
258
|
+
ldx tidx
|
|
259
|
+
lda test_lpx,x
|
|
260
|
+
jsr lpx_to_col // A = column or OFF
|
|
261
|
+
sta got_col
|
|
262
|
+
jsr test_row_y
|
|
263
|
+
ldx #12
|
|
264
|
+
jsr print_cell
|
|
265
|
+
ldx tidx
|
|
266
|
+
lda test_lpy,x
|
|
267
|
+
jsr lpy_to_row // A = row or OFF
|
|
268
|
+
sta got_row
|
|
269
|
+
jsr test_row_y
|
|
270
|
+
ldx #16
|
|
271
|
+
jsr print_cell
|
|
272
|
+
ldx tidx
|
|
273
|
+
lda exp_col,x
|
|
274
|
+
jsr test_row_y
|
|
275
|
+
ldx #21
|
|
276
|
+
jsr print_cell
|
|
277
|
+
ldx tidx
|
|
278
|
+
lda exp_row,x
|
|
279
|
+
jsr test_row_y
|
|
280
|
+
ldx #25
|
|
281
|
+
jsr print_cell
|
|
282
|
+
ldx tidx
|
|
283
|
+
lda got_col
|
|
284
|
+
cmp exp_col,x
|
|
285
|
+
bne test_bad
|
|
286
|
+
lda got_row
|
|
287
|
+
cmp exp_row,x
|
|
288
|
+
bne test_bad
|
|
289
|
+
lda #<txt_ok
|
|
290
|
+
ldy #>txt_ok
|
|
291
|
+
bne test_show
|
|
292
|
+
test_bad:
|
|
293
|
+
inc zp_fail
|
|
294
|
+
lda #<txt_bad
|
|
295
|
+
ldy #>txt_bad
|
|
296
|
+
test_show:
|
|
297
|
+
sta zp_lbl
|
|
298
|
+
sty zp_lbl+1
|
|
299
|
+
jsr test_row_y
|
|
300
|
+
ldx #29
|
|
301
|
+
jsr print_str
|
|
302
|
+
ldx tidx
|
|
303
|
+
inx
|
|
304
|
+
cpx #NTESTS
|
|
305
|
+
beq tests_done
|
|
306
|
+
jmp testloop
|
|
307
|
+
tests_done:
|
|
308
|
+
|
|
309
|
+
// --- part C: the handler's cost, measured with CIA2 timer A --------------
|
|
310
|
+
// The pen line cannot be pulsed from software, so the same handler is
|
|
311
|
+
// entered from a raster interrupt on COST_LINE instead: the entry, the
|
|
312
|
+
// KERNAL dispatch, the handler's reads and stores and the exit through
|
|
313
|
+
// $EA81 are the same instructions whichever $D019 bit set. A fixed loop is
|
|
314
|
+
// timed twice from raster line 5 in the top border, where no badline can
|
|
315
|
+
// stretch it: once with no interrupt armed, once with the raster interrupt
|
|
316
|
+
// armed inside the loop's span. The difference is the interrupt's cost.
|
|
317
|
+
lda #$00
|
|
318
|
+
sta $dd0e
|
|
319
|
+
lda #$ff
|
|
320
|
+
sta $dd04
|
|
321
|
+
sta $dd05
|
|
322
|
+
lda #5
|
|
323
|
+
jsr wait_line
|
|
324
|
+
lda #$11 // start, force load, continuous
|
|
325
|
+
sta $dd0e
|
|
326
|
+
jsr fixed_loop
|
|
327
|
+
lda #$00
|
|
328
|
+
sta $dd0e
|
|
329
|
+
sec
|
|
330
|
+
lda #$ff
|
|
331
|
+
sbc $dd04
|
|
332
|
+
sta base_lo
|
|
333
|
+
lda #$ff
|
|
334
|
+
sbc $dd05
|
|
335
|
+
sta base_hi
|
|
336
|
+
|
|
337
|
+
lda #$ff
|
|
338
|
+
sta $dd04
|
|
339
|
+
sta $dd05
|
|
340
|
+
lda #COST_LINE
|
|
341
|
+
sta $d012
|
|
342
|
+
lda $d011
|
|
343
|
+
and #$7f
|
|
344
|
+
sta $d011
|
|
345
|
+
lda #$ff
|
|
346
|
+
sta $d019
|
|
347
|
+
lda #$01
|
|
348
|
+
sta $d01a // ERST: the raster interrupt drives the handler once
|
|
349
|
+
lda #5
|
|
350
|
+
jsr wait_line
|
|
351
|
+
cli
|
|
352
|
+
lda #$11
|
|
353
|
+
sta $dd0e
|
|
354
|
+
jsr fixed_loop
|
|
355
|
+
lda #$00
|
|
356
|
+
sta $dd0e
|
|
357
|
+
sei
|
|
358
|
+
lda #$00
|
|
359
|
+
sta $d01a
|
|
360
|
+
sec
|
|
361
|
+
lda #$ff
|
|
362
|
+
sbc $dd04
|
|
363
|
+
sta cost_lo
|
|
364
|
+
lda #$ff
|
|
365
|
+
sbc $dd05
|
|
366
|
+
sta cost_hi
|
|
367
|
+
|
|
368
|
+
lda base_lo
|
|
369
|
+
sta zp_val
|
|
370
|
+
lda base_hi
|
|
371
|
+
sta zp_val+1
|
|
372
|
+
ldy #21
|
|
373
|
+
ldx #9
|
|
374
|
+
jsr print_dec5
|
|
375
|
+
lda cost_lo
|
|
376
|
+
sta zp_val
|
|
377
|
+
lda cost_hi
|
|
378
|
+
sta zp_val+1
|
|
379
|
+
ldy #21
|
|
380
|
+
ldx #24
|
|
381
|
+
jsr print_dec5
|
|
382
|
+
sec
|
|
383
|
+
lda cost_lo
|
|
384
|
+
sbc base_lo
|
|
385
|
+
sta zp_val
|
|
386
|
+
lda cost_hi
|
|
387
|
+
sbc base_hi
|
|
388
|
+
sta zp_val+1
|
|
389
|
+
ldy #20
|
|
390
|
+
ldx #13
|
|
391
|
+
jsr print_dec5
|
|
392
|
+
|
|
393
|
+
// --- verdict --------------------------------------------------------------
|
|
394
|
+
lda zp_fail
|
|
395
|
+
bne fail
|
|
396
|
+
lda #$01
|
|
397
|
+
sta RESULT
|
|
398
|
+
lda #$05
|
|
399
|
+
sta $d020
|
|
400
|
+
lda #<txt_pass
|
|
401
|
+
ldy #>txt_pass
|
|
402
|
+
jmp verdict
|
|
403
|
+
fail:
|
|
404
|
+
lda #$02
|
|
405
|
+
sta RESULT
|
|
406
|
+
lda #$02
|
|
407
|
+
sta $d020
|
|
408
|
+
lda #<txt_fail
|
|
409
|
+
ldy #>txt_fail
|
|
410
|
+
verdict:
|
|
411
|
+
sta zp_lbl
|
|
412
|
+
sty zp_lbl+1
|
|
413
|
+
ldy #23
|
|
414
|
+
ldx #8
|
|
415
|
+
jsr print_str
|
|
416
|
+
forever:
|
|
417
|
+
jmp forever
|
|
418
|
+
|
|
419
|
+
// --- the handler ------------------------------------------------------------
|
|
420
|
+
// Entered through $0314 after the KERNAL's $FF48 has pushed A, X and Y.
|
|
421
|
+
// Acknowledge every set bit by writing $D019's own value back, copy the
|
|
422
|
+
// latch, count, and leave through the KERNAL's bare exit.
|
|
423
|
+
irq:
|
|
424
|
+
lda $d019
|
|
425
|
+
sta $d019
|
|
426
|
+
lda $d013
|
|
427
|
+
sta pen_x
|
|
428
|
+
lda $d014
|
|
429
|
+
sta pen_y
|
|
430
|
+
inc irq_count
|
|
431
|
+
bne !+
|
|
432
|
+
inc irq_count+1
|
|
433
|
+
!: jmp $ea81
|
|
434
|
+
|
|
435
|
+
// --- the conversion ---------------------------------------------------------
|
|
436
|
+
// lpx_to_col: A = LPX. Subtract the pen's delay, then the latch is X/2 and
|
|
437
|
+
// the text area starts at X = 24, so column = (LPX - 12) / 4. Below 12 or
|
|
438
|
+
// at 40 or more the point is outside the text area and OFF comes back.
|
|
439
|
+
lpx_to_col:
|
|
440
|
+
sec
|
|
441
|
+
sbc #PEN_DELAY
|
|
442
|
+
bcc lpx_off
|
|
443
|
+
sec
|
|
444
|
+
sbc #12
|
|
445
|
+
bcc lpx_off
|
|
446
|
+
lsr
|
|
447
|
+
lsr
|
|
448
|
+
cmp #40
|
|
449
|
+
bcs lpx_off
|
|
450
|
+
rts
|
|
451
|
+
lpx_off:
|
|
452
|
+
lda #OFF
|
|
453
|
+
rts
|
|
454
|
+
|
|
455
|
+
// lpy_to_row: A = LPY, the raster line. The text area is lines 51 to 250,
|
|
456
|
+
// so row = (LPY - 51) / 8; outside that range OFF comes back.
|
|
457
|
+
lpy_to_row:
|
|
458
|
+
sec
|
|
459
|
+
sbc #51
|
|
460
|
+
bcc lpy_off
|
|
461
|
+
cmp #200
|
|
462
|
+
bcs lpy_off
|
|
463
|
+
lsr
|
|
464
|
+
lsr
|
|
465
|
+
lsr
|
|
466
|
+
rts
|
|
467
|
+
lpy_off:
|
|
468
|
+
lda #OFF
|
|
469
|
+
rts
|
|
470
|
+
|
|
471
|
+
// fixed_loop: a loop of fixed length, long enough to span COST_LINE from
|
|
472
|
+
// line 5 on both models. Its own length cancels out of the measurement.
|
|
473
|
+
fixed_loop:
|
|
474
|
+
ldx #2
|
|
475
|
+
ldy #0
|
|
476
|
+
!: dey
|
|
477
|
+
bne !-
|
|
478
|
+
dex
|
|
479
|
+
bne !-
|
|
480
|
+
rts
|
|
481
|
+
|
|
482
|
+
// test_row_y: Y = 11 + tidx, the screen row of the current table entry.
|
|
483
|
+
test_row_y:
|
|
484
|
+
pha
|
|
485
|
+
lda tidx
|
|
486
|
+
clc
|
|
487
|
+
adc #11
|
|
488
|
+
tay
|
|
489
|
+
pla
|
|
490
|
+
rts
|
|
491
|
+
|
|
492
|
+
// wait_read_line: spin until the raster reaches READ_LINE, having first
|
|
493
|
+
// left it, so consecutive calls land in consecutive frames.
|
|
494
|
+
wait_read_line:
|
|
495
|
+
lda #READ_LINE
|
|
496
|
+
wait_line:
|
|
497
|
+
!: cmp $d012
|
|
498
|
+
beq !-
|
|
499
|
+
!: cmp $d012
|
|
500
|
+
bne !-
|
|
501
|
+
rts
|
|
502
|
+
|
|
503
|
+
// --- printers -------------------------------------------------------------
|
|
504
|
+
set_row:
|
|
505
|
+
lda #<SCREEN
|
|
506
|
+
sta zp_row
|
|
507
|
+
lda #>SCREEN
|
|
508
|
+
sta zp_row+1
|
|
509
|
+
tya
|
|
510
|
+
beq set_row_col
|
|
511
|
+
set_row_next:
|
|
512
|
+
lda zp_row
|
|
513
|
+
clc
|
|
514
|
+
adc #40
|
|
515
|
+
sta zp_row
|
|
516
|
+
bcc set_row_dey
|
|
517
|
+
inc zp_row+1
|
|
518
|
+
set_row_dey:
|
|
519
|
+
dey
|
|
520
|
+
bne set_row_next
|
|
521
|
+
set_row_col:
|
|
522
|
+
txa
|
|
523
|
+
clc
|
|
524
|
+
adc zp_row
|
|
525
|
+
sta zp_row
|
|
526
|
+
bcc set_row_done
|
|
527
|
+
inc zp_row+1
|
|
528
|
+
set_row_done:
|
|
529
|
+
rts
|
|
530
|
+
|
|
531
|
+
// print_hex: A = byte, row Y, column X.
|
|
532
|
+
print_hex:
|
|
533
|
+
pha
|
|
534
|
+
jsr set_row
|
|
535
|
+
pla
|
|
536
|
+
pha
|
|
537
|
+
lsr
|
|
538
|
+
lsr
|
|
539
|
+
lsr
|
|
540
|
+
lsr
|
|
541
|
+
tax
|
|
542
|
+
lda hexdigits,x
|
|
543
|
+
ldy #0
|
|
544
|
+
sta (zp_row),y
|
|
545
|
+
pla
|
|
546
|
+
and #$0f
|
|
547
|
+
tax
|
|
548
|
+
lda hexdigits,x
|
|
549
|
+
iny
|
|
550
|
+
sta (zp_row),y
|
|
551
|
+
rts
|
|
552
|
+
|
|
553
|
+
// print_cell: A = 0..99 or OFF, row Y, column X: two digits, or "--".
|
|
554
|
+
print_cell:
|
|
555
|
+
cmp #OFF
|
|
556
|
+
bne print_dec2
|
|
557
|
+
jsr set_row
|
|
558
|
+
lda #$2d
|
|
559
|
+
ldy #0
|
|
560
|
+
sta (zp_row),y
|
|
561
|
+
iny
|
|
562
|
+
sta (zp_row),y
|
|
563
|
+
rts
|
|
564
|
+
|
|
565
|
+
// print_dec2: A = 0..99, row Y, column X: two digits, leading zero.
|
|
566
|
+
print_dec2:
|
|
567
|
+
pha
|
|
568
|
+
jsr set_row
|
|
569
|
+
pla
|
|
570
|
+
ldx #0
|
|
571
|
+
!: cmp #10
|
|
572
|
+
bcc !+
|
|
573
|
+
sbc #10
|
|
574
|
+
inx
|
|
575
|
+
bne !-
|
|
576
|
+
!: pha
|
|
577
|
+
txa
|
|
578
|
+
ora #$30
|
|
579
|
+
ldy #0
|
|
580
|
+
sta (zp_row),y
|
|
581
|
+
pla
|
|
582
|
+
ora #$30
|
|
583
|
+
iny
|
|
584
|
+
sta (zp_row),y
|
|
585
|
+
rts
|
|
586
|
+
|
|
587
|
+
// print_dec5: zp_val = 16-bit value, row Y, column X: five digits.
|
|
588
|
+
print_dec5:
|
|
589
|
+
jsr set_row
|
|
590
|
+
ldy #0
|
|
591
|
+
ldx #0
|
|
592
|
+
dec5_digit:
|
|
593
|
+
lda #$30
|
|
594
|
+
sta digit
|
|
595
|
+
dec5_sub:
|
|
596
|
+
sec
|
|
597
|
+
lda zp_val
|
|
598
|
+
sbc pow10_lo,x
|
|
599
|
+
pha
|
|
600
|
+
lda zp_val+1
|
|
601
|
+
sbc pow10_hi,x
|
|
602
|
+
bcc dec5_next
|
|
603
|
+
sta zp_val+1
|
|
604
|
+
pla
|
|
605
|
+
sta zp_val
|
|
606
|
+
inc digit
|
|
607
|
+
jmp dec5_sub
|
|
608
|
+
dec5_next:
|
|
609
|
+
pla
|
|
610
|
+
lda digit
|
|
611
|
+
sta (zp_row),y
|
|
612
|
+
iny
|
|
613
|
+
inx
|
|
614
|
+
cpx #5
|
|
615
|
+
bne dec5_digit
|
|
616
|
+
rts
|
|
617
|
+
|
|
618
|
+
// print_str: zp_lbl -> zero-terminated screen-code text, row Y, column X.
|
|
619
|
+
print_str:
|
|
620
|
+
jsr set_row
|
|
621
|
+
ldy #0
|
|
622
|
+
!: lda (zp_lbl),y
|
|
623
|
+
beq !+
|
|
624
|
+
sta (zp_row),y
|
|
625
|
+
iny
|
|
626
|
+
bne !-
|
|
627
|
+
!: rts
|
|
628
|
+
|
|
629
|
+
// draw_labels: walk the label table: row, column, text, 0; a row of $ff ends it.
|
|
630
|
+
draw_labels:
|
|
631
|
+
lda #<labels
|
|
632
|
+
sta zp_lbl
|
|
633
|
+
lda #>labels
|
|
634
|
+
sta zp_lbl+1
|
|
635
|
+
label_next:
|
|
636
|
+
ldy #0
|
|
637
|
+
lda (zp_lbl),y
|
|
638
|
+
cmp #$ff
|
|
639
|
+
beq label_done
|
|
640
|
+
iny
|
|
641
|
+
lda (zp_lbl),y
|
|
642
|
+
tax // X = column
|
|
643
|
+
dey
|
|
644
|
+
lda (zp_lbl),y
|
|
645
|
+
tay // Y = row
|
|
646
|
+
lda zp_lbl
|
|
647
|
+
clc
|
|
648
|
+
adc #2
|
|
649
|
+
sta zp_lbl
|
|
650
|
+
bcc !+
|
|
651
|
+
inc zp_lbl+1
|
|
652
|
+
!: jsr print_str
|
|
653
|
+
ldy #0
|
|
654
|
+
!: lda (zp_lbl),y
|
|
655
|
+
beq !+
|
|
656
|
+
iny
|
|
657
|
+
bne !-
|
|
658
|
+
!: iny
|
|
659
|
+
tya
|
|
660
|
+
clc
|
|
661
|
+
adc zp_lbl
|
|
662
|
+
sta zp_lbl
|
|
663
|
+
bcc label_next
|
|
664
|
+
inc zp_lbl+1
|
|
665
|
+
jmp label_next
|
|
666
|
+
label_done:
|
|
667
|
+
rts
|
|
668
|
+
|
|
669
|
+
clear_screen:
|
|
670
|
+
ldx #0
|
|
671
|
+
lda #$20
|
|
672
|
+
!: sta SCREEN,x
|
|
673
|
+
sta SCREEN+$100,x
|
|
674
|
+
sta SCREEN+$200,x
|
|
675
|
+
sta SCREEN+$300,x
|
|
676
|
+
inx
|
|
677
|
+
bne !-
|
|
678
|
+
rts
|
|
679
|
+
|
|
680
|
+
// --- data -----------------------------------------------------------------
|
|
681
|
+
labels:
|
|
682
|
+
.byte 0, 0
|
|
683
|
+
.text "LIGHT PEN READ, CONTROL PORT 1"
|
|
684
|
+
.byte 0
|
|
685
|
+
.byte 2, 0
|
|
686
|
+
.text "FRAMES SAMPLED"
|
|
687
|
+
.byte 0
|
|
688
|
+
.byte 3, 0
|
|
689
|
+
.text "PEN IRQS COUNTED"
|
|
690
|
+
.byte 0
|
|
691
|
+
.byte 4, 0
|
|
692
|
+
.text "LPX FIRST MIN MAX"
|
|
693
|
+
.byte 0
|
|
694
|
+
.byte 5, 0
|
|
695
|
+
.text "LPY FIRST MIN MAX"
|
|
696
|
+
.byte 0
|
|
697
|
+
.byte 6, 0
|
|
698
|
+
.text "FRAMES LPX MOVED"
|
|
699
|
+
.byte 0
|
|
700
|
+
.byte 6, 23
|
|
701
|
+
.text "LPY"
|
|
702
|
+
.byte 0
|
|
703
|
+
.byte 7, 0
|
|
704
|
+
.text "$D019"
|
|
705
|
+
.byte 0
|
|
706
|
+
.byte 7, 13
|
|
707
|
+
.text "$DC01"
|
|
708
|
+
.byte 0
|
|
709
|
+
.byte 7, 26
|
|
710
|
+
.text "$DC00"
|
|
711
|
+
.byte 0
|
|
712
|
+
.byte 9, 0
|
|
713
|
+
.text "SYNTHETIC LATCH TO TEXT CELL"
|
|
714
|
+
.byte 0
|
|
715
|
+
.byte 10, 0
|
|
716
|
+
.text " LPX LPY COL ROW EXPECTED"
|
|
717
|
+
.byte 0
|
|
718
|
+
.byte 20, 0
|
|
719
|
+
.text "IRQ COST"
|
|
720
|
+
.byte 0
|
|
721
|
+
.byte 20, 19
|
|
722
|
+
.text "CYCLES VIA RASTER"
|
|
723
|
+
.byte 0
|
|
724
|
+
.byte 21, 0
|
|
725
|
+
.text "BASELINE"
|
|
726
|
+
.byte 0
|
|
727
|
+
.byte 21, 15
|
|
728
|
+
.text "WITH IRQ"
|
|
729
|
+
.byte 0
|
|
730
|
+
.byte 23, 0
|
|
731
|
+
.text "RESULT"
|
|
732
|
+
.byte 0
|
|
733
|
+
.byte $ff
|
|
734
|
+
|
|
735
|
+
txt_ok: .text "OK"
|
|
736
|
+
.byte 0
|
|
737
|
+
txt_bad: .text "BAD"
|
|
738
|
+
.byte 0
|
|
739
|
+
txt_pass: .text "PASS"
|
|
740
|
+
.byte 0
|
|
741
|
+
txt_fail: .text "FAIL"
|
|
742
|
+
.byte 0
|
|
743
|
+
hexdigits: .text "0123456789ABCDEF"
|
|
744
|
+
pow10_lo: .byte <10000, <1000, <100, <10, <1
|
|
745
|
+
pow10_hi: .byte >10000, >1000, >100, >10, >1
|
|
746
|
+
|
|
747
|
+
// the synthetic table: latch values and the cell each should land in.
|
|
748
|
+
// $0C,$33 is the top-left corner of the text area; $AB,$FA the bottom-right;
|
|
749
|
+
// $AC,$FB one step past it; $0B,$32 one step before it; $00,$00 the value a
|
|
750
|
+
// pen that never triggered leaves in the registers.
|
|
751
|
+
test_lpx: .byte $0c, $0f, $10, $5c, $ab, $ac, $0b, $00
|
|
752
|
+
test_lpy: .byte $33, $3a, $3b, $95, $fa, $fb, $32, $00
|
|
753
|
+
exp_col: .byte 0, 0, 1, 20, 39, OFF, OFF, OFF
|
|
754
|
+
exp_row: .byte 0, 0, 1, 12, 24, OFF, OFF, OFF
|
|
755
|
+
|
|
756
|
+
digit: .byte 0
|
|
757
|
+
tidx: .byte 0
|
|
758
|
+
got_col: .byte 0
|
|
759
|
+
got_row: .byte 0
|
|
760
|
+
irq_count: .word 0
|
|
761
|
+
pen_irqs: .word 0
|
|
762
|
+
frames: .word 0
|
|
763
|
+
pen_x: .byte 0
|
|
764
|
+
pen_y: .byte 0
|
|
765
|
+
first_x: .byte 0
|
|
766
|
+
min_x: .byte 0
|
|
767
|
+
max_x: .byte 0
|
|
768
|
+
last_x: .byte 0
|
|
769
|
+
first_y: .byte 0
|
|
770
|
+
min_y: .byte 0
|
|
771
|
+
max_y: .byte 0
|
|
772
|
+
last_y: .byte 0
|
|
773
|
+
chg_x: .byte 0
|
|
774
|
+
chg_y: .byte 0
|
|
775
|
+
d019_end: .byte 0
|
|
776
|
+
base_lo: .byte 0
|
|
777
|
+
base_hi: .byte 0
|
|
778
|
+
cost_lo: .byte 0
|
|
779
|
+
cost_hi: .byte 0
|
|
780
|
+
```
|
|
781
|
+
|
|
782
|
+
## Build
|
|
783
|
+
|
|
784
|
+
```bash
|
|
785
|
+
java -jar $KICKASS_JAR light-pen-read.asm -o light-pen-read.prg
|
|
786
|
+
```
|
|
787
|
+
|
|
788
|
+
KickAssembler 5.25 produces a 1,785-byte PRG; the code segment runs
|
|
789
|
+
`$0900` to `$0EF7`.
|
|
790
|
+
|
|
791
|
+
Pinned VICE run (both models, `docs/recipes/runs.json`):
|
|
792
|
+
|
|
793
|
+
```bash
|
|
794
|
+
GSETTINGS_SCHEMA_DIR=/opt/homebrew/share/glib-2.0/schemas \
|
|
795
|
+
x64sc -default -warp +sound +autostart-delay-random -autostartprgmode 1 \
|
|
796
|
+
-limitcycles 12000000 -controlport1device 11 \
|
|
797
|
+
-exitscreenshot light-pen-read.png -autostart light-pen-read.prg
|
|
798
|
+
```
|
|
799
|
+
|
|
800
|
+
Add `-model ntsc` for the second picture. `-controlport1device 11` is
|
|
801
|
+
VICE's "Light Pen (up trigger)" on control port 1; `x64sc -help` (VICE
|
|
802
|
+
3.10) lists six pen and gun devices for port 1, numbers 11 to 16, and
|
|
803
|
+
none for port 2. Nothing is attached to port 2.
|
|
804
|
+
|
|
805
|
+
## Expected output
|
|
806
|
+
|
|
807
|
+
Green border, black background, light blue text. The screen is:
|
|
808
|
+
|
|
809
|
+
```text
|
|
810
|
+
row 0 LIGHT PEN READ, CONTROL PORT 1
|
|
811
|
+
row 2 FRAMES SAMPLED 00300
|
|
812
|
+
row 3 PEN IRQS COUNTED 00000
|
|
813
|
+
row 4 LPX FIRST MIN MAX 00 00 00
|
|
814
|
+
row 5 LPY FIRST MIN MAX 00 00 00
|
|
815
|
+
row 6 FRAMES LPX MOVED 00 LPY 00
|
|
816
|
+
row 7 $D019 71 $DC01 FF $DC00 7F
|
|
817
|
+
row 9 SYNTHETIC LATCH TO TEXT CELL
|
|
818
|
+
row 10 LPX LPY COL ROW EXPECTED
|
|
819
|
+
row 11 0C 33 00 00 00 00 OK
|
|
820
|
+
row 12 0F 3A 00 00 00 00 OK
|
|
821
|
+
row 13 10 3B 01 01 01 01 OK
|
|
822
|
+
row 14 5C 95 20 12 20 12 OK
|
|
823
|
+
row 15 AB FA 39 24 39 24 OK
|
|
824
|
+
row 16 AC FB -- -- -- -- OK
|
|
825
|
+
row 17 0B 32 -- -- -- -- OK
|
|
826
|
+
row 18 00 00 -- -- -- -- OK
|
|
827
|
+
row 20 IRQ COST 00094 CYCLES VIA RASTER
|
|
828
|
+
row 21 BASELINE 02588 WITH IRQ 02682
|
|
829
|
+
row 23 RESULT PASS
|
|
830
|
+
```
|
|
831
|
+
|
|
832
|
+
`recipes/kickassembler/screenshots/light-pen-read.png` (PAL, 384 by
|
|
833
|
+
272) and `light-pen-read-ntsc.png` (NTSC, 384 by 247) were each produced
|
|
834
|
+
twice by the pinned command with identical bytes, and decoded by
|
|
835
|
+
matching every 8 by 8 cell against `chargen-901225-01.bin` (measured in
|
|
836
|
+
VICE x64sc 3.10, rung 1). Every row is the same on both models except
|
|
837
|
+
row 7, where NTSC reads `$D019 70`.
|
|
838
|
+
|
|
839
|
+
What each line shows:
|
|
840
|
+
|
|
841
|
+
- Rows 3 to 6: over 300 frames the pen interrupt fired zero times and
|
|
842
|
+
`$D013` and `$D014` read `$00` on every frame, first, lowest and
|
|
843
|
+
highest, on both models. VICE's light pen takes its position from the
|
|
844
|
+
host mouse, and a headless run has none to move, so the emulated pen
|
|
845
|
+
never triggers. The same zeros came from device 11, the Datel pen
|
|
846
|
+
(13), the Magnum Light Phaser (14) and the Inkwell pen (16) in a
|
|
847
|
+
diagnostic build, PAL and NTSC. What a triggering pen latches, and the
|
|
848
|
+
spread of the latch from frame to frame, is not measured here.
|
|
849
|
+
- Row 7: `$D019` reads `$71` on PAL and `$70` on NTSC after the pen
|
|
850
|
+
interrupt was disabled. Bit 3, the pen flag, is clear on both: no
|
|
851
|
+
trigger happened since the handler's last acknowledge, which agrees
|
|
852
|
+
with the count. Bit 0 is the raster flag; it reads set on PAL and
|
|
853
|
+
clear on NTSC in these runs, nothing in this program arms it before
|
|
854
|
+
that read, and why the two models differ is not established here.
|
|
855
|
+
Bits 4 to 6 are unused and read as ones. `$DC01` is port 1's
|
|
856
|
+
switch byte and reads `$FF`: bit 4, FIRE, is the pen's trigger line
|
|
857
|
+
and is high, not pressed. `$DC00` reads `$7F`, the column pattern the
|
|
858
|
+
KERNAL's last scan left before the CIA1 interrupt was turned off.
|
|
859
|
+
- Rows 11 to 18: the synthetic table, compiled in, so these rows would
|
|
860
|
+
be the same with no pen attached. Each row is an LPX and LPY value,
|
|
861
|
+
the column and row `lpx_to_col` and `lpy_to_row` computed, the
|
|
862
|
+
expected pair, and `OK` when they match. `--` is outside the text
|
|
863
|
+
area. Rows 11 and 15 are the two corners of the 40 by 25 area; rows 16
|
|
864
|
+
and 17 are one step outside each; row 18 is what a pen that never
|
|
865
|
+
triggered leaves, and it lands outside, so a program that converts
|
|
866
|
+
blindly still draws nothing.
|
|
867
|
+
- Rows 20 and 21: the interrupt's whole cost, 94 cycles on both models,
|
|
868
|
+
as the difference between two CIA2 timer A readings around the same
|
|
869
|
+
fixed loop started on raster line 5, once with no interrupt armed
|
|
870
|
+
(2,588) and once with a raster interrupt on line 25 entering the same
|
|
871
|
+
handler (2,682). The figure matches the instruction arithmetic: 7 for
|
|
872
|
+
the interrupt sequence, 29 for the KERNAL's dispatcher from `$FF48`
|
|
873
|
+
to the `$0314` vector, 36 for the handler's nine instructions and 22
|
|
874
|
+
for the exit through `$EA81` (rung 3, agreeing with the rung 1
|
|
875
|
+
measurement). The loop runs in the top border, so no badline is inside
|
|
876
|
+
either window.
|
|
877
|
+
|
|
878
|
+
The pass needs all eight table rows to match and the consistency rule to
|
|
879
|
+
hold: the lowest and highest latch on each axis are equal, and the pen
|
|
880
|
+
interrupt count is either the frame count within one, or zero with bit 3
|
|
881
|
+
of `$D019` clear. A count between those, a pen that triggers on some
|
|
882
|
+
frames only, fails it, and so does a latch that moved.
|
|
883
|
+
|
|
884
|
+
The trigger could not be driven by another route. VICE's joystick
|
|
885
|
+
autofire on port 1 (`-joystick1autofire -joystick1autofiremode 1`) pulls
|
|
886
|
+
the same FIRE line, but it starts at power-up: the KERNAL's keyboard scan
|
|
887
|
+
reads PB4 low as a key in matrix row 4, the autostart's typed `RUN` never
|
|
888
|
+
arrives, and the screen fills with `>` characters at 50 presses a second
|
|
889
|
+
and shows one at 1 per second. The program did not run in either case,
|
|
890
|
+
so whether VICE latches the beam position for a joystick fire press is
|
|
891
|
+
not measured here.
|
|
892
|
+
|
|
893
|
+
## Why this works
|
|
894
|
+
|
|
895
|
+
The VIC latches its horizontal counter, divided by two, into `$D013` and
|
|
896
|
+
the low eight bits of its raster counter into `$D014` when the LP pin
|
|
897
|
+
goes low, and sets bit 3 of `$D019`; with bit 3 of `$D01A` set that
|
|
898
|
+
raises an interrupt. The LP pin is CIA1 PB4, control port 1's FIRE line,
|
|
899
|
+
which is why the pen goes in port 1 and why a joystick fire press there
|
|
900
|
+
latches a position too. The latch takes the first edge of a frame only
|
|
901
|
+
and is reset in the vertical blank, so one read per frame sees
|
|
902
|
+
everything there is (`hardware/vic-ii-reference.md`, "Light pen
|
|
903
|
+
latch"). The handler here acknowledges by writing `$D019`'s own value
|
|
904
|
+
back, which clears every bit that was set and nothing else, copies the
|
|
905
|
+
two registers and counts.
|
|
906
|
+
|
|
907
|
+
The conversion is arithmetic on the hardware page's statements. LPX is
|
|
908
|
+
X/2, the text area starts at X = 24 (sprite coordinates), and a column
|
|
909
|
+
is eight pixels wide, so the column is (LPX - 12) / 4 once the pen's own
|
|
910
|
+
delay has been subtracted; the text area's 200 lines start at raster
|
|
911
|
+
line 51, so the row is (LPY - 51) / 8. A pen reports the beam a little
|
|
912
|
+
after the beam lit the phosphor under it, which shows as a constant
|
|
913
|
+
added to LPX; `PEN_DELAY` is that constant in LPX units, set per pen by
|
|
914
|
+
asking the user to touch a known cell, and left at zero here because no
|
|
915
|
+
pen was available to calibrate. Both routines return `$FF` for a point
|
|
916
|
+
outside the area, and the row-18 case shows why that matters.
|
|
917
|
+
|
|
918
|
+
The CIA1 interrupt is turned off first, so the KERNAL's keyboard scan
|
|
919
|
+
never drives `$DC00` while the port is read: a held key in a driven
|
|
920
|
+
column pulls a row line low on `$DC01`, and the pen's trigger is one of
|
|
921
|
+
those row lines (`pitfalls/input.md`, `joystick2_scan_phantom_press`,
|
|
922
|
+
for the port-1 form of the hazard). The cost measurement uses a raster
|
|
923
|
+
interrupt because the pen line cannot be pulled low by software; the
|
|
924
|
+
entry, the dispatcher, the handler and the exit are the same
|
|
925
|
+
instructions whichever bit of `$D019` set, so the 94 cycles are the
|
|
926
|
+
pen interrupt's cost too.
|