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

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Messages - SMB2J-2Q

Pages: [1] 2 3 4
I believe it's certain that the text for the "bad" (gray sky, 15 days or longer) and "average" (blue sky, 8 to 15 days) endings was switched around. I know this because in the "bad" ending, amid a gray sky, we see Dracula's grave by itself, and in the "average" ending Simon is right there kneeling at it.

The text we see in the "average" ending should really have been in the "bad" one...
Code: [Select]
"Although the confrontation between Simon and Dracula has concluded, Simon couldn't survive his fatal wounds. Transylvania's only hope is a young man who will triumph over evil and rid the city of Dracula's deadly curse."

Whereas, what we see in the "bad" one should have been in the "average" one...
Code: [Select]
"The battle has consummated. Now peace and serenity have been restored to Transylvania and people are free of Dracula's curse forever. And you, Simon Belmont, will always be remembered for your bravery and courage."

What I would like to find out is what parts of the code in the ROM to change to make the text for the bad ending appear in the good one, and vice versa.

Thank you,


Since I researched that the second-run PAL release (Rev. 0A) of Super Mario Bros. actually fixes the goal pipe bug at the end of all underwater levels where if one wedged Super/Fire Mario or Luigi into the gap above the goal pipe in the NTSC version, you're stuck until time runs out (subsequent ports followed PAL Rev. 0A's fix, except for the Game Boy Advance version which is a straight port of the original NES NTSC release), I applied the same fix to the NTSC version of the game. I found that out according to The Cutting Room Floor:

What I did to change the code in the NTSC version, to fix the pipe bug for the water levels... it is pretty easy to do, since the second-run PAL version has most of the code at the same addresses in the ROM as the NTSC version, as the fixes for the PAL version usually involved tweaks to the original NTSC version's program code which either sped up (mostly) or slowed down things.

Change the following bytes in World 5-2/6-2's water room data (0xAE3C-0xAE3F)
E5 09 EE 0F 7D CA 7D 47 FD

DE 0F E5 09 7D CA 7D 47 FD

For World 2-2/7-2... (0xAEB7-0xAEBA)
D5 09 DE 0F 0D CA 7D 47 FD

CE 0F D5 09 0D CA 7D 47 FD

And finally, for World 8-4's short underwater section... (0xAED4-0xAED7)
45 09 4E 0F ED 47 FD

3E 0F 45 09 ED 47 FD


ROM Hacking Discussion / Donkey Kong (NES) - Bonus Timer Fix?
« on: May 17, 2020, 07:13:07 pm »

We all remember that on the arcade Donkey Kong, the bonus timer goes bonkers the moment skilled players reach level 22. At first, the timer shows 100 points, then it counts down from "4000," but in reality there are only 400 points ticking away because 260 (computed from (22*10)+40) is higher than 256 by 4.

How the bonus timer for the arcade DK was originally computed:
Code: [Select]
0F7A - 3A 29 62 - LD A,(#6229) ; load A with level number
0F7D - 47       - LD B,A       ; copy A into B
0F7E - A7       - AND A        ; perform bitwise AND of A with A (or, clear the carry flag)
0F7F - 17       - RLA          ; rotate left the bits in A
0F80 - A7       - AND A        ; perform bitwise AND of A with A
0F81 - 17       - RLA          ; rotate left the bits in A
0F82 - A7       - AND A        ; perform bitwise AND of A with A
0F83 - 17       - RLA          ; rotate left the bits in A
0F84 - 80       - ADD A,B      ; A = A + B
0F85 - 80       - ADD A,B      ; A = A + B
0F86 - C6 28    - ADD A,#28    ; A = A + #28 (40 decimal)
0F88 - FE 51    - CP #51       ; is A ≥ #51 (81 decimal)?
0F8A - 38 02    - JR C,#0F8E   ; no, then skip ahead to #0F8E
0F8C - 3E 50    - LD A,#50     ; yes, then A = #50 (80 decimal)
0F8E - 21 B0 62 - LD HL,#62B0  ; load HL address to store the result

Don Hodges was able to come up with a hack that changes how the bonus timer is computed. His fix involved removing the instruction that checked to see if the value stored in A for the timer went higher than 80, and if it did, to force it back down to 80, and changed it so that the check involved deriving the maximum bonus points from the level number instead; if the level number was higher than 4 in this new check, to keep it at 4, which now means the timer will always count down from 8000 on levels 4 and up:
Code: [Select]
0F7A - 3A 29 62 - LD A,(#6229) ; load A with level number
0F7D - FE 04    - CP #04       ; is the level ≥ 4?
0F7F - 38 02    - JR C,#0F83   ; if not, jump ahead and compute bonus normally
0F81 - 3E 04    - LD A,#04     ; if it is, then set A = 4
0F83 - 47       - LD B,A       ; copy A into B
0F84 - A7       - AND A        ; clear the carry flag
0F85 - 17       - RLA          ; rotate left the bits in A
0F86 - A7       - AND A        ; clear the carry flag
0F87 - 17       - RLA          ; rotate left the bits in A
0F88 - A7       - AND A        ; clear the carry flag
0F89 - 17       - RLA          ; rotate left the bits in A
0F8A - 80       - ADD A,B      ; A = A + B
0F8B - 80       - ADD A,B      ; A = A + B
0F8C - C6 28    - ADD A,#28    ; A = A + #28 (40 decimal)
0F8E - 21 B0 62 - LD HL,#62B0  ; load HL address to store the result   

The bonus timer on the NES version of Donkey Kong behaves the same way.

But how it is computed is obviously different:
Code: [Select]
CB7E - A4 54    - LDY $54     ;
CB80 - C8       - INY         ;
CB81 - 20 D1 F4 - JSR $F4D1   ;
; set initial bonus value
; if the level number stored in Y is lower than 4,
; load the bonus value from memory (C207,Y)
; else, cap it at 8000
CB88 - A9 80    - LDA #$80    ;
CB8A - 88       - DEY         ;
CB8B - C0 04    - CPY #$04    ;
CB8D - 10 03    - BPL $CB92   ;
CB8F - B9 07 C2 - LDA $C207,Y ;
CB92 - 85 2E    - STA $2E     ;

The kill screen for level 133 is done is due to the byte $80, since this begins the two's complement cycle (-127 to 127). Since level 133 is given as byte $84, subtracting 4 ($04) from this value yields $80. What I want to do is change this so that the check does not trigger the two's complement rule.

Additionally, there is also a fifth bonus value stored in the instruction beginning at $C207: $90, for 9000 points.
Code: [Select]
C207 - .BYTE $50
C208 - .BYTE $60
C209 - .BYTE $70
C20A - .BYTE $80
C20B - .BYTE $90

Why it's there, I don't know. But you can make this happen on levels 5 and up by doing two alterations:
Code: [Select]
CB88 - A9 90     - LDA #$90    ;
CB8A - 88        - DEY         ;
CB8B - C0 05     - CPY #$05    ;
Doing these two changes also mean the kill screen will now be on level 134 ($85). On level 133, just as on level 22 in the arcade version, the timer will also behave graphically odd, which is the other reason I am hoping to fix this so the timer will always count down from 9000 - without being glitchy - on levels 5 and up.

Thank you,


ROM Hacking Discussion / Super Mario Bros. 1 - Level Clear Music?
« on: April 07, 2020, 07:56:57 pm »
According to a user from China calling himself "w7n," he says that somewhere in the music data for the Level Complete theme (which starts at $FCB0), there are two bytes that should be changed. One of these is $64 (which corresponds to note C5), which he says does not belong in the Square 1 wave note data table, and the other, he says, is $02 (corresponding to note D6) which would be part of the SQ1 data, but I cannot find that.

From his music hacking guide:

What he says is that the last note of the level clear fanfare is overrode when the timer tick sound plays to give you the bonus points for clearing a level. He says that by exchanging these two pitches, the final note of the fanfare will not be overrode by the timer tick sound.

The exact music data for the Level Clear theme...
Code: [Select]
    .db $87, $04, $06, $0c, $14, $1c, $22, $86, $2c, $22
    .db $87, $04, $60, $0e, $14, $1a, $24, $86, $2c, $24
    .db $87, $04, $08, $10, $18, $1e, $28, $86, $30, $30
    .db $80, $64, $00

    .db $cd, $d5, $dd, $e3, $ed, $f5, $bb, $b5, $cf, $d5
    .db $db, $e5, $ed, $f3, $bd, $b3, $d1, $d9, $df, $e9
    .db $f1, $f7, $bf, $ff, $ff, $ff, $34
    .db $00 ;unused byte

    .db $86, $04, $87, $14, $1c, $22, $86, $34, $84, $2c
    .db $04, $04, $04, $87, $14, $1a, $24, $86, $32, $84
    .db $2c, $04, $86, $04, $87, $18, $1e, $28, $86, $36
    .db $87, $30, $30, $30, $80, $2c


For example, by sacrificing changing Mario name to Luigi, you can change this

Code: [Select]
00:885F: AD 7A 07  LDA $077A
 00:8862: F0 1D     BEQ $8881
 00:8864: AD 53 07  LDA $0753
 00:8867: CA        DEX
 00:8868: D0 09     BNE $8873
 00:886A: AC 70 07  LDY $0770
 00:886D: C0 03     CPY #$03
 00:886F: F0 02     BEQ $8873
 00:8871: 49 01     EOR #$01
 00:8873: 4A        LSR
 00:8874: 90 0B     BCC $8881
 00:8876: A0 04     LDY #$04
 00:8878: B9 ED 87  LDA $87ED,Y
 00:887B: 99 04 03  STA $0304,Y
 00:887E: 88        DEY
 00:887F: 10 F7     BPL $8878
 00:8881: 60        RTS

into this

Code: [Select]
00:885F: AD 5F 07  LDA $075F
 00:8862: D0 05     BNE $8869
 00:8864: A9 01     LDA #$01
 00:8866: 8D 5F 07  STA $075F
 00:8869: 60        RTS

Unlike your current GG, this won't constantly overwrite world number. It will set wanted world number only once, when current world is #$00

What is really going on, that causes the present value to be overwritten in address $9086, whenever I use such codes like YSAOPE+YEAOZA or YSAOLO to overwrite? Here's some more code for you...
Code: [Select]
00:9061: A9 01      LDA #$01
00:9063: 8D 57 07   STA $0757
00:9066: 8D 54 07   STA $0754
00:9069: A9 02      LDA #$02
00:906B: 8D 5A 07   STA $075A
00:906E: 8D 61 07   STA $0761
00:9071: A9 00      LDA #$00
00:9073: 8D 74 07   STA $0774
00:9076: A8         TAY
00:9077: 99 00 03   STA $0300,X
00:907A: C8         INY
00:907B: D0 FA      BNE $9077
00:907D: 8D 59 07   STA $0759
00:9080: 8D 69 07   STA $0769
00:9083: 8D 28 07   STA $0728
00:9086: A9 01      LDA #$01
00:9088: 8D 5F 07   STA $075F
00:908B: AD 1A 07   LDA $071A
00:908E: 4E 78 07   LSR $0778
00:9091: 29 01      AND #$01
00:9093: 6A         ROR
00:9094: 2E 78 07   ROL $0778
00:9097: 20 ED 90   JSR $90ED
00:909A: A9 38      LDA #$38
00:909C: 8D E3 06   STA $06E3
00:909F: A9 48      LDA #$48
00:90A1: 8D E2 06   STA $06E2
00:90A4: A9 58      LDA #$58
00:90A6: 8D E1 06   STA $06E1
00:90A9: A2 0E      LDX #$0E

And (for when I use YSAOLO)...
Code: [Select]
00:9165: B9 16 91   LDA $9116,Y
00:9168: 85 86      STA $0086
00:916A: BD 1C 91   LDA $911C,X
00:916D: 85 CE      STA $00CE
00:916F: BD 25 91   LDA $9125,X
00:9172: 8D C4 03   STA $03C4
00:9175: 20 F1 85   JSR $85F1
00:9178: AC 15 07   LDY $0715
00:917B: F0 1A      BEQ $9197
00:917D: AD 57 07   STA $0757
00:9180: F0 15      BEQ $9197
00:9182: B9 2D 91   LDA $912D,Y
00:9185: 8D F8 07   STA $07F8
00:9188: A9 01      LDA #$01
00:918A: 8D 5F 07   STA $075F
00:918D: 4A         LSR
00:918E: 8D F9 07   STA $07F9
00:9191: 8D 57 07   STA $0757
00:9194: 8D 9F 07   STA $079F


Has anyone saw this version of the SMB Special NES hack?

Video: Faithful Dancing Star

This version actually has the old Mario Bros. enemies added in (Sidesteppers, Fighter Flies) and the Hammer from Donkey Kong.


Regarding Super Mario Bros. for the NES, how do I change the code to make myself start on World 2, but not restart back at the world number I input into the GG?

World number assignments:
00 = World 1
01 = World 2
02 = World 3
03 = World 4
04 = World 5
05 = World 6
06 = World 7
07 = World 8

The Game Genie codes to start on a different world are...

YSAOLO for World 2
YSAOLO + ZEAOPP for World 3
YSAOLO + LEAOPP for World 4
YSAOLO + GEAOPP for World 5
YSAOLO + IEAOPP for World 6
YSAOLO + TEAOPP for World 7
YSAOLO + YEAOPP for World 8

How it works...
Code: [Select]
A9 XX    = LDA #$XX (where "XX" is the world number; e.g., 01 for World 2)
8D 5F 07 = STA $075F (the absolute address that assigns the world number)

What happens is this: after beating the world number you changed to using the GG, and going to the world after it, beating the first level of the world after the one you input (e.g. cleared World 3-1), then you start back at the second level of the world you just input (e.g. World 2-2). You also return to the world you input if you die in the next world, or go down a pipe.

Therefore, how could this be fixed? What GG codes would I use to start at a desired world, but not lose your place in the world after it when you die, go down a pipe or clear the first level of this next world? That is, what I want to do is start from World 2, but to have it progress all the way to World 8 normally and not revert back to World 2 when I clear the first level of the world after.

Would I change anything in this part of the code to get the result I want?
Code: [Select]
00:82E6: 20 03 9C - JSR $9C03 ($9C03 = LoadAreaPointer)       
00:82E9: EE 5D 07 - INC $075D ($075D = Hidden1UPFlag)         ;set hidden 1-UP flag for both players
00:82EC: EE 64 07 - INC $0764 ($0764 = OffScr_Hidden1UPFlag) 
00:82EF: EE 57 07 - INC $0757 ($0757 = FetchNewGameTimerFlag) ;set fetch new game timer flag
00:82F2: EE 70 07 - INC $0770 ($0770 = OperMode)              ;set next game mode
00:82F5: AD FC 07 - LDA $07FC ($07FC = WorldSelectEnableFlag) ;if world select mode is on, then primary
00:82F8: 8D 6A 07 - STA $076A ($076A = PrimaryHardMode)       ;hard mode must be on as well
00:82FB: A9 00    - LDA #$00
00:82FD: 8D 72 07 - STA $0772 ($0772 = OperMode_Task)         ;set game mode here, and clear demo timer
00:8300: 8D A2 07 - STA $07A2 ($07A2 = DemoTimer)
00:8303: A2 17    - LDX #$17
00:8305: A9 00    - LDA #$00
00:8307: 9D DD 07 - STA $07DD,X ($07DD = ScoreandCoinDisplay) ;clear player scores and coin displays
00:830A: CA       - DEX
00:830B: 10 FA    - BPL $8307                                 
00:830D: 60
00:830E: 8D 5F 07 - STA $075F ($075F = WorldNumber)           ;start both players at the first area
00:8311: 8D 66 07 - STA $0766 ($0766 = OffScr_WorldNumber)    ;of the previously saved world number
00:8314: A2 00    - LDX #$00                                  ;note that on power-up using this function
00:8316: 8E 60 07 - STX $0760 ($0760 = AreaNumber)            ;will make no difference
00:8319: 8E 67 07 - STX $0767 ($0767 = OffScr_AreaNumber)   
00:831C: 60       - RTS

Thank you!



This video seems to involve hacking the lives instructions.

Again, I want to try to rework the machinations of the lives instructions to match with that of the SNES Super Mario All-Stars version.


I have a patch that can fix the number lives glitch if you think it could be helpful.
May I see the code for your fix, please?

If your fix works 100 percent correctly, then we should include that on The Cutting Room Floor's Super Mario Bros. page here:

Thank you,


If I'm not mistaken, that happens because the number of lives is stored as a signed 8-bit integer – when you add 1 to 127, the game decides that you have negative 128 lives.  The game checks if your number of lives is positive when you die (dec NumberofLives, bpl StillInGame) to decide if you have a Game Over.

So, I guess you would need to add extra code somewhere – probably a check to see if the number of lives is negative after you gain an extra life, which then sets the number of lives back to 128.  Makes sense?
Yes, indeed... I'd probably have to create a clean-slate ROM and copy the contents of the SMB ROM to that.


July 29, 2017, 10:32:53 pm - (Auto Merged - Double Posts are not allowed before 7 days.)
The code in the SNES version (as part of SMAS) which counts how many lives are earned:
Code: [Select]
CODE_048596: EE 5A 07 INC $075A       ;increase lives by 1 & make sure
CODE_048599: AD 5A 07 LDA $075A       ;it doesn't get past 128
CODE_04859C: C9 80    CMP #$80
CODE_04859E: 90 05    BCC CODE_0485A5
CODE_0485A0: A9 7F    LDA #$7F
CODE_0485A2: 8D 5A 07 STA $075A
CODE_0485A5: 6B       RTL

I wonder where I would be able to put this particular code within the NES version's ROM?


Yes.  Both of those fixes are possible.   :P

What would I change here?

Code: [Select]
    lda NumberOfLives    ;otherwise, check for number of lives
    clc                  ;and increment by one for display
    adc #$01
    cmp #10              ;more than 9 lives?
    bcc PutLives         
    sbc #10              ;if so, subtract 10 and put a crown tile
    ldy #$9f             ;next to the difference... strange things happen if
    sty VRAM_Buffer1+7   ;the number of lives exceeds 19

And where in the code does it prompt a Game Over for racking 129 lives or more, which occurs when losing a life from that point? I want to fix that, too.



I am wondering if there might be a way to hack the NES version of Super Mario Bros. so that I can do the following two fixes?

My intended fixes are:
1. Fixing the number of lives so they are read as proper numbers after both 10 lives and 19 lives instead of showing all these random symbols pulled from the game's character map.

2. Setting the maximum number of lives to 128 ($7f hex) so that (a) you never go beyond this limit, as is the case with the Game Boy Color port Super Mario Bros. Deluxe, though the maximum number of lives in the SNES Super Mario All-Stars version of SMB (and SMB2-J, here called SMB: The Lost Levels) for the NES is 99; and thus (b) no Game Over for losing your next life after racking up 129 or more lives.

Thank you,


I have a question about Super Mario Bros. 1 which involves why no timer bonus is given to you in the x-4 levels. I want to change this so that I can have the same behavior given to you at the end of each x-4 level like in the Japanese version of Super Mario Bros. 2.

Could anyone please show me which part of the code does the routine for giving the players the time bonus at the end of each x-4 level in SMB2J, so I might be able to copy this into SMB1?

Thank you,

Benjamin "Ben" Edge

My friend Shane Mohammed already did this code, but on the famicom version of SMB1. I assume that it's the same code if you look up both SMB2J & SMB1 Disassembly.
That would be the Famicom Disk System version that your friend had modified, correct?


that would be the "Axe" that Mario has to touch to send Bowser to the lava...

in the castle Axe = Flagpole
BTW, I brought this up because in Super Mario Bros. 2 (Japan) (aka The Lost Levels) as well as in Vs. Super Mario Bros. and All Night Nippon Super Mario Bros., and of course the Super Mario All-Stars versions of SMB1 and SMB2(J), the remaining time is added to your score in the castle levels.

Anyway, what would you do to make the timer count down to add to your score in the castle levels after touching Bowser's axe?


There is a question I hope to get answered to regarding Super Mario Bros. for the NES? Why is there no time bonus for each last level of each world - you know, the castle levels (the x-4 worlds)?

I'd like to be able to know what to do to change this so I do get a time remaining award to my score in these levels. Thank you! Which code in the game's ROM instructs to leave out the time remaining bonus in the x-4 levels? Would I have to add more code for this to be done, as is the case with Super Mario Bros. 2 (Japan)?


There is one thing about SMB that was in error: the way Lakitu throws Spiny Eggs down at Mario. Originally, he was supposed to throw them down at him at an angle relevant to Mario's speed, not straight down.

To correct this, simply move the JSR instruction from address 0xC434 to 0xC43D.

Change from:
01:C434:20 46 C3
01:C437:A0 02
01:C439:95 58
01:C43B:C9 00
01:C43D:30 01


01:C434:A0 02
01:C436:95 58
01:C438:C9 00
01:C43A:30 01
01:C43D:20 46 C3

Using a hex edit program such as Hexecute or Hex Workshop, change the code string starting from offset 0x4444 from:
20 46 C3 A0 02 95 58 C9 00 30 01 88

A0 02 95 58 C9 00 30 01 88 20 46 C3

This applies to the NES cartridge version only. The offset for the Spiny Egg throwing routine will be at different addresses for the following variations:
Super Mario Bros. (FDS)
Super Mario Bros. 2 (Japan) (FDS)
All Night Nippon Super Mario Bros. (FDS)
Vs. Super Mario Bros. (NES)



I have a Super Mario Bros. 2 (Japan) related question for you: Could anyone please evaluate why I'm hearing the first note of the Game Over music when the World 9-1 intro screen shows up? I mean, where in the ROM does this happen?

Thank you,

Ben Edge (SMB2J-2Q)

BUMP (1-25-2015)

I am resurrecting this thread yet again for a possible re-updating of the NES hack.

The reason I am resurrecting this post is because on YouTube, a user named "Kevin Smith" has uploaded an entire (world-by-world) playthrough of the Sharp X1 version of SMB Special.

Here's World 1:

I'm hoping you can pay attention to all these videos so that people like Karatorian and Frantik can learn from them for future programming updates to the NES hack.

Thank you,

Benjamin Edge (SMB2J-2Q)

Pages: [1] 2 3 4