Super Mario All-Stars Lives Display Code

Discussion of hardware and software development for Super NES and Super Famicom. See the SNESdev wiki for more information.

Moderator: Moderators

Forum rules
  • For making cartridges of your Super NES games, see Reproduction.
Post Reply
SMB2J-2Q
Posts: 154
Joined: Thu Jul 27, 2017 5:13 pm

Super Mario All-Stars Lives Display Code

Post by SMB2J-2Q »

For all those of you here who are interested, here's the code I found for the lives display (which counts the number of extra lives from 10-99 and 100-128) for Super Mario Bros. and Super Mario Bros.: The Lost Levels within Super Mario All-Stars. It starts at address 0x68E22 in the NTSC ROM:

Code: Select all

lda $075a (NumberofLives)
inc a (for 6502: use clc and adc #$01)
cmp #$0a (10)
stz $64
stz $65 (for 6502: use lda #$00, sta $64 and sta $65)

Upto100:
sec
sbc #$64 (100)
bcc From101to109
inc $e4
bra Upto100 (for 6502: use jmp Upto100)

From101to109:
sec
adc #$64 (100)

Over109:
sec
sbc #$0a (10)
bcc StoreLow
inc $e5
bra Over109 (for 6502: use jmp Over109)

StoreLow:
clc
adc #$0a (10)
sta $e6
ldy $e4
beq StoreHigh
sty VRAM_Buffer1+12

StoreHigh:
lda $e5
sta VRAM_Buffer1+14
lda $e6

PutLives:
sta VRAM_Buffer1+16
ldy WorldNumber
iny
sty VRAM_Buffer1+42
ldy LevelNumber
iny
sty VRAM_Buffer1+46
rts
My question is this: may I please ask how can I convert this 65816-specific code above to 6502-style, for the NES Super Mario Bros. and related games using the same code? What I listed in parentheses is what I know so far as to how to do this. If this code can be further corrected and optimized in any way, I would appreciate that, too.

Thank you,



Ben
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Super Mario All-Stars Lives Display Code

Post by tepples »

I'd probably go with code more like the single-byte binary to decimal conversion in Thwaite.

Code: Select all

lda #0
sta hundreds
sta tens
sec
adc NumberOfLives  ; convert 0-127 to 1-128
cmp #100
bcc :+
  sbc #100
  rol hundreds
:
cmp #80
bcc :+
  sbc #80
  rol tens
:
cmp #40
bcc :+
  sbc #40
  rol tens
:
cmp #20
bcc :+
  sbc #20
  rol tens
:
cmp #10
bcc :+
  sbc #10
  rol tens
:
; End with ones in A
SMB2J-2Q
Posts: 154
Joined: Thu Jul 27, 2017 5:13 pm

Re: Super Mario All-Stars Lives Display Code

Post by SMB2J-2Q »

tepples wrote: Sat Dec 03, 2022 5:47 am I'd probably go with code more like the single-byte binary to decimal conversion in Thwaite.

Code: Select all

lda #0
sta hundreds
sta tens
sec
adc NumberOfLives  ; convert 0-127 to 1-128
cmp #100
bcc :+
  sbc #100
  rol hundreds
:
cmp #80
bcc :+
  sbc #80
  rol tens
:
cmp #40
bcc :+
  sbc #40
  rol tens
:
cmp #20
bcc :+
  sbc #20
  rol tens
:
cmp #10
bcc :+
  sbc #10
  rol tens
:
; End with ones in A
I may try this and see what happens.

BTW, shouldn't that SEC before the ADC $075A be a CLC, instead?

Thank you!


~Ben
Myself086
Posts: 158
Joined: Sat Nov 10, 2018 2:49 pm

Re: Super Mario All-Stars Lives Display Code

Post by Myself086 »

tepples wrote: Sat Dec 03, 2022 5:47 am I'd probably go with code more like the single-byte binary to decimal conversion in Thwaite.
Correcting ROLs

Code: Select all

lda #0
sta hundreds
sta tens
sec
adc NumberOfLives  ; convert 0-127 to 1-128
cmp #100
bcc :+
  sbc #100
:
rol hundreds
cmp #80
bcc :+
  sbc #80
:
rol tens
cmp #40
bcc :+
  sbc #40
:
rol tens
cmp #20
bcc :+
  sbc #20
:
rol tens
cmp #10
bcc :+
  sbc #10
:
rol tens
; End with ones in A
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Super Mario All-Stars Lives Display Code

Post by tepples »

My fault with the rol. Good catch.

The

Code: Select all

sec adc
was there to add 1 to the lives display, converting it from 0-127 to 1-128.
SMB2J-2Q
Posts: 154
Joined: Thu Jul 27, 2017 5:13 pm

Re: Super Mario All-Stars Lives Display Code

Post by SMB2J-2Q »

I just found out that the max lives code located at 0x48596 in the ROM bank (with header) can also be written conservatively to save space.

As written in the ROM bank:

Code: Select all

CODE_048596:
      LDA $075A       ; check player's lives
      INC $075A       ; increment A by one
      CMP #$80        ; are we at 128 lives yet?
      BCC CODE_0485A5 ; no, skip rest of routine
      LDA #$7F        ; otherwise, stop at 127 lives
      STA $075A       ; store in A and leave
CODE_0485A5:
      RTL
65816 also has the single-byte INC A and DEC A opcodes, which can be used to re-write the code:

Code: Select all

CODE_048596:
      LDA $075A       ; check player's lives
      INC A           ; increment A by one
      CMP #$80        ; are we at 128 lives yet?
      BCC CODE_0485A2 ; no, skip rest of routine
      DEC A           ; otherwise, decrement A by one to stop at 127 lives
      STA $075A       ; store in A and leave
CODE_0485A2:
      RTL
However, it can also be re-written in the same way Shane M. did for the max lives for his NES/FDS SMB1 and SMB2J hacks:

Code: Select all

CODE_048596:
      LDA $075A       ; check player's lives
      CMP #$7E        ; are we at 127 lives? (since we wrote down the compare check before we did the incrementing, the hex value is written as one less than what is onscreen)
      BCS CODE_04859E ; if yes, we're done
      INC A           ; otherwise increment A by one (only up to 127 lives)
CODE_04859E:
      RTL
~Ben
Post Reply