News: 11 March 2016 - Forum Rules
Current Moderators - DarkSol, KingMike, MathOnNapkins, Azkadellia, Danke

Author Topic: Super Mario Bros. - 128 Lives Fix  (Read 3219 times)

SMB2J-2Q

  • Full Member
  • ***
  • Posts: 135
    • View Profile
Super Mario Bros. - 128 Lives Fix
« on: September 27, 2014, 12:52:31 am »
It is well known that there is a bug in Super Mario Bros. for the NES that, if you manage to score 128 or more lives, you will get Game Over the next time you die.

My question is, which code would I modify to correct this data, so that obtaining 128 lives and beyond won't mean Game Over anymore, and would also cap 255 ($ff) as the maximum, without resetting to zero? Subsequent remakes such as Super Mario All-Stars (SNES) and Super Mario Bros. Deluxe (Game Boy Color) acknowledged the bug and the resulting side effect from the original NES port, and so have fixed this issue, thus capping the extra life amount to 127.

Thank you,



Ben

Lenophis

  • Discord Staff
  • Hero Member
  • *****
  • Posts: 971
  • The return of the sombrero!
    • View Profile
    • Slick Productions
Re: Super Mario Bros. - 128 Lives Fix
« Reply #1 on: September 27, 2014, 01:34:06 am »
Well, based on what you said, it probably does a DEC on the amount of lives, then does a BPL or a BMI to determine if you have a game over or not. If you are at 128 or higher, the negative flag will be set, and the BMI will trip, causing the game over.

As one alternative, you could do the DEC, but then branch if it's zero or not (BEQ/BNE). This still won't be a perfect check, since the game probably doesn't have any bounds/wrapping check on the number of lives. I don't know this for a fact, however.


https://ff6randomizer.codeplex.com/ - Randomize your FF6 experience!

KingMike

  • Forum Moderator
  • Hero Member
  • *****
  • Posts: 7102
  • *sigh* A changed avatar. Big deal.
    • View Profile
Re: Super Mario Bros. - 128 Lives Fix
« Reply #2 on: September 27, 2014, 01:49:06 am »
It is an incredibly simple patch that I recall taking only about five minutes to find, test and fix, thanks to the SMB Disassembly.
I'd seriously recommend it, if you want to learn how to make your own SMB hacks, than just having the answer given.

Spoiler:
Code: [Select]
000004A7: FF 00
00000851: 01 00
0000107A: 02 03
000011EC: 10 D0

Code: [Select]
00:883C:AD 5A 07  LDA $075A = #$02
 00:883F:18        CLC
 00:8840:69 01     ADC #$01      ;fixes it so that lives shown is number of lives remaining (ie. 3 for 3 lives, instead of 2 for 3 lives)
 00:8842:C9 0A     CMP #$0A
 00:8844:90 07     BCC $884D
 00:8846:E9 0A     SBC #$0A

Code: [Select]
00:9069:A9 02     LDA #$02  ;in accordance with the above change, sets starting lives to 3 for 3 lives
 00:906B:8D 5A 07  STA $075A = #$02

Code: [Select]
00:91D9:CE 5A 07  DEC $075A = #$02    ;this line subtracts a life
 00:91DC:10 0B     BPL $91E9    ;change to BNE $91E9: effect that it goes to Game Over when lives = 0, not when negative flag set

As to 255 lives... I don't care to make a fix but the life+1 instruction is at CPU address $84E6.
Find some free space, if you can because SMB is notoriously low on empty space, to JSR to a 9-byte subroutine you insert in said free space that may or may be able to be found INC $075A: BNE $03: DEC $075A: RTS
"My watch says 30 chickens" Google, 2018

SMB2J-2Q

  • Full Member
  • ***
  • Posts: 135
    • View Profile
Re: Super Mario Bros. - 128 Lives Fix
« Reply #3 on: September 27, 2014, 02:33:14 am »
It is an incredibly simple patch that I recall taking only about five minutes to find, test and fix, thanks to the SMB Disassembly.
I'd seriously recommend it, if you want to learn how to make your own SMB hacks, than just having the answer given.

Spoiler:
Code: [Select]
000004A7: FF 00
00000851: 01 00
0000107A: 02 03
000011EC: 10 D0

Code: [Select]
00:883C:AD 5A 07  LDA $075A = #$02
 00:883F:18        CLC
 00:8840:69 01     ADC #$01      ;fixes it so that lives shown is number of lives remaining (ie. 3 for 3 lives, instead of 2 for 3 lives)
 00:8842:C9 0A     CMP #$0A
 00:8844:90 07     BCC $884D
 00:8846:E9 0A     SBC #$0A

Code: [Select]
00:9069:A9 02     LDA #$02  ;in accordance with the above change, sets starting lives to 3 for 3 lives
 00:906B:8D 5A 07  STA $075A = #$02

Code: [Select]
00:91D9:CE 5A 07  DEC $075A = #$02    ;this line subtracts a life
 00:91DC:10 0B     BPL $91E9    ;change to BNE $91E9: effect that it goes to Game Over when lives = 0, not when negative flag set

As to 255 lives... I don't care to make a fix but the life+1 instruction is at CPU address $84E6.
Find some free space, if you can because SMB is notoriously low on empty space, to JSR to a 9-byte subroutine you insert in said free space that may or may be able to be found INC $075A: BNE $03: DEC $075A: RTS
That modification from BEQ to BNE at $91D9 worked. . . no more "Game Over" at 128 and beyond.

~Ben

Shane M.

  • Jr. Member
  • **
  • Posts: 3
    • View Profile
Re: Super Mario Bros. - 128 Lives Fix
« Reply #4 on: September 28, 2014, 12:34:03 am »
Something like this

Code: [Select]
lives:
inc $075a
bpl skipdec
dec $075a
skipdec:
rts

SMB2J-2Q

  • Full Member
  • ***
  • Posts: 135
    • View Profile
Re: Super Mario Bros. - 128 Lives Fix
« Reply #5 on: September 28, 2014, 01:32:30 am »
Shane,

Thank you, but at the moment what I did is causing side effects. Could you please show me exactly where I should put this? Otherwise, I'd have to assemble a new ROM of this from scratch which would contain your new fix.

The code string in question is:
Code: [Select]
EE 74 07 A9 00 8D 22 07 A9 80 85 FC CE 5A 07 10 0B A9 00 8D 72 07 A9 03 8D 70 07 60
« Last Edit: September 29, 2014, 09:05:50 pm by SMB2J-2Q »