nesdev.comhttp://forums.nesdev.com/ NES Blaster Master Boss Skiphttp://forums.nesdev.com/viewtopic.php?f=2&t=16512 Page 1 of 1

 Author: CLChambers00 [ Tue Sep 19, 2017 4:11 pm ] Post subject: NES Blaster Master Boss Skip The Boss Skip that had been observed during a live run during AGDQ 2017 can be seen here: https://www.youtube.com/watch?v=g5Hq2eA ... e&t=28m55sI have observed that \$03FB will increment after you defeat a boss. From the beginning of the game this is set at value 0, then value 1 after the first boss, and then at value 3 after the second boss. In other words, if you overwrite the value of 3 into \$03FB just before entering the second boss fight then you will observe what we see in the video. The game thinks the boss was already defeated. I have observed that \$03FB increments the same frame that \$03FD reaches a value of 128. \$03FD starts at 0 from the beginning of the game and only does a 255 to 0 count down at the beginning of each boss fight, and then counts up from 0 to 128 upon the death of the boss. When this value reaches 128 then \$03FB, the address that tracks what bosses have been defeated, will increment. Observation #1 The first boss loads normally which means that \$03FB is at value 0 when entering the first boss fight. If this value was 1 or higher then the boss would not spawn. The first moment that \$03FB normally increments is upon the death of the first boss, in which case it increments to 1. Observation #2 Upon entering the second boss fight the boss did not load which means that \$03FB was already at a value of 3.Conclusion: At some point this address is incremented again. My first suspicion is that it occurs after the first boss fight, that some how it is incremented twice. The later portion of this message shows "conditions" upon an overflow may occur that could possibly corrupt this address but it is still unclear exactly how these conditions could be met.This is the most pertinent information that I have been able to find at this time.I played around a little with the Chou-Wakusei Senki - MetaFight (J).nes ROM (GoodNES 3.14) after seeing that happen and will summarize some info here. Hopefully this will serve as a starting point for figuring out the glitch. I used FCEUX 2.2.3 and only played as far as the second boss fight.After the scrolling ends when you enter a boss room, the following code is executed:Code:\$971A:A5 14     LDA \$0014\$971C:29 07     AND #\$07\$971E:AA        TAX\$971F:BD 2B B6  LDA \$B62B,X\$9722:60        RTS\$9627:2D FB 03  AND \$03FB    <-- This is the important check\$962A:D0 0F     BNE \$963B    <-- Branch taken if boss defeated\$962C:A9 C0     LDA #\$C0\$962E:85 51     STA \$0051\$9630:A9 08     LDA #\$08\$9632:20 8C C1  JSR \$C18C\$9635:20 CD 97  JSR \$97CD\$9638:E6 46     INC \$0046\$963A:60        RTS\$963B:20 1A 97  JSR \$971A\$0014 is the value (current area - 1) at this point. At \$B62B, you find a sequence of increasing powers of two, starting with 0x01. Per Data Crystal's RAM map, \$03FB indicates which bosses have been defeated. So this checks if the boss of the current area has been defeated. If it has but the item has not been obtained, then the item is displayed. That seems to be what happened during the race.If the boss has not been defeated, then the room flashes, the boss loads (including its health), and you proceed with the fight. It appears that the health of the first two bosses is hard-coded into the ROM. For area 1, the pertinent code is:Code:\$9C15:A9 80     LDA #\$80\$9C17:85 53     STA \$0053For area 2, the pertinent code is:Code:\$91FD:A9 40     LDA #\$40\$91FF:85 53     STA \$0053The value from \$0053 eventually ends up somewhere around \$0470, but the exact RAM address varies. If you change the health to 0x00 before starting the fight (e.g., set execution breakpoint on \$9C17, change A from 0x80 to 0x00, then continue emulation), the boss graphics load but immediately go into the death animation. This leads me to believe that whatever Skavenger did may have corrupted \$03FB. There are likely other possibilities, but I will let someone with more time and experience take over.Actually, one other thing. This is the code that is executed when a boss is defeated:Code:\$971A:A5 14     LDA \$0014\$971C:29 07     AND #\$07\$971E:AA        TAX\$971F:BD 2B B6  LDA \$B62B,X\$9722:60        RTS\$97A7:0D FB 03  ORA \$03FB\$97AA:8D FB 03  STA \$03FBMost if it should be familiar from that first block, but the last two lines update the value at \$03FB rather than testing it.And another analysis:I haven't looked at Blaster Master before, but this glitch got me curious, so a few observations from looking at the code in case they give anyone any ideas. Note that these are all from the English ROM (the only version I have handy), so if the glitch turns out to be JP-only then none of this may be of much use...- The only stores to \$03FB are the one Dacicus quoted which is done on boss kill, and a few that store literal 0 or 255 (and the 255 clearly can't be the case because the rest of the bosses showed up properly). The store after the area 1 boss kill in that run can't have set the wrong bit, because then the boss would immediately respawn when the room was reloaded after the boss death.- The only indexed stores that could reach \$03FB are the stores to the PPU RAM write buffer at \$0300. I played up to area 2 to check, but the buffer high water mark was \$0340, and a cursory review of the code suggests it's pretty good at flushing the buffer before it overflows, so it seems unlikely to me that a buffer overflow is the cause. (Also, in order to have disabled only the second boss, the store value would have to have been \$02 or \$03, which seems unlikely for an arbitrary PPU data store; and if the buffer overflowed all the way up to \$03FB then it would stomp on lots of other stuff in the \$03xx range, which would probably cause more problems than just a missing boss.) On the other hand, Personman's example of a case when both a boss and its item were missing could indicate a buffer overflow that wrongly set bits in both \$03FB and \$03FC, so I dunno.- The boss-defeated store to \$03FB has this stack trace (again, addresses are from the English ROM - bank 4 is mapped to \$8000 here):Code:(0) A109: sta \$03FB(1) A58C: jsr \$A07B(2) C9D3: jmp (\$007A) = \$A58C(3) C987: jsr \$C9A4(4) C3D8: jsr \$C971For \$A07B to reach the store to \$03FB, the following have to be true:- \$0053 = 0- The low bit of \$0010 is clear- \$03FD >= 127It does look like this routine is called for other purposes as well, so conceivably there could be a case where all those preconditions are (incorrectly) met, which would trigger the glitch.Here's the relevant part of that routine:Code:A07B: A5 53     lda \$53A07D: F0 10     beq \$A08FA07F: AD FD 03  lda \$03FDA082: F0 7B     beq \$A0FFA084: CE FD 03  dec \$03FDA087: D0 76     bne \$A0FFA089: 20 18 A1  jsr \$A118A08C: 4C FC A0  jmp \$A0FCA08F: A5 10     lda \$10A091: 4A        lsr aA092: B0 19     bcs \$A0ADA094: AD FD 03  lda \$03FDA097: D0 0A     bne \$A0A3A099: A9 0A     lda #\$0AA09B: 20 16 C2  jsr \$C216A09E: A9 0B     lda #\$0BA0A0: 20 16 C2  jsr \$C216A0A3: EE FD 03  inc \$03FDA0A6: AD FD 03  lda \$03FDA0A9: C9 80     cmp #\$80A0AB: B0 53     bcs \$A100(...)A100: 20 0E C1  jsr \$C10E  // Only reachable from branch at \$A0ABA103: 20 72 A0  jsr \$A072  // Get bit for current area (encapsulates "lda \$14" etc.)A106: 0D FB 03  ora \$03FB  // Set boss-killed flag for current areaA109: 8D FB 03  sta \$03FB  // Store updated flag byteA10C: A9 5A     lda #\$5AA10E: 85 46     sta \$46A110: A9 00     lda #\$00A112: 20 1A C1  jsr \$C11AA115: 68        plaA116: 68        plaA117: 60        rts

 Author: CLChambers00 [ Wed Sep 20, 2017 6:51 pm ] Post subject: Re: NES Blaster Master Boss Skip This is my first crack at this issue today. Thoughts are always appreciated. At the beginning of the game when the memory is initialized, address \$03FB is set to #\$00. Perhpas a simple hack of the rom could have this value set to 2 and this would still allow the first boss to spawn and cause the second boss not to be present since \$03FB would be at value 3. Since the starting value is 2, then the amount it will increment is based upon the value 2 to the power of \$0014 value. Since area 1 boss is in \$0014 value zero, then 2 to the power of zero is 1, and therefore the resulting value of \$03FB after Boss one is 3. This of course is assuming that the rom was hacked.Code:STA \$0300,X @ \$03FB = #\$00 ;Initializing memory, setting address to zeroUpon entering the Boss 1 room the following executes. Notable is that it loads the value of address \$0014 to the A Register. When I used a Lua Script to change \$0014 to a value of 1, the value of Boss 2 location, I was able to get the Boss 2 to spawn in the Boss 1 area. The value of \$03FB is checked at this time. If the value is a 0, as it is supposed to be, then the Boss will spawn. If the value is 1, which it should be after the Boss fight, then the boss will not spawn. I also checked and even if this value was a 2 then the boss will still spawn. Basically here after the AND \$03FB instruction it will Branch on Not Equal as seen BNE \$963B.Code:\$961F:F0 03     BEQ \$9624                                    A:00 X:0A Y:00 S:FB P:nvUbdIZC     \$9624:20 1A 97  JSR \$971A                                    A:00 X:0A Y:00 S:FB P:nvUbdIZC       \$971A:A5 14     LDA \$0014 = #\$00                             A:00 X:0A Y:00 S:F9 P:nvUbdIZC       \$971C:29 07     AND #\$07                                     A:00 X:0A Y:00 S:F9 P:nvUbdIZC       \$971E:AA        TAX                                          A:00 X:0A Y:00 S:F9 P:nvUbdIZC       \$971F:BD 2B B6  LDA \$B62B,X @ \$B62B = #\$01                   A:00 X:00 Y:00 S:F9 P:nvUbdIZC       \$9722:60        RTS (from \$971A) --------------------------- A:01 X:00 Y:00 S:F9 P:nvUbdIzC     \$9627:2D FB 03  AND \$03FB = #\$00                             A:01 X:00 Y:00 S:FB P:nvUbdIzC     \$962A:D0 0F     BNE \$963B                                    A:00 X:00 Y:00 S:FB P:nvUbdIZC     \$962C:A9 C0     LDA #\$C0                                     A:00 X:00 Y:00 S:FB P:nvUbdIZC     \$962E:85 51     STA \$0051 = #\$00                             A:C0 X:00 Y:00 S:FB P:NvUbdIzC     \$9630:A9 08     LDA #\$08                                     A:C0 X:00 Y:00 S:FB P:NvUbdIzC     \$9632:20 8C C1  JSR \$C18C                                    A:08 X:00 Y:00 S:FB P:nvUbdIzC At the beginning of the Boss 1 fight when the boss begins to load, address 03FD is set to the value 255 and then decrements to 0, at which time the boss begins to move. Upon the death of the boss address 03FD increments up to 128 from zero. Once 03FD reaches 128 (#\$80)then we see the following execute when the Comparision is made. It is at this time that the addition to \$03FB will be 2 to the power of the value of \$0014, the area locator. If at any time that \$0014 is changed via Lua Script then the game starts to glitch between where you are and where you are telling the game where you are. I have observed some funny things as a result of this. What this means is that I think that it is unlikely that the game was confused as to your location and therefore gave a different value in \$03FB, because it thought that you were in a different \$0014 location. If \$0014 was anything but 0 during the boss 1 fight then you would see graphical distortions. Since the addition to \$03FB only occurs after a boss is defeated it would be curious how it might occur at any other time, and if so, then how?Code:    \$9C2D:20 23 97  JSR \$9723                                    A:2D X:2A Y:00 S:FB P:nvUbdIzc       \$9723:A5 53     LDA \$0053 = #\$00                             A:2D X:2A Y:00 S:F9 P:nvUbdIzc       \$9725:F0 10     BEQ \$9737                                    A:00 X:2A Y:00 S:F9 P:nvUbdIZc       \$9737:A5 10     LDA \$0010 = #\$14                             A:00 X:2A Y:00 S:F9 P:nvUbdIZc       \$9739:4A        LSR                                          A:14 X:2A Y:00 S:F9 P:nvUbdIzc       \$973A:B0 19     BCS \$9755                                    A:0A X:2A Y:00 S:F9 P:nvUbdIzc       \$973C:AD FD 03  LDA \$03FD = #\$7F                             A:0A X:2A Y:00 S:F9 P:nvUbdIzc       \$973F:D0 0A     BNE \$974B                                    A:7F X:2A Y:00 S:F9 P:nvUbdIzc       \$974B:EE FD 03  INC \$03FD = #\$7F                             A:7F X:2A Y:00 S:F9 P:nvUbdIzc       \$974E:AD FD 03  LDA \$03FD = #\$80                             A:7F X:2A Y:00 S:F9 P:NvUbdIzc       \$9751:C9 80     CMP #\$80                                     A:80 X:2A Y:00 S:F9 P:NvUbdIzc       \$9753:B0 4C     BCS \$97A1                                    A:80 X:2A Y:00 S:F9 P:nvUbdIZC       \$97A1:20 C9 C0  JSR \$C0C9                                    A:80 X:2A Y:00 S:F9 P:nvUbdIZC         \$C0C9:4C 5B D0  JMP \$D05B                                    A:80 X:2A Y:00 S:F7 P:nvUbdIZC       (...)        \$D066:60        RTS (from \$C0C9) --------------------------- A:0F X:FF Y:00 S:F7 P:NvUbdIzC       \$97A4:20 1A 97  JSR \$971A                                    A:0F X:FF Y:00 S:F9 P:NvUbdIzC         \$971A:A5 14     LDA \$0014 = #\$00                             A:0F X:FF Y:00 S:F7 P:NvUbdIzC         \$971C:29 07     AND #\$07                                     A:00 X:FF Y:00 S:F7 P:nvUbdIZC         \$971E:AA        TAX                                          A:00 X:FF Y:00 S:F7 P:nvUbdIZC         \$971F:BD 2B B6  LDA \$B62B,X @ \$B62B = #\$01                   A:00 X:00 Y:00 S:F7 P:nvUbdIZC         \$9722:60        RTS (from \$971A) --------------------------- A:01 X:00 Y:00 S:F7 P:nvUbdIzC       \$97A7:0D FB 03  ORA \$03FB = #\$00                             A:01 X:00 Y:00 S:F9 P:nvUbdIzC       \$97AA:8D FB 03  STA \$03FB = #\$00                             A:01 X:00 Y:00 S:F9 P:nvUbdIzC       \$97AD:A9 5A     LDA #\$5A                                     A:01 X:00 Y:00 S:F9 P:nvUbdIzC       \$97AF:85 46     STA \$0046 = #\$63                             A:5A X:00 Y:00 S:F9 P:nvUbdIzC       \$97B1:A9 00     LDA #\$00                                     A:5A X:00 Y:00 S:F9 P:nvUbdIzC       \$97B3:20 D5 C0  JSR \$C0D5                                   A:00 X:00 Y:00 S:F9 P:nvUbdIZC Twenty nine frames after this addition to \$03FB occurs the \$971A sub routine runs again (twice). After the first sub routine it checks the \$03FB address, and then it will branch if not equal BNE \$963B, the same as when we entered the room. And the second routine is followed by a check to \$03FC, seeing if you have already collected the item, and then a branch if not equal BNE \$965C.Code:   \$961F:F0 03     BEQ \$9624                                    A:00 X:0A Y:00 S:FB P:nvUbdIZC     \$9624:20 1A 97  JSR \$971A                                    A:00 X:0A Y:00 S:FB P:nvUbdIZC       \$971A:A5 14     LDA \$0014 = #\$00                             A:00 X:0A Y:00 S:F9 P:nvUbdIZC       \$971C:29 07     AND #\$07                                     A:00 X:0A Y:00 S:F9 P:nvUbdIZC       \$971E:AA        TAX                                          A:00 X:0A Y:00 S:F9 P:nvUbdIZC       \$971F:BD 2B B6  LDA \$B62B,X @ \$B62B = #\$01                   A:00 X:00 Y:00 S:F9 P:nvUbdIZC       \$9722:60        RTS (from \$971A) --------------------------- A:01 X:00 Y:00 S:F9 P:nvUbdIzC     \$9627:2D FB 03  AND \$03FB = #\$01                             A:01 X:00 Y:00 S:FB P:nvUbdIzC     \$962A:D0 0F     BNE \$963B                                    A:01 X:00 Y:00 S:FB P:nvUbdIzC     \$963B:20 1A 97  JSR \$971A                                    A:01 X:00 Y:00 S:FB P:nvUbdIzC       \$971A:A5 14     LDA \$0014 = #\$00                             A:01 X:00 Y:00 S:F9 P:nvUbdIzC       \$971C:29 07     AND #\$07                                     A:00 X:00 Y:00 S:F9 P:nvUbdIZC       \$971E:AA        TAX                                          A:00 X:00 Y:00 S:F9 P:nvUbdIZC       \$971F:BD 2B B6  LDA \$B62B,X @ \$B62B = #\$01                   A:00 X:00 Y:00 S:F9 P:nvUbdIZC       \$9722:60        RTS (from \$971A) --------------------------- A:01 X:00 Y:00 S:F9 P:nvUbdIzC     \$963E:2D FC 03  AND \$03FC = #\$00                             A:01 X:00 Y:00 S:FB P:nvUbdIzC     \$9641:D0 19     BNE \$965C                                    A:00 X:00 Y:00 S:FB P:nvUbdIZC     \$9643:A5 14     LDA \$0014 = #\$00                             A:00 X:00 Y:00 S:FB P:nvUbdIZC     \$9645:C9 07     CMP #\$07                                     A:00 X:00 Y:00 S:FB P:nvUbdIZC     \$9647:D0 0E     BNE \$9657                                    A:00 X:00 Y:00 S:FB P:NvUbdIzc     \$9657:A9 6A     LDA #\$6A                                     A:00 X:00 Y:00 S:FB P:NvUbdIzc     \$9659:85 46     STA \$0046 = #\$5A                             A:6A X:00 Y:00 S:FB P:nvUbdIzc     \$965B:60        RTS (from \$C8EC) --------------------------- A:6A X:00 Y:00 S:FB P:nvUbdIzcWhile there may not be anything revelatoty here beyond the previous posts concerning the matter, but it is where I am at with it at the moment.

 Author: B00daW [ Thu Sep 21, 2017 9:53 pm ] Post subject: Re: NES Blaster Master Boss Skip I want to provide you with key information that may help you with this... Values from \$8000+ cannot change in value unless they have been bankswapped through bankswitching. Find out which "mapper" MetaFight or Blaster Master is... Research the bankswitching portion for PRG ROM to figure out if you're seeing values change because of bankswitching.\$8000-\$FFFF is ROM. These values CANNOT be written to... They can be addressed for external functions, such as mappers that perform bankswitching.The address values for subroutines that you describe between \$8000-\$FFFF can change if they have been bankswapped.Bankswitching is a way for the NES/Famicom to address more than 32K of PRG ROM in a quick fashion.Please attach savestates and movie files for those of us who are not as good at videogames as you are.

 Author: tepples [ Fri Sep 22, 2017 6:35 am ] Post subject: Re: NES Blaster Master Boss Skip Blaster Master is SLROM: 128 KiB PRG ROM, 128 KiB CHR ROM, no WRAM, MMC1.

Author:  CLChambers00 [ Fri Sep 22, 2017 10:30 am ]
Post subject:  Re: NES Blaster Master Boss Skip

Thank you B00daW for that explanation, that \$8000+ is used for Rom explains why I could not add \$B62C to the Ram watch, and why I was not able to write a value to it via Lua Script. As for bankswitching/bankswapping I am not sure I quite understand except that I did observe that addresses like \$B62C were temporarily used when it loads the screen after death and loading the screen when unpausing it. Is this an example of bankswitching/bankswapping?

Thank you for the link Tepples.

Attached you will find the disassembly for Chou-Wakusei Senki - MetaFight (J).nes. This is the Rom on which this issue occurred so I am sticking with it. I did notice that the J version has only 6 references to \$03FB while the US version has 7 references. I did not check to see what was added to the US version. The J version was released first so I wonder why the developers thought to modify the US version to involve one more reference to \$03FB. Were they trying to fix something and if so is it relevant. See Zeronoid's analysis of some key differences between these versions, if interested, either way I am focusing on the J version. http://zeronoin.com/bm/0002.html

Attached you will also find three text files compiled by Trace Logger taking a one frame snapshot of when \$03FB is referenced. First when it is checked to see if you have beaten the boss, second after you beat the boss and if so it writes an updated value to it, and third, immediately after to see if this is still true before checking to spawn the item or not.

Shortly I will post the FM2 file for FCEUX which can be played in the TAS Editor up to and defeating the second boss.

 Attachments: Blaster Master J Disassemble.zip [824.81 KiB] Downloaded 45 times Boss 2 logger 3.log [827.28 KiB] Downloaded 41 times Boss 2 logger 2.log [826.88 KiB] Downloaded 43 times Boss 2 logger 1.log [858.54 KiB] Downloaded 49 times

Author:  CLChambers00 [ Fri Sep 22, 2017 10:50 am ]
Post subject:  Re: NES Blaster Master Boss Skip

Attached is the FM2 file of a poor attempt at good game play It plays up to and defeats Boss 2. This Boss 2 is the one that did not spawn but the item did on one live occasion. I have not been able to duplicate this without a Lua Script to \$03FB. I used controller input recording in the TAS Editor and I have to say that FCUEX lags horridly when doing this. It is like playing the game at 1/8 the normal speed. I think that BizHawk does not lag in this same way and I wonder why that is.

 Attachments: MetaFight (J) TASed Example.fm2 [377.45 KiB] Downloaded 43 times

Author:  CLChambers00 [ Fri Sep 22, 2017 11:13 am ]
Post subject:  Re: NES Blaster Master Boss Skip

The following are 5 save states. I did not know how many would be appropriate so I created a save state just before entering a new \$0014 value location, and just before entering the Boss.

FC1 = Just before entering into \$0014 value 0 location from the starting 8 value at beginning of the game. This is when you are playing with the large walking character.
FC2 = Just before entering the Boss 1 fight in \$0014 value 0 location.
FC3 = Just before entering the \$0014 value 9 location. After the Boss one fight in \$0014 value 0 location we back track to value 8 and that is where we are before entering 9.
FC4 = Just before entering the \$0014 value 1 location. This is when you are playing with the large walking character again.
FC5 = Just before entering the Boss 2 fight in \$0014 value 1 locaiton.