data/claims/super-mario-world.yamlSuper Mario World (IsoFrieze/SMWDisX, and measured in Mesen)
Game: Super Mario World.
On the ground, a fresh press of B (or X) starts Mario's jump and a fresh press of A a spin jump; CODE_00D5F2 takes the take-off speed from DATA_00D2BD at an index set by his horizontal speed. super-mario-world/jump-start
About: Super Mario World Jump
CodeSMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) ·bank_00.asm#L9921-L9924CODE_00D5F2:
LDA.B PlayerInAir
BEQ +
JMP CODE_00D682SMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L9940-L9942LDA.B byetudlrFrame
ORA.B axlr0000Frame
BMI CODE_00D630SMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L9953-L9982CODE_00D630:
LDA.B PlayerXSpeed+1
…
+ LSR A
LSR A
AND.B #$FE
TAX
LDA.B axlr0000Frame
BPL CODE_00D65E
…
INX
…
…Checked by claude, 2026-10-20 — read CODE_00D5F2 through CODE_00D67D and ControllerUpdate at the pinned commitbyetudlrFrame carries B and X as fresh presses and axlr0000Frame carries A, so B or X gives a normal jump and A (unless Mario carries an item) a spin jump. The index is |X speed| ÷ 4 with the low bit cleared, one step per 8/16 px/frame; a spin jump adds 1.
Cited by: Jump, Spin jump, Super Mario World
DATA_00D2BD gives a normal jump −80/16 to −97/16 px/frame ($B0–$9F) and a spin jump −74/16 to −90/16 ($B6–$A6), faster for every 0.5 px/frame of horizontal speed. super-mario-world/jump-speed-table
About: Super Mario World Jump
Value
{
"normal": [
-80,
-82,
-85,
-87,
-90,
-92,
-95,
-97
],
"spin": [
-74,
-76,
-78,
-80,
-82,
-85,
-87,
-90
]
}bank_00.asm#L9673-L9675DATA_00D2BD:
db $B0,$B6,$AE,$B4,$AB,$B2,$A9,$B0
db $A6,$AE,$A4,$AB,$A1,$A9,$9F,$A6Checked by claude, 2026-10-20 — read the table at the pinned commit; the probe reads the same 16 bytes from the U ROM at SMW_U.sym's address for the label ($00D2BD)Pairs of (normal, spin) by |X speed| band: 0–7, 8–15, 16–23, 24–31, 32–39, 40–47, 48–55, and 56–63 sixteenths per frame. Speeds are the high byte of PlayerYSpeed, in 1/16 px/frame, negative up.
Cited by: Jump, Spin jump, Super Mario World, Variable jump height
Each frame CODE_00D928 adds 3/16 px/frame to Mario's vertical speed while A or B is held and 6/16 otherwise, rising or falling. super-mario-world/gravity
About: Super Mario World Gravity
Value
{
"held": 3,
"released": 6
}bank_00.asm#L10167-L10169DATA_00D7A5: ;!
db $06,$03,$04,$10,$F4,$01,$03,$04 ;!SMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L10439-L10444CODE_00D928:
LDY.B #$01
LDA.B byetudlrHold
BMI +
CODE_00D92E:
LDY.B #$00SMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L10457-L10459CODE_00D948: ;!
CLC ;!
ADC.W DATA_00D7A5,Y ;!SMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L821-L824 — A shares bit 7 of the held byte with B, so either counts as held+ LDA.W axlr0000P1Hold,X ;\
AND.B #!ButA|!ButX ;| Set up $15, sharing the top two bits of controller data 2 (for A/X).
ORA.W byetudlrP1Hold,X ;|
STA.B byetudlrHold ;/Checked by claude, 2026-10-20 — read CODE_00D7E4 through CODE_00D94C (the NTSC branch) and ControllerUpdate at the pinned commit; small Mario without a cape or Yoshi reaches CODE_00D928Other paths through the same routine, for the cape and for winged Yoshi, use the table's other entries. Swimming has its own routine (CODE_00D988). The probe measured both steps (fall-speed).
Cited by: Gravity, Super Mario World, Variable jump height
Gravity's routine cuts a downward speed above $40 (4 px/frame) back to $40 before adding gravity, so Mario falls at most 70/16 px/frame, or 67/16 holding the button. super-mario-world/fall-speed
About: Super Mario World Gravity
Value
{
"clamp": 64,
"held": 67,
"released": 70
}bank_00.asm#L10171-L10173DATA_00D7AF: ;!
db $40,$40,$20,$40,$40,$40,$40,$40 ;!SMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L10446-L10450+ LDA.B PlayerYSpeed+1 ;! \ If Mario's Y speed is negative (up),
BMI CODE_00D948 ;! / branch to $D948
CMP.W DATA_00D7AF,Y ;!
BCC + ;!
LDA.W DATA_00D7AF,Y ;!Checked by claude, 2026-10-20 — read the clamp at the pinned commit; the probe logged Mario's vertical speed every frame of a standing jump, which ends at 67 with B held and at 70 after an early releaseProbe: probes/jump-physics/emu-jumps.mjsEvery value is stored after gravity, so $40 itself never moves Mario.
Cited by: Gravity, Super Mario World, Variable jump height
Each frame the player routine moves Mario by his current speed (CODE_00DC2D), then handles a jump press (CODE_00D5F2), then adds gravity (CODE_00D7E4), so the press frame doesn't lift him and his first step up is the take-off speed plus held gravity. super-mario-world/motion-order
About: Super Mario World Gravity
CodeSMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) ·bank_00.asm#L8897-L8905CODE_00CD24:
…
+ JSR CODE_00DC2D
JSR CODE_00E92BSMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L8946-L8949CODE_00CD82:
JSR CODE_00D5F2
JSR CODE_00D062
JSR CODE_00D7E4Checked by claude, 2026-10-20 — read the player routine from CODE_00CD24 to CODE_00CD8B at the pinned commit; the probe's first logged speed after a press is −77 (−80 + 3)Cited by: Gravity, Jump, Super Mario World, Variable jump height
CODE_00DC4F adds a speed's low nybble to a subpixel byte and its high nybble, sign-extended, plus the carry to the 16-bit position, so Mario moves in sixteenths of a pixel. super-mario-world/subpixel-motion
About: Super Mario World Gravity
CodeSMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) ·bank_00.asm#L10909-L10933CODE_00DC4F: ;!
LDA.B PlayerXSpeed+1,X ;!
ASL A ;!
ASL A ;!
ASL A ;!
ASL A ;!
CLC ;!
ADC.W PlayerXPosSpx,X ;!
…
ADC.B PlayerXPosNext,X ;!Checked by claude, 2026-10-20 — read CODE_00DC2D and CODE_00DC4F (NTSC branch) at the pinned commitCalled with X = 2, the same routine moves Y, through the byte after PlayerXPosSpx that the RAM map labels PlayerYPosSpx ($13DC). Landing doesn't clear that subpixel, so Mario leaves the ground with whatever fraction he had, and a jump's drawn height can differ by a pixel between take-offs.
Cited by: Fixed-point arithmetic, Gravity, Super Mario World, Variable jump height
Measured in the game, Mario climbs 64.2 px held and 33.3 px tapped from a standstill, 72.6 px held at walking speed, 81.6 px held running, and 85.3 or 91.1 px held sprinting. super-mario-world/rise-by-speed
About: Super Mario World Variable jump height
Value
{
"stand": {
"xspeed": 0,
"tap": {
"rise16": 533,
"at": 14,
"sub": 4,
"apex": 34,
"apexAt": 14,
"airtime": 28
},
"full": {
"rise16": 1027,
"at": 27,
"sub": 4,
"apex": 64,
"apexAt": 25,
"airtime": 54
}
},
"walk": {
"xspeed": 20,
"tap": {
"rise16": 602,
"at": 15,
"sub": 7,
"apex": 38,
"apexAt": 15,
"airtime": 30
},
"full": {
"rise16": 1162,
"at": 29,
"sub": 15,
"apex": 72,
"apexAt": 27,
"airtime": 58
}
},
"run": {
"xspeed": 36,
"tap": {
"rise16": 675,
"at": 16,
"sub": 14,
"apex": 42,
"apexAt": 15,
"airtime": 32
},
"full": {
"rise16": 1305,
"at": 30,
"sub": 11,
"apex": 81,
"apexAt": 28,
"airtime": 61
}
},
"sprint47": {
"xspeed": 47,
"tap": {
"rise16": 705,
"at": 16,
"sub": 13,
"apex": 44,
"apexAt": 16,
"airtime": 33
},
"full": {
"rise16": 1365,
"at": 31,
"sub": 10,
"apex": 85,
"apexAt": 29,
"airtime": 63
}
},
"sprint48": {
"xspeed": 48,
"tap": {
"rise16": 752,
"at": 17,
"sub": 2,
"apex": 47,
"apexAt": 15,
"airtime": 34
},
"full": {
"rise16": 1457,
"at": 32,
"sub": 12,
"apex": 91,
"apexAt": 31,
"airtime": 65
}
}
}bank_00.asm#L9673-L9675 — take-off speedsDATA_00D2BD:
db $B0,$B6,$AE,$B4,$AB,$B2,$A9,$B0SMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L10439-L10459 — gravityLDY.B #$01
LDA.B byetudlrHold
BMI +
…
LDY.B #$00
…
CLC
ADC.W DATA_00D7A5,YChecked by claude-agent, 2026-10-25 — Read the take-off speed table DATA_00D2BD (bank_00.asm L9673-9675: normal and spin columns by speed) and the gravity code (L10439-10459: index 1 while the jump button is held, added from DATA_00D7A5) at the pinned commit; the climbs are the probe's measurement in the game.Probe: probes/jump-physics/emu-jumps.mjsrise16 is the climb in 1/16 px from where Mario stands after the press frame, reached on frame at; it is exact and the same on every take-off. apex, apexAt, and airtime are whole drawn pixels and frames for the take-off subpixel sub, and can differ by one with another subpixel. The tap's sprint48 take-off read 49, the same band. Walking is $14, running $24.
Cited by: Super Mario World, Variable jump height
Measured in the game from a standstill, Mario's climb grows with each frame B is held, from 33.3 px tapped to 64.2 px at 28 frames or more. super-mario-world/rise-by-hold
About: Super Mario World Variable jump height
Value
{
"1": 533,
"2": 571,
"4": 642,
"8": 766,
"12": 866,
"16": 942,
"20": 994,
"24": 1022,
"28": 1027,
"32": 1027,
"40": 1027,
"60": 1027
}bank_00.asm#L10439-L10459 — gravity, by the held byteLDY.B #$01
LDA.B byetudlrHold
BMI +
…
LDY.B #$00
…
CLC
ADC.W DATA_00D7A5,YChecked by claude-agent, 2026-10-25 — Read the gravity code (bank_00.asm L10439-10459) at the pinned commit: Y is 1 while the held byte's top bit is set and 0 otherwise, choosing the gravity from DATA_00D7A5; the climbs for each hold are the probe's measurement in the game.Probe: probes/jump-physics/emu-jumps.mjsHolding past the top changes the fall instead: gravity stays at 3/16 while B is down, so the airtime keeps growing (54 frames for a 60-frame hold against 49 for 28).
Cited by: Super Mario World, Variable jump height
Measured in the game, a standing spin jump climbs 54.8 px with A held and 28.5 px tapped, against 64.2 and 33.3 for a normal jump. super-mario-world/spin-rise
About: Super Mario World Jump
Value
{
"tap": {
"rise16": 456,
"at": 13
},
"full": {
"rise16": 876,
"at": 25
}
}bank_00.asm#L9673-L9675 — the spin column, `$B6` standingDATA_00D2BD:
db $B0,$B6,$AE,$B4,$AB,$B2,$A9,$B0Checked by claude-agent, 2026-10-25 — Read the take-off speed table DATA_00D2BD (bank_00.asm L9673-9675) at the pinned commit: the standing pair is $B0 for a normal jump and $B6 for a spin, a slower rise; the climbs are the probe's measurement in the game.Probe: probes/jump-physics/emu-jumps.mjsCited by: Jump, Spin jump, Super Mario World
Measured on flat ground, Mario's top speed is 20/16 px/frame walking, 36/16 holding Y, and 47/16 to 49/16 once the P-meter is full, near DATA_00D535's $14, $24, and $30. super-mario-world/top-speeds
About: Super Mario World Running
Value
{
"walk": 20,
"run": 36,
"sprint": [
47,
49
]
}bank_00.asm#L9764-L9765DATA_00D535: ;!
db $EC,$14,$DC,$24,$DC,$24,$D0,$30 ;!Checked by claude, 2026-10-20 — read the table at the pinned commit; the probe ran with Right, then Right and Y, and read `PlayerXSpeed+1` at each take-offProbe: probes/jump-physics/emu-jumps.mjsAt a full P-meter the speed wobbles across the jump table's step at 48, so a sprinting jump takes off at −92/16 or −95/16 px/frame depending on the frame (rise-by-speed, sprint47 and sprint48).
Cited by: Super Mario World, Variable jump height
In the air with neither Left nor Right held, Mario's horizontal routine returns before friction, so he keeps his speed. super-mario-world/air-coast
About: Super Mario World Air control
CodeSMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) ·bank_00.asm#L9998-L10000LDA.B byetudlrHold
AND.B #$03
BNE CODE_00D6B1SMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L10021+ JMP CODE_00D764SMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L10125-L10128CODE_00D764:
JSR CODE_00D968
LDA.B PlayerInAir
BNE Return00D7A4Checked by claude, 2026-10-20 — read CODE_00D682 through CODE_00D7A4 at the pinned commitCited by: Super Mario World, Variable jump height
Holding a direction in the air accelerates Mario by MarioAccel_'s 1.5/16 px/frame each frame up to his top speed, or by 5/16 (2.5/16 without Y) while he still moves the other way. super-mario-world/air-steer
About: Super Mario World Air control
Value
{
"accel": 24,
"turnRun": 80,
"turnWalk": 40
}bank_00.asm#L9699 — flat ground, Left walking and running, Right walking and runningdw $FE80,$FE80,$0180,$0180 ;!SMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L9717 — the turning row, 144 bytes indw $FD80,$FB00,$0280,$0500 ;!SMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L10061-L10075LDA.B PlayerXSpeed+1
BEQ CODE_00D713
EOR.W MarioAccel_+1,X
BPL CODE_00D713
…
+ TXA
CLC
ADC.B #$90
TAXSMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L10107-L10123CODE_00D742:
LDA.B PlayerXSpeed+1
SEC
SBC.W DATA_00D535,Y
…
LDA.W MarioAccel_,XChecked by claude, 2026-10-20 — read CODE_00D6D5 through CODE_00D7A0 and the tables at the pinned commit; the probe's air turn (air-measured) slows him 5/16 px/frame a frame, then speeds him up about 1.5/16The same code runs on the ground; only the air skips friction (air-coast). PlayerXSpeed is 16-bit, so 1.5/16 px/frame² is $0180 = 384/256 of a sixteenth. "Up to his top speed" is approximate: the add is unclamped and a speed at or past the cap brakes by 1/16 instead (cap-test), and the turning rate holds while the speed's high byte is nonzero and points the other way (turning). air-rule gives the exact frame step.
Cited by: Air control, Super Mario World, Variable jump height
Measured in the game, a running jump keeps 36/16 px/frame when Right is let go, and turning Left in the air reverses it within 8 frames and reaches 36/16 the other way 29 frames after the turn. super-mario-world/air-measured
About: Super Mario World Air control
Value
{
"coast": 36,
"turnFrames": 8,
"reverseFrames": 29
}bank_00.asm#L10125-L10128 — no friction in the airJSR CODE_00D968
LDA.B PlayerInAir
BNE Return00D7A4SMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L10061-L10075 — the turning accelerationLDA.B PlayerXSpeed+1
BEQ CODE_00D713
EOR.W MarioAccel_+1,X
BPL CODE_00D713
…
TXA
CLC
ADC.B #$90
TAXChecked by claude-agent, 2026-10-25 — Read the released-d-pad branch (bank_00.asm L10125-10128: in the air it returns before friction) and the turning row (L10061-10075: the index moves $90 on when the speed points against the press) at the pinned commit; the frame counts are the probe's measurement in the game.Probe: probes/jump-physics/emu-jumps.mjsEach frame's move uses the previous frame's speed (frame-order), so the counts are of speed updates. From exactly 36.0/16 the 8th turning step overshoots zero to −4/16, and the high byte reads −36 once the 16-bit speed passes below −35/16, which the 21st plain step does; so 29, where a model that stops the turn at zero and waits for −36.0 predicts 32 (air-rule).
Cited by: Super Mario World
Each frame the player routine moves Mario by last frame's speed, runs block collision (which lands him), then CODE_00D5F2 updates his horizontal speed, so a speed change first moves him on the next frame and a landing frame already uses the ground rules. super-mario-world/frame-order
About: Super Mario World Running
Value
[ "move", "collision", "duck-jump-horizontal", "gravity" ]
bank_00.asm#L8897-L8905CODE_00CD24:
…
+ JSR CODE_00DC2D
JSR CODE_00E92BSMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L8946-L8949CODE_00CD82:
JSR CODE_00D5F2
JSR CODE_00D062
JSR CODE_00D7E4SMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L12589-L12595CODE_00EF60:
STA.B PlayerYSpeed+1
…
STZ.B PlayerInAirChecked by claude, 2026-10-21 — read CODE_00CD24 through CODE_00CD8B and the landing in CODE_00EF60 at the pinned commit; in the probe's traces each frame's position step equals the previous frame's speed byte, and the landing frame of a coasting jump already loses 1/16 px/frame to ground frictionProbe: probes/jump-physics/movement.mjsCODE_00E92B is the block collision; CODE_00EF60 clears PlayerInAir when Mario lands. The jump press and the horizontal speed update share CODE_00D5F2 (jump-start), and gravity comes last (motion-order).
PlayerXSpeed is 16 bits, a high byte in 1/16 px/frame and a low byte below it, so acceleration works in 1/4096 px/frame; position moves by the high byte alone. super-mario-world/x-speed-format
About: Super Mario World Running
CodeSMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) ·bank_00.asm#L10114-L10123REP #$20 ; A->16
LDA.W MarioAccel_,X
…
+ CLC
ADC.B PlayerXSpeedSMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L10909-L10917CODE_00DC4F: ;!
LDA.B PlayerXSpeed+1,X ;!Checked by claude, 2026-10-21 — read CODE_00D742 and CODE_00DC4F at the pinned commit; the accelerations are 16-bit adds to `PlayerXSpeed` ($7A-$7B), and the move reads `PlayerXSpeed+1`The high byte of a negative speed is its floor: −35.5/16 px/frame is $DC80, whose high byte reads −36. Every test in the horizontal code (cap, turning) and every move reads that byte.
On flat ground MarioAccel_ speeds Mario toward a held direction by $0180 (1.5/16 px/frame) a frame, with or without Y; holding against his motion uses its turning row, $0280 (2.5/16) walking and $0500 (5/16) with Y. super-mario-world/ground-accel
About: Super Mario World Running
Value
{
"accel": 384,
"turnWalk": 640,
"turnRun": 1280
}bank_00.asm#L9698-L9699MarioAccel_: ;!
dw $FE80,$FE80,$0180,$0180 ;!SMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L9717dw $FD80,$FB00,$0280,$0500 ;!SMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L10055-L10082CODE_00D6EC:
STA.B _1
ASL A
ASL A
ORA.W SlopeType
TAX
…
CODE_00D713:
LDY.B #$00
BIT.B byetudlrHold
BVC CODE_00D737
INX
…Checked by claude, 2026-10-21 — read CODE_00D6D5 through CODE_00D742 and the table at the pinned commit; each row is Left walking, Left with Y, Right walking, Right with Y; the probe's walk and run gain 384 a frame and its skids lose 640 or 1280Probe: probes/jump-physics/movement.mjsRows are per slope (SlopeType, 8 bytes a row); row 0 is flat ground and the turning rows start 144 bytes ($90) in. Slippery ground uses DATA_00D43D instead.
DATA_00D535 caps Mario's ground speed at $14 walking and $24 holding Y, and at $30 while the P-meter is full and charging. super-mario-world/caps
About: Super Mario World Running
Value
{
"walk": 20,
"run": 36,
"sprint": 48,
"runTakeoff": 35,
"pmeterFull": 112,
"pmeterUp": 2,
"pmeterDown": 1
}bank_00.asm#L9764-L9765DATA_00D535: ;!
db $EC,$14,$DC,$24,$DC,$24,$D0,$30 ;!SMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L10083-L10106LDA.B PlayerXSpeed+1
…
+ CMP.B #con($23,$23,$23,$2C,$2C)
BMI CODE_00D737
LDA.B PlayerInAir
BNE CODE_00D732
LDA.B #$10
STA.W RunTakeoffTimer
BRA CODE_00D736
…
CODE_00D736:
INY
…SMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L10504-L10514CODE_00D96A:
LDA.W PlayerPMeter
CLC
ADC.W DATA_00D5EB,Y
BPL +
LDA.B #$00
+ CMP.B #con($70,$70,$70,$40,$68)
BCC +
INY
LDA.B #con($70,$70,$70,$40,$68)
+ STA.W PlayerPMeterSMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L9908-L9909DATA_00D5EB: ;!
db $FF,$FF,$02 ;!Checked by claude, 2026-10-21 — read CODE_00D713 through CODE_00D742, CODE_00D96A, and the tables at the pinned commit; in the probe the P-meter climbs 2 a frame from `$23` with Y held, is full ($70) 56 frames later, and the speed then rises to the `$30` capProbe: probes/jump-physics/movement.mjsThe cap index is 0 walking, 1 with Y, and 2 with Y at $23 or more on the ground (or in a jump that left at full P-meter, PlayerInAir $0C); index 2 adds 2 to the P-meter and the others take 1 away, and a P-meter that reaches $70 bumps the index once more, to the sprint cap. So the sprint cap lasts only while Mario keeps charging. Index 2's cap is $24 again.
CODE_00D742 compares only the speed's high byte with the cap; below it the frame adds the full acceleration, unclamped, and at or past it the frame applies friction instead, so Mario's top speed cycles around the cap. super-mario-world/cap-test
About: Super Mario World Running
CodeSMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) ·bank_00.asm#L10107-L10113CODE_00D742:
LDA.B PlayerXSpeed+1
SEC
SBC.W DATA_00D535,Y
BEQ CODE_00D76B
EOR.W DATA_00D535,Y
BPL CODE_00D76BChecked by claude, 2026-10-21 — read CODE_00D742 at the pinned commit; in the probe a held walk cycles 21.0, 20.0, 19.0, 20.5, 19.5, 21.0/16 px/frame, and a held run 37.0, 36.0, 35.0, 36.5, 35.5, 37.0/16Probe: probes/jump-physics/movement.mjsThe walking cycle averages 20/16 px/frame and the running one 36/16, which is why the measured top speeds wobble by a sixteenth (top-speeds).
Cited by: Running
With no direction held on the ground, CODE_00D76B moves Mario's speed 1/16 px/frame a frame toward the slope's target speed, 0 on flat ground, and stops exactly on it. super-mario-world/friction
About: Super Mario World Running
Value: 256 1/4096 px/frame²
CodeSMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) ·bank_00.asm#L10125-L10163CODE_00D764:
JSR CODE_00D968
LDA.B PlayerInAir
BNE Return00D7A4
…
LDA.W DATA_00D2CD,Y
+ CLC
ADC.B PlayerXSpeed
STA.B PlayerXSpeed
SEC
SBC.W DATA_00D5C9,X
EOR.W DATA_00D2CD,Y
…SMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L9678-L9679DATA_00D2CD: ;!
dw $FF00,$0100,$FF00,$0100 ;!Checked by claude, 2026-10-21 — read CODE_00D764 through Return00D7A4 at the pinned commit; in the probe, letting go at 20/16 stops Mario 20 frames later at exactly 0Probe: probes/jump-physics/movement.mjsThe same routine brakes a speed past the cap (cap-test), on the ground and in the air. In 16-bit mode BIT.B LevelIsWater reads $85 and $86 together, so its sign bit is bit 7 of LevelIsSlippery; slippery ground brakes by DATA_00D309's $0020 (1/128 px/frame²). Each frame with no direction also drains the P-meter by 1.
Mario turns at the turning row's rate while his speed's high byte is nonzero and points against the held direction; the step is not clamped at zero, so the last one overshoots into the new direction. super-mario-world/turning
About: Super Mario World Running
CodeSMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) ·bank_00.asm#L10061-L10075LDA.B PlayerXSpeed+1
BEQ CODE_00D713
EOR.W MarioAccel_+1,X
BPL CODE_00D713
LDA.W SkidTurnTimer
BNE CODE_00D713
LDA.B LevelIsSlippery
BNE +
LDA.B #$0D
STA.W PlayerTurningPose
JSR CODE_00FE4A
+ TXA
…Checked by claude, 2026-10-21 — read CODE_00D6EC through CODE_00D713 at the pinned commit; in the probe a walking skid goes 20.0 → 17.5 … 0 in 8 frames with the skid pose (`$0D`) set, then speeds up the other way by 1.5/16 a frameProbe: probes/jump-physics/movement.mjsA high byte of 0 counts as no motion, so a speed between 0 and 1/16 px/frame accelerates at the plain rate. The test runs in the air too (air-rule). SkidTurnTimer, when running, suppresses the turning rate.
A held Left or Right turns Mario to face it on the same frame, on the ground and in the air, unless he carries an item. super-mario-world/facing
About: Super Mario World Running
CodeSMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) ·bank_00.asm#L10043-L10054CODE_00D6D5:
LDY.B PlayerDirection
CMP.B PlayerDirection
BEQ CODE_00D6EC
LDY.W IsCarryingItem
BEQ CODE_00D6EA
LDY.W FaceScreenTimer
BNE CODE_00D6EC
LDY.B #$08
STY.W FaceScreenTimer
CODE_00D6EA:
STA.B PlayerDirectionChecked by claude, 2026-10-21 — read CODE_00D6B1 through CODE_00D6EC at the pinned commit; in the probe `PlayerDirection` flips on the first frame Left is held, in a skid and in an air turnProbe: probes/jump-physics/movement.mjsPlayerDirection is 0 left, 1 right. Right wins when both are held. Carrying an item, Mario turns only when FaceScreenTimer is 0, which then runs for 8 frames.
On flat ground, Down makes Mario duck, and a ducking Mario ignores Left and Right, so friction alone slows him; the duck flag is set only on the ground, so a duck jump stays ducked and steers. super-mario-world/duck
About: Super Mario World Running
CodeSMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) ·bank_00.asm#L9921-L9933CODE_00D5F2:
LDA.B PlayerInAir
BEQ +
JMP CODE_00D682
…
+ STZ.B PlayerIsDucking
LDA.W PlayerSlopePose
BNE +
LDA.B byetudlrHold
AND.B #$04
BEQ +
STA.B PlayerIsDuckingSMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L9943-L9951CODE_00D61E:
LDA.B PlayerIsDucking
BEQ CODE_00D682
…
+ JMP CODE_00D764Checked by claude, 2026-10-21 — read CODE_00D5F2 through CODE_00D682 at the pinned commit; in the probe, Down from a run brakes by 256 a frame to exactly 0 with `PlayerIsDucking` setProbe: probes/jump-physics/movement.mjsA jump press is checked before the duck branch, so Mario can jump from a duck. Small Mario ducks too; ducking also shrinks his box (clipping).
Measured from a standstill on Yoshi's Island 1, Mario first passes $14 on frame 14 walking and reaches $24 on frame 24 holding Y; with Y held his P-meter fills 56 frames later. super-mario-world/ground-measured
About: Super Mario World Running
Value
{
"walkPass": 14,
"runReach": 24,
"pmeterFrames": 56,
"walkStop": 20
}bank_00.asm#L9698-L9699 — the accelerationMarioAccel_:
dw $FE80,$FE80,$0180,$0180SMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L9908-L9909 — the P-meter's +2 a frameDATA_00D5EB:
db $FF,$FF,$02SMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L9984-L9986 — $70 (US) is the full P-meter a take-off testsLDY.W PlayerPMeter
CPY.B #con($70,$70,$70,$40,$68)
BCC CODE_00D67DChecked by claude-agent, 2026-10-25 — Read MarioAccel_ (bank_00.asm L9698-9699: $0180 a frame), DATA_00D5EB (L9908-9909: the P-meter's +2), and the take-off's full-meter test (L9984-9986: $70 in the US build) at the pinned commit; the frame counts are the probe's measurement in the game.Probe: probes/jump-physics/movement.mjsReleased at 20/16 px/frame, he stops 20 frames later (walkStop).
In the air Mario's horizontal speed follows the ground's code except that a released d-pad keeps the speed and the cap index never reaches 2 unless he left at full P-meter; a frame-by-frame model of these rules reproduces every probed frame. super-mario-world/air-rule
About: Super Mario World Air control
Value
{
"accel": 384,
"turnWalk": 640,
"turnRun": 1280,
"friction": 256,
"caps": [
20,
36,
36,
48
],
"runTakeoff": 35,
"pmeterFull": 112
}bank_00.asm#L10061-L10075 — turning while the high byte points the other wayLDA.B PlayerXSpeed+1
BEQ CODE_00D713
EOR.W MarioAccel_+1,X
BPL CODE_00D713
…
TXA
CLC
ADC.B #$90
TAXSMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L10083-L10101 — the cap index in the airCMP.B #con($23,$23,$23,$2C,$2C)
BMI CODE_00D737
LDA.B PlayerInAir
BNE CODE_00D732
…
CODE_00D732:
CMP.B #$0C
BNE CODE_00D737
CODE_00D736:
INYSMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L10107-L10123 — the cap test and the unclamped addLDA.B PlayerXSpeed+1
SEC
SBC.W DATA_00D535,Y
BEQ CODE_00D76B
EOR.W DATA_00D535,Y
BPL CODE_00D76B
…
CLC
ADC.B PlayerXSpeedSMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L10125-L10128 — no friction with the d-pad released in the airJSR CODE_00D968
LDA.B PlayerInAir
BNE Return00D7A4SMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L9983-L9993 — a take-off with the P-meter at $70 or more (US) sets PlayerInAir to $0C, otherwise $0BLDA.B #$0B
LDY.W PlayerPMeter
CPY.B #con($70,$70,$70,$40,$68)
BCC CODE_00D67D
…
LDA.B #$0C
CODE_00D67D:
STA.B PlayerInAirChecked by claude-agent, 2026-10-25 — Read the take-off (bank_00.asm L9983-9993: PlayerInAir becomes $0C when the P-meter is at $70 or more, else $0B), the turning row (L10061-10075), the cap index in the air (L10083-10101: index 2 in the air only when PlayerInAir is $0C), the cap test and unclamped add (L10107-10123), and the released-d-pad return (L10125-10128) at the pinned commit; the frame-by-frame match is the probe's against traces from the game.Probe: probes/jump-physics/movement.mjsOne frame, with v the 16-bit speed, hi its high byte (floor), and d the held direction (+1 Right, −1 Left, Right first): with no d, the air keeps v and the ground brakes it (friction). Otherwise the turning row applies if hi ≠ 0 and its sign is not d; the cap index is 0, or 1 with Y, or 2 with Y and |hi| ≥ $23 (ground, or a full-P-meter jump), plus 1 when the P-meter fills; then if hi − cap is 0 or has the cap's sign, v moves $0100 toward 0 (clamped there), else v += the acceleration, unclamped. The measured air turn of air-measured follows: from exactly 36/16 ($2400) the turning steps give 31, 26 … 1, then −4 on the 8th frame, overshooting zero; 21 plain steps of −1.5/16 then reach −35.5/16 ($DC80), whose high byte reads −36, on the 29th frame. A model that stops the turn at zero, or that waits for the full −36.0, gets 30 to 32.
Cited by: Air control
Measured frame by frame, a running jump turned with Left and Y held drops from 35/16 px/frame to exactly 0 in 7 frames of −5/16, then gains −1.5/16 a frame and reads −36/16 on the 31st frame of the turn. super-mario-world/air-turn-trace
About: Super Mario World Air control
Value
{
"from": 8960,
"turnFrames": 7,
"reachFrames": 31
}bank_00.asm#L9717 — the turning row, 144 bytes indw $FD80,$FB00,$0280,$0500 ;!Checked by claude, 2026-10-21 — ran the probe; its airturn case presses Left with Y on the 11th frame of the jump at a speed of exactly `$2300`, and the trace shows `$1E00`, `$1900` … `$0000`, then `$FE80` and so on to `$DC00`Probe: probes/jump-physics/movement.mjsThe count depends on the 16-bit speed at the turn: from 35.0 the turning steps land exactly on 0, so no overshoot, while from 36.0 (air-measured) they overshoot to −4/16 and the turn takes 29 frames. At a held run the speed cycles through 35.0, 36.5, 35.5, 37.0, and 36.0 (cap-test), so a turn takes 29 to 31 frames depending on the frame it starts.
The jump press sets only Mario's vertical speed and air state, then falls into the horizontal code, so the press frame already uses the air rules and his speed carries over unchanged. super-mario-world/takeoff-x
About: Super Mario World Jump
VerifiedSMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) ·bank_00.asm#L9981-L9995+ LDA.W DATA_00D2BD,X
STA.B PlayerYSpeed+1
LDA.B #$0B
…
CODE_00D67D:
STA.B PlayerInAir
STZ.W PlayerSlopePose
CODE_00D682:Checked by claude, 2026-10-21 — read CODE_00D630 through CODE_00D682 at the pinned commit; in the probe a walking jump pressed with the d-pad released keeps 20/16 px/frame on the press frame, where the ground would brake it to 19Probe: probes/jump-physics/movement.mjsPlayerInAir is $0B for a jump, or $0C when the P-meter is full (which keeps the sprint cap in the air, caps); $24 means falling. The speed picks the jump's vertical speed (jump-start).
Landing clears PlayerInAir during block collision, before the frame's speed update, so the landing frame already brakes or accelerates by the ground rules; the jump itself leaves the horizontal speed alone. super-mario-world/landing
About: Super Mario World Jump
VerifiedSMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) ·bank_00.asm#L12589-L12598CODE_00EF60:
STA.B PlayerYSpeed+1
TAX
BPL +
INC.W PlayerIsOnGround
+ STZ.W StandingOnCage
STZ.B PlayerInAir
STZ.B PlayerIsClimbing
STZ.W BouncingOnBoard
STZ.W SpinJumpFlagChecked by claude, 2026-10-21 — read CODE_00EF2F through CODE_00EF60 at the pinned commit; in the probe a walking jump with the d-pad released holds 20/16 to the landing frame, which already shows 19/16 and `PlayerInAir` 0, and Y 352 on the floorProbe: probes/jump-physics/movement.mjsIt also clears the spin-jump flag. The vertical speed is set from a table there, then gravity adds to it, so a standing Mario shows a downward speed of 6/16 px/frame every frame.
GetMarioClipping gives Mario a box for touching sprites 12 px wide from x+2, 26 px tall from y+6 when big, and 12 px tall from y+20 when small or ducking. super-mario-world/clipping
About: Super Mario World Hitbox
Value
{
"big": {
"x": 2,
"y": 6,
"width": 12,
"height": 26
},
"small": {
"x": 2,
"y": 20,
"width": 12,
"height": 12
},
"bigYoshi": {
"x": 2,
"y": 16,
"width": 12,
"height": 32
},
"smallYoshi": {
"x": 2,
"y": 24,
"width": 12,
"height": 24
}
}bank_03.asm#L6941-L6977MairoClipDispY:
db $06,$14,$10,$18
…
MarioClippingHeight:
db $1A,$0C,$20,$18
…
LDA.B PlayerXPosNext ; \
CLC ; |
ADC.B #$02 ; |
…
LDA.B #$0C ; \ $06 = Clipping width X (#$0C)
…
…Checked by claude, 2026-10-21 — read GetMarioClipping and its two tables at the pinned commit; index 0 big, 1 small or ducking, +2 on YoshiOffsets are from PlayerXPosNext/PlayerYPosNext, the top-left of Mario's 16×32 px frame for big and small alike.
Cited by: Hitbox
Against blocks Mario tests six points, a center, two side points, a head, and two feet at x+5 and x+11, y+32; big Mario's head point is at y+8 and small Mario's at y+16. super-mario-world/block-points
About: Super Mario World Hitbox
Value
{
"small": {
"center": [
8,
24
],
"side": [
[
14,
26
],
[
14,
22
]
],
"head": [
8,
16
],
"feet": [
[
5,
32
],
[
11,
32
]
]
},
"big": {
"center": [
8,
18
],
"side": [
[
14,
26
],
[
14,
15
]
],
"head": [
8,
8
],
"feet": [
[
5,
32
],
[
11,
32
]
]
},
"rightSideX": 2
}bank_00.asm#L11671-L11690PlayerXHitboxPoints:
db $0C,$0E,$08,$00,$0E,$00,$0E,$00
db $08,$00,$05,$00,$0B,$00,$08,$00
…
PlayerYHitboxPoints:
db $08,$00,$18,$00,$1A,$00,$16,$00
DATA_00E8A4:
db $10,$00,$20,$00,$20,$00,$18,$00SMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L12042-L12074NormalCollision:
LDX.B #$00
…
LDX.B #$18 ; If player is big and not ducking, index = $18
…
ADC.B #$0B ; if on the right, index += $0B
…
JSR GetBlockAtPlayer ; Interaction point 0 (Center)SMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L13273-L13284GetBlockAtPlayer: ; X = position offset idx
INX
INX
REP #$20 ; A->16
LDA.B PlayerXPosNext
CLC
ADC.W PlayerXHitboxPoints,XChecked by claude, 2026-10-21 — read NormalCollision (L12042 on, the six GetBlockAtPlayer calls and their comments) and the tables at the pinned commit; the reads start 2 bytes in, so the table's first word is never used; the values also read back from the ROM at SMW_U.sym's addressesPoints are [x, y] offsets from PlayerXPosNext/PlayerYPosNext. These are for Mario's x in the left half of a 16 px block column; in the right half (the index plus 12 bytes) the side points move to x+2 (rightSideX) and the feet swap order. Small and ducking share a set; Yoshi has two more. The middle of his 16 px frame is x+8, so the feet sit 3 px to either side of it and the side points 6 px; the movement lab centers his box there. NormalCollision tests the points in the order listed, after the frame's move (frame-order), and pushes him out of a wall only after all six (side-push).
Cited by: Hitbox
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. super-mario-world/iframes
About: Super Mario World Invincibility frames
Value: 127 frames
CodeSMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) ·bank_00.asm#L13490-L13496HurtMario:
…
LDA.W IFrameTimer ; \ If flashing...
ORA.W InvinsibilityTimer ; | ...or have star...
ORA.W EndLevelTimer ; | ...or level ending...
BNE Return00F628 ; / ...returnSMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L9442-L9459LDA.W PlayerAniTimer
BEQ CODE_00D140
…
CODE_00D140:
LDA.B #$7F
STA.W IFrameTimerSMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L7902-L7911LDA.B SpriteLock ; \ Branch if sprites locked
BNE CODE_00C569 ; /
INC.B EffFrame
LDX.B #$13
CODE_00C508:
LDA.W ColorFadeTimer,X
BEQ +
DEC.W ColorFadeTimer,X
+ DEX
BNE CODE_00C508SMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · rammap.asm#L1640-L1642ColorFadeTimer: skip 1
PlayerAniTimer: skip 1
IFrameTimer: skip 1Checked by claude, 2026-10-21 — read HurtMario, PowerDownAni, and the timer loop at $00C508; IFrameTimer is ColorFadeTimer+2, inside the loop's X = $13 down to 1GetBlockAtPlayer adds a point's offsets to Mario's position and reads the block holding that pixel, x ÷ 16 for the column and y with its low 4 bits cleared for the row; in a horizontal level's layer 1, every point below y $1B0 (432 px) reads as air. Side points stop at blocks $111–$16D, and a falling foot lands on $100–$16D. super-mario-world/block-lookup
About: Super Mario World Hitbox
Value
{
"blockSize": 16,
"levelBottom": 432
}bank_00.asm#L13273-L13284GetBlockAtPlayer: ; X = position offset idx
INX
INX
REP #$20 ; A->16
LDA.B PlayerXPosNext
CLC
ADC.W PlayerXHitboxPoints,X
STA.B TouchBlockXPos
LDA.B PlayerYPosNext
CLC
ADC.W PlayerYHitboxPoints,X
STA.B TouchBlockYPosSMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L13299-L13313LDA.B TouchBlockYPos
CMP.W #$01B0
SEP #$20 ; A->8
BCS CODE_00F4A0 ; Branch if out of Y bounds
AND.B #$F0
…
LDA.B TouchBlockXPos
LSR A
LSR A
LSR A
LSR A
ORA.B _0 ; A = block position as yyyyxxxxSMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L12140-L12146 — a side point stops only at `$111`–`$16D`; the feet (`Normal_IP4`, `CPY.BNormal_IP1:
JSR GetBlockAtPlayer ; Interaction point 1 (Side body)
BEQ CODE_00EC35 ; Branch if page 0
CPY.B #$11
BCC Normal_IP2
CPY.B #$6E
BCS Normal_IP2Checked by claude, 2026-10-22 — read GetBlockAtPlayer, CODE_00F465 (the horizontal-level branch), and the side and foot checks in NormalCollision at the pinned commitVertical levels and layer 2 have their own branches of the lookup. A point past the level's last screen also reads as air. In the movement lab, every column is solid like a $130 cement block: the lab's stages keep the game's 16 px rows (a column top is a block top), and the model takes the block grid in x through the stage's first column edge.
With Mario's x in the left half of a block column (PlayerBlockXSide 0), collision tests his side points at x+14, and unless he's flush at x mod 16 = 2 marks him blocked on the right; in the right half (1), it tests those at x+2, flush at 13, blocked on the left. After all six points, it moves him 1 px back out of the wall and, if his speed points into the wall, zeroes its high byte but not its low byte. super-mario-world/side-push
About: Super Mario World Hitbox
Value
{
"flush": [
2,
13
],
"step": 1
}bank_00.asm#L12165-L12189CODE_00EC4E: ; Solid side blocks?
…
LDY.B PlayerBlockXSide
LDA.B PlayerXPosNext
AND.B #$0F
CMP.W DATA_00E911,Y ; $02 (left) or $0D (right)
BEQ Normal_IP3
…
CODE_00EC7B:
LDA.W DATA_00E90A,Y ; Load the player blocked bitmask
TSB.B PlayerBlockedDir ; Set the bitmaskSMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L11704-L11714DATA_00E90A:
db $01,$02,$11
…
DATA_00E90D:
db $FF
…
DATA_00E90E:
db $FF,$01,$00
…
DATA_00E911:
db $02,$0DSMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L11841-L11861CODE_00EA0D:
LDA.B PlayerBlockedDir
AND.B #$03
BEQ +
AND.B #$02
TAY
REP #$20 ; A->16
LDA.B PlayerXPosNext
CLC
ADC.W DATA_00E90D,Y
STA.B PlayerXPosNext
…
…SMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L12087-L12099 — the center point in a solid block jumps into the side code with Y = 2, bit `$11` (notes)CODE_00EBC9:
…
LDY.B #$02
+ JMP CODE_00EC6FChecked by claude, 2026-10-22 — read NormalCollision's side points and CODE_00E9FB through CODE_00EA32 at the pinned commit; the probe walked and ran small Mario into a two-block wall each way and onto a one-block step. He rests at x 370 against a wall from x 384 (370 mod 16 = 2) and at x 285 against one ending at x 287 (285 mod 16 = 13); each push frame moves him back 1 px and leaves a speed of 20/16 or 28.5/16 px/frame as its low byte, 0 or 0.5/16, before that frame's accelerationProbe: probes/stage/super-mario-world.mjsFrom the code alone (T3): a solid block at Mario's center point skips the side points and marks him blocked right with bit $11 (CODE_00EBC9, Y = 2), so he is pushed left; the probe doesn't reach that case. Blocked right is bit $01 and pushes −1 px (the word $FFFF at DATA_00E90D), blocked left $02 and +1 px. A speed pointing away from the wall, or a push from the screen edge (bit $80), keeps its high byte. Flush, the side point sits on the wall's outermost column of pixels; between pushes his speed moves only his subpixel. The probe's 16 px step stops him at x 370 too: the side body point is 6 px above his feet.
When neither foot point finds a block and Mario isn't in the air, collision sets PlayerInAir to $24 (falling). Collision follows the move, so he counts as airborne on the frame whose move carries his trailing foot past the edge, already moved by the ground's vertical speed, 6/16 px/frame (3/16 with B held); gravity then adds 6/16 a frame (3/16 held) up to 70/16. super-mario-world/walk-off
About: Super Mario World Coyote time
Value
{
"inAir": 36,
"fall": [
6,
12,
18,
24,
30,
36,
42,
48,
54,
60,
66,
70,
70
],
"fallHeld": [
3,
6,
9
]
}bank_00.asm#L12385-L12389Normal_IP5:
JSR GetBlockAtPlayer ; Interaction point 5 (Left foot)
BNE CODE_00EDF3 ; Do page 1 blocks
JSR RunPage0Blocks_4 ; Do page 0 blocks
BRA CODE_00EE1DSMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L12422-L12428+ LDA.B PlayerBlockedDir ; \
AND.B #$04 ; | If Mario is on an edge or in air,
ORA.B PlayerInAir ; | return
BNE Return00EE39 ; /
CODE_00EE35:
LDA.B #$24 ; \ Set "In air" to x24 (falling)
STA.B PlayerInAir ; /SMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L12541-L12545 — a flat block lands with Y = `$20` (CODE_00EE83), which branches to CODE_00EF38, `LDA.W DATA_00E4DA,Y`CODE_00EF05:
LDX.W DATA_00E4B9,Y
STX.W SlopeType
CPY.B #$1C
BCS CODE_00EF38SMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L11544-L11549 — the 33rd byte, entry `$20`, is `$00`, the vertical speed a landing on a flat block sets before gravity adds 3 or 6DATA_00E4DA:
…
db $00Checked by claude, 2026-10-22 — read Normal_IP4 through Return00EE39 and the landing's speed (CODE_00EF31, Y = `$20`) at the pinned commit; the probe emptied the ground from x 384 on and walked small Mario off from x 354. Walking (20/16 px/frame) he is in the air on frame 28, the first with x at 380, where x+5 = 385 is past the edge; running (36/16) on frame 24, at x 379. Both frames show `PlayerInAir` `$24`, and walking his vertical speed reads 6/16 on the last frame on the ledge, then 12/16, 18/16, and so on to 70/16. With B held from a standing jump through its landing and on while he walks off, it reads 3/16, then 6/16 and 9/16Probe: probes/stage/super-mario-world.mjsThe trailing foot is x+5 walking right and x+11 walking left (block-points), 3 px behind the middle of his frame. Either foot on a block keeps him on it: the foot code checks the second foot only when the first finds nothing. A jump's own $0B turns to $24 at its peak, in gravity's routine (CODE_00D928); the walk-off's $24 isn't $0C, so it doesn't keep the sprint cap in the air (caps).
Mario gets no grace window after walking off a ledge; CODE_00D5F2 starts a jump only while PlayerInAir is 0, and block collision, earlier in the same frame, has already set it to $24. super-mario-world/no-coyote-time
About: Super Mario World Coyote time
VerifiedSMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) ·bank_00.asm#L9921-L9924CODE_00D5F2:
LDA.B PlayerInAir
BEQ +
JMP CODE_00D682SMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L8897-L8905 — the move, then block collision (walk-off); `CODE_00D5F2` comes later (motion-order)CODE_00CD24:
…
+ JSR CODE_00DC2D
JSR CODE_00E92BChecked by claude, 2026-10-22 — read CODE_00D5F2 and the player routine at the pinned commit; in the probe a fresh B press on the last frame on the ledge (27) jumps, at −82/16 px/frame after gravity, and a press on the walk-off frame (28), one frame later, or five frames later leaves him falling, with only gravity's held 3/16 in place of 6/16Probe: probes/stage/super-mario-world.mjsCODE_00D682 is the horizontal code, so the press frame still steers. A spin jump (A) takes the same branch.
Cited by: Coyote time
A foot point in a block's top half lands Mario unless he is moving up; CODE_00EE11 takes the point's row within the block, and below 8 the landing subtracts it from his y, keeping the subpixel, which stands him on the block's top. In the lower half the point doesn't land him. super-mario-world/foot-landing
About: Super Mario World Jump
Value
{
"landAbove": 8
}bank_00.asm#L12393-L12395CODE_00EDF7:
LDA.B PlayerYSpeed+1
BMI Return00EE39SMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L12407-L12413CODE_00EE11: ; Skip this for blocks 159-15B in tilesets 3/E
LDA.B PlayerYPosInBlock
AND.B #$0F
STZ.B PlayerYPosInBlock ; Set intra-block position to 0
CMP.B #$08
STA.B PlayerBlockMoveY ; Set Y position of interaction point (what does this do?)
BCC CODE_00EE3ASMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L12514-L12522CODE_00EED1:
INC.W PlayerIsOnGround
LDA.B PlayerYPosNext
SEC
SBC.B PlayerBlockMoveY
STA.B PlayerYPosNext
LDA.B PlayerYPosNext+1
SBC.B PlayerYPosInBlock
STA.B PlayerYPosNext+1Checked by claude, 2026-10-22 — read CODE_00EDF7 through CODE_00EEE1 at the pinned commit (DoPlayerCollision stores y's low 4 bits in `PlayerYPosInBlock`, which are the foot points' row in their block, 32 px down); in the probe a walking jump onto a 16 px step falls at 70/16 px/frame until the foot points are 2 px into the step's block, and that frame he stands at y 336, 16 px above the floor's 352Probe: probes/stage/super-mario-world.mjsAt most 70/16 px/frame (fall-speed), a falling foot can't pass a block's top half in one frame, so he lands on any top he falls onto. The vertical speed is then set from a table (0 for a flat block) and gravity adds to it (landing). Tiles $159–$15B in tilesets 3 and E skip the landing.
Right after block collision, CODE_00F595 starts Mario's death once his y measured from the top of the screen reaches 256 px, 32 px below the bottom of the 224-line picture, unless YoshiHeavenFlag is set, when it jumps to CODE_00C95B instead. super-mario-world/pit-death
bank_00.asm#L8904-L8907+ JSR CODE_00DC2D
JSR CODE_00E92B
CODE_00CD36:
JSR CODE_00F595SMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L13470-L13486CODE_00F595:
…
+ SEP #$20 ; A->8
LDA.B PlayerYPosScrRel+1
DEC A
BMI Return00F5B6
LDA.W YoshiHeavenFlag
BEQ +
JMP CODE_00C95B
…
+ JSL CODE_00F60ASMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L13532-L13538CODE_00F60A:
…
LDA.B #$09 ; \ Animation sequence = Kill Mario
STA.B PlayerAnimation ; /Checked by claude, 2026-10-22 — read CODE_00F595 and CODE_00F60A at the pinned commit; the player routine calls CODE_00F595 after CODE_00E92BA high byte of 0 (on screen) or $FF (above it) goes negative at the DEC and returns; 1 or more is 256 px down. In the stage probe, small Mario walking off a ledge in Yoshi's Island 1 stops moving 28 frames later, the death animation's freeze. The movement lab has no screen, and lets him fall.
Mario's head point (x+8, and y+8 big or y+16 small; block-points) is the fourth of collision's six points, after the center and side points and before the feet. In the air, when it is in a solid block, collision moves him down by 15 minus the point's row in the block, keeping the subpixel, so the point ends on the block's bottom row, and zeroes his vertical speed if he was rising. Gravity then acts on that frame as usual. A turn block hit this way skips the move on that frame (turn-block-hit). super-mario-world/head-hit
About: Super Mario World Hitbox
Value
{
"row": 15
}bank_00.asm#L12069-L12073 — the base index's `DATA_00E8A4` entry is the head point's y offset, so this is the head point's row in its block+ LDA.B PlayerYPosInBlock
CLC
ADC.W DATA_00E8A4,X ; Get the vertical interaction point position
AND.B #$0F
STA.B PlayerBlockMoveYSMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L12195-L12197Normal_IP3:
JSR GetBlockAtPlayer ; Interaction point 3 (Head)
BNE CODE_00ECB1 ; Do page 1 blocksSMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L12265-L12295 — `$F0` plus the row is negative for any row; its complement is 15 minus the rowCODE_00ED0D:
LDA.B #$F0
…
ADC.B PlayerBlockMoveY ; Add interaction point Y
…
CODE_00ED28:
LDY.B PlayerInAir
BEQ + ; If on ground, skip
EOR.B #$FF
CLC
ADC.B PlayerYPosNext
STA.B PlayerYPosNext ; Clip position to the slope
…Checked by claude, 2026-10-22 — read NormalCollision's setup and Normal_IP3 through CODE_00ED3B at the pinned commit; the probe wrote a cement block ($130) 48 px above the floor over Mario's middle and jumped with B held. Big, the frame his head point first lands in the block (row 14) he is 1 px lower than his speed alone puts him and his vertical speed reads 3/16, gravity's held step from 0; small Mario meets it two frames later. Both then fallProbe: probes/lab/smw-blocks.mjsThe move is an 8-bit add to y's low byte, with the carry into its high byte. The point can stay inside the block on its bottom row for a few frames as he starts to fall; each of those frames moves him by 0 and sets the top-blocked bit. The bonk sound plays only when no other sound is queued that frame. Slopes ($16E up) take the same code with their own heights.
On the ground, a head point in a solid block's upper 9 rows (0–8) ejects Mario left: collision marks him blocked on the right and zeroes his horizontal speed's high byte, and the wall push then moves him 1 px left a frame (side-push). In rows 9–15 he isn't moved. Either way it sets the top-blocked bit, and while that bit is set a jump press on the ground doesn't jump. super-mario-world/head-ground
About: Super Mario World Hitbox
Value
{
"ejectBelow": 9,
"step": 1
}bank_00.asm#L12271-L12280 — bit `$01` is blocked on the right, which pushes him left (side-push)CMP.B #$F9
BCS CODE_00ED28
LDY.B PlayerInAir
BNE CODE_00ED28 ; If not in the air and too high into the ceiling:
LDA.B PlayerBlockedDir ; Eject player to the left
AND.B #$FC ; Unset left+right blocked
ORA.B #$09 ; Set top+left blocked
STA.B PlayerBlockedDir
STZ.B PlayerXSpeed+1
BRA CODE_00ED3BSMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L9934-L9940 — `CODE_00D5F2`: with the top-blocked bit set, the press skips the jump at `CODE_00D630`+ LDA.W StandOnSolidSprite
CMP.B #$02
BEQ CODE_00D61E
LDA.B PlayerBlockedDir
AND.B #$08
BNE CODE_00D61E
LDA.B byetudlrFrameChecked by claude, 2026-10-22 — read CODE_00ED0D through CODE_00ED3B and CODE_00D5F2 at the pinned commit; the probe stood big Mario under a cement block 16 px above the floor, his head point in its row 8, and pressed and held B. He didn't jump, and moved 1 px left on four frames in five, `PlayerBlockedDir` reading `$0D`; on the fifth his vertical subpixel had carried him 1 px lower before the landing, the point was in row 9, and the bit read `$0C`. Once the point left the block his side point met it and pushed him to rest flush, at x mod 16 = 2Probe: probes/lab/smw-blocks.mjsThe game reaches this only when he is already under a low block: walking in, his side head point (y+15 big) stops him at the block's side first. A press made while blocked isn't remembered, so holding B on through the eject never jumps.
A turn block ($11E) under the head point is hit from below like any functional block: it becomes bounce sprite 7, the turning turn block. That path doesn't read Powerup, and it breaks a block only when the block's IntBlk_BounceSprite entry is 7; the turn block's entry is 6 (its sprite number is 7), so a plain head hit never breaks a turn block, big or small. On the hit frame collision skips the head's downward move and only zeroes a rising speed. super-mario-world/turn-block-hit
About: Super Mario World Destructible terrain
Value
{
"breaks": false
}bank_00.asm#L12256-L12264CODE_00ECFA:
…
LDY.B #$00
JSL CODE_00F127 ; Process hurt/functional blocks
LDA.W Map16TileNumber ; Current MAP16 tile number
CMP.B #$1E ; \ If block is turn block, branch to $ED3B
BEQ CODE_00ED3B ; /SMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L12735-L12740 — entry `$0D` (tile `$11E` − `$111`) is `$06`; the bounce sprite's number is the entry plus 1IntBlk_BounceSprite:
…
db $00,$00,$00,$00,$00,$06,$02,$02SMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_02.asm#L902-L905CODE_028752:
LDA.B _4
CMP.B #$07
BNE NotBreakableSMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L12453-L12463 — the break comes from above, a foot on a turn block while big and spin jumping; entry `$21` is `$07`LDA.W Map16TileNumber ; Current MAP16 tile number
CMP.B #$1E ; \ If block isn't "Turn block",
…
LDX.B Powerup
BEQ CODE_00EE83
LDX.W SpinJumpFlag
BEQ CODE_00EE83
LDA.B #$21
JSL HandleFunctionalBlockByIDChecked by claude, 2026-10-22 — read Normal_IP3's page 1 branch, the IntBlk tables, HandleFunctionalBlockByID, CODE_028752, and the foot code at L12453 at the pinned commit; in the probe, big and small Mario jumping into a turn block both left it unbroken (the block buffer cell went `$11E`, `$152`, `$048`, and back to `$11E`), with bounce sprite 7 in slot 3. On the hit frame he wasn't moved down (y 326 big, as the speed put him) and his speed went to 0; the next frame the block, now invisible and solid, moved him down 1 px like any block (head-hit)Probe: probes/lab/smw-blocks.mjs_6, the side, is 0 (below) from the head, which the turn block's activation mask ($08) accepts.
A block hit from below becomes a bounce sprite with an 8-frame timer and a vertical speed of $C0 (−4 px/frame), and on its first frame, the hit frame, the block's cell becomes an invisible solid tile ($152) under it. Each frame the sprite moves by its speed's high nybble plus the carry of its low nybble into a fraction byte, then adds $10 to the speed (a ? block) or $13 (a turn block). Nothing clears that fraction, so a slot's leftover from its last bounce carries into the next. super-mario-world/block-bounce
About: Super Mario World Destructible terrain
Value
{
"speed": -64,
"accel": {
"question": 16,
"turn": 19
},
"timer": 8,
"slots": 4
}bank_02.asm#L1035-L1045%LorW_X(LDA,BlockBounceSpeedY) ; \ Set bounce y speed
STA.W BounceSpriteYSpeed,Y ; /
…
LDA.B #$08 ; \ Time to show bouncing block
STA.W BounceSpriteTimer,YSMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_02.asm#L884-L885 — entry 0 is a hit from belowBlockBounceSpeedY:
db $C0,$00,$00,$40SMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_02.asm#L7031-L7053 — the X move calls this with X + 4, so the byte labeled `BounceSpriteXPosSpx` is the Y fraction; these two lines are the only reads and writes of itCODE_02B526:
LDA.W BounceSpriteYSpeed,X
ASL A
…
ADC.W BounceSpriteXPosSpx,X
STA.W BounceSpriteXPosSpx,X
…
ADC.W BounceSpriteYPosLow,X
STA.W BounceSpriteYPosLow,XSMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_02.asm#L2126-L2127DATA_029072:
db $13,$00,$00,$EDSMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_02.asm#L2173-L2174DATA_0290CE:
db $10,$00,$00,$F0SMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_02.asm#L2290-L2291InvisSldFromBncSpr:
LDA.B #$09 ; Block to generate = Invisible solidChecked by claude, 2026-10-22 — read the bounce sprite's creation (CODE_028752 on), CODE_02904D, TurnBlockSpr, BounceBlockSpr, and CODE_02B526 at the pinned commit; in the probe a ? block's sprite stood 4, 7, 9, 10, 10, 9, and 7 px above its cell on the hit frame and the six after it, and a turn block's first bounce 4, 7, 9, 9, 9, 7. A second hit on the same turn block 270 frames later, in the same slot, rose 4, 6, 8, 9, 8, 6, as the fraction the first bounce leaves by this arithmetic, `$D0`, predictsProbe: probes/lab/smw-blocks.mjsThe ? block's speed steps by $10, so its fraction never changes and its path is always the same; the turn block's $13 leaves a fraction. The timer runs down 7, 6, … from the hit frame. The game has four bounce sprite slots, searched from slot 3 down.
After a head hit, a turn block bounces through the hit frame and the five after it; on the sixth it snaps back to its cell as the always-turning tile ($048), which nothing collides with, so Mario passes through it. Its spin timer, $FF at the hit, runs down by one a frame, and 255 frames after the hit frame the cell becomes a turn block again. super-mario-world/turn-block-spin
About: Super Mario World Destructible terrain
Value
{
"from": 6,
"back": 255
}bank_02.asm#L1046-L1050LDA.W BounceSpriteNumber,Y
CMP.B #$07
BNE +
LDA.B #$FF
STA.W TurnBlockSpinTimer,YSMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_02.asm#L2136-L2168+ LDA.W BounceSpriteTimer,X
BEQ CODE_0290BB
CMP.B #$01
BNE CODE_0290A8
…
LDA.B #$05
JSR TileFromBounceSpr1
…
CODE_0290BB:
LDA.W TurnBlockSpinTimer,X
BEQ +
DEC.W TurnBlockSpinTimer,X
…SMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L7307-L7314 — the turn block's `IntBlk_BlockToGenerate` entry is `$0C`dw CODE_00C077 ; 05 - always turning block
…
dw CODE_00C0C4 ; 0c - turn blockChecked by claude, 2026-10-22 — read TurnBlockSpr and the generated-tile list at the pinned commit; in the probe the cell read `$152` on the hit frame and the five after it, `$048` from the sixth, and `$11E` again on the 255th; big Mario jumping again 64 frames after the hit rose through the spinning block to the height he reaches with no block (y 288), and a jump after it turned back hit it againProbe: probes/lab/smw-blocks.mjsThe bounce timer counts 7 on the hit frame (CODE_02904D decrements it before each run), so it reaches 1 on the sixth frame after.
A ? block under the head point (tile $124, a coin, in the probe) is hit from below: it gives its contents and bounces (block-bounce), and collision then treats it as solid, moving Mario down onto its bottom row and stopping his rise on the same frame (head-hit). When the bounce timer runs out, 7 frames after the hit frame, the cell becomes a used block ($132), which is solid and is never hit again. super-mario-world/question-block-hit
About: Super Mario World Hitbox
Value
{
"usedAt": 7
}bank_00.asm#L12735-L12738 — entries `$10`–`$17` (tiles `$121`–`$128`) give bounce sprite 3, the ? blockIntBlk_BounceSprite:
…
db $02,$02,$02,$02,$02,$02,$02,$02SMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_00.asm#L12756-L12759 — entry `$13` (`$124`) is `$0D`, the used blockIntBlk_BlockToGenerate:
…
db $0D,$0D,$0B,$0D,$0D,$16,$0D,$0DSMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_02.asm#L2242-L2244CODE_02915E:
LDA.W BounceSpriteTimer,X
BNE Return02919CSMWDisX: Super Mario World disassembly (IsoFrieze/SMWDisX) · bank_02.asm#L2260+ JSR TileFromBounceSpr0Checked by claude, 2026-10-22 — read Normal_IP3's page 1 branch, the IntBlk tables, BounceBlockSpr, and TileFromBounceSpr0 at the pinned commit; in the probe big Mario jumping into a `$124` block was moved down 1 px and stopped on the hit frame, the coin count rose by 1, the cell read `$152` for seven frames and `$132` from the seventh after the hit; a second jump into the used block met it as a solid block. Small Mario jumping into `$11F` got the same bounce and timingProbe: probes/lab/smw-blocks.mjsThe lab's ? block holds nothing; the game's coin, item, or vine comes out on the hit.