data/claims/smb3.yamlSuper Mario Bros. 3 (Southbird's disassembly, captainsouthbird/smb3)
Game: Super Mario Bros. 3.
Super Mario Bros. 3 keeps Mario's speeds as 4.4 fixed point: the high nibble is whole pixels per frame, the low nibble sixteenths. Player_ApplyYVelocity caps the fall at FALLRATE_MAX, $40, before the frame's gravity is added, so the move never exceeds 4 px a frame. Measured in Mesen from power-on as Raccoon Mario at World 1-1's start, a jump's fall levels off at 4 px a frame. smb3/velocity-format
About: Super Mario Bros. 3 Gravity
Value: 64 1/16 px/frame
Verifiedsmb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) ·PRG/prg008.asm#L6945-L6950CMP #FALLRATE_MAX
BLS PRG008_BFF9 ; If Player_YVelo < FALLRATE_MAX, jump to PRG008_BFF9
…
LDA #FALLRATE_MAX
STA <Player_YVel ; Player_YVel = FALLRATE_MAXsmb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) · PRG/prg024.asm#L21FALLRATE_MAX = $40 ; Maximum Y velocity falling rateChecked by claude, 2026-10-26 — read Player_ApplyVelocity (fraction from the low nibble, whole part from the high nibble as a signed 4-bit value) and Player_ApplyYVelocityProbe: probes/super-mario-bros-3/movement.mjsCited by: Super Mario Bros. 3
A jump takes off at PLAYER_JUMP, -$38, minus Player_SpeedJumpInc indexed by the whole part of Mario's horizontal speed: -$38, -$3A, -$3C, or -$40. Measured in Mesen from power-on as Raccoon Mario at World 1-1's start, a jump from a standstill and one at the full-meter speed $38 take off at -$38 and -$40 (the first frame's speed, one more after that frame's held-A gravity). smb3/jump-speed
About: Super Mario Bros. 3 Jump
Value
[ -56, -58, -60, -64 ]
smb3.asm#L3563PLAYER_JUMP = -$38 ; Player's root Y velocity for jumping (further adjusted a bit by Player_SpeedJumpInc)smb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) · PRG/prg008.asm#L1199-L1204Player_RootJumpVel: .byte PLAYER_JUMP
…
Player_SpeedJumpInc: .byte $00, $02, $04, $08smb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) · PRG/prg008.asm#L2604-L2612TAX ; X = Magnitude of Player's X Velocity >> 4 (the "whole" part)
…
LDA Player_RootJumpVel ; Get initial jump velocity
SUB Player_SpeedJumpInc,X ; Subtract a tiny bit of boost at certain X Velocity speed levels
STA <Player_YVel ; -> Y velocityChecked by claude, 2026-10-26 — read Player_JumpFlyFlutter from the A press to the take-off; top speed $38 makes the index at most 3Probe: probes/super-mario-bros-3/movement.mjsCited by: Super Mario Bros. 3
In the air Player_JumpFlyFlutter adds 5 to Mario's vertical speed each update, or 1 while A is held and he rises faster than $20; a Micro-Goomba stuck to him keeps the 5 even with A held. A tail wag can then overwrite the speed (flight-time, tail-wag), and a Tanooki statue skips this routine (tanooki-statue). Measured in Mesen from power-on as Raccoon Mario at World 1-1's start, a jump with A held gains 1 a frame until the rise slows to -$20, then 5 a frame; with A pressed for one frame it gains 5 a frame from the frame after the take-off. smb3/gravity
About: Super Mario Bros. 3 Gravity
Value
{
"held": 1,
"normal": 5,
"heldAbove": -32
}PRG/prg008.asm#L2644-L2672PRG008_ACB3:
; Player is mid air...
LDY #$05 ; Y = 5
LDA <Player_YVel
CMP #-$20
BGS PRG008_ACC8 ; If Player's Y velocity >= -$20, jump to PRG008_ACC8
LDA Player_mGoomba
BNE PRG008_ACCD ; If Player has got a microgoomba stuck to him, jump to PRG008_ACCD
LDA <Pad_Holding
BPL PRG008_ACC8 ; If Player is NOT pressing 'A', jump to PRG008_ACC8
LDY #$01 ; Y = 1
BNE PRG008_ACCD ; Jump (technically always) to PRG008_ACCD
…Checked by claude, 2026-10-26 — read PRG008_ACB3 to PRG008_ACCD; BGS is the signed BPL macro in smb3.asm, so the light gravity covers speeds from -$38 to -$21. The probe reads Player_YVel ($CF) after each frameProbe: probes/super-mario-bros-3/movement.mjsCited by: Super Mario Bros. 3, Variable jump height
Measured in Mesen from power-on as Raccoon Mario standing at World 1-1's start, a jump with A held rises 71 px, about four and a half tiles, and a jump with A pressed for one frame rises 21 px. Both follow from the take-off (jump-speed) and the two gravities (gravity). smb3/jump-heights
About: Super Mario Bros. 3 Variable jump height
Value
{
"held": 71,
"tap": 21
}smb3.asm#L3563PLAYER_JUMP = -$38 ; Player's root Y velocity for jumping (further adjusted a bit by Player_SpeedJumpInc)smb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) · PRG/prg008.asm#L2644-L2654PRG008_ACB3:
; Player is mid air...
LDY #$05 ; Y = 5
LDA <Player_YVel
CMP #-$20
BGS PRG008_ACC8 ; If Player's Y velocity >= -$20, jump to PRG008_ACC8
LDA Player_mGoombaChecked by claude, 2026-10-26 — the probe reads Player_YHi and Player_Y ($87, $A2) after each frame of a 60-frame jump with A held and of one with A for a frame, from the same snapshotProbe: probes/super-mario-bros-3/movement.mjsCited by: Super Mario Bros. 3
A jump starts on the frame A goes down if Mario is on the ground, or in the air while Player_AllowAirJump is counting down. smb3/jump-start
About: Super Mario Bros. 3 Jump
Codesmb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) ·PRG/prg008.asm#L2548-L2565Player_JumpFlyFlutter:
LDA Player_AllowAirJump
BEQ PRG008_AC30 ; If Player_AllowAirJump = 0, jump to PRG008_AC30
…
DEC Player_AllowAirJump ; Player_AllowAirJump--
…
LDA <Pad_Input
AND #PAD_A
…
LDA Player_AllowAirJump
BNE PRG008_AC41 ; If Player_AllowAirJump <> 0, jump to PRG008_AC41
…
…Checked by claude, 2026-10-26 — read Player_JumpFlyFlutter's entry; Pad_Input is the new-press byte beside Pad_HoldingSome objects Mario rides set Player_AllowAirJump, a countdown in which a jump still starts in the air, to 5, 8, or 16; the Parabeetle sets 5 as it droops. Player_JumpFlyFlutter decrements the count before testing it, so those values leave 4, 7, or 15 updates in which a press of A jumps. smb3/air-jump-window
About: Super Mario Bros. 3 Coyote time
Value
[ 5, 8, 16 ]
smb3.asm#L1279Player_AllowAirJump: .ds 1 ; Counts down to zero, but while set, you can jump in the airsmb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) · PRG/prg005.asm#L2450-L2452LDA #$10
STA Objects_Timer,X ; Set timer to $10
STA Player_AllowAirJump ; Lets Player jump off boltsmb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) · PRG/prg005.asm#L3561-L3565INC <Objects_YVel,X ; Parabeetle starts to droop
…
; Let's Player jump off Parabeetle
LDA #$05
STA Player_AllowAirJumpsmb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) · PRG/prg005.asm#L4035-L4036LDA #$08
STA Player_AllowAirJumpsmb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) · PRG/prg008.asm#L2548-L2562Player_JumpFlyFlutter:
LDA Player_AllowAirJump
BEQ PRG008_AC30 ; If Player_AllowAirJump = 0, jump to PRG008_AC30
DEC Player_AllowAirJump ; Player_AllowAirJump--
PRG008_AC30:
LDA <Pad_Input
AND #PAD_A
STA <Temp_Var1 ; Temp_Var1 = $80 if Player is pressing 'A', otherwise 0
BEQ PRG008_AC9E ; If Player is NOT pressing 'A', jump to PRG008_AC9E
LDA Player_AllowAirJump
BNE PRG008_AC41 ; If Player_AllowAirJump <> 0, jump to PRG008_AC41Checked by claude, 2026-10-26 — grepped every write of Player_AllowAirJump (four in prg005, the rest clear it in prg008) and read Player_JumpFlyFlutter, which runs the DEC before the BNE that allows the jumpCited by: Coyote time, Jump-input forgiveness
Off uphill slopes, Mario's speed tops out at $18 walking, $28 holding B, and $38 while the P-meter is full; walking uphill, the cap comes from Player_UphillSpeedVals instead. Measured in Mesen from power-on as Raccoon Mario at World 1-1's start, holding Right levels off at $18, and Right with B at $28 until the meter fills, then at $38. smb3/top-speeds
About: Super Mario Bros. 3 Running
Value
{
"walk": 24,
"run": 40,
"power": 56,
"max": 64
}smb3.asm#L3559-L3562PLAYER_TOPWALKSPEED = $18 ; Highest X velocity considered as Player "walking"
PLAYER_TOPRUNSPEED = $28 ; Highest X velocity when Player runs
PLAYER_TOPPOWERSPEED = $38 ; Highest X velocity hit when Player is at full "power"
PLAYER_MAXSPEED = $40 ; Player's maximum speedsmb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) · PRG/prg008.asm#L2320-L2382Player_GroundHControl:
LDA Player_UphillFlag
BEQ PRG008_AB56 ; If Player is not going up hill, jump to PRG008_AB56
INC Player_WalkAnimTicks ; Player_WalkAnimTicks++
LDY #10 ; Y = 10 (Player NOT holding B)
BIT <Pad_Holding
BVC PRG008_AB5B ; If Player is NOT holding 'B', jump to PRG008_AB5B
LDY #1 ; Y = 1 (Player holding B)
BNE PRG008_AB5B ; Jump (technically always) to PRG008_AB5B
PRG008_AB56:
; Use override value
LDY Player_UphillSpeedIdx ; Y = Player_UphillSpeedIdx
…Checked by claude, 2026-10-26 — read Player_GroundHControl to PRG008_AB83, which picks the top speed by slope, B, and Player_Power; the probe reads Player_XVel ($BD)Probe: probes/super-mario-bros-3/movement.mjsCited by: Super Mario Bros. 3
Below the top speed, a held direction adds the suit's entry in Player_XAccelMain plus the carry from adding its Player_XAccelPseudoFrac entry to Counter_Wiggly, on the ground and in the air. Each frame Counter_Wiggly becomes its high nibble minus $90, so it steps through all 16 high nibbles: computed, an $E0 fraction carries on 14 of every 16 frames, so every suit but the Frog gains 1 on 14 frames in 16, about 0.88 a frame, while the Frog's entry adds 2 every frame. Pressing against the motion adds 2 the other way for every suit. With no direction held on the ground, or over the top speed on the ground, the friction entry takes 1 on each frame without a carry: 14 in 16 for Super, Fire, and Raccoon Mario ($20), 10 in 16 for small, Tanooki, and Hammer Mario ($60), and every frame for the Frog ($00). Over the top speed in the air nothing changes it, and slippery ground uses other entries. Measured in Mesen from power-on as Raccoon Mario at World 1-1's start, holding Right from rest gains 1 on 14 of any 16 frames and reaches $28 (with B) on the 46th. smb3/ground-accel
About: Super Mario Bros. 3 Running
Value
{
"perFrame": 1,
"framesOf16": 14
}PRG/prg008.asm#L1141-L1152Player_XAccelMain:
; F = "Friction" (stopping rate), "N = "Normal" accel, S = "Skid" accel, X = unused
; Without B button With B button
; F N S X F N S X
.byte -1, 0, 2, 0, -1, 0, 2, 0 ; Small
.byte -1, 0, 2, 0, -1, 0, 2, 0 ; Big
.byte -1, 0, 2, 0, -1, 0, 2, 0 ; Fire
.byte -1, 0, 2, 0, -1, 0, 2, 0 ; Leaf
.byte -1, 2, 2, 0, -1, 2, 2, 0 ; Frog
.byte -1, 0, 2, 0, -1, 0, 2, 0 ; Tanooki
.byte -1, 0, 2, 0, -1, 0, 2, 0 ; Hammersmb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) · PRG/prg008.asm#L1167-L1178Player_XAccelPseudoFrac:
; F = "Friction" (stopping rate), "N = "Normal" accel, S = "Skid" accel, X = unused
; Without B button With B button
; F N S X F N S X
.byte $60, $E0, $00, $00, $60, $E0, $00, $00 ; Small
.byte $20, $E0, $00, $00, $20, $E0, $00, $00 ; Big
.byte $20, $E0, $00, $00, $20, $E0, $00, $00 ; Fire
.byte $20, $E0, $00, $00, $20, $E0, $00, $00 ; Leaf
.byte $00, $00, $00, $00, $00, $00, $00, $00 ; Frog
.byte $60, $E0, $00, $00, $60, $E0, $00, $00 ; Tanooki
.byte $60, $E0, $00, $00, $60, $E0, $00, $00 ; Hammersmb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) · PRG/prg008.asm#L2383-L2497DEY
TYA
ASL A
ASL A
ASL A
ADD #$40
; Y = 40 if slippery
; Y = 46 if very slippery
; Y = ((Player_Slippery - 1) << 3) + $40
TAY
BNE PRG008_AB9E ; And as long as that's not zero, jump to PRG008_AB9E
PRG008_AB98:
…smb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) · PRG/prg008.asm#L339-L343; Makes for "wobbly" raising of the airship at least..
LDA Counter_Wiggly
AND #$F0
SUB #$90
STA Counter_WigglyChecked by claude, 2026-10-26 — read PRG008_AB83 to PRG008_AC01 (the table offset is the suit times 8, plus 4 with B, plus 0 friction, 1 normal, 2 skid) and the Counter_Wiggly update before Player_Update in the level loop; (W & $F0) - $90 keeps the low nibble 0 and steps the high nibble by 7 mod 16. The probe reads Player_XVel ($BD) each frame; the B-release in the run case shows Raccoon Mario losing 17 in 19 frames over the walking top speedProbe: probes/super-mario-bros-3/movement.mjsCited by: Super Mario Bros. 3
The P-meter, Player_Power, is seven bits. Mario runs, for the meter, on a frame he is on the ground and not sliding, with B held and his speed already $28 or more. Each time Player_PMeterCnt reaches 0, a running frame adds a step and sets it to 8, and any other frame takes one away and sets it to 24; at 0 steps the counter stays 0, so the next run adds one at once. A full meter, $7F, takes 7 steps, and each running frame at full sets the counter to 16, so the meter stays full 16 frames past the last one. While Player_FlyTime is counting, none of this runs (flight-time). Measured in Mesen from power-on as Raccoon Mario at World 1-1's start, with Right and B held from rest the first step comes the frame after he reaches $28, then one every 8 frames to full; with B let go, it drops 16 frames later and then every 24. smb3/p-meter
About: Super Mario Bros. 3 Flight
Value
{
"bits": 7,
"steps": 7,
"fillEvery": 8,
"drainEvery": 24,
"hold": 16,
"full": 127
}PRG/prg008.asm#L2346-L2375PRG008_AB62:
LDY #PLAYER_TOPWALKSPEED
BIT <Pad_Holding
BVC PRG008_AB83 ; If Player is NOT holding 'B', jump to PRG008_AB83
; Player is holding B...
LDA <Player_InAir
ORA Player_Slide
BNE PRG008_AB78 ; If Player is mid air or sliding, jump to PRG008_AB78
LDA <Temp_Var3
CMP #PLAYER_TOPRUNSPEED
BMI PRG008_AB78 ; If Player's X Velocity magnitude is less than PLAYER_TOPRUNSPEED, jump to PRG008_AB78
; Player is going fast enough while holding B on the ground; flag running!
…smb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) · PRG/prg008.asm#L981-L1058Player_PowerUpdate:
LDY Player_FlyTime
BEQ PRG008_A4E4 ; If Player is not flying (or at least high-speed jumping), jump to PRG008_A4E4
CPY #$ff
BEQ Sound_FullPowerRing ; If Player_FlyTime = $FF (P-Wing active), jump to Sound_FullPowerRing
LDA <Counter_1
AND #$01
BEQ PRG008_A4D5 ; Every other tick, jump to PRG008_A4D5
DEY
STY Player_FlyTime ; Player_FlyTime--
PRG008_A4D5:
TYA ; Y (Player_FlyTime) -> A
…smb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) · PRG/prg008.asm#L378-L389; Decrement several adjacent counters!
LDX #$07 ; X = 7
PRG008_A1DE:
LDA Event_Countdown,X
BEQ PRG008_A1E6 ; If counter is = 0, jump to PRG008_A1E6
DEC Event_Countdown,X ; Otherwise, decrement it!
PRG008_A1E6:
DEX ; X--
BPL PRG008_A1DE ; While X >= 0, loop!smb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) · smb3.asm#L1545-L1555; NOTE: Event_Countdown and the following 7 are all decremented together!
Event_Countdown: .ds 1
Player_TailCount: .ds 1 ; Determines display frame of tail wag
Player_InAir_OLD: .ds 1 ; Stores backup of Player_InAir
Player_FireCount: ; Player shoots fireball/hammer, sets sprite frame (shared with Player_FrogHopCnt)
Player_FrogHopCnt: .ds 1 ; Counter used for frog hopping along the ground (shared with Player_FireCount)
.ds 1 ; $0514 unused
Player_PMeterCnt: .ds 1 ; Tick counter used to count when to increase/decrease Power MeterChecked by claude, 2026-10-26 — read Player_PowerUpdate and the RunFlag test in Player_GroundHControl; Player_PMeterCnt is the sixth of the eight counters the loop at PRG008_A1DE decrements each frame, and Player_Update calls Player_PowerUpdate every frame. The probe reads Player_Power ($03DD) each frameProbe: probes/super-mario-bros-3/movement.mjsCited by: Flight, Super Mario Bros. 3
A jump with the meter full and no flight time left sets Player_FlyTime to $80, which counts down every other frame, about 256 frames; when it reaches 0 the meter empties ($FF, the P-Wing's value, never counts down). In the Raccoon or Tanooki suit, the suits with the flight bit in PowerUp_Ability, each press of A in the air starts a 16-frame wag. During a wag, unless he is rising faster than -$18, his vertical speed is set to -$18 while the timer is $0F or more, to -$10 from $0E to $08, and to 0 from $07 to $01; since the timer ticks every other frame, those two stages last 14 frames each. At 0 the tail only slows a fall (tail-wag). Measured in Mesen from power-on as Raccoon Mario at World 1-1's start, a jump at full speed with A pressed every 4 frames sets the timer to $80, climbs at -$18, then for 14 frames at -$10 and 14 at 0, and the timer and meter run out 255 frames after the take-off. smb3/flight-time
About: Super Mario Bros. 3 Flight
Value
{
"flyTime": 128,
"updatesPerTick": 2,
"flySpeed": -24,
"lateBelow": 15,
"lateSpeeds": [
-16,
0
],
"lateFrames": 14
}PRG/prg008.asm#L2621-L2629LDA Player_Power
CMP #$7f
BNE PRG008_AC9E ; If Player is not at max power, jump to PRG008_AC9E
LDA Player_FlyTime
BNE PRG008_AC9E ; If Player still has flight time left, jump to PRG008_AC9E
LDA #$80
STA Player_FlyTime ; Otherwise, Player_FlyTime = $80smb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) · PRG/prg008.asm#L981-L999Player_PowerUpdate:
LDY Player_FlyTime
BEQ PRG008_A4E4 ; If Player is not flying (or at least high-speed jumping), jump to PRG008_A4E4
CPY #$ff
BEQ Sound_FullPowerRing ; If Player_FlyTime = $FF (P-Wing active), jump to Sound_FullPowerRing
LDA <Counter_1
AND #$01
BEQ PRG008_A4D5 ; Every other tick, jump to PRG008_A4D5
DEY
STY Player_FlyTime ; Player_FlyTime--
PRG008_A4D5:
TYA ; Y (Player_FlyTime) -> A
…smb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) · PRG/prg008.asm#L2673-L2730BEQ PRG008_ACD9 ; If Player_WagCount = 0, jump to PRG008_ACD9
DEC <Player_WagCount ; Otherwise, $F0--
PRG008_ACD9:
LDA Player_Kuribo
BNE PRG008_ACEF ; If Player is wearing Kuribo's shoe, jump to PRG008_ACEF
LDX <Player_Suit
LDA PowerUp_Ability,X ; Get "ability" flags for this power up
AND #$01
BEQ PRG008_ACEF ; If this power up does not have flight, jump to PRG008_ACEF
LDY <Temp_Var1 ; Y = $80 if Player was pressing 'A' when this all began
BEQ PRG008_ACEF ; And if he wasn't, jump to PRG008_ACEF
LDA #$10
…smb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) · PRG/prg000.asm#L558-L560PowerUp_Ability:
; Small, Big, Fire, Leaf, Frog, Tanooki, Hammer
.byte $00, $00, $00, $01, $02, $01, $02Checked by claude, 2026-10-26 — read Player_JumpFlyFlutter's take-off and tail-wag blocks and Player_PowerUpdate; BLS is the signed BMI macro, so the wag leaves a faster climb alone. The probe reads Player_FlyTime ($056E), Player_Power, and Player_YVel each frameProbe: probes/super-mario-bros-3/movement.mjsCited by: Flight, Super Mario Bros. 3
On the ground, Player_JumpFlyFlutter clears Player_FlyTime unless the suit has the flight bit, so Raccoon and Tanooki Mario keep the rest of a flight through a landing, with the meter still full, and can take off again; for the other suits a full-meter jump's timer ends when they land. smb3/flight-landing
About: Super Mario Bros. 3 Flight
Codesmb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) ·PRG/prg008.asm#L2631-L2642PRG008_AC9E:
LDA <Player_InAir
BNE PRG008_ACB3 ; If Player is mid air, jump to PRG008_ACB3
LDY <Player_Suit
LDA PowerUp_Ability,Y ; Get "ability" flags for this power up
AND #$01
BNE PRG008_AD1A ; If power up has flight ability, jump to PRG008_AD1A
LDA #$00
STA Player_FlyTime ; Otherwise, Player_FlyTime = 0 :(
JMP PRG008_AD1A ; Jump to PRG008_AD1AChecked by claude, 2026-10-26 — read PRG008_AC9E; Player_PowerUpdate leaves Player_Power alone while Player_FlyTime is nonzero, and the take-off branch sets the timer only when it is 0Cited by: Super Mario Bros. 3
Out of flight time, a wag of A with the Raccoon or Tanooki tail caps Mario's fall at PLAYER_TAILWAG_YVEL, $10, and leaves a rise or a slower fall alone. Measured in Mesen from power-on as Raccoon Mario at World 1-1's start, wagging every 4 frames after a flight runs out, his fall levels off at $10, 1 px a frame. smb3/tail-wag
About: Super Mario Bros. 3 Flight
Value: 16 1/16 px/frame
Verifiedsmb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) ·PRG/prg008.asm#L2683-L2691LDA PowerUp_Ability,X ; Get "ability" flags for this power up
AND #$01
BEQ PRG008_ACEF ; If this power up does not have flight, jump to PRG008_ACEF
LDY <Temp_Var1 ; Y = $80 if Player was pressing 'A' when this all began
BEQ PRG008_ACEF ; And if he wasn't, jump to PRG008_ACEF
LDA #$10
STA <Player_WagCount ; Otherwise, Player_WagCount = $10smb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) · PRG/prg008.asm#L2720-L2730PRG008_AD0E:
LDA <Player_YVel
BMI PRG008_AD1A ; If Player's Y velocity < 0 (moving upward), jump to PRG008_AD1A
CMP #PLAYER_TAILWAG_YVEL
BLT PRG008_AD1A ; If Player's Y velocity < PLAYER_TAILWAG_YVEL, jump to PRG008_AD1A
LDY #PLAYER_TAILWAG_YVEL ; Y = PLAYER_TAILWAG_YVEL
PRG008_AD18:
STY <Player_YVel ; Set appropriate Y velocityChecked by claude, 2026-10-26 — read the wag-count and RACCOON / TANOOKI TAIL WAG LOGIC blocks of Player_JumpFlyFlutter; the probe reads Player_YVel each frameProbe: probes/super-mario-bros-3/movement.mjsCited by: Flight, Super Mario Bros. 3
Raccoon and Tanooki Mario swing the tail on a press of B when Down isn't held and no swing is under way: Player_TailAttack is set to $12, 18 frames of the swing. smb3/tail-attack
PRG/prg008.asm#L3574-L3591Player_TailAttackAnim:
LDA <Pad_Holding
AND #PAD_DOWN
BNE PRG008_B109 ; If Player is holding down, jump to PRG008_B109
BIT <Pad_Input
BVC PRG008_B0E2 ; If Player is NOT pressing 'B', jump to PRG008_B0E2
LDA Player_TailAttack
BNE PRG008_B0E2 ; If Player is performing tail attack, jump to PRG008_B0E2
LDA #$12
STA Player_TailAttack ; Player_TailAttack = $12
; Plays the tail wag sound
LDA Sound_QLevel1
…smb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) · PRG/prg008.asm#L2010-L2015GndMov_Leaf:
JSR Player_GroundHControl ; Do Player left/right input control
JSR Player_JumpFlyFlutter ; Do Player jump, fly, flutter wag
JSR Player_AnimTailWag ; Do Player's tail animations
JSR Player_TailAttackAnim ; Do Player's tail attack animations
RTS ; ReturnChecked by claude, 2026-10-26 — read Player_TailAttackAnim, which GndMov_Leaf and GndMov_Tanooki call; Player_TailAttack is one of the counters the loop at PRG008_A1DE decrements each frameCited by: Super Mario Bros. 3
With neither Left nor Right held, Mario's horizontal speed gets friction only on the ground; in the air the routine returns and he keeps his speed. smb3/air-coast
About: Super Mario Bros. 3 Air control
Codesmb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) ·PRG/prg008.asm#L2413-L2421PRG008_ABA6:
LDA <Pad_Holding
AND #(PAD_LEFT | PAD_RIGHT)
BNE PRG008_ABB8 ; If Player is pressing LEFT or RIGHT, jump to PRG008_ABB8
…
LDA <Player_InAir
BNE PRG008_AC01 ; If Player is mid air, jump to PRG008_AC01 (RTS)Checked by claude, 2026-10-26 — read PRG008_ABA6 to PRG008_ABCD; a held direction applies the suit's acceleration table in the air too, but over top speed the air case also returns without frictionCited by: Super Mario Bros. 3
Holding only Down on a slope starts a slide, except in the Frog or Hammer suit (bit 1 of PowerUp_Ability) or Kuribo's Shoe. Each update the slope's push is added to the slide speed, which is capped at $40 and then loses 1 toward 0, so it tops out at $3F. smb3/slope-slide
About: Super Mario Bros. 3 Slope sliding
Value
{
"cap": 64,
"friction": 1
}PRG/prg008.asm#L5990-L6017PRG008_BBBF:
LDA Player_Slide
BNE PRG008_BBE0 ; If Player is sliding, jump to PRG008_BBE0
; Check ability to slide
TXA ; Effect on velocity -> 'A'
BEQ PRG008_BC0D ; If no effect (flat ground), jump to PRG008_BC0D
LDY <Player_Suit
LDA PowerUp_Ability,Y
AND #$02
BNE PRG008_BC0D ; If the Player's suit CANNOT slide on slopes, jump to PRG008_BC0D
LDA Player_Kuribo
BNE PRG008_BC0D ; If Player is wearing Kuribo's shoe, jump to PRG008_BC0D
…smb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) · PRG/prg008.asm#L6024-L6042CMP #$40
BLS PRG008_BBFD ; If magnitude of Player_Slide < $40, jump to PRG008_BBFD
…
DEC Player_Slide ; Player_Slide--
BPL PRG008_BC08 ; If Player_Slide >= 0, jump to PRG008_BC08
…
INC Player_Slide
INC Player_Slidesmb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) · smb3.asm#L1590Player_Slide: .ds 1 ; Positive values sliding forward, negative values sliding backward; directly sets Player_XVelChecked by claude, 2026-10-26 — read PRG008_BBBF to PRG008_BC08; suits whose ability flags have bit 1 set, and Kuribo's shoe, can't start a slideCited by: Slope sliding, Super Mario Bros. 3
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. smb3/flash-invincibility
About: Super Mario Bros. 3 Invincibility frames
Value: 113 draws
Codesmb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) ·PRG/prg000.asm#L5620-L5629Player_GetHurt:
; If Player is...
LDA Player_FlashInv ; ... flashing invincible ...
…
BNE PRG000_D9B7 ; ... then jump to PRG000_D9B7 (RTS)smb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) · PRG/prg000.asm#L5744-L5746PRG000_DA6D:
LDA #$71
STA Player_FlashInv ; Player_FlashInv = $71smb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) · PRG/prg029.asm#L423-L429LDA Player_FlashInv
BEQ PRG029_CED7 ; If Player_FlashInv = 0, jump to PRG029_CED7
…
DEC Player_FlashInv ; Player_FlashInv--
AND #$02
BEQ PRG029_CED7 ; Every 2 ticks, draw PlayerChecked by claude, 2026-10-26 — read Player_GetHurt through PRG000_DA6D and the countdown in Player_Draw (prg029)Cited by: Super Mario Bros. 3
PowerUp_Ability gives each form two flags: bit 0, flight and the tail wag, for the Raccoon and Tanooki suits; bit 1, which keeps Mario from starting a slope slide, for the Frog and Hammer suits. Small, Super, and Fire Mario have neither. smb3/suit-abilities
PRG/prg000.asm#L558-L560PowerUp_Ability:
; Small, Big, Fire, Leaf, Frog, Tanooki, Hammer
.byte $00, $00, $00, $01, $02, $01, $02smb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) · PRG/prg008.asm#L583-L590LevelInit_StartSliding:
LDY <Player_Suit
LDA PowerUp_Ability,Y
AND #$02
BNE LevelInit_DoNothing ; If this powerup is not able to slide on slopes, jump to LevelInit_DoNothing
INC Player_Slide ; Otherwise, begin sliding...Checked by claude, 2026-10-26 — read the table and its uses in Player_JumpFlyFlutter (ANDCited by: Super Mario Bros. 3
In the Tanooki suit, a press of B while Down is held, when he isn't a statue already, queues the statue: Player_Update sets Player_Statue to $C0, and it counts down one a frame while Down stays held, about 3.2 seconds at most; letting go of Down, or the count reaching 1, ends it. A statue doesn't move sideways, gets 7 a frame of gravity in the air in place of the jump routine's, and skips the suit's other moves; at $60 left, Player_FlashInv is set so he blinks for the rest. smb3/tanooki-statue
PRG/prg008.asm#L3319-L3400Player_TanookiStatue:
LDA <Pad_Holding
AND #PAD_DOWN
TAY
BEQ PRG008_AFE3 ; If Player is NOT pressing down, jump to PRG008_AFE3
BIT <Pad_Input
BVC PRG008_AFE3 ; If Player is NOT pressing 'B', jump to PRG008_AFE3
LDA Player_Statue
BNE PRG008_AFE3 ; If Player is transformed into a statue, jump to PRG008_AFE3
JSR Sound_StatueSwitch ; Play statue transformation sound
LDA #$20
STA Player_QueueSuit ; Player_QueueSuit = $20
…smb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) · PRG/prg008.asm#L794-L815Player_Update:
LDA Player_QueueSuit
BEQ PRG008_A3FA ; If we don't have a suit change queued, jump to PRG008_A3FA
CMP #$0f
BLS PRG008_A3EC ; If Player_QueueSuit < $0F (statue enable), jump to PRG008_A3EC
CMP #$80
BNE PRG008_A3DC ; If Player_QueueSuit <> $80 (Kuribo's shoe), jump to PRG008_A3DC
; Kuribo's shoe enable!
INC Player_Kuribo ; Set the Player_Kuribo flag
BNE PRG008_A3F2 ; Jump (expectedly always) to PRG008_A3F2
PRG008_A3DC:
CMP #$40
…smb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) · PRG/prg008.asm#L2238-L2244GndMov_Tanooki:
JSR Player_TanookiStatue ; Change into/maintain Tanooki statue (NOTE: Will not return here if statue!)
JSR Player_GroundHControl ; Do Player left/right input control
JSR Player_JumpFlyFlutter ; Do Player jump, fly, flutter wag
JSR Player_AnimTailWag ; Do Player's tail animations
JSR Player_TailAttackAnim ; Do Player's tail attack animations
RTS ; ReturnChecked by claude, 2026-10-26 — read Player_TanookiStatue, the queue in Player_Update ($20 is at least $0F and neither $40 nor $80, so it becomes the statue), and GndMov_Tanooki; the PLA PLA at PRG008_AFE0 drops the return into GndMov_Tanooki, so its control, jump, and tail calls don't runCited by: Super Mario Bros. 3
Enemies and their fireballs don't hurt a Tanooki statue: Player_GetHurt, the enemy-contact check, and the special objects' contact check all return while Player_Statue is set. Where an enemy can't otherwise be stomped, or Mario is in water, landing on it from above as a statue (or in Kuribo's Shoe) leaves an enemy flagged OA2_STOMPDONTCARE as it was, since the routine returns; any other enemy is stomped, then squashed if a stomp would squash it, or else killed outright. smb3/statue-contact
PRG/prg000.asm#L5620-L5631Player_GetHurt:
; If Player is...
LDA Player_FlashInv ; ... flashing invincible ...
ORA Player_Statue ; ... a statue ...
ORA Player_StarInv ; ... invincible by star ...
ORA Player_SuitLost ; ... just lost a power-up suit ...
ORA <Player_HaltGame ; ... gameplay halted ...
ORA Player_HaltTick ; ... Player halted ...
ORA Player_DebugNoHitFlag ; ... debug invincibility flag is set (unused) ...
BNE PRG000_D9B7 ; ... then jump to PRG000_D9B7 (RTS)
JMP PRG000_DA15 ; Jump to PRG000_DA15 (skips lost/dead Japanese version code)smb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) · PRG/prg000.asm#L3862-L3904PRG000_D267:
; Player is in water (can't stomp in water) OR attribute 3 bit 5 is set (can't stomp anyway)...
LDA Player_Kuribo
ORA Player_Statue
BNE PRG000_D272 ; If in Kuribo's shoe or transformed into statue, ignore this and jump to PRG000_D272
JMP PRG000_D355 ; Jump to PRG000_D355 (hurt Player!)
PRG000_D272:
; Enemy got stomped!
LDY ObjGroupRel_Idx ; Y = group relative index
LDA ObjectGroup_Attributes2,Y ; Get object attribute set 2
AND #OA2_STOMPDONTCARE
BNE PRG000_D2B3 ; If OA2_STOMPDONTCARE is set (object is indifferent about stomping), jump to PRG000_D2B3 (RTS)
…smb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) · PRG/prg000.asm#L4070-L4075PRG000_D355:
; Player potentially gonna get hurt!
LDA Player_FlashInv ; If Player is flashing from getting hit recently...
ORA Player_Statue ; ... or Player is a statue ...smb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) · PRG/prg007.asm#L4769-L4777PRG007_B805:
LDA Player_FlashInv ; If Player is flashing from being hit ...
ORA Player_Statue ; ... if Player is a statue ...
ORA <Player_HaltGame ; ... if gameplay is halted ...
ORA Player_IsDying ; ... Player is dying ...
ORA Player_OffScreen ; ... Player is off-screen ...
ORA Player_Behind_En ; ... Player is legitimately hidden behind the scenes ...
ORA <Temp_Var14 ; ... or special object is not vertically on-screen ...
BNE PRG007_B843 ; ... jump to Player_Behind_En (RTS)Checked by claude, 2026-10-26 — read the hit-from-top branch of the player-enemy contact code (PRG000_D267 to PRG000_D297) and PRG000_D355; Kuribo's Shoe takes the same stomp branchCited by: Super Mario Bros. 3
Out of water and not holding anything, Frog Mario hops. On the ground, when no hop is under way, his horizontal speed is set to 0, and a held direction starts a hop (Player_FrogHopCnt = $1F), during which the Frog's acceleration entry adds 2 a frame (ground-accel). In the air, unless he is sinking in quicksand, the hop count is cleared and Player_GroundHControl steers him as it does the other suits. Holding something, he moves like the other suits on the ground too. smb3/frog-hop
PRG/prg008.asm#L2019-L2063GndMov_Frog:
JSR Player_GroundHControl ; Do Player left/right input control
JSR Player_JumpFlyFlutter ; Do Player jump, fly, flutter wag
LDA Player_IsHolding
BNE PRG008_AA23 ; If Player is holding something, jump to PRG008_AA23
LDA <Player_InAir
BEQ PRG008_AA00 ; If Player is NOT in mid air, jump to PRG008_AA00
LDA Player_SandSink
LSR A
BCS PRG008_AA00 ; If bit 0 of Player_SandSink is set, jump to PRG008_AA00
LDA #$00
STA Player_FrogHopCnt ; Player_FrogHopCnt = 0
…Checked by claude, 2026-10-26 — read GndMov_Frog: Player_GroundHControl and Player_JumpFlyFlutter run first in every case, and holding something branches straight to the RTS. Player_FrogHopCnt counts down with the loop at PRG008_A1DECited by: Super Mario Bros. 3
Under water the Frog suit sets Mario's speed straight from the d-pad: 16 (1 px/frame) each way, doubled to 32 while A is held, and with a direction released that speed eases back toward 0 by 1 a frame; Up gives 0 while he is above the top of the screen. smb3/frog-swim
PRG/prg008.asm#L2082-L2175Frog_Velocity:
.byte 16, -16
Swim_Frog:
LDX #$ff ; X = $FF
LDA <Pad_Holding
AND #(PAD_UP | PAD_DOWN)
BEQ PRG008_AA61 ; If Player is NOT pressing up/down, jump to PRG008_AA61
;
STA <Player_InAir
LSR A
LSR A
LSR A
…Checked by claude, 2026-10-26 — read Swim_Frog to PRG008_AA9C. The `PLAYER_FROG_MAXYVEL` cap never acts: Player_InAir has just been set to the held Up or Down bits, so the branch past the cap is always takenCited by: Super Mario Bros. 3
With the Fire Flower or the Hammer Suit, a press of B throws a weapon unless Mario is ducking, kicking, in a pipe, or the game is halted: Fire Mario's fireball starts downward, the Hammer Suit's hammer upward. Ducking in the Hammer Suit, the fireballs of Piranha Plants, Nippers, Fire Bros., and Fire Chomps collide with him as if he had a Starman's invincibility, which destroys the fireball instead of hurting him. smb3/hammer-suit
PRG/prg007.asm#L479-L499CMP #PLAYERSUIT_HAMMER
BEQ PRG007_A251 ; If Player is wearing a Hammer Suit, jump to PRG007_A251
CMP #PLAYERSUIT_FIRE
BNE PRG007_A268 ; If Player is not Fire, jump to PRG007_A268
PRG007_A251:
; Player wearing a Hammer Suit or Fire
LDA Player_HaltTick ; If Player is not halted ...
ORA Player_IsDucking ; ... Player is ducking ...
ORA Player_Kick ; ... Player is kicking ...
ORA Player_InPipe ; ... Player is in a pipe ...
ORA <Player_HaltGame ; ... gameplay is halted ...
BNE PRG007_A268 ; ... then jump to PRG007_A268
…smb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) · PRG/prg007.asm#L586-L601LDA #$01 ; A = 1
LDY <Player_Suit
CPY #PLAYERSUIT_HAMMER
SEC ; Set carry (if NOT wearing the hammer suit)
BNE PRG007_A2E3 ; If Player is NOT wearing the Hammer Suit, jump to PRG007_A2E3
ASL A ; Clears carry, also A = 2
PRG007_A2E3:
STA PlayerProj_ID,X ; Set projectile as type 1 or 2
; Set Player Projectile Y velocity
LDA #$03 ; A = $03 (Fireballs are thrown down)
BCS PRG007_A2EC ; If Player is NOT wearing Hammer Suit, jump to PRG007_A2EC
LDA #-$03 ; A = -$03 (Hammers are thrown up)
…smb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) · PRG/prg007.asm#L3184-L3198.word SObj_Fireball ; 04: Nipper fireball
.word SObj_Fireball ; 05: Piranha fireball
…
.word SObj_Fireball ; 0C: Fire bro bouncing fireball
…
.word SObj_Fireball ; 12: Fire Chomp's firesmb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) · PRG/prg007.asm#L5213-L5242PRG007_BA6E:
; Set fireball attributes
STA Sprite_RAM+$02,Y
LDX <SlotIndexBackup ; X = special object slot index
LDA <Player_Suit
CMP #$06
BNE PRG007_BA8F ; If Player is not wearing the Hammer Suit, jump to PRG007_BA8F
LDA Player_IsDucking
BEQ PRG007_BA8F ; If Player is NOT ducking (immunity to fireballs), jump to PRG007_BA8F
LDA Player_StarInv
PHA ; Save Player's Star Man invincibility status
; Collide with it like Player were invincible! (Visually the shell protects him)
…smb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) · PRG/prg007.asm#L4805-L4824PRG007_B836:
LDA Player_StarInv
BNE PRG007_B844 ; If Player is Star Man invincible, jump to PRG007_B844
JMP Player_GetHurt ; Hurt Player and don't come back!
SpecialObj_Remove:
; Remove special object
LDA #$00
STA SpecialObj_ID,X
PRG007_B843:
RTS ; Return
PRG007_B844:
; Player is invincible; destroy the special object!
…Checked by claude, 2026-10-26 — read Gameplay_UpdateAndDrawMisc's weapon throw, the special-object jump table (SObj_Fireball serves the four fireballs named), the end of SObj_Fireball, and SObj_PlayerCollide, which removes the object with a kick sound when Player_StarInv is set and otherwise calls Player_GetHurtCited by: Super Mario Bros. 3
In this release a hit takes Mario down one step: from the Fire Flower or any suit (Raccoon, Frog, Tanooki, Hammer) back to Super Mario, from Super to small, and as small Mario he dies. In Kuribo's Shoe the hit takes the shoe and he keeps his form. A hit is ignored while he blinks from the last one, is a statue, has a Starman, has just lost a suit, or the game is halted, and while the debug no-hit flag is set. smb3/power-down
PRG/prg000.asm#L5620-L5632Player_GetHurt:
; If Player is...
LDA Player_FlashInv ; ... flashing invincible ...
ORA Player_Statue ; ... a statue ...
ORA Player_StarInv ; ... invincible by star ...
ORA Player_SuitLost ; ... just lost a power-up suit ...
ORA <Player_HaltGame ; ... gameplay halted ...
ORA Player_HaltTick ; ... Player halted ...
ORA Player_DebugNoHitFlag ; ... debug invincibility flag is set (unused) ...
BNE PRG000_D9B7 ; ... then jump to PRG000_D9B7 (RTS)
JMP PRG000_DA15 ; Jump to PRG000_DA15 (skips lost/dead Japanese version code)smb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) · PRG/prg000.asm#L5673-L5755PRG000_DA15:
LDA Player_Kuribo
BNE PRG000_DA32 ; If Player is in Kuribo's shoe, jump to PRG000_DA32
LDA <Player_Suit
CMP #PLAYERSUIT_FIRE ; SB: Change this to "PLAYERSUIT_SUPERSUITBEGIN" and you restore Japanese version's "always shrink" code!!
BLS PRG000_DA4E ; If Player is Big or small, jump to PRG000_DA4E
…
LDA #$02 ; Return to Big (SB: Would be small in Japanese version!!)
JMP PRG000_DA44 ; Jump to PRG000_DA44
…
LDA #$00
STA <Temp_Var1 ; Temp_Var1 = 0
…Checked by claude, 2026-10-26 — read Player_GetHurt from PRG000_DA15; Player_QueueSuit holds the form plus 1, so 2 is Super Mario, and DEC after 2 makes 1, small. Player_DebugNoHitFlag is toggled only by the debug code in prg000Cited by: Super Mario Bros. 3
Player_GetHurt jumps over a block that Southbird's comments mark as the Japanese version's code, and a comment says the Japanese version "always" shrinks Mario: in that block, any hit on a powered Mario queues small Mario, with the Frog, Tanooki, and Hammer suits flying off. smb3/power-down-japan
PRG/prg000.asm#L5631-L5671JMP PRG000_DA15 ; Jump to PRG000_DA15 (skips lost/dead Japanese version code)
;;;;;;;;;;;;;; Begin SMB3-J Only Code ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; SB: Lost/Dead Code -- This was the Japanese version suit loss code
; For detail why it was removed, see PRG007 LostShoe_Pattern
; $D9EC
LDA Player_Kuribo
BNE PRG000_D9F7 ; If Player is in Kuribo's Shoe, jump to PRG000_D9F7
; Player is NOT in Kuribo's Shoe...
LDA <Player_Suit
CMP #PLAYERSUIT_SUPERSUITBEGIN
BLS PRG000_DA4E ; If Player is not in one of the Super Suits, jump to PRG000_DA4E
…
…smb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) · PRG/prg000.asm#L5678CMP #PLAYERSUIT_FIRE ; SB: Change this to "PLAYERSUIT_SUPERSUITBEGIN" and you restore Japanese version's "always shrink" code!!Checked by claude, 2026-10-26 — read the SMB3-J block (unreached in this build); Player_QueueSuit 1 is small Mario, and Fire, Raccoon, and Super Mario fall through to the shrink at PRG000_DA4E. The Japanese ROM itself isn't read hereTier 1 because the Japanese version's behavior rests on the comments; a probe on the Japanese cartridge would settle it.
Cited by: Super Mario Bros. 3
Touching a shell as a statue or in Kuribo's Shoe kicks it. Otherwise the touch does nothing while he is already holding something; with B held he picks the shell up, and without B he kicks it. A carried shell is kicked when B is let go, except while he is in a pipe or dying. A kicked shell gets 3 px/frame ($30) the way he faces, or for a shell on the ground away from him, plus half his speed when he moves the same way. A Bob-omb is thrown instead (bobomb-throw), and a carried shell let go against a wall dies (shell-wall-kill). smb3/shell-carry
PRG/prg000.asm#L4042-L4066Object_HoldKickOrHurtPlayer:
LDA Objects_State,X
CMP #OBJSTATE_SHELLED
BNE PRG000_D355 ; If object state is not Shelled, jump to PRG000_D355 (hurt Player!)
LDA Player_Kuribo
ORA Player_Statue
BEQ PRG000_D343 ; If Player is NOT in Kuribo's shoe and NOT in a statue, jump to PRG000_D343
JMP PRG000_D2A2 ; Otherwise, jump to PRG000_D2A2
PRG000_D343:
LDA Player_ISHolding_OLD
BNE PRG000_D39F ; If Player WAS holding something, jump to PRG000_D39F (RTS)
BIT <Pad_Holding
…smb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) · PRG/prg000.asm#L2794ObjectKickXVelMoving: .byte -$30, $30smb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) · PRG/prg000.asm#L2810-L2849ObjState_Held:
LDA <Player_IsDying
BEQ PRG000_CE28 ; If Player is NOT dying, jump to PRG000_CE28
JMP PRG000_CF98 ; Jump to PRG000_CF98 (just draw held object)
PRG000_CE28:
JSR Object_ShellDoWakeUp ; Wake up while Player is holding object...
BIT <Pad_Holding
BVC Player_KickObject ; If Player is NOT holding B button, jump to Player_KickObject
PRG000_CE2F:
JMP PRG000_CEEF ; Jump to PRG000_CEEF
Player_KickObject:
LDA Level_PipeMove
…smb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) · PRG/prg000.asm#L2934-L2988PRG000_CEB4:
; Object kicked not against wall...
LDY #0 ; Y = 0
LDA <Player_FlipBits
BEQ PRG000_CEBB ; If Player has not turned around, jump to PRG000_CEBB
INY ; Y = 1
PRG000_CEBB:
JMP PRG000_CEC6 ; Jump to PRG000_CEC6
PRG000_CEBE:
; Object kicked, was not held
; Make sure Player is facing object he's kicking
JSR Level_ObjCalcXDiffs
…Checked by claude, 2026-10-26 — read Object_HoldKickOrHurtPlayer, ObjState_Held, Player_KickObject to the Bob-omb test, and PRG000_CEB4 to PRG000_CEE8; the half speed is an arithmetic shift right of Player_XVel. A kicked object already killed keeps its stateCited by: Super Mario Bros. 3
Kicking a Bob-omb, lit or not, throws it instead: it keeps its normal state, bounces up at -$20, and moves away from Mario at $28, or at $30 plus half his speed when he moves that way. smb3/bobomb-throw
PRG/prg000.asm#L2794-L2800ObjectKickXVelMoving: .byte -$30, $30
; Set appropriate flip bits based on object's relative position to Player
PlayerKickFlipBits: .byte $00, $40
; X velocities depending on kick direction
BobombKickXVel: .byte -$28, $28smb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3) · PRG/prg000.asm#L2844-L2879CMP #OBJ_BOBOMBEXPLODE
BEQ PRG000_CE54 ; If this is a Bob-omb ready to explode, jump to PRG000_CE54
CMP #OBJ_BOBOMB
BNE PRG000_CE79 ; If this is NOT a Bob-omb, jump to PRG000_CE79
PRG000_CE54:
; Bob-ombs only...
; State remains "normal"
LDA #OBJSTATE_NORMAL
STA Objects_State,X
; Set Y vel to -$20 (bounce up)
LDA #-$20
STA <Objects_YVel,X
…Checked by claude, 2026-10-26 — read Player_KickObject's Bob-omb branch, PRG000_CE54 to PRG000_CE76; the EOR with Player_XVel tests whether the two speeds share a signCited by: Super Mario Bros. 3
Kicking a carried object other than a Bob-omb or an ice block first gives it a speed of 1 the way Mario faces and tests it against the level. If it touches a wall it dies instead, flying up at -$40, for 100 points; otherwise the kick goes ahead (shell-carry). smb3/shell-wall-kill
PRG/prg000.asm#L2880-L2933PRG000_CE79:
; Anything besides a Bob-omb...
; Clear Objects_KillTally
LDA #$00
STA Objects_KillTally,X
LDA Objects_State,X
CMP #OBJSTATE_HELD
BNE PRG000_CEBE ; If object's state is not Held, jump to PRG000_CEBE
; This object is being held by Player...
LDA Level_ObjectID,X
CMP #OBJ_ICEBLOCK
BEQ PRG000_CEB4 ; If this is an ice block, jump to PRG000_CEB4
…Checked by claude, 2026-10-26 — read PRG000_CE79 to PRG000_CEB4; an object kicked without being held skips to PRG000_CEBE, so the wall test applies only to a carried oneCited by: Super Mario Bros. 3