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,338 @@
|
|
|
1
|
+
---
|
|
2
|
+
recipe: sideborder-open
|
|
3
|
+
toolchain: kickassembler
|
|
4
|
+
output_format: PRG
|
|
5
|
+
region: pal
|
|
6
|
+
techniques: [sideborder_open, stable_raster_irq, double_irq]
|
|
7
|
+
file_formats: [PRG]
|
|
8
|
+
uses_registers: [D011, D012, D016, D019, D01A, D000, D001, D010, D015, D017, D027]
|
|
9
|
+
uses_kernal: []
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
<!-- doc-type: recipe -->
|
|
13
|
+
|
|
14
|
+
# KickAssembler — Open the Side Borders
|
|
15
|
+
|
|
16
|
+
## Synopsis
|
|
17
|
+
|
|
18
|
+
Opens the left and right side borders over a 42-line loop region (41 lines
|
|
19
|
+
of open border in the measured picture, see Expected output) and stands
|
|
20
|
+
sprites in them. The mechanism is one register write per line: the VIC-II
|
|
21
|
+
sets its border flip-flop when the beam reaches X=344 with CSEL=1, or X=335
|
|
22
|
+
with CSEL=0; switch CSEL from 1 to 0 between the two, on cycle 56 of the
|
|
23
|
+
line (PAL), and neither comparison fires, so the flip-flop stays clear and
|
|
24
|
+
neither this line's right border nor the next line's left border is drawn.
|
|
25
|
+
There is no separate "left border" write; the earlier version of this
|
|
26
|
+
recipe claimed one and never opened anything.
|
|
27
|
+
|
|
28
|
+
The write has to land on one cycle, so the region runs from a stable
|
|
29
|
+
raster interrupt (`stable-raster-irq.md`) and through a per-line loop whose
|
|
30
|
+
timing is fixed by two things the text explains: all eight sprites are
|
|
31
|
+
active on every line of the region, and no line in the region is a badline.
|
|
32
|
+
KickAssembler-only because the loop is counted in cycles; no C compiler
|
|
33
|
+
places a store on cycle 56.
|
|
34
|
+
|
|
35
|
+
Verified in VICE x64sc: inside the region the pixels at the far left and
|
|
36
|
+
far right of the frame are the background colour, not the border colour,
|
|
37
|
+
and the two border sprites are visible there.
|
|
38
|
+
|
|
39
|
+
## Source
|
|
40
|
+
|
|
41
|
+
```asm
|
|
42
|
+
// sideborder-open.asm
|
|
43
|
+
// Opens both side borders over a 42-line region with all eight sprites
|
|
44
|
+
// active in it, two of them standing in the borders. One write per line
|
|
45
|
+
// does it: the border flip-flop is set when the beam reaches X=344 with
|
|
46
|
+
// CSEL=1, or X=335 with CSEL=0. Switch CSEL from 1 to 0 between the two,
|
|
47
|
+
// on cycle 56 of the line (PAL), and neither comparison fires; the
|
|
48
|
+
// flip-flop stays clear, so the right border of this line and the left
|
|
49
|
+
// border of the next are not drawn.
|
|
50
|
+
//
|
|
51
|
+
// The write has to land on one specific cycle, so the region runs from a
|
|
52
|
+
// stable raster (double IRQ, see stable-raster-irq.asm). Two things make
|
|
53
|
+
// the per-line timing work out (see text):
|
|
54
|
+
// - every line in the region has all eight sprites active, so the VIC
|
|
55
|
+
// takes the bus from cycle 55 to cycle 10 of the next line on every
|
|
56
|
+
// line alike. DEC $D016's two write cycles fall on 55 and 56, which
|
|
57
|
+
// the CPU is still allowed; its next read stalls until cycle 11.
|
|
58
|
+
// - YSCROLL is rewritten every line so no line in the region is a
|
|
59
|
+
// badline; the character display idles and shows the background.
|
|
60
|
+
|
|
61
|
+
.const REGION_TOP = 101 // sprites' Y; 101 & 7 = 5 keeps the sync line clean
|
|
62
|
+
.const REGION_LINES = 42 // Y-expanded sprites: 42 lines of sprite DMA
|
|
63
|
+
.const SYNC_PAD = 11 // measured in VICE, as in stable-raster-irq
|
|
64
|
+
.const ENTRY_PAD = 43 // cycles from the end of the sync to the first DEC
|
|
65
|
+
|
|
66
|
+
BasicUpstart2(start)
|
|
67
|
+
|
|
68
|
+
.macro Delay(n) {
|
|
69
|
+
.if (n < 2) .error "Delay needs >= 2 cycles"
|
|
70
|
+
.if ((n & 1) != 0) { bit $ea }
|
|
71
|
+
.for (var i = 0; i < ((n & 1) != 0 ? n - 3 : n) / 2; i++) { nop }
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// $D011 written on line REGION_TOP+i, after the sprite DMA: DEN=1, RSEL=1,
|
|
75
|
+
// YSCROLL = (line+4)&7, which never equals line&7.
|
|
76
|
+
* = $0c00
|
|
77
|
+
d011_table:
|
|
78
|
+
.fill REGION_LINES, $18 | ((REGION_TOP + i + 4) & 7)
|
|
79
|
+
// X positions: one sprite in each side border, six across the screen.
|
|
80
|
+
// Sprites 0, 6 and 7 are past X=255, so bits 0, 6 and 7 of $D010 are set
|
|
81
|
+
// (an earlier version set only bits 0 and 7 and put sprite 6 at X=24).
|
|
82
|
+
spr_x: .byte <500, <40, <88, <136, <184, <232, <280, <344
|
|
83
|
+
spr_x_msb: .byte %11000001
|
|
84
|
+
// Colours: none of them 6 (blue), which is the background and invisible on it.
|
|
85
|
+
spr_col: .byte 1, 2, 3, 4, 5, 13, 7, 8
|
|
86
|
+
|
|
87
|
+
// A solid 24x21 sprite.
|
|
88
|
+
* = $0e00
|
|
89
|
+
sprite_block:
|
|
90
|
+
.fill 63, $ff
|
|
91
|
+
.byte 0
|
|
92
|
+
|
|
93
|
+
* = $0900
|
|
94
|
+
start:
|
|
95
|
+
sei
|
|
96
|
+
lda #$7f
|
|
97
|
+
sta $dc0d
|
|
98
|
+
lda $dc0d
|
|
99
|
+
|
|
100
|
+
.for (var s = 0; s < 8; s++) {
|
|
101
|
+
lda spr_x + s
|
|
102
|
+
sta $d000 + s * 2
|
|
103
|
+
lda #REGION_TOP
|
|
104
|
+
sta $d001 + s * 2 // all eight on the same lines
|
|
105
|
+
lda #sprite_block / 64
|
|
106
|
+
sta $07f8 + s
|
|
107
|
+
lda spr_col + s // white, red, cyan, purple, green, light green, yellow, orange
|
|
108
|
+
sta $d027 + s
|
|
109
|
+
}
|
|
110
|
+
lda spr_x_msb
|
|
111
|
+
sta $d010
|
|
112
|
+
lda #$ff
|
|
113
|
+
sta $d017 // Y-expanded: 42 lines of DMA per sprite
|
|
114
|
+
sta $d015 // all eight on
|
|
115
|
+
|
|
116
|
+
lda #<irq1
|
|
117
|
+
sta $0314
|
|
118
|
+
lda #>irq1
|
|
119
|
+
sta $0315
|
|
120
|
+
lda #$1b
|
|
121
|
+
sta $d011
|
|
122
|
+
lda #$c8
|
|
123
|
+
sta $d016 // CSEL=1, MCM=0, XSCROLL=0
|
|
124
|
+
lda #REGION_TOP - 3
|
|
125
|
+
sta $d012
|
|
126
|
+
lda #$01
|
|
127
|
+
sta $d01a
|
|
128
|
+
sta $d019
|
|
129
|
+
cli
|
|
130
|
+
jmp *
|
|
131
|
+
|
|
132
|
+
// Double IRQ, as in stable-raster-irq.asm.
|
|
133
|
+
irq1:
|
|
134
|
+
lda #<irq2
|
|
135
|
+
sta $0314
|
|
136
|
+
lda #>irq2
|
|
137
|
+
sta $0315
|
|
138
|
+
lda #REGION_TOP - 1
|
|
139
|
+
sta $d012
|
|
140
|
+
lda #$01
|
|
141
|
+
sta $d019
|
|
142
|
+
tsx
|
|
143
|
+
stx saved_sp
|
|
144
|
+
cli
|
|
145
|
+
.for (var i = 0; i < 40; i++) { nop }
|
|
146
|
+
|
|
147
|
+
irq2:
|
|
148
|
+
ldx saved_sp
|
|
149
|
+
txs
|
|
150
|
+
Delay(SYNC_PAD)
|
|
151
|
+
lda $d012
|
|
152
|
+
cmp $d012
|
|
153
|
+
beq !+
|
|
154
|
+
!:
|
|
155
|
+
// A known cycle of REGION_TOP. Reach the first DEC on cycle 51.
|
|
156
|
+
ldx #0
|
|
157
|
+
Delay(ENTRY_PAD)
|
|
158
|
+
line:
|
|
159
|
+
dec $d016 // 51-56: reads 51-54, writes $C8 on 55 and $C7 on 56.
|
|
160
|
+
// BA went low on 55 for sprite 0; the writes go
|
|
161
|
+
// through, the next read waits for cycle 11.
|
|
162
|
+
inc $d016 // 11-16: back to $C8
|
|
163
|
+
lda d011_table, x // 17-20
|
|
164
|
+
sta $d011 // 21-24: this line's YSCROLL, no badline
|
|
165
|
+
inx // 25-26
|
|
166
|
+
cpx #REGION_LINES // 27-28
|
|
167
|
+
beq done // 29-30 when not taken
|
|
168
|
+
Delay(17) // 31-47
|
|
169
|
+
jmp line // 48-50
|
|
170
|
+
done:
|
|
171
|
+
lda #$1b
|
|
172
|
+
sta $d011 // normal display again
|
|
173
|
+
lda #REGION_TOP - 3
|
|
174
|
+
sta $d012
|
|
175
|
+
lda #<irq1
|
|
176
|
+
sta $0314
|
|
177
|
+
lda #>irq1
|
|
178
|
+
sta $0315
|
|
179
|
+
lda #$01
|
|
180
|
+
sta $d019
|
|
181
|
+
pla
|
|
182
|
+
tay
|
|
183
|
+
pla
|
|
184
|
+
tax
|
|
185
|
+
pla
|
|
186
|
+
rti
|
|
187
|
+
|
|
188
|
+
saved_sp: .byte 0
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Build
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
java -jar KickAss.jar sideborder-open.asm -o sideborder-open.prg
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## Expected output
|
|
198
|
+
|
|
199
|
+
The normal BASIC screen, with a band in which the light-blue side borders
|
|
200
|
+
are gone: the blue background runs from the left edge of the frame to the
|
|
201
|
+
right edge. Measured in the VICE PNG (PAL, screenshot row = raster line
|
|
202
|
+
minus 16): the right border is open on raster lines 102-142 and the left
|
|
203
|
+
border on lines 103-143, 41 lines each, the left lagging by one line because
|
|
204
|
+
each write opens this line's right border and the next line's left. The
|
|
205
|
+
earlier text said a 42-line band from line 102; the loop does run 42 lines
|
|
206
|
+
(101-142), but the first line's `DEC` does not open line 101 in any pad
|
|
207
|
+
tried (see the paddings section). In that band, eight solid sprites stand
|
|
208
|
+
on the same lines, Y-expanded to 42 lines (102-143): a white one in the
|
|
209
|
+
left border (visible from 103, where the left border first opens), an
|
|
210
|
+
orange one in the right border, and six more (red, cyan, purple, green,
|
|
211
|
+
light green, yellow) across the screen at X=40, 88, 136, 184, 232, 280. An
|
|
212
|
+
earlier version of the listing put the yellow sprite at X=24 (missing $D010
|
|
213
|
+
bit 6) and coloured the sixth sprite blue, which is the background colour
|
|
214
|
+
and therefore invisible; both are fixed. Inside the band the character
|
|
215
|
+
display is idle (see below), so the text rows the band crosses are blank;
|
|
216
|
+
above and below it the screen is untouched.
|
|
217
|
+
|
|
218
|
+
If the borders stay closed, the `DEC $D016` is not writing on cycle 56. If
|
|
219
|
+
the band opens for a few lines and then stops, something changed the
|
|
220
|
+
per-line cycle count: a badline that got through, or a sprite that is not
|
|
221
|
+
active on every line of the region.
|
|
222
|
+
|
|
223
|
+
Screenshot from the VICE run this page describes: `screenshots/sideborder-open.png`.
|
|
224
|
+
|
|
225
|
+
## Why this works
|
|
226
|
+
|
|
227
|
+
### The border flip-flop
|
|
228
|
+
|
|
229
|
+
The VIC-II's main border flip-flop is *set* at a fixed horizontal
|
|
230
|
+
position — X=344 when CSEL=1 (40 columns), X=335 when CSEL=0 (38
|
|
231
|
+
columns) — and *reset* at X=24 or X=31 respectively, both only while the
|
|
232
|
+
vertical border flip-flop is clear. Set means "draw border colour". On PAL
|
|
233
|
+
the beam is at X=335 during cycle 55 and at X=344 during cycle 56.
|
|
234
|
+
|
|
235
|
+
If CSEL is 1 when the beam passes 335, that comparison does nothing; if it
|
|
236
|
+
is 0 when the beam passes 344, that comparison does nothing either. So a
|
|
237
|
+
1-to-0 transition landing between the two leaves the flip-flop clear for
|
|
238
|
+
the rest of the line, and since the reset comparison at X=24/31 on the next
|
|
239
|
+
line has nothing to reset, the next line's left border is not drawn either.
|
|
240
|
+
That is the whole trick, and it is one write per line: `DEC $D016` on $C8
|
|
241
|
+
gives $C7 (CSEL=0, and XSCROLL=7 as a side effect, which does not matter on
|
|
242
|
+
an idle display), `INC $D016` afterwards restores $C8 in time for the next
|
|
243
|
+
line's comparisons. The restore has the whole of the next line up to cycle
|
|
244
|
+
55: measured in VICE x64sc 3.10 for this page, a variant of the loop that
|
|
245
|
+
puts the `INC $D016` on cycles 42-47 of the following line gives a picture
|
|
246
|
+
identical to the shipped one. The earlier recipe's separate "left border
|
|
247
|
+
toggle at cycle 1" does not correspond to anything in the chip.
|
|
248
|
+
|
|
249
|
+
### Why the write can land on cycle 56 with sprites active
|
|
250
|
+
|
|
251
|
+
`DEC abs` is six cycles: opcode, address low, address high, read, write
|
|
252
|
+
old, write new. Started on cycle 51, its writes are on 55 and 56, and the
|
|
253
|
+
new value goes out on 56. Sprite 0's DMA begins with a p-access on cycle
|
|
254
|
+
58, and the VIC pulls BA low three cycles earlier, on 55. The 6510 stops on
|
|
255
|
+
its next *read* while BA is low, but completes write cycles, up to three of
|
|
256
|
+
them. The two writes on 55 and 56 therefore go through; the opcode fetch on
|
|
257
|
+
57 waits.
|
|
258
|
+
|
|
259
|
+
With all eight sprites active the VIC holds the bus through sprite 7's
|
|
260
|
+
accesses, which end on cycle 10 of the next line, and the CPU resumes on
|
|
261
|
+
cycle 11. That is the second half of the timing: from cycle 11 to the next
|
|
262
|
+
`DEC` on cycle 51 is 40 cycles of code, every line, with no need to count
|
|
263
|
+
the stall, because the stall always ends on the same cycle. It ends on the
|
|
264
|
+
same cycle only if the same sprites are active on every line, which is why
|
|
265
|
+
all eight sit on the same Y and are Y-expanded to cover the region. Stagger
|
|
266
|
+
them, as the first draft of this rewrite did, and the stall length changes
|
|
267
|
+
from line to line; the border opened for six lines and then the loop lost
|
|
268
|
+
its phase.
|
|
269
|
+
|
|
270
|
+
Without sprites, the loop has to be exactly 63 cycles by itself and the
|
|
271
|
+
`INC` follows the `DEC` immediately. Either way the constraint is the same:
|
|
272
|
+
one write on one cycle, every line.
|
|
273
|
+
|
|
274
|
+
### Why the region has no badlines
|
|
275
|
+
|
|
276
|
+
A badline (`(line & 7) == YSCROLL`, lines $30-$F7, DEN set) takes the bus
|
|
277
|
+
from cycle 12 (BA low) to cycle 54. The 6510 stops on its first read at or
|
|
278
|
+
after cycle 12 and that read completes on cycle 55, so a fresh instruction
|
|
279
|
+
cannot start before 55 and this loop's `DEC $D016`, whose new value is
|
|
280
|
+
written on its sixth cycle, cannot reach cycle 56 on a badline; that is why
|
|
281
|
+
the region is kept badline-free. The earlier text went further and said
|
|
282
|
+
there is "no way to place a write on cycle 56" on a badline, with the
|
|
283
|
+
earliest write on 58. That is not established: by the same cycle budget, a
|
|
284
|
+
`STA $D016` whose high address byte is the read stalled on cycle 12
|
|
285
|
+
completes that read on 55 and writes on 56 (arithmetic from the stated
|
|
286
|
+
cycles, not measured here; `docs/techniques/raster.md` still states the
|
|
287
|
+
absolute form). The loop
|
|
288
|
+
writes $D011 on every line with YSCROLL = (line+4)&7, which never matches,
|
|
289
|
+
so no badline condition arises during the region. Line 101 itself, the
|
|
290
|
+
first, has YSCROLL 3 and 101&7 = 5, and is safe without help.
|
|
291
|
+
|
|
292
|
+
The cost is the display: with no badlines the VIC has no new character row
|
|
293
|
+
to fetch and goes to its idle state, showing the byte at $3FFF (zero on a
|
|
294
|
+
stock machine) in the background colour. The band is blank. Opening the
|
|
295
|
+
side border *with* a live character display on badline rows is a different
|
|
296
|
+
and much harder problem; the recipes that appear to do it either cover the
|
|
297
|
+
badline rows or use the tricks catalogued under `fld_flexible_line_distance` and `vsp_glitch` in
|
|
298
|
+
`docs/techniques/raster.md`.
|
|
299
|
+
|
|
300
|
+
### The stable entry and the two paddings
|
|
301
|
+
|
|
302
|
+
`SYNC_PAD` is the double-IRQ sync padding from `stable-raster-irq.md`,
|
|
303
|
+
unchanged because the code path before the sync is identical. `ENTRY_PAD`
|
|
304
|
+
is meant to put the first `DEC` on cycle 51 of line 101; it was set by
|
|
305
|
+
trying 41-45 in VICE and all five open the region, because a `DEC` that
|
|
306
|
+
starts a cycle or two off still gets its writes into the BA-low window on
|
|
307
|
+
the first line and the sprite stall re-phases everything from the second
|
|
308
|
+
line on. That tolerance is a property of this code path with sprites, not
|
|
309
|
+
of the trick. Re-measured for this page with pads 41, 42, 43 and 44: all
|
|
310
|
+
four give a pixel-identical picture, and in none of them does line 101's
|
|
311
|
+
own right border open (the band starts on 102), so which pad, if any, lands
|
|
312
|
+
the first `DEC` on cycle 51 of line 101 has not been identified; the
|
|
313
|
+
"cycle 51" in the source comments is the loop's steady state from line 102
|
|
314
|
+
on, inferred from the stall ending on cycle 11, not a measured cycle on
|
|
315
|
+
line 101.
|
|
316
|
+
|
|
317
|
+
`REGION_TOP = 101` because the sync line 100 must not be a badline
|
|
318
|
+
(100&7 = 4) while the badline 99 falls inside irq1's NOP slide, where a
|
|
319
|
+
stall is harmless; see the line-selection note in `stable-raster-irq.md`.
|
|
320
|
+
|
|
321
|
+
### Sprite positions
|
|
322
|
+
|
|
323
|
+
X coordinates run 0-503 on PAL, wrapping inside the left border: the
|
|
324
|
+
visible left border is X 480-503 then 0-23, the right border 344-375 on a
|
|
325
|
+
typical display. X=500 puts a sprite across the wrap in the left border;
|
|
326
|
+
X=344 puts one at the start of the right border. Both need bit 8 of X, as
|
|
327
|
+
does the yellow sprite at X=280, hence `%11000001` in $D010 (the earlier
|
|
328
|
+
`%10000001` left sprite 6 at X=24). A sprite with Y=101 has its DMA turned on at
|
|
329
|
+
cycle 55 of line 101 and is drawn from line 102, which is why the region
|
|
330
|
+
loop starts its `DEC` on line 101 and the opened band is seen from 102.
|
|
331
|
+
|
|
332
|
+
### NTSC
|
|
333
|
+
|
|
334
|
+
`region: pal`. The 6567R8 has 65 cycles per line and the sprite DMA
|
|
335
|
+
cycles differ; the border positions in X are the same, so the write still
|
|
336
|
+
has to land between X=335 and X=344, but the cycle number and the
|
|
337
|
+
post-stall budget both change. Re-derive from the 6567 timing table before
|
|
338
|
+
trying this on NTSC.
|
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
---
|
|
2
|
+
recipe: sine-scroller
|
|
3
|
+
toolchain: kickassembler
|
|
4
|
+
output_format: PRG
|
|
5
|
+
region: both
|
|
6
|
+
techniques: [soft_scroll_h, char_scroll_buffer_h]
|
|
7
|
+
file_formats: [PRG]
|
|
8
|
+
uses_registers: [D011, D012, D016, D019, D01A]
|
|
9
|
+
uses_kernal: []
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
<!-- doc-type: recipe -->
|
|
13
|
+
|
|
14
|
+
# KickAssembler — Sine-Wave Scroller
|
|
15
|
+
|
|
16
|
+
## Synopsis
|
|
17
|
+
|
|
18
|
+
A text scroller whose forty character columns ride a sine wave. The whole
|
|
19
|
+
screen is fine-scrolled a pixel per frame with $D016 XSCROLL; every eighth
|
|
20
|
+
frame the forty-character ring buffer shifts left by one and takes the next
|
|
21
|
+
character of the message. Each frame the nine-row band is cleared and every
|
|
22
|
+
column's character is placed on the row the sine table gives for that
|
|
23
|
+
column. The sine table, the row-address table and the screen-code text are
|
|
24
|
+
all built by the assembler. Nothing is cycle-exact: the redraw runs in the
|
|
25
|
+
vertical blank.
|
|
26
|
+
|
|
27
|
+
Verified in VICE x64sc: the message appears in white on a wave across the
|
|
28
|
+
middle of the screen and moves left.
|
|
29
|
+
|
|
30
|
+
## Source
|
|
31
|
+
|
|
32
|
+
```asm
|
|
33
|
+
// sine-scroller.asm
|
|
34
|
+
// A text scroller whose 40 columns ride a sine wave. The whole screen is
|
|
35
|
+
// fine-scrolled with $D016 XSCROLL; every eighth frame the 40-character
|
|
36
|
+
// ring buffer shifts left by one and takes the next character of the
|
|
37
|
+
// message. Each frame the nine-row band is cleared and every column's
|
|
38
|
+
// character is placed on the row the sine table gives for that column.
|
|
39
|
+
//
|
|
40
|
+
// Region: both. Nothing here is cycle-exact; the redraw runs in the
|
|
41
|
+
// vertical blank and takes about 4,650 cycles in an ordinary frame and
|
|
42
|
+
// about 5,300 in a frame that also shifts the buffer (measured with a
|
|
43
|
+
// CIA timer), of the roughly 7,100 available between raster line 250
|
|
44
|
+
// and the first badline of the next frame on PAL.
|
|
45
|
+
|
|
46
|
+
.const BAND_TOP = 8 // first screen row of the band
|
|
47
|
+
.const CENTER = 12 // row the wave is centred on
|
|
48
|
+
.const AMPLITUDE = 4 // rows above and below CENTER
|
|
49
|
+
.const STEP = 6 // sine-table steps between adjacent columns
|
|
50
|
+
.const SPEED = 2 // sine-table steps per frame
|
|
51
|
+
.const IRQ_LINE = 250 // last visible PAL line: the redraw runs in the blank
|
|
52
|
+
.const TEXT_COLOUR = 1 // white
|
|
53
|
+
|
|
54
|
+
.const SCREEN = $0400
|
|
55
|
+
.const COLOUR = $d800
|
|
56
|
+
|
|
57
|
+
BasicUpstart2(start)
|
|
58
|
+
|
|
59
|
+
// ---------------------------------------------------------------------------
|
|
60
|
+
// Tables, built by the assembler.
|
|
61
|
+
// ---------------------------------------------------------------------------
|
|
62
|
+
* = $0c00
|
|
63
|
+
sine: .fill 256, round(sin(toRadians(i * 360 / 256)) * AMPLITUDE)
|
|
64
|
+
row_lo: .fill 25, <(SCREEN + i * 40)
|
|
65
|
+
row_hi: .fill 25, >(SCREEN + i * 40)
|
|
66
|
+
|
|
67
|
+
.encoding "screencode_upper" // .text emits screen codes for the upper-case charset
|
|
68
|
+
message:
|
|
69
|
+
.text " GREETINGS FROM A SINE SCROLLER THAT WAS ASSEMBLED, RUN AND "
|
|
70
|
+
.text "PHOTOGRAPHED BEFORE IT WAS WRITTEN UP ... "
|
|
71
|
+
.byte 0
|
|
72
|
+
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
// State
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
76
|
+
* = $0b00
|
|
77
|
+
scroll_buf: .fill 40, $20 // the 40 visible characters, left to right
|
|
78
|
+
xscroll: .byte 0 // 0-7, written to $D016
|
|
79
|
+
phase: .byte 0 // sine-table index of column 0
|
|
80
|
+
col_phase: .byte 0
|
|
81
|
+
col: .byte 0
|
|
82
|
+
.const zp_row = $fb // zero-page pointer to the current row
|
|
83
|
+
.const msg_ptr = $fd // zero-page pointer into the message: (zp),y needs zero page
|
|
84
|
+
|
|
85
|
+
// ---------------------------------------------------------------------------
|
|
86
|
+
// Setup
|
|
87
|
+
// ---------------------------------------------------------------------------
|
|
88
|
+
* = $0900
|
|
89
|
+
start:
|
|
90
|
+
sei
|
|
91
|
+
lda #$7f
|
|
92
|
+
sta $dc0d
|
|
93
|
+
lda $dc0d
|
|
94
|
+
|
|
95
|
+
// Clear the screen and colour the band.
|
|
96
|
+
lda #$20
|
|
97
|
+
ldx #0
|
|
98
|
+
!: sta SCREEN, x
|
|
99
|
+
sta SCREEN + $100, x
|
|
100
|
+
sta SCREEN + $200, x
|
|
101
|
+
sta SCREEN + $2e8, x
|
|
102
|
+
inx
|
|
103
|
+
bne !-
|
|
104
|
+
lda #TEXT_COLOUR
|
|
105
|
+
ldx #0
|
|
106
|
+
!: .for (var r = BAND_TOP; r <= BAND_TOP + 2 * AMPLITUDE; r++) {
|
|
107
|
+
sta COLOUR + r * 40, x
|
|
108
|
+
}
|
|
109
|
+
inx
|
|
110
|
+
cpx #40
|
|
111
|
+
bne !-
|
|
112
|
+
|
|
113
|
+
lda #<message
|
|
114
|
+
sta msg_ptr
|
|
115
|
+
lda #>message
|
|
116
|
+
sta msg_ptr + 1
|
|
117
|
+
|
|
118
|
+
lda #$1b
|
|
119
|
+
sta $d011
|
|
120
|
+
lda #$c0 // CSEL=0: 38 columns, the edge columns are hidden
|
|
121
|
+
sta $d016
|
|
122
|
+
lda #<irq
|
|
123
|
+
sta $0314
|
|
124
|
+
lda #>irq
|
|
125
|
+
sta $0315
|
|
126
|
+
lda #IRQ_LINE
|
|
127
|
+
sta $d012
|
|
128
|
+
lda #$01
|
|
129
|
+
sta $d01a
|
|
130
|
+
sta $d019
|
|
131
|
+
cli
|
|
132
|
+
jmp *
|
|
133
|
+
|
|
134
|
+
// ---------------------------------------------------------------------------
|
|
135
|
+
// Once per frame, in the vertical blank.
|
|
136
|
+
// ---------------------------------------------------------------------------
|
|
137
|
+
irq:
|
|
138
|
+
// 1. Fine scroll one pixel left; every eighth frame shift the buffer.
|
|
139
|
+
dec xscroll
|
|
140
|
+
bpl set_d016
|
|
141
|
+
lda #7
|
|
142
|
+
sta xscroll
|
|
143
|
+
jsr shift_buffer
|
|
144
|
+
set_d016:
|
|
145
|
+
lda xscroll
|
|
146
|
+
ora #$c0
|
|
147
|
+
sta $d016
|
|
148
|
+
|
|
149
|
+
// 2. Advance the wave.
|
|
150
|
+
lda phase
|
|
151
|
+
clc
|
|
152
|
+
adc #SPEED
|
|
153
|
+
sta phase
|
|
154
|
+
|
|
155
|
+
// 3. Clear the band.
|
|
156
|
+
lda #$20
|
|
157
|
+
ldx #39
|
|
158
|
+
!: .for (var r = BAND_TOP; r <= BAND_TOP + 2 * AMPLITUDE; r++) {
|
|
159
|
+
sta SCREEN + r * 40, x
|
|
160
|
+
}
|
|
161
|
+
dex
|
|
162
|
+
bpl !-
|
|
163
|
+
|
|
164
|
+
// 4. Place each column's character on its row.
|
|
165
|
+
lda phase
|
|
166
|
+
sta col_phase
|
|
167
|
+
ldx #0
|
|
168
|
+
place:
|
|
169
|
+
stx col
|
|
170
|
+
ldy col_phase
|
|
171
|
+
lda sine, y
|
|
172
|
+
clc
|
|
173
|
+
adc #CENTER // row = CENTER + sine[col_phase], 8..16
|
|
174
|
+
tay
|
|
175
|
+
lda row_lo, y
|
|
176
|
+
sta zp_row
|
|
177
|
+
lda row_hi, y
|
|
178
|
+
sta zp_row + 1
|
|
179
|
+
lda scroll_buf, x
|
|
180
|
+
ldy col
|
|
181
|
+
sta (zp_row), y
|
|
182
|
+
lda col_phase
|
|
183
|
+
clc
|
|
184
|
+
adc #STEP
|
|
185
|
+
sta col_phase
|
|
186
|
+
inx
|
|
187
|
+
cpx #40
|
|
188
|
+
bne place
|
|
189
|
+
|
|
190
|
+
lda #$01
|
|
191
|
+
sta $d019
|
|
192
|
+
jmp $ea31 // KERNAL housekeeping once a frame; CIA1 is masked
|
|
193
|
+
|
|
194
|
+
// Shift the ring left and append the next message character.
|
|
195
|
+
shift_buffer:
|
|
196
|
+
ldx #0
|
|
197
|
+
!: lda scroll_buf + 1, x
|
|
198
|
+
sta scroll_buf, x
|
|
199
|
+
inx
|
|
200
|
+
cpx #39
|
|
201
|
+
bne !-
|
|
202
|
+
ldy #0
|
|
203
|
+
lda (msg_ptr), y
|
|
204
|
+
bne !+
|
|
205
|
+
lda #<message // end of message: wrap
|
|
206
|
+
sta msg_ptr
|
|
207
|
+
lda #>message
|
|
208
|
+
sta msg_ptr + 1
|
|
209
|
+
lda (msg_ptr), y
|
|
210
|
+
!: sta scroll_buf + 39
|
|
211
|
+
inc msg_ptr
|
|
212
|
+
bne !+
|
|
213
|
+
inc msg_ptr + 1
|
|
214
|
+
!: rts
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## Build
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
java -jar KickAss.jar sine-scroller.asm -o sine-scroller.prg
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## Expected output
|
|
224
|
+
|
|
225
|
+
A blue screen with the message in white, one character per column, each
|
|
226
|
+
column on a row between 8 and 16 so the text forms a sine wave just under
|
|
227
|
+
one period wide (40 columns × STEP 6 = 240 of the 256 table entries; an
|
|
228
|
+
earlier version of this page said "about 1.7 periods", which the picture
|
|
229
|
+
contradicts). The text moves left one pixel per frame (50 px/s PAL,
|
|
230
|
+
60 px/s NTSC) and the wave rolls with it, two table steps per frame. The
|
|
231
|
+
38-column mode covers the left 7 and right 9 pixels of the 40-column
|
|
232
|
+
window, so characters slide out under the left border and in from under
|
|
233
|
+
the right one a pixel at a time rather than popping.
|
|
234
|
+
|
|
235
|
+
Screenshot from the VICE run this page describes: `screenshots/sine-scroller.png`.
|
|
236
|
+
|
|
237
|
+
## Why this works
|
|
238
|
+
|
|
239
|
+
### Fine scroll plus buffer shift
|
|
240
|
+
|
|
241
|
+
$D016 bits 0-2 (XSCROLL) shift the whole character display right by 0-7
|
|
242
|
+
pixels. Counting XSCROLL down from 7 to 0 moves the picture left a pixel per
|
|
243
|
+
frame; when it would go below 0 it is reset to 7 and the character data is
|
|
244
|
+
moved left one column instead, which puts the picture back where the
|
|
245
|
+
viewer's eye expects it. Here the data being moved is the forty-byte ring
|
|
246
|
+
buffer, not screen RAM: the screen is redrawn from the buffer every frame
|
|
247
|
+
anyway, so shifting the buffer is the whole carry step. This is the
|
|
248
|
+
`soft_scroll_h` and `char_scroll_buffer_h` pair from
|
|
249
|
+
`docs/techniques/scroll.md`.
|
|
250
|
+
|
|
251
|
+
Bit 3 of $D016 (CSEL) is cleared, giving 38 columns: the window narrows
|
|
252
|
+
from X 24–343 to X 31–334, 7 pixels off the left and 9 off the right
|
|
253
|
+
(`docs/hardware/vic-ii-reference.md`). All forty columns are still written
|
|
254
|
+
and fetched; what changes is how much of columns 0, 38 and 39 the border
|
|
255
|
+
covers. Measured in VICE x64sc: column 39 is never visible at any XSCROLL;
|
|
256
|
+
column 38 is hidden at XSCROLL=7 and shows 7 pixels at XSCROLL=0; column 0
|
|
257
|
+
is fully visible at XSCROLL=7 and down to its last pixel at XSCROLL=0. So
|
|
258
|
+
as XSCROLL counts down the newest character (written to column 39, moved
|
|
259
|
+
to 38 by the shift) emerges from under the right border a pixel at a time,
|
|
260
|
+
and the oldest slides out under the left one — no character pops in whole
|
|
261
|
+
at XSCROLL=7. An earlier version of this paragraph said columns 0 and 39
|
|
262
|
+
both "fall under the border"; column 0 does not.
|
|
263
|
+
|
|
264
|
+
### The wave
|
|
265
|
+
|
|
266
|
+
For column `c` the row is `CENTER + sine[(phase + c*STEP) & 255]`, with
|
|
267
|
+
`sine` a 256-entry table of `round(sin(θ) * AMPLITUDE)` (the scalings and
|
|
268
|
+
the byte-level check of such tables are `table_generation` in
|
|
269
|
+
`../../techniques/cpu-cycle-tricks.md`). `phase` advances by
|
|
270
|
+
`SPEED` per frame. `STEP = 6` across forty columns spans 240 table entries,
|
|
271
|
+
just under a full period. Rows are reached through a 25-entry table of row
|
|
272
|
+
start addresses, loaded into a zero-page pointer and indexed by the column
|
|
273
|
+
in Y. No multiplies at run time; nothing but table lookups.
|
|
274
|
+
|
|
275
|
+
The band is cleared before the columns are placed, because a column's
|
|
276
|
+
character moves to a different row every frame and the old one would
|
|
277
|
+
otherwise stay behind. The clear is 360 stores unrolled nine rows wide,
|
|
278
|
+
about 2,000 cycles.
|
|
279
|
+
|
|
280
|
+
### Where the work runs
|
|
281
|
+
|
|
282
|
+
The interrupt is at line 250, the last visible line on PAL. Everything —
|
|
283
|
+
the shift, the clear and the forty placements — happens between there and
|
|
284
|
+
the next frame's first badline at line 51: 113 lines × 63 = about 7,100
|
|
285
|
+
cycles on PAL, but only 64 lines × 65 = about 4,200 on NTSC (263 lines).
|
|
286
|
+
Measured with a CIA timer in VICE x64sc, the handler body takes 4,648
|
|
287
|
+
cycles in an ordinary frame and 5,312 in a frame that also shifts the
|
|
288
|
+
buffer, so on NTSC it runs some ten to eighteen lines past line 51. That
|
|
289
|
+
does no harm: the only rows it writes are 8–16, whose first badline is at
|
|
290
|
+
line 115, so on both models every screen write finishes long before the
|
|
291
|
+
VIC fetches the band and there is no tearing without any further raster
|
|
292
|
+
work. (An earlier version of this paragraph said "6,000 on NTSC" and
|
|
293
|
+
"about 4,500"; both figures were wrong, and the NTSC one implied a margin
|
|
294
|
+
that does not exist at line 51.) The handler exits through `$EA31` so the
|
|
295
|
+
KERNAL still scans the keyboard and runs the jiffy clock once a frame; CIA1
|
|
296
|
+
is masked so that routine's `$DC0D` read is harmless.
|
|
297
|
+
|
|
298
|
+
### Three things that were wrong in the earlier version
|
|
299
|
+
|
|
300
|
+
1. Its memory map overlapped: code at $0900 ran into the sine table at
|
|
301
|
+
$0A00, and KickAssembler refused to assemble it.
|
|
302
|
+
2. It kept the message pointer in ordinary RAM and used it with `(ptr),y`.
|
|
303
|
+
That addressing mode only exists for zero page; the assembler truncated
|
|
304
|
+
the operand to a zero-page address silently, and the scroller printed
|
|
305
|
+
BASIC's workspace bytes instead of the message (a screen full of `3`s in
|
|
306
|
+
the first run of this rewrite, since it used $2B/$2C). The pointer now
|
|
307
|
+
lives at $FD/$FE. Check every `(zp),y` operand is below $100.
|
|
308
|
+
3. It commented the message as "PETSCII $41-$5A". Screen RAM holds screen
|
|
309
|
+
codes, in which upper-case letters are $01-$1A; `.encoding
|
|
310
|
+
"screencode_upper"` makes `.text` emit those. The default encoding,
|
|
311
|
+
`screencode_mixed`, emits upper-case source letters as $41-$5A, which
|
|
312
|
+
the default upper/graphics character set displays as graphics symbols.
|
|
313
|
+
|
|
314
|
+
### Region
|
|
315
|
+
|
|
316
|
+
`region: both`. The mechanism is the same on NTSC; the animation runs 20 %
|
|
317
|
+
faster and the blank between line 250 and line 51 is about 2,900 cycles
|
|
318
|
+
shorter (about 4,200 against PAL's 7,100 — an earlier version said "about
|
|
319
|
+
1,000 cycles shorter, still ample"). The handler overruns line 51 on NTSC
|
|
320
|
+
but finishes well before the band's first badline at line 115; run on the
|
|
321
|
+
6567R8 model in VICE x64sc, the wave draws correctly.
|