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 > mthumb-interwork help

#1952 - regularkid - Sun Jan 26, 2003 6:52 pm

Hi. I have a problem using the -mthumb-interwork compiler option. Ok, heres what I want to do: I need to make a pixel plot function in assembly that plots 16bits at a time, so that means I need to use THUMB assembly. Ok, this is fine, so that means that when I compile my code I need to add the -mthumb-interwork compiler option because the main C code is in ARM and without this option I cant switch between THUMB and ARM (i think). So here is what my compiler rule for my makefile looks like:

Code:

CFLAGS   =   -c -g -Wall -mthumb-interwork -O2
ASFLAGS   =   -mthumb-interwork
LFLAGS   =   -Tbss 0x03000000 -Tdata 0x08000000 -Ttext

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

%.o : %.s
   $(AS) $(ASFLAGS) $< -o $@

$(GAME).elf : $(OBJS)
                ld -o $(GAME).elf $(LFLAGS) $(OBJS)


Everything compiles fine, but when I go to link it gives me tons of warnings saying:
Code:

/cygdrive/c/DEVKITADV/BIN/../lib/gcc-lib/arm-agb-elf/3.0.2/../../../../arm-agb-elf/bin/ld: Warning: _divsi3.o does not support interworking, whereas Game.elf does
/cygdrive/c/DEVKITADV/BIN/../lib/gcc-lib/arm-agb-elf/3.0.2/../../../../arm-agb-elf/bin/ld: Warning: _dvmd_tls.o does not support interworking, whereas Game.elf does
/cygdrive/c/DEVKITADV/BIN/../lib/gcc-lib/arm-agb-elf/3.0.2/../../../../arm-agb-elf/bin/ld: Warning: __main.o does not support interworking, whereas Game.elf does
/cygdrive/c/DEVKITADV/BIN/../lib/gcc-lib/arm-agb-elf/3.0.2/../../../../arm-agb-elf/bin/ld: Warning: unwind-dw2-fde.o does not support interworking, whereas Game.elf does
/cygdrive/c/DEVKITADV/BIN/../lib/gcc-lib/arm-agb-elf/3.0.2/../../../../arm-agb-elf/bin/ld: Warning: abort.o does not support interworking, whereas Game.elf does
/cygdrive/c/DEVKITADV/BIN/../lib/gcc-lib/arm-agb-elf/3.0.2/../../../../arm-agb-elf/bin/ld: Warning: atexit.o does not support interworking, whereas Game.elf does
/cygdrive/c/DEVKITADV/BIN/../lib/gcc-lib/arm-agb-elf/3.0.2/../../../../arm-agb-elf/bin/ld: Warning: impure.o does not support interworking, whereas Game.elf does
/cygdrive/c/DEVKITADV/BIN/../lib/gcc-lib/arm-agb-elf/3.0.2/../../../../arm-agb-elf/bin/ld: Warning: malloc.o does not support interworking, whereas Game.elf does
/cygdrive/c/DEVKITADV/BIN/../lib/gcc-lib/arm-agb-elf/3.0.2/../../../../arm-agb-elf/bin/ld: Warning: mallocr.o does not support interworking, whereas Game.elf does
/cygdrive/c/DEVKITADV/BIN/../lib/gcc-lib/arm-agb-elf/3.0.2/../../../../arm-agb-elf/bin/ld: Warning: mlock.o does not support interworking, whereas Game.elf does
/cygdrive/c/DEVKITADV/BIN/../lib/gcc-lib/arm-agb-elf/3.0.2/../../../../arm-agb-elf/bin/ld: Warning: sbrkr.o does not support interworking, whereas Game.elf does
/cygdrive/c/DEVKITADV/BIN/../lib/gcc-lib/arm-agb-elf/3.0.2/../../../../arm-agb-elf/bin/ld: Warning: signal.o does not support interworking, whereas Game.elf does
/cygdrive/c/DEVKITADV/BIN/../lib/gcc-lib/arm-agb-elf/3.0.2/../../../../arm-agb-elf/bin/ld: Warning: signalr.o does not support interworking, whereas Game.elf does
/cygdrive/c/DEVKITADV/BIN/../lib/gcc-lib/arm-agb-elf/3.0.2/../../../../arm-agb-elf/bin/ld: Warning: strlen.o does not support interworking, whereas Game.elf does
/cygdrive/c/DEVKITADV/BIN/../lib/gcc-lib/arm-agb-elf/3.0.2/../../../../arm-agb-elf/bin/ld: Warning: syscalls.o does not support interworking, whereas Game.elf does
/cygdrive/c/DEVKITADV/BIN/../lib/gcc-lib/arm-agb-elf/3.0.2/../../../../arm-agb-elf/bin/ld: Warning: vsprintf.o does not support interworking, whereas Game.elf does
/cygdrive/c/DEVKITADV/BIN/../lib/gcc-lib/arm-agb-elf/3.0.2/../../../../arm-agb-elf/bin/ld: Warning: errno.o does not support interworking, whereas Game.elf does
/cygdrive/c/DEVKITADV/BIN/../lib/gcc-lib/arm-agb-elf/3.0.2/../../../../arm-agb-elf/bin/ld: Warning: freer.o does not support interworking, whereas Game.elf does
/cygdrive/c/DEVKITADV/BIN/../lib/gcc-lib/arm-agb-elf/3.0.2/../../../../arm-agb-elf/bin/ld: Warning: vfprintf.o does not support interworking, whereas Game.elf does
/cygdrive/c/DEVKITADV/BIN/../lib/gcc-lib/arm-agb-elf/3.0.2/../../../../arm-agb-elf/bin/ld: Warning: wsetup.o does not support interworking, whereas Game.elf does
/cygdrive/c/DEVKITADV/BIN/../lib/gcc-lib/arm-agb-elf/3.0.2/../../../../arm-agb-elf/bin/ld: Warning: dtoa.o does not support interworking, whereas Game.elf does
/cygdrive/c/DEVKITADV/BIN/../lib/gcc-lib/arm-agb-elf/3.0.2/../../../../arm-agb-elf/bin/ld: Warning: fflush.o does not support interworking, whereas Game.elf does
/cygdrive/c/DEVKITADV/BIN/../lib/gcc-lib/arm-agb-elf/3.0.2/../../../../arm-agb-elf/bin/ld: Warning: findfp.o does not support interworking, whereas Game.elf does
/cygdrive/c/DEVKITADV/BIN/../lib/gcc-lib/arm-agb-elf/3.0.2/../../../../arm-agb-elf/bin/ld: Warning: fvwrite.o does not support interworking, whereas Game.elf does
/cygdrive/c/DEVKITADV/BIN/../lib/gcc-lib/arm-agb-elf/3.0.2/../../../../arm-agb-elf/bin/ld: Warning: fwalk.o does not support interworking, whereas Game.elf does
/cygdrive/c/DEVKITADV/BIN/../lib/gcc-lib/arm-agb-elf/3.0.2/../../../../arm-agb-elf/bin/ld: Warning: locale.o does not support interworking, whereas Game.elf does
/cygdrive/c/DEVKITADV/BIN/../lib/gcc-lib/arm-agb-elf/3.0.2/../../../../arm-agb-elf/bin/ld: Warning: makebuf.o does not support interworking, whereas Game.elf does
/cygdrive/c/DEVKITADV/BIN/../lib/gcc-lib/arm-agb-elf/3.0.2/../../../../arm-agb-elf/bin/ld: Warning: mbtowc_r.o does not support interworking, whereas Game.elf does
/cygdrive/c/DEVKITADV/BIN/../lib/gcc-lib/arm-agb-elf/3.0.2/../../../../arm-agb-elf/bin/ld: Warning: memchr.o does not support interworking, whereas Game.elf does
/cygdrive/c/DEVKITADV/BIN/../lib/gcc-lib/arm-agb-elf/3.0.2/../../../../arm-agb-elf/bin/ld: Warning: memcpy.o does not support interworking, whereas Game.elf does
/cygdrive/c/DEVKITADV/BIN/../lib/gcc-lib/arm-agb-elf/3.0.2/../../../../arm-agb-elf/bin/ld: Warning: memmove.o does not support interworking, whereas Game.elf does
/cygdrive/c/DEVKITADV/BIN/../lib/gcc-lib/arm-agb-elf/3.0.2/../../../../arm-agb-elf/bin/ld: Warning: memset.o does not support interworking, whereas Game.elf does
/cygdrive/c/DEVKITADV/BIN/../lib/gcc-lib/arm-agb-elf/3.0.2/../../../../arm-agb-elf/bin/ld: Warning: mprec.o does not support interworking, whereas Game.elf does
/cygdrive/c/DEVKITADV/BIN/../lib/gcc-lib/arm-agb-elf/3.0.2/../../../../arm-agb-elf/bin/ld: Warning: s_isinf.o does not support interworking, whereas Game.elf does
/cygdrive/c/DEVKITADV/BIN/../lib/gcc-lib/arm-agb-elf/3.0.2/../../../../arm-agb-elf/bin/ld: Warning: s_isnan.o does not support interworking, whereas Game.elf does
/cygdrive/c/DEVKITADV/BIN/../lib/gcc-lib/arm-agb-elf/3.0.2/../../../../arm-agb-elf/bin/ld: Warning: stdio.o does not support interworking, whereas Game.elf does
/cygdrive/c/DEVKITADV/BIN/../lib/gcc-lib/arm-agb-elf/3.0.2/../../../../arm-agb-elf/bin/ld: Warning: strcmp.o does not support interworking, whereas Game.elf does


What am I doing wrong? Thanks!
_________________
- RegularKid

#1957 - Splam - Sun Jan 26, 2003 7:30 pm

C code, in ARM? Are you relocating that to IWRAM? if not then use thumb instead (for rom) OR compile to arm in iwram then you're not wasting the iwram instruction prefetch.

Also why does your code need to be thumb to do a 16bit plot? hmm I'm not sure what's wrong with the interworking, but it's probably something to do with your confusion about arm/thumb and what they do.

#1958 - regularkid - Sun Jan 26, 2003 7:35 pm

Quote:

Also why does your code need to be thumb to do a 16bit plot


I could be wrong, If i'm in mode 3 and want to plot one pixel (16 bits) and I use ARM assembly it only is able to move 32 bits at a time, right? Please correct me if I'm wrong (and maybe show an example :) ).

Quote:

C code, in ARM? Are you relocating that to IWRAM? if not then use thumb instead (for rom) OR compile to arm in iwram then you're not wasting the iwram instruction prefetch.


I thought regular C code was automatically in ARM?

Quote:

hmm I'm not sure what's wrong with the interworking, but it's probably something to do with your confusion about arm/thumb and what they do.


Yeah, i'm kind of confused about them and what they do. Could you explain to me? Thanks!
_________________
- RegularKid

#1959 - Splam - Sun Jan 26, 2003 7:51 pm

Arm 16bit move
strh r0,[r1] the H means halfword, word (on this processer) = 32bit, halfword = 16bit byte (strb) = 8bit.
Of course theres nothing to stop you moving 32bits at a time to vram, it's faster due to less actual str instructions.

C is usually compiled to thumb as it's usually held in rom and thumb runs faster from rom than arm (thumb =16bits per instruction, arm =32). (of course we could go into why that isn't ALWAYS the case, but thats not what you're asking here).

Basically interworking lets the compiler know that you want to swap from arm/thumb or thumb/arm processing. The only thing SHOULD involve is changing the lowest bit of the PC when loading it with the location of the code you want to jump to, however, because the compiler has other things to deal with as well it has a tendency to need to do this jump via a register (it can all get a bit confusing here hehe) which is where the interworking comes in.

#1961 - regularkid - Sun Jan 26, 2003 7:55 pm

Whoa! Thanks, that helped a lot! You are very good at explaining things (i think you have helped me out before in some other posts).

On a side note, I was just reading a post you had helping someone with screen effects. You mentioned using the gba's windows feature. The only source of info on the subject I can dig up is in the Cowbite and GBATEK hardware specs. Do you know of a good tutorial on the windows feature? Thanks!
_________________
- RegularKid

#1963 - Splam - Sun Jan 26, 2003 8:29 pm

Glad to help.

As for tutorials for Window modes, can't say I've ever seen any but they're pretty simple to use.

You've got 2 of them, they each have an X and Y for top left and bottom right positions and registers for what is switched on/off inside and outside the widowed area which lets you control bg0,1,2,3, OBJ and Colour special effects (alpha blend etc).

So to have a window in the middle of the screen which had bg0 outside its area and bg1 inside you'd do something like this..

#define top_left_x 40
#define top_left_y 20

#define bottom_right_x 200
#define bottom_right_y 140

WIN0H = (top_left_x<<8) | bottom_right_x;
WIN0V = (top_left_y<<8) | bottom_right_y;

WININ = 2;
WINOUT = 1;



WININ = 16bit 2 x 8bits for each window
same for WINOUT
bits are as follows

0 = BG0
1 = BG1
2 = BG2
3 = BG3
4 = OBJ
5 = COLOUR EFFECTS

then repeated <<8 for the 2nd window

So you can see about the WININ now holds 2 which = BG1 for the INside of the window and WINOUT holds 1 = BG0 for OUTside

Should be all you need ;) of course there are 2 windows so you can end up doing some crazy stuff especially if you alter those values on hdma or hblanks as I mentioned in my other post.

#1964 - regularkid - Sun Jan 26, 2003 8:42 pm

Would it be possible to clip each gba sprite seperatly? By that I mean be able to pretty much make each sprite have it's own clipping rectangle?
_________________
- RegularKid

#1967 - Splam - Sun Jan 26, 2003 9:18 pm

This is the tough question ;) Using the normal windows the answer is no as you only have 2 windows available (and you'd need one for each sprite) BUT the WINOUT register ALSO controls the OBJ window (this is the bit I haven't used yet so I'm not totally sure of the results).

OBJ window is set by puting 10 (bits) at bits 10 and 11 of the OBJ attrib 0. When this is set the sprite isn't displayed BUT any non 0 bytes in the sprite become the Object Window.

Then the bits (bg0-3, obj, colour fx) of the WINOUT register then effect that object.

As I say I haven't done any tests on this but as far as I can make out you could mask your sprites by creating an extra sprite, setting it to obj window mode then setting the OBJ bit in WINOUT to off. Trouble would start when sprites overlapped and therefore the obj window sprite would turn them all off.

Basically it creates a mask but like the normal windows will effect EVERYTHING under it, not sure about what would happen if you could order the sprite priorities properly, maybe the hardware would take that into account and you could safely use this method, just means more sprites to use as the obj windows.

#1970 - Splam - Sun Jan 26, 2003 10:29 pm

Ok, just done a quick test thing and found this out about OBJ Windows.

They do work as I thought (the same as the normal windows) EXCEPT where the inside/outside areas which are usually controlled by WININ and WINOUT, with the sprites the inside/outside areas are BOTH controlled by WINOUT but each 8bits of the 16bit register holds the inside and outside control.. make sense? errr :P

Instead of WINOUT being outside control..

8bits--8bits
win1--win0

its now
8bits---8bits
inside-outside
for the OBJ windows control

Also, sprite priority seems to make NO difference, if there's an OBJ Window there it overrides all other OBJs no matter what order they're in.

#2091 - Maddox - Wed Jan 29, 2003 5:54 am

Hey, regularkid. I would guess that you are getting link messages because GCC expects to find a separate library for the -mthumb-interwork option. Do yourself a favor and run for your life! Disable all the standard libraries, math libraries, start up files, etc. in your project.

I use -nostartfiles -nodefaultlibs -nostdlib and boy I'm I glad I did. GCC NEVER tells me it needs a file or library. Awesome! It does tell me it needs a symbol like memcpy, strcpy, or _call_via_r0 but when it does I code it myself (in either ARM or THUMB) and it kicks way more *ss than GCC versions.

You will learn a lot in the process, too. Do it.
_________________
You probably suck. I hope you're is not a game programmer.

#2100 - t0ne - Wed Jan 29, 2003 11:16 am

@regularkid: You need to tell the linker (ld) to use the thumb-interwork versions of the libraries to link with.
Use the -L flag to give ld the paths to the interwork libraries or use gcc with the -mthumb-interwork flag to invoke the linker for you:

Code:

$(GAME).elf : $(OBJS)
                gcc -mthumb-interwork -o $(GAME).elf $(OBJS)

#2111 - regularkid - Wed Jan 29, 2003 6:12 pm

Thanks! You guys are awsome, both of you guys were right (maddox and tOne). I tried both ways and they both worked! :)
_________________
- RegularKid