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.

ASM > Strange error... (inline asm)

#7568 - Arek the Absolute - Fri Jun 20, 2003 2:32 am

Let me first off confess that I barely know any assembly, and that this question is actually for a C++ program, but it uses inline assembly, and that's what's causing my problem, so it seemed most fitting here. I'm using source for multiboot programs that I got from a site Tepples was so kind as to point me to. (here) and for a while it suited me just fine, so I've never really tampered with it. However, now I've noticed that sometimes I get an error from G++'s assembler that reads "/cygdrive/c/WINDOWS/TEMP/cciz3X2B.s: Assembler messages:
/cygdrive/c/WINDOWS/TEMP/cciz3X2B.s:16092: Error: invalid literal constant: pool needs to be closer"

The assembly code it's pointing at is contained in this:
Code:

void SendROM()
{
   u8 palette;
   u8 debug = 1;
   u16 i;
   u16 key;
   u32 length;

   mp.cb = 2;
   mp.pc = 0xd1;
   mp.startp = (u8 *)&multiboot [0xc0];
   length = sizeof(multiboot) - 0xc0;
   length = (length + 15) & ~15; // 16 byte units
   if (length < 0x1c0) length = 0x1c0;
   mp.endp = (u8 *)&multiboot [0xc0] + length;

   palette = 0xc1;
   mp.palette = palette;

   i = xfer(0x6300+palette);
   i = xfer(0x6300+palette);

   mp.cd[0] = i;
   mp.cd[1] = 0xff;
   mp.cd[2] = 0xff;

   key = (0x11 + (i & 0xff) + 0xff + 0xff) & 0xff;
   mp.hs_data = key;

   i = xfer(0x6400 | (key & 0xff));

   // Execute BIOS routine to transfer client binary to slave unit
   asm volatile (
      " ldr r0,=mp\n" // <- i suspect it's this line causing the problem
      " mov r1,#1\n"
      " swi 0x250000\n"       //NOTE!!!!! Use 0x250000 for ARM C Compiler mode.
      :  // Outputs       // 0x25 here will only work for Thumb mode.
      :  // Inputs
      : "r0","r1","r2","r8","r9","r10","r11","r12"     // Regs crushed & smushed
      );
}

The problem is, not being that familiar with assembly, I have no idea what that error means. Worse yet, it seems to pop up at very odd moments. Here's an example from my main function:

Code:

   REG_DISPCNT = 0x1442; // screenmode = mode 2, sprites enabled
                         // bg2 enabled, 1d object mapping

   game.InitPlayers(); // just initializes sprites

   // DMA copy in the image and palette data for the sprite
DMA_Copy(3,(void*)imagedataPalette,(void*)OBJPaletteMem,128,0x84000000);
   DMA_Copy(3,(void*)imagedata_image,(void*)OAMData,256,0x84000000);

   REG_BG2CNT = 0x5983;

   // DMA copy in the image and palette data for the tiles
   BGPaletteMem[0] = 0xBBBB;

   // set REG_RCNT bits E-F to determine transfer mode?
   Text("Waiting for connection",30,100); // prints to the screen using sprites

       .... etc...



I stop there because I've noticed that if I comment out that last line of code, the one that prints to the screen using sprites, I get that error from the assembler. If I don't comment it out, I don't get the error. I can post source for the Text function if necessary, but it's somewhat lengthy and I figured it's probably enough to say that it doesn't use anything related to the multiboot stuff. All it uses is a constant image array containing image data for the sprites, and DMA copies to put the image data where it belongs. Simply put, I have no idea why it's causing any problem, or rather, why it's solving any problems by being there.

Any suggestions? Can anyone maybe clue me in as to what that error means, at least? I can't seem to make any sense out of this problem, much less solve it.
_________________
-Arek the Absolute

#7569 - tepples - Fri Jun 20, 2003 3:18 am

Arek the Absolute wrote:
I'm using source for multiboot programs that I got from a site Tepples was so kind as to point me to. (here)

Which I have recently got to work.

Quote:
However, now I've noticed that sometimes I get an error from G++'s assembler that reads "/cygdrive/c/WINDOWS/TEMP/cciz3X2B.s: Assembler messages:
/cygdrive/c/WINDOWS/TEMP/cciz3X2B.s:16092: Error: invalid literal constant: pool needs to be closer"

In general, "pool needs to be closer" means that a function is too big. In the ARM architecture, large constants are stored in data blocks called "pools" placed between functions. A pool has to be close enough for PC-relative addressing to reach it. To force a pool to be added within arm's reach (pun intended), try putting SendROM() and the other multiboot.c functions in a file by itself, compiling it to a .o file, and including it in your link command line.

DON'T:
Add other C files to your main.c by #include "foo.c".

DO:
Add other C files by compiling them separately (gcc {options} -c foo.c -o foo.o) and link them together (gcc {options} a.o b.o c.o d.o -o game.elf).
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#7608 - Arek the Absolute - Fri Jun 20, 2003 10:51 pm

And once again you've done me quite the favor by explaining that. Thanks a lot!
_________________
-Arek the Absolute