gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Coding > C++ and inline ASM

#26457 - RiZeUp - Thu Sep 16, 2004 1:23 am

I'm trying to learn how to get multiplayer working on gba. The come i'm looking at is in c while my application is in c++. When I compile my code i get an undefined reference in my ASM code. From what I could gather(correct me if im wrong) g++ mangles the names and functiones when compiling.

What do I need to do to fix this?

here is my makefile(i tried both ways). I'm really running out of ideas.

rem g++ -c -O3 -mthumb -mthumb-interwork main.cpp
rem g++ -c -O3 -mthumb -mthumb-interwork multiplayer.cpp

g++ -Wall -O -mthumb -mthumb-interwork -o mp.elf main.cpp multiplayer.cpp

g++ -mthumb -mthumb-interwork -o mp.elf main.o multiplayer.o


objcopy -O binary mp.elf multiplayer.gba
_________________
~RiZeUp

#26460 - sajiimori - Thu Sep 16, 2004 1:57 am

C++ does mangle names, and it's not just a GCC thing. To specify that a name is not or should not be mangled, wrap it in this:
Code:
extern "C" { ... }

#26461 - RiZeUp - Thu Sep 16, 2004 2:08 am

yeah I tried that.
i think I need a break cause my error is probably really simple but i just don t see it.

with extern "C" i get syntax error before string constant.

and this is my code extern "C" code

Code:
   #ifdef  __cplusplus
   extern "C" {
   #endif

   // Execute BIOS routine to transfer client binary to slave unit
   asm volatile (
     " ldr r0,=mp\n"
     " mov r1,#1\n"
     " swi 0x25\n"  /* for ARM change to 0x00250000 */
     ::: "r0","r1","r2","r8","r9","r10","r11","r12"
   );
   #ifdef  __cplusplus
   }
   #endif

Thanks for taking the time to help me
_________________
~RiZeUp

#26462 - sajiimori - Thu Sep 16, 2004 3:07 am

I don't know the source of the syntax error, but you want to put extern "C" around the declaration of the object you want to access, not around the code that does the access.

#26472 - RiZeUp - Thu Sep 16, 2004 3:14 pm

ok i'm starting to understand how it works a little bit better. I did a little research on newsgroups but i'm still having a little bit of a hard time.
I still get syntax errors with this and undefined references. I read that you don't need to put extern "C" for typedefs.

Code:

typedef struct {
  u32 reserve1[5];      //
  u8 hs_data;           // 20 ($14) Needed by BIOS
  u8 reserve2;          // 21 ($15)
  u16 reserve3;         // 22 ($16)
  u8 pc;                // 24 ($18) Needed by BIOS
  u8 cd[3];             // 25 ($19)
  u8 palette;           // 28 ($1c) Needed by BIOS - Palette flash while load
  u8 reserve4;          // 29 ($1d) rb
  u8 cb;                // 30 ($1e) Needed by BIOS
  u8 reserve5;          // 31 ($1f)
  u8 *startp;           // 32 ($20) Needed by BIOS
  u8 *endp;             // 36 ($24) Needed by BIOS
  u8 *reserve6;         // 40 ($28)
  u8 *reserve7[3];      // 44 ($2c)
  u32 reserve8[4];      // 56 ($38)
  u8 reserve9;          // 72 ($48)
  u8 reserve10;         // 73 ($49)
  u8 reserve11;         // 74 ($4a)
  u8 reserve12;         // 75 ($4b)
} MBStruct;

class Multiplayer
{
public:
   extern "C" MBStruct mp;
   void DelayCycles(u32 cycles);
   u16 send(u16 send);
   void sendMB();
};

_________________
~RiZeUp

#26474 - sajiimori - Thu Sep 16, 2004 6:34 pm

Does that compile?? I've never seen that use of extern before. Besides, if you're accessing a struct from assembly, you don't access elements by name -- you access them by offset. Try this for computing the offset of an element:
Code:
#define STRUCT_OFFSET(type, element) (&((type*)0)->element)