Tool-assisted game movies
When human skills are just not enough

Submission #4315: Masterjun's SNES Super Mario World "game end glitch" in 00:41.98

Console: Super NES
Game name: Super Mario World
Game version: USA
ROM filename: Super Mario World (U) [!].smc
Branch: game end glitch
Emulator: lsnes rr2-β21
Movie length: 00:41.98
FrameCount: 2523
Re-record count: 6394
Author's real name: Julian N.
Author's nickname: Masterjun
Submitter: Masterjun
Submitted at: 2014-05-19 21:17:10
Text last edited at: 2015-04-05 21:05:35
Text last edited by: Masterjun
Download: Download (2677 bytes)
Status: published
Click to view the actual publication
Submission instructions
Discuss this submission (also rating / voting)
List all submissions by this submitter
List pages on this site that refer to this submission
View submission text history
Back to the submission list
Author's comments and explanations:
As it will happen eventually, destroying all my previous work for this game, have fun watching even less of this game.

(Link to video)

Game objectives

  • Emulator used: lsnes rr2-β21
  • Aims for fastest time
  • Uses game-breaking glitches
  • Achieves credits early


Go ahead and watch the TAS first, it doesn't really take that long.

This is basically the reason why I cancelled the Kirby Super Star submission. You can maybe see why I prefer the previous movie over this one. But first...

What happens this time?

Let's start at the basics. In SMW there are sprites which can change the status of Mario called powerups (such as mushrooms, flowers, stars and so on). It's easy enough for the game to just run a routine to change it as soon as Mario touches a sprite which is listed as a powerup. Now the problem comes when Yoshi eats a sprite, because if it is a powerup, it should be applied to Mario. The game checks if the sprite has a specific property that says the game if it should give Mario a powerup when it is being eaten. Interestingly enough, chucks have this property! Normally, this isn't a problem because you can't actually eat chucks because they have another property which ensures that the sprite won't be caught by Yoshi's tongue (it goes right through), making it impossible to get it on Yoshi's tongue and eat it... or is it?

Item Swap

This glitch is also used in the warps run in YI2 to get the goal tape to replace the shell on Yoshi's tongue, getting the level end earlier or in YI1 to replace a sprite on Yoshi's tongue with a chuck so that Yoshi can... eat it!

This is what I'm doing, too. I replace a sprite on Yoshi's tongue with a chuck. How do I do that? Well, it is possible to get a coin by touching it, but it is also possible to get a coin on Yoshi's tongue. Now just do both things at the same time (see pictures on the right) and Yoshi's tongue will hold a nonexistent sprite or simply nothing. All the game now knows is that Yoshi's tongue holds a sprite in a specific slot and if in that moment a sprite such as a chuck wants to spawn in that slot, its position will be overwritten since it's now on Yoshi's tongue. Yoshi is now able to eat the chuck which is apparently a powerup to the game.

Eating a chuck

Since the chuck powerup isn't intended by the developers and accidentally in the game, the code doesn't account for it and incorrectly indexes the sprite to put in the item box (which is a lakitu cloud) and also gets the subroutine location wrong to jump afterwards. Instead of jumping to a routine to change Mario's status, it jumps to $014A13... which is Open Bus.

Open Bus

Open Bus is an area in the SNES which isn't mapped to a location like WRAM or ROM, which means no such device answers the request from the console to get the next instruction to execute. This means that the console will just execute whatever value was the last one on data bus.

The code just jumped to $014A13 so the last value on data bus is 0x01.

data bus instruction information
0x01 ORA ($01,x) X is 0x09, $0A holds 0x0107, $0107 holds 0x17, A turns to 0x17 and data bus is 0x17
0x17 ORA ($17),Y $17 is interesting because $17 and $18 are SMW's controller data, so this is where I can kinda manipulate the outcome

This is the reason why I pressed X and the next frame AXL just before the glitch started so that $17 is 0xE0 and $18 is 0xA0. The code manages to change the SNES to emulation mode so now it can survive BRKs easily, as the vector changed. Then it managed to reach $4219 which are controller registers.

Controller Registers

These are the last 5 frames of input:
               1-1              1-2              2-1              2-2
  F. 0 0|....u.l.AXL.....|BY..u.lr...R....|.Ys..d..AXLR0.23|................
  F. 0 0|...Su...A.L.0..3|BY..u.lr...R....|.Ys..d..AX.R0...|BYsSu...A.......
  F. 0 0|..sSud.rA....123|BY..u.lr...R....|.Ys..d......0.23|BYsSu...A.......
  F. 0 0|....u...A.L.0..3|BY..u.lr...R....|.Ys..d..A.L.0.23|BYsSu...A.......
  F. 0 0|BY...dl.A...01.3|B........XLR..2.|..s........R..23|BYsSu...A.......
or in bytes ($4218 - $421F):
  E0 0A FB 64 10 CB 00 00
  A9 18 D8 64 10 CB 80 F8
  87 3D 0B 64 10 CB 80 F8
  A9 08 AB 64 10 CB 80 F8
  8D C6 13 20 72 80 80 F8
One thing to notice is that "64 10 CB" and "80 F8" occur often. "64 10 CB" is executed as STZ $10 : WAI which STores Zero to $10 and then WAits for an Interrupt. That effectively advances one frame and lets Auto-Joypad Read finish so that we have new input. Then it executes "80 F8" of the next frame (which is why there isn't one in the first frame). "80 F8" means BRA $F8 or BRAnch -8 bytes (or simply 8 bytes back), so we reach $4218 once again and can execute more code.

(The 0xE0 in the first frame isn't actually executed since we start at $4219, which is good because we needed that for the Open Bus part)

byte instruction information
0A ASL A used for clearing carry
FB XCE to recover to native mode after emulation mode to safely let NMI execute
A9 18 LDA #$18 load 0x18 into A for the game mode later
D8 CLD clear decimal mode flag to avoid the game getting confused with calculations
87 3D STA ($3D) store A to whatever long address is in $3D, which happens to be $000100 which is the game mode
0B PHD push direct page register so that I have 00's on the stack for later
A9 08 LDA #$08 load 0x08 into A for $13C6 later
AB PLB pull data bank which is now 00 thanks to the PHD before
8D C6 13 STA $13C6 store A to $13C6 to complete all necessary steps
20 72 80 JSR $8072 jump to the main game routine and free the game from any further gameplay

Suggested Screenshot

Special Thanks to:

  • Ilari for explaining Open Bus to me
  • Pat for not being able to chuck-glitch

Nach: Accepting as improvement to existing run.

Ilari: processing

Similar submissions (by title and categories where applicable):