Original Post

Hello all,

I’m interested in trying to use GCCVB to compile multiple input source files and link them into a final binary to be run on Virtual Boy.

I know from the Demos on the wiki that it is possible to generate a Virtual Boy binary using objcopy. However, objcopy only works for one input file. The canonical way to convert multiple input ELF files into a single ELF file is to use ld with the “-r” switch. However, when I attempt to do that, while I indeed get a single output ELF file, the resultant binary when running objcopy on this ELF output is 32MB in size! Presumably, this has to something to do with how the default linker script changes the ELF file when ld is run, whereas all the demos on this site are a single source file (and just run objcopy directly instead of ld).

According to objdump, this is because the output file that “ld -r” generates thinks it starts at 0x7000000, and there are a number of symbols that is absolutely positioned at address 0x0. Incidentally, the resultant binary size is not a power of two either.

Has anyone had any luck with running GCCVB with multiple input C files to generate a Virtual Boy binary? If so, can anyone provide a linker script which permits this? I’d MUCH rather divide my source files by purpose and use multiple source files, instead of one master file with a large number of includes :P.

The following lines are the commands I am using:

v810-gcc -o mainloop.o -c -Wall -nostdlib -nostartfiles -nodefaultlibs -mv810 -xc -Ilibgccvb mainloop.c
v810-gcc -o vbmain.o -c -Wall -nostdlib -nostartfiles -nodefaultlibs -mv810 -xc -Ilibgccvb vbmain.c
v810-ld -o vbdemo.elf -r vbmain.o mainloop.o
v810-objcopy -S -O binary vbdemo.elf vbdemo.vb

I have attached mainloop.c and vbmain.c as well. The libgccvb used is the same exact one provided in the 6 simple demos, and the libgccvb directory itself should be placed in the same directory as the attached source files.

Thanks for any help!

Attachments:
7 Replies

I don’t use GCCVB for my Virtual Boy development, so I’m not readily able to just type in some commands to see what works, but I can tell you that ordinary multi-file compiles in gcc look something like this:

gcc main.c another.c third_file.c -o binary.exe

Pretending for a moment you didn’t already know that, you might give it a try and see if it helps you do what you’re trying to do.

Unfortunately, compiling all the object files in a single command line doesn’t solve the problem either- the minute that GCC defers to the linker is when the problems begin with the binary being too large (a SINGLE piece of data is placed at offset 0x0, and the rest begins at 0x7000000), and the file no longer being a power of two.

This leads me to believe the linker script is wrong, or I’m not using the correct command line switches :P. FWIW, I’m using RunnerPack’s MinGW version that uses GCC 4.4, which may not be well tested.

As an alternative for the time being, I’ll probably just go ahead and use the include approach… include guards between headers and the fact that function definitions are extern by default should permit me to compile successfully anyway.

Guy Perfect wrote:
I don’t use GCCVB for my Virtual Boy development…

Just out of curiosity, what DO you use then? I’ve found links to the official C compiler (Virtual Utopia C Compiler) that Intelligent Systems sent developers on this site… I’m considering running a DOSBOX session and using that to compile instead, even if the optimization wouldn’t be as good as GCC.

The ability to separate source files is rather important to me. But of course, it’s also cool to be able to use the same tools that real VB developers used back in the day :P.

… Seriously, that’s an insane find!

v810-gcc -o vbmain.o -c -Wall -nodefaultlibs -mv810 -xc -Ilibgccvb vbmain.c
libgccvb/misc.h:14: warning: 'itoa' defined but not used
v810-gcc -o mainloop.o -c -Wall -nodefaultlibs -mv810 -xc -Ilibgccvb mainloop.c
v810-gcc -o vbdemo.elf vbmain.o mainloop.o
v810-objcopy -S -O binary vbdemo.elf vbdemo.vb

So, it appears I used everything EXCEPT the correct command line. Something I tend to forget about ELF is that it specifies both an object and executable format.

All the demos in the six simple demos zip file use one single source file. However, what I didn’t notice is that each Makefile does both compiling and linking in one command (i.e. the “-c” switch is absent). This means that the output from the compiler from each demo is an ELF executable, and objcopy just removes the ELF relocation and header.

I did not realize this and was attempting to use ld combine ELF object (contrast with executable) files into one large object file, and attempting to run that non-executable ELF object file through objcopy instead. Problem solved!… I think.

If I really wanted to know what GCC was doing behind the scenes (not recommended if you value your sanity), I could always dump the specs file or use the -### option.

cr1901 wrote:

Guy Perfect wrote:
I don’t use GCCVB for my Virtual Boy development…

Just out of curiosity, what DO you use then?

He uses “devkitv810”, which is also based on GCC, so I’m not sure how it is better than gccVB. When he’s too cool for C and assembly, he writes instructions manually with a hex editor.

I’ve found links to the official C compiler (Virtual Utopia C Compiler) that Intelligent Systems sent developers on this site… I’m considering running a DOSBOX session and using that to compile instead, even if the optimization wouldn’t be as good as GCC.

VUCC is actually quite good, I think it’s better than GCC in some situations. It’s also very flexible. But unless you have a really fast computer, it would be probably too slow in DOSBox. There’s also the question of how legal it is to use it.

Unfortunately, it appears the version of libgccvb that the demos provide is not idempotent, despite having include guards: I cannot include it in multiple source files and successfully compile a working program. I get multiple definition errors for all functions and typedef’ed structs :P.

The solution presumably is to take each variable declaration and make them extern, defining them in various C files, or using an approach like TI does for their MSP430 microcontroller registers.

I know there’s a thread for libgccvb committee around here. Has there been any interest in reviving that, taking the best routines from the various versions, and creating a static library which can be linked against?

cr1901 wrote:
Unfortunately, it appears the version of libgccvb that the demos provide is not idempotent, despite having include guards: I cannot include it in multiple source files and successfully compile a working program. I get multiple definition errors for all functions and typedef’ed structs :P.

The solution presumably is to take each variable declaration and make them extern, defining them in various C files, or using an approach like TI does for their MSP430 microcontroller registers.

I know there’s a thread for libgccvb committee around here. Has there been any interest in reviving that, taking the best routines from the various versions, and creating a static library which can be linked against?

libgccvb didn’t change much during the last years (besides modified version found in releases here and there). dasi and GuyPerfect started on a new lib from the scratch quite some time ago. It did sound promising but there was never an official release.

As far as I know VBDE does contain the latest official version of libgccvb: http://www.planetvb.com/modules/newbb/viewtopic.php?post_id=22265#forumpost22265
It has also a more recent gccVB inside in is very easy to use.

 

Write a reply

You must be logged in to reply to this topic.