Re: [cc65] Emitting data into segments defined in an interleaved way, while maintaining addresses?

From: Ullrich von Bassewitz <uz1musoftware.de>
Date: 2012-08-23 23:10:41
On Thu, Aug 23, 2012 at 04:38:22PM -0400, David Schmidt wrote:
> I see that the linker does in fact re-pack the various segments
> together as expected - effectively un-interleaving them.  But the
> addresses in MSGTABLE after File1.asm are incorrect.  The addresses
> in the output from File2.asm are actually relative to the file when
> it got assembled (vs. linked), which are different at link time once
> the re-packing occurred.

I'm almost sure that this is an error in your sources. There's a lot of code
out there that relies on the linker to relocate the arguments of .addr
correctly.

Unfortunately your code does not assemble, so my assumption is that you did
not use exactly this example for your test. When changing "asc" to ".asciiz",
the code works as expected, which should prove that it's not the assembler
that causes the problem. After placing above code into t1.s and t2.s and the
config into t.cfg, I get

uz@trixie:~/src/cc65/src/ca65$ ./ca65 t1.s
uz@trixie:~/src/cc65/src/ca65$ ./ca65 t2.s
uz@trixie:~/src/cc65/src/ca65$ ../ld65/ld65 -o t -C t.cfg t1.o t2.o
uz@trixie:~/src/cc65/src/ca65$ hexdump -C t
00000000  32 41 00 32 42 00 32 41  00 32 42 00 03 03 03 03  |2A.2B.2A.2B.....|
00000010  00 08 03 08 06 08 09 08                           |........|
00000018

As you can see, the output file has the expected contents.

What I would look for is a .ORG statement somewhere. This would explain what
you're seeing.

Some additional tips:

  * You can make your life easier by using the .sizeof() function. Instead
    of

        .segment "MESSAGES"
        M11:     .byte      "1A"
                M11_END =*
        .segment "MSGLEN"
                .byte M11_END-M11

    you can use

        .segment "MESSAGES"
        M11:    .byte      "1A"
        .segment "MSGLEN"
                .byte   .sizeof (M11)

    which is somewhat simpler.


  * A macro will help to make it even easier. Using

        .macro  Msg     arg
        .local  Label
        .pushseg
        .segment "MESSAGES"
        Label:  .byte   arg
        .segment "MSGLEN"
                .byte   .sizeof (Label)
        .segment "MSGTABLE"
                .addr   Label
        .popseg
        .endmacro

    will allow you to define messages anywhere by just saying

        Msg     "2A"
        Msg     "2B"

    The macro will output the data into the segments, the assembler will
    collect the data, and the linker will put all the tables together.

    Since I'm not sure how you're going to use the data you might need to
    modify the macro slightly (for example by passing the label).

> Aside from custom file
> processing to generate a single file out of several at build time,
> is there a way I can convince the toolchain to do what I want with
> separate files like this?

As said above, the problem is not the toolchain.

Regards


        Uz


P.S.: I'm leaving for vacation for about 10 days tomorrow. I will have
      probably have internet access but there might be delays.

-- 
Ullrich von Bassewitz                                  uz@musoftware.de
----------------------------------------------------------------------
To unsubscribe from the list send mail to majordomo@musoftware.de with
the string "unsubscribe cc65" in the body(!) of the mail.
Received on Thu Aug 23 23:10:59 2012

This archive was generated by hypermail 2.1.8 : 2012-08-23 23:11:04 CEST