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

Invincibility frames are a window after a hit in which the player can’t be hurt again. The game starts a timer when the hit lands and skips the contact check until it runs out. The Legend of Zelda and Metroid, both released in 1986, do it this way1,2,3,4. In both, the same hit also pushes the character away3,5.

#How it works

on contact with an enemy:
    if timer > 0: nothing happens
    else:         take damage; timer = T; start the knockback
every frame the game counts:
    if timer > 0: timer -= 1

The window is T times the frames per step. The check happens on contact, so an enemy still touching the player when the timer reaches 0 hurts again on that frame25.

#Implementations

#The Legend of Zelda (1986)

A hit sets Link’s timer to 243. DecrementInvincibilityTimer counts it down only on even frames, so a timer of t lasts 2t frames24,24. Measured in the ROM, a monster held against Link hurts him every 47 or 48 frames25, depending on the frame’s parity25. The comment in the code calls the 24 “frames”3.

Monsters use the same timer and routine. A weapon’s hit sets a monster’s timer to 16, which lasts 32 frames26. The clock adds 16 to Link’s timer every frame, which keeps him invincible27.

#Metroid (1986)

A hit sets Samus’s blink counter to $32, which is 505,5. The comment beside it says 32 frames5. The counter drops on every frame of game logic, and the collision code skips enemies while it is above 06,4. Measured in the ROM, hits land 50 frames7 of game logic apart; lag frames can stretch that on screen7.

Lava uses the blink against the player. It holds the counter at 50, which keeps enemies off Samus, while the lava’s own damage keeps coming8.

#Later games

Mega Man 3 starts the window after the knockback: when the hurt state ends, it sets the timer to 60 and counts it down every frame15. Mega Man 2 sets 111 at the moment of the hit15. The atlas hasn’t traced how Mega Man 3 ignores contact during the hurt state itself15.

A hit in Sonic the Hedgehog 2 sets the count to 120, and landing sets it to 120 again; it counts down only in the control routine, so Sonic blinks for 120 frames after he lands18. Where Zelda and Metroid start the window with the push3,5, Sonic’s begins at the landing. Sonic 3 & Knuckles stores the count in a byte, still 120, set by the hit and again on landing21.

A hit in Castlevania III: Dracula’s Curse sets a counter to 120, which counts down once a frame while the character flickers; one branch of the hit code returns at once while it is nonzero14. Reading that counter as invincibility is the atlas’s interpretation14.

#Compared

The Legend of ZeldaMetroid
Timer set by a hit243505
Counts downon even frames24every frame of logic6
Next hit, measured47 or 48 frames2550 frames of logic7
Enemies have oneyes, 32 frames26no claim yet
Damage that ignores itno claim yetlava8
What the code’s comment says“$18 frames”, 24 steps3“32 frames”, hex $325

Both comments miscount their games’ windows: Zelda’s counts timer steps as frames, and Metroid’s reads hex as decimal3,5.

Games

GameYearHowNote
Metroid1986Frame timera 50-frame blink
Mega Man1987Frame timera fixed spell of invincibility after each hit
Mega Man 21988Frame timera fixed spell of invincibility after each hit, as in Mega Man
Super Mario Bros. 21988Frame timera hit sets 127 frames, counted every frame
Super Mario Bros. 31988Frame timera hit sets a blink in which further hits are ignored
Castlevania III: Dracula's Curse1989Frame timerafter a hit the character flickers for a fixed count
Mega Man 31990Frame timera spell of invincibility that starts once the knockback ends
Super Mario World1990Frame timerafter the power-down animation, 127 frames counted every frame
Metroid II: Return of Samus1991Frame timera 51-frame timer that drops each time Samus is drawn
Sonic the Hedgehog1991Frame timerafter a hit he blinks, safe, for a while counted from his landing
The Legend of Zelda: A Link to the Past1991Frame timer58 frames, counted down every frame
Sonic the Hedgehog 21992Frame timerafter a hit he blinks, safe, for a while counted from his landing
Mega Man 61993Frame timerthe timer starts only once the push ends, for a second and a half in all
The Legend of Zelda: Link's Awakening1993Frame timer80 frames, counted down every frame
Sonic 3 & Knuckles1994Frame timera blinking spell after a hit, counted again from the landing
Super Metroid1994Frame timer96 frames after an enemy's touch
The Legend of Zelda: Oracle of Seasons and Oracle of Ages2001Frame timer34 frames after a standard enemy's touch, read from a collision table
The Legend of Zelda: The Minish Cap2004Frame timer30 frames after an Octorok's touch, read from a collision matrix
Super Mario Bros.1985Slow timerafter a hit he can't be hurt again for about two and a half seconds
Super Mario Bros.: The Lost Levels1986Slow timerSuper Mario Bros.'s blink after a hit
The Legend of Zelda1986Slow timer24 on a timer that counts down every other frame
Zelda II: The Adventure of Link1987Slow timera timer of 4 that ticks once every 21 frames, 64 to 84 frames in all
Every claim about this mechanic, by game (32)
Super Mario Bros. 1985A hit on big Mario sets InjuryTimer to 8, and enemy contact is skipped until it is back at 0. It is one of the interval timers, which DecTimers counts down once every 21 frames, so the window lasts 8 such ticks, 148 to 168 frames while the game's timers run.Code
Metroid 1986A hit sets SamusBlink to $32, which is 50, gives Samus an upward speed of $FD with the hit gravity $38, and takes the push direction from the hit; the comment says "Set blink for 32 frames".Code
Each frame, the crash detection skips the contact check between Samus and the enemies while SamusBlink is above 0.Code
CheckHealthStatus, which Samus's routines call once per frame, lowers SamusBlink by 1 each time, so the blink lasts 50 frames of game logic.Code
Measured in the ROM, a crawler held against Samus in Brinstar's first room takes 8 units with each hit, and the next hit lands 50 game frames later; one of the two gaps also held 2 lag frames, for 52 frames of video.Verified
In lava, Samus's blink is set to 50 on every frame, so enemies can't touch her, while the lava takes 0.7 units twice every 8 frames without a push; the Varia suit cuts that to once, and SubtractHealth halves it to 0.3 units.Code
Super Mario Bros.: The Lost Levels 1986A hit on big Mario sets InjuryTimer to 8, as in Super Mario Bros., and the timer counts down once every 21 frames with the interval timers, through the same timer loop as Super Mario Bros.'s.Code
The Legend of Zelda 1986A monster that touches Link while his invincibility timer is above 0 does nothing; a hit sets the timer to 24 and his shove distance to 32 px.Code
DecrementInvincibilityTimer lowers an object's invincibility timer by 1 only on frames when FrameCounter is even, so a timer of t lasts 2t frames.Code
While Link holds the clock, BeginUpdateWorld adds 16 to his invincibility timer every frame, and monsters' contact checks return no collision.Code
Measured in Rev 1, a Tektite held against Link hurts him every 47 or 48 frames, taking half a heart each time; from three hearts, five hits leave $20 and $7D, 3/256 of a heart under a half heart.Verified
A weapon that hurts a monster sets the monster's invincibility timer to 16, which lasts 32 frames, and shoves it 64 px in the weapon's direction, unless the monster is already invincible or immune to the weapon's damage type.Code
Mega Man 1987A hit sets zmegaman_invincibility_time to 111 ($6F); while it is nonzero no contact damages Mega Man, and the stage loop counts it down by 1 on each pass that runs the enemies.Code
Zelda II: The Adventure of Link 1987A hit sets Link's immunity timer to 4 and his injured timer to 32. The game counts the injured timer down every frame but the immunity timer only once every 21 frames, so the immunity lasts 64 to 84 frames, depending on where in the cycle the hit lands.Code
Mega Man 2 1988A hit sets zmegaman_invincibility_time to 111 ($6F); contact damage is skipped while it is nonzero, and it counts down by 1 each time Mega Man's sprite is processed, hiding him on alternate pairs of frames.Code
Super Mario Bros. 2 1988Health is $0F for one mark of the life meter and $10 more for each further mark, up to $3F for four. A hit takes $10, one mark, and sets DamageInvulnTime to $7F, during which DamagePlayer returns at once; the timer drops every frame. If the health left is $10 or more, two marks or more, the hit also launches the player upward at $C0 and sideways at four times the screen distance from the enemy. A hit on the last mark (health under $10) stores no health and sets no invulnerability: it turns the enemy toward the player (for the types before Enemy_BeezoDiving), stuns it for $10 frames, sets the player's vertical speed to $C0 and PlayerStateTimer to $20, and jumps to KillPlayer, which sets the dying state and health to 0. A dying player holds still for those 32 frames, then rises at $C0 and falls back, gaining $02 a frame up to $39, and loses a life once below the screen.Code
Super Mario Bros. 3 1988A hit that doesn't kill Mario, including one that only takes Kuribo's Shoe, sets Player_FlashInv to $71, and Player_GetHurt ignores hits while it is nonzero. Player_Draw counts it down each time it runs, blinking Mario in 2-tick halves.Code
Castlevania III: Dracula's Curse 1989A hit in Dracula's Curse sets $80 to 120, which the player's update counts down once a frame while flickering the character; one branch of the hit handling returns at once while $80, or $AD, is nonzero.Code
Mega Man 3 1990Mega Man 3 starts the invincibility after the knockback: when the hurt state ends it sets invincibility_timer to 60 ($3C), which the prelude counts down every frame. Mega Man 2 sets 111 at the moment of the hit.Code
Super Mario World 1990HurtMario returns at once while IFrameTimer is nonzero. After the power-down animation Super Mario World sets it to $7F, and the timer loop counts it down on every frame the sprites aren't locked.Code
The Legend of Zelda: A Link to the Past 1991A monster's touch does nothing while Link's blink timer is above 0. A hit sets it to 58, and Link's sprite routine counts it down once a frame, so the protection lasts 58 frames.Code
Metroid II: Return of Samus 1991An enemy hit sets samusInvulnerableTimer to $33 (51), and while it is above 0 the hit code returns before any damage. drawSamus takes 1 from it each time it draws her, once per frame of play, and blinks her 4 frames on, 4 off.Code
Sonic the Hedgehog 1991A hit sets flashtime to 120 frames and landing sets it to 120 again; it counts down only in the control routine, so Sonic blinks and can't be hurt for 120 frames after he lands.Code
Sonic the Hedgehog 2 1992A hit sets invulnerable_time to $78 (120) and landing sets it to 120 again; it counts down only in the control routine, so Sonic has 120 frames of blinking invulnerability after he lands.Code
The Legend of Zelda: Link's Awakening 1993A monster's touch does nothing while Link's invincibility counter is above 0; a hit sets it to $50, and the main loop counts it down every frame, so the protection lasts 80 frames.Code
The 1993 Game Boy release has the same hit code as DX without the tunic check. It reads the damage from its health-group table, applies the Guardian Acorn's rule, and stores the same $50 in the invincibility counter.Code
Mega Man 6 1993A hit sets Mega Man 6's invincibility timer $A2 to 60 frames ($3C), but the 30-frame knockback runs through the frame routine's entry past the countdown (code_388EB9), so the timer starts to count, and he starts to blink, only once the knockback ends: he can't be hurt for 90 frames in all (computed). The damage routine skips a hit while $A2 isn't 0.Code
Sonic 3 & Knuckles 1994The invulnerability count is now a byte but still 120, set by the hit and again on landing, and still blinks the sprite.Code
Super Metroid 1994An enemy's touch sets SamusInvincibilityTimer to $60 (96), and Samus's contact check returns early while it is above 0. DecrementSamusHurtTimers_ClearActiveEnemyIndicesLists takes 1 from it, which the gameplay routine calls once per frame.Code
The timer a hit sets starts at 50 in Metroid (SamusBlink, $32), 51 in Metroid II (samusInvulnerableTimer, $33), and 96 in Super Metroid (SamusInvincibilityTimer, $60).Code
The Legend of Zelda: Oracle of Seasons and Oracle of Ages 2001In both US releases what a touch does to Link comes from a collision table indexed by the enemy's collision mode. A standard enemy (Octorok's collision mode) uses the plain damage effect, which sets Link's invincibility counter to $22, so he can't be hit for 34 frames, counted one per object update. The low- and high-knockback effects set 25 and 42. Link's Awakening DX sets $50, 80 frames, on every hit.Code
The Legend of Zelda: The Minish Cap 2004The Minish Cap takes a touch's effects from a collision matrix: the entry at the toucher's hit type × 34 + the touched one's hurt type. For an Octorok or a Leever (hit type 25) touching Link in his normal state (hurt type 0), the US ROM's entry gives Link 30 invincibility frames, a knockback duration of 8, and 2 damage, a quarter heart. The collision loop skips a pair while either has a nonzero iframe count, unless either has bit 7 of its collision flags set, and Link's count steps one toward 0 each frame his update runs, so the protection lasts 30 frames. Link's Awakening sets its count to 80 and A Link to the Past to 58.Code

References

  1. ^Wikidata lists Nintendo and Nintendo Entertainment Analysis & Development as the developers of The Legend of Zelda and Nintendo as its publisher; it dates the game 21 February 1986, with no place or platform, and its NES release in North America 22 August 1987.WikidataWikidata
    How we know
    +1986-02-21T00:00:00Z … +1987-11-15T00:00:00Z … +1987-08-22T00:00:00Z
    Q12395, P178 developer, P123 publisher, and P577 publication date qualified by P291 place and P400 platform · archived copy ↗

    The quote matches our archived copy.

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

    In the claim ledger

  2. ^Wikidata lists Nintendo Research & Development 1 as the developer of Metroid and Nintendo as its publisher, and dates its release on the Famicom Disk System in Japan 6 August 1986.WikidataWikidata
    How we know
    +1986-08-06T00:00:00Z … +1987-08-15T00:00:00Z … +1987-08-00T00:00:00Z
    Q2530723, P178 developer, P123 publisher, and P577 publication date qualified by P291 place and P400 platform · archived copy ↗

    The quote matches our archived copy.

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

    In the claim ledger

  3. ^ abcdefghiA monster that touches Link while his invincibility timer is above 0 does nothing; a hit sets the timer to 24 and his shove distance to 32 px.Codealdonunez/zelda1-disassembly · “Legend of Zelda, The (USA) (Rev 1)”
    How we know
    5610    ; If Link is invincible, or we have the magic clock,
    5611    ; or Link is stunned, or the monster is stunned;
    5612    ; then return no collision.
    5613    LDA ObjInvincibilityTimer
    5614    ORA InvClock
    5615    ORA ObjStunTimer
    5616    ORA ObjStunTimer, X
    5617    BNE L73A9_Exit
    
    src/Z_01.asm lines 5610–5617 at 50a1c86 · upstream ↗
    6589    ; If Link is invincible, return without shoving.
    6590    LDA ObjInvincibilityTimer
    6591    BNE @Exit
    ⋮
    6601    ; Mark Link invincible $18 frames, and should move $20 pixels.
    6602    LDA #$18
    6603    STA ObjInvincibilityTimer
    6604    LDA #$20
    6605    STA ObjShoveDistance
    
    src/Z_01.asm lines 6589–6605 at 50a1c86 · upstream ↗

    In the cartridge (“Legend of Zelda, The (USA) (Rev 1)”): bank 1 BeginShove, run from RAM at $7E26. We don't reproduce the bytes.

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

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

    In the claim ledger

  4. ^ abcEach frame, the crash detection skips the contact check between Samus and the enemies while SamusBlink is above 0.Codenmikstas/metroid-disassembly · “Metroid (USA)”
    How we know
    7696*   ldy #$00
    7697    lda SamusBlink
    7698    bne NextEnemy
    7699    jsr IsSamusDead
    7700    beq NextEnemy
    7701    jsr LF140
    7702    jsr LF282
    
    Source_Files/Bank07.asm lines 7696–7702 at 4270d57 · upstream ↗

    In the cartridge (“Metroid (USA)”): bank 7 crash detection, $F034, which ends by calling SubtractHealth. We don't reproduce the bytes.

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

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

    In the claim ledger

  5. ^ abcdefghiA hit sets SamusBlink to $32, which is 50, gives Samus an upward speed of $FD with the hit gravity $38, and takes the push direction from the hit; the comment says "Set blink for 32 frames".Codenmikstas/metroid-disassembly · “Metroid (USA)”
    How we know
    2421CheckHealthStatus:
    2422LCDFA:  lda SamusHit            ;
    2423    and #$20            ;Has Samus been hit?
    2424    beq +++             ;If not, branch to check if still blinking from recent hit.
    2425    lda #$32            ;
    2426    sta SamusBlink          ;Samus has been hit. Set blink for 32 frames.
    ⋮
    2428    sta DmgPushDir
    ⋮
    2431    beq ++
    ⋮
    2434*   lda SamusHit
    2435    and #$08
    2436    lsr
    2437    lsr
    ⋮
    
    Source_Files/Bank07.asm lines 2421–2443 at 4270d57 · upstream ↗

    In the cartridge (“Metroid (USA)”): bank 7 CheckHealthStatus, $CDFA. We don't reproduce the bytes.

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

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

    In the claim ledger

  6. ^ abcCheckHealthStatus, which Samus's routines call once per frame, lowers SamusBlink by 1 each time, so the blink lasts 50 frames of game logic.Codenmikstas/metroid-disassembly · “Metroid (USA)”
    How we know
    2448*   lda SamusBlink
    2449    beq CheckHealthBeep
    2450    dec SamusBlink
    
    Source_Files/Bank07.asm lines 2448–2450 at 4270d57 · upstream ↗
    2342LCD7E:* JSR CheckHealthStatus       ;($CDFA)Check if Samus hit, blinking or Health low.
    
    Source_Files/Bank07.asm line 2342 at 4270d57 · upstream ↗

    In the cartridge (“Metroid (USA)”): bank 7 CheckHealthStatus. We don't reproduce the bytes.

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

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

    In the claim ledger

  7. ^ abcdMeasured in the ROM, a crawler held against Samus in Brinstar's first room takes 8 units with each hit, and the next hit lands 50 game frames later; one of the two gaps also held 2 lag frames, for 52 frames of video.Verified“Metroid (USA)” · nmikstas/metroid-disassembly
    How we know

    In the cartridge (“Metroid (USA)”): bank 7 CheckHealthStatus, which the probe's hits run. We don't reproduce the bytes.

    2449    beq CheckHealthBeep
    2450    dec SamusBlink
    
    Source_Files/Bank07.asm lines 2421–2504 at 4270d57 · upstream ↗

    Measured by a script in MesenCE 2.2.1 (build 4b8a196), on Metroid (USA) (SHA-1 2080059bea45…). It fails if the result disagrees with the claim.

    The numbers come from the run; its author, an AI model, checked the script measures what the claim says, 2026-10-25.

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

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

    In the claim ledger

  8. ^ abcIn lava, Samus's blink is set to 50 on every frame, so enemies can't touch her, while the lava takes 0.7 units twice every 8 frames without a push; the Varia suit cuts that to once, and SubtractHealth halves it to 0.3 units.Codenmikstas/metroid-disassembly · “Metroid (USA)”revised
    How we know
    5432LE27B:  sty DmgPushDir     ;Don't push Samus from lava damage.
    5433LE27D:  jsr ClearHealthChange       ;($F323)Clear any pending health changes to Samus.
    5434LE280:  lda #$32            ;
    5435LE282:  sta SamusBlink          ;Make Samus blink.
    ⋮
    5441LE28F:  lsr             ;This portion of the code causes Samus to be damaged by
    5442LE290:  and #$03            ;lava twice every 8 frames if she does not have the varia
    5443LE292:  bne ++              ;but only once every 8 frames if she does.
    ⋮
    5448LE29D:* lda #$07            ;
    5449LE29F:  sta HealthLoChange      ;Samus takes lava damage.
    5450LE2A1:  jsr SubtractHealth      ;($CE92)
    
    Source_Files/Bank07.asm lines 5432–5450 at 4270d57 · upstream ↗
    2523LCEAC:  lda SamusGear           ;
    2524LCEAF:  and #gr_VARIA           ;Check is Samus has Varia.
    ⋮
    2526LCEB3:  lsr HealthLoChange      ;If Samus has Varia, divide damage by 2.
    
    Source_Files/Bank07.asm lines 2523–2527 at 4270d57 · upstream ↗

    In the cartridge (“Metroid (USA)”): bank 7 LavaAndMoveCheck, $E269. We don't reproduce the bytes.

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

    Revised after a check by a second AI model, 2026-10-21: The Varia suit halves lava damage, to 0.3 units.

    In the claim ledger

  9. ^A hit sets zmegaman_invincibility_time to 111 ($6F); while it is nonzero no contact damages Mega Man, and the stage loop counts it down by 1 on each pass that runs the enemies.Codelsmmega/mm1
    How we know
    123@not_death:
    124	LDA z:z0D
    125	AND #objects_right
    126	EOR #objects_right
    127	ORA #$03
    128	STA aobject_flag
    129	LDA #$6F
    130	STA z:zmegaman_invincibility_time
    131	RTS
    
    engine/check_megaman_damaged.asm lines 123–131 at b606a84 · upstream ↗
    18	LDA z:zmegaman_invincibility_time
    19	BNE @cant_damage
    
    engine/check_megaman_damaged.asm lines 18–19 at b606a84 · upstream ↗
    41	LDA aobject_flag
    42	AND #%00001111
    43	CMP #can_collide_map
    44	BEQ @can_collide_map
    45	JSR _run_weapons_trajectory
    46	JSR _run_bosses_ai
    47	LDA z:zmegaman_invincibility_time
    48	BEQ @no_invincibility
    49	DEC z:zmegaman_invincibility_time
    ⋮
    51@no_invincibility:
    52	JSR _check_megaman_damaged
    
    engine/stage_loop.asm lines 41–52 at b606a84 · upstream ↗

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

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

    In the claim ledger

  10. ^ abMega Man 2 keeps Mega Man's hit numbers too, 111 frames of invincibility ($6F) and a knockback of 1.25 px/frame up and 0.5625 back.Codelsmmega/mm1 · lsmmega/mm2
    How we know
    129	LDA #$6F
    130	STA z:zmegaman_invincibility_time
    
    engine/check_megaman_damaged.asm lines 129–130 at b606a84 · upstream ↗
    64	.BYTE $12, $01 | $40
    
    engine/handle_special_megaman_objects.asm line 64 at b606a84 · upstream ↗
    12	.BYTE $00 | $90
    
    data/special_xcoord_speed_table.asm line 12 at b606a84 · upstream ↗
    11	LDA #$6F
    12	STA z:zmegaman_invincibility_time
    13	LDA #$01
    14	STA aobject_ycoord_speed
    15	LDA #$40
    16	STA aobject_ycoord_speed_fraction
    17	LDA #$00
    18	STA aobject_xcoord_speed
    19	LDA #$90
    20	STA aobject_xcoord_speed_fraction
    
    home/megaman_hit.asm lines 11–20 at 94f0bf3 · upstream ↗

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

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

    In the claim ledger

  11. ^A hit sets zmegaman_invincibility_time to 111 ($6F); contact damage is skipped while it is nonzero, and it counts down by 1 each time Mega Man's sprite is processed, hiding him on alternate pairs of frames.Codelsmmega/mm2
    How we know
    11	LDA #$6F
    12	STA z:zmegaman_invincibility_time
    
    home/megaman_hit.asm lines 11–12 at 94f0bf3 · upstream ↗
    34	LDA z:zmegaman_invincibility_time
    35	BNE @skip_1
    
    home/object_hit.asm lines 34–35 at 94f0bf3 · upstream ↗
    277_is_megaman_object:
    278	TAY
    279	CPX #1
    280	BCS @not_megaman_object
    281	LDA z:zmegaman_invincibility_time
    282	BEQ @skip
    283	DEC z:zmegaman_invincibility_time
    284	LDA z:znmi_frame
    285	AND #%00000010
    286	BEQ @skip
    ⋮
    288@is_out_of_screen:
    289	JMP _skip_draw
    
    home/sprites.asm lines 277–289 at 94f0bf3 · upstream ↗

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

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

    In the claim ledger

  12. ^Health is $0F for one mark of the life meter and $10 more for each further mark, up to $3F for four. A hit takes $10, one mark, and sets DamageInvulnTime to $7F, during which DamagePlayer returns at once; the timer drops every frame. If the health left is $10 or more, two marks or more, the hit also launches the player upward at $C0 and sideways at four times the screen distance from the enemy. A hit on the last mark (health under $10) stores no health and sets no invulnerability: it turns the enemy toward the player (for the types before Enemy_BeezoDiving), stuns it for $10 frames, sets the player's vertical speed to $C0 and PlayerStateTimer to $20, and jumps to KillPlayer, which sets the dying state and health to 0. A dying player holds still for those 32 frames, then rises at $C0 and falls back, gaining $02 a frame up to $39, and loses a life once below the screen.CodeSMB2 Discombobulatedrevised
    How we know
    11362DamagePlayer:
    11363	LDA DamageInvulnTime
    11364	BNE locret_BANK3_BA31
    ⋮
    11366	LDA PlayerHealth
    11367	SEC
    11368	SBC #$10
    11369	BCC loc_BANK3_BA32
    ⋮
    11371	STA PlayerHealth
    11372	LDY #$7F
    11373	STY DamageInvulnTime
    11374	LDY #$00
    11375	STY PlayerYVelocity
    ⋮
    
    src/prg-2-3.asm lines 11362–11388 at b73415e · upstream ↗
    3171	; Decrement player state timers
    3172	LDX #$03
    3173DecrementPlayerStateTimers_Loop:
    3174	LDA PlayerStateTimer, X
    ⋮
    3177	DEC PlayerStateTimer, X
    
    src/prg-e-f.asm lines 3171–3177 at b73415e · upstream ↗
    291PlayerStateTimer:
    ⋮
    297DamageInvulnTime:
    
    src/ram.asm lines 291–298 at b73415e · upstream ↗
    11404loc_BANK3_BA32:
    11405	TXA
    ⋮
    11407loc_BANK3_BA33:
    11408	PHA
    11409	LDX byte_RAM_12
    11410	LDA ObjectType, X
    11411	CMP #Enemy_BeezoDiving
    11412	BCS loc_BANK3_BA48
    ⋮
    11414	JSR EnemyFindWhichSidePlayerIsOn
    ⋮
    11416	INY
    11417	TYA
    11418	CMP EnemyMovementDirection, X
    ⋮
    
    src/prg-2-3.asm lines 11404–11439 at b73415e · upstream ↗
    5154KillPlayer:
    5155	LDA #PlayerState_Dying ; Mark player as dead
    5156	STA PlayerState
    5157	LDA #$00 ; Clear some variables
    5158IFNDEF RESPAWN_INSTEAD_OF_DEATH
    5159	STA PlayerHealth
    
    src/prg-e-f.asm lines 5154–5159 at b73415e · upstream ↗
    1995HandlePlayerState_Dying:
    1996	LDA PlayerStateTimer
    1997	BNE locret_BANK0_8A86
    ⋮
    1999	LDA PlayerScreenYHi
    2000	CMP #02
    2001	BEQ LoseALife
    ⋮
    2003	JSR ApplyPlayerPhysicsY
    ⋮
    2005	LDA PlayerYVelocity
    2006	BMI loc_BANK0_8A72
    ⋮
    2008	CMP #$39
    2009	BCS locret_BANK0_8A86
    ⋮
    2011loc_BANK0_8A72:
    ⋮
    
    src/prg-0-1.asm lines 1995–2014 at b73415e · upstream ↗
    270; enum PlayerHealthValues
    271PlayerHealth_1_HP = $0F
    272PlayerHealth_2_HP = $1F
    273PlayerHealth_3_HP = $2F
    274PlayerHealth_4_HP = $3F
    
    src/defs.asm lines 270–274 at b73415e · upstream ↗

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

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

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

    In the claim ledger

  13. ^A hit that doesn't kill Mario, including one that only takes Kuribo's Shoe, sets Player_FlashInv to $71, and Player_GetHurt ignores hits while it is nonzero. Player_Draw counts it down each time it runs, blinking Mario in 2-tick halves.CodeSouthbird's SMB3 disassembly
    How we know
    5620Player_GetHurt:
    5621	; If Player is...
    5622	LDA Player_FlashInv		; ... flashing invincible ...
    ⋮
    5629	BNE PRG000_D9B7	 ; ... then jump to PRG000_D9B7 (RTS)
    
    PRG/prg000.asm lines 5620–5629 at 09b1bd8 · upstream ↗
    5744PRG000_DA6D: 
    5745	LDA #$71
    5746	STA Player_FlashInv	 ; Player_FlashInv = $71
    
    PRG/prg000.asm lines 5744–5746 at 09b1bd8 · upstream ↗
    423	LDA Player_FlashInv
    424	BEQ PRG029_CED7	 	; If Player_FlashInv = 0, jump to PRG029_CED7
    ⋮
    426	DEC Player_FlashInv	; Player_FlashInv--
    427	AND #$02	 
    428	BEQ PRG029_CED7	 	; Every 2 ticks, draw Player
    
    PRG/prg029.asm lines 423–429 at 09b1bd8 · upstream ↗

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

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

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

    In the claim ledger

  14. ^ abcA hit in Dracula's Curse sets $80 to 120, which the player's update counts down once a frame while flickering the character; one branch of the hit handling returns at once while $80, or $AD, is nonzero.Codevinheim3/castlevania3-disasmrevised
    How we know
    lda #$78 … sta $80
    code/playerStateProcessing_b1c.s#L298-L299 · upstream ↗
    lda $80 … dec $80 … ldy #$80 … lda wGameStateLoopCounter … and #$01 … sty wEntityState.w
    code/playerStateProcessing_b1c.s#L166-L176 · upstream ↗
    lda $80 … ora $ad … bne B28_012b
    code/playerStateProcessing_b1c.s#L257-L259 · upstream ↗

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

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

    In the claim ledger

  15. ^ abcdMega Man 3 starts the invincibility after the knockback: when the hurt state ends it sets invincibility_timer to 60 ($3C), which the prelude counts down every frame. Mega Man 2 sets 111 at the moment of the hit.Codeplasticsmoke/megaman3-disassembly-ca65 · lsmmega/mm2
    How we know
    828player_knockback_set_invincible:  sta     player_state ; set return player state
    829        lda     #$3C                    ; $39 = $3C (60 frames invincibility)
    830        sta     invincibility_timer     ; 60 frames of invincibility
    
    src/fixed/player_states.asm lines 828–830 at 58ca1c3 · upstream ↗
    657prelude_invincibility_timer:  lda     invincibility_timer ; load invincibility timer
    658        beq     prelude_charge_shot_check ; zero → skip
    659        dec     invincibility_timer     ; decrement timer
    
    src/fixed/game_loop.asm lines 657–659 at 58ca1c3 · upstream ↗
    141        lda     invincibility_timer     ; skip if invincibility active
    142        bne     metatile_cleanup_return ; immune → skip hazard check
    
    src/fixed/collision.asm lines 141–142 at 58ca1c3 · upstream ↗
    11	LDA #$6F
    12	STA z:zmegaman_invincibility_time
    
    home/megaman_hit.asm lines 11–12 at 94f0bf3 · upstream ↗

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

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

    In the claim ledger

  16. ^HurtMario returns at once while IFrameTimer is nonzero. After the power-down animation Super Mario World sets it to $7F, and the timer loop counts it down on every frame the sprites aren't locked.CodeSMWDisX
    How we know
    13490HurtMario:
    ⋮
    13492    BNE Return00F628                          ; /
    13493    LDA.W IFrameTimer                         ; \ If flashing...
    13494    ORA.W InvinsibilityTimer                  ; | ...or have star...
    13495    ORA.W EndLevelTimer                       ; | ...or level ending...
    13496    BNE Return00F628                          ; / ...return
    
    bank_00.asm lines 13490–13496 at 30643c7 · upstream ↗
    9443    LDA.W PlayerAniTimer
    9444    BEQ CODE_00D140
    ⋮
    9452    LDA.W PlayerAniTimer
    ⋮
    9457CODE_00D140:
    9458    LDA.B #$7F
    9459    STA.W IFrameTimer
    
    bank_00.asm lines 9442–9459 at 30643c7 · upstream ↗
    7903    BNE CODE_00C569                           ; /
    7904    INC.B EffFrame
    7905    LDX.B #$13
    7906CODE_00C508:
    7907    LDA.W ColorFadeTimer,X
    7908    BEQ +
    7909    DEC.W ColorFadeTimer,X
    7910  + DEX
    7911    BNE CODE_00C508
    
    bank_00.asm lines 7902–7911 at 30643c7 · upstream ↗
    1640ColorFadeTimer: skip 1
    1641PlayerAniTimer: skip 1
    1642IFrameTimer: skip 1
    
    rammap.asm lines 1640–1642 at 30643c7 · upstream ↗

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

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

    In the claim ledger

  17. ^A monster's touch does nothing while Link's blink timer is above 0. A hit sets it to 58, and Link's sprite routine counts it down once a frame, so the protection lasts 58 frames.Codespannerisms/usdasm
    How we know
    22715#AttemptDamageToLinkPlusRecoil:
    22716|06F3DB| LDA.w $031F
    22717|06F3DE| ORA.w $037B
    22718|06F3E1| BNE .no_damage
    
    bank_06.asm lines 22715–22718 at bcdd96e · upstream ↗
    146|0780B4| LDA.w $031F
    147|0780B7| BNE .have_iframes
    ⋮
    149|0780B9| LDA.b #$3A
    150|0780BB| STA.w $031F
    
    bank_07.asm lines 146–150 at bcdd96e · upstream ↗
    4530|0DAA46| LDA.b $11
    4531|0DAA48| BNE .check_stair_visibility
    ⋮
    4533|0DAA4A| LDA.w $031F
    4534|0DAA4D| BEQ .check_stair_visibility
    ⋮
    4536|0DAA4F| DEC A
    4537|0DAA50| STA.w $031F
    
    bank_0D.asm lines 4530–4537 at bcdd96e · upstream ↗

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

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

    In the claim ledger

  18. ^ abA hit sets invulnerable_time to $78 (120) and landing sets it to 120 again; it counts down only in the control routine, so Sonic has 120 frames of blinking invulnerability after he lands.Codesonicretro/s2disasm
    How we know
    85696	move.w	#$78,invulnerable_time(a0)
    
    s2.asm line 85696 at 4ef457c · upstream ↗
    38262	btst	#status.player.in_air,status(a0)
    38263	bne.s	return_1B1C8
    ⋮
    38271	move.w	#$78,invulnerable_time(a0)
    
    s2.asm lines 38262–38271 at 4ef457c · upstream ↗
    36325Sonic_Display:
    ⋮
    36328	subq.w	#1,invulnerable_time(a0)	; decrease invulnerability frames
    36329	lsr.w	#3,d0						; check every 3 or 4 frames
    
    s2.asm lines 36325–36330 at 4ef457c · upstream ↗
    85635	tst.w	invulnerable_time(a0)
    85636	bne.s	Touch_NoHurt
    
    s2.asm lines 85633–85636 at 4ef457c · upstream ↗

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

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

    In the claim ledger

  19. ^A monster's touch does nothing while Link's invincibility counter is above 0; a hit sets it to $50, and the main loop counts it down every frame, so the protection lasts 80 frames.Codezladx/LADX-Disassembly · “Legend of Zelda, The - Link's Awakening (USA, Europe) (Rev 2)”revised
    How we know
    ld a, [wInvincibilityCounter] … jp nz, setCarryAndReturn
    src/code/entities/bank3.asm#L5300-L5307 · upstream ↗
    5347    ld   a, $50                                   ;; 03:6DB2 $3E $50
    
    src/code/entities/bank3.asm lines 5347–5348 at 2a5c2c0 · upstream ↗
    1500    ; If wInvincibilityCounter > 0, decrement it
    
    src/code/bank0.asm lines 1500–1505 at 2a5c2c0 · upstream ↗

    In the cartridge (“Legend of Zelda, The - Link's Awakening (USA, Europe) (Rev 2)”): the same decrement in the 1993 release, bank 0 (ld hl,$DBC7; ld a,[hl]; and a; jr z; dec [hl]); the 1993 release's hit code, from the counter test to the `$50` store (game-boy-hit). We don't reproduce the bytes.

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

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

    In the claim ledger

  20. ^The 1993 Game Boy release has the same hit code as DX without the tunic check. It reads the damage from its health-group table, applies the Guardian Acorn's rule, and stores the same $50 in the invincibility counter.Code“Legend of Zelda, The - Link's Awakening (USA, Europe) (Rev 2)” · zladx/LADX-Disassemblyrevised
    How we know

    In the cartridge (“Legend of Zelda, The - Link's Awakening (USA, Europe) (Rev 2)”): bank 3; from the counter test to the `$50` store, DX's bytes less the 7-byte tunic test. We don't reproduce the bytes.

    5323    ld   a, [wTunicType]                          ;; 03:6D94 $FA $0F $DC
    5324    cp   TUNIC_BLUE                               ;; 03:6D97 $FE $02
    5325    jr   z, .takeHalfDamages                      ;; 03:6D99 $28 $0E
    
    src/code/entities/bank3.asm lines 5323–5325 at 2a5c2c0 · upstream ↗

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

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

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

    In the claim ledger

  21. ^ abThe invulnerability count is now a byte but still 120, set by the hit and again on landing, and still blinks the sprite.Codesonicretro/skdisasm · sonicretro/s1disasm · sonicretro/s2disasmrevised
    How we know
    21146		move.b	#120,invulnerability_timer(a0)
    
    sonic3k.asm line 21146 at 73de97c · upstream ↗
    24545		move.b	#2*60,invulnerability_timer(a0)
    
    sonic3k.asm line 24545 at 73de97c · upstream ↗
    22074		move.b	invulnerability_timer(a0),d0
    22075		beq.s	loc_10CA6
    22076		subq.b	#1,invulnerability_timer(a0)
    22077		lsr.b	#3,d0
    
    sonic3k.asm lines 22073–22078 at 73de97c · upstream ↗
    410		move.w	#2*60,flashtime(a0)			; set temporary invulnerability time to 2 seconds
    
    _incObj/Sonic ReactToItem.asm line 410 at 15dfa3a · upstream ↗
    85696	move.w	#$78,invulnerable_time(a0)
    
    s2.asm line 85696 at 4ef457c · upstream ↗
    38271	move.w	#$78,invulnerable_time(a0)
    
    s2.asm line 38271 at 4ef457c · upstream ↗

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

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

    In the claim ledger

  22. ^A hit on big Mario sets InjuryTimer to 8, and enemy contact is skipped until it is back at 0. It is one of the interval timers, which DecTimers counts down once every 21 frames, so the window lasts 8 such ticks, 148 to 168 frames while the game's timers run.CodeXkeeper0/smb1
    How we know
    10583InjurePlayer:
    10584	LDA InjuryTimer                              ; check again to see if injured invincibility timer is
    10585	BNE ExInjColRoutines                         ; at zero, and branch to leave if so
    ⋮
    10591	LDA #$08
    10592	STA InjuryTimer                              ; set injured invincibility timer
    
    src/prg.asm lines 10583–10592 at 1cc3c92 · upstream ↗
    127	LDX #$14                                     ; load end offset for end of frame timers
    128	DEC IntervalTimerControl                     ; decrement interval timer control,
    129	BPL DecTimersLoop                            ; if not expired, only frame timers will decrement
    130	LDA #$14
    131	STA IntervalTimerControl                     ; if control for interval timers expired,
    132	LDX #$23                                     ; interval timers will decrement along with frame timers
    
    src/prg.asm lines 126–139 at 1cc3c92 · upstream ↗
    60Timers                = $0780
    ⋮
    78InjuryTimer           = $079e
    
    src/ram.asm lines 60–78 at 1cc3c92 · upstream ↗

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

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

    In the claim ledger

  23. ^A hit on big Mario sets InjuryTimer to 8, as in Super Mario Bros., and the timer counts down once every 21 frames with the interval timers, through the same timer loop as Super Mario Bros.'s.Codedoppelganger's SMB2J disassembly · Xkeeper0/smb1revised
    How we know
    10424      lda InjuryTimer          ;check again to see if either of the two
    10425      ora StarInvincibleTimer  ;invincibility timers have expired, branch if not
    10426      bne ExInjColRoutines
    ⋮
    10428ForceInjury:
    10429          ldx PlayerStatus          ;check player's status
    10430          beq KillPlayer            ;branch if small
    10431          sta PlayerStatus          ;otherwise set player's status to small
    10432          lda #$08
    10433          sta InjuryTimer           ;set injured invincibility timer
    
    sm2main.asm lines 10424–10433 at 9c40114 · upstream ↗
    928   ldx #$14                  ;set offset to decrement only frame timers
    929   dec IntervalTimerControl  ;if interval timer control not expired, branch
    930   bpl DecrTheTimers         ;to skip and thus decrement only frame timers
    931   lda #$14
    932   sta IntervalTimerControl  ;otherwise reset interval timer control to 20 frames
    933   ldx #$23                  ;and load offset to decrement frame and interval timers
    
    sm2main.asm lines 928–933 at 9c40114 · upstream ↗
    81Timers                = $0780
    ⋮
    99InjuryTimer           = $079e
    
    sm2main.asm lines 81–99 at 9c40114 · upstream ↗
    10583InjurePlayer:
    10584	LDA InjuryTimer                              ; check again to see if injured invincibility timer is
    10585	BNE ExInjColRoutines                         ; at zero, and branch to leave if so
    ⋮
    10587ForceInjury:
    10588	LDX PlayerStatus                             ; check player's status
    10589	BEQ KillPlayer                               ; branch if small
    10590	STA PlayerStatus                             ; otherwise set player's status to small
    10591	LDA #$08
    10592	STA InjuryTimer                              ; set injured invincibility timer
    
    src/prg.asm lines 10583–10592 at 1cc3c92 · upstream ↗
    126DecTimers:
    127	LDX #$14                                     ; load end offset for end of frame timers
    128	DEC IntervalTimerControl                     ; decrement interval timer control,
    129	BPL DecTimersLoop                            ; if not expired, only frame timers will decrement
    130	LDA #$14
    131	STA IntervalTimerControl                     ; if control for interval timers expired,
    132	LDX #$23                                     ; interval timers will decrement along with frame timers
    133DecTimersLoop:
    134	LDA Timers,x                                 ; check current timer
    135	BEQ SkipExpTimer                             ; if current timer expired, branch to skip,
    136	DEC Timers,x                                 ; otherwise decrement the current timer
    137SkipExpTimer:
    ⋮
    
    src/prg.asm lines 126–139 at 1cc3c92 · upstream ↗

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

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

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

    In the claim ledger

  24. ^ abcdDecrementInvincibilityTimer lowers an object's invincibility timer by 1 only on frames when FrameCounter is even, so a timer of t lasts 2t frames.Codealdonunez/zelda1-disassembly · “Legend of Zelda, The (USA) (Rev 1)”
    How we know
    5782DecrementInvincibilityTimer:
    5783    LDA ObjInvincibilityTimer, X
    5784    BEQ @Exit                   ; If the timer is already zero, then return.
    5785    LDA FrameCounter            ; Every two frames, decrease the timer.
    5786    LSR
    5787    BCS @Exit
    5788    DEC ObjInvincibilityTimer, X
    
    src/Z_07.asm lines 5782–5788 at 50a1c86 · upstream ↗

    In the cartridge (“Legend of Zelda, The (USA) (Rev 1)”): bank 7 $FE98. We don't reproduce the bytes.

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

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

    In the claim ledger

  25. ^ abcdeMeasured in Rev 1, a Tektite held against Link hurts him every 47 or 48 frames, taking half a heart each time; from three hearts, five hits leave $20 and $7D, 3/256 of a heart under a half heart.Verified“Legend of Zelda, The (USA) (Rev 1)” · aldonunez/zelda1-disassembly
    How we know

    In the cartridge (“Legend of Zelda, The (USA) (Rev 1)”): bank 1, the contact check and damage the probe exercises. We don't reproduce the bytes.

    5769    LDA HeartPartial
    5770    CMP $0E
    5771    BCC @BorrowHeart
    5772    SEC
    5773    SBC $0E
    5774    STA HeartPartial
    ⋮
    5784    SEC
    ⋮
    5796    SEC
    ⋮
    5802    DEC HeartValues
    5803    LDA #$FF
    5804    STA HeartPartial
    ⋮
    5817    STA HeartPartial
    
    src/Z_01.asm lines 5600–5822 at 50a1c86 · upstream ↗

    Measured by a script in MesenCE 2.2.1 (build 4b8a196), on Legend of Zelda, The (USA) (Rev 1) (SHA-1 4671517d72d0…). It fails if the result disagrees with the claim.

    The numbers come from the run; its author, an AI model, checked the script measures what the claim says, 2026-10-25.

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

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

    In the claim ledger

  26. ^ abcA weapon that hurts a monster sets the monster's invincibility timer to 16, which lasts 32 frames, and shoves it 64 px in the weapon's direction, unless the monster is already invincible or immune to the weapon's damage type.Codealdonunez/zelda1-disassembly · “Legend of Zelda, The (USA) (Rev 1)”
    How we know
    6503BeginShove:
    6504    ; If a weapon attacks a monster, and the weapon's damage
    6505    ; type matches the monster's invincibility mask;
    6506    ; then return without shoving.
    
    src/Z_01.asm lines 6503–6514 at 50a1c86 · upstream ↗
    6636    ; Set the shove direction to the weapon's direction,
    ⋮
    6653    ; If the monster is invincible, then return without shoving.
    6654    LDA ObjInvincibilityTimer, X
    6655    BNE @Exit2
    ⋮
    6671    BNE @Exit2
    ⋮
    6676    BNE @Exit2
    ⋮
    6687    ; Mark the monster invincible $10 frames, and should move $40 pixels.
    6688    LDA #$40
    6689    STA ObjShoveDistance, X
    6690    LDA #$10
    6691    STA ObjInvincibilityTimer, X
    
    src/Z_01.asm lines 6636–6691 at 50a1c86 · upstream ↗

    In the cartridge (“Legend of Zelda, The (USA) (Rev 1)”): bank 1 BeginShove. We don't reproduce the bytes.

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

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

    In the claim ledger

  27. ^ abWhile Link holds the clock, BeginUpdateWorld adds 16 to his invincibility timer every frame, and monsters' contact checks return no collision.Codealdonunez/zelda1-disassembly · “Legend of Zelda, The (USA) (Rev 1)”
    How we know
    1876BeginUpdateWorld:
    1877    ; If we have the clock, then
    1878    ; force the player's invincibility.
    1879    LDA InvClock
    1880    BEQ @NotInvincible
    1881    LDA ObjInvincibilityTimer
    1882    CLC
    1883    ADC #$10
    1884    STA ObjInvincibilityTimer
    
    src/Z_07.asm lines 1876–1884 at 50a1c86 · upstream ↗

    In the cartridge (“Legend of Zelda, The (USA) (Rev 1)”): bank 7 $EC7A, these lines only; BeginUpdateWorld differs in Rev 1 further on. We don't reproduce the bytes.

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

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

    In the claim ledger

  28. ^A hit sets Link's immunity timer to 4 and his injured timer to 32. The game counts the injured timer down every frame but the immunity timer only once every 21 frames, so the immunity lasts 64 to 84 frames, depending on where in the cycle the hit lands.CodeFiendsOfTheElements/z2disassembly · “Zelda II - The Adventure of Link (USA)”
    How we know
    5461    STA      $050C                     ; 0x1e35e $E34E 8D 0C 05                ; Timer for Link being in injured state
    ⋮
    5463    STA      $0518                     ; 0x1e363 $E353 8D 18 05                ; Timer for Link being immune (0 = vulnerable)
    
    src/prg7.asm lines 5460–5463 at c4c3a4c · upstream ↗
    5414    LDA      $0518                     ; 0x1e301 $E2F1 AD 18 05                ; Timer for Link immunity (0 = vulnerable)
    
    src/prg7.asm lines 5412–5416 at c4c3a4c · upstream ↗
    398    DEC      $0501,x                   ; 0x1c18c $C17C DE 01 05                ; decrease all 5xx timers (if > 0)
    
    src/prg7.asm lines 388–401 at c4c3a4c · upstream ↗

    In the cartridge (“Zelda II - The Adventure of Link (USA)”): bank 7 $C169-$C181, the timer loop; the source's `BPL :-` assembles to the wrong target, and the ROM's F5 branches back to $C177. We don't reproduce the bytes.

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

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

    In the claim ledger

Sources

Code

Secondary