Topics

UTTORI ASM ยท IN DEVELOPMENT

SNES output and patching

Use snes output and patching in SNES projects, with syntax and behavior notes.

On this page

SNES behavior

Target Options

Option Values Default Effect
checksumMode "asar", "simple" "asar" Choose mirrored-tail or direct byte summation
checksumEnabled boolean true Write checksum and complement when a header exists
asarSuperFxMoveShortAddress boolean false Reproduce Asar's Super FX short-MOVE operand quirk

Invalid checksumMode values fail during plugin activation. Non-boolean checksumEnabled values normalize to false. Use real JSON booleans rather than strings.

Checksum Finalization

For mapped ROM modes, the output finalizer locates the header according to the mapper, temporarily sets complement/checksum to $FFFF/$0000, computes the 16-bit sum, and writes ~checksum plus checksum at header offsets $1C and $1E.

simple sums every output byte once. asar does the same for power-of-two images. For a non-power-of-two image it mirrors the trailing region to the next power-of-two shape before summing. That mirrors common cartridge behavior described by the wiki's non-power-of-two ROM size article.

Selecting norom disables checksum output. If the image is too short to contain the chosen header plus its checksum fields, finalization leaves it alone.

Fresh Output versus a Patch

Without --base-image, output grows from an empty byte array and gaps use the current fill byte. With a base image, the assembler begins with a copy of those bytes. This makes the following a patch:

lorom
check title
assert read1($00FFD5) == $20, "Wrong base ROM map"

org $0A8000
db $EA,$EA,$EA
npx uttori-asm patch.asm patched.sfc --base-image clean.sfc

The CLI writes a new output path. It does not overwrite the base path unless you explicitly choose the same path. Keeping a pristine base ROM is still the civilized move.