| Super Mario Bros.'s cartridge ROM, counted by part of the game: each stretch of code or data goes to the part its code shows it serves, and the value sums the bytes of each part. | 0x10-0xa00f | 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. | 0x10-0x240 | 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. | 0x39b-0x470 | 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. | 0x4af-0x8bd | 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. | 0x8be-0xd63 | 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. | 0xe14-0xf03 | 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. | 0xf04-0x12bf | 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. | 0x12c0-0x1c05 | 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. | 0x2efa-0x3059 | 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. | 0x305a-0x3633 | 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. | 0x3634-0x39c9 | 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. | 0x39ca-0x3f11 | 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. | 0x3f12-0x4056 | 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. | 0x4057-0x47ee | 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. | 0x47ef-0x52dc | 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. | 0x52dd-0x56e5 | 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. | 0x56e9-0x6441 | 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. | 0x6443-0x72d9 | 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. | 0x24f-0x32c0x350-0x39a | 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. | 0x1c08-0x1d7f | 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. | 0x72e0-0x791c | 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. | 0x791d-0x8009 | 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). | 0x79c5-0x7ed7 | 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. | 0x76a1-0x791c | Code |
The player's 80 sprite tiles, $00-$4F of the sprite pattern table, are Super Mario Bros.'s byte for byte. | 0x8010-0x850f | 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. | 0x8510-0x900f | 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. | 0x9010-0x924f | 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. | 0x9250-0x9ecf | Code |