How to INCBIN with gcc

C and PASCAL (or any other high-level languages) in here please

Moderators: simonsunnyboy, Mug UK, Zorro 2, Moderator Team

User avatar
simonsunnyboy
Moderator
Moderator
Posts: 5129
Joined: Wed Oct 23, 2002 4:36 pm
Location: Friedrichshafen, Germany
Contact:

How to INCBIN with gcc

Postby simonsunnyboy » Fri Apr 11, 2014 3:25 pm

How can I effectively place binary inline with my .c/.s files for use with gcc and its tools like DEVPAC or AHCC can do with the INCBIN directive?
I want to be able to avoid loading resources from disk if possible.

I'm ok with having a seperate source file to link and declaring my data in a C header with extern uint8_t datafile[];
Simon Sunnyboy/Paradize - http://paradize.atari.org/

Stay cool, stay Atari!

1x2600jr, 1x1040STFm, 1x1040STE 4MB+TOS2.06+SatanDisk, 1xF030 14MB+FPU+NetUS-Bee

User avatar
shoggoth
Nature
Nature
Posts: 976
Joined: Tue Aug 01, 2006 9:21 am
Location: Halmstad, Sweden
Contact:

Re: How to INCBIN with gcc

Postby shoggoth » Fri Apr 11, 2014 3:43 pm

simonsunnyboy wrote:How can I effectively place binary inline with my .c/.s files for use with gcc and its tools like DEVPAC or AHCC can do with the INCBIN directive?
I want to be able to avoid loading resources from disk if possible.

I'm ok with having a seperate source file to link and declaring my data in a C header with extern uint8_t datafile[];


Use the GAS incbin-counterpart to turn the data into linkable format in a .s file. That's what I do, usually. Think it's called ".incbin", iirc.
Ain't no space like PeP-space.

User avatar
simonsunnyboy
Moderator
Moderator
Posts: 5129
Joined: Wed Oct 23, 2002 4:36 pm
Location: Friedrichshafen, Germany
Contact:

Re: How to INCBIN with gcc

Postby simonsunnyboy » Fri Apr 11, 2014 4:11 pm

shoggoth wrote:
simonsunnyboy wrote:How can I effectively place binary inline with my .c/.s files for use with gcc and its tools like DEVPAC or AHCC can do with the INCBIN directive?
I want to be able to avoid loading resources from disk if possible.

I'm ok with having a seperate source file to link and declaring my data in a C header with extern uint8_t datafile[];


Use the GAS incbin-counterpart to turn the data into linkable format in a .s file. That's what I do, usually. Think it's called ".incbin", iirc.


I assume so, a working example would be most helpful as the GNU as syntax differs alot if you are used to DEVPAC or AHCC/Pure C.
Simon Sunnyboy/Paradize - http://paradize.atari.org/

Stay cool, stay Atari!

1x2600jr, 1x1040STFm, 1x1040STE 4MB+TOS2.06+SatanDisk, 1xF030 14MB+FPU+NetUS-Bee

User avatar
mfro
Atari Super Hero
Atari Super Hero
Posts: 808
Joined: Thu Aug 02, 2012 10:33 am
Location: SW Germany

Re: How to INCBIN with gcc

Postby mfro » Sat Apr 12, 2014 7:34 am

simonsunnyboy wrote:I assume so, a working example would be most helpful as the GNU as syntax differs alot if you are used to DEVPAC or AHCC/Pure C.


Here you go:

Code: Select all

#include <stdio.h>

char *inlined_binary(void)
{
    static char *buf_addr;

    __asm__ __volatile__(
        "       move.l      #label,%[addr]  \n\t"
        "       .data                       \n\t"
        "label:                             \n\t"
        "       .incbin     \"binary.bin\"  \n\t"
        "       .align      2               \n\t"
        "       .text                       \n\t"
        : [addr] "=g" (buf_addr)
        :
        :
    );

    return buf_addr;
}

int main(int argc, char *argv[])
{
    char *b;

    b = inlined_binary();

    /* do something with b */
}


This is untested and quickly nailed together from more complex code but should be working (I hope). If you need to include code instead of data, you obviously need to leave out the .data and .text directives.

User avatar
mfro
Atari Super Hero
Atari Super Hero
Posts: 808
Joined: Thu Aug 02, 2012 10:33 am
Location: SW Germany

Re: How to INCBIN with gcc

Postby mfro » Sat Apr 12, 2014 8:00 am

P.S.: remembered there is a little bit less flexible, but much easier way to to include arbitrary files into the final binary with the gnu tools.

With objcopy, you can convert any file to a linkable object:

Code: Select all

# echo "Hello World" > tst.txt
# m68k-atari-mint-objcopy -Ibinary -Oa.out-zero-big -Bm68k tst.txt tst.o

This wil produce a linkable object tst.o with a symbol named after the original filename (if the file was named "tst.txt", the symbol will become "binary_tst_txt_start"):

Code: Select all

# m68k-atari-mint-objdump -D tst.o

tst.o:     file format a.out-zero-big


Disassembly of section .data:

00000000 <_binary_tst_txt_start>:
   ...


Additionally, there will be a "binary_tst_txt_size" predefined with the length of the data as well as a "binary_tst_txt_end" pointing behind your text.

Code: Select all

tst.c:

int main(int argc, char *argv[])
{
    extern char binary_tst_txt_start[];

    printf("%s\n", binary_tst_txt_start);
}

You can now link the binary as usual:

Code: Select all

# m68k-atari-mint-gcc -o tst.tos tst.c tst.o


(this one has just been tested - and works - since I didn't remember the exact syntax of objcopy)

User avatar
simonsunnyboy
Moderator
Moderator
Posts: 5129
Joined: Wed Oct 23, 2002 4:36 pm
Location: Friedrichshafen, Germany
Contact:

Re: How to INCBIN with gcc

Postby simonsunnyboy » Sat Apr 12, 2014 10:37 am

Thanks for those rather unconventional tips. For starters I used the inline assembly syntax and tried the follow:

.s file with incbinned data:

Code: Select all

.data
__myfile:
.incbin "test.pi1"   
.align 2
.end


I can compile that to a nice object file with "m68k-atari-mint-gcc -c test_incbin.s"

Now I tried writing a short C file that references this data:

Code: Select all

#include <stdint.h>
#include <stdio.h>

extern uint8_t myfile[];

int main(int argc, char **argv)
{
   printf("degaspic res = %d\n", myfile[0]);
   return 0;
}


I run "m68k-atari-mint-gcc -o test_incbin.tos test_incbin_main.c test_incbin.o" which works well but it does not link:

Code: Select all

$ m68k-atari-mint-gcc -o test_incbin.tos test_incbin_main.c test_incbin.o
/tmp/ccoUcCd0.o:/tmp/ccoUcCd0.o:(.text+0x20): undefined reference to `_myfile'
collect2: ld returned 1 exit status


How do I have to declare my label for incbin for the linker to recognize it?
Simon Sunnyboy/Paradize - http://paradize.atari.org/

Stay cool, stay Atari!

1x2600jr, 1x1040STFm, 1x1040STE 4MB+TOS2.06+SatanDisk, 1xF030 14MB+FPU+NetUS-Bee

User avatar
mfro
Atari Super Hero
Atari Super Hero
Posts: 808
Joined: Thu Aug 02, 2012 10:33 am
Location: SW Germany

Re: How to INCBIN with gcc

Postby mfro » Sat Apr 12, 2014 10:57 am

Did not try, but assume your aproach will work if you'd remove one underscore in the .s file (_myfile instead of __myfile) and added a ".globl _myfile".

User avatar
simonsunnyboy
Moderator
Moderator
Posts: 5129
Joined: Wed Oct 23, 2002 4:36 pm
Location: Friedrichshafen, Germany
Contact:

Re: How to INCBIN with gcc

Postby simonsunnyboy » Sat Apr 12, 2014 11:13 am

Yes, that resolved the linker problem. Now I have to try if the access to the binary data works as expected from my C file. The current "do nothing" compiled to 230K .tos but for a test it works.

*EDIT* Works as expected, with a couple of lines I have my DEGAS picture on screen :) I'll probably switch over to gcc soon for my ST needs 8)
Simon Sunnyboy/Paradize - http://paradize.atari.org/

Stay cool, stay Atari!

1x2600jr, 1x1040STFm, 1x1040STE 4MB+TOS2.06+SatanDisk, 1xF030 14MB+FPU+NetUS-Bee

User avatar
dml
Fuji Shaped Bastard
Fuji Shaped Bastard
Posts: 3474
Joined: Sat Jun 30, 2012 9:33 am

Re: How to INCBIN with gcc

Postby dml » Sat Apr 12, 2014 1:10 pm

I often use 'cincbin' - a small commandline tool which turns raw data into a formatted c sourcefile which you can just add to your project. You specify the byte size of each element and the number of elements per line, and it spits out a sourcefile.

Not always what you want, but for precalculated tables and stuff it works well and it's very easy to integrate as a Makefile rule so the data is converted for you when you build, if the data has changed.

[EDIT]

Here's an example rule from one of my projects which makes c table files automatically based on datafile extensions. You just need to name the file 'mydata.bin8' and add the dependency 'mydata.o' (or '.c', depending on how your makefile works) to your project and the rule does the rest. The array ends up with the name of the input file.

Code: Select all

# rule to convert binary data into C source
%.c: %.bin8
   cincbin $< /o$@ /w100 /s1
%.c: %.bin16
   cincbin $< /o$@ /w100 /s2
%.c: %.bin32
   cincbin $< /o$@ /w100 /s4


Social Media

     

Return to “C / PASCAL etc.”

Who is online

Users browsing this forum: No registered users and 2 guests