On this page
  1. How it works
  2. Implementations
  3. History
  4. Related
  5. Games
  6. References
  7. Sources

A cartridge game keeps progress after power-off either as a password, which the player copies down and types back in, or in RAM that a battery on the cartridge keeps alive. The games read here range from Mega Man 2’s grid of 9 dots1, to Dragon Warrior’s ten copies of each save, each with its own CRC2.

  • PasswordMega Man 2 (1988). Nine dots on a grid record the bosses beaten and the Energy Tanks.1,3,4,5,6
  • Password with a check valueMetroid (1986). 24 characters of 6 bits holding 18 bytes, with an 8-bit sum and a random rotation.7,8,9,10,11,12,13Castlevania II: Simon's Quest (1987). A password keeps Simon's items, whip, and day, but not his hearts.14,15,16,17
  • Battery save with a check valuePokémon Red and Blue (1996). One copy with a complemented 8-bit sum.18,19
  • Battery save with copiesDragon Warrior (1986). The Famicom original gives a password to write down; the NES cartridge keeps three adventures, each written ten times over.20,21,22,23,2,24The Legend of Zelda (1986). Three files with a 16-bit sum and marker bytes; each save goes to a scratch copy first.25,26,27

#How it works

A password packs the state into as few symbols as possible. Metroid uses 6 bits a symbol, 24 symbols for 18 bytes8. A check value lets the game reject a mistyped code: Metroid stores the sum of its other bytes9. Metroid then rotates its first 16 bytes by a random count of 1-15 bits and stores the count in the password, so, as the code reads, one state can encode to more than one password9.

A battery save keeps the bytes themselves. A check value tells the game that a file has changed since it was written19. A second copy gives it one to fall back on27,2.

Kept asHoldsCheckOn a failure
Mega Man 29 dots on a 5 by 5 grid1E-tanks and 8 bosses beaten6each boss must have a dot5PASSWORD ERROR, back to the menu5
Metroid24 characters of 6 bits818 bytes: items, area, gear, missiles, age78-bit sum, after a rotation9ERROR TRY AGAIN for 120 frames10
Castlevania II: Simon’s Quest16 characters of 5 bits15level, day, laurels, garlics, items, whip1416-bit sum, after an XOR and an add16MISS ENTRY, then the prompt again17
Pokémon Red and Blueone copy in battery RAM18the whole game, party, and current box18complemented 8-bit sum18“The file data is destroyed!”; no save file19
The Legend of Zeldaa file and a scratch copy26436 bytes per file2516-bit sum and two marker bytes25finish the save from the copy, or erase the file27
Dragon Warriorten copies of a 32-byte record2experience, gold, items, flags, name, HP, MP2216-bit CRC23load the first good copy; with none, erase the slot2

#Implementations

#Mega Man 2

The grid’s top row holds the E-tank count, one dot in five cells. The other 20 cells give each of the 8 Robot Masters a “beaten” cell and a “not beaten” cell, with 4 cells left over3. The E-tank count shifts which cell is which, wrapping around the 204. The decoder accepts any grid that covers every boss with at least one of its cells5. The weapons and the three items follow from the bosses beaten6.

#Metroid

The 18 bytes hold one bit for each of 59 items, doors, and Tourian objects, the starting area, the suit bit, equipment, missiles, and Samus’s age7. To make a password, the game sums 17 bytes into the 18th, then rotates the first 16 as one 128-bit number by a random 1-15 bits9. Entering one reverses the rotation and compares the sum, and nothing else10. A password made after Mother Brain’s defeat brings her back, along with the zebetites and Tourian’s doors12.

Before any of this, the game compares the first 16 characters with NARPASSWORD00000, a code that, every frame, writes $03 to Samus’s health high byte, $FF to her equipment byte, and 5 to her missile count11. JUSTIN BAILEY ------ ------ has no such case: by the atlas’s decoding of the lines it is an ordinary password whose sum happens to match, with the bit that drops Samus’s suit set13.

#Simon’s Quest

The 16 characters hold 10 bytes: Simon’s level, the day count, the laurels and garlics, three item bytes, and the whip, then a 16-bit sum of those seven and a scramble byte14. Each character carries 5 bits and is one of 36 symbols, which by the atlas’s reading of the font’s glyphs are A-Z and 0-915. The frame counter picks one of 16 XOR tables and an add of 0-4. The first 14 characters are XORed with the table and then raised by the add, and the last two carry the choice in the clear, so one state has up to 16 passwords16. The decoder rejects a blank character, a sum that doesn’t match, or a field out of range, such as a day digit above 9, and writes MISS ENTRY17. Hearts aren’t kept: a password starts Simon with none, 48 HP, and 3 lives14.

#Pokémon Red and Blue

One copy of the game sits in battery RAM, followed by a single check byte, the complement of the bytes’ 8-bit sum18. A mismatch on loading prints “The file data is destroyed!” and the main menu then offers no save to continue19.

#The Legend of Zelda

Each of the three files carries a 16-bit sum and two marker bytes, $5A and $A525. A save goes to a scratch copy first, marked uncommitted, and is copied over the file only after its sum checks out again26. When the file screen starts, an uncommitted copy that checks out is finished, and a file that fails its markers or its sum is erased27.

#Dragon Warrior

A save is a 32-byte record with a 16-bit CRC over its first 30 bytes22,23. The game writes it 10 times; loading takes the first copy that passes and rewrites the other nine from it2. The string KEN MASUTA, kept before and after the save slots, tells it whether the RAM held anything at all; if neither copy is intact, every slot is erased24.

#History

Games

GameYearHowNote
Dragon Warrior II1987the Famicom original gives a password at a king's castle; the NES cartridge records the game when the party visits a king
Dragon Warrior III1988the cartridge keeps three adventure logs, written when the party visits a king
Mega Man 61993a password grid resumes from the stage where it was given
Sonic 3 & Knuckles1994six games kept on the Sonic 3 cartridge, each saved when it ends or Reset is pressed
Mega Man 21988Passwordnine dots on a grid record the bosses beaten and the Energy Tanks
Metroid1986Password with a check value24 characters of 6 bits holding 18 bytes, with an 8-bit sum and a random rotation
Castlevania II: Simon's Quest1987Password with a check valuea password keeps Simon's items, whip, and day, but not his hearts
Pokémon Red and Blue1996Battery save with a check valueone copy with a complemented 8-bit sum
Dragon Warrior1986Battery save with copiesthe Famicom original gives a password to write down; the NES cartridge keeps three adventures, each written ten times over
The Legend of Zelda1986Battery save with copiesthree files with a 16-bit sum and marker bytes; each save goes to a scratch copy first
Every claim about this mechanic, by game (25)
Dragon Warrior 1986Dragon Warrior saves the hero as a 32-byte record in battery-backed cartridge RAM; bytes 0-1 hold experience, 2-3 gold, 4-7 the inventory, 8 the magic keys (capped at 6), 9 the herbs, 10 the equipment, 11-13 spell, player, and story flags, 14-21 the name, 22 the message speed, 23 HP, 24 MP, 25 whether HP and MP are refilled at the start, 26-29 the filler byte $C8, and 30-31 a check value.Code
Dragon Warrior's check value is a 16-bit CRC of the record's first 30 bytes, read from byte 29 down to byte 0, one bit at a time from the top, with the polynomial $1021 and both bytes seeded with $1D.Code
Dragon Warrior writes each save 10 times, one record after another, into its slot's 320 bytes; loading checks the copies in order, counts each one whose CRC fails, loads the first that passes, and rewrites all 10 from it, and if none passes the game marks the slot invalid (clearing its valid flag and mask bit, not its data) and says no deeds were recorded.Code
Dragon Warrior marks its battery RAM as initialized with the 10 ASCII bytes KEN MASUTA, written both before and after the three save slots; before showing the saved games it checks the copy after the slots and then the one before, and only if neither matches does it erase all three slots, then rewrites both copies.Code
Metroid 1986Metroid's password holds 18 bytes; bytes 0-7 carry one bit for each of 59 items, doors, and Tourian objects collected, byte 8 the starting area (bits 0-5) and whether Samus wears her suit (bit 7), byte 9 her equipment, byte 10 her missile count, bytes 11-13 her age, byte 15 the Kraid and Ridley statue and defeat bits, byte 14 a copy of the RAM byte after the age, which nmikstas labels unused, byte 16 a scramble count, and byte 17 a check byte.Code
Metroid writes the 18 bytes as 24 characters of 6 bits each, three bytes to every four characters, from a 64-symbol set of 0-9, A-Z, a-z, ?, and -; the entry grid's 65th symbol, a space, enters as $FF, all 8 bits set.Code
To make a password, Metroid sums bytes 0-16 into byte 17, then rotates bytes 0-15 right as one 128-bit number, one bit at a time, as many times as byte 16 says; byte 16 is the low 4 bits of a random byte, redrawn until it is not 0.Code
When the player presses Start, Metroid rebuilds the 18 bytes from the 24 characters, rotates bytes 0-15 back left by byte 16's count, and compares their sum with byte 17; on a mismatch it plays the wrong-password sound and shows ERROR TRY AGAIN for 120 frames, and on a match it starts the game; nothing else in the password is checked.Code
Metroid compares the first 16 characters entered with NARPASSWORD00000 before anything else and, on a match, sets a flag and ignores the rest; while that flag is set, the game engine writes $03 to Samus's health high byte, $FF to her equipment byte, and 5 to her missile count, every frame.Code
If Mother Brain has been destroyed when Metroid makes a password, it clears her bit and every Tourian bit in bytes 6 and 7, so the password brings back Mother Brain, the zebetites, and Tourian's missile doors.Code
Computed from the decoder's lines, the password JUSTIN BAILEY ------ ------ passes; after 255 rotations, its bytes 0-16 sum to $FF mod 256, which equals its check byte, byte 17, and byte 8's bit 7 is set, which the game loads as Samus without her suit.Code
The Legend of Zelda 1986The 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.Code
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.Code
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.Code
Castlevania II: Simon's Quest 1987Simon's Quest's password packs 10 bytes: 7 of state, the byte FoxCunning labels Simon's level, the day count in BCD, the laurel and garlic counts in 4 bits each (the encoder writes a count above 8 as 8), the bytes labeled body parts, misc items 1, and misc items 2, and the whip level; then the 16-bit sum of those 7 as a check value; then a scramble byte. Hearts are not kept: accepting a password zeroes the bytes FoxCunning labels hearts and experience, sets HP to 48 and lives to 3, and zeroes $30 and $50-$57 (labeled the map type, scene, sub-room, and scroll position), $82 (night), $84, and $85 (the time wait counter and the minute).Code
Simon's Quest writes the 10 bytes, 80 bits, as 16 characters of 5 bits each, high bit first, so the scramble byte fills the last 8 bits; the screen draws a value n as tile n + 1 of CHR bank 16, where by the atlas's reading of the tiles 1-36 are A-Z and 0-9. Since the scramble adds up to 4 to characters 1-14, they can show all 36 (computed), and characters 15 and 16 only A-Z and 0-5. On the entry grid, pressing A on cells 0-35 enters that symbol, cells 36 and 37 step the cursor back and forward, and a later cell submits.Code
To make a password, Simon's Quest sums the 7 state bytes into a 16-bit check value and takes a scramble from the frame counter: its low 4 bits number one of 16 tables of 14 XOR values, and its low 3 bits pick an add from 0, 1, 2, 3, 4, 1, 2, 3. After packing, characters 1-14 are XORed with the table and then have the add added; characters 15 and 16 carry the add and the table number unscrambled. Since the add follows from the table number, one state has at most 16 passwords (computed).Code
On entry Simon's Quest rejects a password with any of its 16 characters blank. Otherwise it subtracts the add from characters 1-14, XORs them, unpacks the 10 bytes, and accepts only when both bytes of the sum match the 7 state bytes again, the level is below 7, the body-parts and misc-items-2 bytes are below $80, misc items 1 is below $10, the whip level is below 5, both of the day's digits are 0-9, and laurels and garlics are each at most 8. A rejection writes MISS and ENTRY to the screen, plays sound $24, and after 128 frames brings back the ENTER YOUR PASSWORD prompt and returns to input, writing nothing to the entered characters on the way; an acceptance writes ENTRY COMPLETED.Code
Mega Man 2 1988Mega Man 2's password is 9 dots on a 5 by 5 grid; the entry screen counts down from 9 as the player places dots with A and takes them back with B, and reads the password when the ninth is placed.Code
Mega Man 2's password holds the E-tank count and, for each of the 8 Robot Masters, whether he is beaten; a dot in the top row's first five cells gives 0-4 E-tanks, and each Robot Master has one "beaten" cell and one "not beaten" cell among the other 20, which also include 4 cells that mean nothing.Code
Mega Man 2 shifts the 20 boss cells by the E-tank count; table entry i goes to cell 5 + (E-tanks + i) mod 20, wrapping from the last cell back to the first cell of the second row, so the same bosses beaten give a different grid for each E-tank count.Code
Mega Man 2 reads the E-tank count as the first dot in the top row's first four cells, or 4 if none of them holds one, without looking at the fifth; it then ORs each dotted cell's boss into a beaten byte or a not-beaten byte and accepts the password only if the two together cover all 8 bosses, else it writes PASSWORD ERROR ! and, after two waits of 125 frames, returns to the menu of START and PASSWORD.Code
A correct Mega Man 2 password gives Mega Man the weapon of every boss in its beaten byte, Item 1 if Heat Man is beaten, Item 2 if Air Man is, and Item 3 if Flash Man is, plus its E-tank count; the password holds nothing else.Code
Pokémon Red and Blue 1996Pokémon Red and Blue keep one copy of the game in battery-backed cartridge RAM (the player's name, the main data, the map's sprites, the party, the current PC box, and one byte for tile animations), followed by a check byte that is the complement of the 8-bit sum of all those bytes.Code
When Pokémon Red and Blue load, they recompute the check byte for each of the three parts they copy (the main data twice before giving up), and on a mismatch print "The file data is destroyed!", wait 100 frames, and set the save status to 1, which the main menu treats as no save file; the saved bytes are not erased.Code

References

  1. ^ abcMega Man 2's password is 9 dots on a 5 by 5 grid; the entry screen counts down from 9 as the player places dots with A and takes them back with B, and reads the password when the ninth is placed.Codelsmmega/mm2
    How we know
    107	LDA #$09
    108	STA aobject_frameset_lower_timer
    
    engine/password.asm lines 105–108 at 94f0bf3 · upstream ↗
    165	BEQ @skip
    ⋮
    168	AND #a_button
    169	BEQ @b_pressed
    170	LDA aobject_flag, X
    171	BNE @skip
    172	track_queue track_1up
    173	INC aobject_flag, X
    174	DEC aobject_frameset_lower_timer
    175	BEQ @all_ball_set
    176	BNE @skip
    ⋮
    178@b_pressed:
    179	LDA aobject_flag, X
    ⋮
    
    engine/password.asm lines 162–189 at 94f0bf3 · upstream ↗
    18password_oamycoord:
    19	.BYTE $40, $40, $40, $40, $40
    ⋮
    25password_oamxcoord:
    26	.BYTE $41, $51, $61, $71, $81
    27	.BYTE $41, $51, $61, $71, $81
    28	.BYTE $41, $51, $61, $71, $81
    29	.BYTE $41, $51, $61, $71, $81
    30	.BYTE $41, $51, $61, $71, $81
    
    data/password/password_oam.asm lines 18–30 at 94f0bf3 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  2. ^ abcdefDragon Warrior writes each save 10 times, one record after another, into its slot's 320 bytes; loading checks the copies in order, counts each one whose CRC fails, loads the first that passes, and rewrites all 10 from it, and if none passes the game marks the slot invalid (clearing its valid flag and mask bit, not its data) and says no deeds were recorded.Codenmikstas/dragon-warrior-disassembly
    How we know
    662.alias SavedGame1       $6068   ;Through $61A7. Save game slot 1. Data repeated 10 times.
    ⋮
    666.alias CRCFail1         $6432   ;CRC failures for save game 1.
    
    source_files/Dragon_Warrior_Defines.asm lines 662–668 at ebe6a13 · upstream ↗
    9815LF9F9:  JSR SaveData            ;($FA18)Save player's data to battery backed RAM.
    9816LF9FC:  JSR GetCRC              ;($FBE0)Get CRC for selected game data.
    ⋮
    9825LFA0F:  JSR Save10Times         ;($FAA3)Save game data 10 times accross different addresses.
    
    source_files/Bank03.asm lines 9798–9832 at ebe6a13 · upstream ↗
    9980LFAD0:  LDX #$0A                ;Prepare to copy game data to 10 different locations.
    ⋮
    9986LFAD4:  JSR CheckValidCRC       ;($FB4A)Check if the CRC for the selected save game is valid.
    9987LFAD7:  BCS CRCCheckFail        ;Is data valid? If not, branch.
    ⋮
    9989LFAD9:  JSR LoadSavedData       ;($FB6B)Load save game data into game engine registers.
    ⋮
    9997LFAE9:  JSR Copy10Times         ;($FB15)Copy of saved game data 10 times to same addresses.
    ⋮
    10005LFAF3:  LDX SaveNumber          ;Increment CRC fail counter.
    10006LFAF6:  INC CRCFail1,X          ;
    ⋮
    10022LFB0A:  LDA #$FF                ;Indicate saved game data cannot be successfully copied.
    
    source_files/Bank03.asm lines 9966–10035 at ebe6a13 · upstream ↗
    9320LF781:  JSR Copy100Times        ;($FAC1)Make up to 100 copies of saved game to validate.
    9321LF784:  CMP #$00                ;Is RAM for saved game valid?
    9322LF786:  BEQ DoneValidateSave    ;If so, branch to check next saved game.
    ⋮
    9324LF788:  LDA SaveNumber          ;Saved game RAM was corrupted. Erase game.
    9325LF78B:  JSR ClearValidSaves     ;($F80F)Clear ValidSave variable for selected game.
    ⋮
    9337LF79E:  JSR DoDialogHiBlock     ;($C7C5)Unfortunately no deeds were recorded...
    
    source_files/Bank03.asm lines 9315–9338 at ebe6a13 · upstream ↗
    9455LF834:  AND #$06                ;Clear LSB of saved game bit mask.
    9456LF836:  LDX #$00                ;Clear ValidSave1.
    9457LF838:  STX ValidSave1          ;
    ⋮
    9460LF83B:  STA SaveBitMask         ;Update valid save game bit mask.
    
    source_files/Bank03.asm lines 9455–9460 at ebe6a13 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  3. ^ abMega Man 2's password holds the E-tank count and, for each of the 8 Robot Masters, whether he is beaten; a dot in the top row's first five cells gives 0-4 E-tanks, and each Robot Master has one "beaten" cell and one "not beaten" cell among the other 20, which also include 4 cells that mean nothing.Codelsmmega/mm2
    How we know
    1password_boss_clear_set:
    2	.BYTE no_boss_clear,        boss_heatman_clear,  no_boss_clear,        boss_quickman_clear, boss_woodman_clear
    ⋮
    7password_boolean:
    8	.BYTE boss_clear_yes, boss_clear_yes, boss_clear_yes, boss_clear_yes, boss_clear_no
    
    data/password/password.asm lines 1–11 at 94f0bf3 · upstream ↗
    31;boss clear flags
    32	no_boss_clear        = 0
    33	boss_heatman_clear   = 1 << 0
    ⋮
    42;boss clear in password
    43.ENUM
    44	boss_clear_yes
    45	boss_clear_no
    
    constants/flags.asm lines 30–46 at 94f0bf3 · upstream ↗
    29	LDA z:zgot_weapon_flag
    30	STA z:z00
    31	EOR #%11111111
    32	STA z:z01
    33	CLC
    34	LDA z:ze_tank
    35	TAX
    36	ADC #$05
    37	STA z:z03
    38	INC aobject_flag, X
    ⋮
    42	LDY password_boolean, X
    43	LDA a:z00, Y
    ⋮
    
    engine/show_password.asm lines 29–60 at 94f0bf3 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  4. ^ abMega Man 2 shifts the 20 boss cells by the E-tank count; table entry i goes to cell 5 + (E-tanks + i) mod 20, wrapping from the last cell back to the first cell of the second row, so the same bosses beaten give a different grid for each E-tank count.Codelsmmega/mm2
    How we know
    34	LDA z:ze_tank
    35	TAX
    36	ADC #$05
    37	STA z:z03
    ⋮
    51	INY
    52	CPY #$19
    53	BNE @next_1
    54	LDY #$05
    
    engine/show_password.asm lines 33–57 at 94f0bf3 · upstream ↗
    202@get_e_tank:
    203	STX z:z04
    204	TXA
    205	CLC
    206	ADC #$05
    207	TAX
    ⋮
    226	INX
    227	CPX #$19
    228	BNE @check_continue
    229	LDX #$05
    
    engine/password.asm lines 202–235 at 94f0bf3 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  5. ^ abcdMega Man 2 reads the E-tank count as the first dot in the top row's first four cells, or 4 if none of them holds one, without looking at the fifth; it then ORs each dotted cell's boss into a beaten byte or a not-beaten byte and accepts the password only if the two together cover all 8 bosses, else it writes PASSWORD ERROR ! and, after two waits of 125 frames, returns to the menu of START and PASSWORD.Codelsmmega/mm2revised
    How we know
    195@loop_6:
    196	LDA aobject_flag, X
    197	BNE @get_e_tank
    198	INX
    199	CPX #$04
    200	BNE @loop_6
    ⋮
    213@loop_7:
    214	LDA aobject_flag, X
    215	BEQ @ball_not_set
    216	LDY z:z01
    217	LDA password_boss_clear_set, Y
    218	PHA
    ⋮
    
    engine/password.asm lines 189–273 at 94f0bf3 · upstream ↗
    10	.BYTE "@START@@@"
    ⋮
    19	.BYTE "@PASSWORD@"
    ⋮
    28	.BYTE "PASSWORD@"
    ⋮
    37	.BYTE "ERROR@!@@@"
    
    data/password/strings.asm lines 1–37 at 94f0bf3 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Revised after a check by a second AI model, 2026-10-22.

    In the claim ledger

  6. ^ abcA correct Mega Man 2 password gives Mega Man the weapon of every boss in its beaten byte, Item 1 if Heat Man is beaten, Item 2 if Air Man is, and Item 3 if Flash Man is, plus its E-tank count; the password holds nothing else.Codelsmmega/mm2
    How we know
    275@correct:
    276	LDA z:z02
    277	STA z:zgot_weapon_flag
    278	AND #%00000011
    279	STA z:zgot_item_flag
    280	LDA z:zgot_weapon_flag
    281	AND #%00100000
    282	LSR
    283	LSR
    284	LSR
    285	ORA z:zgot_item_flag
    286	STA z:zgot_item_flag
    ⋮
    
    engine/password.asm lines 275–288 at 94f0bf3 · upstream ↗
    33	boss_heatman_clear   = 1 << 0
    34	boss_airman_clear    = 1 << 1
    ⋮
    38	boss_flashman_clear  = 1 << 5
    
    constants/flags.asm lines 30–39 at 94f0bf3 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  7. ^ abcMetroid's password holds 18 bytes; bytes 0-7 carry one bit for each of 59 items, doors, and Tourian objects collected, byte 8 the starting area (bits 0-5) and whether Samus wears her suit (bit 7), byte 9 her equipment, byte 10 her missile count, bytes 11-13 her age, byte 15 the Kraid and Ridley statue and defeat bits, byte 14 a copy of the RAM byte after the age, which nmikstas labels unused, byte 16 a scramble count, and byte 17 a check byte.Codenmikstas/metroid-disassemblyrevised
    How we know
    615.alias PasswordByte00   $6988   ;Stores status of items 0 thru 7.
    ⋮
    622.alias PasswordByte07   $698F   ;Stores status of items 56 thru 58(bits 0 thru 2).
    623.alias PasswordByte08   $6990   ;start location(bits 0 thru 5), Samus suit status (bit 7).
    624.alias PasswordByte09   $6991   ;Stores SamusGear.
    625.alias PasswordByte0A   $6992   ;Stores MissileCount.
    ⋮
    629.alias PasswordByte0E   $6996   ;Stores no data.
    630.alias PasswordByte0F   $6997   ;Stores Statue statuses(bits 4 thu 7).
    631.alias PasswordByte10   $6998   ;Stores value RandomNumber1.
    632.alias PasswordByte11   $6999   ;Stores sum of $6988 thru $6998(Checksum).
    
    Source_Files/Metroid_Defines.asm lines 615–632 at 4270d57 · upstream ↗
    1655L8C9E:* LDA InArea              ;Store InArea in bits 0 thru 5 in
    ⋮
    1659L8CA7:  ORA #$80                ;Sets MSB of $6990 is Samus is suitless.
    1660L8CA9:* STA PasswordByte08      ;
    1661L8CAC:  LDA SamusGear           ;
    1662L8CAF:  STA PasswordByte09      ;SamusGear stored in $6991.
    1663L8CB2:  LDA MissileCount        ;
    1664L8CB5:  STA PasswordByte0A      ;MissileCount stored in $6992.
    ⋮
    1692L8CF2:  STA PasswordByte0F      ;Stores statue statuses in 4 MSB at $6997.
    1693L8CF5:  LDY #$03                ;
    1694L8CF7:* LDA SamusAgeLo,Y        ;Store SamusAgeLo in $6993,
    1695L8CFA:  STA PasswordByte0B,Y    ;SamusAgeMid in $6994 and
    
    Source_Files/Bank00.asm lines 1655–1697 at 4270d57 · upstream ↗
    589.alias SamusAgeLo       $687D   ;Low byte of Samus' age.
    ⋮
    592.alias SamusStat01      $6880   ;Unused memory address for storing Samus info.
    
    Source_Files/Metroid_Defines.asm lines 589–592 at 4270d57 · upstream ↗
    1554L8BDD:  LDA #$3B                ;
    1555L8BDF:  STA $07                 ;Maximum number of unique items(59 or #$3B).
    
    Source_Files/Bank00.asm lines 1549–1560 at 4270d57 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Revised after a check by a second AI model, 2026-10-22.

    In the claim ledger

  8. ^ abcMetroid writes the 18 bytes as 24 characters of 6 bits each, three bytes to every four characters, from a 64-symbol set of 0-9, A-Z, a-z, ?, and -; the entry grid's 65th symbol, a space, enters as $FF, all 8 bits set.Codenmikstas/metroid-disassembly
    How we know
    1884;The following code takes the 18 password bytes and converts them into 24 characters
    1885;to be displayed to the player as the password.  NOTE: the two MSBs will always be 0.
    
    Source_Files/Bank00.asm lines 1884–1885 at 4270d57 · upstream ↗
    1962SixUpperBits:
    1963L8F2D:  LDA PasswordByte00,Y    ;Uses six upper bits to create a new byte.
    ⋮
    1968TwoLoAndFourUp:
    ⋮
    1978FourLoAndTwoUp:
    ⋮
    1992SixLowerBits:
    1993L8F5A:  LDA PasswordByte00,Y    ;Discard bits 6 and 7.
    
    Source_Files/Bank00.asm lines 1962–1995 at 4270d57 · upstream ↗
    3016PasswordRow0:
    3017;              0    1    2    3    4    5    6    7    8    9    A    B    C
    ⋮
    3032PasswordRow4:
    3033;              q    r    s    t    u    v    w    x    y    z    ?    -  Space
    
    Source_Files/Bank00.asm lines 3016–3034 at 4270d57 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  9. ^ abcdeTo make a password, Metroid sums bytes 0-16 into byte 17, then rotates bytes 0-15 right as one 128-bit number, one bit at a time, as many times as byte 16 says; byte 16 is the low 4 bits of a random byte, redrawn until it is not 0.Codenmikstas/metroid-disassembly
    How we know
    1698L8D00:* JSR $C000               ;
    1699L8D03:  LDA RandomNumber1       ;
    1700L8D05:  AND #$0F                ;Store the value of $2E at $6998
    1701L8D07:  BEQ -                   ;When any of the 4 LSB are set. (Does not
    1702L8D09:  STA PasswordByte10      ;allow RandomNumber1 to be a multiple of 16).
    1703L8D0C:  JSR PswrdChksmNScrmbl   ;($8E17)Calculate checksum and scramble password.
    
    Source_Files/Bank00.asm lines 1698–1704 at 4270d57 · upstream ↗
    1836L8E17:  JSR PasswordChecksum    ;($8E21)Store the combined added value of
    1837L8E1A:  STA PasswordByte11      ;addresses $6988 thu $6998 in $6999.
    1838L8E1D:  JSR PasswordScramble    ;($8E2D)Scramble password.
    ⋮
    1844L8E25:* CLC                     ;Add the values at addresses
    1845L8E26:  ADC PasswordByte00,Y    ;$6988 thru $6998 together.
    ⋮
    1857L8E3B:* ROR PasswordByte00,X    ;Rotate right, including carry, all values in
    1858L8E3E:  INX                     ;addresses $6988 thru $6997.
    ⋮
    1861L8E42:  ROR $00                 ;Rotate right $6988 to ensure the LSB
    1862L8E44:  LDA $00                 ;from address $6997 is rotated to the
    1863L8E46:  STA PasswordByte00      ;MSB of $6988.
    1864L8E49:  DEC $02                 ;
    1865L8E4B:  BNE --                  ;Continue rotating until $02=0.
    
    Source_Files/Bank00.asm lines 1835–1866 at 4270d57 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  10. ^ abcWhen the player presses Start, Metroid rebuilds the 18 bytes from the 24 characters, rotates bytes 0-15 back left by byte 16's count, and compares their sum with byte 17; on a mismatch it plays the wrong-password sound and shows ERROR TRY AGAIN for 120 frames, and on a match it starts the game; nothing else in the password is checked.Codenmikstas/metroid-disassembly
    How we know
    1626L8C5E:  JSR ConsolidatePassword ;($8F60)Convert password characters to password bytes.
    1627L8C61:  JSR ValidatePassword    ;($8DDE)Verify password is correct.
    1628L8C64:  BCS +                   ;Branch if incorrect password.
    1629L8C66:  JMP InitializeGame      ;($92D4)Preliminary housekeeping before game starts.
    1630L8C69:* LDA MultiSFXFlag        ;
    1631L8C6C:  ORA #$01                ;Set IncorrectPassword SFX flag.
    ⋮
    1634L8C73:  STA Timer3              ;Set Timer3 time for 120 frames (2 seconds).
    
    Source_Files/Bank00.asm lines 1625–1637 at 4270d57 · upstream ↗
    1818L8DF7:* JSR UnscramblePassword  ;($8E4E)Unscramble password.
    1819L8DFA:  JSR PasswordChecksum    ;($8E21)Calculate password checksum.
    1820L8DFD:  CMP PasswordByte11      ;Verify proper checksum.
    1821L8E00:  BEQ +                   ;
    1822L8E02:  SEC                     ;If password is invalid, sets carry flag.
    
    Source_Files/Bank00.asm lines 1818–1825 at 4270d57 · upstream ↗
    1869L8E4E:  LDA PasswordByte10      ;Stores random number used to scramble the password.
    ⋮
    1874L8E5A:* ROL PasswordByte00,X    ;The following loop rolls left the first 16 bytes
    
    Source_Files/Bank00.asm lines 1868–1882 at 4270d57 · upstream ↗
    2274L9169:  LDA Timer3              ;
    2275L916B:  BEQ +                   ;
    2276L916D:  LDA #$59                ;
    
    Source_Files/Bank00.asm lines 2274–2276 at 4270d57 · upstream ↗
    809;The following error message is diplayed if the player enters an incorrect password.
    810;              E    R    R    O    R    _    T    R    Y    _    A    G    A    I    N
    811L8759:  .byte $0E, $1B, $1B, $18, $1B, $FF, $1D, $1B, $22, $FF, $0A, $10, $0A, $12, $17
    
    Source_Files/Bank00.asm lines 809–811 at 4270d57 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-25.

    Checked by a second AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-25.

    In the claim ledger

  11. ^ abMetroid compares the first 16 characters entered with NARPASSWORD00000 before anything else and, on a match, sets a flag and ignores the rest; while that flag is set, the game engine writes $03 to Samus's health high byte, $FF to her equipment byte, and 5 to her missile count, every frame.Codenmikstas/metroid-disassembly
    How we know
    1810L8DE5:* LDA PasswordChar00,Y    ;
    1811L8DE8:  CMP NARPASSWORDTbl,Y    ;If NARPASSWORD was entered at the
    1812L8DEB:  BNE +                   ;password screen, activate invincible
    1813L8DED:  DEY                     ;Samus, else continue to process password.
    ⋮
    1828;NOTE: any characters after the 16th character will be ignored if the first 16 characters
    1829;match the values below.
    ⋮
    1832;              N    A    R    P    A    S    S    W    O    R    D    0    0    0    0    0
    
    Source_Files/Bank00.asm lines 1806–1833 at 4270d57 · upstream ↗
    1592LC931:  lda NARPASSWORD         ;
    1593LC934:  beq +                   ;
    1594LC936:  lda #$03                ;The following code is only accessed if 
    1595LC938:  sta HealthHi            ;NARPASSWORD has been entered at the 
    1596LC93B:  lda #$FF                ;password screen. Gives you new health,
    1597LC93D:  sta SamusGear           ;missiles and every power-up every frame.
    1598LC940:  lda #$05                ;
    1599LC942:  sta MissileCount        ;
    
    Source_Files/Bank07.asm lines 1592–1599 at 4270d57 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  12. ^ abIf Mother Brain has been destroyed when Metroid makes a password, it clears her bit and every Tourian bit in bytes 6 and 7, so the password brings back Mother Brain, the zebetites, and Tourian's missile doors.Codenmikstas/metroid-disassembly
    How we know
    1647L8C8A:  LDA PasswordByte07      ;
    1648L8C8D:  AND #$04                ;Check to see if mother brain has been defeated,
    1649L8C8F:  BEQ +                   ;If so, restore mother brain, zeebetites and
    1650L8C91:  LDA #$00                ;all missile doors in Tourian as punishment for
    1651L8C93:  STA PasswordByte07      ;dying after mother brain defeated. Only reset in the
    1652L8C96:  LDA PasswordByte06      ;password.  Continuing without resetting will not
    1653L8C99:  AND #$03                ;restore those items.
    1654L8C9B:  STA PasswordByte06      ;
    
    Source_Files/Bank00.asm lines 1647–1654 at 4270d57 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  13. ^ abComputed from the decoder's lines, the password JUSTIN BAILEY ------ ------ passes; after 255 rotations, its bytes 0-16 sum to $FF mod 256, which equals its check byte, byte 17, and byte 8's bit 7 is set, which the game loads as Samus without her suit.Codenmikstas/metroid-disassemblyrevised
    How we know
    2001L8F60:  LDY #$00                ;Password characters #$00 and #$01.
    2002L8F62:  JSR SixLowerAndTwoUpper ;($8FF1)
    2003L8F65:  STA PasswordByte00      ;Store results.
    
    Source_Files/Bank00.asm lines 2000–2020 at 4270d57 · upstream ↗
    2057SixLowerAndTwoUpper:
    2058L8FF1:  LDA PasswordChar00,Y    ;Remove upper two bits and transfer
    ⋮
    2067FourLoNFiveThruTwo:
    ⋮
    2077TwoLowerAndSixLower:
    2078L9011:  LDA PasswordChar00,Y    ;Shifts two lower bits to two higest bits
    
    Source_Files/Bank00.asm lines 2057–2086 at 4270d57 · upstream ↗
    1869L8E4E:  LDA PasswordByte10      ;Stores random number used to scramble the password.
    
    Source_Files/Bank00.asm lines 1868–1882 at 4270d57 · upstream ↗
    1712L8D1F:  LDA PasswordByte08      ;If MSB in PasswordByte08 is set,
    1713L8D22:  AND #$80                ;Samus is not wearing her suit.
    1714L8D24:  BEQ +                   ;           
    1715L8D26:  INY                     ;
    1716L8D27:* STY JustInBailey        ;
    
    Source_Files/Bank00.asm lines 1712–1716 at 4270d57 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Revised after a check by a second AI model, 2026-10-22.

    In the claim ledger

  14. ^ abcdSimon's Quest's password packs 10 bytes: 7 of state, the byte FoxCunning labels Simon's level, the day count in BCD, the laurel and garlic counts in 4 bits each (the encoder writes a count above 8 as 8), the bytes labeled body parts, misc items 1, and misc items 2, and the whip level; then the 16-bit sum of those 7 as a check value; then a scramble byte. Hearts are not kept: accepting a password zeroes the bytes FoxCunning labels hearts and experience, sets HP to 48 and lives to 3, and zeroes $30 and $50-$57 (labeled the map type, scene, sub-room, and scroll position), $82 (night), $84, and $85 (the time wait counter and the minute).Code“Castlevania II - Simon's Quest (USA)” · FoxCunning/Castlevania2revised
    How we know

    In the cartridge (“Castlevania II - Simon's Quest (USA)”): bank 4 $AF21-$AF61, EncodePassword_Compress: $8B, $83, $4C and $4D (each ANDed with $0F, then 8 if 8 or more, garlics shifted into the high nibble), $91, $92, $4A, and $0434 copied to $0520-$0526; bank 4 $AE3E-$AE5D, EncodePassword_CreateChecksum: $0520-$0526 summed with carry into $0527 (high) and $0528 (low); bank 4 $AEFB-$AF20, EncodePassword_CreateAddSub and its table: the add shifted into the high nibble of $0529, the XOR number in the low; bank 4 $AD47-$ADB5, the accepted path: $0434 kept on the stack across a JSR to $C5A1, then a JSR to $C419, $90, $4F, $33, $1E, $82, $30, $50-$57, $84, and $85 zeroed, $80 = $30, $31 = 3; bank 7 $C419-$C423, ResetHeartsAndExp: zero to $48, $49, $46, $47. We don't reproduce the bytes.

    48	Edigits0011 = $46						; $46
    ⋮
    51	HeartsDigits1100 = $49					; $49
    
    globals.inc lines 48–51 at 2abe12c · upstream ↗
    33	CurrentLevelMapType = $30							; $30
    34	RemainingLives = $31								; $31
    
    globals.inc lines 33–34 at 2abe12c · upstream ↗
    52	InventoryMiscItems2 = $4A				; $4A
    ⋮
    54	InventoryNumLaurels = $4C				; $4C
    55	InventoryNumGarlics = $4D				; $4D
    ⋮
    58	CurrentLevelSceneNumber = $50					; $50
    59	CurrentLevelSubRoomNumber = $51					; $51
    60	CurrentXScrollingPositionPixels = $53			; $53
    61	CurrentXScrollingPositionScreens = $54			; $54
    62	CurrentYScrollingPositionPixels_Mod240 = $56	; $56
    63	Current_WhatUnknown57 = $57						; $57
    
    globals.inc lines 52–63 at 2abe12c · upstream ↗
    88	CurrentHP = $80					; $80
    ⋮
    90	IsNightTime = $82				; $82
    91	CurrentDayBCD = $83				; $83
    92	CurrentTimeWaitCounter = $84	; $84
    93	CurrentMinuteBCD = $85			; $85
    
    globals.inc lines 88–93 at 2abe12c · upstream ↗
    102	InventoryBodyParts1 = $91						; $91
    103	InventoryMiscItems1 = $92						; $92
    
    globals.inc lines 102–103 at 2abe12c · upstream ↗
    258	CurrentWhipLevel = $0434				; $0434
    
    globals.inc line 258 at 2abe12c · upstream ↗
    97	CurrentLevel = $8B								; $8B
    
    globals.inc line 97 at 2abe12c · upstream ↗
    301	PasswordLevel = $0520				; $0520
    302	PasswordCurrentDayBCD = $0521		; $0521
    303	PasswordLaurelsGarlics = $0522		; $0522
    304	PasswordBodyparts = $0523			; $0523
    305	PasswordMiscItems1 = $0524			; $0524
    306	PasswordMiscItems2 = $0525			; $0525
    307	PasswordWhipLevel = $0526			; $0526
    308	PasswordChecksumHi = $0527			; $0527
    309	PasswordChecksumLo = $0528			; $0528
    310	PasswordXorAdd = $0529				; $0529
    
    globals.inc lines 301–310 at 2abe12c · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Revised after a check by a second AI model, 2026-10-22.

    In the claim ledger

  15. ^ abcSimon's Quest writes the 10 bytes, 80 bits, as 16 characters of 5 bits each, high bit first, so the scramble byte fills the last 8 bits; the screen draws a value n as tile n + 1 of CHR bank 16, where by the atlas's reading of the tiles 1-36 are A-Z and 0-9. Since the scramble adds up to 4 to characters 1-14, they can show all 36 (computed), and characters 15 and 16 only A-Z and 0-5. On the entry grid, pressing A on cells 0-35 enters that symbol, cells 36 and 37 step the cursor back and forward, and a later cell submits.Code“Castlevania II - Simon's Quest (USA)”revised
    How we know

    In the cartridge (“Castlevania II - Simon's Quest (USA)”): bank 4 $AFC7-$B0D9, EncodePassword_Convert8_to_6: $0520-$0529 shifted and masked, high bits first, into 5-bit values at $0530-$053F; bank 4 $AB75-$ABA2: the tile sent to the screen is the cursor cell ($04F4) plus 1, kept in $0F; a cleared character sends 0; bank 4 $AB3F-$AB66, A pressed: a cell below $24 enters a character, $24 and $25 decrement and increment the character position, any other advances the screen's state to the check; bank 4 $ABF9-$AC26: entering stores $0F at $0540 + position; clearing stores 0; bank 7 $C394-$C39C, before the entry screen: $10 and $11 written to $0101 and $0102, FoxCunning's Mapper1reg_reg1 and reg2, the 4 KB CHR banks; CHR ROM bank 16, tiles $01-$26: the glyphs A to Z, 0 to 9, a left arrow, and a right arrow. We don't reproduce the bytes.

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Revised after a check by a second AI model, 2026-10-22.

    In the claim ledger

  16. ^ abcTo make a password, Simon's Quest sums the 7 state bytes into a 16-bit check value and takes a scramble from the frame counter: its low 4 bits number one of 16 tables of 14 XOR values, and its low 3 bits pick an add from 0, 1, 2, 3, 4, 1, 2, 3. After packing, characters 1-14 are XORed with the table and then have the add added; characters 15 and 16 carry the add and the table number unscrambled. Since the add follows from the table number, one state has at most 16 passwords (computed).Code“Castlevania II - Simon's Quest (USA)”
    How we know

    In the cartridge (“Castlevania II - Simon's Quest (USA)”): bank 4 $AE24-$AE3D, EncodePassword: compress, checksum, choose the scramble, pack, XOR, add; bank 4 $AE3E-$AE5D: 16-bit sum of $0520-$0526; bank 4 $AEFB-$AF20: FrameCounter ($1D) AND 7 indexes the 8-entry add table, AND $0F gives the XOR number; bank 4 $B205-$B327, Password_DoXorring: 16 pointers to 14-byte tables, each value below $20, XORed into $0530-$053D; bank 4 $AEE9-$AEFA, EncodePassword_DoAdding: the add added to $0530-$053D. We don't reproduce the bytes.

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  17. ^ abcOn entry Simon's Quest rejects a password with any of its 16 characters blank. Otherwise it subtracts the add from characters 1-14, XORs them, unpacks the 10 bytes, and accepts only when both bytes of the sum match the 7 state bytes again, the level is below 7, the body-parts and misc-items-2 bytes are below $80, misc items 1 is below $10, the whip level is below 5, both of the day's digits are 0-9, and laurels and garlics are each at most 8. A rejection writes MISS and ENTRY to the screen, plays sound $24, and after 128 frames brings back the ENTER YOUR PASSWORD prompt and returns to input, writing nothing to the entered characters on the way; an acceptance writes ENTRY COMPLETED.Code“Castlevania II - Simon's Quest (USA)” · FoxCunning/Castlevania2revised
    How we know

    In the cartridge (“Castlevania II - Simon's Quest (USA)”): bank 4 $AD16-$AD46, DecodePassword_VerifyIt: any 0 at $0540-$054F goes to the error; each value less 1 into $0530-$053F; the error sends string $59, sets the delay to $80, plays $24; bank 4 $AE15-$AE23, DecodePassword: read the scramble, subtract, XOR, unpack, check; bank 4 $AFA6-$AFC6, DecodePassword_LastByte: XOR number from $053F's low 4 bits, add from $053F bit 4 and $053E bits 0-2; bank 4 $AF94-$AFA5, DecodePassword_DoSubbing: the add subtracted from $0530-$053D; bank 4 $B0DA-$B204, DecodePassword_Convert6_to_8: the 5-bit values back into $0520-$0528; bank 4 $AE5E-$AEE0, DecodePassword_VerifyChecksum and its maxima $07, $FF, $FF, $80, $10, $80, $05: the sum recomputed and both bytes compared, level below 7, bytes 3-6 below their maxima, each day nibble below $0A, each laurel and garlic nibble below 9; on a pass, string $5A and sound $25; bank 4 $ADB6-$ADC5: count the delay down, send string $5B, set state 2; bank 4 $ADFE-$AE01, where the error jumps: increment the state ($04EF), 3 to 4; bank 4 $AAA2-$AABD, the screen's dispatch on $04EF: state 2 is $AB0C, the input handler, 3 is $AD16, the check, 4 is $ADB6, the wait. We don't reproduce the bytes.

    327	PasswordInputtedCode0 = $0540		; $0540
    
    globals.inc line 327 at 2abe12c · upstream ↗

    In the cartridge (“Castlevania II - Simon's Quest (USA)”): bank 7 $C9EA-$CA03, string $59: tiles spelling MISS, then ENTRY and two punctuation tiles; bank 7 $CA04-$CA1D, string $5A: ENTRY, then COMPLETED. We don't reproduce the bytes.

    1434	.word (PPU_Text_StringsList_59_bank7_PasswordError) ;C9EA (1C9EA) ([8:8][A:9])
    1435	.word (PPU_Text_StringsList_5A_bank7_EntryCompleted) ;CA04 (1CA04) ([8:8][A:9])
    1436	.word (PPU_Text_StringsList_5B_bank7_EnterYourPassword) ;CA1E (1CA1E) ([8:8][A:9])
    
    bank_7.asm lines 1434–1436 at 2abe12c · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Revised after a check by a second AI model, 2026-10-22.

    In the claim ledger

  18. ^ abcdePokémon Red and Blue keep one copy of the game in battery-backed cartridge RAM (the player's name, the main data, the map's sprites, the party, the current PC box, and one byte for tile animations), followed by a check byte that is the complement of the 8-bit sum of all those bytes.Codepret/pokered
    How we know
    12SECTION "Save Data", SRAM
    ⋮
    16sGameData::
    17sPlayerName::  ds NAME_LENGTH
    18sMainData::    ds wMainDataEnd - wMainDataStart
    19sSpriteData::  ds wSpriteDataEnd - wSpriteDataStart
    20sPartyData::   ds wPartyDataEnd - wPartyDataStart
    21sCurBoxData::  ds wBoxDataEnd - wBoxDataStart
    22sTileAnimations:: db
    23sGameDataEnd::
    24sMainDataCheckSum:: db
    
    ram/sram.asm lines 12–24 at af51989 · upstream ↗
    290SaveGameData::
    ⋮
    297CalcCheckSum:
    298;Check Sum (result[1 byte] is complemented)
    299	ld d, 0
    300.loop
    301	ld a, [hli]
    302	add d
    303	ld d, a
    304	dec bc
    305	ld a, b
    306	or c
    307	jr nz, .loop
    ⋮
    
    engine/menus/save.asm lines 290–310 at af51989 · upstream ↗
    237	ld hl, sGameData
    238	ld bc, sGameDataEnd - sGameData
    239	call CalcCheckSum
    240	ld [sMainDataCheckSum], a
    
    engine/menus/save.asm lines 237–240 at af51989 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  19. ^ abcdWhen Pokémon Red and Blue load, they recompute the check byte for each of the three parts they copy (the main data twice before giving up), and on a mismatch print "The file data is destroyed!", wait 100 frames, and set the save status to 1, which the main menu treats as no save file; the saved bytes are not erased.Codepret/pokered
    How we know
    1TryLoadSaveFile:
    ⋮
    5	call LoadMainData
    6	jr c, .badsum
    7	call LoadCurrentBoxData
    8	jr c, .badsum
    9	call LoadPartyAndDexData
    10	jr c, .badsum
    11	ld a, $2 ; good checksum
    ⋮
    13.badsum
    ⋮
    17	ld hl, FileDataDestroyedText
    18	call PrintText
    19	ld c, 100
    ⋮
    
    engine/menus/save.asm lines 1–57 at af51989 · upstream ↗
    1_FileDataDestroyedText::
    2	text "The file data is"
    3	line "destroyed!"
    
    data/text/text_3.asm lines 1–3 at af51989 · upstream ↗
    32	ld a, [wSaveFileStatus]
    33	cp 1
    34	jr z, .noSaveFile
    
    engine/menus/main_menu.asm lines 32–34 at af51989 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  20. ^The Famicom original saves by password, the "revival spell", which the King gives the player to write down before stopping.ManualDragon Quest FC manual
    How we know
    ゲームをやめるときは、必ず王様に会いにいき、復活の呪文を書きとっておいてください。
    section まえの続きをするには (p. 7) · archived copy ↗

    The quote matches our archived copy.

    Checked by a second AI model, 2026-10-23.

    In the claim ledger

  21. ^The North American release saves to a battery in the cartridge, holding up to three games as Adventure Logs, recorded by visiting King Lorik in Tantegel Castle.ManualDragon Warrior Explorer's Handbook · Dragon Warrior NES manual
    How we know
    Pak has a battery in it. This allows it to save your game … Up to three different games can be saved at once
    p. 2, Option Screen · archived copy ↗
    To save your game, you must return to Tantegel Castle and visit King Lorik on the second floor.
    PDF p. 15 (pp. 27-28), Visit the King · archived copy ↗

    The quote matches our archived copy.

    Checked by a second AI model, 2026-10-23.

    In the claim ledger

  22. ^ abcDragon Warrior saves the hero as a 32-byte record in battery-backed cartridge RAM; bytes 0-1 hold experience, 2-3 gold, 4-7 the inventory, 8 the magic keys (capped at 6), 9 the herbs, 10 the equipment, 11-13 spell, player, and story flags, 14-21 the name, 22 the message speed, 23 HP, 24 MP, 25 whether HP and MP are refilled at the start, 26-29 the filler byte $C8, and 30-31 a check value.Code“Dragon Warrior (USA) (Rev 1)” · nmikstas/dragon-warrior-disassembly
    How we know

    In the cartridge (“Dragon Warrior (USA) (Rev 1)”): header flags 6, $12: bit 1 set, battery-backed PRG RAM at $6000-$7FFF. We don't reproduce the bytes.

    9836SaveData:
    9837LFA18:  LDY #$00                ;Zero out index.
    ⋮
    9841LFA1E:  INY                     ;Save player's experience points.
    ⋮
    9847LFA26:  STA (GameDatPtr),Y      ;Save player's gold.
    ⋮
    9868LFA46:  CMP #$07                ;Does player have more than 6 keys?
    ⋮
    9871LFA4A:  LDA #$06                ;6 keys max.
    ⋮
    9911LFA7D:  LDA MessageSpeed        ;Save player's message speed.
    ⋮
    9915LFA82:  LDA HitPoints           ;Save player's hit points.
    ⋮
    9919LFA87:  LDA MagicPoints         ;Save player's magic points.
    ⋮
    9923LFA8E:  LDA StartStatus1,X      ;Save player's restart status.
    ⋮
    9927LFA94:  LDA #$C8                ;
    ⋮
    9931LFA9A:  STA (GameDatPtr),Y      ;Fill spare bytes.
    
    source_files/Bank03.asm lines 9836–9936 at ebe6a13 · upstream ↗
    10198LFBE3:  LDY #$1E                ;CRC is stored in bytes 31 and 32 of saved game data.
    
    source_files/Bank03.asm lines 10196–10198 at ebe6a13 · upstream ↗
    658.alias StartStatus1     $6045   ;#$78=Full HP and MP on start, #$AB=Do not restore, Save game 1.
    
    source_files/Dragon_Warrior_Defines.asm lines 658–660 at ebe6a13 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  23. ^ abcDragon Warrior's check value is a 16-bit CRC of the record's first 30 bytes, read from byte 29 down to byte 0, one bit at a time from the top, with the polynomial $1021 and both bytes seeded with $1D.Codenmikstas/dragon-warrior-disassembly
    How we know
    10209DoCRC:
    10210LFBEF:  LDY #$1D                ;30 bytes of saved game data.
    ⋮
    10212LFBF1:  STY CRCLB               ;Seed the LFSR.
    10213LFBF3:  STY CRCUB               ;
    ⋮
    10215LFBF5:* LDA (GameDatPtr),Y      ;Loop until all saved data bytes are processed.
    10216LFBF7:  STA GenByte3C           ;
    10217LFBF9:  JSR DoLFSR              ;($FC2A)Put data through an LFSR.
    10218LFBFC:  DEY                     ;
    
    source_files/Bank03.asm lines 10209–10220 at ebe6a13 · upstream ↗
    10265LFC2C:  LDY #$08                ;
    10266LFC2E:* LDA CRCUB               ;
    10267LFC30:  EOR GenByte3C           ;
    10268LFC32:  ASL CRCLB               ;
    10269LFC34:  ROL CRCUB               ;
    10270LFC36:  ASL GenByte3C           ;
    10271LFC38:  ASL                     ;Some kind of linear feedback shift register I think.
    10272LFC39:  BCC +                   ;The saved data is run though this function and a 16-bit
    10273LFC3B:  LDA CRCLB               ;CRC appears to be generated. 
    10274LFC3D:  EOR #$21                ;
    10275LFC3F:  STA CRCLB               ;
    10276LFC41:  LDA CRCUB               ;
    ⋮
    
    source_files/Bank03.asm lines 10261–10284 at ebe6a13 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  24. ^ abDragon Warrior marks its battery RAM as initialized with the 10 ASCII bytes KEN MASUTA, written both before and after the three save slots; before showing the saved games it checks the copy after the slots and then the one before, and only if neither matches does it erase all three slots, then rewrites both copies.Codenmikstas/dragon-warrior-disassembly
    How we know
    9242GetValidSaves:
    9243LF6F4:  LDX #$09                ;Prepare to check for Ken Masuta's name in battery backed RAM.
    9244LF6F6:* LDA KenMasuta1,X        ;
    9245LF6F9:  CMP KenMasutaTbl,X      ;Check if Ken's name is intact in the battery backed RAM.
    9246LF6FC:  BNE InitSaves           ;Is the name correct? If not, branch to invalidae all saved games.
    ⋮
    9254LF706:* LDA KenMasuta2,X        ;
    ⋮
    9257LF70C:  BNE ClearSaveGameRAM    ;If not, RAM values are corrupt. Branch to rease saved games.
    ⋮
    9269LF71A:* STA SavedGame1,X        ;Clear first 256 bytes of save game data for all slots.
    ⋮
    9295LF753:  LDX #$09                ;Write Ken Masuta's name to 2 different RAM locations.
    
    source_files/Bank03.asm lines 9242–9300 at ebe6a13 · upstream ↗
    10321KenMasutaTbl:
    10322;              K    E    N    _    M    A    S    U    T    A
    10323LFC76:  .byte $4B, $45, $4E, $20, $4D, $41, $53, $55, $54, $41 
    
    source_files/Bank03.asm lines 10321–10323 at ebe6a13 · upstream ↗
    657.alias KenMasuta2       $603B   ;Through $6044. Stores Ken Masuta's name.
    ⋮
    665.alias KenMasuta1       $6428   ;Through $6431. Stores Ken Masuta's name.
    
    source_files/Dragon_Warrior_Defines.asm lines 657–665 at ebe6a13 · upstream ↗
    9477LF853:  BRK                     ;Load BG and sprite palettes for selecting saved game.
    ⋮
    9480LF856:  JSR GetValidSaves       ;($F6F4)Get valid save game slots.
    
    source_files/Bank03.asm lines 9470–9480 at ebe6a13 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-25.

    Checked by a second AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-25.

    In the claim ledger

  25. ^ abcdThe 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.Code“Legend of Zelda, The (USA) (Rev 1)” · aldonunez/zelda1-disassemblyrevised
    How we know

    In the cartridge (“Legend of Zelda, The (USA) (Rev 1)”): header flags 6, $12: bit 1 set, battery-backed PRG RAM at $6000-$7FFF. We don't reproduce the bytes.

    301SaveRamBegin := $6001
    302SaveFileAName0 := $6002
    ⋮
    305SaveFileAItems0 := $601A
    ⋮
    308SaveFileAWorldFlags0 := $6092
    ⋮
    320SaveFileOpenMarkers := $651E
    321SaveFileCloseMarkers := $6521
    322FileAChecksums := $6524
    323IsSaveFileBCommitted := $652A
    
    src/Variables.inc lines 301–323 at 50a1c86 · upstream ↗
    2321CalculateFileAChecksum:
    ⋮
    2323    STA $0E
    2324    STA $0F
    2325    LDY #$07                    ; Sum the name (8 bytes).
    ⋮
    2329    JSR AddATo0F0E
    ⋮
    2332    LDY #$27                    ; Add the Items block ($28 bytes) to [$0F:0E].
    ⋮
    2336    JSR AddATo0F0E
    ⋮
    2343    LDY #$00                    ; Add World Flags ($180 bytes) to [$0F:0E].
    ⋮
    2347    JSR AddATo0F0E
    ⋮
    2357    LDA ($06), Y                ; IsSaveSlotActive
    2358    JSR AddATo0F0E
    2359    LDA ($08), Y                ; TODO: Add byte at [[$08:09]] to [$0F:0E].
    ⋮
    
    src/Z_02.asm lines 2319–2372 at 50a1c86 · upstream ↗
    2289    LDA SaveFileOpenMarkers, Y  ; Are the static markers intact?
    2290    CMP #$5A
    2291    BNE @FormatA
    2292    LDA SaveFileCloseMarkers, Y
    2293    CMP #$A5
    
    src/Z_02.asm lines 2289–2295 at 50a1c86 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Revised after a check by a second AI model, 2026-10-22.

    In the claim ledger

  26. ^ abcThe 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.Codealdonunez/zelda1-disassembly
    How we know
    2944UpdateModeDSave_Sub0:
    2945    ; Initialize file B, and copy profile to it.
    2946    ; Calculate and store file B checksum.
    2947    ; Mark file B uncommitted.
    2948    JSR FetchFileBAddressSet
    ⋮
    2950    JSR FetchFileBAddressSet
    ⋮
    2959    LDY CurSaveSlot
    ⋮
    2965    LDY CurSaveSlot
    ⋮
    3011    JSR FetchFileBAddressSet
    ⋮
    3016UpdateModeDSave_Sub1:
    3017    LDY CurSaveSlot
    3018    LDA IsSaveFileBCommitted, Y
    ⋮
    
    src/Z_02.asm lines 2944–3046 at 50a1c86 · upstream ↗
    3048CopyFileBToFileA:
    3049    LDY CurSaveSlot
    3050    LDA #$00                    ; Reset the save file markers.
    3051    STA SaveFileOpenMarkers, Y
    3052    STA SaveFileCloseMarkers, Y
    ⋮
    3056    LDA #$00
    ⋮
    3084    LDY CurSaveSlot
    ⋮
    3124    LDY CurSaveSlot
    3125    LDA #$5A                    ; Write the save file markers.
    3126    STA SaveFileOpenMarkers, Y
    ⋮
    3128    STA SaveFileCloseMarkers, Y
    3129    TYA                         ; Copy the checksum from file B to file A.
    ⋮
    
    src/Z_02.asm lines 3048–3140 at 50a1c86 · upstream ↗
    1350SaveFileBAddressSets:
    1351    .BYTE $98, $68, $10, $69, $80, $68, $90, $6D
    
    src/Z_02.asm lines 1350–1360 at 50a1c86 · upstream ↗
    325LevelBlockAttrsA := $687E
    
    src/Variables.inc line 325 at 50a1c86 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  27. ^ abcdWhen 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.Codealdonunez/zelda1-disassembly
    How we know
    2253    ; For each save slot:
    2254    ;   If file B is uncommitted and valid, then
    2255    ;     Copy file B to file A (also marks file B committed)
    2256    ;   If file A's static markers are wrong or file is invalid, then
    2257    ;     Format file A
    ⋮
    2286    JSR FetchFileAAddressSet
    ⋮
    2291    BNE @FormatA
    ⋮
    2298    LDA FileAChecksums, Y       ; Does the checksum match?
    2299    CMP $0E
    2300    BNE @FormatA
    ⋮
    2302    LDA FileAChecksums, Y
    ⋮
    2306@FormatA:
    ⋮
    
    src/Z_02.asm lines 2252–2316 at 50a1c86 · upstream ↗
    2374FormatFileA:
    2375    LDY #$07
    2376    LDA #$24                    ; Make the name 8 spaces.
    ⋮
    2382    LDY #$27                    ; Reset the file's Items block.
    2383    LDA #$00
    ⋮
    2393    LDY #$00                    ; Reset World Flags ($180 bytes) at [$02:03].
    ⋮
    2396    LDA #$00
    ⋮
    2407    LDA #$00
    2408    STA ($06), Y                ; Reset the file's IsSaveSlotActive.
    
    src/Z_02.asm lines 2374–2410 at 50a1c86 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

Sources

Code