This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

CA65 Indirection Problems

CA65 Indirection Problems
by on (#169920)
Long story short I need to have some tables. I have several metasprite mappings, like this. The data in question is completely contrived, it's simplified for the example:

    .byte $01, $22, $34, $45
    .byte $56, $67, $AF, $11
    .byte $22, $33, $44, $55,
    .byte $55, $66, $77, $88
     so on and so forth

Now, I have another table, which is a list of pointers to my mappings. All of this is in readonly, stored as absolute addresses.


    .addr mapping0
    .addr mapping1
    ; so on and so forth

However, in every case, the entries in mapping_table are off by $10. I can move the tables around, change their order, and the problem remains. Has anyone else experienced a similar problem?

.addr A
produces identical code to
.byte <A, >A
, by the way. That I am pretty sure of, as it looks that way from inspection with a hex editor.

This file contains the tables in question. You can see the +$10 I did as a kludge. The code to read the tables isn't perfect yet (this many levels of indirection is a bit hard for an asm first timer) but I've been verifying this data using a hex editor rather than my code. ... s/girl.asm
Re: CA65 Indirection Problems
by on (#169922)
No, I've never seen a problem like that.

I would suspect if you find your labels off by 16 bytes, you've probably got some problem with your linker configuration. Maybe you've got an iNES header jammed into the wrong place?

If they're coming up off by 16, I'd expect any non-relocatable code to fail too (any jsr, jmp, vectors, etc.) is this problem really confined to your tables?

Generating debug information and label files (via your ca65/ld65 command lines) might help you understand what is happening.
Re: CA65 Indirection Problems
by on (#169932)
player.asm:PLAYER_ANIM_ADDROFF = $10

Could it be? Unless that's the kludge you've been talking about...
Re: CA65 Indirection Problems
by on (#169944)
Nope, that's actually a coincidence. That's the offset into the player struct in zero-page, which is evaluated like this:

; X is either 0 for player 1, or sizeof(player_struct) for player 2
; load A with the lowbyte of the animation script address for player X
lda player_struct + PLAYER_ANIM_ADDROFF, x
sta addr_ptr
; Now the hibyte
lda player_struct + PLAYER_ANIM_ADDROFF + 1, x
sta addr_ptr + 1

player_struct is a label in zero-page, but it's constant at assembly time. PLAYER_ANIM_ADDROFF is also constant, so no actual address math is being done at the point of assembly.
Re: CA65 Indirection Problems
by on (#169947)
Linker configuration has my vote as well.

I've seen some example configurations where certain things (ex. ZEROPAGE segment) start at $10 rather than $00, to allow for up to 16 bytes of "free floating variable use" (or something; I forget). I'd also suggest using the -m filename flag (sometimes along with -vm) with ld65 which generates a file that contains what the linker decided, address/offset-wise, things should be at. I've used this more times than I can count.
Re: CA65 Indirection Problems
by on (#169953)
Since your linker config is on github, I took a peek.

Most of your MEMORY blocks are missing a file attribute. The default is file = %O, so all those places you specify this are the same as all the places you don't. Areas that are in RAM should have file = "" to prevent anything from getting generated there. I don't think this is really your problem, though, since all the segments that use these areas are type zp/bss so they shouldn't be able to generate any data to go in the file either, but it seems worth pointing out at least.

So... I don't think there's anything wrong with that config file, at least.

Here's what I meant about command line arguments from before:

1. Add -g to your ca65 command line to generate debug information (there is no downside to this except larger object files).

2. Add -Ln labels.txt to your ld65 command line to dump a complete list of labels and their addresses; this will let you inspect the generated addresses of every label in your code.

koitsu suggested -m, which is the map file, which shows overall output layout and exported symbols, whereas -Ln will get you all labels. They're both useful, kinda different information from each. (You can use both options on your command line, too.)

Myself, I like to feed the label dump to a parser that generates FCEUX debugging symbols for me.
Re: CA65 Indirection Problems
by on (#170019)
The code I had before was kind of crappy, so I rewrote it. I also added the suggested changes to the linker config for the RAM sections. I don't know if it was fixed by fluke, or if updating the config helped, or if I was simply reading the problem incorrectly, but the pointer is now the correct address and my animation scripts are working great.