Super Metroid
Nintendo R&D1's 1994 side-view action-adventure for the Super NES, read through InsaneFirebat's disassembly built on P.JBoy's bank logs.
On this page
The atlas reads Super Metroid through InsaneFirebat’s sm_disassembly, which reassembles the NTSC release byte for byte1. Many of its comments come from P.JBoy’s bank logs. Labels and comments cited here are the disassembly’s. Nothing here has been measured in the ROM yet.
Samus jumps at 4.875 px/frame (6 with the Hi-Jump Boots)2 in air, 6 px/frame with the Hi-Jump Boots, and slower in water and lava2. Gravity is one constant, 0.109375 px/frame²3 in air3. Letting go of jump during the rise stops it at once4. Running tops out at 2.75 px/frame, and holding dash adds a second speed that builds on top of it5.
An enemy’s touch gives 96 frames6 of invincibility6 and launches Samus up and away from the enemy7.
The wall jump works only from a spin jump, with the d-pad held away from the wall8. With the Space Jump, a new press makes a fresh jump during part of the fall9.
#Across the line
Super Metroid’s running acceleration is Metroid’s, 0.1875 px/frame², with a higher top speed10. It keeps Metroid’s release cut but drops the 32 px minimum rise11. Each game builds the high jump its own way: Metroid lowers the gravity, Metroid II lengthens a faster held rise, and Super Metroid raises the take-off speed12. A hit’s invincibility grows from 50 frames in Metroid and 51 in Metroid II to 9613.
Mechanics
| Mechanic | Kind | How |
|---|---|---|
| Jump | Speed by state | a table by medium and the Hi-Jump Boots, 4.875 px/frame in air or 6 with the boots |
| Gravity | One gravity | 0.109375 px/frame² in air, held or not, with lighter values in water and lava |
| Variable jump height | Release cap | letting go during the rise sets the vertical speed to 0 |
| Running | Run button | 2.75 px/frame, and holding dash builds up to 2 px/frame more, 7 with the Speed Booster |
| Air control | Stops on release | in a normal jump, a held direction accelerates Samus to 1.25 px/frame, and letting go stops her base speed |
| Invincibility frames | Frame timer | 96 frames after an enemy's touch |
| Knockback | Launch | 5 px/frame up, then the usual gravity |
| Health upgrade | Whole containers | energy tanks of 100 each, from 99 at the start, each refilling her energy |
| Ammunition | Several pools | missiles, super missiles, and power bombs, 5 per tank |
| Morph ball | an item, with a top speed on the ground above running's | |
| Space Jump | Window of fall speed | a new press jumps again while the fall is between 2.5 and 5 px/frame |
| Screw Attack | Any spin | the spin's touch deals a base 2000 damage |
| Wall jump | Push off from a spin | from a spin jump, holding away from a wall within 8 px |
| HDMA | Scroll wave | BG2 below the waterline ripples a pixel either way in an 8-line pattern that moves every 6 frames |
| HDMA | Color gradient | Ceres station's haze steps a color down the screen in 8-line bands |
| Raster effects | Per line | HDMA writes BG2's scroll on every line under the water |
Every claim about this game, by concept (21)
References
- ^InsaneFirebat's sm_disassembly, assembled with asar for NTSC, equals Super Metroid (Japan, USA) (En,Ja) byte for byte.Code“Super Metroid (Japan, USA) (En,Ja)” · InsaneFirebat/sm_disassembly
How we know
In the cartridge (“Super Metroid (Japan, USA) (En,Ja)”): bank $90 $9E8B, SamusPhysicsConstants, the table most claims below read. We don't reproduce the bytes.
19echo Success! This ROM matches vanilla Super Metroidtest_build.bat line 19 at 7af131e · upstream ↗ 34print "NTSC VERSION" 35!FPS = 1 36!SPF = 1
src/main.asm lines 34–36 at 7af131e · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^ ab
Make_Samus_Jumppicks the take-off speed from a table by medium and the Hi-Jump Boots: 4.875 px/frame up in air, 1.75 in water, 2.75 in lava or acid, and 6, 2.5, and 3.5 with the boots. With the Speed Booster equipped, it adds Samus's extra run speed, the whole part halved.CodeInsaneFirebat/sm_disassemblyHow we know
4198 .merge: ⋮ 4208 .hiJumpEquipped:
src/bank_90.asm lines 4198–4227 at 7af131e · upstream ↗ 4184 .normalGravity: ⋮ 4188 .submergedInWater: ⋮ 4195 .submergedInAcidLava:
src/bank_90.asm lines 4184–4196 at 7af131e · upstream ↗ 3995 .running:src/bank_90.asm lines 3995–3998 at 7af131e · upstream ↗ 5124 .InitialYSpeeds_Jumping: ⋮ 5127 .InitialYSubSpeeds_Jumping: ⋮ 5130 .InitialYSpeeds_HiJumpJumping:
src/bank_90.asm lines 5124–5134 at 7af131e · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^ abGravity is one constant in air,
$1C00subpixels (0.109375 px/frame²) every frame of a jump or fall, held button or not; water uses$0800and lava or acid$0900. A fall stops gaining speed at 5 px/frame.CodeInsaneFirebat/sm_disassemblyHow we know
5076 .YSubAccelerationInAir: 5077; Samus Y subacceleration in air ⋮ 5081; Samus Y subacceleration in water
src/bank_90.asm lines 5076–5082 at 7af131e · upstream ↗ 4719 .notSubmerged:src/bank_90.asm lines 4719–4720 at 7af131e · upstream ↗ 2984 .down:src/bank_90.asm lines 2972–2994 at 7af131e · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^In a normal or spin jump, letting go of jump while Samus rises sets her vertical speed to 0 and starts the fall at once; held, the rise lasts until gravity brings the speed to 0.CodeInsaneFirebat/sm_disassembly
How we know
2785 .jumping:src/bank_90.asm lines 2785–2798 at 7af131e · upstream ↗ LDA.B DP_Controller1Input AND.W JumpBinding BEQ + … + STZ.W SamusYSubSpeed STZ.W SamusYSpeed
src/bank_90.asm#L2846-L2857 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^Running accelerates Samus at 0.1875 px/frame² to 2.75 px/frame and slows her at 0.5 px/frame² once she lets go. Holding dash while running builds a separate extra run speed at 0.0625 px/frame², up to 2 px/frame, or 7 with the Speed Booster.CodeInsaneFirebat/sm_disassembly
How we know
5193; Used for Samus X base speed (due to general movement) ⋮ 5200 dd wordSwap($0030*!SPF*$100),wordSwap($02C0*!SPF*$100), wordSwap($0080*!SPF*$100) ; 1: Running
src/bank_90.asm lines 5192–5200 at 7af131e · upstream ↗ 3982 .gravityContinued: ⋮ 3989 .checkDash:
src/bank_90.asm lines 3982–3998 at 7af131e · upstream ↗ 4040 .accelerating:src/bank_90.asm lines 4040–4047 at 7af131e · upstream ↗ 5163 .XSubAccelerations_DashHeld: ⋮ 5166 .MaxXExtraRunSpeeds_SpeedBooster: ⋮ 5172 .MaxXExtraRunSpeeds_NoSpeedBooster:
src/bank_90.asm lines 5163–5173 at 7af131e · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^ abAn enemy's touch sets
SamusInvincibilityTimerto$60(96), and Samus's contact check returns early while it is above 0.DecrementSamusHurtTimers_ClearActiveEnemyIndicesListstakes 1 from it, which the gameplay routine calls once per frame.CodeInsaneFirebat/sm_disassemblyHow we know
LDA.L EnemyHeaders_damage,X JSL.L Suit_Damage_Division JSL.L Deal_A_Damage_to_Samus LDA.W #$0060 STA.W SamusInvincibilityTimer
src/bank_A0.asm#L4915-L4919 · upstream ↗ 3392 .normalContact:src/bank_A0.asm lines 3392–3394 at 7af131e · upstream ↗ 2093DecrementSamusHurtTimers_ClearActiveEnemyIndicesLists:src/bank_A0.asm lines 2093–2096 at 7af131e · upstream ↗ JSL.L DecrementSamusHurtTimers_ClearActiveEnemyIndicesLists
src/bank_82.asm#L1566 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^An enemy's touch sets a 5-frame
SamusKnockbackTimerand a knockback direction from Samus's position against the enemy's. The knockback launches her at 5 px/frame up, or 2 in water, lava, or acid, and the upward knockback then moves her with the usual Y-speed code, gravity included.CodeInsaneFirebat/sm_disassemblyHow we know
LDA.W #$0005 STA.W SamusKnockbackTimer LDY.W #$0000 LDX.W EnemyIndex LDA.W SamusXPosition SEC SBC.W Enemy.XPosition,X … STY.W KnockbackXDirection
src/bank_A0.asm#L4920-L4931 · upstream ↗ 4352 .merge:src/bank_90.asm lines 4352–4356 at 7af131e · upstream ↗ 5148 .InitialYSpeeds_Knockback:src/bank_90.asm lines 5148–5149 at 7af131e · upstream ↗ 14262KnockbackMoement_Up:src/bank_90.asm lines 14262–14264 at 7af131e · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^A wall jump starts only from a spin jump or another wall jump. Once the spin animation reaches its wall-jump frames, with a direction held away from a wall or solid enemy within 8 px, a new jump press jumps off at 4.625 px/frame up, or 5.5 with the Hi-Jump Boots.CodeInsaneFirebat/sm_disassembly
How we know
4838WallJump_Check:src/bank_90.asm lines 4838–4861 at 7af131e · upstream ↗ 4941 .wallJumpEligiblePressingLeft:src/bank_90.asm lines 4941–4951 at 7af131e · upstream ↗ 4960 .wallJumpEligiblePressingRight:src/bank_90.asm lines 4960–4986 at 7af131e · upstream ↗ LDA.W SamusPhysicsConstants_MaximumDistanceFromWallForWallJump STA.B DP_Temp12 STZ.B DP_Temp14 JSR.W WallJump_Check
src/bank_90.asm#L2897-L2900 · upstream ↗ 5072 .MaximumDistanceFromWallForWallJump: 5073; Maximum distance from wall for wall-jump
src/bank_90.asm lines 5072–5074 at 7af131e · upstream ↗ 5136 .InitialYSpeeds_WallJumping: ⋮ 5142 .InitialYSpeeds_HiJumpWallJumping:
src/bank_90.asm lines 5136–5143 at 7af131e · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^In a spin jump in air with the Space Jump, a new jump press makes a fresh jump only while Samus falls at 2.5 px/frame or faster and below 5.CodeInsaneFirebat/sm_disassemblyrevised
How we know
5467SamusMovement_SpinJumping: 5468; Handles space jump ⋮ 5513 .spaceJumpEligible: ⋮ 5526 .airPhysics:
src/bank_90.asm lines 5467–5540 at 7af131e · upstream ↗ 5056 .SpaceJumpMinimumYVelocityInAir: 5057; Space jump minimum Y velocity in air * 100h ⋮ 5061; Space jump maximum Y velocity in air * 100h
src/bank_90.asm lines 5056–5062 at 7af131e · 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.
- ^Super Metroid's running acceleration is Metroid's,
$30/256 (0.1875) px/frame² in both, but its top speed rises from Metroid's 1.5 px/frame to 2.75. Metroid II, between them, has no acceleration and walks at 1.5 px/frame.Codenmikstas/metroid-disassembly · alex-west/M2RoS · InsaneFirebat/sm_disassemblyHow we know
2245RunAccelerationTbl: 2246LCCC0: .byte $30 ;Accelerate right.
Source_Files/Bank07.asm lines 2245–2246 at 4270d57 · upstream ↗ 5592LE37F: lda #$18 ; 5593LE381: sta SamusHorzSpdMax ;Set Samus maximum running speed.
Source_Files/Bank07.asm lines 5592–5593 at 4270d57 · upstream ↗ 5648HorzAccelerate: 5649LE3E5: lda SamusHorzSpdMax 5650 jsr Amul16 ; * 16 ⋮ 5653 lda SamusHorzSpdMax 5654 jsr Adiv16 ; / 16 ⋮ 5658 lda HorzCntrLinear 5659 clc 5660 adc SamusHorzAccel
Source_Files/Bank07.asm lines 5648–5660 at 4270d57 · upstream ↗ 4609 ; Normal walking speed (1.5 px/f) 4610 ldh a, [frameCounter] 4611 and $01 4612 add $01 4613 ld b, a ⋮ 4617 ldh a, [hSamusXPixel] 4618 add b
SRC/bank_000.asm lines 4609–4618 at 031aea3 · upstream ↗ 5200 dd wordSwap($0030*!SPF*$100),wordSwap($02C0*!SPF*$100), wordSwap($0080*!SPF*$100) ; 1: Runningsrc/bank_90.asm line 5200 at 7af131e · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^Super Metroid keeps Metroid's release cut, a release during the rise setting the vertical speed to 0, but drops Metroid's 32 px minimum rise. Metroid II, between them, holds a fixed rise for as long as A is held, up to a frame limit.Codenmikstas/metroid-disassembly · alex-west/M2RoS · InsaneFirebat/sm_disassembly
How we know
2705 CMP #$20 2706 BCC + ; branch if jumped less than 32 pixels upwards 2707 BIT Joy1Status 2708 BMI + ; branch if JUMP button still pressed 2709 JSR StopVertMovement ;($D147)Stop jump (start falling).
Source_Files/Bank07.asm lines 2705–2709 at 4270d57 · upstream ↗ 3884 ; Check if in linear portion of ascent 3885 ld a, [samus_jumpArcCounter] 3886 cp samus_jumpArrayBaseOffset 3887 jr nc, .endIf_A 3888 ; If so, check if A is pressed 3889 ldh a, [hInputPressed] 3890 bit PADB_A, a 3891 jr z, .endIf_B ⋮ 3900 .endIf_B: 3901 ; If A is not pressed, start falling portion of arc 3902 ld a, samus_jumpArrayBaseOffset + $16 ;56 3903 ld [samus_jumpArcCounter], a
SRC/bank_000.asm lines 3884–3903 at 031aea3 · upstream ↗ LDA.W SamusYDirection CMP.W #$0001 BNE .setFallingEnd LDA.B DP_Controller1Input AND.W JumpBinding BEQ + LDA.W SamusYSpeed BPL .setFallingEnd + STZ.W SamusYSubSpeed STZ.W SamusYSpeed
src/bank_90.asm#L2786-L2796 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-25.
Checked by a second AI model, 2026-10-21.
Checked by a second AI model, 2026-10-25.
- ^The three games build the high jump three ways. Metroid's High Jump Boots lower the jump's gravity from
$18to$12and keep the take-off speed. Metroid II's Hi-Jump starts the held rise at a lower counter and adds 1 px/frame to it, 3 px/frame for up to 31 frames against 2 for up to 15. Super Metroid's Hi-Jump Boots raise the take-off speed from 4.875 to 6 px/frame, with gravity unchanged.Codenmikstas/metroid-disassembly · alex-west/M2RoS · InsaneFirebat/sm_disassemblyrevisedHow we know
2672SetSamusJump: ⋮ 2681 LDA #$FC 2682 STA ObjVertSpeed ⋮ 2686 LDA SamusGear ⋮ 2693LCFF3: LDY #$18 ; gravity (high value -> low jump) 2694 LDA SamusGear 2695 AND #gr_HIGHJUMP 2696 BEQ + ; branch if Samus doesn't have High Jump 2697 LDY #$12 ; lower gravity value -> high jump! 2698* STY SamusGravity
Source_Files/Bank07.asm lines 2672–2698 at 4270d57 · upstream ↗ 3328 ; High jump parameters 3329 ld a, samus_jumpArrayBaseOffset - $1F ;$21 ⋮ 3337 ; Normal jump parameters 3338 ld a, samus_jumpArrayBaseOffset - $0F ;$31
SRC/bank_000.asm lines 3328–3339 at 031aea3 · upstream ↗ 26def samus_jumpArrayBaseOffset = $40SRC/constants.asm line 26 at 031aea3 · upstream ↗ 3884 ; Check if in linear portion of ascent 3885 ld a, [samus_jumpArcCounter] 3886 cp samus_jumpArrayBaseOffset 3887 jr nc, .endIf_A
SRC/bank_000.asm lines 3884–3887 at 031aea3 · upstream ↗ 3937 ; Increment jump counter 3938 ld a, [samus_jumpArcCounter] 3939 inc a 3940 ld [samus_jumpArcCounter], a
SRC/bank_000.asm lines 3937–3940 at 031aea3 · upstream ↗ 3892 ; Set speed, subtracting an extra 1 from it if we have high jump 3893 ld a, [samusItems] 3894 and itemMask_hiJump 3895 srl a 3896 ld b, a 3897 ld a, -2 ; $FE 3898 sub b
SRC/bank_000.asm lines 3892–3898 at 031aea3 · upstream ↗ 5124 .InitialYSpeeds_Jumping: ⋮ 5130 .InitialYSpeeds_HiJumpJumping:
src/bank_90.asm lines 5124–5131 at 7af131e · upstream ↗ 4702Determine_Samus_YAcceleration: ⋮ 4719 .notSubmerged:
src/bank_90.asm lines 4702–4720 at 7af131e · 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.
- ^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).Codenmikstas/metroid-disassembly · alex-west/M2RoS · InsaneFirebat/sm_disassemblyHow we know
2425 lda #$32 ; 2426 sta SamusBlink ;Samus has been hit. Set blink for 32 frames.
Source_Files/Bank07.asm lines 2421–2426 at 4270d57 · upstream ↗ 7810 ; Give Samus i-frames 7811 ld a, $33 7812 ld [samusInvulnerableTimer], a
SRC/bank_000.asm lines 7810–7812 at 031aea3 · upstream ↗ LDA.W #$0060 STA.W SamusInvincibilityTimer
src/bank_A0.asm#L4918-L4919 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
Sources
Code
- 1994. “Super Metroid (Japan, USA) (En,Ja).” · licence, all uses
- InsaneFirebat and P.JBoy. 2026. “sm_disassembly: a relocatable disassembly of Super Metroid.” Commit 7af131e. InsaneFirebat/sm_disassembly @ 7af131e · licence, all uses
- nmikstas and Kent Hansen. 2025. “metroid-disassembly: Metroid software disassembly.” Commit 4270d57. nmikstas/metroid-disassembly @ 4270d57 · licence, all uses
- alex-west. 2026. “M2RoS: Return of Samus Disassembly.” Commit 031aea3. alex-west/M2RoS @ 031aea3 · licence, all uses