News:

11 March 2016 - Forum Rules

Main Menu

SMB1 - Possible to Add More RAM Addresses?

Started by SMB2J-2Q, September 30, 2022, 08:51:18 PM

Previous topic - Next topic

SMB2J-2Q

Is it possible to add any of the RAM addresses, those that are exclusive to Super Mario Bros. 2 for the Famicom Disk System, to the NES SMB1 ROM?

Examples of the SMB2J-specific addresses:
$07f6 - FlagpoleMusicFlag
$07e7 - CoinDisplay (different from ScoreAndCoinDisplay)

The reason I ask about this is because I have tried to incorporate 1-UPs on a flag into SMB1, as well as adding a timer bonus for each x-4 world, without success.

~Ben


SMB2J-2Q

#2
Quote from: Cyneprepou4uk on October 01, 2022, 02:50:30 AMIt's possible.

~Ken
Ken,

I have tried to add $07f6 to the SMB1 ROM, but while the define itself was recognized in X816, it caused the flagpole music itself to go silent. I wonder if there are other things I have to do to make them work correctly in SMB1?

Just so you know, here's what I tried to do to "enhance" SMB1...
SecondaryGameSetup:
    lda #$00
    sta DisableScreenFlag
    sta FlagpoleMusicFlag
    tay

PlayerEndLevel:
    lda #$01
    jsr AutoControlPlayer
    lda Player_Y_Position
    cmp #$ae
    bcc ChkStop
    lda #$00
    sta ScrollLock
    lda FlagpoleMusicFlag
    bne ChkStop
    lda #EndOfLevelMusic
    sta EventMusicQueue
    inc FlagpoleMusicFlag

BTW, the reason the EndCastleAward routine failed to work for me the last time I updated this ROM was because I simply forgot to do one thing:
VictoryModeSubroutines:
    lda OperMode_Task
    jsr JumpEngine
     
    .dw BridgeCollapse
    .dw SetupVictoryMode
    .dw PlayerVictoryWalk
    .dw PrintVictoryMessages
    .dw EndCastleAward
    .dw PlayerEndWorld
Once I locked that in there, it worked perfectly in all eight worlds.

~Ben

Cyneprepou4uk

QuoteI wonder if there are other things I have to do to make them work correctly in SMB1?

Yeah, how about you start learning NES assembly and stop creating SMB topics with stupid questions?

Quotehere's what I tried to do

And what exactly did you do? Did you wrote all of it all by yourself? Did you change one minor detail? Where is "before" and "after" code comparsion?

Quote...the reason the EndCastleAward routine failed to work for me...

TF are you even referring to? Oh, right, that's probably was in one of your previous topics, and naturally you expect everyone to remember exactly what you were doing and when.

~Mike

SMB2J-2Q

#4
Quote from: Cyneprepou4uk on October 01, 2022, 08:22:57 AMYeah, how about you start learning NES assembly and stop creating SMB topics with stupid questions?

And what exactly did you do? Did you wrote all of it all by yourself? Did you change one minor detail? Where is "before" and "after" code comparsion?

TF are you even referring to? Oh, right, that's probably was in one of your previous topics, and naturally you expect everyone to remember exactly what you were doing and when.

~Mike
Before and after...

The before...
VictoryModeSubroutines:
    lda OperMode_Task
    jsr JumpEngine

    .dw BridgeCollapse
    .dw SetupVictoryMode
    .dw PlayerVictoryWalk
    .dw PrintVictoryMessages
    .dw PlayerEndWorld

SecondaryGameSetup:
    lda #$00
    sta DisableScreenFlag
    tay

PlayerEndLevel:
    lda #$01
    jsr AutoControlPlayer
    lda Player_Y_Position
    cmp #$ae
    bcc ChkStop
    lda ScrollLock
    beq ChkStop
    lda #EndOfLevelMusic
    sta EventMusicQueue
    lda #$00
    sta ScrollLock

The after:
VictoryModeSubroutines:
    lda OperMode_Task
    jsr JumpEngine

    .dw BridgeCollapse
    .dw SetupVictoryMode
    .dw PlayerVictoryWalk
    .dw PrintVictoryMessages
    .dw EndCastleAward
    .dw PlayerEndWorld
Results:


 
SecondaryGameSetup:
    lda #$00
    sta DisableScreenFlag
    sta FlagpoleMusicFlag
    tay

PlayerEndLevel:
    lda #$01
    jsr AutoControlPlayer
    lda Player_Y_Position
    cmp #$ae
    bcc ChkStop
    lda #$00
    sta ScrollLock
    lda FlagpoleMusicFlag
    bne ChkStop
    lda #EndOfLevelMusic
    sta EventMusicQueue
    inc FlagpoleMusicFlag

These were from the respective disassemblies, both by doppelganger, for SMB1 and SMB2J.

Here's what led me to bring up this topic in the first place...
https://forums.nesdev.org/viewtopic.php?p=134208#p134208

~Ben

SMB2J-2Q

#5
Quote from: Cyneprepou4uk on October 01, 2022, 08:22:57 AMYeah, how about you start learning NES assembly and stop creating SMB topics with stupid questions?

And what exactly did you do? Did you wrote all of it all by yourself? Did you change one minor detail? Where is "before" and "after" code comparsion?

TF are you even referring to? Oh, right, that's probably was in one of your previous topics, and naturally you expect everyone to remember exactly what you were doing and when.

~Mike
Mike,

UPDATE 10-9-2022:
I finally got the FlagpoleMusicFlag ($076f) instruction to work correctly, by having removed the Block_ResidualCounter ($03f0) RAM address, which itself doesn't really do anything and is used by only one routine.

Before:
ReplaceBlockMetatile:
    jsr WriteBlockMetatile
    inc Block_ResidualCounter
    dec Block_RepFlag,x
    rts

After:
ReplaceBlockMetatile:
    jsr WriteBlockMetatile
    dec Block_RepFlag,x
    rts

UPDATE 2: I even got it to work under the ProcELoop routine to prevent the area music from reloading if one managed to slide down the flagpole with Starman power.

Before:
ProcELoop:    stx ObjectOffset           ;put incremented offset in X as enemy object offset
              jsr EnemiesAndLoopsCore    ;process enemy objects
              jsr FloateyNumbersRoutine  ;process floatey numbers
              inx
              cpx #$06                   ;do these two subroutines until the whole buffer is done
              bne ProcELoop
              jsr GetPlayerOffscreenBits ;get offscreen bits for player object
              jsr RelativePlayerPosition ;get relative coordinates for player object
              jsr PlayerGfxHandler       ;draw the player
              jsr BlockObjMT_Updater     ;replace block objects with metatiles if necessary
              ldx #$01
              stx ObjectOffset           ;set offset for second
              jsr BlockObjectsCore       ;process second block object
              dex
              stx ObjectOffset           ;set offset for first
              jsr BlockObjectsCore       ;process first block object
              jsr MiscObjectsCore        ;process misc objects (hammer, jumping coins)
              jsr ProcessCannons         ;process bullet bill cannons
              jsr ProcessWhirlpools      ;process whirlpools
              jsr FlagpoleRoutine        ;process the flagpole
              jsr RunGameTimer           ;count down the game timer
              jsr ColorRotation          ;cycle one of the background colors
              lda Player_Y_HighPos
              cmp #$02                   ;if player is below the screen, don't bother with the music
              bpl NoChgMus
              lda StarInvincibleTimer    ;if star mario invincibility timer at zero,
              beq ClrPlrPal              ;skip this part
              cmp #$04
              bne NoChgMus               ;if not yet at a certain point, continue
              lda IntervalTimerControl   ;if interval timer not yet expired,
              bne NoChgMus               ;branch ahead, don't bother with the music
              jsr GetAreaMusic           ;to re-attain appropriate level music

After:
ProcELoop:    stx ObjectOffset           ;put incremented offset in X as enemy object offset
              jsr EnemiesAndLoopsCore    ;process enemy objects
              jsr FloateyNumbersRoutine  ;process floatey numbers
              inx
              cpx #$06                   ;do these two subroutines until the whole buffer is done
              bne ProcELoop
              jsr GetPlayerOffscreenBits ;get offscreen bits for player object
              jsr RelativePlayerPosition ;get relative coordinates for player object
              jsr PlayerGfxHandler       ;draw the player
              jsr BlockObjMT_Updater     ;replace block objects with metatiles if necessary
              ldx #$01
              stx ObjectOffset           ;set offset for second
              jsr BlockObjectsCore       ;process second block object
              dex
              stx ObjectOffset           ;set offset for first
              jsr BlockObjectsCore       ;process first block object
              jsr MiscObjectsCore        ;process misc objects (hammer, jumping coins)
              jsr ProcessCannons         ;process bullet bill cannons
              jsr ProcessWhirlpools      ;process whirlpools
              jsr FlagpoleRoutine        ;process the flagpole
              jsr RunGameTimer           ;count down the game timer
              jsr ColorRotation          ;cycle one of the background colors
              lda Player_Y_HighPos
              cmp #$02                   ;if player is below the screen, don't bother with the music
              bpl NoChgMus
              lda StarInvincibleTimer    ;if star mario invincibility timer at zero,
              beq ClrPlrPal              ;skip this part
              cmp #$04
              bne NoChgMus               ;if not yet at a certain point, continue
              lda IntervalTimerControl   ;if interval timer not yet expired,
              bne NoChgMus               ;branch ahead, don't bother with the music
              lda FlagpoleMusicFlag      ;is win level music playing?
              bne NoChgMus               ;if so, don't bother
              jsr GetAreaMusic           ;otherwise, re-attain appropriate level music


~Ben