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,535 @@
|
|
|
1
|
+
---
|
|
2
|
+
recipe: directory-reader
|
|
3
|
+
toolchain: oscar64
|
|
4
|
+
output_format: PRG
|
|
5
|
+
region: both
|
|
6
|
+
techniques: [directory_read_and_select, kernal_file_read_seq, kernal_file_write_seq, error_channel_check, joystick_edge_detect]
|
|
7
|
+
file_formats: [PRG, D64]
|
|
8
|
+
uses_registers: [DC00, D012, D020, DD04, DD05, DD06, DD07, DD0E, DD0F]
|
|
9
|
+
uses_kernal: [SETLFS, SETNAM, OPEN, CLOSE, CHKIN, CHKOUT, CLRCHN, CHRIN, CHROUT, READST]
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
<!-- doc-type: recipe -->
|
|
13
|
+
|
|
14
|
+
# Oscar64 Directory Reader and File Selector
|
|
15
|
+
|
|
16
|
+
## Synopsis
|
|
17
|
+
|
|
18
|
+
Against a freshly formatted disk in drive 8: write three small files
|
|
19
|
+
with known names and sizes (`ALPHA` 50 bytes, `BRAVO` 300 bytes and
|
|
20
|
+
`CHARLIE` 600 bytes, the third opened as a PRG), open the directory as
|
|
21
|
+
the file `$` on a data channel, stream it through CHKIN and CHRIN into
|
|
22
|
+
a buffer, parse every line into a table of name, block count and file
|
|
23
|
+
type, print the table, and let a joystick in port 2 move a highlight
|
|
24
|
+
and pick one entry. An autopilot presses down once and then fire
|
|
25
|
+
through the same edge logic, so the pinned picture shows the second
|
|
26
|
+
entry picked. The verdict compares the parsed table with the three
|
|
27
|
+
files just written: `$02FF` = 1 and a green border on PASS, 2 and red
|
|
28
|
+
on FAIL. The drive's status is read after the write and after the
|
|
29
|
+
directory read, and CIA2's timers count the transfer and the parse
|
|
30
|
+
separately. Use it as the skeleton for a loader menu or a save slot
|
|
31
|
+
picker. The technique is `directory_read_and_select` in
|
|
32
|
+
`techniques/file-io.md`.
|
|
33
|
+
|
|
34
|
+
## Source
|
|
35
|
+
|
|
36
|
+
```c
|
|
37
|
+
// directory-reader.c
|
|
38
|
+
// Against a fresh disk in drive 8: write three small files with known
|
|
39
|
+
// names and sizes, open the directory as the file "$" on a data channel,
|
|
40
|
+
// stream it through CHKIN and CHRIN into a buffer, parse every line into
|
|
41
|
+
// a table of name, block count and file type, print the table, and let a
|
|
42
|
+
// joystick in port 2 move a highlight and pick one entry. An autopilot
|
|
43
|
+
// feeds the same input path (down once, then fire) so the picture proves
|
|
44
|
+
// the selector as well as the parse. The verdict is the parsed table
|
|
45
|
+
// against the names, types and block counts of the files just written:
|
|
46
|
+
// $02FF = 1 and a green border on PASS, 2 and red on FAIL.
|
|
47
|
+
#include <stdio.h>
|
|
48
|
+
#include <c64/kernalio.h>
|
|
49
|
+
#include <c64/joystick.h>
|
|
50
|
+
|
|
51
|
+
#define DRIVE 8
|
|
52
|
+
#define DIR_LFN 2 // logical file for "$"
|
|
53
|
+
#define DIR_MAX 16 // entries the table can hold
|
|
54
|
+
#define TABLE_ROW 7 // screen row of the first entry
|
|
55
|
+
#define RESULT (*(volatile char *)0x02ff)
|
|
56
|
+
#define BORDER (*(volatile char *)0xd020)
|
|
57
|
+
#define RASTER (*(volatile char *)0xd012)
|
|
58
|
+
#define SCREEN ((char *)0x0400)
|
|
59
|
+
|
|
60
|
+
#ifndef AUTOPILOT
|
|
61
|
+
#define AUTOPILOT 1
|
|
62
|
+
#endif
|
|
63
|
+
|
|
64
|
+
typedef struct {
|
|
65
|
+
char name[17]; // up to 16 PETSCII bytes plus zero
|
|
66
|
+
char type[4]; // PRG, SEQ, REL, USR or DEL
|
|
67
|
+
unsigned blocks; // the line number of the "$" line
|
|
68
|
+
bool splat; // '*' before the type: not closed
|
|
69
|
+
} DirEntry;
|
|
70
|
+
|
|
71
|
+
typedef struct {
|
|
72
|
+
char disk[17]; // header name, 16 bytes plus zero
|
|
73
|
+
char id[7]; // the six bytes after the name: " 01 2A"
|
|
74
|
+
unsigned free; // the BLOCKS FREE line number
|
|
75
|
+
char count; // entries parsed
|
|
76
|
+
DirEntry entry[DIR_MAX];
|
|
77
|
+
} Directory;
|
|
78
|
+
|
|
79
|
+
// The three files this program writes before it reads the directory.
|
|
80
|
+
// A 1541 data block holds 254 bytes, so 50, 300 and 600 bytes are
|
|
81
|
+
// 1, 2 and 3 blocks. The third is opened ",P,W" so the table shows
|
|
82
|
+
// a PRG beside two SEQs.
|
|
83
|
+
typedef struct { const char *open; const char *name; const char *type;
|
|
84
|
+
unsigned size; unsigned blocks; } Wanted;
|
|
85
|
+
|
|
86
|
+
static const Wanted wanted[3] = {
|
|
87
|
+
{ "ALPHA,S,W", "ALPHA", "SEQ", 50, 1 },
|
|
88
|
+
{ "BRAVO,S,W", "BRAVO", "SEQ", 300, 2 },
|
|
89
|
+
{ "CHARLIE,P,W", "CHARLIE", "PRG", 600, 3 }
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
static char raw[1024]; // the "$" stream, link bytes and all
|
|
93
|
+
static unsigned rawlen;
|
|
94
|
+
static Directory dir;
|
|
95
|
+
static char reply[40];
|
|
96
|
+
|
|
97
|
+
// CIA2 timers A and B chained as a free-running 32-bit cycle counter.
|
|
98
|
+
#define CIA2 ((volatile char *)0xdd00)
|
|
99
|
+
|
|
100
|
+
static void counter_start(void)
|
|
101
|
+
{
|
|
102
|
+
CIA2[4] = 0xff; CIA2[5] = 0xff;
|
|
103
|
+
CIA2[6] = 0xff; CIA2[7] = 0xff;
|
|
104
|
+
CIA2[15] = 0x41; // B: start, count A underflows
|
|
105
|
+
CIA2[14] = 0x01; // A: start, continuous
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
static unsigned long counter_now(void)
|
|
109
|
+
{
|
|
110
|
+
volatile char *c = CIA2;
|
|
111
|
+
unsigned lo = c[4] | ((unsigned)c[5] << 8);
|
|
112
|
+
unsigned hi = c[6] | ((unsigned)c[7] << 8);
|
|
113
|
+
return ~(((unsigned long)hi << 16) | lo);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
static void put_hex2(char v)
|
|
117
|
+
{
|
|
118
|
+
char d = v >> 4;
|
|
119
|
+
putchar(d < 10 ? '0' + d : 'A' + d - 10);
|
|
120
|
+
d = v & 15;
|
|
121
|
+
putchar(d < 10 ? '0' + d : 'A' + d - 10);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
static void put_hex4(unsigned v)
|
|
125
|
+
{
|
|
126
|
+
put_hex2(v >> 8);
|
|
127
|
+
put_hex2(v & 0xff);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
static void put_hex8(unsigned long v)
|
|
131
|
+
{
|
|
132
|
+
put_hex4(v >> 16);
|
|
133
|
+
put_hex4(v & 0xffff);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Channel 15: one status line, without its CR.
|
|
137
|
+
static void drive_reply(void)
|
|
138
|
+
{
|
|
139
|
+
reply[0] = 0;
|
|
140
|
+
krnio_setnam("");
|
|
141
|
+
if (krnio_open(15, DRIVE, 15)) {
|
|
142
|
+
int n = krnio_gets(15, reply, sizeof(reply));
|
|
143
|
+
if (n > 0 && reply[n - 1] == 13)
|
|
144
|
+
reply[n - 1] = 0;
|
|
145
|
+
krnio_close(15);
|
|
146
|
+
}
|
|
147
|
+
printf("DRIVE: %s\n", reply);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Write one file of the given size; the bytes are a running count.
|
|
151
|
+
static void write_file(const Wanted *w)
|
|
152
|
+
{
|
|
153
|
+
static char block[64];
|
|
154
|
+
unsigned left = w->size;
|
|
155
|
+
char v = 0;
|
|
156
|
+
krnio_setnam(w->open);
|
|
157
|
+
if (!krnio_open(3, DRIVE, 3))
|
|
158
|
+
return;
|
|
159
|
+
while (left) {
|
|
160
|
+
unsigned n = left < sizeof(block) ? left : sizeof(block);
|
|
161
|
+
for (unsigned i = 0; i < n; i++)
|
|
162
|
+
block[i] = v++;
|
|
163
|
+
krnio_write(3, block, n);
|
|
164
|
+
left -= n;
|
|
165
|
+
}
|
|
166
|
+
krnio_close(3);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Open "$" on secondary 0 and pull the whole stream into raw[]. This is
|
|
170
|
+
// CHKIN once, then CHRIN and READST per byte until EOI: the same loop as
|
|
171
|
+
// kernal_file_read_seq, stopped by the buffer size as well as by ST.
|
|
172
|
+
static char read_directory(void)
|
|
173
|
+
{
|
|
174
|
+
char st = 0;
|
|
175
|
+
rawlen = 0;
|
|
176
|
+
krnio_setnam("$");
|
|
177
|
+
if (!krnio_open(DIR_LFN, DRIVE, 0))
|
|
178
|
+
return 0xff;
|
|
179
|
+
if (krnio_chkin(DIR_LFN)) {
|
|
180
|
+
for (;;) {
|
|
181
|
+
char b = krnio_chrin();
|
|
182
|
+
st = krnio_status();
|
|
183
|
+
if (st & ~0x40) // any error bit: keep nothing
|
|
184
|
+
break;
|
|
185
|
+
raw[rawlen++] = b;
|
|
186
|
+
if (st || rawlen == sizeof(raw))
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
krnio_clrchn();
|
|
191
|
+
krnio_close(DIR_LFN);
|
|
192
|
+
return st;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Parse raw[] as the BASIC program the drive pretends "$" is: a load
|
|
196
|
+
// address, then lines of link (2), line number (2), text, zero; a zero
|
|
197
|
+
// link ends the listing. The first line is the header, the last is
|
|
198
|
+
// BLOCKS FREE, the rest are entries.
|
|
199
|
+
static void parse_directory(void)
|
|
200
|
+
{
|
|
201
|
+
unsigned p = 2; // skip the load address $0401
|
|
202
|
+
char line = 0;
|
|
203
|
+
dir.count = 0;
|
|
204
|
+
while (p + 4 <= rawlen) {
|
|
205
|
+
char link_lo = raw[p], link_hi = raw[p + 1];
|
|
206
|
+
if (link_lo == 0 && link_hi == 0)
|
|
207
|
+
break;
|
|
208
|
+
unsigned number = raw[p + 2] | ((unsigned)raw[p + 3] << 8);
|
|
209
|
+
p += 4;
|
|
210
|
+
unsigned start = p;
|
|
211
|
+
while (p < rawlen && raw[p] != 0)
|
|
212
|
+
p++;
|
|
213
|
+
unsigned end = p; // raw[end] is the zero
|
|
214
|
+
p++;
|
|
215
|
+
// find the quoted name, if there is one
|
|
216
|
+
unsigned q = start;
|
|
217
|
+
while (q < end && raw[q] != '"')
|
|
218
|
+
q++;
|
|
219
|
+
if (q == end) { // no quotes: the free line
|
|
220
|
+
dir.free = number;
|
|
221
|
+
} else if (line == 0) { // header: name then id
|
|
222
|
+
char i = 0;
|
|
223
|
+
q++;
|
|
224
|
+
while (q < end && raw[q] != '"' && i < 16) {
|
|
225
|
+
char c = raw[q++];
|
|
226
|
+
if (c == 0xa0) // the header pads with shifted spaces
|
|
227
|
+
c = ' ';
|
|
228
|
+
dir.disk[i++] = c;
|
|
229
|
+
}
|
|
230
|
+
while (i > 0 && dir.disk[i - 1] == ' ')
|
|
231
|
+
i--;
|
|
232
|
+
dir.disk[i] = 0;
|
|
233
|
+
q++; // closing quote
|
|
234
|
+
i = 0;
|
|
235
|
+
while (q < end && i < 6)
|
|
236
|
+
dir.id[i++] = raw[q++];
|
|
237
|
+
dir.id[i] = 0;
|
|
238
|
+
} else if (dir.count < DIR_MAX) {
|
|
239
|
+
DirEntry *e = &dir.entry[dir.count];
|
|
240
|
+
char i = 0;
|
|
241
|
+
q++;
|
|
242
|
+
while (q < end && raw[q] != '"' && i < 16)
|
|
243
|
+
e->name[i++] = raw[q++];
|
|
244
|
+
e->name[i] = 0;
|
|
245
|
+
q++; // closing quote
|
|
246
|
+
while (q < end && raw[q] == ' ')
|
|
247
|
+
q++;
|
|
248
|
+
e->splat = (q < end && raw[q] == '*');
|
|
249
|
+
if (e->splat)
|
|
250
|
+
q++;
|
|
251
|
+
for (i = 0; i < 3; i++)
|
|
252
|
+
e->type[i] = (q < end) ? raw[q++] : ' ';
|
|
253
|
+
e->type[3] = 0;
|
|
254
|
+
e->blocks = number;
|
|
255
|
+
dir.count++;
|
|
256
|
+
}
|
|
257
|
+
line++;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
static bool str_eq(const char *a, const char *b)
|
|
262
|
+
{
|
|
263
|
+
while (*a && *a == *b) { a++; b++; }
|
|
264
|
+
return *a == *b;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// One table row straight into screen RAM, so the highlight can move
|
|
268
|
+
// without disturbing the printf cursor. Upper-case PETSCII letters map
|
|
269
|
+
// to screen codes by clearing bit 6; digits, space and quotes are the
|
|
270
|
+
// same in both. Bit 7 set is reverse video.
|
|
271
|
+
static void draw_row(char i, bool selected)
|
|
272
|
+
{
|
|
273
|
+
char *row = SCREEN + 40 * (TABLE_ROW + i);
|
|
274
|
+
char buf[40];
|
|
275
|
+
const DirEntry *e = &dir.entry[i];
|
|
276
|
+
char n = 0, k;
|
|
277
|
+
for (k = 0; k < 40; k++)
|
|
278
|
+
buf[k] = ' ';
|
|
279
|
+
buf[n++] = selected ? '>' : ' ';
|
|
280
|
+
buf[n++] = ' ';
|
|
281
|
+
buf[n++] = e->blocks >= 100 ? '0' + (e->blocks / 100) % 10 : ' ';
|
|
282
|
+
buf[n++] = e->blocks >= 10 ? '0' + (e->blocks / 10) % 10 : ' ';
|
|
283
|
+
buf[n++] = '0' + e->blocks % 10;
|
|
284
|
+
buf[n++] = ' ';
|
|
285
|
+
buf[n++] = '"';
|
|
286
|
+
for (k = 0; e->name[k]; k++)
|
|
287
|
+
buf[n++] = e->name[k];
|
|
288
|
+
buf[n++] = '"';
|
|
289
|
+
n = 26;
|
|
290
|
+
buf[n++] = e->splat ? '*' : ' ';
|
|
291
|
+
for (k = 0; k < 3; k++)
|
|
292
|
+
buf[n++] = e->type[k];
|
|
293
|
+
for (k = 0; k < 40; k++) {
|
|
294
|
+
char c = buf[k];
|
|
295
|
+
if (c >= 'A' && c <= 'Z')
|
|
296
|
+
c &= 0x3f;
|
|
297
|
+
row[k] = selected ? (c | 0x80) : c;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
static void wait_frame(void)
|
|
302
|
+
{
|
|
303
|
+
while (RASTER != 0xff) ;
|
|
304
|
+
while (RASTER == 0xff) ;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
int main(void)
|
|
308
|
+
{
|
|
309
|
+
unsigned long t0, txfer, tparse;
|
|
310
|
+
char st, i;
|
|
311
|
+
bool ok;
|
|
312
|
+
|
|
313
|
+
counter_start();
|
|
314
|
+
printf("%cDIRECTORY READER / FILE SELECTOR\n", 147);
|
|
315
|
+
|
|
316
|
+
// 1. put three files on the blank disk so there is something to list
|
|
317
|
+
printf("WRITE");
|
|
318
|
+
for (i = 0; i < 3; i++) {
|
|
319
|
+
printf(" %s %u", wanted[i].name, wanted[i].size);
|
|
320
|
+
write_file(&wanted[i]);
|
|
321
|
+
}
|
|
322
|
+
putchar('\n');
|
|
323
|
+
drive_reply();
|
|
324
|
+
|
|
325
|
+
// 2. the directory as a stream, then the parse, timed apart
|
|
326
|
+
t0 = counter_now();
|
|
327
|
+
st = read_directory();
|
|
328
|
+
txfer = counter_now() - t0;
|
|
329
|
+
printf("READ $ %u BYTES ST=", rawlen);
|
|
330
|
+
put_hex2(st);
|
|
331
|
+
putchar('\n');
|
|
332
|
+
drive_reply();
|
|
333
|
+
|
|
334
|
+
t0 = counter_now();
|
|
335
|
+
parse_directory();
|
|
336
|
+
tparse = counter_now() - t0;
|
|
337
|
+
|
|
338
|
+
// 3. the table: header, entries, free blocks
|
|
339
|
+
printf("DISK \"%s\"%s, %d ENTRIES\n\n", dir.disk, dir.id, dir.count);
|
|
340
|
+
for (i = 0; i < dir.count; i++) {
|
|
341
|
+
draw_row(i, i == 0);
|
|
342
|
+
putchar('\n'); // leave the row to draw_row
|
|
343
|
+
}
|
|
344
|
+
printf("%u BLOCKS FREE\n", dir.free);
|
|
345
|
+
|
|
346
|
+
// 4. the verdict: exactly the files written, in order
|
|
347
|
+
ok = (dir.count == 3);
|
|
348
|
+
for (i = 0; ok && i < 3; i++) {
|
|
349
|
+
const DirEntry *e = &dir.entry[i];
|
|
350
|
+
if (!str_eq(e->name, wanted[i].name) ||
|
|
351
|
+
!str_eq(e->type, wanted[i].type) ||
|
|
352
|
+
e->blocks != wanted[i].blocks || e->splat)
|
|
353
|
+
ok = false;
|
|
354
|
+
}
|
|
355
|
+
printf("TABLE %s\n", ok ? "PASS" : "FAIL");
|
|
356
|
+
RESULT = ok ? 1 : 2;
|
|
357
|
+
BORDER = ok ? 5 : 2;
|
|
358
|
+
|
|
359
|
+
printf("CYCLES XFER $");
|
|
360
|
+
put_hex8(txfer);
|
|
361
|
+
printf(" PARSE $");
|
|
362
|
+
put_hex8(tparse);
|
|
363
|
+
putchar('\n');
|
|
364
|
+
|
|
365
|
+
// 5. the selector: joystick 2 moves the highlight, fire picks. The
|
|
366
|
+
// autopilot presses down on frame 10 and fire on frame 30 through
|
|
367
|
+
// the same edge logic, so the picture shows the second entry picked.
|
|
368
|
+
char sel = 0, prev = 0, frame = 0;
|
|
369
|
+
for (;;) {
|
|
370
|
+
char now;
|
|
371
|
+
wait_frame();
|
|
372
|
+
joy_poll(0); // port 2 is index 0
|
|
373
|
+
now = (joyy[0] < 0 ? 1 : 0) | (joyy[0] > 0 ? 2 : 0) | (joyb[0] ? 4 : 0);
|
|
374
|
+
#if AUTOPILOT
|
|
375
|
+
if (frame == 10) now |= 2;
|
|
376
|
+
if (frame == 30) now |= 4;
|
|
377
|
+
#endif
|
|
378
|
+
char pressed = now & ~prev;
|
|
379
|
+
prev = now;
|
|
380
|
+
if (frame < 255) frame++;
|
|
381
|
+
if ((pressed & 1) && sel > 0) {
|
|
382
|
+
draw_row(sel, false); sel--; draw_row(sel, true);
|
|
383
|
+
}
|
|
384
|
+
if ((pressed & 2) && sel + 1 < dir.count) {
|
|
385
|
+
draw_row(sel, false); sel++; draw_row(sel, true);
|
|
386
|
+
}
|
|
387
|
+
if (pressed & 4)
|
|
388
|
+
break;
|
|
389
|
+
}
|
|
390
|
+
printf("PICKED %d \"%s\" %s %u\n", sel + 1, dir.entry[sel].name,
|
|
391
|
+
dir.entry[sel].type, dir.entry[sel].blocks);
|
|
392
|
+
return 0;
|
|
393
|
+
}
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
## Build
|
|
397
|
+
|
|
398
|
+
```bash
|
|
399
|
+
oscar64 -tm=c64 -O2 -o=directory-reader.prg directory-reader.c
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
Produces `directory-reader.prg`, 7,199 bytes. `kernalio.h` and
|
|
403
|
+
`joystick.h` each carry a `#pragma compile` for their `.c` file, so no
|
|
404
|
+
second source goes on the command line. The run needs a fresh disk in
|
|
405
|
+
drive 8:
|
|
406
|
+
|
|
407
|
+
```bash
|
|
408
|
+
c1541 -format "TEST,01" d64 test.d64
|
|
409
|
+
x64sc -default -warp +sound +autostart-delay-random -autostartprgmode 1 \
|
|
410
|
+
-limitcycles 30000000 -8 test.d64 -drive8truedrive \
|
|
411
|
+
-drive8wobbleamplitude 0 -drive8wobblefrequency 0 \
|
|
412
|
+
-exitscreenshot directory-reader.png -autostart directory-reader.prg
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
`-dAUTOPILOT=0` builds the version with no scripted presses; it waits
|
|
416
|
+
for a real joystick in port 2 and was not run here, because a headless
|
|
417
|
+
run cannot hold one. In the default build the joystick still works
|
|
418
|
+
beside the autopilot, since the two are ORed before the edge test.
|
|
419
|
+
|
|
420
|
+
## Expected output
|
|
421
|
+
|
|
422
|
+
```
|
|
423
|
+
DIRECTORY READER / FILE SELECTOR
|
|
424
|
+
WRITE ALPHA 50 BRAVO 300 CHARLIE 600
|
|
425
|
+
DRIVE: 00, OK,00,00
|
|
426
|
+
READ $ 160 BYTES ST=40
|
|
427
|
+
DRIVE: 00, OK,00,00
|
|
428
|
+
DISK "TEST" 01 2A, 3 ENTRIES
|
|
429
|
+
|
|
430
|
+
1 "ALPHA" SEQ
|
|
431
|
+
> 2 "BRAVO" SEQ
|
|
432
|
+
3 "CHARLIE" PRG
|
|
433
|
+
658 BLOCKS FREE
|
|
434
|
+
TABLE PASS
|
|
435
|
+
CYCLES XFER $0007DE33 PARSE $000035FD
|
|
436
|
+
PICKED 2 "BRAVO" SEQ 2
|
|
437
|
+
|
|
438
|
+
READY.
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
Light blue text on blue with a green border. The `BRAVO` row is drawn
|
|
442
|
+
in reverse video. The `CYCLES` line is the only line that differs
|
|
443
|
+
between regions: NTSC shows `$00082CC0` and `$000037AB`. Screenshots
|
|
444
|
+
from the pinned command: `screenshots/directory-reader.png` (PAL) and
|
|
445
|
+
`screenshots/directory-reader-ntsc.png` (NTSC). A second run of the
|
|
446
|
+
same command on another fresh disk gave a byte-identical PNG on each
|
|
447
|
+
model.
|
|
448
|
+
|
|
449
|
+
One thing in the picture is not as typed above: the disk name after
|
|
450
|
+
`DISK` is four graphics glyphs, not `TEST`. The header line the drive
|
|
451
|
+
sent holds `D4 C5 D3 D4` for the name, shifted PETSCII, because
|
|
452
|
+
`c1541 -format "TEST,01"` stores an upper-case host argument shifted
|
|
453
|
+
(`pitfalls/kernal-and-io.md`, `c1541_uppercase_filename_petscii_shift`,
|
|
454
|
+
and the bytes were read back from track 18 sector 0 of the disk the
|
|
455
|
+
run left behind). The program prints the bytes as it received them;
|
|
456
|
+
the file names it wrote itself came back as plain `ALPHA`, `BRAVO`
|
|
457
|
+
and `CHARLIE` because SETNAM passed the ASCII literal's bytes through,
|
|
458
|
+
and those are the same as unshifted PETSCII. A disk formatted from the
|
|
459
|
+
C64 side would show its name in the ordinary font.
|
|
460
|
+
|
|
461
|
+
What the run measured:
|
|
462
|
+
|
|
463
|
+
- The three writes leave the drive at `00, OK,00,00`. The directory
|
|
464
|
+
the drive sent is 160 bytes, the last of them arriving with
|
|
465
|
+
ST = `$40`, and the drive says `00, OK,00,00` again after the close.
|
|
466
|
+
Reading `$` is an ordinary read: the DOS builds a BASIC listing on
|
|
467
|
+
the fly and hands it over on the data channel like any SEQ file.
|
|
468
|
+
- The parse found the header, three entries and the free line. The
|
|
469
|
+
block counts are 1, 2 and 3 for 50, 300 and 600 bytes: a 1541 data
|
|
470
|
+
block carries 254 bytes of payload, so 300 bytes need two blocks and
|
|
471
|
+
600 need three. `658 BLOCKS FREE` is 664 less those six.
|
|
472
|
+
- `TABLE PASS`: names, types, block counts and the absence of a splat
|
|
473
|
+
mark all match the table compiled in.
|
|
474
|
+
- The transfer (OPEN, CHKIN, 160 CHRIN and READST pairs, CLRCHN,
|
|
475
|
+
CLOSE) took 515,635 cycles on PAL and 535,744 on NTSC, about 3,200
|
|
476
|
+
cycles a byte with the open and close folded in. The parse of the
|
|
477
|
+
160 bytes in the buffer took 13,821 cycles on PAL and 14,251 on
|
|
478
|
+
NTSC, about 86 cycles a byte. The counter is CIA2 timers A and B
|
|
479
|
+
chained, read before and after each step, as in
|
|
480
|
+
`save-load-seq-file.md`. The counter is read unlatched, one byte at
|
|
481
|
+
a time from running timers, so a carry between two reads can skew a
|
|
482
|
+
sample; take each figure as good to within a few hundred cycles, not
|
|
483
|
+
to the cycle. The two figures move by a few hundred cycles between
|
|
484
|
+
builds of different size, as the earlier draft of this listing
|
|
485
|
+
showed, and are identical between runs of one build.
|
|
486
|
+
- After the run, `c1541 -attach test.d64 -list` printed the same
|
|
487
|
+
three entries with `seq`, `seq`, `prg` and `658 blocks free.`
|
|
488
|
+
|
|
489
|
+
## Why this works
|
|
490
|
+
|
|
491
|
+
The DOS treats `$` as a file name. OPEN on a data channel with that
|
|
492
|
+
name makes the drive assemble a BASIC program image, and CHRIN then
|
|
493
|
+
reads it byte by byte with EOI on the last one, so the loop is
|
|
494
|
+
`kernal_file_read_seq` with a different name. The image starts with a
|
|
495
|
+
two-byte load address (`$0401`, the PET's BASIC start, which is why a
|
|
496
|
+
`LOAD "$",8` lands where a program would). Each line is two link
|
|
497
|
+
bytes, a two-byte line number, PETSCII text and a zero; two zero link
|
|
498
|
+
bytes end the listing. The link bytes are meaningless here, since the
|
|
499
|
+
drive does not know where the listing will be stored, and the parser
|
|
500
|
+
skips them. The line number carries the payload: on the header line
|
|
501
|
+
it is the drive number, on an entry it is the file's block count, and
|
|
502
|
+
on the last line it is the count of free blocks. The text of an entry
|
|
503
|
+
is padding, the name in quotes, padding, an optional `*` for a file
|
|
504
|
+
that was never closed, the three type letters and an optional `<` for
|
|
505
|
+
a locked file. The header line begins with `$12`, reverse on, and
|
|
506
|
+
quotes the disk name padded to sixteen characters with `$A0`; the
|
|
507
|
+
parser turns those into spaces and trims them.
|
|
508
|
+
|
|
509
|
+
The parser reads from a buffer rather than from the bus so that the
|
|
510
|
+
parse can be timed on its own and so that CLRCHN and CLOSE happen
|
|
511
|
+
before any screen output. A version that parses straight from CHRIN
|
|
512
|
+
works the same way and needs no buffer; the technique entry shows the
|
|
513
|
+
shape. Either way the whole listing must be consumed or the channel
|
|
514
|
+
closed before the next file operation, because the drive keeps the
|
|
515
|
+
directory channel open until then.
|
|
516
|
+
|
|
517
|
+
The table rows are written straight into screen RAM by `draw_row`, so
|
|
518
|
+
the highlight moves without disturbing the KERNAL's cursor and the
|
|
519
|
+
`printf` lines before and after the table land where they should.
|
|
520
|
+
Upper-case PETSCII letters become screen codes by clearing bit 6;
|
|
521
|
+
digits, space and quotes are the same in both; bit 7 set is reverse
|
|
522
|
+
video. The selector reads port 2 through `joy_poll(0)`, builds a
|
|
523
|
+
three-bit level word (up, down, fire), ORs the autopilot's presses
|
|
524
|
+
for frames 10 and 30 into it, and takes the rising edges against the
|
|
525
|
+
previous frame, which is `joystick_edge_detect` from
|
|
526
|
+
`techniques/input.md`. A held direction therefore moves one row, not
|
|
527
|
+
one row a frame; a game that wants repeat adds `joystick_autorepeat`.
|
|
528
|
+
The frame wait polls `$D012` for the raster to pass line 255 and come
|
|
529
|
+
back, which is enough here because no IRQ is running.
|
|
530
|
+
|
|
531
|
+
`LOAD "$",8` from BASIC replaces the program in memory with the
|
|
532
|
+
listing, which is why a BASIC program cannot show a directory that
|
|
533
|
+
way and survive. A machine-code or C program has no such problem when
|
|
534
|
+
it uses OPEN and CHRIN: nothing is loaded anywhere, and the listing
|
|
535
|
+
goes only where the program puts it.
|