Advertisement
SethBling

SMW "Kill Bowser" RLX Route Technical Explanation

Feb 11th, 2018
2,183
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.92 KB | None | 0 0
  1. SMW "Kill Bowser" RLX Route Technical Explanation
  2. by SethBling
  3.  
  4. This is a technical explanation of how the arbitrary code execution works in the "Kill Bowser" RLX Route.
  5. SNES instruction set: https://wiki.superfamicom.org/65816-reference
  6. SMW Ram map: http://www.smwcentral.net/?p=map&type=ram
  7.  
  8. Performing the item swap with the chargin' chuck causes Yoshi to eat the chuck, which is normally disallowed. As a result, an out-of-bounds function table lookup causes processor execution to jump to $014A13. This is in a region of the address space called open bus, which is not mapped to any device, so all reads will just return the contents of MDR (memory data register), which will contain whatever memory value was last written/read.
  9.  
  10. Since the data bank of the JMP to $014A13 was the last byte read, the MDR contains $01, so the instruction is ORA ($01,x). The x register is determined by the sprite slot of the chargin' chuck that's being eaten, which is 9. So the indirect lookup uses the address at $01+9=$0A. $0A was most recently set as the high byte of Yoshi's x-coordinate and $0B as the high byte of his y-coordinate. In this case, $0A=$0107. So the instruction will OR the "a" register with the contents of memory address $0107. This RAM address contains $17. OR a with $17. Now the MDR contains $17.
  11.  
  12. The next instruction is ORA [$17],y. Direct page addresses $17 and $18 are controller registers for axlr----, $17 is the current frame, and $18 is for first-frame presses. By holding down RLX, $17 is $70, and $18 is $00, because none of the presses are first-frame. $19 is $00 because Mario has no powerup. Because y contains $74, the instruction ORs a with the contents of $000070+74=$0000E4. $E4 is the low byte of the x-coordinate for sprite slot 0, which was the shell on the ground at the beginning of the level. It was left at a position for a value of $FC, so the MDR is now $FC.
  13.  
  14. The next instruction looks like it should be JSR ($FCFC,x) (jump to subroutine). JSR interacts strangely with open bus:
  15. * First, the instruction is read as $FC (JSR)
  16. * The low byte of the destination is also read as $FC
  17. * Then, the high byte of the return address is pushed to the stack ($4A)
  18. * Then, the low byte of the return address is pushed to the stack ($19). The MDR is now $19.
  19. * Finally, the high byte of the destination is read ($19)
  20. So the instruction is actually JSR ($19FC,x). x is still 9, so we JSR to the address contained at $1A05. $1A05 is in a part of memory responsible for keeping track of collected coins and used ?-boxes. $1A05 is always $00 in YI2, because there aren't any item boxes or coins in that part of the level. The Yoshi box is tracked by the $02 bit of $1A06, it becomes 1 when you hit it. By duping that Yoshi block to the right, we also set the $01 bit of $1A06, so that $1A06 becomes $03. That means we JSR to $0300, which is the middle of the OAM table. The return address $4A19 is pushed onto the stack, and will need to be cleared later to avoid returning back to open bus.
  21.  
  22. The OAM table is responsible for drawing tiles to the screen. Different entries of the OAM table are used for certain types of tiles. $0300 is used for drawing Yoshi swallowing an item, and also for Mario when he turns around while carrying an item. Since we turned around while holding a shell while running left, $0300 is set by the x coordinate of the turn-around animation, which was last seen as $80. $0301 is set by the y coordinate of the tile, which is set to $F0 (off-screen) after the animation is done. The next instruction is BRA $F0, which branches backwards $10 bytes (after moving forward 2 for executing the instruction). We land at $02F2.
  23.  
  24. $02F0-$02FF are used for white "splat" tiles whenever you kill or hit an enemy. $02F2 is $7C (the splat tile identifier), which is JMP (addr,x). $02F3 is $20 (the splat tile attributes). $02F4 is the x-coordinate of one of the splat tiles, whenever it was last seen, which is when we kicked the shell on the left side of the screen, and set to $18. So the instruction is JMP ($1820,x). x is still 9, so it's JMP ($1829), we'll end up at the address that's contained by $1829.
  25.  
  26. $1829 is inside the minor extended sprite y-velocity table. Some minor extended sprites, such as coins don't use this table. But Yoshi egg fragments do. $1829 is the top right fragment, and $182A is the bottom left fragment. We let the bottom left fragment despawn naturally for a value of $42. The top right fragment gets despawned early by our screen scroll at a y-velocity of $1A. The instruction ends up being JMP $421A.
  27.  
  28. $4218-$421F are the joypad auto-read registers. Each controller takes two bytes, the first byte being AXLR0000 and the second byte being BYETUDLR. $421A-B is port 2 controller 1, $421C-D is port 1 controller 2, and $421E-F is port 2 controller 2. These controllers have buttons held down for values $20 $E2 $00 $82 $A0 $98. These are interpreted as JSR $00E2; BRL $DAC0.
  29.  
  30. $E2 is within the sprite y-coordinate low byte table. The last two sprite slots are reserved for special sprites. In this case they both contain berry sprite y-coordinates. $E2 is $6A, which is the glitched berry that remained uneaten. This is ROR A. The accumlator is $FF, and the processor's carry flag is clear, so this sets the accumulator to $7F, and shifts the low bit into the carry flag, setting it. $E3 is the berry Yoshi ate while jumping. There are a few safe values, $42 being the easiest. $42 is a 2-byte no-op instruction, called WDM, which is set aside expansion of the instruction set. This consumes $E3 and $E4, which is necessary since it's not desirable to run the $FC instruction that was required in address $E4. Address $E4 onward is the sprite x-coordinate low byte table, which we filled with values by spitting out red shells at specific coordinates. $E5 contains the code ROR A; LDX #$31; STX $13BF; RTS. This second ROR A instruction shifts the carry bit into the high bit of the accumulator, and all other bits right, for a value of $BF. Then the X register gets the value $31, and that value gets stored to address $13BF, which is the translevel number. RTS returns control to the joypad auto read registers.
  31.  
  32. The next instruction branches into ROM, mid-subroutine, at address $01DAC0. After a few instructions, this subroutine writes the accumulator to $D8,x. Since x is $31, this writes $BF to address $0109. Then it pulls two values off the stack (the return address to open bus) and returns back to the sprite eating code, which resumes normal gameplay code.
  33.  
  34. Whenever the game tries to load the overworld map, it checks address $0109. If it's non-zero, it loads that level instead of going to the overworld. In this case, $BF indicates a mirror of the Bowser boss room.
  35.  
  36. When you kill a boss (including Bowser), the game checks the current translevel number at address $13BF to see which cutscene to play. Normally, the translevel number is set whenever you enter a level from the overworld. This address must contain $31 or $32 in order to trigger the credits.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement