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.

Beginners > code in IW_RAM

#51155 - wiz - Tue Aug 16, 2005 9:10 pm

Hello!

Well this week I be mostly coding... stuff in IW_RAM

I read about this, and tried it, and wow! it does make functions a lot faster..

I seem to be getting a lot of errors to do with "relocation truncated" when Im trying to pass a pointer to a test function from a function in IW_RAM, why could this be?

Heres a test I made:
Code:
void TESTER(s8 *stuff)
{
   stuff[0] = 0;
}

s8 stuff[40];


IN_IWRAM void Test()
{
   u8 t;
   TESTER((s8*)stuff);
}

#51157 - strager - Tue Aug 16, 2005 9:28 pm

wiz wrote:
I seem to be getting a lot of errors to do with "relocation truncated" when Im trying to pass a pointer to a test function from a function in IW_RAM, why could this be?


I get the same errors when using the Krawall library. I haven't found any way to prevent the errors, but turning multiboot on fixes it (odd it would... maybe because it cannot branch into that range?).

#51158 - tepples - Tue Aug 16, 2005 9:46 pm

You need to use long_call when calling between ROM and RAM. Google is your friend.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#51159 - Quirky - Tue Aug 16, 2005 9:48 pm

Code:
IN_IWRAM void Test()
{
   u8 t;
   TESTER((s8*)stuff);
}


How is IN_IWRAM defined? You need a long_call attribute in there:

Code:
#define IN_IWRAM __attribute__ ((section (".iwram"), long_call))


For example try changing the comment here:

in main.c
Code:

#define IN_IWRAM __attribute__ ((section (".iwram"), long_call))
//#define IN_IWRAM __attribute__ ((section (".iwram")))

void test(void) IN_IWRAM;
int main(void)
{
  test();
  while(1)
  {
  }
  return 0;
}


in test.c
Code:

//#define IN_IWRAM __attribute__ ((section (".iwram")))
#define IN_IWRAM __attribute__ ((section (".iwram"), long_call))

IN_IWRAM void test(){}


It's important that they are in different files or it will work without problems.

EDIT: tepples beat me to it. My answer got full marks though ;)

#51163 - wiz - Tue Aug 16, 2005 10:09 pm

Hi, and many thanks for the fast replies

it seems to be defined correctly:
Code:
#define IN_IWRAM __attribute__ ((section (".iwram"), long_call))


the problem is only happening when I pass a pointer to an array, its fine when passing variables.

please note that Im calling a normal function from the function thats in IN_IWRAM (if that makes any difference)

#51172 - wiz - Tue Aug 16, 2005 10:53 pm

To add to my previous reply:

I have changed my compiler settings and removed the statement "-mthumb" from the compiler line in my batch file.

I then called the function using the following FarCall macro:

Code:
#define FarCall(FUNCTION) \
    ({ \
        typeof (FUNCTION) *volatile _POINTER; \
        \
        _POINTER = &(FUNCTION); \
    })


and now its working! however Im now even more confused :S

is it better to compile without the -mthumb ? I have no idea what it means heh :)

#51174 - tepples - Tue Aug 16, 2005 11:04 pm

Any code that goes in IWRAM should be compiled as ARM. Any code that goes in EWRAM or ROM should be compiled as Thumb.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#51217 - wiz - Wed Aug 17, 2005 8:43 am

ah right so thats what it is,

so its correct to say code placed IN_IWRAM needs to be compiled differently (like Quirky mentioned something about being in its own file)

#51264 - Quirky - Wed Aug 17, 2005 8:02 pm

ARM is 32-bit code, THUMB is 16-bit and uses a different instruction set. The advantage of THUMB is as tepples mentioned, faster from ROM, plus (I find) it tends to generate smaller binaries, as on average 1 arm instruction tends to be equivalent to a touch 1.75 thumb ones.

I mentioned the second file there so that you would see the relocation error, it manages to sort out the the location if the functions are in the same compilation unit.

To get arm compilation flags, I tend to do the following in a Makefile:

Code:

%.o : %.arm.c
  $(GCC) $(CFLAGS) -marm -mthumb-interwork -c -o $@ $<


Though I've also seen the cute trick of having $(CFLAGS-$<) which lets you do things like:

Code:

CFLAGS-interrupt.c=-marm -mthumb-interwork
CFLAGS-needs_oomph.c= -O3
.....

%.o : %.c
  $(GCC) $(CFLAGS) $(INCLUDES) $(CFLAGS-$<) -c -o $@ $<


As for problems calling from code in RAM to code in ROM - I get the same error here... hmmm a puzzler... The only way I see is to place the ROM code in the same .c as the IN_IWRAM code that calls it.