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,572 @@
|
|
|
1
|
+
---
|
|
2
|
+
recipe: object-pool
|
|
3
|
+
toolchain: oscar64
|
|
4
|
+
output_format: PRG
|
|
5
|
+
region: both
|
|
6
|
+
techniques: [object_pool]
|
|
7
|
+
file_formats: [PRG]
|
|
8
|
+
uses_registers: [DC04, DC05, DC0E, D011, D020, D021]
|
|
9
|
+
uses_kernal: []
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
<!-- doc-type: recipe -->
|
|
13
|
+
|
|
14
|
+
# Oscar64 object pool: scan allocator, wave table and per-frame tick, with a self-check
|
|
15
|
+
|
|
16
|
+
## Synopsis
|
|
17
|
+
|
|
18
|
+
A pool of eight game objects held as parallel arrays, allocated by
|
|
19
|
+
scanning for state 0, filled from a five-byte-per-entry wave table,
|
|
20
|
+
ticked once a frame (move, off-screen test, countdown timer) and freed by
|
|
21
|
+
writing state 0. The program runs a scripted scenario on the 6510:
|
|
22
|
+
sixteen spawns into eight slots, three despawns and three respawns that
|
|
23
|
+
must land in the freed slots, a hit that expires by timer, an object that
|
|
24
|
+
leaves the screen. It folds the final slot table into a checksum that
|
|
25
|
+
must match the value computed in Python and compiled in, prints PASS or
|
|
26
|
+
FAIL, and prints the cycle cost of the allocator (best, middle and full
|
|
27
|
+
cases), a free-list pop and push, the update pass with eight and with no
|
|
28
|
+
active slots, and a spawn, all timed with CIA1 timer A. It implements `object_pool` (`techniques/logic.md`); the pattern is
|
|
29
|
+
described under "Object pool" in `../../game-design/game-design-patterns.md`.
|
|
30
|
+
|
|
31
|
+
## Source
|
|
32
|
+
|
|
33
|
+
```c
|
|
34
|
+
// object-pool.c
|
|
35
|
+
// A fixed pool of MAX_OBJ game objects held as parallel arrays. Slots are
|
|
36
|
+
// allocated by scanning for state 0, filled from a wave table, ticked once
|
|
37
|
+
// per frame (movement, off-screen check, countdown timer) and freed by
|
|
38
|
+
// writing state 0. The program runs a scripted scenario on the 6510, folds
|
|
39
|
+
// the final slot bytes into a checksum that must match the value computed
|
|
40
|
+
// in Python and compiled in below, and times the allocator and the update
|
|
41
|
+
// pass with CIA1 timer A.
|
|
42
|
+
#include <c64/vic.h>
|
|
43
|
+
#include <c64/cia.h>
|
|
44
|
+
|
|
45
|
+
#define SCREEN ((char *)0x0400)
|
|
46
|
+
#define COLOUR ((char *)0xd800)
|
|
47
|
+
|
|
48
|
+
#define MAX_OBJ 8
|
|
49
|
+
#define NO_SLOT 0xff
|
|
50
|
+
#define OFF_BOTTOM 250 // y at or past this is below the visible window
|
|
51
|
+
|
|
52
|
+
#define OBJ_FREE 0
|
|
53
|
+
#define OBJ_ALIVE 1
|
|
54
|
+
#define OBJ_DYING 2
|
|
55
|
+
|
|
56
|
+
#define EXPECT_CHK 0x0A95 // Python fold over the 48 final slot bytes
|
|
57
|
+
|
|
58
|
+
// The slot table: one byte per slot per attribute. Index = slot number.
|
|
59
|
+
char obj_state[MAX_OBJ]; // 0 = free, otherwise the object's state
|
|
60
|
+
char obj_type[MAX_OBJ]; // indexes the per-type tables below
|
|
61
|
+
char obj_x[MAX_OBJ];
|
|
62
|
+
char obj_y[MAX_OBJ];
|
|
63
|
+
char obj_dy[MAX_OBJ]; // signed pixels per frame
|
|
64
|
+
char obj_timer[MAX_OBJ]; // frames to live; 0 = no timer
|
|
65
|
+
|
|
66
|
+
// Per-type data.
|
|
67
|
+
static const char type_life[4] = { 0, 12, 12, 40 };
|
|
68
|
+
static const char type_dy[4] = { 0, 1, 1, 2 };
|
|
69
|
+
|
|
70
|
+
// Wave table: frame, type, x, y, count; a frame byte of $ff ends it.
|
|
71
|
+
// Entries are in frame order. count objects are placed 16 pixels apart.
|
|
72
|
+
static const char wave_table[] = {
|
|
73
|
+
0, 1, 24, 50, 8,
|
|
74
|
+
0, 2, 24, 60, 8,
|
|
75
|
+
1, 3, 100, 70, 3,
|
|
76
|
+
0xff };
|
|
77
|
+
static char wave_pos;
|
|
78
|
+
|
|
79
|
+
// Counters the scenario reads back.
|
|
80
|
+
char spawn_ok, spawn_refused, expired, went_off;
|
|
81
|
+
char spawn_log[16]; // slot taken by each successful spawn
|
|
82
|
+
char spawn_log_n;
|
|
83
|
+
|
|
84
|
+
// Find a free slot: the first slot whose state is 0.
|
|
85
|
+
__noinline char pool_alloc(void)
|
|
86
|
+
{
|
|
87
|
+
for (char i = 0; i < MAX_OBJ; i++)
|
|
88
|
+
if (obj_state[i] == OBJ_FREE)
|
|
89
|
+
return i;
|
|
90
|
+
return NO_SLOT;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Free-list alternative: a stack of free slot numbers.
|
|
94
|
+
char free_stack[MAX_OBJ];
|
|
95
|
+
char free_top;
|
|
96
|
+
|
|
97
|
+
__noinline char fl_alloc(void)
|
|
98
|
+
{
|
|
99
|
+
if (free_top == 0)
|
|
100
|
+
return NO_SLOT;
|
|
101
|
+
return free_stack[--free_top];
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
__noinline void fl_free(char slot)
|
|
105
|
+
{
|
|
106
|
+
free_stack[free_top++] = slot;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
__noinline char spawn(char type, char x, char y)
|
|
110
|
+
{
|
|
111
|
+
char s = pool_alloc();
|
|
112
|
+
if (s == NO_SLOT)
|
|
113
|
+
{
|
|
114
|
+
spawn_refused++;
|
|
115
|
+
return NO_SLOT;
|
|
116
|
+
}
|
|
117
|
+
obj_type[s] = type;
|
|
118
|
+
obj_x[s] = x;
|
|
119
|
+
obj_y[s] = y;
|
|
120
|
+
obj_dy[s] = type_dy[type];
|
|
121
|
+
obj_timer[s] = type_life[type];
|
|
122
|
+
obj_state[s] = OBJ_ALIVE;
|
|
123
|
+
spawn_ok++;
|
|
124
|
+
spawn_log[spawn_log_n++] = s;
|
|
125
|
+
return s;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
__noinline void despawn(char slot)
|
|
129
|
+
{
|
|
130
|
+
obj_state[slot] = OBJ_FREE;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// A hit starts the dying state: five frames of explosion, then the slot
|
|
134
|
+
// is freed by the timer.
|
|
135
|
+
static void hit(char slot)
|
|
136
|
+
{
|
|
137
|
+
obj_state[slot] = OBJ_DYING;
|
|
138
|
+
obj_timer[slot] = 5;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Spawn every wave entry due on this frame.
|
|
142
|
+
static void wave_step(char frame)
|
|
143
|
+
{
|
|
144
|
+
while (wave_table[wave_pos] == frame)
|
|
145
|
+
{
|
|
146
|
+
char type = wave_table[wave_pos + 1];
|
|
147
|
+
char x = wave_table[wave_pos + 2];
|
|
148
|
+
char y = wave_table[wave_pos + 3];
|
|
149
|
+
char count = wave_table[wave_pos + 4];
|
|
150
|
+
for (char k = 0; k < count; k++)
|
|
151
|
+
spawn(type, x + (k << 4), y);
|
|
152
|
+
wave_pos += 5;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// One frame for every active slot: move, drop what left the screen,
|
|
157
|
+
// count the timer down and free the slot when it reaches zero.
|
|
158
|
+
__noinline void update_all(void)
|
|
159
|
+
{
|
|
160
|
+
for (char i = 0; i < MAX_OBJ; i++)
|
|
161
|
+
{
|
|
162
|
+
if (obj_state[i] == OBJ_FREE)
|
|
163
|
+
continue;
|
|
164
|
+
char y = obj_y[i] + obj_dy[i];
|
|
165
|
+
obj_y[i] = y;
|
|
166
|
+
if (y >= OFF_BOTTOM)
|
|
167
|
+
{
|
|
168
|
+
obj_state[i] = OBJ_FREE;
|
|
169
|
+
went_off++;
|
|
170
|
+
}
|
|
171
|
+
else if (obj_timer[i] != 0 && --obj_timer[i] == 0)
|
|
172
|
+
{
|
|
173
|
+
obj_state[i] = OBJ_FREE;
|
|
174
|
+
expired++;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
static char frame;
|
|
180
|
+
|
|
181
|
+
static void game_frame(void)
|
|
182
|
+
{
|
|
183
|
+
wave_step(frame);
|
|
184
|
+
update_all();
|
|
185
|
+
frame++;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// ---- timing subjects -----------------------------------------------------
|
|
189
|
+
|
|
190
|
+
__noinline void nothing(void)
|
|
191
|
+
{
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
__noinline void fl_pop_push(void)
|
|
195
|
+
{
|
|
196
|
+
fl_free(fl_alloc());
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
__noinline void spawn_despawn(void)
|
|
200
|
+
{
|
|
201
|
+
despawn(spawn(1, 0, 0));
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// CIA1 timer A: force-load $FFFF, count phi2 while fn runs 100 times, read.
|
|
205
|
+
// 100 and not 256: eight active slots for 256 calls would pass 65,535
|
|
206
|
+
// cycles and the 16-bit timer would wrap (it did, in the first build).
|
|
207
|
+
static unsigned time_loop(void (*fn)(void))
|
|
208
|
+
{
|
|
209
|
+
cia1.cra = 0x00;
|
|
210
|
+
cia1.ta = 0xffff;
|
|
211
|
+
cia1.cra = 0x11;
|
|
212
|
+
char i = 100;
|
|
213
|
+
do
|
|
214
|
+
{
|
|
215
|
+
fn();
|
|
216
|
+
} while (--i);
|
|
217
|
+
cia1.cra = 0x00;
|
|
218
|
+
return 0xffff - cia1.ta;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// pool_alloc through a void(*)(void) pointer: the result is discarded.
|
|
222
|
+
volatile char sink;
|
|
223
|
+
__noinline void alloc_call(void)
|
|
224
|
+
{
|
|
225
|
+
sink = pool_alloc();
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// ---- screen --------------------------------------------------------------
|
|
229
|
+
|
|
230
|
+
static void put_str(char row, char col, const char *s)
|
|
231
|
+
{
|
|
232
|
+
char *p = SCREEN + 40 * row + col;
|
|
233
|
+
while (*s)
|
|
234
|
+
{
|
|
235
|
+
char c = *s++;
|
|
236
|
+
*p++ = (c >= 'a' && c <= 'z') ? c - 'a' + 1 : c;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
static void put_dec(char row, char col, unsigned v, char width)
|
|
241
|
+
{
|
|
242
|
+
char *p = SCREEN + 40 * row + col + width;
|
|
243
|
+
do
|
|
244
|
+
{
|
|
245
|
+
*--p = '0' + v % 10;
|
|
246
|
+
v /= 10;
|
|
247
|
+
} while (--width);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
static const char hex_glyph[16] = {
|
|
251
|
+
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 1, 2, 3, 4, 5, 6 };
|
|
252
|
+
|
|
253
|
+
static void put_hex16(char row, char col, unsigned v)
|
|
254
|
+
{
|
|
255
|
+
char *p = SCREEN + 40 * row + col;
|
|
256
|
+
p[0] = hex_glyph[(v >> 12) & 15];
|
|
257
|
+
p[1] = hex_glyph[(v >> 8) & 15];
|
|
258
|
+
p[2] = hex_glyph[(v >> 4) & 15];
|
|
259
|
+
p[3] = hex_glyph[v & 15];
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Net cycles per call to two decimals: (t - t0) / 100 calls.
|
|
263
|
+
static void put_per_call(char row, char col, unsigned t, unsigned t0)
|
|
264
|
+
{
|
|
265
|
+
unsigned n = t - t0; // hundredths of a cycle per call
|
|
266
|
+
put_dec(row, col, n / 100, 3);
|
|
267
|
+
SCREEN[40 * row + col + 3] = '.';
|
|
268
|
+
put_dec(row, col + 4, n % 100, 2);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
static unsigned fold(unsigned cs, unsigned v)
|
|
272
|
+
{
|
|
273
|
+
return (cs ^ v) * 5 + 1;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
static char count_active(void)
|
|
277
|
+
{
|
|
278
|
+
char n = 0;
|
|
279
|
+
for (char i = 0; i < MAX_OBJ; i++)
|
|
280
|
+
if (obj_state[i] != OBJ_FREE)
|
|
281
|
+
n++;
|
|
282
|
+
return n;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
int main(void)
|
|
286
|
+
{
|
|
287
|
+
for (unsigned i = 0; i < 1000; i++)
|
|
288
|
+
{
|
|
289
|
+
SCREEN[i] = 0x20;
|
|
290
|
+
COLOUR[i] = VCOL_WHITE;
|
|
291
|
+
}
|
|
292
|
+
vic.color_back = VCOL_BLACK;
|
|
293
|
+
vic.color_border = VCOL_BLACK;
|
|
294
|
+
|
|
295
|
+
put_str(0, 0, "object pool 8 slots scan alloc");
|
|
296
|
+
|
|
297
|
+
// Frame 0: the wave table asks for 16 objects; 8 fit.
|
|
298
|
+
game_frame();
|
|
299
|
+
char ok0 = spawn_ok, ref0 = spawn_refused;
|
|
300
|
+
put_str(1, 0, "spawn 16 ok refused");
|
|
301
|
+
put_dec(1, 14, ok0, 2);
|
|
302
|
+
put_dec(1, 27, ref0, 2);
|
|
303
|
+
|
|
304
|
+
// The player shoots slots 1, 4 and 6; frame 1's wave entry refills them.
|
|
305
|
+
despawn(1);
|
|
306
|
+
despawn(4);
|
|
307
|
+
despawn(6);
|
|
308
|
+
game_frame();
|
|
309
|
+
put_str(2, 0, "despawn 1 4 6 respawn 3 ->");
|
|
310
|
+
put_dec(2, 29, spawn_log[8], 1);
|
|
311
|
+
put_dec(2, 31, spawn_log[9], 1);
|
|
312
|
+
put_dec(2, 33, spawn_log[10], 1);
|
|
313
|
+
|
|
314
|
+
// Slot 3 is hit: five dying frames, then the timer frees it.
|
|
315
|
+
hit(3);
|
|
316
|
+
for (char f = 0; f < 5; f++)
|
|
317
|
+
game_frame();
|
|
318
|
+
char exp1 = expired, act1 = count_active();
|
|
319
|
+
put_str(3, 0, "hit slot 3 expired active");
|
|
320
|
+
put_dec(3, 20, exp1, 1);
|
|
321
|
+
put_dec(3, 30, act1, 2);
|
|
322
|
+
|
|
323
|
+
// A new object just above the bottom edge leaves the screen next frame.
|
|
324
|
+
char s_off = spawn(1, 0, OFF_BOTTOM - 1);
|
|
325
|
+
game_frame();
|
|
326
|
+
char off1 = went_off, act2 = count_active();
|
|
327
|
+
put_str(4, 0, "spawn y249 -> slot off active");
|
|
328
|
+
put_dec(4, 19, s_off, 1);
|
|
329
|
+
put_dec(4, 26, off1, 1);
|
|
330
|
+
put_dec(4, 36, act2, 2);
|
|
331
|
+
put_str(5, 0, "frame");
|
|
332
|
+
put_dec(5, 6, frame, 2);
|
|
333
|
+
|
|
334
|
+
// Checksum over every byte of the final slot table.
|
|
335
|
+
unsigned chk = 0;
|
|
336
|
+
for (char i = 0; i < MAX_OBJ; i++)
|
|
337
|
+
{
|
|
338
|
+
chk = fold(chk, obj_state[i]);
|
|
339
|
+
chk = fold(chk, obj_type[i]);
|
|
340
|
+
chk = fold(chk, obj_x[i]);
|
|
341
|
+
chk = fold(chk, obj_y[i]);
|
|
342
|
+
chk = fold(chk, obj_dy[i]);
|
|
343
|
+
chk = fold(chk, obj_timer[i]);
|
|
344
|
+
}
|
|
345
|
+
put_str(6, 0, "chk exp");
|
|
346
|
+
put_hex16(6, 4, chk);
|
|
347
|
+
put_hex16(6, 13, EXPECT_CHK);
|
|
348
|
+
|
|
349
|
+
bool pass = ok0 == 8 && ref0 == 8 &&
|
|
350
|
+
spawn_log[8] == 1 && spawn_log[9] == 4 && spawn_log[10] == 6 &&
|
|
351
|
+
exp1 == 1 && act1 == 7 && s_off == 3 && off1 == 1 &&
|
|
352
|
+
act2 == 7 && frame == 8 && chk == EXPECT_CHK;
|
|
353
|
+
|
|
354
|
+
// Cycle costs. Interrupts off and DEN off so nothing steals cycles.
|
|
355
|
+
__asm { sei }
|
|
356
|
+
vic.ctrl1 = 0x0b;
|
|
357
|
+
vic_waitFrame();
|
|
358
|
+
unsigned t0 = time_loop(nothing);
|
|
359
|
+
|
|
360
|
+
// Scan with slot 0 free (best case) and with every slot taken.
|
|
361
|
+
unsigned t_scan0 = time_loop(alloc_call); // slot 3 is free
|
|
362
|
+
obj_state[3] = OBJ_ALIVE;
|
|
363
|
+
unsigned t_full = time_loop(alloc_call); // refused, 8 compares
|
|
364
|
+
obj_state[0] = OBJ_FREE;
|
|
365
|
+
unsigned t_best = time_loop(alloc_call); // slot 0 free
|
|
366
|
+
|
|
367
|
+
// Free list: pop then push, one entry on the stack.
|
|
368
|
+
free_stack[0] = 0;
|
|
369
|
+
free_top = 1;
|
|
370
|
+
unsigned t_fl = time_loop(fl_pop_push);
|
|
371
|
+
|
|
372
|
+
// Update pass with 8 active slots that neither move nor expire, and
|
|
373
|
+
// with none active.
|
|
374
|
+
for (char i = 0; i < MAX_OBJ; i++)
|
|
375
|
+
{
|
|
376
|
+
obj_state[i] = OBJ_ALIVE;
|
|
377
|
+
obj_dy[i] = 0;
|
|
378
|
+
obj_y[i] = 100;
|
|
379
|
+
obj_timer[i] = 250;
|
|
380
|
+
}
|
|
381
|
+
unsigned t_it8 = time_loop(update_all);
|
|
382
|
+
for (char i = 0; i < MAX_OBJ; i++)
|
|
383
|
+
obj_state[i] = OBJ_FREE;
|
|
384
|
+
unsigned t_it0 = time_loop(update_all);
|
|
385
|
+
|
|
386
|
+
// Spawn into slot 0 then free it again.
|
|
387
|
+
unsigned t_sp = time_loop(spawn_despawn);
|
|
388
|
+
vic.ctrl1 = 0x1b;
|
|
389
|
+
|
|
390
|
+
put_str(8, 0, "cycles x100 total per call");
|
|
391
|
+
put_str(9, 0, "empty call");
|
|
392
|
+
put_dec(9, 21, t0, 5);
|
|
393
|
+
put_str(10, 0, "scan, slot 0 free");
|
|
394
|
+
put_dec(10, 21, t_best, 5);
|
|
395
|
+
put_per_call(10, 29, t_best, t0);
|
|
396
|
+
put_str(11, 0, "scan, slot 3 free");
|
|
397
|
+
put_dec(11, 21, t_scan0, 5);
|
|
398
|
+
put_per_call(11, 29, t_scan0, t0);
|
|
399
|
+
put_str(12, 0, "scan, pool full");
|
|
400
|
+
put_dec(12, 21, t_full, 5);
|
|
401
|
+
put_per_call(12, 29, t_full, t0);
|
|
402
|
+
put_str(13, 0, "free list pop+push");
|
|
403
|
+
put_dec(13, 21, t_fl, 5);
|
|
404
|
+
put_per_call(13, 29, t_fl, t0);
|
|
405
|
+
put_str(14, 0, "update, 8 active");
|
|
406
|
+
put_dec(14, 21, t_it8, 5);
|
|
407
|
+
put_per_call(14, 29, t_it8, t0);
|
|
408
|
+
put_str(15, 0, "update, 0 active");
|
|
409
|
+
put_dec(15, 21, t_it0, 5);
|
|
410
|
+
put_per_call(15, 29, t_it0, t0);
|
|
411
|
+
put_str(16, 0, "spawn+despawn");
|
|
412
|
+
put_dec(16, 21, t_sp, 5);
|
|
413
|
+
put_per_call(16, 29, t_sp, t0);
|
|
414
|
+
|
|
415
|
+
put_str(18, 0, pass ? "pass" : "fail");
|
|
416
|
+
vic.color_border = pass ? VCOL_GREEN : VCOL_RED;
|
|
417
|
+
for (;;)
|
|
418
|
+
;
|
|
419
|
+
return 0;
|
|
420
|
+
}
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
## Build
|
|
424
|
+
|
|
425
|
+
```
|
|
426
|
+
oscar64 -tm=c64 -O2 -o=object-pool.prg object-pool.c
|
|
427
|
+
GSETTINGS_SCHEMA_DIR=/opt/homebrew/share/glib-2.0/schemas timeout 180 x64sc -default -warp +sound +autostart-delay-random -autostartprgmode 1 -limitcycles 8000000 -exitscreenshot object-pool.png -autostart object-pool.prg
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
Add `-model ntsc` for the NTSC picture. 8,000,000 cycles is the pinned
|
|
431
|
+
run; the timed loops total about 108,000 cycles (the sum of the TOTAL
|
|
432
|
+
column) and the scenario is a few thousand more, so the screen is
|
|
433
|
+
complete long before the limit.
|
|
434
|
+
|
|
435
|
+
## Expected output
|
|
436
|
+
|
|
437
|
+
Black screen, green border. Decoded from `screenshots/object-pool.png`
|
|
438
|
+
(PAL) with the character ROM; rows 7, 17 and 19 to 24 are blank:
|
|
439
|
+
|
|
440
|
+
```
|
|
441
|
+
OBJECT POOL 8 SLOTS SCAN ALLOC
|
|
442
|
+
SPAWN 16 OK 08 REFUSED 08
|
|
443
|
+
DESPAWN 1 4 6 RESPAWN 3 -> 1 4 6
|
|
444
|
+
HIT SLOT 3 EXPIRED 1 ACTIVE 07
|
|
445
|
+
SPAWN Y249 -> SLOT 3 OFF 1 ACTIVE 07
|
|
446
|
+
FRAME 08
|
|
447
|
+
CHK 0A95 EXP 0A95
|
|
448
|
+
|
|
449
|
+
CYCLES X100 TOTAL PER CALL
|
|
450
|
+
EMPTY CALL 03709
|
|
451
|
+
SCAN, SLOT 0 FREE 06409 027.00
|
|
452
|
+
SCAN, SLOT 3 FREE 10109 064.00
|
|
453
|
+
SCAN, POOL FULL 16109 124.00
|
|
454
|
+
FREE LIST POP+PUSH 08109 044.00
|
|
455
|
+
UPDATE, 8 ACTIVE 41709 380.00
|
|
456
|
+
UPDATE, 0 ACTIVE 14309 106.00
|
|
457
|
+
SPAWN+DESPAWN 18309 146.00
|
|
458
|
+
|
|
459
|
+
PASS
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
`screenshots/object-pool-ntsc.png` (`-model ntsc`) has the same text in
|
|
463
|
+
every cell: the 320 by 200 ink mask of the two pictures compared equal
|
|
464
|
+
cell for cell, and both borders read green (measured in VICE x64sc 3.10).
|
|
465
|
+
Nothing in the program depends on the frame rate; the CIA counts phi2
|
|
466
|
+
cycles with the screen blanked, and the counts are identical on both
|
|
467
|
+
models.
|
|
468
|
+
|
|
469
|
+
What each row states, and what the Python model gives for it:
|
|
470
|
+
|
|
471
|
+
- Row 1: frame 0's two wave entries ask for 16 objects; 8 are placed and
|
|
472
|
+
8 refused with `NO_SLOT`.
|
|
473
|
+
- Row 2: slots 1, 4 and 6 are freed; frame 1's entry spawns 3, and the
|
|
474
|
+
scan hands out exactly 1, 4 and 6, in that order.
|
|
475
|
+
- Row 3: slot 3 is hit (state 2, timer 5); after five frames the timer
|
|
476
|
+
frees it, the only expiry so far, leaving 7 active.
|
|
477
|
+
- Row 4: a spawn at y 249 takes slot 3, the lowest free; the next tick
|
|
478
|
+
moves it to 250 and the off-screen test frees it, so 7 are active again.
|
|
479
|
+
- Row 5: eight frames ran.
|
|
480
|
+
- Row 6: the fold over the 48 bytes of the six arrays is $0A95 on the 6510
|
|
481
|
+
and in Python.
|
|
482
|
+
- Rows 9 to 16: CIA1 timer A over 100 calls, total and net per call. The
|
|
483
|
+
per-call column subtracts the empty-call row and divides by 100.
|
|
484
|
+
|
|
485
|
+
The Python side of the scenario:
|
|
486
|
+
|
|
487
|
+
```python
|
|
488
|
+
life = {0: 0, 1: 12, 2: 12, 3: 40}
|
|
489
|
+
dyt = {0: 0, 1: 1, 2: 1, 3: 2}
|
|
490
|
+
st, ty, x, y, dy, tm = ([0] * 8 for _ in range(6))
|
|
491
|
+
wave = [(0, 1, 24, 50, 8), (0, 2, 24, 60, 8), (1, 3, 100, 70, 3)]
|
|
492
|
+
log, frame = [], 0
|
|
493
|
+
|
|
494
|
+
def spawn(t, xx, yy):
|
|
495
|
+
for s in range(8):
|
|
496
|
+
if st[s] == 0:
|
|
497
|
+
ty[s], x[s], y[s], dy[s], tm[s], st[s] = t, xx & 255, yy, dyt[t], life[t], 1
|
|
498
|
+
log.append(s)
|
|
499
|
+
return s
|
|
500
|
+
return None
|
|
501
|
+
|
|
502
|
+
def game_frame():
|
|
503
|
+
global frame
|
|
504
|
+
for f, t, xx, yy, c in wave:
|
|
505
|
+
if f == frame:
|
|
506
|
+
for k in range(c):
|
|
507
|
+
spawn(t, xx + (k << 4), yy)
|
|
508
|
+
for i in range(8):
|
|
509
|
+
if st[i] == 0:
|
|
510
|
+
continue
|
|
511
|
+
y[i] = (y[i] + dy[i]) & 255
|
|
512
|
+
if y[i] >= 250:
|
|
513
|
+
st[i] = 0
|
|
514
|
+
elif tm[i] != 0:
|
|
515
|
+
tm[i] -= 1
|
|
516
|
+
if tm[i] == 0:
|
|
517
|
+
st[i] = 0
|
|
518
|
+
frame += 1
|
|
519
|
+
|
|
520
|
+
game_frame() # 16 asked, 8 placed
|
|
521
|
+
for s in (1, 4, 6):
|
|
522
|
+
st[s] = 0
|
|
523
|
+
game_frame() # log[8:11] == [1, 4, 6]
|
|
524
|
+
st[3], tm[3] = 2, 5
|
|
525
|
+
for _ in range(5):
|
|
526
|
+
game_frame() # slot 3 expires on the fifth
|
|
527
|
+
spawn(1, 0, 249) # takes slot 3
|
|
528
|
+
game_frame() # slot 3 leaves the screen
|
|
529
|
+
|
|
530
|
+
def fold(c, v):
|
|
531
|
+
return ((c ^ v) * 5 + 1) & 0xFFFF
|
|
532
|
+
|
|
533
|
+
chk = 0
|
|
534
|
+
for i in range(8):
|
|
535
|
+
for v in (st[i], ty[i], x[i], y[i], dy[i], tm[i]):
|
|
536
|
+
chk = fold(chk, v)
|
|
537
|
+
print(log[8:11], frame, hex(chk)) # [1, 4, 6] 8 0xa95
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
## Why this works
|
|
541
|
+
|
|
542
|
+
The allocator is a linear scan and its cost says so: 27 cycles with slot
|
|
543
|
+
0 free, 64 with slot 3 the first free, 124 for a full pool, about 12
|
|
544
|
+
cycles per slot examined. The free-list pop and push pair at 44 is the
|
|
545
|
+
alternative when the pool is large; here its only advantage is the
|
|
546
|
+
constant cost, and it needs every free to go through `fl_free`. The
|
|
547
|
+
update pass costs 380 cycles for eight active slots and 106 for eight
|
|
548
|
+
free ones, so skipping a free slot is 13.25 cycles and ticking a live one
|
|
549
|
+
47.5. Oscar64 -O2 compiles `update_all` to one absolute-indexed loop and
|
|
550
|
+
folds the timer decrement into an `sbc #0` that borrows the clear carry
|
|
551
|
+
left by the off-screen compare.
|
|
552
|
+
|
|
553
|
+
The scenario checks the two properties a pool must have. The scan hands
|
|
554
|
+
out the lowest free slot, so the three respawns after freeing 1, 4 and 6
|
|
555
|
+
must land there in that order; and a slot is freed by exactly one write
|
|
556
|
+
of state 0, from whichever of the three paths (despawn, timer, off
|
|
557
|
+
screen) reaches it first. The checksum covers every byte of every array,
|
|
558
|
+
including the stale fields of the freed slot, so the Python model has to
|
|
559
|
+
reproduce the order of the tick's writes and not just the live objects.
|
|
560
|
+
|
|
561
|
+
Timing: `time_loop` stops CIA1 timer A, writes $FFFF to its latch,
|
|
562
|
+
force-loads and starts it counting phi2 (`cra = $11`), calls the subject
|
|
563
|
+
100 times through a pointer, stops the timer and reads it. The first
|
|
564
|
+
build called each subject 200 times and the eight-active update read
|
|
565
|
+
52.32 cycles per call: 200 calls at 380 cycles pass 65,535 and the 16-bit timer reloads from its latch and carries on,
|
|
566
|
+
so the reading was the count modulo 65,536. A per-call figure with a
|
|
567
|
+
fraction in it, from a loop whose body does the same work every time, is
|
|
568
|
+
the sign of that wrap. 100 calls keep the largest subject under 42,000.
|
|
569
|
+
`sei` and DEN off keep the KERNAL interrupt and badlines out of the count;
|
|
570
|
+
the subjects for the update pass have `dy` 0 and timers of 250 so that no
|
|
571
|
+
slot moves or expires during the 100 calls, and the scan subjects do not
|
|
572
|
+
write the table at all.
|