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.

DS development > Chishm's DLDI loader in PALib [how to]

#141433 - spinal_cord - Tue Sep 25, 2007 12:35 pm

First of all, this way worked for me, I can not guarantee it will work for other people.

Getting Chishm's DLDI loader to work with PALib.

1. Copy the load.bin to your Data folder.
2. Copy nds_loader_arm9.c and nds_loader_arm9.h to you your source folder.
3. Add the following line to your main.c
Code:
#include "nds_loader_arm9.h"

4. Navigate to the PALib arm7 folder (C:\devkitPro\PAlib\lib\arm7). Copy nds_loader_arm7.c and nds_loader_arm7.h to C:\devkitPro\PAlib\lib\arm7\
5. Add the following line to the main.c
Code:
#include "nds_loader_arm7.h"

6. Find the following line,
Code:
void PA_VBL(void)
, and place the collowing line after it.
Code:
runNdsLoaderCheck();

7. Re-compile PALib by running C:\devkitPro\PAlib\fastbuild.bat
8. Back in your project folder, replace the makefile with the following one modified by Jayenkai to handle the load.bin file forrectly.
Code:

PROGNAME = PAlib
OFILES   +=
ADD_LIBS +=

PATH       := $(DEVKITARM)/bin:$(PATH)

ARM7BIN      := -7 $(PAPATH)/lib/arm7/arm7.bin
TEXT1       := SPinal's MENU
TEXT2       := using PAlib!
TEXT3       := spinal.dizidesigns.co.uk
ICON       := -b $(CURDIR)/../logo.bmp
LOGO      := -o $(CURDIR)/../logo_wifi.bmp

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


include $(DEVKITARM)/ds_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   :=   $(shell basename $(CURDIR))
BUILD      :=   build
SOURCES   :=   gfx source
INCLUDES   :=   include build
DATA      :=   data

EXPORT_DIR := /c/ndsexamples/
#---------------------------------------------------------------------------------
# ARM7BIN is the path to an arm7 binary other than the default
#   usage: ARM7BIN := -7 binaryName.bin
#
# ICON is the path to an icon to be used int the header plus text
#   usage: ICON := -t iconName.bmp "text line one; text line 2; text line 3"
#
#---------------------------------------------------------------------------------



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

# note: arm9tdmi isn't the correct CPU arch, but anything newer and LD
# *insists* it has a FPU or VFP, and it won't take no for an answer!
CFLAGS   :=   -g  -Wformat=2 -Winline -Wall -O2\

       -mcpu=arm946e-s -mtune=arm946e-s -fomit-frame-pointer\
      -ffast-math \
      $(ARCH)

CFLAGS   +=   $(INCLUDE) -DARM9 -I$(DEVKITPRO)/PAlib/include/nds

ASFLAGS   :=   -g $(ARCH)
LDFLAGS   :=   -g $(ARCH) -mno-fpu -L$(DEVKITPRO)/PAlib/lib


#---------------------------------------------------------------------------------
# path to tools - this can be deleted if you set the path in windows
#---------------------------------------------------------------------------------
# export PATH      :=   /d/dev/ds/devkitARM_r11/bin:/bin
 
#---------------------------------------------------------------------------------
# PATH to ndslib - just make a system variable called NDSLIBPATH and be done with it
#---------------------------------------------------------------------------------
# NDSLIBPATH   :=   /d/dev/ds/ndslib/
 
#---------------------------------------------------------------------------------
# the prefix on the compiler executables
#---------------------------------------------------------------------------------
PREFIX         :=   arm-eabi-
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project
#---------------------------------------------------------------------------------
LIBS   := -lfat -lnds9 -ldswifi9
LIBSPA   := -lpa9
 
 
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS   :=   $(DEVKITPRO)/libnds
LIBDIRPA   :=   $(PAPATH)
 
 
#---------------------------------------------------------------------------------
# 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 CC      :=   $(PREFIX)gcc
export CXX      :=   $(PREFIX)g++
export AR      :=   $(PREFIX)ar
export OBJCOPY   :=   $(PREFIX)objcopy

#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
export LD      :=   $(CXX)
#export LD      :=   $(CC)
 

CFILES      :=   $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES   :=   $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
SFILES      :=   $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
PCXFILES   :=   $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.pcx)))
PALFILES   :=   $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.pal)))
RAWFILES   :=   $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.raw)))
MAPFILES   :=   $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.map)))
JPEGFILES   :=   $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.jpg)))
MODFILES   :=   $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.mod)))
GIFFILES   :=   $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.gif)))
BMPFILES   :=   $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.bmp)))
BINFILES   :=   $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))

 
export OFILES   :=   $(addsuffix .o,$(BINFILES)) \
               $(MAPFILES:.map=.o) $(RAWFILES:.raw=.o) $(PALFILES:.pal=.o) $(PCXFILES:.pcx=.o) $(JPEGFILES:.jpg=.o) $(MODFILES:.mod=.o) $(GIFFILES:.gif=.o) $(BMPFILES:.bmp=.o)\
               $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
 
export INCLUDE   :=   $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
               $(foreach dir,$(LIBDIRS),-I$(dir)/include) \
               $(foreach dir,$(LIBDIRS),-I$(dir)/include/nds) \
               -I$(PAPATH)/include/nds\
               -I$(CURDIR)/$(BUILD)
 
export LIBPATHS   :=   $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
export LIBPATHPA   :=   $(foreach dir,$(LIBDIRPA),-L$(dir)/lib)
 
.PHONY: $(BUILD) clean export
 
#---------------------------------------------------------------------------------
$(BUILD):
   @[ -d $@ ] || mkdir -p $@
   @make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
 
#---------------------------------------------------------------------------------
clean:
   @echo clean ...$(TARGET)
   @rm -fr $(BUILD) *.elf *.*ds*
 
export:
   @echo exporting ...$(TARGET)
   @cp *.nds $(EXPORT_DIR)/$(TARGET).nds

#---------------------------------------------------------------------------------
else
 
DEPENDS   :=   $(OFILES:.o=.d)
 
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
$(OUTPUT).ds.gba   :    $(OUTPUT).nds

$(OUTPUT).nds   :    $(OUTPUT).bin

$(OUTPUT).bin   :   $(OUTPUT).elf
 
$(OUTPUT).elf   :   $(OFILES)


 
#---------------------------------------------------------------------------------
%.ds.gba: %.nds
   @echo built ... $(notdir $@)
   @dsbuild $<
   @cp $(CURDIR)/../$(notdir $@) ../$(notdir $(OUTPUT)).sc.nds

#---------------------------------------------------------------------------------
%.nds: %.bin
   
   @ndstool -c $@ -9 $(TARGET).bin $(ARM7BIN) $(LOGO) $(ICON) "$(TEXT1);$(TEXT2);$(TEXT3)"


#---------------------------------------------------------------------------------
%.bin: %.elf
   
   @$(OBJCOPY) -O binary $(TARGET).elf $(TARGET).bin
 
#---------------------------------------------------------------------------------
%.elf:
   @echo $(LD)  $(LDFLAGS) -specs=ds_arm9.specs $(OFILES) $(LIBPATHPA) $(LIBSPA) $(LIBPATHS) $(LIBS) -o $(TARGET).elf
   @$(LD)  $(LDFLAGS) -specs=ds_arm9.specs $(OFILES) $(LIBPATHPA) $(LIBSPA) $(LIBPATHS) $(LIBS) -o $(TARGET).elf
 
 
 
#---------------------------------------------------------------------------------
# Compile Targets for C/C++
#---------------------------------------------------------------------------------
 

 
#---------------------------------------------------------------------------------
%.o : %.cpp
   @echo $(notdir $<)
   @$(CXX) -MM $(CFLAGS) -o $*.d $<
   @$(CXX) $(CFLAGS) -c $< -o$@
 
#---------------------------------------------------------------------------------
%.o : %.c
   @echo $(notdir $<)
   @$(CC) -MM $(CFLAGS) -o $*.d $<
   @$(CC)  $(CFLAGS) -c $< -o$@
 
#---------------------------------------------------------------------------------
%.o : %.s
   @echo $(notdir $<)
   @$(CC) -MM $(CFLAGS) -o $*.d $<
   @$(CC)  $(ASFLAGS) -c $< -o$@

 

 
define bin2o_PA
   cp $(<) $(*).tmp
   echo -n $$(( `cat $(*).tmp | wc -c` & 3 )) | sed -e 's/0//g' | sed -e 's/1/000/g' | sed -e 's/2/00/g' | sed -e 's/3/0/g' >> $(*).tmp
   $(OBJCOPY) -I binary -O elf32-littlearm -B arm \
   --rename-section .data=.rodata \
   --redefine-sym _binary_$*_tmp_start=$*\
   --redefine-sym _binary_$*_tmp_end=$*_end\
   --redefine-sym _binary_$*_tmp_size=$*_size\
   $(*).tmp $(@)      
   echo "extern const u8" $(*)"[];" > $(*).h
   echo "extern const u32" $(*)_size[]";" >> $(*).h
   rm $(*).tmp
endef
 
#---------------------------------------------------------------------------------
%.o   :   %.pcx
#---------------------------------------------------------------------------------
   @echo $(notdir $<)
   @$(bin2o_PA)

#---------------------------------------------------------------------------------
%.o   :   %.raw
#---------------------------------------------------------------------------------
   @echo $(notdir $<)
   @$(bin2o_PA)
 
#---------------------------------------------------------------------------------
%.bin.o   :   %.bin
#---------------------------------------------------------------------------------
   @echo $(notdir $<)
   @$(bin2o)
   #  Jayenkai kicks ass!!!!
   #  and Spinal rules!
 
#---------------------------------------------------------------------------------
%.o   :   %.pal
#---------------------------------------------------------------------------------
   @echo $(notdir $<)
   @$(bin2o_PA)
 
#---------------------------------------------------------------------------------
%.o   :   %.map
#---------------------------------------------------------------------------------
   @echo $(notdir $<)
   @$(bin2o_PA)

#---------------------------------------------------------------------------------
%.o   :   %.mdl
#---------------------------------------------------------------------------------
   @echo $(notdir $<)
   @$(bin2o_PA)

#---------------------------------------------------------------------------------
%.o   :   %.jpg
#---------------------------------------------------------------------------------
   @echo $(notdir $<)
   @$(bin2o_PA)

#---------------------------------------------------------------------------------
%.o   :   %.mod
#---------------------------------------------------------------------------------
   @echo $(notdir $<)
   @$(bin2o_PA)

#---------------------------------------------------------------------------------
%.o   :   %.gif
#---------------------------------------------------------------------------------
   @echo $(notdir $<)
   @$(bin2o_PA)

#---------------------------------------------------------------------------------
%.o   :   %.bmp
#---------------------------------------------------------------------------------
   @echo $(notdir $<)
   @$(bin2o_PA)

 
-include $(DEPENDS)
#---------------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------------


10. To load a .nds in your code, just use following line.
Code:
runNdsFile ("filename.nds");


Hope that helps some people.
_________________
I'm not a boring person, it's just that boring things keep happening to me.
Homepage

#142197 - tondopie - Sat Oct 06, 2007 1:00 am

I just tried to test it out but...

Code:
Makefile:153: *** missing separator.  Stop.


EDIT: You must replace the indent spaces with TABs!

#142207 - spinal_cord - Sat Oct 06, 2007 2:03 pm

It works fine for me, I copied it directly from the makefile i'm using.
_________________
I'm not a boring person, it's just that boring things keep happening to me.
Homepage

#142246 - tondopie - Sat Oct 06, 2007 9:12 pm

its still not working for me, I think it might be because I'm not loading from the root...

#142827 - calcprogrammer1 - Sun Oct 14, 2007 5:33 am

Compiling gives me this error:

Makefile(152): *** missing separator. Stop.

Around line 152 is this:
Code:
#---------------------------------------------------------------------------------
$(BUILD):
   @[ -d $@ ] || mkdir -p $@  //Line 152, gives error
   @make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
 
#---------------------------------------------------------------------------------


What am I doing wrong?

EDIT: found about the tabs thing...but that's a LOT of tabs...

Why didn't you just post a link to the makefile? Now I got to replace a LOT of tabs...
...
...

Now it gives me
Code:
make[1]: *** No rule to make target `copy.bmp.o', needed by `/c/devkitPro/Projects/DSFile2/DSFile2/DSFile2.elf'.  Stop.
make: *** [build] Error 2

_________________
DS Firmware 1, Datel Games n' Music card / Chism's FW hacked GBA MP v2 CF

There's no place like 127.0.0.1.

#142833 - spinal_cord - Sun Oct 14, 2007 10:39 am

OK, here is my exact makefile, just remove the .txt extention.

http://www.geocities.com/spinal_cord/makefile.txt
_________________
I'm not a boring person, it's just that boring things keep happening to me.
Homepage

#142849 - tondopie - Sun Oct 14, 2007 4:33 pm

calcprogrammer1 wrote:
Compiling gives me this error:

Makefile(152): *** missing separator. Stop.

Around line 152 is this:
Code:
#---------------------------------------------------------------------------------
$(BUILD):
   @[ -d $@ ] || mkdir -p $@  //Line 152, gives error
   @make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
 
#---------------------------------------------------------------------------------


What am I doing wrong?

EDIT: found about the tabs thing...but that's a LOT of tabs...

Why didn't you just post a link to the makefile? Now I got to replace a LOT of tabs...
...
...

Now it gives me
Code:
make[1]: *** No rule to make target `copy.bmp.o', needed by `/c/devkitPro/Projects/DSFile2/DSFile2/DSFile2.elf'.  Stop.
make: *** [build] Error 2


in the future just replace 8 spaces with TABs and and put a .bmp before the .o in the makefile for what ever extension you have.

#142864 - calcprogrammer1 - Sun Oct 14, 2007 7:12 pm

Finally got DSFile to boot .nds from whatever it's patched for!

Now, is there a way to append the GBAMP's DLDI patch into the .nds itself? I'd like to be able to boot from GBAMP using it, but I don't know how you would put the GBAMP's DLDI patch into the .nds and then call it using runNds(). Does anyone have any info on how that would work?
_________________
DS Firmware 1, Datel Games n' Music card / Chism's FW hacked GBA MP v2 CF

There's no place like 127.0.0.1.

#142871 - spinal_cord - Sun Oct 14, 2007 8:19 pm

I thought gbamp didnt need dldi?
_________________
I'm not a boring person, it's just that boring things keep happening to me.
Homepage

#142873 - calcprogrammer1 - Sun Oct 14, 2007 8:22 pm

Chishm said (and my tests prove) that the loader (not libfat) requires a DLDI patch for every device. Libfat works without it but the loader needs the DLDI. I'd eventually like to include DLDI's for all libfat supported devices in the .nds itself, but I have no clue how to do this or if it's even possible.

It would be really cool if working DLDI's for all devices could be put into one .nds and have a loader that works on any combination of devices...but that'd probably be really hard.
_________________
DS Firmware 1, Datel Games n' Music card / Chism's FW hacked GBA MP v2 CF

There's no place like 127.0.0.1.

#142883 - tondopie - Sun Oct 14, 2007 8:45 pm

if you were just doing GBAMP here, just check with fat if the device in SLot-2 was a GBAMP then use the GBAMP .nds loading method. You can then also use a different method for SC and a different for method for M3. Those are the only cards with known internal loaders.

#142887 - calcprogrammer1 - Sun Oct 14, 2007 8:58 pm

How exactly do you check if the device is a GBAMP? I've wanted to know this but I can't find any information on how to check what device is inserted.
_________________
DS Firmware 1, Datel Games n' Music card / Chism's FW hacked GBA MP v2 CF

There's no place like 127.0.0.1.

#142890 - tondopie - Sun Oct 14, 2007 9:14 pm

Code:
switch(DiscType())

   {

      case 0x4643504D: // gbamp

      {
                   function();
                }
        }



something similar to that. There's a function in libfat to detect the disctype.

#142891 - spinal_cord - Sun Oct 14, 2007 9:14 pm

There is a post on the forum already about detecting wich flshcard is being used.
detecting flashcard

I used it to use the gbamp loader instead of the dldi one if your using a gbamp. Like this...

Code:

fatInitDefault();
struct stat st;
stat("/.", &st);
int device_id = st.st_dev;

if(device_id==1178816589)
         {
            // Is GBAMP
         }

_________________
I'm not a boring person, it's just that boring things keep happening to me.
Homepage

#142896 - calcprogrammer1 - Sun Oct 14, 2007 10:03 pm

Thanks for that code, I wrote a little program to show the device ID of both slots (download here). It says:

Games n' Music is 1179929927
GBAMP V2 CF is 1178816589

How hard is it to implement the GBAMP loader (and the SCCF, M3CF loaders eventually) in PAlib? I'll try adding support for those later.
_________________
DS Firmware 1, Datel Games n' Music card / Chism's FW hacked GBA MP v2 CF

There's no place like 127.0.0.1.

#142897 - tepples - Sun Oct 14, 2007 10:06 pm

calcprogrammer1 wrote:
I wrote a little program to show the device ID of both slots (download here). It says:

Games n' Music is 1179929927
GBAMP V2 CF is 1178816589

Convert to hexadecimal notation:
GNM is 46544D47
GBAMP is 4643504D

Convert ASCII codes to characters, reading right to left because the GBA CPU is little endian:
GNM is "GMTF"
GBAMP is "MPCF"
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#142900 - spinal_cord - Sun Oct 14, 2007 10:10 pm

our friend tondopie (aka teendev) posted a tut on palib forum.
here it is

basically you use the following instead of the dldi code.

Code:

void bootGBAMPnds(void) {      
      
      REG_EXEMEMCNT &= ~(0x8080);
 
             
 
       FILE *handle = fopen("filename.nds", "rb");
       if(handle < 0) {
          iprintf("\nLoader has failed!\n");
       }
       //u32 fileCluster = GetFileCluster();

      struct stat st;
      u32 cluster;

      stat("/filename.nds", &st);

      cluster = st.st_ino;
       
      fclose(handle);
 
       REG_EXEMEMCNT |= (0x8080);
 
       REG_IME = IME_DISABLE;   // Disable interrupts
       REG_EXEMEMCNT |= (0x8080);  // ARM7 has access to GBA cart
       *((vu32*)0x027FFFFC) = cluster;  // Start cluster of NDS to load
       *((vu32*)0x027FFE04) = (u32)0xE59FF018;  // ldr pc, 0x027FFE24
       *((vu32*)0x027FFE24) = (u32)0x027FFE04;  // Set ARM9 Loop address
       swiSoftReset();  // Reset
}


[edit] Any ideas how I can empty as much memory as possible before attempting to load a .nds?
_________________
I'm not a boring person, it's just that boring things keep happening to me.
Homepage

#142915 - tondopie - Mon Oct 15, 2007 1:10 am

look in the DSO or moonshell source. There are a few files about reseting memory. They use inline ASM for the most part.


calcprogrammer1 wrote:

How hard is it to implement the GBAMP loader (and the SCCF, M3CF loaders eventually) in PAlib? I'll try adding support for those later.


The SCCF and M3CF ones are a little more difficult as you have to unlock RAM and such and transfer the bootstrap to RAM. I'll have those done soon hopefully. I'm disecting them from the DSO source to make them a bit easier to use. Eventually I might just compile a library with all of them.
_________________
Development Blog: http://teendev.org
Homebrew Podcast: http://homebrewcast.net
Web Design: http://xtendesign.net

#143187 - calcprogrammer1 - Wed Oct 17, 2007 10:23 pm

That code has bugs...

REG_EXEMEMCNT is undeclared, but I searched and found that it's actually REG_EXMEMCNT, so changing that seemed to fix it.
_________________
DS Firmware 1, Datel Games n' Music card / Chism's FW hacked GBA MP v2 CF

There's no place like 127.0.0.1.

#143188 - tondopie - Wed Oct 17, 2007 10:38 pm

calcprogrammer1 wrote:
That code has bugs...

REG_EXEMEMCNT is undeclared, but I searched and found that it's actually REG_EXMEMCNT, so changing that seemed to fix it.



that is because I was uding libnds 01272007
_________________
Development Blog: http://teendev.org
Homebrew Podcast: http://homebrewcast.net
Web Design: http://xtendesign.net