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,1071 @@
|
|
|
1
|
+
---
|
|
2
|
+
recipe: sprite-cache-flip
|
|
3
|
+
toolchain: kickassembler
|
|
4
|
+
output_format: PRG
|
|
5
|
+
region: both
|
|
6
|
+
techniques: [sprite_cache_flip]
|
|
7
|
+
file_formats: [PRG]
|
|
8
|
+
uses_registers: [D000, D001, D002, D003, D004, D005, D006, D007, D008, D009, D00A, D00B, D00C, D00D, D00E, D00F, D010, D011, D015, D017, D01C, D01D, D020, D025, D026, D027, D028, D029, D02A, D02B, D02C, D02D, D02E, DD04, DD05, DD06, DD07, DD0E, DD0F]
|
|
9
|
+
uses_kernal: [CHROUT]
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
<!-- doc-type: recipe -->
|
|
13
|
+
|
|
14
|
+
# KickAssembler — Sprite Cache with Frames Mirrored at Run Time
|
|
15
|
+
|
|
16
|
+
## Synopsis
|
|
17
|
+
|
|
18
|
+
Stores five sprite frames facing right only, packed as a row mask plus
|
|
19
|
+
the non-empty rows, and depacks them on demand into an 8-slot sprite
|
|
20
|
+
cache in the VIC bank, mirrored when a request asks for the left-facing
|
|
21
|
+
version. Both mirror tables, bit-reversed for hires and pair-reversed
|
|
22
|
+
for multicolour, are built on the machine at start. The program checks
|
|
23
|
+
the tables against tables the assembler computed, checks every mirrored
|
|
24
|
+
frame against a frame the assembler mirrored by reversing its pixel
|
|
25
|
+
strings, checks that mirroring twice gives the frame back, counts cache
|
|
26
|
+
misses, hits and evictions, and times each step with the CIA2 timers.
|
|
27
|
+
Eight sprites show two hires and two multicolour frames, each beside its
|
|
28
|
+
mirror. This is the `sprite_cache_flip` technique; use it when a game's
|
|
29
|
+
frames facing both ways do not fit the VIC bank.
|
|
30
|
+
|
|
31
|
+
Verified in VICE x64sc 3.10: the text on screen is identical on PAL and
|
|
32
|
+
NTSC, and on both pictures every left-facing sprite is the exact pixel
|
|
33
|
+
mirror of its neighbour and matches the frame definitions in the
|
|
34
|
+
listing, pixel for pixel.
|
|
35
|
+
|
|
36
|
+
## Source
|
|
37
|
+
|
|
38
|
+
```asm
|
|
39
|
+
// sprite-cache-flip.asm
|
|
40
|
+
// Sprite frames are stored facing right only and packed: a 21-bit mask of
|
|
41
|
+
// the rows that are not empty, then 3 bytes per non-empty row. A cache of
|
|
42
|
+
// 8 sprite blocks at $2000 (pointers $80-$87) is filled on demand by
|
|
43
|
+
// depacking a frame, mirrored or not, into the next slot round-robin.
|
|
44
|
+
// Mirroring uses a 256-byte table built at start: bit order reversed for
|
|
45
|
+
// a hires frame (HFLIP), bit PAIRS reversed for a multicolour frame
|
|
46
|
+
// (MFLIP), and bytes 0 and 2 of each row swapped.
|
|
47
|
+
// Checks, all printed on screen:
|
|
48
|
+
// TABLES BAD entries of HFLIP and MFLIP that differ from tables the
|
|
49
|
+
// assembler computed another way (bit arithmetic on i)
|
|
50
|
+
// MIRROR BAD bytes of each depacked left-facing frame that differ from
|
|
51
|
+
// the frame the assembler mirrored by reversing its strings
|
|
52
|
+
// ROUND BAD bytes where flip(flip(frame)) differs from the frame
|
|
53
|
+
// MISS/HIT/EVICT counters of the cache over a fixed request sequence
|
|
54
|
+
// Cycles (CIA2 timers, screen blanked, IRQs off) for table generation, a
|
|
55
|
+
// flip of one 63-byte sprite, a cache fill and a cache hit.
|
|
56
|
+
// Verdict: $02FF = $01, green border and PASS when every check holds;
|
|
57
|
+
// $02FF = $02, red border and FAIL otherwise.
|
|
58
|
+
// The eight sprites show keys 0-7 of the cache: frame 0 right, frame 0
|
|
59
|
+
// left, frame 1 right, ... frame 3 left. Frames 0-1 hires, 2-3 multicolour.
|
|
60
|
+
|
|
61
|
+
BasicUpstart2(start)
|
|
62
|
+
|
|
63
|
+
.const CHROUT = $ffd2
|
|
64
|
+
.const RESULT = $02ff
|
|
65
|
+
.const BORDER = $d020
|
|
66
|
+
.const SCREEN = $0400
|
|
67
|
+
|
|
68
|
+
.const CACHE = $2000 // 8 slots of 64 bytes, VIC bank 0
|
|
69
|
+
.const CACHE_PTR = CACHE / 64 // sprite pointer of slot 0 ($80)
|
|
70
|
+
.const SLOTS = 8
|
|
71
|
+
.const HFLIP = $3000 // built at start, page-aligned
|
|
72
|
+
.const MFLIP = $3100
|
|
73
|
+
.const HREF = $3200 // computed by the assembler
|
|
74
|
+
.const MREF = $3300
|
|
75
|
+
.const BUF_A = $3600 // depacked right-facing frame
|
|
76
|
+
.const BUF_B = $3640 // depacked left-facing frame
|
|
77
|
+
.const BUF_C = $3680 // BUF_B flipped again
|
|
78
|
+
.const FRAMES = 5
|
|
79
|
+
.const KEYS = FRAMES * 2 // key = frame * 2 + facing (1 = left)
|
|
80
|
+
|
|
81
|
+
.const sp = $fb // flip63 source pointer
|
|
82
|
+
.const dp = $fd // destination pointer (flip63, depack)
|
|
83
|
+
.const pk = $02 // packed frame pointer
|
|
84
|
+
.const ptr = $04 // puts pointer
|
|
85
|
+
.const cp = $06 // compare pointer
|
|
86
|
+
.const m0 = $08 // row mask, 3 bytes
|
|
87
|
+
.const tmp = $0b
|
|
88
|
+
.const res = $0c
|
|
89
|
+
.const so = $0d // offset into the packed rows
|
|
90
|
+
.const yr = $0e
|
|
91
|
+
.const b0 = $0f // one packed row, 3 bytes
|
|
92
|
+
.const face = $12
|
|
93
|
+
.const key = $13
|
|
94
|
+
|
|
95
|
+
// ---------------------------------------------------------------------------
|
|
96
|
+
// Frame definitions, assembled into packed data and a mirrored reference.
|
|
97
|
+
// Hires rows are 24 characters, '#' set; multicolour rows 12 characters,
|
|
98
|
+
// '.' or a colour 1-3 per double-wide pixel.
|
|
99
|
+
// ---------------------------------------------------------------------------
|
|
100
|
+
.function rowval(s) {
|
|
101
|
+
.var v = 0
|
|
102
|
+
.if (s.size() == 24) {
|
|
103
|
+
.for (var i = 0; i < 24; i++) {
|
|
104
|
+
.eval v = v * 2
|
|
105
|
+
.if (s.charAt(i) == '#') .eval v = v + 1
|
|
106
|
+
}
|
|
107
|
+
} else {
|
|
108
|
+
.for (var i = 0; i < 12; i++) {
|
|
109
|
+
.eval v = v * 4
|
|
110
|
+
.if (s.charAt(i) != '.') .eval v = v + (s.charAt(i) - '0')
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
.return v
|
|
114
|
+
}
|
|
115
|
+
.function mirror(s) { // reverse the characters: a mirrored row
|
|
116
|
+
.var r = ""
|
|
117
|
+
.for (var i = s.size() - 1; i >= 0; i--) .eval r = r + s.charAt(i)
|
|
118
|
+
.return r
|
|
119
|
+
}
|
|
120
|
+
.macro Packed(rows) { // 3 mask bytes, then the non-empty rows
|
|
121
|
+
.var mask = 0
|
|
122
|
+
.for (var r = 0; r < 21; r++) {
|
|
123
|
+
.if (rowval(rows.get(r)) != 0) .eval mask = mask | (1 << r)
|
|
124
|
+
}
|
|
125
|
+
.byte mask & $ff, (mask >> 8) & $ff, mask >> 16
|
|
126
|
+
.for (var r = 0; r < 21; r++) {
|
|
127
|
+
.var v = rowval(rows.get(r))
|
|
128
|
+
.if (v != 0) .byte v >> 16, (v >> 8) & $ff, v & $ff
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
.macro Mirrored(rows) { // 63 bytes, the frame facing left
|
|
132
|
+
.for (var r = 0; r < 21; r++) {
|
|
133
|
+
.var v = rowval(mirror(rows.get(r)))
|
|
134
|
+
.byte v >> 16, (v >> 8) & $ff, v & $ff
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
.function rev8(x) { // bit i goes to bit 7 - i
|
|
138
|
+
.var v = 0
|
|
139
|
+
.for (var i = 0; i < 8; i++) .eval v = v * 2 + ((x >> i) & 1)
|
|
140
|
+
.return v
|
|
141
|
+
}
|
|
142
|
+
.function revpairs(x) { // pair i goes to pair 3 - i
|
|
143
|
+
.var v = 0
|
|
144
|
+
.for (var i = 0; i < 4; i++) .eval v = v * 4 + ((x >> (2 * i)) & 3)
|
|
145
|
+
.return v
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.var E = "........................"
|
|
149
|
+
.var e = "............"
|
|
150
|
+
.var f0 = List().add(E, E, E, E, // hires arrow pointing right
|
|
151
|
+
"..............#.........",
|
|
152
|
+
"..............##........",
|
|
153
|
+
"..............###.......",
|
|
154
|
+
"..............####......",
|
|
155
|
+
"###############.###.....",
|
|
156
|
+
"###############.####....",
|
|
157
|
+
"####################....",
|
|
158
|
+
"#####################...",
|
|
159
|
+
"######################..",
|
|
160
|
+
"#####################...",
|
|
161
|
+
"####################....",
|
|
162
|
+
".............######.....",
|
|
163
|
+
".............#####......",
|
|
164
|
+
".............####.......",
|
|
165
|
+
".............###........",
|
|
166
|
+
E, E)
|
|
167
|
+
.var f1 = List() // hires staircase with a dotted edge
|
|
168
|
+
.for (var r = 0; r < 21; r++) {
|
|
169
|
+
.var s = ""
|
|
170
|
+
.for (var c = 0; c < 24; c++) {
|
|
171
|
+
.if (c <= r || (c == 23 && (r & 1) == 0)) .eval s = s + "#"
|
|
172
|
+
else .eval s = s + "."
|
|
173
|
+
}
|
|
174
|
+
.eval f1.add(s)
|
|
175
|
+
}
|
|
176
|
+
.var f2 = List().add(e, e, e, // multicolour fish facing right
|
|
177
|
+
"......111...",
|
|
178
|
+
"....1111111.",
|
|
179
|
+
"3..111111211",
|
|
180
|
+
"33111111111.",
|
|
181
|
+
"331122222111",
|
|
182
|
+
"33112222221.",
|
|
183
|
+
"3311111111..",
|
|
184
|
+
"3..1111111..",
|
|
185
|
+
"....11111...",
|
|
186
|
+
"......1.....",
|
|
187
|
+
e, e, e, e, e, e, e, e)
|
|
188
|
+
.var f3 = List() // multicolour ramp: colour by column
|
|
189
|
+
.for (var r = 0; r < 21; r++) {
|
|
190
|
+
.var s = ""
|
|
191
|
+
.for (var c = 0; c < 12; c++) {
|
|
192
|
+
.if (c * 2 <= r) .eval s = s + toIntString(1 + mod(c, 3))
|
|
193
|
+
else .eval s = s + "."
|
|
194
|
+
}
|
|
195
|
+
.eval f3.add(s)
|
|
196
|
+
}
|
|
197
|
+
.var f4 = List() // hires flag, used only to be evicted
|
|
198
|
+
.for (var r = 0; r < 21; r++) {
|
|
199
|
+
.if (r < 8) .eval f4.add("##########..............")
|
|
200
|
+
else .eval f4.add("#.......................")
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
start:
|
|
204
|
+
sei
|
|
205
|
+
lda #0
|
|
206
|
+
sta $dd0e // stop both CIA2 timers, latches $FFFF
|
|
207
|
+
sta $dd0f
|
|
208
|
+
lda #$ff
|
|
209
|
+
sta $dd04
|
|
210
|
+
sta $dd05
|
|
211
|
+
sta $dd06
|
|
212
|
+
sta $dd07
|
|
213
|
+
lda $d011 // blank the screen: no badlines while timing
|
|
214
|
+
and #$ef
|
|
215
|
+
sta $d011
|
|
216
|
+
!: lda $d011 // DEN is sampled on line $30: wait a frame
|
|
217
|
+
bpl !-
|
|
218
|
+
!: lda $d011
|
|
219
|
+
bmi !-
|
|
220
|
+
|
|
221
|
+
ldx #KEYS - 1 // empty cache
|
|
222
|
+
lda #$ff
|
|
223
|
+
!: sta slot_of,x
|
|
224
|
+
dex
|
|
225
|
+
bpl !-
|
|
226
|
+
ldx #SLOTS - 1
|
|
227
|
+
!: sta key_of,x
|
|
228
|
+
dex
|
|
229
|
+
bpl !-
|
|
230
|
+
|
|
231
|
+
Time(nothing, t_empty)
|
|
232
|
+
Time(gen_h, t_genh)
|
|
233
|
+
Time(gen_m, t_genm)
|
|
234
|
+
|
|
235
|
+
// one 63-byte flip each way, from the depacked frame 0 into BUF_C
|
|
236
|
+
lda #0
|
|
237
|
+
sta face
|
|
238
|
+
lda #0
|
|
239
|
+
jsr setframe
|
|
240
|
+
Set16(dp, BUF_A)
|
|
241
|
+
jsr depack
|
|
242
|
+
Set16(sp, BUF_A)
|
|
243
|
+
Set16(dp, BUF_C)
|
|
244
|
+
lda #>HFLIP
|
|
245
|
+
jsr settbl
|
|
246
|
+
Time(flip63, t_fliph)
|
|
247
|
+
lda #>MFLIP
|
|
248
|
+
jsr settbl
|
|
249
|
+
Time(flip63, t_flipm)
|
|
250
|
+
|
|
251
|
+
// the request sequence: 9 misses (the last evicts frame 4), 8 hits
|
|
252
|
+
Req(8, t_scratch) // frame 4 right, into slot 0
|
|
253
|
+
Req(0, t_fill0r)
|
|
254
|
+
Req(2, t_fill1r)
|
|
255
|
+
Req(4, t_scratch)
|
|
256
|
+
Req(6, t_scratch)
|
|
257
|
+
Req(1, t_fill0l)
|
|
258
|
+
Req(3, t_fill1l)
|
|
259
|
+
Req(5, t_scratch)
|
|
260
|
+
Req(7, t_scratch) // slot 0 again: frame 4 is evicted
|
|
261
|
+
Req(0, t_scratch)
|
|
262
|
+
Req(1, t_hit)
|
|
263
|
+
Req(2, t_scratch)
|
|
264
|
+
Req(3, t_scratch)
|
|
265
|
+
Req(4, t_scratch)
|
|
266
|
+
Req(5, t_scratch)
|
|
267
|
+
Req(6, t_scratch)
|
|
268
|
+
Req(7, t_scratch)
|
|
269
|
+
|
|
270
|
+
Net(t_genh)
|
|
271
|
+
Net(t_genm)
|
|
272
|
+
Net(t_fliph)
|
|
273
|
+
Net(t_flipm)
|
|
274
|
+
Net(t_fill0r)
|
|
275
|
+
Net(t_fill0l)
|
|
276
|
+
Net(t_fill1l)
|
|
277
|
+
Net(t_fill1r)
|
|
278
|
+
Net(t_hit)
|
|
279
|
+
|
|
280
|
+
// the flip tables against the assembler's tables
|
|
281
|
+
ldx #0
|
|
282
|
+
!: lda HFLIP,x
|
|
283
|
+
cmp HREF,x
|
|
284
|
+
beq ok_h
|
|
285
|
+
inc bad_tab
|
|
286
|
+
ok_h:
|
|
287
|
+
lda MFLIP,x
|
|
288
|
+
cmp MREF,x
|
|
289
|
+
beq ok_m
|
|
290
|
+
inc bad_tab
|
|
291
|
+
ok_m:
|
|
292
|
+
inx
|
|
293
|
+
bne !-
|
|
294
|
+
|
|
295
|
+
// every frame: left against the assembler's mirror, flip(flip) = frame
|
|
296
|
+
lda #0
|
|
297
|
+
sta frame
|
|
298
|
+
chk:
|
|
299
|
+
lda frame
|
|
300
|
+
jsr setframe
|
|
301
|
+
lda #0
|
|
302
|
+
sta face
|
|
303
|
+
Set16(dp, BUF_A)
|
|
304
|
+
jsr depack
|
|
305
|
+
lda #1
|
|
306
|
+
sta face
|
|
307
|
+
Set16(dp, BUF_B)
|
|
308
|
+
jsr depack
|
|
309
|
+
ldx frame
|
|
310
|
+
lda mir_lo,x
|
|
311
|
+
sta cp
|
|
312
|
+
lda mir_hi,x
|
|
313
|
+
sta cp+1
|
|
314
|
+
Set16(sp, BUF_B)
|
|
315
|
+
jsr compare // BUF_B against the mirrored reference
|
|
316
|
+
clc
|
|
317
|
+
adc bad_mir
|
|
318
|
+
sta bad_mir
|
|
319
|
+
Set16(dp, BUF_C)
|
|
320
|
+
jsr flip63 // BUF_C = flip(BUF_B)
|
|
321
|
+
Set16(cp, BUF_A)
|
|
322
|
+
Set16(sp, BUF_C)
|
|
323
|
+
jsr compare
|
|
324
|
+
clc
|
|
325
|
+
adc bad_round
|
|
326
|
+
sta bad_round
|
|
327
|
+
inc frame
|
|
328
|
+
lda frame
|
|
329
|
+
cmp #FRAMES
|
|
330
|
+
bne chk
|
|
331
|
+
|
|
332
|
+
lda $d011 // screen back on
|
|
333
|
+
ora #$10
|
|
334
|
+
sta $d011
|
|
335
|
+
cli
|
|
336
|
+
|
|
337
|
+
lda bad_tab // verdict
|
|
338
|
+
ora bad_mir
|
|
339
|
+
ora bad_round
|
|
340
|
+
bne fail
|
|
341
|
+
lda misses
|
|
342
|
+
cmp #9
|
|
343
|
+
bne fail
|
|
344
|
+
lda hits
|
|
345
|
+
cmp #8
|
|
346
|
+
bne fail
|
|
347
|
+
lda evicts
|
|
348
|
+
cmp #1
|
|
349
|
+
bne fail
|
|
350
|
+
lda slot_of + 8 // frame 4 must no longer be cached
|
|
351
|
+
bpl fail
|
|
352
|
+
lda #$01
|
|
353
|
+
ldy #5 // green
|
|
354
|
+
bne verdict
|
|
355
|
+
fail:
|
|
356
|
+
lda #$02
|
|
357
|
+
ldy #2 // red
|
|
358
|
+
verdict:
|
|
359
|
+
sta RESULT
|
|
360
|
+
sty BORDER
|
|
361
|
+
|
|
362
|
+
lda #$93
|
|
363
|
+
jsr CHROUT
|
|
364
|
+
Line2(t_genh_txt, t_genh, t_genm_txt, t_genm)
|
|
365
|
+
Line2(t_flip_txt, t_fliph, t_flipm_txt, t_flipm)
|
|
366
|
+
Line2(t_fill_txt, t_fill0r, t_fill0l_txt, t_fill0l)
|
|
367
|
+
Line2(t_fill1_txt, t_fill1r, t_fill1l_txt, t_fill1l)
|
|
368
|
+
Line2(t_hit_txt, t_hit, t_miss_txt, misses)
|
|
369
|
+
Line2(t_hits_txt, hits, t_evict_txt, evicts)
|
|
370
|
+
Line2(t_tab_txt, bad_tab, t_mir_txt, bad_mir)
|
|
371
|
+
Line1(t_round_txt, bad_round)
|
|
372
|
+
ldx #<t_res_txt
|
|
373
|
+
ldy #>t_res_txt
|
|
374
|
+
jsr puts
|
|
375
|
+
lda RESULT
|
|
376
|
+
jsr hexbyte
|
|
377
|
+
ldx #<t_pass_txt
|
|
378
|
+
ldy #>t_pass_txt
|
|
379
|
+
lda RESULT
|
|
380
|
+
cmp #$01
|
|
381
|
+
beq !+
|
|
382
|
+
ldx #<t_fail_txt
|
|
383
|
+
ldy #>t_fail_txt
|
|
384
|
+
!: jsr puts
|
|
385
|
+
|
|
386
|
+
// sprite n shows cache key n
|
|
387
|
+
ldx #7
|
|
388
|
+
spr:
|
|
389
|
+
lda slot_of,x
|
|
390
|
+
clc
|
|
391
|
+
adc #CACHE_PTR
|
|
392
|
+
sta SCREEN + $3f8,x
|
|
393
|
+
lda xpos,x
|
|
394
|
+
ldy pairs,x
|
|
395
|
+
sta $d000,y
|
|
396
|
+
lda #170
|
|
397
|
+
sta $d001,y
|
|
398
|
+
lda #1 // white; the multicolour ones use it too
|
|
399
|
+
sta $d027,x
|
|
400
|
+
dex
|
|
401
|
+
bpl spr
|
|
402
|
+
lda #0
|
|
403
|
+
sta $d010
|
|
404
|
+
sta $d017
|
|
405
|
+
sta $d01d
|
|
406
|
+
lda #%11110000 // sprites 4-7 are frames 2 and 3
|
|
407
|
+
sta $d01c
|
|
408
|
+
lda #10 // %01 light red
|
|
409
|
+
sta $d025
|
|
410
|
+
lda #7 // %11 yellow; %10 is the sprite colour
|
|
411
|
+
sta $d026
|
|
412
|
+
lda #$ff
|
|
413
|
+
sta $d015
|
|
414
|
+
jmp *
|
|
415
|
+
|
|
416
|
+
nothing:
|
|
417
|
+
rts
|
|
418
|
+
|
|
419
|
+
// ---------------------------------------------------------------------------
|
|
420
|
+
// gen_h: HFLIP[x] = x with its 8 bits in reverse order
|
|
421
|
+
// ---------------------------------------------------------------------------
|
|
422
|
+
gen_h:
|
|
423
|
+
ldx #0
|
|
424
|
+
gh:
|
|
425
|
+
stx tmp
|
|
426
|
+
ldy #8
|
|
427
|
+
!: lsr tmp // bit 0 out first ...
|
|
428
|
+
rol // ... ends at bit 7 after 8 rotates
|
|
429
|
+
dey
|
|
430
|
+
bne !-
|
|
431
|
+
sta HFLIP,x
|
|
432
|
+
inx
|
|
433
|
+
bne gh
|
|
434
|
+
rts
|
|
435
|
+
|
|
436
|
+
// ---------------------------------------------------------------------------
|
|
437
|
+
// gen_m: MFLIP[x] = x with its 4 bit pairs in reverse order; each pair
|
|
438
|
+
// keeps its own bit order, so a pixel keeps its colour
|
|
439
|
+
// ---------------------------------------------------------------------------
|
|
440
|
+
gen_m:
|
|
441
|
+
ldx #0
|
|
442
|
+
gm:
|
|
443
|
+
stx tmp
|
|
444
|
+
lda #0
|
|
445
|
+
ldy #4
|
|
446
|
+
!: asl
|
|
447
|
+
asl
|
|
448
|
+
sta res
|
|
449
|
+
lda tmp
|
|
450
|
+
and #%00000011 // lowest pair of what is left
|
|
451
|
+
ora res
|
|
452
|
+
lsr tmp
|
|
453
|
+
lsr tmp
|
|
454
|
+
dey
|
|
455
|
+
bne !-
|
|
456
|
+
sta MFLIP,x
|
|
457
|
+
inx
|
|
458
|
+
bne gm
|
|
459
|
+
rts
|
|
460
|
+
|
|
461
|
+
// ---------------------------------------------------------------------------
|
|
462
|
+
// settbl: A = high byte of the flip table used by flip63 and depack
|
|
463
|
+
// ---------------------------------------------------------------------------
|
|
464
|
+
settbl:
|
|
465
|
+
sta fa + 2
|
|
466
|
+
sta fb + 2
|
|
467
|
+
sta fc + 2
|
|
468
|
+
sta da + 2
|
|
469
|
+
sta db + 2
|
|
470
|
+
sta dc + 2
|
|
471
|
+
rts
|
|
472
|
+
|
|
473
|
+
// ---------------------------------------------------------------------------
|
|
474
|
+
// flip63: (dp) = mirror of the 63 bytes at (sp). Row r: dst[r] = T[src[r+2]],
|
|
475
|
+
// dst[r+1] = T[src[r+1]], dst[r+2] = T[src[r]]. Source and destination
|
|
476
|
+
// must not overlap: dst[r] is written before src[r] is read.
|
|
477
|
+
// ---------------------------------------------------------------------------
|
|
478
|
+
.align $100 // flip63 and depack in one page: no
|
|
479
|
+
// branch crosses a page, so the cycle
|
|
480
|
+
// counts do not move when code grows
|
|
481
|
+
flip63:
|
|
482
|
+
ldy #0
|
|
483
|
+
frow:
|
|
484
|
+
sty yr
|
|
485
|
+
iny
|
|
486
|
+
iny
|
|
487
|
+
lda (sp),y
|
|
488
|
+
tax
|
|
489
|
+
fa: lda HFLIP,x
|
|
490
|
+
ldy yr
|
|
491
|
+
sta (dp),y
|
|
492
|
+
iny
|
|
493
|
+
lda (sp),y
|
|
494
|
+
tax
|
|
495
|
+
fb: lda HFLIP,x
|
|
496
|
+
sta (dp),y
|
|
497
|
+
dey
|
|
498
|
+
lda (sp),y
|
|
499
|
+
tax
|
|
500
|
+
fc: lda HFLIP,x
|
|
501
|
+
iny
|
|
502
|
+
iny
|
|
503
|
+
sta (dp),y
|
|
504
|
+
iny
|
|
505
|
+
cpy #63
|
|
506
|
+
bne frow
|
|
507
|
+
rts
|
|
508
|
+
|
|
509
|
+
// ---------------------------------------------------------------------------
|
|
510
|
+
// setframe: A = frame; points pk at its packed data, selects its table
|
|
511
|
+
// ---------------------------------------------------------------------------
|
|
512
|
+
setframe:
|
|
513
|
+
tax
|
|
514
|
+
lda pk_lo,x
|
|
515
|
+
sta pk
|
|
516
|
+
lda pk_hi,x
|
|
517
|
+
sta pk+1
|
|
518
|
+
lda is_mc,x
|
|
519
|
+
beq !+
|
|
520
|
+
lda #>MFLIP
|
|
521
|
+
jmp settbl
|
|
522
|
+
!: lda #>HFLIP
|
|
523
|
+
jmp settbl
|
|
524
|
+
|
|
525
|
+
// ---------------------------------------------------------------------------
|
|
526
|
+
// depack: 63 bytes at (dp) from the packed frame at (pk), mirrored when
|
|
527
|
+
// face = 1. An empty row costs 3 stores; a present row 3 reads, 3 stores,
|
|
528
|
+
// and 3 table lookups when mirrored.
|
|
529
|
+
// ---------------------------------------------------------------------------
|
|
530
|
+
depack:
|
|
531
|
+
ldy #0
|
|
532
|
+
lda (pk),y
|
|
533
|
+
sta m0
|
|
534
|
+
iny
|
|
535
|
+
lda (pk),y
|
|
536
|
+
sta m0+1
|
|
537
|
+
iny
|
|
538
|
+
lda (pk),y
|
|
539
|
+
sta m0+2
|
|
540
|
+
iny
|
|
541
|
+
sty so // rows start after the mask
|
|
542
|
+
ldy #0
|
|
543
|
+
drow:
|
|
544
|
+
lsr m0+2 // next row's bit into carry
|
|
545
|
+
ror m0+1
|
|
546
|
+
ror m0
|
|
547
|
+
bcc dempty
|
|
548
|
+
sty yr
|
|
549
|
+
ldy so
|
|
550
|
+
lda (pk),y
|
|
551
|
+
sta b0
|
|
552
|
+
iny
|
|
553
|
+
lda (pk),y
|
|
554
|
+
sta b0+1
|
|
555
|
+
iny
|
|
556
|
+
lda (pk),y
|
|
557
|
+
sta b0+2
|
|
558
|
+
iny
|
|
559
|
+
sty so
|
|
560
|
+
ldy yr
|
|
561
|
+
lda face
|
|
562
|
+
beq dcopy
|
|
563
|
+
ldx b0+2
|
|
564
|
+
da: lda HFLIP,x
|
|
565
|
+
sta (dp),y
|
|
566
|
+
iny
|
|
567
|
+
ldx b0+1
|
|
568
|
+
db: lda HFLIP,x
|
|
569
|
+
sta (dp),y
|
|
570
|
+
iny
|
|
571
|
+
ldx b0
|
|
572
|
+
dc: lda HFLIP,x
|
|
573
|
+
sta (dp),y
|
|
574
|
+
iny
|
|
575
|
+
bne dnext // always: y <= 63
|
|
576
|
+
dcopy:
|
|
577
|
+
lda b0
|
|
578
|
+
sta (dp),y
|
|
579
|
+
iny
|
|
580
|
+
lda b0+1
|
|
581
|
+
sta (dp),y
|
|
582
|
+
iny
|
|
583
|
+
lda b0+2
|
|
584
|
+
sta (dp),y
|
|
585
|
+
iny
|
|
586
|
+
bne dnext
|
|
587
|
+
dempty:
|
|
588
|
+
lda #0
|
|
589
|
+
sta (dp),y
|
|
590
|
+
iny
|
|
591
|
+
sta (dp),y
|
|
592
|
+
iny
|
|
593
|
+
sta (dp),y
|
|
594
|
+
iny
|
|
595
|
+
dnext:
|
|
596
|
+
cpy #63
|
|
597
|
+
bne drow
|
|
598
|
+
rts
|
|
599
|
+
|
|
600
|
+
// ---------------------------------------------------------------------------
|
|
601
|
+
// request: A = key (frame * 2 + facing). Returns the slot in A. On a miss
|
|
602
|
+
// the next slot round-robin is taken; its old key is forgotten and the
|
|
603
|
+
// frame is depacked into it.
|
|
604
|
+
// ---------------------------------------------------------------------------
|
|
605
|
+
req_cur:
|
|
606
|
+
lda key
|
|
607
|
+
request:
|
|
608
|
+
sta key
|
|
609
|
+
tax
|
|
610
|
+
lda slot_of,x
|
|
611
|
+
bmi miss
|
|
612
|
+
inc hits
|
|
613
|
+
rts
|
|
614
|
+
miss:
|
|
615
|
+
inc misses
|
|
616
|
+
ldx next_slot
|
|
617
|
+
lda key_of,x
|
|
618
|
+
bmi free
|
|
619
|
+
tay
|
|
620
|
+
lda #$ff // evict: the old key has no slot now
|
|
621
|
+
sta slot_of,y
|
|
622
|
+
inc evicts
|
|
623
|
+
free:
|
|
624
|
+
lda key
|
|
625
|
+
sta key_of,x
|
|
626
|
+
tay
|
|
627
|
+
txa
|
|
628
|
+
sta slot_of,y
|
|
629
|
+
lsr // dp = CACHE + slot * 64
|
|
630
|
+
lsr
|
|
631
|
+
clc
|
|
632
|
+
adc #>CACHE
|
|
633
|
+
sta dp+1
|
|
634
|
+
txa
|
|
635
|
+
and #3
|
|
636
|
+
lsr
|
|
637
|
+
ror
|
|
638
|
+
ror
|
|
639
|
+
sta dp
|
|
640
|
+
inx
|
|
641
|
+
txa
|
|
642
|
+
and #SLOTS - 1
|
|
643
|
+
sta next_slot
|
|
644
|
+
lda key
|
|
645
|
+
and #1
|
|
646
|
+
sta face
|
|
647
|
+
lda key
|
|
648
|
+
lsr
|
|
649
|
+
jsr setframe
|
|
650
|
+
jsr depack
|
|
651
|
+
ldx key
|
|
652
|
+
lda slot_of,x
|
|
653
|
+
rts
|
|
654
|
+
|
|
655
|
+
// ---------------------------------------------------------------------------
|
|
656
|
+
// compare: A = number of the 63 bytes at (sp) that differ from (cp)
|
|
657
|
+
// ---------------------------------------------------------------------------
|
|
658
|
+
compare:
|
|
659
|
+
ldx #0
|
|
660
|
+
ldy #62
|
|
661
|
+
!: lda (sp),y
|
|
662
|
+
cmp (cp),y
|
|
663
|
+
beq !+
|
|
664
|
+
inx
|
|
665
|
+
!: dey
|
|
666
|
+
bpl !--
|
|
667
|
+
txa
|
|
668
|
+
rts
|
|
669
|
+
|
|
670
|
+
puts: // print the zero-terminated string at Y:X
|
|
671
|
+
stx ptr
|
|
672
|
+
sty ptr+1
|
|
673
|
+
ldy #0
|
|
674
|
+
!: lda (ptr),y
|
|
675
|
+
beq !+
|
|
676
|
+
jsr CHROUT
|
|
677
|
+
iny
|
|
678
|
+
bne !-
|
|
679
|
+
!: rts
|
|
680
|
+
|
|
681
|
+
putdec: // print the 24-bit value in num, decimal
|
|
682
|
+
ldx #0
|
|
683
|
+
stx lead
|
|
684
|
+
digit:
|
|
685
|
+
lda #'0' - 1
|
|
686
|
+
sta dig
|
|
687
|
+
!: inc dig
|
|
688
|
+
sec
|
|
689
|
+
lda num
|
|
690
|
+
sbc pow10,x
|
|
691
|
+
sta num
|
|
692
|
+
lda num+1
|
|
693
|
+
sbc pow10+1,x
|
|
694
|
+
sta num+1
|
|
695
|
+
lda num+2
|
|
696
|
+
sbc pow10+2,x
|
|
697
|
+
sta num+2
|
|
698
|
+
bcs !-
|
|
699
|
+
lda num // undo the last subtraction
|
|
700
|
+
adc pow10,x
|
|
701
|
+
sta num
|
|
702
|
+
lda num+1
|
|
703
|
+
adc pow10+1,x
|
|
704
|
+
sta num+1
|
|
705
|
+
lda num+2
|
|
706
|
+
adc pow10+2,x
|
|
707
|
+
sta num+2
|
|
708
|
+
lda dig
|
|
709
|
+
cmp #'0'
|
|
710
|
+
bne show
|
|
711
|
+
cpx #6 * 3 // the last digit always prints
|
|
712
|
+
beq show
|
|
713
|
+
lda lead
|
|
714
|
+
beq skip // suppress a leading zero
|
|
715
|
+
lda #'0'
|
|
716
|
+
show:
|
|
717
|
+
jsr CHROUT
|
|
718
|
+
inc lead
|
|
719
|
+
skip:
|
|
720
|
+
inx
|
|
721
|
+
inx
|
|
722
|
+
inx
|
|
723
|
+
cpx #7 * 3
|
|
724
|
+
bne digit
|
|
725
|
+
rts
|
|
726
|
+
|
|
727
|
+
hexbyte: // print A as two hex digits
|
|
728
|
+
pha
|
|
729
|
+
lsr
|
|
730
|
+
lsr
|
|
731
|
+
lsr
|
|
732
|
+
lsr
|
|
733
|
+
jsr hexdigit
|
|
734
|
+
pla
|
|
735
|
+
and #$0f
|
|
736
|
+
hexdigit:
|
|
737
|
+
cmp #10
|
|
738
|
+
bcc !+
|
|
739
|
+
adc #6 // carry set: +7 lands on 'A'
|
|
740
|
+
!: adc #'0'
|
|
741
|
+
jmp CHROUT
|
|
742
|
+
|
|
743
|
+
// ---------------------------------------------------------------------------
|
|
744
|
+
.macro Set16(zp, value) {
|
|
745
|
+
lda #<value
|
|
746
|
+
sta zp
|
|
747
|
+
lda #>value
|
|
748
|
+
sta zp+1
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
// Time(routine, slot): CIA2 timer A counts phi2, timer B its underflows;
|
|
752
|
+
// the 24-bit count lands in slot
|
|
753
|
+
.macro Time(routine, slot) {
|
|
754
|
+
lda #$51
|
|
755
|
+
sta $dd0f
|
|
756
|
+
lda #$11
|
|
757
|
+
sta $dd0e
|
|
758
|
+
jsr routine
|
|
759
|
+
lda #0
|
|
760
|
+
sta $dd0e
|
|
761
|
+
sta $dd0f
|
|
762
|
+
sec
|
|
763
|
+
lda #$ff
|
|
764
|
+
sbc $dd04
|
|
765
|
+
sta slot
|
|
766
|
+
lda #$ff
|
|
767
|
+
sbc $dd05
|
|
768
|
+
sta slot+1
|
|
769
|
+
lda #$ff
|
|
770
|
+
sbc $dd06
|
|
771
|
+
sta slot+2
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
.macro Net(slot) { // slot -= the cost of an empty timed call
|
|
775
|
+
sec
|
|
776
|
+
lda slot
|
|
777
|
+
sbc t_empty
|
|
778
|
+
sta slot
|
|
779
|
+
lda slot+1
|
|
780
|
+
sbc t_empty+1
|
|
781
|
+
sta slot+1
|
|
782
|
+
lda slot+2
|
|
783
|
+
sbc t_empty+2
|
|
784
|
+
sta slot+2
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
.macro Req(k, slot) { // a timed cache request for key k
|
|
788
|
+
lda #k
|
|
789
|
+
sta key
|
|
790
|
+
Time(req_cur, slot)
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
.macro Line2(label1, v1, label2, v2) { // "LABEL1 n LABEL2 n"
|
|
794
|
+
ldx #<label1
|
|
795
|
+
ldy #>label1
|
|
796
|
+
jsr puts
|
|
797
|
+
lda v1
|
|
798
|
+
sta num
|
|
799
|
+
lda v1+1
|
|
800
|
+
sta num+1
|
|
801
|
+
lda v1+2
|
|
802
|
+
sta num+2
|
|
803
|
+
jsr putdec
|
|
804
|
+
ldx #<label2
|
|
805
|
+
ldy #>label2
|
|
806
|
+
jsr puts
|
|
807
|
+
lda v2
|
|
808
|
+
sta num
|
|
809
|
+
lda v2+1
|
|
810
|
+
sta num+1
|
|
811
|
+
lda v2+2
|
|
812
|
+
sta num+2
|
|
813
|
+
jsr putdec
|
|
814
|
+
lda #$0d
|
|
815
|
+
jsr CHROUT
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
.macro Line1(label, v) { // "LABEL n"
|
|
819
|
+
ldx #<label
|
|
820
|
+
ldy #>label
|
|
821
|
+
jsr puts
|
|
822
|
+
lda v
|
|
823
|
+
sta num
|
|
824
|
+
lda v+1
|
|
825
|
+
sta num+1
|
|
826
|
+
lda v+2
|
|
827
|
+
sta num+2
|
|
828
|
+
jsr putdec
|
|
829
|
+
lda #$0d
|
|
830
|
+
jsr CHROUT
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
pow10: .byte <1000000, >1000000, 1000000 >> 16
|
|
834
|
+
.byte <100000, >100000, 100000 >> 16
|
|
835
|
+
.byte <10000, >10000, 0
|
|
836
|
+
.byte <1000, >1000, 0
|
|
837
|
+
.byte <100, >100, 0
|
|
838
|
+
.byte <10, >10, 0
|
|
839
|
+
.byte <1, >1, 0
|
|
840
|
+
|
|
841
|
+
t_empty: .byte 0, 0, 0
|
|
842
|
+
t_genh: .byte 0, 0, 0
|
|
843
|
+
t_genm: .byte 0, 0, 0
|
|
844
|
+
t_fliph: .byte 0, 0, 0
|
|
845
|
+
t_flipm: .byte 0, 0, 0
|
|
846
|
+
t_fill0r: .byte 0, 0, 0
|
|
847
|
+
t_fill0l: .byte 0, 0, 0
|
|
848
|
+
t_fill1l: .byte 0, 0, 0
|
|
849
|
+
t_fill1r: .byte 0, 0, 0
|
|
850
|
+
t_hit: .byte 0, 0, 0
|
|
851
|
+
t_scratch: .byte 0, 0, 0
|
|
852
|
+
misses: .byte 0, 0, 0 // counters are 24-bit for Line2
|
|
853
|
+
hits: .byte 0, 0, 0
|
|
854
|
+
evicts: .byte 0, 0, 0
|
|
855
|
+
bad_tab: .byte 0, 0, 0
|
|
856
|
+
bad_mir: .byte 0, 0, 0
|
|
857
|
+
bad_round: .byte 0, 0, 0
|
|
858
|
+
num: .byte 0, 0, 0
|
|
859
|
+
dig: .byte 0
|
|
860
|
+
lead: .byte 0
|
|
861
|
+
frame: .byte 0
|
|
862
|
+
next_slot: .byte 0
|
|
863
|
+
slot_of: .fill KEYS, $ff // key -> slot, $FF = not cached
|
|
864
|
+
key_of: .fill SLOTS, $ff // slot -> key, $FF = free
|
|
865
|
+
|
|
866
|
+
pairs: .byte 0, 2, 4, 6, 8, 10, 12, 14
|
|
867
|
+
xpos: .byte 32, 60, 96, 124, 160, 188, 224, 252 // all < 256: $D010 stays 0
|
|
868
|
+
|
|
869
|
+
pk_lo: .byte <p0, <p1, <p2, <p3, <p4
|
|
870
|
+
pk_hi: .byte >p0, >p1, >p2, >p3, >p4
|
|
871
|
+
is_mc: .byte 0, 0, 1, 1, 0
|
|
872
|
+
mir_lo: .byte <r0, <r1, <r2, <r3, <r4
|
|
873
|
+
mir_hi: .byte >r0, >r1, >r2, >r3, >r4
|
|
874
|
+
|
|
875
|
+
p0: Packed(f0)
|
|
876
|
+
p1: Packed(f1)
|
|
877
|
+
p2: Packed(f2)
|
|
878
|
+
p3: Packed(f3)
|
|
879
|
+
p4: Packed(f4)
|
|
880
|
+
|
|
881
|
+
.encoding "petscii_upper"
|
|
882
|
+
t_genh_txt: .text "GEN H "
|
|
883
|
+
.byte 0
|
|
884
|
+
t_genm_txt: .text " M "
|
|
885
|
+
.byte 0
|
|
886
|
+
t_flip_txt: .text "FLIP63 H "
|
|
887
|
+
.byte 0
|
|
888
|
+
t_flipm_txt: .text " M "
|
|
889
|
+
.byte 0
|
|
890
|
+
t_fill_txt: .text "FILL 0R "
|
|
891
|
+
.byte 0
|
|
892
|
+
t_fill0l_txt: .text " 0L "
|
|
893
|
+
.byte 0
|
|
894
|
+
t_fill1_txt: .text "FILL 1R "
|
|
895
|
+
.byte 0
|
|
896
|
+
t_fill1l_txt: .text " 1L "
|
|
897
|
+
.byte 0
|
|
898
|
+
t_hit_txt: .text "HIT "
|
|
899
|
+
.byte 0
|
|
900
|
+
t_miss_txt: .text " MISS "
|
|
901
|
+
.byte 0
|
|
902
|
+
t_hits_txt: .text "HITS "
|
|
903
|
+
.byte 0
|
|
904
|
+
t_evict_txt: .text " EVICT "
|
|
905
|
+
.byte 0
|
|
906
|
+
t_tab_txt: .text "TABLES BAD "
|
|
907
|
+
.byte 0
|
|
908
|
+
t_mir_txt: .text " MIRROR BAD "
|
|
909
|
+
.byte 0
|
|
910
|
+
t_round_txt: .text "ROUND BAD "
|
|
911
|
+
.byte 0
|
|
912
|
+
t_res_txt: .text "RESULT "
|
|
913
|
+
.byte 0
|
|
914
|
+
t_pass_txt: .text " PASS"
|
|
915
|
+
.byte 0
|
|
916
|
+
t_fail_txt: .text " FAIL"
|
|
917
|
+
.byte 0
|
|
918
|
+
|
|
919
|
+
*= HREF "reference tables"
|
|
920
|
+
.fill 256, rev8(i)
|
|
921
|
+
.fill 256, revpairs(i)
|
|
922
|
+
|
|
923
|
+
*= $3400 "mirrored frames"
|
|
924
|
+
r0: Mirrored(f0)
|
|
925
|
+
r1: Mirrored(f1)
|
|
926
|
+
r2: Mirrored(f2)
|
|
927
|
+
r3: Mirrored(f3)
|
|
928
|
+
r4: Mirrored(f4)
|
|
929
|
+
```
|
|
930
|
+
|
|
931
|
+
## Build
|
|
932
|
+
|
|
933
|
+
```bash
|
|
934
|
+
java -jar KickAss.jar sprite-cache-flip.asm -o sprite-cache-flip.prg
|
|
935
|
+
```
|
|
936
|
+
|
|
937
|
+
Run headless (PAL shown; add `-model ntsc` for NTSC):
|
|
938
|
+
|
|
939
|
+
```bash
|
|
940
|
+
GSETTINGS_SCHEMA_DIR=/opt/homebrew/share/glib-2.0/schemas x64sc -default -minimized -warp +sound \
|
|
941
|
+
+autostart-delay-random -autostartprgmode 1 -limitcycles 8000000 \
|
|
942
|
+
-exitscreenshot sprite-cache-flip.png -autostart sprite-cache-flip.prg
|
|
943
|
+
```
|
|
944
|
+
|
|
945
|
+
## Expected output
|
|
946
|
+
|
|
947
|
+
Blue screen, green border. Nine lines of light-blue text at the top,
|
|
948
|
+
decoded from the exit screenshot against the character ROM, the same on
|
|
949
|
+
PAL and NTSC:
|
|
950
|
+
|
|
951
|
+
```text
|
|
952
|
+
GEN H 28161 M 34817
|
|
953
|
+
FLIP63 H 1597 M 1597
|
|
954
|
+
FILL 0R 2099 0L 2264
|
|
955
|
+
FILL 1R 2441 1L 2672
|
|
956
|
+
HIT 20 MISS 9
|
|
957
|
+
HITS 8 EVICT 1
|
|
958
|
+
TABLES BAD 0 MIRROR BAD 0
|
|
959
|
+
ROUND BAD 0
|
|
960
|
+
RESULT 01 PASS
|
|
961
|
+
```
|
|
962
|
+
|
|
963
|
+
Below the text, one row of eight sprites with their top row on raster
|
|
964
|
+
line 171 (Y register 170): a white arrow pointing right, the same arrow
|
|
965
|
+
pointing left, a white staircase, its mirror, a multicolour fish facing
|
|
966
|
+
right, the fish facing left, a multicolour ramp and its mirror.
|
|
967
|
+
|
|
968
|
+
Screenshots from the pinned run, 8,000,000 cycles, both models:
|
|
969
|
+
`screenshots/sprite-cache-flip.png` and
|
|
970
|
+
`screenshots/sprite-cache-flip-ntsc.png`. Two runs of each gave
|
|
971
|
+
byte-identical files.
|
|
972
|
+
|
|
973
|
+
| Line | Meaning |
|
|
974
|
+
|---|---|
|
|
975
|
+
| GEN H, M | cycles to build HFLIP and MFLIP, 256 entries each |
|
|
976
|
+
| FLIP63 H, M | cycles to mirror one 63-byte sprite into another buffer with each table |
|
|
977
|
+
| FILL 0R, 0L | a cache miss for frame 0 (15 of 21 rows present), right and left |
|
|
978
|
+
| FILL 1R, 1L | a cache miss for frame 1 (all 21 rows present), right and left |
|
|
979
|
+
| HIT | a cache hit |
|
|
980
|
+
| MISS, HITS, EVICT | counters over the 17 requests: 9 misses, 8 hits, 1 eviction |
|
|
981
|
+
| TABLES BAD | table entries that differ from the assembler's tables |
|
|
982
|
+
| MIRROR BAD | bytes of the five left-facing frames that differ from the assembler's mirrors |
|
|
983
|
+
| ROUND BAD | bytes where mirroring a left-facing frame again does not give the right-facing one |
|
|
984
|
+
| RESULT | `01` PASS and a green border, `02` FAIL and a red border; also stored at $02FF |
|
|
985
|
+
|
|
986
|
+
Every cycle figure is less the cost of an empty timed call, and the fill
|
|
987
|
+
and hit figures include the call through `request`. Mirroring during a
|
|
988
|
+
fill costs 11 cycles a row over a plain copy: 2,672 - 2,441 = 231 for 21
|
|
989
|
+
rows, 2,264 - 2,099 = 165 for 15 (arithmetic from the screen). The
|
|
990
|
+
verdict also requires the evicted frame's key to read as not cached.
|
|
991
|
+
|
|
992
|
+
### Reading the sprites off the picture
|
|
993
|
+
|
|
994
|
+
The sprites sit at X 32, 60, 96, 124, 160, 188, 224 and 252, so their
|
|
995
|
+
boxes start at screenshot column X + 8; the top row is screenshot row 155
|
|
996
|
+
on PAL and 143 on NTSC (line 171 less 16 or 28). A PIL script mapped
|
|
997
|
+
every pixel of each 24 by 21 box to a palette index with the model's
|
|
998
|
+
table in `runtime/vice-reference.md`, rebuilt the five frame definitions
|
|
999
|
+
from the listing independently in Python, and compared:
|
|
1000
|
+
|
|
1001
|
+
| Check | PAL | NTSC |
|
|
1002
|
+
|---|---|---|
|
|
1003
|
+
| Pixels differing from the expected frame, all 8 sprites | 0 | 0 |
|
|
1004
|
+
| Pixels where a left sprite differs from the mirror of its right neighbour, 4 pairs | 0 | 0 |
|
|
1005
|
+
| Set pixels in the rows just above and below the boxes | 0 | 0 |
|
|
1006
|
+
|
|
1007
|
+
A hires pixel is white (index 1); a multicolour pixel is two screen
|
|
1008
|
+
pixels wide, %01 light red ($D025 = 10), %10 white (the sprite colour),
|
|
1009
|
+
%11 yellow ($D026 = 7).
|
|
1010
|
+
|
|
1011
|
+
**Negative run.** The same listing with `is_mc` set to 0 for every
|
|
1012
|
+
frame, so the multicolour frames are mirrored with the hires table,
|
|
1013
|
+
prints `MIRROR BAD 62`, `ROUND BAD 0` and `RESULT 02 FAIL` on a red
|
|
1014
|
+
border. On the picture the fish and the ramp facing left keep their
|
|
1015
|
+
shape but 136 and 176 of their screen pixels change colour, %01 and %10
|
|
1016
|
+
swapped. The round trip still passes because HFLIP is its own inverse
|
|
1017
|
+
too: only a comparison with an independently mirrored frame catches the
|
|
1018
|
+
wrong table.
|
|
1019
|
+
|
|
1020
|
+
## Why this works
|
|
1021
|
+
|
|
1022
|
+
**The tables.** `gen_h` shifts each index out to the right eight times
|
|
1023
|
+
and rotates the bits into the accumulator from the right, so bit 0 ends
|
|
1024
|
+
in bit 7. `gen_m` shifts the result left two places and ORs in the
|
|
1025
|
+
lowest pair of what is left of the index, four times, so pair 0 ends in
|
|
1026
|
+
pair 3 with its two bits in their original order. The references are
|
|
1027
|
+
`.fill 256, rev8(i)` and `.fill 256, revpairs(i)`, computed by the
|
|
1028
|
+
assembler from the bit arithmetic, a different path to the same table.
|
|
1029
|
+
|
|
1030
|
+
**The mirror.** `flip63` and the mirrored branch of `depack` write
|
|
1031
|
+
`T[b2], T[b1], T[b0]` for each row. The source and destination must not
|
|
1032
|
+
overlap: `flip63` writes byte `r` of a row before reading byte `r` of
|
|
1033
|
+
the source. The table's page is patched into the six `lda table,x`
|
|
1034
|
+
operands by `settbl`, so one routine serves both modes. The two
|
|
1035
|
+
routines share one page (`.align $100`); an earlier build in which the
|
|
1036
|
+
loop branch of `flip63` crossed a page measured `FLIP63 1617`, 20 cycles
|
|
1037
|
+
more, one per taken branch.
|
|
1038
|
+
|
|
1039
|
+
**The packing.** The assembler turns each frame's pixel strings into
|
|
1040
|
+
three mask bytes, one bit per row, and emits 3 bytes for each row whose
|
|
1041
|
+
value is not zero. `depack` shifts the 24-bit mask right once per row;
|
|
1042
|
+
the carry says whether to read a row or store three zeros. Byte 63 of a
|
|
1043
|
+
slot is never written.
|
|
1044
|
+
|
|
1045
|
+
**The cache.** `request` takes a key, `frame * 2 + facing`. A hit
|
|
1046
|
+
returns `slot_of[key]`. A miss takes `next_slot`, clears `slot_of` for
|
|
1047
|
+
the key the slot held, depacks the frame into `$2000 + slot * 64`,
|
|
1048
|
+
records both mappings and advances `next_slot` modulo 8. The sequence
|
|
1049
|
+
requests frame 4 first (key 8), then keys 0, 2, 4, 6, 1, 3, 5 and 7, so
|
|
1050
|
+
key 7 lands in slot 0 and evicts frame 4; the second pass over keys 0 to 7 is all hits. The
|
|
1051
|
+
sprite pointer for key `n` is `$80 + slot_of[n]`, because the cache
|
|
1052
|
+
starts at $2000 in VIC bank 0, 128 blocks in.
|
|
1053
|
+
|
|
1054
|
+
**The measurement.** CIA2 timer A counts phi2 and timer B counts its
|
|
1055
|
+
underflows, the harness of `sine-table-runtime.md`. All timed work runs
|
|
1056
|
+
under `SEI` with the screen blanked a frame early, since DEN is sampled
|
|
1057
|
+
once, on line $30, so no badline steals cycles.
|
|
1058
|
+
|
|
1059
|
+
**The positions.** Every X is below 256, so $D010 stays 0. A first
|
|
1060
|
+
draft placed the last pair at X 256 and 288 with $D010 clear; the
|
|
1061
|
+
sprites appeared at X 0 and 32, one hidden in the border and one on top
|
|
1062
|
+
of the first arrow (`sprite_x_high_bit_wrong_register`).
|
|
1063
|
+
|
|
1064
|
+
## What this recipe does not show
|
|
1065
|
+
|
|
1066
|
+
Protection of on-screen frames from eviction: the recipe never has more
|
|
1067
|
+
distinct frames on screen than slots, so plain round-robin is enough
|
|
1068
|
+
here and is not enough in a game (see the technique's Eviction
|
|
1069
|
+
paragraph). A cache under the I/O area, which needs $01 banking with
|
|
1070
|
+
IRQs off during the fill. Depacking inside a running game loop with a
|
|
1071
|
+
multiplexer; every fill here runs before the display starts.
|