[CA65][GLITCH] Listing files: ROM addresses become off

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems. See the NESdev wiki for more information.

Moderator: Moderators

Post Reply
User avatar
Hamtaro126
Posts: 818
Joined: Thu Jan 19, 2006 5:08 pm

[CA65][GLITCH] Listing files: ROM addresses become off

Post by Hamtaro126 »

For example, in SMB, I see code like this:

This is the NMI code, What seems to be off here?

EDIT: THIS IS A SNIPPET OF A DISASSEMBLY BY DOPPLEGANGER CONVERTED TO CA65, PROCEED WITH CARE.

Code: Select all

00005Ar 1               ;$00 - vram buffer address table low, also used for pseudorandom bit
00005Ar 1               ;$01 - vram buffer address table high
00005Ar 1               
00005Ar 1               VRAM_AddrTable_Low:
00005Ar 1  01 rr rr           .byte <VRAM_Buffer1, <WaterPaletteData, <GroundPaletteData
00005Dr 1  rr rr 00           .byte <UndergroundPaletteData, <CastlePaletteData, <VRAM_Buffer1_Offset
000060r 1  41 41 rr           .byte <VRAM_Buffer2, <VRAM_Buffer2, <BowserPaletteData
000063r 1  rr rr rr           .byte <DaySnowPaletteData, <NightSnowPaletteData, <MushroomPaletteData
000066r 1  rr rr rr           .byte <MarioThanksMessage, <LuigiThanksMessage, <MushroomRetainerSaved
000069r 1  rr rr rr           .byte <PrincessSaved1, <PrincessSaved2, <WorldSelectMessage1
00006Cr 1  rr                 .byte <WorldSelectMessage2
00006Dr 1               
00006Dr 1               VRAM_AddrTable_High:
00006Dr 1  03 rr rr           .byte >VRAM_Buffer1, >WaterPaletteData, >GroundPaletteData
000070r 1  rr rr 03           .byte >UndergroundPaletteData, >CastlePaletteData, >VRAM_Buffer1_Offset
000073r 1  03 03 rr           .byte >VRAM_Buffer2, >VRAM_Buffer2, >BowserPaletteData
000076r 1  rr rr rr           .byte >DaySnowPaletteData, >NightSnowPaletteData, >MushroomPaletteData
000079r 1  rr rr rr           .byte >MarioThanksMessage, >LuigiThanksMessage, >MushroomRetainerSaved
00007Cr 1  rr rr rr           .byte >PrincessSaved1, >PrincessSaved2, >WorldSelectMessage1
00007Fr 1  rr                 .byte >WorldSelectMessage2
000080r 1               
000080r 1               VRAM_Buffer_Offset:
000080r 1  00 40              .byte <VRAM_Buffer1_Offset, <VRAM_Buffer2_Offset
000082r 1               
000082r 1               NonMaskableInterrupt:
000082r 1  AD 78 07                    lda Mirror_PPU_CTRL_REG1  ;disable NMIs in mirror reg
000085r 1  29 7F                       and #%01111111            ;save all other bits
000087r 1  8D 78 07                    sta Mirror_PPU_CTRL_REG1
00008Ar 1  29 7E                       and #%01111110            ;alter name table address to be $2800
00008Cr 1  8D 00 20                    sta PPU_CTRL_REG1         ;(essentially $2000) but save other bits
00008Fr 1  AD 79 07                    lda Mirror_PPU_CTRL_REG2  ;disable OAM and background display by default
000092r 1  29 E6                       and #%11100110
000094r 1  AC 74 07                    ldy DisableScreenFlag     ;get screen disable flag
000097r 1  D0 05                       bne ScreenOff             ;if set, used bits as-is
000099r 1  AD 79 07                    lda Mirror_PPU_CTRL_REG2  ;otherwise reenable bits and save them
00009Cr 1  09 1E                       ora #%00011110
00009Er 1  8D 79 07     ScreenOff:     sta Mirror_PPU_CTRL_REG2  ;save bits for later but not in register at the moment
0000A1r 1  29 E7                       and #%11100111            ;disable screen for now
0000A3r 1  8D 01 20                    sta PPU_CTRL_REG2
0000A6r 1  AE 02 20                    ldx PPU_STATUS            ;reset flip-flop and reset scroll registers to zero
0000A9r 1  A9 00                       lda #$00
0000ABr 1  20 rr rr                    jsr InitScroll
0000AEr 1  8D 03 20                    sta PPU_SPR_ADDR          ;reset spr-ram address register
0000B1r 1  A9 02                       lda #$02                  ;perform spr-ram DMA access on $0200-$02ff
0000B3r 1  8D 14 40                    sta SPR_DMA
0000B6r 1  AE 73 07                    ldx VRAM_Buffer_AddrCtrl  ;load control for pointer to buffer contents
0000B9r 1  BD rr rr                    lda VRAM_AddrTable_Low,x  ;set indirect at $00 to pointer
0000BCr 1  85 00                       sta $00
0000BEr 1  BD rr rr                    lda VRAM_AddrTable_High,x
0000C1r 1  85 01                       sta $01
0000C3r 1  20 rr rr                    jsr UpdateScreen          ;update screen with buffer contents
0000C6r 1  A0 00                       ldy #$00
0000C8r 1  AE 73 07                    ldx VRAM_Buffer_AddrCtrl  ;check for usage of $0341
0000CBr 1  E0 06                       cpx #$06
0000CDr 1  D0 01                       bne InitBuffer
0000CFr 1  C8                          iny                       ;get offset based on usage
0000D0r 1  BE rr rr     InitBuffer:    ldx VRAM_Buffer_Offset,y
0000D3r 1  A9 00                       lda #$00                  ;clear buffer header at last location
0000D5r 1  9D 00 03                    sta VRAM_Buffer1_Offset,x
0000D8r 1  9D 01 03                    sta VRAM_Buffer1,x
0000DBr 1  8D 73 07                    sta VRAM_Buffer_AddrCtrl  ;reinit address control to $0301
0000DEr 1  AD 79 07                    lda Mirror_PPU_CTRL_REG2  ;copy mirror of $2001 to register
0000E1r 1  8D 01 20                    sta PPU_CTRL_REG2
0000E4r 1  20 rr rr                    jsr SoundEngine           ;play sound
0000E7r 1  20 rr rr                    jsr ReadJoypads           ;read joypads
0000EAr 1  20 rr rr                    jsr PauseRoutine          ;handle pause
0000EDr 1  20 rr rr                    jsr UpdateTopScore
0000F0r 1  AD 76 07                    lda GamePauseStatus       ;check for pause status
0000F3r 1  4A                          lsr
0000F4r 1  B0 25                       bcs PauseSkip
0000F6r 1  AD 47 07                    lda TimerControl          ;if master timer control not set, decrement
0000F9r 1  F0 05                       beq DecTimers             ;all frame and interval timers
0000FBr 1  CE 47 07                    dec TimerControl
0000FEr 1  D0 19                       bne NoDecTimers
000100r 1  A2 14        DecTimers:     ldx #$14                  ;load end offset for end of frame timers
000102r 1  CE 7F 07                    dec IntervalTimerControl  ;decrement interval timer control,
000105r 1  10 07                       bpl DecTimersLoop         ;if not expired, only frame timers will decrement
000107r 1  A9 14                       lda #$14
000109r 1  8D 7F 07                    sta IntervalTimerControl  ;if control for interval timers expired,
00010Cr 1  A2 23                       ldx #$23                  ;interval timers will decrement along with frame timers
00010Er 1  BD 80 07     DecTimersLoop: lda Timers,x              ;check current timer
000111r 1  F0 03                       beq SkipExpTimer          ;if current timer expired, branch to skip,
000113r 1  DE 80 07                    dec Timers,x              ;otherwise decrement the current timer
000116r 1  CA           SkipExpTimer:  dex                       ;move onto next timer
000117r 1  10 F5                       bpl DecTimersLoop         ;do this until all timers are dealt with
000119r 1  E6 09        NoDecTimers:   inc FrameCounter          ;increment frame counter
00011Br 1  A2 00        PauseSkip:     ldx #$00
00011Dr 1  A0 07                       ldy #$07
00011Fr 1  AD A7 07                    lda PseudoRandomBitReg    ;get first memory location of LSFR bytes
000122r 1  29 02                       and #%00000010            ;mask out all but d1
000124r 1  85 00                       sta $00                   ;save here
000126r 1  AD A8 07                    lda PseudoRandomBitReg+1  ;get second memory location
000129r 1  29 02                       and #%00000010            ;mask out all but d1
00012Br 1  45 00                       eor $00                   ;perform exclusive-OR on d1 from first and second bytes
00012Dr 1  18                          clc                       ;if neither or both are set, carry will be clear
00012Er 1  F0 01                       beq RotPRandomBit
000130r 1  38                          sec                       ;if one or the other is set, carry will be set
000131r 1  7E A7 07     RotPRandomBit: ror PseudoRandomBitReg,x  ;rotate carry into d7, and rotate last bit into carry
000134r 1  E8                          inx                       ;increment to next byte
000135r 1  88                          dey                       ;decrement for loop
000136r 1  D0 F9                       bne RotPRandomBit
000138r 1  AD 22 07                    lda Sprite0HitDetectFlag  ;check for flag here
00013Br 1  F0 1F                       beq SkipSprite0
00013Dr 1  AD 02 20     Sprite0Clr:    lda PPU_STATUS            ;wait for sprite 0 flag to clear, which will
000140r 1  29 40                       and #%01000000            ;not happen until vblank has ended
000142r 1  D0 F9                       bne Sprite0Clr
000144r 1  AD 76 07                    lda GamePauseStatus       ;if in pause mode, do not bother with sprites at all
000147r 1  4A                          lsr
000148r 1  B0 06                       bcs Sprite0Hit
00014Ar 1  20 rr rr                    jsr MoveSpritesOffscreen
00014Dr 1  20 rr rr                    jsr SpriteShuffler
000150r 1  AD 02 20     Sprite0Hit:    lda PPU_STATUS            ;do sprite #0 hit detection
000153r 1  29 40                       and #%01000000
000155r 1  F0 F9                       beq Sprite0Hit
000157r 1  A0 14                       ldy #$14                  ;small delay, to wait until we hit horizontal blank time
000159r 1  88           HBlankDelay:   dey
00015Ar 1  D0 FD                       bne HBlankDelay
00015Cr 1  AD 3F 07     SkipSprite0:   lda HorizontalScroll      ;set scroll registers from variables
00015Fr 1  8D 05 20                    sta PPU_SCROLL_REG
000162r 1  AD 40 07                    lda VerticalScroll
000165r 1  8D 05 20                    sta PPU_SCROLL_REG
000168r 1  AD 78 07                    lda Mirror_PPU_CTRL_REG1  ;load saved mirror of $2000
00016Br 1  48                          pha
00016Cr 1  8D 00 20                    sta PPU_CTRL_REG1
00016Fr 1  AD 76 07                    lda GamePauseStatus       ;if in pause mode, do not perform operation mode stuff
000172r 1  4A                          lsr
000173r 1  B0 03                       bcs SkipMainOper
000175r 1  20 rr rr                    jsr OperModeExecutionTree ;otherwise do one of many, many possible subroutines
000178r 1  AD 02 20     SkipMainOper:  lda PPU_STATUS            ;reset flip-flop
00017Br 1  68                          pla
00017Cr 1  09 80                       ora #%10000000            ;reactivate NMIs
00017Er 1  8D 00 20                    sta PPU_CTRL_REG1
000181r 1  40                          rti                       ;we are done until the next frame!
Last edited by Hamtaro126 on Fri Apr 22, 2022 6:46 pm, edited 1 time in total.
AKA SmilyMZX/AtariHacker.
User avatar
Dwedit
Posts: 4924
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: [CA65][GLITCH] Listing files: ROM addresses become off

Post by Dwedit »

Is that code not fully linked or something? Are there missing labels in other source files that were included? R isn't a number.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
User avatar
Hamtaro126
Posts: 818
Joined: Thu Jan 19, 2006 5:08 pm

Re: [CA65][GLITCH] Listing files: ROM addresses become off

Post by Hamtaro126 »

Dwedit wrote: Fri Apr 22, 2022 6:00 pm Is that code not fully linked or something? Are there missing labels in other source files that were included? R isn't a number.
It's CA65's doing, not mine!

Besides, The code is fine. (when assembled)
AKA SmilyMZX/AtariHacker.
User avatar
Cyneprepou4uk
Posts: 24
Joined: Fri Jun 21, 2019 12:20 am
Location: Belarus

Re: [CA65][GLITCH] Listing files: ROM addresses become off

Post by Cyneprepou4uk »

What seems to be off here?
Can you answer your own question, so we could understand what exactly did you expect to see in your listing file?

Anyway, if you're talking about 00005Ar not being 00805Ar or something, add .org $8000 somewhere at the beginning of your asm file.
User avatar
Dwedit
Posts: 4924
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: [CA65][GLITCH] Listing files: ROM addresses become off

Post by Dwedit »

Well it looks like it can't find the address of any external symbol when it generates the listing for that single file. So it's generating a listing before the entire project is linked together.

Also it looks like the addresses are relative to the start of the file.

So it looks like it's a single object being compiled, then a listing is being generated from that alone. But that object isn't linked to anything, so final addresses don't exist yet.

Would need to generate a listing file during the linking step rather than the step where you assemble one file.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
Post Reply