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,586 @@
|
|
|
1
|
+
<!-- doc-type: reference -->
|
|
2
|
+
|
|
3
|
+
# C64 Art Asset Pipelines
|
|
4
|
+
|
|
5
|
+
This document answers one narrow question: how does a file produced by an artist
|
|
6
|
+
or musician on a modern host — a Koala bitmap, a SpritePad sprite sheet, a CharPad
|
|
7
|
+
charset, a PETSCII screen, a GoatTracker song — become bytes that Oscar64 or
|
|
8
|
+
KickAssembler code can include at build time?
|
|
9
|
+
|
|
10
|
+
The artist side of the workflow is covered in `./art-production-reference.md`. The
|
|
11
|
+
music side is covered in `../music/music-production-reference.md`. The compression
|
|
12
|
+
and loading side is covered in `../techniques/loaders-packers.md`. The binary format
|
|
13
|
+
specifications are in `../formats/c64-file-formats.md`. This document sits between
|
|
14
|
+
those references and focuses purely on the conversion and integration step.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Format breakdown per asset type
|
|
19
|
+
|
|
20
|
+
### Koala bitmap (.kla)
|
|
21
|
+
|
|
22
|
+
Koala Painter's native format is a 10003-byte file laid out as follows:
|
|
23
|
+
|
|
24
|
+
| Offset | Size | Contents |
|
|
25
|
+
|--------|--------|----------------------------------------------|
|
|
26
|
+
| 0x0000 | 2 | Load address (`$6000`, little-endian) |
|
|
27
|
+
| 0x0002 | 8000 | Bitmap data (320×200, 2bpp multicolor) |
|
|
28
|
+
| 0x1F42 | 1000 | Screen RAM (color pair per 4×8 cell) |
|
|
29
|
+
| 0x232A | 1000 | Color RAM (third color per 4×8 cell) |
|
|
30
|
+
| 0x2712 | 1 | Background color register value |
|
|
31
|
+
|
|
32
|
+
The 2-byte load address is specific to Koala Painter's own load routine. Most C64
|
|
33
|
+
production pipelines discard it and place the three data regions independently:
|
|
34
|
+
|
|
35
|
+
- **Bitmap data (8000 bytes)** → typically at `$6000`, bank 1, VIC-visible
|
|
36
|
+
- **Screen RAM (1000 bytes)** → typically at `$5800` or `$0400`
|
|
37
|
+
- **Color RAM (1000 bytes)** → always at `$D800` (hardware-fixed)
|
|
38
|
+
- **Background byte (1 byte)** → written directly to `$D021` at runtime
|
|
39
|
+
|
|
40
|
+
For Oscar64, strip the 2-byte header and split the file into three `.bin` chunks
|
|
41
|
+
during the build. A Makefile recipe is shown in the worked examples below.
|
|
42
|
+
|
|
43
|
+
For KickAssembler, `.import binary` with an offset skips the header in-place:
|
|
44
|
+
|
|
45
|
+
```asm
|
|
46
|
+
* = $6000
|
|
47
|
+
.import binary "picture.kla", 2, 8000 ; bitmap, skip 2-byte header
|
|
48
|
+
* = $5800
|
|
49
|
+
.import binary "picture.kla", 8002, 1000 ; screen RAM
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The 1000-byte color RAM chunk must be copied to `$D800` at runtime because the
|
|
53
|
+
C64's color memory is not directly addressable for `incbin`-style placement. A
|
|
54
|
+
tight loop or `memcpy`-style routine handles this before the VIC is switched to
|
|
55
|
+
multicolor bitmap mode.
|
|
56
|
+
|
|
57
|
+
**Byte-order note.** The Koala format uses no multi-byte fields beyond the load
|
|
58
|
+
address — all data regions are plain bytes. There is no endianness issue beyond
|
|
59
|
+
the load address itself.
|
|
60
|
+
|
|
61
|
+
**Multicolor cell layout.** Each 8×8 cell in the bitmap uses 2 bits per pixel,
|
|
62
|
+
packed high-bit-first within each byte. Bit pairs `%00`, `%01`, `%10`, `%11` map
|
|
63
|
+
to background, screen-RAM high nybble, screen-RAM low nybble, and color-RAM values
|
|
64
|
+
respectively. An earlier version of this paragraph had the two screen-RAM nybbles
|
|
65
|
+
the other way round; decoding a png2prg Koala file against its source image gave
|
|
66
|
+
0 wrong pixels with this order and 16,000 of 32,000 with the old one, and VICE
|
|
67
|
+
showed the file pixel-exact (see [png2prg](../toolchains/png2prg.md), "Round trip,
|
|
68
|
+
measured"). The cell ordering is left-to-right, top-to-bottom in reading order.
|
|
69
|
+
A converter that re-packs pixels must replicate this cell-major layout or the
|
|
70
|
+
image will display with scrambled columns.
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
### Sprites (.spd from SpritePad)
|
|
75
|
+
|
|
76
|
+
SpritePad's native `.spd` format stores a header followed by 64-byte sprite blocks.
|
|
77
|
+
**Correction (2026-09-23).** The 9-byte table below is the version 1 layout, and its byte at `0x06` is the transparent colour, not a multicolour flag (the version 1 meaning is read from Oscar64's reader, not measured here: no version 1 file was found); the version 5 files SpritePad Pro writes and Oscar64 embeds have a 20-byte header with two-byte counts, decoded per version in `../formats/c64-file-formats.md` under `.SPD`.
|
|
78
|
+
SpritePad 2.x `.spd` files begin with a 9-byte header:
|
|
79
|
+
|
|
80
|
+
| Offset | Size | Contents |
|
|
81
|
+
|--------|------|-------------------------------------|
|
|
82
|
+
| 0x00 | 4 | Magic `"SPD"` + version byte |
|
|
83
|
+
| 0x04 | 1 | Number of sprites minus one |
|
|
84
|
+
| 0x05 | 1 | Number of animations minus one |
|
|
85
|
+
| 0x06 | 1 | Multicolor flag (0=hires, 1=multi) |
|
|
86
|
+
| 0x07 | 2 | Multicolor registers MC1, MC2 |
|
|
87
|
+
|
|
88
|
+
Each sprite immediately follows as a 64-byte block (63 bytes of pixel data + 1
|
|
89
|
+
byte containing the sprite color in the low nybble).
|
|
90
|
+
|
|
91
|
+
For production use, the typical path is:
|
|
92
|
+
|
|
93
|
+
1. Export from SpritePad as a raw binary (File → Export → Binary). SpritePad
|
|
94
|
+
writes only the 64-byte blocks with no header, suitable for direct `incbin`.
|
|
95
|
+
2. If multiplexer tables are needed (Y-sort order, pointer lookup), generate them
|
|
96
|
+
from a converter script at build time rather than by hand.
|
|
97
|
+
|
|
98
|
+
A sprite multiplexer expects a table of sprite data pointers. Each pointer is a
|
|
99
|
+
single byte giving the high byte of the sprite data address divided by 64 — the
|
|
100
|
+
value written to `$07F8`–`$07FF` (the VIC sprite data pointers at the default
|
|
101
|
+
screen location). For a contiguous 64-byte-aligned sprite bank starting at `$3000`:
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
sprite 0 data at $3000 → pointer byte = $3000 / 64 = $C0
|
|
105
|
+
sprite 1 data at $3040 → pointer byte = $C1
|
|
106
|
+
...
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
**Multicolor double-pixel padding.** In multicolor sprite mode, each pixel is 2
|
|
110
|
+
bits wide and displays as a double-width pixel — the physical sprite is 24 pixels
|
|
111
|
+
wide but displayed as 12 double-pixels. A converter tool porting hires art to
|
|
112
|
+
multicolor must halve the horizontal resolution. Direct incbin of a hires sprite
|
|
113
|
+
block into a multicolor slot produces the correct bit layout but the wrong visual —
|
|
114
|
+
no converter can recover lost horizontal detail, so multicolor sprites must be
|
|
115
|
+
authored at the correct reduced resolution.
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
### Charsets (.ctm from CharPad)
|
|
120
|
+
|
|
121
|
+
CharPad's native `.ctm` (CharPad Tilemap) format is a structured binary with a
|
|
122
|
+
32-byte header, followed by character data, attribute data, and optional tile/map
|
|
123
|
+
data. **Correction (2026-09-23).** No decoded file has a 32-byte header: version 5 has 20 bytes and version 8 has 14 (both decoded from files), and version 9 has 19 (read from Oscar64's reader, not measured here), followed by marker-framed sections whose presence depends on the flags and colouring method; the per-version field tables are in `../formats/c64-file-formats.md` under `.CTM`. Drawing the tile and map data it carries is `tile_map_render` in
|
|
124
|
+
`../techniques/scroll.md`; the Oscar64 `#embed ctm_*` specifiers are in
|
|
125
|
+
`../toolchains/oscar64-reference.md`. For a charset-only extraction (no tiles):
|
|
126
|
+
|
|
127
|
+
- **Character data:** 8 bytes per character × N characters. A full 256-char
|
|
128
|
+
charset is 2048 bytes.
|
|
129
|
+
- **Attribute data (CharPad 2.x):** 1 byte per character giving the character's
|
|
130
|
+
color and attribute flags.
|
|
131
|
+
|
|
132
|
+
For most production work, CharPad's File → Export paths emit simpler outputs:
|
|
133
|
+
|
|
134
|
+
- **Characters binary:** raw 8-byte character data, 2048 bytes for a full charset.
|
|
135
|
+
Load this at a VIC-visible address aligned to a 2KB boundary (e.g., `$2000`,
|
|
136
|
+
`$2800`, `$3000`, `$3800`) by setting `$D018` bits 1–3.
|
|
137
|
+
- **Screen binary:** 1000-byte screen map (character indices for the 40×25 display).
|
|
138
|
+
Load this into the VIC screen RAM region (`$0400` default, or another 1 KB
|
|
139
|
+
boundary within the active bank).
|
|
140
|
+
- **Color binary:** 1000-byte color map for the screen. Must be copied to `$D800`
|
|
141
|
+
at runtime, exactly as with Koala.
|
|
142
|
+
|
|
143
|
+
In Oscar64, these three exports become three `incbin` or `#pragma data` blocks.
|
|
144
|
+
KickAssembler places them with `.import binary` at the appropriate addresses.
|
|
145
|
+
|
|
146
|
+
**Alignment requirement.** The VIC-II reads character ROM or custom charset data
|
|
147
|
+
from addresses determined by `$D018` bits 1–3 (charset base) and bit 4 (screen
|
|
148
|
+
base). The charset must be aligned to a 2 KB boundary within the current VIC bank
|
|
149
|
+
(`$DD00` bits 0–1 select the bank). A charset placed at an odd address will
|
|
150
|
+
display as garbage — the alignment constraint must be enforced in the build script
|
|
151
|
+
or the linker config, not left to chance.
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
### PETSCII screens
|
|
156
|
+
|
|
157
|
+
A PETSCII screen consists of two 1000-byte arrays:
|
|
158
|
+
|
|
159
|
+
- **Screen RAM:** 40×25 bytes of character codes (PETSCII or screen codes,
|
|
160
|
+
depending on the editor). KoalaPad, Marq's PETSCII Editor, and PetMate use
|
|
161
|
+
screen codes (the VIC-II's native representation); terminal-mode PETSCII uses
|
|
162
|
+
a different code point mapping.
|
|
163
|
+
- **Color RAM:** 40×25 bytes of color nybbles (low 4 bits used, high 4 ignored).
|
|
164
|
+
|
|
165
|
+
For PetMate and Marq's editor, File → Export → Binary produces a 2000-byte file
|
|
166
|
+
(screen + color concatenated) or two separate 1000-byte files. Either layout is
|
|
167
|
+
suitable for `incbin`. The color half must be `memcpy`'d to `$D800` at runtime.
|
|
168
|
+
|
|
169
|
+
Most PETSCII editors export with load addresses prepended. Strip 2 bytes from each
|
|
170
|
+
chunk as with Koala. Some editors export in SEQ or PRG format — use `dd` or a
|
|
171
|
+
small Python script to extract just the payload bytes.
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
### Music: GoatTracker (.sng) → usable output
|
|
176
|
+
|
|
177
|
+
GoatTracker 2 is the most common cross-platform tracker for SID music in a
|
|
178
|
+
build pipeline. Its native format is `.sng`, a binary song file; the field
|
|
179
|
+
table is in `../formats/c64-file-formats.md` under `.SNG`. The tracker does not
|
|
180
|
+
export source code. Its one export is the packer/relocator, reached with F9 in
|
|
181
|
+
the editor or as the standalone `gt2reloc` utility, and it writes one of three
|
|
182
|
+
things, chosen by the extension of the output file name:
|
|
183
|
+
|
|
184
|
+
| Extension | Contents |
|
|
185
|
+
|-----------|----------|
|
|
186
|
+
| `.prg` | two-byte load address, then the player code and the packed song data |
|
|
187
|
+
| `.bin` | the same bytes without the load address |
|
|
188
|
+
| `.sid` | a PSID v2 header (`$7C` bytes), then the `.prg` bytes |
|
|
189
|
+
|
|
190
|
+
**Option A: Standalone `.prg` with embedded player.**
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
gt2reloc song.sng music.prg -W10 -ZFC
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
`-Wxx` is the player address high byte in hex (default `10`, so `$1000`) and
|
|
197
|
+
`-Zxx` the first of the two zero-page bytes the player uses (default `$FC`).
|
|
198
|
+
There is no positional address argument. The other options that matter in a
|
|
199
|
+
game build are `-B1` buffered SID writes, `-D1` sound-effect support, `-E1`
|
|
200
|
+
volume-change support, `-H1` store the author string at `base+$20`, `-N` NTSC
|
|
201
|
+
timing and `-Sx` the speed multiplier; `gt2reloc -?` lists them all. The
|
|
202
|
+
relocator drops unused patterns, instruments, table rows and player code, so
|
|
203
|
+
the output size depends on the song. Measured with `gt2reloc` built from the
|
|
204
|
+
GoatTracker 2.77 source (its banner says v2.73): the distribution's
|
|
205
|
+
`consultant.sng` gives 1,786 bytes at `$1000` (1,119 of them player) and a
|
|
206
|
+
1,788-byte `.prg`; `dojo.sng` gives 2,655 bytes.
|
|
207
|
+
|
|
208
|
+
The player's jump table is at the start of the output: `JSR base` with the
|
|
209
|
+
subtune number in A (from 0) initialises, `JSR base+3` plays one frame. A third
|
|
210
|
+
entry at `base+6` exists only when `-D1` or `-E1` compiled it in (sound effect,
|
|
211
|
+
or volume; with both, volume is at `base+9`). There is no stop entry. The full
|
|
212
|
+
call contract, zero-page use and ghost-register copy loop are in the
|
|
213
|
+
`goattracker_player_api` entry of the SID techniques page under
|
|
214
|
+
`../techniques/`.
|
|
215
|
+
|
|
216
|
+
**Option B: Inline in a KickAssembler build.** Write a `.bin` (or `.prg`) and
|
|
217
|
+
import it at the address it was relocated for:
|
|
218
|
+
|
|
219
|
+
```text
|
|
220
|
+
.pc = $1000 "music"
|
|
221
|
+
.import binary "music.bin" ; relocated with -W10
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
or write a `.sid` and let KickAssembler read the header:
|
|
225
|
+
|
|
226
|
+
```text
|
|
227
|
+
.var music = LoadSid("music.sid")
|
|
228
|
+
.pc = music.location "music"
|
|
229
|
+
.fill music.size, music.getData(i)
|
|
230
|
+
// music.init and music.play hold the entry addresses
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
Both fragments were assembled with KickAssembler 5.25 against `dojo.sng`
|
|
234
|
+
relocated to `$1000`; each produced a file byte-identical to the relocator's
|
|
235
|
+
own `.prg`. For Oscar64 the `.bin` goes in through `#embed` into an array
|
|
236
|
+
placed at the relocation address (see "Oscar64 native data inclusion" below),
|
|
237
|
+
or the `.prg` is loaded as a separate file and called through a function
|
|
238
|
+
pointer.
|
|
239
|
+
|
|
240
|
+
**Correction (2026-09-23).** An earlier version of this section named a
|
|
241
|
+
`gt2asm` converter that emits a `.asm`/`.inc` file with the song as labelled
|
|
242
|
+
tables. No such utility exists: the GoatTracker 2.77 distribution ships
|
|
243
|
+
`goattrk2` (the editor), `gt2reloc` (the packer/relocator), `ins2snd2`
|
|
244
|
+
(instrument to sound-effect data), `sngspli2` (pattern splitter) and `mod2sng`
|
|
245
|
+
(MOD import), and its makefile builds nothing else. The same text gave
|
|
246
|
+
`gt2reloc` a `-f` flag and a positional `$1000` argument, which it does not
|
|
247
|
+
accept, and a `stop` entry at `base+6`, which is the sound-effect or volume
|
|
248
|
+
entry when compiled in.
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
## Conversion toolchain
|
|
253
|
+
|
|
254
|
+
### Standalone tools
|
|
255
|
+
|
|
256
|
+
| Tool | Input | Output | Notes |
|
|
257
|
+
|------|-------|--------|-------|
|
|
258
|
+
| SpritePad 2.x | .spd | raw sprite binary, .asm includes | GUI; built-in export |
|
|
259
|
+
| CharPad 2.x | .ctm | charset binary, screen binary, color binary | GUI; built-in export |
|
|
260
|
+
| Koala Painter (PC port) | .kla | n/a | Use strip-header script instead |
|
|
261
|
+
| koala-tools (CLI) | .kla | .bin chunks, C headers | Python; strips header, splits regions |
|
|
262
|
+
| gt2reloc | .sng | .prg / .bin (player + data), .sid | GoatTracker 2 distribution; format chosen by output extension |
|
|
263
|
+
| ins2snd2 | .ins | sound-effect data as DASM-style source or binary (`-b`) | GoatTracker 2 distribution; an earlier row here named a `gt2asm` .sng-to-include converter, which does not exist |
|
|
264
|
+
| Exomizer 3 | any binary | .exo stream or .prg with depacker | Compression; see below |
|
|
265
|
+
| c1541 | .d64 | individual files | Commodore disk image tool |
|
|
266
|
+
| [png2prg](../toolchains/png2prg.md) 1.12 | .png (C64 palette, cell rules already met) | Koala, hires, charset, sprite .prg; optional self-running viewer | CLI; refuses colour clashes and a 17th colour instead of fixing them |
|
|
267
|
+
| [sidreloc](../toolchains/sidreloc.md) 1.0 | .sid | .sid moved by whole pages, zero page remapped | CLI; for tunes you have only as a `.sid`; checks its own output |
|
|
268
|
+
|
|
269
|
+
### Oscar64 native data inclusion
|
|
270
|
+
|
|
271
|
+
Oscar64's `#pragma data` and `__attribute__((aligned))` allow static byte arrays
|
|
272
|
+
to be placed at specific linker-controlled addresses. For small assets that do not
|
|
273
|
+
need to be VIC-bank-aligned, embedding data directly in the C source avoids an
|
|
274
|
+
extra conversion step:
|
|
275
|
+
|
|
276
|
+
```c
|
|
277
|
+
// Declares a byte array placed by the linker in the 'main' region.
|
|
278
|
+
// Address alignment must match VIC bank requirements if applicable.
|
|
279
|
+
__attribute__((section("charset"), aligned(0x800)))
|
|
280
|
+
static const unsigned char charset_data[] = {
|
|
281
|
+
#embed "charset_export.bin"
|
|
282
|
+
};
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
Oscar64 supports `#embed` (C23) for importing raw binary files at compile time.
|
|
286
|
+
This is suitable for assets under a few kilobytes. For larger assets or assets
|
|
287
|
+
that must be placed at hardware-constrained addresses, use a separate `.bin` with
|
|
288
|
+
the linker config or KickAssembler's `.import binary`.
|
|
289
|
+
|
|
290
|
+
### Custom Python/Node converter patterns
|
|
291
|
+
|
|
292
|
+
When the standard tool chain cannot produce the exact layout needed — address
|
|
293
|
+
remapping, palette quantization, table reordering — a short converter script is
|
|
294
|
+
the least-friction solution. The skeleton below handles the most common case:
|
|
295
|
+
strip a load-address header and split into named output chunks.
|
|
296
|
+
|
|
297
|
+
```python
|
|
298
|
+
#!/usr/bin/env python3
|
|
299
|
+
"""Strip a 2-byte load-address header and emit named chunks.
|
|
300
|
+
Usage: convert_koala.py picture.kla out/
|
|
301
|
+
"""
|
|
302
|
+
import sys
|
|
303
|
+
import pathlib
|
|
304
|
+
|
|
305
|
+
BITMAP_SIZE = 8000
|
|
306
|
+
SCREEN_SIZE = 1000
|
|
307
|
+
COLOR_SIZE = 1000
|
|
308
|
+
|
|
309
|
+
src = pathlib.Path(sys.argv[1]).read_bytes()
|
|
310
|
+
dest = pathlib.Path(sys.argv[2])
|
|
311
|
+
dest.mkdir(parents=True, exist_ok=True)
|
|
312
|
+
|
|
313
|
+
payload = src[2:] # strip 2-byte load address
|
|
314
|
+
offset = 0
|
|
315
|
+
|
|
316
|
+
(dest / "bitmap.bin").write_bytes(payload[offset : offset + BITMAP_SIZE])
|
|
317
|
+
offset += BITMAP_SIZE
|
|
318
|
+
|
|
319
|
+
(dest / "screen.bin").write_bytes(payload[offset : offset + SCREEN_SIZE])
|
|
320
|
+
offset += SCREEN_SIZE
|
|
321
|
+
|
|
322
|
+
(dest / "color.bin").write_bytes(payload[offset : offset + COLOR_SIZE])
|
|
323
|
+
offset += COLOR_SIZE
|
|
324
|
+
|
|
325
|
+
(dest / "bgcolor.bin").write_bytes(payload[offset : offset + 1])
|
|
326
|
+
print("Wrote bitmap, screen, color, bgcolor to", dest)
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
This pattern — read entire file, slice by known offsets, write named outputs —
|
|
330
|
+
applies to any format with a fixed layout. Extend it to emit a C header with
|
|
331
|
+
`__attribute__((section(...)))` declarations if the Oscar64 build benefits from
|
|
332
|
+
compile-time inclusion.
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
336
|
+
## Build-pipeline integration
|
|
337
|
+
|
|
338
|
+
### Makefile / build-script pattern
|
|
339
|
+
|
|
340
|
+
The canonical pattern for a C64 build with asset conversion is:
|
|
341
|
+
|
|
342
|
+
1. Artist commits source files (`.kla`, `.spd`, `.ctm`, `.sng`) to the repository.
|
|
343
|
+
2. A conversion step runs first, producing `.bin` / `.inc` artifacts in a build
|
|
344
|
+
output directory.
|
|
345
|
+
3. The compiler or assembler references those artifacts via `#embed`, `.import
|
|
346
|
+
binary`, or `incbin`.
|
|
347
|
+
4. The linker (Oscar64 integrated, or `ld65` for cc65) produces the final `.prg`.
|
|
348
|
+
|
|
349
|
+
This separation keeps source-controlled art in the artist's native format and the
|
|
350
|
+
build artifacts reproducible and disposable.
|
|
351
|
+
|
|
352
|
+
```makefile
|
|
353
|
+
BUILD := build
|
|
354
|
+
SRC_ART := art
|
|
355
|
+
SRC_MUS := music
|
|
356
|
+
OSCAR64 := oscar64
|
|
357
|
+
|
|
358
|
+
# Asset conversion outputs
|
|
359
|
+
$(BUILD)/bitmap.bin $(BUILD)/screen.bin $(BUILD)/color.bin $(BUILD)/bgcolor.bin: \
|
|
360
|
+
$(SRC_ART)/picture.kla | $(BUILD)
|
|
361
|
+
python3 tools/convert_koala.py $< $(BUILD)
|
|
362
|
+
|
|
363
|
+
$(BUILD)/music_player.prg: $(SRC_MUS)/song.sng | $(BUILD)
|
|
364
|
+
gt2reloc $< $@ -W10
|
|
365
|
+
|
|
366
|
+
# Final PRG
|
|
367
|
+
$(BUILD)/game.prg: src/main.c \
|
|
368
|
+
$(BUILD)/bitmap.bin $(BUILD)/screen.bin \
|
|
369
|
+
$(BUILD)/color.bin $(BUILD)/bgcolor.bin \
|
|
370
|
+
$(BUILD)/music_player.prg
|
|
371
|
+
$(OSCAR64) -n -O2 -tf=prg $< -o $@
|
|
372
|
+
|
|
373
|
+
$(BUILD):
|
|
374
|
+
mkdir -p $(BUILD)
|
|
375
|
+
|
|
376
|
+
clean:
|
|
377
|
+
rm -rf $(BUILD)
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
Make's dependency tracking ensures that a changed `.kla` triggers re-conversion
|
|
381
|
+
and recompilation automatically. For projects with many assets, a per-asset
|
|
382
|
+
conversion pattern rule (`$(BUILD)/%.bin: $(SRC_ART)/%.kla`) reduces boilerplate.
|
|
383
|
+
|
|
384
|
+
### Common pitfalls
|
|
385
|
+
|
|
386
|
+
**Byte-order surprises with multi-byte table entries.** Any time a converter emits
|
|
387
|
+
16-bit values (sprite pointer tables, PRG load addresses, tilemap indices), verify
|
|
388
|
+
endianness. The 6502 is little-endian; a script that emits `struct.pack('>H', v)`
|
|
389
|
+
(big-endian) will produce a reversed pointer table that causes subtle crashes.
|
|
390
|
+
Use `struct.pack('<H', v)` for all 16-bit and 32-bit fields in 6502-targeted data.
|
|
391
|
+
|
|
392
|
+
**Color-RAM endianness.** Color RAM at `$D800` holds one nybble per cell. The
|
|
393
|
+
nybble is in the low 4 bits of each byte; the upper 4 bits are undefined on read.
|
|
394
|
+
Some older tools export color data with the color in the high nybble. A color
|
|
395
|
+
display that appears uniformly wrong (all cells one color, or all black) is
|
|
396
|
+
usually a nybble-position bug: `AND #$0F` or shift the data appropriately in the
|
|
397
|
+
converter.
|
|
398
|
+
|
|
399
|
+
**Multicolor sprite double-pixel padding.** A multicolor sprite cell is 24 bits
|
|
400
|
+
wide but displayed as 12 double-pixels. If the source sprite was drawn at 24-pixel
|
|
401
|
+
hires resolution and then converted by bit-packing pairs, the result will look
|
|
402
|
+
compressed horizontally. Multicolor sprites must be drawn at 12-pixel effective
|
|
403
|
+
width, stored as the standard 64-byte block format, and imported without horizontal
|
|
404
|
+
scaling. Document this constraint in the art brief so artists author at the correct
|
|
405
|
+
resolution.
|
|
406
|
+
|
|
407
|
+
**VIC bank and charset alignment.** The VIC-II can only address 16 KB at a time
|
|
408
|
+
(bank 0: `$0000`–`$3FFF`, bank 1: `$4000`–`$7FFF`, bank 2: `$8000`–`$BFFF`,
|
|
409
|
+
bank 3: `$C000`–`$FFFF`). Within a bank, charset data must start at a 2 KB
|
|
410
|
+
boundary and bitmap data at an 8 KB boundary. A build that places a charset at
|
|
411
|
+
`$2100` instead of `$2000` due to a missing `ALIGN` directive in the linker config
|
|
412
|
+
will display character corruption that has no obvious cause at runtime.
|
|
413
|
+
|
|
414
|
+
### Compression: Exomizer integration
|
|
415
|
+
|
|
416
|
+
For productions where disk space or RAM footprint is a constraint, Exomizer 3 is
|
|
417
|
+
the standard compression pass. Exomizer accepts any raw binary or PRG and produces
|
|
418
|
+
either a self-extracting PRG or a raw compressed stream for use with a separate
|
|
419
|
+
depacker. See `../techniques/loaders-packers.md` for the full operational details.
|
|
420
|
+
|
|
421
|
+
The key trade-off in an asset pipeline is decrunch time versus disk size:
|
|
422
|
+
|
|
423
|
+
- A Koala bitmap (10001 payload bytes) compresses to roughly 6000–7500 bytes with
|
|
424
|
+
Exomizer, depending on the image content. Bitmaps with large solid areas compress
|
|
425
|
+
better; dithered bitmaps approach incompressibility.
|
|
426
|
+
- Decrunch time for a 6 KB stream on a stock 6510 at 1 MHz is approximately
|
|
427
|
+
0.3–0.5 seconds, imperceptible during a loading screen.
|
|
428
|
+
- A full sprite bank (e.g., 128 sprites × 64 bytes = 8192 bytes) typically
|
|
429
|
+
compresses to around 4000–6000 bytes. Sprite data with animation frames sharing
|
|
430
|
+
similar content compresses well.
|
|
431
|
+
|
|
432
|
+
Exomizer raw stream mode (`exomizer raw`) is used when the depacker is embedded in
|
|
433
|
+
the production code rather than prepended to the file:
|
|
434
|
+
|
|
435
|
+
```bash
|
|
436
|
+
exomizer raw -o bitmap.exo build/bitmap.bin
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
The depacker entry point and depacker code are linked into the production's PRG,
|
|
440
|
+
and the decompression call precedes the VIC switch-on. This avoids the overhead of
|
|
441
|
+
a separate self-extracting PRG layer when multiple assets are decompressed in
|
|
442
|
+
sequence.
|
|
443
|
+
|
|
444
|
+
---
|
|
445
|
+
|
|
446
|
+
## Worked examples
|
|
447
|
+
|
|
448
|
+
### Example 1: Koala bitmap → Oscar64 C header
|
|
449
|
+
|
|
450
|
+
This Makefile target converts a Koala file and produces a C header that Oscar64
|
|
451
|
+
can `#include`. The header declares `extern` arrays with section attributes that
|
|
452
|
+
the Oscar64 linker places at the correct VIC-visible addresses.
|
|
453
|
+
|
|
454
|
+
```makefile
|
|
455
|
+
# Makefile excerpt
|
|
456
|
+
$(BUILD)/koala.h: art/title.kla tools/koala_to_header.py | $(BUILD)
|
|
457
|
+
python3 tools/koala_to_header.py $< $@
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
```python
|
|
461
|
+
#!/usr/bin/env python3
|
|
462
|
+
"""koala_to_header.py — emit an Oscar64-compatible C header from a Koala .kla file."""
|
|
463
|
+
import sys, pathlib
|
|
464
|
+
|
|
465
|
+
BITMAP_ADDR = 0x6000
|
|
466
|
+
SCREEN_ADDR = 0x5800
|
|
467
|
+
src = pathlib.Path(sys.argv[1]).read_bytes()
|
|
468
|
+
out = pathlib.Path(sys.argv[2])
|
|
469
|
+
|
|
470
|
+
payload = src[2:] # strip load address
|
|
471
|
+
bitmap = list(payload[0:8000])
|
|
472
|
+
screen = list(payload[8000:9000])
|
|
473
|
+
color = list(payload[9000:10000])
|
|
474
|
+
bgcolor = payload[10000]
|
|
475
|
+
|
|
476
|
+
def array(name, section, align, data):
|
|
477
|
+
hex_vals = ", ".join(f"0x{b:02X}" for b in data)
|
|
478
|
+
return (
|
|
479
|
+
f'__attribute__((section("{section}"), aligned({align})))\n'
|
|
480
|
+
f"static const unsigned char {name}[] = {{{hex_vals}}};\n\n"
|
|
481
|
+
)
|
|
482
|
+
|
|
483
|
+
lines = ["#pragma once\n\n"]
|
|
484
|
+
lines.append(array("koala_bitmap", "bitmap", 0x2000, bitmap))
|
|
485
|
+
lines.append(array("koala_screen", "screen", 0x0400, screen))
|
|
486
|
+
lines.append(array("koala_color", "color", 0x0001, color))
|
|
487
|
+
lines.append(f"static const unsigned char koala_bgcolor = 0x{bgcolor:02X};\n")
|
|
488
|
+
out.write_text("".join(lines))
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
In the C source, `#include "koala.h"` makes the arrays available. The linker
|
|
492
|
+
places each at its declared section address. The runtime code copies `koala_color`
|
|
493
|
+
to `$D800`, writes `koala_bgcolor` to `$D021`, and enables multicolor bitmap mode
|
|
494
|
+
via `$D011`/`$D016`/`$D018`.
|
|
495
|
+
|
|
496
|
+
---
|
|
497
|
+
|
|
498
|
+
### Example 2: GoatTracker → KickAssembler import flow
|
|
499
|
+
|
|
500
|
+
```text
|
|
501
|
+
# 1. Pack and relocate the song to $1000 as a headerless binary
|
|
502
|
+
gt2reloc song.sng music.bin -W10
|
|
503
|
+
|
|
504
|
+
# 2. KickAssembler source fragment
|
|
505
|
+
.pc = $1000 "Music"
|
|
506
|
+
.import binary "music.bin"
|
|
507
|
+
|
|
508
|
+
# 3. In the IRQ handler (after stable raster setup):
|
|
509
|
+
# LDA #0 ; subtune number
|
|
510
|
+
# JSR $1000 ; init, once at startup
|
|
511
|
+
# JSR $1003 ; play, every frame from the IRQ
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
The relocator's output is player code followed by the packed song data, with
|
|
515
|
+
the jump table first: `init` at base and `play` at base+3. A third entry is
|
|
516
|
+
present only when the song was packed with sound-effect (`-D1`) or volume
|
|
517
|
+
(`-E1`) support. One `.import binary` brings in code and data together, so no
|
|
518
|
+
separate load step is needed; the block must sit at the address given to
|
|
519
|
+
`-W`, because the player is not position-independent. An earlier version of
|
|
520
|
+
this example ran a `gt2asm` converter and imported its output with
|
|
521
|
+
`.import source`; no such converter exists in the GoatTracker 2 distribution,
|
|
522
|
+
and the `stop` entry it described at base+6 is not in the player's jump table.
|
|
523
|
+
|
|
524
|
+
---
|
|
525
|
+
|
|
526
|
+
### Example 3: Sprite sheet converter skeleton
|
|
527
|
+
|
|
528
|
+
This skeleton reads a SpritePad raw binary export (64 bytes per sprite, no header)
|
|
529
|
+
and emits a C array plus a pointer table for an 8-sprite multiplexer. It produces
|
|
530
|
+
one `.h` file.
|
|
531
|
+
|
|
532
|
+
```python
|
|
533
|
+
#!/usr/bin/env python3
|
|
534
|
+
"""spd_to_header.py — SpritePad raw binary → Oscar64 sprite table header.
|
|
535
|
+
Usage: spd_to_header.py sprites.bin $3000 out/sprites.h
|
|
536
|
+
"""
|
|
537
|
+
import sys, pathlib, struct
|
|
538
|
+
|
|
539
|
+
SPRITE_BYTES = 64
|
|
540
|
+
src_path = pathlib.Path(sys.argv[1])
|
|
541
|
+
base_addr = int(sys.argv[2], 16)
|
|
542
|
+
out_path = pathlib.Path(sys.argv[3])
|
|
543
|
+
|
|
544
|
+
raw = src_path.read_bytes()
|
|
545
|
+
count = len(raw) // SPRITE_BYTES
|
|
546
|
+
|
|
547
|
+
sprites = [raw[i*SPRITE_BYTES:(i+1)*SPRITE_BYTES] for i in range(count)]
|
|
548
|
+
|
|
549
|
+
# VIC sprite pointer = (base_addr + i*64) / 64
|
|
550
|
+
pointers = [(base_addr // 64) + i for i in range(count)]
|
|
551
|
+
|
|
552
|
+
lines = ["#pragma once\n\n"]
|
|
553
|
+
lines.append(f"#define SPRITE_COUNT {count}\n\n")
|
|
554
|
+
|
|
555
|
+
hex_data = ", ".join(f"0x{b:02X}" for sprite in sprites for b in sprite)
|
|
556
|
+
lines.append(
|
|
557
|
+
f'__attribute__((section("sprites"), aligned(64)))\n'
|
|
558
|
+
f"static const unsigned char sprite_data[{count * SPRITE_BYTES}] = {{{hex_data}}};\n\n"
|
|
559
|
+
)
|
|
560
|
+
|
|
561
|
+
ptr_vals = ", ".join(str(p) for p in pointers)
|
|
562
|
+
lines.append(
|
|
563
|
+
f"static const unsigned char sprite_ptrs[{count}] = {{{ptr_vals}}};\n"
|
|
564
|
+
)
|
|
565
|
+
|
|
566
|
+
out_path.write_text("".join(lines))
|
|
567
|
+
print(f"Converted {count} sprites from {src_path.name}")
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
The alignment constraint `aligned(64)` ensures the Oscar64 linker places the sprite
|
|
571
|
+
bank at a 64-byte boundary, making the pointer arithmetic (`address / 64`) exact.
|
|
572
|
+
If the linker does not honor the 64-byte alignment (verify with the `.map` output),
|
|
573
|
+
add a dedicated linker segment with an explicit start address.
|
|
574
|
+
|
|
575
|
+
---
|
|
576
|
+
|
|
577
|
+
## Cross-references
|
|
578
|
+
|
|
579
|
+
- `./art-production-reference.md` — upstream: art tool workflows, canvas setup,
|
|
580
|
+
multicolor vs hires decisions, PETSCII editor workflows.
|
|
581
|
+
- `../music/music-production-reference.md` — upstream: GoatTracker composition,
|
|
582
|
+
SID voice routing, tracker export settings.
|
|
583
|
+
- `../techniques/loaders-packers.md` — compression (Exomizer, ByteBoozer, WCF)
|
|
584
|
+
and fast-loader integration for asset streaming.
|
|
585
|
+
- `../formats/c64-file-formats.md` — authoritative byte-level specifications for
|
|
586
|
+
`.prg`, `.d64`, and raw binary formats referenced here.
|