I've got DevKitPro working on Game Boy Advance, but I've run into a few problems. The biggest one I see is that my code is assembled at 0x00000000
instead of the normal 0x08000000
for ROM cartridges. My understanding is that C compilers don't use an .org
directive to create the code at a specified memory location; rather the linker is supposed to take care of all that for me. But it seems to be placing the code at the "wrong" address. The game will run correctly, but I imagine this is because it's running on an emulator and the emulator doesn't care that it's located somewhere it shouldn't be. How do I get the code to be "assembled" at 0x08000000
?
I'm new to the concept of makefiles, compilers, linkers, etc. so I probably have everything set up very poorly. I'll show my makefile, batch script that runs the makefile, and the C code that's being compiled. I've also included the objdump in case that's relevant.
C code:
// LIBGBA HEADERS
#include <gba_console.h>
#include <gba_video.h>
#include <gba_interrupt.h>
#include <gba_systemcalls.h>
#include <gba_input.h>
#include <stdio.h>
#include <stdlib.h>
// GAME-SPECIFIC INCLUDES
#include "M:\SrcGBA\PaintBoyAdvance\include\bitmap.h"
#include "M:\SrcGBA\PaintBoyAdvance\include\bitmap.c" //BITMAP SCREEN FUNCTIONS
//---------------------------------------------------------------------------------
// 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);
// consoleDemoInit();
REG_DISPCNT = 0x1403;
while (1) {
VBlankIntrWait();
}
}
Batch script:
@echo off
set path=C:\devkitPro\;%path%
cd M:\SrcGBA\PaintBoyAdvance
make
if not "%errorlevel%"=="0" goto Abandon
C:\devkitPro\devkitARM\bin\arm-none-eabi-objdump -h M:\SrcGBA\PaintBoyAdvance\build\paintboyadvance.o
C:\Users\puppy\Documents\VisualBoyAdvance\visualboyadvance-m.exe M:\SrcGBA\PaintBoyAdvance\PaintBoyAdvance.gba
:Abandon
exit
Makefile:
#---------------------------------------------------------------------------------
.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
# 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
# DATA is a list of directories containing binary data
# GRAPHICS is a list of directories containing files to be processed by grit
#
# All directories are specified relative to the project directory where
# the makefile is found
#
#---------------------------------------------------------------------------------
TARGET := $(notdir $(CURDIR))
BUILD := build
SOURCES := source
INCLUDES := include
DATA := data
MUSIC :=
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
ARCH := -mthumb -mthumb-interwork
SPECS := -specs=gba.specs
CFLAGS := -g -Wall -O2\
-mcpu=arm7tdmi -mtune=arm7tdmi\
-ffreestanding \
$(ARCH)
CFLAGS := $(INCLUDE)
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
ASFLAGS := -g $(ARCH)
LDFLAGS = -g $(ARCH) $(INCLUDE) -Wl,-Map,$(notdir $@.map)
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project
#---------------------------------------------------------------------------------
LIBS := -lmm -lgba
#---------------------------------------------------------------------------------
# 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)) \
$(foreach dir,$(GRAPHICS),$(CURDIR)/$(dir))
export DEPSDIR := $(CURDIR)/$(BUILD)
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)/*.*)))
ifneq ($(strip $(MUSIC)),)
export AUDIOFILES := $(foreach dir,$(notdir $(wildcard $(MUSIC)/*.*)),$(CURDIR)/$(MUSIC)/$(dir))
BINFILES += soundbank.bin
endif
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
#---------------------------------------------------------------------------------
export LD := $(CC)
#---------------------------------------------------------------------------------
else
#---------------------------------------------------------------------------------
export LD := $(CXX)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
export OFILES_SOURCES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
export OFILES := $(OFILES_BIN) $(OFILES_SOURCES)
export HFILES := $(addsuffix .h,$(subst .,_,$(BINFILES)))
export INCLUDE := $(foreach dir,$(INCLUDES),-iquote $(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
-I$(CURDIR)/$(BUILD)
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
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
$(OUTPUT).gba : $(OUTPUT).elf
$(OUTPUT).elf : $(OFILES)
$(OFILES_SOURCES) : $(HFILES)
#---------------------------------------------------------------------------------
# The bin2o rule should be copied and modified
# for each extension used in the data directories
#---------------------------------------------------------------------------------
#---------------------------------------------------------------------------------
# rule to build soundbank from music files
#---------------------------------------------------------------------------------
soundbank.bin soundbank.h : $(AUDIOFILES)
#---------------------------------------------------------------------------------
@mmutil $^ -osoundbank.bin -hsoundbank.h
#---------------------------------------------------------------------------------
# This rule links in binary data with the .bin extension
#---------------------------------------------------------------------------------
%.bin.o %_bin.h : %.bin
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(bin2o)
-include $(DEPSDIR)/*.d
#---------------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------------
Output of object dump:
M:\SrcGBA\PaintBoyAdvance\build\paintboyadvance.o: file format elf32-littlearm
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000268 00000000 00000000 00000034 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
1 .data 00000000 00000000 00000000 0000029c 2**0
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000000 00000000 00000000 0000029c 2**0
ALLOC
3 .comment 00000024 00000000 00000000 0000029c 2**0
CONTENTS, READONLY
4 .ARM.attributes 0000002a 00000000 00000000 000002c0 2**0
CONTENTS, READONLY
EDIT: As requested here is the output of the batch file:
\SrcGBA\PaintBoyAdvance\compile.bat paintboyadvance.c M:\SrcGBA\PaintBoyAdvance\source nopause
Process started >>>
paintboyadvance.c
linking cartridge
built ... PaintBoyAdvance.gba
ROM fixed!
M:\SrcGBA\PaintBoyAdvance\build\paintboyadvance.o: file format elf32-littlearm
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000280 00000000 00000000 00000034 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
1 .data 00000000 00000000 00000000 000002b4 2**0
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000000 00000000 00000000 000002b4 2**0
ALLOC
3 .comment 00000024 00000000 00000000 000002b4 2**0
CONTENTS, READONLY
4 .ARM.attributes 0000002a 00000000 00000000 000002d8 2**0
CONTENTS, READONLY