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,1484 @@
|
|
|
1
|
+
---
|
|
2
|
+
recipe: eight-way-scroll
|
|
3
|
+
toolchain: kickassembler
|
|
4
|
+
output_format: PRG
|
|
5
|
+
region: both
|
|
6
|
+
techniques: [eight_way_scroll_double_buffer, screen_double_buffer_d018, soft_scroll_h, soft_scroll_v, tile_map_render, irq_chain_table]
|
|
7
|
+
file_formats: [PRG]
|
|
8
|
+
uses_registers: [D011, D012, D016, D018, D019, D01A, D020, D021, DC06, DC07, DC0D, DC0F, DD0D]
|
|
9
|
+
uses_kernal: []
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
<!-- doc-type: recipe -->
|
|
13
|
+
|
|
14
|
+
# KickAssembler — Eight-way tile scroll with a double-buffered screen matrix
|
|
15
|
+
|
|
16
|
+
## Synopsis
|
|
17
|
+
|
|
18
|
+
Scrolls a 64 x 48 tile world through a 40 x 25 window in all eight
|
|
19
|
+
directions, one pixel every two fields, and measures what each field costs.
|
|
20
|
+
Sub-tile motion is the fine scroll in `$D016` and `$D011`. Whole-tile motion
|
|
21
|
+
is a redraw of the entire matrix into the screen page that is not on display,
|
|
22
|
+
followed by a `$D018` flip in the vertical blank, so no partly drawn matrix
|
|
23
|
+
is ever visible. The redraw is spread over at most four fields per crossing.
|
|
24
|
+
|
|
25
|
+
Colour RAM is not paged. Both halves are written in `irqColB` at raster 4
|
|
26
|
+
in four calls after each flip: two for the top half (rows 0 to 11) and two
|
|
27
|
+
for the bottom (rows 12 to 24). The first top call uses `BAND_FIRST = 5`
|
|
28
|
+
rows so the colour write finishes before row 6's badline even when
|
|
29
|
+
`irqColB` starts as late as raster 33 on NTSC. The remaining calls use
|
|
30
|
+
`BAND_MAX = 7`. During the four write fields, rows not yet updated show the
|
|
31
|
+
previous origin's colour: three displayed fields per tile crossing, about
|
|
32
|
+
one in four, measured at 60 ms PAL and 50 ms NTSC.
|
|
33
|
+
|
|
34
|
+
A camera path table walks the eight directions in turn, thirty-two fields
|
|
35
|
+
each. CIA 1 timer B measures every field. Row 1 of the screen shows the
|
|
36
|
+
camera position, the leg index, waited flips, the worst field in cycles,
|
|
37
|
+
late applies, skipped preps and first-band deadline violations. `$02FF` is
|
|
38
|
+
`$01` and the border green when the marker tile is where the camera says it
|
|
39
|
+
should be, no flip waited, no late apply occurred, no prep was skipped, no
|
|
40
|
+
first-band call missed the row-6 badline, and the worst field is under the
|
|
41
|
+
stated budget; `$02` and red otherwise. PAL and NTSC.
|
|
42
|
+
|
|
43
|
+
## Source
|
|
44
|
+
|
|
45
|
+
```asm
|
|
46
|
+
// Eight-way tile scroll over a double-buffered screen matrix.
|
|
47
|
+
//
|
|
48
|
+
// A 64 x 48 tile world is viewed through a 40 x 25 window. The camera
|
|
49
|
+
// moves one pixel every two fields along a fixed eight-leg path. Sub-tile
|
|
50
|
+
// motion is the fine scroll in $D016 and $D011; whole-tile motion is a
|
|
51
|
+
// redraw of the whole matrix into the page that is not on screen,
|
|
52
|
+
// followed by a $D018 flip in the vertical blank.
|
|
53
|
+
//
|
|
54
|
+
// Colour RAM is not paged. Both halves are written in irqColB at raster 4.
|
|
55
|
+
// The top half (rows 0..SPLIT-1) is written in two calls after the flip: the
|
|
56
|
+
// first uses BAND_FIRST rows, which fits safely even when irqColB starts as
|
|
57
|
+
// late as raster 33 on NTSC; the second uses BAND_MAX. The bottom half
|
|
58
|
+
// (rows SPLIT..24) follows in two more calls at BAND_MAX rows each. Four
|
|
59
|
+
// colour calls span the same four fields as the four matrix-redraw preps.
|
|
60
|
+
|
|
61
|
+
.const WORLD = $2000 // 64 x 48 tile codes
|
|
62
|
+
.const WCOL = $2c00 // 64 x 48 colour nybbles
|
|
63
|
+
.const WORLD_W = 64
|
|
64
|
+
.const WORLD_H = 48
|
|
65
|
+
.const SCR0 = $0400
|
|
66
|
+
.const SCR1 = $0800
|
|
67
|
+
.const MAX_COL = WORLD_W - 40 // 24
|
|
68
|
+
.const MAX_ROW = WORLD_H - 25 // 23
|
|
69
|
+
.const MARK_X = 30 // marker tile, world coordinates
|
|
70
|
+
.const MARK_Y = 24
|
|
71
|
+
.const MARK_CH = $2a // '*'
|
|
72
|
+
.const SPLIT = 12 // first row of the bottom half
|
|
73
|
+
.const RAS_COLB = 4 // bottom colour half: beam above row 12
|
|
74
|
+
.const RAS_PREP = 152 // decide and top colour half: beam below row 12
|
|
75
|
+
.const RAS_APPLY = 251 // registers: vertical blank
|
|
76
|
+
.const CHECK_AT = 320 // frame at which the verdict is published
|
|
77
|
+
.const BAND_MAX = 7 // matrix rows drawn per prep field (any kind)
|
|
78
|
+
.const BAND_FIRST = 5 // top-half colour rows on the first call after a flip
|
|
79
|
+
.const BUDGET = 18000 // worst-field cycle budget
|
|
80
|
+
|
|
81
|
+
// --- zero page -------------------------------------------------------
|
|
82
|
+
.const camx = $20 // camera in world pixels
|
|
83
|
+
.const camy = $21
|
|
84
|
+
.const ztmp2 = $22
|
|
85
|
+
.const visCol = $24 // tile origin of the matrix on screen
|
|
86
|
+
.const visRow = $25
|
|
87
|
+
.const offCol = $26 // tile origin the spare matrix holds
|
|
88
|
+
.const offRow = $27
|
|
89
|
+
.const pgVis = $28 // 0 = $0400 on screen, 1 = $0800
|
|
90
|
+
.const rdState = $29 // 1 while the spare matrix is being redrawn
|
|
91
|
+
.const offOK = $2a
|
|
92
|
+
.const sgnx = $2b
|
|
93
|
+
.const sgny = $2c
|
|
94
|
+
.const legIdx = $2d
|
|
95
|
+
.const legCnt = $2e
|
|
96
|
+
.const zrow = $2f
|
|
97
|
+
.const zend = $30
|
|
98
|
+
.const zv = $31 // word
|
|
99
|
+
.const ztmp = $33
|
|
100
|
+
.const t1 = $34
|
|
101
|
+
.const t2 = $35
|
|
102
|
+
.const wptr = $36 // word
|
|
103
|
+
.const wx = $38
|
|
104
|
+
.const wy = $39
|
|
105
|
+
.const wantCol = $3a
|
|
106
|
+
.const wantRow = $3b
|
|
107
|
+
.const tgtCol = $3c
|
|
108
|
+
.const tgtRow = $3d
|
|
109
|
+
.const stalls = $3e // flips wanted while the spare page was unready
|
|
110
|
+
.const framesX = $3f // frames until the next column crossing
|
|
111
|
+
.const framesY = $40
|
|
112
|
+
.const deadlin = $41
|
|
113
|
+
.const dcol = $42
|
|
114
|
+
.const drow = $43
|
|
115
|
+
.const colCol = $44 // origin the colour halves are being written for
|
|
116
|
+
.const colRow = $45
|
|
117
|
+
.const colPend = $46
|
|
118
|
+
.const pendVM = $47 // register values waiting for the blank
|
|
119
|
+
.const pendD16 = $48
|
|
120
|
+
.const pendD11 = $49
|
|
121
|
+
.const frameL = $4a
|
|
122
|
+
.const frameH = $4b
|
|
123
|
+
.const markBad = $4c
|
|
124
|
+
.const tNow = $4d // word
|
|
125
|
+
.const tEnt = $4f // word
|
|
126
|
+
.const frameAc = $51 // word
|
|
127
|
+
.const worst = $53 // word
|
|
128
|
+
.const colTop = $55 // word, raster at which the top half finished
|
|
129
|
+
.const colBot = $57 // word
|
|
130
|
+
.const cbSrcHi = $59
|
|
131
|
+
.const cbDstHi = $5a
|
|
132
|
+
.const cbCol = $5b
|
|
133
|
+
.const cbRow = $5c
|
|
134
|
+
.const pnI = $5d
|
|
135
|
+
.const pnD = $5e
|
|
136
|
+
.const pnTL = $5f
|
|
137
|
+
.const srcp = $60 // word
|
|
138
|
+
.const cptr = $62 // word
|
|
139
|
+
.const done = $64
|
|
140
|
+
.const fullCnt = $65
|
|
141
|
+
.const rdNext = $66 // next view row the spare matrix still needs
|
|
142
|
+
.const colWork = $67 // this field has already rewritten a colour half
|
|
143
|
+
.const statIdx = $68
|
|
144
|
+
.const rowsF = $69
|
|
145
|
+
.const wDbg = $6a
|
|
146
|
+
.const lateCol = $6b // colour halves that missed the beam
|
|
147
|
+
.const prepRas = $6c
|
|
148
|
+
.const lateApply = $6d // apply entries that fired with raster < RAS_APPLY
|
|
149
|
+
.const skipPrep = $6e // colB entries with no preceding prep
|
|
150
|
+
.const prepFired = $6f // set in irqPrep, checked and cleared in irqColB
|
|
151
|
+
.const stepParity = $70 // toggles each field; pathStep runs when 0
|
|
152
|
+
.const colTopCur = $71 // cursor into top colour half (0..SPLIT; SPLIT=done)
|
|
153
|
+
.const colBotCur = $72 // cursor into bottom colour half (SPLIT..25; 25=done)
|
|
154
|
+
.const b1Dead = $73 // first top-half calls that missed the row-6 badline
|
|
155
|
+
|
|
156
|
+
.pc = $0801 "BASIC"
|
|
157
|
+
:BasicUpstart2(main)
|
|
158
|
+
|
|
159
|
+
// The program sits at $1000. In VIC bank 0 the chip sees the character
|
|
160
|
+
// generator ROM at $1000-$1FFF, so that RAM is invisible to it and free
|
|
161
|
+
// for code. $0800 is the second screen matrix and must stay clear.
|
|
162
|
+
.pc = $1000 "Main"
|
|
163
|
+
|
|
164
|
+
main:
|
|
165
|
+
sei
|
|
166
|
+
lda #$35 // RAM under BASIC and KERNAL, I/O visible
|
|
167
|
+
sta $01
|
|
168
|
+
|
|
169
|
+
lda #$7f // silence both CIAs
|
|
170
|
+
sta $dc0d
|
|
171
|
+
sta $dd0d
|
|
172
|
+
lda $dc0d
|
|
173
|
+
lda $dd0d
|
|
174
|
+
|
|
175
|
+
jsr genWorld
|
|
176
|
+
jsr clearScreens
|
|
177
|
+
jsr initStatus
|
|
178
|
+
|
|
179
|
+
lda #$00
|
|
180
|
+
sta $d020
|
|
181
|
+
sta $d021
|
|
182
|
+
|
|
183
|
+
// Camera start. The sub-tile phase is a design choice, not an
|
|
184
|
+
// arbitrary one: with camx and camy both congruent to 2 mod 8
|
|
185
|
+
// the gap between successive tile crossings never falls below
|
|
186
|
+
// three frames, which is what lets the redraw be split in two.
|
|
187
|
+
lda #66
|
|
188
|
+
sta camx
|
|
189
|
+
sta camy
|
|
190
|
+
lda #8
|
|
191
|
+
sta visCol
|
|
192
|
+
sta visRow
|
|
193
|
+
sta offCol
|
|
194
|
+
sta offRow
|
|
195
|
+
lda #0
|
|
196
|
+
sta pgVis
|
|
197
|
+
sta rdState
|
|
198
|
+
sta offOK
|
|
199
|
+
sta sgnx
|
|
200
|
+
sta sgny
|
|
201
|
+
sta stalls
|
|
202
|
+
sta colPend
|
|
203
|
+
sta frameL
|
|
204
|
+
sta frameH
|
|
205
|
+
sta markBad
|
|
206
|
+
sta frameAc
|
|
207
|
+
sta frameAc+1
|
|
208
|
+
sta worst
|
|
209
|
+
sta worst+1
|
|
210
|
+
sta colTop
|
|
211
|
+
sta colTop+1
|
|
212
|
+
sta colBot
|
|
213
|
+
sta colBot+1
|
|
214
|
+
sta done
|
|
215
|
+
sta fullCnt
|
|
216
|
+
sta rdNext
|
|
217
|
+
sta colWork
|
|
218
|
+
sta statIdx
|
|
219
|
+
sta rowsF
|
|
220
|
+
sta wDbg
|
|
221
|
+
sta lateCol
|
|
222
|
+
sta prepRas
|
|
223
|
+
sta lateApply
|
|
224
|
+
sta skipPrep
|
|
225
|
+
sta b1Dead
|
|
226
|
+
sta stepParity
|
|
227
|
+
lda #1
|
|
228
|
+
sta prepFired // so the first irqColB does not count as a skip
|
|
229
|
+
lda #SPLIT
|
|
230
|
+
sta colTopCur // SPLIT = no top-half colour pending
|
|
231
|
+
lda #25
|
|
232
|
+
sta colBotCur // 25 = no bottom-half colour pending
|
|
233
|
+
lda #7
|
|
234
|
+
sta legIdx // so the first step loads leg 0
|
|
235
|
+
lda #1
|
|
236
|
+
sta legCnt
|
|
237
|
+
|
|
238
|
+
// Draw the opening view straight into the page that is on
|
|
239
|
+
// screen, and its colour with it.
|
|
240
|
+
lda #1
|
|
241
|
+
sta pgVis // aim drawMatrix at page 0
|
|
242
|
+
lda #0
|
|
243
|
+
sta zrow
|
|
244
|
+
lda #24
|
|
245
|
+
sta zend
|
|
246
|
+
jsr drawMatrix
|
|
247
|
+
lda #0
|
|
248
|
+
sta pgVis
|
|
249
|
+
lda visCol
|
|
250
|
+
sta colCol
|
|
251
|
+
lda visRow
|
|
252
|
+
sta colRow
|
|
253
|
+
lda #0
|
|
254
|
+
sta zrow
|
|
255
|
+
lda #24
|
|
256
|
+
sta zend
|
|
257
|
+
jsr drawColour
|
|
258
|
+
|
|
259
|
+
lda #$14 // matrix $0400, charset ROM at $1000
|
|
260
|
+
sta $d018
|
|
261
|
+
sta pendVM
|
|
262
|
+
lda #7
|
|
263
|
+
sta pendD16
|
|
264
|
+
lda #$17
|
|
265
|
+
sta pendD11
|
|
266
|
+
sta $d011
|
|
267
|
+
lda #7
|
|
268
|
+
sta $d016
|
|
269
|
+
|
|
270
|
+
lda #$ff // free-running frame timer
|
|
271
|
+
sta $dc06
|
|
272
|
+
sta $dc07
|
|
273
|
+
lda #$11
|
|
274
|
+
sta $dc0f
|
|
275
|
+
|
|
276
|
+
lda #<irqColB
|
|
277
|
+
sta $fffe
|
|
278
|
+
lda #>irqColB
|
|
279
|
+
sta $ffff
|
|
280
|
+
lda #RAS_COLB
|
|
281
|
+
sta $d012
|
|
282
|
+
lda #$01
|
|
283
|
+
sta $d01a
|
|
284
|
+
lda #$ff
|
|
285
|
+
sta $d019
|
|
286
|
+
cli
|
|
287
|
+
|
|
288
|
+
idle: jmp idle
|
|
289
|
+
|
|
290
|
+
// --- bottom colour half, beam above row 13 ---------------------------
|
|
291
|
+
irqColB:
|
|
292
|
+
pha
|
|
293
|
+
txa
|
|
294
|
+
pha
|
|
295
|
+
tya
|
|
296
|
+
pha
|
|
297
|
+
cld // the D flag is not cleared on IRQ entry
|
|
298
|
+
lda #$ff
|
|
299
|
+
sta $d019
|
|
300
|
+
lda #<irqPrep // arm the next stage first: this handler
|
|
301
|
+
sta $fffe // can outlast its own raster line
|
|
302
|
+
lda #>irqPrep
|
|
303
|
+
sta $ffff
|
|
304
|
+
lda $d011 // the split follows YSCROLL: row 12 ends at
|
|
305
|
+
and #7 // raster 151 + YSCROLL, so the top colour
|
|
306
|
+
clc // half may start one line after that
|
|
307
|
+
adc #RAS_PREP
|
|
308
|
+
sta $d012
|
|
309
|
+
sta prepRas
|
|
310
|
+
|
|
311
|
+
lda #0 // a new field: restart the frame timer
|
|
312
|
+
sta frameAc
|
|
313
|
+
sta frameAc+1
|
|
314
|
+
sta colWork
|
|
315
|
+
sta rowsF
|
|
316
|
+
jsr markIn
|
|
317
|
+
|
|
318
|
+
// skipPrep: if irqPrep never ran since the last irqColB, count it.
|
|
319
|
+
lda prepFired
|
|
320
|
+
bne cb_prepok
|
|
321
|
+
inc skipPrep
|
|
322
|
+
cb_prepok:
|
|
323
|
+
lda #0
|
|
324
|
+
sta prepFired
|
|
325
|
+
|
|
326
|
+
// Band-limited colour write: at most BAND_MAX rows per irqColB call.
|
|
327
|
+
// By limiting each call, irqColB always finishes well before irqPrep's
|
|
328
|
+
// raster even when irqColB starts late (due to irqApply overrunning the
|
|
329
|
+
// NTSC blank). Phase 1 writes rows from colTopCur toward SPLIT; phase 2
|
|
330
|
+
// writes rows from colBotCur toward 24.
|
|
331
|
+
lda colPend
|
|
332
|
+
bne cb_has_pend
|
|
333
|
+
jmp cb_none
|
|
334
|
+
cb_has_pend:
|
|
335
|
+
cmp #1
|
|
336
|
+
bne cb_bottom
|
|
337
|
+
// Phase 1: top half. BAND_FIRST rows on the first call (colTopCur == 0)
|
|
338
|
+
// so the colour finishes before the row-6 badline even when irqColB
|
|
339
|
+
// starts as late as raster 33 on NTSC. Subsequent calls use BAND_MAX.
|
|
340
|
+
lda colTopCur
|
|
341
|
+
sta zrow
|
|
342
|
+
lda colTopCur
|
|
343
|
+
beq cb_top_first
|
|
344
|
+
clc
|
|
345
|
+
adc #BAND_MAX-1
|
|
346
|
+
jmp cb_top_clamp
|
|
347
|
+
cb_top_first:
|
|
348
|
+
lda #BAND_FIRST-1
|
|
349
|
+
cb_top_clamp:
|
|
350
|
+
cmp #SPLIT-1
|
|
351
|
+
bcc !+
|
|
352
|
+
lda #SPLIT-1
|
|
353
|
+
!: sta zend
|
|
354
|
+
jsr drawColour
|
|
355
|
+
// First top-half call (zend == BAND_FIRST-1): check it finished before
|
|
356
|
+
// row 6's badline (96 + YSCROLL). If not, count a deadline violation.
|
|
357
|
+
lda zend
|
|
358
|
+
cmp #BAND_FIRST-1
|
|
359
|
+
bne cb_top_nodead
|
|
360
|
+
jsr readRaster
|
|
361
|
+
lda zv+1
|
|
362
|
+
bne cb_top_nodead // raster above 255: in blank, on time
|
|
363
|
+
lda $d011
|
|
364
|
+
and #7
|
|
365
|
+
clc
|
|
366
|
+
adc #96
|
|
367
|
+
cmp zv // 96+YSCROLL >= raster: on time
|
|
368
|
+
bcs cb_top_nodead
|
|
369
|
+
inc b1Dead
|
|
370
|
+
cb_top_nodead:
|
|
371
|
+
inc colWork
|
|
372
|
+
lda zend
|
|
373
|
+
cmp #SPLIT-1
|
|
374
|
+
bcc cb_top_more
|
|
375
|
+
lda #SPLIT // top half complete; start bottom half
|
|
376
|
+
sta colTopCur
|
|
377
|
+
lda #2
|
|
378
|
+
sta colPend
|
|
379
|
+
jmp cb_none
|
|
380
|
+
cb_top_more:
|
|
381
|
+
lda zend
|
|
382
|
+
clc
|
|
383
|
+
adc #1
|
|
384
|
+
sta colTopCur // resume here next call
|
|
385
|
+
jmp cb_none
|
|
386
|
+
cb_bottom:
|
|
387
|
+
// Phase 2: bottom half, BAND_MAX rows per call.
|
|
388
|
+
lda colBotCur
|
|
389
|
+
sta zrow
|
|
390
|
+
lda colBotCur
|
|
391
|
+
clc
|
|
392
|
+
adc #BAND_MAX-1
|
|
393
|
+
cmp #24
|
|
394
|
+
bcc !+
|
|
395
|
+
lda #24
|
|
396
|
+
!: sta zend
|
|
397
|
+
jsr drawColour
|
|
398
|
+
jsr readRaster // timing check: first band must land before row 12
|
|
399
|
+
lda zv
|
|
400
|
+
sta colBot
|
|
401
|
+
lda zv+1
|
|
402
|
+
sta colBot+1
|
|
403
|
+
bne cb_late // past raster 255 is far too late
|
|
404
|
+
lda $d011
|
|
405
|
+
and #7
|
|
406
|
+
clc
|
|
407
|
+
adc #144 // row 12 starts at raster 144 + YSCROLL
|
|
408
|
+
cmp colBot
|
|
409
|
+
bcs cb_intime
|
|
410
|
+
cb_late:
|
|
411
|
+
inc lateCol
|
|
412
|
+
cb_intime:
|
|
413
|
+
inc colWork
|
|
414
|
+
lda zend
|
|
415
|
+
cmp #24
|
|
416
|
+
bcc cb_bot_more
|
|
417
|
+
lda #25 // bottom half complete
|
|
418
|
+
sta colBotCur
|
|
419
|
+
lda #0
|
|
420
|
+
sta colPend
|
|
421
|
+
jmp cb_none
|
|
422
|
+
cb_bot_more:
|
|
423
|
+
lda zend
|
|
424
|
+
clc
|
|
425
|
+
adc #1
|
|
426
|
+
sta colBotCur // resume here next call
|
|
427
|
+
cb_none:
|
|
428
|
+
jsr markOut
|
|
429
|
+
jmp irqExit
|
|
430
|
+
|
|
431
|
+
// --- decide the next field, top colour half --------------------------
|
|
432
|
+
irqPrep:
|
|
433
|
+
pha
|
|
434
|
+
txa
|
|
435
|
+
pha
|
|
436
|
+
tya
|
|
437
|
+
pha
|
|
438
|
+
cld // the D flag is not cleared on IRQ entry
|
|
439
|
+
lda #$ff
|
|
440
|
+
sta $d019
|
|
441
|
+
lda #<irqApply
|
|
442
|
+
sta $fffe
|
|
443
|
+
lda #>irqApply
|
|
444
|
+
sta $ffff
|
|
445
|
+
lda #RAS_APPLY
|
|
446
|
+
sta $d012
|
|
447
|
+
jsr markIn
|
|
448
|
+
|
|
449
|
+
lda #1 // signal that prep ran (for skipPrep detection)
|
|
450
|
+
sta prepFired
|
|
451
|
+
|
|
452
|
+
// Half-speed camera: advance one pixel every two fields so the
|
|
453
|
+
// redraw always completes before the next tile crossing.
|
|
454
|
+
lda stepParity
|
|
455
|
+
eor #1
|
|
456
|
+
sta stepParity
|
|
457
|
+
beq pr_step_skip
|
|
458
|
+
jsr pathStep
|
|
459
|
+
pr_step_skip:
|
|
460
|
+
|
|
461
|
+
lda camx
|
|
462
|
+
lsr
|
|
463
|
+
lsr
|
|
464
|
+
lsr
|
|
465
|
+
sta wantCol
|
|
466
|
+
lda camy
|
|
467
|
+
lsr
|
|
468
|
+
lsr
|
|
469
|
+
lsr
|
|
470
|
+
sta wantRow
|
|
471
|
+
|
|
472
|
+
// Flip only if the wanted origin has moved and the spare page
|
|
473
|
+
// already holds exactly that origin.
|
|
474
|
+
lda wantCol
|
|
475
|
+
cmp visCol
|
|
476
|
+
bne pr_try
|
|
477
|
+
lda wantRow
|
|
478
|
+
cmp visRow
|
|
479
|
+
beq pr_fine
|
|
480
|
+
pr_try:
|
|
481
|
+
lda offOK
|
|
482
|
+
beq pr_stall
|
|
483
|
+
lda offCol
|
|
484
|
+
cmp wantCol
|
|
485
|
+
bne pr_stall
|
|
486
|
+
lda offRow
|
|
487
|
+
cmp wantRow
|
|
488
|
+
bne pr_stall
|
|
489
|
+
|
|
490
|
+
lda pgVis // the flip is queued for the blank
|
|
491
|
+
eor #1
|
|
492
|
+
sta pgVis
|
|
493
|
+
tax
|
|
494
|
+
lda d018T,x
|
|
495
|
+
sta pendVM
|
|
496
|
+
lda offCol
|
|
497
|
+
sta visCol
|
|
498
|
+
sta colCol
|
|
499
|
+
lda offRow
|
|
500
|
+
sta visRow
|
|
501
|
+
sta colRow
|
|
502
|
+
lda #0
|
|
503
|
+
sta offOK
|
|
504
|
+
sta colTopCur // start top-half colour write from row 0
|
|
505
|
+
lda #SPLIT
|
|
506
|
+
sta colBotCur // bottom-half cursor starts at SPLIT
|
|
507
|
+
lda #1
|
|
508
|
+
sta colPend // irqColB will write top half (phase 1), then bottom (phase 2)
|
|
509
|
+
jmp pr_fine
|
|
510
|
+
pr_stall:
|
|
511
|
+
lda stalls
|
|
512
|
+
cmp #255
|
|
513
|
+
beq pr_fine
|
|
514
|
+
inc stalls
|
|
515
|
+
|
|
516
|
+
pr_fine:
|
|
517
|
+
// Fine scroll for the origin that will be on screen. Both
|
|
518
|
+
// registers are written whole, never read-modify-write, so CSEL,
|
|
519
|
+
// MCM and the raster high bit cannot be clobbered.
|
|
520
|
+
lda visCol
|
|
521
|
+
asl
|
|
522
|
+
asl
|
|
523
|
+
asl
|
|
524
|
+
sta ztmp
|
|
525
|
+
lda camx
|
|
526
|
+
sec
|
|
527
|
+
sbc ztmp
|
|
528
|
+
jsr clamp07
|
|
529
|
+
sta ztmp
|
|
530
|
+
lda #7
|
|
531
|
+
sec
|
|
532
|
+
sbc ztmp
|
|
533
|
+
sta pendD16
|
|
534
|
+
|
|
535
|
+
lda visRow
|
|
536
|
+
asl
|
|
537
|
+
asl
|
|
538
|
+
asl
|
|
539
|
+
sta ztmp
|
|
540
|
+
lda camy
|
|
541
|
+
sec
|
|
542
|
+
sbc ztmp
|
|
543
|
+
jsr clamp07
|
|
544
|
+
sta ztmp
|
|
545
|
+
lda #7
|
|
546
|
+
sec
|
|
547
|
+
sbc ztmp
|
|
548
|
+
ora #$10 // DEN on, RSEL 0, raster high bit clear
|
|
549
|
+
sta pendD11
|
|
550
|
+
|
|
551
|
+
// Frames until each axis crosses a tile boundary.
|
|
552
|
+
lda sgnx
|
|
553
|
+
beq fx_never
|
|
554
|
+
bmi fx_left
|
|
555
|
+
lda camx
|
|
556
|
+
and #7
|
|
557
|
+
sta ztmp
|
|
558
|
+
lda #8
|
|
559
|
+
sec
|
|
560
|
+
sbc ztmp
|
|
561
|
+
jmp fx_put
|
|
562
|
+
fx_left:
|
|
563
|
+
lda camx
|
|
564
|
+
and #7
|
|
565
|
+
clc
|
|
566
|
+
adc #1
|
|
567
|
+
jmp fx_put
|
|
568
|
+
fx_never:
|
|
569
|
+
lda #$7f
|
|
570
|
+
fx_put: sta framesX
|
|
571
|
+
|
|
572
|
+
lda sgny
|
|
573
|
+
beq fy_never
|
|
574
|
+
bmi fy_up
|
|
575
|
+
lda camy
|
|
576
|
+
and #7
|
|
577
|
+
sta ztmp
|
|
578
|
+
lda #8
|
|
579
|
+
sec
|
|
580
|
+
sbc ztmp
|
|
581
|
+
jmp fy_put
|
|
582
|
+
fy_up:
|
|
583
|
+
lda camy
|
|
584
|
+
and #7
|
|
585
|
+
clc
|
|
586
|
+
adc #1
|
|
587
|
+
jmp fy_put
|
|
588
|
+
fy_never:
|
|
589
|
+
lda #$7f
|
|
590
|
+
fy_put: sta framesY
|
|
591
|
+
|
|
592
|
+
lda framesX
|
|
593
|
+
cmp framesY
|
|
594
|
+
bcc !+
|
|
595
|
+
lda framesY
|
|
596
|
+
!: sta deadlin
|
|
597
|
+
|
|
598
|
+
// The spare page is drawn for the origin after the next
|
|
599
|
+
// crossing, which is one axis unless both cross together.
|
|
600
|
+
lda #0
|
|
601
|
+
sta dcol
|
|
602
|
+
sta drow
|
|
603
|
+
lda framesX
|
|
604
|
+
cmp framesY
|
|
605
|
+
beq tg_both
|
|
606
|
+
bcc tg_x
|
|
607
|
+
lda sgny
|
|
608
|
+
sta drow
|
|
609
|
+
jmp tg_have
|
|
610
|
+
tg_x: lda sgnx
|
|
611
|
+
sta dcol
|
|
612
|
+
jmp tg_have
|
|
613
|
+
tg_both:
|
|
614
|
+
lda sgnx
|
|
615
|
+
sta dcol
|
|
616
|
+
lda sgny
|
|
617
|
+
sta drow
|
|
618
|
+
tg_have:
|
|
619
|
+
lda visCol
|
|
620
|
+
clc
|
|
621
|
+
adc dcol
|
|
622
|
+
bpl !+
|
|
623
|
+
lda #0
|
|
624
|
+
!: cmp #MAX_COL+1
|
|
625
|
+
bcc !+
|
|
626
|
+
lda #MAX_COL
|
|
627
|
+
!: sta tgtCol
|
|
628
|
+
lda visRow
|
|
629
|
+
clc
|
|
630
|
+
adc drow
|
|
631
|
+
bpl !+
|
|
632
|
+
lda #0
|
|
633
|
+
!: cmp #MAX_ROW+1
|
|
634
|
+
bcc !+
|
|
635
|
+
lda #MAX_ROW
|
|
636
|
+
!: sta tgtRow
|
|
637
|
+
|
|
638
|
+
lda offCol
|
|
639
|
+
cmp tgtCol
|
|
640
|
+
bne pr_start
|
|
641
|
+
lda offRow
|
|
642
|
+
cmp tgtRow
|
|
643
|
+
bne pr_start
|
|
644
|
+
jmp pr_step
|
|
645
|
+
pr_start:
|
|
646
|
+
lda tgtCol
|
|
647
|
+
sta offCol
|
|
648
|
+
lda tgtRow
|
|
649
|
+
sta offRow
|
|
650
|
+
lda #1
|
|
651
|
+
sta rdState
|
|
652
|
+
lda #0
|
|
653
|
+
sta rdNext
|
|
654
|
+
sta offOK
|
|
655
|
+
pr_step:
|
|
656
|
+
lda rdState
|
|
657
|
+
beq pr_done
|
|
658
|
+
lda rdNext
|
|
659
|
+
sta zrow
|
|
660
|
+
lda #BAND_MAX-1 // at most BAND_MAX rows per field regardless of kind
|
|
661
|
+
clc
|
|
662
|
+
adc rdNext
|
|
663
|
+
cmp #24
|
|
664
|
+
bcc !+
|
|
665
|
+
lda #24
|
|
666
|
+
!: sta zend
|
|
667
|
+
jsr drawMatrix
|
|
668
|
+
jsr countRows
|
|
669
|
+
lda zend
|
|
670
|
+
cmp #24
|
|
671
|
+
beq rs_ready
|
|
672
|
+
clc
|
|
673
|
+
adc #1
|
|
674
|
+
sta rdNext
|
|
675
|
+
jmp pr_done
|
|
676
|
+
rs_ready:
|
|
677
|
+
lda #0
|
|
678
|
+
sta rdState
|
|
679
|
+
lda #1
|
|
680
|
+
sta offOK
|
|
681
|
+
pr_done:
|
|
682
|
+
jsr markOut
|
|
683
|
+
jmp irqExit
|
|
684
|
+
|
|
685
|
+
// --- apply the registers in the blank --------------------------------
|
|
686
|
+
irqApply:
|
|
687
|
+
pha
|
|
688
|
+
txa
|
|
689
|
+
pha
|
|
690
|
+
tya
|
|
691
|
+
pha
|
|
692
|
+
cld // the D flag is not cleared on IRQ entry
|
|
693
|
+
lda #$ff
|
|
694
|
+
sta $d019
|
|
695
|
+
lda #<irqColB
|
|
696
|
+
sta $fffe
|
|
697
|
+
lda #>irqColB
|
|
698
|
+
sta $ffff
|
|
699
|
+
lda #RAS_COLB
|
|
700
|
+
sta $d012
|
|
701
|
+
jsr markIn
|
|
702
|
+
|
|
703
|
+
// Late-apply detection: if irqPrep overran, the raster has already
|
|
704
|
+
// advanced past RAS_APPLY into the next field. Raster bit 8 is clear
|
|
705
|
+
// for rasters 0-255; a raster below RAS_APPLY here means we are in
|
|
706
|
+
// the next field. The CPU defers the IRQ until irqPrep's rti, so a
|
|
707
|
+
// late apply is always at a raster below 251 with bit 8 clear.
|
|
708
|
+
jsr readRaster
|
|
709
|
+
lda zv+1
|
|
710
|
+
bne ap_ontime // raster > 255: still in the blank, on time
|
|
711
|
+
lda zv
|
|
712
|
+
cmp #RAS_APPLY
|
|
713
|
+
bcs ap_ontime
|
|
714
|
+
inc lateApply
|
|
715
|
+
ap_ontime:
|
|
716
|
+
|
|
717
|
+
lda pendVM
|
|
718
|
+
sta $d018
|
|
719
|
+
lda pendD16
|
|
720
|
+
sta $d016
|
|
721
|
+
lda pendD11
|
|
722
|
+
sta $d011
|
|
723
|
+
|
|
724
|
+
jsr checkMarker
|
|
725
|
+
jsr buildStatus // one field per frame keeps the readout cheap
|
|
726
|
+
jsr stampStatus
|
|
727
|
+
|
|
728
|
+
inc frameL
|
|
729
|
+
bne !+
|
|
730
|
+
inc frameH
|
|
731
|
+
!:
|
|
732
|
+
jsr markOut
|
|
733
|
+
|
|
734
|
+
lda frameAc // keep the worst field seen
|
|
735
|
+
cmp worst
|
|
736
|
+
lda frameAc+1
|
|
737
|
+
sbc worst+1
|
|
738
|
+
bcc ap_nw
|
|
739
|
+
lda frameAc
|
|
740
|
+
sta worst
|
|
741
|
+
lda frameAc+1
|
|
742
|
+
sta worst+1
|
|
743
|
+
lda #0
|
|
744
|
+
ldx colWork
|
|
745
|
+
beq dbg_no
|
|
746
|
+
dbg_l: clc
|
|
747
|
+
adc #100
|
|
748
|
+
dex
|
|
749
|
+
bne dbg_l
|
|
750
|
+
dbg_no: clc
|
|
751
|
+
adc rowsF
|
|
752
|
+
sta wDbg
|
|
753
|
+
ap_nw:
|
|
754
|
+
lda done
|
|
755
|
+
bne ap_end
|
|
756
|
+
lda frameL
|
|
757
|
+
cmp #<CHECK_AT
|
|
758
|
+
lda frameH
|
|
759
|
+
sbc #>CHECK_AT
|
|
760
|
+
bcc ap_end
|
|
761
|
+
jsr verdict
|
|
762
|
+
lda #1
|
|
763
|
+
sta done
|
|
764
|
+
ap_end:
|
|
765
|
+
irqExit:
|
|
766
|
+
pla
|
|
767
|
+
tay
|
|
768
|
+
pla
|
|
769
|
+
tax
|
|
770
|
+
pla
|
|
771
|
+
rti
|
|
772
|
+
|
|
773
|
+
// --- verdict ---------------------------------------------------------
|
|
774
|
+
verdict:
|
|
775
|
+
lda markBad
|
|
776
|
+
bne vd_fail
|
|
777
|
+
lda stalls
|
|
778
|
+
bne vd_fail
|
|
779
|
+
lda lateCol
|
|
780
|
+
bne vd_fail
|
|
781
|
+
lda lateApply
|
|
782
|
+
bne vd_fail
|
|
783
|
+
lda skipPrep
|
|
784
|
+
bne vd_fail
|
|
785
|
+
lda b1Dead
|
|
786
|
+
bne vd_fail
|
|
787
|
+
lda worst
|
|
788
|
+
cmp #<BUDGET
|
|
789
|
+
lda worst+1
|
|
790
|
+
sbc #>BUDGET
|
|
791
|
+
bcs vd_fail
|
|
792
|
+
lda #$01
|
|
793
|
+
sta $02ff
|
|
794
|
+
lda #$05 // green
|
|
795
|
+
sta $d020
|
|
796
|
+
rts
|
|
797
|
+
vd_fail:
|
|
798
|
+
lda #$02
|
|
799
|
+
sta $02ff
|
|
800
|
+
lda #$02 // red
|
|
801
|
+
sta $d020
|
|
802
|
+
rts
|
|
803
|
+
|
|
804
|
+
// The marker tile must sit where the camera origin says it does.
|
|
805
|
+
checkMarker:
|
|
806
|
+
lda #MARK_X
|
|
807
|
+
sec
|
|
808
|
+
sbc visCol
|
|
809
|
+
sta ztmp
|
|
810
|
+
lda #MARK_Y
|
|
811
|
+
sec
|
|
812
|
+
sbc visRow
|
|
813
|
+
tax
|
|
814
|
+
lda rowLoT,x
|
|
815
|
+
clc
|
|
816
|
+
adc ztmp
|
|
817
|
+
sta srcp
|
|
818
|
+
lda rowHiT,x
|
|
819
|
+
adc #0
|
|
820
|
+
ldx pgVis
|
|
821
|
+
clc
|
|
822
|
+
adc pageHiT,x
|
|
823
|
+
sta srcp+1
|
|
824
|
+
ldy #0
|
|
825
|
+
lda (srcp),y
|
|
826
|
+
cmp #MARK_CH
|
|
827
|
+
beq cm_ok
|
|
828
|
+
lda #1
|
|
829
|
+
sta markBad
|
|
830
|
+
cm_ok: rts
|
|
831
|
+
|
|
832
|
+
// --- camera path -----------------------------------------------------
|
|
833
|
+
pathStep:
|
|
834
|
+
dec legCnt
|
|
835
|
+
bne ps_move
|
|
836
|
+
inc legIdx
|
|
837
|
+
lda legIdx
|
|
838
|
+
cmp #8
|
|
839
|
+
bcc !+
|
|
840
|
+
lda #0
|
|
841
|
+
sta legIdx
|
|
842
|
+
!: tax
|
|
843
|
+
lda pathDX,x
|
|
844
|
+
sta sgnx
|
|
845
|
+
lda pathDY,x
|
|
846
|
+
sta sgny
|
|
847
|
+
lda pathLen,x
|
|
848
|
+
sta legCnt
|
|
849
|
+
ps_move:
|
|
850
|
+
lda camx
|
|
851
|
+
clc
|
|
852
|
+
adc sgnx
|
|
853
|
+
sta camx
|
|
854
|
+
lda camy
|
|
855
|
+
clc
|
|
856
|
+
adc sgny
|
|
857
|
+
sta camy
|
|
858
|
+
rts
|
|
859
|
+
|
|
860
|
+
clamp07:
|
|
861
|
+
bpl !+
|
|
862
|
+
lda #0
|
|
863
|
+
rts
|
|
864
|
+
!: cmp #8
|
|
865
|
+
bcc !+
|
|
866
|
+
lda #7
|
|
867
|
+
!: rts
|
|
868
|
+
|
|
869
|
+
// --- band copies -----------------------------------------------------
|
|
870
|
+
// Rows zrow..zend of the view, from the world into the spare matrix.
|
|
871
|
+
drawMatrix:
|
|
872
|
+
lda pgVis
|
|
873
|
+
eor #1
|
|
874
|
+
tax
|
|
875
|
+
lda pageHiT,x
|
|
876
|
+
sta cbDstHi
|
|
877
|
+
lda #>WORLD
|
|
878
|
+
sta cbSrcHi
|
|
879
|
+
lda offCol
|
|
880
|
+
sta cbCol
|
|
881
|
+
lda offRow
|
|
882
|
+
sta cbRow
|
|
883
|
+
jmp copyBand
|
|
884
|
+
|
|
885
|
+
// Rows zrow..zend of the view, from the colour world into colour RAM.
|
|
886
|
+
drawColour:
|
|
887
|
+
lda #$d8
|
|
888
|
+
sta cbDstHi
|
|
889
|
+
lda #>WCOL
|
|
890
|
+
sta cbSrcHi
|
|
891
|
+
lda colCol
|
|
892
|
+
sta cbCol
|
|
893
|
+
lda colRow
|
|
894
|
+
sta cbRow
|
|
895
|
+
jmp copyBand
|
|
896
|
+
|
|
897
|
+
copyBand:
|
|
898
|
+
cb_row:
|
|
899
|
+
lda cbRow
|
|
900
|
+
clc
|
|
901
|
+
adc zrow
|
|
902
|
+
sta zv
|
|
903
|
+
lsr
|
|
904
|
+
lsr
|
|
905
|
+
clc
|
|
906
|
+
adc cbSrcHi
|
|
907
|
+
sta cpSrc+2
|
|
908
|
+
lda zv
|
|
909
|
+
asl
|
|
910
|
+
asl
|
|
911
|
+
asl
|
|
912
|
+
asl
|
|
913
|
+
asl
|
|
914
|
+
asl
|
|
915
|
+
clc
|
|
916
|
+
adc cbCol
|
|
917
|
+
sta cpSrc+1
|
|
918
|
+
ldx zrow
|
|
919
|
+
lda rowLoT,x
|
|
920
|
+
sta cpDst+1
|
|
921
|
+
lda rowHiT,x
|
|
922
|
+
clc
|
|
923
|
+
adc cbDstHi
|
|
924
|
+
sta cpDst+2
|
|
925
|
+
jsr copyRow
|
|
926
|
+
lda zrow
|
|
927
|
+
cmp zend
|
|
928
|
+
beq cb_done
|
|
929
|
+
inc zrow
|
|
930
|
+
jmp cb_row
|
|
931
|
+
cb_done:
|
|
932
|
+
rts
|
|
933
|
+
|
|
934
|
+
copyRow:
|
|
935
|
+
ldx #39
|
|
936
|
+
cr_l:
|
|
937
|
+
cpSrc: lda $ffff,x
|
|
938
|
+
cpDst: sta $ffff,x
|
|
939
|
+
dex
|
|
940
|
+
bpl cr_l
|
|
941
|
+
rts
|
|
942
|
+
|
|
943
|
+
// --- frame timer -----------------------------------------------------
|
|
944
|
+
readTimer:
|
|
945
|
+
rt_l: lda $dc07
|
|
946
|
+
sta tNow+1
|
|
947
|
+
lda $dc06
|
|
948
|
+
sta tNow
|
|
949
|
+
lda $dc07
|
|
950
|
+
cmp tNow+1
|
|
951
|
+
bne rt_l
|
|
952
|
+
rts
|
|
953
|
+
|
|
954
|
+
markIn:
|
|
955
|
+
jsr readTimer
|
|
956
|
+
lda tNow
|
|
957
|
+
sta tEnt
|
|
958
|
+
lda tNow+1
|
|
959
|
+
sta tEnt+1
|
|
960
|
+
rts
|
|
961
|
+
|
|
962
|
+
markOut:
|
|
963
|
+
jsr readTimer
|
|
964
|
+
lda tEnt // the timer counts down
|
|
965
|
+
sec
|
|
966
|
+
sbc tNow
|
|
967
|
+
sta ztmp
|
|
968
|
+
lda tEnt+1
|
|
969
|
+
sbc tNow+1
|
|
970
|
+
sta ztmp2
|
|
971
|
+
lda frameAc
|
|
972
|
+
clc
|
|
973
|
+
adc ztmp
|
|
974
|
+
sta frameAc
|
|
975
|
+
lda frameAc+1
|
|
976
|
+
adc ztmp2
|
|
977
|
+
sta frameAc+1
|
|
978
|
+
rts
|
|
979
|
+
|
|
980
|
+
// Did the top colour half finish before the beam reached row 0 of the
|
|
981
|
+
// next field? A finish raster at or above the one the handler started on
|
|
982
|
+
// is still inside this field and always in time.
|
|
983
|
+
topLate:
|
|
984
|
+
lda colTop+1
|
|
985
|
+
bne tl_ok
|
|
986
|
+
lda colTop
|
|
987
|
+
cmp prepRas
|
|
988
|
+
bcs tl_ok
|
|
989
|
+
lda pendD11
|
|
990
|
+
and #7
|
|
991
|
+
clc
|
|
992
|
+
adc #48
|
|
993
|
+
cmp colTop
|
|
994
|
+
bcs tl_ok
|
|
995
|
+
inc lateCol
|
|
996
|
+
tl_ok: rts
|
|
997
|
+
|
|
998
|
+
countRows:
|
|
999
|
+
lda zend
|
|
1000
|
+
sec
|
|
1001
|
+
sbc rdNext
|
|
1002
|
+
clc
|
|
1003
|
+
adc #1
|
|
1004
|
+
clc
|
|
1005
|
+
adc rowsF
|
|
1006
|
+
sta rowsF
|
|
1007
|
+
rts
|
|
1008
|
+
|
|
1009
|
+
// The nine-bit raster line, into zv.
|
|
1010
|
+
readRaster:
|
|
1011
|
+
lda $d012
|
|
1012
|
+
sta zv
|
|
1013
|
+
lda $d011
|
|
1014
|
+
and #$80
|
|
1015
|
+
beq !+
|
|
1016
|
+
lda #1
|
|
1017
|
+
sta zv+1
|
|
1018
|
+
rts
|
|
1019
|
+
!: lda #0
|
|
1020
|
+
sta zv+1
|
|
1021
|
+
rts
|
|
1022
|
+
|
|
1023
|
+
// --- status line -----------------------------------------------------
|
|
1024
|
+
// Row 1 is the topmost matrix row the display window shows in full at
|
|
1025
|
+
// every YSCROLL value, so the digits never slide under the border.
|
|
1026
|
+
initStatus:
|
|
1027
|
+
ldx #39
|
|
1028
|
+
lda #$20
|
|
1029
|
+
!: sta statBuf,x
|
|
1030
|
+
dex
|
|
1031
|
+
bpl !-
|
|
1032
|
+
lda #$18 // X
|
|
1033
|
+
sta statBuf+1
|
|
1034
|
+
lda #$19 // Y
|
|
1035
|
+
sta statBuf+6
|
|
1036
|
+
lda #$0c // L
|
|
1037
|
+
sta statBuf+11
|
|
1038
|
+
lda #$13 // S
|
|
1039
|
+
sta statBuf+15
|
|
1040
|
+
lda #$17 // W
|
|
1041
|
+
sta statBuf+19
|
|
1042
|
+
lda #$14 // T
|
|
1043
|
+
sta statBuf+25
|
|
1044
|
+
lda #$02 // B
|
|
1045
|
+
sta statBuf+29
|
|
1046
|
+
lda #$04 // D
|
|
1047
|
+
sta statBuf+34
|
|
1048
|
+
rts
|
|
1049
|
+
|
|
1050
|
+
buildStatus:
|
|
1051
|
+
ldx statIdx
|
|
1052
|
+
ldy stSrc,x
|
|
1053
|
+
lda $0000,y
|
|
1054
|
+
sta zv
|
|
1055
|
+
lda #0
|
|
1056
|
+
sta zv+1
|
|
1057
|
+
lda stWrd,x
|
|
1058
|
+
beq !+
|
|
1059
|
+
iny
|
|
1060
|
+
lda $0000,y
|
|
1061
|
+
sta zv+1
|
|
1062
|
+
!: lda stDig,x
|
|
1063
|
+
sta pnI
|
|
1064
|
+
ldy stPos,x
|
|
1065
|
+
jsr putNum
|
|
1066
|
+
inc statIdx
|
|
1067
|
+
lda statIdx
|
|
1068
|
+
cmp #8
|
|
1069
|
+
bcc !+
|
|
1070
|
+
lda #0
|
|
1071
|
+
sta statIdx
|
|
1072
|
+
!: rts
|
|
1073
|
+
|
|
1074
|
+
putByte:
|
|
1075
|
+
sta zv
|
|
1076
|
+
lda #0
|
|
1077
|
+
sta zv+1
|
|
1078
|
+
lda #2
|
|
1079
|
+
sta pnI
|
|
1080
|
+
// fall through
|
|
1081
|
+
|
|
1082
|
+
// zv = value, Y = position in statBuf, pnI = first power of ten to use
|
|
1083
|
+
putNum:
|
|
1084
|
+
pn_dig: lda #0
|
|
1085
|
+
sta pnD
|
|
1086
|
+
pn_sub: ldx pnI
|
|
1087
|
+
lda zv
|
|
1088
|
+
sec
|
|
1089
|
+
sbc pwTabLo,x
|
|
1090
|
+
sta pnTL
|
|
1091
|
+
lda zv+1
|
|
1092
|
+
sbc pwTabHi,x
|
|
1093
|
+
bcc pn_out
|
|
1094
|
+
sta zv+1
|
|
1095
|
+
lda pnTL
|
|
1096
|
+
sta zv
|
|
1097
|
+
inc pnD
|
|
1098
|
+
jmp pn_sub
|
|
1099
|
+
pn_out: lda pnD
|
|
1100
|
+
clc
|
|
1101
|
+
adc #$30
|
|
1102
|
+
sta statBuf,y
|
|
1103
|
+
iny
|
|
1104
|
+
inc pnI
|
|
1105
|
+
lda pnI
|
|
1106
|
+
cmp #5
|
|
1107
|
+
bne pn_dig
|
|
1108
|
+
rts
|
|
1109
|
+
|
|
1110
|
+
stampStatus:
|
|
1111
|
+
ldx #39
|
|
1112
|
+
ss_l: lda statBuf,x
|
|
1113
|
+
sta SCR0+40,x
|
|
1114
|
+
sta SCR1+40,x
|
|
1115
|
+
lda #$01
|
|
1116
|
+
sta $d800+40,x
|
|
1117
|
+
dex
|
|
1118
|
+
bpl ss_l
|
|
1119
|
+
rts
|
|
1120
|
+
|
|
1121
|
+
// --- one-off setup ---------------------------------------------------
|
|
1122
|
+
clearScreens:
|
|
1123
|
+
ldx #0
|
|
1124
|
+
lda #$20
|
|
1125
|
+
!: sta SCR0,x
|
|
1126
|
+
sta SCR0+$100,x
|
|
1127
|
+
sta SCR0+$200,x
|
|
1128
|
+
sta SCR0+$300,x
|
|
1129
|
+
sta SCR1,x
|
|
1130
|
+
sta SCR1+$100,x
|
|
1131
|
+
sta SCR1+$200,x
|
|
1132
|
+
sta SCR1+$300,x
|
|
1133
|
+
inx
|
|
1134
|
+
bne !-
|
|
1135
|
+
rts
|
|
1136
|
+
|
|
1137
|
+
genWorld:
|
|
1138
|
+
lda #<WORLD
|
|
1139
|
+
sta wptr
|
|
1140
|
+
lda #>WORLD
|
|
1141
|
+
sta wptr+1
|
|
1142
|
+
lda #<WCOL
|
|
1143
|
+
sta cptr
|
|
1144
|
+
lda #>WCOL
|
|
1145
|
+
sta cptr+1
|
|
1146
|
+
lda #0
|
|
1147
|
+
sta wy
|
|
1148
|
+
gw_row:
|
|
1149
|
+
lda #0
|
|
1150
|
+
sta wx
|
|
1151
|
+
gw_col:
|
|
1152
|
+
lda wx
|
|
1153
|
+
and #7
|
|
1154
|
+
sta t1
|
|
1155
|
+
lda wy
|
|
1156
|
+
and #7
|
|
1157
|
+
sta t2
|
|
1158
|
+
lda #$20
|
|
1159
|
+
sta ztmp
|
|
1160
|
+
lda t2
|
|
1161
|
+
bne gw_x
|
|
1162
|
+
lda #$40 // horizontal rule
|
|
1163
|
+
sta ztmp
|
|
1164
|
+
gw_x:
|
|
1165
|
+
lda t1
|
|
1166
|
+
bne gw_b
|
|
1167
|
+
lda t2
|
|
1168
|
+
bne gw_v
|
|
1169
|
+
lda #$51 // ball at a grid crossing
|
|
1170
|
+
sta ztmp
|
|
1171
|
+
jmp gw_b
|
|
1172
|
+
gw_v:
|
|
1173
|
+
lda #$5d // vertical rule
|
|
1174
|
+
sta ztmp
|
|
1175
|
+
gw_b:
|
|
1176
|
+
lda wx
|
|
1177
|
+
beq gw_edge
|
|
1178
|
+
cmp #WORLD_W-1
|
|
1179
|
+
beq gw_edge
|
|
1180
|
+
lda wy
|
|
1181
|
+
beq gw_edge
|
|
1182
|
+
cmp #WORLD_H-1
|
|
1183
|
+
beq gw_edge
|
|
1184
|
+
jmp gw_put
|
|
1185
|
+
gw_edge:
|
|
1186
|
+
lda #$a0 // solid world edge
|
|
1187
|
+
sta ztmp
|
|
1188
|
+
gw_put:
|
|
1189
|
+
lda ztmp // colour follows the tile code
|
|
1190
|
+
ldx #2 // red edge
|
|
1191
|
+
cmp #$a0
|
|
1192
|
+
beq gw_pc
|
|
1193
|
+
ldx #1 // white ball
|
|
1194
|
+
cmp #$51
|
|
1195
|
+
beq gw_pc
|
|
1196
|
+
ldx #11 // dark grey background
|
|
1197
|
+
cmp #$20
|
|
1198
|
+
beq gw_pc
|
|
1199
|
+
ldx #14 // light blue rules
|
|
1200
|
+
gw_pc:
|
|
1201
|
+
ldy #0
|
|
1202
|
+
lda ztmp
|
|
1203
|
+
sta (wptr),y
|
|
1204
|
+
txa
|
|
1205
|
+
sta (cptr),y
|
|
1206
|
+
inc wptr
|
|
1207
|
+
bne !+
|
|
1208
|
+
inc wptr+1
|
|
1209
|
+
!: inc cptr
|
|
1210
|
+
bne !+
|
|
1211
|
+
inc cptr+1
|
|
1212
|
+
!: inc wx
|
|
1213
|
+
lda wx
|
|
1214
|
+
cmp #WORLD_W
|
|
1215
|
+
beq !+
|
|
1216
|
+
jmp gw_col
|
|
1217
|
+
!: inc wy
|
|
1218
|
+
lda wy
|
|
1219
|
+
cmp #WORLD_H
|
|
1220
|
+
beq !+
|
|
1221
|
+
jmp gw_row
|
|
1222
|
+
!:
|
|
1223
|
+
|
|
1224
|
+
lda #<(WORLD + MARK_Y*WORLD_W + MARK_X)
|
|
1225
|
+
sta wptr
|
|
1226
|
+
lda #>(WORLD + MARK_Y*WORLD_W + MARK_X)
|
|
1227
|
+
sta wptr+1
|
|
1228
|
+
ldy #0
|
|
1229
|
+
lda #MARK_CH
|
|
1230
|
+
sta (wptr),y
|
|
1231
|
+
lda #<(WCOL + MARK_Y*WORLD_W + MARK_X)
|
|
1232
|
+
sta wptr
|
|
1233
|
+
lda #>(WCOL + MARK_Y*WORLD_W + MARK_X)
|
|
1234
|
+
sta wptr+1
|
|
1235
|
+
lda #7 // yellow marker
|
|
1236
|
+
sta (wptr),y
|
|
1237
|
+
rts
|
|
1238
|
+
|
|
1239
|
+
// --- tables ----------------------------------------------------------
|
|
1240
|
+
d018T: .byte $14, $24
|
|
1241
|
+
pageHiT: .byte >SCR0, >SCR1
|
|
1242
|
+
statBuf: .fill 40, $20
|
|
1243
|
+
rowLoT: .fill 25, <(i*40)
|
|
1244
|
+
rowHiT: .fill 25, >(i*40)
|
|
1245
|
+
stSrc: .byte camx, camy, legIdx, stalls, worst, lateApply, skipPrep, b1Dead
|
|
1246
|
+
stPos: .byte 2, 7, 12, 16, 20, 26, 30, 35
|
|
1247
|
+
stDig: .byte 2, 2, 2, 2, 0, 2, 2, 2
|
|
1248
|
+
stWrd: .byte 0, 0, 0, 0, 1, 0, 0, 0
|
|
1249
|
+
pwTabLo: .byte <10000, <1000, <100, <10, <1
|
|
1250
|
+
pwTabHi: .byte >10000, >1000, >100, >10, >1
|
|
1251
|
+
|
|
1252
|
+
// right, down, left, up, down-right, down-left, up-left, up-right
|
|
1253
|
+
pathDX: .byte 1, 0, $ff, 0, 1, $ff, $ff, 1
|
|
1254
|
+
pathDY: .byte 0, 1, 0, $ff, 1, 1, $ff, $ff
|
|
1255
|
+
pathLen: .byte 32, 32, 32, 32, 32, 32, 32, 32
|
|
1256
|
+
```
|
|
1257
|
+
|
|
1258
|
+
## Build
|
|
1259
|
+
|
|
1260
|
+
```bash
|
|
1261
|
+
java -jar KickAss.jar eight-way-scroll.asm -o eight-way-scroll.prg
|
|
1262
|
+
x64sc -default -warp +sound +autostart-delay-random -autostartprgmode 1 \
|
|
1263
|
+
-limitcycles 20946000 -exitscreenshot eight-way-scroll.png \
|
|
1264
|
+
-autostart eight-way-scroll.prg
|
|
1265
|
+
```
|
|
1266
|
+
|
|
1267
|
+
## Expected output
|
|
1268
|
+
|
|
1269
|
+
A grid of light blue rules on black with white balls at the crossings,
|
|
1270
|
+
sliding in whichever direction the current leg is going, and a yellow
|
|
1271
|
+
marker tile that moves with the world. Row 1 carries the readout. The
|
|
1272
|
+
border is green from frame 320 on.
|
|
1273
|
+
|
|
1274
|
+
The readout is sampled: one of its eight fields is rebuilt each frame, so
|
|
1275
|
+
a field can be up to eight frames behind the camera. Measured in the exit
|
|
1276
|
+
screenshots, both models at 20,946,000 cycles, in a clean window at least
|
|
1277
|
+
four fields past the last tile crossing:
|
|
1278
|
+
|
|
1279
|
+
| Model | Camera | Leg | Waited flips | Worst field | Late applies | Skipped preps | First-band deadline |
|
|
1280
|
+
|---|---|---|---|---|---|---|---|
|
|
1281
|
+
| PAL | 69, 127 | 5 | 0 | 13,111 | 0 | 0 | 0 |
|
|
1282
|
+
| NTSC | 63, 73 | 7 | 0 | 13,152 | 0 | 0 | 0 |
|
|
1283
|
+
|
|
1284
|
+
The border is green in both, so the marker check held on every frame of
|
|
1285
|
+
both runs. The two pictures are byte-identical across two runs of the
|
|
1286
|
+
same command.
|
|
1287
|
+
|
|
1288
|
+
The rules sit eight tiles apart in the world, so they land 64 pixels apart
|
|
1289
|
+
in the picture, and their phase is the camera's position within that
|
|
1290
|
+
64-pixel period. The camera positions above are from the HUD at the exit
|
|
1291
|
+
screenshot; the rule geometry varies with camera position.
|
|
1292
|
+
|
|
1293
|
+
A tile crossing produces four colour-write fields: the first top call
|
|
1294
|
+
(`BAND_FIRST = 5` rows, rows 0 to 4), the second top call (rows 5 to 11),
|
|
1295
|
+
the first bottom call (rows 12 to 18) and the second bottom call (rows 19
|
|
1296
|
+
to 24). During those fields, rows not yet rewritten show the previous
|
|
1297
|
+
origin's colour alongside the new matrix. The exit screenshots above are
|
|
1298
|
+
taken in the clean window; a capture inside the three stale fields shows
|
|
1299
|
+
grey horizontal rules in the rows not yet rewritten and a dimmer HUD row
|
|
1300
|
+
for one field while row 1's colour updates. This is documented in "What it
|
|
1301
|
+
does not establish" below.
|
|
1302
|
+
|
|
1303
|
+
Screenshots from the VICE runs this page describes:
|
|
1304
|
+
`screenshots/eight-way-scroll.png` (PAL) and
|
|
1305
|
+
`screenshots/eight-way-scroll-ntsc.png`.
|
|
1306
|
+
|
|
1307
|
+
## Why this works
|
|
1308
|
+
|
|
1309
|
+
### Fine scroll and the tile origin
|
|
1310
|
+
|
|
1311
|
+
The camera is a position in world pixels. Its tile origin is `camx >> 3`
|
|
1312
|
+
and `camy >> 3`, and the sub-tile remainder is what the fine scroll has to
|
|
1313
|
+
absorb. XSCROLL moves the display right, so a camera moving right needs a
|
|
1314
|
+
decreasing XSCROLL: the listing writes `7 - (camx & 7)` and
|
|
1315
|
+
`7 - (camy & 7)`, which walks 7 down to 0 across a tile and wraps as the
|
|
1316
|
+
origin advances.
|
|
1317
|
+
|
|
1318
|
+
Both registers are written whole, never read-modify-write, so CSEL, MCM,
|
|
1319
|
+
the raster compare's high bit and DEN keep the values the listing intends.
|
|
1320
|
+
RSEL and CSEL are both left at 0. The narrow window hides the partial row
|
|
1321
|
+
at each edge, so a 40 x 25 matrix covers the display at every fine scroll
|
|
1322
|
+
value and no column or row is half drawn at the border.
|
|
1323
|
+
|
|
1324
|
+
### Why the matrix is double buffered
|
|
1325
|
+
|
|
1326
|
+
A whole-tile step needs all 1,000 matrix bytes replaced. That copy is far
|
|
1327
|
+
too long for the blank on either model, so it cannot be done between
|
|
1328
|
+
fields; drawn into the live page it would be visible as a tear running
|
|
1329
|
+
down the screen. Instead it goes into the page that is not on display, and
|
|
1330
|
+
only the `$D018` VM nibble changes when it is complete. The flip is one
|
|
1331
|
+
store in the blank.
|
|
1332
|
+
|
|
1333
|
+
The flip is refused unless the spare page already holds exactly the origin
|
|
1334
|
+
wanted, and every refusal is counted. That counter reading zero is the
|
|
1335
|
+
evidence that the redraw always finished in time.
|
|
1336
|
+
|
|
1337
|
+
### Drawing for the origin after next, not the current one
|
|
1338
|
+
|
|
1339
|
+
The spare page cannot be drawn for the origin the camera has now, because
|
|
1340
|
+
by the time it is ready the camera has moved on. It is drawn for the
|
|
1341
|
+
origin after the next tile crossing. On a diagonal the two axes cross on
|
|
1342
|
+
different frames, and a single spare page cannot serve two origins, so the
|
|
1343
|
+
listing works out which axis crosses first, from `8 - (cam & 7)` when that
|
|
1344
|
+
axis is increasing and `(cam & 7) + 1` when it is decreasing, and targets
|
|
1345
|
+
that crossing alone.
|
|
1346
|
+
|
|
1347
|
+
The gap between crossings is set by the camera's starting position within
|
|
1348
|
+
its tile. Starting both axes at 66 (2 within the tile) at half speed, the
|
|
1349
|
+
smallest gap anywhere on the path is six fields: the three-field minimum
|
|
1350
|
+
at one pixel per field doubles when the camera moves one pixel every two
|
|
1351
|
+
fields. An earlier start position gave a gap of one at full speed and the
|
|
1352
|
+
flip was refused on every diagonal.
|
|
1353
|
+
|
|
1354
|
+
### Splitting the redraw
|
|
1355
|
+
|
|
1356
|
+
`BAND_MAX` rows per field is the cap that applies everywhere. With
|
|
1357
|
+
`BAND_MAX = 7` and a 25-row matrix, the spare page is ready in at most
|
|
1358
|
+
four fields. The camera advances one pixel every two fields, so tile
|
|
1359
|
+
crossings are sixteen fields apart on straight legs and there is always room.
|
|
1360
|
+
|
|
1361
|
+
The requirement is five fields: four fields of matrix redraw make the spare
|
|
1362
|
+
page ready so a flip is possible from the fifth field, and the four colour
|
|
1363
|
+
calls finish in the same span. The minimum gap between crossings is six
|
|
1364
|
+
fields at half speed, leaving one field of slack. Half speed is sufficient;
|
|
1365
|
+
a slower rate is not needed.
|
|
1366
|
+
|
|
1367
|
+
In the flip field, the matrix band is drawn into the page still on display
|
|
1368
|
+
until raster 251. `irqPrep` toggles `pgVis` at the flip decision while
|
|
1369
|
+
`pendVM` is applied at 251; `drawMatrix` targets `pgVis eor 1`, so the
|
|
1370
|
+
band drawn between raster 152 + YSCROLL and 251 goes into the page the
|
|
1371
|
+
beam is still showing. This is safe because `BAND_MAX = 7` keeps those
|
|
1372
|
+
rows (0 to 6) above the beam at that raster. Raising `BAND_MAX` past 12
|
|
1373
|
+
would draw into rows the beam has already reached, tearing the live page.
|
|
1374
|
+
|
|
1375
|
+
An earlier rule let a field with no colour work clear the whole debt. That
|
|
1376
|
+
looked equivalent and was not: a change of leg moves the target origin
|
|
1377
|
+
with no page flip, so a plain field started a 25-row redraw from nothing
|
|
1378
|
+
and the field cost 20,506 cycles. Capping every band fixed it.
|
|
1379
|
+
|
|
1380
|
+
A second wrap arriving mid-redraw cannot happen here, because the redraw
|
|
1381
|
+
always completes in four fields and the gap is sixteen on straight legs at half speed. If
|
|
1382
|
+
it did, the flip would be refused, the waited-flips counter would rise and
|
|
1383
|
+
the verdict would fail; the program does not try to abandon a part-drawn
|
|
1384
|
+
page.
|
|
1385
|
+
|
|
1386
|
+
### Colour RAM
|
|
1387
|
+
|
|
1388
|
+
Colour RAM has one copy at `$D800` whatever `$D018` says, so it cannot be
|
|
1389
|
+
flipped with the matrix. Both halves are written in `irqColB` at raster 4.
|
|
1390
|
+
|
|
1391
|
+
On NTSC, `irqApply` (register writes plus readout stamp) exceeds the
|
|
1392
|
+
twelve-raster blank and finishes inside the next field, so `irqColB`
|
|
1393
|
+
starts as late as raster 33. The first top call is limited to `BAND_FIRST
|
|
1394
|
+
= 5` rows (rows 0 to 4) so it finishes before row 6's badline even at the
|
|
1395
|
+
worst-case entry raster. The remaining calls use `BAND_MAX = 7`, which
|
|
1396
|
+
always finishes before `irqPrep`'s raster.
|
|
1397
|
+
|
|
1398
|
+
The split at row 12 gives the top half twelve rows and the bottom thirteen.
|
|
1399
|
+
Rows 0 to 4 see new colour in the flip field if the first call finishes in
|
|
1400
|
+
time; rows 5 to 24 show old colour for one to three more fields. Over a
|
|
1401
|
+
512-field loop about one field in four shows stale rows somewhere, and
|
|
1402
|
+
three fields in eight on the opposite-sign diagonals where crossings are
|
|
1403
|
+
closer together.
|
|
1404
|
+
|
|
1405
|
+
### The IRQ chain
|
|
1406
|
+
|
|
1407
|
+
Three handlers a field: raster 4 for the band-limited colour write,
|
|
1408
|
+
152 + YSCROLL for the path step, flip decision and matrix band, and 251
|
|
1409
|
+
for the register writes in the blank. Each arms the next one's `$D012` and
|
|
1410
|
+
vector as its first act, before doing any work. A handler here can run for
|
|
1411
|
+
well over a raster line, and if it armed its successor at the end it would
|
|
1412
|
+
arm a compare the beam had already passed and lose a whole field.
|
|
1413
|
+
|
|
1414
|
+
The VIC sets the raster interrupt flag regardless of the CPU's interrupt
|
|
1415
|
+
state. When the CPU's I flag is set because a previous handler is still
|
|
1416
|
+
running, the CPU defers the new interrupt and takes it at the current
|
|
1417
|
+
handler's `rti`. That is what lets a late `irqApply` be detected: if
|
|
1418
|
+
`irqPrep` overruns the 251-raster mark, `irqApply` fires after the `rti`
|
|
1419
|
+
at whatever raster `irqPrep` left the CPU, and reading `$D012` at
|
|
1420
|
+
`irqApply`'s entry gives a number below 251.
|
|
1421
|
+
|
|
1422
|
+
The `$D016` write is deliberately whole-register (`lda pendD16; sta $D016`)
|
|
1423
|
+
rather than read-modify-write. Two lint findings flag this as a potential
|
|
1424
|
+
CSEL or MCM collision, but the write is intentional: CSEL and MCM are both
|
|
1425
|
+
left at 0 throughout, and a read-modify-write would require an extra byte
|
|
1426
|
+
of state to track the stable bits.
|
|
1427
|
+
|
|
1428
|
+
`$01` is set to `$35`, so RAM is banked in under BASIC and KERNAL with I/O
|
|
1429
|
+
still visible and the vector at `$FFFE` is the one that runs.
|
|
1430
|
+
|
|
1431
|
+
### Where the code lives
|
|
1432
|
+
|
|
1433
|
+
The two screen pages are `$0400` and `$0800`, both in VIC bank 0. The
|
|
1434
|
+
program is at `$1000`, which the chip sees as character ROM, so that RAM
|
|
1435
|
+
is free for code and cannot be mistaken for screen data. An earlier draft
|
|
1436
|
+
sat at `$0810` and the routine that clears the second screen page wrote
|
|
1437
|
+
over it; the program ran once, cleared itself and stopped with the BASIC
|
|
1438
|
+
screen still up.
|
|
1439
|
+
|
|
1440
|
+
### What the timer measures
|
|
1441
|
+
|
|
1442
|
+
CIA 1 timer B free-runs from `$FFFF`. Each handler reads it on entry and
|
|
1443
|
+
on exit and adds the difference to a per-field total, which the last
|
|
1444
|
+
handler compares against the worst seen. The count is wall-clock, so
|
|
1445
|
+
badline stalls are in it: the VIC holds the CPU for about 40 to 43 cycles
|
|
1446
|
+
on every eighth line, and a copy loop that costs 14 cycles a byte in
|
|
1447
|
+
instruction terms measures 17.6 to 17.8 cycles per byte. That figure comes
|
|
1448
|
+
from reading the CIA timer before and after a full 25-row draw (1,000
|
|
1449
|
+
bytes) at start-up on both models; it is a measured average, not
|
|
1450
|
+
calculated from instruction timings alone.
|
|
1451
|
+
|
|
1452
|
+
The readout is inside the measured region. It builds one of its eight
|
|
1453
|
+
fields a frame for that reason: built whole every sixteenth frame it added
|
|
1454
|
+
about 3,000 cycles to whichever field it landed on, and the worst field is
|
|
1455
|
+
the number this page reports.
|
|
1456
|
+
|
|
1457
|
+
A PAL field is 19,656 cycles and an NTSC field 17,095. The worst field
|
|
1458
|
+
measured here is 13,111 on PAL and 13,152 on NTSC, both under the 18,000
|
|
1459
|
+
budget the verdict checks. The NTSC figure is the larger of the two:
|
|
1460
|
+
3,943 cycles of margin, twenty-three per cent of the field.
|
|
1461
|
+
|
|
1462
|
+
### What it does not establish
|
|
1463
|
+
|
|
1464
|
+
**Colour continuity across a flip.** A tile crossing writes colour to
|
|
1465
|
+
colour RAM over four consecutive `irqColB` calls (two for the top half,
|
|
1466
|
+
two for the bottom). During those fields the rows not yet rewritten show
|
|
1467
|
+
the previous origin's colour alongside the new matrix, producing a brief
|
|
1468
|
+
mismatch. This lasts three displayed fields (60 ms PAL, 50 ms NTSC) and
|
|
1469
|
+
is the trade-off the band cap makes. Rows 0 to 4 may show old colour for
|
|
1470
|
+
one field on NTSC when `irqColB` starts late enough that the first band
|
|
1471
|
+
finishes after row 4's badline.
|
|
1472
|
+
|
|
1473
|
+
**Camera path coverage.** `MAX_COL` and `MAX_ROW` clamp the visible
|
|
1474
|
+
origin so the camera never leaves the world. The path used here stays in
|
|
1475
|
+
columns 4 to 12 and rows 8 to 16, so those clamps are never reached.
|
|
1476
|
+
Whether the design is correct at the boundary is not tested.
|
|
1477
|
+
|
|
1478
|
+
**The one-pixel-per-field form.** At full speed the camera crosses a tile
|
|
1479
|
+
boundary every field. Tile crossings are then eight fields apart on
|
|
1480
|
+
straight legs, but the minimum gap on diagonals falls to three fields,
|
|
1481
|
+
which is less than the five-field requirement. The band at `BAND_MAX = 7`
|
|
1482
|
+
fits the available windows at either speed; what full speed loses is the
|
|
1483
|
+
crossing gap. The half-speed camera doubles the minimum gap to six fields
|
|
1484
|
+
and leaves one field of slack.
|