UTTORI ASM ยท IN DEVELOPMENT
65816 source export
Export reviewed 65816 analysis as source and raw assets for exact rebuilds.
exportSnes65816Source() converts a validated analysis project and its hash-matching RomImage
into mapper-bank native source. It re-decodes persisted CFG nodes from their recorded incoming
state, emits only compatible non-conflicting boundaries as instructions, and preserves all other
bytes in deterministic incbin assets. The selected internal header, an optional expanded header,
and all 16 native/emulation vector words are emitted as named, decoded db/dw source following
the SNESdev ROM-header and
CPU-vector layouts. Native instructions carry explicit
.b/.w/.l operand qualification. Ambient .a8/.a16/.i8/.i16 directives are
not emitted: explicit operand sizes preserve the encoding without source churn from captured flag changes.
defines.asm covers the SNESdev PPU, MMIO, and DMA/HDMA tables with a hover comment on every
register and compatibility aliases for older names. source prepare uses this pure renderer to
create a verified immutable Git generation; source preview, apply and finish integrate it with
current edits. source build validates and builds ordinary working source.
The editable ram-map.json generates documented symbols in ram-defines.asm and
substitutes them in known memory operands. Entries default to canonical WRAM
($7E0000โ$7FFFFF). Fixed CPU WRAM mirrors resolve to those entries. Declare
"memory": "sram" explicitly for cartridge RAM, using its CPU bus address, for
example { "name": "SRAM_LAST_SELECTED_FILE", "address": "$307FFF", "memory": "sram", "description": "Persistent zero-based file index." }. SRAM entries must fit within
a standard LoROM/HiROM SRAM window. They match only the declared CPU addresses:
the map author must establish the actual cartridge mapping, size and aliases.
They do not create ROM data or permit SRAM bindings in struct-map.json.
To add a WRAM name, edit the generated workspace's user-owned ram-map.json:
{
"format": "uttori-asm-snes-ram-map",
"schemaVersion": 1,
"includeSourceInformation": false,
"variables": [
{ "name": "PlayerHealth", "address": "$7E0100", "size": 2, "description": "Current health." }
]
}
includeSourceInformation defaults to false. Set it to true to include provenance citations
in generated RAM definition comments. Store new citations in each variable's optional sources
array; keep descriptive notes in notes, which remain visible. Existing standalone file/line
citations such as Secret of Mana information.txt:L401. and file paths such as
research/weather.md in notes also follow this setting. References embedded in explanatory prose
are preserved. Descriptions, categories and sizes are always included, and comments end with punctuation.
For example, the default renders RAM_SNOW_AMOUNT = $7ECFF7 ; Party โ Snow amount.;
enabling source information restores its citation. The setting affects generated comments only;
the input map retains all citations.
Keep existing entries when adding a variable. Maps live alongside the assembly, under source/
in newly initialized projects. Declare map paths in .uttori/generation-inputs.json recipes relative
to its sourceRoot. Analyze changed research, prepare a candidate, preview it with current edits,
commit a checkpoint and apply/finish the native merge. Pure rendering generates ram-defines.asm;
the merge preserves and combines ordinary source edits. Store original-identity research in
.uttori/research/ and reusable layouts in struct-map.json.
Pristine asset declarations in the generation recipe pin original bytes with SHA-256 and either the
accepted generation, a bounded romRange, or an immutable originalBlob. Working asset edits stay
in the current source branch. Verify pure generations against the original ROM before integrating
those edits. See CLI source workflow.
An optional struct-map.json beside main.asm binds reusable layouts to RAM or ROM:
Its optional instructionUses metadata accepts checked native expressions and records
capture-backed data references in generated source. See the
instruction-use guide for byte checks and provenance.
{
"format": "uttori-asm-snes-struct-map",
"schemaVersion": 1,
"structures": [
{
"id": "LevelStats",
"size": 3,
"fields": [
{ "name": "hp", "offset": 0, "size": 2, "type": "dw" },
{ "name": "mp", "offset": 2, "size": 1, "type": "db" }
]
}
],
"bindings": [
{
"name": "Levels",
"structure": "LevelStats",
"address": 12615680,
"fileOffset": 32768,
"count": 10
}
]
}
For HiROM, this example places ten records at CPU $C08000, file $008000.
Omit fileOffset for canonical WRAM bindings. Export generates and includes structs.asm,
names known data operands such as Levels.hp,x, and emits complete ROM records as
dataStruct or indexed dataStructs tables with built-in placement checks. Typed fields
use db/dw/dl/dd or arrays such as db[2]. Opaque gaps retain their original bytes.
Interior labels/comments keep the raw field directives and address assertions so their
addresses do not move. The optional metadata type must match size. Size-only v1 inputs
retain their previous scalar convention for sizes 1โ4 and use byte arrays otherwise.
Layout and binding names share the source symbol namespace. Overlapping fields/bindings and conflicts with
exportable code or cartridge headers are rejected. Struct names take precedence over flat
RAM names at bound fields. Unknown addresses keep the existing naming behavior.
firstIndex defaults to zero. Set it to one for one-based tables: address and fileOffset
still locate the first physical entry, while Levels[1].hp names that entry. The native
base is reduced by one record so Levels.hp,x accepts the game's original index. This
biased base is used only for indexed operand naming. Declare the struct map as a generation recipe
so its definitions participate in the next candidate and reviewed native merge. The map and bank
sources remain ordinary editable Git inputs.