Claim set · data/claims/zelda-save.yaml

The Legend of Zelda's battery save (Aldo Núñez's disassembly and the US ROM)

Game: The Legend of Zelda.

The Legend of Zelda keeps three save files in battery-backed cartridge RAM; each holds an 8-byte name, a 40-byte item block, 384 bytes of world flags, and four single bytes (whether the slot is in use, one unlabeled byte, the death count, and the quest), with a 16-bit checksum that is the plain sum of those 436 bytes, and, kept apart and outside the sum, two marker bytes, $5A and $A5. zelda-save/file

About: The Legend of Zelda Password and battery save

Value
{
 "files": 3,
 "fields": [
  {
   "what": "name",
   "bytes": 8
  },
  {
   "what": "items",
   "bytes": 40
  },
  {
   "what": "world flags",
   "bytes": 384
  },
  {
   "what": "slot in use",
   "bytes": 1
  },
  {
   "what": "unlabeled",
   "bytes": 1
  },
  {
   "what": "death count",
   "bytes": 1
  },
  {
   "what": "quest number",
   "bytes": 1
  }
 ],
 "check": "16-bit sum of the 436 bytes",
 "markers": [
  90,
  165
 ]
}
CodeLegend of Zelda, The (USA) (Rev 1) · 0x6-0x6 — header flags 6, $12: bit 1 set, battery-backed PRG RAM at $6000-$7FFFzelda1-disassembly: A complete disassembly of The Legend of Zelda · src/Variables.inc#L301-L323SaveRamBegin := $6001 SaveFileAName0 := $6002 … SaveFileAItems0 := $601A … SaveFileAWorldFlags0 := $6092 … SaveFileOpenMarkers := $651E SaveFileCloseMarkers := $6521 FileAChecksums := $6524 IsSaveFileBCommitted := $652Azelda1-disassembly: A complete disassembly of The Legend of Zelda · src/Z_02.asm#L2319-L2372CalculateFileAChecksum: … LDY #$07 ; Sum the name (8 bytes). … LDY #$27 ; Add the Items block ($28 bytes) to [$0F:0E]. … LDY #$00 ; Add World Flags ($180 bytes) to [$0F:0E]. … LDA ($06), Y ; IsSaveSlotActive JSR AddATo0F0E LDA ($08), Y ; TODO: Add byte at [[$08:09]] to [$0F:0E]. JSR AddATo0F0E …zelda1-disassembly: A complete disassembly of The Legend of Zelda · src/Z_02.asm#L2289-L2295LDA SaveFileOpenMarkers, Y ; Are the static markers intact? CMP #$5A BNE @FormatA LDA SaveFileCloseMarkers, Y CMP #$A5Checked by claude, 2026-10-22 — read CalculateFileAChecksum and the save RAM definitions at the pinned commit (bank 2 and the definitions match Rev 1, per the source record); read the Rev 1 header byte

The sum adds each byte into a 16-bit total with carry, so it catches a changed byte but not two bytes swapped. Aldo Núñez leaves the fourth single byte unnamed (a TODO). CalculateFileAChecksum reads only the name, items, world flags, and the four single bytes; the markers ($651E, $6521) and the sum itself are checked on their own.

Cited by: Password and battery save

The Legend of Zelda saves in two steps; it first writes the whole file to a second copy, file B, sums it, stores that sum, and marks B uncommitted, and on the next step it sums B again and, if the sums agree, clears file A's markers, copies B over A, writes A's markers and sum, and marks B committed. zelda-save/two-step-save

About: The Legend of Zelda Password and battery save

Codezelda1-disassembly: A complete disassembly of The Legend of Zelda · src/Z_02.asm#L2944-L3046UpdateModeDSave_Sub0: ; Initialize file B, and copy profile to it. ; Calculate and store file B checksum. ; Mark file B uncommitted. … UpdateModeDSave_Sub1: LDY CurSaveSlot LDA IsSaveFileBCommitted, Y BNE @IncSubmode JSR FetchFileBAddressSet JSR CalculateFileBChecksum … …zelda1-disassembly: A complete disassembly of The Legend of Zelda · src/Z_02.asm#L3048-L3140CopyFileBToFileA: LDY CurSaveSlot LDA #$00 ; Reset the save file markers. STA SaveFileOpenMarkers, Y STA SaveFileCloseMarkers, Y … LDA #$5A ; Write the save file markers. … TYA ; Copy the checksum from file B to file A. … LDA #$FF ; File B has been committed. STA IsSaveFileBCommitted, Yzelda1-disassembly: A complete disassembly of The Legend of Zelda · src/Z_02.asm#L1350-L1360SaveFileBAddressSets: .BYTE $98, $68, $10, $69, $80, $68, $90, $6Dzelda1-disassembly: A complete disassembly of The Legend of Zelda · src/Variables.inc#L325LevelBlockAttrsA := $687EChecked by claude, 2026-10-22 — read UpdateModeDSave's first two submodes and CopyFileBToFileA at the pinned commit

File B's pointers start at $6898 (items), $6910 (world flags), and $6880 (name), in battery RAM from $6880 to $6D9B; the disassembly also labels that range as level data (LevelBlockAttrsA from $687E). The commit flag, IsSaveFileBCommitted, is itself in battery RAM at $652A.

Cited by: Password and battery save

When its title demo or its file select screen starts, The Legend of Zelda checks each of the three slots; a file B still marked uncommitted whose sum matches is copied over file A, finishing a save that was cut off, and a file A whose markers are not $5A and $A5 or whose sum doesn't match is formatted, its name set to spaces and every other byte to 0. zelda-save/file-check

About: The Legend of Zelda Password and battery save

Codezelda1-disassembly: A complete disassembly of The Legend of Zelda · src/Z_02.asm#L2252-L2316; For each save slot: ; If file B is uncommitted and valid, then ; Copy file B to file A (also marks file B committed) ; If file A's static markers are wrong or file is invalid, then ; Format file A … LDA FileAChecksums, Y ; Does the checksum match? CMP $0E BNE @FormatA … @FormatA: JSR FetchFileAAddressSet …zelda1-disassembly: A complete disassembly of The Legend of Zelda · src/Z_02.asm#L2374-L2410FormatFileA: LDY #$07 LDA #$24 ; Make the name 8 spaces. … LDY #$27 ; Reset the file's Items block. LDA #$00 … LDY #$00 ; Reset World Flags ($180 bytes) at [$02:03]. … STA ($06), Y ; Reset the file's IsSaveSlotActive.Checked by claude, 2026-10-22 — read UpdateMode0Demo_Sub1 and FormatFileA at the pinned commit

The routine is submode 1 of mode 0, the demo, and the init of mode 1, the file select screen. FormatFileA then writes a fresh sum and the markers, so an erased slot reads as an empty, valid file.

Cited by: Password and battery save