New Possibilities
I've discovered further possibilities regarding the "new method for the game end glitch" I posted about the other day, so I'm summarizing them here.
In this movie, as a demonstration, Mario swims in YI2 in just 2412f=40.13sec (probably the fastest ACE ever! Since this TAS was made roughly for demonstration purposes, I think it could be shortened by several dozen frames further).
Technical Details
The same part as before
First, use yoshification to set Yoshi's $1594 (mouth routine pointer) in slot 8 to 6.
(For details, see the
previous post)
This causes the PC to jump to $01221d. Of course, this is inside open bus, and the first opcode is ora ($01,x).
Previously, setting the second opcode to bpl $10 and successfully landed on $01421d (controller registers).
This time, the strategy is based on finishing setup quickly, then automatically triggering yoshification a few seconds later to jump to the credits and potentially break the current record. Therefore, we cannot use the controller register. So what should we do?
Exploits the I/O registers at $4210 – $4217.
Resistor with unused bits
According to
this site, the following registers appear to have a bit that is open bus.
Unused bits (in Ports with less than 8 used bits)
Addr Mask Name Unused Bits
4016h FCh JOYA Bit7-2 are open bus
4017h E0h JOYB Bit7-5 are open bus
4210h 70h RDNMI Bit6-4 are open bus
4211h 7Fh TIMEUP Bit6-0 are open bus
4212h 3Eh HVBJOY Bit5-1 are open bus
Generally, open bus bits behave as open bus, while non-open bus bits return values corresponding to their role when read, but do not update the corresponding bit in the MDR. (If you don't think of it as fetching values through the bus, it might be obvious.)
Let's take $4016 as an example.
JOYSER0 - NES-style Joypad Access Port 1 Rd: ------ca Wr: -------l
a/b = These bits return the state of the Data1 line.
c/d = These bits return the state of the Data2 line.
Reading $4016 drives the Clock line of Controller Port 1 low.
The SNES then reads the Data1 and Data2 lines, and Clock is set
back to high. $4017 does the same for Port 2.
This time, we can focus solely on Rd, and since the controller is not being operated, both the c and a bits will return 1. - indicates an open bus.
Now, regarding the method for the current record holder masterjun's
game end glitch,
- F8 is SED, which just sets the decimal flag. As this doesn't change the Data Bus, this happens over and over until we reach $14016.
- Remember how I mentioned there are CPU registers prior to our target? As it turns out, this location is actually only partially Open Bus. By what can only be described as a miracle, the resulting instruction here is FB, which swaps the emulation and carry flag.
This was explained as such, but considering that f8 = 1111,1000,
fetching a value from $4016 while MDR = 1111,1000 yields 1111,1011 = fb, and executing xce explains the behavior.
Now, we'll apply the same theory to $4210 - $4217 this time.
$4016 JOYSER0 ----,--11
$4017 JOYSER1 ---1,1111
...
$4210 RDNMI n---,0010 //n = NMI flag
$4211 TIMEUP i---,---- //i = IRQ flag
$4212 HVBJOY vh--,---a //v,h = V, H-Blank flag, a = auto joypad mode flag
$4213 RDIO 1111,1111 //I'm not entirely sure about this, but it's probably fixed. I'd be very happy if I could change the value.
$4214 RDDIVL ??
$4215 RDDIVH ??
$4216 RDMPYL 00
$4217 RDMPYH 00
$4214, $4215 are the quotients of the division results, and can be altered to some extent by Mario walking diagonally on the map or Yoshi sticking out his tongue.
$4214 ... 68 c0 80 40 00 c0 80 40 00 c0 80 40 40 40 40 40 40 40 40 40 00
$4215 ... 00 00 01 02 03 03 04 05 06 06 07 08 07 06 05 04 03 02 01 00 00
When Mario completes the path from Yoshi's House → YI2 on the map, this register's value becomes 0068. When Yoshi extends his tongue, the value changes as described above. By performing eat-cancel, you can lock it to any desired value!
As a simple application, let's pass through here with MDR = 4d.
01400c eor $4d4d A:225d X:0008 Y:00d4 S:01eb D:0000 B:01 nvMXdizc V:03d H:0ab
01400f eor $4d4d A:2210 X:0008 Y:00d4 S:01eb D:0000 B:01 nvMXdizc V:03d H:0b5
014012 eor $4d4d A:225d X:0008 Y:00d4 S:01eb D:0000 B:01 nvMXdizc V:03d H:0c0
014015 eor $5f4f A:2210 X:0008 Y:00d4 S:01eb D:0000 B:01 nvMXdizc V:03d H:0ca //Since $5f4f is inside open bus, the fetched value remains 4d.
014018 eor $4d4d A:225d X:0008 Y:00d4 S:01eb D:0000 B:01 nvMXdizc V:03d H:0d5
01401b eor $4d4d A:2210 X:0008 Y:00d4 S:01eb D:0000 B:01 nvMXdizc V:03d H:0df
01401e eor $4d4d A:225d X:0008 Y:00d4 S:01eb D:0000 B:01 nvMXdizc V:03d H:0ea
014021 eor $4d4d A:2210 X:0008 Y:00d4 S:01eb D:0000 B:01 nvMXdizc V:03d H:0f4
014024 eor $4d4d A:225d X:0008 Y:00d4 S:01eb D:0000 B:01 nvMXdizc V:03d H:0ff
...
//MDR = 4d = 0100,1101
//$4016 = ----,--11 -> 0100,1111 = 4f
//$4017 = ---1,1111 -> 0101,1111 = 5f
014207 eor $4d4d A:2210 X:0008 Y:00d4 S:01eb D:0000 B:01 nvMXdizc V:042 H:118
01420a eor $4d4d A:225d X:0008 Y:00d4 S:01eb D:0000 B:01 nvMXdizc V:042 H:11e
01420d eor $4d4d A:2210 X:0008 Y:00d4 S:01eb D:0000 B:01 nvMXdizc V:042 H:124
014210 wdm $4d A:225d X:0008 Y:00d4 S:01eb D:0000 B:01 nvMXdizc V:042 H:12a
//MDR = 4d = 0100,1101
//$4210 = n---,0010 -> 0100,0010 = 42 [wdm $??]
//$4211 = i---,---- -> 0100,1101 = 4d
//$4212 = vh--,---a -> 0100,1100 = 4c [jmp $????]
//$4213 = ff
//$4214 = 68
//$4215 = 00 //Since Yoshi didn't stick out his tongue, the values are as shown in the table above.
This causes...
014212 jmp $68ff A:225d X:0008 Y:00d4 S:01eb D:0000 B:01 nvMXdizc V:042 H:12d //H:12d, so currently H-blank !
0168ff eor $4d4d 014d4d A:225d X:0008 Y:00d4 S:01eb D:0000 B:01 nvMXdizc V:042 H:131
016902 eor $4d4d 014d4d A:2210 X:0008 Y:00d4 S:01eb D:0000 B:01 nvMXdizc V:042 H:139
016905 eor $4d4d 014d4d A:225d X:0008 Y:00d4 S:01eb D:0000 B:01 nvMXdizc V:042 H:140
016908 eor $4d4d 014d4d A:2210 X:0008 Y:00d4 S:01eb D:0000 B:01 nvMXdizc V:042 H:147
01690b eor $4d4d 014d4d A:225d X:0008 Y:00d4 S:01eb D:0000 B:01 nvMXdizc V:042 H:14e
01690e eor $4d4d 014d4d A:2210 X:0008 Y:00d4 S:01eb D:0000 B:01 nvMXdizc V:043 H:002
016911 eor $4d4d 014d4d A:225d X:0008 Y:00d4 S:01eb D:0000 B:01 nvMXdizc V:043 H:009
016914 eor $4d4d 014d4d A:2210 X:0008 Y:00d4 S:01eb D:0000 B:01 nvMXdizc V:043 H:011
016917 eor $4d4d 014d4d A:225d X:0008 Y:00d4 S:01eb D:0000 B:01 nvMXdizc V:043 H:018
...
017fee eor $4d4d 014d4d A:2210 X:0008 Y:00d4 S:01eb D:0000 B:01 nvMXdizc V:06f H:04e
017ff1 eor $4d4d 014d4d A:225d X:0008 Y:00d4 S:01eb D:0000 B:01 nvMXdizc V:06f H:055
017ff4 eor $4d4d 014d4d A:2210 X:0008 Y:00d4 S:01eb D:0000 B:01 nvMXdizc V:06f H:05d
017ff7 eor $4d4d 014d4d A:225d X:0008 Y:00d4 S:01eb D:0000 B:01 nvMXdizc V:06f H:064
017ffa eor $4d4d 014d4d A:2210 X:0008 Y:00d4 S:01eb D:0000 B:01 nvMXdizc V:06f H:06c
017ffd eor $4d4d 014d4d A:225d X:0008 Y:00d4 S:01eb D:0000 B:01 nvMXdizc V:06f H:073
018000 bra $8042 [018042] A:2210 X:0008 Y:00d4 S:01eb D:0000 B:01 nvMXdizc V:06f H:07b
018042 phb A:2210 X:0008 Y:00d4 S:01eb D:0000 B:01 nvMXdizc V:06f H:080
018043 phk A:2210 X:0008 Y:00d4 S:01ea D:0000 B:01 nvMXdizc V:06f H:086
018044 plb A:2210 X:0008 Y:00d4 S:01e9 D:0000 B:01 nvMXdizc V:06f H:095
018045 jsr $9cf3 019cf3 A:2210 X:0008 Y:00d4 S:01ea D:0000 B:01 nvMXdizc V:06f H:09c
019cf3 ldy #$00 A:2210 X:0008 Y:00d4 S:01e8 D:0000 B:01 nvMXdizc V:06f H:0a8
019cf5 sta $05 [000005] A:2210 X:0008 Y:0000 S:01e8 D:0000 B:01 nvMXdiZc V:06f H:0ac
019cf7 sty $0f 00000f A:2210 X:0008 Y:0000 S:01e8 D:0000 B:01 nvMXdiZc V:06f H:0b2
019cf9 jsr $a365 01a365 A:2210 X:0008 Y:0000 S:01e8 D:0000 B:01 nvMXdiZc V:06f H:0b8
...
01b843 rts A:0170 X:0008 Y:00e4 S:01e6 D:0000 B:01 nvMXdizc V:077 H:153
019d5e rts A:0170 X:0008 Y:00e4 S:01e8 D:0000 B:01 nvMXdizc V:078 H:009
018048 plb A:0170 X:0008 Y:00e4 S:01ea D:0000 B:01 nvMXdizc V:078 H:014
018049 rtl A:0170 X:0008 Y:00e4 S:01eb D:0000 B:01 nvMXdizc V:078 H:01b
afeedf cmp $de00,x 01de08 A:0170 X:0008 Y:00e4 S:01ee D:0000 B:01 nvMXdizc V:078 H:026
afeee2 sbc $00ffff,x[010007] A:0170 X:0008 Y:00e4 S:01ee D:0000 B:01 NvMXdizc V:078 H:02e
afeee6 brk #$00 A:01a1 X:0008 Y:00e4 S:01ee D:0000 B:01 NVMXdizc V:078 H:038
00ffff brl $0172 [000172] A:01a1 X:0008 Y:00e4 S:01ea D:0000 B:01 NVMXdIzc V:078 H:048
000172 bvc $01b1 0001b1 A:01a1 X:0008 Y:00e4 S:01ea D:0000 B:01 NVMXdIzc V:078 H:04f
000174 bvc $01b3 0001b3 A:01a1 X:0008 Y:00e4 S:01ea D:0000 B:01 NVMXdIzc V:078 H:053
000176 bvc $01b5 0001b5 A:01a1 X:0008 Y:00e4 S:01ea D:0000 B:01 NVMXdIzc V:078 H:057
000178 bvc $01b7 0001b7 A:01a1 X:0008 Y:00e4 S:01ea D:0000 B:01 NVMXdIzc V:078 H:05b
...
0001b6 bvc $01f5 0001f5 A:01a1 X:0008 Y:00e4 S:01ea D:0000 B:01 NVMXdIzc V:078 H:0e1
0001b8 bvc $01f7 0001f7 A:01a1 X:0008 Y:00e4 S:01ea D:0000 B:01 NVMXdIzc V:078 H:0e5
0001ba bvs $01f9 0001f9 A:01a1 X:0008 Y:00e4 S:01ea D:0000 B:01 NVMXdIzc V:078 H:0e9
0001f9 stp A:01a1 X:0008 Y:00e4 S:01ea D:0000 B:01 NVMXdIzc V:078 H:0ef
This is how it works. You can see there are various possibilities. By executing jmp (4c, 5c, 6c, 7c) at $4211,12, you can jump to different locations. Furthermore, changing the value of x increases the possibilities even more...
Even just the USA version: 68ff, 00ff, 40ff, 80ff, c0ff, 0535, 0300, 1400, 1558, 1490, c8c8, fac8, 1d30, 571d, ffff, 3880, 0438, 1417, 1564, 1c90...
Even a rough check shows you can jump to more locations than this! And you can escape crashes just by one RTS!
Furthermore, jumping to 0300 allows you to jump to over 256 additional locations using the method employed in RTA.
This movie's trace log
This time, the trace log is as follows:
0086f7 jmp [$0000] 01221d A:221d X:0008 Y:00d4 S:01eb D:0000 B:01 NvMXdizc V:00d H:0a4
01221d ora (01,x) A:221d X:0008 Y:00d4 S:01eb D:0000 B:01 NvMXdizc V:00d H:0b0
01221f sta $85 A:229d X:0008 Y:00d4 S:01eb D:0000 B:01 NvMXdizc V:00d H:0ba //$85 = water level flag. If this isn't zero, we can swim in the level.
012221 sta $9d9d,x A:229d X:0008 Y:00d4 S:01eb D:0000 B:01 NvMXdizc V:00d H:0bf
012224 sta $9d9d,x A:229d X:0008 Y:00d4 S:01eb D:0000 B:01 NvMXdizc V:00d H:0c7
012227 sta $9d9d,x A:229d X:0008 Y:00d4 S:01eb D:0000 B:01 NvMXdizc V:00d H:0cf
...
012d01 sta $9d9d,x A:229d X:0008 Y:00d4 S:01eb D:0000 B:01 NvMXdizc V:023 H:14c
012d04 sta $9d9d,x A:229d X:0008 Y:00d4 S:01eb D:0000 B:01 NvMXdizc V:024 H:000
008374 sei A:229d X:0008 Y:00d4 S:01e7 D:0000 B:01 NvMXdIzc V:024 H:017
...(IRQ)
0083b9 rti A:229d X:0008 Y:00d4 S:01e7 D:0000 B:01 NvMXdIzc V:026 H:01c
012d07 ora (01,x) A:229d X:0008 Y:00d4 S:01eb D:0000 B:01 NvMXdizc V:026 H:029
012d09 sta $85 A:229d X:0008 Y:00d4 S:01eb D:0000 B:01 NvMXdizc V:026 H:033
012d0b sta $9d9d,x A:229d X:0008 Y:00d4 S:01eb D:0000 B:01 NvMXdizc V:026 H:038
...
//MDR = 9d = 1001,1101
//$4016 = ----,--11 -> 1001,1111 = 9f [sta $??????,x]
//$4017 = ---1,1111 -> 1001,1111 = 9f
014013 sta $9d9d,x A:229d X:0008 Y:00d4 S:01eb D:0000 B:01 NvMXdizc V:04d H:0b2
014016 sta $9d9f9f,x A:229d X:0008 Y:00d4 S:01eb D:0000 B:01 NvMXdizc V:04d H:0be
01401a sta $9d9d,x A:229d X:0008 Y:00d4 S:01eb D:0000 B:01 NvMXdizc V:04d H:0cc
01401d sta $9d9d,x A:229d X:0008 Y:00d4 S:01eb D:0000 B:01 NvMXdizc V:04d H:0d9
...
//MDR = 9d = 1001,1101
//$4210 = n---,0010 -> 0001,0010 = 12
//$4211 = i---,---- -> 0001,1101 = 1d
//$4212 = vh--,---a -> 0101,1100 = 5c [jml $??????]
//$4213 = ff
//$4214 = 80
//$4215 = 01 //Similarly, you can easily adjust it with Yoshi's tongue.
01420f sta $1d12,x A:229d X:0008 Y:00d4 S:01eb D:0000 B:01 NvMXdizc V:053 H:11b
014212 jml $0180ff A:229d X:0008 Y:00d4 S:01eb D:0000 B:01 NvMXdizc V:053 H:123 //here ,H-Blank is occurring. By adjusting the score, H-Blank can be easily adjusted through base conversion processing.
0180ff cli A:229d X:0008 Y:00d4 S:01eb D:0000 B:01 NvMXdizc V:053 H:129
018100 ora $f0,x 0000f8 A:229d X:0008 Y:00d4 S:01eb D:0000 B:01 NvMXdizc V:053 H:12d
018102 ora $de,s 0002c9 A:229d X:0008 Y:00d4 S:01eb D:0000 B:01 NvMXdizc V:053 H:134
018104 cli A:22fd X:0008 Y:00d4 S:01eb D:0000 B:01 NvMXdizc V:053 H:13c
018105 ora $bd,x 0000c5 A:22fd X:0008 Y:00d4 S:01eb D:0000 B:01 NvMXdizc V:053 H:13f
018107 stz $15 [000015] A:22fd X:0008 Y:00d4 S:01eb D:0000 B:01 NvMXdizc V:053 H:146
018109 beq $810e 01810e A:22fd X:0008 Y:00d4 S:01eb D:0000 B:01 NvMXdizc V:053 H:14c
01810b dec $1564,x 01156c A:22fd X:0008 Y:00d4 S:01eb D:0000 B:01 NvMXdizc V:053 H:150
01810e lda $1fe2,x 011fea A:22fd X:0008 Y:00d4 S:01eb D:0000 B:01 NvMXdizc V:054 H:009
018111 beq $8116 [018116] A:2203 X:0008 Y:00d4 S:01eb D:0000 B:01 nvMXdizc V:054 H:011
018113 dec $1fe2,x 011fea A:2203 X:0008 Y:00d4 S:01eb D:0000 B:01 nvMXdizc V:054 H:015
018116 lda $15ac,x 0115b4 A:2203 X:0008 Y:00d4 S:01eb D:0000 B:01 nvMXdizc V:054 H:022
018119 beq $811e 01811e A:2200 X:0008 Y:00d4 S:01eb D:0000 B:01 nvMXdiZc V:054 H:02a
01811e lda $163e,x [011646] A:2200 X:0008 Y:00d4 S:01eb D:0000 B:01 nvMXdiZc V:054 H:02f
018121 beq $8126 [018126] A:2200 X:0008 Y:00d4 S:01eb D:0000 B:01 nvMXdiZc V:054 H:037
018126 rts A:2200 X:0008 Y:00d4 S:01eb D:0000 B:01 nvMXdiZc V:054 H:03d //Successfully escaped the crash!
01eedf lda $1410 [011410] A:2200 X:0008 Y:00d4 S:01ed D:0000 B:01 nvMXdiZc V:054 H:047
01eee2 cmp #$02 A:2200 X:0008 Y:00d4 S:01ed D:0000 B:01 nvMXdiZc V:054 H:04f
01eee4 bcc $ef17 01ef17 A:2200 X:0008 Y:00d4 S:01ed D:0000 B:01 NvMXdizc V:054 H:053
The setup required for this TAS is:
- Preparing for Yoshification
- Adjusting the x-coordinate of the lowest slot
- Having Yoshi stick out his tongue slightly
- H-Blank adjustment (easily done by adjusting the score)
That's all. Since there's still time to adjust the coordinates of other slots, I hope we can break the game end glitch record...!
Other possibilities
- ($92) = 0100 is easy to adjust, so you can simply change the game mode by setting 92, or sta ($92), in the open bus.
In practice, I determined that it was theoretically possible to perform the following actions solely within the open bus, but the setup was too cumbersome to be practical.
ora (01,x)
cpx $e4
inc $e6
sbc $e5
sep #$e2
...
(IRQ)
ora (01,x)
cpx $e4
inc $e6
inc $e6
sbc [$e7]
cmp [$d7],y
sta $92 //$0100 = 26
rol $26
lda ($b2)
rts
- Couldn't we make good use of this glitch?
- If we could set the value of $4213 to 3f, we could easily jump to 00e6. But is it possible to connect peripherals and manipulate the value? I'd like someone knowledgeable about hardware to look into this.