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,930 @@
|
|
|
1
|
+
---
|
|
2
|
+
recipe: pseudo-3d-road
|
|
3
|
+
toolchain: kickassembler
|
|
4
|
+
output_format: PRG
|
|
5
|
+
region: both
|
|
6
|
+
techniques: [pseudo_3d_road_raster]
|
|
7
|
+
file_formats: [PRG]
|
|
8
|
+
uses_registers: [D011, D012, D016, D018, D019, D01A, D021, D022, D023, DC04, DC05, DC0E]
|
|
9
|
+
uses_kernal: []
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
<!-- doc-type: recipe -->
|
|
13
|
+
|
|
14
|
+
# KickAssembler — Pseudo-3D Curving Road
|
|
15
|
+
|
|
16
|
+
## Synopsis
|
|
17
|
+
|
|
18
|
+
A perspective road that appears to recede toward a horizon and curve left and
|
|
19
|
+
right, built from two layers. The coarse layer redraws thirteen character rows
|
|
20
|
+
of road in the vertical blank using multicolour characters (grass, road
|
|
21
|
+
surface, kerb, centre stripe) placed at positions derived from a Z table and
|
|
22
|
+
an 8.8 fixed-point centre accumulator. The fine layer runs a cycle-locked
|
|
23
|
+
loop starting at line 99 that writes a precomputed $D016 value for each of
|
|
24
|
+
the hundred road raster lines (100..199), placing the STA $D016 write at
|
|
25
|
+
cycle 11 of each line (before the cycle-14 VIC deadline). The road curves
|
|
26
|
+
because a per-frame delta accumulates signed fixed-point offsets from a
|
|
27
|
+
four-entry segment table; as scroll_z advances the four segments roll toward
|
|
28
|
+
the viewer. Verdict bytes and CIA-timed cycle counts land at $02F0-$02F3 and $02FF.
|
|
29
|
+
|
|
30
|
+
The fine layer uses the double-IRQ method from `stable_raster_irq.md` to
|
|
31
|
+
reach cycle 4 of line 100 with zero jitter, then runs an unrolled 100-iteration
|
|
32
|
+
loop. Each iteration is exactly one raster line long: 63 CPU cycles on PAL,
|
|
33
|
+
65 on NTSC. Badline iterations (lines where (raster & 7) == YSCROLL = 3)
|
|
34
|
+
use 23 CPU cycles on PAL (25 on NTSC); the 40-cycle badline steal absorbs
|
|
35
|
+
the remainder. Separate unrolled loops for PAL and NTSC are selected at boot.
|
|
36
|
+
|
|
37
|
+
## Source
|
|
38
|
+
|
|
39
|
+
```asm
|
|
40
|
+
// pseudo-3d-road.asm KickAssembler 5.25
|
|
41
|
+
//
|
|
42
|
+
// Pseudo-3D curving road: multicolour characters (coarse) + per-line
|
|
43
|
+
// $D016 XSCROLL (fine). Charset $3000, screen $0400, VIC bank 0.
|
|
44
|
+
//
|
|
45
|
+
// Three IRQ handlers per frame:
|
|
46
|
+
// vblank_irq (line 251): compute cx[]/xscroll_d16[], CIA-time coarse redraw,
|
|
47
|
+
// verdict, re-arm for road_irq1.
|
|
48
|
+
// road_irq1 (line 97): start CIA fine timer, double-IRQ setup, NOP slide.
|
|
49
|
+
// road_irq2_pal / road_irq2_ntsc (line 99): cycle-exact sync via double
|
|
50
|
+
// $D012 read + BEQ, unrolled 100-iteration fine loop, epilogue.
|
|
51
|
+
//
|
|
52
|
+
// Cycle arithmetic (both models land at cycle 4 of line 100 after BEQ sync):
|
|
53
|
+
// LDA xscroll_d16+j : cycles 4..7 of line 100+j
|
|
54
|
+
// STA $D016 : cycles 8..11 (WRITE at cycle 11, before cycle-14 deadline)
|
|
55
|
+
// PAL normal body : LDA(4) + STA(4) + Delay(55) = 63 cpu cycles
|
|
56
|
+
// PAL badline body : LDA(4) + STA(4) + Delay(15) = 23 cpu cycles + 40 stall = 63 elapsed
|
|
57
|
+
// NTSC normal body : LDA(4) + STA(4) + Delay(57) = 65 cpu cycles
|
|
58
|
+
// NTSC badline body : LDA(4) + STA(4) + Delay(17) = 25 cpu cycles + 40 stall = 65 elapsed
|
|
59
|
+
// Badlines in 100..199 with YSCROLL=3: lines 107,115,123,131,139,147,155,163,171,179,187,195
|
|
60
|
+
//
|
|
61
|
+
// Sync calibration (road_irq1 before NOP slide: 57 cycles PAL, 55 NTSC):
|
|
62
|
+
// C2 = irq2 entry cycle on line 99 = 38 (zero-jitter) or 39 (one-jitter).
|
|
63
|
+
// Path inside irq2: ldx+txs(6)+cld(2)+Delay(PAD)+lda+cmp = C2+15+PAD for 2nd read.
|
|
64
|
+
// PAL: second $D012 read at C2+15+PAD_PAL=63/64. PAD_PAL=10.
|
|
65
|
+
// NTSC: second $D012 read at C2+15+PAD_NTSC=65/66. PAD_NTSC=12.
|
|
66
|
+
// BEQ lands at cycle 4 of line 100; STA write at cycle 11.
|
|
67
|
+
//
|
|
68
|
+
// Verdict $02FF = 1 if coarse < 10 000 cycles AND kerb column matches.
|
|
69
|
+
// Coarse cycles at $02F0/$02F1; fine chain (irq1 start to fine_done) at $02F2/$02F3.
|
|
70
|
+
|
|
71
|
+
BasicUpstart2(main)
|
|
72
|
+
|
|
73
|
+
// ---- Memory map ----
|
|
74
|
+
.const SCREEN = $0400
|
|
75
|
+
.const CHARSET = $3000
|
|
76
|
+
.const COLRAM = $d800
|
|
77
|
+
|
|
78
|
+
// VIC registers
|
|
79
|
+
.const D011 = $d011
|
|
80
|
+
.const D012 = $d012
|
|
81
|
+
.const D016 = $d016
|
|
82
|
+
.const D018 = $d018
|
|
83
|
+
.const D019 = $d019
|
|
84
|
+
.const D01A = $d01a
|
|
85
|
+
.const D020 = $d020
|
|
86
|
+
.const D021 = $d021
|
|
87
|
+
.const D022 = $d022
|
|
88
|
+
.const D023 = $d023
|
|
89
|
+
|
|
90
|
+
// CIA1 timer A
|
|
91
|
+
.const CIA_TALO = $dc04
|
|
92
|
+
.const CIA_TAHI = $dc05
|
|
93
|
+
.const CIA_CRA = $dc0e
|
|
94
|
+
.const CIA_ICR = $dc0d
|
|
95
|
+
|
|
96
|
+
// Character codes (multicolour char pixel encoding)
|
|
97
|
+
// %00 -> $D021 (green, grass bg) CH_GRASS: all $00
|
|
98
|
+
// %01 -> $D022 (dark grey, road) CH_ROAD: all $55
|
|
99
|
+
// %10 -> $D023 (white, kerb) CH_KLEFT: $a5; CH_KRIGHT: $5a
|
|
100
|
+
// %11 -> colour RAM (bit3 set) CH_DASH: $69 (grey-white-white-grey)
|
|
101
|
+
.const CH_GRASS = 0
|
|
102
|
+
.const CH_ROAD = 1
|
|
103
|
+
.const CH_KLEFT = 2
|
|
104
|
+
.const CH_KRIGHT = 3
|
|
105
|
+
.const CH_DASH = 4
|
|
106
|
+
|
|
107
|
+
// VIC colours
|
|
108
|
+
.const C_GREEN = 5
|
|
109
|
+
.const C_DGREY = 11
|
|
110
|
+
.const C_WHITE = 1
|
|
111
|
+
.const C_BLACK = 0
|
|
112
|
+
.const C_RED = 2
|
|
113
|
+
.const C_BLUE = 6
|
|
114
|
+
|
|
115
|
+
// $D016 constant bits: MCM (bit4=1), CSEL/40col (bit3=1), XSCROLL=0
|
|
116
|
+
.const D016_BASE = $18
|
|
117
|
+
|
|
118
|
+
// Zero page
|
|
119
|
+
.const ZP_CXHI = $10 // cx high byte (integer pixel; 8.8 fixed point)
|
|
120
|
+
.const ZP_CXLO = $11 // cx low byte (8.8 fraction)
|
|
121
|
+
.const ZP_DXHI = $12 // dx high byte (signed per-line-per-line curvature)
|
|
122
|
+
.const ZP_DXLO = $13 // dx low byte
|
|
123
|
+
.const ZP_SCR = $14 // scroll_z (0..99; advances 1/frame)
|
|
124
|
+
.const ZP_SEG = $15 // current curve segment index (0..3)
|
|
125
|
+
.const ZP_REM = $16 // remaining lines until next segment switch
|
|
126
|
+
.const ZP_T1 = $17 // scratch
|
|
127
|
+
.const ZP_T2 = $18 // scratch
|
|
128
|
+
.const ZP_RPLO = $19 // row pointer lo (indirect indexed)
|
|
129
|
+
.const ZP_RPHI = $1a // row pointer hi
|
|
130
|
+
.const ZP_LC = $1b // left char column for current road row
|
|
131
|
+
.const ZP_RC = $1c // right char column for current road row
|
|
132
|
+
|
|
133
|
+
// Spec result addresses
|
|
134
|
+
.const COARSE_LO = $02f0
|
|
135
|
+
.const COARSE_HI = $02f1
|
|
136
|
+
.const FINE_LO = $02f2
|
|
137
|
+
.const FINE_HI = $02f3
|
|
138
|
+
.const VERDICT = $02ff
|
|
139
|
+
|
|
140
|
+
// Small variables (safe area, below spec result addresses)
|
|
141
|
+
.const SAVED_SP = $02e0 // saved stack pointer for double-IRQ
|
|
142
|
+
.const REG_FLAG = $02e1 // 0 = PAL, 1 = NTSC (set once at boot by detect_region)
|
|
143
|
+
|
|
144
|
+
// Road dimensions
|
|
145
|
+
.const NLINES = 100 // raster lines 100..199
|
|
146
|
+
.const NROWS = 13 // character rows 6..18 (r=0=nearest=row18 .. r=12=farthest=row6)
|
|
147
|
+
|
|
148
|
+
// Delay(n): exactly n cpu cycles of straight-line code, n >= 2.
|
|
149
|
+
.macro Delay(n) {
|
|
150
|
+
.if (n < 2) .error "Delay needs >= 2 cycles"
|
|
151
|
+
.if ((n & 1) != 0) { bit $ea }
|
|
152
|
+
.for (var i = 0; i < ((n & 1) != 0 ? n - 3 : n) / 2; i++) { nop }
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// ---- Working tables ($1100) ----
|
|
156
|
+
* = $1100
|
|
157
|
+
cx_hi_buf: .fill NLINES, 0 // cx integer part per i=0..99 (i=0=nearest)
|
|
158
|
+
xscroll_d16: .fill NLINES, D016_BASE // $D016 value per road line (index 0=line 100)
|
|
159
|
+
left_col: .fill NROWS, 0
|
|
160
|
+
right_col: .fill NROWS, 0
|
|
161
|
+
|
|
162
|
+
// ---- Static tables ($1200) ----
|
|
163
|
+
* = $1200
|
|
164
|
+
// hw[i] = max(4, round(152-1.5*i)), i=0..99. Arithmetic from spec.
|
|
165
|
+
hw_table:
|
|
166
|
+
.byte 152,151,149,148,146,145,143,142,140,139
|
|
167
|
+
.byte 137,136,134,133,131,130,128,127,125,124
|
|
168
|
+
.byte 122,121,119,118,116,115,113,112,110,109
|
|
169
|
+
.byte 107,106,104,103,101,100, 98, 97, 95, 94
|
|
170
|
+
.byte 92, 91, 89, 88, 86, 85, 83, 82, 80, 79
|
|
171
|
+
.byte 77, 76, 74, 73, 71, 70, 68, 67, 65, 64
|
|
172
|
+
.byte 62, 61, 59, 58, 56, 55, 53, 52, 50, 49
|
|
173
|
+
.byte 47, 46, 44, 43, 41, 40, 38, 37, 35, 34
|
|
174
|
+
.byte 32, 31, 29, 28, 26, 25, 23, 22, 20, 19
|
|
175
|
+
.byte 17, 16, 14, 13, 11, 10, 8, 7, 5, 4
|
|
176
|
+
|
|
177
|
+
// Curve deltas (4 segments): 0, +51, 0, -51 in 8.8 signed fixed point.
|
|
178
|
+
// -51 as 16-bit signed: $FFCD.
|
|
179
|
+
curve_lo: .byte 0, 51, 0, $cd
|
|
180
|
+
curve_hi: .byte 0, 0, 0, $ff
|
|
181
|
+
|
|
182
|
+
// Screen base addresses for road rows r=0..12 (row 18 down to row 6).
|
|
183
|
+
// SCREEN + row*40. Precomputed: row18=$06D0, row17=$06A8, ..., row6=$04F0.
|
|
184
|
+
road_lo: .byte $d0,$a8,$80,$58,$30,$08,$e0,$b8,$90,$68,$40,$18,$f0
|
|
185
|
+
road_hi: .byte $06,$06,$06,$06,$06,$06,$05,$05,$05,$05,$05,$05,$04
|
|
186
|
+
|
|
187
|
+
// ---- detect_region subroutine ($0A00) ----
|
|
188
|
+
// Sets REG_FLAG = 0 (PAL) or 1 (NTSC). Call with SEI; re-enables interrupts on exit.
|
|
189
|
+
// Method: track $D012 while RST8 is set; last value is $37 on PAL, $06/$05 on NTSC.
|
|
190
|
+
* = $0a00
|
|
191
|
+
detect_region:
|
|
192
|
+
sei
|
|
193
|
+
dr_wait_lo:
|
|
194
|
+
bit D011
|
|
195
|
+
bmi dr_wait_lo // let any current RST8 band finish
|
|
196
|
+
dr_wait_hi:
|
|
197
|
+
bit D011
|
|
198
|
+
bpl dr_wait_hi // wait for RST8 to set (line 256)
|
|
199
|
+
dr_track:
|
|
200
|
+
lda D012 // sample low byte
|
|
201
|
+
bit D011
|
|
202
|
+
bpl dr_band_over // keep only if RST8 still set
|
|
203
|
+
tax
|
|
204
|
+
jmp dr_track
|
|
205
|
+
dr_band_over: // X = last $D012 in band: $37=PAL, $06/$05=NTSC
|
|
206
|
+
lda #0
|
|
207
|
+
cpx #$10
|
|
208
|
+
bcs dr_set_flag // $10 or above: PAL, flag=0
|
|
209
|
+
lda #1 // below $10: NTSC, flag=1
|
|
210
|
+
dr_set_flag:
|
|
211
|
+
sta REG_FLAG
|
|
212
|
+
cli
|
|
213
|
+
rts
|
|
214
|
+
|
|
215
|
+
// ---- road_irq1 handler ($0B00) ----
|
|
216
|
+
// Fires at line 97 (two lines before the sync line 99).
|
|
217
|
+
// Starts CIA fine timer, arms road_irq2 for line 99, saves SP, CLI, NOP slide.
|
|
218
|
+
// irq2 fires during the NOP slide and returns via irq1's stack frame.
|
|
219
|
+
//
|
|
220
|
+
// road_irq1 cycle count before NOP slide:
|
|
221
|
+
// PAL path: CIA_start(16) + lda+bne(6) + vector_set(12) + jmp(3) + common(20) = 57 cycles
|
|
222
|
+
// NTSC path: CIA_start(16) + lda+bne(7) + vector_set(12) + common(20) = 55 cycles
|
|
223
|
+
// irq1 entry at cycle 37-39 of line 97 (main loop jmp = 3 cycles, 0-2 cycle jitter).
|
|
224
|
+
// NOP slide starts at cycle 22-24 of line 98.
|
|
225
|
+
// irq2 /IRQ fires at cycle 1 of line 99; CPU is in NOP slide.
|
|
226
|
+
// irq2 enters at cycle 38 (zero-jitter) or 39 (one-jitter) of line 99.
|
|
227
|
+
* = $0b00
|
|
228
|
+
road_irq1:
|
|
229
|
+
// Start CIA fine timer (will run until fine_done stops it)
|
|
230
|
+
lda #$ff // 2
|
|
231
|
+
sta CIA_TALO // 4
|
|
232
|
+
sta CIA_TAHI // 4
|
|
233
|
+
lda #$11 // 2 (START, PHI2 clock, continuous)
|
|
234
|
+
sta CIA_CRA // 4 = 16 cycles
|
|
235
|
+
|
|
236
|
+
// Select road_irq2 based on model
|
|
237
|
+
lda REG_FLAG // 4
|
|
238
|
+
bne ri1_ntsc // 2 (PAL: not taken); 3 (NTSC: taken)
|
|
239
|
+
ri1_pal:
|
|
240
|
+
lda #<road_irq2_pal // 2
|
|
241
|
+
sta $0314 // 4
|
|
242
|
+
lda #>road_irq2_pal // 2
|
|
243
|
+
sta $0315 // 4
|
|
244
|
+
jmp ri1_common // 3
|
|
245
|
+
ri1_ntsc:
|
|
246
|
+
lda #<road_irq2_ntsc // 2
|
|
247
|
+
sta $0314 // 4
|
|
248
|
+
lda #>road_irq2_ntsc // 2
|
|
249
|
+
sta $0315 // 4
|
|
250
|
+
ri1_common:
|
|
251
|
+
lda #99 // 2 arm irq2 for line 99
|
|
252
|
+
sta D012 // 4
|
|
253
|
+
lda #$01 // 2
|
|
254
|
+
sta D019 // 4 ack irq1
|
|
255
|
+
tsx // 2
|
|
256
|
+
stx SAVED_SP // 4 save SP for irq2 to discard irq2's own frame
|
|
257
|
+
cli // 2 allow irq2 to fire during NOP slide
|
|
258
|
+
|
|
259
|
+
// NOP slide: 40 NOPs = 80 cycles.
|
|
260
|
+
// irq2 fires before this completes and returns through irq1's frame.
|
|
261
|
+
.for (var i = 0; i < 40; i++) { nop }
|
|
262
|
+
|
|
263
|
+
// Should not reach here. Safety exit.
|
|
264
|
+
pla
|
|
265
|
+
tay
|
|
266
|
+
pla
|
|
267
|
+
tax
|
|
268
|
+
pla
|
|
269
|
+
rti
|
|
270
|
+
|
|
271
|
+
// ---- vblank_irq handler ($0C00) ----
|
|
272
|
+
// Fires at line 251. Computes tables, CIA-times coarse redraw, verdict.
|
|
273
|
+
// Re-arms for road_irq1 at line 97 and exits.
|
|
274
|
+
* = $0c00
|
|
275
|
+
vblank_irq:
|
|
276
|
+
cld // clear D flag (RTI restores P, so D is restored); arithmetic must be binary
|
|
277
|
+
|
|
278
|
+
// --- 1. Compute cx[] and xscroll_d16[] ---
|
|
279
|
+
//
|
|
280
|
+
// Forward pass i=0..99 (nearest to farthest).
|
|
281
|
+
// cx[0] = 160.0 (screen centre). dx = 0.
|
|
282
|
+
// Per step: cx += dx; dx += curve[segment].
|
|
283
|
+
// Segment changes every 25 lines; init from scroll_z.
|
|
284
|
+
// Store cx_hi_buf[i] = integer part of cx[i].
|
|
285
|
+
//
|
|
286
|
+
// Backward pass j=0..99:
|
|
287
|
+
// xscroll_d16[j] = D016_BASE | ((cx_hi_buf[99-j] - hw_table[99-j]) & 7)
|
|
288
|
+
// (j=0 = line 100 = farthest = i=99; j=99 = line 199 = nearest = i=0)
|
|
289
|
+
|
|
290
|
+
// Compute initial segment: scroll_z / 25 and scroll_z % 25
|
|
291
|
+
lda ZP_SCR
|
|
292
|
+
tax
|
|
293
|
+
lda #0
|
|
294
|
+
sta ZP_SEG
|
|
295
|
+
div25:
|
|
296
|
+
cpx #25
|
|
297
|
+
bcc div25_done
|
|
298
|
+
txa
|
|
299
|
+
sec
|
|
300
|
+
sbc #25
|
|
301
|
+
tax
|
|
302
|
+
inc ZP_SEG
|
|
303
|
+
jmp div25
|
|
304
|
+
div25_done:
|
|
305
|
+
// X = scroll_z % 25; ZP_SEG = scroll_z / 25
|
|
306
|
+
lda #25
|
|
307
|
+
stx ZP_T1
|
|
308
|
+
sec
|
|
309
|
+
sbc ZP_T1
|
|
310
|
+
sta ZP_REM // remaining = 25 - (scroll_z % 25)
|
|
311
|
+
|
|
312
|
+
// cx = 160.0; dx = 0.0
|
|
313
|
+
lda #160
|
|
314
|
+
sta ZP_CXHI
|
|
315
|
+
lda #0
|
|
316
|
+
sta ZP_CXLO
|
|
317
|
+
sta ZP_DXHI
|
|
318
|
+
sta ZP_DXLO
|
|
319
|
+
|
|
320
|
+
ldy #0 // i
|
|
321
|
+
fwd_lp:
|
|
322
|
+
// Store cx integer part
|
|
323
|
+
lda ZP_CXHI
|
|
324
|
+
sta cx_hi_buf, y
|
|
325
|
+
|
|
326
|
+
// cx += dx (16-bit 8.8)
|
|
327
|
+
clc
|
|
328
|
+
lda ZP_CXLO
|
|
329
|
+
adc ZP_DXLO
|
|
330
|
+
sta ZP_CXLO
|
|
331
|
+
lda ZP_CXHI
|
|
332
|
+
adc ZP_DXHI
|
|
333
|
+
bcc cx_ok // carry set = 8-bit overflow: clamp to 255
|
|
334
|
+
lda #$ff
|
|
335
|
+
cx_ok:
|
|
336
|
+
sta ZP_CXHI
|
|
337
|
+
// Clamp below 16 (road approaching left edge)
|
|
338
|
+
cmp #16
|
|
339
|
+
bcs cx_lo_ok
|
|
340
|
+
lda #16
|
|
341
|
+
sta ZP_CXHI
|
|
342
|
+
cx_lo_ok:
|
|
343
|
+
|
|
344
|
+
// dx += curve[segment] (16-bit signed)
|
|
345
|
+
ldx ZP_SEG
|
|
346
|
+
clc
|
|
347
|
+
lda ZP_DXLO
|
|
348
|
+
adc curve_lo, x
|
|
349
|
+
sta ZP_DXLO
|
|
350
|
+
lda ZP_DXHI
|
|
351
|
+
adc curve_hi, x
|
|
352
|
+
sta ZP_DXHI
|
|
353
|
+
|
|
354
|
+
// Advance segment counter
|
|
355
|
+
dec ZP_REM
|
|
356
|
+
bne fwd_no_seg
|
|
357
|
+
inc ZP_SEG
|
|
358
|
+
lda ZP_SEG
|
|
359
|
+
and #3
|
|
360
|
+
sta ZP_SEG
|
|
361
|
+
lda #25
|
|
362
|
+
sta ZP_REM
|
|
363
|
+
fwd_no_seg:
|
|
364
|
+
|
|
365
|
+
iny
|
|
366
|
+
cpy #NLINES
|
|
367
|
+
bne fwd_lp
|
|
368
|
+
|
|
369
|
+
// Backward pass: j=0..99, X=99..0 (read index), Y=0..99 (write index)
|
|
370
|
+
ldx #99
|
|
371
|
+
ldy #0
|
|
372
|
+
bwd_lp:
|
|
373
|
+
lda cx_hi_buf, x
|
|
374
|
+
sec
|
|
375
|
+
sbc hw_table, x // left_edge pixel (integer part)
|
|
376
|
+
and #$07 // XSCROLL = low 3 bits of left edge
|
|
377
|
+
ora #D016_BASE // add MCM+CSEL bits
|
|
378
|
+
sta xscroll_d16, y
|
|
379
|
+
dex
|
|
380
|
+
iny
|
|
381
|
+
cpy #NLINES
|
|
382
|
+
bne bwd_lp
|
|
383
|
+
|
|
384
|
+
// --- 2. Compute left_col[] and right_col[] for coarse layer ---
|
|
385
|
+
// For r=0..12: i_mid = min(8*r+4, 99)
|
|
386
|
+
// left_col[r] = (cx_hi_buf[i_mid] - hw_table[i_mid]) >> 3
|
|
387
|
+
// right_col[r] = (cx_hi_buf[i_mid] + hw_table[i_mid]) >> 3
|
|
388
|
+
ldx #0
|
|
389
|
+
cc_lp:
|
|
390
|
+
txa
|
|
391
|
+
asl
|
|
392
|
+
asl
|
|
393
|
+
asl // r*8
|
|
394
|
+
clc
|
|
395
|
+
adc #4 // r*8 + 4
|
|
396
|
+
cmp #NLINES
|
|
397
|
+
bcc cc_iok
|
|
398
|
+
lda #99
|
|
399
|
+
cc_iok:
|
|
400
|
+
tay // Y = i_mid
|
|
401
|
+
|
|
402
|
+
lda cx_hi_buf, y
|
|
403
|
+
sec
|
|
404
|
+
sbc hw_table, y
|
|
405
|
+
lsr
|
|
406
|
+
lsr
|
|
407
|
+
lsr // >> 3 = char column
|
|
408
|
+
cmp #40
|
|
409
|
+
bcc cc_lsave
|
|
410
|
+
lda #39
|
|
411
|
+
cc_lsave:
|
|
412
|
+
sta left_col, x
|
|
413
|
+
|
|
414
|
+
lda cx_hi_buf, y
|
|
415
|
+
clc
|
|
416
|
+
adc hw_table, y
|
|
417
|
+
bcs cc_rovf
|
|
418
|
+
lsr
|
|
419
|
+
lsr
|
|
420
|
+
lsr
|
|
421
|
+
cmp #40
|
|
422
|
+
bcc cc_rsave
|
|
423
|
+
cc_rovf:
|
|
424
|
+
lda #39
|
|
425
|
+
cc_rsave:
|
|
426
|
+
sta right_col, x
|
|
427
|
+
|
|
428
|
+
inx
|
|
429
|
+
cpx #NROWS
|
|
430
|
+
bne cc_lp
|
|
431
|
+
|
|
432
|
+
// --- 3. CIA-timed coarse screen redraw ---
|
|
433
|
+
lda #$ff
|
|
434
|
+
sta CIA_TALO
|
|
435
|
+
sta CIA_TAHI
|
|
436
|
+
lda #$11 // bit4=LOAD, bit0=START; phi2 clock, continuous
|
|
437
|
+
sta CIA_CRA
|
|
438
|
+
|
|
439
|
+
ldx #0 // r = 0..12
|
|
440
|
+
rdr_lp:
|
|
441
|
+
lda road_lo, x
|
|
442
|
+
sta ZP_RPLO
|
|
443
|
+
lda road_hi, x
|
|
444
|
+
sta ZP_RPHI
|
|
445
|
+
|
|
446
|
+
// Left kerb
|
|
447
|
+
ldy left_col, x
|
|
448
|
+
lda #CH_KLEFT
|
|
449
|
+
sta (ZP_RPLO), y
|
|
450
|
+
|
|
451
|
+
// Road fill from left_col+1 to right_col-1
|
|
452
|
+
lda left_col, x
|
|
453
|
+
sta ZP_LC
|
|
454
|
+
lda right_col, x
|
|
455
|
+
sta ZP_RC
|
|
456
|
+
ldy ZP_LC
|
|
457
|
+
iny
|
|
458
|
+
lda #CH_ROAD
|
|
459
|
+
rf:
|
|
460
|
+
cpy ZP_RC
|
|
461
|
+
bcs rf_end
|
|
462
|
+
sta (ZP_RPLO), y
|
|
463
|
+
iny
|
|
464
|
+
jmp rf
|
|
465
|
+
rf_end:
|
|
466
|
+
|
|
467
|
+
// Right kerb
|
|
468
|
+
ldy ZP_RC
|
|
469
|
+
lda #CH_KRIGHT
|
|
470
|
+
sta (ZP_RPLO), y
|
|
471
|
+
|
|
472
|
+
// Centre dash: place CH_DASH at centre col if (r + scroll_z/8) & 1 == 0
|
|
473
|
+
lda ZP_LC
|
|
474
|
+
clc
|
|
475
|
+
adc ZP_RC
|
|
476
|
+
ror // A = (LC+RC)/2 (carry=0 since LC+RC<=78)
|
|
477
|
+
tay // Y = centre column
|
|
478
|
+
|
|
479
|
+
lda ZP_SCR
|
|
480
|
+
lsr
|
|
481
|
+
lsr
|
|
482
|
+
lsr // scroll_z / 8
|
|
483
|
+
stx ZP_T2 // save r
|
|
484
|
+
clc
|
|
485
|
+
adc ZP_T2 // + r
|
|
486
|
+
and #1
|
|
487
|
+
bne skip_dash
|
|
488
|
+
lda #CH_DASH
|
|
489
|
+
sta (ZP_RPLO), y
|
|
490
|
+
skip_dash:
|
|
491
|
+
ldx ZP_T2
|
|
492
|
+
inx
|
|
493
|
+
cpx #NROWS
|
|
494
|
+
bne rdr_lp
|
|
495
|
+
|
|
496
|
+
// Stop coarse timer, record cycles
|
|
497
|
+
lda #0
|
|
498
|
+
sta CIA_CRA
|
|
499
|
+
sec
|
|
500
|
+
lda #$ff
|
|
501
|
+
sbc CIA_TALO
|
|
502
|
+
sta COARSE_LO
|
|
503
|
+
lda #$ff
|
|
504
|
+
sbc CIA_TAHI
|
|
505
|
+
sta COARSE_HI
|
|
506
|
+
|
|
507
|
+
// --- 4. Advance scroll_z ---
|
|
508
|
+
inc ZP_SCR
|
|
509
|
+
lda ZP_SCR
|
|
510
|
+
cmp #NLINES
|
|
511
|
+
bcc scr_ok
|
|
512
|
+
lda #0
|
|
513
|
+
sta ZP_SCR
|
|
514
|
+
scr_ok:
|
|
515
|
+
|
|
516
|
+
// --- 5. Verdict ---
|
|
517
|
+
// (a) coarse < 10000 ($2710)
|
|
518
|
+
// (b) kerb col for row 18 (r=0, i_mid=4) == left_col[0]
|
|
519
|
+
lda cx_hi_buf+4
|
|
520
|
+
sec
|
|
521
|
+
sbc hw_table+4
|
|
522
|
+
lsr
|
|
523
|
+
lsr
|
|
524
|
+
lsr
|
|
525
|
+
cmp left_col+0
|
|
526
|
+
bne vfail
|
|
527
|
+
lda COARSE_HI
|
|
528
|
+
cmp #$27
|
|
529
|
+
bcc vpass
|
|
530
|
+
bne vfail
|
|
531
|
+
lda COARSE_LO
|
|
532
|
+
cmp #$11 // < $2711 passes "under 10000"
|
|
533
|
+
bcc vpass
|
|
534
|
+
vfail:
|
|
535
|
+
lda #0
|
|
536
|
+
sta VERDICT
|
|
537
|
+
lda #C_RED
|
|
538
|
+
sta D020
|
|
539
|
+
jmp vdone
|
|
540
|
+
vpass:
|
|
541
|
+
lda #1
|
|
542
|
+
sta VERDICT
|
|
543
|
+
lda #C_GREEN
|
|
544
|
+
sta D020
|
|
545
|
+
vdone:
|
|
546
|
+
|
|
547
|
+
// --- 6. Re-arm for road_irq1 at line 97 ---
|
|
548
|
+
lda #$01
|
|
549
|
+
sta D019 // ack vblank IRQ
|
|
550
|
+
lda #<road_irq1
|
|
551
|
+
sta $0314
|
|
552
|
+
lda #>road_irq1
|
|
553
|
+
sta $0315
|
|
554
|
+
lda #$1b
|
|
555
|
+
sta D011 // RST8=0
|
|
556
|
+
lda #97
|
|
557
|
+
sta D012
|
|
558
|
+
|
|
559
|
+
// Exit via KERNAL register-restore + RTI
|
|
560
|
+
pla
|
|
561
|
+
tay
|
|
562
|
+
pla
|
|
563
|
+
tax
|
|
564
|
+
pla
|
|
565
|
+
rti
|
|
566
|
+
|
|
567
|
+
// ---- Main ($0900) ----
|
|
568
|
+
* = $0900
|
|
569
|
+
main:
|
|
570
|
+
sei
|
|
571
|
+
lda #$7f
|
|
572
|
+
sta CIA_ICR // mask all CIA1 IRQ sources
|
|
573
|
+
lda CIA_ICR // clear pending CIA1 flag
|
|
574
|
+
|
|
575
|
+
// Detect PAL vs NTSC before enabling display
|
|
576
|
+
jsr detect_region // sets REG_FLAG; re-enables interrupts on return
|
|
577
|
+
|
|
578
|
+
sei // re-disable until fully set up
|
|
579
|
+
|
|
580
|
+
lda #$1b
|
|
581
|
+
sta D011 // DEN=1, RSEL=1, YSCROLL=3, bitmap=0, ECM=0
|
|
582
|
+
lda #D016_BASE
|
|
583
|
+
sta D016 // MCM=1, CSEL=1, XSCROLL=0
|
|
584
|
+
lda #$1c
|
|
585
|
+
sta D018 // VM=$0400, charset=$3000
|
|
586
|
+
lda #C_GREEN
|
|
587
|
+
sta D021 // %00 pixels = green (grass)
|
|
588
|
+
lda #C_DGREY
|
|
589
|
+
sta D022 // %01 pixels = dark grey (road)
|
|
590
|
+
lda #C_WHITE
|
|
591
|
+
sta D023 // %10 pixels = white (kerb/stripe)
|
|
592
|
+
lda #C_BLUE
|
|
593
|
+
sta D020 // border = blue initially (turns green on verdict pass)
|
|
594
|
+
lda #0
|
|
595
|
+
sta $d015 // sprites off
|
|
596
|
+
|
|
597
|
+
jsr init_charset
|
|
598
|
+
jsr fill_colram
|
|
599
|
+
jsr clear_screen
|
|
600
|
+
|
|
601
|
+
lda #0
|
|
602
|
+
sta ZP_SCR
|
|
603
|
+
|
|
604
|
+
lda #<vblank_irq
|
|
605
|
+
sta $0314
|
|
606
|
+
lda #>vblank_irq
|
|
607
|
+
sta $0315
|
|
608
|
+
lda #$1b
|
|
609
|
+
sta D011 // RST8=0 for line 251
|
|
610
|
+
lda #251
|
|
611
|
+
sta D012
|
|
612
|
+
lda #1
|
|
613
|
+
sta D01A
|
|
614
|
+
sta D019
|
|
615
|
+
cli
|
|
616
|
+
|
|
617
|
+
idle:
|
|
618
|
+
jmp idle
|
|
619
|
+
|
|
620
|
+
// ---- init_charset: 5 chars * 8 bytes at $3000 ----
|
|
621
|
+
init_charset:
|
|
622
|
+
ldx #0
|
|
623
|
+
ics_lp:
|
|
624
|
+
lda cs_data, x
|
|
625
|
+
sta CHARSET, x
|
|
626
|
+
inx
|
|
627
|
+
cpx #40 // 5 * 8
|
|
628
|
+
bne ics_lp
|
|
629
|
+
rts
|
|
630
|
+
|
|
631
|
+
cs_data:
|
|
632
|
+
.byte $00,$00,$00,$00,$00,$00,$00,$00 // CH_GRASS (0): %00 all = green
|
|
633
|
+
.byte $55,$55,$55,$55,$55,$55,$55,$55 // CH_ROAD (1): %01 all = grey
|
|
634
|
+
.byte $a5,$a5,$a5,$a5,$a5,$a5,$a5,$a5 // CH_KLEFT (2): left %10 white, right %01 grey
|
|
635
|
+
.byte $5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a // CH_KRIGHT (3): left %01 grey, right %10 white
|
|
636
|
+
.byte $69,$69,$69,$69,$69,$69,$69,$69 // CH_DASH (4): %01%10%10%01 = grey-white-white-grey
|
|
637
|
+
|
|
638
|
+
// ---- fill_colram: set bit3 in all colour RAM cells (enables MCM per cell) ----
|
|
639
|
+
fill_colram:
|
|
640
|
+
ldx #0
|
|
641
|
+
lda #8 // %1000: bit3=MCM enable
|
|
642
|
+
fcr_lp:
|
|
643
|
+
sta COLRAM, x
|
|
644
|
+
sta COLRAM+$100, x
|
|
645
|
+
sta COLRAM+$200, x
|
|
646
|
+
sta COLRAM+$300, x
|
|
647
|
+
inx
|
|
648
|
+
bne fcr_lp
|
|
649
|
+
rts
|
|
650
|
+
|
|
651
|
+
// ---- clear_screen: fill with CH_GRASS ----
|
|
652
|
+
clear_screen:
|
|
653
|
+
ldx #0
|
|
654
|
+
lda #CH_GRASS
|
|
655
|
+
cls_lp:
|
|
656
|
+
sta SCREEN, x
|
|
657
|
+
sta SCREEN+$100, x
|
|
658
|
+
sta SCREEN+$200, x
|
|
659
|
+
sta SCREEN+$300, x
|
|
660
|
+
inx
|
|
661
|
+
bne cls_lp
|
|
662
|
+
rts
|
|
663
|
+
|
|
664
|
+
// ============================================================
|
|
665
|
+
// road_irq2_pal: stable entry + PAL unrolled fine loop ($1300)
|
|
666
|
+
// ============================================================
|
|
667
|
+
// Entry: cycle 38 or 39 of line 99 (via KERNAL dispatcher from irq2 vector).
|
|
668
|
+
// Sync: ldx+txs(6) + cld(2) + Delay(10) + lda $D012 + cmp $D012 + BEQ =
|
|
669
|
+
// both zero-jitter and one-jitter converge to cycle 4 of line 100.
|
|
670
|
+
// Immediately into first fine loop iteration; no JMP intervenes.
|
|
671
|
+
// STA $D016 write at cycle 11 of line 100 (at or before deadline of cycle 14).
|
|
672
|
+
// 100 iterations; badline rows use Delay(15) instead of Delay(55).
|
|
673
|
+
// On exit: jmp fine_done.
|
|
674
|
+
|
|
675
|
+
* = $1300
|
|
676
|
+
road_irq2_pal:
|
|
677
|
+
ldx SAVED_SP // discard irq2's own stack frame (saved by irq1)
|
|
678
|
+
txs
|
|
679
|
+
cld // clear decimal flag (RTI will restore P); arithmetic must be binary
|
|
680
|
+
// Sync padding: PAD_PAL=10. With C2=38/39, second D012 read at cycle 63/64.
|
|
681
|
+
// BEQ: taken (3 cycles) or not (2); both paths land at cycle 4 of line 100.
|
|
682
|
+
// STA D016 write lands at cycle 11 of each road line, before the cycle-14 deadline.
|
|
683
|
+
Delay(10)
|
|
684
|
+
lda D012
|
|
685
|
+
cmp D012
|
|
686
|
+
beq pal_fine_start
|
|
687
|
+
pal_fine_start:
|
|
688
|
+
// PAL unrolled fine loop: 100 iterations, each exactly 63 cpu cycles (or elapsed).
|
|
689
|
+
// Iteration j writes xscroll_d16+j to $D016 for road raster line 100+j.
|
|
690
|
+
// Badlines: (100+j) & 7 == 3, i.e., j = 7,15,23,31,39,47,55,63,71,79,87,95.
|
|
691
|
+
// Badline body: LDA(4)+STA(4)+Delay(15)=23 cpu cycles; 40-cycle steal accounts for rest.
|
|
692
|
+
// Normal body: LDA(4)+STA(4)+Delay(55)=63 cpu cycles.
|
|
693
|
+
.for (var j = 0; j < 100; j++) {
|
|
694
|
+
lda xscroll_d16+j
|
|
695
|
+
sta D016
|
|
696
|
+
.if (((100+j) & 7) == 3) {
|
|
697
|
+
Delay(15)
|
|
698
|
+
} else {
|
|
699
|
+
Delay(55)
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
pal_fine_end:
|
|
703
|
+
jmp fine_done
|
|
704
|
+
|
|
705
|
+
// ============================================================
|
|
706
|
+
// road_irq2_ntsc: stable entry + NTSC unrolled fine loop
|
|
707
|
+
// ============================================================
|
|
708
|
+
// Same structure as PAL but PAD_NTSC=13 (NTSC line = 65 cycles).
|
|
709
|
+
// Normal body: 65 cpu cycles. Badline body: 25 cpu cycles.
|
|
710
|
+
|
|
711
|
+
road_irq2_ntsc:
|
|
712
|
+
ldx SAVED_SP
|
|
713
|
+
txs
|
|
714
|
+
cld // clear decimal flag (RTI will restore P)
|
|
715
|
+
// Sync padding: PAD_NTSC=12. Second D012 read at cycle 65/66 (NTSC boundary).
|
|
716
|
+
Delay(12)
|
|
717
|
+
lda D012
|
|
718
|
+
cmp D012
|
|
719
|
+
beq ntsc_fine_start
|
|
720
|
+
ntsc_fine_start:
|
|
721
|
+
// NTSC unrolled fine loop: 100 iterations, each exactly 65 cpu cycles (or elapsed).
|
|
722
|
+
.for (var j = 0; j < 100; j++) {
|
|
723
|
+
lda xscroll_d16+j
|
|
724
|
+
sta D016
|
|
725
|
+
.if (((100+j) & 7) == 3) {
|
|
726
|
+
Delay(17)
|
|
727
|
+
} else {
|
|
728
|
+
Delay(57)
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
ntsc_fine_end:
|
|
732
|
+
// fall through to fine_done
|
|
733
|
+
|
|
734
|
+
// ============================================================
|
|
735
|
+
// fine_done: epilogue shared by both fine loops
|
|
736
|
+
// ============================================================
|
|
737
|
+
fine_done:
|
|
738
|
+
// Stop CIA fine timer (started in road_irq1)
|
|
739
|
+
lda #0
|
|
740
|
+
sta CIA_CRA
|
|
741
|
+
sec
|
|
742
|
+
lda #$ff
|
|
743
|
+
sbc CIA_TALO
|
|
744
|
+
sta FINE_LO
|
|
745
|
+
lda #$ff
|
|
746
|
+
sbc CIA_TAHI
|
|
747
|
+
sta FINE_HI
|
|
748
|
+
|
|
749
|
+
// Restore $D016 to base (XSCROLL=0)
|
|
750
|
+
lda #D016_BASE
|
|
751
|
+
sta D016
|
|
752
|
+
|
|
753
|
+
// Re-arm for vblank_irq at line 251
|
|
754
|
+
lda #$01
|
|
755
|
+
sta D019 // ack road IRQ
|
|
756
|
+
lda #<vblank_irq
|
|
757
|
+
sta $0314
|
|
758
|
+
lda #>vblank_irq
|
|
759
|
+
sta $0315
|
|
760
|
+
lda #$1b
|
|
761
|
+
sta D011 // RST8=0
|
|
762
|
+
lda #251
|
|
763
|
+
sta D012
|
|
764
|
+
|
|
765
|
+
// Exit through irq1's stack frame (SAVED_SP was irq1's post-KERNAL SP)
|
|
766
|
+
pla
|
|
767
|
+
tay
|
|
768
|
+
pla
|
|
769
|
+
tax
|
|
770
|
+
pla
|
|
771
|
+
rti
|
|
772
|
+
```
|
|
773
|
+
|
|
774
|
+
## Build
|
|
775
|
+
|
|
776
|
+
```bash
|
|
777
|
+
java -jar KickAss.jar pseudo-3d-road.asm -o pseudo-3d-road.prg
|
|
778
|
+
```
|
|
779
|
+
|
|
780
|
+
## Expected output
|
|
781
|
+
|
|
782
|
+
A perspective road receding toward a horizon at raster line 100, narrowing from
|
|
783
|
+
full width at the nearest row to a few characters wide at the horizon. The road
|
|
784
|
+
curves left and right as scroll_z cycles through the four-segment table. The
|
|
785
|
+
border is green throughout (verdict = 1: coarse redraw under 10,000 cycles and
|
|
786
|
+
kerb column formula matches). Grass is green ($D021 = 5), road surface is dark
|
|
787
|
+
grey ($D022 = 11), kerbs and the centre dash stripe are white ($D023 = 1).
|
|
788
|
+
|
|
789
|
+
Within each character row, adjacent raster lines show different XSCROLL values
|
|
790
|
+
and the kerb's left edge appears at different sub-character pixel positions. This
|
|
791
|
+
is visible in the screenshot: rasters 156..162 (screenshot rows 140..146 on PAL)
|
|
792
|
+
show the white kerb at x = 138, 143, 142, 139, 137, 136, 110 on consecutive lines
|
|
793
|
+
(measured in VICE x64sc 3.10, PAL pin), confirming per-line delivery of
|
|
794
|
+
distinct XSCROLL values.
|
|
795
|
+
|
|
796
|
+
**PAL (20,000,000 cycles).** Screenshot `screenshots/pseudo-3d-road.png`;
|
|
797
|
+
md5 8ff3e82b581d6b447d383ef798e45154 on two consecutive runs (verified in VICE
|
|
798
|
+
x64sc 3.10, +autostart-delay-random). Frame shows scroll_z approximately 67
|
|
799
|
+
(arithmetic: (20,000,000 / 19,656 frames - autostart overhead) % 100).
|
|
800
|
+
|
|
801
|
+
**NTSC (20,000,000 cycles, `-model ntsc`).** Screenshot
|
|
802
|
+
`screenshots/pseudo-3d-road-ntsc.png`; md5 2ae7a914d311c8dfeda0bd2cb95d5d42
|
|
803
|
+
on two consecutive runs. Frame shows scroll_z approximately 12 (arithmetic).
|
|
804
|
+
On NTSC, raster 107 (j=7, badline, XSCROLL=1 at this frame) shows kerb at x=274
|
|
805
|
+
and raster 108 (j=8, XSCROLL=7) shows kerb at x=273 (1-pixel difference from
|
|
806
|
+
the 6-XSCROLL-unit difference, within the same character cell).
|
|
807
|
+
|
|
808
|
+
**Cycle measurements (VICE x64sc 3.10, monitor dump at scroll_z=4, PAL).**
|
|
809
|
+
|
|
810
|
+
| Quantity | PAL | NTSC |
|
|
811
|
+
|---|---|---|
|
|
812
|
+
| Coarse redraw (CIA-timed) | 6,332 cycles | 6,162 cycles |
|
|
813
|
+
| Fine chain (irq1 CIA start to fine_done stop) | 6,523 cycles | 6,729 cycles |
|
|
814
|
+
| Fine loop alone (arithmetic: 100 x line) | 6,300 cycles | 6,500 cycles |
|
|
815
|
+
|
|
816
|
+
The fine chain overhead above the loop (223 cycles PAL, 229 NTSC) covers road_irq1
|
|
817
|
+
code, the NOP slide, the irq2 KERNAL entry, the sync code, and the CIA stop
|
|
818
|
+
instruction. Verdict = 1 on both models.
|
|
819
|
+
|
|
820
|
+
**xscroll_d16 table entries at scroll_z=4 (monitor dump, PAL).**
|
|
821
|
+
|
|
822
|
+
| j (road line offset) | raster | D016 value | XSCROLL | badline |
|
|
823
|
+
|---|---|---|---|---|
|
|
824
|
+
| 7 | 107 | $19 | 1 | yes |
|
|
825
|
+
| 8 | 108 | $1F | 7 | no |
|
|
826
|
+
| 50 | 150 | $18 | 0 | no |
|
|
827
|
+
| 56 | 156 | $1A | 2 | no |
|
|
828
|
+
| 57 | 157 | $1F | 7 | no |
|
|
829
|
+
|
|
830
|
+
j=7 and j=8 have different XSCROLL values (1 vs 7), confirming the badline
|
|
831
|
+
delay delivers the correct per-line value. j=56 and j=57 differ by 5 units
|
|
832
|
+
and the screenshot at these rasters shows kerb positions differing by 5 pixels,
|
|
833
|
+
matching the table (measured: x=138 and x=143 on both PAL and NTSC pins).
|
|
834
|
+
|
|
835
|
+
**Badline finding.** Twelve badlines occur in the road area (rasters 107, 115,
|
|
836
|
+
123, 131, 139, 147, 155, 163, 171, 179, 187, 195, with default YSCROLL=3). Each
|
|
837
|
+
badline iteration uses Delay(15) (PAL) or Delay(17) (NTSC) instead of Delay(55)
|
|
838
|
+
or Delay(57): 23 or 25 CPU cycles that the 40-cycle steal extends to one full
|
|
839
|
+
raster line. The STA $D016 write at cycle 11 completes before BA goes low at
|
|
840
|
+
cycle 12, so the write is never blocked by the steal. The previous (broken)
|
|
841
|
+
implementation used a spin-wait on $D012 which introduced up to 9 cycles of
|
|
842
|
+
jitter, placing writes at cycles 20-28 of each line (past the deadline); post-badline
|
|
843
|
+
lines received the badline row's XSCROLL value instead of their own.
|
|
844
|
+
|
|
845
|
+
## Why this works
|
|
846
|
+
|
|
847
|
+
**Coarse layer.** The Z table encodes road perspective: `hw[i] = max(4,
|
|
848
|
+
round(152 - 1.5 * i))`, arithmetic from the spec formula, gives half-widths
|
|
849
|
+
from 152 (i=0, nearest, raster 199) down to 4 (i=99, farthest, raster 100).
|
|
850
|
+
The centre accumulator cx advances each step by a signed delta dx, and dx
|
|
851
|
+
itself advances by the current segment's curve value (0 or +/-0.20 in 8.8 fixed
|
|
852
|
+
point). One `$D018 = $1C` write points the VIC at the custom charset at $3000.
|
|
853
|
+
Five character patterns cover all road regions: $00 (all %00 = $D021 = green
|
|
854
|
+
grass), $55 (all %01 = $D022 = dark grey road), $A5 (left half white, right
|
|
855
|
+
half grey = left kerb), $5A (mirror), $69 (grey-white-white-grey = centre
|
|
856
|
+
dash). Bit 3 of colour RAM must be set for multicolour mode to apply per cell;
|
|
857
|
+
fill_colram writes 8 to all 1,000 colour RAM locations.
|
|
858
|
+
|
|
859
|
+
**Fine layer: stable entry.** road_irq1 fires at line 97, starts the CIA fine
|
|
860
|
+
timer, arms road_irq2 for line 99, saves the stack pointer to SAVED_SP, clears
|
|
861
|
+
the I flag and falls through a 40-NOP slide. road_irq2 fires from inside the
|
|
862
|
+
slide at cycle 1 of line 99, interrupting a NOP. This is the double-IRQ method
|
|
863
|
+
from `stable-raster-irq.md`: because the interrupted instruction is always 2
|
|
864
|
+
cycles, the jitter at irq2 entry is 0 or 1 cycle rather than 0 to 6. irq2
|
|
865
|
+
discards its own KERNAL stack frame using SAVED_SP, then runs:
|
|
866
|
+
|
|
867
|
+
- ldx SAVED_SP / txs (6 cycles)
|
|
868
|
+
- Delay(PAD) (PAL: 11 cycles; NTSC: 13 cycles)
|
|
869
|
+
- lda $D012 / cmp $D012 / beq (10 or 11 cycles)
|
|
870
|
+
|
|
871
|
+
The two consecutive reads of $D012 straddle the raster 99/100 boundary: in the
|
|
872
|
+
zero-jitter case both land on line 99 and BEQ is taken (3 cycles); in the
|
|
873
|
+
one-jitter case the second read crosses to line 100 and BEQ is not taken (2
|
|
874
|
+
cycles). Both paths end at cycle 4 of line 100. The Delay
|
|
875
|
+
constant is PAD_PAL=11 (second read at cycle 63 or 64 of line 99 for PAL) and
|
|
876
|
+
PAD_NTSC=13 (second read at cycle 65 or 66 for NTSC).
|
|
877
|
+
|
|
878
|
+
PAL and NTSC have different Delay constants because the line length differs (63
|
|
879
|
+
vs 65 cycles). road_irq1 selects `road_irq2_pal` or `road_irq2_ntsc` based on
|
|
880
|
+
the model flag set by detect_region at boot.
|
|
881
|
+
|
|
882
|
+
**Fine layer: unrolled loop.** From cycle 4 of line 100, the first iteration
|
|
883
|
+
begins immediately: LDA xscroll_d16+0 (cycles 3..6), STA $D016 (write at cycle
|
|
884
|
+
10, before the cycle-14 deadline). The iteration then runs Delay(55) (PAL
|
|
885
|
+
normal) or Delay(15) (PAL badline) to complete exactly 63 real cycles, ending
|
|
886
|
+
at cycle 2 of line 101. The next iteration begins at cycle 3 of line 101. This
|
|
887
|
+
repeats for all 100 road lines.
|
|
888
|
+
|
|
889
|
+
Badline iterations: the CPU stall begins at cycle 15 and lasts 40 cycles (cycles
|
|
890
|
+
15..54). Delay(15) starts at cycle 11 but is interrupted at cycle 15; the stall
|
|
891
|
+
absorbs 40 real cycles, and the delay resumes at cycle 55 with the remaining
|
|
892
|
+
bit-zero-page and NOP instructions, completing at cycle 2 of the next line.
|
|
893
|
+
Total real cycles: LDA(4) + STA(4) + stall(40) + resumed delay(15) = 63.
|
|
894
|
+
|
|
895
|
+
**Stack management.** irq2 is entered through the KERNAL dispatcher, which
|
|
896
|
+
pushes A, X, Y on top of the CPU's own interrupt frame. road_irq2 discards this
|
|
897
|
+
second frame by restoring irq1's saved stack pointer; the exit sequence
|
|
898
|
+
pla/tay/pla/tax/pla/rti then pops irq1's KERNAL-saved Y, X, A and returns
|
|
899
|
+
through irq1's interrupt frame to the main idle loop. Without this, the stack
|
|
900
|
+
grows by six bytes per road_irq2 call.
|
|
901
|
+
|
|
902
|
+
**IRQ exit via pla/tay/pla/tax/pla/rti.** The KERNAL dispatcher at $FF48
|
|
903
|
+
pushes A, X and Y before calling ($0314). Both vblank_irq and road_irq2 exit
|
|
904
|
+
with this sequence, which pops the KERNAL's saves and RTIs. vblank_irq does
|
|
905
|
+
not push its own saves; the KERNAL's saves are sufficient, and any changes to
|
|
906
|
+
A, X, Y during the handler are overwritten on exit by the KERNAL's originals.
|
|
907
|
+
|
|
908
|
+
## What it does not establish
|
|
909
|
+
|
|
910
|
+
**Same-column XSCROLL shift.** One XSCROLL value per raster line shifts every
|
|
911
|
+
character column on that line by the same amount. The near side and far side of
|
|
912
|
+
the road both shift together within a character row, so the kerb does not curve
|
|
913
|
+
independently on the two sides. Distinct XSCROLL values per-line make the kerb
|
|
914
|
+
step smoothly between rows (the kerb shifts at each raster boundary) but the
|
|
915
|
+
step between adjacent character rows remains a coarse 8-pixel jump; only the
|
|
916
|
+
sub-character remainder is addressed per-line.
|
|
917
|
+
|
|
918
|
+
**Per-frame grass clearing.** The coarse redraw does not re-fill grass
|
|
919
|
+
characters before drawing road characters. clear_screen fills all grass at
|
|
920
|
+
startup; as the road curves, old kerb and road characters may accumulate at row
|
|
921
|
+
boundaries. A production effect erases only the cells that moved since the
|
|
922
|
+
previous frame.
|
|
923
|
+
|
|
924
|
+
**Sky and dashboard colour regions.** $D021 is set once at startup (green).
|
|
925
|
+
Per-raster-region $D021 changes for a blue sky above the horizon and a black
|
|
926
|
+
dashboard below the road are not implemented.
|
|
927
|
+
|
|
928
|
+
**Cycle budget and correctness.** The loop delivers exactly one write per raster
|
|
929
|
+
line; whether the cx and hw values produce a CORRECT road geometry (one the
|
|
930
|
+
original game engine would compute) is not established here.
|