The game keeps a Mode 7 angle, 0 to $1FF for a full turn, and an X and a Y scale, $20 for 1.0, and turns them into the matrix with a quarter-wave sine table of 129 entries; D copies A and C is −B, a rotation scaled per axis. | bank_00.asm L1303–1318bank_00.asm L1319bank_00.asm L1371–1374bank_00.asm L379–412 | Code |
In the Reznor fight the Reznor in sprite slot 7 sets the Mode 7 center to $80 and adds 1 to the angle each frame, wrapping at $1FF, so the Mode 7 wheel the four Reznors ride (the "Reznor sign" in the comments) turns once every 512 frames. | bank_03.asm L3194–3206bank_03.asm L3219–3223 | Code |
| In the Mode 7 boss rooms other than Bowser's, the NMI sets Mode 1 for the status bar at the top of the frame, and an interrupt at the line where the bar ends switches to Mode 7 and writes the Mode 7 layer's scroll; the bar ends at line 36, or 45 in Morton's and Roy's rooms. Bowser's room skips the status bar interrupt and goes straight to Mode 7. | bank_00.asm L379–381bank_00.asm L413–421bank_00.asm L423–433bank_00.asm L505–519constants.asm L57 | Code |
The sound engine runs on the SPC700. Its set-instrument command ($DA) reads a 5-byte entry from a table in audio RAM at $5F46 and writes the first four bytes to the voice's DSP registers, the sample number (SRCN), ADSR1, ADSR2, and GAIN, and keeps the fifth as a pitch multiplier, so every instrument is a recorded sample with an envelope. | bank_0E.asm L1–8bank_0E.asm L1174–1215 | Code |
The engine's main loop waits on timer 0, set to tick every 2 ms; for each tick it adds the song's tempo byte to an 8-bit accumulator, and on a carry out it calls the routine APU_0BC0, unless a flag at audio RAM $0388 is set. That routine wasn't read; the structure suggests it is one step of the music, which would make the tempo set the step rate. The tempo starts at $36, which gives 500 × 54 / 256, about 105 carries a second. | bank_0E.asm L56–62bank_0E.asm L63–95bank_0E.asm L1294–1298 | Code |
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. | bank_00.asm L9921–9924bank_00.asm L9940–9942bank_00.asm L9953–9982 | Code |
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. | bank_00.asm L9673–9675 | Code |
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. | bank_00.asm L10167–10169bank_00.asm L10439–10444bank_00.asm L10457–10459bank_00.asm L821–824 | Code |
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. | bank_00.asm L10171–10173bank_00.asm L10446–10450 | Verified |
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. | bank_00.asm L8897–8905bank_00.asm L8946–8949 | Code |
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. | bank_00.asm L10909–10933 | Code |
| 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. | bank_00.asm L9673–9675bank_00.asm L10439–10459 | Verified |
| 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. | bank_00.asm L10439–10459 | Verified |
| 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. | bank_00.asm L9673–9675 | Verified |
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. | bank_00.asm L9764–9765 | Verified |
| In the air with neither Left nor Right held, Mario's horizontal routine returns before friction, so he keeps his speed. | bank_00.asm L9998–10000bank_00.asm L10021bank_00.asm L10125–10128 | Code |
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. | bank_00.asm L9699bank_00.asm L9717bank_00.asm L10061–10075bank_00.asm L10107–10123 | Code |
| 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. | bank_00.asm L10125–10128bank_00.asm L10061–10075 | Verified |
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. | bank_00.asm L8897–8905bank_00.asm L8946–8949bank_00.asm L12589–12595 | Verified |
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. | bank_00.asm L10114–10123bank_00.asm L10909–10917 | Code |
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. | bank_00.asm L9698–9699bank_00.asm L9717bank_00.asm L10055–10082 | Code |
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. | bank_00.asm L9764–9765bank_00.asm L10083–10106bank_00.asm L10504–10514bank_00.asm L9908–9909 | Code |
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. | bank_00.asm L10107–10113 | Code |
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. | bank_00.asm L10125–10163bank_00.asm L9678–9679 | Code |
| 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. | bank_00.asm L10061–10075 | Code |
| 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. | bank_00.asm L10043–10054 | Code |
| 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. | bank_00.asm L9921–9933bank_00.asm L9943–9951 | Code |
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. | bank_00.asm L9698–9699bank_00.asm L9908–9909bank_00.asm L9984–9986 | Verified |
| 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. | bank_00.asm L10061–10075bank_00.asm L10083–10101bank_00.asm L10107–10123bank_00.asm L10125–10128bank_00.asm L9983–9993 | Verified |
| 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. | bank_00.asm L9717 | Verified |
| 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. | bank_00.asm L9981–9995 | Verified |
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. | bank_00.asm L12589–12598 | Verified |
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. | bank_03.asm L6941–6977 | Code |
| 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. | bank_00.asm L11671–11690bank_00.asm L12042–12074bank_00.asm L13273–13284 | Code |
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. | bank_00.asm L13490–13496bank_00.asm L9442–9459bank_00.asm L7902–7911rammap.asm L1640–1642 | Code |
GetBlockAtPlayer 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. | bank_00.asm L13273–13284bank_00.asm L13299–13313bank_00.asm L12140–12146 | Code |
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. | bank_00.asm L12165–12189bank_00.asm L11704–11714bank_00.asm L11841–11861bank_00.asm L12087–12099 | Verified |
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. | bank_00.asm L12385–12389bank_00.asm L12422–12428bank_00.asm L12541–12545bank_00.asm L11544–11549 | Verified |
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. | bank_00.asm L9921–9924bank_00.asm L8897–8905 | Verified |
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. | bank_00.asm L12393–12395bank_00.asm L12407–12413bank_00.asm L12514–12522 | Verified |
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. | bank_00.asm L8904–8907bank_00.asm L13470–13486bank_00.asm L13532–13538 | Code |
| 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). | bank_00.asm L12069–12073bank_00.asm L12195–12197bank_00.asm L12265–12295 | Verified |
| 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. | bank_00.asm L12271–12280bank_00.asm L9934–9940 | Verified |
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. | bank_00.asm L12256–12264bank_00.asm L12735–12740bank_02.asm L902–905bank_00.asm L12453–12463 | Verified |
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. | bank_02.asm L1035–1045bank_02.asm L884–885bank_02.asm L7031–7053bank_02.asm L2126–2127bank_02.asm L2173–2174bank_02.asm L2290–2291 | Verified |
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. | bank_02.asm L1046–1050bank_02.asm L2136–2168bank_00.asm L7307–7314 | Verified |
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. | bank_00.asm L12735–12738bank_00.asm L12756–12759bank_02.asm L2242–2244bank_02.asm L2260 | Verified |