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,813 @@
|
|
|
1
|
+
---
|
|
2
|
+
region: PAL+NTSC
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# PAL vs NTSC Region Reference
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
The Commodore 64 shipped in two main video regions that are mostly software-
|
|
10
|
+
compatible but differ in clock rate, frame timing, raster geometry, and SID
|
|
11
|
+
audio frequency. Code that does not account for the region difference will
|
|
12
|
+
exhibit one or more of: music played at the wrong tempo, raster IRQs that
|
|
13
|
+
fire on the wrong line, sprite multiplexers that overflow the visible area,
|
|
14
|
+
side-border-opening tricks that fail outright, and digi playback that pitches
|
|
15
|
+
up or down by roughly 4%.
|
|
16
|
+
|
|
17
|
+
The two regions covered by this document are:
|
|
18
|
+
|
|
19
|
+
- **PAL** — used in Europe, Australia, parts of South America, and most of
|
|
20
|
+
Asia. Driven by a 17.734472 MHz crystal divided by 18 (some sources give
|
|
21
|
+
17.734475 MHz, four times the PAL colour subcarrier; the 0.17 Hz that
|
|
22
|
+
makes on the CPU clock is below anything measured here — an earlier
|
|
23
|
+
version of this line paired 17.734475 with the 985,248.444 Hz quotient
|
|
24
|
+
below, which belongs to 17.734472), a CPU clock of approximately
|
|
25
|
+
985,248 Hz. Frame rate is 50 Hz, 312 scanlines per frame,
|
|
26
|
+
63 cycles per scanline.
|
|
27
|
+
- **NTSC** — used in the United States, Canada, Japan, and Mexico. Driven by
|
|
28
|
+
a 14.31818 MHz crystal, divides down to a CPU clock of approximately
|
|
29
|
+
1,022,727 Hz. Frame rate is ~59.826 Hz (commonly called "60 Hz"), 263
|
|
30
|
+
scanlines per frame, 65 cycles per scanline.
|
|
31
|
+
|
|
32
|
+
Two minor variants — **PAL-N** (Argentina/Paraguay/Uruguay; the Drean
|
|
33
|
+
C64, VIC 6572) and **PAL-M** (Brazil) — are out of scope for the tables
|
|
34
|
+
in this reference, but they do NOT share PAL CPU timing, as an earlier
|
|
35
|
+
version of this page said. Measured in VICE x64sc with `-model drean`
|
|
36
|
+
(not on a 6572 on a bench): 312 raster lines of **65** cycles, 20,280
|
|
37
|
+
cycles per frame, CPU clock about 1.0234 MHz (1,023,451 cycles/s read
|
|
38
|
+
against the CIA TOD; VICE's own constant is 1,023,440). That is an
|
|
39
|
+
NTSC-length line on a PAL-length frame. Consequences: a per-frame CIA
|
|
40
|
+
timer needs $4F37 (20,279) there, not $4CC7; any loop padded to 63
|
|
41
|
+
cycles per line drifts 2 cycles per line, so PAL stable-raster and
|
|
42
|
+
side-border code loses sync; the SID clock follows the CPU clock, so
|
|
43
|
+
PAL frequency tables play about 3.9 % sharp (1,023,440 / 985,248) — use
|
|
44
|
+
NTSC-derived tables. Frame rate is 50.46 Hz, so per-frame music tempo
|
|
45
|
+
is within 1 % of PAL. All three detection methods below report PAL-N
|
|
46
|
+
as PAL (max raster 311, frame time $4F38 >= $4800, KERNAL $02A6 = 1).
|
|
47
|
+
PAL-M is unmeasured here: VICE has no PAL-M model, so do not assume it
|
|
48
|
+
shares PAL timing either.
|
|
49
|
+
|
|
50
|
+
Sources for this document: c64-wiki PAL article, c64-wiki NTSC article,
|
|
51
|
+
codebase64 PAL/NTSC compatibility wiki, and the Bauer "VIC-II Article"
|
|
52
|
+
(cebix mirror).
|
|
53
|
+
|
|
54
|
+
## Quick reference
|
|
55
|
+
|
|
56
|
+
| Property | PAL (6569) | NTSC (6567R8) | NTSC-old (6567R56A) |
|
|
57
|
+
|-------------------------|------------------------|------------------------|------------------------|
|
|
58
|
+
| CPU clock | 985,248.444 Hz | 1,022,727.143 Hz | 1,022,727.143 Hz |
|
|
59
|
+
| Dot clock | 7,881,987 Hz | 8,181,817 Hz | 8,181,817 Hz |
|
|
60
|
+
| Frame rate (nominal) | 50.125 Hz | 59.826 Hz | 60.993 Hz |
|
|
61
|
+
| Scanlines per frame | 312 | 263 | 262 |
|
|
62
|
+
| Cycles per scanline | 63 | 65 | 64 |
|
|
63
|
+
| Cycles per frame | 19,656 | 17,095 | 16,768 |
|
|
64
|
+
| Visible Y range (Bauer, not measured here) | 16-299 (284 lines) | 41-262 then 0-12 (235 lines) | 41-261 then 0-12 (234 lines) |
|
|
65
|
+
| Visible X range (cycles)| 12-59 (approx) | 14-61 (approx) | 13-60 (approx) |
|
|
66
|
+
| First badline (default) | $33 (51) | $33 (51) | $33 (51) |
|
|
67
|
+
| Last badline (default) | $F3 (243) | $F3 (243) | $F3 (243) |
|
|
68
|
+
| $D012 wraps at line | 312 (back to 0) | 263 (back to 0) | 262 (back to 0) |
|
|
69
|
+
| Vertical blank starts | line 300 | line 13 | line 13 |
|
|
70
|
+
| Top border opens at | line 51 ($33) | line 51 ($33) | line 51 ($33) |
|
|
71
|
+
| Bottom border opens at | line 251 ($FB) | line 251 ($FB) | line 251 ($FB) |
|
|
72
|
+
| Side border CSEL write | cycle 56 (one cycle) | not measured here | not measured here |
|
|
73
|
+
| CIA timer A for frame | $4CC7 (19,655) | $42C6 (17,094) | $417F (16,767) |
|
|
74
|
+
|
|
75
|
+
Note on $D012 wrap: $D012 is only 8 bits wide. The 9th bit lives in
|
|
76
|
+
$D011 bit 7 (RST8). PAL frames see $D012 take values 0..255 with RST8=0
|
|
77
|
+
followed by 0..55 with RST8=1, then wrap; NTSC frames see 0..255 with
|
|
78
|
+
RST8=0 followed by 0..6 with RST8=1, then wrap. See
|
|
79
|
+
`d012_wrap_around` in [raster-and-badline.md](../pitfalls/raster-and-badline.md)
|
|
80
|
+
for the RST8 set/clear pattern, and `raster_line_count_difference` in
|
|
81
|
+
[region-timing.md](../pitfalls/region-timing.md) for the per-region wrap
|
|
82
|
+
point.
|
|
83
|
+
|
|
84
|
+
## Timing table — detailed
|
|
85
|
+
|
|
86
|
+
### Cycles per frame
|
|
87
|
+
|
|
88
|
+
PAL frames are 19,656 cycles long (312 lines × 63 cycles). NTSC frames
|
|
89
|
+
on the modern 6567R8 are 17,095 cycles (263 × 65). The older 6567R56A
|
|
90
|
+
NTSC chip uses 262 lines × 64 cycles = 16,768 cycles per frame; the
|
|
91
|
+
R56A is uncommon and is reported to have shipped only in the earliest
|
|
92
|
+
U.S. machines (production history from published sources, not verified
|
|
93
|
+
here). Any code that assumes a fixed cycle count per frame must be
|
|
94
|
+
parameterized per region. PAL-N (6572): 312 × 65 = 20,280 cycles per
|
|
95
|
+
frame, measured in VICE x64sc `-model drean`.
|
|
96
|
+
|
|
97
|
+
A PAL frame is roughly 15% longer than an NTSC frame in cycles (19,656
|
|
98
|
+
vs 17,095) but about 19% longer in time (19.95 ms vs 16.71 ms), because
|
|
99
|
+
the NTSC CPU clock is also 3.8% faster. That means:
|
|
100
|
+
|
|
101
|
+
- A music routine called once per frame plays about 19% faster on NTSC
|
|
102
|
+
(59.83 Hz vs 50.12 Hz frames; measured in VICE x64sc as 600 vs 502
|
|
103
|
+
frames per 10 s of CIA TOD time). An earlier version of this page said
|
|
104
|
+
15%, which is the cycle-count ratio — it describes the CPU budget per
|
|
105
|
+
frame, not tempo. See [Music tempo](#music-tempo).
|
|
106
|
+
- A demo effect that consumes N cycles per frame has 2,561 more cycles
|
|
107
|
+
to work with on PAL.
|
|
108
|
+
- A raster split that "just barely fits" on PAL may not fit on NTSC
|
|
109
|
+
because each scanline is 2 cycles longer (giving more time per line)
|
|
110
|
+
but each frame contains 49 fewer scanlines (50 on the R56A, whose
|
|
111
|
+
lines are only 1 cycle longer) to work with — the cycle budget is
|
|
112
|
+
what matters, not the line count.
|
|
113
|
+
|
|
114
|
+
### Visible region
|
|
115
|
+
|
|
116
|
+
The "visible region" is the rectangle of raster lines where the VIC-II
|
|
117
|
+
generates picture content (as opposed to vertical or horizontal blanking).
|
|
118
|
+
Lines outside the visible Y range still execute on the CPU, but anything
|
|
119
|
+
drawn there will be off-screen.
|
|
120
|
+
|
|
121
|
+
PAL picture lines are 16-299 (284 lines; vertical blank 300-15). NTSC
|
|
122
|
+
picture lines are 41-262 wrapping to 0-12 (235 lines on the R8, 234 on
|
|
123
|
+
the R56A; vertical blank 13-40). These spans are from Bauer's VIC-II
|
|
124
|
+
article and are not measured here; what is measured (VICE x64sc 3.10)
|
|
125
|
+
is the frame length: maximum raster line 311 PAL, 262 R8, 261 R56A. An
|
|
126
|
+
earlier revision of this page gave 16-287 (272 lines) for PAL and
|
|
127
|
+
41-300 (260 lines) for NTSC — the PAL figure is VICE's default
|
|
128
|
+
screenshot crop (384x272, raster 16-287), not the chip's picture area,
|
|
129
|
+
and it left lines 288-299 unaccounted for against this page's own
|
|
130
|
+
"vertical blank starts line 300"; the NTSC figure ran 38 lines past the
|
|
131
|
+
end of a 263-line frame. VICE's default exit screenshots crop to raster
|
|
132
|
+
16-287 on PAL and 28-262 then 0-11 (247 rows) on NTSC; do not read
|
|
133
|
+
either as the visible area.
|
|
134
|
+
|
|
135
|
+
The default 25-row text display lives at lines 51-250 in both regions,
|
|
136
|
+
which is centered on PAL but pushed slightly low on NTSC. Most games
|
|
137
|
+
work fine because they target the 200-line display, not the larger
|
|
138
|
+
visible area.
|
|
139
|
+
|
|
140
|
+
### Badline range
|
|
141
|
+
|
|
142
|
+
A "badline" is a scanline on which the VIC-II steals 40-43 cycles from
|
|
143
|
+
the CPU to fetch character pointers. By default, badlines occur on every
|
|
144
|
+
8th line starting at line 51 ($33) — lines 51, 59, 67, ..., 243 in both
|
|
145
|
+
regions, 25 badlines for 25 character rows (measured in VICE x64sc, PAL
|
|
146
|
+
and NTSC R8). An earlier revision gave 247 here and $F8 (248) in the
|
|
147
|
+
table; neither is a badline: 248 lies outside the $30–$F7 window the
|
|
148
|
+
condition tests, and 247 & 7 = 7 ≠ YSCROLL (3). The badline range
|
|
149
|
+
itself is region-independent because it is anchored to the fixed raster
|
|
150
|
+
window $30-$F7 (48-247) and to YSCROLL ($D011 bits 0-2), gated by DEN
|
|
151
|
+
having been set on line $30 — not to the border geometry: RSEL ($D011
|
|
152
|
+
bit 3) and CSEL ($D016 bit 3) move the border, not the badlines.
|
|
153
|
+
Measured in VICE x64sc 3.10 on the 8565 (VICE's default C64C; an earlier
|
|
154
|
+
version said 6569), 6567R8 and 6567R56A: clearing
|
|
155
|
+
RSEL or CSEL leaves the badlines on 51, 59, ..., 243; YSCROLL=4 moves
|
|
156
|
+
every one of them to 52, 60, ..., 244. An earlier version of this
|
|
157
|
+
paragraph attributed the anchor to RSEL/CSEL.
|
|
158
|
+
|
|
159
|
+
What differs by region is the number of non-badlines before and after
|
|
160
|
+
the display window:
|
|
161
|
+
|
|
162
|
+
- PAL has 51 lines (0-50) before the first badline and 68 lines
|
|
163
|
+
(244-311) after the last.
|
|
164
|
+
- NTSC R8 has 51 lines (0-50) before and 19 lines (244-262) after.
|
|
165
|
+
|
|
166
|
+
The narrow post-display window on NTSC is the main reason NTSC
|
|
167
|
+
demos struggle with effects that "open" the bottom border — there
|
|
168
|
+
are far fewer lines to do setup work between the last badline and
|
|
169
|
+
the next frame's first badline.
|
|
170
|
+
|
|
171
|
+
## VIC-II chip differences
|
|
172
|
+
|
|
173
|
+
The PAL/NTSC split is enforced by which VIC-II chip is socketed.
|
|
174
|
+
There is no software register to read region directly; agents must
|
|
175
|
+
detect by timing or by the raster line counter (see
|
|
176
|
+
[Detection at runtime](#detection-at-runtime)).
|
|
177
|
+
|
|
178
|
+
### 6569 — PAL VIC-II family
|
|
179
|
+
|
|
180
|
+
- **6569R1 / 6569R3** — early PAL VIC-II revisions with the same
|
|
181
|
+
timing. (An earlier version of this page said R3 "fixes a
|
|
182
|
+
sprite-vs-background priority bug"; nothing on this machine can check
|
|
183
|
+
a revision history, so that claim is withdrawn rather than repeated.)
|
|
184
|
+
- **6569R4 / 6569R5** — later NMOS revisions, same timing as R3.
|
|
185
|
+
- **8565** — HMOS-II PAL VIC-II shipped in the C64C (C64-II, 1986+).
|
|
186
|
+
Same timing as 6569R3 but with slightly different colour output
|
|
187
|
+
(brighter greys, slightly different luminance levels). All 8565
|
|
188
|
+
parts are timing-compatible with 6569 from a software perspective.
|
|
189
|
+
|
|
190
|
+
PAL VIC-II chips were the most-produced variant because Europe was
|
|
191
|
+
Commodore's largest market for the C64.
|
|
192
|
+
|
|
193
|
+
### 6567 — NTSC VIC-II family
|
|
194
|
+
|
|
195
|
+
- **6567R56A** — the original NTSC chip. 262 scanlines per frame, 64
|
|
196
|
+
cycles per scanline (measured in VICE x64sc `-model oldntsc`). Its
|
|
197
|
+
shipping history — early U.S. machines, 1982-83 — is from published
|
|
198
|
+
sources and not verified here.
|
|
199
|
+
- **6567R8** — the standard NTSC chip from 1983 onward. 263
|
|
200
|
+
scanlines per frame, 65 cycles per scanline. This is what
|
|
201
|
+
virtually all NTSC software is written for.
|
|
202
|
+
- **8562** — HMOS-II NTSC VIC-II shipped in the C64C. Timing-
|
|
203
|
+
compatible with 6567R8.
|
|
204
|
+
|
|
205
|
+
The 6567R56A is the only common case where "NTSC" is not enough
|
|
206
|
+
information to write timing-exact code. Code that needs to run
|
|
207
|
+
on R56A machines must detect by counting raster lines in a frame
|
|
208
|
+
(262 vs 263) — see [Detection at runtime](#detection-at-runtime).
|
|
209
|
+
|
|
210
|
+
### Cross-region chip swaps
|
|
211
|
+
|
|
212
|
+
Physically swapping a 6569 for a 6567 (or vice versa) in a real
|
|
213
|
+
machine does not work without also changing the crystal oscillator,
|
|
214
|
+
because the CPU and VIC-II share a clock. Emulators sidestep this
|
|
215
|
+
by letting you select a region independent of any physical part.
|
|
216
|
+
|
|
217
|
+
## SID frequency table differences
|
|
218
|
+
|
|
219
|
+
The SID chip's tone generators are clocked from the CPU clock (called
|
|
220
|
+
phi2 — "phase 2"). A given $D400 register value therefore produces
|
|
221
|
+
different output frequencies on PAL vs NTSC.
|
|
222
|
+
|
|
223
|
+
The SID frequency formula is:
|
|
224
|
+
|
|
225
|
+
```
|
|
226
|
+
output_hz = (freq_register * cpu_clock_hz) / 16777216
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
where `freq_register` is the 16-bit value written to $D400/$D401
|
|
230
|
+
(or $D407/$D408, $D40E/$D40F) and `16777216` is 2^24.
|
|
231
|
+
|
|
232
|
+
Using the canonical clocks:
|
|
233
|
+
|
|
234
|
+
- PAL: `output_hz = freq_register * 985248 / 16777216`
|
|
235
|
+
- NTSC: `output_hz = freq_register * 1022727 / 16777216`
|
|
236
|
+
|
|
237
|
+
To produce the same audio pitch on both regions, the frequency
|
|
238
|
+
register must be scaled:
|
|
239
|
+
|
|
240
|
+
```
|
|
241
|
+
freq_ntsc = freq_pal * (985248 / 1022727)
|
|
242
|
+
= freq_pal * 0.96334...
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Or in reverse:
|
|
246
|
+
|
|
247
|
+
```
|
|
248
|
+
freq_pal = freq_ntsc * (1022727 / 985248)
|
|
249
|
+
= freq_ntsc * 1.03804...
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
A PAL-tuned music routine played without correction on NTSC plays
|
|
253
|
+
roughly 0.65 semitones sharp. Conversely, an NTSC-tuned routine
|
|
254
|
+
played on PAL plays roughly 0.65 semitones flat.
|
|
255
|
+
|
|
256
|
+
### Common approach: two frequency tables
|
|
257
|
+
|
|
258
|
+
The usual approach is one precomputed frequency table per region —
|
|
259
|
+
96 notes × 2 bytes = 192 bytes each, so carrying both is cheap — and a
|
|
260
|
+
region flag read once at start-up (`pal_ntsc_detection` in
|
|
261
|
+
`techniques/raster.md`) to choose between them. Which named editors and
|
|
262
|
+
players do this, and how, is not verified here; an earlier version of
|
|
263
|
+
this paragraph named three and called the tables "12-note", which its
|
|
264
|
+
own byte count contradicted.
|
|
265
|
+
|
|
266
|
+
Example PAL-vs-NTSC frequency for middle A (A4, ~440 Hz):
|
|
267
|
+
|
|
268
|
+
- PAL: $D400/$D401 = $1D45 (7493 decimal)
|
|
269
|
+
- NTSC: $D400/$D401 = $1C32 (7218 decimal)
|
|
270
|
+
|
|
271
|
+
A music driver that hard-codes the PAL table and runs on NTSC plays
|
|
272
|
+
A4 at:
|
|
273
|
+
|
|
274
|
+
```
|
|
275
|
+
7493 * 1022727 / 16777216 = 456.8 Hz
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
which is 65 cents sharp — clearly audible.
|
|
279
|
+
|
|
280
|
+
### Filter cutoff and resonance
|
|
281
|
+
|
|
282
|
+
The SID filter's cutoff frequency ($D415/$D416) is also clock-
|
|
283
|
+
dependent, but the relationship is non-linear and varies by chip
|
|
284
|
+
revision (6581 vs 8580). Most code does not try to match filter
|
|
285
|
+
behavior precisely across regions because the per-chip variation
|
|
286
|
+
within a region is already larger than the cross-region drift.
|
|
287
|
+
|
|
288
|
+
## CIA timer values
|
|
289
|
+
|
|
290
|
+
The two CIA chips ($DC00-$DCFF and $DD00-$DDFF) contain 16-bit timers
|
|
291
|
+
clocked from phi2 (the CPU clock). A timer loaded with value `N`
|
|
292
|
+
fires after `N+1` cycles (the +1 accounts for the reload itself).
|
|
293
|
+
|
|
294
|
+
For "once per frame" timing without a raster IRQ, the typical CIA
|
|
295
|
+
timer A latch value is:
|
|
296
|
+
|
|
297
|
+
| Region | Timer A latch | Cycles per frame |
|
|
298
|
+
|---------------|---------------|------------------|
|
|
299
|
+
| PAL | $4CC7 (19,655)| 19,656 |
|
|
300
|
+
| NTSC R8 | $42C6 (17,094)| 17,095 |
|
|
301
|
+
| NTSC R56A | $417F (16,767)| 16,768 |
|
|
302
|
+
|
|
303
|
+
(Latch = cycles - 1: a continuous timer with latch N repeats every N+1
|
|
304
|
+
cycles. Measured in VICE x64sc: latch $4CC7 repeats every 19,656 cycles
|
|
305
|
+
exactly and stays on the same PAL raster line frame after frame; $4CC6
|
|
306
|
+
repeats every 19,655 and drifts one cycle per frame. An earlier version
|
|
307
|
+
of this table said cycles - 2.)
|
|
308
|
+
|
|
309
|
+
The KERNAL's default IRQ uses CIA #1 timer A at roughly 60 Hz on BOTH
|
|
310
|
+
regions; it is not once per frame. At reset ($FDDD, entered from IOINIT
|
|
311
|
+
and again from CINT once $FF5B has set the PAL/NTSC flag at $02A6 —
|
|
312
|
+
1 = PAL, 0 = NTSC) it writes the timer A latch as $4025 on PAL (16,422
|
|
313
|
+
cycles, 59.996 Hz) and $4295 on NTSC (17,046 cycles, 59.998 Hz) — ROM
|
|
314
|
+
bytes $FDE2-$FDF5. Read from the 901227-03 ROM image and confirmed in
|
|
315
|
+
VICE x64sc by sampling the free-running counter (maximum seen $401E on
|
|
316
|
+
PAL, $428E on NTSC). So TI/TI$ ticks about 60 times a second on a PAL
|
|
317
|
+
machine too, and on PAL the KERNAL IRQ drifts against the raster rather
|
|
318
|
+
than locking to it. An earlier version of this page gave $4CC6 (PAL) /
|
|
319
|
+
$42C5 (NTSC) and "50 Hz on PAL" for the KERNAL's defaults; those are
|
|
320
|
+
this page's own once-per-frame latches, which the KERNAL never writes.
|
|
321
|
+
Many games disable the KERNAL IRQ and reprogram timer A to
|
|
322
|
+
their own value (often once-per-frame, sometimes higher rates for
|
|
323
|
+
music routines that run faster than the frame rate).
|
|
324
|
+
|
|
325
|
+
### Music tempo
|
|
326
|
+
|
|
327
|
+
A music driver that runs once per frame plays at:
|
|
328
|
+
|
|
329
|
+
- PAL: 50.12 Hz (one tick per ~19.95 ms)
|
|
330
|
+
- NTSC: 59.83 Hz (one tick per ~16.71 ms)
|
|
331
|
+
|
|
332
|
+
If the music data is authored at 50 Hz tick rate and played on NTSC
|
|
333
|
+
without correction, the music plays 19.4% faster — a noticeably
|
|
334
|
+
brighter tempo. The standard fix is to skip one call in six on NTSC —
|
|
335
|
+
run the driver from the frame IRQ but skip its update on every 6th
|
|
336
|
+
call, so it ticks on five of every six frames: 59.83 × 5/6 ≈ 49.86 Hz,
|
|
337
|
+
0.54% below PAL's 50.12 Hz, inaudible. The other option is to ship
|
|
338
|
+
per-region tempo tables in the music data (checklist item (c) below;
|
|
339
|
+
region-timing.md, Approach 2). Do not force a 50 Hz tick from a CIA
|
|
340
|
+
timer instead — see region-timing.md, "What not to do". An earlier
|
|
341
|
+
revision of this sentence said "every 6th NTSC frame instead of every
|
|
342
|
+
5th", which read literally is one call in six, or 9.97 Hz (measured in
|
|
343
|
+
VICE x64sc: 50 calls in 300 NTSC frames against 250 for five-of-six).
|
|
344
|
+
Most modern drivers handle this automatically given a region flag.
|
|
345
|
+
|
|
346
|
+
## Border timing differences
|
|
347
|
+
|
|
348
|
+
The VIC-II has two famous timing windows that let demo code "open"
|
|
349
|
+
the screen border — turning the normally-fixed border colour region
|
|
350
|
+
into addressable pixels. The exact cycle window during which the
|
|
351
|
+
border-disable bits ($D011 bit 3 for vertical, $D016 bit 3 for
|
|
352
|
+
horizontal) must be toggled differs slightly between PAL and NTSC.
|
|
353
|
+
|
|
354
|
+
### Top/bottom border (vertical) opening
|
|
355
|
+
|
|
356
|
+
To open the bottom border, code must clear $D011 bit 3 (24-row mode)
|
|
357
|
+
after the VIC-II has finished comparing line 247 — the bottom-border
|
|
358
|
+
line for 24-row mode (RSEL=0) — and before it starts comparing line
|
|
359
|
+
251, the bottom-border line for 25-row mode (RSEL=1); then restore
|
|
360
|
+
RSEL=1 from line 252 on. RSEL must still be 1 for the whole of line 247
|
|
361
|
+
and already be 0 when line 251 begins, so the RSEL=0 write lands in
|
|
362
|
+
lines 248-250. Measured in VICE x64sc 3.10 (PAL, stable IRQ, write
|
|
363
|
+
cycle calibrated against the cycle-56 CSEL reference): a write on any
|
|
364
|
+
cycle of line 247 up to cycle 62 closes the display (from line 247 if
|
|
365
|
+
the write is on cycle 16 or earlier, from 248 otherwise); writes from
|
|
366
|
+
cycle 63 of line 247 through cycle 63 of line 250 open it; a write on
|
|
367
|
+
cycle 1 of line 251, or anywhere later in 251, leaves the border on
|
|
368
|
+
from 251. The open window is three lines plus one cycle:
|
|
369
|
+
|
|
370
|
+
- PAL: 190 cycles (measured)
|
|
371
|
+
- NTSC R8: 196 cycles (3 × 65 + 1, arithmetic; VICE shows the same
|
|
372
|
+
lines closing and opening on NTSC)
|
|
373
|
+
- NTSC R56A: 193 cycles (3 × 64 + 1, arithmetic)
|
|
374
|
+
|
|
375
|
+
The line range is the same in every region because the 247/251 compare
|
|
376
|
+
values are internal to the VIC-II; only the per-line cycle count
|
|
377
|
+
differs. Bauer's description (one compare at cycle 63, one at the left
|
|
378
|
+
edge) would also admit the first 16 cycles of line 251; x64sc latches
|
|
379
|
+
the compare on every cycle and does not, and it has not been measured
|
|
380
|
+
on a real 6569 here. An earlier version of this page gave lines
|
|
381
|
+
247-251 / 5 lines / ~315 cycles, with the two modes' thresholds
|
|
382
|
+
swapped.
|
|
383
|
+
|
|
384
|
+
There is no separate top-border write. Once the bottom comparison has
|
|
385
|
+
been suppressed the flip-flop stays clear through the vertical blank
|
|
386
|
+
and the next frame's top border, and line 51's top comparison resets a
|
|
387
|
+
flip-flop that is already clear; a write near line 55 on its own opens
|
|
388
|
+
nothing (measured in VICE x64sc 3.10 — the two writes, the window sweep
|
|
389
|
+
and the controls are in `recipes/kickassembler/topbottom-border-open.md`).
|
|
390
|
+
|
|
391
|
+
### Side border (horizontal) opening
|
|
392
|
+
|
|
393
|
+
The side-border open is a one-cycle target per scanline, not a window.
|
|
394
|
+
The VIC-II sets the border flip-flop when the beam reaches X=335 with
|
|
395
|
+
CSEL=0 or X=344 with CSEL=1; on PAL the beam is at X=335 during cycle
|
|
396
|
+
55 and X=344 during cycle 56 (cycles numbered 1-63 as in VICE and
|
|
397
|
+
Bauer), so the write that takes CSEL ($D016 bit 3) from 1 to 0 must
|
|
398
|
+
land on cycle 56: a `DEC $D016` on $C8 started on cycle 51 does it. Set
|
|
399
|
+
CSEL back to 1 any time before cycle 55 of the next line; there is no
|
|
400
|
+
separate left-border or close window, because a flip-flop that was
|
|
401
|
+
never set has nothing to reset at X=24/31. Measured in VICE x64sc 3.10
|
|
402
|
+
(recipes/kickassembler/sideborder-open.md; a one-cycle sweep with a
|
|
403
|
+
badline anchor opens only on the cycle-56 write, and a restore on
|
|
404
|
+
cycle 47 of the next line still opens).
|
|
405
|
+
|
|
406
|
+
NTSC 6567R8 / R56A: not measured here. The X positions are the same,
|
|
407
|
+
but the cycle number and the per-line loop length (65 or 64 cycles, not
|
|
408
|
+
63) have to be re-derived from the 6567 timing table.
|
|
409
|
+
|
|
410
|
+
Earlier text here gave a 1-2 cycle window at zero-indexed cycles 57-58
|
|
411
|
+
with a close window at 14-15 of the next line, and 58-59 for the R8;
|
|
412
|
+
none of those windows exist, and 57-58 in any indexing leaves the
|
|
413
|
+
border closed.
|
|
414
|
+
|
|
415
|
+
## Sample rate caveats for $D418 digi
|
|
416
|
+
|
|
417
|
+
"$D418 digi" is the technique of generating pseudo-PCM audio by
|
|
418
|
+
rapidly writing 4-bit volume values to the SID volume register
|
|
419
|
+
($D418). The output sample rate equals the rate at which $D418
|
|
420
|
+
is written.
|
|
421
|
+
|
|
422
|
+
A common scheme is to write $D418 once per scanline using a
|
|
423
|
+
raster IRQ. The resulting sample rate is:
|
|
424
|
+
|
|
425
|
+
- PAL: 985,248 Hz ÷ 63 cycles per line = 15,639 Hz
|
|
426
|
+
- NTSC R8: 1,022,727 Hz ÷ 65 cycles per line = 15,734 Hz
|
|
427
|
+
- NTSC R56A: 1,022,727 Hz ÷ 64 cycles per line = 15,980 Hz
|
|
428
|
+
|
|
429
|
+
PAL and NTSC R8 are close enough (0.6% apart, about 10 cents) that
|
|
430
|
+
the same digi data can play on both regions without resampling and
|
|
431
|
+
still sound correct. The pitch shift is below 20 cents, which is at
|
|
432
|
+
the limit of audibility. The rare R56A is the exception: it runs
|
|
433
|
+
2.2% faster than PAL, about 37 cents, which is audible.
|
|
434
|
+
|
|
435
|
+
However, a digi played by a CIA timer at a fixed cycle interval
|
|
436
|
+
will drift more:
|
|
437
|
+
|
|
438
|
+
- A timer of $0080 (128+1 = 129 cycles per sample) gives
|
|
439
|
+
~7,638 Hz on PAL and ~7,928 Hz on NTSC R8 — a 290 Hz / ~3.8%
|
|
440
|
+
difference, audible as a pitch shift.
|
|
441
|
+
|
|
442
|
+
To play a sample at the same rate on both regions, scale the
|
|
443
|
+
timer value by the clock ratio:
|
|
444
|
+
|
|
445
|
+
```
|
|
446
|
+
timer_ntsc = timer_pal * (1022727 / 985248)
|
|
447
|
+
= timer_pal * 1.03804
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
### 8580 vs 6581 digi
|
|
451
|
+
|
|
452
|
+
The 6581 SID has a known DC-coupling quirk in $D418 that makes
|
|
453
|
+
$D418 digi loud and clear. The 8580 SID fixes this DC quirk, which
|
|
454
|
+
makes $D418 digi much quieter (some tracks are barely audible on
|
|
455
|
+
an 8580). This is a chip-revision issue, not a region issue —
|
|
456
|
+
both 6581 and 8580 ship in both PAL and NTSC machines. C64Cs from
|
|
457
|
+
~1986 onward typically ship with 8580; earlier C64s ship with 6581.
|
|
458
|
+
|
|
459
|
+
## Detection at runtime
|
|
460
|
+
|
|
461
|
+
There is no register that returns "I am PAL" or "I am NTSC". Code
|
|
462
|
+
must detect the region by observation. Two methods are reliable.
|
|
463
|
+
|
|
464
|
+
### Method 1: Read $D012 + $D011 bit 7 at frame top
|
|
465
|
+
|
|
466
|
+
Wait for $D011 bit 7 to be set (raster line >= 256), then keep reading
|
|
467
|
+
$D012 until bit 7 clears again; the last low byte seen while bit 7 was
|
|
468
|
+
set is the last line of the frame: $37 (311) on PAL, $06 (262) on the
|
|
469
|
+
6567R8, $05 (261) on the 6567R56A.
|
|
470
|
+
|
|
471
|
+
Maximum raster line value:
|
|
472
|
+
- PAL: 311 ($137 — i.e., $D012=$37 with $D011 bit 7=1)
|
|
473
|
+
- NTSC R8: 262 ($106 — $D012=$06 with $D011 bit 7=1)
|
|
474
|
+
- NTSC R56A: 261 ($105 — $D012=$05 with $D011 bit 7=1)
|
|
475
|
+
|
|
476
|
+
The routine below tracks the low byte while RST8 is set and returns
|
|
477
|
+
the region when RST8 falls. It works from any entry line. The earlier
|
|
478
|
+
listing here ended in `...`, never set A, and its loop exited on the
|
|
479
|
+
first pass because it was entered while the raster was still on line
|
|
480
|
+
0; it also read $D011 before $D012, which lets it mistake line 256 for
|
|
481
|
+
line 0 about 40% of the time (measured in VICE x64sc: 24 of 72 starts).
|
|
482
|
+
|
|
483
|
+
```kickassembler
|
|
484
|
+
// Region by last raster line. On exit A = 0 PAL (6569), 1 NTSC 6567R8, 2 NTSC 6567R56A.
|
|
485
|
+
// Trashes X, Y. Call with interrupts disabled. Measured in VICE x64sc 3.10 on all three models.
|
|
486
|
+
detect_region:
|
|
487
|
+
wait_lo:
|
|
488
|
+
lda $D011
|
|
489
|
+
bmi wait_lo // a band already in progress: let it finish (see below)
|
|
490
|
+
wait_hi:
|
|
491
|
+
lda $D011
|
|
492
|
+
bpl wait_hi // wait for RST8 = 1 (line >= 256)
|
|
493
|
+
ldy #0
|
|
494
|
+
track:
|
|
495
|
+
ldx $D012 // candidate low byte
|
|
496
|
+
lda $D011
|
|
497
|
+
bpl wrapped // RST8 fell: X may already be line 0, Y is the last good one
|
|
498
|
+
txa
|
|
499
|
+
tay // Y = last $D012 seen while RST8 = 1
|
|
500
|
+
jmp track // 17 cycles a pass, well under one line
|
|
501
|
+
wrapped:
|
|
502
|
+
lda #0
|
|
503
|
+
cpy #$10
|
|
504
|
+
bcs done // $37 -> PAL
|
|
505
|
+
lda #1
|
|
506
|
+
cpy #$06
|
|
507
|
+
beq done // $06 -> R8
|
|
508
|
+
lda #2 // $05 -> R56A
|
|
509
|
+
done:
|
|
510
|
+
rts
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
The `wait_lo` loop closes a race at the end of the band, not the start.
|
|
514
|
+
A call landing in the last cycles of line 311 reads $D012 on that line
|
|
515
|
+
and $D011 on line 0, so `bpl wrapped` is taken before the first `tay`
|
|
516
|
+
and Y is still 0: the routine would answer R56A on a PAL machine. A call
|
|
517
|
+
landing mid-band needs no guard — the lines it skips are the smaller
|
|
518
|
+
values — but with the guard `wait_hi` can only exit at line 256.
|
|
519
|
+
Measured on the equivalent tracking loop (`pal_ntsc_detection` in
|
|
520
|
+
`techniques/raster.md`, VICE x64sc 3.10): without the guard, entered on
|
|
521
|
+
PAL line 311 with the entry phase swept in 4-cycle steps, 2 of 16 phases
|
|
522
|
+
returned the register's preloaded junk; with it, all 16 returned $37.
|
|
523
|
+
Runtime depends on the entry line: 57 lines at best on PAL (called from
|
|
524
|
+
line 255) and 368 at worst (called as RST8 rises — the rest of that
|
|
525
|
+
band, 256 clear lines, and a whole band again), 8 to 270 lines on the
|
|
526
|
+
6567R8; that loop measured 3,575 and 23,172 cycles on PAL, 500 and
|
|
527
|
+
17,535 on the R8, 432 and 17,131 on the R56A against CIA 1 timer A.
|
|
528
|
+
|
|
529
|
+
A simpler and more common approach is to time a frame:
|
|
530
|
+
|
|
531
|
+
```
|
|
532
|
+
; Time one frame in cycles using CIA timer B.
|
|
533
|
+
; Returns approx 19656 (PAL) or 17095 (NTSC R8) in $FB/$FC
|
|
534
|
+
; (measured in VICE x64sc: $4CC2..$4CC9 and $42C0..$42C7; the
|
|
535
|
+
; spread is the 7-cycle poll loop).
|
|
536
|
+
;
|
|
537
|
+
; Method: let any current line 0 pass, wait for raster line 0,
|
|
538
|
+
; start timer B counting down from $FFFF, wait for the next
|
|
539
|
+
; line 0, read timer B, subtract from $FFFF.
|
|
540
|
+
;
|
|
541
|
+
; An earlier version of this listing read $D011 before $D012, so
|
|
542
|
+
; a read pair straddling the 255->256 wrap passed as line 0, and
|
|
543
|
+
; it re-tested for line 0 immediately after arming the timer; in
|
|
544
|
+
; VICE it returned ~$0DC8 (lines 256-311 only) or ~$0011 (a few
|
|
545
|
+
; cycles), never a frame.
|
|
546
|
+
|
|
547
|
+
time_frame:
|
|
548
|
+
sei
|
|
549
|
+
lda #$7F
|
|
550
|
+
sta $DC0D ; mask all CIA #1 IRQ sources
|
|
551
|
+
lda $DC0D ; ack any pending
|
|
552
|
+
lda #$00
|
|
553
|
+
sta $DC0F ; stop timer B
|
|
554
|
+
lda #$FF
|
|
555
|
+
sta $DC06 ; timer B latch low
|
|
556
|
+
sta $DC07 ; timer B latch high (loads the counter while stopped)
|
|
557
|
+
pre0:
|
|
558
|
+
lda $D012
|
|
559
|
+
beq pre0 ; already on line 0 (or 256): let it pass first
|
|
560
|
+
wait0a:
|
|
561
|
+
lda $D012 ; low byte first: a 255->256 straddle cannot pass as line 0
|
|
562
|
+
bne wait0a
|
|
563
|
+
lda $D011
|
|
564
|
+
bmi wait0a ; RST8 set: that was line 256, keep waiting
|
|
565
|
+
lda #$19 ; start + one-shot + force load, phi2 input
|
|
566
|
+
sta $DC0F
|
|
567
|
+
leave0:
|
|
568
|
+
lda $D012
|
|
569
|
+
beq leave0 ; let this line 0 go by before waiting for the next one
|
|
570
|
+
wait0b:
|
|
571
|
+
lda $D012
|
|
572
|
+
bne wait0b
|
|
573
|
+
lda $D011
|
|
574
|
+
bmi wait0b
|
|
575
|
+
lda #$00
|
|
576
|
+
sta $DC0F ; stop timer B
|
|
577
|
+
sec
|
|
578
|
+
lda #$FF
|
|
579
|
+
sbc $DC06
|
|
580
|
+
sta $FB
|
|
581
|
+
lda #$FF
|
|
582
|
+
sbc $DC07
|
|
583
|
+
sta $FC
|
|
584
|
+
cli
|
|
585
|
+
rts
|
|
586
|
+
|
|
587
|
+
; Caller: if $FC >= $48 -> PAL ($4CC2..$4CC9; frame latch is $4CC7)
|
|
588
|
+
; else -> NTSC ($42C0..$42C7)
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
The threshold $4800 (18,432) sits comfortably between the NTSC R8
|
|
592
|
+
cycle count (17,095) and the PAL cycle count (19,656).
|
|
593
|
+
|
|
594
|
+
### Method 2: Read $D012 wrap point
|
|
595
|
+
|
|
596
|
+
Wait for $D011 bit 7 to go high (i.e., raster line ≥ 256), then
|
|
597
|
+
poll $D012 until it stops counting up. The last value before wrap
|
|
598
|
+
is the discriminator:
|
|
599
|
+
|
|
600
|
+
- PAL: $D012 reaches $37 (55) then wraps -> max line 311
|
|
601
|
+
- NTSC R8: $D012 reaches $06 (6) then wraps -> max line 262
|
|
602
|
+
- NTSC R56A: $D012 reaches $05 (5) then wraps -> max line 261
|
|
603
|
+
|
|
604
|
+
Practical discriminator: read $D012 when $D011 bit 7 is 1. If
|
|
605
|
+
the value is ever $10 or higher, you're on PAL.
|
|
606
|
+
|
|
607
|
+
```
|
|
608
|
+
; Detect PAL vs NTSC by raster line wrap. Carry clear = NTSC,
|
|
609
|
+
; carry set = PAL.
|
|
610
|
+
detect_pal:
|
|
611
|
+
sei
|
|
612
|
+
wait_lo:
|
|
613
|
+
lda $D011
|
|
614
|
+
bmi wait_lo ; a band already in progress: let it finish (see below)
|
|
615
|
+
wait_hi:
|
|
616
|
+
lda $D011
|
|
617
|
+
bpl wait_hi ; wait for RST8=1 (raster >= 256)
|
|
618
|
+
scan:
|
|
619
|
+
lda $D011
|
|
620
|
+
bpl is_ntsc ; RST8 fell before $D012 reached $10: 262/263-line frame
|
|
621
|
+
lda $D012
|
|
622
|
+
cmp #$10 ; >= $10 means PAL (NTSC tops at $06/$05)
|
|
623
|
+
bcc scan ; keep polling while the raster is below 272
|
|
624
|
+
sec ; line 272 exists: 312-line frame (PAL, PAL-N)
|
|
625
|
+
rts
|
|
626
|
+
is_ntsc:
|
|
627
|
+
clc
|
|
628
|
+
rts
|
|
629
|
+
```
|
|
630
|
+
|
|
631
|
+
An earlier version of this listing read $D012 once, immediately after
|
|
632
|
+
RST8 rose — i.e. on line 256, where $D012 is 0 — and so returned NTSC
|
|
633
|
+
on a PAL machine from every raster phase below 272 (six of eight phases
|
|
634
|
+
measured in VICE x64sc); the prose above it already described polling,
|
|
635
|
+
the code did not. The `wait_lo` guard is the end-of-band race from
|
|
636
|
+
Method 1: a call in the last cycles of line 311 would pass `wait_hi`
|
|
637
|
+
there and take `bpl is_ntsc` on line 0. Technique: `pal_ntsc_detection`
|
|
638
|
+
in `techniques/raster.md`; recipe: `recipes/oscar64/pal-ntsc-detect.md`.
|
|
639
|
+
|
|
640
|
+
This is the shortest reliable detect. It does not distinguish R8 from
|
|
641
|
+
R56A — for that, use the Method 1 `detect_region` routine above, whose
|
|
642
|
+
Y register ends as $06 on the R8 and $05 on the R56A (measured in VICE
|
|
643
|
+
x64sc 3.10, `-model ntsc` and `-model oldntsc`, not on hardware).
|
|
644
|
+
|
|
645
|
+
### Method 3: Read the KERNAL's own flag at $02A6
|
|
646
|
+
|
|
647
|
+
The stock C64 KERNAL does store a region byte. At reset ($FCFB ->
|
|
648
|
+
JSR $FF5B) it runs the screen-editor init at $E518, whose VIC register
|
|
649
|
+
table sets the raster compare to line 311 ($D011 = $9B, $D012 = $37)
|
|
650
|
+
and clears $D019; $FF5B then waits for $D012 = 0, reads $D019 bit 0
|
|
651
|
+
and stores it at $02A6: 0 = NTSC, 1 = PAL (also 1 on 312-line
|
|
652
|
+
PAL-N/Drean, which it cannot tell from PAL). It then jumps to $FDDD,
|
|
653
|
+
which reads $02A6 to choose the CIA #1 timer A jiffy latch; $F42C
|
|
654
|
+
reads it again to pick the RS-232 baud table. Read from the 901227-03
|
|
655
|
+
ROM image ($FF5B: `20 18 E5 AD 12 D0 D0 FB AD 19 D0 29 01 8D A6 02 4C
|
|
656
|
+
DD FD`). Measured in VICE x64sc after boot: $02A6 = 1 on the PAL and
|
|
657
|
+
Drean models, 0 on NTSC 6567R8 and 6567R56A.
|
|
658
|
+
|
|
659
|
+
It is plain RAM written once at reset, so trust it only if nothing has
|
|
660
|
+
overwritten it, and it cannot separate R8 from R56A. $D030 has nothing
|
|
661
|
+
to do with it: on a C64 the address is unmapped and reads $FF; on the
|
|
662
|
+
C128 it is the VIC-IIe 2 MHz/test register, read/write (bit 0 toggles
|
|
663
|
+
when written, measured in x128), and carries no region information. An
|
|
664
|
+
earlier version of this page said the stock KERNAL stores no region
|
|
665
|
+
byte and called $D030 a read-only C128 region flag; both statements
|
|
666
|
+
were wrong.
|
|
667
|
+
|
|
668
|
+
**Recommendation:** Use Method 2 (poll $D012 while RST8=1) for simple
|
|
669
|
+
PAL/NTSC distinction. Use Method 1's `detect_region` to distinguish R8
|
|
670
|
+
from R56A (Y = $06 / $05; measured in VICE x64sc 3.10, `-model ntsc`
|
|
671
|
+
and `-model oldntsc`, not on hardware), or `time_frame` if you want the
|
|
672
|
+
cycle count itself. $02A6 is a free check only when you know nothing
|
|
673
|
+
has touched it since reset.
|
|
674
|
+
|
|
675
|
+
## Region-portability checklist
|
|
676
|
+
|
|
677
|
+
When writing code intended to run on both regions, parameterize
|
|
678
|
+
the following:
|
|
679
|
+
|
|
680
|
+
- [ ] **CPU clock constant.** Define a symbol (e.g., `CPU_CLOCK`)
|
|
681
|
+
and select it at startup based on detected region. Used by
|
|
682
|
+
anything that converts seconds -> cycles.
|
|
683
|
+
- [ ] **SID frequency table.** Carry two tables. Select pointer
|
|
684
|
+
at startup. Cost: ~192 bytes per table.
|
|
685
|
+
- [ ] **CIA timer values.** Any timer set to "once per frame" or
|
|
686
|
+
"once per N frames" must be region-scaled. Hardcoding
|
|
687
|
+
$4CC7 breaks NTSC; hardcoding $42C6 breaks PAL.
|
|
688
|
+
- [ ] **Music driver tick rate.** If the driver is authored at
|
|
689
|
+
50 Hz tick rate, decide whether to (a) accept the 20% tempo
|
|
690
|
+
jump on NTSC, (b) skip 1 frame in 6 on NTSC to approximate
|
|
691
|
+
50 Hz, or (c) ship a re-tuned NTSC version of the music data.
|
|
692
|
+
- [ ] **Raster IRQ line numbers.** Most line numbers are
|
|
693
|
+
region-independent because the display window is the same.
|
|
694
|
+
But anything placed below the display window must be checked
|
|
695
|
+
against the NTSC wrap point: lines 263-311 do not exist on the
|
|
696
|
+
6567R8 (262-311 on the R56A) — a raster IRQ set there never
|
|
697
|
+
fires on NTSC (measured in VICE x64sc: an IRQ at line 262 fires
|
|
698
|
+
on both regions, one at line 263 fires only on PAL). Lines
|
|
699
|
+
251-262 exist in both regions. An earlier version of this page
|
|
700
|
+
said lines 252-262 did not exist on NTSC; they do.
|
|
701
|
+
- [ ] **Sprite multiplexer schedule.** If multiplexer slots are
|
|
702
|
+
placed in the bottom blanking, they must be moved or
|
|
703
|
+
eliminated on NTSC.
|
|
704
|
+
- [ ] **Side-border-open timing.** Use a region-dispatch table
|
|
705
|
+
for the cycle offset.
|
|
706
|
+
- [ ] **Digi playback rate.** If using a CIA timer for the
|
|
707
|
+
sample rate, scale by clock ratio. If using a raster IRQ
|
|
708
|
+
(one sample per line), the rate auto-adjusts.
|
|
709
|
+
- [ ] **Visible Y range assumptions.** Don't write to $D011
|
|
710
|
+
bits 0-2 (vertical scroll) assuming a specific display
|
|
711
|
+
offset on screen.
|
|
712
|
+
- [ ] **Frame counter overflow.** A frame counter that wraps
|
|
713
|
+
every N seconds wraps at different real times on PAL vs
|
|
714
|
+
NTSC. If timestamps matter, compute in frames and convert
|
|
715
|
+
to seconds at display time.
|
|
716
|
+
- [ ] **Game speed.** Per-frame movement deltas must be scaled by
|
|
717
|
+
the frame-period ratio 50.125/59.826 = 0.838 when moving from
|
|
718
|
+
PAL authoring to NTSC. A delta is applied once per frame, so it
|
|
719
|
+
scales with the frame rate, not with the cycles in a frame; an
|
|
720
|
+
earlier version of this page gave the cycles-per-frame ratio
|
|
721
|
+
17,095/19,656 = 0.870, which is the CPU-budget ratio and leaves
|
|
722
|
+
the game 3.8% fast (the NTSC/PAL clock ratio). Many ported
|
|
723
|
+
European games skip the scaling and play 19.4% faster on U.S.
|
|
724
|
+
machines (the famous "European games run too fast in the U.S."
|
|
725
|
+
problem).
|
|
726
|
+
- [ ] **Loader timing.** Custom IRQ-based loaders that bit-
|
|
727
|
+
bang the serial bus often depend on cycle counts; many
|
|
728
|
+
PAL loaders fail on NTSC because the timing windows
|
|
729
|
+
shift.
|
|
730
|
+
|
|
731
|
+
## Pitfalls
|
|
732
|
+
|
|
733
|
+
- **Music tempo drift**: Hard-coding a single SID frequency table
|
|
734
|
+
causes 4% pitch error and 20% tempo error across regions. See
|
|
735
|
+
[SID frequency table differences](#sid-frequency-table-differences).
|
|
736
|
+
- **Raster IRQ misfire**: A raster IRQ set to fire on line 280
|
|
737
|
+
fires on PAL but never on NTSC (max line is 262). Always
|
|
738
|
+
detect region before installing IRQs that target lines above
|
|
739
|
+
262. See [Detection at runtime](#detection-at-runtime).
|
|
740
|
+
- **Sideborder open on NTSC**: PAL side-border code assumes a
|
|
741
|
+
63-cycle line; on the 6567R8 the loop must be 65 cycles (64 on the
|
|
742
|
+
R56A) and the sprite-stall and badline phases differ, so the write
|
|
743
|
+
no longer lands where it did. The cycle of the write on NTSC is not
|
|
744
|
+
measured here; re-derive it, do not shift it by one on faith. See
|
|
745
|
+
[Border timing differences](#border-timing-differences).
|
|
746
|
+
- **CIA timer A frame timing**: Loading $4CC7 (PAL frame) on
|
|
747
|
+
NTSC fires every 1.15 frames, producing slow scrolling and
|
|
748
|
+
off-beat music. Always set the timer based on detected region.
|
|
749
|
+
- **$D012 raster wrap**: Comparing $D012 against >=256 requires
|
|
750
|
+
combining with $D011 bit 7. The wrap point differs by region
|
|
751
|
+
(312 PAL, 263 NTSC). See `d012_wrap_around` in
|
|
752
|
+
[raster-and-badline.md](../pitfalls/raster-and-badline.md) (RST8
|
|
753
|
+
handling) and `raster_line_count_difference` in
|
|
754
|
+
[region-timing.md](../pitfalls/region-timing.md) (wrap point per
|
|
755
|
+
region).
|
|
756
|
+
- **Digi pitch shift**: A fixed CIA timer produces different
|
|
757
|
+
sample rates on PAL vs NTSC. For accurate cross-region digi,
|
|
758
|
+
scale the timer or use a raster-IRQ-driven (per-line) digi.
|
|
759
|
+
- **Cross-region 6567R56A**: The R56A has 262 lines / 64 cycles
|
|
760
|
+
rather than 263 / 65. Method 1's `detect_region` tells it from the
|
|
761
|
+
R8 by the frame's last line, $05 against $06; the flag-only
|
|
762
|
+
`detect_pal` (Method 2) cannot, and `time_frame` sees 16,768 against
|
|
763
|
+
17,095 cycles.
|
|
764
|
+
- **PAL-N / PAL-M misdetection**: Raster-wrap, frame-timing and
|
|
765
|
+
KERNAL ($02A6) detection all report a PAL-N (Drean, 6572) machine
|
|
766
|
+
as PAL, but its lines are 65 cycles, not 63 (measured in VICE x64sc
|
|
767
|
+
`-model drean`; 20,280 cycles per frame). Cycle-exact PAL code and
|
|
768
|
+
PAL SID tables are wrong there. If you must tell them apart, time a
|
|
769
|
+
frame: 20,280 vs 19,656 cycles ($4F vs $4C in the high byte)
|
|
770
|
+
separates PAL-N from PAL; the raster wrap cannot. PAL-M is
|
|
771
|
+
unmeasured (no VICE model). An earlier version of this bullet said
|
|
772
|
+
PAL was the correct answer for CPU timing on these machines.
|
|
773
|
+
- **Game-speed porting**: Ported games that skip the 50.125/59.826 =
|
|
774
|
+
0.838 movement-delta scaling play 19.4% too fast in the region they
|
|
775
|
+
weren't authored in (the ratio is the frame period, not the
|
|
776
|
+
17,095/19,656 = 0.870 cycle budget this page previously gave). This
|
|
777
|
+
is a content issue, not a hardware issue, but it surfaces during
|
|
778
|
+
region porting.
|
|
779
|
+
- **Visible Y range vs display window**: Setting $D011 bit 3
|
|
780
|
+
(24 vs 25 rows) and bits 0-2 (vertical scroll) on NTSC can
|
|
781
|
+
push the display below the visible area; values that look
|
|
782
|
+
fine on PAL may clip on NTSC.
|
|
783
|
+
|
|
784
|
+
## Cross-references
|
|
785
|
+
|
|
786
|
+
- VIC-II chip register details: [vic-ii-reference.md](vic-ii-reference.md)
|
|
787
|
+
- SID chip register details: [sid-reference.md](sid-reference.md)
|
|
788
|
+
- CIA chip register details: [cia-reference.md](cia-reference.md)
|
|
789
|
+
- $D012 raster-wrap handling: [raster-and-badline.md](../pitfalls/raster-and-badline.md) (`d012_wrap_around`)
|
|
790
|
+
- Per-region raster line count: [region-timing.md](../pitfalls/region-timing.md) (`raster_line_count_difference`)
|
|
791
|
+
|
|
792
|
+
## Source citations
|
|
793
|
+
|
|
794
|
+
- c64-wiki, "PAL": https://www.c64-wiki.com/wiki/PAL — refresh
|
|
795
|
+
rates, frame structure, region geographies.
|
|
796
|
+
- c64-wiki, "NTSC": https://www.c64-wiki.com/wiki/NTSC — NTSC
|
|
797
|
+
timing and chip revisions (6567R56A vs 6567R8).
|
|
798
|
+
- codebase64, "PAL/NTSC compatibility":
|
|
799
|
+
https://codebase64.org/doku.php?id=base:pal_ntsc_compatibility —
|
|
800
|
+
detection routines, region-portability practices.
|
|
801
|
+
- Christian Bauer, "The MOS 6567/6569 video controller (VIC-II)
|
|
802
|
+
and its application in the Commodore 64" (cebix mirror):
|
|
803
|
+
https://www.cebix.net/VIC-Article.txt — per-region cycle tables,
|
|
804
|
+
raster geometry, border-open cycle windows.
|
|
805
|
+
- VICE 3.10, `x64sc`, models `default`, `ntsc`, `oldntsc` — the
|
|
806
|
+
instrument behind every figure marked measured under Method 2
|
|
807
|
+
(the three wrap bytes, the entry-line runs, the `wait_lo` race,
|
|
808
|
+
the CIA-timed durations). https://vice-emu.sourceforge.io/
|
|
809
|
+
- KickAssembler 5.25 — assembled the Method 1 and Method 2 listings.
|
|
810
|
+
- VICE's `kernal-901227-03.bin` — the bytes at $FF5B, $E518,
|
|
811
|
+
$ECB9 and $FDDD behind Method 3 and the IOINIT timer values.
|
|
812
|
+
|
|
813
|
+
<!-- doc-type: hardware-reference -->
|