From db276d8e521ae6b8ea9fb40c33d6961d713f31b7 Mon Sep 17 00:00:00 2001 From: FIX94 Date: Fri, 8 Apr 2016 00:19:16 +0200 Subject: first commit, enjoy --- Makefile | 131 ++++++++++++++++++ Makefile.gc | 131 ++++++++++++++++++ Makefile.wii | 131 ++++++++++++++++++ README.md | 6 +- build.bat | 10 ++ gba/Makefile | 168 +++++++++++++++++++++++ gba/source/main.c | 94 +++++++++++++ source/main.c | 400 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 1070 insertions(+), 1 deletion(-) create mode 100644 Makefile create mode 100644 Makefile.gc create mode 100644 Makefile.wii create mode 100644 build.bat create mode 100644 gba/Makefile create mode 100644 gba/source/main.c create mode 100644 source/main.c diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f7dcdae --- /dev/null +++ b/Makefile @@ -0,0 +1,131 @@ +#--------------------------------------------------------------------------------- +# Clear the implicit built in rules +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- +ifeq ($(strip $(DEVKITPPC)),) +$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=devkitPPC") +endif + +include $(DEVKITPPC)/wii_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 := boot +BUILD := build +SOURCES := source +DATA := data +INCLUDES := source + +#--------------------------------------------------------------------------------- +# options for code generation +#--------------------------------------------------------------------------------- + +CFLAGS = -g -O2 -Wall $(MACHDEP) $(INCLUDE) +CXXFLAGS = $(CFLAGS) + +LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map + +#--------------------------------------------------------------------------------- +# any extra libraries we wish to link with the project +#--------------------------------------------------------------------------------- +LIBS := -lfat -logc + + +#--------------------------------------------------------------------------------- +# list of directories containing libraries, this must be the top level containing +# include and lib +#--------------------------------------------------------------------------------- +LIBDIRS := $(DEVKITPPC)/lib $(CURDIR) + +#--------------------------------------------------------------------------------- +# 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 DEPSDIR := $(CURDIR)/$(BUILD) + +#--------------------------------------------------------------------------------- +# automatically build a list of object files for our project +#--------------------------------------------------------------------------------- +CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) +CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) +sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) +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 := $(addsuffix .o,$(BINFILES)) \ + $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \ + $(sFILES:.s=.o) $(SFILES:.S=.o) + +#--------------------------------------------------------------------------------- +# build a list of include paths +#--------------------------------------------------------------------------------- +export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + -I$(CURDIR)/$(BUILD) \ + -I$(LIBOGC_INC) + +#--------------------------------------------------------------------------------- +# build a list of library paths +#--------------------------------------------------------------------------------- +export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \ + -L$(LIBOGC_LIB) + +export OUTPUT := $(CURDIR)/$(TARGET) +.PHONY: $(BUILD) clean + +#--------------------------------------------------------------------------------- +$(BUILD): + @[ -d $@ ] || mkdir -p $@ + @make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).dol $(CURDIR)/data/gba_mb.gba + +#--------------------------------------------------------------------------------- +else + +DEPENDS := $(OFILES:.o=.d) + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +$(OUTPUT).dol: $(OUTPUT).elf +$(OUTPUT).elf: $(OFILES) + +#--------------------------------------------------------------------------------- +# This rule links in binary data with the .jpg extension +#--------------------------------------------------------------------------------- +%.gba.o : %.gba +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + $(bin2o) + +-include $(DEPENDS) + +#--------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------- diff --git a/Makefile.gc b/Makefile.gc new file mode 100644 index 0000000..82e10f1 --- /dev/null +++ b/Makefile.gc @@ -0,0 +1,131 @@ +#--------------------------------------------------------------------------------- +# Clear the implicit built in rules +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- +ifeq ($(strip $(DEVKITPPC)),) +$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=devkitPPC") +endif + +include $(DEVKITPPC)/gamecube_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 := linkcabledump_gc +BUILD := build +SOURCES := source +DATA := data +INCLUDES := source + +#--------------------------------------------------------------------------------- +# options for code generation +#--------------------------------------------------------------------------------- + +CFLAGS = -g -O2 -Wall $(MACHDEP) $(INCLUDE) +CXXFLAGS = $(CFLAGS) + +LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map + +#--------------------------------------------------------------------------------- +# any extra libraries we wish to link with the project +#--------------------------------------------------------------------------------- +LIBS := -lfat -logc + + +#--------------------------------------------------------------------------------- +# list of directories containing libraries, this must be the top level containing +# include and lib +#--------------------------------------------------------------------------------- +LIBDIRS := $(DEVKITPPC)/lib $(CURDIR) + +#--------------------------------------------------------------------------------- +# 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 DEPSDIR := $(CURDIR)/$(BUILD) + +#--------------------------------------------------------------------------------- +# automatically build a list of object files for our project +#--------------------------------------------------------------------------------- +CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) +CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) +sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) +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 := $(addsuffix .o,$(BINFILES)) \ + $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \ + $(sFILES:.s=.o) $(SFILES:.S=.o) + +#--------------------------------------------------------------------------------- +# build a list of include paths +#--------------------------------------------------------------------------------- +export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + -I$(CURDIR)/$(BUILD) \ + -I$(LIBOGC_INC) + +#--------------------------------------------------------------------------------- +# build a list of library paths +#--------------------------------------------------------------------------------- +export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \ + -L$(LIBOGC_LIB) + +export OUTPUT := $(CURDIR)/$(TARGET) +.PHONY: $(BUILD) clean + +#--------------------------------------------------------------------------------- +$(BUILD): + @[ -d $@ ] || mkdir -p $@ + @make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile.gc + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).dol + +#--------------------------------------------------------------------------------- +else + +DEPENDS := $(OFILES:.o=.d) + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +$(OUTPUT).dol: $(OUTPUT).elf +$(OUTPUT).elf: $(OFILES) + +#--------------------------------------------------------------------------------- +# This rule links in binary data with the .jpg extension +#--------------------------------------------------------------------------------- +%.gba.o : %.gba +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + $(bin2o) + +-include $(DEPENDS) + +#--------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------- diff --git a/Makefile.wii b/Makefile.wii new file mode 100644 index 0000000..341c37b --- /dev/null +++ b/Makefile.wii @@ -0,0 +1,131 @@ +#--------------------------------------------------------------------------------- +# Clear the implicit built in rules +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- +ifeq ($(strip $(DEVKITPPC)),) +$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=devkitPPC") +endif + +include $(DEVKITPPC)/wii_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 := linkcabledump_wii +BUILD := build +SOURCES := source +DATA := data +INCLUDES := source + +#--------------------------------------------------------------------------------- +# options for code generation +#--------------------------------------------------------------------------------- + +CFLAGS = -g -O2 -Wall $(MACHDEP) $(INCLUDE) +CXXFLAGS = $(CFLAGS) + +LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map + +#--------------------------------------------------------------------------------- +# any extra libraries we wish to link with the project +#--------------------------------------------------------------------------------- +LIBS := -lfat -logc + + +#--------------------------------------------------------------------------------- +# list of directories containing libraries, this must be the top level containing +# include and lib +#--------------------------------------------------------------------------------- +LIBDIRS := $(DEVKITPPC)/lib $(CURDIR) + +#--------------------------------------------------------------------------------- +# 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 DEPSDIR := $(CURDIR)/$(BUILD) + +#--------------------------------------------------------------------------------- +# automatically build a list of object files for our project +#--------------------------------------------------------------------------------- +CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) +CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) +sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) +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 := $(addsuffix .o,$(BINFILES)) \ + $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \ + $(sFILES:.s=.o) $(SFILES:.S=.o) + +#--------------------------------------------------------------------------------- +# build a list of include paths +#--------------------------------------------------------------------------------- +export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + -I$(CURDIR)/$(BUILD) \ + -I$(LIBOGC_INC) + +#--------------------------------------------------------------------------------- +# build a list of library paths +#--------------------------------------------------------------------------------- +export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \ + -L$(LIBOGC_LIB) + +export OUTPUT := $(CURDIR)/$(TARGET) +.PHONY: $(BUILD) clean + +#--------------------------------------------------------------------------------- +$(BUILD): + @[ -d $@ ] || mkdir -p $@ + @make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile.wii + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).dol + +#--------------------------------------------------------------------------------- +else + +DEPENDS := $(OFILES:.o=.d) + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +$(OUTPUT).dol: $(OUTPUT).elf +$(OUTPUT).elf: $(OFILES) + +#--------------------------------------------------------------------------------- +# This rule links in binary data with the .jpg extension +#--------------------------------------------------------------------------------- +%.gba.o : %.gba +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + $(bin2o) + +-include $(DEPENDS) + +#--------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------- diff --git a/README.md b/README.md index 0d0ac36..6598337 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,6 @@ # gba-link-cable-dumper -a gc and wii homebrew app to dump gba roms via the gc gba link cable +a gc and wii homebrew app to dump gba roms via the gc gba link cable. + +# Usage +just have a gc controller in port 1 and a gba without a game inserted in port 2. +The gba files dumped will be placed in a folder called "dumps" on your main device (sd gecko on gamecube and sd/usb on wii). diff --git a/build.bat b/build.bat new file mode 100644 index 0000000..aece78f --- /dev/null +++ b/build.bat @@ -0,0 +1,10 @@ +cd gba +make clean +make +cd .. +mv -f gba/gba_mb.gba data/gba_mb.gba +make -f Makefile.gc clean +make -f Makefile.gc +make -f Makefile.wii clean +make -f Makefile.wii +pause \ No newline at end of file diff --git a/gba/Makefile b/gba/Makefile new file mode 100644 index 0000000..99dfbb6 --- /dev/null +++ b/gba/Makefile @@ -0,0 +1,168 @@ +#--------------------------------------------------------------------------------- +# Clear the implicit built in rules +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- +ifeq ($(strip $(DEVKITARM)),) +$(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM) +endif + +include $(DEVKITARM)/gba_rules + +#--------------------------------------------------------------------------------- +# TARGET is the name of the output, if this ends with _mb a multiboot image is generated +# BUILD is the directory where object files & intermediate files will be placed +# SOURCES is a list of directories containing source code +# DATA is a list of directories containing data files +# INCLUDES is a list of directories containing header files +#--------------------------------------------------------------------------------- +TARGET := $(shell basename $(CURDIR))_mb +BUILD := build +SOURCES := source +DATA := +GRAPHICS := gfx +INCLUDES := + +#--------------------------------------------------------------------------------- +# options for code generation +#--------------------------------------------------------------------------------- +ARCH := -mthumb -mthumb-interwork + +CFLAGS := -g -Wall -O3\ + -mcpu=arm7tdmi -mtune=arm7tdmi\ + -fomit-frame-pointer\ + -ffast-math \ + $(ARCH) + +CFLAGS += $(INCLUDE) + +CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions + +ASFLAGS := $(ARCH) +LDFLAGS = -g $(ARCH) -Wl,-Map,$(notdir $@).map + +#--------------------------------------------------------------------------------- +# any extra libraries we wish to link with the project +#--------------------------------------------------------------------------------- +LIBS := -lgba + +#--------------------------------------------------------------------------------- +# list of directories containing libraries, this must be the top level containing +# include and lib +#--------------------------------------------------------------------------------- +LIBDIRS := $(LIBGBA) + +#--------------------------------------------------------------------------------- +# no real need to edit anything past this point unless you need to add additional +# rules for different file extensions +#--------------------------------------------------------------------------------- +ifneq ($(BUILD),$(notdir $(CURDIR))) +#--------------------------------------------------------------------------------- + +export OUTPUT := $(CURDIR)/$(TARGET) +export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) + +export DEPSDIR := $(CURDIR)/$(BUILD) + +#--------------------------------------------------------------------------------- +# automatically build a list of object files for our project +#--------------------------------------------------------------------------------- +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)/*.*))) +BMPFILES := $(foreach dir,$(GRAPHICS),$(notdir $(wildcard $(dir)/*.bmp))) + +#--------------------------------------------------------------------------------- +# 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)) \ + $(BMPFILES:.bmp=.o) \ + $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) + +#--------------------------------------------------------------------------------- +# build a list of include paths +#--------------------------------------------------------------------------------- +export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + -I$(CURDIR)/$(BUILD) + +#--------------------------------------------------------------------------------- +# build a list of library paths +#--------------------------------------------------------------------------------- +export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) + +.PHONY: $(BUILD) clean + +#--------------------------------------------------------------------------------- +$(BUILD): + @[ -d $@ ] || mkdir -p $@ + @make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile + +all : $(BUILD) +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr $(BUILD) $(TARGET).elf $(TARGET).gba + +#--------------------------------------------------------------------------------- +else + +DEPENDS := $(OFILES:.o=.d) + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +$(OUTPUT).gba : $(OUTPUT).elf + +$(OUTPUT).elf : $(OFILES) + + +#--------------------------------------------------------------------------------- +# The bin2o rule should be copied and modified +# for each extension used in the data directories +#--------------------------------------------------------------------------------- + +#--------------------------------------------------------------------------------- +# This rule links in binary data with the .bin extension +#--------------------------------------------------------------------------------- +%.bin.o : %.bin +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + @$(bin2o) + +#--------------------------------------------------------------------------------- +# This rule links in binary data with the .raw extension +#--------------------------------------------------------------------------------- +%.raw.o : %.raw +#--------------------------------------------------------------------------------- + @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 : %.bmp %.grit +#--------------------------------------------------------------------------------- + grit $< -fts -o$* + +-include $(DEPENDS) + +#--------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------- diff --git a/gba/source/main.c b/gba/source/main.c new file mode 100644 index 0000000..9d05189 --- /dev/null +++ b/gba/source/main.c @@ -0,0 +1,94 @@ + +#include +#include +#include +#include +#include +#include +#include +#include + +u32 getGameSize(void) +{ + if(*(vu32*)(0x08000004) != 0x51AEFF24) + return 0; + u32 i; + for(i = (1<<20); i < (1<<25); i<<=1) + { + vu16 *rompos = (vu16*)(0x08000000+i); + int j; + bool romend = true; + for(j = 0; j < 0x1000; j++) + { + if(rompos[j] != j) + { + romend = false; + break; + } + } + if(romend) break; + } + return i; +} +//--------------------------------------------------------------------------------- +// Program entry point +//--------------------------------------------------------------------------------- +int main(void) { +//--------------------------------------------------------------------------------- + + // the vblank interrupt must be enabled for VBlankIntrWait() to work + // since the default dispatcher handles the bios flags no vblank handler + // is required + irqInit(); + irqEnable(IRQ_VBLANK); + + consoleDemoInit(); + REG_JOYTR = 0; + // ansi escape sequence to set print co-ordinates + // /x1b[line;columnH + u32 i; + iprintf("\x1b[9;10HROM Dumper\n"); + iprintf("\x1b[10;5HPlease look at the TV\n"); + REG_HS_CTRL |= 6; + while (1) { + if((REG_HS_CTRL&4)) + { + REG_HS_CTRL |= 4; + u32 gamesize = getGameSize(); + REG_JOYTR = gamesize; + while((REG_HS_CTRL&4) == 0) ; + REG_HS_CTRL |= 4; + if(gamesize == 0) + { + REG_JOYTR = 0; + continue; //nothing to read + } + //game in, send header + for(i = 0; i < 0xC0; i+=4) + { + REG_JOYTR = *(vu32*)(0x08000000+i); + while((REG_HS_CTRL&4) == 0) ; + REG_HS_CTRL |= 4; + } + //wait for other side to choose + while((REG_HS_CTRL&2) == 0) ; + REG_HS_CTRL |= 2; + if(REG_JOYRE == 0) + { + REG_JOYTR = 0; + continue; //nothing to read + } + //dump the game + for(i = 0; i < gamesize; i+=4) + { + REG_JOYTR = *(vu32*)(0x08000000+i); + while((REG_HS_CTRL&4) == 0) ; + REG_HS_CTRL |= 4; + } + REG_JOYTR = 0; + } + Halt(); + } +} + + diff --git a/source/main.c b/source/main.c new file mode 100644 index 0000000..afe3423 --- /dev/null +++ b/source/main.c @@ -0,0 +1,400 @@ +/* + * Copyright (C) 2016 FIX94 + * + * This software may be modified and distributed under the terms + * of the MIT license. See the LICENSE file for details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern u8 gba_mb_gba[]; +extern u32 gba_mb_gba_size; + +void printmain() +{ + printf("\x1b[2J"); + printf("\x1b[37m"); + printf("GBA Link Cable Dumper v1.0 by FIX94\n"); +} + +u8 *resbuf,*cmdbuf; +volatile u16 pads = 0; +volatile bool ctrlerr = false; +void ctrlcb(s32 chan, u32 ret) +{ + if(ret) + { + ctrlerr = true; + return; + } + //just call us again + pads = (~((resbuf[1]<<8)|resbuf[0]))&0x3FF; + SI_Transfer(1,cmdbuf,1,resbuf,5,ctrlcb,350); +} + +volatile u32 transval = 0; +void transcb(s32 chan, u32 ret) +{ + transval = 1; +} + +volatile u32 resval = 0; +void acb(s32 res, u32 val) +{ + resval = val; +} + +unsigned int docrc(u32 crc, u32 val) +{ + int i; + for(i = 0; i < 0x20; i++) + { + if((crc^val)&1) + { + crc>>=1; + crc^=0xa1c1; + } + else + crc>>=1; + val>>=1; + } + return crc; +} + +static inline void wait_for_transfer() +{ + //350 is REALLY pushing it already, cant go further + do{ usleep(350); }while(transval == 0); +} + +void endproc() +{ + printf("Start pressed, exit\n"); + VIDEO_WaitVSync(); + VIDEO_WaitVSync(); + exit(0); +} +unsigned int calckey(unsigned int size) +{ + unsigned int ret = 0; + size=(size-0x200) >> 3; + int res1 = (size&0x3F80) << 1; + res1 |= (size&0x4000) << 2; + res1 |= (size&0x7F); + res1 |= 0x380000; + int res2 = res1; + res1 = res2 >> 0x10; + int res3 = res2 >> 8; + res3 += res1; + res3 += res2; + res3 <<= 24; + res3 |= res2; + res3 |= 0x80808080; + + if((res3&0x200) == 0) + { + ret |= (((res3)&0xFF)^0x4B)<<24; + ret |= (((res3>>8)&0xFF)^0x61)<<16; + ret |= (((res3>>16)&0xFF)^0x77)<<8; + ret |= (((res3>>24)&0xFF)^0x61); + } + else + { + ret |= (((res3)&0xFF)^0x73)<<24; + ret |= (((res3>>8)&0xFF)^0x65)<<16; + ret |= (((res3>>16)&0xFF)^0x64)<<8; + ret |= (((res3>>24)&0xFF)^0x6F); + } + return ret; +} +void doreset() +{ + cmdbuf[0] = 0xFF; //reset + transval = 0; + SI_Transfer(1,cmdbuf,1,resbuf,3,transcb,0); + wait_for_transfer(); +} +void getstatus() +{ + cmdbuf[0] = 0; //status + transval = 0; + SI_Transfer(1,cmdbuf,1,resbuf,3,transcb,0); + wait_for_transfer(); +} +u32 recvsafe() +{ + memset(resbuf,0,32); + cmdbuf[0]=0x14; //read + transval = 0; + SI_Transfer(1,cmdbuf,1,resbuf,5,transcb,0); + wait_for_transfer(); + return *(vu32*)resbuf; +} +void sendsafe(u32 msg) +{ + cmdbuf[0]=0x15;cmdbuf[1]=(msg>>0)&0xFF;cmdbuf[2]=(msg>>8)&0xFF; + cmdbuf[3]=(msg>>16)&0xFF;cmdbuf[4]=(msg>>24)&0xFF; + transval = 0; + resbuf[0] = 0; + SI_Transfer(1,cmdbuf,5,resbuf,1,transcb,0); + wait_for_transfer(); +} +u32 recvfast() +{ + cmdbuf[0]=0x14; //read + transval = 0; + SI_Transfer(1,cmdbuf,1,resbuf,5,transcb,0); + usleep(275); + while(transval == 0) ; + return *(vu32*)resbuf; +} +bool dirExists(const char *path) +{ + DIR *dir; + dir = opendir(path); + if(dir) + { + closedir(dir); + return true; + } + return false; +} +int main(int argc, char *argv[]) +{ + void *xfb = NULL; + GXRModeObj *rmode = NULL; + VIDEO_Init(); + rmode = VIDEO_GetPreferredMode(NULL); + xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode)); + VIDEO_Configure(rmode); + VIDEO_SetNextFramebuffer(xfb); + VIDEO_SetBlack(FALSE); + VIDEO_Flush(); + VIDEO_WaitVSync(); + if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync(); + int x = 24, y = 32, w, h; + w = rmode->fbWidth - (32); + h = rmode->xfbHeight - (48); + CON_InitEx(rmode, x, y, w, h); + VIDEO_ClearFrameBuffer(rmode, xfb, COLOR_BLACK); + PAD_Init(); + cmdbuf = memalign(32,32); + resbuf = memalign(32,32); + u8 *testdump = memalign(32,0x400000); + if(!testdump) return 0; + if(!fatInitDefault()) + { + printmain(); + printf("ERROR: No usable device found to write dumped files to!\n"); + VIDEO_WaitVSync(); + VIDEO_WaitVSync(); + sleep(5); + exit(0); + } + mkdir("/dumps", S_IREAD | S_IWRITE); + if(!dirExists("/dumps")) + { + printmain(); + printf("ERROR: Could not create dumps folder, make sure you have a supported device connected!\n"); + VIDEO_WaitVSync(); + VIDEO_WaitVSync(); + sleep(5); + exit(0); + } + int i; + while(1) + { + printmain(); + printf("Waiting for a GBA in port 2...\n"); + resval = 0; + ctrlerr = false; + + SI_GetTypeAsync(1,acb); + while(1) + { + if(resval) + { + if(resval == 0x80 || resval & 8) + { + resval = 0; + SI_GetTypeAsync(1,acb); + } + else if(resval) + break; + } + PAD_ScanPads(); + VIDEO_WaitVSync(); + if(PAD_ButtonsHeld(0)) + endproc(); + } + if(resval & SI_GBA) + { + printf("GBA Found! Waiting on BIOS\n"); + resbuf[2]=0; + while(!(resbuf[2]&0x10)) + { + doreset(); + getstatus(); + } + printf("Ready, sending dumper\n"); + unsigned int sendsize = ((gba_mb_gba_size+7)&~7); + unsigned int ourkey = calckey(sendsize); + //printf("Our Key: %08x\n", ourkey); + //get current sessionkey + u32 sessionkeyraw = recvsafe(); + u32 sessionkey = __builtin_bswap32(sessionkeyraw^0x7365646F); + //send over our own key + sendsafe(__builtin_bswap32(ourkey)); + unsigned int fcrc = 0x15a0; + //send over gba header + for(i = 0; i < 0xC0; i+=4) + { + sendsafe(__builtin_bswap32(*(vu32*)(gba_mb_gba+i))); + if(!(resbuf[0]&0x2)) printf("Possible error %02x\n",resbuf[0]); + } + //printf("Header done! Sending ROM...\n"); + for(i = 0xC0; i < sendsize; i+=4) + { + u32 enc = ((gba_mb_gba[i+3]<<24)|(gba_mb_gba[i+2]<<16)|(gba_mb_gba[i+1]<<8)|(gba_mb_gba[i])); + fcrc=docrc(fcrc,enc); + sessionkey = (sessionkey*0x6177614B)+1; + enc^=sessionkey; + enc^=((~(i+(0x20<<20)))+1); + enc^=0x20796220; + sendsafe(enc); + if(!(resbuf[0]&0x2)) printf("Possible error %02x\n",resbuf[0]); + } + fcrc |= (sendsize<<16); + //printf("ROM done! CRC: %08x\n", fcrc); + //send over CRC + sessionkey = (sessionkey*0x6177614B)+1; + fcrc^=sessionkey; + fcrc^=((~(i+(0x20<<20)))+1); + fcrc^=0x20796220; + sendsafe(fcrc); + //get crc back (unused) + recvsafe(); + printf("Done!\n"); + sleep(2); + //hm + while(1) + { + printmain(); + printf("Press A once you have a GBA Game inserted.\n \n"); + PAD_ScanPads(); + VIDEO_WaitVSync(); + u32 btns = PAD_ButtonsDown(0); + if(btns&PAD_BUTTON_START) + endproc(); + else if(btns&PAD_BUTTON_A) + { + if(recvsafe() == 0) //ready + { + sleep(1); //gba rom prepare + u32 gbasize = __builtin_bswap32(recvsafe()); + if(gbasize == 0) + { + printf("ERROR: No (Valid) GBA Card inserted!\n"); + VIDEO_WaitVSync(); + VIDEO_WaitVSync(); + sleep(2); + continue; + } + for(i = 0; i < 0xC0; i+=4) + *(vu32*)(testdump+i) = recvfast(); + printf("Game Name: %.12s\n",(char*)(testdump+0xA0)); + printf("Game ID: %.4s\n",(char*)(testdump+0xAC)); + printf("Company ID: %.2s\n",(char*)(testdump+0xB0)); + printf("ROM Size: %02.02f MB\n \n",((float)(gbasize/1024))/1024.f); + char gamename[64]; + sprintf(gamename,"/dumps/%.12s [%.4s%.2s].gba", + (char*)(testdump+0xA0),(char*)(testdump+0xAC),(char*)(testdump+0xB0)); + FILE *f = fopen(gamename,"rb"); + if(f) + { + fclose(f); + sendsafe(0); + printf("ERROR: Game already dumped! Please insert another game.\n"); + VIDEO_WaitVSync(); + VIDEO_WaitVSync(); + sleep(2); + continue; + } + printf("Press A to dump this game, it will take about %i minutes.\n",gbasize/1024/1024*3/2); + printf("Press B if you want to cancel dumping this game.\n\n"); + int dumping = 0; + while(1) + { + PAD_ScanPads(); + VIDEO_WaitVSync(); + u32 btns = PAD_ButtonsDown(0); + if(btns&PAD_BUTTON_START) + endproc(); + else if(btns&PAD_BUTTON_A) + { + dumping = 1; + break; + } + else if(btns&PAD_BUTTON_B) + break; + } + sendsafe(dumping); + if(dumping == 0) + continue; + //create base file with size + printf("Creating file...\n"); + int fd = open(gamename, O_WRONLY|O_CREAT); + if(fd >= 0) + { + ftruncate(fd, gbasize); + close(fd); + } + f = fopen(gamename,"wb"); + if(!f) + { + printf("ERROR: Could not create file! Exit...\n"); + VIDEO_WaitVSync(); + VIDEO_WaitVSync(); + sleep(5); + exit(0); + } + printf("Dumping...\n"); + u32 bytes_read = 0; + while(gbasize > 0) + { + int toread = (gbasize > 0x400000 ? 0x400000 : gbasize); + int j; + for(j = 0; j < toread; j+=4) + { + *(vu32*)(testdump+j) = recvfast(); + bytes_read+=4; + if((bytes_read&0xFFFF) == 0) + { + printf("\r%02.02f MB done",(float)(bytes_read/1024)/1024.f); + VIDEO_WaitVSync(); + } + //printf("%02x%02x%02x%02x",resbuf[0],resbuf[1],resbuf[2],resbuf[3]); + } + fwrite(testdump,toread,1,f); + gbasize -= toread; + } + printf("\nClosing file\n"); + fclose(f); + printf("Game dumped!\n"); + sleep(5); + } + } + } + } + } + return 0; +} -- cgit 1.4.1