Joka
He/Him
Player (5)
Joined: 3/19/2013
Posts: 42
Location: Sweden
Lord Tom wrote:
Also, was able to get a successful demo of the hopefully easier upper room realtime strat.
I tried everything in real time and got the following: http://imgur.com/lVtFnIR.jpg but it didn't work :( Do I need to get into the pipe first attempt or something?
Signature
Lord_Tom
He/Him
Expert player (3274)
Joined: 5/25/2007
Posts: 399
Location: New England
Jokaah wrote:
I tried everything in real time and got the following: http://imgur.com/lVtFnIR.jpg but it didn't work :( Do I need to get into the pipe first attempt or something?
Those memory addresses are correct, but there are others upstream that can also mess things up (though the strat was designed to minimize that). Unfortunately, I can't help just based on that screenshot, but if you pass along a movie file (.fm2 or bizhawk) I could take a look. Edit: Best of all would be to run the Lua script I posted just before you jump in the glitch area. If it says "Fail" something clearly identifiable is wrong.
Lord_Tom
He/Him
Expert player (3274)
Joined: 5/25/2007
Posts: 399
Location: New England
True wrote:
Console verifying shortly. Been sick as fuck and everything here is a mess. Edit: here is the result
That is amazing to see. Thank you!
Joined: 7/2/2007
Posts: 3960
So how does the glitch work, anyway? Are you just doing the walljump glitch (i.e. embedding yourself in a wall) and then somehow entering the pipe because you're "standing" on it? I thought you had to be standing near the middle of the pipe to be able to enter it though. I assume the reason you're able to enter it at all is because the game uses the same sprite object for pipe caps regardless of if they're on top or on bottom, and chooses the direction to send you in based on the direction you entered the pipe from.
Pyrel - an open-source rewrite of the Angband roguelike game in Python.
HHS
Active player (282)
Joined: 10/8/2006
Posts: 356
The X position and the tile you're standing on are used to determine if you can enter. To trigger the pipe glitch your X position & 15 must be equal to 11, and you must then be ejected 1 pixel to the right. The game will still think you're on the right side of the pipe, although you've been ejected into a different tile. If you are standing, you can then enter the pipe if you hold down on the same frame. This also works on the top side of the pipe, of course.
Tompa
Any
Editor, Expert player (2142)
Joined: 8/15/2005
Posts: 1934
Location: Mullsjö, Sweden
Producks and Mitchflowerpower have both been able to get some runs going with this now! Mitch has the record currently with a 4:47, starts here: http://www.twitch.tv/mitchflowerpower/b/512076453?t=2h34m42s
Lord_Tom
He/Him
Expert player (3274)
Joined: 5/25/2007
Posts: 399
Location: New England
That's awesome. I updated the subtitles on the demo run to note that you need to kill the flying koopa in the top room while it's going upward, not downward. Thanks to Jokaah for helping figure that out.
Joka
He/Him
Player (5)
Joined: 3/19/2013
Posts: 42
Location: Sweden
Hey! I also got it a few times :) http://www.twitch.tv/jokaah/c/3911309 Thanks Lord Tom, for that "easy" setup!
Signature
Joined: 12/29/2007
Posts: 489
How much frame/pixel perfection is required for the real time setup?
Lord_Tom
He/Him
Expert player (3274)
Joined: 5/25/2007
Posts: 399
Location: New England
For the upper-room strat, there's about a 4-frame window to kill the flying koopa. For the other koopa killed in that top room there's only a 2-frame window (shell needs to stop on the right single pixel, but turtles only walk every other frame). For the other realtime strat that doesn't use the upper room there are 2, 2-frame windows to hit, so about twice as hard.
Editor, Expert player (2315)
Joined: 5/15/2007
Posts: 3856
Location: Germany
But going to the upper room and doing shenanigans there looked really slow in comparison.. 2 2F windows doesn't sound too bad.
Lord_Tom
He/Him
Expert player (3274)
Joined: 5/25/2007
Posts: 399
Location: New England
Agreed, there are much faster strats available if you're willing to tolerate lower completion %. The upper room strat focused on just proving the glitch could be done on console by a human.
Joined: 12/29/2007
Posts: 489
How does the whole thing work anyway? Is it similar to SML2 where RAM gets displayed on screen and can be manipulated?
Lord_Tom
He/Him
Expert player (3274)
Joined: 5/25/2007
Posts: 399
Location: New England
HHS understands the details best, I think, but I'll try. Basically it's similar to in SMW -- the game ends up trying to read game data (enemy & Mario locations, etc) as programming instructions. Normally, this would induce random/useless behavior -- like if you tried to figure out how to fix your car by reading a phone book. But by manipulating pieces of the data you know the game is going to try to translate into instructions, you can essentially write your own little program that tells it to skip to the ending. In this case, we're really just trying to get it run 1 command: JSR $e38f (Jump to a subroutine at address $e38f, corresponding to the ending credits) So the challenge is how to manipulate things you can affect by playing the game (enemies, Mario) to generate that command and have the game run it. Well, the command above in digital form consists of 3 bytes; in hex: 0x20, 0xe3, 0x8f. In decimal the three values are 32, 227 and 143. So amidst whatever happens when the game goes haywire, if it ends up trying to read an instruction out of those 3 bytes (in order), it'll jump to the ending credits.
Joined: 12/29/2007
Posts: 489
So could this somehow, in theory, lead to arbitrary code execution? I was under the impression that executing RAM as code required corrupting the program counter - in this case, to make it read sprite locations as code in the first place. In a game like SMW, that was done by generating a glitch sprite whose behavior caused the PC to jump to a nonexistent routine. What causes the jump here?
Lord_Tom
He/Him
Expert player (3274)
Joined: 5/25/2007
Posts: 399
Location: New England
Having it jump to the credits *IS* arbitrary code execution. But if you mean can this be used to introduce significant new programming as was done with SMW playing Pong, I don't know for sure but I imagine it's possible. I don't know if this is how it was done with SMW, but if you were able to set up a loop that repeatedly executes the bytes corresponding to the controller states, you could presumably use controller inputs to write whatever program you want, byte by byte, somewhere in memory and then jump to it.
HHS
Active player (282)
Joined: 10/8/2006
Posts: 356
Zowayix wrote:
What causes the jump here?
When going outside the valid coordinates, it will start interpreting ROM bytes as tiles. In this glitch, we interact with a note block, and the game wants to replace it with a blank tile. But, by writing to the ROM area, we program a MMC3 register instead, and the PRG-ROM layout changes, so that wrong code gets executed, and it ends up doing a RTS with S=FF, taking the bytes $80 and $00 from $0100, thus returning to $0081.
Skilled player (1707)
Joined: 9/17/2009
Posts: 4952
Location: ̶C̶a̶n̶a̶d̶a̶ "Kanatah"
HHS wrote:
Zowayix wrote:
What causes the jump here?
When going outside the valid coordinates, it will start interpreting ROM bytes as tiles. In this glitch, we interact with a note block, and the game wants to replace it with a blank tile. But, by writing to the ROM area, we program a MMC3 register instead, and the PRG-ROM layout changes, so that wrong code gets executed, and it ends up doing a RTS with S=FF, taking the bytes $80 and $00 from $0100, thus returning to $0081.
How manipulable is this? Is it possible to make the game run input as code like in the SMW TAS?
Joined: 12/29/2007
Posts: 489
HHS wrote:
Zowayix wrote:
What causes the jump here?
When going outside the valid coordinates, it will start interpreting ROM bytes as tiles. In this glitch, we interact with a note block, and the game wants to replace it with a blank tile. But, by writing to the ROM area, we program a MMC3 register instead, and the PRG-ROM layout changes, so that wrong code gets executed, and it ends up doing a RTS with S=FF, taking the bytes $80 and $00 from $0100, thus returning to $0081.
So it's the note block that starts everything; that's what I was curious about. Thanks!
Lord_Tom
He/Him
Expert player (3274)
Joined: 5/25/2007
Posts: 399
Location: New England
I've been brainstorming ways one might use the 7-1 glitch to obtain robust control of the game, similar to the SMW Pong example. I looked for a case where I could over-write a function pointer as was done in the recent Super Metroid, but it doesn't seem possible -- jumps are always defined in ROM (unmodifiable) or in the few indirect cases that jump based on RAM the target address is set immediately prior to the jump (no chance to modify). Another technique which seems promising is writing a false location directly at the base of the stack ($01FE). The false location would point to a small program in memory which would perform some logic then JMP back to the originally intended location. This works to misdirect execution once, but the stack data gets overwritten after the JMP back to the main game loop. What I'm working on now will probably work but be very tedious to implement: repeatedly invoking the glitch in 7-1 and manipulating the sprites such that each time, another byte is added to a "staging program" in some unused spot of RAM, and a JSR command is executed that pops Mario back to 7-1 (e.g. JSR $9100 aka 20 00 91). On the final iteration, execution would be jumped to the staging program, whose function is to loop each frame and write a "total control" program, one byte per frame, using controller input. This "total control" program would simulate the logic of the main game loop, but with logic (triggered by controller-2 input) to rewrite a "custom" section whenever desired. I've written a working prototype of a "staging" program. Since each byte in this program requires invoking the 7-1 glitch, this needs to be very short:
Start:
STY $20   -- save y register
JSR GraphicsBuf_Prep_And_WaitVSync  -- timing 1 iteration/frame
JSR Read_Joypads -- read the controllers
LDY $20 -- restore y register value
INY -- advance to next byte location
LDA $f7 -- load controller-1 input
STA,y $1111 -- store this byte (location arbitrary; maybe bonus-game ram would be good) 
BEQ 03 -- stop looping if controller input=0
JMP Start -- loop
JSR $1111 -- jump to "total control" program
I've acquired a basic working knowledge of 6502 assembly looking at Metroid and SMB3 code the past couple years, but if anyone has ideas/advice on a better way to do this I'd be very grateful. I've got a lot of ideas for what to do with this sort of "invokable rewrite" capability in a playaround TAS. EDIT: BTW, Tompa & I are almost done with that any % TAS using the glitch, there's one minor technical hurdle holding us back a bit.
HHS
Active player (282)
Joined: 10/8/2006
Posts: 356
I think you don't need to call ReadJoypads, as it's called automatically during NMI. The X register is then free. The extraneous jumps are unnecessary. Thus, you get:
loop:
jsr $96e5
inx
lda $f7
sta program - initialX - 1, x
bne loop
program:
It would be beneficial to find a spot where a suitable BNE instruction already exists, so you don't need to enter it. Another possibility:
lda $f7
ldx $f8
sta somewhere, x
jsr $897b
Lord_Tom
He/Him
Expert player (3274)
Joined: 5/25/2007
Posts: 399
Location: New England
Thanks for those suggestions! I couldn't get your first example working as is, not sure why. You're right that the NMI reads the joypads. I found the NMI also updates the $15 counter, saving the need to waste byte(s) incrementing. This version works and is 12 bytes long, though one byte is a 00 so only 11 glitch activations would be needed. Appropriate placement of the final program bytes requires the correct starting value of $15.
Loop:
JSR $96E5 -- NMI
LDX $15 -- load counter into X
LDA $F7 -- controller one into accumulator
STA,X $0100 -- store byte at next location
BNE Loop -- loop if controller used
Program:
Your second suggestion is intriguing for implementing the staging program:
LDA $15
STA $01xx
JSR $897b
That's only 8 bytes so would be doable using a combination of the x and y sprite locations. It may end up preferable to use the $15 counter to define each byte here since not all values 0-255 are actually available via the controller (up + down and left + right are not recognized, independent of emulator settings). I don't think that limitation would be a show-stopper for writing the final program since there's a lot more flexibility with length there. Edit: Got a 9-byte version working, short enough that it should be possible to implement with a single invocation of the 7-1 glitch!
JSR $96e5   -- NMI
LDA $F7      -- load controller 1
STA ($15,y) -- store to zero-page, using $15 counter to advance to next byte
                  -- y never changes 
BNE loop:    -- loop while controller1 input non-zero
Tompa
Any
Editor, Expert player (2142)
Joined: 8/15/2005
Posts: 1934
Location: Mullsjö, Sweden
Felt like giving an update here. Tom and I have been working on the 100% run with steady progress for awhile. We are currently at 4-4. I'm not sure we plan to show and public WIPs or not until it's done, we'll see. We also plan to improve the Warpless run that is up on the site. So far I have made it up to the first Castle. Being 2* frames ahead of Glitchman's WIP. Will be another 30 because the Fire Flower has already been obtained, which also made 1-5 slightly slower. This WIP I feel like I can show at least: http://dehacked.2y.net/microstorage.php/info/768374296/SMB3%20Warpless.fm2
Experienced player (761)
Joined: 12/20/2009
Posts: 120
Good job. Keep it up:D
Skilled player (1707)
Joined: 9/17/2009
Posts: 4952
Location: ̶C̶a̶n̶a̶d̶a̶ "Kanatah"
I've been thinking about it so I'll ask here.
While the main focus is to complete Super Mario Bros. 3 as fast as possible
Can the multi-run TAS be improved by using the modified ACE route for real time runs? Or would the input needed screw over the other games progress?