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,875 @@
|
|
|
1
|
+
---
|
|
2
|
+
recipe: tape-turbo-loader
|
|
3
|
+
toolchain: kickassembler
|
|
4
|
+
output_format: PRG
|
|
5
|
+
region: both
|
|
6
|
+
techniques: [tape_turbo_loader]
|
|
7
|
+
file_formats: [PRG, TAP]
|
|
8
|
+
uses_registers: [D011, D012, D020, DC06, DC07, DC0D, DC0F, DD04, DD05, DD06, DD07, DD0E, DD0F]
|
|
9
|
+
uses_kernal: [CHROUT]
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
<!-- doc-type: recipe -->
|
|
13
|
+
|
|
14
|
+
# KickAssembler Tape Turbo Loader
|
|
15
|
+
|
|
16
|
+
## Synopsis
|
|
17
|
+
|
|
18
|
+
Read a block from tape at one pulse per bit, without the KERNAL's tape
|
|
19
|
+
routines. A Python script writes a TAP file whose stream is a lead-in of
|
|
20
|
+
1 bits, a sync byte, a two-byte length, 500 bytes of known data and an
|
|
21
|
+
XOR checksum, with a 256-cycle pulse for a 0 and a 512-cycle pulse for
|
|
22
|
+
a 1. The loader turns the motor on through `$01`, polls the FLAG bit of
|
|
23
|
+
`$DC0D` for each falling edge of the cassette read line, times the gap
|
|
24
|
+
between edges with a free-running CIA 1 Timer B, sorts each gap against
|
|
25
|
+
a threshold of 384 cycles, waits for sixty-four 1 bits and the 0 that
|
|
26
|
+
opens the sync byte, and then assembles the bytes. It prints the lead-in
|
|
27
|
+
pulses it saw, the length, its own checksum beside the tape's, the CIA 2
|
|
28
|
+
cycle count over the timed span and the bytes per second that gives on
|
|
29
|
+
the detected model, and the shortest and longest pulse it measured for
|
|
30
|
+
each bit value. The verdict at `$02FF` is `01` and the border turns
|
|
31
|
+
green when the length, both checksums and every byte match the
|
|
32
|
+
compiled-in expectation, else `02` and red. The technique is
|
|
33
|
+
`tape_turbo_loader` on `../../techniques/file-io.md`; the KERNAL's own
|
|
34
|
+
pulse-pair encoding, which this deliberately is not, is measured in
|
|
35
|
+
`../../formats/c64-file-formats.md` under "KERNAL bit encoding".
|
|
36
|
+
|
|
37
|
+
## Source
|
|
38
|
+
|
|
39
|
+
```asm
|
|
40
|
+
// tape-turbo-loader.asm
|
|
41
|
+
// Read a one-pulse-per-bit turbo block from tape without the KERNAL's tape
|
|
42
|
+
// routines: motor on through $01, FLAG edges polled in $DC0D, each pulse
|
|
43
|
+
// timed by a free-running CIA 1 Timer B, bits sorted by a threshold.
|
|
44
|
+
// Prints the lead-in count, the block's checksum, the cycles and bytes per
|
|
45
|
+
// second over the block and the pulse lengths seen for each bit value.
|
|
46
|
+
BasicUpstart2(start)
|
|
47
|
+
|
|
48
|
+
.const CHROUT = $ffd2
|
|
49
|
+
.const VERDICT = $02ff
|
|
50
|
+
.const PORT = $01 // 6510 port: bit 4 sense (0 = PLAY down), bit 5 motor (0 = on)
|
|
51
|
+
.const ICR = $dc0d // CIA 1 interrupt control: bit 4 is the FLAG edge
|
|
52
|
+
.const TBLO = $dc06
|
|
53
|
+
.const TBHI = $dc07
|
|
54
|
+
.const CRB = $dc0f
|
|
55
|
+
.const C2TALO = $dd04 // CIA 2 timers cascaded as a 32-bit stopwatch
|
|
56
|
+
.const C2TAHI = $dd05
|
|
57
|
+
.const C2TBLO = $dd06
|
|
58
|
+
.const C2TBHI = $dd07
|
|
59
|
+
.const C2CRA = $dd0e
|
|
60
|
+
.const C2CRB = $dd0f
|
|
61
|
+
.const BORDER = $d020
|
|
62
|
+
.const SCRCTL = $d011
|
|
63
|
+
.const RASTER = $d012
|
|
64
|
+
|
|
65
|
+
.const THRESH = 384 // cycles: a 0 is 256 cycles, a 1 is 512, on the tape written by make_tap.py
|
|
66
|
+
.const SYNC = $5a // first bit 0, so it also ends the lead-in of 1 bits
|
|
67
|
+
.const LEADIN_MIN = 64 // consecutive 1 bits before a 0 counts as sync
|
|
68
|
+
.const EXPECT_LEN = 500
|
|
69
|
+
.const EXPECT_CHK = $40 // XOR of the 500 bytes (i*7+3)&255, printed by make_tap.py
|
|
70
|
+
.const BUF = $4000
|
|
71
|
+
.const PAL_CLOCK = 985248
|
|
72
|
+
.const NTSC_CLOCK = 1022727
|
|
73
|
+
|
|
74
|
+
// zero page
|
|
75
|
+
.const last = $fb // Timer B at the previous edge
|
|
76
|
+
.const now = $fd
|
|
77
|
+
.const pulse = $02 // length of the last pulse, cycles
|
|
78
|
+
.const byte = $04
|
|
79
|
+
.const ptr = $05 // 2 bytes
|
|
80
|
+
.const remain = $07 // 2 bytes: bytes still to read
|
|
81
|
+
.const chk = $09
|
|
82
|
+
.const n = $0a // 4 bytes: dividend / value to print
|
|
83
|
+
.const d = $0e // 2 bytes: divisor
|
|
84
|
+
.const rem = $10 // 3 bytes
|
|
85
|
+
.const cnt = $13
|
|
86
|
+
.const tmp = $14 // 2 bytes
|
|
87
|
+
|
|
88
|
+
start:
|
|
89
|
+
lda #$93
|
|
90
|
+
jsr CHROUT
|
|
91
|
+
ldx #0
|
|
92
|
+
!: lda title,x
|
|
93
|
+
beq !+
|
|
94
|
+
jsr CHROUT
|
|
95
|
+
inx
|
|
96
|
+
bne !-
|
|
97
|
+
!:
|
|
98
|
+
sei
|
|
99
|
+
lda #$7f
|
|
100
|
+
sta ICR // no CIA 1 interrupts while we poll the ICR
|
|
101
|
+
lda ICR // clear anything pending
|
|
102
|
+
lda #$00
|
|
103
|
+
sta CRB // Timer B stopped
|
|
104
|
+
lda #$ff
|
|
105
|
+
sta TBLO
|
|
106
|
+
sta TBHI // latch $FFFF
|
|
107
|
+
lda #$11 // force load and run continuously from the system clock
|
|
108
|
+
sta CRB
|
|
109
|
+
|
|
110
|
+
wait_play:
|
|
111
|
+
lda PORT
|
|
112
|
+
and #$10
|
|
113
|
+
bne wait_play // bit 4 low: PLAY is down
|
|
114
|
+
lda PORT
|
|
115
|
+
and #$df
|
|
116
|
+
sta PORT // bit 5 low: motor on
|
|
117
|
+
lda SCRCTL
|
|
118
|
+
and #$ef
|
|
119
|
+
sta SCRCTL // screen off: no badline steals the poll
|
|
120
|
+
|
|
121
|
+
lda #0
|
|
122
|
+
sta leadin
|
|
123
|
+
sta leadin+1
|
|
124
|
+
sta ones
|
|
125
|
+
jsr read_pulse // prime 'last'
|
|
126
|
+
|
|
127
|
+
// lead-in: wait for LEADIN_MIN consecutive 1 bits, then the first 0 is bit 7 of SYNC
|
|
128
|
+
sync_loop:
|
|
129
|
+
jsr read_bit
|
|
130
|
+
inc leadin
|
|
131
|
+
bne !+
|
|
132
|
+
inc leadin+1
|
|
133
|
+
!: bcc got_zero
|
|
134
|
+
lda ones
|
|
135
|
+
cmp #LEADIN_MIN
|
|
136
|
+
bcs sync_loop
|
|
137
|
+
inc ones
|
|
138
|
+
bne sync_loop
|
|
139
|
+
got_zero:
|
|
140
|
+
lda ones
|
|
141
|
+
cmp #LEADIN_MIN
|
|
142
|
+
bcc reset_ones // a 0 too early: start counting again
|
|
143
|
+
lda #0
|
|
144
|
+
sta byte
|
|
145
|
+
lda #7
|
|
146
|
+
sta cnt
|
|
147
|
+
!: jsr read_bit // read_bit leaves X as the stats slot, so count in memory
|
|
148
|
+
rol byte
|
|
149
|
+
dec cnt
|
|
150
|
+
bne !-
|
|
151
|
+
lda byte
|
|
152
|
+
cmp #SYNC
|
|
153
|
+
beq synced
|
|
154
|
+
reset_ones:
|
|
155
|
+
lda #0
|
|
156
|
+
sta ones
|
|
157
|
+
beq sync_loop
|
|
158
|
+
|
|
159
|
+
synced:
|
|
160
|
+
jsr stats_reset // set up now: a 0 pulse is short and the next edge will not wait
|
|
161
|
+
jsr stopwatch_start
|
|
162
|
+
jsr read_byte
|
|
163
|
+
sta remain
|
|
164
|
+
sta length
|
|
165
|
+
jsr read_byte
|
|
166
|
+
sta remain+1
|
|
167
|
+
sta length+1
|
|
168
|
+
lda #<BUF
|
|
169
|
+
sta ptr
|
|
170
|
+
lda #>BUF
|
|
171
|
+
sta ptr+1
|
|
172
|
+
lda #0
|
|
173
|
+
sta chk
|
|
174
|
+
ldy #0
|
|
175
|
+
block_loop:
|
|
176
|
+
lda remain
|
|
177
|
+
ora remain+1
|
|
178
|
+
beq block_done
|
|
179
|
+
jsr read_byte
|
|
180
|
+
sta (ptr),y
|
|
181
|
+
eor chk
|
|
182
|
+
sta chk
|
|
183
|
+
inc ptr
|
|
184
|
+
bne !+
|
|
185
|
+
inc ptr+1
|
|
186
|
+
!: lda remain
|
|
187
|
+
bne !+
|
|
188
|
+
dec remain+1
|
|
189
|
+
!: dec remain
|
|
190
|
+
jmp block_loop
|
|
191
|
+
block_done:
|
|
192
|
+
jsr read_byte
|
|
193
|
+
sta tapechk
|
|
194
|
+
jsr stopwatch_stop // timed: length, block and checksum, EXPECT_LEN + 3 bytes
|
|
195
|
+
|
|
196
|
+
lda PORT
|
|
197
|
+
ora #$20
|
|
198
|
+
sta PORT // motor off
|
|
199
|
+
lda SCRCTL
|
|
200
|
+
ora #$10
|
|
201
|
+
sta SCRCTL
|
|
202
|
+
lda #$81
|
|
203
|
+
sta ICR // Timer A interrupt back on for the KERNAL
|
|
204
|
+
cli
|
|
205
|
+
|
|
206
|
+
// verdict: length, checksum and every byte against the generating formula
|
|
207
|
+
lda #2
|
|
208
|
+
sta verdict
|
|
209
|
+
lda length
|
|
210
|
+
cmp #<EXPECT_LEN
|
|
211
|
+
bne judged
|
|
212
|
+
lda length+1
|
|
213
|
+
cmp #>EXPECT_LEN
|
|
214
|
+
bne judged
|
|
215
|
+
lda chk
|
|
216
|
+
cmp #EXPECT_CHK
|
|
217
|
+
bne judged
|
|
218
|
+
cmp tapechk
|
|
219
|
+
bne judged
|
|
220
|
+
jsr check_bytes
|
|
221
|
+
bcs judged
|
|
222
|
+
lda #1
|
|
223
|
+
sta verdict
|
|
224
|
+
judged:
|
|
225
|
+
|
|
226
|
+
// report
|
|
227
|
+
jsr detect_model
|
|
228
|
+
lda #<t_leadin
|
|
229
|
+
ldy #>t_leadin
|
|
230
|
+
jsr print
|
|
231
|
+
lda leadin
|
|
232
|
+
sta n
|
|
233
|
+
lda leadin+1
|
|
234
|
+
sta n+1
|
|
235
|
+
lda #0
|
|
236
|
+
sta n+2
|
|
237
|
+
sta n+3
|
|
238
|
+
jsr print_dec
|
|
239
|
+
lda #<t_len
|
|
240
|
+
ldy #>t_len
|
|
241
|
+
jsr print
|
|
242
|
+
lda length
|
|
243
|
+
sta n
|
|
244
|
+
lda length+1
|
|
245
|
+
sta n+1
|
|
246
|
+
jsr print_dec
|
|
247
|
+
lda #<t_chk
|
|
248
|
+
ldy #>t_chk
|
|
249
|
+
jsr print
|
|
250
|
+
lda chk
|
|
251
|
+
jsr print_hex
|
|
252
|
+
lda #<t_tapechk
|
|
253
|
+
ldy #>t_tapechk
|
|
254
|
+
jsr print
|
|
255
|
+
lda tapechk
|
|
256
|
+
jsr print_hex
|
|
257
|
+
lda #13
|
|
258
|
+
jsr CHROUT
|
|
259
|
+
|
|
260
|
+
lda #<t_cycles
|
|
261
|
+
ldy #>t_cycles
|
|
262
|
+
jsr print
|
|
263
|
+
ldx #3
|
|
264
|
+
!: lda cycles,x
|
|
265
|
+
sta n,x
|
|
266
|
+
dex
|
|
267
|
+
bpl !-
|
|
268
|
+
jsr print_dec
|
|
269
|
+
lda #<t_bps
|
|
270
|
+
ldy #>t_bps
|
|
271
|
+
jsr print
|
|
272
|
+
// bytes per second = clock / (cycles / length)
|
|
273
|
+
ldx #3
|
|
274
|
+
!: lda cycles,x
|
|
275
|
+
sta n,x
|
|
276
|
+
dex
|
|
277
|
+
bpl !-
|
|
278
|
+
lda #<[EXPECT_LEN + 3]
|
|
279
|
+
sta d
|
|
280
|
+
lda #>[EXPECT_LEN + 3]
|
|
281
|
+
sta d+1
|
|
282
|
+
jsr div32 // n = cycles per byte
|
|
283
|
+
lda n
|
|
284
|
+
sta d
|
|
285
|
+
lda n+1
|
|
286
|
+
sta d+1
|
|
287
|
+
lda model
|
|
288
|
+
bne !+
|
|
289
|
+
lda #<PAL_CLOCK
|
|
290
|
+
sta n
|
|
291
|
+
lda #>PAL_CLOCK
|
|
292
|
+
sta n+1
|
|
293
|
+
lda #[PAL_CLOCK >> 16]
|
|
294
|
+
sta n+2
|
|
295
|
+
bne !++
|
|
296
|
+
!: lda #<NTSC_CLOCK
|
|
297
|
+
sta n
|
|
298
|
+
lda #>NTSC_CLOCK
|
|
299
|
+
sta n+1
|
|
300
|
+
lda #[NTSC_CLOCK >> 16]
|
|
301
|
+
sta n+2
|
|
302
|
+
!: lda #0
|
|
303
|
+
sta n+3
|
|
304
|
+
jsr div32
|
|
305
|
+
jsr print_dec
|
|
306
|
+
lda #<t_model
|
|
307
|
+
ldy #>t_model
|
|
308
|
+
jsr print
|
|
309
|
+
lda model
|
|
310
|
+
beq !+
|
|
311
|
+
lda #<t_ntsc
|
|
312
|
+
ldy #>t_ntsc
|
|
313
|
+
bne !++
|
|
314
|
+
!: lda #<t_pal
|
|
315
|
+
ldy #>t_pal
|
|
316
|
+
!: jsr print
|
|
317
|
+
|
|
318
|
+
lda #<t_bit0
|
|
319
|
+
ldy #>t_bit0
|
|
320
|
+
jsr print
|
|
321
|
+
ldx #0
|
|
322
|
+
jsr print_range
|
|
323
|
+
lda #<t_bit1
|
|
324
|
+
ldy #>t_bit1
|
|
325
|
+
jsr print
|
|
326
|
+
ldx #4
|
|
327
|
+
jsr print_range
|
|
328
|
+
lda #13
|
|
329
|
+
jsr CHROUT
|
|
330
|
+
|
|
331
|
+
lda verdict
|
|
332
|
+
sta VERDICT
|
|
333
|
+
cmp #1
|
|
334
|
+
beq good
|
|
335
|
+
lda #2
|
|
336
|
+
sta BORDER
|
|
337
|
+
lda #<t_bad
|
|
338
|
+
ldy #>t_bad
|
|
339
|
+
jmp print
|
|
340
|
+
good:
|
|
341
|
+
lda #5
|
|
342
|
+
sta BORDER
|
|
343
|
+
lda #<t_ok
|
|
344
|
+
ldy #>t_ok
|
|
345
|
+
jmp print
|
|
346
|
+
|
|
347
|
+
// ---------------------------------------------------------------- tape input
|
|
348
|
+
|
|
349
|
+
// Wait for a FLAG edge and measure the time since the previous one.
|
|
350
|
+
// Timer B free-runs down from $FFFF, so the length is last - now.
|
|
351
|
+
read_pulse:
|
|
352
|
+
lda ICR
|
|
353
|
+
and #$10
|
|
354
|
+
beq read_pulse
|
|
355
|
+
lda TBHI
|
|
356
|
+
sta now+1
|
|
357
|
+
lda TBLO
|
|
358
|
+
sta now
|
|
359
|
+
lda TBHI
|
|
360
|
+
cmp now+1 // the low byte wrapped between the reads: take both again
|
|
361
|
+
beq !+
|
|
362
|
+
sta now+1
|
|
363
|
+
lda TBLO
|
|
364
|
+
sta now
|
|
365
|
+
!: sec
|
|
366
|
+
lda last
|
|
367
|
+
sbc now
|
|
368
|
+
sta pulse
|
|
369
|
+
lda last+1
|
|
370
|
+
sbc now+1
|
|
371
|
+
sta pulse+1
|
|
372
|
+
lda now
|
|
373
|
+
sta last
|
|
374
|
+
lda now+1
|
|
375
|
+
sta last+1
|
|
376
|
+
rts
|
|
377
|
+
|
|
378
|
+
// One bit into the carry: 0 below THRESH cycles, 1 at or above it.
|
|
379
|
+
read_bit:
|
|
380
|
+
jsr read_pulse
|
|
381
|
+
lda pulse+1
|
|
382
|
+
cmp #>THRESH
|
|
383
|
+
bne !+
|
|
384
|
+
lda pulse
|
|
385
|
+
cmp #<THRESH
|
|
386
|
+
!: php
|
|
387
|
+
bcc !+
|
|
388
|
+
ldx #4 // stats slot for a 1
|
|
389
|
+
bne !++
|
|
390
|
+
!: ldx #0
|
|
391
|
+
!: jsr stats_update
|
|
392
|
+
plp
|
|
393
|
+
rts
|
|
394
|
+
|
|
395
|
+
// Eight bits, most significant first.
|
|
396
|
+
read_byte:
|
|
397
|
+
lda #8
|
|
398
|
+
sta cnt
|
|
399
|
+
!: jsr read_bit
|
|
400
|
+
rol byte
|
|
401
|
+
dec cnt
|
|
402
|
+
bne !-
|
|
403
|
+
lda byte
|
|
404
|
+
rts
|
|
405
|
+
|
|
406
|
+
// min and max pulse length per bit value: min0, max0 at stats+0..3, min1, max1 at +4..7
|
|
407
|
+
stats_reset:
|
|
408
|
+
ldx #1
|
|
409
|
+
!: lda #$ff
|
|
410
|
+
sta stats,x // minima start at $FFFF
|
|
411
|
+
sta stats+4,x
|
|
412
|
+
lda #0
|
|
413
|
+
sta stats+2,x // maxima at 0
|
|
414
|
+
sta stats+6,x
|
|
415
|
+
dex
|
|
416
|
+
bpl !-
|
|
417
|
+
rts
|
|
418
|
+
|
|
419
|
+
stats_update:
|
|
420
|
+
lda pulse+1
|
|
421
|
+
cmp stats+1,x
|
|
422
|
+
bne !+
|
|
423
|
+
lda pulse
|
|
424
|
+
cmp stats,x
|
|
425
|
+
!: bcs !+
|
|
426
|
+
lda pulse
|
|
427
|
+
sta stats,x
|
|
428
|
+
lda pulse+1
|
|
429
|
+
sta stats+1,x
|
|
430
|
+
!: lda stats+3,x
|
|
431
|
+
cmp pulse+1
|
|
432
|
+
bne !+
|
|
433
|
+
lda stats+2,x
|
|
434
|
+
cmp pulse
|
|
435
|
+
!: bcs !+
|
|
436
|
+
lda pulse
|
|
437
|
+
sta stats+2,x
|
|
438
|
+
lda pulse+1
|
|
439
|
+
sta stats+3,x
|
|
440
|
+
!: rts
|
|
441
|
+
|
|
442
|
+
// ---------------------------------------------------------------- stopwatch
|
|
443
|
+
|
|
444
|
+
stopwatch_start:
|
|
445
|
+
lda #0
|
|
446
|
+
sta C2CRA
|
|
447
|
+
sta C2CRB
|
|
448
|
+
lda #$ff
|
|
449
|
+
sta C2TALO
|
|
450
|
+
sta C2TAHI
|
|
451
|
+
sta C2TBLO
|
|
452
|
+
sta C2TBHI
|
|
453
|
+
lda #$51 // B counts A underflows, force load, start
|
|
454
|
+
sta C2CRB
|
|
455
|
+
lda #$11 // A counts the clock, force load, start
|
|
456
|
+
sta C2CRA
|
|
457
|
+
rts
|
|
458
|
+
|
|
459
|
+
stopwatch_stop:
|
|
460
|
+
lda #0
|
|
461
|
+
sta C2CRA
|
|
462
|
+
sta C2CRB
|
|
463
|
+
sec
|
|
464
|
+
lda #$ff
|
|
465
|
+
sbc C2TALO
|
|
466
|
+
sta cycles
|
|
467
|
+
lda #$ff
|
|
468
|
+
sbc C2TAHI
|
|
469
|
+
sta cycles+1
|
|
470
|
+
sec
|
|
471
|
+
lda #$ff
|
|
472
|
+
sbc C2TBLO
|
|
473
|
+
sta cycles+2
|
|
474
|
+
lda #$ff
|
|
475
|
+
sbc C2TBHI
|
|
476
|
+
sta cycles+3
|
|
477
|
+
rts
|
|
478
|
+
|
|
479
|
+
// ---------------------------------------------------------------- checks
|
|
480
|
+
|
|
481
|
+
// C=0 when every byte of the block is (i*7+3)&255.
|
|
482
|
+
check_bytes:
|
|
483
|
+
lda #<BUF
|
|
484
|
+
sta ptr
|
|
485
|
+
lda #>BUF
|
|
486
|
+
sta ptr+1
|
|
487
|
+
lda #3
|
|
488
|
+
sta byte
|
|
489
|
+
lda #<EXPECT_LEN
|
|
490
|
+
sta remain
|
|
491
|
+
lda #>EXPECT_LEN
|
|
492
|
+
sta remain+1
|
|
493
|
+
ldy #0
|
|
494
|
+
!: lda (ptr),y
|
|
495
|
+
cmp byte
|
|
496
|
+
bne bad_byte
|
|
497
|
+
lda byte
|
|
498
|
+
clc
|
|
499
|
+
adc #7
|
|
500
|
+
sta byte
|
|
501
|
+
inc ptr
|
|
502
|
+
bne !+
|
|
503
|
+
inc ptr+1
|
|
504
|
+
!: lda remain
|
|
505
|
+
bne !+
|
|
506
|
+
dec remain+1
|
|
507
|
+
!: dec remain
|
|
508
|
+
lda remain
|
|
509
|
+
ora remain+1
|
|
510
|
+
bne !--
|
|
511
|
+
clc
|
|
512
|
+
rts
|
|
513
|
+
bad_byte:
|
|
514
|
+
sec
|
|
515
|
+
rts
|
|
516
|
+
|
|
517
|
+
// model = 0 for PAL, 1 for NTSC: a raster line at or past 288 exists only on PAL.
|
|
518
|
+
// 4096 reads of about 20 cycles cover four frames on either model.
|
|
519
|
+
detect_model:
|
|
520
|
+
lda #1
|
|
521
|
+
sta model
|
|
522
|
+
ldx #0
|
|
523
|
+
ldy #16
|
|
524
|
+
dm_loop:
|
|
525
|
+
lda SCRCTL
|
|
526
|
+
bpl dm_next
|
|
527
|
+
lda RASTER
|
|
528
|
+
cmp #$20
|
|
529
|
+
bcc dm_next
|
|
530
|
+
lda #0
|
|
531
|
+
sta model
|
|
532
|
+
rts
|
|
533
|
+
dm_next:
|
|
534
|
+
dex
|
|
535
|
+
bne dm_loop
|
|
536
|
+
dey
|
|
537
|
+
bne dm_loop
|
|
538
|
+
rts
|
|
539
|
+
|
|
540
|
+
// ---------------------------------------------------------------- output
|
|
541
|
+
|
|
542
|
+
print:
|
|
543
|
+
sta ptr
|
|
544
|
+
sty ptr+1
|
|
545
|
+
ldy #0
|
|
546
|
+
!: lda (ptr),y
|
|
547
|
+
beq !+
|
|
548
|
+
jsr CHROUT
|
|
549
|
+
iny
|
|
550
|
+
bne !-
|
|
551
|
+
!: rts
|
|
552
|
+
|
|
553
|
+
print_hex:
|
|
554
|
+
pha
|
|
555
|
+
lsr
|
|
556
|
+
lsr
|
|
557
|
+
lsr
|
|
558
|
+
lsr
|
|
559
|
+
jsr print_nibble
|
|
560
|
+
pla
|
|
561
|
+
and #$0f
|
|
562
|
+
print_nibble:
|
|
563
|
+
ora #$30
|
|
564
|
+
cmp #$3a
|
|
565
|
+
bcc !+
|
|
566
|
+
adc #6
|
|
567
|
+
!: jmp CHROUT
|
|
568
|
+
|
|
569
|
+
// print stats slot X as "min-max"
|
|
570
|
+
print_range:
|
|
571
|
+
lda stats,x
|
|
572
|
+
sta n
|
|
573
|
+
lda stats+1,x
|
|
574
|
+
sta n+1
|
|
575
|
+
lda #0
|
|
576
|
+
sta n+2
|
|
577
|
+
sta n+3
|
|
578
|
+
lda stats+2,x
|
|
579
|
+
sta tmp
|
|
580
|
+
lda stats+3,x
|
|
581
|
+
sta tmp+1
|
|
582
|
+
jsr print_dec
|
|
583
|
+
lda #'-'
|
|
584
|
+
jsr CHROUT
|
|
585
|
+
lda tmp
|
|
586
|
+
sta n
|
|
587
|
+
lda tmp+1
|
|
588
|
+
sta n+1
|
|
589
|
+
jmp print_dec
|
|
590
|
+
|
|
591
|
+
// n (32-bit) in decimal, by repeated division by ten
|
|
592
|
+
print_dec:
|
|
593
|
+
lda #0
|
|
594
|
+
sta cnt
|
|
595
|
+
!: lda #10
|
|
596
|
+
sta d
|
|
597
|
+
lda #0
|
|
598
|
+
sta d+1
|
|
599
|
+
jsr div32
|
|
600
|
+
lda rem
|
|
601
|
+
pha
|
|
602
|
+
inc cnt
|
|
603
|
+
lda n
|
|
604
|
+
ora n+1
|
|
605
|
+
ora n+2
|
|
606
|
+
ora n+3
|
|
607
|
+
bne !-
|
|
608
|
+
!: pla
|
|
609
|
+
ora #$30
|
|
610
|
+
jsr CHROUT
|
|
611
|
+
dec cnt
|
|
612
|
+
bne !-
|
|
613
|
+
rts
|
|
614
|
+
|
|
615
|
+
// n = n / d, rem = n mod d; shift-and-subtract, 32 steps
|
|
616
|
+
div32:
|
|
617
|
+
lda #0
|
|
618
|
+
sta rem
|
|
619
|
+
sta rem+1
|
|
620
|
+
sta rem+2
|
|
621
|
+
ldx #32
|
|
622
|
+
!: asl n
|
|
623
|
+
rol n+1
|
|
624
|
+
rol n+2
|
|
625
|
+
rol n+3
|
|
626
|
+
rol rem
|
|
627
|
+
rol rem+1
|
|
628
|
+
rol rem+2
|
|
629
|
+
sec
|
|
630
|
+
lda rem
|
|
631
|
+
sbc d
|
|
632
|
+
tay
|
|
633
|
+
lda rem+1
|
|
634
|
+
sbc d+1
|
|
635
|
+
pha
|
|
636
|
+
lda rem+2
|
|
637
|
+
sbc #0
|
|
638
|
+
bcc !+
|
|
639
|
+
sta rem+2
|
|
640
|
+
pla
|
|
641
|
+
sta rem+1
|
|
642
|
+
sty rem
|
|
643
|
+
inc n
|
|
644
|
+
bne !++
|
|
645
|
+
!: pla
|
|
646
|
+
!: dex
|
|
647
|
+
bne !---
|
|
648
|
+
rts
|
|
649
|
+
|
|
650
|
+
// ---------------------------------------------------------------- data
|
|
651
|
+
|
|
652
|
+
title: .text "TAPE TURBO LOADER"
|
|
653
|
+
.byte 13, 0
|
|
654
|
+
t_leadin: .text "LEADIN "
|
|
655
|
+
.byte 0
|
|
656
|
+
t_len: .text " LEN "
|
|
657
|
+
.byte 0
|
|
658
|
+
t_chk: .text " CHK "
|
|
659
|
+
.byte 0
|
|
660
|
+
t_tapechk: .text "/"
|
|
661
|
+
.byte 0
|
|
662
|
+
t_cycles: .text "CYCLES "
|
|
663
|
+
.byte 0
|
|
664
|
+
t_bps: .text " B/S "
|
|
665
|
+
.byte 0
|
|
666
|
+
t_model: .text " "
|
|
667
|
+
.byte 0
|
|
668
|
+
t_pal: .text "PAL"
|
|
669
|
+
.byte 13, 0
|
|
670
|
+
t_ntsc: .text "NTSC"
|
|
671
|
+
.byte 13, 0
|
|
672
|
+
t_bit0: .text "BIT0 "
|
|
673
|
+
.byte 0
|
|
674
|
+
t_bit1: .text " BIT1 "
|
|
675
|
+
.byte 0
|
|
676
|
+
t_ok: .text "OK"
|
|
677
|
+
.byte 13, 0
|
|
678
|
+
t_bad: .text "BAD"
|
|
679
|
+
.byte 13, 0
|
|
680
|
+
|
|
681
|
+
leadin: .word 0
|
|
682
|
+
ones: .byte 0
|
|
683
|
+
length: .word 0
|
|
684
|
+
tapechk: .byte 0
|
|
685
|
+
verdict: .byte 0
|
|
686
|
+
model: .byte 0
|
|
687
|
+
cycles: .byte 0, 0, 0, 0
|
|
688
|
+
stats: .fill 8, 0
|
|
689
|
+
```
|
|
690
|
+
|
|
691
|
+
## Build
|
|
692
|
+
|
|
693
|
+
The tape first. This script is not part of the listing; save it as
|
|
694
|
+
`make_tap.py` beside the source and run it once:
|
|
695
|
+
|
|
696
|
+
```text
|
|
697
|
+
#!/usr/bin/env python3
|
|
698
|
+
"""Write a TAP v1 file for the tape-turbo-loader recipe.
|
|
699
|
+
|
|
700
|
+
One pulse per bit: a short pulse is a 0, a long pulse is a 1. The
|
|
701
|
+
stream is a lead-in of 1 bits, a sync byte, a two-byte length, the data
|
|
702
|
+
block and an XOR checksum, most significant bit first inside each byte.
|
|
703
|
+
"""
|
|
704
|
+
import struct
|
|
705
|
+
import sys
|
|
706
|
+
|
|
707
|
+
SHORT = 0x20 # 0 bit: 32 TAP units = 256 cycles
|
|
708
|
+
LONG = 0x40 # 1 bit: 64 TAP units = 512 cycles
|
|
709
|
+
LEADIN = 12000 # 1 bits before the sync byte: about 6 s, the tape runs from power-on
|
|
710
|
+
SYNC = 0x5A
|
|
711
|
+
LENGTH = 500
|
|
712
|
+
|
|
713
|
+
|
|
714
|
+
def data_byte(i):
|
|
715
|
+
return (i * 7 + 3) & 0xFF
|
|
716
|
+
|
|
717
|
+
|
|
718
|
+
def bits_of(byte):
|
|
719
|
+
return [(byte >> (7 - k)) & 1 for k in range(8)]
|
|
720
|
+
|
|
721
|
+
|
|
722
|
+
def main(path):
|
|
723
|
+
pulses = []
|
|
724
|
+
pulses += [LONG] * LEADIN
|
|
725
|
+
data = bytes(data_byte(i) for i in range(LENGTH))
|
|
726
|
+
check = 0
|
|
727
|
+
for b in data:
|
|
728
|
+
check ^= b
|
|
729
|
+
stream = bytes([SYNC, LENGTH & 0xFF, LENGTH >> 8]) + data + bytes([check])
|
|
730
|
+
for byte in stream:
|
|
731
|
+
for bit in bits_of(byte):
|
|
732
|
+
pulses.append(LONG if bit else SHORT)
|
|
733
|
+
# a trailer of long pulses so the last data edge is followed by another
|
|
734
|
+
pulses += [LONG] * 3000
|
|
735
|
+
body = bytes(pulses)
|
|
736
|
+
header = b"C64-TAPE-RAW" + bytes([1, 0, 0, 0]) + struct.pack("<I", len(body))
|
|
737
|
+
with open(path, "wb") as f:
|
|
738
|
+
f.write(header + body)
|
|
739
|
+
cycles = sum(p * 8 for p in pulses[LEADIN + 8:LEADIN + 8 * (3 + LENGTH + 1)])
|
|
740
|
+
print(f"wrote {path}: {len(body)} pulses, checksum ${check:02X}, "
|
|
741
|
+
f"timed span {cycles} cycles")
|
|
742
|
+
|
|
743
|
+
|
|
744
|
+
if __name__ == "__main__":
|
|
745
|
+
main(sys.argv[1] if len(sys.argv) > 1 else "turbo.tap")
|
|
746
|
+
```
|
|
747
|
+
|
|
748
|
+
It prints `wrote turbo.tap: 19032 pulses, checksum $40, timed span
|
|
749
|
+
1540608 cycles`. Every TAP entry is one pulse of `value * 8` cycles, so
|
|
750
|
+
the file is 20 bytes of header and 19,032 bytes of pulses. The checksum
|
|
751
|
+
`$40` is the `EXPECT_CHK` constant in the listing; change `LENGTH` or
|
|
752
|
+
`data_byte` and the constant must follow. Then:
|
|
753
|
+
|
|
754
|
+
```bash
|
|
755
|
+
java -jar $KICKASS_JAR tape-turbo-loader.asm -o tape-turbo-loader.prg
|
|
756
|
+
printf 'tapectrl 1\n' > play.mon
|
|
757
|
+
x64sc -default -warp +sound +autostart-delay-random -autostartprgmode 1 \
|
|
758
|
+
-limitcycles 12000000 +dsresetwithcpu \
|
|
759
|
+
-dstapewobbleamp 0 -dstapewobblefreq 0 -dsspeedtuning 0 -dstapeerror 0 \
|
|
760
|
+
-1 turbo.tap -moncommands play.mon \
|
|
761
|
+
-exitscreenshot tape-turbo-loader.png -autostart tape-turbo-loader.prg
|
|
762
|
+
```
|
|
763
|
+
|
|
764
|
+
Add `-model ntsc` for the NTSC run. Three of those options matter and
|
|
765
|
+
were found by running without them. `-1` attaches the TAP, and
|
|
766
|
+
`tapectrl 1` in the monitor command file presses PLAY at power-on
|
|
767
|
+
(`help tapectrl` lists 0 stop, 1 start, 2 forward, 3 rewind, 4 record,
|
|
768
|
+
5 reset, 6 reset counter). `+dsresetwithcpu` keeps that press through
|
|
769
|
+
the reset autostart performs after the monitor commands have run;
|
|
770
|
+
without it the loader sat at its PLAY wait for the whole run. The four
|
|
771
|
+
`-ds` options turn off VICE's tape speed error and wobble so that two
|
|
772
|
+
runs give the same picture; with them at their defaults the block still
|
|
773
|
+
loaded and verified, but the pulse ranges widened (see below). The
|
|
774
|
+
program presses nothing itself: it waits for bit 4 of `$01` to go low,
|
|
775
|
+
then drives bit 5 low for the motor.
|
|
776
|
+
|
|
777
|
+
## Expected output
|
|
778
|
+
|
|
779
|
+
```
|
|
780
|
+
TAPE TURBO LOADER
|
|
781
|
+
LEADIN 10195 LEN 500 CHK 40/40
|
|
782
|
+
CYCLES 1540498 B/S 321 PAL
|
|
783
|
+
BIT0 248-264 BIT1 506-520
|
|
784
|
+
OK
|
|
785
|
+
```
|
|
786
|
+
|
|
787
|
+
Line by line: the number of lead-in pulses the loader saw before the
|
|
788
|
+
sync byte (the tape has been running since the KERNAL saw PLAY at
|
|
789
|
+
power-on, so the loader joins the lead-in part way through); the length
|
|
790
|
+
read from the tape; the loader's XOR of the block beside the checksum
|
|
791
|
+
byte from the tape; the CIA 2 cycle count from the end of the sync byte
|
|
792
|
+
to the end of the checksum byte, the 503 bytes of length, data and
|
|
793
|
+
checksum, and the bytes per second that count gives on the detected
|
|
794
|
+
model; and the shortest and longest pulse measured for a 0 and for a 1,
|
|
795
|
+
in cycles. `OK` and a green border mean `$02FF` holds `01`.
|
|
796
|
+
|
|
797
|
+
Measured on the windowless x64sc build of VICE 3.10 with the command
|
|
798
|
+
above (rung 1); two runs per model gave byte-identical screenshots, and
|
|
799
|
+
every character cell was decoded against the character ROM. The
|
|
800
|
+
pictures are `../../figures/tape-turbo-loader-pal.png` and
|
|
801
|
+
`../../figures/tape-turbo-loader-ntsc.png`. The NTSC picture reads
|
|
802
|
+
`LEADIN 9957`, `CYCLES 1540502 B/S 334 NTSC` and the same `BIT0 248-264
|
|
803
|
+
BIT1 506-520`: the TAP stores pulses in cycles, so the block costs the
|
|
804
|
+
same cycles on either model and the faster NTSC clock turns them into
|
|
805
|
+
more bytes per second. The 1,540,498 cycles the loader timed are 110
|
|
806
|
+
less than the 1,540,608 the script summed for the same span, which is
|
|
807
|
+
the poll's position inside the first and last pulse. The measured pulses
|
|
808
|
+
sit within 8 cycles of the 256 and 512 the file holds: that is the
|
|
809
|
+
polling loop's own granularity, `LDA`, `AND`, `BEQ`, nine cycles round.
|
|
810
|
+
|
|
811
|
+
With the four `-ds` options left out, so VICE's default tape speed
|
|
812
|
+
error and wobble apply, the PAL run read `LEADIN 10201`, `CYCLES
|
|
813
|
+
1547961 B/S 320`, `BIT0 231-283 BIT1 487-542` and still `OK`; NTSC gave
|
|
814
|
+
`CYCLES 1547864 B/S 332`, `BIT0 231-283 BIT1 490-539`. The spread grew
|
|
815
|
+
from 16 cycles to 52 on either bit and the block took 0.5 % longer. The
|
|
816
|
+
threshold of 384 had at least 101 cycles to spare on either side (101
|
|
817
|
+
below, 103 and 106 above), which is why the checksum survived; a real
|
|
818
|
+
Datasette's speed error is not measured here.
|
|
819
|
+
|
|
820
|
+
**Not pinned.** The listing gate assembles the source, but the
|
|
821
|
+
verifier's run cannot be pinned in `runs.json`: it formats a blank disk
|
|
822
|
+
and attaches nothing else, and this program needs the TAP on `-1`, the
|
|
823
|
+
`tapectrl 1` command file and `+dsresetwithcpu`. The pictures therefore
|
|
824
|
+
live under `docs/figures/` rather than `screenshots/`, and the command
|
|
825
|
+
above is the one that made them. A verifier run without the TAP leaves
|
|
826
|
+
the loader at its PLAY wait, so `--update` must not be run on this page:
|
|
827
|
+
the picture it would freeze shows nothing but that wait.
|
|
828
|
+
|
|
829
|
+
## Why this works
|
|
830
|
+
|
|
831
|
+
A Datasette turbo is a different stream from the KERNAL's, not a faster
|
|
832
|
+
reading of it. The KERNAL writes a bit as a pair of pulses drawn from
|
|
833
|
+
three lengths, twenty pulses to a byte and every block twice; this
|
|
834
|
+
stream has one pulse per bit and two lengths, eight pulses to a byte and
|
|
835
|
+
one copy. The C64 sees each pulse as one falling edge on the cassette
|
|
836
|
+
read line, which is wired to CIA 1's FLAG input, so `read_pulse` waits
|
|
837
|
+
for bit 4 of `$DC0D` and then reads Timer B, which was started once with
|
|
838
|
+
`$11` in `$DC0F` and runs down from `$FFFF` continuously. The length of
|
|
839
|
+
a pulse is the previous reading less this one, in cycles, with no timer
|
|
840
|
+
restart and nothing lost between pulses. Reading the timer takes two
|
|
841
|
+
instructions, and the low byte can wrap between them, so the high byte
|
|
842
|
+
is read again and both bytes taken afresh if it moved; a first version
|
|
843
|
+
that only re-read when the low byte was `$FF` mismeasured one pulse in
|
|
844
|
+
about sixty by 256 cycles, because the two reads are seven cycles apart
|
|
845
|
+
and any wrap inside that window is missed. `read_bit` compares the
|
|
846
|
+
16-bit length against 384 and returns the bit in the carry.
|
|
847
|
+
|
|
848
|
+
The sync scheme is what lets the loader start anywhere. The lead-in is
|
|
849
|
+
all 1 bits, so a run of sixty-four of them proves the loader is inside
|
|
850
|
+
it, and the first 0 after that run is, by construction, bit 7 of `$5A`.
|
|
851
|
+
Seven more bits are rotated in behind it; if the byte is not `$5A` the
|
|
852
|
+
count starts again. Because the tape has been running since the
|
|
853
|
+
KERNAL's interrupt saw PLAY at power-on, the loader joins the lead-in
|
|
854
|
+
late and the count printed is what was left. Everything after the sync
|
|
855
|
+
byte is plain: two length bytes, the block into `BUF`, one checksum.
|
|
856
|
+
The loader runs with interrupts off and CIA 1's interrupt sources
|
|
857
|
+
masked (`$7F` to `$DC0D`, then a read to clear what was pending),
|
|
858
|
+
because reading `$DC0D` clears every bit in it, and a KERNAL interrupt
|
|
859
|
+
that read it first would steal FLAG edges; the KERNAL's own tape code
|
|
860
|
+
uses the same register and is left out for the same reason. Timer A's
|
|
861
|
+
interrupt is re-enabled afterwards so the KERNAL's clock and keyboard
|
|
862
|
+
scan resume.
|
|
863
|
+
|
|
864
|
+
The 256-cycle 0 pulse is not arbitrary. An earlier build of this recipe
|
|
865
|
+
used 208 and 416 cycles with the threshold at 312, and its checksum
|
|
866
|
+
came out `C0` against the tape's `40`: the first data byte read `83`
|
|
867
|
+
for `03`, a 0 read as 376 cycles. The loader had spent about 170
|
|
868
|
+
cycles between the last length bit and the first data bit resetting its
|
|
869
|
+
statistics and starting the stopwatch, so it polled that edge late, and
|
|
870
|
+
its per-bit path (the poll, the double timer read, the subtraction, the
|
|
871
|
+
compare and the minimum and maximum bookkeeping) is about 175 cycles,
|
|
872
|
+
which leaves a 208-cycle pulse no room to absorb the debt. Moving the
|
|
873
|
+
setup ahead of the length bytes and widening the pulses to 256 and 512
|
|
874
|
+
cured it. A loader without the statistics can run shorter pulses; how
|
|
875
|
+
short, on this build, is not measured here.
|