| The disk side of Super Mario Bros.: The Lost Levels, counted by part of the game: each stretch of code or data in its eight files goes to the part its code shows it serves, and the value sums the bytes of each part. | fdswrap.asm L1–133 | Code |
| The Lost Levels keeps Super Mario Bros.'s movement tables for Mario byte for byte. Take-off speeds, held and falling gravities, frictions, and top speeds all match. | sm2main.asm L4955–4974 | Code |
Picking Luigi copies his own gravities and frictions over Mario's: held gravity $18–$22 for the five jump rows against Mario's $1E–$28, falling gravity $3E–$5D against $60–$90, and friction $B4, $68, $A0 against $E4, $98, $D0. It also writes an RTS over the ASL that doubles Mario's friction when he faces away from his motion. His take-off speeds are Mario's. Each area's setup loads the chosen player's set; the axe at the end of a castle loads Mario's set and ASL back for the walk that follows, whoever is playing, until the next area loads the player's own again. | sm2main.asm L14477–14488sm2main.asm L14490–14507sm2main.asm L5124–5129sm2main.asm L2605–2611sm2main.asm L11158–11165 | Code |
ProcJumping starts a jump only while Player_State is 0, on the ground, or while the player is swimming, as Super Mario Bros.'s does. Walking off a ledge doesn't keep that state: PlayerBGCollision sets a player in the normal or climbing state to falling (or, swimming, to state 1) on each frame of play before it looks for ground, and only landing on a block sets the state back to 0, so out of water a jump can't start after walking off a ledge. The background check skips that step only during the game's scripted routines (GameEngineSubroutine 0 to 3 and $0B). | sm2main.asm L5015–5019sm2main.asm L10936–10949sm2main.asm L11046–11056 | Code |
A hit on big Mario sets InjuryTimer to 8, as in Super Mario Bros., and the timer counts down once every 21 frames with the interval timers, through the same timer loop as Super Mario Bros.'s. | sm2main.asm L10424–10433sm2main.asm L928–933sm2main.asm L81–99 | Code |
Wind blows the player to the right. An area object turns it on (WindOn) and another off (WindOff), and the setup that runs at the start of every area clears it. While it is on, and only in ground-type areas (underground, water, and castle areas stay calm), it moves the player 1 px right on every fourth frame while the frame counter is below 128 and on every second frame from 128 to 255: 96 px every 256 frames, 0.375 px a frame on average. The push is added to the position after the player's own move, on the ground and in the air but not while climbing, so it adds to a rightward speed and takes from a leftward one whatever the speed, and the screen scrolls with it. Its leaves and sound play while it is on, in every type of area. None of it runs until the game has loaded a disk file beyond worlds 1 to 4 (worlds 5 to 8, the ending, or worlds A to D): before that, FileListNumber is 0 and both calls are skipped. | sm2data2.asm L179–202sm2data4.asm L322–345sm2main.asm L4848–4853sm2main.asm L4892sm2main.asm L4830–4835sm2main.asm L4273–4275sm2data2.asm L217–221sm2data2.asm L264–270sm2main.asm L4236–4239sm2main.asm L2615–2618 | Code |
| A poison mushroom comes out of a block of its own kind, and stays a poison mushroom whatever the player's size, where an ordinary mushroom block gives a fire flower to a big or fiery player. It slides along like a mushroom. Touching it removes it and runs the injury routine: a small player dies, and a big or fiery one drops straight to small, with the blink that follows any hit. During that blink, or while a star's invincibility lasts, it is removed and does nothing. | sm2main.asm L6308–6339sm2main.asm L6123–6130sm2main.asm L6148–6155sm2main.asm L6161sm2main.asm L10253–10258sm2main.asm L10423–10436 | Code |
The poison mushroom is drawn from the same four tiles as the mushroom and the 1-up mushroom ($D8, $DA, $DB, $FF) in sprite palette 3, where the mushroom uses palette 2 and the 1-up palette 1. Like them it keeps its colors, where the fire flower and the star cycle theirs. | sm2main.asm L12527–12535sm2main.asm L12565–12571 | Code |
| Every area from World 4-4 on, and every area of worlds A to D, starts with the secondary hard mode flag set; the areas of worlds 1 to 3 and 4-1 to 4-3 start without it. The memory clear at the start of each area resets it first. | sm2main.asm L2557–2559sm2main.asm L2591–2600 | Code |
With the secondary hard mode flag set: enemies the level data marks for hard mode appear, where otherwise they are skipped; a Bullet Bill cannon is picked to fire when a pseudorandom number masked to three bits is below 6 (6 of 8 values, against 6 of 16 with four bits); up to four flying Cheep Cheeps at once instead of three; hammer bros throw on a shorter timer ($1C against $30), can take the longer of two jump timers ($37 against $20), and in worlds 1 to 6 wait a shorter time before walking left ($50 against $80; in worlds 7 to 9 they don't wait either way, and worlds A to D, which share world numbers 1 to 4 and always have the flag, take $50); Bloopers pick a new direction when two pseudorandom bits are clear rather than six, and then a Blooper in an even enemy slot turns toward the player, one in an odd slot takes the player's moving direction; Bowser's fire breath and the flames that fly in on their own come 16 timer ticks sooner, and the flames move faster ($60 subtracted from their fractional position each frame, against $40); and the large lifts are drawn four sprites wide instead of six with a smaller box, as they always are in castles, with balance platforms and their ropes placed for the shorter width. | sm2main.asm L6968–6973sm2main.asm L5753–5754sm2main.asm L5763–5767sm2main.asm L7408–7414sm2main.asm L8207–8208sm2main.asm L8227–8231sm2main.asm L8241–8242sm2main.asm L8267–8273sm2main.asm L7166–7167sm2main.asm L7173–7178sm2main.asm L8469–8470sm2main.asm L8476–8488sm2main.asm L9257–9262sm2main.asm L7554–7561sm2main.asm L9331–9335sm2main.asm L12395–12402sm2main.asm L7935–7942sm2main.asm L7885–7888sm2main.asm L7985–7986sm2main.asm L9813–9821 | Code |
The code keeps the primary hard mode flag's checks, which turn Goombas into Buzzy Beetles, start walking enemies faster ($F4 against $F8), and revive stomped enemies sooner and send them off faster. Nothing in The Lost Levels' code sets the flag, and starting a game clears it, so none of these takes effect. Super Mario Bros. sets it from its world select flag when a game starts. | sm2main.asm L6983–6989sm2main.asm L7751–7756sm2main.asm L7148–7157sm2main.asm L8213–8214sm2main.asm L8351–8356sm2main.asm L10518–10519sm2main.asm L10530–10532sm2main.asm L14848–14849 | Code |
| A warp zone leads to one world, whichever of its pipes the player takes. In world 1 it leads to world 2 from the first underground area, to world 3 from a ground area, and to world 4 from any other; in world 3, back to world 1; in world 5, to world 6 from one ground area (the 12th in the area table, which the disassembly's comment places at 5-1), to world 8 from any other ground area, and to world 7 from any other area; in worlds 2, 4, and 6 to 9, to world 5, which from 6 to 8 is back. In worlds A to D it goes by level: from a second level to world B, a third to world C, a fourth to world D; the table holds no world for a first level. | sm2main.asm L3425–3468sm2main.asm L1689–1690sm2main.asm L11332–11343 | Code |
| Clearing a world's castle sets that world's bit in a record of completed worlds. After the ending that follows 8-4, the game goes on to World 9 if all eight bits are set, and back to the title screen if any is missing; after D-4 it always goes back to the title. The record is cleared when a game starts and when the player picks Retry at a game over, and Continue keeps it, so a world skipped by a warp counts only if the player warps back and clears its castle. | sm2main.asm L1185–1195sm2data3.asm L428–451sm2main.asm L14692–14698sm2main.asm L14455–14460sm2main.asm L14462–14473 | Code |
| World 9 begins with one life. A game over there ends the game, with no continue menu. Its four levels loop: after 9-4 the game starts 9-1 again. | sm2data3.asm L446–451sm2main.asm L2850–2867sm2main.asm L4793–4803sm2main.asm L1303–1313 | Code |
| Each time the ending loads, after 8-4 or D-4, the count of games beaten goes up by one, to at most 24 (a short read of the ending's files resets it to 0 first). After 8-4 the game writes the count to the disk's save file (a disk error aside); after D-4 it doesn't, and the title screen, which reloads the disk's first files after a game in worlds A to D or from world 5 on, reads the saved count back, so D-4 adds nothing. The title screen shows a star for each game beaten, in two rows of 12. With 8 or more, holding A while pressing Start begins the game at World A, loading worlds A to D, with their own halfway points, from the disk. | sm2main.asm L14261–14280sm2data3.asm L391–426sm2main.asm L14180–14193sm2main.asm L14301–14308sm2main.asm L14832–14847sm2main.asm L14692–14706sm2main.asm L14147–14160sm2main.asm L1196–1202 | Code |
Landing on a springboard sets both the held and the falling gravity to $70 and a launch speed of −7 px a frame ($F9). Over the spring's four steps it carries the player down 2 px a step, then up 2 px a step, and on the last step it launches them. A press of A, not held from before, in the second step or later raises the launch to −12 px a frame ($F4), or to −32 px a frame ($E0) on the green springboards of world numbers 2, 3, and 7, which the letter worlds share as B and C, since the test reads the world number without the letter-world flag. With both gravities at $70, the bounce rises and falls under one pull whether A is held or not, for Mario and Luigi alike. While the game's timers are stopped the spring waits. | sm2main.asm L11291–11303sm2main.asm L5574–5620sm2main.asm L12672–12683sm2main.asm L6575–6584 | Code |
| Piranha plants are green in worlds 1 to 3 and red in worlds 4 to 9 and A to D. A green one stays in its pipe while the player is less than 33 px from it across, and moves on every second frame; a red one stays in only while the player is less than 19 px away, and moves on every frame. | sm2main.asm L7805–7821sm2main.asm L9593–9596sm2main.asm L9612–9619 | Code |
While Lakitu's stretch of a level runs, the game checks every 128 frames whether a Lakitu is on screen. When none is, it counts the check, and on the third it sends a new Lakitu if an enemy slot is free (if none is, it tries again at the next check); the count starts over when a Lakitu is set up. The new one flies high in worlds 1 to 6 ($20) and lower in worlds 7 to 9 and A to D ($60). When one is on screen, the same check leads to the Spiny throw, not covered here. | sm2main.asm L7251–7288sm2main.asm L7234–7236sm2main.asm L928–933 | Code |
| At a game over outside World 9, Select switches between CONTINUE and RETRY and Start picks. Continue restarts the current world at its first level, small, with three lives, the score and coins at zero, and the hidden 1-up available again. Retry ends the game and clears the record of completed worlds. | sm2main.asm L14431–14444sm2main.asm L14455–14473sm2main.asm L2869–2881 | Code |
| Grabbing the flagpole gives an extra life in place of the height's points when the coin count's two digits are the same and match the timer's last digit (11 coins with the timer ending in 1, for example). | sm2main.asm L11219–11231sm2main.asm L5551–5559 | Code |
| Fireworks go off over the castle when the timer's last digit matches the coin count's last digit as the level ends: three when the digit is odd, six when it is even, and none when they differ. | sm2main.asm L9470–9485 | Code |
The Lost Levels' boot, NMI and pause code (Start through MoveAllSpritesOffscreen) is Super Mario Bros.'s with these changes: Start sets mirroring through the disk drive's control register, keeps WorldNumber across the reset and sets the BIOS's IRQ flag; the NMI arms the drive's timer IRQ to split the status bar from the level, where Super Mario Bros. waits for the sprite 0 hit, and its VRAM address table is one table of 31 words where Super Mario Bros. has low and high byte tables of 19; PauseRoutine allows a pause in game-mode task 4 instead of 3, the game mode's task list having gained a disk task at its head. SpriteShuffler and MoveAllSpritesOffscreen are byte for byte the same, and the operating-mode dispatch differs only in its addresses. | sm2main.asm L801sm2main.asm L822sm2main.asm L834sm2main.asm L868–873sm2main.asm L846–853sm2main.asm L1033sm2main.asm L4235sm2main.asm L801–1129 | Code |
The castle victory sequence (VictoryMode through PrintVictoryMessages) is Super Mario Bros.'s with these changes: on world 8, which world D also uses, VictoryMode runs a second task list that loads the ending from disk; SetupVictoryMode also sets the world's bit in CompletedWorlds and queues the castle-clear music; PrintVictoryMessages loses Super Mario Bros.'s world 8 branch and its victory music, and gains EndCastleAward, which counts the remaining time into points. DrawTitleScreen, which sits in the middle, shrinks to a few instructions that queue a layout held in the program, where Super Mario Bros. copies it out of CHR ROM. PlayerVictoryWalk keeps every instruction; only its addresses and one branch's distance differ. | sm2main.asm L1152sm2main.asm L1173sm2main.asm L1194sm2main.asm L1203sm2main.asm L1287sm2main.asm L1134–1318 | Code |
The score numbers, the screen setup tasks, the status bar and the game's text (FloateyNumbersRoutine through ResetScreenTimer) are Super Mario Bros.'s with these changes: GetPlayerColors no longer picks a palette row by CurrentPlayer (Super Mario Bros.'s table has a row for Luigi); WriteBottomStatusLine goes through a new GetWorldNumForDisplay, which shows worlds A to D as letters; DisplayIntermediate blanks the screen after the world and lives screen in world 9, and DisplayTimeUp writes its text and resets the screen timer itself where Super Mario Bros. jumps into DisplayIntermediate; ClearBuffersDrawIcon's title-screen part moves to the title code; the screen task list gains DemoReset; GameText drops the two-player and Luigi texts and adds CONTINUE and RETRY to the game-over screen. InitScreen, SetupIntermediate, GetAreaPalette, GetAlternatePalette1, WriteTopStatusLine, AreaParserTaskControl and ResetScreenTimer keep every instruction, with only addresses changed. | sm2main.asm L1502–1505sm2main.asm L1556sm2main.asm L1574–1580sm2main.asm L1620sm2main.asm L1434sm2main.asm L1674sm2main.asm L1325–1758 | Code |
The background renderer, the metatile tables and the area palettes (RenderAreaGraphics through the palette data) are Super Mario Bros.'s with the metatiles renumbered: The Lost Levels inserts new metatiles, so ReplaceBlockMetatile compares against shifted numbers ($56, $4F, $5C and $50 for Super Mario Bros.'s $58, $51, $5D and $52), and MetatileGraphics_Low moves some entries and adds others. The palette data region also holds two new messages. RenderAttributeTables is byte for byte the same, and RenderAreaGraphics and ColorRotatePalette differ only in their addresses. | sm2main.asm L2006sm2main.asm L2190sm2main.asm L2153sm2main.asm L2274–2287sm2main.asm L1771–2287 | Code |
JumpEngine, InitializeNameTables, ReadJoypads and UpdateScreen are Super Mario Bros.'s, instruction for instruction: JumpEngine is byte for byte the same, and the other three differ only in the addresses of their calls, jumps and tables. | sm2main.asm L2292–2429 | Code |
The status bar numbers, game setup, lives and game over (PrintStatusBarNumbers through RunGameOver) are Super Mario Bros.'s with a new GameOverSubs dispatch among them and these changes: the status bar's digit tables lose the second player's entries; UpdateTopScore checks one score where Super Mario Bros. checks two; DigitsMathRoutine drops a compare with zero before its BEQ; DefaultSprOffsets loses the sprite 0 data; InitializeArea loads the player's physics (LoadPhysicsData) and sets the secondary hard mode flag from 4-4 on and in all of worlds A to D (HardWorldFlag), where Super Mario Bros. sets it from 5-3 on or once the primary hard mode flag is set; SecondaryGameSetup sets the name table and switches on the status bar's IRQ split, where Super Mario Bros. sets the second player's lives and switches on the sprite 0 check; InitializeMemory also spares $0100-$0108; PlayerLoseLife reads its own halfway pages and no longer swaps players; RunGameOver opens the continue-or-retry menu (or, in world 9, ends the game) where Super Mario Bros. ends the game on Start or when the screen timer runs out and then hands over to the other player if they have lives left. GetAreaMusic and Entrance_GameTimerSetup keep every instruction, though the level timer's digits moved from $07F8 to $07EC. | sm2main.asm L2444sm2main.asm L2591–2598sm2main.asm L2609sm2main.asm L2631sm2main.asm L2645sm2main.asm L2660–2661sm2main.asm L2854–2856sm2main.asm L2751sm2main.asm L2438–2881 | Code |
The area parser and its object builders (AreaParserTaskHandler through GetBlockBufferAddr) are Super Mario Bros.'s, with most changes in the metatile numbers they write, which shift with the renumbered metatiles (bridges, flagpole, coins, bricks, cannons, stairs, blocks, water pipe). Beyond those: the object jump table gains entries, the wind on and off commands among them, so three offsets into it change; ScrollLockObject_Warp picks the warp zone's destination by world, level and area; the third ledge style uses metatiles $8A-$8C and draws no stem, where Super Mario Bros.'s mushroom ledge uses $19-$1B with a stem (and RenderUnderPart drops its stem checks); the vertical pipes place a piranha plant through a shared SetupPiranhaPlant, with no exception for world 1-1; Jumpspring places nothing when no enemy slot is free. IncrementColumnPos, AlterAreaAttributes, KillEnemies and the object position helpers are byte for byte the same. | sm2main.asm L3246sm2main.asm L3385–3386sm2main.asm L3429sm2main.asm L3550sm2main.asm L3560sm2main.asm L4145sm2main.asm L3772–3773sm2main.asm L4040sm2main.asm L2893–4227 | Code |
GameCoreRoutine and ScrollHandler are Super Mario Bros.'s with three changes: the game mode's task list gains GameModeDiskRoutines at its head and the core no longer reads the current player's saved joypad bits; each frame of play calls SimulateWind once a disk file beyond worlds 1 to 4 is loaded; ScrollHandler waits for the status bar's timer IRQ before it scrolls and keeps the name table in NameTableSelect, where Super Mario Bros. sets it in its PPU control mirror. GetScreenPosition is byte for byte the same. | sm2main.asm L4235sm2main.asm L4275sm2main.asm L4341sm2main.asm L4357sm2main.asm L4232–4406 | Code |
The player's control and movement code (GameRoutines through ImposeFriction) is Super Mario Bros.'s, instruction for instruction in 14 of its 19 regions, with these changes: OnGroundStateSub and the jump and swim code move the player through a new JmpMove, which lets the wind push them (BlowPlayerAround) once a disk file beyond worlds 1 to 4 is loaded; PlayerPhysicsSub's friction table moves up to follow the fall forces, inside the 17 bytes that LoadPhysicsData overwrites with Mario's or Luigi's set; PlayerEndLevel queues the level-end music once, guarded by a new FlagpoleMusicFlag, where Super Mario Bros. queues it whenever ScrollLock is set, and sets the hidden 1-up's flag on 10 coins in any world, where Super Mario Bros. reads a per-world table, and starts world 9 over after 9-4; PlayerDeath shares one RTS. The entrances, pipes, size change, injury blink, flagpole slide, falling, climbing, animation speed and ImposeFriction differ only in their addresses. | sm2main.asm L4848–4852sm2main.asm L4892sm2main.asm L4962sm2main.asm L4768–4772sm2main.asm L4790sm2main.asm L4794–4802sm2main.asm L14490–14504sm2main.asm L4411–5207 | Code |
Fireballs, the level timer and the stage objects (ProcFireballs through VineObjectHandler) are Super Mario Bros.'s with these changes: RunGameTimer tests the player's height with BPL instead of BCS and points at the timer digits' new place; WarpZoneObject no longer counts up WarpZoneControl; FlagpoleRoutine gives a life for the new sixth flagpole score; JumpspringHandler launches with the green springs' force on world numbers 2, 3 and 7; VineObjectHandler erases the vine and its metatiles once it goes off the left of the screen. ProcFireballs and ProcessWhirlpools differ only in their addresses, and SetupVine is byte for byte the same. | sm2main.asm L5387sm2main.asm L5404sm2main.asm L5552–5557sm2main.asm L5604–5611sm2main.asm L5714–5724sm2main.asm L5215–5749 | Code |
Cannons, hammers, coins, power-ups and blocks (ProcessCannons through BlockObjMT_Updater) are Super Mario Bros.'s with the poison mushroom added and one player: BumpBlock's contents table gains poison mushroom blocks and MushFlowerBlock gains PoisonMushBlock, which sets power-up type 4; PowerUpObjHandler walks types 4 and 5 like a mushroom; BlockBumpedChk checks 19 block metatiles where Super Mario Bros. checks 14; GiveOneCoin and AddToScore use fixed offsets where Super Mario Bros. indexes by CurrentPlayer; the head-collision and coin checks use the renumbered metatiles. SetupPowerUp is byte for byte Super Mario Bros.'s, though the poison mushroom now passes through it, and so are InitBlock_XY_Pos and SpawnBrickChunks; the cannons, hammers, jumping coins, brick shatter and bouncing blocks differ only in their addresses. | sm2main.asm L6305sm2main.asm L6319–6322sm2main.asm L6333sm2main.asm L6152–6155sm2main.asm L6358sm2main.asm L6071sm2main.asm L6227sm2main.asm L5754–6512 | Code |
The movement and gravity routines (MoveObjectHorizontally through ImposeGravity) are Super Mario Bros.'s, instruction for instruction: ImposeGravity and MoveDropPlatform are byte for byte the same, and the other seven differ only in the addresses of their calls and jumps. | sm2main.asm L6520–6748 | Code |
Enemy spawning and set-up (EnemiesAndLoopsCore through InitJumpGPTroopa) are Super Mario Bros.'s with these changes: ProcLoopCommand reads 12 loop entries where Super Mario Bros. reads 11, and takes each loop's number of checks from a new MultiLoopCount table where Super Mario Bros. special-cases world 7; ProcessEnemyData skips a check in world 9 and gives one enemy code a piranha plant set-up; InitHammerBro checks the world; LakituAndSpinyHandler brings Lakitu back once LakituReappearTimer reaches 3, where Super Mario Bros. waits until it reaches 7, and brings him back lower on the screen in worlds 7 to 9 and A to D; InitBowser first erases any other Bowser; InitPiranhaPlant patches the plant's palette and pipe distance, green in worlds 1 to 3 and red from world 4 and in A to D; InitJumpGPTroopa starts the jumping paratroopa at x speed $F4 where Super Mario Bros. uses $F8. Of its 27 regions, 15 differ only in their addresses and 5 are byte for byte the same. | sm2main.asm L6832sm2main.asm L6850sm2main.asm L7018–7020sm2main.asm L7173–7175sm2main.asm L7265–7266sm2main.asm L7280–7285sm2main.asm L7483–7493sm2main.asm L7810–7821sm2main.asm L7874sm2main.asm L6758–7878 | Code |
The platforms' set-up, the enemy object loop, the enemies' movers, Bowser and the fireworks (InitBalPlatform through RunFireworks, 32 regions) are Super Mario Bros.'s instruction for instruction, with two changes: the enemy movers' jump table (EnemyMovementSubs) sends enemy 4, the upside-down piranha plant, to the new MoveUpsideDownPiranhaP, where Super Mario Bros. has MoveNormalEnemy; MoveSwimmingCheepCheep adds $40 to a swimming Cheep Cheep's vertical fraction each frame where Super Mario Bros. adds $20. Three of the regions are byte for byte the same, and the rest differ only in the addresses of their calls, jumps and tables. | sm2main.asm L8093sm2main.asm L8621–8622sm2main.asm L7883–9443 | Code |
RunStarFlagObj through OffscreenBoundsCheck are Super Mario Bros.'s with these changes: RunStarFlagObj sets off fireworks when the timer's last digit matches the coin tally's, where Super Mario Bros. matches the timer's last digit against 1, 3 and 6, and adds its points to the one player's score; MovePiranhaPlant moves red piranha plants (the patched palette) every frame; BalancePlatform leaves a platform alone when its partner is no balance platform; OffscreenBoundsCheck treats upside-down piranha plants like upright ones. FirebarSpin is byte for byte the same, and the moving platforms differ only in their addresses. | sm2main.asm L9472sm2main.asm L9615sm2main.asm L9682–9684sm2main.asm L10023sm2main.asm L9448–10064 | Code |
The collision code (FireballEnemyCollision through BlockBufferCollision) is Super Mario Bros.'s with the upside-down piranha plant, the poison mushroom and the renumbered metatiles added: the fireball, enemy, background and stomp checks treat the upside-down plant like a piranha plant; HandlePowerUpCollision injures the player on power-up type 4; InjurePlayer also does nothing while the star's StarInvincibleTimer runs; HandlePECollisions checks for the cannon's Bullet Bill before the piranha plants and Podoboo, where Super Mario Bros. checks it after them; PlayerEnemyCollision decides a stomp with LDY, DEY, BPL on the vertical speed where Super Mario Bros. uses BMI and BNE (the two disagree only at speed $80); every stomp bounces the player through a new SetBounce, at vertical speed $FA, or $F8 off red paratroopas and flying green paratroopas, where Super Mario Bros. sets $FD after a stomp that defeats an enemy and $FC after one that demotes a paratroopa or knocks an enemy into its shell; HandleClimbing gives a life for grabbing the flagpole when the coin tally's digits and the timer's last digit match; HandlePipeEntry sends the player to the warp zone's one destination whichever pipe they take, where Super Mario Bros. picks by the pipe's x position; HandleCoinMetatile's axe restores Mario's physics; ChkForLandJumpSpring sets VerticalForceDown to $70 as well as VerticalForce; PlayerHammerCollision also skips while the player is off screen; HandleEToBGCollision bounces a power-up on a bumped block without stunning it and never demotes a piranha plant; CheckPlayerVertical drops its test of how far down the screen the player is; one bounding box grows from $14 to $16. The platform collisions, LandEnemyProperly, the side checks and BlockBufferCollision differ only in their addresses, and three regions, PlayerCollisionCore among them, are byte for byte the same. | sm2main.asm L10190sm2main.asm L10255–10258sm2main.asm L10424–10425sm2main.asm L10356–10361sm2main.asm L11294–11296sm2main.asm L10399–10401sm2main.asm L10533–10541sm2main.asm L11225–11231sm2main.asm L11334–11336sm2main.asm L11163sm2main.asm L10224sm2main.asm L11501–11515sm2main.asm L11827sm2main.asm L10070–12141 | Code |
The sprite drawing code (DrawVine through DrawSpriteObject) is Super Mario Bros.'s with these changes: DrawPowerUp draws every mushroom from tiles $D8, $DA, $DB and $FF where Super Mario Bros. uses $76-$79, and gives the poison mushroom, a fifth row, palette 3; EnemyGfxHandler's tile table takes up $76-$79, and the handler also flips the upside-down piranha plants and colors the jumpsprings green on world numbers 2, 3 and 7; RenderPlayerSub plays the skid sound; FlagpoleGfxHandler's score table gains the 1-up; GetYOffscreenBits has two of its tables' halves swapped, its instructions unchanged; DrawBlock uses a renumbered metatile. 12 regions, PlayerGfxHandler among them, differ only in their addresses, and five, DrawSpriteObject among them, are byte for byte the same. | sm2main.asm L12528sm2main.asm L12532sm2main.asm L12535sm2main.asm L12635sm2main.asm L12672–12683sm2main.asm L13691–13695sm2main.asm L12309sm2main.asm L14020–14028sm2main.asm L12153–14117 | Code |
GameMenuRoutine and DemoEngine are Super Mario Bros.'s menu and demo, rewritten in part: the menu drops the one- or two-player choice and the world select, and starts the game at world 1, or at world A when A is held and the game has been beaten 8 times; Select switches between Mario and Luigi; the demo plays new button presses and durations through the same code. | sm2main.asm L14699–14705sm2main.asm L14727–14729sm2main.asm L14783sm2main.asm L14692–14806 | Code |
LoadAreaPointer, FindAreaPointer and GetAreaDataAddrs are Super Mario Bros.'s, with the area data address tables made tables of words (indexed with an ASL) where Super Mario Bros. keeps separate low and high byte tables; the tables themselves hold The Lost Levels' worlds, and AreaDataOfsLoopback its 12 loop points. Of the level data, only the 9-byte pipe intro area (L_GroundArea10) is byte for byte Super Mario Bros.'s. | sm2main.asm L14565sm2main.asm L14567sm2main.asm L14526sm2main.asm L14536–14686 | Code |
The sound engine (SoundEngine through MusicHandler) is Super Mario Bros.'s with two new sounds in the noise handler: the skid, played on the triangle channel from SkidSfxFreqData, and the wind, played from WindFreqEnvData; both tables sit after the square 2 handler. SoundEngine, Dump_Squ1_Regs, Square1SfxHandler and MusicHandler differ only in their addresses. | sm2main.asm L15793–15805sm2main.asm L15857sm2main.asm L15784sm2main.asm L15886–15890sm2main.asm L15286–16251 | Code |
SM2MAIN's music data is Super Mario Bros.'s less the victory theme: the headers lose VictoryMusHdr and their offsets shift by its five bytes, the residual header bytes differ, and VictoryMusData is gone from between the castle-clear music and the frequency tables, with two of the three unused bytes after it (the ending's music lives in SM2DATA3). The notes of every other song and the frequency, note-length and envelope tables after them are byte for byte the same. | sm2main.asm L16294sm2main.asm L16254–16623 | Code |
1,299 bytes of The Lost Levels' music are Super Mario Bros.'s byte for byte: the last bytes of the music headers and the notes of every song SM2MAIN plays, from the star music (Star_CloudMData) through the ground music's parts, death, castle, game over, time running out, level end, underground, water and the castle-clear music (EndOfCastleMusData). | sm2main.asm L16341–16574 | Code |
AlternateSoundEngine, the ending's sound engine in SM2DATA3, is a rewrite of Super Mario Bros.'s MusicHandler that keeps its note and length code: it has no event or area music buffers and no time-running-out handling, steps through a list of patterns with PatternNumber, reading each pattern's header from MusicHeaderData, has its own pause and silence code, and plays the ending's music on the disk system's wavetable channel as well as the square, triangle and noise channels, with its own waveform, envelope and modulation tables. | sm2data3.asm L771–777sm2data3.asm L803–807sm2data3.asm L815sm2data3.asm L773–774sm2data3.asm L818–820sm2data3.asm L771–1186 | Code |
The player's 80 sprite tiles, $00-$4F of the sprite pattern table, are Super Mario Bros.'s byte for byte. | fdswrap.asm L61 | Code |
Sprite tiles $50-$FF are Super Mario Bros.'s but for 15: $5B, $76-$7B, $85, $86, $D8, $DA, $DB and $FD-$FF differ, among them $76-$79, Super Mario Bros.'s mushroom, which The Lost Levels' enemy table now draws, and the mushrooms' new tiles. | fdswrap.asm L61 | Code |
The font, background tiles $00-$23 (the digits and A to Z), keeps Super Mario Bros.'s layout, so GameText spells with the same numbers, but every one of its 36 tiles differs from Super Mario Bros.'s. | fdswrap.asm L61 | Code |
Background tiles $24-$EB are Super Mario Bros.'s but for 65 of their 200: $28, $29, $2B-$2D, $30-$3C, $45, $47, $4B, $4C, $4E-$52, $5D, $5E, $6B-$76, $80, $81, $9B-$9E, $A0, $A1, $A9, $AA, $AF, $B4-$BD, $C0, $C1 and $CF differ. | fdswrap.asm L61 | Code |