Improve Icon UI
* No Icon graphic is now a seperate banner asset that loads when no icon is present. This allows using proper background behind valid banners that have alpha pixels. * Reorganized make files to allow building with custom arm7 code. * N-Card Autorun1.nds with NRIO.dldi added to bootstrap makefile. * bootstub disabled as it was causing some applications to hang on exit.
@ -20,6 +20,7 @@ all: checkarm7 checkarm9 \
|
|||||||
_ds_menu.dat ismat.dat ez5sys.bin \
|
_ds_menu.dat ismat.dat ez5sys.bin \
|
||||||
akmenu4.nds TTMENU.DAT _BOOT_MP.NDS \
|
akmenu4.nds TTMENU.DAT _BOOT_MP.NDS \
|
||||||
ACE3DS/_ds_menu.dat ACE3DS/_dsmenu.dat
|
ACE3DS/_ds_menu.dat ACE3DS/_dsmenu.dat
|
||||||
|
# AUTORUN1.NDS
|
||||||
|
|
||||||
_ds_menu.dat : $(TARGET).nds r4tfv2.dldi
|
_ds_menu.dat : $(TARGET).nds r4tfv2.dldi
|
||||||
@cp $(TARGET).nds _ds_menu.nds
|
@cp $(TARGET).nds _ds_menu.nds
|
||||||
@ -59,6 +60,9 @@ ismat.dat : $(TARGET).nds mati.dldi
|
|||||||
@cp $< $@
|
@cp $< $@
|
||||||
@dlditool mati.dldi $@
|
@dlditool mati.dldi $@
|
||||||
|
|
||||||
|
AUTORUN1.NDS : $(TARGET).nds nrio.dldi
|
||||||
|
@cp $< $@
|
||||||
|
@dlditool nrio.dldi $@
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# Building separate .dsi and .nds binaries here is done purely to allow the .nds
|
# Building separate .dsi and .nds binaries here is done purely to allow the .nds
|
||||||
# binary to be used to replace various flashcart boot menus.
|
# binary to be used to replace various flashcart boot menus.
|
||||||
|
BIN
BootStrap/nrio.dldi
Normal file
203
Makefile
@ -1,122 +1,40 @@
|
|||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
.SUFFIXES:
|
.SUFFIXES:
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
.SECONDARY:
|
|
||||||
|
|
||||||
ifeq ($(strip $(DEVKITARM)),)
|
ifeq ($(strip $(DEVKITARM)),)
|
||||||
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
|
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
|
||||||
endif
|
endif
|
||||||
|
|
||||||
include $(DEVKITARM)/ds_rules
|
export TARGET := hbmenu
|
||||||
|
export TOPDIR := $(CURDIR)
|
||||||
|
|
||||||
export HBMENU_MAJOR := 0
|
export HBMENU_MAJOR := 0
|
||||||
export HBMENU_MINOR := 9
|
export HBMENU_MINOR := 9
|
||||||
export HBMENU_PATCH := 2
|
export HBMENU_PATCH := 3
|
||||||
|
|
||||||
|
|
||||||
VERSION := $(HBMENU_MAJOR).$(HBMENU_MINOR).$(HBMENU_PATCH)
|
VERSION := $(HBMENU_MAJOR).$(HBMENU_MINOR).$(HBMENU_PATCH)
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
# TARGET is the name of the output
|
# GMAE_ICON is the image used to create the game icon, leave blank to use default rule
|
||||||
# BUILD is the directory where object files & intermediate files will be placed
|
GAME_ICON :=
|
||||||
# SOURCES is a list of directories containing source code
|
|
||||||
# INCLUDES is a list of directories containing extra header files
|
# specify a directory which contains the nitro filesystem
|
||||||
# DATA is a list of directories containing binary files embedded using bin2o
|
# this is relative to the Makefile
|
||||||
# GRAPHICS is a list of directories containing image files to be converted with grit
|
NITRO_FILES :=
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
TARGET := hbmenu
|
# These set the information text in the nds file
|
||||||
BUILD := build
|
#GAME_TITLE := My Wonderful Homebrew
|
||||||
SOURCES := source
|
#GAME_SUBTITLE1 := built with devkitARM
|
||||||
INCLUDES := include
|
#GAME_SUBTITLE2 := http://devitpro.org
|
||||||
DATA := data
|
|
||||||
GRAPHICS := gfx
|
include $(DEVKITARM)/ds_rules
|
||||||
|
|
||||||
|
.PHONY: data ndsbootloader bootstub BootStrap exceptionstub clean
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# options for code generation
|
# main targets
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
ARCH := -mthumb -mthumb-interwork
|
all: ndsbootloader bootstub exceptionstub $(TARGET).nds BootStrap
|
||||||
|
|
||||||
CFLAGS := -g -Wall -O2 \
|
|
||||||
-ffunction-sections -fdata-sections \
|
|
||||||
-march=armv5te -mtune=arm946e-s -fomit-frame-pointer\
|
|
||||||
-ffast-math \
|
|
||||||
$(ARCH)
|
|
||||||
|
|
||||||
CFLAGS += $(INCLUDE) -DARM9
|
|
||||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
|
|
||||||
|
|
||||||
ASFLAGS := -g $(ARCH)
|
|
||||||
LDFLAGS = -specs=ds_arm9.specs -g -Wl,--gc-sections $(ARCH) -Wl,-Map,$(notdir $*.map)
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
# any extra libraries we wish to link with the project (order is important)
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
LIBS := -lfat -lnds329
|
|
||||||
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
# list of directories containing libraries, this must be the top level containing
|
|
||||||
# include and lib
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
LIBDIRS := $(LIBNDS)
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
# 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)))
|
|
||||||
PNGFILES := $(foreach dir,$(GRAPHICS),$(notdir $(wildcard $(dir)/*.png)))
|
|
||||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
|
||||||
BINFILES := load.bin bootstub.bin exceptionstub.bin
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
# 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)) \
|
|
||||||
$(PNGFILES:.png=.o) \
|
|
||||||
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
icons := $(wildcard *.bmp)
|
|
||||||
|
|
||||||
ifneq (,$(findstring $(TARGET).bmp,$(icons)))
|
|
||||||
export GAME_ICON := $(CURDIR)/$(TARGET).bmp
|
|
||||||
else
|
|
||||||
ifneq (,$(findstring icon.bmp,$(icons)))
|
|
||||||
export GAME_ICON := $(CURDIR)/icon.bmp
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
.PHONY: ndsbootloader bootstub BootStrap exceptionstub $(BUILD) clean cia
|
|
||||||
|
|
||||||
all: ndsbootloader bootstub exceptionstub $(BUILD) BootStrap
|
|
||||||
|
|
||||||
cia:
|
cia:
|
||||||
$(MAKE) -C BootStrap bootstrap.cia
|
$(MAKE) -C BootStrap bootstrap.cia
|
||||||
@ -124,7 +42,10 @@ cia:
|
|||||||
dist: all
|
dist: all
|
||||||
rm -fr hbmenu
|
rm -fr hbmenu
|
||||||
mkdir -p hbmenu/nds
|
mkdir -p hbmenu/nds
|
||||||
cp hbmenu.nds hbmenu/BOOT.NDS
|
ndstool -c boot.nds -7 arm7/$(TARGET).elf -9 arm9/$(TARGET).elf \
|
||||||
|
-b $(CURDIR)/icon.bmp "hbmenu;$(VERSION);http://devkitpro.org" \
|
||||||
|
-g #### 01 "HBMENU" -z 80040407 -u 00030015 -a 001FFFFF -p 0001
|
||||||
|
cp boot.nds hbmenu/BOOT.NDS
|
||||||
cp BootStrap/_BOOT_MP.NDS BootStrap/TTMENU.DAT BootStrap/_ds_menu.dat BootStrap/ez5sys.bin BootStrap/akmenu4.nds BootStrap/ismat.dat hbmenu
|
cp BootStrap/_BOOT_MP.NDS BootStrap/TTMENU.DAT BootStrap/_ds_menu.dat BootStrap/ez5sys.bin BootStrap/akmenu4.nds BootStrap/ismat.dat hbmenu
|
||||||
cp -r BootStrap/ACE3DS hbmenu
|
cp -r BootStrap/ACE3DS hbmenu
|
||||||
ifneq (,$(wildcard BootStrap/bootstrap.cia))
|
ifneq (,$(wildcard BootStrap/bootstrap.cia))
|
||||||
@ -132,63 +53,55 @@ ifneq (,$(wildcard BootStrap/bootstrap.cia))
|
|||||||
endif
|
endif
|
||||||
cp testfiles/* hbmenu/nds
|
cp testfiles/* hbmenu/nds
|
||||||
zip -9r hbmenu-$(VERSION).zip hbmenu README.md COPYING
|
zip -9r hbmenu-$(VERSION).zip hbmenu README.md COPYING
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
checkarm7:
|
||||||
|
$(MAKE) -C arm7
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
$(BUILD):
|
checkarm9:
|
||||||
@[ -d $@ ] || mkdir -p $@
|
$(MAKE) -C arm9
|
||||||
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
clean:
|
$(TARGET).nds : $(NITRO_FILES) arm7/$(TARGET).elf arm9/$(TARGET).elf
|
||||||
@echo clean ...
|
ndstool -c $(TARGET).nds -7 arm7/$(TARGET).elf -9 arm9/$(TARGET).elf \
|
||||||
@rm -fr $(BUILD) $(TARGET).elf $(TARGET).nds $(TARGET).arm9 data
|
-b $(CURDIR)/icon.bmp "hbmenu;$(VERSION);http://devkitpro.org" \
|
||||||
@$(MAKE) -C ndsbootloader clean
|
-g HOME 01 "HBMENU" -z 80040407 -u 00030015 -a 001FFFFF -p 0001
|
||||||
@$(MAKE) -C bootstub clean
|
@cp $(TARGET).nds 00000000.app
|
||||||
@$(MAKE) -C BootStrap clean
|
|
||||||
@$(MAKE) -C exception-stub clean
|
|
||||||
|
|
||||||
data:
|
data:
|
||||||
@mkdir -p data
|
@mkdir -p data
|
||||||
|
|
||||||
ndsbootloader: data
|
ndsbootloader: data
|
||||||
@$(MAKE) -C ndsbootloader LOADBIN=$(CURDIR)/data/load.bin
|
$(MAKE) -C ndsbootloader LOADBIN=$(CURDIR)/data/load.bin
|
||||||
|
|
||||||
exceptionstub: data
|
exceptionstub: data
|
||||||
@$(MAKE) -C exception-stub STUBBIN=$(CURDIR)/data/exceptionstub.bin
|
$(MAKE) -C exception-stub STUBBIN=$(CURDIR)/data/exceptionstub.bin
|
||||||
|
|
||||||
bootstub: data
|
bootstub: data
|
||||||
@$(MAKE) -C bootstub
|
$(MAKE) -C bootstub
|
||||||
|
|
||||||
BootStrap:
|
BootStrap: data
|
||||||
@$(MAKE) -C BootStrap
|
$(MAKE) -C BootStrap
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
else
|
arm7/$(TARGET).elf:
|
||||||
|
$(MAKE) -C arm7
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# main targets
|
arm9/$(TARGET).elf: ndsbootloader
|
||||||
#---------------------------------------------------------------------------------
|
$(MAKE) -C arm9
|
||||||
$(OUTPUT).nds : $(OUTPUT).elf
|
|
||||||
$(OUTPUT).elf : $(OFILES)
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
%.bin.o : %.bin
|
clean:
|
||||||
#---------------------------------------------------------------------------------
|
$(MAKE) -C arm9 clean
|
||||||
@echo $(notdir $<)
|
$(MAKE) -C arm7 clean
|
||||||
$(bin2o)
|
$(MAKE) -C ndsbootloader clean
|
||||||
|
$(MAKE) -C bootstub clean
|
||||||
|
$(MAKE) -C BootStrap clean
|
||||||
|
$(MAKE) -C exception-stub clean
|
||||||
|
rm -rf data
|
||||||
|
rm -rf hbmenu
|
||||||
|
rm -f $(TARGET).nds
|
||||||
|
rm -f boot.nds
|
||||||
|
rm -f 00000000.app
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
# This rule creates assembly source files using grit
|
|
||||||
# grit takes an image file and a .grit describing how the file is to be processed
|
|
||||||
# add additional rules like this for each image extension
|
|
||||||
# you use in the graphics folders
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
%.s %.h : %.png %.grit
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
grit $< -fts -o$*
|
|
||||||
|
|
||||||
-include $(DEPSDIR)/*.d
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------------
|
|
||||||
endif
|
|
||||||
#---------------------------------------------------------------------------------------
|
|
||||||
|
122
arm7/Makefile
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
.SUFFIXES:
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
ifeq ($(strip $(DEVKITARM)),)
|
||||||
|
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
|
||||||
|
endif
|
||||||
|
|
||||||
|
include $(DEVKITARM)/ds_rules
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# 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 files
|
||||||
|
# all directories are relative to this makefile
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
BUILD := build
|
||||||
|
SOURCES := source
|
||||||
|
INCLUDES := include build
|
||||||
|
DATA :=
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# options for code generation
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
ARCH := -mthumb -mthumb-interwork
|
||||||
|
|
||||||
|
CFLAGS := -g -Wall -Os \
|
||||||
|
$(ARCH) $(INCLUDE) -DARM7
|
||||||
|
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
|
||||||
|
ASFLAGS := -g $(ARCH)
|
||||||
|
LDFLAGS = -specs=ds_arm7.specs -g $(ARCH) -Wl,-Map,$(notdir $*).map
|
||||||
|
|
||||||
|
LIBS := -lnds7
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# list of directories containing libraries, this must be the top level containing
|
||||||
|
# include and lib
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
LIBDIRS := $(LIBNDS)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# 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 ARM7ELF := $(CURDIR)/$(TARGET).elf
|
||||||
|
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||||
|
|
||||||
|
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir))\
|
||||||
|
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
|
||||||
|
|
||||||
|
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_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
|
||||||
|
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
else
|
||||||
|
|
||||||
|
DEPENDS := $(OFILES:.o=.d)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# main targets
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
$(ARM7ELF) : $(OFILES)
|
||||||
|
@echo linking $(notdir $@)
|
||||||
|
@$(LD) $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@
|
||||||
|
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
%.bin.o %_bin.h : %.bin
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
@echo $(notdir $<)
|
||||||
|
@$(bin2o)
|
||||||
|
|
||||||
|
-include $(DEPENDS)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------------
|
||||||
|
endif
|
||||||
|
#---------------------------------------------------------------------------------------
|
23
arm7/source/main.c
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#include <nds.h>
|
||||||
|
|
||||||
|
void VcountHandler() { inputGetAndSend(); }
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
readUserSettings();
|
||||||
|
ledBlink(0);
|
||||||
|
irqInit();
|
||||||
|
initClockIRQ();
|
||||||
|
fifoInit();
|
||||||
|
touchInit();
|
||||||
|
SetYtrigger(80);
|
||||||
|
installSystemFIFO();
|
||||||
|
irqSet(IRQ_VCOUNT, VcountHandler);
|
||||||
|
irqEnable(IRQ_VCOUNT);
|
||||||
|
if (REG_SNDEXTCNT != 0) {
|
||||||
|
i2cWriteRegister(0x4A, 0x12, 0x00); // Press power-button for auto-reset
|
||||||
|
i2cWriteRegister(0x4A, 0x70, 0x01); // Bootflag = Warmboot/SkipHealthSafety
|
||||||
|
}
|
||||||
|
while(1)swiWaitForVBlank();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
143
arm9/Makefile
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
.SUFFIXES:
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
ifeq ($(strip $(DEVKITARM)),)
|
||||||
|
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
|
||||||
|
endif
|
||||||
|
|
||||||
|
include $(DEVKITARM)/ds_rules
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# 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 files embedded using bin2o
|
||||||
|
# GRAPHICS is a list of directories containing image files to be converted with grit
|
||||||
|
# all directories are relative to this makefile
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
BUILD := build
|
||||||
|
SOURCES := source
|
||||||
|
INCLUDES := include
|
||||||
|
DATA := ../data
|
||||||
|
GRAPHICS := gfx
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# options for code generation
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
ARCH := -mthumb -mthumb-interwork
|
||||||
|
|
||||||
|
CFLAGS := -g -Wall -O2 \
|
||||||
|
-ffunction-sections -fdata-sections \
|
||||||
|
-march=armv5te -mtune=arm946e-s -fomit-frame-pointer\
|
||||||
|
-ffast-math \
|
||||||
|
$(ARCH)
|
||||||
|
|
||||||
|
CFLAGS += $(INCLUDE) -DARM9 -D_NO_BOOTSTUB_
|
||||||
|
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
|
||||||
|
ASFLAGS := -g $(ARCH)
|
||||||
|
LDFLAGS = -specs=dsi_arm9.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# any extra libraries we wish to link with the project
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
LIBS := -lfat -lnds329
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# list of directories containing libraries, this must be the top level containing
|
||||||
|
# include and lib
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
LIBDIRS := $(LIBNDS) $(PORTLIBS)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# 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 ARM9ELF := $(CURDIR)/$(TARGET).elf
|
||||||
|
|
||||||
|
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)))
|
||||||
|
PNGFILES := $(foreach dir,$(GRAPHICS),$(notdir $(wildcard $(dir)/*.png)))
|
||||||
|
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_BIN := $(addsuffix .o,$(BINFILES))
|
||||||
|
|
||||||
|
export OFILES_SOURCES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
||||||
|
|
||||||
|
export OFILES := $(PNGFILES:.png=.o) $(OFILES_BIN) $(OFILES_SOURCES)
|
||||||
|
|
||||||
|
export HFILES := $(PNGFILES:.png=.h) $(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
|
||||||
|
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
else
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# main targets
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
$(ARM9ELF) : $(OFILES)
|
||||||
|
@echo linking $(notdir $@)
|
||||||
|
@$(LD) $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
%.bin.o %_bin.h : %.bin
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
@echo $(notdir $<)
|
||||||
|
@$(bin2o)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# This rule creates assembly source files using grit
|
||||||
|
# grit takes an image file and a .grit describing how the file is to be processed
|
||||||
|
# add additional rules like this for each image extension
|
||||||
|
# you use in the graphics folders
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
%.s %.h: %.png %.grit
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
grit $< -fts -o$*
|
||||||
|
|
||||||
|
-include $(DEPSDIR)/*.d
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------------
|
||||||
|
endif
|
||||||
|
#---------------------------------------------------------------------------------------
|
||||||
|
|
Before Width: | Height: | Size: 688 B After Width: | Height: | Size: 688 B |
Before Width: | Height: | Size: 758 B After Width: | Height: | Size: 758 B |
BIN
arm9/gfx/hbmenu_banner.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
5
arm9/source/defaultBanners.s
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
.arm
|
||||||
|
.global hbNoIcon_bin
|
||||||
|
|
||||||
|
hbNoIcon_bin: .incbin "../include/hbNoIcon.bin"
|
||||||
|
|
@ -74,7 +74,6 @@ void getDirectoryContents (vector<DirEntry>& dirContents, const vector<string> e
|
|||||||
if (pdir == NULL) {
|
if (pdir == NULL) {
|
||||||
iprintf ("Unable to open the directory.\n");
|
iprintf ("Unable to open the directory.\n");
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
while(true) {
|
while(true) {
|
||||||
DirEntry dirEntry;
|
DirEntry dirEntry;
|
||||||
|
|
||||||
@ -88,9 +87,7 @@ void getDirectoryContents (vector<DirEntry>& dirContents, const vector<string> e
|
|||||||
if (dirEntry.name.compare(".") != 0 && (dirEntry.isDirectory || nameEndsWith(dirEntry.name, extensionList))) {
|
if (dirEntry.name.compare(".") != 0 && (dirEntry.isDirectory || nameEndsWith(dirEntry.name, extensionList))) {
|
||||||
dirContents.push_back (dirEntry);
|
dirContents.push_back (dirEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
closedir(pdir);
|
closedir(pdir);
|
||||||
}
|
}
|
||||||
|
|
@ -42,6 +42,8 @@ static int bg2, bg3;
|
|||||||
static u16 *sprite;
|
static u16 *sprite;
|
||||||
static tNDSBanner banner;
|
static tNDSBanner banner;
|
||||||
|
|
||||||
|
extern tNDSBanner hbNoIcon_bin;
|
||||||
|
|
||||||
static inline void writecharRS (int row, int col, u16 car) {
|
static inline void writecharRS (int row, int col, u16 car) {
|
||||||
// get map pointer
|
// get map pointer
|
||||||
u16 *gfx = bgGetMapPtr(bg2);
|
u16 *gfx = bgGetMapPtr(bg2);
|
||||||
@ -77,9 +79,7 @@ static inline void writeRow (int rownum, const char* text) {
|
|||||||
writecharRS (rownum, i, 0);
|
writecharRS (rownum, i, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void clearIcon (void) {
|
static inline void clearIcon (void) { dmaFillHalfWords(0, sprite, sizeof(banner.icon)); }
|
||||||
dmaFillHalfWords(0, sprite, sizeof(banner.icon));
|
|
||||||
}
|
|
||||||
|
|
||||||
void iconTitleInit (void) {
|
void iconTitleInit (void) {
|
||||||
// initialize video mode
|
// initialize video mode
|
||||||
@ -126,10 +126,21 @@ void iconTitleInit (void) {
|
|||||||
swiWaitForVBlank();
|
swiWaitForVBlank();
|
||||||
oamUpdate(&oamMain);
|
oamUpdate(&oamMain);
|
||||||
|
|
||||||
|
// Load Default Icon.
|
||||||
|
DC_FlushAll();
|
||||||
|
dmaCopy(hbNoIcon_bin.icon, sprite, sizeof(hbNoIcon_bin.icon));
|
||||||
|
dmaCopy(hbNoIcon_bin.palette, SPRITE_PALETTE, sizeof(hbNoIcon_bin.palette));
|
||||||
|
|
||||||
// everything's ready :)
|
// everything's ready :)
|
||||||
writeRow (1,"===>>> HBMenu+ <<<===");
|
writeRow (1,"===>>> HBMenu+ <<<===");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void loadDefaultIcon() {
|
||||||
|
DC_FlushAll();
|
||||||
|
dmaCopy(hbNoIcon_bin.icon, sprite, sizeof(hbNoIcon_bin.icon));
|
||||||
|
dmaCopy(hbNoIcon_bin.palette, SPRITE_PALETTE, sizeof(hbNoIcon_bin.palette));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void iconTitleUpdate (int isdir, const std::string& name) {
|
void iconTitleUpdate (int isdir, const std::string& name) {
|
||||||
writeRow (0, name.c_str());
|
writeRow (0, name.c_str());
|
||||||
@ -142,11 +153,13 @@ void iconTitleUpdate (int isdir, const std::string& name) {
|
|||||||
writeRow (2, "[directory]");
|
writeRow (2, "[directory]");
|
||||||
// icon
|
// icon
|
||||||
clearIcon();
|
clearIcon();
|
||||||
|
loadDefaultIcon();
|
||||||
} else {
|
} else {
|
||||||
std::string ndsPath;
|
std::string ndsPath;
|
||||||
if (!argsNdsPath(name, ndsPath)) {
|
if (!argsNdsPath(name, ndsPath)) {
|
||||||
writeRow(2, "(invalid argv or NDS file!)");
|
writeRow(2, "(invalid argv or NDS file!)");
|
||||||
clearIcon();
|
clearIcon();
|
||||||
|
loadDefaultIcon();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,16 +173,17 @@ void iconTitleUpdate (int isdir, const std::string& name) {
|
|||||||
writeRow (2,"(can't open file!)");
|
writeRow (2,"(can't open file!)");
|
||||||
// icon
|
// icon
|
||||||
clearIcon();
|
clearIcon();
|
||||||
|
loadDefaultIcon();
|
||||||
fclose (fp);
|
fclose (fp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fseek (fp, offsetof(tNDSHeader, bannerOffset), SEEK_SET) != 0 ||
|
if (fseek (fp, offsetof(tNDSHeader, bannerOffset), SEEK_SET) != 0 || fread (&Icon_title_offset, sizeof(int), 1, fp) != 1) {
|
||||||
fread (&Icon_title_offset, sizeof(int), 1, fp) != 1) {
|
|
||||||
// text
|
// text
|
||||||
writeRow (2, "(can't read file!)");
|
writeRow (2, "(can't read file!)");
|
||||||
// icon
|
// icon
|
||||||
clearIcon();
|
clearIcon();
|
||||||
|
loadDefaultIcon();
|
||||||
fclose (fp);
|
fclose (fp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -179,16 +193,17 @@ void iconTitleUpdate (int isdir, const std::string& name) {
|
|||||||
writeRow (2, "(no title/icon)");
|
writeRow (2, "(no title/icon)");
|
||||||
// icon
|
// icon
|
||||||
clearIcon();
|
clearIcon();
|
||||||
|
loadDefaultIcon();
|
||||||
fclose (fp);
|
fclose (fp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fseek (fp, Icon_title_offset, SEEK_SET) != 0 ||
|
if (fseek (fp, Icon_title_offset, SEEK_SET) != 0 || fread (&banner, sizeof(banner), 1, fp) != 1) {
|
||||||
fread (&banner, sizeof(banner), 1, fp) != 1) {
|
|
||||||
// text
|
// text
|
||||||
writeRow (2,"(can't read icon/title!)");
|
writeRow (2,"(can't read icon/title!)");
|
||||||
// icon
|
// icon
|
||||||
clearIcon();
|
clearIcon();
|
||||||
|
loadDefaultIcon();
|
||||||
fclose (fp);
|
fclose (fp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -198,17 +213,23 @@ void iconTitleUpdate (int isdir, const std::string& name) {
|
|||||||
|
|
||||||
// turn unicode into ascii (kind of)
|
// turn unicode into ascii (kind of)
|
||||||
// and convert 0x0A into 0x00
|
// and convert 0x0A into 0x00
|
||||||
char *p = (char*)banner.titles[0];
|
char *p = (char*)banner.titles[1];
|
||||||
for (size_t i = 0; i < sizeof(banner.titles[0]); i = i+2) {
|
int rowOffset = 1;
|
||||||
if ((p[i] == 0x0A) || (p[i] == 0xFF))
|
int lineReturns = 0;
|
||||||
|
for (size_t i = 0; i < sizeof(banner.titles[1]); i = i+2) {
|
||||||
|
if ((p[i] == 0x0A) || (p[i] == 0xFF)) {
|
||||||
p[i/2] = 0;
|
p[i/2] = 0;
|
||||||
else
|
lineReturns++;
|
||||||
|
} else {
|
||||||
p[i/2] = p[i];
|
p[i/2] = p[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lineReturns < 2)rowOffset = 2; // Recenter if bennar has less 2 or less rows of text maintaining empty row gap between nds file name and nds banner.
|
||||||
|
|
||||||
// text
|
// text
|
||||||
for (size_t i = 0; i < 3; ++i) {
|
for (size_t i = 0; i < 3; ++i) {
|
||||||
writeRow(i+1, p);
|
writeRow(i+rowOffset, p);
|
||||||
p += strlen(p) + 1;
|
p += strlen(p) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,3 +239,4 @@ void iconTitleUpdate (int isdir, const std::string& name) {
|
|||||||
dmaCopy(banner.palette, SPRITE_PALETTE, sizeof(banner.palette));
|
dmaCopy(banner.palette, SPRITE_PALETTE, sizeof(banner.palette));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
354
arm9/source/nds_loader_arm9.c
Normal file
@ -0,0 +1,354 @@
|
|||||||
|
/*-----------------------------------------------------------------
|
||||||
|
Copyright (C) 2005 - 2010
|
||||||
|
Michael "Chishm" Chisholm
|
||||||
|
Dave "WinterMute" Murphy
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
------------------------------------------------------------------*/
|
||||||
|
#include <string.h>
|
||||||
|
#include <nds.h>
|
||||||
|
#include <nds/arm9/dldi.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fat.h>
|
||||||
|
|
||||||
|
#include "load_bin.h"
|
||||||
|
|
||||||
|
#ifndef _NO_BOOTSTUB_
|
||||||
|
#include "bootstub_bin.h"
|
||||||
|
#include "exceptionstub_bin.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "nds_loader_arm9.h"
|
||||||
|
|
||||||
|
#define TMP_DATA 0x02100000
|
||||||
|
|
||||||
|
#define LCDC_BANK_D (u16*)0x06860000
|
||||||
|
#define STORED_FILE_CLUSTER (*(((u32*)LCDC_BANK_D) + 1))
|
||||||
|
#define INIT_DISC (*(((u32*)LCDC_BANK_D) + 2))
|
||||||
|
#define WANT_TO_PATCH_DLDI (*(((u32*)LCDC_BANK_D) + 3))
|
||||||
|
|
||||||
|
#define STORED_FILE_CLUSTER_OFFSET 4
|
||||||
|
#define INIT_DISC_OFFSET 8
|
||||||
|
#define WANT_TO_PATCH_DLDI_OFFSET 12
|
||||||
|
#define ARG_START_OFFSET 16
|
||||||
|
#define ARG_SIZE_OFFSET 20
|
||||||
|
#define HAVE_DSISD_OFFSET 28
|
||||||
|
#define DSIMODE_OFFSET 32
|
||||||
|
|
||||||
|
typedef signed int addr_t;
|
||||||
|
typedef unsigned char data_t;
|
||||||
|
|
||||||
|
#define FIX_ALL 0x01
|
||||||
|
#define FIX_GLUE 0x02
|
||||||
|
#define FIX_GOT 0x04
|
||||||
|
#define FIX_BSS 0x08
|
||||||
|
|
||||||
|
enum DldiOffsets {
|
||||||
|
DO_magicString = 0x00, // "\xED\xA5\x8D\xBF Chishm"
|
||||||
|
DO_magicToken = 0x00, // 0xBF8DA5ED
|
||||||
|
DO_magicShortString = 0x04, // " Chishm"
|
||||||
|
DO_version = 0x0C,
|
||||||
|
DO_driverSize = 0x0D,
|
||||||
|
DO_fixSections = 0x0E,
|
||||||
|
DO_allocatedSpace = 0x0F,
|
||||||
|
|
||||||
|
DO_friendlyName = 0x10,
|
||||||
|
|
||||||
|
DO_text_start = 0x40, // Data start
|
||||||
|
DO_data_end = 0x44, // Data end
|
||||||
|
DO_glue_start = 0x48, // Interworking glue start -- Needs address fixing
|
||||||
|
DO_glue_end = 0x4C, // Interworking glue end
|
||||||
|
DO_got_start = 0x50, // GOT start -- Needs address fixing
|
||||||
|
DO_got_end = 0x54, // GOT end
|
||||||
|
DO_bss_start = 0x58, // bss start -- Needs setting to zero
|
||||||
|
DO_bss_end = 0x5C, // bss end
|
||||||
|
|
||||||
|
// IO_INTERFACE data
|
||||||
|
DO_ioType = 0x60,
|
||||||
|
DO_features = 0x64,
|
||||||
|
DO_startup = 0x68,
|
||||||
|
DO_isInserted = 0x6C,
|
||||||
|
DO_readSectors = 0x70,
|
||||||
|
DO_writeSectors = 0x74,
|
||||||
|
DO_clearStatus = 0x78,
|
||||||
|
DO_shutdown = 0x7C,
|
||||||
|
DO_code = 0x80
|
||||||
|
};
|
||||||
|
|
||||||
|
static addr_t readAddr (data_t *mem, addr_t offset) { return ((addr_t*)mem)[offset/sizeof(addr_t)]; }
|
||||||
|
|
||||||
|
static void writeAddr (data_t *mem, addr_t offset, addr_t value) { ((addr_t*)mem)[offset/sizeof(addr_t)] = value; }
|
||||||
|
|
||||||
|
static void vramcpy (void* dst, const void* src, int len) {
|
||||||
|
u16* dst16 = (u16*)dst;
|
||||||
|
u16* src16 = (u16*)src;
|
||||||
|
|
||||||
|
for ( ; len > 0; len -= 2) { *dst16++ = *src16++; }
|
||||||
|
}
|
||||||
|
|
||||||
|
static addr_t quickFind (const data_t* data, const data_t* search, size_t dataLen, size_t searchLen) {
|
||||||
|
const int* dataChunk = (const int*) data;
|
||||||
|
int searchChunk = ((const int*)search)[0];
|
||||||
|
addr_t i;
|
||||||
|
addr_t dataChunkEnd = (addr_t)(dataLen / sizeof(int));
|
||||||
|
|
||||||
|
for ( i = 0; i < dataChunkEnd; i++) {
|
||||||
|
if (dataChunk[i] == searchChunk) {
|
||||||
|
if ((i*sizeof(int) + searchLen) > dataLen)return -1;
|
||||||
|
if (memcmp (&data[i*sizeof(int)], search, searchLen) == 0)return i*sizeof(int);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normal DLDI uses "\xED\xA5\x8D\xBF Chishm"
|
||||||
|
// Bootloader string is different to avoid being patched
|
||||||
|
static const data_t dldiMagicLoaderString[] = "\xEE\xA5\x8D\xBF Chishm"; // Different to a normal DLDI file
|
||||||
|
|
||||||
|
#define DEVICE_TYPE_DLDI 0x49444C44
|
||||||
|
|
||||||
|
static bool dldiPatchLoader (data_t *binData, u32 binSize, bool clearBSS) {
|
||||||
|
addr_t memOffset; // Offset of DLDI after the file is loaded into memory
|
||||||
|
addr_t patchOffset; // Position of patch destination in the file
|
||||||
|
addr_t relocationOffset; // Value added to all offsets within the patch to fix it properly
|
||||||
|
addr_t ddmemOffset; // Original offset used in the DLDI file
|
||||||
|
addr_t ddmemStart; // Start of range that offsets can be in the DLDI file
|
||||||
|
addr_t ddmemEnd; // End of range that offsets can be in the DLDI file
|
||||||
|
addr_t ddmemSize; // Size of range that offsets can be in the DLDI file
|
||||||
|
|
||||||
|
addr_t addrIter;
|
||||||
|
|
||||||
|
data_t *pDH;
|
||||||
|
data_t *pAH;
|
||||||
|
|
||||||
|
size_t dldiFileSize = 0;
|
||||||
|
|
||||||
|
// Find the DLDI reserved space in the file
|
||||||
|
patchOffset = quickFind (binData, dldiMagicLoaderString, binSize, sizeof(dldiMagicLoaderString));
|
||||||
|
|
||||||
|
if (patchOffset < 0)return false; // does not have a DLDI section
|
||||||
|
|
||||||
|
pDH = (data_t*)(io_dldi_data);
|
||||||
|
|
||||||
|
pAH = &(binData[patchOffset]);
|
||||||
|
|
||||||
|
if (*((u32*)(pDH + DO_ioType)) == DEVICE_TYPE_DLDI)return false; // No DLDI patch
|
||||||
|
|
||||||
|
if (pDH[DO_driverSize] > pAH[DO_allocatedSpace])return false; // Not enough space for patch
|
||||||
|
|
||||||
|
dldiFileSize = 1 << pDH[DO_driverSize];
|
||||||
|
|
||||||
|
memOffset = readAddr (pAH, DO_text_start);
|
||||||
|
if (memOffset == 0)memOffset = readAddr (pAH, DO_startup) - DO_code;
|
||||||
|
ddmemOffset = readAddr (pDH, DO_text_start);
|
||||||
|
relocationOffset = memOffset - ddmemOffset;
|
||||||
|
|
||||||
|
ddmemStart = readAddr (pDH, DO_text_start);
|
||||||
|
ddmemSize = (1 << pDH[DO_driverSize]);
|
||||||
|
ddmemEnd = ddmemStart + ddmemSize;
|
||||||
|
|
||||||
|
// Remember how much space is actually reserved
|
||||||
|
pDH[DO_allocatedSpace] = pAH[DO_allocatedSpace];
|
||||||
|
// Copy the DLDI patch into the application
|
||||||
|
vramcpy (pAH, pDH, dldiFileSize);
|
||||||
|
|
||||||
|
// Fix the section pointers in the header
|
||||||
|
writeAddr (pAH, DO_text_start, readAddr (pAH, DO_text_start) + relocationOffset);
|
||||||
|
writeAddr (pAH, DO_data_end, readAddr (pAH, DO_data_end) + relocationOffset);
|
||||||
|
writeAddr (pAH, DO_glue_start, readAddr (pAH, DO_glue_start) + relocationOffset);
|
||||||
|
writeAddr (pAH, DO_glue_end, readAddr (pAH, DO_glue_end) + relocationOffset);
|
||||||
|
writeAddr (pAH, DO_got_start, readAddr (pAH, DO_got_start) + relocationOffset);
|
||||||
|
writeAddr (pAH, DO_got_end, readAddr (pAH, DO_got_end) + relocationOffset);
|
||||||
|
writeAddr (pAH, DO_bss_start, readAddr (pAH, DO_bss_start) + relocationOffset);
|
||||||
|
writeAddr (pAH, DO_bss_end, readAddr (pAH, DO_bss_end) + relocationOffset);
|
||||||
|
// Fix the function pointers in the header
|
||||||
|
writeAddr (pAH, DO_startup, readAddr (pAH, DO_startup) + relocationOffset);
|
||||||
|
writeAddr (pAH, DO_isInserted, readAddr (pAH, DO_isInserted) + relocationOffset);
|
||||||
|
writeAddr (pAH, DO_readSectors, readAddr (pAH, DO_readSectors) + relocationOffset);
|
||||||
|
writeAddr (pAH, DO_writeSectors, readAddr (pAH, DO_writeSectors) + relocationOffset);
|
||||||
|
writeAddr (pAH, DO_clearStatus, readAddr (pAH, DO_clearStatus) + relocationOffset);
|
||||||
|
writeAddr (pAH, DO_shutdown, readAddr (pAH, DO_shutdown) + relocationOffset);
|
||||||
|
|
||||||
|
if (pDH[DO_fixSections] & FIX_ALL) {
|
||||||
|
// Search through and fix pointers within the data section of the file
|
||||||
|
for (addrIter = (readAddr(pDH, DO_text_start) - ddmemStart); addrIter < (readAddr(pDH, DO_data_end) - ddmemStart); addrIter++) {
|
||||||
|
if ((ddmemStart <= readAddr(pAH, addrIter)) && (readAddr(pAH, addrIter) < ddmemEnd)) {
|
||||||
|
writeAddr (pAH, addrIter, readAddr(pAH, addrIter) + relocationOffset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pDH[DO_fixSections] & FIX_GLUE) {
|
||||||
|
// Search through and fix pointers within the glue section of the file
|
||||||
|
for (addrIter = (readAddr(pDH, DO_glue_start) - ddmemStart); addrIter < (readAddr(pDH, DO_glue_end) - ddmemStart); addrIter++) {
|
||||||
|
if ((ddmemStart <= readAddr(pAH, addrIter)) && (readAddr(pAH, addrIter) < ddmemEnd)) {
|
||||||
|
writeAddr (pAH, addrIter, readAddr(pAH, addrIter) + relocationOffset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pDH[DO_fixSections] & FIX_GOT) {
|
||||||
|
// Search through and fix pointers within the Global Offset Table section of the file
|
||||||
|
for (addrIter = (readAddr(pDH, DO_got_start) - ddmemStart); addrIter < (readAddr(pDH, DO_got_end) - ddmemStart); addrIter++) {
|
||||||
|
if ((ddmemStart <= readAddr(pAH, addrIter)) && (readAddr(pAH, addrIter) < ddmemEnd)) {
|
||||||
|
writeAddr (pAH, addrIter, readAddr(pAH, addrIter) + relocationOffset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clearBSS && (pDH[DO_fixSections] & FIX_BSS)) {
|
||||||
|
// Initialise the BSS to 0, only if the disc is being re-inited
|
||||||
|
memset (&pAH[readAddr(pDH, DO_bss_start) - ddmemStart] , 0, readAddr(pDH, DO_bss_end) - readAddr(pDH, DO_bss_start));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
eRunNdsRetCode runNds (const void* loader, u32 loaderSize, u32 cluster, bool initDisc, bool dldiPatchNds, int argc, const char** argv) {
|
||||||
|
char* argStart;
|
||||||
|
u16* argData;
|
||||||
|
u16 argTempVal = 0;
|
||||||
|
int argSize;
|
||||||
|
const char* argChar;
|
||||||
|
|
||||||
|
irqDisable(IRQ_ALL);
|
||||||
|
|
||||||
|
// Direct CPU access to VRAM bank C
|
||||||
|
VRAM_D_CR = VRAM_ENABLE | VRAM_D_LCD;
|
||||||
|
// Load the loader/patcher into the correct address
|
||||||
|
vramcpy (LCDC_BANK_D, loader, loaderSize);
|
||||||
|
|
||||||
|
// Set the parameters for the loader
|
||||||
|
// STORED_FILE_CLUSTER = cluster;
|
||||||
|
writeAddr ((data_t*) LCDC_BANK_D, STORED_FILE_CLUSTER_OFFSET, cluster);
|
||||||
|
// INIT_DISC = initDisc;
|
||||||
|
writeAddr ((data_t*) LCDC_BANK_D, INIT_DISC_OFFSET, initDisc);
|
||||||
|
|
||||||
|
writeAddr ((data_t*) LCDC_BANK_D, DSIMODE_OFFSET, isDSiMode());
|
||||||
|
if(argv[0][0]=='s' && argv[0][1]=='d') {
|
||||||
|
dldiPatchNds = false;
|
||||||
|
writeAddr ((data_t*) LCDC_BANK_D, HAVE_DSISD_OFFSET, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// WANT_TO_PATCH_DLDI = dldiPatchNds;
|
||||||
|
writeAddr ((data_t*) LCDC_BANK_D, WANT_TO_PATCH_DLDI_OFFSET, dldiPatchNds);
|
||||||
|
// Give arguments to loader
|
||||||
|
argStart = (char*)LCDC_BANK_D + readAddr((data_t*)LCDC_BANK_D, ARG_START_OFFSET);
|
||||||
|
argStart = (char*)(((int)argStart + 3) & ~3); // Align to word
|
||||||
|
argData = (u16*)argStart;
|
||||||
|
argSize = 0;
|
||||||
|
|
||||||
|
for (; argc > 0 && *argv; ++argv, --argc) {
|
||||||
|
for (argChar = *argv; *argChar != 0; ++argChar, ++argSize) {
|
||||||
|
if (argSize & 1) {
|
||||||
|
argTempVal |= (*argChar) << 8;
|
||||||
|
*argData = argTempVal;
|
||||||
|
++argData;
|
||||||
|
} else {
|
||||||
|
argTempVal = *argChar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (argSize & 1) { *argData = argTempVal; ++argData; }
|
||||||
|
argTempVal = 0;
|
||||||
|
++argSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
*argData = argTempVal;
|
||||||
|
|
||||||
|
writeAddr ((data_t*) LCDC_BANK_D, ARG_START_OFFSET, (addr_t)argStart - (addr_t)LCDC_BANK_D);
|
||||||
|
writeAddr ((data_t*) LCDC_BANK_D, ARG_SIZE_OFFSET, argSize);
|
||||||
|
|
||||||
|
if(dldiPatchNds) {
|
||||||
|
// Patch the loader with a DLDI for the card
|
||||||
|
if (!dldiPatchLoader ((data_t*)LCDC_BANK_D, loaderSize, initDisc))return RUN_NDS_PATCH_DLDI_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
irqDisable(IRQ_ALL);
|
||||||
|
|
||||||
|
// Give the VRAM to the ARM7
|
||||||
|
VRAM_D_CR = VRAM_ENABLE | VRAM_D_ARM7_0x06020000;
|
||||||
|
// Reset into a passme loop
|
||||||
|
REG_EXMEMCNT |= ARM7_OWNS_ROM | ARM7_OWNS_CARD;
|
||||||
|
*((vu32*)0x02FFFFFC) = 0;
|
||||||
|
*((vu32*)0x02FFFE04) = (u32)0xE59FF018;
|
||||||
|
*((vu32*)0x02FFFE24) = (u32)0x02FFFE04;
|
||||||
|
|
||||||
|
resetARM7(0x06020000);
|
||||||
|
|
||||||
|
swiSoftReset();
|
||||||
|
return RUN_NDS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
eRunNdsRetCode runNdsFile (const char* filename, int argc, const char** argv) {
|
||||||
|
struct stat st;
|
||||||
|
char filePath[PATH_MAX];
|
||||||
|
int pathLen;
|
||||||
|
const char* args[1];
|
||||||
|
|
||||||
|
|
||||||
|
if (stat (filename, &st) < 0)return RUN_NDS_STAT_FAILED;
|
||||||
|
|
||||||
|
if (argc <= 0 || !argv) {
|
||||||
|
// Construct a command line if we weren't supplied with one
|
||||||
|
if (!getcwd (filePath, PATH_MAX))return RUN_NDS_GETCWD_FAILED;
|
||||||
|
pathLen = strlen (filePath);
|
||||||
|
strcpy (filePath + pathLen, filename);
|
||||||
|
args[0] = filePath;
|
||||||
|
argv = args;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool havedsiSD = false;
|
||||||
|
|
||||||
|
if(argv[0][0]=='s' && argv[0][1]=='d') havedsiSD = true;
|
||||||
|
|
||||||
|
installBootStub(havedsiSD);
|
||||||
|
|
||||||
|
return runNds (load_bin, load_bin_size, st.st_ino, true, true, argc, argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
void(*exceptionstub)(void) = (void(*)(void))0x2FFA000;
|
||||||
|
|
||||||
|
bool installBootStub(bool havedsiSD) {
|
||||||
|
#ifndef _NO_BOOTSTUB_
|
||||||
|
extern char *fake_heap_end;
|
||||||
|
struct __bootstub *bootstub = (struct __bootstub *)fake_heap_end;
|
||||||
|
u32 *bootloader = (u32*)(fake_heap_end+bootstub_bin_size);
|
||||||
|
memcpy(bootstub,bootstub_bin,bootstub_bin_size);
|
||||||
|
memcpy(bootloader,load_bin,load_bin_size);
|
||||||
|
bool ret = false;
|
||||||
|
bootloader[8] = isDSiMode();
|
||||||
|
if( havedsiSD) {
|
||||||
|
ret = true;
|
||||||
|
bootloader[3] = 0; // don't dldi patch
|
||||||
|
bootloader[7] = 1; // use internal dsi SD code
|
||||||
|
} else {
|
||||||
|
ret = dldiPatchLoader((data_t*)bootloader, load_bin_size,false);
|
||||||
|
}
|
||||||
|
bootstub->arm9reboot = (VoidFn)(((u32)bootstub->arm9reboot)+fake_heap_end);
|
||||||
|
bootstub->arm7reboot = (VoidFn)(((u32)bootstub->arm7reboot)+fake_heap_end);
|
||||||
|
bootstub->bootsize = load_bin_size;
|
||||||
|
memcpy(exceptionstub,exceptionstub_bin,exceptionstub_bin_size);
|
||||||
|
exceptionstub();
|
||||||
|
DC_FlushAll();
|
||||||
|
return ret;
|
||||||
|
#else
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
50
arm9/source/nds_loader_arm9.h
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/*-----------------------------------------------------------------
|
||||||
|
Copyright (C) 2005 - 2010
|
||||||
|
Michael "Chishm" Chisholm
|
||||||
|
Dave "WinterMute" Murphy
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef NDS_LOADER_ARM9_H
|
||||||
|
#define NDS_LOADER_ARM9_H
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
RUN_NDS_OK = 0,
|
||||||
|
RUN_NDS_STAT_FAILED,
|
||||||
|
RUN_NDS_GETCWD_FAILED,
|
||||||
|
RUN_NDS_PATCH_DLDI_FAILED,
|
||||||
|
} eRunNdsRetCode;
|
||||||
|
|
||||||
|
#define LOAD_DEFAULT_NDS 0
|
||||||
|
|
||||||
|
eRunNdsRetCode runNds (const void* loader, u32 loaderSize, u32 cluster, bool initDisc, bool dldiPatchNds, int argc, const char** argv);
|
||||||
|
|
||||||
|
eRunNdsRetCode runNdsFile (const char* filename, int argc, const char** argv);
|
||||||
|
|
||||||
|
bool installBootStub(bool havedsiSD);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // NDS_LOADER_ARM7_H
|
||||||
|
|
Before Width: | Height: | Size: 1.6 KiB |