diff --git a/.gitignore b/.gitignore index 4c706f9797..743e75bed4 100644 --- a/.gitignore +++ b/.gitignore @@ -21,4 +21,4 @@ Debug Release ipch *.user -gx/app_booter/app_booter.bin +gx/app_booter/app_booter_*.bin diff --git a/Makefile.gc b/Makefile.gc index 8e78fdb914..f16b11f04c 100644 --- a/Makefile.gc +++ b/Makefile.gc @@ -37,7 +37,9 @@ CFLAGS += -Wall -std=gnu99 $(MACHDEP) $(INCLUDE) LDFLAGS := $(MACHDEP) -Wl,-Map,$(notdir $(ELF_TARGET)).map -T gx/ld/ogc.ld LIBS := -lfat -lretro_wii -logc -OBJ = console/griffin/griffin.o console/font.binobj console/rzlib/rzlib.o +APP_BOOTER_DIR = gx/app_booter + +OBJ = console/griffin/griffin.o console/font.binobj console/rzlib/rzlib.o $(APP_BOOTER_DIR)/app_booter_gc.binobj ifeq ($(HAVE_LOGGER), 1) CFLAGS += -DHAVE_LOGGER @@ -76,6 +78,9 @@ $(ELF_TARGET): $(OBJ) %.binobj: %.bin $(LD) -r -b binary -o $@ $< +$(APP_BOOTER_DIR)/app_booter_gc.bin: + $(MAKE) -C $(APP_BOOTER_DIR) platform=gc + pkg: all # cp -r $(DOL_TARGET) gx/pkg/CORE.dol @@ -83,6 +88,7 @@ clean: rm -f $(DOL_TARGET) rm -f $(ELF_TARGET) rm -f $(OBJ) + $(MAKE) -C $(APP_BOOTER_DIR) platform=gc clean .PHONY: clean diff --git a/Makefile.gc.salamander b/Makefile.gc.salamander new file mode 100644 index 0000000000..1027ce2db2 --- /dev/null +++ b/Makefile.gc.salamander @@ -0,0 +1,91 @@ +### +## +# Makefile for RetroArch GameCube. +## + +DEBUG = 0 +HAVE_LOGGER = 0 +HAVE_FILE_LOGGER = 0 + +# system platform +system_platform = unix +ifeq ($(shell uname -a),) +EXE_EXT = .exe + system_platform = win +else ifneq ($(findstring Darwin,$(shell uname -a)),) + system_platform = osx +else ifneq ($(findstring MINGW,$(shell uname -a)),) + system_platform = win +endif + +PC_DEVELOPMENT_IP_ADDRESS = "192.168.1.7" +PC_DEVELOPMENT_UDP_PORT = 3490 + +CC = $(DEVKITPPC)/bin/powerpc-eabi-gcc$(EXE_EXT) +CXX = $(DEVKITPPC)/bin/powerpc-eabi-g++$(EXE_EXT) +LD = $(DEVKITPPC)/bin/powerpc-eabi-ld$(EXE_EXT) +ELF2DOL = $(DEVKITPPC)/bin/elf2dol$(EXE_EXT) + +DOL_TARGET := retroarch-salamander_gx_gc.dol +ELF_TARGET := retroarch-salamander_gx_gc.elf + +INCLUDE := -I. -I$(DEVKITPRO)/libogc/include +LIBDIRS := -L$(DEVKITPRO)/libogc/lib/cube -L. + +MACHDEP := -DGEKKO -DHW_DOL -mogc -mcpu=750 -meabi -mhard-float +CFLAGS += -Wall -std=gnu99 $(MACHDEP) $(INCLUDE) +LDFLAGS := $(MACHDEP) -Wl,-Map,$(notdir $(ELF_TARGET)).map +LIBS := -lfat -lretro_wii -logc + +APP_BOOTER_DIR = gx/app_booter + +OBJ = gx/salamander/main.o console/rarch_console_exec.o console/rarch_console_libretro_mgmt.o file_path.o compat/compat.o conf/config_file.o $(APP_BOOTER_DIR)/app_booter_gc.binobj + +ifeq ($(HAVE_LOGGER), 1) +CFLAGS += -DHAVE_LOGGER +CFLAGS += -DPC_DEVELOPMENT_IP_ADDRESS=\"$(PC_DEVELOPMENT_IP_ADDRESS)\" -DPC_DEVELOPMENT_UDP_PORT=$(PC_DEVELOPMENT_UDP_PORT) +CFLAGS += -Iconsole/logger +OBJ += console/logger/logger.o +endif + +ifeq ($(HAVE_FILE_LOGGER), 1) +CFLAGS += -DHAVE_FILE_LOGGER +CFLAGS += -Iconsole/logger +endif + +CFLAGS += -std=gnu99 -DHAVE_DEFAULT_RETROPAD_INPUT -DIS_SALAMANDER -DRARCH_CONSOLE -DHAVE_RARCH_EXEC -DHAVE_CONFIGFILE=1 -DGEKKO -DPACKAGE_VERSION=\"0.9.7\" -Wno-char-subscripts + +ifeq ($(DEBUG), 1) + CFLAGS += -O0 -g +else + CFLAGS += -O3 +endif + +all: $(DOL_TARGET) + +%.dol: %.elf + $(ELF2DOL) $< $@ + +$(ELF_TARGET): $(OBJ) + $(CXX) -o $@ $(LDFLAGS) $(LIBDIRS) $(OBJ) $(LIBS) + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +%.binobj: %.bin + $(LD) -r -b binary -o $@ $< + +$(APP_BOOTER_DIR)/app_booter_gc.bin: + $(MAKE) -C $(APP_BOOTER_DIR) platform=gc + +pkg: all + #cp -r $(DOL_TARGET) gx/pkg/boot.dol + +clean: + rm -f $(DOL_TARGET) + rm -f $(ELF_TARGET) + rm -f $(OBJ) + $(MAKE) -C $(APP_BOOTER_DIR) platform=gc clean + +.PHONY: clean + diff --git a/Makefile.wii b/Makefile.wii index 202ada9fea..3c92569158 100644 --- a/Makefile.wii +++ b/Makefile.wii @@ -39,7 +39,7 @@ LIBS := -lfat -lretro_wii -lwiiuse -logc -lbte APP_BOOTER_DIR = gx/app_booter -OBJ = console/griffin/griffin.o console/font.binobj console/rzlib/rzlib.o $(APP_BOOTER_DIR)/app_booter.binobj +OBJ = console/griffin/griffin.o console/font.binobj console/rzlib/rzlib.o $(APP_BOOTER_DIR)/app_booter_wii.binobj ifeq ($(HAVE_LOGGER), 1) CFLAGS += -DHAVE_LOGGER @@ -78,8 +78,8 @@ $(ELF_TARGET): $(OBJ) %.binobj: %.bin $(LD) -r -b binary -o $@ $< -$(APP_BOOTER_DIR)/app_booter.bin: - $(MAKE) -C $(APP_BOOTER_DIR) +$(APP_BOOTER_DIR)/app_booter_wii.bin: + $(MAKE) -C $(APP_BOOTER_DIR) platform=wii pkg: all cp -r $(DOL_TARGET) gx/pkg/CORE.dol @@ -88,7 +88,7 @@ clean: rm -f $(DOL_TARGET) rm -f $(ELF_TARGET) rm -f $(OBJ) - $(MAKE) -C $(APP_BOOTER_DIR) clean + $(MAKE) -C $(APP_BOOTER_DIR) platform=wii clean .PHONY: clean diff --git a/Makefile.wii.salamander b/Makefile.wii.salamander index f1ceab6f48..c20c48b9a9 100644 --- a/Makefile.wii.salamander +++ b/Makefile.wii.salamander @@ -39,7 +39,7 @@ LIBS := -lfat -lretro_wii -lwiiuse -logc -lbte APP_BOOTER_DIR = gx/app_booter -OBJ = gx/salamander/main.o console/rarch_console_exec.o console/rarch_console_libretro_mgmt.o file_path.o compat/compat.o conf/config_file.o $(APP_BOOTER_DIR)/app_booter.binobj +OBJ = gx/salamander/main.o console/rarch_console_exec.o console/rarch_console_libretro_mgmt.o file_path.o compat/compat.o conf/config_file.o $(APP_BOOTER_DIR)/app_booter_wii.binobj ifeq ($(HAVE_LOGGER), 1) CFLAGS += -DHAVE_LOGGER @@ -53,7 +53,7 @@ CFLAGS += -DHAVE_FILE_LOGGER CFLAGS += -Iconsole/logger endif -CFLAGS += -std=gnu99 -DHAVE_DEFAULT_RETROPAD_INPUT -DIS_SALAMANDER -DRARCH_CONSOLE -DHAVE_RARCH_EXEC -DHAVE_CONFIGFILE=1 -DGEKKO -DHW_RVL -DPACKAGE_VERSION=\"0.9.7\" -Wno-char-subscripts +CFLAGS += -std=gnu99 -DHAVE_DEFAULT_RETROPAD_INPUT -DIS_SALAMANDER -DRARCH_CONSOLE -DHAVE_RARCH_EXEC -DHAVE_CONFIGFILE=1 -DGEKKO -DPACKAGE_VERSION=\"0.9.7\" -Wno-char-subscripts ifeq ($(DEBUG), 1) CFLAGS += -O0 -g @@ -75,8 +75,8 @@ $(ELF_TARGET): $(OBJ) %.binobj: %.bin $(LD) -r -b binary -o $@ $< -$(APP_BOOTER_DIR)/app_booter.bin: - $(MAKE) -C $(APP_BOOTER_DIR) +$(APP_BOOTER_DIR)/app_booter_wii.bin: + $(MAKE) -C $(APP_BOOTER_DIR) platform=wii pkg: all cp -r $(DOL_TARGET) gx/pkg/boot.dol @@ -85,7 +85,7 @@ clean: rm -f $(DOL_TARGET) rm -f $(ELF_TARGET) rm -f $(OBJ) - $(MAKE) -C $(APP_BOOTER_DIR) clean + $(MAKE) -C $(APP_BOOTER_DIR) platform=wii clean .PHONY: clean diff --git a/console/rarch_console_exec.c b/console/rarch_console_exec.c index f587bc10c7..0953b31d04 100644 --- a/console/rarch_console_exec.c +++ b/console/rarch_console_exec.c @@ -25,29 +25,53 @@ #include #elif defined(_XBOX) #include -#elif defined(HW_RVL) +#elif defined(GEKKO) #include #include #include #include #include #include + +#ifdef HW_RVL #include #include +#else +#include +#endif + #endif #include "rarch_console_exec.h" #include "../retroarch_logger.h" +#ifdef GEKKO + #ifdef HW_RVL + #define EXECUTE_ADDR ((uint8_t *) 0x91800000) #define BOOTER_ADDR ((uint8_t *) 0x93000000) #define ARGS_ADDR ((uint8_t *) 0x93200000) -extern uint8_t _binary_gx_app_booter_app_booter_bin_start[]; -extern uint8_t _binary_gx_app_booter_app_booter_bin_end[]; +extern uint8_t _binary_gx_app_booter_app_booter_wii_bin_start[]; +extern uint8_t _binary_gx_app_booter_app_booter_wii_bin_end[]; +#define booter_start _binary_gx_app_booter_app_booter_wii_bin_start +#define booter_end _binary_gx_app_booter_app_booter_wii_bin_end + +#else + +#define ARAMSTART 0x8000 +#define BOOTER_ADDR ((uint8_t *) 0x81300000) extern void __exception_closeall(void); +extern uint8_t _binary_gx_app_booter_app_booter_gc_bin_start[]; +extern uint8_t _binary_gx_app_booter_app_booter_gc_bin_end[]; +#define booter_start _binary_gx_app_booter_app_booter_gc_bin_start +#define booter_end _binary_gx_app_booter_app_booter_gc_bin_end + +#endif + +#ifdef HW_RVL // NOTE: this does not update the path to point to the new loading .dol file. // we only need it for keeping the current directory anyway. void dol_copy_argv_path(void) @@ -65,6 +89,7 @@ void dol_copy_argv_path(void) DCFlushRange(ARGS_ADDR, sizeof(struct __argv) + argv->length); } #endif +#endif void rarch_console_exec(const char *path) { @@ -99,36 +124,67 @@ void rarch_console_exec(const char *path) sys_net_finalize_network(); cellSysmoduleUnloadModule(CELL_SYSMODULE_SYSUTIL_NP); cellSysmoduleUnloadModule(CELL_SYSMODULE_NET); -#elif defined(HW_RVL) +#elif defined(GEKKO) FILE * fp = fopen(path, "rb"); if (fp == NULL) { RARCH_ERR("Could not execute DOL file.\n"); return; } + +#ifdef HW_RVL fseek(fp, 0, SEEK_END); size_t size = ftell(fp); fseek(fp, 0, SEEK_SET); fread(EXECUTE_ADDR, 1, size, fp); fclose(fp); DCFlushRange(EXECUTE_ADDR, size); +#else + uint8_t buffer[0x800]; + size_t size; + size_t offset = 0; + AR_Init(NULL, 0); + while ((size = fread(buffer, 1, sizeof(buffer), fp)) != 0) + { + if (size != sizeof(buffer)) + memset(&buffer[size], 0, sizeof(buffer) - size); + + AR_StartDMA(AR_MRAMTOARAM, (u32) buffer, (u32) offset + ARAMSTART, sizeof(buffer)); + while (AR_GetDMAStatus()); + offset += sizeof(buffer); + } +#endif + +#ifdef HW_RVL dol_copy_argv_path(); +#endif fatUnmount("carda:"); fatUnmount("cardb:"); +#ifdef HW_RVL fatUnmount("sd:"); fatUnmount("usb:"); __io_wiisd.shutdown(); __io_usbstorage.shutdown(); +#endif - size_t booter_size = _binary_gx_app_booter_app_booter_bin_end - _binary_gx_app_booter_app_booter_bin_start; - memcpy(BOOTER_ADDR, _binary_gx_app_booter_app_booter_bin_start, booter_size); + size_t booter_size = booter_end - booter_start; + memcpy(BOOTER_ADDR, booter_start, booter_size); DCFlushRange(BOOTER_ADDR, booter_size); - RARCH_LOG("jumping to %08x\n", BOOTER_ADDR); + RARCH_LOG("jumping to %08x\n", (unsigned) BOOTER_ADDR); +#ifdef HW_RVL SYS_ResetSystem(SYS_SHUTDOWN,0,0); +#else // we need to keep the ARAM alive for the booter app. + int level; + _CPU_ISR_Disable(level); + __exception_closeall(); +#endif __lwp_thread_stopmultitasking((void (*)(void)) BOOTER_ADDR); +#ifdef HW_DOL + _CPU_ISR_Restore(level); +#endif #else RARCH_WARN("External loading of executables is not supported for this platform.\n"); #endif diff --git a/gx/app_booter/Makefile b/gx/app_booter/Makefile index 45b1126508..d23a0a7211 100644 --- a/gx/app_booter/Makefile +++ b/gx/app_booter/Makefile @@ -18,8 +18,13 @@ CC = $(DEVKITPPC)/bin/powerpc-eabi-gcc$(EXE_EXT) LD = $(DEVKITPPC)/bin/powerpc-eabi-ld$(EXE_EXT) OBJCOPY = $(DEVKITPPC)/bin/powerpc-eabi-objcopy$(EXE_EXT) -BIN_TARGET := app_booter.bin -ELF_TARGET := app_booter.elf +ifeq ($(platform),wii) + BIN_TARGET := app_booter_wii.bin + ELF_TARGET := app_booter_wii.elf +else + BIN_TARGET := app_booter_gc.bin + ELF_TARGET := app_booter_gc.elf +endif INCLUDE := -I. -I$(DEVKITPRO)/libogc/include LIBDIRS := -L$(DEVKITPRO)/libogc/lib/wii @@ -27,6 +32,13 @@ LIBDIRS := -L$(DEVKITPRO)/libogc/lib/wii MACHDEP := -mno-eabi -mno-sdata -mcpu=750 # todo: find out why -Os spits out linker errors CFLAGS += -Wall -O2 -ffreestanding -std=gnu99 $(MACHDEP) $(INCLUDE) + +ifeq ($(platform),wii) + CFLAGS += -DHW_RVL +else + CFLAGS += -DHW_DOL +endif + LDFLAGS := -T link.ld OBJ = crt0.o dolloader.o elfloader.o main.o string.o sync.o diff --git a/gx/app_booter/main.c b/gx/app_booter/main.c index 5a03b02315..b84a5dc8b8 100644 --- a/gx/app_booter/main.c +++ b/gx/app_booter/main.c @@ -10,14 +10,22 @@ #include "elfloader.h" #include "sync.h" +#if HW_RVL #define EXECUTABLE_MEM_ADDR 0x91800000 #define SYSTEM_ARGV ((struct __argv *) 0x93200000) +#endif // if we name this main, GCC inserts the __eabi symbol, even when we specify -mno-eabi // what a lovely "feature" void app_booter_main(void) { +#if HW_RVL void *exeBuffer = (void *) EXECUTABLE_MEM_ADDR; +#else + uint8_t _exeBuffer[0x200]; // should be enough for most elf headers, and more than enough for dol headers + memcpy(_exeBuffer, 0, sizeof(_exeBuffer)); + void *exeBuffer = _exeBuffer; +#endif u32 exeEntryPointAddress = 0; entrypoint exeEntryPoint; @@ -30,12 +38,14 @@ void app_booter_main(void) if (!exeEntryPoint) return; +#ifdef HW_RVL if (SYSTEM_ARGV->argvMagic == ARGV_MAGIC) { void *new_argv = (void *) (exeEntryPointAddress + 8); memcpy(new_argv, SYSTEM_ARGV, sizeof(struct __argv)); sync_before_exec(new_argv, sizeof(struct __argv)); } +#endif exeEntryPoint (); } diff --git a/gx/app_booter/string.c b/gx/app_booter/string.c index 016396b82d..5766b73131 100644 --- a/gx/app_booter/string.c +++ b/gx/app_booter/string.c @@ -4,22 +4,81 @@ #include +#ifdef HW_DOL +#include +#include + +#define DSPCR_DSPDMA 0x0200 // ARAM dma in progress, if set +#define DSPCR_DSPINT 0x0080 // * interrupt active (RWC) +#define DSPCR_ARINT 0x0020 +#define DSPCR_AIINT 0x0008 + +#define ARAMSTART 0x8000 + +#define _SHIFTR(v, s, w) \ + ((u32)(((u32)(v) >> (s)) & ((0x01 << (w)) - 1))) + +static vu16* const _dspReg = (u16*) 0xCC005000; +static __inline__ void __ARClearInterrupt() +{ + u16 cause; + + cause = _dspReg[5]&~(DSPCR_DSPINT|DSPCR_AIINT); + _dspReg[5] = (cause|DSPCR_ARINT); +} + +static __inline__ void __ARWaitDma() +{ + while(_dspReg[5]&DSPCR_DSPDMA); +} + +static void __ARReadDMA(u32 memaddr,u32 aramaddr,u32 len) +{ + int level; + _CPU_ISR_Disable(level); + // set main memory address + _dspReg[16] = (_dspReg[16]&~0x03ff)|_SHIFTR(memaddr,16,16); + _dspReg[17] = (_dspReg[17]&~0xffe0)|_SHIFTR(memaddr, 0,16); + + // set aram address + _dspReg[18] = (_dspReg[18]&~0x03ff)|_SHIFTR(aramaddr,16,16); + _dspReg[19] = (_dspReg[19]&~0xffe0)|_SHIFTR(aramaddr, 0,16); + + // set cntrl bits + _dspReg[20] = (_dspReg[20]&~0x8000)|0x8000; + _dspReg[20] = (_dspReg[20]&~0x03ff)|_SHIFTR(len,16,16); + _dspReg[21] = (_dspReg[21]&~0xffe0)|_SHIFTR(len, 0,16); + + __ARWaitDma(); + __ARClearInterrupt(); + _CPU_ISR_Restore(level); +} +#endif + void *memset(void *b, int c, size_t len) { - size_t i; + size_t i; - for (i = 0; i < len; i++) - ((unsigned char *)b)[i] = c; + for (i = 0; i < len; i++) + ((unsigned char *)b)[i] = c; - return b; + return b; } void *memcpy(void *dst, const void *src, size_t len) { - size_t i; +#ifdef HW_DOL + if (((unsigned) src & ~0x00FFFFFF) == 0) + { + __ARReadDMA((u32) dst, (u32) src + ARAMSTART, len); - for (i = 0; i < len; i++) - ((unsigned char *)dst)[i] = ((unsigned char *)src)[i]; + return dst; + } +#endif + size_t i; - return dst; + for (i = 0; i < len; i++) + ((unsigned char *)dst)[i] = ((unsigned char *)src)[i]; + + return dst; } diff --git a/gx/frontend/main.c b/gx/frontend/main.c index 3ddd74b0bb..df9400071d 100644 --- a/gx/frontend/main.c +++ b/gx/frontend/main.c @@ -410,6 +410,9 @@ int rarch_main(int argc, char **argv); static void get_environment_settings(void) { +#ifdef HW_DOL + chdir("carda:/retroarch/cores"); +#endif getcwd(default_paths.core_dir, MAXPATHLEN); char *last_slash = strrchr(default_paths.core_dir, '/'); if (last_slash) diff --git a/gx/salamander/main.c b/gx/salamander/main.c index 8d9e2f963d..e23115796b 100644 --- a/gx/salamander/main.c +++ b/gx/salamander/main.c @@ -122,6 +122,9 @@ static void init_settings(void) static void get_environment_settings(void) { +#ifdef HW_DOL + chdir("carda:/retroarch/cores"); +#endif getcwd(default_paths.core_dir, MAXPATHLEN); char *last_slash = strrchr(default_paths.core_dir, '/'); if (last_slash)