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,581 @@
|
|
|
1
|
+
---
|
|
2
|
+
recipe: divide-check
|
|
3
|
+
toolchain: oscar64
|
|
4
|
+
output_format: PRG
|
|
5
|
+
region: both
|
|
6
|
+
techniques: [division_8_16bit, decimal_print]
|
|
7
|
+
file_formats: [PRG]
|
|
8
|
+
uses_registers: [DC04, DC05, DC0E, D011, D012]
|
|
9
|
+
uses_kernal: []
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
<!-- doc-type: recipe -->
|
|
13
|
+
|
|
14
|
+
# Oscar64 Divide Check: shift-and-subtract division, checked and timed
|
|
15
|
+
|
|
16
|
+
## Synopsis
|
|
17
|
+
|
|
18
|
+
Three shift-and-subtract divide loops in `__asm`, 8/8, 16/8 and 16/16,
|
|
19
|
+
each giving quotient and remainder, plus two loop-free ways to divide a
|
|
20
|
+
byte by ten (a shift-add reciprocal and a 256-byte table). Every routine
|
|
21
|
+
is checked two ways in the same run: against Oscar64's own `/` and `%`
|
|
22
|
+
(a miss count) and against a 16-bit checksum Python computed. The 8/8
|
|
23
|
+
loop runs over every dividend and every non-zero divisor, the 16/8 loop
|
|
24
|
+
over every 16-bit dividend, the 16/16 loop over a sweep of 21,845 pairs.
|
|
25
|
+
A CIA1 timer A harness then prints the cycle cost of each route, and of
|
|
26
|
+
a five-digit decimal print done by repeated divide-by-ten beside the
|
|
27
|
+
subtract-powers print from `print-number.md`, so the screenshot settles
|
|
28
|
+
which to use. It implements `division_8_16bit` (`techniques/maths.md`)
|
|
29
|
+
and the comparison `decimal_print` (`techniques/text.md`) points at.
|
|
30
|
+
|
|
31
|
+
## Source
|
|
32
|
+
|
|
33
|
+
```c
|
|
34
|
+
// divide-check.c
|
|
35
|
+
// Shift-and-subtract division on the 6510: 8/8, 16/8 and 16/16, each an
|
|
36
|
+
// __asm loop, run over every 8-bit pair and a sweep of 16-bit values and
|
|
37
|
+
// checked two ways: against Oscar64's own / and % (a miss count) and
|
|
38
|
+
// against a 16-bit checksum Python computed. Divide by ten is then done
|
|
39
|
+
// four ways (general 16/8 divide, shift-add reciprocal, table lookup, and
|
|
40
|
+
// the subtract-powers digit route) and CIA1 timer A prints the cycle
|
|
41
|
+
// cost of every route.
|
|
42
|
+
#include <c64/vic.h>
|
|
43
|
+
#include <c64/cia.h>
|
|
44
|
+
|
|
45
|
+
#define SCREEN ((char *)0x0400)
|
|
46
|
+
|
|
47
|
+
// Expected checksums, computed by the same fold in Python (page text).
|
|
48
|
+
#define EXPECT_D8 0x7122 // 8/8: n = 0..255 outer, d = 1..255 inner, fold q then r
|
|
49
|
+
#define EXPECT_D16 0xBBC4 // 16/8: n = 0..65535, d = (n >> 8) + n, 0 -> 7, fold q lo, q hi, r
|
|
50
|
+
#define EXPECT_D32 0x6DA5 // 16/16: n = 0..65532 step 3, d = n * $9E37 + $1234, 0 -> 1, fold q lo, q hi, r lo, r hi
|
|
51
|
+
#define EXPECT_T10 0xAD4C // by ten: n = 0..255, shift-add then table, fold q, r each
|
|
52
|
+
#define EXPECT_DEC 0x3D19 // five digits by divide: n = 0..65530 step 5, fold the five codes
|
|
53
|
+
|
|
54
|
+
// Operands and results, absolute memory so the asm reads them by name.
|
|
55
|
+
// volatile: the asm writes them, and without it Oscar64 -O2 kept the
|
|
56
|
+
// dividend it had just stored and compared that against itself.
|
|
57
|
+
volatile char dvs8, rem8; // 8-bit divisor and remainder
|
|
58
|
+
volatile unsigned dvd; // dividend in, quotient out (8/8 uses the low byte)
|
|
59
|
+
volatile unsigned dvs16, rem16; // 16-bit divisor and remainder
|
|
60
|
+
volatile char q10, r10; // divide-by-ten results
|
|
61
|
+
|
|
62
|
+
// --- the routines under test ------------------------------------------------
|
|
63
|
+
|
|
64
|
+
// 8-bit dividend / 8-bit divisor. Quotient replaces the dividend in dvd,
|
|
65
|
+
// remainder in rem8. Eight passes; the partial remainder never exceeds
|
|
66
|
+
// 9 bits, and the carry out of rol rem8 is that ninth bit.
|
|
67
|
+
__noinline void div8(void)
|
|
68
|
+
{
|
|
69
|
+
__asm volatile
|
|
70
|
+
{
|
|
71
|
+
lda #0
|
|
72
|
+
sta rem8
|
|
73
|
+
ldx #8
|
|
74
|
+
l8: asl dvd
|
|
75
|
+
rol rem8
|
|
76
|
+
lda rem8
|
|
77
|
+
bcs s8
|
|
78
|
+
cmp dvs8
|
|
79
|
+
bcc n8
|
|
80
|
+
s8: sbc dvs8
|
|
81
|
+
sta rem8
|
|
82
|
+
inc dvd
|
|
83
|
+
n8: dex
|
|
84
|
+
bne l8
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// 16-bit dividend / 8-bit divisor. Quotient in dvd, remainder in rem8.
|
|
89
|
+
// Sixteen passes of the same body with a 16-bit shift.
|
|
90
|
+
__noinline void div16_8(void)
|
|
91
|
+
{
|
|
92
|
+
__asm volatile
|
|
93
|
+
{
|
|
94
|
+
lda #0
|
|
95
|
+
sta rem8
|
|
96
|
+
ldx #16
|
|
97
|
+
l16: asl dvd
|
|
98
|
+
rol dvd + 1
|
|
99
|
+
rol rem8
|
|
100
|
+
lda rem8
|
|
101
|
+
bcs s16
|
|
102
|
+
cmp dvs8
|
|
103
|
+
bcc n16
|
|
104
|
+
s16: sbc dvs8
|
|
105
|
+
sta rem8
|
|
106
|
+
inc dvd
|
|
107
|
+
n16: dex
|
|
108
|
+
bne l16
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// 16-bit dividend / 16-bit divisor. Quotient in dvd, remainder in rem16.
|
|
113
|
+
// The bcs after the second rol is kept for symmetry with div16_8; with
|
|
114
|
+
// equal widths the remainder cannot reach 17 bits (the sweep passes with
|
|
115
|
+
// it deleted; see pitfalls/maths.md, division_loop_missing_ninth_bit_guard).
|
|
116
|
+
__noinline void div16_16(void)
|
|
117
|
+
{
|
|
118
|
+
__asm volatile
|
|
119
|
+
{
|
|
120
|
+
lda #0
|
|
121
|
+
sta rem16
|
|
122
|
+
sta rem16 + 1
|
|
123
|
+
ldx #16
|
|
124
|
+
l32: asl dvd
|
|
125
|
+
rol dvd + 1
|
|
126
|
+
rol rem16
|
|
127
|
+
rol rem16 + 1
|
|
128
|
+
bcs s32
|
|
129
|
+
lda rem16 + 1
|
|
130
|
+
cmp dvs16 + 1
|
|
131
|
+
bcc n32
|
|
132
|
+
bne s32
|
|
133
|
+
lda rem16
|
|
134
|
+
cmp dvs16
|
|
135
|
+
bcc n32
|
|
136
|
+
s32: lda rem16
|
|
137
|
+
sbc dvs16
|
|
138
|
+
sta rem16
|
|
139
|
+
lda rem16 + 1
|
|
140
|
+
sbc dvs16 + 1
|
|
141
|
+
sta rem16 + 1
|
|
142
|
+
inc dvd
|
|
143
|
+
n32: dex
|
|
144
|
+
bne l32
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// 8-bit divide by ten with no loop: q = n * 0.1 approximated by shifts
|
|
149
|
+
// (1/2 + 1/4 = 0.75, then times 1 + 1/16 = 0.797, then /8 = 0.0996),
|
|
150
|
+
// remainder by subtracting q * 10, one fix-up when it lands at 10 or 11.
|
|
151
|
+
// Reads the low byte of dvd; results in q10 and r10.
|
|
152
|
+
__noinline void div10_8(void)
|
|
153
|
+
{
|
|
154
|
+
__asm volatile
|
|
155
|
+
{
|
|
156
|
+
lda dvd
|
|
157
|
+
lsr
|
|
158
|
+
sta q10 // n/2
|
|
159
|
+
lsr
|
|
160
|
+
clc
|
|
161
|
+
adc q10 // n/2 + n/4
|
|
162
|
+
sta q10
|
|
163
|
+
lsr
|
|
164
|
+
lsr
|
|
165
|
+
lsr
|
|
166
|
+
lsr
|
|
167
|
+
clc
|
|
168
|
+
adc q10 // q + q/16
|
|
169
|
+
lsr
|
|
170
|
+
lsr
|
|
171
|
+
lsr // /8
|
|
172
|
+
sta q10
|
|
173
|
+
asl
|
|
174
|
+
asl
|
|
175
|
+
adc q10 // q * 5 (carry clear after the shifts, q < 32)
|
|
176
|
+
asl // q * 10
|
|
177
|
+
sta r10
|
|
178
|
+
lda dvd
|
|
179
|
+
sec
|
|
180
|
+
sbc r10 // r = n - q * 10, 0..11
|
|
181
|
+
cmp #10
|
|
182
|
+
bcc d10
|
|
183
|
+
sbc #10
|
|
184
|
+
inc q10
|
|
185
|
+
d10: sta r10
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// 8-bit divide by ten by lookup: two 256-byte tables, built at start.
|
|
190
|
+
char tq10[256], tr10[256];
|
|
191
|
+
__noinline void div10_tab(void)
|
|
192
|
+
{
|
|
193
|
+
__asm volatile
|
|
194
|
+
{
|
|
195
|
+
ldx dvd
|
|
196
|
+
lda tq10, x
|
|
197
|
+
sta q10
|
|
198
|
+
lda tr10, x
|
|
199
|
+
sta r10
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// 16-bit to five screen codes by repeated divide by ten (div16_8 with
|
|
204
|
+
// divisor 10), units digit first.
|
|
205
|
+
__noinline void fmt_dec_div(unsigned v, char *dst)
|
|
206
|
+
{
|
|
207
|
+
dvd = v; dvs8 = 10;
|
|
208
|
+
for (char i = 4; i > 0; i--)
|
|
209
|
+
{
|
|
210
|
+
div16_8();
|
|
211
|
+
dst[i] = 0x30 + rem8;
|
|
212
|
+
}
|
|
213
|
+
dst[0] = 0x30 + (char)dvd;
|
|
214
|
+
char lead = 1;
|
|
215
|
+
for (char i = 0; i < 4; i++)
|
|
216
|
+
if (dst[i] == 0x30 && lead) dst[i] = 0x20; else lead = 0;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// The subtract-powers route from print-number.md, for comparison.
|
|
220
|
+
__noinline void fmt_dec_sub(unsigned v, char *dst)
|
|
221
|
+
{
|
|
222
|
+
static const unsigned pow10[4] = { 10000, 1000, 100, 10 };
|
|
223
|
+
char lead = 1;
|
|
224
|
+
for (char i = 0; i < 4; i++)
|
|
225
|
+
{
|
|
226
|
+
unsigned p = pow10[i];
|
|
227
|
+
char d = 0x30;
|
|
228
|
+
while (v >= p) { v -= p; d++; }
|
|
229
|
+
if (d != 0x30 || !lead) { dst[i] = d; lead = 0; }
|
|
230
|
+
else dst[i] = 0x20;
|
|
231
|
+
}
|
|
232
|
+
dst[4] = 0x30 + v;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
__noinline void null_call(void)
|
|
236
|
+
{
|
|
237
|
+
// timing control: same call shape, empty body
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// --- helpers ---------------------------------------------------------------
|
|
241
|
+
|
|
242
|
+
static const char hex_glyph[16] = {
|
|
243
|
+
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
|
244
|
+
0x38, 0x39, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
static void put_text(char row, char col, const char *s)
|
|
248
|
+
{
|
|
249
|
+
char *p = SCREEN + 40 * row + col;
|
|
250
|
+
while (*s)
|
|
251
|
+
{
|
|
252
|
+
char c = *s++;
|
|
253
|
+
if (c >= 'A' && c <= 'Z') c -= 64;
|
|
254
|
+
*p++ = c;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
static void put_hex16(char row, char col, unsigned v)
|
|
259
|
+
{
|
|
260
|
+
char *p = SCREEN + 40 * row + col;
|
|
261
|
+
p[0] = hex_glyph[(v >> 12) & 15]; p[1] = hex_glyph[(v >> 8) & 15];
|
|
262
|
+
p[2] = hex_glyph[(v >> 4) & 15]; p[3] = hex_glyph[v & 15];
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
static unsigned fold(unsigned chk, char value)
|
|
266
|
+
{
|
|
267
|
+
return (chk ^ value) * 5 + 1;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
static void put_check(char row, const char *label, unsigned chk, unsigned exp, unsigned miss)
|
|
271
|
+
{
|
|
272
|
+
put_text(row, 0, label);
|
|
273
|
+
put_text(row, 12, "CHK");
|
|
274
|
+
put_hex16(row, 16, chk);
|
|
275
|
+
put_text(row, 21, "EXP");
|
|
276
|
+
put_hex16(row, 25, exp);
|
|
277
|
+
put_text(row, 30, chk == exp && miss == 0 ? "PASS" : "FAIL");
|
|
278
|
+
fmt_dec_sub(miss, SCREEN + 40 * row + 35);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// --- timing harness: CIA1 timer A, force-loaded from $FFFF, phi2 ----------
|
|
282
|
+
|
|
283
|
+
static char tbuf[8];
|
|
284
|
+
static volatile unsigned tval = 65535;
|
|
285
|
+
static volatile char tval8 = 255;
|
|
286
|
+
|
|
287
|
+
static void t_start(void)
|
|
288
|
+
{
|
|
289
|
+
cia1.cra = 0x00;
|
|
290
|
+
cia1.ta = 0xffff;
|
|
291
|
+
cia1.cra = 0x11;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
static unsigned t_stop(void)
|
|
295
|
+
{
|
|
296
|
+
cia1.cra = 0x00;
|
|
297
|
+
return 0xffff - cia1.ta;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
static void show_cycles(char row, const char *label, unsigned raw, unsigned base)
|
|
301
|
+
{
|
|
302
|
+
put_text(row, 0, label);
|
|
303
|
+
fmt_dec_sub(raw - base, SCREEN + 40 * row + 20);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
int main(void)
|
|
307
|
+
{
|
|
308
|
+
__asm { sei }
|
|
309
|
+
for (unsigned i = 0; i < 1000; i++) SCREEN[i] = 0x20;
|
|
310
|
+
put_text(0, 0, "DIVIDE CHECK");
|
|
311
|
+
|
|
312
|
+
// Build the divide-by-ten tables by counting, no divide needed.
|
|
313
|
+
{
|
|
314
|
+
char q = 0, r = 0;
|
|
315
|
+
for (unsigned i = 0; i < 256; i++)
|
|
316
|
+
{
|
|
317
|
+
tq10[i] = q; tr10[i] = r;
|
|
318
|
+
if (++r == 10) { r = 0; q++; }
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// Cycle costs, body only, display off, from the start of a frame.
|
|
323
|
+
vic.ctrl1 &= ~0x10;
|
|
324
|
+
while (vic.raster != 0x80) ;
|
|
325
|
+
while (vic.raster != 0x00) ;
|
|
326
|
+
unsigned base, c;
|
|
327
|
+
t_start(); null_call(); base = t_stop();
|
|
328
|
+
|
|
329
|
+
dvd = tval8; dvs8 = 1; t_start(); div8(); c = t_stop();
|
|
330
|
+
show_cycles(11, "DIV8 255/1", c, base);
|
|
331
|
+
dvd = tval8; dvs8 = 255; t_start(); div8(); unsigned c2 = t_stop();
|
|
332
|
+
show_cycles(12, "DIV8 255/255", c2, base);
|
|
333
|
+
dvd = tval; dvs8 = 1; t_start(); div16_8(); c = t_stop();
|
|
334
|
+
show_cycles(13, "DIV16/8 65535/1", c, base);
|
|
335
|
+
dvd = tval; dvs8 = 10; t_start(); div16_8(); c2 = t_stop();
|
|
336
|
+
show_cycles(14, "DIV16/8 65535/10", c2, base);
|
|
337
|
+
dvd = tval; dvs16 = 1; t_start(); div16_16(); c = t_stop();
|
|
338
|
+
show_cycles(15, "DIV16/16 65535/1", c, base);
|
|
339
|
+
dvd = tval; dvs16 = 0x8000; t_start(); div16_16(); c2 = t_stop();
|
|
340
|
+
show_cycles(16, "DIV16/16 65535/$8000", c2, base);
|
|
341
|
+
dvd = tval8; t_start(); div10_8(); c = t_stop();
|
|
342
|
+
show_cycles(17, "DIV10 SHIFT-ADD 255", c, base);
|
|
343
|
+
dvd = tval8; t_start(); div10_tab(); c2 = t_stop();
|
|
344
|
+
show_cycles(18, "DIV10 TABLE 255", c2, base);
|
|
345
|
+
unsigned v = tval; t_start(); fmt_dec_div(v, tbuf); c = t_stop();
|
|
346
|
+
show_cycles(19, "DEC5 BY DIV10 65535", c, base);
|
|
347
|
+
v = tval; t_start(); fmt_dec_sub(v, tbuf); c2 = t_stop();
|
|
348
|
+
show_cycles(20, "DEC5 BY SUB 65535", c2, base);
|
|
349
|
+
v = 59999; t_start(); fmt_dec_sub(v, tbuf); c2 = t_stop();
|
|
350
|
+
show_cycles(21, "DEC5 BY SUB 59999", c2, base);
|
|
351
|
+
show_cycles(22, "NULL CALL", base, 0);
|
|
352
|
+
vic.ctrl1 |= 0x10;
|
|
353
|
+
put_text(10, 0, "CYCLES, BODY ONLY (CIA1 TIMER A)");
|
|
354
|
+
|
|
355
|
+
// Exhaustive and swept checks against Oscar64's own / and %.
|
|
356
|
+
unsigned chk, miss;
|
|
357
|
+
|
|
358
|
+
chk = 0; miss = 0;
|
|
359
|
+
for (unsigned n = 0; n < 256; n++)
|
|
360
|
+
for (unsigned d = 1; d < 256; d++)
|
|
361
|
+
{
|
|
362
|
+
dvd = n; dvs8 = d; div8();
|
|
363
|
+
if (dvd != n / d || rem8 != n % d) miss++;
|
|
364
|
+
chk = fold(chk, (char)dvd); chk = fold(chk, rem8);
|
|
365
|
+
}
|
|
366
|
+
put_check(2, "8/8 ALL", chk, EXPECT_D8, miss);
|
|
367
|
+
|
|
368
|
+
chk = 0; miss = 0;
|
|
369
|
+
unsigned n = 0;
|
|
370
|
+
do
|
|
371
|
+
{
|
|
372
|
+
char d = (char)((n >> 8) + n);
|
|
373
|
+
if (d == 0) d = 7;
|
|
374
|
+
dvd = n; dvs8 = d; div16_8();
|
|
375
|
+
if (dvd != n / d || rem8 != n % d) miss++;
|
|
376
|
+
chk = fold(chk, (char)dvd); chk = fold(chk, (char)(dvd >> 8)); chk = fold(chk, rem8);
|
|
377
|
+
} while (++n != 0);
|
|
378
|
+
put_check(3, "16/8 ALL", chk, EXPECT_D16, miss);
|
|
379
|
+
|
|
380
|
+
chk = 0; miss = 0;
|
|
381
|
+
for (n = 0; n < 65533; n += 3)
|
|
382
|
+
{
|
|
383
|
+
unsigned d = n * 0x9e37 + 0x1234;
|
|
384
|
+
if (d == 0) d = 1;
|
|
385
|
+
dvd = n; dvs16 = d; div16_16();
|
|
386
|
+
if (dvd != n / d || rem16 != n % d) miss++;
|
|
387
|
+
chk = fold(chk, (char)dvd); chk = fold(chk, (char)(dvd >> 8));
|
|
388
|
+
chk = fold(chk, (char)rem16); chk = fold(chk, (char)(rem16 >> 8));
|
|
389
|
+
}
|
|
390
|
+
put_check(4, "16/16 SWEEP", chk, EXPECT_D32, miss);
|
|
391
|
+
|
|
392
|
+
chk = 0; miss = 0;
|
|
393
|
+
for (n = 0; n < 256; n++)
|
|
394
|
+
{
|
|
395
|
+
dvd = n; div10_8();
|
|
396
|
+
if (q10 != n / 10 || r10 != n % 10) miss++;
|
|
397
|
+
chk = fold(chk, q10); chk = fold(chk, r10);
|
|
398
|
+
dvd = n; div10_tab();
|
|
399
|
+
if (q10 != n / 10 || r10 != n % 10) miss++;
|
|
400
|
+
chk = fold(chk, q10); chk = fold(chk, r10);
|
|
401
|
+
}
|
|
402
|
+
put_check(5, "BY 10 ALL", chk, EXPECT_T10, miss);
|
|
403
|
+
|
|
404
|
+
chk = 0; miss = 0;
|
|
405
|
+
for (n = 0; n < 65535; n += 5)
|
|
406
|
+
{
|
|
407
|
+
char a[5], b[5];
|
|
408
|
+
fmt_dec_div(n, a); fmt_dec_sub(n, b);
|
|
409
|
+
for (char i = 0; i < 5; i++) { if (a[i] != b[i]) miss++; chk = fold(chk, a[i]); }
|
|
410
|
+
}
|
|
411
|
+
put_check(6, "DEC5 SWEEP", chk, EXPECT_DEC, miss);
|
|
412
|
+
|
|
413
|
+
for (;;) ;
|
|
414
|
+
return 0;
|
|
415
|
+
}
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
## Build
|
|
419
|
+
|
|
420
|
+
```bash
|
|
421
|
+
oscar64 -tm=c64 -O2 -o=divide-check.prg divide-check.c
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
Then run headless (PAL; add `-model ntsc` for NTSC):
|
|
425
|
+
|
|
426
|
+
```bash
|
|
427
|
+
GSETTINGS_SCHEMA_DIR=/opt/homebrew/share/glib-2.0/schemas timeout 180 x64sc -default -warp +sound +autostart-delay-random -autostartprgmode 1 -limitcycles 600000000 -exitscreenshot divide-check.png -autostart divide-check.prg
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
The cycle limit is 600,000,000 because the checks call Oscar64's own
|
|
431
|
+
16-bit divide and modulo twice for every one of the 152,000 or so test
|
|
432
|
+
divides, which costs more than the routines under test; at 300,000,000
|
|
433
|
+
the last row (`DEC5 SWEEP`) had not been written yet. About 30 s in
|
|
434
|
+
warp on this machine.
|
|
435
|
+
|
|
436
|
+
## Expected output
|
|
437
|
+
|
|
438
|
+
`screenshots/divide-check.png` (PAL) and `screenshots/divide-check-ntsc.png`
|
|
439
|
+
(NTSC), both read cell by cell against the character ROM. Light blue
|
|
440
|
+
text on the default blue screen:
|
|
441
|
+
|
|
442
|
+
```
|
|
443
|
+
DIVIDE CHECK
|
|
444
|
+
|
|
445
|
+
8/8 ALL CHK 7122 EXP 7122 PASS 0
|
|
446
|
+
16/8 ALL CHK BBC4 EXP BBC4 PASS 0
|
|
447
|
+
16/16 SWEEP CHK 6DA5 EXP 6DA5 PASS 0
|
|
448
|
+
BY 10 ALL CHK AD4C EXP AD4C PASS 0
|
|
449
|
+
DEC5 SWEEP CHK 3D19 EXP 3D19 PASS 0
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
|
|
453
|
+
CYCLES, BODY ONLY (CIA1 TIMER A)
|
|
454
|
+
DIV8 255/1 351
|
|
455
|
+
DIV8 255/255 260
|
|
456
|
+
DIV16/8 65535/1 791
|
|
457
|
+
DIV16/8 65535/10 674
|
|
458
|
+
DIV16/16 65535/1 1339
|
|
459
|
+
DIV16/16 65535/$8000 715
|
|
460
|
+
DIV10 SHIFT-ADD 255 79
|
|
461
|
+
DIV10 TABLE 255 20
|
|
462
|
+
DEC5 BY DIV10 65535 2793
|
|
463
|
+
DEC5 BY SUB 65535 936
|
|
464
|
+
DEC5 BY SUB 59999 1340
|
|
465
|
+
NULL CALL 17
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
The last column of each check row is the miss count against Oscar64's
|
|
469
|
+
`/` and `%`; `PASS` needs the checksum to match and the count to be
|
|
470
|
+
zero. The checksums are the fold `chk = ((chk ^ byte) * 5 + 1) & 0xFFFF`
|
|
471
|
+
over the bytes named in the `EXPECT_` comments, in that order. In
|
|
472
|
+
Python:
|
|
473
|
+
|
|
474
|
+
```python
|
|
475
|
+
def fold(chk, v): return ((chk ^ v) * 5 + 1) & 0xffff
|
|
476
|
+
chk = 0
|
|
477
|
+
for n in range(256):
|
|
478
|
+
for d in range(1, 256):
|
|
479
|
+
chk = fold(chk, n // d); chk = fold(chk, n % d)
|
|
480
|
+
print(hex(chk)) # 0x7122
|
|
481
|
+
chk = 0
|
|
482
|
+
for n in range(65536):
|
|
483
|
+
d = ((n >> 8) + n) & 0xff or 7
|
|
484
|
+
q, r = n // d, n % d
|
|
485
|
+
chk = fold(chk, q & 0xff); chk = fold(chk, q >> 8); chk = fold(chk, r)
|
|
486
|
+
print(hex(chk)) # 0xbbc4
|
|
487
|
+
chk = 0
|
|
488
|
+
for n in range(0, 65533, 3):
|
|
489
|
+
d = (n * 0x9e37 + 0x1234) & 0xffff or 1
|
|
490
|
+
q, r = n // d, n % d
|
|
491
|
+
chk = fold(chk, q & 0xff); chk = fold(chk, q >> 8)
|
|
492
|
+
chk = fold(chk, r & 0xff); chk = fold(chk, r >> 8)
|
|
493
|
+
print(hex(chk)) # 0x6da5
|
|
494
|
+
chk = 0
|
|
495
|
+
for n in range(256):
|
|
496
|
+
for _ in range(2):
|
|
497
|
+
chk = fold(chk, n // 10); chk = fold(chk, n % 10)
|
|
498
|
+
print(hex(chk)) # 0xad4c
|
|
499
|
+
chk = 0
|
|
500
|
+
for n in range(0, 65535, 5):
|
|
501
|
+
for b in str(n).rjust(5).encode('ascii'):
|
|
502
|
+
chk = fold(chk, b)
|
|
503
|
+
print(hex(chk)) # 0x3d19
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
The cycle figures are the value of CIA1 timer A after each call, less
|
|
507
|
+
the 17 cycles of the same sequence around an empty function, so they
|
|
508
|
+
are the body of the routine without its `JSR` and `RTS`. PAL and NTSC
|
|
509
|
+
give identical figures, and two runs of each model gave the same PNG
|
|
510
|
+
byte for byte (rung 1, VICE x64sc 3.10). The operands live in absolute
|
|
511
|
+
memory; the figures for a zero-page copy are worked out, not measured,
|
|
512
|
+
on the technique page.
|
|
513
|
+
|
|
514
|
+
The two operand pairs per loop are the two ends of its range. 255/1
|
|
515
|
+
subtracts on every pass and is the worst case for the 8/8 loop; 255/255
|
|
516
|
+
subtracts once. 65535/1 is the worst case for both 16-bit loops.
|
|
517
|
+
65535/$8000 is the divisor that needs the 17th remainder bit, and it is
|
|
518
|
+
in the sweep too: `n * $9E37 + $1234` lands above `$8000` for about
|
|
519
|
+
half the values.
|
|
520
|
+
|
|
521
|
+
## Why this works
|
|
522
|
+
|
|
523
|
+
Each loop is long division in binary. The dividend is shifted left one
|
|
524
|
+
bit at a time into a remainder register; after each shift, if the
|
|
525
|
+
remainder is at least the divisor, the divisor is subtracted and a 1 is
|
|
526
|
+
set in the bit of the dividend that was just vacated. After as many
|
|
527
|
+
passes as the dividend has bits, the dividend byte(s) hold the quotient
|
|
528
|
+
and the remainder register holds the remainder. Both come out of one
|
|
529
|
+
loop, which is what makes the same routine serve `/` and `%`.
|
|
530
|
+
|
|
531
|
+
The partial remainder can be one bit wider than the divisor: before the
|
|
532
|
+
subtract it is up to twice the divisor less one. `rol rem8` shifts that
|
|
533
|
+
extra bit into the carry, and `bcs` jumps straight to the subtract
|
|
534
|
+
without a compare, because a remainder with its ninth bit set is always
|
|
535
|
+
at least any 8-bit divisor. The carry is also already set, which is what
|
|
536
|
+
`sbc` needs. On the other path `cmp` leaves the carry set exactly when
|
|
537
|
+
the subtract should happen, so the two paths meet at `sbc` with the
|
|
538
|
+
carry right either way. The 16/16 loop keeps the same `bcs` and a
|
|
539
|
+
two-byte compare that stops early when the high bytes differ, but with
|
|
540
|
+
equal widths the extra bit never appears: the remainder can only exceed
|
|
541
|
+
the divisor's width once the loop has consumed more dividend bits than
|
|
542
|
+
the divisor has, which takes a seventeenth pass. Measured by rebuilding
|
|
543
|
+
this page with all three `bcs` guards deleted: `8/8 ALL` and `16/16
|
|
544
|
+
SWEEP` still pass with 0 misses, `16/8 ALL` fails with 24,400 misses
|
|
545
|
+
(checksum `4223` against `BBC4`), and the threshold is a divisor of
|
|
546
|
+
`$81`, so `256 / 255` comes out as 0 remainder 0. An earlier version of
|
|
547
|
+
this paragraph said a routine without the `bcs` "is wrong for every
|
|
548
|
+
divisor of `$8000` or more"; the `65535/$8000` row passes without it.
|
|
549
|
+
The measurement is in `pitfalls/maths.md` under
|
|
550
|
+
`division_loop_missing_ninth_bit_guard`.
|
|
551
|
+
|
|
552
|
+
`div10_8` replaces the loop with an approximation of `n / 10` built
|
|
553
|
+
from shifts: `n/2 + n/4` is `0.75n`, adding a sixteenth of that gives
|
|
554
|
+
`0.797n`, and dividing by 8 gives `0.0996n`, always equal to or one
|
|
555
|
+
below the true quotient for `n` up to 255. The remainder `n - 10q` is
|
|
556
|
+
then 0 to 11 and one compare fixes it (Python over all 256 values
|
|
557
|
+
agrees, and the run checks it). The table route is two indexed loads.
|
|
558
|
+
The reciprocal multiply form, `(n * 205) >> 11`, is exact for the same
|
|
559
|
+
range and is on the technique page; it is not in this listing because
|
|
560
|
+
it needs a multiply.
|
|
561
|
+
|
|
562
|
+
The five-digit print by repeated division is three times the cost of
|
|
563
|
+
the subtract-powers print, 2,793 cycles against 936, and it is the
|
|
564
|
+
answer to the question of whether a HUD should divide by ten: it should
|
|
565
|
+
not, on this CPU, unless the digits are needed in the other order. The
|
|
566
|
+
divide route's advantage is the units digit first, which suits a
|
|
567
|
+
right-to-left field or a number of unknown width.
|
|
568
|
+
|
|
569
|
+
The globals the `__asm` blocks read and write are declared `volatile`.
|
|
570
|
+
Without it Oscar64 at `-O2` treated `div8()` as a call that does not
|
|
571
|
+
touch `dvd`, kept the dividend it had just stored in a zero-page
|
|
572
|
+
temporary, and compared that against `n / d`: the first build of this
|
|
573
|
+
page reported 64,770 misses for 8/8 with a listing for `div8` that was
|
|
574
|
+
correct to the byte. `__asm volatile` keeps the block in place; it does
|
|
575
|
+
not tell the compiler what the block writes.
|
|
576
|
+
|
|
577
|
+
The timing harness and screen writes are the ones in `print-number.md`:
|
|
578
|
+
timer A force-loaded from `$FFFF` and stopped before it is read, the
|
|
579
|
+
display blanked and the run started at the top of a frame so no badline
|
|
580
|
+
is inside the count, everything written as screen codes at `$0400`
|
|
581
|
+
under `sei`.
|