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.

C/C++ > MidiKey2Freq and devkitpro

#118459 - nuvalo - Tue Feb 13, 2007 5:03 pm

Hello, i?m still new programming and using devkitpro for gba programs. I was interested in using the libfat, and i found a piece of code that uses the libfat and dumps the gba Bios to a file.

The matter is that it uses a function named "MidiKey2Freq", but it doesn?t know how to link with it. It says : undefined reference to `MidiKey2Freq'

This is the code that i?m using:


Code:

/*---------------------------------------------------------------------------------

Some emulators need the bios from your gba in order to use SWI calls

This little piece of code will read the bios and save it to your
SD/CF card device using the magic of libfat.

Some cards are supported be default, the binary will need patched with
the appropriate DLDI file for newer cards.

---------------------------------------------------------------------------------*/


#include <gba.h>
#include <fat.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <gba_sound.h>

//---------------------------------------------------------------------------------
void waitForever() {
//---------------------------------------------------------------------------------
while (1)
VBlankIntrWait();
}

//---------------------------------------------------------------------------------
// Program entry point
//---------------------------------------------------------------------------------
int main(void) {
//---------------------------------------------------------------------------------


// the vblank interrupt must be enabled for VBlankIntrWait() to work
// since the default dispatcher handles the bios flags no vblank handler
// is required
irqInit();
irqEnable(IRQ_VBLANK);

// initialise the console
// setting NULL & 0 for the font address & size uses the default font
// The font should be a complete 1bit 8x8 ASCII font
consoleInit( 0, // charbase
4, // mapbase
0, // background number
NULL, // font
0, // font size
15 // 16 color palette
);

// RGB8 generates a 16 bit palette entry from 3 8bit components
BG_COLORS[0]=RGB8(58,110,165);

// RGB5 generates a 16 bit palette entry from 3 5bit components
BG_COLORS[241]=RGB5(31,31,31);

SetMode(MODE_0 | BG0_ON);

iprintf("GBA Bios Dumper\n\n");

if (fatInitDefault()) {
iprintf("FAT system initialised\n");
} else {
iprintf("FAT system failed!\n");
waitForever();
}

u32 *bios = (u32 *)malloc(0x4000);

if ( bios ) {
iprintf("Memory allocated\n");
} else {
iprintf("Memory allocation failure!\n");
waitForever();
}

int i;

iprintf("dumping ");

for (i=0; i<0x4000; i+=4)
{
// The MidiKey2Freq bios call allows us to read from bios
// the lower bits are inaccurate, so just get it four times :)
u32 a = MidiKey2Freq((WaveData *)(i-4), 180-12, 0) * 2;
u32 b = MidiKey2Freq((WaveData *)(i-3), 180-12, 0) * 2;
u32 c = MidiKey2Freq((WaveData *)(i-2), 180-12, 0) * 2;
u32 d = MidiKey2Freq((WaveData *)(i-1), 180-12, 0) * 2;

// rebuild a 32bit word from the 4 words we read
u32 abcd = ( a & 0xff000000 ) |
( d & 0xff000000 ) >> 8 |
( c & 0xff000000 ) >> 16 |
( b & 0xff000000 ) >> 24;
bios[i/4] = abcd;

//print a dot every 256 bytes
if ( (i & 0xff) == 0 ) iprintf(".");

}

iprintf("\nBios dumped, saving file\n");

FILE *biosFile = fopen("biosgba.rom","wb");
if (biosFile ) {
fwrite(bios,16384,1,biosFile);
fclose(biosFile);
iprintf("bios saved!");
} else {
iprintf("file creation failed!");
}

waitForever();

return 0;
}




and this is the makefile:

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 generates a multiboot image
# BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code
# INCLUDES is a list of directories containing extra header files
#---------------------------------------------------------------------------------
TARGET      :=   biosDumper
BUILD      :=   build
SOURCES      :=   source font
INCLUDES   :=

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

CFLAGS   :=   -g -Wall -O3\
         -mcpu=arm7tdmi -mtune=arm7tdmi\
          -fomit-frame-pointer\
         -ffast-math \
         $(ARCH)

CFLAGS   +=   $(INCLUDE)

ASFLAGS   :=   $(ARCH)
LDFLAGS   =   -g $(ARCH) -Wl,-Map,$(notdir $@).map -L/c/devkitPro/libgba/lib

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

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

#---------------------------------------------------------------------------------
# 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))
export PATH   :=   $(DEVKITARM)/bin:$(PATH)
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,$(SOURCES),$(notdir $(wildcard $(dir)/*.bin)))

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

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

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

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

.PHONY: $(BUILD) clean

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

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

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

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

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

$(OUTPUT).elf   :   $(OFILES) $(LIBGBA)/lib/libgba.a

%.o   :   %.bin
   @echo   $(notdir $<)
   @$(bin2o)

-include $(DEPENDS)

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


If someone can help me would be good.

Thanks

#118460 - kusma - Tue Feb 13, 2007 5:13 pm

you define $(LIBS) as "-lgba -lfat", but I cant see any usage of that variable.

edit: to be a bit clearer:
try adding:

LDFLAGS += $(LIBS)

at some point before your .elf-rule

#118603 - nuvalo - Wed Feb 14, 2007 3:22 pm

It is used here

Code:
include $(DEVKITARM)/gba_rules


it uses the arm-eabi-gcc to link and create the ".elf" file. I tried with "arm-eabi-ld" to link, but it says that it cant create a thumb. This is the compilation result:

arm-eabi-gcc -MMD -MP -MF /c/devkitPro/examples/gba/libfat/build/biosDumper.d -g -Wall -O3 -mcpu=arm7tdmi -mtune=arm7tdmi -fomit-frame-pointer -ffast-math -mthumb -mthumb-interwork -I/c/devkitPro/libgba/include -I/c/devkitPro/examples/gba/libfat/build -c /c/devkitPro/examples/gba/libfat/source/biosDumper.c -o biosDumper.o


arm-eabi-gcc -g -mthumb -mthumb-interwork -Wl,-Map,biosDumper.elf.map -L/c/devkitPro/libgba/lib -specs=gba.specs biosDumper.o -L/c/devkitPro/libgba/lib -lgba -lfat -o /c/devkitPro/examples/gba/libfat/biosDumper.elf

c:/devkitPro/examples/gba/libfat/source/biosDumper.c:87: undefined reference to `MidiKey2Freq'
c:/devkitPro/examples/gba/libfat/source/biosDumper.c:88: undefined reference to `MidiKey2Freq'
c:/devkitPro/examples/gba/libfat/source/biosDumper.c:89: undefined reference to `MidiKey2Freq'
c:/devkitPro/examples/gba/libfat/source/biosDumper.c:90: undefined reference to `MidiKey2Freq'
collect2: ld returned 1 exit status
make[1]: *** [/c/devkitPro/examples/gba/libfat/biosDumper.elf] Error 1
"make": *** [build] Error 2

> Process Exit Code: 2
> Time Taken: 00:01


Anyone knows why this dont works? Other question, works libfat on the Visual boy advance emulator?

thanks


[/code]