kabaudio

Super Mario Bros. 3 Wrong Warp - technical details by KabAudio

Sep 11th, 2020 (edited)
9,238
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 173.10 KB | None | 0 0
  1. SMB3 Wrong Warp Detailed Explanation (For nerds)
  2.  
  3.  
  4. The SMB3 Wrong Warp is possible solely because of the blockchange routine, trying to turn the "noteblock" (which is invisible) into a background tile, and place a bouncing sprite version in its place. This in turn causes the MMC3 bank switcher to mess up, and as explained below, eventually execution reaches ram at address $81. We set a few enemies into pixel perfect positions to create one line of code, and then this line is (usually) executed at $93. This line of code tells the game to run the ending credits.
  5.  
  6. For quite some time the pipe glitch in 7-1 was known, and it was also known that you could easily crash the game once you enter the out of bounds area.
  7. In 2014, RAT926 was playing around with the pipe glitch (without actually setting any enemy positions intentionally) and eventually had a crash that landed him in world 8.
  8. HHS then explained what was happening, and how RAM was eventually being executed. It was theorised that Arbitrary Code Execution should then be possible by placing enemies in certain positions.
  9. Shortly after, Lord Tom had a TAS Proof-Of-Concept showing that a Warp from 7-1 to the ending credits was indeed possible.
  10. The following link is the forum discussion from when the wrong warp was first found.
  11. http://tasvideos.org/forum/viewtopic.php?p=368799#368799
  12.  
  13. From there, eventually RTA methods were discovered and refined. Producks was responsible for coming up with almost all of the RTA methods currently used, and spent a LOT of time on them. So hats off to him.
  14. The first method used fire flower, and involved climbing right to the top of 7-1, and fire killing 2 Koopa's frame perfectly, then killing one more Koopa on a ? block.
  15. This was then improved to use the tail, and the RTA record continued to fall….
  16. Most setups using the tail can be seen on the leaderboards at https://www.speedrun.com/smb3#Any
  17.  
  18. So how is the Wrong Warp possible?
  19.  
  20. Firstly, enemies are manipulated within 7-1 to move certain Koopa’s into the correct object slots. They are then either killed or despawned at pixel-perfect x positions.
  21.  
  22. Once this is completed, the “Pipe glitch” is performed. That is, we clip into the side of a pipe exit tile, and hold DOWN. This sends mario down until another pipe exit tile is found.
  23. Eventually, we end up out of the level bounds, with all sorts of garbage tiles around us. This is because the game ended up loading ROM, then part of the stack, then more of the ROM, as level data. Within this level data, one of the bytes that was read was the same Hex value as a pipe exit tile, so Mario is spat out.
  24. Lucky for us, right next to us on the right is an invisible note block. The game has a few different note block tiles, this one in particular is the one that is invisible until hit, with tile value $03. This tile is most well known in 7-2, when you have to make a bridge out of them to clear the wide gap.
  25.  
  26. This invisible note block is at mario’s head height (unless you are small mario), so to get under it, he must duck. Once underneath it, if the JUMP button is pressed, the note block will be bounced.
  27. To animate the bouncing effect, the background tile must be replaced with a sprite version, since background tiles cannot be moved individually in pixel increments.
  28.  
  29. Within the main game loop, there is a routine that updates any tiles that need to be replaced.
  30. After the note block is hit, this BlockChange routine tries to update what would normally be a ram address containing the level block data (somewhere in between $6000 - $794F), as SRAM is between $6000 - $7FFF.
  31. HOWEVER, because the invisible noteblock is out of bounds, it tries to change what it currently thinks is the address for this tile which it interprets as $9C70.
  32. It writes the value #$80 (empty background tile) to $9C70, or at least attempts to, because $9C70 is ROM. Normally writes to rom don't do much, however, because SMB3 uses ROM bank mapping (MMC3), writes to rom addresses have special functions as used by the mapper.
  33. Normally, SMB3 only changes ROM banks at $A000 and $C000, with PRG 30 permanently loaded into $8000 and PRG 31 permanently loaded into $E000.
  34.  
  35. At the moment the invisible noteblock change event happens, we were originally in the main game loop which runs between $8DD8 and $9006, and had entered subroutine "ChangeBlock_Do" by setting up a bank swap: (From Southbird's Disassembly)
  36.  
  37. PRG030: (Within Main Game Loop)
  38.  
  39.  
  40. $8F42 LDA #29 ; Load page 29 @ C000 (Page 29 contains the subroutine “BlockChange_Do")
  41. $8F44 STA PAGE_C000
  42. $8F47 JSR PRGROM_Change_C000 ;Run subroutine to actually change the $C000 bank
  43. $8F4A JSR BlockChange_Do ; Jump to subroutine, Do Block Change event, if necessary
  44.  
  45. ---within this subroutine, the important part is here: ——
  46. PRG 29:
  47. TileChange_OneTile:
  48. $DD11 LDX Level_ChgTileEvent = #$02
  49. $DD14 DEX
  50. $DD15 LDY Temp_Var5 = #$0F ;row/column offset value
  51. $DD17 LDA $DCB7,X @ $DCB8 = #$80 ; LDA OneTile_ChangeToTile,X (note block changes to empty block, which is #$80)
  52. $DD1A STA ($63), Y @ 9C70 = #$80 ; STA [MAP_Tile_AddrL],Y (Store new tile to this tile address. This is where it interprets the tile address as $9C70, and writes #$80 to it)
  53.  
  54. Immediately before the attempted write of #$80 to $9C70 within the BlockChange_Do subroutine, the MMC3 mapper has PRG 7 loaded in at $A000, and PRG 29 loaded in at $C000.
  55. As normal, PRG 30 is at $8000 and PRG 31 at $E000.
  56.  
  57. In normal game execution, once the BlockChange_DO subroutine has finished, execution returns to the main game loop and continuos on normally. At this stage in the main game loop (in level), the stack is normally empty.
  58.  
  59. However, when Out of bounds in 7-1, this doesn’t happen.
  60. As soon as the write of #$80 to $9C70 happens within the BlockChange_Do subroutine, a number of things occur due to the MMC3 mapper interpreting the write to ROM as an MMC3 Command Update. Normally bank changes are done by writing to ROM addresses $8000 and $8001, with $8000 being the MMC3 “Command", and $8001 being the Page number for the MMC3 to swap in.
  61. The commands used for SMB3 are always set so that bank changing ONLY ever occurs at $A000 and $C000, and NEVER set so that bank swapping occurs at $8000 and $C000. This is because PRG 30 is always loaded into $8000.
  62.  
  63. #$80 is %10000000. To understand how this write to the MMC command causes the ensuring chaos and crash, we must first understand how the MMC command works.
  64.  
  65. From the disassembly:
  66.  
  67. "
  68. ; MMC3_COMMAND:
  69. ; Bits 0-2 - Command number:
  70. ; * 000 - Swap two 1 KB VROM banks at PPU $0000.
  71. ; * 001 - Swap two 1 KB VROM banks at PPU $0800.
  72. ; * 010 - Swap one 1 KB VROM bank at PPU $1000.
  73. ; * 011 - Swap one 1 KB VROM bank at PPU $1400.
  74. ; * 100 - Swap one 1 KB VROM bank at PPU $1800.
  75. ; * 101 - Swap one 1 KB VROM bank at PPU $1C00.
  76. ; * 110 - Swap PRG-ROM bank at either $8000 or $C000 based on bit 6.
  77. ; * 111 - Swap PRG-ROM bank at either $A000
  78. ;
  79. ; Bit 6 - If 0, enables swapping at $8000 and $A000, if 1, enables
  80. ; swapping at $C000 and $A000.
  81. ;
  82. ; NOTE: This is what SMB3 uses, so all MMC commands will have bit 6 SET
  83. ;
  84. ; Bit 7 - If 1, causes addresses for commands 0-5 to be the exclusive-or
  85. ; of the address stated and $1000.
  86.  
  87. ; Note that bit 6 is set on all of these consistently since SMB3 uses the PRG switch this way
  88. MMC3_2K_TO_PPU_0000 = %01000000 ; 0
  89. MMC3_2K_TO_PPU_0800 = %01000001 ; 1
  90. MMC3_1K_TO_PPU_1000 = %01000010 ; 2
  91. MMC3_1K_TO_PPU_1400 = %01000011 ; 3
  92. MMC3_1K_TO_PPU_1800 = %01000100 ; 4
  93. MMC3_1K_TO_PPU_1C00 = %01000101 ; 5
  94. MMC3_8K_TO_PRG_C000 = %01000110 ; 6
  95. MMC3_8K_TO_PRG_A000 = %01000111 ; 7
  96. MMC3_PPU_XOR_1000 = %10000000
  97.  
  98. Note that Bit 6 as used in SMB3, is always set as 1, as we always want bank swaps at $A000 and $C000.
  99.  
  100. From our value being written to the MMC3 command (well, it’s being written to $9C70 but has the same effect as far as MMC3 is concerned) , we effectively have a %10000000 command being executed to MMC3.
  101. From the above table, since bits 1,2 and 3 are 0, and bit 7 is 1, the actual MMC3 instruction is MMC3_2K_TO_PPU_1000 - I.e swap out 2kB of VROM at PPU address $1000.
  102. Also, since bit 6 was 0, it means enable bank swapping at $8000 and $A000.
  103.  
  104. THIS IS the KEY part in making this whole Wrong Warp possible!
  105. SMB3 is never EVER meant to have anything except PRG30 at $8000, but with this command, we have just told it to use bank swapping at $8000 and $C000, instead of the normal $A000 and $C000. We also told it to change 2x 1KB VROM banks at PPU address $1000, which probably explains why the next frame the video updates, it is very glitched out.
  106.  
  107. At the moment %10000000 is written to MMC3 command (Via the write to $9C70), the MMC3 immediately does a bank switch, changing $8000 to PRG 29, $A000 to PRG 7, $C000 to PRG 30 (meant to be in bank $8000!) and $E000 stays at PRG 31 .
  108. Since we are currently executing within $C000-$DFFF, at $DD1A, and it just changed mid execution to PRG30, we are now executing code from PRG30 at $DD1C, which is actually in the middle of the autoscroll routine normally at $9D1A:
  109. PRG 30:
  110.  
  111. $DD1C LSR
  112. $DD1D LSR
  113. $DD1E LSR
  114. $DD1F LSR
  115. $DD20 CLC
  116. $DD21 ADC #$20
  117. $DD23 STA Scroll_ToVRAMHi = $28 ; (messing up the screen, won’t be apparent until next frame)
  118. $DD26 LDA $23,X @ Scroll_ColumnL = #$72
  119. $DD28 AND #$30
  120. $DD2A ASL
  121. $DD2B ASL
  122. $DD2C STA Scroll_LastCol8 = #$C0 ; (Again, messing up screen, won’t be apparent until next frame)
  123. $DD2F LDA Vert_Scroll = #$9A
  124. $DD31 AND #$08
  125. $DD33 BEQ $DD3E
  126. $DD35 LDA Scroll_LastCol8 = #$C0
  127. $DD38 CLC
  128. $DD39 ADC #$20
  129. $DD3B STA Scroll_LastCol8 = #$E0 ; (Again, messing up screen, won’t be apparent until next frame)
  130. $DD3E RTS ———————————————————
  131.  
  132. When we hit an RTS (ReTurn from Subroutine), we look at the stack and the stack pointer, to work out our return address.
  133.  
  134. Before we do this, let’s have a look at the stack, and what it contains right at this moment:
  135.  
  136. On the NES, the stack is located at memory addresses $100 through to $1FF. This means that in theory, there can be 256 different values stored on the stack. The Stack Pointer (SP) is a single byte. This pointer basically tells the CPU the “position” of the stack - where to put the next value if a value is pushed to the stack.
  137. So, for example, the instruction PHA, we PusH the value of the Accumulator, to the address of the stack pointer.
  138. Similarly, from this, we also know which value to pull from the stack, because it will be one position further than the stack pointer i.e SP +1.
  139.  
  140. Right before the banks were swapped, the stack pointer (SP) value was $FD. None of the instructions executed up until $DD3E have changed the stack, so the SP is still $FD.
  141. The stack contents are as follows:
  142.  
  143. $0100: 80 00 XX XX XX XX XX XX XX XX XX XX XX XX XX XX
  144. $0110: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX
  145. $0120: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX
  146. $0130: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX
  147. $0140: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX
  148. $0150: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX
  149. $0160: 00 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX
  150. $0170: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX
  151. $0180: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX
  152. $0190: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX
  153. $01A0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX
  154. $01B0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX
  155. $01C0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX
  156. $01D0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX
  157. $01E0: XX XX XX XX XX 60 3A E7 86 60 3A 60 3A 48 6B 00
  158. $01F0: F3 45 15 99 C7 6A 81 D8 F3 D3 2F A3 84 DC 4C 8F
  159.  
  160. Note that the XX values are undefined, because on an actual console, the contents of ram at power on is not defined, and is quite variable.
  161. Some games clear out all ram on startup including the stack, however, SMB3 only initialises the Stack Pointer to $FF on startup. The values in the stack are never cleared, only overwritten as the stack is filled.
  162.  
  163. The first two values are being used as ram, since the developers knew (thought?) that the stack would never be this full.
  164.  
  165. Address $100 stores the value of Update Select: This changes which path of “Update routines” are executed within the NMI.… $20 = title screen, $40 = spade game, $80 = vertical levels, $A0 = 32 pixel partition, $C0 = Normal levels.
  166.  
  167. Address $101 stores the value of Raster Effect: This changes which path of raster effects are executed within the IRQ (MMC3 scanline interrupt) - $00 is standard status bar, $20 is title/ending, $40 is 32 pixel partition, $60 = spade bonus game, $80 is nothing (e.g. 2P versus,part of ending)
  168.  
  169. This is why in 7-1, since it’s a vertical level, and has standard status bar, memory at $0100 and $0101 hold the bytes $80 and $00 respectively.
  170.  
  171. At address $160, we have the debug flag. If set to $80, debug mode is enabled. If it’s anything but the value $80, $00 is written to it on the title screen start press. This is why it is $00 in the above table.
  172.  
  173. When the RTS instruction is executed at $DD3E, This tells us to jump to the address held at the stack pointer + 1. The SP is $FD. To pull values from the stack, we look at the address of the stack pointer + 1. Since this is an address, we will need to pull two bytes - The first byte is the least significant, and second byte is most significant.
  174. So we have $4C and $8F - which make up our return address of $8F4C +1 = $8F4D. The stack pointer is then incremented twice, to $FF. The stack is now empty.
  175.  
  176. So we effectively return to where we left off, which should be within the main game loop, as our return address was $8F4D.
  177.  
  178. If the banks hadn’t been messed up earlier, we would normally return here:
  179.  
  180. $8F4D LDA #$00 ; Load page 0 @ C000
  181. $8F4F STA PAGE_C000
  182. $8F52 JSR PRGROM_Change_C000 ; Change Rom bank at $C000
  183. $8F55 LDA Scroll_ToVRAMHi
  184. $8F58 BNE PRG030_8F80 ; If scroll updates need to be committed, jump to PRG030_8F80
  185. $8F5A LDA Scroll_ToVRAMHA
  186. $8F5D BNE PRG030_8F80 ; If scroll updates need to be committed, jump to PRG030_8F80
  187. $8F5F LDA Level_SkipStatusBarUpd
  188. $8F62 BNE PRG030_8F80 ; If requesting we skip the status bar updates for this frame, jump to PRG030_8F80
  189. $8F64 LDA <Graphics_Queue
  190. $8F66 BNE PRG030_8F80 ; If we have a video update to do, skip the status bar updates for this frame, jump to PRG030_8F80
  191.  
  192. etc etc, game loop continues normally.
  193.  
  194. HOWEVER, because of the bank swapping and MMC3 mode change, we no longer return to the main game loop, because bank 30 is no longer loaded into $8000. Instead, page 29 is loaded into $8000, so we end up within a subroutine for Drawing the player, called “Player_Draw”. Since this is a subroutine, we will eventually hit another RTS instruction..
  195. This “Player_Draw” subroutine is normally meant to start at $CE9F (but actually $8E9F,since this rom bank is now at $8000-9FFF)
  196. We end up landing in the middle of it at $8F4D, mid instruction, since this was our return address.
  197.  
  198. PRG 29:
  199.  
  200. $8F4D:05 02 ORA Temp_Var3 = #$11 ;We actually landed mid instruction, this should have been STA $205,X, but since we cut off the 9D, we are left with 05 02 (the address $0205) which turns into ORA $02. Funnily enough, if we had have returned one byte later at $8F4E, we would have the KIL opcode $02, and the CPU would be locked up, and the Wrong Warp would never be possible! Thankfully this wasn’t the case.
  201. $8F4F:C8 INY
  202. $8F50:B1 E1 LDA ($E1),Y @ $CC5D = #$4F
  203. $8F52:9D 09 02 STA $0209,X @ $020A = #$20
  204. $8F55:A5 EF LDA Player_FlipBits = #$00
  205. $8F57:29 C0 AND #$C0
  206. $8F59:05 00 ORA Temp_Var1 = #$84
  207. $8F5B:9D 02 02 STA $0202,X @ $0203 = #$D8 ;Code to do with storing player sprites
  208. $8F5E:9D 06 02 STA $0206,X @ $0207 = #$D8
  209. $8F61:9D 0A 02 STA $020A,X @ $020B = #$E0
  210. $8F64:9D 0E 02 STA $020E,X @ $020F = #$E0
  211. $8F67:9D 12 02 STA $0212,X @ $0213 = #$D8
  212. $8F6A:9D 16 02 STA $0216,X @ $0217 = #$E0
  213. (Many more instructions….)
  214. $90E8:AD 71 05 LDA Level_PipeMove = #$00
  215. $90EB:F0 4D BEQ $913A
  216. $913A:60 RTS ————————————————————
  217.  
  218. At the end of this routine, we have hit another RTS (ReTurn from Subroutine)
  219. This loads the values from the stack by pulling the last two values off the stack, and returning to this address +1. BUT as this point, because normally we would be within the normal game loop, the stack is empty. We try to pull the values anyways, so we wrap back around to the very top values of the stack at address $0100 and $0101.
  220. Because the stack is NEVER this full, the developers decided to use address $0100 as a “game mode”, where vertical levels are #$80 and horizontal levels are #$C0. So currently we have #$80 at address $0100 and #$00 at address $0101. The return address is thus worked out to be $0080 +1, which is $0081.
  221. This is now within RAM.
  222. We begin executing ram starting at address $0081.
  223.  
  224. Ram here is organised like this, when in a level:
  225.  
  226. $81 Objects_Var4 slot2
  227. $82 Objects_Var4 slot3
  228. $83 Objects_Var4 slot4
  229. $84 Pipe_PlayerX: .ds 1 ; Stores Player's X when they went into pipe (non-transit)
  230. $85 Pipe_PlayerY: .ds 1 ; Stores Player's Y when they went into pipe (non-transit, aligned to nearest 16, minus 1)
  231. $86 unused, always #$00
  232. $87 Player_YHi (Player Y high byte)
  233. $88 Objects_YHi Slot 0 (normal object, normally enemies etc)
  234. $89 Objects_YHi Slot 1 (normal object, normally enemies etc)
  235. $8A Objects_YHi Slot 2 (normal object, normally enemies etc)
  236. $8B Objects_YHi Slot 3 (normal object, normally enemies etc)
  237. $8C Objects_YHi Slot 4 (normal object, normally enemies etc)
  238. $8D Objects_YHi Slot 5 (Powerup object e.g. mushroom, leaf etc)
  239. $8E Objects_YHi Slot 6 (Bump block object 0 - used for creating the bumping animation when a block is hit, or a note block, etc.)
  240. $8F Objects_YHi Slot 7 (Bump block object 1)
  241. $90 Player_X (Player X position)
  242. $91 Objects_X Slot 0 (Normal object, normally enemies etc)
  243. $92 Objects_X Slot 1 (Normal object, normally enemies etc)
  244. $93 Objects_X Slot 2 (Normal object, normally enemies etc)
  245. $94 Objects_X Slot 3 (Normal object, normally enemies etc)
  246. $95 Objects_X Slot 4 (Normal object, normally enemies etc)
  247. $96 Objects_X Slot 5 (Powerup object e.g. mushroom, leaf etc)
  248. $97 Objects_X Slot 6 (Bump block object 0 - used for creating the bumping animation when a block is hit, or a note block, etc.)
  249. $98 Objects_X Slot 7 (Bump block object 1)
  250.  
  251. Note that within these ram values, a BRK instruction will be executed, as a few of these memory addresses hold #$00. This runs the MMC3 scanline interrupt code, which calls a bank swap. Since all the bank swaps within the native SMB3 code are set to use $A000 and $C000 as the swappable banks, once the PPU bank swap within the MMC3 scanline code is executed, our banks then return to their normal positions, with PRG 30 at $8000 and PRG 31 at $E000 permanently again. This is why once we get to $93 where we have our koopa x positions, it all works normally again.
  252.  
  253. When the doing the wrong warp, we organise our object x positions so that at $0093 we will have #$20, $0094 we will have #$E3, and $0095 will have #$8F.
  254.  
  255. Execution at $93 would be this
  256. $0093 JSR 8FE3 ; Jump to subroutine at address 8FE3, i.e, setup and run princess ending cutscene
  257.  
  258.  
  259. For Zikubi’s 3:02 Run, the Ram values were like this, and resulted in the following instructions:
  260.  
  261. $0081: BRK
  262. $0083: BRK
  263. $0085: CPY #$00
  264. $0087: ORA ($05), Y
  265. $0089: ORA ($05)
  266. $008B: ORA ($12)
  267. $008D: BRK
  268. $008F: BRK
  269. $0091: NOP ($74), X
  270. $0093: JSR $8FE3
  271.  
  272. It’s interesting to note, that before we execute JSR $8FE3 at $0093, the Stack Pointer is still $01. It has been $01 since we started executing ram at $0081. It stays this way until we hit our JSR $8FE3. This means jump to the subroutine at address $8FE3. When entering the subroutine, the address we just left is pushed onto the stack at address $0100 and $0101, and the stack pointer is decremented twice to $FF.
  273. We did overwrite the Update Select ($0100) and Raster Effect ($0101) values with $E3 and $8F respectively - however, the credits routine updates these values, since they need to be set to $20 and $80.
  274. Since the stack pointer is now at $FF, the Update Select ($0100) and Raster Effect ($0101) will not be overwritten unintentionally again. This is because when the game normally runs the credits (after beating bowser), it never actually uses a JSR instruction…While in levels, within the main game loop, it actually checks every frame whether we are exiting back to the map, and if we are, it then checks if we are doing the ending sequence (a simple flag in RAM is set at the end of the bowser fight)
  275. If this ending flag is set, it loads in the correct pages into $A000 and $C000, then jumps to the ending code at $B85A within PRG18.
  276.  
  277. Within main game loop:
  278.  
  279. $8FDE:AD 8D 07 LDA Player_RescuePrincess
  280. $8FE1:F0 19 BEQ $8FFC ; If Player_RescuePrincess = 0, Branch to $8FFC
  281. $8FE3:A9 19 LDA #$19 ; Load Page 25 into $C000
  282. $8FE5:8D 1F 07 STA PAGE_C000 = #$1D
  283. $8FE8:A9 18 LDA #$18 ; Load Page 24 into $A000
  284. $8FEA:8D 20 07 STA PAGE_A000 = #$07
  285. $8FED:20 BF FF JSR PRGROM_Change_Both2 ; Swap banks as above
  286. $8FF0:A9 A8 LDA #$A8
  287. $8FF2:85 FF STA PPU_CTL1_Copy = #$A8
  288. $8FF4:A9 20 LDA #$20 ; Change Update_Select to #$20 (Title screen/Ending setting)
  289. $8FF6:8D 00 01 STA Update_Select = #$95
  290. $8FF9:4C 5A B8 JMP $B85A ;Jump to Credits Routine at $B85A
  291. $B85A:A9 5C LDA #$5C
  292. $B85C:8D 19 07 STA PatTable_BankSel = #$58
  293. $B85F:A9 5E LDA #$5E
  294. $B861:8D 1A 07 STA $071A = #$64
  295. $B864:20 A9 FD JSR Reset_PPU_Clear_Nametables
  296.  
  297. So when we start executing our Credits Routine since we used a JSR, the stack pointer is now correctly back at $FF.
  298.  
  299. If we didn’t use a JSR instruction (JSR $8FE3), and instead used a JMP instruction, (i.e JMP $8FE3), the stack pointer would always be resting at $01, which means memory address $100 and $101 will be constantly overwritten as values are pushed and pulled from the stack. This has the effect of glitching out the credits, with graphical glitches on the upper left of the princess chamber, and the second half of the credits doesn’t come up at all. The music plays, but it never shows the worlds, nor “the end” screen.
  300.  
  301. A common question asked, is whether this Wrong Warp is possible on the SNES (All Stars) version.
  302. Unfortunately, it is impossible on the SMAS version on SNES, because the SMAS version no longer needs to use bank swapping - Since the SNES has a much larger address space than the NES, All the bank swapping was removed from the code since it was no longer needed. Without the MMC3 bank swapping, this particular glitch cannot be possible.
  303.  
  304. Some other quirks about the wrong warp:
  305. If doing the faster wrong warp setup, occasionally it will crash, even if you have the right values for $93, $94, and $95.
  306. This is because we are executing through ram, and with the faster wrong warp setup, we can have different values for the object 0 x position at address $0091.
  307. Objects are filled into ram in reverse order, so the first object loaded will be object 4, then 3, then 2, etc etc.
  308. When doing the harder wrong warp setups, the first koopa at the bottom is in slot 4, the plants in slot 3,2,1, and the koopa above the plants in slot 0. Because we use the koopa from the bottom to throw and kill the plants, it doesn’t despawn until we fly up high enough, so the walking koopa in slot 0 will be walking along and its x value will be changing constantly as you fly up. Which value it despawns on is dependant on how fast you fly up and jump past the note block. We want that koopa in slot $91 to despawn on a one or two byte opcode, as long as it’s not a RTI or RTS instruction. if you are unlucky, it can be either a KIL opcode which jams the processor, or an RTS instruction, which move execution to address $0000, which is almost always bad since you usually end up executing a KIL instruction somewhere between $0000 and $0081. A 3 byte opcode is also bad since it will eat up your JSR instruction at $0093.
  309.  
  310.  
  311. Values for ram address $91 commonly occurring in fast wrong warp setup, and their Opcodes:
  312. #$60 RTS ; 1 byte, bad, will pull more values off the stack, returning to address $0000, either endlessly looping between $0000 and $0091, or crashing because of a KIL opcode being executed.
  313. #$61 ADC ; 2 byte, zeropage indirect, indexed with x - okay
  314. #$62 KIL (Illegal opcode) ; Locks up the processor until it is reset - hence called KILL, cause it kills it for good! no further instructions can fix it, only a reset or power cycle
  315. #$63 RRA (Illegal opcode) ; 2 byte, zeropage indirect, indeed with x - okay
  316. #$64 NOP (Illegal opcode) ; 2 byte, No operation - okay
  317. #$65 ADC ; 2 byte, zero page - okay
  318. #$66 ROR ; 2 byte, zero page - okay
  319. #$67 RRA ; 2 byte, zero page - okay
  320. #$68 PLA ; 1 byte, okay, means next executed byte is $92, this value is the vertical moving plant, always at x position $88. Opcode for $88 is DEY, a single byte opcode, which means we will then execute at $0093, good.
  321. However, the PLA (Pull to Accumulator) instruction will increment the stack pointer by one, so this causes the cutscene to be glitchy at the top left, and the world part of the cutscene doesn't work, due to the IRQ mode which is stored at $0100 being overwritten by anything that uses the stack, since the stack pointer was decremented with the PLA instruction.
  322. #$69 ADC ; 2 byte, immediate - okay
  323. #$6A ROR ; 1 byte, okay, as explained before - okay
  324. #$6B ARR (Illegal opcode) ; 2 byte, immediate - okay
  325. #$6C JMP ; 3 byte, indirect, eats up your JSR interaction at $0093. Bad.
  326. #$6D ADC ; 3 byte, absolute, eats up your JSR interaction at $0093. Bad.
  327. #$6E ROR ; 3 byte, absolute, eats up your JSR interaction at $0093. Bad.
  328. #$6F RRA (Illegal Opcode) ; 3 byte, absolute, eats up your JSR interaction at $0093. Bad.
  329. #$70 BVS ; 2 byte, relative - okay
  330. #$71 ADC ; 2 byte, zeropage indirect, indexed with y - okay
  331. #$72 KIL ; Locks up processor as explained above
  332. #$73 RRA ; 2 byte, zeropage indirect, indexed with y - okay
  333. #$74 NOP ; 2 byte, zeropage, indexed with x - okay
  334. #$75 ADC ;2 byte, zeropage, indexed with x - okay
  335. #$76 ROR ;2 byte, zeropage, indexed with x - okay
  336.  
  337. $#76 was the highest value Zikubi achieved while practicing (about 1/10 goes), with $#74 much more common.
  338. given the koopa walks one pixel per frame, this means that Zikubi was frames away from getting a crash.
  339.  
  340. Reversing Pipe Glitch:
  341. Also, occasionally when playing the wrong warp on console, you get a glitch where the pipe that takes you down under the level, ends up spitting you back out up the top.
  342. I have seen this happen to 3 players -Kirua, Zikubi and Joshua69_yt. They were all on console. It only seems to happen after doing 7-1 attempts previously, and ONLY on console. This is because after a failed Wrong Warp attempt, usually the game will crash. Some crashes can actually overwrite most of the ram, and since the stack is in RAM, it can fill the stack with garbage values. It’s pretty rare, but it can happen.
  343.  
  344. When you take the pipe glitch, and the pipe takes you underneath the normal level bounds, at some point it actually reads part of the stack as it scrolls down, reading the tiles, looking for the pipe control tiles: theres the exit tiles, and also the corner bend tiles. Normally, the stack doesn’t contain any pipe control tiles within the section that is read by the pipe control routine. However, if a crash happens to fill the stack with certain hex values, the pipe logic can interpret these tiles as a pipe that turns around… and mario will end up coming back up into the level, eventually getting spat out when the pipe logic detects a pipe exit tile. Although this is hilarious to see happen, it was quite annoying to the runners who had it happen to them.
  345. The following link is a clip of this happening to Zikubi, while attempting the All Forts Wrong Warp. He was not impressed, given this was almost 40 minutes into a run!
  346.  
  347. https://www.twitch.tv/zikubi/clip/NaiveSmilingPelicanCoolStoryBob
  348.  
  349. A complete power off and on is the only thing that will fix it. This makes sense when you think about it, because in SMB3, the ram clear routines never clear the stack, even after a reset. Only the stack pointer is initialised to FF. So a power off and on WILL cause the stack to loose it's memory, and it fixes it. Most emulators, however, on reset/power on, initialise all ram to hold some sort of pattern… usually alternating 00 00 00 00 FF FF FF FF 00 00 00 00 FF FF FF FF, or sometimes all FF or all 00. So this particular glitch will never happen on an emulator in runs.
  350. Note that on a real console, to avoid this happening, it has to be powered off for a second or so, to allow the power supply capacitors to discharge, since the RAM chip will only loose its memory contents once its voltage is too low.
  351.  
  352. Music glitch:
  353.  
  354. Sometimes, when the Wrong Warp is performed, the princess chamber can be seen, but then the game crashes. This is actually because of the sound engine.
  355.  
  356. *Note first, that this is a very simplified explanation. In reality, the sound engine is very complex..*
  357.  
  358. When the credits code is being run, one of the first thing that happens is that all ram between $01 and $FF is cleared.
  359. Because the sound engine uses addresses $6B -> $73, and because the music is playing when the glitch is performed, this has some side effects.
  360. Note that the rest of the sound engine mostly uses addresses between $0461 - 04FF. Hence the rest of the sound engine ram is NOT cleared.
  361. The side effects of clearing $6B - 73 are dependant on where in the music track we currently are.
  362. To explain why, let’s have a look at the sound engine in SMB3.
  363.  
  364. The sound engine is contained within PRG 28. When executed near the end of the NMI code, PRG28 is loaded into bank $A000. Part of the sound engine’s code is also contained in PRG31, which is bank $E000-FFFF, i.e the one that never changes. This becomes important later.
  365.  
  366. Songs in SMB3 are made of segments. This is so that sections of songs that have repeating parts, can be stored more efficiently.
  367. For example, the song “Underground” may have 5 sections, A,B,C,D,E.
  368. The song may be arranged as such:
  369. A B C C D D E
  370. At the end of segment E, we go back to the start again and repeat.
  371.  
  372. The lookup address for the currently playing song’s notes is stored at ram address $6B and $6C.
  373.  
  374. Each segment is made up of notes and rests. Notes specify things like frequency, volume, etc. and Rests specify how long to play the note for, or how long to rest for.
  375. When a note or a rest plays, the rest value decrements down every frame, until it hits 0. When it hits 0, it loads the next note.
  376. This is the case for all the sound channels, i.e
  377.  
  378. Square 2
  379. Square 1
  380. Triangle
  381. Noise
  382. DMC
  383.  
  384. Note that the Rest is decremented before anything else is done, in each sound channel’s code.
  385.  
  386. Square 2 has a special case, in which if it loads in note $00, it signals to the music engine that we hit the end of the segment, and to either load the next segment, or to go back to the start of the song, depending on the current segment position, and if it hits the value stored at “end of segment”.
  387. However, when the Noise track or DMC track reads a $00 note, it sets the track position back to the starting value, then loads in the next note/rest from the lookup address. It then reads this note, and either plays it or rests.
  388. This is where things get interesting….
  389. When the rest counter for the noise track reaches 0, we then load the next note as per the lookup table. We find the lookup table by looking at the value at the address contained in $6B and $6C. We then index the table address with Y, to find our next note/rest. Because the RAM between $00 and $FF was cleared, $6B and $6C both hold #$00. So therefore, the address to look at is $0000 + Y. So we are looking at RAM between $0000 and $0100, i.e the ram we just cleared. So all these values are zero. We then load this value, which is $00. This value is then stored as the noise note. We then jump back into the noise channel’s code and read what is meant to be the new value. However, because the RAM was cleared, we read $00 again. So we reset the noise track position back to the start, then load in the next note as per the lookup table… again we read $00, so we jump back… and forth… and back:
  390.  
  391. The following is code that has been logged from a Wrong Warp attempt:
  392.  
  393. $E6C7:AC D1 04 LDY Music_NseTrkPos = #$AE ; Load Noise track position into Y register
  394. $E6CA:EE D1 04 INC Music_NseTrkPos = #$AE ; Increment Noise Track Position
  395. $E6CD:B1 6B LDA ($6B),Y @ $00AE = #$00 ; Load A with address contained within $6B and 6C, and then index with Y
  396. $E6CF:F0 2F BEQ $E700 ; If $00, branch to $E700
  397. $E700:AD F3 07 LDA Music_NseStart = #$AE ; Load A with Noise track starting position
  398. $E703:8D D1 04 STA Music_NseTrkPos = #$AF ; Store starting track position into Noise track position
  399. $E706:4C C7 E6 JMP $E6C7 ; Jump back to Noise track code…
  400. $E6C7:AC D1 04 LDY Music_NseTrkPos = #$AE ; Same as above, repeated indefinitely
  401. $E6CA:EE D1 04 INC Music_NseTrkPos = #$AE
  402. $E6CD:B1 6B LDA ($6B),Y @ $00AE = #$00
  403. $E6CF:F0 2F BEQ $E700
  404. $E700:AD F3 07 LDA Music_NseStart = #$AE
  405. $E703:8D D1 04 STA Music_NseTrkPos = #$AF
  406. $E706:4C C7 E6 JMP $E6C7
  407. $E6C7:AC D1 04 LDY Music_NseTrkPos = #$AE
  408. $E6CA:EE D1 04 INC Music_NseTrkPos = #$AE
  409. $E6CD:B1 6B LDA ($6B),Y @ $00AE = #$00
  410. $E6CF:F0 2F BEQ $E700
  411. $E700:AD F3 07 LDA Music_NseStart = #$AE
  412. $E703:8D D1 04 STA Music_NseTrkPos = #$AF
  413. $E706:4C C7 E6 JMP $E6C7
  414. $E6C7:AC D1 04 LDY Music_NseTrkPos = #$AE
  415.  
  416. Because we never finished running the noise channel’s code, we never ended up storing the new “Rest” value. it is still $00.
  417. So this back and forth loop goes on continuously, until we hit the next NMI.
  418. We run through the NMI and eventually run the Sound engine again (Even though the last NMI never finished)
  419. This time when we get to the noise track’s code, the rest value is decremented to $FF. Because the rest value hasn’t hit 0 yet, we skip the noise track’s code and do the DMC code. The same continuous loop problem can also happen to the DMC channel when it’s rest hits $00.
  420. If the DMC rest hasn’t hit 0 yet, then we finish the NMI, and end up back in our continuous loop, or we get stuck in a DMC loop, and are stuck here until the next NMI. If that happens, then again, when the sound engine is run, the Rest values will all be decremented. Since the DMC rest value is now $FF, we finish this NMI, and end up back in our continuous loop, either the DMC loop, or just the noise loop, depending on the music position when we executed the Wrong warp.
  421. This loop will just continue on and on, until another NMI. Now, since the noise and DMC channel’s rest values are fairly high ($FE and $FF), they won’t hit zero for at least $FE frames (254 frames). This is fortunate, because in the underground song, Square 2 track’s rest value is never higher than $48. Because of this, after a number of NMI’s (between $0 and $48), square 2’s rest will eventually hit $00. As previously stated, if square 2’s rest value hits $00, then the sound engine knows we hit the end of the music segment, and loads in the new one. When it loads in the new segment, it writes in the required values for our note lookup address to RAM.
  422. Once this is done, all the rest values are also set to $01, so they will update. Once the music engine is finished, we return to our continuous loop, now with the proper lookup tables loaded into RAM at $6B and $6C.
  423. Since the Noise channel and the DMC channel can now load in the actual note values instead of $00, we exit this loop.
  424. When we eventually hit an RTS instruction, we are meant to return to the main sound engine code, then hit another RTS, back to our NMI code.
  425. However, because another NMI occurred before the original NMI finished, the sound engine bank (PRG28) has been swapped out of bank $A000.
  426. So we end up executing code from PRG24 instead of PRG28.
  427.  
  428. The first line we execute is this:
  429. $A087:FE 93 95 INC $9593,X
  430.  
  431. This Increments the value stored in memory address $(9593 + X). The value of X depends on what the sound engine was doing previously, in the last NMI.
  432.  
  433. If we are unlucky, the memory address we attempt to increment will be an even number, This has the same effect as writing a value to MMC3 Page ($8001).
  434. For instance, if X is 0, then we will attempt to increment $9593. Since $9593 has value $C0, this is the same as writing $C1 to MMC3 Page ($8001). We only have pages 0-31, i.e, 32 pages total. If we tell the mapper to change to page 32, its the same as page 0. page 33 is the same as page 1. etc etc.
  435. Since this is $C1 mod $20, we end up with $01. So we load in PRG01.
  436. This changes the page at $A000 to PRG01, and we continue executing, now in a different bank.
  437.  
  438. $A08A:BE AD BE LDX $BEAD,Y @ $BEAE = #$38
  439. $A08D:AD BE AD LDA $ADBE = #$20
  440. $A090:A0 D3 LDY #$D3
  441. $A092:BC A2 A0 LDY $A0A2,X @ $A0DA = #$11
  442. $A095:D3 UNDEFINED ; Undefined are illegal opcodes, the debugger doesn’t know their mnemonics.
  443. $A097:D3 UNDEFINED
  444. $A099:A3 UNDEFINED
  445. $A09B:A4 A0 LDY $00A0 = #$00
  446. $A09D:D3 UNDEFINED
  447. etc etc until we get to
  448. ...
  449. $A0D2:D2 KIL
  450.  
  451. The byte $D2 is the KIL opcode. It locks up the CPU for good, and nothing else happens with the CPU until the reset button is pressed, or the game is powered off and back on.
  452.  
  453. However, If we are lucky, when executing at $A087, X will be $7F and we will attempt to increment $9612, for instance. This has the same effect as writing $61 to MMC3 command.
  454.  
  455. $61 = %01100001
  456.  
  457. From out earlier document, we can see that this tells the MMC3 to swap out two 1 KB VROM banks at PPU $0800. Since this does not affect the ROM banks, we continue executing in PRG24:
  458.  
  459. $A08A:91 91 STA ($91),Y @ Temp_Var9 = #$00
  460. $A08C:91 91 STA ($91),Y @ Temp_Var9 = #$00
  461. $A08E:91 91 STA ($91),Y @ Temp_Var9 = #$00
  462. $A090:91 91 STA ($91),Y @ Temp_Var9 = #$00
  463. $A092:91 91 STA ($91),Y @ Temp_Var9 = #$00
  464. $A094:91 91 STA ($91),Y @ Temp_Var9 = #$00
  465. $A096:91 91 STA ($91),Y @ Temp_Var9 = #$00
  466. $A098:91 91 STA ($91),Y @ Temp_Var9 = #$00
  467. $A09A:91 91 STA ($91),Y @ Temp_Var9 = #$00
  468. $A09C:91 91 STA ($91),Y @ Temp_Var9 = #$00
  469. $A09E:97 UNDEFINED
  470. $A0A0:16 16 ASL $16,X @ $0095 = #$00
  471. $A0A2:16 16 ASL $16,X @ $0095 = #$00
  472. $A0A4:16 16 ASL $16,X @ $0095 = #$00
  473. $A0A6:2C AD 18 BIT $18AD = #$00
  474. $A0A9:05 D0 ORA Objects_YVel = #$00
  475. $A0AB:6D AD 7A ADC $7AAD = #$00
  476. $A0AE:07 UNDEFINED
  477. $A0B0:5A UNDEFINED
  478. $A0B1:90 66 BCC $A119 ; Branch on Carry Clear - Carry was clear, so we branch
  479. $A119:60 RTS
  480.  
  481. Since we eventually hit an RTS instruction, we Finnish off the NMI we started ages ago (Since it’s in PRG31, it never leaves bank $E000-FFFF)
  482. If we were 2 levels deep (i.e we had a noise loop and a DMC loop), then we would exit the loop same as before, before returning to normal execution - the credits continue on normally.
  483.  
  484. Values that the X register can contain, depending on where in the music we triggered the Wrong Warp:
  485.  
  486. 00 = $9593 (holds C0) (Crash)
  487. 0A = $959D (holds 04) (crash)
  488. 48 = $95DB (holds 53) (Crash)
  489. 7F = $9612 (holds 60) (okay)
  490.  
  491. Note that since the values for the Noise channel (and maybe DMC channel) were modified, this results in strange “crash” sounds or other audio anomalies.
  492.  
  493. If we happen to trigger the credits warp when square 2 was playing a note (i.e the melody part of Underground is playing), then it’s rest value will hit $00 before any other channel - as explained before, this tells the sound engine to go to the next segment, which fixes up the music engine ram at $6B & 6C.
  494. So we never get stuck in the continuous loop, we have no risk of a crash, and we reach the credits earlier.
  495.  
  496. If square 2 is not playing a note, then it is resting. Depending on the rest value of the square 2 channel when we execute the credits warp, we may end up with a large rest value, and hence a long delay as it decrements this value every frame until it hits 0.
  497. This is why some credits warps are very slow - they were triggered with a higher square 2 rest value.
  498. The difference between optimal credits and slow credits warp is usually $47 frames, or in decimal, 71 frames. Although there is one part of the song that results in an additional $1A frames, for a worst case scenario of $47 + $1A = $61 frames = decimal 97 frames!!! in other words, over 1.5 seconds can be lost because of the music!
  499.  
  500. To help avoid a crash from the music engine, we can release the down button just before we hit A to trigger the glitch.
  501. This results in the “Jump” sound playing, instead of the “Bump” sound. This seems to affect the X register, usually having the value $7F. This means we won’t eventually crash and lock up the CPU.
  502.  
  503. Testing revealed that letting go of down just before triggering the credits warp, will save 99% of crashes caused by the sound engine.
  504.  
  505.  
  506. The developers always stopped the music before clearing the zero page RAM, so in normal game play, there’s no issues.
  507.  
  508. Note, this page may be updated as I spend more time on things like the sound engine explanation / pipe glitch mechanics etc.
  509.  
  510.  
  511.  
  512. -----Music Engine - EVEN MORE DETAILS! (Update)——
  513.  
  514.  
  515. Note that the following contains large execution dumps. It is mostly a more detailed version of the above, with more info as to why the jump sound stops most crashes.
  516.  
  517. Sound fx are played on Square 1, square 2, and noise.
  518. The bytes that control which sound fx play are as follows:
  519.  
  520. From Southbird’s disassembly:
  521. ; For any of these queues, the value is a bit value, which offers
  522. ; a simple prioritization system; lowest value plays over any other
  523.  
  524. Sound_QPlayer: Sound fx that uses square 1
  525.  
  526. SND_PLAYERJUMP = $01 ; Jump
  527. SND_PLAYERBUMP = $02 ; Bump
  528. SND_PLAYERSWIM = $04 ; Swim / Squish
  529. SND_PLAYERKICK = $08 ; Kick
  530. SND_PLAYERPIPE = $10 ; Pipe / shrink
  531. SND_PLAYERFIRE = $20 ; Fireball
  532. SND_PLAYERPOWER = $40 ; Full power ringing (must be constantly set or you don't hear it)
  533. SND_PLAYERFROG = $80 ; frog hop
  534.  
  535. Sound_QLevel1: Sound FX that uses square 2
  536.  
  537. SND_LEVELCOIN = $01 ; Coin
  538. SND_LEVELRISE = $02 ; Powerup rising from block
  539. SND_LEVELVINE = $04 ; Vine rising
  540. SND_LEVELBABOOM = $08 ; Cannon fire
  541. SND_LEVELBLIP = $10 ; Text "type" sound / card select
  542. SND_LEVELPOWER = $20 ; Power up
  543. SND_LEVEL1UP = $40 ; 1-up
  544. SND_LEVELPOOF = $80 ; Lost suit / wand shot
  545. SND_LEVELUNK = $90 ; Unknown / lost sound
  546. SND_LEVELSHOE = $A0 ; Lost Kuirbo's Shoe
  547. SND_LEVELTAILWAG= $B0 ; Tail wag
  548.  
  549. Sound_QLevel2: Sound FX that uses noise channel, or triangle (for skid)
  550.  
  551. SND_LEVELCRUMBLE= $01 ; Crumbling brick
  552. SND_LEVELFLAME = $02 ; Flame jet
  553. SND_BOOMERANG = $04 ; Boomerang
  554. SND_LEVELAIRSHIP= $08 ; Airship fly
  555. SND_LEVELMARCH = $10 ; Hammer Bros. march around
  556. ; $20 - Unused
  557. ; $40 - Unused
  558. SND_LEVELSKID = $80 ; Skid
  559.  
  560.  
  561. If a sound effect is being played by Sound_QPlayer, since it uses square 1, then square 1’s music code is mostly skipped. This is so that the sound fx can be played on the same channels as the music (since the NES has limited sound channels… no longer an issue on SNES)
  562. Once the sound effect is finished playing (i.e Sound_Qplayer is zero) then the music resumes for that channel.
  563. So basically, the music note that was going to play on square 1 is blocked if SndCur_Player is anything but zero.
  564. Likewise for Sound_QLevel1, blocks music on square 2.
  565.  
  566. So for the JUMP sound effect, we know it will block the music on square 1.
  567. This affects the code that is being executed, and hence the X register.
  568.  
  569. Let’s have a look at the sound engine code that is run during each NMI (Non Maskable Interrupt)
  570. This execution dump is on the frame before the sound engine gets stuck in a loop. So the sound engine runs, finishes, and we then finish up our interrupt.
  571.  
  572. A:1C X:00 Y:00 S:F3 P:nvUbdizC $F57B:20 00 A0 JSR MMC3_MIRROR_or_Sound_Engine_Beg
  573. MMC3_MIRROR_or_Sound_Engine_Beg:
  574. A:1C X:00 Y:00 S:F1 P:nvUbdizC $A000:A9 FF LDA #$FF
  575. A:FF X:00 Y:00 S:F1 P:NvUbdizC $A002:8D 17 40 STA FRAMECTR_CTL = #$03
  576. A:FF X:00 Y:00 S:F1 P:NvUbdizC $A005:AD F7 04 LDA Sound_QPause = #$00
  577. A:00 X:00 Y:00 S:F1 P:nvUbdiZC $A008:D0 0D BNE SndPause
  578. A:00 X:00 Y:00 S:F1 P:nvUbdiZC $A00A:AD E7 04 LDA SndCur_Pause = #$00
  579. A:00 X:00 Y:00 S:F1 P:nvUbdiZC $A00D:D0 40 BNE $A04F
  580. A:00 X:00 Y:00 S:F1 P:nvUbdiZC $A00F:AD ED 04 LDA Sound_IsPaused = #$00 ;if sound is paused, skip almost all of the sound engine. Otherwise, continue
  581. A:00 X:00 Y:00 S:F1 P:nvUbdiZC $A012:D0 7B BNE $A08F
  582. A:00 X:00 Y:00 S:F1 P:nvUbdiZC $A014:4C 78 A0 JMP Sound_Process
  583. Sound_Process:
  584. A:00 X:00 Y:00 S:F1 P:nvUbdiZC $A078:20 61 A6 JSR Sound_PlayLevel2 ; Play Sound fx “Sound_QLevel2”…
  585. Sound_PlayLevel2:
  586. A:00 X:00 Y:00 S:EF P:nvUbdiZC $A661:AD E3 04 LDA SndCur_Level2 = #$00
  587. A:00 X:00 Y:00 S:EF P:nvUbdiZC $A664:C9 08 CMP #$08
  588. A:00 X:00 Y:00 S:EF P:NvUbdizc $A666:D0 03 BNE $A66B
  589. A:00 X:00 Y:00 S:EF P:NvUbdizc $A66B:AD E3 04 LDA SndCur_Level2 = #$00
  590. A:00 X:00 Y:00 S:EF P:nvUbdiZc $A66E:30 A8 BMI SndLev2_SkidCont
  591. A:00 X:00 Y:00 S:EF P:nvUbdiZc $A670:AC F3 04 LDY Sound_QLevel2 = #$00
  592. A:00 X:00 Y:00 S:EF P:nvUbdiZc $A673:F0 1B BEQ $A690
  593. A:00 X:00 Y:00 S:EF P:nvUbdiZc $A690:AD E3 04 LDA SndCur_Level2 = #$00
  594. A:00 X:00 Y:00 S:EF P:nvUbdiZc $A693:F0 0F BEQ $A6A4 ;nothing playing, return
  595. A:00 X:00 Y:00 S:EF P:nvUbdiZc $A6A4:60 RTS (from Sound_PlayLevel2) ----------------
  596. A:00 X:00 Y:00 S:F1 P:nvUbdiZc $A07B:20 AB A2 JSR Sound_PlayPlayer ; Play Sound fx “Sound_QPlayer”…
  597. Sound_PlayPlayer:
  598. A:00 X:00 Y:00 S:EF P:nvUbdiZc $A2AB:AC F1 04 LDY Sound_QPlayer = #$00
  599. A:00 X:00 Y:00 S:EF P:nvUbdiZc $A2AE:F0 20 BEQ $A2D0
  600. A:00 X:00 Y:00 S:EF P:nvUbdiZc $A2D0:AD E1 04 LDA SndCur_Player = #$03 ;Since both the bump and jump sounds were triggered on the same frame, A = 3. Because of the priority system, the jump sound plays ($01) rather than bump ($02)
  601. A:03 X:00 Y:00 S:EF P:nvUbdizc $A2D3:F0 14 BEQ $A2E9
  602. A:03 X:00 Y:00 S:EF P:nvUbdizc $A2D5:30 8F BMI PlayerSnd_FrogCont
  603. A:03 X:00 Y:00 S:EF P:nvUbdizc $A2D7:4A LSR
  604. A:01 X:00 Y:00 S:EF P:nvUbdizC $A2D8:B0 25 BCS PlayerSnd_JumpCont
  605. PlayerSnd_JumpCont:
  606. A:01 X:00 Y:00 S:EF P:nvUbdizC $A2FF:4C 66 A2 JMP PlayerSnd_FrogCont
  607. PlayerSnd_FrogCont:
  608. A:01 X:00 Y:00 S:EF P:nvUbdizC $A266:AD E0 04 LDA SFX_Counter1 = #$22 ; $22 frames (Decimal 34 frames) remaining on this sound effect
  609. A:22 X:00 Y:00 S:EF P:nvUbdizC $A269:C9 25 CMP #$25
  610. A:22 X:00 Y:00 S:EF P:NvUbdizc $A26B:D0 06 BNE $A273
  611. A:22 X:00 Y:00 S:EF P:NvUbdizc $A273:C9 20 CMP #$20
  612. A:22 X:00 Y:00 S:EF P:nvUbdizC $A275:D0 2F BNE $A2A6
  613. A:22 X:00 Y:00 S:EF P:nvUbdizC $A2A6:D0 7D BNE $A325
  614. A:22 X:00 Y:00 S:EF P:nvUbdizC $A325:D0 28 BNE PlayerSnd_CounterUpd
  615. PlayerSnd_CounterUpd:
  616. A:22 X:00 Y:00 S:EF P:nvUbdizC $A34F:CE E0 04 DEC SFX_Counter1 = #$22 ; Sound_PlayPlayer continues for another $21 = 33 frames
  617. A:22 X:00 Y:00 S:EF P:nvUbdizC $A352:D0 0F BNE $A363
  618. A:22 X:00 Y:00 S:EF P:nvUbdizC $A363:60 RTS (from Sound_PlayPlayer) ----------------
  619. A:22 X:00 Y:00 S:F1 P:nvUbdizC $A07E:20 49 A4 JSR Sound_PlayLevel1 ; Play Sound fx “Sound_QLevel1”…
  620. Sound_PlayLevel1:
  621. A:22 X:00 Y:00 S:EF P:nvUbdizC $A449:AD E2 04 LDA SndCur_Level1 = #$00
  622. A:00 X:00 Y:00 S:EF P:nvUbdiZC $A44C:29 40 AND #$40
  623. A:00 X:00 Y:00 S:EF P:nvUbdiZC $A44E:D0 5E BNE SndLev1_1upCont
  624. A:00 X:00 Y:00 S:EF P:nvUbdiZC $A450:AC F2 04 LDY Sound_QLevel1 = #$00
  625. A:00 X:00 Y:00 S:EF P:nvUbdiZC $A453:F0 25 BEQ $A47A
  626. A:00 X:00 Y:00 S:EF P:nvUbdiZC $A47A:AD E2 04 LDA SndCur_Level1 = #$00
  627. A:00 X:00 Y:00 S:EF P:nvUbdiZC $A47D:F0 17 BEQ $A496 ; nothing playing, return
  628. A:00 X:00 Y:00 S:EF P:nvUbdiZC $A496:60 RTS (from Sound_PlayLevel1) ----------------
  629. A:00 X:00 Y:00 S:F1 P:nvUbdiZC $A081:20 A1 A0 JSR Sound_PlayMapSounds
  630. Sound_PlayMapSounds:
  631. A:00 X:00 Y:00 S:EF P:nvUbdiZC $A0A1:AD F6 04 LDA Sound_QMap = #$00
  632. A:00 X:00 Y:00 S:EF P:nvUbdiZC $A0A4:D0 06 BNE MapSound_Queued
  633. A:00 X:00 Y:00 S:EF P:nvUbdiZC $A0A6:AD E6 04 LDA SndCur_Map = #$00
  634. A:00 X:00 Y:00 S:EF P:nvUbdiZC $A0A9:D0 35 BNE MapSound_Playing ; no map sounds playing, return
  635. A:00 X:00 Y:00 S:EF P:nvUbdiZC $A0AB:60 RTS (from Sound_PlayMapSounds) -------------
  636. A:00 X:00 Y:00 S:F1 P:nvUbdiZC $A084:20 4F E3 JSR Sound_PlayMusic
  637. A:00 X:00 Y:00 S:EF P:nvUbdiZC $E34F:AD F4 04 LDA Sound_QMusic1 = #$00
  638. A:00 X:00 Y:00 S:EF P:nvUbdiZC $E352:D0 F5 BNE SndMus_QueueCommonJ
  639. A:00 X:00 Y:00 S:EF P:nvUbdiZC $E354:AD E4 04 LDA SndCur_Music1 = #$00
  640. A:00 X:00 Y:00 S:EF P:nvUbdiZC $E357:F0 0B BEQ $E364
  641. A:00 X:00 Y:00 S:EF P:nvUbdiZC $E364:AD F4 04 LDA Sound_QMusic1 = #$00
  642. A:00 X:00 Y:00 S:EF P:nvUbdiZC $E367:D0 E0 BNE SndMus_QueueCommonJ
  643. A:00 X:00 Y:00 S:EF P:nvUbdiZC $E369:AD F5 04 LDA Sound_QMusic2 = #$00
  644. A:00 X:00 Y:00 S:EF P:nvUbdiZC $E36C:29 F0 AND #$F0
  645. A:00 X:00 Y:00 S:EF P:nvUbdiZC $E36E:F0 D9 BEQ SndMus_QueueCommonJ
  646. A:00 X:00 Y:00 S:EF P:nvUbdiZC $E349:4C EE E3 JMP SndMus_QueueCommon
  647. A:00 X:00 Y:00 S:EF P:nvUbdiZC $E3EE:AD F4 04 LDA Sound_QMusic1 = #$00
  648. A:00 X:00 Y:00 S:EF P:nvUbdiZC $E3F1:D0 52 BNE SndMus_Queue1
  649. A:00 X:00 Y:00 S:EF P:nvUbdiZC $E3F3:AD F5 04 LDA Sound_QMusic2 = #$00
  650. A:00 X:00 Y:00 S:EF P:nvUbdiZC $E3F6:D0 09 BNE $E401
  651. A:00 X:00 Y:00 S:EF P:nvUbdiZC $E3F8:AD E4 04 LDA SndCur_Music1 = #$00
  652. A:00 X:00 Y:00 S:EF P:nvUbdiZC $E3FB:0D E5 04 ORA SndCur_Music2 = #$20 ; current song playing = $20 = underground song
  653. A:20 X:00 Y:00 S:EF P:nvUbdizC $E3FE:D0 EB BNE $E3EB
  654. A:20 X:00 Y:00 S:EF P:nvUbdizC $E3EB:4C C5 E4 JMP Music_Sq2Track ; Go to square 2 code
  655. A:20 X:00 Y:00 S:EF P:nvUbdizC $E4C5:CE D4 04 DEC Music_Sq2Rest = #$38 ; Square 2 is resting for another $37 = 55 frames
  656. A:20 X:00 Y:00 S:EF P:nvUbdizC $E4C8:F0 03 BEQ $E4CD
  657. A:20 X:00 Y:00 S:EF P:nvUbdizC $E4CA:4C 7A E5 JMP $E57A
  658. A:20 X:00 Y:00 S:EF P:nvUbdizC $E57A:AD E2 04 LDA SndCur_Level1 = #$00
  659. A:00 X:00 Y:00 S:EF P:nvUbdiZC $E57D:D0 28 BNE $E5A7 ; Is there a sound effect playing on Square 2? If there is, skip most of the square 2 music code, and prevent bend effects. Otherwise, continue
  660. A:00 X:00 Y:00 S:EF P:nvUbdiZC $E57F:AD F4 7A LDA Music_Sq2Bend = #$00 ; If bend effects, apply them
  661. A:00 X:00 Y:00 S:EF P:nvUbdiZC $E582:F0 08 BEQ $E58C
  662. A:00 X:00 Y:00 S:EF P:nvUbdiZC $E58C:AC D5 04 LDY Music_Sq2NoteLen = #$00 ; If Music_Sq2NoteLen is anything but zero, decrement, otherwise don’t decrement
  663. A:00 X:00 Y:00 S:EF P:nvUbdiZC $E58F:F0 03 BEQ $E594
  664. A:00 X:00 Y:00 S:EF P:nvUbdiZC $E594:AD D3 04 LDA Music_Sq2RestH = #$48
  665. A:48 X:00 Y:00 S:EF P:nvUbdizC $E597:AE F7 07 LDX Music_Sq2Patch = #$D0
  666. A:48 X:D0 Y:00 S:EF P:NvUbdizC $E59A:20 85 E7 JSR Music_PatchGetCTL ; using A, X and Y from above, get patch Control value, and return it in the Accumulator
  667. A:48 X:D0 Y:00 S:ED P:NvUbdizC $E785:48 PHA
  668. A:48 X:D0 Y:00 S:EC P:NvUbdizC $E786:8A TXA
  669. A:D0 X:D0 Y:00 S:EC P:NvUbdizC $E787:29 70 AND #$70
  670. A:50 X:D0 Y:00 S:EC P:nvUbdizC $E789:4A LSR
  671. A:28 X:D0 Y:00 S:EC P:nvUbdizc $E78A:4A LSR
  672. A:14 X:D0 Y:00 S:EC P:nvUbdizc $E78B:4A LSR
  673. A:0A X:D0 Y:00 S:EC P:nvUbdizc $E78C:AA TAX
  674. A:0A X:0A Y:00 S:EC P:nvUbdizc $E78D:68 PLA
  675. A:48 X:0A Y:00 S:ED P:nvUbdizc $E78E:C9 13 CMP #$13
  676. A:48 X:0A Y:00 S:ED P:nvUbdizC $E790:90 0C BCC $E79E
  677. A:48 X:0A Y:00 S:ED P:nvUbdizC $E792:BD 65 E7 LDA Music_PatchTableLong,X @ $E76F = #$61
  678. A:61 X:0A Y:00 S:ED P:nvUbdizC $E795:85 71 STA Music_PatchAdrL = #$61
  679. A:61 X:0A Y:00 S:ED P:nvUbdizC $E797:BD 66 E7 LDA $E766,X @ $E770 = #$B3
  680. A:B3 X:0A Y:00 S:ED P:NvUbdizC $E79A:85 72 STA Music_PatchAdrH = #$B3
  681. A:B3 X:0A Y:00 S:ED P:NvUbdizC $E79C:D0 0A BNE $E7A8
  682. A:B3 X:0A Y:00 S:ED P:NvUbdizC $E7A8:B1 71 LDA ($71),Y @ $B361 = #$50
  683. A:50 X:0A Y:00 S:ED P:nvUbdizC $E7AA:60 RTS (from Music_PatchGetCTL) ---------------
  684. A:50 X:0A Y:00 S:EF P:nvUbdizC $E59D:8D 04 40 STA PAPU_CTL2 = #$50 ; Store Patch Control value that we just calculated from above subroutine into PAPU_CTL2
  685. A:50 X:0A Y:00 S:EF P:nvUbdizC $E5A0:A2 7F LDX #$7F ;Load X with $7F, then store it into PAPU_RAMP2.
  686. A:50 X:7F Y:00 S:EF P:nvUbdizC $E5A2:8E 05 40 STX PAPU_RAMP2 = #$7F
  687. A:50 X:7F Y:00 S:EF P:nvUbdizC $E5A5:D0 05 BNE Music_Sq1Track ; Go to square 1 code
  688. A:50 X:7F Y:00 S:EF P:nvUbdizC $E5AC:CE D6 04 DEC Music_Sq1Rest = #$38 ; Square 1 is resting for $37 = 55 frames
  689. A:50 X:7F Y:00 S:EF P:nvUbdizC $E5AF:D0 7A BNE $E62B
  690. A:50 X:7F Y:00 S:EF P:nvUbdizC $E62B:AD E1 04 LDA SndCur_Player = #$03 ; Is there a sound effect playing on Square 1? If there is, skip most of the square 2 music code, and prevent bend effects. Otherwise, continue. SndCur_Player = #$03, so we skip
  691. A:03 X:7F Y:00 S:EF P:nvUbdizC $E62E:0D E6 04 ORA SndCur_Map = #$00
  692. A:03 X:7F Y:00 S:EF P:nvUbdizC $E631:D0 2D BNE $E660
  693. A:03 X:7F Y:00 S:EF P:nvUbdizC $E660:A9 00 LDA #$00 ; prevent bend effects
  694. A:00 X:7F Y:00 S:EF P:nvUbdiZC $E662:8D F0 7A STA Music_Sq1Bend = #$00
  695. A:00 X:7F Y:00 S:EF P:nvUbdiZC $E665:AD D0 04 LDA Music_TriTrkPos = #$95 ; If triangle track is silenced, jump to noise track. Otherwise, continue
  696. A:95 X:7F Y:00 S:EF P:NvUbdizC $E668:F0 53 BEQ Music_NseTrack
  697. A:95 X:7F Y:00 S:EF P:NvUbdizC $E66A:CE D9 04 DEC Music_TriRest = #$38 ; Triangle is resting for another $37 = 55 frames
  698. A:95 X:7F Y:00 S:EF P:nvUbdizC $E66D:D0 4E BNE Music_NseTrack
  699. A:95 X:7F Y:00 S:EF P:nvUbdizC $E6BD:AD D1 04 LDA Music_NseTrkPos = #$B0 ; If noise track is silenced, jump to PCM track. Otherwise, continue
  700. A:B0 X:7F Y:00 S:EF P:NvUbdizC $E6C0:F0 3B BEQ Music_PCMTrack
  701. A:B0 X:7F Y:00 S:EF P:NvUbdizC $E6C2:CE DA 04 DEC Music_NoiseRest = #$02 ; Noise is resting for another $01 = 1 frame
  702. A:B0 X:7F Y:00 S:EF P:nvUbdizC $E6C5:D0 36 BNE Music_PCMTrack
  703. A:B0 X:7F Y:00 S:EF P:nvUbdizC $E6FD:4C 09 E7 JMP $E709
  704. A:B0 X:7F Y:00 S:EF P:nvUbdizC $E709:AD D2 04 LDA Music_PCMTrkPos = #$A6
  705. A:A6 X:7F Y:00 S:EF P:NvUbdizC $E70C:F0 2A BEQ $E738
  706. A:A6 X:7F Y:00 S:EF P:NvUbdizC $E70E:CE DC 04 DEC Music_DMCRest = #$0B ; DMC is resting for another $0A = 10 frames
  707. A:A6 X:7F Y:00 S:EF P:nvUbdizC $E711:D0 25 BNE $E738
  708. A:A6 X:7F Y:00 S:EF P:nvUbdizC $E738:20 C0 E2 JSR Music_PlayDMC
  709. A:A6 X:7F Y:00 S:ED P:nvUbdizC $E2C0:AD F0 07 LDA DMC_Queue = #$00
  710. A:00 X:7F Y:00 S:ED P:nvUbdiZC $E2C3:C9 7E CMP #$7E
  711. A:00 X:7F Y:00 S:ED P:NvUbdizc $E2C5:F0 0F BEQ Music_StopDMC
  712. A:00 X:7F Y:00 S:ED P:NvUbdizc $E2C7:AD F0 07 LDA DMC_Queue = #$00
  713. A:00 X:7F Y:00 S:ED P:nvUbdiZc $E2CA:D0 15 BNE $E2E1
  714. A:00 X:7F Y:00 S:ED P:nvUbdiZc $E2CC:AD F1 07 LDA DMC_Current = #$01
  715. A:01 X:7F Y:00 S:ED P:nvUbdizc $E2CF:F0 05 BEQ Music_StopDMC
  716. A:01 X:7F Y:00 S:ED P:nvUbdizc $E2D1:CE F8 04 DEC DMC_Time = #$99
  717. A:01 X:7F Y:00 S:ED P:NvUbdizc $E2D4:D0 0A BNE $E2E0
  718. A:01 X:7F Y:00 S:ED P:NvUbdizc $E2E0:60 RTS (from Music_PlayDMC) -------------------
  719. A:01 X:7F Y:00 S:EF P:NvUbdizc $E73B:A9 00 LDA #$00
  720. A:00 X:7F Y:00 S:EF P:nvUbdiZc $E73D:8D F0 07 STA DMC_Queue = #$00
  721. A:00 X:7F Y:00 S:EF P:nvUbdiZc $E740:60 RTS (from Sound_PlayMusic) -----------------
  722. A:00 X:7F Y:00 S:F1 P:nvUbdiZc $A087:A9 00 LDA #$00 ;Clear all Queued music and sound FX
  723. A:00 X:7F Y:00 S:F1 P:nvUbdiZc $A089:8D F5 04 STA Sound_QMusic2 = #$00
  724. A:00 X:7F Y:00 S:F1 P:nvUbdiZc $A08C:8D F4 04 STA Sound_QMusic1 = #$00
  725. A:00 X:7F Y:00 S:F1 P:nvUbdiZc $A08F:A9 00 LDA #$00
  726. A:00 X:7F Y:00 S:F1 P:nvUbdiZc $A091:8D F1 04 STA Sound_QPlayer = #$00
  727. A:00 X:7F Y:00 S:F1 P:nvUbdiZc $A094:8D F2 04 STA Sound_QLevel1 = #$00
  728. A:00 X:7F Y:00 S:F1 P:nvUbdiZc $A097:8D F3 04 STA Sound_QLevel2 = #$00
  729. A:00 X:7F Y:00 S:F1 P:nvUbdiZc $A09A:8D F6 04 STA Sound_QMap = #$00
  730. A:00 X:7F Y:00 S:F1 P:nvUbdiZc $A09D:8D F7 04 STA Sound_QPause = #$00
  731. A:00 X:7F Y:00 S:F1 P:nvUbdiZc $A0A0:60 RTS (from MMC3_MIRROR_or_Sound_Engine_Beg) -
  732. A:00 X:7F Y:00 S:F3 P:nvUbdiZc $F57E:20 6F FC JSR PRGROM_Change_Both ; Change banks $A000 and $C000 to whatever they were BEFORE the NMI (24 and 25)
  733. A:00 X:7F Y:00 S:F1 P:nvUbdiZc $FC6F:A9 46 LDA #$46
  734. A:46 X:7F Y:00 S:F1 P:nvUbdizc $FC71:8D 00 80 STA MMC3_COMMAND = #$00
  735. A:46 X:7F Y:00 S:F1 P:nvUbdizc $FC74:AD 1F 07 LDA PAGE_C000 = #$19
  736. A:19 X:7F Y:00 S:F1 P:nvUbdizc $FC77:8D 01 80 STA MMC3_PAGE = #$60
  737. A:19 X:7F Y:00 S:F1 P:nvUbdizc $FC7A:A9 47 LDA #$47
  738. A:47 X:7F Y:00 S:F1 P:nvUbdizc $FC7C:8D 00 80 STA MMC3_COMMAND = #$00
  739. A:47 X:7F Y:00 S:F1 P:nvUbdizc $FC7F:AD 20 07 LDA PAGE_A000 = #$18
  740. A:18 X:7F Y:00 S:F1 P:nvUbdizc $FC82:8D 01 80 STA MMC3_PAGE = #$60
  741. A:18 X:7F Y:00 S:F1 P:nvUbdizc $FC85:60 RTS (from PRGROM_Change_Both) --------------
  742. A:18 X:7F Y:00 S:F3 P:nvUbdizc $F581:E6 15 INC Counter_1 = #$06
  743. A:18 X:7F Y:00 S:F3 P:nvUbdizc $F583:AD 21 07 LDA PAGE_CMD = #$47
  744. A:47 X:7F Y:00 S:F3 P:nvUbdizc $F586:8D 00 80 STA MMC3_COMMAND = #$00
  745. A:47 X:7F Y:00 S:F3 P:nvUbdizc $F589:68 PLA ; Restore A, X, Y to what they were before the NMI, then return to where we were before the NMI fired!
  746. A:33 X:7F Y:00 S:F4 P:nvUbdizc $F58A:85 02 STA Temp_Var3 = #$80
  747. A:33 X:7F Y:00 S:F4 P:nvUbdizc $F58C:68 PLA
  748. A:B8 X:7F Y:00 S:F5 P:NvUbdizc $F58D:85 01 STA Temp_Var2 = #$00
  749. A:B8 X:7F Y:00 S:F5 P:NvUbdizc $F58F:68 PLA
  750. A:99 X:7F Y:00 S:F6 P:NvUbdizc $F590:85 00 STA Temp_Var1 = #$80
  751. A:99 X:7F Y:00 S:F6 P:NvUbdizc $F592:68 PLA
  752. A:B0 X:7F Y:00 S:F7 P:NvUbdizc $F593:A8 TAY
  753. A:B0 X:7F Y:B0 S:F7 P:NvUbdizc $F594:68 PLA
  754. A:01 X:7F Y:B0 S:F8 P:nvUbdizc $F595:AA TAX
  755. A:01 X:01 Y:B0 S:F8 P:nvUbdizc $F596:68 PLA
  756. A:00 X:01 Y:B0 S:F9 P:nvUbdiZc $F597:28 PLP
  757. A:00 X:01 Y:B0 S:FA P:nvUBdIZc $F598:40 RTI ; ReTurn from Interrupt
  758.  
  759. From above, we can see that the X register was set to $7F on line $E5A2:8E 05 40 STX PAPU_RAMP2 = #$7F. The X register then remained unchanged until the end of the NMI, when it was returned to what it was before the NMI started.
  760. This is important, because on the next frame, we enter the loop that continues until Square 2 is done resting. While in this loop, whatever the X register was when it enters the loop, will end up being the value that the NMI’s following return it to when they Finnish.
  761.  
  762. The next execution dump will have less comments, as most of it is the same as above.
  763.  
  764. A:1C X:00 Y:00 S:F3 P:nvUbdizC $F57B:20 00 A0 JSR MMC3_MIRROR_or_Sound_Engine_Beg
  765. MMC3_MIRROR_or_Sound_Engine_Beg:
  766. A:1C X:00 Y:00 S:F1 P:nvUbdizC $A000:A9 FF LDA #$FF
  767. f13929 c414815411 i50239851 A:FF X:00 Y:00 S:F1 P:NvUbdizC $A002:8D 17 40 STA FRAMECTR_CTL = #$03
  768. f13929 c414815415 i50239852 A:FF X:00 Y:00 S:F1 P:NvUbdizC $A005:AD F7 04 LDA Sound_QPause = #$00
  769. f13929 c414815419 i50239853 A:00 X:00 Y:00 S:F1 P:nvUbdiZC $A008:D0 0D BNE SndPause
  770. f13929 c414815421 i50239854 A:00 X:00 Y:00 S:F1 P:nvUbdiZC $A00A:AD E7 04 LDA SndCur_Pause = #$00
  771. f13929 c414815425 i50239855 A:00 X:00 Y:00 S:F1 P:nvUbdiZC $A00D:D0 40 BNE $A04F
  772. f13929 c414815427 i50239856 A:00 X:00 Y:00 S:F1 P:nvUbdiZC $A00F:AD ED 04 LDA Sound_IsPaused = #$00
  773. f13929 c414815431 i50239857 A:00 X:00 Y:00 S:F1 P:nvUbdiZC $A012:D0 7B BNE $A08F
  774. f13929 c414815433 i50239858 A:00 X:00 Y:00 S:F1 P:nvUbdiZC $A014:4C 78 A0 JMP Sound_Process
  775. Sound_Process:
  776. f13929 c414815436 i50239859 A:00 X:00 Y:00 S:F1 P:nvUbdiZC $A078:20 61 A6 JSR Sound_PlayLevel2
  777. Sound_PlayLevel2:
  778. f13929 c414815442 i50239860 A:00 X:00 Y:00 S:EF P:nvUbdiZC $A661:AD E3 04 LDA SndCur_Level2 = #$00
  779. f13929 c414815446 i50239861 A:00 X:00 Y:00 S:EF P:nvUbdiZC $A664:C9 08 CMP #$08
  780. f13929 c414815448 i50239862 A:00 X:00 Y:00 S:EF P:NvUbdizc $A666:D0 03 BNE $A66B
  781. f13929 c414815451 i50239863 A:00 X:00 Y:00 S:EF P:NvUbdizc $A66B:AD E3 04 LDA SndCur_Level2 = #$00
  782. f13929 c414815455 i50239864 A:00 X:00 Y:00 S:EF P:nvUbdiZc $A66E:30 A8 BMI SndLev2_SkidCont
  783. f13929 c414815457 i50239865 A:00 X:00 Y:00 S:EF P:nvUbdiZc $A670:AC F3 04 LDY Sound_QLevel2 = #$00
  784. f13929 c414815461 i50239866 A:00 X:00 Y:00 S:EF P:nvUbdiZc $A673:F0 1B BEQ $A690
  785. f13929 c414815464 i50239867 A:00 X:00 Y:00 S:EF P:nvUbdiZc $A690:AD E3 04 LDA SndCur_Level2 = #$00
  786. f13929 c414815468 i50239868 A:00 X:00 Y:00 S:EF P:nvUbdiZc $A693:F0 0F BEQ $A6A4
  787. f13929 c414815471 i50239869 A:00 X:00 Y:00 S:EF P:nvUbdiZc $A6A4:60 RTS (from Sound_PlayLevel2) ----------------
  788. f13929 c414815477 i50239870 A:00 X:00 Y:00 S:F1 P:nvUbdiZc $A07B:20 AB A2 JSR Sound_PlayPlayer
  789. Sound_PlayPlayer:
  790. f13929 c414815483 i50239871 A:00 X:00 Y:00 S:EF P:nvUbdiZc $A2AB:AC F1 04 LDY Sound_QPlayer = #$00
  791. f13929 c414815487 i50239872 A:00 X:00 Y:00 S:EF P:nvUbdiZc $A2AE:F0 20 BEQ $A2D0
  792. f13929 c414815490 i50239873 A:00 X:00 Y:00 S:EF P:nvUbdiZc $A2D0:AD E1 04 LDA SndCur_Player = #$03
  793. f13929 c414815494 i50239874 A:03 X:00 Y:00 S:EF P:nvUbdizc $A2D3:F0 14 BEQ $A2E9
  794. f13929 c414815496 i50239875 A:03 X:00 Y:00 S:EF P:nvUbdizc $A2D5:30 8F BMI PlayerSnd_FrogCont
  795. f13929 c414815498 i50239876 A:03 X:00 Y:00 S:EF P:nvUbdizc $A2D7:4A LSR
  796. f13929 c414815500 i50239877 A:01 X:00 Y:00 S:EF P:nvUbdizC $A2D8:B0 25 BCS PlayerSnd_JumpCont
  797. PlayerSnd_JumpCont:
  798. f13929 c414815503 i50239878 A:01 X:00 Y:00 S:EF P:nvUbdizC $A2FF:4C 66 A2 JMP PlayerSnd_FrogCont
  799. PlayerSnd_FrogCont:
  800. f13929 c414815506 i50239879 A:01 X:00 Y:00 S:EF P:nvUbdizC $A266:AD E0 04 LDA SFX_Counter1 = #$21
  801. f13929 c414815510 i50239880 A:21 X:00 Y:00 S:EF P:nvUbdizC $A269:C9 25 CMP #$25
  802. f13929 c414815512 i50239881 A:21 X:00 Y:00 S:EF P:NvUbdizc $A26B:D0 06 BNE $A273
  803. f13929 c414815515 i50239882 A:21 X:00 Y:00 S:EF P:NvUbdizc $A273:C9 20 CMP #$20
  804. f13929 c414815517 i50239883 A:21 X:00 Y:00 S:EF P:nvUbdizC $A275:D0 2F BNE $A2A6
  805. f13929 c414815520 i50239884 A:21 X:00 Y:00 S:EF P:nvUbdizC $A2A6:D0 7D BNE $A325
  806. f13929 c414815524 i50239885 A:21 X:00 Y:00 S:EF P:nvUbdizC $A325:D0 28 BNE PlayerSnd_CounterUpd
  807. PlayerSnd_CounterUpd:
  808. f13929 c414815527 i50239886 A:21 X:00 Y:00 S:EF P:nvUbdizC $A34F:CE E0 04 DEC SFX_Counter1 = #$21
  809. f13929 c414815533 i50239887 A:21 X:00 Y:00 S:EF P:nvUbdizC $A352:D0 0F BNE $A363
  810. f13929 c414815536 i50239888 A:21 X:00 Y:00 S:EF P:nvUbdizC $A363:60 RTS (from Sound_PlayPlayer) ----------------
  811. f13929 c414815542 i50239889 A:21 X:00 Y:00 S:F1 P:nvUbdizC $A07E:20 49 A4 JSR Sound_PlayLevel1
  812. Sound_PlayLevel1:
  813. f13929 c414815548 i50239890 A:21 X:00 Y:00 S:EF P:nvUbdizC $A449:AD E2 04 LDA SndCur_Level1 = #$00
  814. f13929 c414815552 i50239891 A:00 X:00 Y:00 S:EF P:nvUbdiZC $A44C:29 40 AND #$40
  815. f13929 c414815554 i50239892 A:00 X:00 Y:00 S:EF P:nvUbdiZC $A44E:D0 5E BNE SndLev1_1upCont
  816. f13929 c414815556 i50239893 A:00 X:00 Y:00 S:EF P:nvUbdiZC $A450:AC F2 04 LDY Sound_QLevel1 = #$00
  817. f13929 c414815560 i50239894 A:00 X:00 Y:00 S:EF P:nvUbdiZC $A453:F0 25 BEQ $A47A
  818. f13929 c414815563 i50239895 A:00 X:00 Y:00 S:EF P:nvUbdiZC $A47A:AD E2 04 LDA SndCur_Level1 = #$00
  819. f13929 c414815567 i50239896 A:00 X:00 Y:00 S:EF P:nvUbdiZC $A47D:F0 17 BEQ $A496
  820. f13929 c414815570 i50239897 A:00 X:00 Y:00 S:EF P:nvUbdiZC $A496:60 RTS (from Sound_PlayLevel1) ----------------
  821. f13929 c414815576 i50239898 A:00 X:00 Y:00 S:F1 P:nvUbdiZC $A081:20 A1 A0 JSR Sound_PlayMapSounds
  822. Sound_PlayMapSounds:
  823. f13929 c414815582 i50239899 A:00 X:00 Y:00 S:EF P:nvUbdiZC $A0A1:AD F6 04 LDA Sound_QMap = #$00
  824. f13929 c414815586 i50239900 A:00 X:00 Y:00 S:EF P:nvUbdiZC $A0A4:D0 06 BNE MapSound_Queued
  825. f13929 c414815588 i50239901 A:00 X:00 Y:00 S:EF P:nvUbdiZC $A0A6:AD E6 04 LDA SndCur_Map = #$00
  826. f13929 c414815592 i50239902 A:00 X:00 Y:00 S:EF P:nvUbdiZC $A0A9:D0 35 BNE MapSound_Playing
  827. f13929 c414815594 i50239903 A:00 X:00 Y:00 S:EF P:nvUbdiZC $A0AB:60 RTS (from Sound_PlayMapSounds) -------------
  828. f13929 c414815600 i50239904 A:00 X:00 Y:00 S:F1 P:nvUbdiZC $A084:20 4F E3 JSR Sound_PlayMusic
  829. f13929 c414815606 i50239905 A:00 X:00 Y:00 S:EF P:nvUbdiZC $E34F:AD F4 04 LDA Sound_QMusic1 = #$00
  830. f13929 c414815610 i50239906 A:00 X:00 Y:00 S:EF P:nvUbdiZC $E352:D0 F5 BNE SndMus_QueueCommonJ
  831. f13929 c414815612 i50239907 A:00 X:00 Y:00 S:EF P:nvUbdiZC $E354:AD E4 04 LDA SndCur_Music1 = #$00
  832. f13929 c414815616 i50239908 A:00 X:00 Y:00 S:EF P:nvUbdiZC $E357:F0 0B BEQ $E364
  833. f13929 c414815619 i50239909 A:00 X:00 Y:00 S:EF P:nvUbdiZC $E364:AD F4 04 LDA Sound_QMusic1 = #$00
  834. f13929 c414815623 i50239910 A:00 X:00 Y:00 S:EF P:nvUbdiZC $E367:D0 E0 BNE SndMus_QueueCommonJ
  835. f13929 c414815625 i50239911 A:00 X:00 Y:00 S:EF P:nvUbdiZC $E369:AD F5 04 LDA Sound_QMusic2 = #$00
  836. f13929 c414815629 i50239912 A:00 X:00 Y:00 S:EF P:nvUbdiZC $E36C:29 F0 AND #$F0
  837. f13929 c414815631 i50239913 A:00 X:00 Y:00 S:EF P:nvUbdiZC $E36E:F0 D9 BEQ SndMus_QueueCommonJ
  838. f13929 c414815634 i50239914 A:00 X:00 Y:00 S:EF P:nvUbdiZC $E349:4C EE E3 JMP SndMus_QueueCommon
  839. f13929 c414815637 i50239915 A:00 X:00 Y:00 S:EF P:nvUbdiZC $E3EE:AD F4 04 LDA Sound_QMusic1 = #$00
  840. f13929 c414815641 i50239916 A:00 X:00 Y:00 S:EF P:nvUbdiZC $E3F1:D0 52 BNE SndMus_Queue1
  841. f13929 c414815643 i50239917 A:00 X:00 Y:00 S:EF P:nvUbdiZC $E3F3:AD F5 04 LDA Sound_QMusic2 = #$00
  842. f13929 c414815647 i50239918 A:00 X:00 Y:00 S:EF P:nvUbdiZC $E3F6:D0 09 BNE $E401
  843. f13929 c414815649 i50239919 A:00 X:00 Y:00 S:EF P:nvUbdiZC $E3F8:AD E4 04 LDA SndCur_Music1 = #$00
  844. f13929 c414815653 i50239920 A:00 X:00 Y:00 S:EF P:nvUbdiZC $E3FB:0D E5 04 ORA SndCur_Music2 = #$20
  845. f13929 c414815657 i50239921 A:20 X:00 Y:00 S:EF P:nvUbdizC $E3FE:D0 EB BNE $E3EB
  846. f13929 c414815661 i50239922 A:20 X:00 Y:00 S:EF P:nvUbdizC $E3EB:4C C5 E4 JMP Music_Sq2Track
  847. f13929 c414815664 i50239923 A:20 X:00 Y:00 S:EF P:nvUbdizC $E4C5:CE D4 04 DEC Music_Sq2Rest = #$37
  848. f13929 c414815670 i50239924 A:20 X:00 Y:00 S:EF P:nvUbdizC $E4C8:F0 03 BEQ $E4CD
  849. f13929 c414815672 i50239925 A:20 X:00 Y:00 S:EF P:nvUbdizC $E4CA:4C 7A E5 JMP $E57A
  850. f13929 c414815675 i50239926 A:20 X:00 Y:00 S:EF P:nvUbdizC $E57A:AD E2 04 LDA SndCur_Level1 = #$00
  851. f13929 c414815679 i50239927 A:00 X:00 Y:00 S:EF P:nvUbdiZC $E57D:D0 28 BNE $E5A7
  852. f13929 c414815681 i50239928 A:00 X:00 Y:00 S:EF P:nvUbdiZC $E57F:AD F4 7A LDA Music_Sq2Bend = #$00
  853. f13929 c414815685 i50239929 A:00 X:00 Y:00 S:EF P:nvUbdiZC $E582:F0 08 BEQ $E58C
  854. f13929 c414815688 i50239930 A:00 X:00 Y:00 S:EF P:nvUbdiZC $E58C:AC D5 04 LDY Music_Sq2NoteLen = #$00
  855. f13929 c414815692 i50239931 A:00 X:00 Y:00 S:EF P:nvUbdiZC $E58F:F0 03 BEQ $E594
  856. f13929 c414815695 i50239932 A:00 X:00 Y:00 S:EF P:nvUbdiZC $E594:AD D3 04 LDA Music_Sq2RestH = #$48
  857. f13929 c414815699 i50239933 A:48 X:00 Y:00 S:EF P:nvUbdizC $E597:AE F7 07 LDX Music_Sq2Patch = #$D0
  858. f13929 c414815703 i50239934 A:48 X:D0 Y:00 S:EF P:NvUbdizC $E59A:20 85 E7 JSR Music_PatchGetCTL
  859. f13929 c414815709 i50239935 A:48 X:D0 Y:00 S:ED P:NvUbdizC $E785:48 PHA
  860. f13929 c414815712 i50239936 A:48 X:D0 Y:00 S:EC P:NvUbdizC $E786:8A TXA
  861. f13929 c414815714 i50239937 A:D0 X:D0 Y:00 S:EC P:NvUbdizC $E787:29 70 AND #$70
  862. f13929 c414815716 i50239938 A:50 X:D0 Y:00 S:EC P:nvUbdizC $E789:4A LSR
  863. f13929 c414815718 i50239939 A:28 X:D0 Y:00 S:EC P:nvUbdizc $E78A:4A LSR
  864. f13929 c414815720 i50239940 A:14 X:D0 Y:00 S:EC P:nvUbdizc $E78B:4A LSR
  865. f13929 c414815722 i50239941 A:0A X:D0 Y:00 S:EC P:nvUbdizc $E78C:AA TAX
  866. f13929 c414815724 i50239942 A:0A X:0A Y:00 S:EC P:nvUbdizc $E78D:68 PLA
  867. f13929 c414815728 i50239943 A:48 X:0A Y:00 S:ED P:nvUbdizc $E78E:C9 13 CMP #$13
  868. f13929 c414815730 i50239944 A:48 X:0A Y:00 S:ED P:nvUbdizC $E790:90 0C BCC $E79E
  869. f13929 c414815732 i50239945 A:48 X:0A Y:00 S:ED P:nvUbdizC $E792:BD 65 E7 LDA Music_PatchTableLong,X @ $E76F = #$61
  870. f13929 c414815736 i50239946 A:61 X:0A Y:00 S:ED P:nvUbdizC $E795:85 71 STA Music_PatchAdrL = #$61
  871. f13929 c414815739 i50239947 A:61 X:0A Y:00 S:ED P:nvUbdizC $E797:BD 66 E7 LDA $E766,X @ $E770 = #$B3
  872. f13929 c414815743 i50239948 A:B3 X:0A Y:00 S:ED P:NvUbdizC $E79A:85 72 STA Music_PatchAdrH = #$B3
  873. f13929 c414815746 i50239949 A:B3 X:0A Y:00 S:ED P:NvUbdizC $E79C:D0 0A BNE $E7A8
  874. f13929 c414815749 i50239950 A:B3 X:0A Y:00 S:ED P:NvUbdizC $E7A8:B1 71 LDA ($71),Y @ $B361 = #$50
  875. f13929 c414815754 i50239951 A:50 X:0A Y:00 S:ED P:nvUbdizC $E7AA:60 RTS (from Music_PatchGetCTL) ---------------
  876. f13929 c414815760 i50239952 A:50 X:0A Y:00 S:EF P:nvUbdizC $E59D:8D 04 40 STA PAPU_CTL2 = #$50
  877. f13929 c414815764 i50239953 A:50 X:0A Y:00 S:EF P:nvUbdizC $E5A0:A2 7F LDX #$7F
  878. f13929 c414815766 i50239954 A:50 X:7F Y:00 S:EF P:nvUbdizC $E5A2:8E 05 40 STX PAPU_RAMP2 = #$7F
  879. f13929 c414815770 i50239955 A:50 X:7F Y:00 S:EF P:nvUbdizC $E5A5:D0 05 BNE Music_Sq1Track
  880. f13929 c414815773 i50239956 A:50 X:7F Y:00 S:EF P:nvUbdizC $E5AC:CE D6 04 DEC Music_Sq1Rest = #$37
  881. f13929 c414815779 i50239957 A:50 X:7F Y:00 S:EF P:nvUbdizC $E5AF:D0 7A BNE $E62B
  882. f13929 c414815783 i50239958 A:50 X:7F Y:00 S:EF P:nvUbdizC $E62B:AD E1 04 LDA SndCur_Player = #$03
  883. f13929 c414815787 i50239959 A:03 X:7F Y:00 S:EF P:nvUbdizC $E62E:0D E6 04 ORA SndCur_Map = #$00
  884. f13929 c414815791 i50239960 A:03 X:7F Y:00 S:EF P:nvUbdizC $E631:D0 2D BNE $E660
  885. f13929 c414815794 i50239961 A:03 X:7F Y:00 S:EF P:nvUbdizC $E660:A9 00 LDA #$00
  886. f13929 c414815796 i50239962 A:00 X:7F Y:00 S:EF P:nvUbdiZC $E662:8D F0 7A STA Music_Sq1Bend = #$00
  887. f13929 c414815800 i50239963 A:00 X:7F Y:00 S:EF P:nvUbdiZC $E665:AD D0 04 LDA Music_TriTrkPos = #$95
  888. f13929 c414815804 i50239964 A:95 X:7F Y:00 S:EF P:NvUbdizC $E668:F0 53 BEQ Music_NseTrack
  889. f13929 c414815806 i50239965 A:95 X:7F Y:00 S:EF P:NvUbdizC $E66A:CE D9 04 DEC Music_TriRest = #$37
  890. f13929 c414815812 i50239966 A:95 X:7F Y:00 S:EF P:nvUbdizC $E66D:D0 4E BNE Music_NseTrack
  891. f13929 c414815815 i50239967 A:95 X:7F Y:00 S:EF P:nvUbdizC $E6BD:AD D1 04 LDA Music_NseTrkPos = #$B0
  892. f13929 c414815819 i50239968 A:B0 X:7F Y:00 S:EF P:NvUbdizC $E6C0:F0 3B BEQ Music_PCMTrack
  893. f13929 c414815821 i50239969 A:B0 X:7F Y:00 S:EF P:NvUbdizC $E6C2:CE DA 04 DEC Music_NoiseRest = #$01 ; Noise is finished resting! We don’t branch.
  894. f13929 c414815827 i50239970 A:B0 X:7F Y:00 S:EF P:nvUbdiZC $E6C5:D0 36 BNE Music_PCMTrack
  895. f13929 c414815829 i50239971 A:B0 X:7F Y:00 S:EF P:nvUbdiZC $E6C7:AC D1 04 LDY Music_NseTrkPos = #$B0 ; Load Y With Noise track position
  896. f13929 c414815833 i50239972 A:B0 X:7F Y:B0 S:EF P:NvUbdizC $E6CA:EE D1 04 INC Music_NseTrkPos = #$B0 ; Increment Noise track position
  897. f13929 c414815839 i50239973 A:B0 X:7F Y:B0 S:EF P:NvUbdizC $E6CD:B1 6B LDA ($6B),Y @ $00B0 = #$00 ; Using Y as an index, load next byte from music track.
  898. f13929 c414815844 i50239974 A:00 X:7F Y:B0 S:EF P:nvUbdiZC $E6CF:F0 2F BEQ $E700 ; If zero, reset noise track position back to the start
  899. f13929 c414815848 i50239975 A:00 X:7F Y:B0 S:EF P:nvUbdiZC $E700:AD F3 07 LDA Music_NseStart = #$AE
  900. f13929 c414815852 i50239976 A:AE X:7F Y:B0 S:EF P:NvUbdizC $E703:8D D1 04 STA Music_NseTrkPos = #$B1
  901. f13929 c414815856 i50239977 A:AE X:7F Y:B0 S:EF P:NvUbdizC $E706:4C C7 E6 JMP $E6C7 ; Go back and load in new byte from start of music track. However, we hit a problem! Because $6B and $6C were cleared when the zero page RAM was cleared, they no longer point to the music track data. instead, they point to $0000, indexed with Y = $00B0. This also holds zero! So we try and reset the track back to the start again, to no avail.. we are stuck!
  902. f13929 c414815859 i50239978 A:AE X:7F Y:B0 S:EF P:NvUbdizC $E6C7:AC D1 04 LDY Music_NseTrkPos = #$AE
  903. f13929 c414815863 i50239979 A:AE X:7F Y:AE S:EF P:NvUbdizC $E6CA:EE D1 04 INC Music_NseTrkPos = #$AE
  904. f13929 c414815869 i50239980 A:AE X:7F Y:AE S:EF P:NvUbdizC $E6CD:B1 6B LDA ($6B),Y @ $00AE = #$00
  905. f13929 c414815874 i50239981 A:00 X:7F Y:AE S:EF P:nvUbdiZC $E6CF:F0 2F BEQ $E700
  906. f13929 c414815878 i50239982 A:00 X:7F Y:AE S:EF P:nvUbdiZC $E700:AD F3 07 LDA Music_NseStart = #$AE
  907. f13929 c414815882 i50239983 A:AE X:7F Y:AE S:EF P:NvUbdizC $E703:8D D1 04 STA Music_NseTrkPos = #$AF
  908. f13929 c414815886 i50239984 A:AE X:7F Y:AE S:EF P:NvUbdizC $E706:4C C7 E6 JMP $E6C7
  909. f13929 c414815889 i50239985 A:AE X:7F Y:AE S:EF P:NvUbdizC $E6C7:AC D1 04 LDY Music_NseTrkPos = #$AE
  910. f13929 c414815893 i50239986 A:AE X:7F Y:AE S:EF P:NvUbdizC $E6CA:EE D1 04 INC Music_NseTrkPos = #$AE
  911. f13929 c414815899 i50239987 A:AE X:7F Y:AE S:EF P:NvUbdizC $E6CD:B1 6B LDA ($6B),Y @ $00AE = #$00
  912. f13929 c414815904 i50239988 A:00 X:7F Y:AE S:EF P:nvUbdiZC $E6CF:F0 2F BEQ $E700
  913. f13929 c414815908 i50239989 A:00 X:7F Y:AE S:EF P:nvUbdiZC $E700:AD F3 07 LDA Music_NseStart = #$AE
  914. f13929 c414815912 i50239990 A:AE X:7F Y:AE S:EF P:NvUbdizC $E703:8D D1 04 STA Music_NseTrkPos = #$AF
  915. f13929 c414815916 i50239991 A:AE X:7F Y:AE S:EF P:NvUbdizC $E706:4C C7 E6 JMP $E6C7
  916. f13929 c414815919 i50239992 A:AE X:7F Y:AE S:EF P:NvUbdizC $E6C7:AC D1 04 LDY Music_NseTrkPos = #$AE
  917. f13929 c414815923 i50239993 A:AE X:7F Y:AE S:EF P:NvUbdizC $E6CA:EE D1 04 INC Music_NseTrkPos = #$AE
  918. f13929 c414815929 i50239994 A:AE X:7F Y:AE S:EF P:NvUbdizC $E6CD:B1 6B LDA ($6B),Y @ $00AE = #$00
  919. f13929 c414815934 i50239995 A:00 X:7F Y:AE S:EF P:nvUbdiZC $E6CF:F0 2F BEQ $E700
  920. f13929 c414815938 i50239996 A:00 X:7F Y:AE S:EF P:nvUbdiZC $E700:AD F3 07 LDA Music_NseStart = #$AE
  921. f13929 c414815942 i50239997 A:AE X:7F Y:AE S:EF P:NvUbdizC $E703:8D D1 04 STA Music_NseTrkPos = #$AF
  922. f13929 c414815946 i50239998 A:AE X:7F Y:AE S:EF P:NvUbdizC $E706:4C C7 E6 JMP $E6C7
  923. f13929 c414815949 i50239999 A:AE X:7F Y:AE S:EF P:NvUbdizC $E6C7:AC D1 04 LDY Music_NseTrkPos = #$AE
  924. f13929 c414815953 i50240000 A:AE X:7F Y:AE S:EF P:NvUbdizC $E6CA:EE D1 04 INC Music_NseTrkPos = #$AE
  925. f13929 c414815959 i50240001 A:AE X:7F Y:AE S:EF P:NvUbdizC $E6CD:B1 6B LDA ($6B),Y @ $00AE = #$00
  926. f13929 c414815964 i50240002 A:00 X:7F Y:AE S:EF P:nvUbdiZC $E6CF:F0 2F BEQ $E700
  927. …. continues along until next NMI.
  928.  
  929. Note that the X value is $7F, so when subsequent NMI’s are finished, X will be returned to $7F.
  930.  
  931. Depending on when we activated the Wrong Warp, the value of Music_Sq2Rest will be different. If it’s a high value, then the DMC track will also finish resting, and get caught up in a loop just like the noise track.
  932.  
  933. Note this is 10 frames later, so all Rests have decremented by 10.
  934.  
  935. -------------
  936. f13939 c415112689 i50309478 A:00 X:00 Y:00 S:E3 P:nvUbdiZc $A084:20 4F E3 JSR Sound_PlayMusic
  937. f13939 c415112695 i50309479 A:00 X:00 Y:00 S:E1 P:nvUbdiZc $E34F:AD F4 04 LDA Sound_QMusic1 = #$00
  938. f13939 c415112699 i50309480 A:00 X:00 Y:00 S:E1 P:nvUbdiZc $E352:D0 F5 BNE SndMus_QueueCommonJ
  939. f13939 c415112701 i50309481 A:00 X:00 Y:00 S:E1 P:nvUbdiZc $E354:AD E4 04 LDA SndCur_Music1 = #$00
  940. f13939 c415112705 i50309482 A:00 X:00 Y:00 S:E1 P:nvUbdiZc $E357:F0 0B BEQ $E364
  941. f13939 c415112708 i50309483 A:00 X:00 Y:00 S:E1 P:nvUbdiZc $E364:AD F4 04 LDA Sound_QMusic1 = #$00
  942. f13939 c415112712 i50309484 A:00 X:00 Y:00 S:E1 P:nvUbdiZc $E367:D0 E0 BNE SndMus_QueueCommonJ
  943. f13939 c415112714 i50309485 A:00 X:00 Y:00 S:E1 P:nvUbdiZc $E369:AD F5 04 LDA Sound_QMusic2 = #$00
  944. f13939 c415112718 i50309486 A:00 X:00 Y:00 S:E1 P:nvUbdiZc $E36C:29 F0 AND #$F0
  945. f13939 c415112720 i50309487 A:00 X:00 Y:00 S:E1 P:nvUbdiZc $E36E:F0 D9 BEQ SndMus_QueueCommonJ
  946. f13939 c415112723 i50309488 A:00 X:00 Y:00 S:E1 P:nvUbdiZc $E349:4C EE E3 JMP SndMus_QueueCommon
  947. f13939 c415112726 i50309489 A:00 X:00 Y:00 S:E1 P:nvUbdiZc $E3EE:AD F4 04 LDA Sound_QMusic1 = #$00
  948. f13939 c415112730 i50309490 A:00 X:00 Y:00 S:E1 P:nvUbdiZc $E3F1:D0 52 BNE SndMus_Queue1
  949. f13939 c415112732 i50309491 A:00 X:00 Y:00 S:E1 P:nvUbdiZc $E3F3:AD F5 04 LDA Sound_QMusic2 = #$00
  950. f13939 c415112736 i50309492 A:00 X:00 Y:00 S:E1 P:nvUbdiZc $E3F6:D0 09 BNE $E401
  951. f13939 c415112738 i50309493 A:00 X:00 Y:00 S:E1 P:nvUbdiZc $E3F8:AD E4 04 LDA SndCur_Music1 = #$00
  952. f13939 c415112742 i50309494 A:00 X:00 Y:00 S:E1 P:nvUbdiZc $E3FB:0D E5 04 ORA SndCur_Music2 = #$20
  953. f13939 c415112746 i50309495 A:20 X:00 Y:00 S:E1 P:nvUbdizc $E3FE:D0 EB BNE $E3EB
  954. f13939 c415112750 i50309496 A:20 X:00 Y:00 S:E1 P:nvUbdizc $E3EB:4C C5 E4 JMP Music_Sq2Track
  955. f13939 c415112753 i50309497 A:20 X:00 Y:00 S:E1 P:nvUbdizc $E4C5:CE D4 04 DEC Music_Sq2Rest = #$2D
  956. f13939 c415112759 i50309498 A:20 X:00 Y:00 S:E1 P:nvUbdizc $E4C8:F0 03 BEQ $E4CD
  957. f13939 c415112761 i50309499 A:20 X:00 Y:00 S:E1 P:nvUbdizc $E4CA:4C 7A E5 JMP $E57A
  958. f13939 c415112764 i50309500 A:20 X:00 Y:00 S:E1 P:nvUbdizc $E57A:AD E2 04 LDA SndCur_Level1 = #$00
  959. f13939 c415112768 i50309501 A:00 X:00 Y:00 S:E1 P:nvUbdiZc $E57D:D0 28 BNE $E5A7
  960. f13939 c415112770 i50309502 A:00 X:00 Y:00 S:E1 P:nvUbdiZc $E57F:AD F4 7A LDA Music_Sq2Bend = #$00
  961. f13939 c415112774 i50309503 A:00 X:00 Y:00 S:E1 P:nvUbdiZc $E582:F0 08 BEQ $E58C
  962. f13939 c415112777 i50309504 A:00 X:00 Y:00 S:E1 P:nvUbdiZc $E58C:AC D5 04 LDY Music_Sq2NoteLen = #$00
  963. f13939 c415112781 i50309505 A:00 X:00 Y:00 S:E1 P:nvUbdiZc $E58F:F0 03 BEQ $E594
  964. f13939 c415112784 i50309506 A:00 X:00 Y:00 S:E1 P:nvUbdiZc $E594:AD D3 04 LDA Music_Sq2RestH = #$48
  965. f13939 c415112788 i50309507 A:48 X:00 Y:00 S:E1 P:nvUbdizc $E597:AE F7 07 LDX Music_Sq2Patch = #$D0
  966. f13939 c415112792 i50309508 A:48 X:D0 Y:00 S:E1 P:NvUbdizc $E59A:20 85 E7 JSR Music_PatchGetCTL
  967. f13939 c415112798 i50309509 A:48 X:D0 Y:00 S:DF P:NvUbdizc $E785:48 PHA
  968. f13939 c415112801 i50309510 A:48 X:D0 Y:00 S:DE P:NvUbdizc $E786:8A TXA
  969. f13939 c415112803 i50309511 A:D0 X:D0 Y:00 S:DE P:NvUbdizc $E787:29 70 AND #$70
  970. f13939 c415112805 i50309512 A:50 X:D0 Y:00 S:DE P:nvUbdizc $E789:4A LSR
  971. f13939 c415112807 i50309513 A:28 X:D0 Y:00 S:DE P:nvUbdizc $E78A:4A LSR
  972. f13939 c415112809 i50309514 A:14 X:D0 Y:00 S:DE P:nvUbdizc $E78B:4A LSR
  973. f13939 c415112811 i50309515 A:0A X:D0 Y:00 S:DE P:nvUbdizc $E78C:AA TAX
  974. f13939 c415112813 i50309516 A:0A X:0A Y:00 S:DE P:nvUbdizc $E78D:68 PLA
  975. f13939 c415112817 i50309517 A:48 X:0A Y:00 S:DF P:nvUbdizc $E78E:C9 13 CMP #$13
  976. f13939 c415112819 i50309518 A:48 X:0A Y:00 S:DF P:nvUbdizC $E790:90 0C BCC $E79E
  977. f13939 c415112821 i50309519 A:48 X:0A Y:00 S:DF P:nvUbdizC $E792:BD 65 E7 LDA Music_PatchTableLong,X @ $E76F = #$61
  978. f13939 c415112825 i50309520 A:61 X:0A Y:00 S:DF P:nvUbdizC $E795:85 71 STA Music_PatchAdrL = #$61
  979. f13939 c415112828 i50309521 A:61 X:0A Y:00 S:DF P:nvUbdizC $E797:BD 66 E7 LDA $E766,X @ $E770 = #$B3
  980. f13939 c415112832 i50309522 A:B3 X:0A Y:00 S:DF P:NvUbdizC $E79A:85 72 STA Music_PatchAdrH = #$B3
  981. f13939 c415112835 i50309523 A:B3 X:0A Y:00 S:DF P:NvUbdizC $E79C:D0 0A BNE $E7A8
  982. f13939 c415112838 i50309524 A:B3 X:0A Y:00 S:DF P:NvUbdizC $E7A8:B1 71 LDA ($71),Y @ $B361 = #$50
  983. f13939 c415112843 i50309525 A:50 X:0A Y:00 S:DF P:nvUbdizC $E7AA:60 RTS (from Music_PatchGetCTL) ---------------
  984. f13939 c415112849 i50309526 A:50 X:0A Y:00 S:E1 P:nvUbdizC $E59D:8D 04 40 STA PAPU_CTL2 = #$50
  985. f13939 c415112853 i50309527 A:50 X:0A Y:00 S:E1 P:nvUbdizC $E5A0:A2 7F LDX #$7F
  986. f13939 c415112855 i50309528 A:50 X:7F Y:00 S:E1 P:nvUbdizC $E5A2:8E 05 40 STX PAPU_RAMP2 = #$7F
  987. f13939 c415112859 i50309529 A:50 X:7F Y:00 S:E1 P:nvUbdizC $E5A5:D0 05 BNE Music_Sq1Track
  988. f13939 c415112862 i50309530 A:50 X:7F Y:00 S:E1 P:nvUbdizC $E5AC:CE D6 04 DEC Music_Sq1Rest = #$2D
  989. f13939 c415112868 i50309531 A:50 X:7F Y:00 S:E1 P:nvUbdizC $E5AF:D0 7A BNE $E62B
  990. f13939 c415112872 i50309532 A:50 X:7F Y:00 S:E1 P:nvUbdizC $E62B:AD E1 04 LDA SndCur_Player = #$03
  991. f13939 c415112876 i50309533 A:03 X:7F Y:00 S:E1 P:nvUbdizC $E62E:0D E6 04 ORA SndCur_Map = #$00
  992. f13939 c415112880 i50309534 A:03 X:7F Y:00 S:E1 P:nvUbdizC $E631:D0 2D BNE $E660
  993. f13939 c415112883 i50309535 A:03 X:7F Y:00 S:E1 P:nvUbdizC $E660:A9 00 LDA #$00
  994. f13939 c415112885 i50309536 A:00 X:7F Y:00 S:E1 P:nvUbdiZC $E662:8D F0 7A STA Music_Sq1Bend = #$00
  995. f13939 c415112889 i50309537 A:00 X:7F Y:00 S:E1 P:nvUbdiZC $E665:AD D0 04 LDA Music_TriTrkPos = #$95
  996. f13939 c415112893 i50309538 A:95 X:7F Y:00 S:E1 P:NvUbdizC $E668:F0 53 BEQ Music_NseTrack
  997. f13939 c415112895 i50309539 A:95 X:7F Y:00 S:E1 P:NvUbdizC $E66A:CE D9 04 DEC Music_TriRest = #$2D
  998. f13939 c415112901 i50309540 A:95 X:7F Y:00 S:E1 P:nvUbdizC $E66D:D0 4E BNE Music_NseTrack
  999. f13939 c415112904 i50309541 A:95 X:7F Y:00 S:E1 P:nvUbdizC $E6BD:AD D1 04 LDA Music_NseTrkPos = #$AF
  1000. f13939 c415112908 i50309542 A:AF X:7F Y:00 S:E1 P:NvUbdizC $E6C0:F0 3B BEQ Music_PCMTrack
  1001. f13939 c415112910 i50309543 A:AF X:7F Y:00 S:E1 P:NvUbdizC $E6C2:CE DA 04 DEC Music_NoiseRest = #$F7
  1002. f13939 c415112916 i50309544 A:AF X:7F Y:00 S:E1 P:NvUbdizC $E6C5:D0 36 BNE Music_PCMTrack
  1003. f13939 c415112919 i50309545 A:AF X:7F Y:00 S:E1 P:NvUbdizC $E6FD:4C 09 E7 JMP $E709
  1004. f13939 c415112922 i50309546 A:AF X:7F Y:00 S:E1 P:NvUbdizC $E709:AD D2 04 LDA Music_PCMTrkPos = #$A6
  1005. f13939 c415112926 i50309547 A:A6 X:7F Y:00 S:E1 P:NvUbdizC $E70C:F0 2A BEQ $E738
  1006. f13939 c415112928 i50309548 A:A6 X:7F Y:00 S:E1 P:NvUbdizC $E70E:CE DC 04 DEC Music_DMCRest = #$01 ; DMC is finished resting! We don’t branch.
  1007. f13939 c415112934 i50309549 A:A6 X:7F Y:00 S:E1 P:nvUbdiZC $E711:D0 25 BNE $E738
  1008. f13939 c415112936 i50309550 A:A6 X:7F Y:00 S:E1 P:nvUbdiZC $E713:AC D2 04 LDY Music_PCMTrkPos = #$A6 ;Similar to noise track, we load Y with the PCM track position
  1009. f13939 c415112940 i50309551 A:A6 X:7F Y:A6 S:E1 P:NvUbdizC $E716:EE D2 04 INC Music_PCMTrkPos = #$A6 ; Increment PCM track position
  1010. f13939 c415112946 i50309552 A:A6 X:7F Y:A6 S:E1 P:NvUbdizC $E719:B1 6B LDA ($6B),Y @ $00A6 = #$00 ; Using Y as an index, load next byte from music track.
  1011. f13939 c415112951 i50309553 A:00 X:7F Y:A6 S:E1 P:nvUbdiZC $E71B:F0 24 BEQ $E741 ; ;If zero, reset DMC track position back to the start
  1012. f13939 c415112954 i50309554 A:00 X:7F Y:A6 S:E1 P:nvUbdiZC $E741:AD DE 04 LDA Music_PCMStart = #$95
  1013. f13939 c415112958 i50309555 A:95 X:7F Y:A6 S:E1 P:NvUbdizC $E744:8D D2 04 STA Music_PCMTrkPos = #$A7
  1014. f13939 c415112962 i50309556 A:95 X:7F Y:A6 S:E1 P:NvUbdizC $E747:4C 13 E7 JMP $E713 ; Go back and load in new byte from start of music track. However, we hit a problem! Because $6B and $6C were cleared when the zero page RAM was cleared, they no longer point to the music track data. instead, they point to $0000, indexed with Y = $00A6. This also holds zero! So we try and reset the track back to the start again, to no avail.. we are stuck, again!
  1015. f13939 c415112965 i50309557 A:95 X:7F Y:A6 S:E1 P:NvUbdizC $E713:AC D2 04 LDY Music_PCMTrkPos = #$95
  1016. f13939 c415112969 i50309558 A:95 X:7F Y:95 S:E1 P:NvUbdizC $E716:EE D2 04 INC Music_PCMTrkPos = #$95
  1017. f13939 c415112975 i50309559 A:95 X:7F Y:95 S:E1 P:NvUbdizC $E719:B1 6B LDA ($6B),Y @ $0095 = #$00
  1018. f13939 c415112980 i50309560 A:00 X:7F Y:95 S:E1 P:nvUbdiZC $E71B:F0 24 BEQ $E741
  1019. f13939 c415112983 i50309561 A:00 X:7F Y:95 S:E1 P:nvUbdiZC $E741:AD DE 04 LDA Music_PCMStart = #$95
  1020. f13939 c415112987 i50309562 A:95 X:7F Y:95 S:E1 P:NvUbdizC $E744:8D D2 04 STA Music_PCMTrkPos = #$96
  1021. f13939 c415112991 i50309563 A:95 X:7F Y:95 S:E1 P:NvUbdizC $E747:4C 13 E7 JMP $E713
  1022. f13939 c415112994 i50309564 A:95 X:7F Y:95 S:E1 P:NvUbdizC $E713:AC D2 04 LDY Music_PCMTrkPos = #$95
  1023. f13939 c415112998 i50309565 A:95 X:7F Y:95 S:E1 P:NvUbdizC $E716:EE D2 04 INC Music_PCMTrkPos = #$95
  1024. f13939 c415113004 i50309566 A:95 X:7F Y:95 S:E1 P:NvUbdizC $E719:B1 6B LDA ($6B),Y @ $0095 = #$00
  1025. f13939 c415113009 i50309567 A:00 X:7F Y:95 S:E1 P:nvUbdiZC $E71B:F0 24 BEQ $E741
  1026.  
  1027. So now we have 2 loops to exit, if we want to get out of this mess! Luckily for us, eventually we do exit the loop: Because of Square 2.
  1028. Note that the X value is $7F, so when subsequent NMI’s are finished, X will be returned to $7F.
  1029. This becomes important because after $2c = 44 frames, square 2 will be done resting. It will load the next byte from the music data, but like above, $6B and $6C are still zero, so we load in $00. Unlike the other tracks, if square 2 loads a $00, it signals the end of the Music segment, and loads in either the next segment in the song, or if we hit the end of the song, we restart back to the first segment.
  1030. When this happens, the addresses stored between $6B - $73 are updated! So we are able to exit the loops that we were stuck in.
  1031.  
  1032. f13983 c416423006 i50625994 A:00 X:00 Y:00 S:D5 P:nvUbdiZc $A084:20 4F E3 JSR Sound_PlayMusic
  1033. f13983 c416423012 i50625995 A:00 X:00 Y:00 S:D3 P:nvUbdiZc $E34F:AD F4 04 LDA Sound_QMusic1 = #$00
  1034. f13983 c416423016 i50625996 A:00 X:00 Y:00 S:D3 P:nvUbdiZc $E352:D0 F5 BNE SndMus_QueueCommonJ
  1035. f13983 c416423018 i50625997 A:00 X:00 Y:00 S:D3 P:nvUbdiZc $E354:AD E4 04 LDA SndCur_Music1 = #$00
  1036. f13983 c416423022 i50625998 A:00 X:00 Y:00 S:D3 P:nvUbdiZc $E357:F0 0B BEQ $E364
  1037. f13983 c416423025 i50625999 A:00 X:00 Y:00 S:D3 P:nvUbdiZc $E364:AD F4 04 LDA Sound_QMusic1 = #$00
  1038. f13983 c416423029 i50626000 A:00 X:00 Y:00 S:D3 P:nvUbdiZc $E367:D0 E0 BNE SndMus_QueueCommonJ
  1039. f13983 c416423031 i50626001 A:00 X:00 Y:00 S:D3 P:nvUbdiZc $E369:AD F5 04 LDA Sound_QMusic2 = #$00
  1040. f13983 c416423035 i50626002 A:00 X:00 Y:00 S:D3 P:nvUbdiZc $E36C:29 F0 AND #$F0
  1041. f13983 c416423037 i50626003 A:00 X:00 Y:00 S:D3 P:nvUbdiZc $E36E:F0 D9 BEQ SndMus_QueueCommonJ
  1042. f13983 c416423040 i50626004 A:00 X:00 Y:00 S:D3 P:nvUbdiZc $E349:4C EE E3 JMP SndMus_QueueCommon
  1043. f13983 c416423043 i50626005 A:00 X:00 Y:00 S:D3 P:nvUbdiZc $E3EE:AD F4 04 LDA Sound_QMusic1 = #$00
  1044. f13983 c416423047 i50626006 A:00 X:00 Y:00 S:D3 P:nvUbdiZc $E3F1:D0 52 BNE SndMus_Queue1
  1045. f13983 c416423049 i50626007 A:00 X:00 Y:00 S:D3 P:nvUbdiZc $E3F3:AD F5 04 LDA Sound_QMusic2 = #$00
  1046. f13983 c416423053 i50626008 A:00 X:00 Y:00 S:D3 P:nvUbdiZc $E3F6:D0 09 BNE $E401
  1047. f13983 c416423055 i50626009 A:00 X:00 Y:00 S:D3 P:nvUbdiZc $E3F8:AD E4 04 LDA SndCur_Music1 = #$00
  1048. f13983 c416423059 i50626010 A:00 X:00 Y:00 S:D3 P:nvUbdiZc $E3FB:0D E5 04 ORA SndCur_Music2 = #$20
  1049. f13983 c416423063 i50626011 A:20 X:00 Y:00 S:D3 P:nvUbdizc $E3FE:D0 EB BNE $E3EB
  1050. f13983 c416423067 i50626012 A:20 X:00 Y:00 S:D3 P:nvUbdizc $E3EB:4C C5 E4 JMP Music_Sq2Track
  1051. f13983 c416423070 i50626013 A:20 X:00 Y:00 S:D3 P:nvUbdizc $E4C5:CE D4 04 DEC Music_Sq2Rest = #$01 ; Square 2 is finished resting! Load next Byte from Music segment data
  1052. f13983 c416423076 i50626014 A:20 X:00 Y:00 S:D3 P:nvUbdiZc $E4C8:F0 03 BEQ $E4CD
  1053. f13983 c416423079 i50626015 A:20 X:00 Y:00 S:D3 P:nvUbdiZc $E4CD:AC FE 04 LDY Music_Sq2TrkOff = #$4A
  1054. f13983 c416423083 i50626016 A:20 X:00 Y:4A S:D3 P:nvUbdizc $E4D0:EE FE 04 INC Music_Sq2TrkOff = #$4A
  1055. f13983 c416423089 i50626017 A:20 X:00 Y:4A S:D3 P:nvUbdizc $E4D3:B1 6B LDA ($6B),Y @ $004A = #$00 ; Again, $6B and $6C hold $00, so we load in $00.
  1056. f13983 c416423094 i50626018 A:00 X:00 Y:4A S:D3 P:nvUbdiZc $E4D5:F0 04 BEQ Music_EndSegment ; If $00 byte loaded, this signals the end of the segment!
  1057. f13983 c416423097 i50626019 A:00 X:00 Y:4A S:D3 P:nvUbdiZc $E4DB:AD E4 04 LDA SndCur_Music1 = #$00 ; The following code essentially loads in the new data for the next segment, or if we hit the last segment, loads in the next segment according to Music_Loop.
  1058. f13983 c416423101 i50626020 A:00 X:00 Y:4A S:D3 P:nvUbdiZc $E4DE:F0 17 BEQ $E4F7
  1059. f13983 c416423104 i50626021 A:00 X:00 Y:4A S:D3 P:nvUbdiZc $E4F7:AD E5 04 LDA SndCur_Music2 = #$20
  1060. f13983 c416423108 i50626022 A:20 X:00 Y:4A S:D3 P:nvUbdizc $E4FA:29 F0 AND #$F0
  1061. f13983 c416423110 i50626023 A:20 X:00 Y:4A S:D3 P:nvUbdizc $E4FC:F0 1A BEQ $E518
  1062. f13983 c416423112 i50626024 A:20 X:00 Y:4A S:D3 P:nvUbdizc $E4FE:4C A3 E3 JMP SndMus2B_Next
  1063. f13983 c416423115 i50626025 A:20 X:00 Y:4A S:D3 P:nvUbdizc $E3A3:EE DF 04 INC Music_NextIndex = #$08
  1064. f13983 c416423121 i50626026 A:20 X:00 Y:4A S:D3 P:nvUbdizc $E3A6:AC DF 04 LDY Music_NextIndex = #$09
  1065. f13983 c416423125 i50626027 A:20 X:00 Y:09 S:D3 P:nvUbdizc $E3A9:CC E1 7A CPY Music_End = #$09
  1066. f13983 c416423129 i50626028 A:20 X:00 Y:09 S:D3 P:nvUbdiZC $E3AC:D0 08 BNE SndMus2B_LoadNext
  1067. f13983 c416423131 i50626029 A:20 X:00 Y:09 S:D3 P:nvUbdiZC $E3AE:AD E2 7A LDA Music_Loop = #$07
  1068. f13983 c416423135 i50626030 A:07 X:00 Y:09 S:D3 P:nvUbdizC $E3B1:D0 ED BNE SndMus2B_NextOrStop
  1069. f13983 c416423138 i50626031 A:07 X:00 Y:09 S:D3 P:nvUbdizC $E3A0:8D DF 04 STA Music_NextIndex = #$09
  1070. f13983 c416423142 i50626032 A:07 X:00 Y:09 S:D3 P:nvUbdizC $E3A3:EE DF 04 INC Music_NextIndex = #$07
  1071. f13983 c416423148 i50626033 A:07 X:00 Y:09 S:D3 P:nvUbdizC $E3A6:AC DF 04 LDY Music_NextIndex = #$08
  1072. f13983 c416423152 i50626034 A:07 X:00 Y:08 S:D3 P:nvUbdizC $E3A9:CC E1 7A CPY Music_End = #$09
  1073. f13983 c416423156 i50626035 A:07 X:00 Y:08 S:D3 P:NvUbdizc $E3AC:D0 08 BNE SndMus2B_LoadNext
  1074. f13983 c416423159 i50626036 A:07 X:00 Y:08 S:D3 P:NvUbdizc $E3B6:B9 FF B3 LDA $B3FF,Y @ $B407 = #$BD
  1075. f13983 c416423164 i50626037 A:BD X:00 Y:08 S:D3 P:NvUbdizc $E3B9:A8 TAY
  1076. f13983 c416423166 i50626038 A:BD X:00 Y:BD S:D3 P:NvUbdizc $E3BA:B9 2D B4 LDA $B42D,Y @ $B4EA = #$50
  1077. f13983 c416423170 i50626039 A:50 X:00 Y:BD S:D3 P:nvUbdizc $E3BD:8D FD 04 STA Music_RestH_Base = #$50
  1078. f13983 c416423174 i50626040 A:50 X:00 Y:BD S:D3 P:nvUbdizc $E3C0:B9 2E B4 LDA $B42E,Y @ $B4EB = #$73
  1079. f13983 c416423178 i50626041 A:73 X:00 Y:BD S:D3 P:nvUbdizc $E3C3:85 6B STA Music_Base_L = #$00 ; Updating $6B
  1080. f13983 c416423181 i50626042 A:73 X:00 Y:BD S:D3 P:nvUbdizc $E3C5:B9 2F B4 LDA $B42F,Y @ $B4EC = #$C0
  1081. f13983 c416423185 i50626043 A:C0 X:00 Y:BD S:D3 P:NvUbdizc $E3C8:85 6C STA Music_Base_H = #$00 ; Updating $6C
  1082. f13983 c416423188 i50626044 A:C0 X:00 Y:BD S:D3 P:NvUbdizc $E3CA:B9 30 B4 LDA $B430,Y @ $B4ED = #$4B ; Update all track positions
  1083. f13983 c416423192 i50626045 A:4B X:00 Y:BD S:D3 P:nvUbdizc $E3CD:8D D0 04 STA Music_TriTrkPos = #$95
  1084. f13983 c416423196 i50626046 A:4B X:00 Y:BD S:D3 P:nvUbdizc $E3D0:B9 31 B4 LDA $B431,Y @ $B4EE = #$00
  1085. f13983 c416423200 i50626047 A:00 X:00 Y:BD S:D3 P:nvUbdiZc $E3D3:8D FF 04 STA Music_Sq1TrkOff = #$4A
  1086. f13983 c416423204 i50626048 A:00 X:00 Y:BD S:D3 P:nvUbdiZc $E3D6:B9 32 B4 LDA $B432,Y @ $B4EF = #$AE
  1087. f13983 c416423208 i50626049 A:AE X:00 Y:BD S:D3 P:NvUbdizc $E3D9:8D D1 04 STA Music_NseTrkPos = #$AF
  1088. f13983 c416423212 i50626050 A:AE X:00 Y:BD S:D3 P:NvUbdizc $E3DC:8D F3 07 STA Music_NseStart = #$AE
  1089. f13983 c416423216 i50626051 A:AE X:00 Y:BD S:D3 P:NvUbdizc $E3DF:B9 33 B4 LDA $B433,Y @ $B4F0 = #$95
  1090. f13983 c416423220 i50626052 A:95 X:00 Y:BD S:D3 P:NvUbdizc $E3E2:8D D2 04 STA Music_PCMTrkPos = #$96
  1091. f13983 c416423224 i50626053 A:95 X:00 Y:BD S:D3 P:NvUbdizc $E3E5:8D DE 04 STA Music_PCMStart = #$95
  1092. f13983 c416423228 i50626054 A:95 X:00 Y:BD S:D3 P:NvUbdizc $E3E8:4C 8C E4 JMP $E48C
  1093. f13983 c416423231 i50626055 A:95 X:00 Y:BD S:D3 P:NvUbdizc $E48C:A9 01 LDA #$01 ; Set rests to $01, so that they will all update (since the rest is decremented before it checks if it’s zero)
  1094. f13983 c416423233 i50626056 A:01 X:00 Y:BD S:D3 P:nvUbdizc $E48E:8D D4 04 STA Music_Sq2Rest = #$00
  1095. f13983 c416423237 i50626057 A:01 X:00 Y:BD S:D3 P:nvUbdizc $E491:8D D6 04 STA Music_Sq1Rest = #$01
  1096. f13983 c416423241 i50626058 A:01 X:00 Y:BD S:D3 P:nvUbdizc $E494:8D D9 04 STA Music_TriRest = #$01
  1097. f13983 c416423245 i50626059 A:01 X:00 Y:BD S:D3 P:nvUbdizc $E497:8D DA 04 STA Music_NoiseRest = #$CB
  1098. f13983 c416423249 i50626060 A:01 X:00 Y:BD S:D3 P:nvUbdizc $E49A:8D DC 04 STA Music_DMCRest = #$D5
  1099. f13983 c416423253 i50626061 A:01 X:00 Y:BD S:D3 P:nvUbdizc $E49D:A9 00 LDA #$00 ; Clear a few variables
  1100. f13983 c416423255 i50626062 A:00 X:00 Y:BD S:D3 P:nvUbdiZc $E49F:8D FE 04 STA Music_Sq2TrkOff = #$4B
  1101. f13983 c416423259 i50626063 A:00 X:00 Y:BD S:D3 P:nvUbdiZc $E4A2:8D FA 04 STA Music_Sq1AltRamp = #$00
  1102. f13983 c416423263 i50626064 A:00 X:00 Y:BD S:D3 P:nvUbdiZc $E4A5:8D F0 7A STA Music_Sq1Bend = #$00
  1103. f13983 c416423267 i50626065 A:00 X:00 Y:BD S:D3 P:nvUbdiZc $E4A8:8D F4 7A STA Music_Sq2Bend = #$00
  1104. f13983 c416423271 i50626066 A:00 X:00 Y:BD S:D3 P:nvUbdiZc $E4AB:AD E4 04 LDA SndCur_Music1 = #$00
  1105. f13983 c416423275 i50626067 A:00 X:00 Y:BD S:D3 P:nvUbdiZc $E4AE:C9 01 CMP #$01
  1106. f13983 c416423277 i50626068 A:00 X:00 Y:BD S:D3 P:NvUbdizc $E4B0:D0 09 BNE $E4BB
  1107. f13983 c416423280 i50626069 A:00 X:00 Y:BD S:D3 P:NvUbdizc $E4BB:A9 0B LDA #$0B
  1108. f13983 c416423282 i50626070 A:0B X:00 Y:BD S:D3 P:nvUbdizc $E4BD:8D 15 40 STA PAPU_EN = #$0F
  1109. f13983 c416423286 i50626071 A:0B X:00 Y:BD S:D3 P:nvUbdizc $E4C0:A9 0F LDA #$0F
  1110. f13983 c416423288 i50626072 A:0F X:00 Y:BD S:D3 P:nvUbdizc $E4C2:8D 15 40 STA PAPU_EN = #$0B
  1111. f13983 c416423292 i50626073 A:0F X:00 Y:BD S:D3 P:nvUbdizc $E4C5:CE D4 04 DEC Music_Sq2Rest = #$01
  1112. f13983 c416423298 i50626074 A:0F X:00 Y:BD S:D3 P:nvUbdiZc $E4C8:F0 03 BEQ $E4CD
  1113. f13983 c416423301 i50626075 A:0F X:00 Y:BD S:D3 P:nvUbdiZc $E4CD:AC FE 04 LDY Music_Sq2TrkOff = #$00
  1114. f13983 c416423305 i50626076 A:0F X:00 Y:00 S:D3 P:nvUbdiZc $E4D0:EE FE 04 INC Music_Sq2TrkOff = #$00
  1115. f13983 c416423311 i50626077 A:0F X:00 Y:00 S:D3 P:nvUbdizc $E4D3:B1 6B LDA ($6B),Y @ $C073 = #$DC
  1116. f13983 c416423316 i50626078 A:DC X:00 Y:00 S:D3 P:NvUbdizc $E4D5:F0 04 BEQ Music_EndSegment
  1117. f13983 c416423318 i50626079 A:DC X:00 Y:00 S:D3 P:NvUbdizc $E4D7:10 64 BPL Music_Sq2NoteOn
  1118. f13983 c416423320 i50626080 A:DC X:00 Y:00 S:D3 P:NvUbdizc $E4D9:D0 43 BNE $E51E
  1119. f13983 c416423324 i50626081 A:DC X:00 Y:00 S:D3 P:NvUbdizc $E51E:C9 FF CMP #$FF
  1120. f13983 c416423326 i50626082 A:DC X:00 Y:00 S:D3 P:NvUbdizc $E520:D0 06 BNE $E528
  1121. f13983 c416423329 i50626083 A:DC X:00 Y:00 S:D3 P:NvUbdizc $E528:AA TAX
  1122. f13983 c416423331 i50626084 A:DC X:DC Y:00 S:D3 P:NvUbdizc $E529:29 F0 AND #$F0
  1123. f13983 c416423333 i50626085 A:D0 X:DC Y:00 S:D3 P:NvUbdizc $E52B:8D F7 07 STA Music_Sq2Patch = #$D0
  1124. f13983 c416423337 i50626086 A:D0 X:DC Y:00 S:D3 P:NvUbdizc $E52E:8A TXA
  1125. f13983 c416423339 i50626087 A:DC X:DC Y:00 S:D3 P:NvUbdizc $E52F:20 3B E3 JSR Music_GetRestTicks
  1126. f13983 c416423345 i50626088 A:DC X:DC Y:00 S:D1 P:NvUbdizc $E33B:29 0F AND #$0F
  1127. f13983 c416423347 i50626089 A:0C X:DC Y:00 S:D1 P:nvUbdizc $E33D:18 CLC
  1128. f13983 c416423349 i50626090 A:0C X:DC Y:00 S:D1 P:nvUbdizc $E33E:6D FD 04 ADC Music_RestH_Base = #$50
  1129. f13983 c416423353 i50626091 A:5C X:DC Y:00 S:D1 P:nvUbdizc $E341:6D F7 7A ADC Music_RestH_Off = #$00
  1130. f13983 c416423357 i50626092 A:5C X:DC Y:00 S:D1 P:nvUbdizc $E344:A8 TAY
  1131. f13983 c416423359 i50626093 A:5C X:DC Y:5C S:D1 P:nvUbdizc $E345:B9 74 E8 LDA Music_RestH_LUT,Y @ $E8D0 = #$48
  1132. f13983 c416423363 i50626094 A:48 X:DC Y:5C S:D1 P:nvUbdizc $E348:60 RTS (from Music_GetRestTicks) --------------
  1133. f13983 c416423369 i50626095 A:48 X:DC Y:5C S:D3 P:nvUbdizc $E532:8D D3 04 STA Music_Sq2RestH = #$48
  1134. f13983 c416423373 i50626096 A:48 X:DC Y:5C S:D3 P:nvUbdizc $E535:AC FE 04 LDY Music_Sq2TrkOff = #$01
  1135. f13983 c416423377 i50626097 A:48 X:DC Y:01 S:D3 P:nvUbdizc $E538:EE FE 04 INC Music_Sq2TrkOff = #$01
  1136. f13983 c416423383 i50626098 A:48 X:DC Y:01 S:D3 P:nvUbdizc $E53B:B1 6B LDA ($6B),Y @ $C074 = #$7E
  1137. f13983 c416423388 i50626099 A:7E X:DC Y:01 S:D3 P:nvUbdizc $E53D:AA TAX
  1138. f13983 c416423390 i50626100 A:7E X:7E Y:01 S:D3 P:nvUbdizc $E53E:AD E2 04 LDA SndCur_Level1 = #$00
  1139. f13983 c416423394 i50626101 A:00 X:7E Y:01 S:D3 P:nvUbdiZc $E541:D0 31 BNE $E574
  1140. f13983 c416423396 i50626102 A:00 X:7E Y:01 S:D3 P:nvUbdiZc $E543:8A TXA
  1141. f13983 c416423398 i50626103 A:7E X:7E Y:01 S:D3 P:nvUbdizc $E544:20 31 E8 JSR Sound_Sq2_NoteOn_NoPAPURAMP
  1142. f13983 c416423404 i50626104 A:7E X:7E Y:01 S:D1 P:nvUbdizc $E831:A2 04 LDX #$04
  1143. f13983 c416423406 i50626105 A:7E X:04 Y:01 S:D1 P:nvUbdizc $E833:D0 8C BNE $E7C1
  1144. f13983 c416423410 i50626106 A:7E X:04 Y:01 S:D1 P:nvUbdizc $E7C1:C9 7E CMP #$7E
  1145. f13983 c416423412 i50626107 A:7E X:04 Y:01 S:D1 P:nvUbdiZC $E7C3:D0 03 BNE $E7C8
  1146. f13983 c416423414 i50626108 A:7E X:04 Y:01 S:D1 P:nvUbdiZC $E7C5:A9 00 LDA #$00
  1147. f13983 c416423416 i50626109 A:00 X:04 Y:01 S:D1 P:nvUbdiZC $E7C7:60 RTS (from Sound_Sq2_NoteOn_NoPAPURAMP) -----
  1148. f13983 c416423422 i50626110 A:00 X:04 Y:01 S:D3 P:nvUbdiZC $E547:A8 TAY
  1149. f13983 c416423424 i50626111 A:00 X:04 Y:00 S:D3 P:nvUbdiZC $E548:D0 06 BNE $E550
  1150. f13983 c416423426 i50626112 A:00 X:04 Y:00 S:D3 P:nvUbdiZC $E54A:AD FB 04 LDA Music_LOST4FB = #$00
  1151. f13983 c416423430 i50626113 A:00 X:04 Y:00 S:D3 P:nvUbdiZC $E54D:4C 59 E5 JMP $E559
  1152. f13983 c416423433 i50626114 A:00 X:04 Y:00 S:D3 P:nvUbdiZC $E559:8D D5 04 STA Music_Sq2NoteLen = #$00
  1153. f13983 c416423437 i50626115 A:00 X:04 Y:00 S:D3 P:nvUbdiZC $E55C:AC FE 04 LDY Music_Sq2TrkOff = #$02
  1154. f13983 c416423441 i50626116 A:00 X:04 Y:02 S:D3 P:nvUbdizC $E55F:EE FE 04 INC Music_Sq2TrkOff = #$02
  1155. f13983 c416423447 i50626117 A:00 X:04 Y:02 S:D3 P:nvUbdizC $E562:B1 6B LDA ($6B),Y @ $C075 = #$7E
  1156. f13983 c416423452 i50626118 A:7E X:04 Y:02 S:D3 P:nvUbdizC $E564:C9 FF CMP #$FF
  1157. f13983 c416423454 i50626119 A:7E X:04 Y:02 S:D3 P:nvUbdizc $E566:D0 09 BNE $E571
  1158. f13983 c416423457 i50626120 A:7E X:04 Y:02 S:D3 P:nvUbdizc $E571:CE FE 04 DEC Music_Sq2TrkOff = #$03
  1159. f13983 c416423463 i50626121 A:7E X:04 Y:02 S:D3 P:nvUbdizc $E574:AD D3 04 LDA Music_Sq2RestH = #$48
  1160. f13983 c416423467 i50626122 A:48 X:04 Y:02 S:D3 P:nvUbdizc $E577:8D D4 04 STA Music_Sq2Rest = #$00
  1161. f13983 c416423471 i50626123 A:48 X:04 Y:02 S:D3 P:nvUbdizc $E57A:AD E2 04 LDA SndCur_Level1 = #$00
  1162. f13983 c416423475 i50626124 A:00 X:04 Y:02 S:D3 P:nvUbdiZc $E57D:D0 28 BNE $E5A7
  1163. f13983 c416423477 i50626125 A:00 X:04 Y:02 S:D3 P:nvUbdiZc $E57F:AD F4 7A LDA Music_Sq2Bend = #$00
  1164. f13983 c416423481 i50626126 A:00 X:04 Y:02 S:D3 P:nvUbdiZc $E582:F0 08 BEQ $E58C
  1165. f13983 c416423484 i50626127 A:00 X:04 Y:02 S:D3 P:nvUbdiZc $E58C:AC D5 04 LDY Music_Sq2NoteLen = #$00
  1166. f13983 c416423488 i50626128 A:00 X:04 Y:00 S:D3 P:nvUbdiZc $E58F:F0 03 BEQ $E594
  1167. f13983 c416423491 i50626129 A:00 X:04 Y:00 S:D3 P:nvUbdiZc $E594:AD D3 04 LDA Music_Sq2RestH = #$48
  1168. f13983 c416423495 i50626130 A:48 X:04 Y:00 S:D3 P:nvUbdizc $E597:AE F7 07 LDX Music_Sq2Patch = #$D0
  1169. f13983 c416423499 i50626131 A:48 X:D0 Y:00 S:D3 P:NvUbdizc $E59A:20 85 E7 JSR Music_PatchGetCTL
  1170. f13983 c416423505 i50626132 A:48 X:D0 Y:00 S:D1 P:NvUbdizc $E785:48 PHA
  1171. f13983 c416423508 i50626133 A:48 X:D0 Y:00 S:D0 P:NvUbdizc $E786:8A TXA
  1172. f13983 c416423510 i50626134 A:D0 X:D0 Y:00 S:D0 P:NvUbdizc $E787:29 70 AND #$70
  1173. f13983 c416423512 i50626135 A:50 X:D0 Y:00 S:D0 P:nvUbdizc $E789:4A LSR
  1174. f13983 c416423514 i50626136 A:28 X:D0 Y:00 S:D0 P:nvUbdizc $E78A:4A LSR
  1175. f13983 c416423516 i50626137 A:14 X:D0 Y:00 S:D0 P:nvUbdizc $E78B:4A LSR
  1176. f13983 c416423518 i50626138 A:0A X:D0 Y:00 S:D0 P:nvUbdizc $E78C:AA TAX
  1177. f13983 c416423520 i50626139 A:0A X:0A Y:00 S:D0 P:nvUbdizc $E78D:68 PLA
  1178. f13983 c416423524 i50626140 A:48 X:0A Y:00 S:D1 P:nvUbdizc $E78E:C9 13 CMP #$13
  1179. f13983 c416423526 i50626141 A:48 X:0A Y:00 S:D1 P:nvUbdizC $E790:90 0C BCC $E79E
  1180. f13983 c416423528 i50626142 A:48 X:0A Y:00 S:D1 P:nvUbdizC $E792:BD 65 E7 LDA Music_PatchTableLong,X @ $E76F = #$61
  1181. f13983 c416423532 i50626143 A:61 X:0A Y:00 S:D1 P:nvUbdizC $E795:85 71 STA Music_PatchAdrL = #$61
  1182. f13983 c416423535 i50626144 A:61 X:0A Y:00 S:D1 P:nvUbdizC $E797:BD 66 E7 LDA $E766,X @ $E770 = #$B3
  1183. f13983 c416423539 i50626145 A:B3 X:0A Y:00 S:D1 P:NvUbdizC $E79A:85 72 STA Music_PatchAdrH = #$B3
  1184. f13983 c416423542 i50626146 A:B3 X:0A Y:00 S:D1 P:NvUbdizC $E79C:D0 0A BNE $E7A8
  1185. f13983 c416423545 i50626147 A:B3 X:0A Y:00 S:D1 P:NvUbdizC $E7A8:B1 71 LDA ($71),Y @ $B361 = #$50
  1186. f13983 c416423550 i50626148 A:50 X:0A Y:00 S:D1 P:nvUbdizC $E7AA:60 RTS (from Music_PatchGetCTL) ---------------
  1187. f13983 c416423556 i50626149 A:50 X:0A Y:00 S:D3 P:nvUbdizC $E59D:8D 04 40 STA PAPU_CTL2 = #$50
  1188. f13983 c416423560 i50626150 A:50 X:0A Y:00 S:D3 P:nvUbdizC $E5A0:A2 7F LDX #$7F
  1189. f13983 c416423562 i50626151 A:50 X:7F Y:00 S:D3 P:nvUbdizC $E5A2:8E 05 40 STX PAPU_RAMP2 = #$7F
  1190. f13983 c416423566 i50626152 A:50 X:7F Y:00 S:D3 P:nvUbdizC $E5A5:D0 05 BNE Music_Sq1Track
  1191. f13983 c416423569 i50626153 A:50 X:7F Y:00 S:D3 P:nvUbdizC $E5AC:CE D6 04 DEC Music_Sq1Rest = #$01
  1192. f13983 c416423575 i50626154 A:50 X:7F Y:00 S:D3 P:nvUbdiZC $E5AF:D0 7A BNE $E62B
  1193. f13983 c416423577 i50626155 A:50 X:7F Y:00 S:D3 P:nvUbdiZC $E5B1:AC FF 04 LDY Music_Sq1TrkOff = #$00
  1194. f13983 c416423581 i50626156 A:50 X:7F Y:00 S:D3 P:nvUbdiZC $E5B4:EE FF 04 INC Music_Sq1TrkOff = #$00
  1195. f13983 c416423587 i50626157 A:50 X:7F Y:00 S:D3 P:nvUbdizC $E5B7:B1 6B LDA ($6B),Y @ $C073 = #$DC
  1196. f13983 c416423592 i50626158 A:DC X:7F Y:00 S:D3 P:NvUbdizC $E5B9:10 1F BPL $E5DA
  1197. f13983 c416423594 i50626159 A:DC X:7F Y:00 S:D3 P:NvUbdizC $E5BB:C9 FF CMP #$FF
  1198. f13983 c416423596 i50626160 A:DC X:7F Y:00 S:D3 P:NvUbdizc $E5BD:D0 06 BNE $E5C5
  1199. f13983 c416423599 i50626161 A:DC X:7F Y:00 S:D3 P:NvUbdizc $E5C5:AA TAX
  1200. f13983 c416423601 i50626162 A:DC X:DC Y:00 S:D3 P:NvUbdizc $E5C6:29 F0 AND #$F0
  1201. f13983 c416423603 i50626163 A:D0 X:DC Y:00 S:D3 P:NvUbdizc $E5C8:8D F8 07 STA Music_Sq1Patch = #$D0
  1202. f13983 c416423607 i50626164 A:D0 X:DC Y:00 S:D3 P:NvUbdizc $E5CB:8A TXA
  1203. f13983 c416423609 i50626165 A:DC X:DC Y:00 S:D3 P:NvUbdizc $E5CC:20 3B E3 JSR Music_GetRestTicks
  1204. f13983 c416423615 i50626166 A:DC X:DC Y:00 S:D1 P:NvUbdizc $E33B:29 0F AND #$0F
  1205. f13983 c416423617 i50626167 A:0C X:DC Y:00 S:D1 P:nvUbdizc $E33D:18 CLC
  1206. f13983 c416423619 i50626168 A:0C X:DC Y:00 S:D1 P:nvUbdizc $E33E:6D FD 04 ADC Music_RestH_Base = #$50
  1207. f13983 c416423623 i50626169 A:5C X:DC Y:00 S:D1 P:nvUbdizc $E341:6D F7 7A ADC Music_RestH_Off = #$00
  1208. f13983 c416423627 i50626170 A:5C X:DC Y:00 S:D1 P:nvUbdizc $E344:A8 TAY
  1209. f13983 c416423629 i50626171 A:5C X:DC Y:5C S:D1 P:nvUbdizc $E345:B9 74 E8 LDA Music_RestH_LUT,Y @ $E8D0 = #$48
  1210. f13983 c416423633 i50626172 A:48 X:DC Y:5C S:D1 P:nvUbdizc $E348:60 RTS (from Music_GetRestTicks) --------------
  1211. f13983 c416423639 i50626173 A:48 X:DC Y:5C S:D3 P:nvUbdizc $E5CF:8D F9 04 STA Music_Sq1RestH = #$48
  1212. f13983 c416423643 i50626174 A:48 X:DC Y:5C S:D3 P:nvUbdizc $E5D2:AC FF 04 LDY Music_Sq1TrkOff = #$01
  1213. f13983 c416423647 i50626175 A:48 X:DC Y:01 S:D3 P:nvUbdizc $E5D5:EE FF 04 INC Music_Sq1TrkOff = #$01
  1214. f13983 c416423653 i50626176 A:48 X:DC Y:01 S:D3 P:nvUbdizc $E5D8:B1 6B LDA ($6B),Y @ $C074 = #$7E
  1215. f13983 c416423658 i50626177 A:7E X:DC Y:01 S:D3 P:nvUbdizc $E5DA:A8 TAY
  1216. f13983 c416423660 i50626178 A:7E X:DC Y:7E S:D3 P:nvUbdizc $E5DB:D0 0F BNE Music_Sq1NoteOn
  1217. f13983 c416423663 i50626179 A:7E X:DC Y:7E S:D3 P:nvUbdizc $E5EC:AA TAX
  1218. f13983 c416423665 i50626180 A:7E X:7E Y:7E S:D3 P:nvUbdizc $E5ED:AD E1 04 LDA SndCur_Player = #$00
  1219. f13983 c416423669 i50626181 A:00 X:7E Y:7E S:D3 P:nvUbdiZc $E5F0:0D E6 04 ORA SndCur_Map = #$00
  1220. f13983 c416423673 i50626182 A:00 X:7E Y:7E S:D3 P:nvUbdiZc $E5F3:D0 30 BNE $E625
  1221. f13983 c416423675 i50626183 A:00 X:7E Y:7E S:D3 P:nvUbdiZc $E5F5:8A TXA
  1222. f13983 c416423677 i50626184 A:7E X:7E Y:7E S:D3 P:nvUbdizc $E5F6:20 BF E7 JSR Sound_Sq1_NoteOn_NoPAPURAMP
  1223. f13983 c416423683 i50626185 A:7E X:7E Y:7E S:D1 P:nvUbdizc $E7BF:A2 00 LDX #$00
  1224. f13983 c416423685 i50626186 A:7E X:00 Y:7E S:D1 P:nvUbdiZc $E7C1:C9 7E CMP #$7E
  1225. f13983 c416423687 i50626187 A:7E X:00 Y:7E S:D1 P:nvUbdiZC $E7C3:D0 03 BNE $E7C8
  1226. f13983 c416423689 i50626188 A:7E X:00 Y:7E S:D1 P:nvUbdiZC $E7C5:A9 00 LDA #$00
  1227. f13983 c416423691 i50626189 A:00 X:00 Y:7E S:D1 P:nvUbdiZC $E7C7:60 RTS (from Sound_Sq1_NoteOn_NoPAPURAMP) -----
  1228. f13983 c416423697 i50626190 A:00 X:00 Y:7E S:D3 P:nvUbdiZC $E5F9:D0 06 BNE $E601
  1229. f13983 c416423699 i50626191 A:00 X:00 Y:7E S:D3 P:nvUbdiZC $E5FB:AD FB 04 LDA Music_LOST4FB = #$00
  1230. f13983 c416423703 i50626192 A:00 X:00 Y:7E S:D3 P:nvUbdiZC $E5FE:4C 0A E6 JMP $E60A
  1231. f13983 c416423706 i50626193 A:00 X:00 Y:7E S:D3 P:nvUbdiZC $E60A:8D D7 04 STA Music_Sq1NoteLen = #$00
  1232. f13983 c416423710 i50626194 A:00 X:00 Y:7E S:D3 P:nvUbdiZC $E60D:AC FF 04 LDY Music_Sq1TrkOff = #$02
  1233. f13983 c416423714 i50626195 A:00 X:00 Y:02 S:D3 P:nvUbdizC $E610:EE FF 04 INC Music_Sq1TrkOff = #$02
  1234. f13983 c416423720 i50626196 A:00 X:00 Y:02 S:D3 P:nvUbdizC $E613:B1 6B LDA ($6B),Y @ $C075 = #$7E
  1235. f13983 c416423725 i50626197 A:7E X:00 Y:02 S:D3 P:nvUbdizC $E615:C9 FF CMP #$FF
  1236. f13983 c416423727 i50626198 A:7E X:00 Y:02 S:D3 P:nvUbdizc $E617:D0 09 BNE $E622
  1237. f13983 c416423730 i50626199 A:7E X:00 Y:02 S:D3 P:nvUbdizc $E622:CE FF 04 DEC Music_Sq1TrkOff = #$03
  1238. f13983 c416423736 i50626200 A:7E X:00 Y:02 S:D3 P:nvUbdizc $E625:AD F9 04 LDA Music_Sq1RestH = #$48
  1239. f13983 c416423740 i50626201 A:48 X:00 Y:02 S:D3 P:nvUbdizc $E628:8D D6 04 STA Music_Sq1Rest = #$00
  1240. f13983 c416423744 i50626202 A:48 X:00 Y:02 S:D3 P:nvUbdizc $E62B:AD E1 04 LDA SndCur_Player = #$00
  1241. f13983 c416423748 i50626203 A:00 X:00 Y:02 S:D3 P:nvUbdiZc $E62E:0D E6 04 ORA SndCur_Map = #$00
  1242. f13983 c416423752 i50626204 A:00 X:00 Y:02 S:D3 P:nvUbdiZc $E631:D0 2D BNE $E660
  1243. f13983 c416423754 i50626205 A:00 X:00 Y:02 S:D3 P:nvUbdiZc $E633:AD F0 7A LDA Music_Sq1Bend = #$00
  1244. f13983 c416423758 i50626206 A:00 X:00 Y:02 S:D3 P:nvUbdiZc $E636:F0 08 BEQ $E640
  1245. f13983 c416423761 i50626207 A:00 X:00 Y:02 S:D3 P:nvUbdiZc $E640:AC D7 04 LDY Music_Sq1NoteLen = #$00
  1246. f13983 c416423765 i50626208 A:00 X:00 Y:00 S:D3 P:nvUbdiZc $E643:F0 03 BEQ $E648
  1247. f13983 c416423768 i50626209 A:00 X:00 Y:00 S:D3 P:nvUbdiZc $E648:AD F9 04 LDA Music_Sq1RestH = #$48
  1248. f13983 c416423772 i50626210 A:48 X:00 Y:00 S:D3 P:nvUbdizc $E64B:AE F8 07 LDX Music_Sq1Patch = #$D0
  1249. f13983 c416423776 i50626211 A:48 X:D0 Y:00 S:D3 P:NvUbdizc $E64E:20 85 E7 JSR Music_PatchGetCTL
  1250. f13983 c416423782 i50626212 A:48 X:D0 Y:00 S:D1 P:NvUbdizc $E785:48 PHA
  1251. f13983 c416423785 i50626213 A:48 X:D0 Y:00 S:D0 P:NvUbdizc $E786:8A TXA
  1252. f13983 c416423787 i50626214 A:D0 X:D0 Y:00 S:D0 P:NvUbdizc $E787:29 70 AND #$70
  1253. f13983 c416423789 i50626215 A:50 X:D0 Y:00 S:D0 P:nvUbdizc $E789:4A LSR
  1254. f13983 c416423791 i50626216 A:28 X:D0 Y:00 S:D0 P:nvUbdizc $E78A:4A LSR
  1255. f13983 c416423793 i50626217 A:14 X:D0 Y:00 S:D0 P:nvUbdizc $E78B:4A LSR
  1256. f13983 c416423795 i50626218 A:0A X:D0 Y:00 S:D0 P:nvUbdizc $E78C:AA TAX
  1257. f13983 c416423797 i50626219 A:0A X:0A Y:00 S:D0 P:nvUbdizc $E78D:68 PLA
  1258. f13983 c416423801 i50626220 A:48 X:0A Y:00 S:D1 P:nvUbdizc $E78E:C9 13 CMP #$13
  1259. f13983 c416423803 i50626221 A:48 X:0A Y:00 S:D1 P:nvUbdizC $E790:90 0C BCC $E79E
  1260. f13983 c416423805 i50626222 A:48 X:0A Y:00 S:D1 P:nvUbdizC $E792:BD 65 E7 LDA Music_PatchTableLong,X @ $E76F = #$61
  1261. f13983 c416423809 i50626223 A:61 X:0A Y:00 S:D1 P:nvUbdizC $E795:85 71 STA Music_PatchAdrL = #$61
  1262. f13983 c416423812 i50626224 A:61 X:0A Y:00 S:D1 P:nvUbdizC $E797:BD 66 E7 LDA $E766,X @ $E770 = #$B3
  1263. f13983 c416423816 i50626225 A:B3 X:0A Y:00 S:D1 P:NvUbdizC $E79A:85 72 STA Music_PatchAdrH = #$B3
  1264. f13983 c416423819 i50626226 A:B3 X:0A Y:00 S:D1 P:NvUbdizC $E79C:D0 0A BNE $E7A8
  1265. f13983 c416423822 i50626227 A:B3 X:0A Y:00 S:D1 P:NvUbdizC $E7A8:B1 71 LDA ($71),Y @ $B361 = #$50
  1266. f13983 c416423827 i50626228 A:50 X:0A Y:00 S:D1 P:nvUbdizC $E7AA:60 RTS (from Music_PatchGetCTL) ---------------
  1267. f13983 c416423833 i50626229 A:50 X:0A Y:00 S:D3 P:nvUbdizC $E651:8D 00 40 STA PAPU_CTL1 = #$50
  1268. f13983 c416423837 i50626230 A:50 X:0A Y:00 S:D3 P:nvUbdizC $E654:AD FA 04 LDA Music_Sq1AltRamp = #$00
  1269. f13983 c416423841 i50626231 A:00 X:0A Y:00 S:D3 P:nvUbdiZC $E657:D0 02 BNE $E65B
  1270. f13983 c416423843 i50626232 A:00 X:0A Y:00 S:D3 P:nvUbdiZC $E659:A9 7F LDA #$7F
  1271. f13983 c416423845 i50626233 A:7F X:0A Y:00 S:D3 P:nvUbdizC $E65B:8D 01 40 STA PAPU_RAMP1 = #$7F
  1272. f13983 c416423849 i50626234 A:7F X:0A Y:00 S:D3 P:nvUbdizC $E65E:D0 05 BNE Music_TriTrack
  1273. f13983 c416423852 i50626235 A:7F X:0A Y:00 S:D3 P:nvUbdizC $E665:AD D0 04 LDA Music_TriTrkPos = #$4B
  1274. f13983 c416423856 i50626236 A:4B X:0A Y:00 S:D3 P:nvUbdizC $E668:F0 53 BEQ Music_NseTrack
  1275. f13983 c416423858 i50626237 A:4B X:0A Y:00 S:D3 P:nvUbdizC $E66A:CE D9 04 DEC Music_TriRest = #$01
  1276. f13983 c416423864 i50626238 A:4B X:0A Y:00 S:D3 P:nvUbdiZC $E66D:D0 4E BNE Music_NseTrack
  1277. f13983 c416423866 i50626239 A:4B X:0A Y:00 S:D3 P:nvUbdiZC $E66F:AC D0 04 LDY Music_TriTrkPos = #$4B
  1278. f13983 c416423870 i50626240 A:4B X:0A Y:4B S:D3 P:nvUbdizC $E672:EE D0 04 INC Music_TriTrkPos = #$4B
  1279. f13983 c416423876 i50626241 A:4B X:0A Y:4B S:D3 P:nvUbdizC $E675:B1 6B LDA ($6B),Y @ $C0BE = #$8C
  1280. f13983 c416423881 i50626242 A:8C X:0A Y:4B S:D3 P:NvUbdizC $E677:10 15 BPL Music_TriNoteOn
  1281. f13983 c416423883 i50626243 A:8C X:0A Y:4B S:D3 P:NvUbdizC $E679:20 3B E3 JSR Music_GetRestTicks
  1282. f13983 c416423889 i50626244 A:8C X:0A Y:4B S:D1 P:NvUbdizC $E33B:29 0F AND #$0F
  1283. f13983 c416423891 i50626245 A:0C X:0A Y:4B S:D1 P:nvUbdizC $E33D:18 CLC
  1284. f13983 c416423893 i50626246 A:0C X:0A Y:4B S:D1 P:nvUbdizc $E33E:6D FD 04 ADC Music_RestH_Base = #$50
  1285. f13983 c416423897 i50626247 A:5C X:0A Y:4B S:D1 P:nvUbdizc $E341:6D F7 7A ADC Music_RestH_Off = #$00
  1286. f13983 c416423901 i50626248 A:5C X:0A Y:4B S:D1 P:nvUbdizc $E344:A8 TAY
  1287. f13983 c416423903 i50626249 A:5C X:0A Y:5C S:D1 P:nvUbdizc $E345:B9 74 E8 LDA Music_RestH_LUT,Y @ $E8D0 = #$48
  1288. f13983 c416423907 i50626250 A:48 X:0A Y:5C S:D1 P:nvUbdizc $E348:60 RTS (from Music_GetRestTicks) --------------
  1289. f13983 c416423913 i50626251 A:48 X:0A Y:5C S:D3 P:nvUbdizc $E67C:8D D8 04 STA Music_TriRestH = #$48
  1290. f13983 c416423917 i50626252 A:48 X:0A Y:5C S:D3 P:nvUbdizc $E67F:A9 1F LDA #$1F
  1291. f13983 c416423919 i50626253 A:1F X:0A Y:5C S:D3 P:nvUbdizc $E681:8D 08 40 STA PAPU_TCR1 = #$80
  1292. f13983 c416423923 i50626254 A:1F X:0A Y:5C S:D3 P:nvUbdizc $E684:AC D0 04 LDY Music_TriTrkPos = #$4C
  1293. f13983 c416423927 i50626255 A:1F X:0A Y:4C S:D3 P:nvUbdizc $E687:EE D0 04 INC Music_TriTrkPos = #$4C
  1294. f13983 c416423933 i50626256 A:1F X:0A Y:4C S:D3 P:nvUbdizc $E68A:B1 6B LDA ($6B),Y @ $C0BF = #$7E
  1295. f13983 c416423938 i50626257 A:7E X:0A Y:4C S:D3 P:nvUbdizc $E68C:F0 26 BEQ $E6B4
  1296. f13983 c416423940 i50626258 A:7E X:0A Y:4C S:D3 P:nvUbdizc $E68E:20 35 E8 JSR Sound_Tri_NoteOn
  1297. f13983 c416423946 i50626259 A:7E X:0A Y:4C S:D1 P:nvUbdizc $E835:A2 08 LDX #$08
  1298. f13983 c416423948 i50626260 A:7E X:08 Y:4C S:D1 P:nvUbdizc $E837:D0 88 BNE $E7C1
  1299. f13983 c416423952 i50626261 A:7E X:08 Y:4C S:D1 P:nvUbdizc $E7C1:C9 7E CMP #$7E
  1300. f13983 c416423954 i50626262 A:7E X:08 Y:4C S:D1 P:nvUbdiZC $E7C3:D0 03 BNE $E7C8
  1301. f13983 c416423956 i50626263 A:7E X:08 Y:4C S:D1 P:nvUbdiZC $E7C5:A9 00 LDA #$00
  1302. f13983 c416423958 i50626264 A:00 X:08 Y:4C S:D1 P:nvUbdiZC $E7C7:60 RTS (from Sound_Tri_NoteOn) ----------------
  1303. f13983 c416423964 i50626265 A:00 X:08 Y:4C S:D3 P:nvUbdiZC $E691:F0 1F BEQ $E6B2
  1304. f13983 c416423967 i50626266 A:00 X:08 Y:4C S:D3 P:nvUbdiZC $E6B2:A9 80 LDA #$80
  1305. f13983 c416423969 i50626267 A:80 X:08 Y:4C S:D3 P:NvUbdizC $E6B4:8D 08 40 STA PAPU_TCR1 = #$1F
  1306. f13983 c416423973 i50626268 A:80 X:08 Y:4C S:D3 P:NvUbdizC $E6B7:AE D8 04 LDX Music_TriRestH = #$48
  1307. f13983 c416423977 i50626269 A:80 X:48 Y:4C S:D3 P:nvUbdizC $E6BA:8E D9 04 STX Music_TriRest = #$00
  1308. f13983 c416423981 i50626270 A:80 X:48 Y:4C S:D3 P:nvUbdizC $E6BD:AD D1 04 LDA Music_NseTrkPos = #$AE
  1309. f13983 c416423985 i50626271 A:AE X:48 Y:4C S:D3 P:NvUbdizC $E6C0:F0 3B BEQ Music_PCMTrack
  1310. f13983 c416423987 i50626272 A:AE X:48 Y:4C S:D3 P:NvUbdizC $E6C2:CE DA 04 DEC Music_NoiseRest = #$01
  1311. f13983 c416423993 i50626273 A:AE X:48 Y:4C S:D3 P:nvUbdiZC $E6C5:D0 36 BNE Music_PCMTrack
  1312. f13983 c416423995 i50626274 A:AE X:48 Y:4C S:D3 P:nvUbdiZC $E6C7:AC D1 04 LDY Music_NseTrkPos = #$AE
  1313. f13983 c416423999 i50626275 A:AE X:48 Y:AE S:D3 P:NvUbdizC $E6CA:EE D1 04 INC Music_NseTrkPos = #$AE
  1314. f13983 c416424005 i50626276 A:AE X:48 Y:AE S:D3 P:NvUbdizC $E6CD:B1 6B LDA ($6B),Y @ $C121 = #$84
  1315. f13983 c416424011 i50626277 A:84 X:48 Y:AE S:D3 P:NvUbdizC $E6CF:F0 2F BEQ $E700
  1316. f13983 c416424013 i50626278 A:84 X:48 Y:AE S:D3 P:NvUbdizC $E6D1:10 10 BPL Music_NseNoteOn
  1317. f13983 c416424015 i50626279 A:84 X:48 Y:AE S:D3 P:NvUbdizC $E6D3:20 3B E3 JSR Music_GetRestTicks
  1318. f13983 c416424021 i50626280 A:84 X:48 Y:AE S:D1 P:NvUbdizC $E33B:29 0F AND #$0F
  1319. f13983 c416424023 i50626281 A:04 X:48 Y:AE S:D1 P:nvUbdizC $E33D:18 CLC
  1320. f13983 c416424025 i50626282 A:04 X:48 Y:AE S:D1 P:nvUbdizc $E33E:6D FD 04 ADC Music_RestH_Base = #$50
  1321. f13983 c416424029 i50626283 A:54 X:48 Y:AE S:D1 P:nvUbdizc $E341:6D F7 7A ADC Music_RestH_Off = #$00
  1322. f13983 c416424033 i50626284 A:54 X:48 Y:AE S:D1 P:nvUbdizc $E344:A8 TAY
  1323. f13983 c416424035 i50626285 A:54 X:48 Y:54 S:D1 P:nvUbdizc $E345:B9 74 E8 LDA Music_RestH_LUT,Y @ $E8C8 = #$09
  1324. f13983 c416424039 i50626286 A:09 X:48 Y:54 S:D1 P:nvUbdizc $E348:60 RTS (from Music_GetRestTicks) --------------
  1325. f13983 c416424045 i50626287 A:09 X:48 Y:54 S:D3 P:nvUbdizc $E6D6:8D DB 04 STA Music_NseRestH = #$09
  1326. f13983 c416424049 i50626288 A:09 X:48 Y:54 S:D3 P:nvUbdizc $E6D9:AC D1 04 LDY Music_NseTrkPos = #$AF
  1327. f13983 c416424053 i50626289 A:09 X:48 Y:AF S:D3 P:NvUbdizc $E6DC:EE D1 04 INC Music_NseTrkPos = #$AF
  1328. f13983 c416424059 i50626290 A:09 X:48 Y:AF S:D3 P:NvUbdizc $E6DF:B1 6B LDA ($6B),Y @ $C122 = #$02
  1329. f13983 c416424065 i50626291 A:02 X:48 Y:AF S:D3 P:nvUbdizc $E6E1:F0 1D BEQ $E700
  1330. f13983 c416424067 i50626292 A:02 X:48 Y:AF S:D3 P:nvUbdizc $E6E3:4A LSR
  1331. f13983 c416424069 i50626293 A:01 X:48 Y:AF S:D3 P:nvUbdizc $E6E4:A8 TAY
  1332. f13983 c416424071 i50626294 A:01 X:48 Y:01 S:D3 P:nvUbdizc $E6E5:B9 4A E7 LDA Music_NoiseLUTA,Y @ $E74B = #$1E
  1333. f13983 c416424075 i50626295 A:1E X:48 Y:01 S:D3 P:nvUbdizc $E6E8:8D 0C 40 STA PAPU_NCTL1 = #$1E
  1334. f13983 c416424079 i50626296 A:1E X:48 Y:01 S:D3 P:nvUbdizc $E6EB:B9 4E E7 LDA Music_NoiseLUTB,Y @ $E74F = #$03
  1335. f13983 c416424083 i50626297 A:03 X:48 Y:01 S:D3 P:nvUbdizc $E6EE:8D 0E 40 STA NOISE_LO = #$03
  1336. f13983 c416424087 i50626298 A:03 X:48 Y:01 S:D3 P:nvUbdizc $E6F1:B9 52 E7 LDA Music_NoiseLUTC,Y @ $E753 = #$18
  1337. f13983 c416424091 i50626299 A:18 X:48 Y:01 S:D3 P:nvUbdizc $E6F4:8D 0F 40 STA PAPU_NFREQ2 = #$18
  1338. f13983 c416424095 i50626300 A:18 X:48 Y:01 S:D3 P:nvUbdizc $E6F7:AD DB 04 LDA Music_NseRestH = #$09
  1339. f13983 c416424099 i50626301 A:09 X:48 Y:01 S:D3 P:nvUbdizc $E6FA:8D DA 04 STA Music_NoiseRest = #$00
  1340. f13983 c416424103 i50626302 A:09 X:48 Y:01 S:D3 P:nvUbdizc $E6FD:4C 09 E7 JMP $E709
  1341. f13983 c416424106 i50626303 A:09 X:48 Y:01 S:D3 P:nvUbdizc $E709:AD D2 04 LDA Music_PCMTrkPos = #$95
  1342. f13983 c416424110 i50626304 A:95 X:48 Y:01 S:D3 P:NvUbdizc $E70C:F0 2A BEQ $E738
  1343. f13983 c416424112 i50626305 A:95 X:48 Y:01 S:D3 P:NvUbdizc $E70E:CE DC 04 DEC Music_DMCRest = #$01
  1344. f13983 c416424118 i50626306 A:95 X:48 Y:01 S:D3 P:nvUbdiZc $E711:D0 25 BNE $E738
  1345. f13983 c416424120 i50626307 A:95 X:48 Y:01 S:D3 P:nvUbdiZc $E713:AC D2 04 LDY Music_PCMTrkPos = #$95
  1346. f13983 c416424124 i50626308 A:95 X:48 Y:95 S:D3 P:NvUbdizc $E716:EE D2 04 INC Music_PCMTrkPos = #$95
  1347. f13983 c416424130 i50626309 A:95 X:48 Y:95 S:D3 P:NvUbdizc $E719:B1 6B LDA ($6B),Y @ $C108 = #$8A
  1348. f13983 c416424136 i50626310 A:8A X:48 Y:95 S:D3 P:NvUbdizc $E71B:F0 24 BEQ $E741
  1349. f13983 c416424138 i50626311 A:8A X:48 Y:95 S:D3 P:NvUbdizc $E71D:10 10 BPL $E72F
  1350. f13983 c416424140 i50626312 A:8A X:48 Y:95 S:D3 P:NvUbdizc $E71F:20 3B E3 JSR Music_GetRestTicks
  1351. f13983 c416424146 i50626313 A:8A X:48 Y:95 S:D1 P:NvUbdizc $E33B:29 0F AND #$0F
  1352. f13983 c416424148 i50626314 A:0A X:48 Y:95 S:D1 P:nvUbdizc $E33D:18 CLC
  1353. f13983 c416424150 i50626315 A:0A X:48 Y:95 S:D1 P:nvUbdizc $E33E:6D FD 04 ADC Music_RestH_Base = #$50
  1354. f13983 c416424154 i50626316 A:5A X:48 Y:95 S:D1 P:nvUbdizc $E341:6D F7 7A ADC Music_RestH_Off = #$00
  1355. f13983 c416424158 i50626317 A:5A X:48 Y:95 S:D1 P:nvUbdizc $E344:A8 TAY
  1356. f13983 c416424160 i50626318 A:5A X:48 Y:5A S:D1 P:nvUbdizc $E345:B9 74 E8 LDA Music_RestH_LUT,Y @ $E8CE = #$24
  1357. f13983 c416424164 i50626319 A:24 X:48 Y:5A S:D1 P:nvUbdizc $E348:60 RTS (from Music_GetRestTicks) --------------
  1358. f13983 c416424170 i50626320 A:24 X:48 Y:5A S:D3 P:nvUbdizc $E722:8D DD 04 STA Music_DMCRestH = #$12
  1359. f13983 c416424174 i50626321 A:24 X:48 Y:5A S:D3 P:nvUbdizc $E725:AC D2 04 LDY Music_PCMTrkPos = #$96
  1360. f13983 c416424178 i50626322 A:24 X:48 Y:96 S:D3 P:NvUbdizc $E728:EE D2 04 INC Music_PCMTrkPos = #$96
  1361. f13983 c416424184 i50626323 A:24 X:48 Y:96 S:D3 P:NvUbdizc $E72B:B1 6B LDA ($6B),Y @ $C109 = #$01
  1362. f13983 c416424190 i50626324 A:01 X:48 Y:96 S:D3 P:nvUbdizc $E72D:F0 12 BEQ $E741
  1363. f13983 c416424192 i50626325 A:01 X:48 Y:96 S:D3 P:nvUbdizc $E72F:8D F0 07 STA DMC_Queue = #$00
  1364. f13983 c416424196 i50626326 A:01 X:48 Y:96 S:D3 P:nvUbdizc $E732:AD DD 04 LDA Music_DMCRestH = #$24
  1365. f13983 c416424200 i50626327 A:24 X:48 Y:96 S:D3 P:nvUbdizc $E735:8D DC 04 STA Music_DMCRest = #$00
  1366. f13983 c416424204 i50626328 A:24 X:48 Y:96 S:D3 P:nvUbdizc $E738:20 C0 E2 JSR Music_PlayDMC
  1367. f13983 c416424210 i50626329 A:24 X:48 Y:96 S:D1 P:nvUbdizc $E2C0:AD F0 07 LDA DMC_Queue = #$01
  1368. f13983 c416424214 i50626330 A:01 X:48 Y:96 S:D1 P:nvUbdizc $E2C3:C9 7E CMP #$7E
  1369. f13983 c416424216 i50626331 A:01 X:48 Y:96 S:D1 P:NvUbdizc $E2C5:F0 0F BEQ Music_StopDMC
  1370. f13983 c416424218 i50626332 A:01 X:48 Y:96 S:D1 P:NvUbdizc $E2C7:AD F0 07 LDA DMC_Queue = #$01
  1371. f13983 c416424222 i50626333 A:01 X:48 Y:96 S:D1 P:nvUbdizc $E2CA:D0 15 BNE $E2E1
  1372. f13983 c416424225 i50626334 A:01 X:48 Y:96 S:D1 P:nvUbdizc $E2E1:8D F1 07 STA DMC_Current = #$01
  1373. f13983 c416424229 i50626335 A:01 X:48 Y:96 S:D1 P:nvUbdizc $E2E4:A8 TAY
  1374. f13983 c416424231 i50626336 A:01 X:48 Y:01 S:D1 P:nvUbdizc $E2E5:B9 29 E3 LDA $E329,Y @ DMC_MODCTL_LUT = #$0F
  1375. f13983 c416424235 i50626337 A:0F X:48 Y:01 S:D1 P:nvUbdizc $E2E8:8D 10 40 STA PAPU_MODCTL = #$0F
  1376. f13983 c416424239 i50626338 A:0F X:48 Y:01 S:D1 P:nvUbdizc $E2EB:8D FF 7A STA PAPU_MODCTL_Copy = #$0F
  1377. f13983 c416424243 i50626339 A:0F X:48 Y:01 S:D1 P:nvUbdizc $E2EE:B9 09 E3 LDA $E309,Y @ DMC_MODADDR_LUT = #$80
  1378. f13983 c416424247 i50626340 A:80 X:48 Y:01 S:D1 P:NvUbdizc $E2F1:8D 12 40 STA PAPU_MODADDR = #$80
  1379. f13983 c416424251 i50626341 A:80 X:48 Y:01 S:D1 P:NvUbdizc $E2F4:B9 19 E3 LDA $E319,Y @ DMC_MODLEN_LUT = #$08
  1380. f13983 c416424255 i50626342 A:08 X:48 Y:01 S:D1 P:nvUbdizc $E2F7:8D 13 40 STA PAPU_MODLEN = #$08
  1381. f13983 c416424259 i50626343 A:08 X:48 Y:01 S:D1 P:nvUbdizc $E2FA:A9 A0 LDA #$A0
  1382. f13983 c416424261 i50626344 A:A0 X:48 Y:01 S:D1 P:NvUbdizc $E2FC:8D F8 04 STA DMC_Time = #$64
  1383. f13983 c416424265 i50626345 A:A0 X:48 Y:01 S:D1 P:NvUbdizc $E2FF:A9 0F LDA #$0F
  1384. f13983 c416424267 i50626346 A:0F X:48 Y:01 S:D1 P:nvUbdizc $E301:8D 15 40 STA PAPU_EN = #$0F
  1385. f13983 c416424271 i50626347 A:0F X:48 Y:01 S:D1 P:nvUbdizc $E304:A9 1F LDA #$1F
  1386. f13983 c416424273 i50626348 A:1F X:48 Y:01 S:D1 P:nvUbdizc $E306:8D 15 40 STA PAPU_EN = #$0F
  1387. f13983 c416424277 i50626349 A:1F X:48 Y:01 S:D1 P:nvUbdizc $E309:60 RTS (from Music_PlayDMC) -------------------
  1388. f13983 c416424287 i50626350 A:1F X:48 Y:01 S:D3 P:nvUbdizc $E73B:A9 00 LDA #$00
  1389. f13983 c416424289 i50626351 A:00 X:48 Y:01 S:D3 P:nvUbdiZc $E73D:8D F0 07 STA DMC_Queue = #$01
  1390. f13983 c416424293 i50626352 A:00 X:48 Y:01 S:D3 P:nvUbdiZc $E740:60 RTS (from Sound_PlayMusic) -----------------
  1391. f13983 c416424299 i50626353 A:00 X:48 Y:01 S:D5 P:nvUbdiZc $A087:A9 00 LDA #$00
  1392. f13983 c416424301 i50626354 A:00 X:48 Y:01 S:D5 P:nvUbdiZc $A089:8D F5 04 STA Sound_QMusic2 = #$00
  1393. f13983 c416424305 i50626355 A:00 X:48 Y:01 S:D5 P:nvUbdiZc $A08C:8D F4 04 STA Sound_QMusic1 = #$00
  1394. f13983 c416424309 i50626356 A:00 X:48 Y:01 S:D5 P:nvUbdiZc $A08F:A9 00 LDA #$00
  1395. f13983 c416424311 i50626357 A:00 X:48 Y:01 S:D5 P:nvUbdiZc $A091:8D F1 04 STA Sound_QPlayer = #$00
  1396. f13983 c416424315 i50626358 A:00 X:48 Y:01 S:D5 P:nvUbdiZc $A094:8D F2 04 STA Sound_QLevel1 = #$00
  1397. f13983 c416424319 i50626359 A:00 X:48 Y:01 S:D5 P:nvUbdiZc $A097:8D F3 04 STA Sound_QLevel2 = #$00
  1398. f13983 c416424323 i50626360 A:00 X:48 Y:01 S:D5 P:nvUbdiZc $A09A:8D F6 04 STA Sound_QMap = #$00
  1399. f13983 c416424327 i50626361 A:00 X:48 Y:01 S:D5 P:nvUbdiZc $A09D:8D F7 04 STA Sound_QPause = #$00
  1400. f13983 c416424331 i50626362 A:00 X:48 Y:01 S:D5 P:nvUbdiZc $A0A0:60 RTS (from MMC3_MIRROR_or_Sound_Engine_Beg) -
  1401. f13983 c416424337 i50626363 A:00 X:48 Y:01 S:D7 P:nvUbdiZc $F57E:20 6F FC JSR PRGROM_Change_Both
  1402. f13983 c416424343 i50626364 A:00 X:48 Y:01 S:D5 P:nvUbdiZc $FC6F:A9 46 LDA #$46
  1403. f13983 c416424345 i50626365 A:46 X:48 Y:01 S:D5 P:nvUbdizc $FC71:8D 00 80 STA MMC3_COMMAND = #$00
  1404. f13983 c416424349 i50626366 A:46 X:48 Y:01 S:D5 P:nvUbdizc $FC74:AD 1F 07 LDA PAGE_C000 = #$19
  1405. f13983 c416424353 i50626367 A:19 X:48 Y:01 S:D5 P:nvUbdizc $FC77:8D 01 80 STA MMC3_PAGE = #$60
  1406. f13983 c416424357 i50626368 A:19 X:48 Y:01 S:D5 P:nvUbdizc $FC7A:A9 47 LDA #$47
  1407. f13983 c416424359 i50626369 A:47 X:48 Y:01 S:D5 P:nvUbdizc $FC7C:8D 00 80 STA MMC3_COMMAND = #$00
  1408. f13983 c416424363 i50626370 A:47 X:48 Y:01 S:D5 P:nvUbdizc $FC7F:AD 20 07 LDA PAGE_A000 = #$18
  1409. f13983 c416424367 i50626371 A:18 X:48 Y:01 S:D5 P:nvUbdizc $FC82:8D 01 80 STA MMC3_PAGE = #$60
  1410. f13983 c416424371 i50626372 A:18 X:48 Y:01 S:D5 P:nvUbdizc $FC85:60 RTS (from PRGROM_Change_Both) --------------
  1411. f13983 c416424377 i50626373 A:18 X:48 Y:01 S:D7 P:nvUbdizc $F581:E6 15 INC Counter_1 = #$3B
  1412. f13983 c416424382 i50626374 A:18 X:48 Y:01 S:D7 P:nvUbdizc $F583:AD 21 07 LDA PAGE_CMD = #$47
  1413. f13983 c416424386 i50626375 A:47 X:48 Y:01 S:D7 P:nvUbdizc $F586:8D 00 80 STA MMC3_COMMAND = #$00
  1414. f13983 c416424390 i50626376 A:47 X:48 Y:01 S:D7 P:nvUbdizc $F589:68 PLA
  1415. f13983 c416424394 i50626377 A:80 X:48 Y:01 S:D8 P:NvUbdizc $F58A:85 02 STA Temp_Var3 = #$80
  1416. f13983 c416424397 i50626378 A:80 X:48 Y:01 S:D8 P:NvUbdizc $F58C:68 PLA
  1417. f13983 c416424401 i50626379 A:00 X:48 Y:01 S:D9 P:nvUbdiZc $F58D:85 01 STA Temp_Var2 = #$00
  1418. f13983 c416424404 i50626380 A:00 X:48 Y:01 S:D9 P:nvUbdiZc $F58F:68 PLA
  1419. f13983 c416424408 i50626381 A:80 X:48 Y:01 S:DA P:NvUbdizc $F590:85 00 STA Temp_Var1 = #$80
  1420. f13983 c416424411 i50626382 A:80 X:48 Y:01 S:DA P:NvUbdizc $F592:68 PLA
  1421. f13983 c416424415 i50626383 A:95 X:48 Y:01 S:DB P:NvUbdizc $F593:A8 TAY
  1422. f13983 c416424417 i50626384 A:95 X:48 Y:95 S:DB P:NvUbdizc $F594:68 PLA
  1423. f13983 c416424421 i50626385 A:7F X:48 Y:95 S:DC P:nvUbdizc $F595:AA TAX
  1424. f13983 c416424423 i50626386 A:7F X:7F Y:95 S:DC P:nvUbdizc $F596:68 PLA
  1425. f13983 c416424427 i50626387 A:00 X:7F Y:95 S:DD P:nvUbdiZc $F597:28 PLP
  1426. f13983 c416424431 i50626388 A:00 X:7F Y:95 S:DE P:nvUBdIZC $F598:40 RTI
  1427.  
  1428. We finnish the NMI, now having loaded in proper values at $6B and $6C. Now that they hold the actual Music_Base values, the two loops we were stuck in will exit.
  1429. However, we hit a snag...
  1430.  
  1431.  
  1432. f13983 c416424437 i50626389 A:00 X:7F Y:95 S:E1 P:nvUbdiZC $E71B:F0 24 BEQ $E741
  1433. f13983 c416424440 i50626390 A:00 X:7F Y:95 S:E1 P:nvUbdiZC $E741:AD DE 04 LDA Music_PCMStart = #$95
  1434. f13983 c416424444 i50626391 A:95 X:7F Y:95 S:E1 P:NvUbdizC $E744:8D D2 04 STA Music_PCMTrkPos = #$97
  1435. f13983 c416424448 i50626392 A:95 X:7F Y:95 S:E1 P:NvUbdizC $E747:4C 13 E7 JMP $E713
  1436. f13983 c416424451 i50626393 A:95 X:7F Y:95 S:E1 P:NvUbdizC $E713:AC D2 04 LDY Music_PCMTrkPos = #$95
  1437. f13983 c416424455 i50626394 A:95 X:7F Y:95 S:E1 P:NvUbdizC $E716:EE D2 04 INC Music_PCMTrkPos = #$95
  1438. f13983 c416424461 i50626395 A:95 X:7F Y:95 S:E1 P:NvUbdizC $E719:B1 6B LDA ($6B),Y @ $C108 = #$01
  1439. f13983 c416424467 i50626396 A:01 X:7F Y:95 S:E1 P:nvUbdizC $E71B:F0 24 BEQ $E741
  1440. f13983 c416424469 i50626397 A:01 X:7F Y:95 S:E1 P:nvUbdizC $E71D:10 10 BPL $E72F
  1441. f13983 c416424472 i50626398 A:01 X:7F Y:95 S:E1 P:nvUbdizC $E72F:8D F0 07 STA DMC_Queue = #$00
  1442. f13983 c416424476 i50626399 A:01 X:7F Y:95 S:E1 P:nvUbdizC $E732:AD DD 04 LDA Music_DMCRestH = #$24
  1443. f13983 c416424480 i50626400 A:24 X:7F Y:95 S:E1 P:nvUbdizC $E735:8D DC 04 STA Music_DMCRest = #$24
  1444. f13983 c416424484 i50626401 A:24 X:7F Y:95 S:E1 P:nvUbdizC $E738:20 C0 E2 JSR Music_PlayDMC
  1445. f13983 c416424490 i50626402 A:24 X:7F Y:95 S:DF P:nvUbdizC $E2C0:AD F0 07 LDA DMC_Queue = #$01
  1446. f13983 c416424494 i50626403 A:01 X:7F Y:95 S:DF P:nvUbdizC $E2C3:C9 7E CMP #$7E
  1447. f13983 c416424496 i50626404 A:01 X:7F Y:95 S:DF P:NvUbdizc $E2C5:F0 0F BEQ Music_StopDMC
  1448. f13983 c416424498 i50626405 A:01 X:7F Y:95 S:DF P:NvUbdizc $E2C7:AD F0 07 LDA DMC_Queue = #$01
  1449. f13983 c416424502 i50626406 A:01 X:7F Y:95 S:DF P:nvUbdizc $E2CA:D0 15 BNE $E2E1
  1450. f13983 c416424505 i50626407 A:01 X:7F Y:95 S:DF P:nvUbdizc $E2E1:8D F1 07 STA DMC_Current = #$01
  1451. f13983 c416424509 i50626408 A:01 X:7F Y:95 S:DF P:nvUbdizc $E2E4:A8 TAY
  1452. f13983 c416424511 i50626409 A:01 X:7F Y:01 S:DF P:nvUbdizc $E2E5:B9 29 E3 LDA $E329,Y @ DMC_MODCTL_LUT = #$0F
  1453. f13983 c416424515 i50626410 A:0F X:7F Y:01 S:DF P:nvUbdizc $E2E8:8D 10 40 STA PAPU_MODCTL = #$0F
  1454. f13983 c416424519 i50626411 A:0F X:7F Y:01 S:DF P:nvUbdizc $E2EB:8D FF 7A STA PAPU_MODCTL_Copy = #$0F
  1455. f13983 c416424523 i50626412 A:0F X:7F Y:01 S:DF P:nvUbdizc $E2EE:B9 09 E3 LDA $E309,Y @ DMC_MODADDR_LUT = #$80
  1456. f13983 c416424527 i50626413 A:80 X:7F Y:01 S:DF P:NvUbdizc $E2F1:8D 12 40 STA PAPU_MODADDR = #$80
  1457. f13983 c416424531 i50626414 A:80 X:7F Y:01 S:DF P:NvUbdizc $E2F4:B9 19 E3 LDA $E319,Y @ DMC_MODLEN_LUT = #$08
  1458. f13983 c416424535 i50626415 A:08 X:7F Y:01 S:DF P:nvUbdizc $E2F7:8D 13 40 STA PAPU_MODLEN = #$08
  1459. f13983 c416424539 i50626416 A:08 X:7F Y:01 S:DF P:nvUbdizc $E2FA:A9 A0 LDA #$A0
  1460. f13983 c416424541 i50626417 A:A0 X:7F Y:01 S:DF P:NvUbdizc $E2FC:8D F8 04 STA DMC_Time = #$A0
  1461. f13983 c416424545 i50626418 A:A0 X:7F Y:01 S:DF P:NvUbdizc $E2FF:A9 0F LDA #$0F
  1462. f13983 c416424547 i50626419 A:0F X:7F Y:01 S:DF P:nvUbdizc $E301:8D 15 40 STA PAPU_EN = #$1F
  1463. f13983 c416424551 i50626420 A:0F X:7F Y:01 S:DF P:nvUbdizc $E304:A9 1F LDA #$1F
  1464. f13983 c416424553 i50626421 A:1F X:7F Y:01 S:DF P:nvUbdizc $E306:8D 15 40 STA PAPU_EN = #$0F
  1465. f13983 c416424557 i50626422 A:1F X:7F Y:01 S:DF P:nvUbdizc $E309:60 RTS (from Music_PlayDMC) -------------------
  1466. f13983 c416424563 i50626423 A:1F X:7F Y:01 S:E1 P:nvUbdizc $E73B:A9 00 LDA #$00
  1467. f13983 c416424565 i50626424 A:00 X:7F Y:01 S:E1 P:nvUbdiZc $E73D:8D F0 07 STA DMC_Queue = #$01
  1468. f13983 c416424569 i50626425 A:00 X:7F Y:01 S:E1 P:nvUbdiZc $E740:60 RTS ————————————————————
  1469.  
  1470. Because another NMI occurred before the original NMI finished, the sound engine bank (PRG28) has been swapped out of bank $A000.
  1471. So we end up executing code from PRG24 instead of PRG28.
  1472.  
  1473. The first line we execute is this:
  1474.  
  1475. f13983 c416424575 i50626426 A:00 X:7F Y:01 S:E3 P:nvUbdiZc $A087:FE 93 95 INC $9593,X @ $9612 = #$60
  1476.  
  1477. This Increments the value stored in memory address $(9593 + X). The value of X depends on what the sound engine was doing previously, in the last NMI.
  1478. From above, we can see X is still $7F. So we will attempt to increment $9612. This has the same effect as writing $61 to MMC3 command.
  1479.  
  1480. $61 = %01100001
  1481.  
  1482. From out earlier document, we can see that this tells the MMC3 to swap out two 1 KB VROM banks at PPU $0800. Since this does not affect the ROM banks, we continue executing in PRG24:
  1483.  
  1484.  
  1485.  
  1486. f13983 c416424582 i50626427 A:00 X:7F Y:01 S:E3 P:nvUbdizc $A08A:91 91 STA ($91),Y @ Temp_Var2 = #$00
  1487. f13983 c416424588 i50626428 A:00 X:7F Y:01 S:E3 P:nvUbdizc $A08C:91 91 STA ($91),Y @ Temp_Var2 = #$00
  1488. f13983 c416424594 i50626429 A:00 X:7F Y:01 S:E3 P:nvUbdizc $A08E:91 91 STA ($91),Y @ Temp_Var2 = #$00
  1489. f13983 c416424600 i50626430 A:00 X:7F Y:01 S:E3 P:nvUbdizc $A090:91 91 STA ($91),Y @ Temp_Var2 = #$00
  1490. f13983 c416424606 i50626431 A:00 X:7F Y:01 S:E3 P:nvUbdizc $A092:91 91 STA ($91),Y @ Temp_Var2 = #$00
  1491. f13983 c416424612 i50626432 A:00 X:7F Y:01 S:E3 P:nvUbdizc $A094:91 91 STA ($91),Y @ Temp_Var2 = #$00
  1492. f13983 c416424618 i50626433 A:00 X:7F Y:01 S:E3 P:nvUbdizc $A096:91 91 STA ($91),Y @ Temp_Var2 = #$00
  1493. f13983 c416424624 i50626434 A:00 X:7F Y:01 S:E3 P:nvUbdizc $A098:91 91 STA ($91),Y @ Temp_Var2 = #$00
  1494. f13983 c416424634 i50626435 A:00 X:7F Y:01 S:E3 P:nvUbdizc $A09A:91 91 STA ($91),Y @ Temp_Var2 = #$00
  1495. f13983 c416424640 i50626436 A:00 X:7F Y:01 S:E3 P:nvUbdizc $A09C:91 91 STA ($91),Y @ Temp_Var2 = #$00
  1496. f13983 c416424646 i50626437 A:00 X:7F Y:01 S:E3 P:nvUbdizc $A09E:97 UNDEFINED
  1497. f13983 c416424650 i50626438 A:00 X:7F Y:01 S:E3 P:nvUbdizc $A0A0:16 16 ASL $16,X @ $0095 = #$00
  1498. f13983 c416424656 i50626439 A:00 X:7F Y:01 S:E3 P:nvUbdiZc $A0A2:16 16 ASL $16,X @ $0095 = #$00
  1499. f13983 c416424662 i50626440 A:00 X:7F Y:01 S:E3 P:nvUbdiZc $A0A4:16 16 ASL $16,X @ $0095 = #$00
  1500. f13983 c416424668 i50626441 A:00 X:7F Y:01 S:E3 P:nvUbdiZc $A0A6:2C AD 18 BIT $18AD = #$00
  1501. f13983 c416424672 i50626442 A:00 X:7F Y:01 S:E3 P:nvUbdiZc $A0A9:05 D0 ORA Objects_YVel = #$00
  1502. f13983 c416424675 i50626443 A:00 X:7F Y:01 S:E3 P:nvUbdiZc $A0AB:6D AD 7A ADC $7AAD = #$00
  1503. f13983 c416424679 i50626444 A:00 X:7F Y:01 S:E3 P:nvUbdiZc $A0AE:07 UNDEFINED
  1504. f13983 c416424684 i50626445 A:00 X:7F Y:01 S:E3 P:nvUbdiZc $A0B0:5A UNDEFINED
  1505. f13983 c416424686 i50626446 A:00 X:7F Y:01 S:E3 P:nvUbdiZc $A0B1:90 66 BCC $A119 ; Branch on carry Clear. Carry, is clear, so we branch, and, good for us, we hit an RTS!
  1506. f13983 c416424690 i50626447 A:00 X:7F Y:01 S:E3 P:nvUbdiZc $A119:60 RTS (from MMC3_MIRROR_or_Sound_Engine_Beg) -
  1507.  
  1508. Now we can continue finishing off the NMI we started ages ago, since this part of the NMI is in bank $E000, it never changes.
  1509.  
  1510. f13983 c416424696 i50626448 A:00 X:7F Y:01 S:E5 P:nvUbdiZc $F57E:20 6F FC JSR PRGROM_Change_Both
  1511. f13983 c416424702 i50626449 A:00 X:7F Y:01 S:E3 P:nvUbdiZc $FC6F:A9 46 LDA #$46
  1512. f13983 c416424704 i50626450 A:46 X:7F Y:01 S:E3 P:nvUbdizc $FC71:8D 00 80 STA MMC3_COMMAND = #$00
  1513. f13983 c416424708 i50626451 A:46 X:7F Y:01 S:E3 P:nvUbdizc $FC74:AD 1F 07 LDA PAGE_C000 = #$19
  1514. f13983 c416424712 i50626452 A:19 X:7F Y:01 S:E3 P:nvUbdizc $FC77:8D 01 80 STA MMC3_PAGE = #$60
  1515. f13983 c416424716 i50626453 A:19 X:7F Y:01 S:E3 P:nvUbdizc $FC7A:A9 47 LDA #$47
  1516. f13983 c416424718 i50626454 A:47 X:7F Y:01 S:E3 P:nvUbdizc $FC7C:8D 00 80 STA MMC3_COMMAND = #$00
  1517. f13983 c416424722 i50626455 A:47 X:7F Y:01 S:E3 P:nvUbdizc $FC7F:AD 20 07 LDA PAGE_A000 = #$18
  1518. f13983 c416424726 i50626456 A:18 X:7F Y:01 S:E3 P:nvUbdizc $FC82:8D 01 80 STA MMC3_PAGE = #$60
  1519. f13983 c416424730 i50626457 A:18 X:7F Y:01 S:E3 P:nvUbdizc $FC85:60 RTS (from PRGROM_Change_Both) --------------
  1520. f13983 c416424736 i50626458 A:18 X:7F Y:01 S:E5 P:nvUbdizc $F581:E6 15 INC Counter_1 = #$3C
  1521. f13983 c416424741 i50626459 A:18 X:7F Y:01 S:E5 P:nvUbdizc $F583:AD 21 07 LDA PAGE_CMD = #$47
  1522. f13983 c416424745 i50626460 A:47 X:7F Y:01 S:E5 P:nvUbdizc $F586:8D 00 80 STA MMC3_COMMAND = #$00
  1523. f13983 c416424749 i50626461 A:47 X:7F Y:01 S:E5 P:nvUbdizc $F589:68 PLA
  1524. f13983 c416424753 i50626462 A:80 X:7F Y:01 S:E6 P:NvUbdizc $F58A:85 02 STA Temp_Var3 = #$80
  1525. f13983 c416424756 i50626463 A:80 X:7F Y:01 S:E6 P:NvUbdizc $F58C:68 PLA
  1526. f13983 c416424760 i50626464 A:00 X:7F Y:01 S:E7 P:nvUbdiZc $F58D:85 01 STA Temp_Var2 = #$00
  1527. f13983 c416424763 i50626465 A:00 X:7F Y:01 S:E7 P:nvUbdiZc $F58F:68 PLA
  1528. f13983 c416424767 i50626466 A:80 X:7F Y:01 S:E8 P:NvUbdizc $F590:85 00 STA Temp_Var1 = #$80
  1529. f13983 c416424770 i50626467 A:80 X:7F Y:01 S:E8 P:NvUbdizc $F592:68 PLA
  1530. f13983 c416424774 i50626468 A:AE X:7F Y:01 S:E9 P:NvUbdizc $F593:A8 TAY
  1531. f13983 c416424776 i50626469 A:AE X:7F Y:AE S:E9 P:NvUbdizc $F594:68 PLA
  1532. f13983 c416424780 i50626470 A:7F X:7F Y:AE S:EA P:nvUbdizc $F595:AA TAX
  1533. f13983 c416424782 i50626471 A:7F X:7F Y:AE S:EA P:nvUbdizc $F596:68 PLA
  1534. f13983 c416424786 i50626472 A:AE X:7F Y:AE S:EB P:NvUbdizc $F597:28 PLP
  1535. f13983 c416424790 i50626473 A:AE X:7F Y:AE S:EC P:NvUBdIzC $F598:40 RTI
  1536.  
  1537. Now we return to the first loop we were stuck in, and, just like above, we eventually exit.
  1538.  
  1539. f13983 c416424796 i50626474 A:AE X:7F Y:AE S:EF P:NvUbdizC $E6CD:B1 6B LDA ($6B),Y @ $C121 = #$E4
  1540. f13983 c416424802 i50626475 A:E4 X:7F Y:AE S:EF P:NvUbdizC $E6CF:F0 2F BEQ $E700
  1541. f13983 c416424804 i50626476 A:E4 X:7F Y:AE S:EF P:NvUbdizC $E6D1:10 10 BPL Music_NseNoteOn
  1542. f13983 c416424806 i50626477 A:E4 X:7F Y:AE S:EF P:NvUbdizC $E6D3:20 3B E3 JSR Music_GetRestTicks
  1543. f13983 c416424812 i50626478 A:E4 X:7F Y:AE S:ED P:NvUbdizC $E33B:29 0F AND #$0F
  1544. f13983 c416424814 i50626479 A:04 X:7F Y:AE S:ED P:nvUbdizC $E33D:18 CLC
  1545. f13983 c416424816 i50626480 A:04 X:7F Y:AE S:ED P:nvUbdizc $E33E:6D FD 04 ADC Music_RestH_Base = #$50
  1546. f13983 c416424820 i50626481 A:54 X:7F Y:AE S:ED P:nvUbdizc $E341:6D F7 7A ADC Music_RestH_Off = #$00
  1547. f13983 c416424824 i50626482 A:54 X:7F Y:AE S:ED P:nvUbdizc $E344:A8 TAY
  1548. f13983 c416424826 i50626483 A:54 X:7F Y:54 S:ED P:nvUbdizc $E345:B9 74 E8 LDA Music_RestH_LUT,Y @ $E8C8 = #$09
  1549. f13983 c416424830 i50626484 A:09 X:7F Y:54 S:ED P:nvUbdizc $E348:60 RTS (from Music_GetRestTicks) --------------
  1550. f13983 c416424836 i50626485 A:09 X:7F Y:54 S:EF P:nvUbdizc $E6D6:8D DB 04 STA Music_NseRestH = #$09
  1551. f13983 c416424840 i50626486 A:09 X:7F Y:54 S:EF P:nvUbdizc $E6D9:AC D1 04 LDY Music_NseTrkPos = #$B0
  1552. f13983 c416424844 i50626487 A:09 X:7F Y:B0 S:EF P:NvUbdizc $E6DC:EE D1 04 INC Music_NseTrkPos = #$B0
  1553. f13983 c416424850 i50626488 A:09 X:7F Y:B0 S:EF P:NvUbdizc $E6DF:B1 6B LDA ($6B),Y @ $C123 = #$11
  1554. f13983 c416424856 i50626489 A:11 X:7F Y:B0 S:EF P:nvUbdizc $E6E1:F0 1D BEQ $E700
  1555. f13983 c416424858 i50626490 A:11 X:7F Y:B0 S:EF P:nvUbdizc $E6E3:4A LSR
  1556. f13983 c416424860 i50626491 A:08 X:7F Y:B0 S:EF P:nvUbdizC $E6E4:A8 TAY
  1557. f13983 c416424862 i50626492 A:08 X:7F Y:08 S:EF P:nvUbdizC $E6E5:B9 4A E7 LDA Music_NoiseLUTA,Y @ Music_NoiseLUTC = #$0
  1558. f13983 c416424866 i50626493 A:00 X:7F Y:08 S:EF P:nvUbdiZC $E6E8:8D 0C 40 STA PAPU_NCTL1 = #$1E
  1559. f13983 c416424870 i50626494 A:00 X:7F Y:08 S:EF P:nvUbdiZC $E6EB:B9 4E E7 LDA Music_NoiseLUTB,Y @ Music_CalcNoteLen = #
  1560. f13983 c416424874 i50626495 A:C9 X:7F Y:08 S:EF P:NvUbdizC $E6EE:8D 0E 40 STA NOISE_LO = #$03
  1561. f13983 c416424878 i50626496 A:C9 X:7F Y:08 S:EF P:NvUbdizC $E6F1:B9 52 E7 LDA Music_NoiseLUTC,Y @ $E75A = #$A9
  1562. f13983 c416424882 i50626497 A:A9 X:7F Y:08 S:EF P:NvUbdizC $E6F4:8D 0F 40 STA PAPU_NFREQ2 = #$18
  1563. f13983 c416424886 i50626498 A:A9 X:7F Y:08 S:EF P:NvUbdizC $E6F7:AD DB 04 LDA Music_NseRestH = #$09
  1564. f13983 c416424890 i50626499 A:09 X:7F Y:08 S:EF P:nvUbdizC $E6FA:8D DA 04 STA Music_NoiseRest = #$09
  1565. f13983 c416424894 i50626500 A:09 X:7F Y:08 S:EF P:nvUbdizC $E6FD:4C 09 E7 JMP $E709
  1566. f13983 c416424897 i50626501 A:09 X:7F Y:08 S:EF P:nvUbdizC $E709:AD D2 04 LDA Music_PCMTrkPos = #$96
  1567. f13983 c416424901 i50626502 A:96 X:7F Y:08 S:EF P:NvUbdizC $E70C:F0 2A BEQ $E738
  1568. f13983 c416424903 i50626503 A:96 X:7F Y:08 S:EF P:NvUbdizC $E70E:CE DC 04 DEC Music_DMCRest = #$24
  1569. f13983 c416424909 i50626504 A:96 X:7F Y:08 S:EF P:nvUbdizC $E711:D0 25 BNE $E738
  1570. f13983 c416424912 i50626505 A:96 X:7F Y:08 S:EF P:nvUbdizC $E738:20 C0 E2 JSR Music_PlayDMC
  1571. f13983 c416424918 i50626506 A:96 X:7F Y:08 S:ED P:nvUbdizC $E2C0:AD F0 07 LDA DMC_Queue = #$00
  1572. f13983 c416424922 i50626507 A:00 X:7F Y:08 S:ED P:nvUbdiZC $E2C3:C9 7E CMP #$7E
  1573. f13983 c416424924 i50626508 A:00 X:7F Y:08 S:ED P:NvUbdizc $E2C5:F0 0F BEQ Music_StopDMC
  1574. f13983 c416424926 i50626509 A:00 X:7F Y:08 S:ED P:NvUbdizc $E2C7:AD F0 07 LDA DMC_Queue = #$00
  1575. f13983 c416424930 i50626510 A:00 X:7F Y:08 S:ED P:nvUbdiZc $E2CA:D0 15 BNE $E2E1
  1576. f13983 c416424932 i50626511 A:00 X:7F Y:08 S:ED P:nvUbdiZc $E2CC:AD F1 07 LDA DMC_Current = #$01
  1577. f13983 c416424936 i50626512 A:01 X:7F Y:08 S:ED P:nvUbdizc $E2CF:F0 05 BEQ Music_StopDMC
  1578. f13983 c416424938 i50626513 A:01 X:7F Y:08 S:ED P:nvUbdizc $E2D1:CE F8 04 DEC DMC_Time = #$A0
  1579. f13983 c416424944 i50626514 A:01 X:7F Y:08 S:ED P:NvUbdizc $E2D4:D0 0A BNE $E2E0
  1580. f13983 c416424947 i50626515 A:01 X:7F Y:08 S:ED P:NvUbdizc $E2E0:60 RTS (from Music_PlayDMC) -------------------
  1581. f13983 c416424953 i50626516 A:01 X:7F Y:08 S:EF P:NvUbdizc $E73B:A9 00 LDA #$00
  1582. f13983 c416424955 i50626517 A:00 X:7F Y:08 S:EF P:nvUbdiZc $E73D:8D F0 07 STA DMC_Queue = #$00
  1583. f13983 c416424959 i50626518 A:00 X:7F Y:08 S:EF P:nvUbdiZc $E740:60 RTS ————————————————————
  1584.  
  1585. Again, X = $7F, and like above, we do not change the rom bank, so we continue executing in bank 24:
  1586.  
  1587. f13983 c416424965 i50626519 A:00 X:7F Y:08 S:F1 P:nvUbdiZc $A087:FE 93 95 INC $9593,X @ $9612 = #$60
  1588. f13983 c416424972 i50626520 A:00 X:7F Y:08 S:F1 P:nvUbdizc $A08A:91 91 STA ($91),Y @ Temp_Var9 = #$00
  1589. f13983 c416424978 i50626521 A:00 X:7F Y:08 S:F1 P:nvUbdizc $A08C:91 91 STA ($91),Y @ Temp_Var9 = #$00
  1590. f13983 c416424984 i50626522 A:00 X:7F Y:08 S:F1 P:nvUbdizc $A08E:91 91 STA ($91),Y @ Temp_Var9 = #$00
  1591. f13983 c416424990 i50626523 A:00 X:7F Y:08 S:F1 P:nvUbdizc $A090:91 91 STA ($91),Y @ Temp_Var9 = #$00
  1592. f13983 c416424996 i50626524 A:00 X:7F Y:08 S:F1 P:nvUbdizc $A092:91 91 STA ($91),Y @ Temp_Var9 = #$00
  1593. f13983 c416425002 i50626525 A:00 X:7F Y:08 S:F1 P:nvUbdizc $A094:91 91 STA ($91),Y @ Temp_Var9 = #$00
  1594. f13983 c416425008 i50626526 A:00 X:7F Y:08 S:F1 P:nvUbdizc $A096:91 91 STA ($91),Y @ Temp_Var9 = #$00
  1595. f13983 c416425014 i50626527 A:00 X:7F Y:08 S:F1 P:nvUbdizc $A098:91 91 STA ($91),Y @ Temp_Var9 = #$00
  1596. f13983 c416425020 i50626528 A:00 X:7F Y:08 S:F1 P:nvUbdizc $A09A:91 91 STA ($91),Y @ Temp_Var9 = #$00
  1597. f13983 c416425026 i50626529 A:00 X:7F Y:08 S:F1 P:nvUbdizc $A09C:91 91 STA ($91),Y @ Temp_Var9 = #$00
  1598. f13983 c416425032 i50626530 A:00 X:7F Y:08 S:F1 P:nvUbdizc $A09E:97 UNDEFINED
  1599. f13983 c416425036 i50626531 A:00 X:7F Y:08 S:F1 P:nvUbdizc $A0A0:16 16 ASL $16,X @ $0095 = #$00
  1600. f13983 c416425042 i50626532 A:00 X:7F Y:08 S:F1 P:nvUbdiZc $A0A2:16 16 ASL $16,X @ $0095 = #$00
  1601. f13983 c416425048 i50626533 A:00 X:7F Y:08 S:F1 P:nvUbdiZc $A0A4:16 16 ASL $16,X @ $0095 = #$00
  1602. f13983 c416425054 i50626534 A:00 X:7F Y:08 S:F1 P:nvUbdiZc $A0A6:2C AD 18 BIT $18AD = #$00
  1603. f13983 c416425062 i50626535 A:00 X:7F Y:08 S:F1 P:nvUbdiZc $A0A9:05 D0 ORA Objects_YVel = #$00
  1604. f13983 c416425065 i50626536 A:00 X:7F Y:08 S:F1 P:nvUbdiZc $A0AB:6D AD 7A ADC $7AAD = #$00
  1605. f13983 c416425069 i50626537 A:00 X:7F Y:08 S:F1 P:nvUbdiZc $A0AE:07 UNDEFINED
  1606. f13983 c416425074 i50626538 A:00 X:7F Y:08 S:F1 P:nvUbdiZc $A0B0:5A UNDEFINED
  1607. f13983 c416425076 i50626539 A:00 X:7F Y:08 S:F1 P:nvUbdiZc $A0B1:90 66 BCC $A119
  1608. f13983 c416425080 i50626540 A:00 X:7F Y:08 S:F1 P:nvUbdiZc $A119:60 RTS (from MMC3_MIRROR_or_Sound_Engine_Beg) -
  1609. f13983 c416425086 i50626541 A:00 X:7F Y:08 S:F3 P:nvUbdiZc $F57E:20 6F FC JSR PRGROM_Change_Both
  1610. f13983 c416425092 i50626542 A:00 X:7F Y:08 S:F1 P:nvUbdiZc $FC6F:A9 46 LDA #$46
  1611. f13983 c416425094 i50626543 A:46 X:7F Y:08 S:F1 P:nvUbdizc $FC71:8D 00 80 STA MMC3_COMMAND = #$00
  1612. f13983 c416425098 i50626544 A:46 X:7F Y:08 S:F1 P:nvUbdizc $FC74:AD 1F 07 LDA PAGE_C000 = #$19
  1613. f13983 c416425102 i50626545 A:19 X:7F Y:08 S:F1 P:nvUbdizc $FC77:8D 01 80 STA MMC3_PAGE = #$60
  1614. f13983 c416425106 i50626546 A:19 X:7F Y:08 S:F1 P:nvUbdizc $FC7A:A9 47 LDA #$47
  1615. f13983 c416425108 i50626547 A:47 X:7F Y:08 S:F1 P:nvUbdizc $FC7C:8D 00 80 STA MMC3_COMMAND = #$00
  1616. f13983 c416425112 i50626548 A:47 X:7F Y:08 S:F1 P:nvUbdizc $FC7F:AD 20 07 LDA PAGE_A000 = #$18
  1617. f13983 c416425116 i50626549 A:18 X:7F Y:08 S:F1 P:nvUbdizc $FC82:8D 01 80 STA MMC3_PAGE = #$60
  1618. f13983 c416425120 i50626550 A:18 X:7F Y:08 S:F1 P:nvUbdizc $FC85:60 RTS (from PRGROM_Change_Both) --------------
  1619. f13983 c416425126 i50626551 A:18 X:7F Y:08 S:F3 P:nvUbdizc $F581:E6 15 INC Counter_1 = #$3D
  1620. f13983 c416425131 i50626552 A:18 X:7F Y:08 S:F3 P:nvUbdizc $F583:AD 21 07 LDA PAGE_CMD = #$47
  1621. f13983 c416425135 i50626553 A:47 X:7F Y:08 S:F3 P:nvUbdizc $F586:8D 00 80 STA MMC3_COMMAND = #$00
  1622. f13983 c416425139 i50626554 A:47 X:7F Y:08 S:F3 P:nvUbdizc $F589:68 PLA
  1623. f13983 c416425143 i50626555 A:33 X:7F Y:08 S:F4 P:nvUbdizc $F58A:85 02 STA Temp_Var3 = #$80
  1624. f13983 c416425146 i50626556 A:33 X:7F Y:08 S:F4 P:nvUbdizc $F58C:68 PLA
  1625. f13983 c416425150 i50626557 A:B8 X:7F Y:08 S:F5 P:NvUbdizc $F58D:85 01 STA Temp_Var2 = #$00
  1626. f13983 c416425153 i50626558 A:B8 X:7F Y:08 S:F5 P:NvUbdizc $F58F:68 PLA
  1627. f13983 c416425157 i50626559 A:99 X:7F Y:08 S:F6 P:NvUbdizc $F590:85 00 STA Temp_Var1 = #$80
  1628. f13983 c416425160 i50626560 A:99 X:7F Y:08 S:F6 P:NvUbdizc $F592:68 PLA
  1629. f13983 c416425164 i50626561 A:B0 X:7F Y:08 S:F7 P:NvUbdizc $F593:A8 TAY
  1630. f13983 c416425166 i50626562 A:B0 X:7F Y:B0 S:F7 P:NvUbdizc $F594:68 PLA
  1631. f13983 c416425170 i50626563 A:01 X:7F Y:B0 S:F8 P:nvUbdizc $F595:AA TAX
  1632. f13983 c416425172 i50626564 A:01 X:01 Y:B0 S:F8 P:nvUbdizc $F596:68 PLA
  1633. f13983 c416425176 i50626565 A:00 X:01 Y:B0 S:F9 P:nvUbdiZc $F597:28 PLP
  1634. f13983 c416425180 i50626566 A:00 X:01 Y:B0 S:FA P:nvUBdIZc $F598:40 RTI
  1635.  
  1636. Finally, we can continue on with the credits code, that we were executing many, many many frames ago!!!
  1637.  
  1638. f13983 c416425186 i50626567 A:00 X:01 Y:B0 S:FD P:nvUbdiZc $A81E:10 FC BPL $A81C
  1639. f13983 c416425189 i50626568 A:00 X:01 Y:B0 S:FD P:nvUbdiZc $A81C:A5 10 LDA VBlank_Tick = #$C9
  1640. f13983 c416425192 i50626569 A:C9 X:01 Y:B0 S:FD P:NvUbdizc $A81E:10 FC BPL $A81C
  1641. f13983 c416425194 i50626570 A:C9 X:01 Y:B0 S:FD P:NvUbdizc $A820:A9 00 LDA #$00
  1642. f13983 c416425196 i50626571 A:00 X:01 Y:B0 S:FD P:nvUbdiZc $A822:85 1C STA VBlank_TickEn = #$01
  1643. f13983 c416425199 i50626572 A:00 X:01 Y:B0 S:FD P:nvUbdiZc $A824:58 CLI
  1644. f13983 c416425201 i50626573 A:00 X:01 Y:B0 S:FD P:nvUbdiZc $A825:60 RTS (from $A806) ---------------------------
  1645. f13983 c416425207 i50626574 A:00 X:01 Y:B0 S:FF P:nvUbdiZc $B8A3:20 AF B8 JSR $B8AF
  1646. f13983 c416425213 i50626575 A:00 X:01 Y:B0 S:FD P:nvUbdiZc $B8AF:20 44 AF JSR $AF44
  1647. etc etc.
  1648.  
  1649.  
  1650. So what happens if X isn’t 7F?
  1651.  
  1652. Unfortunately, the Bump sound is very short, so the square 1 music channel is only blocked for 15 frames - usually, the bump sound has finished playing well before square 2 finishes resting, and because of this, square 1 runs it’s normal music code:
  1653.  
  1654. f13939 c415112827 i51347938 A:50 X:0A Y:00 S:E1 P:nvUbdizC $E5A0:A2 7F LDX #$7F
  1655. f13939 c415112829 i51347939 A:50 X:7F Y:00 S:E1 P:nvUbdizC $E5A2:8E 05 40 STX PAPU_RAMP2 = #$7F ; At this point, X = $7F
  1656. f13939 c415112833 i51347940 A:50 X:7F Y:00 S:E1 P:nvUbdizC $E5A5:D0 05 BNE Music_Sq1Track
  1657. f13939 c415112836 i51347941 A:50 X:7F Y:00 S:E1 P:nvUbdizC $E5AC:CE D6 04 DEC Music_Sq1Rest = #$2D
  1658. f13939 c415112842 i51347942 A:50 X:7F Y:00 S:E1 P:nvUbdizC $E5AF:D0 7A BNE $E62B
  1659. f13939 c415112846 i51347943 A:50 X:7F Y:00 S:E1 P:nvUbdizC $E62B:AD E1 04 LDA SndCur_Player = #$00
  1660. f13939 c415112850 i51347944 A:00 X:7F Y:00 S:E1 P:nvUbdiZC $E62E:0D E6 04 ORA SndCur_Map = #$00 ; Because Sound Fx on square 1 are NOT playing, we run square 1’s code.
  1661. f13939 c415112854 i51347945 A:00 X:7F Y:00 S:E1 P:nvUbdiZC $E631:D0 2D BNE $E660
  1662. f13939 c415112856 i51347946 A:00 X:7F Y:00 S:E1 P:nvUbdiZC $E633:AD F0 7A LDA Music_Sq1Bend = #$00
  1663. f13939 c415112860 i51347947 A:00 X:7F Y:00 S:E1 P:nvUbdiZC $E636:F0 08 BEQ $E640
  1664. f13939 c415112863 i51347948 A:00 X:7F Y:00 S:E1 P:nvUbdiZC $E640:AC D7 04 LDY Music_Sq1NoteLen = #$00
  1665. f13939 c415112867 i51347949 A:00 X:7F Y:00 S:E1 P:nvUbdiZC $E643:F0 03 BEQ $E648
  1666. f13939 c415112870 i51347950 A:00 X:7F Y:00 S:E1 P:nvUbdiZC $E648:AD F9 04 LDA Music_Sq1RestH = #$48
  1667. f13939 c415112874 i51347951 A:48 X:7F Y:00 S:E1 P:nvUbdizC $E64B:AE F8 07 LDX Music_Sq1Patch = #$D0
  1668. f13939 c415112878 i51347952 A:48 X:D0 Y:00 S:E1 P:NvUbdizC $E64E:20 85 E7 JSR Music_PatchGetCTL
  1669. f13939 c415112884 i51347953 A:48 X:D0 Y:00 S:DF P:NvUbdizC $E785:48 PHA
  1670. f13939 c415112887 i51347954 A:48 X:D0 Y:00 S:DE P:NvUbdizC $E786:8A TXA
  1671. f13939 c415112889 i51347955 A:D0 X:D0 Y:00 S:DE P:NvUbdizC $E787:29 70 AND #$70
  1672. f13939 c415112891 i51347956 A:50 X:D0 Y:00 S:DE P:nvUbdizC $E789:4A LSR
  1673. f13939 c415112893 i51347957 A:28 X:D0 Y:00 S:DE P:nvUbdizc $E78A:4A LSR
  1674. f13939 c415112895 i51347958 A:14 X:D0 Y:00 S:DE P:nvUbdizc $E78B:4A LSR
  1675. f13939 c415112897 i51347959 A:0A X:D0 Y:00 S:DE P:nvUbdizc $E78C:AA TAX ; Here, X is set to A… = $0A
  1676. f13939 c415112899 i51347960 A:0A X:0A Y:00 S:DE P:nvUbdizc $E78D:68 PLA
  1677. f13939 c415112903 i51347961 A:48 X:0A Y:00 S:DF P:nvUbdizc $E78E:C9 13 CMP #$13
  1678. f13939 c415112905 i51347962 A:48 X:0A Y:00 S:DF P:nvUbdizC $E790:90 0C BCC $E79E
  1679. f13939 c415112907 i51347963 A:48 X:0A Y:00 S:DF P:nvUbdizC $E792:BD 65 E7 LDA Music_PatchTableLong,X @ $E76F = #$61 ; Load Patch address using X as an index
  1680. f13939 c415112911 i51347964 A:61 X:0A Y:00 S:DF P:nvUbdizC $E795:85 71 STA Music_PatchAdrL = #$61
  1681. f13939 c415112914 i51347965 A:61 X:0A Y:00 S:DF P:nvUbdizC $E797:BD 66 E7 LDA $E766,X @ $E770 = #$B3
  1682. f13939 c415112918 i51347966 A:B3 X:0A Y:00 S:DF P:NvUbdizC $E79A:85 72 STA Music_PatchAdrH = #$B3
  1683. f13939 c415112921 i51347967 A:B3 X:0A Y:00 S:DF P:NvUbdizC $E79C:D0 0A BNE $E7A8
  1684. f13939 c415112924 i51347968 A:B3 X:0A Y:00 S:DF P:NvUbdizC $E7A8:B1 71 LDA ($71),Y @ $B361 = #$50
  1685. f13939 c415112929 i51347969 A:50 X:0A Y:00 S:DF P:nvUbdizC $E7AA:60 RTS (from Music_PatchGetCTL) ---------------
  1686. f13939 c415112935 i51347970 A:50 X:0A Y:00 S:E1 P:nvUbdizC $E651:8D 00 40 STA PAPU_CTL1 = #$50 ; Store Patch into PAPU_CTL1
  1687. f13939 c415112939 i51347971 A:50 X:0A Y:00 S:E1 P:nvUbdizC $E654:AD FA 04 LDA Music_Sq1AltRamp = #$00
  1688. f13939 c415112943 i51347972 A:00 X:0A Y:00 S:E1 P:nvUbdiZC $E657:D0 02 BNE $E65B
  1689. f13939 c415112945 i51347973 A:00 X:0A Y:00 S:E1 P:nvUbdiZC $E659:A9 7F LDA #$7F
  1690. f13939 c415112947 i51347974 A:7F X:0A Y:00 S:E1 P:nvUbdizC $E65B:8D 01 40 STA PAPU_RAMP1 = #$7F
  1691. f13939 c415112951 i51347975 A:7F X:0A Y:00 S:E1 P:nvUbdizC $E65E:D0 05 BNE Music_TriTrack
  1692. f13939 c415112954 i51347976 A:7F X:0A Y:00 S:E1 P:nvUbdizC $E665:AD D0 04 LDA Music_TriTrkPos = #$95
  1693. f13939 c415112958 i51347977 A:95 X:0A Y:00 S:E1 P:NvUbdizC $E668:F0 53 BEQ Music_NseTrack
  1694. f13939 c415112960 i51347978 A:95 X:0A Y:00 S:E1 P:NvUbdizC $E66A:CE D9 04 DEC Music_TriRest = #$2D
  1695. f13939 c415112966 i51347979 A:95 X:0A Y:00 S:E1 P:nvUbdizC $E66D:D0 4E BNE Music_NseTrack
  1696. f13939 c415112969 i51347980 A:95 X:0A Y:00 S:E1 P:nvUbdizC $E6BD:AD D1 04 LDA Music_NseTrkPos = #$AE
  1697. f13939 c415112973 i51347981 A:AE X:0A Y:00 S:E1 P:NvUbdizC $E6C0:F0 3B BEQ Music_PCMTrack
  1698. f13939 c415112975 i51347982 A:AE X:0A Y:00 S:E1 P:NvUbdizC $E6C2:CE DA 04 DEC Music_NoiseRest = #$F7
  1699. f13939 c415112981 i51347983 A:AE X:0A Y:00 S:E1 P:NvUbdizC $E6C5:D0 36 BNE Music_PCMTrack
  1700. f13939 c415112984 i51347984 A:AE X:0A Y:00 S:E1 P:NvUbdizC $E6FD:4C 09 E7 JMP $E709
  1701. f13939 c415112987 i51347985 A:AE X:0A Y:00 S:E1 P:NvUbdizC $E709:AD D2 04 LDA Music_PCMTrkPos = #$A6
  1702. f13939 c415112991 i51347986 A:A6 X:0A Y:00 S:E1 P:NvUbdizC $E70C:F0 2A BEQ $E738
  1703. f13939 c415112993 i51347987 A:A6 X:0A Y:00 S:E1 P:NvUbdizC $E70E:CE DC 04 DEC Music_DMCRest = #$01
  1704. f13939 c415112999 i51347988 A:A6 X:0A Y:00 S:E1 P:nvUbdiZC $E711:D0 25 BNE $E738
  1705. f13939 c415113001 i51347989 A:A6 X:0A Y:00 S:E1 P:nvUbdiZC $E713:AC D2 04 LDY Music_PCMTrkPos = #$A6
  1706. f13939 c415113005 i51347990 A:A6 X:0A Y:A6 S:E1 P:NvUbdizC $E716:EE D2 04 INC Music_PCMTrkPos = #$A6
  1707. f13939 c415113011 i51347991 A:A6 X:0A Y:A6 S:E1 P:NvUbdizC $E719:B1 6B LDA ($6B),Y @ $00A6 = #$00
  1708. f13939 c415113016 i51347992 A:00 X:0A Y:A6 S:E1 P:nvUbdiZC $E71B:F0 24 BEQ $E741
  1709. f13939 c415113019 i51347993 A:00 X:0A Y:A6 S:E1 P:nvUbdiZC $E741:AD DE 04 LDA Music_PCMStart = #$95
  1710. f13939 c415113023 i51347994 A:95 X:0A Y:A6 S:E1 P:NvUbdizC $E744:8D D2 04 STA Music_PCMTrkPos = #$A7
  1711. f13939 c415113027 i51347995 A:95 X:0A Y:A6 S:E1 P:NvUbdizC $E747:4C 13 E7 JMP $E713
  1712. f13939 c415113030 i51347996 A:95 X:0A Y:A6 S:E1 P:NvUbdizC $E713:AC D2 04 LDY Music_PCMTrkPos = #$95
  1713. f13939 c415113034 i51347997 A:95 X:0A Y:95 S:E1 P:NvUbdizC $E716:EE D2 04 INC Music_PCMTrkPos = #$95
  1714. f13939 c415113040 i51347998 A:95 X:0A Y:95 S:E1 P:NvUbdizC $E719:B1 6B LDA ($6B),Y @ $0095 = #$00
  1715. f13939 c415113045 i51347999 A:00 X:0A Y:95 S:E1 P:nvUbdiZC $E71B:F0 24 BEQ $E741
  1716. f13939 c415113048 i51348000 A:00 X:0A Y:95 S:E1 P:nvUbdiZC $E741:AD DE 04 LDA Music_PCMStart = #$95
  1717. f13939 c415113052 i51348001 A:95 X:0A Y:95 S:E1 P:NvUbdizC $E744:8D D2 04 STA Music_PCMTrkPos = #$96
  1718. f13939 c415113056 i51348002 A:95 X:0A Y:95 S:E1 P:NvUbdizC $E747:4C 13 E7 JMP $E713
  1719. f13939 c415113059 i51348003 A:95 X:0A Y:95 S:E1 P:NvUbdizC $E713:AC D2 04 LDY Music_PCMTrkPos = #$95
  1720. f13939 c415113063 i51348004 A:95 X:0A Y:95 S:E1 P:NvUbdizC $E716:EE D2 04 INC Music_PCMTrkPos = #$95
  1721. f13939 c415113069 i51348005 A:95 X:0A Y:95 S:E1 P:NvUbdizC $E719:B1 6B LDA ($6B),Y @ $0095 = #$00
  1722. f13939 c415113074 i51348006 A:00 X:0A Y:95 S:E1 P:nvUbdiZC $E71B:F0 24 BEQ $E741
  1723.  
  1724. So we are stuck in the PCM loop, but X is now $0A…
  1725.  
  1726. We attempt to increment $959D. Since $959D has value $04, this is the same as writing $05 to MMC3 Page ($8001). So we load in PRG05.
  1727. This changes the page at $A000 to PRG05, and we continue executing, now in a different bank.
  1728.  
  1729. f13983 c416424574 i51664921 A:00 X:0A Y:01 S:E3 P:nvUbdiZc $A087:FE 93 95 INC $9593,X @ $959D = #$04
  1730. f13983 c416424581 i51664922 A:00 X:0A Y:01 S:E3 P:nvUbdizc $A08A:4F UNDEFINED
  1731. f13983 c416424587 i51664923 A:27 X:0A Y:01 S:E3 P:nvUbdizC $A08D:A4 F3 LDY Obj01_Flag = #$00
  1732. f13983 c416424590 i51664924 A:27 X:0A Y:00 S:E3 P:nvUbdiZC $A08F:A2 A0 LDX #$A0
  1733. f13983 c416424592 i51664925 A:27 X:A0 Y:00 S:E3 P:NvUbdizC $A091:D3 UNDEFINED
  1734. f13983 c416424600 i51664926 A:27 X:A0 Y:00 S:E3 P:NvUbdizc $A093:D3 UNDEFINED
  1735. etc etc… many more frames of garbage execution…
  1736. Until we get here:
  1737. f13983 c416425620 i51665181 A:27 X:A0 Y:00 S:E3 P:nvUBdiZc $A0EE:15 15 ORA $15,X @ Objects_SpriteY = #$00
  1738. f13983 c416425624 i51665182 A:27 X:A0 Y:00 S:E3 P:nvUBdizc $A0F0:30 30 BMI $A122
  1739. f13983 c416425626 i51665183 A:27 X:A0 Y:00 S:E3 P:nvUBdizc $A0F2:02 UNDEFINED
  1740.  
  1741. ^The last instruction executed was $02. $02 is the KIL opcode.. It locks up the CPU for good, and nothing else happens with the CPU until the reset button is pressed, or the game is powered off and back on.
  1742.  
  1743.  
  1744. To help avoid a crash from the music engine, we can release the down button just before we hit A to trigger the glitch.
  1745. This results in the “Jump” sound playing, instead of the “Bump” sound. Because this stops the square 1 music code from being ran, it means X will always be $7F. This means we won’t eventually crash and lock up the CPU.
  1746. Testing revealed that letting go of down just before triggering the credits warp, will save 99% of crashes caused by the sound engine.
  1747.  
  1748. Values that the X register can contain, depending on where in the music we triggered the Wrong Warp:
  1749.  
  1750. $00 = $9593 (holds C0) (Crash)
  1751. $0A = $959D (holds 04) (crash)
  1752. $48 = $95DB (holds 53) (Crash)
  1753. $7F = $9612 (holds 60) (okay)
  1754.  
  1755. Note that since the values for the Noise channel (and maybe DMC channel) were modified, this results in strange “crash” sounds or other audio anomalies.
  1756.  
  1757. If we happen to trigger the credits warp when square 2 was playing a note (i.e the melody part of Underground is playing), then it’s rest value will hit $00 before any other channel - as explained before, this tells the sound engine to go to the next segment, which fixes up the music engine ram at $6B & 6C.
  1758. So we never get stuck in the continuous loop, we have no risk of a crash, and we reach the credits earlier.
  1759.  
  1760. If square 2 is not playing a note, then it is resting. Depending on the rest value of the square 2 channel when we execute the credits warp, we may end up with a large rest value, and hence a long delay as it decrements this value every frame until it hits 0.
  1761. This is why some credits warps are very slow - they were triggered with a higher square 2 rest value.
  1762. The difference between optimal credits and slow credits warp is usually $47 frames, or in decimal, 71 frames. Although there is one part of the song that results in an additional $1A frames, for a worst case scenario of $47 + $1A = $61 frames = decimal 97 frames!!! in other words, over 1.5 seconds can be lost because of the music!
  1763.  
  1764.  
  1765. Credits to Southbird for his work on the NES SMB3 disassembly.
  1766. -KabAudio October 2020
Add Comment
Please, Sign In to add comment