From 11bf35dfced32b02c7458d7488079af259224040 Mon Sep 17 00:00:00 2001 From: Lorenzooone Date: Tue, 12 Nov 2024 04:30:19 +0100 Subject: [PATCH] Add libnds2 basic support --- Makefile | 2 +- Makefile.arm9 | 2 +- Makefile.arm9libnds2 | 132 +++++++++++++++++++++++++++++++++++++ include/base_include.h | 21 +++++- source/gen3_save.c | 4 ++ source/gen_converter.c | 14 ++-- source/graphics_handler.c | 2 + source/main.c | 12 +++- source/multiboot_handler.c | 12 ++-- source/print_system.c | 7 ++ 10 files changed, 192 insertions(+), 16 deletions(-) create mode 100644 Makefile.arm9libnds2 diff --git a/Makefile b/Makefile index 1c0ba13..7d351e3 100644 --- a/Makefile +++ b/Makefile @@ -31,7 +31,7 @@ ARCH := -mthumb -mthumb-interwork CFLAGS := -g -Wall -Wstrict-overflow=5 -Wextra\ -Wpointer-arith -Wpedantic -Wcast-qual -Wswitch-default\ - -Wstrict-prototypes -Wmissing-prototypes\ + -Wmissing-prototypes\ -Wshadow -Wwrite-strings -save-temps -Os -s\ -mcpu=arm7tdmi -mtune=arm7tdmi -masm-syntax-unified\ -fomit-frame-pointer -flto=auto \ diff --git a/Makefile.arm9 b/Makefile.arm9 index bf39304..01fa09b 100644 --- a/Makefile.arm9 +++ b/Makefile.arm9 @@ -101,7 +101,7 @@ SOURCES_CPP := $(shell find -L $(SOURCEDIRS) -name "*.cpp") # Compiler and linker flags # ------------------------- -DEFINES += -D__NDS__ -DARM9 +DEFINES += -D__NDS__ -DARM9 -D__BLOCKSDS__ ARCH := -march=armv5te -mtune=arm946e-s diff --git a/Makefile.arm9libnds2 b/Makefile.arm9libnds2 new file mode 100644 index 0000000..0f72e49 --- /dev/null +++ b/Makefile.arm9libnds2 @@ -0,0 +1,132 @@ +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- + +ifeq ($(strip $(DEVKITARM)),) +$(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") +endif + +include $(DEVKITARM)/ds_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 +#--------------------------------------------------------------------------------- +TARGET := $(shell basename $(CURDIR)) +BUILD := build_ds +SOURCES := gfx source data +INCLUDES := include $(BUILD) +NAME_MAKEFILE := Makefile.arm9 + +#--------------------------------------------------------------------------------- +# options for code generation +#--------------------------------------------------------------------------------- +ARCH := -march=armv5te -mtune=arm946e-s -mthumb + +CFLAGS := -g -Wall\ + -Wstrict-overflow=5 -Wextra\ + -Wpointer-arith -Wpedantic -Wcast-qual -Wswitch-default\ + -Wmissing-prototypes\ + -Wshadow -Wwrite-strings -save-temps -Os -s\ + -masm-syntax-unified\ + -fomit-frame-pointer -flto=auto \ + -ffast-math \ + -fno-tree-loop-distribute-patterns \ + $(ARCH) + +CFLAGS += $(INCLUDE) -DARM9 +CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions + +ASFLAGS := -g $(ARCH) +LDFLAGS = -specs=ds_arm9.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) + +#--------------------------------------------------------------------------------- +# any extra libraries we wish to link with the project +#--------------------------------------------------------------------------------- +LIBS := -lnds9 -lagbabi + + +#--------------------------------------------------------------------------------- +# list of directories containing libraries, this must be the top level containing +# include and lib +#--------------------------------------------------------------------------------- +LIBDIRS := $(LIBNDS) $(LIBAGBABI) + +#--------------------------------------------------------------------------------- +# 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 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,$(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=.bin.o) \ + $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) + +export INCLUDE := $(foreach dir,$(INCLUDES),-I$(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)/$(NAME_MAKEFILE) + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr $(BUILD) $(TARGET).elf $(TARGET).nds $(TARGET).ds.gba + + +#--------------------------------------------------------------------------------- +else + +DEPENDS := $(OFILES:.o=.d) + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +$(OUTPUT).nds : $(OUTPUT).elf +$(OUTPUT).elf : $(OFILES) + +#--------------------------------------------------------------------------------- +%.bin.o : %.bin +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + $(bin2o) + + +-include $(DEPENDS) + +#--------------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------------- diff --git a/include/base_include.h b/include/base_include.h index aba4fe6..6869314 100644 --- a/include/base_include.h +++ b/include/base_include.h @@ -86,9 +86,28 @@ typedef struct { #define DivMod(x, y) swiRemainder(x, y) #define Sqrt(x) swiSqrt(x) #define LZ77UnCompWram(x, y) swi_LZ77UnCompWrite8bit(x, y) +#ifdef __BLOCKSDS__ #define CpuFastSet(x, y, z) swiFastCopy(x, y, z) -#define VBlankIntrWait() swiWaitForVBlank() #define Halt() CP15_WaitForInterrupt() +#else +static void CpuFastSet(volatile const void*, volatile void*, volatile int); +static void Halt(void); + +ALWAYS_INLINE MAX_OPTIMIZE void CpuFastSet(volatile const void* source, volatile void* dest, volatile int flags) +{ + register uint32_t src asm("r0") = (uint32_t)source; + register uint32_t dst asm("r1") = (uint32_t)dest; + register uint32_t flg asm("r2") = (uint32_t)flags; + register uint32_t after_destroyed asm("r3"); + + asm volatile( + "swi 0xC;" : "=r"(src), "=r"(dst), "=r"(flg) : + "r"(src), "r"(dst), "r"(flg), "r"(after_destroyed) : + ); +} +ALWAYS_INLINE void Halt() {__asm__("swi 0x6");} +#endif +#define VBlankIntrWait() swiWaitForVBlank() #define DIV_SWI_VAL "0x09" #endif diff --git a/source/gen3_save.c b/source/gen3_save.c index 3d7473e..296c2fe 100644 --- a/source/gen3_save.c +++ b/source/gen3_save.c @@ -825,14 +825,18 @@ IWRAM_CODE u8 has_cartridge_been_removed(){ ALWAYS_INLINE void start_gen3_save_data_transfer() { #ifdef __NDS__ + #ifdef __BLOCKSDS__ disableSleep(); #endif + #endif } ALWAYS_INLINE void end_gen3_save_data_transfer() { #ifdef __NDS__ + #ifdef __BLOCKSDS__ enableSleep(); #endif + #endif } u8 read_gen_3_data(struct game_data_t* game_data, struct game_data_priv_t* game_data_priv){ diff --git a/source/gen_converter.c b/source/gen_converter.c index dcc7cdf..96fe7ca 100644 --- a/source/gen_converter.c +++ b/source/gen_converter.c @@ -1045,13 +1045,13 @@ void special_convert_strings_distribution(struct gen3_mon* dst, u16 species) { const u8* mon_name = get_pokemon_name_pure(species, 0, dst->language); const u8* trainer_name = NULL; - switch(species) { - case CELEBI_SPECIES: - trainer_name = get_celebi_trainer_name(dst->language); - break; - default: - break; - } + switch(species) { + case CELEBI_SPECIES: + trainer_name = get_celebi_trainer_name(dst->language); + break; + default: + break; + } if(mon_name) text_gen3_copy(mon_name, dst->nickname, gen3_nickname_cap, gen3_nickname_cap); diff --git a/source/graphics_handler.c b/source/graphics_handler.c index d79c51f..49673fc 100644 --- a/source/graphics_handler.c +++ b/source/graphics_handler.c @@ -28,7 +28,9 @@ void convert_3bpp_forward_even(const u8*, u32*, size_t); MAX_OPTIMIZE void load_pokemon_sprite_gfx(const u32* src, u32* dst, u8 is_3bpp, u8 zero_fill, u8 index, u8* colors){ + u32 zero = 0; u32 buffer[BUFFER_SIZE]; + CpuFastSet(&zero, buffer, BUFFER_SIZE|CPUFASTSET_FILL); LZ77UnCompWram(src, buffer); size_t processed_size = TOTAL_POKEMON_SPRITE_SIZE; diff --git a/source/main.c b/source/main.c index 8910ef9..621cf1f 100644 --- a/source/main.c +++ b/source/main.c @@ -714,6 +714,9 @@ void prepare_crash_screen(enum CRASH_REASONS reason) { print_crash(reason); enable_screen(CRASH_WINDOW_SCREEN); prepare_flush(); + #if defined(__NDS__) && (!defined(__BLOCKSDS__)) + pmMainLoop(); + #endif } void crash_on_cartridge_removed() { @@ -780,6 +783,10 @@ int main(void) #ifdef __GBA__ RegisterRamReset(RESET_SIO|RESET_SOUND|RESET_OTHER); disable_all_irqs(); + #else + #ifndef __BLOCKSDS__ + gbacartOpen(); + #endif #endif curr_state = MAIN_MENU; counter = 0; @@ -847,10 +854,13 @@ int main(void) //PRINT_FUNCTION("\n\n0x\x0D: 0x\x0D\n", REG_MEMORY_CONTROLLER_ADDR, 8, REG_MEMORY_CONTROLLER, 8); scanKeys(); keys = keysDown(); - + while(1) { do { + #if defined(__NDS__) && (!defined(__BLOCKSDS__)) + pmMainLoop(); + #endif prepare_flush(); VBlankIntrWait(); scanKeys(); diff --git a/source/multiboot_handler.c b/source/multiboot_handler.c index 8ee21d0..1d2e525 100644 --- a/source/multiboot_handler.c +++ b/source/multiboot_handler.c @@ -12,6 +12,9 @@ void multiboot_send(int, int, u16*); +#ifndef HAS_SIO +void multiboot_send(int UNUSED(data), int UNUSED(is_normal), u16* UNUSED(out_buffer)) { +#else void multiboot_send(int data, int is_normal, u16* out_buffer) { // Only this part of REG_SIODATA32 is used during setup. // The rest is handled by SWI $25 @@ -21,14 +24,13 @@ void multiboot_send(int data, int is_normal, u16* out_buffer) { out_buffer[0] = timed_sio_normal_master(data, SIO_32, MULTIBOOT_VCOUNTWAIT) >> 0x10; else timed_sio_multi_master(data, MULTIBOOT_VCOUNTWAIT, out_buffer); +#endif } -#ifdef HAS_SIO -enum MULTIBOOT_RESULTS multiboot_normal (u16* data, u16* end, int is_normal) { -#else +#ifndef HAS_SIO enum MULTIBOOT_RESULTS multiboot_normal (u16* UNUSED(data), u16* UNUSED(end), int UNUSED(is_normal)) { -#endif - #ifdef HAS_SIO +#else +enum MULTIBOOT_RESULTS multiboot_normal (u16* data, u16* end, int is_normal) { u16 response[MAX_NUM_SLAVES]; u8 clientMask = 0; u8 client_bit; diff --git a/source/print_system.c b/source/print_system.c index fb4b80a..584bc4e 100644 --- a/source/print_system.c +++ b/source/print_system.c @@ -188,6 +188,13 @@ void init_text_system() { #if defined (__NDS__) && (SAME_ON_BOTH_SCREENS) REG_DISPCNT_SUB = 0 | TILE_1D_MAP | ACTIVATE_SCREEN_HW; #endif + + #ifdef __NDS__ + vramSetBankA(VRAM_A_MAIN_BG); + vramSetBankB(VRAM_B_MAIN_SPRITE); + vramSetBankC(VRAM_C_SUB_BG); + vramSetBankD(VRAM_D_SUB_SPRITE); + #endif screens_flush = 0; for(int i = 0; i < TOTAL_BG; i++) { enabled_screen[i] = 0;