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 > makefile, how do I add .S-files & link correctly?(slvd)

#107379 - Ant6n - Sun Oct 29, 2006 3:57 am

Hi,

I recently switched from the managed make system of vham to eclipse. I used the eclipse tutorial that floats around here in the forum somewhere. they gave an example makefile, so i basicly just copy pasted my source file names. I dont know much about makefiles, so i dont know how i can add my .S files
I tried this:

Code:

# --- Project details ---
PROJ    := lib
EXT     := gba

CFILES  := main.c lib_time.c lib_frame.c lib_math.c lib_interrupt.c lib_memory.c lib_sprite.c lib_stile.c rock.c ship.c shipdata.c
SFILES  := lib_asmirqhandler.S lib_asmagbprint.S
   
COBJS   := $(CFILES:.c=.o)
SOBJS   := $(SFILES:.S=.o)
OBJS    := $(COBJS) $(SOBJS)

#--- Tool settings ---
# for devkitARM r19+ use PREFIX := arm-eabi
PREFIX := arm-eabi-
AS      := $(PREFIX)as
CC      := $(PREFIX)gcc
LD      := $(PREFIX)gcc
OBJCOPY := $(PREFIX)objcopy


MODEL   := -mthumb-interwork -mthumb
SPECS   := -specs=gba.specs         # comment out for DKA

ASFLAGS := -mthumb-interwork
CFLAGS  := -I./ $(MODEL) -O2 -Wall
LDFLAGS := $(SPECS) $(MODEL)

#--- Build steps ---
build : $(PROJ).$(EXT)

$(PROJ).$(EXT) : $(PROJ).elf
   @$(OBJCOPY) -v -O binary $< $@
   -@gbafix $@

$(PROJ).elf : $(OBJS)
   @$(LD) $(OBJS) $(LDFLAGS) -o $@

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

$(SOBJS) : %.o : %.S
   $(AS) $(ASLAGS) -g -c $< -o $@


# --- Clean ---
.PHONY : clean
clean :
   @rm -fv $(COBJS)
   @rm -fv $(SOBJS)
   @rm -fv $(PROJ).$(EXT)
   @rm -fv $(PROJ).elf   


earlier this at least compiled, but the asm files seemed not to link. the debugger showed the pc run jump around and then settle in an infite loop when calling agbprint.
i fiddled around with it, and now it doesnt even compile anymore, giving the error message:
"make -k build
make: *** No rule to make target `lib_asmirqhandler.S', needed by `lib_asmirqhandler.o'.
make: *** No rule to make target `lib_asmagbprint.S', needed by `lib_asmagbprint.o'.
make: Target `build' not remade because of errors."

can anybody please point out what i am doing wrong here. Its porbably something obvious for people who use make and asm files.
Thank you very much

Anton


Last edited by Ant6n on Wed Nov 01, 2006 4:05 pm; edited 4 times in total

#107383 - gladius - Sun Oct 29, 2006 6:23 am

You can add this rule to a normal makefile:
Code:

%.o : %.S
   @echo $(notdir $<)
   @$(CC) -MM $(CFLAGS) -o $*.d $<
   @$(CC)  $(ASFLAGS) -c $< -o$@

#107391 - Ant6n - Sun Oct 29, 2006 9:13 am

Thank you for the tip, gladious.
ok, the whole thing compiles alright, but when i run the rom i still get a white screen. I have a program that first thing of all simply calls agbprint in lib_asmagbprint.S. The debugger dissassembly runs this:


0x0800028a <main+2>: ldr r0, [pc, #248] (0x8000384 <main+252>)
0x0800028c <main+4>: bl 0x80021cc <__agbprint_from_thumb>

0x080021cc <__agbprint_from_thumb>: bx pc
0x080021ce <__agbprint_from_thumb+2>: nop (mov r8, r8)

0x080021d0 <__agbprint_change_to_arm>: b 0x7000120

0x07000120 andeq r0, r0, r0

0x080000c0 <rom_header_end>: b 0x80000e0 <start_vector>

0x080000e0 <start_vector>: mov r0, #67108864 ; 0x4000000
0x080000e4 <start_vector+4>: str r0, [r0, #520]
0x080000e8 <start_vector+8>: mov r0, #18 ; 0x12
0x080000ec <start_vector+12>: msr CPSR_fc, r0
0x080000f0 <start_vector+16>: ldr sp, [pc, #180] ; 0x80001ac <CIDExit+2>
0x080000f4 <start_vector+20>: mov r0, #31 ; 0x1f
0x080000f8 <start_vector+24>: msr CPSR_fc, r0
0x080000fc <start_vector+28>: ldr sp, [pc, #172] ; 0x80001b0 <CIDExit+6>
0x08000100 <start_vector+32>: add r0, pc, #1 ; 0x1
0x08000104 <start_vector+36>: bx r0
0x08000108 <start_vector+40>: cmpeq r0, r10, lsr #16
0x0800010c <start_vector+44>: ldrmibt sp, [r8], -r11, lsl #4
0x08000110 <start_vector+48>: movwle r0, #53568 ; 0xd140
0x08000114 <start_vector+52>: ldreq r2, [r2], -r2, lsl #4
0x08000118 <start_vector+56>: bne 0x66d2dbc
0x0800011c <start_vector+60>: addeqs r1, r1, r6, lsl r12
0x08000120 <start_vector+64>: undefined instruction 0xf83bf000
0x08000124 <start_vector+68>: cmpcs r0, r0, lsr r7

0x08000128 <DoEWRAMClear+2>: biceq r0, r8, r9, lsl #6
0x0800012c <DoEWRAMClear+6>: undefined instruction 0xf82bf000

0x08000184 <CEW0Skip+20>: andcs pc, r3, #847872 ; 0xcf000

x08000188 <ClearMem+2>: orrmis r1, r1, #8978432 ; 0x890000
0x0800018c <ClearMem+6>: andcs sp, r0, #3 ; 0x3

0x08000190 <ClrLoop>: stmccdb r4, {r2, lr, pc}
0x08000194 <ClrLoop+4>: undefined


the program loops within the last two instructions.
I suspect there is something wrong right in the beginning when going from thumb c code to arm asm code...
...Does anybody have any idea what i am doing wrong? i am completely puzzled at this; still would like to use .S files

Thank you

Anton

#107439 - gmiller - Sun Oct 29, 2006 6:48 pm

Looking at the original make file you were trying for thumb mode instructions and based on the the instruction debugging your are in ARM mode (THUMB instructions are 16 but so each one would be +2 from the other, ARM mode instructions are 32 bits so each one would be +4 from the other). In your original CFLAGS have the -mthumb-interwork which will allow both instruction to work together ARM code to call THUMB and vice versa. Can't see enough information that yells at me here but someone else might be better idea. I use VHAM with devkitPRO so this is "my" makefile: (this my current template, only requires adding stuff to LIB for additional libraries, and using slightly modified make files from the devkitARM)
Code:

#---------------------------------------------------------------------------------
# Clear the implicit built in rules
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITARM)),)
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM)
endif

-include $(DEVKITARM)/gba_rules

#---------------------------------------------------------------------------------
# TARGET is the name of the output, if this ends with _mb a multiboot image is generated
# BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code
# DATA is a list of directories containing data files
# INCLUDES is a list of directories containing header files
#---------------------------------------------------------------------------------
# HAM Stuff no longer used ....
#
#PROGNAME =unused
#OFILES+= unused
#ADD_LIBS+= unused   

# .................
#

TARGET      :=   $(shell basename $(CURDIR))
BUILD      :=   build
SOURCES      :=   source
DATA      :=   
INCLUDES   :=   $(DEVKITARM)
GDB_DIRS   =    $cdir:$cwd:$(ADD_GDB_SOURCE_DIRS)

ifeq ($(MAKECMDGOALS),gdb)
DEBUG_SET   :=   gdb
endif

#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
#ARCH   :=   -mthumb -mthumb-interwork
ARCH   :=

ifneq ($(DEBUG_SET),gdb)
THIS_BUILD   :=   "Release Build"
CFLAGS   :=   -Wall -O3 -save-temps \
         -mcpu=arm7tdmi -mtune=arm7tdmi\
          -fomit-frame-pointer\
         -ffast-math \
         $(ARCH)
ASFLAGS   :=   $(ARCH)
else
THIS_BUILD   :=   "Debug Build"
CFLAGS   :=   -g -Wall -O0 -save-temps \
         -mcpu=arm7tdmi -mtune=arm7tdmi\
         -ffast-math \
         $(ARCH)
ASFLAGS   :=   $(ARCH) -g
endif
CFLAGS   +=   $(INCLUDE)



ifneq ($(DEBUG_SET),gdb)
LDFLAGS   =   $(ARCH) -Wl,-Map,$(notdir $@).map
else
LDFLAGS   =   -g $(ARCH) -Wl,-Map,$(notdir $@).map
endif

#---------------------------------------------------------------------------------
# path to tools - this can be deleted if you set the path to the toolchain in windows
#---------------------------------------------------------------------------------
export PATH      :=   $(DEVKITARM)/bin:$(DEVKITPRO)/msys/bin:$(PATH)

#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project
#---------------------------------------------------------------------------------
LIBS   :=

#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS   :=   $(LIBGBA)

#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
# rules for different file extensions
#---------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------

export OUTPUT   :=   $(CURDIR)/$(TARGET)
export VPATH   :=   $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
               $(foreach dir,$(DATA),$(CURDIR)/$(dir))

export DEPSDIR   :=   $(CURDIR)/$(BUILD)

#---------------------------------------------------------------------------------
# automatically build a list of object files for our project
#---------------------------------------------------------------------------------
CFILES      :=   $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES   :=   $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
SFILES      :=   $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
BINFILES   :=   $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))

#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
#---------------------------------------------------------------------------------
   export LD   :=   $(CC)
#---------------------------------------------------------------------------------
else
#---------------------------------------------------------------------------------
   export LD   :=   $(CXX)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------

export OFILES   := $(addsuffix .o,$(BINFILES)) $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)

#---------------------------------------------------------------------------------
# build a list of include paths
#---------------------------------------------------------------------------------
export INCLUDE   :=   $(foreach dir,$(INCLUDES),-I$(dir)/include) \
               $(foreach dir,$(LIBDIRS),-I$(dir)/include) \
               $(foreach dir,$(CURDIR), -I$(dir)/include) \
               -I$(CURDIR)

#---------------------------------------------------------------------------------
# build a list of library paths
#---------------------------------------------------------------------------------
export LIBPATHS   :=   $(foreach dir,$(LIBDIRS),-L$(dir)/lib)

.PHONY: $(BUILD) clean

#---------------------------------------------------------------------------------
$(BUILD):
   @[ -d $@ ] || mkdir -p $@
   make "DEBUG_SET=$(DEBUG_SET)" --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile

all   : buildtype $(BUILD)

buildtype:
   @echo "Build type: " $(THIS_BUILD)

#---------------------------------------------------------------------------------
clean:
   @echo clean ...
   rm -fr $(BUILD) $(TARGET).elf $(TARGET).gba

#---------------------------------------------------------------------------------
vbawin:   clean all
   $(DEVKITPRO)/tools/win32/vbawin.exe $(TARGET).gba

#---------------------------------------------------------------------------------
runvbawin:
   $(DEVKITPRO)/tools/win32/vbawin.exe $(TARGET).gba

#---------------------------------------------------------------------------------
vba:   clean all
   $(DEVKITPRO)/tools/win32/vbaSDL/vba.exe -3 $(TARGET).gba

#---------------------------------------------------------------------------------
runvba:
   $(DEVKITPRO)/tools/win32/vbaSDL/vba.exe -3 $(TARGET).gba

#---------------------------------------------------------------------------------
startsdl:
   $(DEVKITPRO)/tools/win32/vbaSDL/vba.exe -3 -Gtcp:44444 &

#---------------------------------------------------------------------------------
makeini:
   echo "File $(TARGET).elf" > insight.ini
   echo "target remote 127.0.0.1:44444" >>insight.ini
   echo "load $(TARGET).elf" >>insight.ini
   echo "b main" >>insight.ini
   echo "directory $(GDB_DIRS)">>insight.ini
   echo "c" >>insight.ini

#---------------------------------------------------------------------------------
startinsight:
   $(DEVKITPRO)/insight-6.4.50/bin/arm-elf-insight.exe --command=insight.ini $(TARGET).elf

#---------------------------------------------------------------------------------
gdb:   clean
   @make "DEBUG_SET=$(DEBUG_SET)" all
   make startsdl makeini startinsight

#---------------------------------------------------------------------------------
rungdb: startsdl makeini startinsight

testinsight: makeini startinsight

#---------------------------------------------------------------------------------
else

DEPENDS   :=   $(OFILES:.o=.d)

#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
$(OUTPUT).gba   :   $(OUTPUT).elf

$(OUTPUT).elf   :   $(OFILES)

%.o   :   %.pcx
   echo $(notdir $<)
   $(bin2o)

-include $(DEPENDS)

#---------------------------------------------------------------------------------
endif
#--------------------------------------------------------------------------------



gba_rules
Code:

ifeq ($(strip $(DEVKITPRO)),)
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>devkitPro)
endif

include $(DEVKITARM)/base_rules

LIBGBA   :=   $(DEVKITPRO)/libgba

#---------------------------------------------------------------------------------
%.gba: %.elf
   @$(OBJCOPY) -O binary $< $@
   @echo built ... $(notdir $@)
   gbafix $@

#---------------------------------------------------------------------------------
%_mb.elf:
   @echo linking multiboot
   $(LD) -specs=gba_mb.specs $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@

#---------------------------------------------------------------------------------
%.elf:
   @echo linking cartridge
   $(LD)  $(LDFLAGS) -specs=gba.specs $(OFILES) $(LIBPATHS) $(LIBS) -o $@

base_rules
Code:

#---------------------------------------------------------------------------------
# path to tools - this can be deleted if you set the path in windows
#---------------------------------------------------------------------------------
export PATH      :=   $(DEVKITARM)/bin:$(PATH)

#---------------------------------------------------------------------------------
# the prefix on the compiler executables
#---------------------------------------------------------------------------------
PREFIX      :=   arm-eabi-

export CC   :=   $(PREFIX)gcc
export CXX   :=   $(PREFIX)g++
export AS   :=   $(PREFIX)as
export AR   :=   $(PREFIX)ar
export OBJCOPY   :=   $(PREFIX)objcopy

#---------------------------------------------------------------------------------
%.a:
#---------------------------------------------------------------------------------
   @echo $(notdir $@)
   @echo "'Lib' Rule"
   @rm -f $@
   $(AR) -rc $@ $^

#---------------------------------------------------------------------------------
%.iwram.o: %.iwram.cpp
   @echo $(notdir $<)
   @echo "'CPP' ARM IWRAM Rule"
   $(CXX) -MMD -MP -MF $(DEPSDIR)/$*.d -marm -mthumb-interwork $(CXXFLAGS) -c $< -o $@

#---------------------------------------------------------------------------------
%.arm.o: %.arm.cpp
   @echo $(notdir $<)
   @echo "'CPP' ARM Rule"
   $(CXX) -MMD -MP -MF $(DEPSDIR)/$*.d -marm -mthumb-interwork $(CXXFLAGS) -c $< -o $@

#---------------------------------------------------------------------------------
%.iwram.o: %.iwram.c
   @echo $(notdir $<)
   @echo "'C' ARM IWRAM Rule"
   $(CC) -MMD -MP -MF $(DEPSDIR)/$*.d -marm -mthumb-interwork $(CFLAGS) -c $< -o $@

#---------------------------------------------------------------------------------
%.arm.o: %.arm.c
   @echo $(notdir $<)
   @echo "'C' ARM Rule"
   $(CC) -MMD -MP -MF $(DEPSDIR)/$*.d -marm -mthumb-interwork $(CFLAGS) -c $< -o $@

#---------------------------------------------------------------------------------
%.itcm.o: %.itcm.cpp
   @echo $(notdir $<)
   @echo "'CPP' ARM ITCM Rule"
   $(CXX) -MMD -MP -MF $(DEPSDIR)/$*.d -marm -mthumb-interwork $(CXXFLAGS) -c $< -o $@

#---------------------------------------------------------------------------------
%.itcm.o: %.itcm.c
   @echo $(notdir $<)
   @echo "'C' ARM ITCM Rule"
   $(CC) -MMD -MP -MF $(DEPSDIR)/$*.d -marm -mthumb-interwork $(CFLAGS) -c $< -o $@

#---------------------------------------------------------------------------------
%.o: %.cpp
   @echo $(notdir $<)
   @echo "'CPP' THUMB Rule"
   $(CXX) -MMD -MP -MF $(DEPSDIR)/$*.d -mthumb -mthumb-interwork $(CXXFLAGS) -c $< -o $@
   
#---------------------------------------------------------------------------------
%.o: %.c
   @echo $(notdir $<)
   @echo "'C' THUMB Rule"
   $(CC) -MMD -MP -MF $(DEPSDIR)/$*.d -mthumb -mthumb-interwork $(CFLAGS) -c $< -o $@

#---------------------------------------------------------------------------------
%.iwram.o: %.iwram.s
   @echo $(notdir $<)
   @echo "'ASM' ARM IWRAM Rule"
   $(CC) -MMD -MP -MF $(DEPSDIR)/$*.d -x assembler-with-cpp -marm -mthumb-interwork $(ASFLAGS) -c $< -o $@

#---------------------------------------------------------------------------------
%.arm.o: %.arm.s
   @echo $(notdir $<)
   @echo "'ASM' ARM Rule"
   $(CC) -MMD -MP -MF $(DEPSDIR)/$*.d -x assembler-with-cpp -marm -mthumb-interwork $(ASFLAGS) -c $< -o $@

#---------------------------------------------------------------------------------
%.iwram.o: %.iwram.S
   @echo $(notdir $<)
   @echo "'ASM' ARM IWRAM Rule"
   $(CC) -MMD -MP -MF $(DEPSDIR)/$*.d -x assembler-with-cpp -marm -mthumb-interwork $(ASFLAGS) -c $< -o $@

#---------------------------------------------------------------------------------
%.arm.o: %.arm.S
   @echo $(notdir $<)
   @echo "'ASM' ARM Rule"
   $(CC) -MMD -MP -MF $(DEPSDIR)/$*.d -x assembler-with-cpp -marm -mthumb-interwork $(ASFLAGS) -c $< -o $@

#---------------------------------------------------------------------------------
%.o: %.s
   @echo $(notdir $<)
   @echo "'ASM' THUMB Rule"
   $(CC) -MMD -MP -MF $(DEPSDIR)/$*.d -x assembler-with-cpp -mthumb -mthumb-interwork $(ASFLAGS) -c $< -o $@

#---------------------------------------------------------------------------------
%.o: %.S
   @echo $(notdir $<)
   @echo "'ASM' THUMB Rule"
   $(CC) -MMD -MP -MF $(DEPSDIR)/$*.d -x assembler-with-cpp -mthumb -mthumb-interwork $(ASFLAGS) -c $< -o $@

#---------------------------------------------------------------------------------
# canned command sequence for binary data
#---------------------------------------------------------------------------------
define bin2o
   bin2s $< | $(AS) $(ARCH) -o $(@)
   echo "extern const u8" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"_end[];" > `(echo $(<F) | tr . _)`.h
   echo "extern const u8" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"[];" >> `(echo $(<F) | tr . _)`.h
   echo "extern const u32" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(<F) | tr . _)`.h
endef

#107459 - gmiller - Sun Oct 29, 2006 8:46 pm

Just an added comment on project structure that the projects that I use these projects assume.

all files to be compiled are in the "source" folder in the project, as soon as you put a file there is will be compiled and linked. Any file that does not have ".arm." , ".iwram." or ".itcm." at the end of the file name prior to the extention will be compiled in THUMB mode and the files with these will be compiled in ARM mode. Since your GBA interrupt function needs to be in ARM code to staart out with I put my interrupt handler in "intr.arm.c" so that the code generated will be in ARM mode. Most of this was already in the makefile and I just added "echo" commands to help me confirm the rule I was using.

the header files are in the include folder or the project folder.

the object files will be created in the build folder along with the generated aassembly files (-save-temps) so I can examine what the compiler did.

I am sure I have missed something but these have worked for all of the stuff I have done so far.

#107497 - Ant6n - Mon Oct 30, 2006 7:27 am

Your way of working with makefiles is quite interesting. I should look into that further. Especially the naming conventions that relate to linking options (iwram, arm), the possibility to have different options when debugging (-o0) and the use of multiple directories.
....But you dont seem to have different options for .S files than I do, so I really wonder whats going wrong. I compiled my code in vham again and it works. I could write everything using inline assembler, but that seems messy to me - esp., because i dont know what happens if one compiles a c file in thumb mode that has arm inline asm.

anton

#107514 - gmiller - Mon Oct 30, 2006 1:03 pm

The default option for the compilers is THUMB mode and it also appears that way for the assembler. Mixing the code in the same assembly file has not worked for me even with what I thought was the appropriate assembly directives. If the code is "somehow" in the wrong mode then the instructions executed will not be those you specify because the number of bytes for an instruction will be wrong. Calling THUMB mode from ARM or calling ARM from THUMB is doable. With the compiler use the -mthumb-interwork to have the mode switch back and forth. If it works in VHAM then maybe the order of your command line options is different. I have found at times that the order matters but I have no specific rules that I know of. I have found that the -marm or -mthunb needs to be early on the command line for things to work the way I wanted. This is not something I found in a document just through experimentation so there could be some other issues here.

#107670 - Ant6n - Wed Nov 01, 2006 1:30 am

This sounds really odd. I poked around in the forum a little, and it seems that you had probs with the devkitpro options before.

I tried to consult TONC, but his tutorial (http://user.chem.tue.nl/jakvijn/tonc/toncmake.htm) is officially out of date since 2004. the devkitpro website doesnt seem to have any documentation, nor does the software package itself (only examples). All people who seem to have a clue on how this works seem to have moved to NDS development..

Can anybody direct me to a recent tutorial or documentation regarding the interworking arm and thumb options that would enable me to generate projects that uses both arm and thumb in both asm and c - with a recent version of devkitarm??

thank you very much

Anton

#107679 - tepples - Wed Nov 01, 2006 3:24 am

LOCKJAW: The Overdose (TOD) has ARM assembly, Thumb assembly, ARM C, Thumb C, and x86 C, all in one project. Unlike previous versions, TOD M4 is compiled with devkitARM r19b. You might want to inspect its makefile.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#107698 - Ant6n - Wed Nov 01, 2006 7:04 am

thank you for the hint (quite a cool game you made there ;0). i further played around with the makefiles \quite some time again, and came up with this

MODEL := -mthumb-interwork -marm
SPECS := -specs=gba.specs

ASFLAGS := -mthumb-interwork -Wall
CFLAGS := -I./ $(MODEL) -O2 -mthumb -Wall
LDFLAGS := $(SPECS) $(MODEL)

but i define the function that made vba crash - the agbprint - as

/* agbprint */
extern void agbprint(char *s) __attribute__ ((section (".iwram"), long_call));

The odd thing is that main.c is thumb, and agbprint is arm, and the debugger manages to reach that agbprint and switch to arm, but when jumping back it doesnt seem to switch back to thumb again.
I am tempted to compile everything in arm for now.
Is this a feature, or something that can be fixed?

Anton

here the agbprint function
Code:
   .SECTION    .iwram,"ax",%progbits
    .ALIGN
    .ARM
    .GLOBAL     agbprint

agbprint:
    swi 0xff0000   @ r0 is the argument, and its already there
    mov pc, lr      @ branch return

    .ALIGN
    .POOL

#107702 - Cearn - Wed Nov 01, 2006 9:27 am

Use 'bx lr' instead of 'mov pc, lr'. mov can't switch states. Or you could do the whole thing in thumb code:

Code:
@ void agbprint(const char *string);
    .text
    .align
    .thumb_func
    .global agbprint
agbprint:
    swi     0xFF
    bx      lr


EDIT:
Ant6n wrote:
I tried to consult TONC, but his tutorial (http://user.chem.tue.nl/jakvijn/tonc/toncmake.htm) is officially out of date since 2004.
That should have read 20060428, not 20040428. ^_^;;

Last edited by Cearn on Wed Nov 01, 2006 10:29 am; edited 1 time in total

#107703 - wintermute - Wed Nov 01, 2006 9:36 am

Code:

   .SECTION    .iwram,"ax",%progbits
    .ALIGN
    .ARM
    .GLOBAL     agbprint
    .arm_func
agbprint:
    swi 0xff0000   @ r0 is the argument, and its already there
    bx lr      @ return and switch mode if necessary

    .ALIGN
    .POOL


does this function need to be in either ARM or in iwram? Seems a bit wasteful to me really.

Code:

static inline void agbprint( const char *string) {
   #if   defined   ( __thumb__ )
      __asm ("mov r0,%0\n\tSWI   0xff\n" ::  "=r"(string) : "r1", "r2", "r3");
   #else
      __asm ("mov r0,%0\n\tSWI   0xff<<16\n" :: "=r"(string) : "r1", "r2", "r3");
   #endif
}



Off the top of my head and not tested but you should get the idea. I'd need to go check the inline assembly syntax to be absolutely certain as well.

The mov r0,%0 moves the parameter to r0 which may seem a little wasteful but gcc can use any spare registers it likes for inline functions - the optimiser should remove unnecessary code if it's already in r0.

You can also do it the way Cearn suggests - he's posted while I was editing this :P
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog

#107720 - gmiller - Wed Nov 01, 2006 3:41 pm

Ant6n wrote:
This sounds really odd. I poked around in the forum a little, and it seems that you had probs with the devkitpro options before.

I tried to consult TONC, but his tutorial (http://user.chem.tue.nl/jakvijn/tonc/toncmake.htm) is officially out of date since 2004. the devkitpro website doesnt seem to have any documentation, nor does the software package itself (only examples). All people who seem to have a clue on how this works seem to have moved to NDS development..

Can anybody direct me to a recent tutorial or documentation regarding the interworking arm and thumb options that would enable me to generate projects that uses both arm and thumb in both asm and c - with a recent version of devkitarm??

thank you very much

Anton


Yep, I did have problems when mixing ARM and THUMB if I forced the ARM code into IWRAM. The issue there was needing to do "long calls" because of the offsets between the code. It is still something I want to automate in my make files. One of the issues with creating a global CFLAGS value is that when mixing code models it does not apply to every file.

I am considering adding things like "long-calls" to files that have ".iwram.c(pp)" at the end in my standard make files.

#107722 - Ant6n - Wed Nov 01, 2006 3:53 pm

So from here i see i have to keep in mind
- to use bx for jump return so that it works with interwork
- the subtleties of long calls

I have been looking for something to enable me to write inline assembler macros that support both arm and thumb (mostly for fixed point math, but also stuff like agbprint).

so thank you all

Anton