Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
InvoxiPlayGames committed Jul 30, 2023
0 parents commit aaac11a
Show file tree
Hide file tree
Showing 15 changed files with 1,094 additions and 0 deletions.
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# payload artifacts
*.bin
*.elf
*.o
*.gci
# executable artifacts
*.exe
gci_builder
*.dSYM
# other stuff
*.zip
339 changes: 339 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

29 changes: 29 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
GCIBUILDER := gci_builder
ifeq ($(OS),Windows_NT)
GCIBUILDER := $(addsuffix .exe,$(GCIBUILDER))
endif

PAYLOAD_DIR := gc_payload
GCI_BUILDER_DIR := gci_builder_src

.PHONY: $(GCIBUILDER) payload_bins eur usa clean
all: eur usa

$(GCIBUILDER):
@$(MAKE) -C $(GCI_BUILDER_DIR)
@cp $(GCI_BUILDER_DIR)/$(GCIBUILDER) $(GCIBUILDER)

payload_bins:
@$(MAKE) -C $(PAYLOAD_DIR)

eur: payload_bins $(GCIBUILDER)
@./$(GCIBUILDER) $(PAYLOAD_DIR)/robohaxx-EUR.bin E

usa: payload_bins $(GCIBUILDER)
@./$(GCIBUILDER) $(PAYLOAD_DIR)/robohaxx-USA.bin U

clean:
@$(MAKE) -C $(PAYLOAD_DIR) clean
@$(MAKE) -C $(GCI_BUILDER_DIR) clean
@-rm $(GCIBUILDER)
@-rm *.gci
45 changes: 45 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# robohaxx: stackcry

A savegame exploit / homebrew entrypoint for the game Robotech: Battlecry on the GameCube.

Compatible with both USA and EUR revisions of the game. (Only USA has been tested on real GC hardware.)

["it's a stack overflow in the profile name on a 6th gen console game"](https://tenor.com/view/buzz-lightyear-factory-you-will-never-find-another-store-shelf-a-bunch-of-buzz-lightyears-gif-21719996) (Tenor GIF link)

## How to Use

1. Copy the .gci file for your region from [the robohaxx releases page](https://github.com/InvoxiPlayGames/robohaxx/releases)
to your Memory Card using [GCMM](https://github.com/suloku/gcmm/releases).
* While you're here, make sure you have the latest Swiss boot GCI, too. (Or any other boot.dol.)
* Ensure there are **NO** other savegames for Robotech: Battlecry on the memory card.
2. Launch Robotech: Battlecry.
3. At the main menu, select the "Load Game" option.
4. Afetr a few seconds, Swiss (or any other homebrew) *should* load!

## Credits

Thank you to [FIX94](https://github.com/FIX94) for the gc-exploit-common-loader DOL loader, and for
example code for memory card loaders in other GC savegame exploits.

Thanks to [Essem](https://github.com/TheEssem) for testing on real hardware, and being the inspiration behind this
[by just wanting a way to launch Swiss that isn't Animal Crossing.](https://wetdry.world/@esm/110792836912696997)

## Building from Source

The source has two components, the memory card loader and the GCI builder. The memory card loader will
build if you have devkitPPC installed (although any powerpc-eabi GCC will work, change the Makefile).

The GCI builder should build on any macOS/Linux system, and should be fine building under MingW64 on Windows.

The Makefile in the root of the repository will compile the memcard loader for EUR and USA regions,
compile the GCI builder, and then build the robohaxx GCI savefiles. Type `make` at a terminal.

If you only want to build for a specific region, type `make usa` or `make eur`.

## License

The memory card loader and GCI builder are licensed under the GNU General Public License version 2. See attached
LICENSE file for more details.

This chain uses FIX94's [gc-exploit-common-loader](https://github.com/FIX94/gc-exploit-common-loader), also licensed
under GPLv2.
49 changes: 49 additions & 0 deletions gc_payload/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# What toolchain prefix should we use
# Most people who want to build this will have failkit already
CROSS ?= $(DEVKITPPC)/bin/powerpc-eabi-

# Set CC, LD, OBJCOPY based on CROSS, unless they are set already
ifeq ($(origin CC), default)
CC := $(CROSS)gcc -m32
endif
ifeq ($(origin LD), default)
LD := $(CROSS)ld
endif
OBJCOPY ?= $(CROSS)objcopy

CFLAGS := -Wall -W -O1 -ffreestanding -mno-eabi -mno-sdata -fno-asynchronous-unwind-tables -mcpu=750
Q :=

SOURCES := memcard_loader.c
OBJS := $(SOURCES:.c=.o)

.PHONY: usa eur
all: usa eur

usa: robohaxx-USA.bin

eur: robohaxx-EUR.bin

robohaxx-USA.bin: robohaxx-USA.elf
@echo " OBJCOPY $@"
$(Q)$(OBJCOPY) -Obinary $< $@

robohaxx-USA.elf: $(OBJS)
@echo " LINK $@"
$(Q)$(LD) -T robohaxx-USA.ld $^ -o $@

robohaxx-EUR.bin: robohaxx-EUR.elf
@echo " OBJCOPY $@"
$(Q)$(OBJCOPY) -Obinary $< $@

robohaxx-EUR.elf: $(OBJS)
@echo " LINK $@"
$(Q)$(LD) -T robohaxx-EUR.ld $^ -o $@

$(OBJS): $(SOURCES)
@echo " COMPILE $@"
$(Q)$(CC) $(CFLAGS) -c $< -o $@

clean:
@echo " CLEAN"
@-rm -f $(OBJS) robohaxx-EUR.elf robohaxx-EUR.bin robohaxx-USA.elf robohaxx-USA.bin
87 changes: 87 additions & 0 deletions gc_payload/loader.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
Compiled version of FIX94's gc-exploit-common-loader DOL loading code.
Source code is included within "loader.tar.gz". Also available on GitHub:
https://github.com/FIX94/gc-exploit-common-loader
Licensed under the GNU GPL version 2: http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*/

#define loader_size 0x4bc

const unsigned char loader[] = {
0x7C, 0x60, 0x00, 0xA6, 0x54, 0x63, 0x04, 0x5E, 0x60, 0x63, 0x20, 0x00, 0x7C, 0x60, 0x01, 0x24,
0x4C, 0x00, 0x01, 0x2C, 0x3C, 0x20, 0x80, 0x00, 0x38, 0x21, 0x26, 0xC0, 0x38, 0x00, 0x00, 0x00,
0x94, 0x01, 0xFF, 0xC0, 0x3C, 0x60, 0x80, 0x00, 0x38, 0x63, 0x1C, 0xBC, 0x38, 0x80, 0x00, 0x00,
0x3C, 0xA0, 0x80, 0x00, 0x38, 0xA5, 0x1E, 0xC0, 0x7C, 0xA3, 0x28, 0x50, 0x48, 0x00, 0x00, 0xAD,
0x48, 0x00, 0x02, 0xB0, 0x39, 0x44, 0x00, 0x1F, 0x7D, 0x4A, 0x1A, 0x14, 0x55, 0x4A, 0x00, 0x34,
0x54, 0x69, 0x00, 0x34, 0x7D, 0x29, 0x50, 0x50, 0x55, 0x29, 0xD9, 0x7F, 0x41, 0x82, 0x00, 0x1C,
0x7D, 0x29, 0x03, 0xA6, 0x7C, 0x00, 0x18, 0x6C, 0x7C, 0x00, 0x1F, 0xAC, 0x38, 0x63, 0x00, 0x20,
0x39, 0x29, 0xFF, 0xFF, 0x42, 0x00, 0xFF, 0xF0, 0x7C, 0x00, 0x04, 0xAC, 0x4C, 0x00, 0x01, 0x2C,
0x4E, 0x80, 0x00, 0x20, 0x54, 0x8A, 0x84, 0x3E, 0x3D, 0x20, 0xCC, 0x00, 0x61, 0x29, 0x50, 0x20,
0xB1, 0x49, 0x00, 0x00, 0x39, 0x29, 0x00, 0x02, 0xB0, 0x89, 0x00, 0x00, 0x54, 0xAA, 0x84, 0x3E,
0x39, 0x29, 0x00, 0x02, 0xB1, 0x49, 0x00, 0x00, 0x39, 0x29, 0x00, 0x02, 0xB0, 0xA9, 0x00, 0x00,
0x54, 0x63, 0x78, 0x20, 0x54, 0xC9, 0x84, 0x3E, 0x7C, 0x63, 0x4B, 0x78, 0x3D, 0x20, 0xCC, 0x00,
0x61, 0x29, 0x50, 0x28, 0xB0, 0x69, 0x00, 0x00, 0x39, 0x29, 0x00, 0x02, 0xB0, 0xC9, 0x00, 0x00,
0x3D, 0x40, 0xCC, 0x00, 0x61, 0x4A, 0x50, 0x0A, 0xA1, 0x2A, 0x00, 0x00, 0x71, 0x29, 0x02, 0x00,
0x40, 0x82, 0xFF, 0xF8, 0x4E, 0x80, 0x00, 0x20, 0x2C, 0x05, 0x00, 0x00, 0x4D, 0x82, 0x00, 0x20,
0x39, 0x23, 0xFF, 0xFF, 0x7C, 0xA9, 0x03, 0xA6, 0x9C, 0x89, 0x00, 0x01, 0x38, 0xA5, 0xFF, 0xFF,
0x42, 0x00, 0xFF, 0xF8, 0x4E, 0x80, 0x00, 0x20, 0x2C, 0x05, 0x00, 0x00, 0x4D, 0x82, 0x00, 0x20,
0x38, 0x84, 0xFF, 0xFF, 0x39, 0x23, 0xFF, 0xFF, 0x7C, 0xA9, 0x03, 0xA6, 0x8D, 0x44, 0x00, 0x01,
0x9D, 0x49, 0x00, 0x01, 0x38, 0xA5, 0xFF, 0xFF, 0x42, 0x00, 0xFF, 0xF4, 0x4E, 0x80, 0x00, 0x20,
0x94, 0x21, 0xFF, 0xD0, 0x7C, 0x08, 0x02, 0xA6, 0x90, 0x01, 0x00, 0x34, 0x7D, 0x80, 0x00, 0x26,
0x93, 0x61, 0x00, 0x1C, 0x93, 0x81, 0x00, 0x20, 0x93, 0xA1, 0x00, 0x24, 0x93, 0xC1, 0x00, 0x28,
0x93, 0xE1, 0x00, 0x2C, 0x91, 0x81, 0x00, 0x0C, 0x7C, 0x7D, 0x1B, 0x78, 0x7C, 0x9E, 0x23, 0x78,
0x54, 0xBC, 0x00, 0x2C, 0x70, 0xBB, 0x01, 0xFF, 0x40, 0x82, 0x00, 0x40, 0x2C, 0x1E, 0x00, 0x00,
0x41, 0x82, 0x01, 0x54, 0x93, 0x01, 0x00, 0x10, 0x93, 0x21, 0x00, 0x14, 0x93, 0x41, 0x00, 0x18,
0x3F, 0x40, 0x80, 0x00, 0x3B, 0x5A, 0x1C, 0xC0, 0x3B, 0x7A, 0x02, 0x1F, 0x57, 0x7B, 0x00, 0x34,
0x7F, 0x7A, 0xD8, 0x50, 0x57, 0x7B, 0xD9, 0x7E, 0x2E, 0x1B, 0x00, 0x00, 0x3F, 0x00, 0x80, 0x00,
0x7F, 0x59, 0xD3, 0x78, 0x48, 0x00, 0x00, 0xC8, 0x7C, 0xBF, 0x2B, 0x78, 0x3C, 0x80, 0x80, 0x00,
0x38, 0x84, 0x1C, 0xC0, 0x39, 0x44, 0x02, 0x1F, 0x55, 0x4A, 0x00, 0x34, 0x7D, 0x44, 0x50, 0x50,
0x55, 0x4A, 0xD9, 0x7F, 0x41, 0x82, 0x00, 0x1C, 0x7C, 0x89, 0x23, 0x78, 0x7D, 0x49, 0x03, 0xA6,
0x7C, 0x00, 0x48, 0xAC, 0x39, 0x29, 0x00, 0x20, 0x39, 0x4A, 0xFF, 0xFF, 0x42, 0x00, 0xFF, 0xF4,
0x7C, 0x00, 0x04, 0xAC, 0x38, 0xC0, 0x02, 0x00, 0x7F, 0x85, 0xE3, 0x78, 0x38, 0x60, 0x00, 0x01,
0x4B, 0xFF, 0xFE, 0x95, 0x7F, 0xC9, 0xF3, 0x78, 0x28, 0x1E, 0x02, 0x00, 0x40, 0x81, 0x00, 0x08,
0x39, 0x20, 0x02, 0x00, 0x7F, 0xFF, 0xE0, 0x50, 0x7F, 0xE9, 0xFA, 0x14, 0x7F, 0xE5, 0xFB, 0x78,
0x3C, 0x80, 0x80, 0x00, 0x38, 0x84, 0x1C, 0xC0, 0x7C, 0x84, 0xDA, 0x14, 0x7F, 0xA3, 0xEB, 0x78,
0x4B, 0xFF, 0xFE, 0xE9, 0x7F, 0xE4, 0xFB, 0x78, 0x7F, 0xA3, 0xEB, 0x78, 0x4B, 0xFF, 0xFE, 0x19,
0x3B, 0x9C, 0x02, 0x00, 0x7F, 0xBD, 0xFA, 0x14, 0x7F, 0xDF, 0xF0, 0x50, 0x4B, 0xFF, 0xFF, 0x30,
0x7F, 0xE5, 0xFB, 0x78, 0x7F, 0x24, 0xCB, 0x78, 0x7F, 0xA3, 0xEB, 0x78, 0x4B, 0xFF, 0xFE, 0xBD,
0x7F, 0xE4, 0xFB, 0x78, 0x7F, 0xA3, 0xEB, 0x78, 0x4B, 0xFF, 0xFD, 0xED, 0x3B, 0x9C, 0x02, 0x00,
0x7F, 0xBD, 0xFA, 0x14, 0x7F, 0xDF, 0xF0, 0x51, 0x41, 0x82, 0x00, 0x50, 0x41, 0x92, 0x00, 0x20,
0x7F, 0x6A, 0xDB, 0x78, 0x39, 0x38, 0x1C, 0xC0, 0x7F, 0x69, 0x03, 0xA6, 0x7C, 0x00, 0x48, 0xAC,
0x39, 0x29, 0x00, 0x20, 0x39, 0x4A, 0xFF, 0xFF, 0x42, 0x00, 0xFF, 0xF4, 0x7C, 0x00, 0x04, 0xAC,
0x38, 0xC0, 0x02, 0x00, 0x7F, 0x85, 0xE3, 0x78, 0x7F, 0x44, 0xD3, 0x78, 0x38, 0x60, 0x00, 0x01,
0x4B, 0xFF, 0xFD, 0xE5, 0x7F, 0xDF, 0xF3, 0x78, 0x28, 0x1E, 0x02, 0x00, 0x40, 0xA1, 0xFF, 0x94,
0x3B, 0xE0, 0x02, 0x00, 0x4B, 0xFF, 0xFF, 0x8C, 0x83, 0x01, 0x00, 0x10, 0x83, 0x21, 0x00, 0x14,
0x83, 0x41, 0x00, 0x18, 0x80, 0x01, 0x00, 0x34, 0x81, 0x81, 0x00, 0x0C, 0x7C, 0x08, 0x03, 0xA6,
0x83, 0x61, 0x00, 0x1C, 0x83, 0x81, 0x00, 0x20, 0x83, 0xA1, 0x00, 0x24, 0x83, 0xC1, 0x00, 0x28,
0x83, 0xE1, 0x00, 0x2C, 0x7D, 0x80, 0x81, 0x20, 0x38, 0x21, 0x00, 0x30, 0x4E, 0x80, 0x00, 0x20,
0x94, 0x21, 0xFE, 0xF0, 0x7C, 0x08, 0x02, 0xA6, 0x90, 0x01, 0x01, 0x14, 0x93, 0xA1, 0x01, 0x04,
0x93, 0xC1, 0x01, 0x08, 0x93, 0xE1, 0x01, 0x0C, 0x3C, 0x80, 0x80, 0x00, 0x38, 0x84, 0x1C, 0xC0,
0x39, 0x44, 0x02, 0x1F, 0x55, 0x4A, 0x00, 0x34, 0x7D, 0x44, 0x50, 0x50, 0x55, 0x4A, 0xD9, 0x7F,
0x41, 0x82, 0x00, 0x1C, 0x7C, 0x89, 0x23, 0x78, 0x7D, 0x49, 0x03, 0xA6, 0x7C, 0x00, 0x48, 0xAC,
0x39, 0x29, 0x00, 0x20, 0x39, 0x4A, 0xFF, 0xFF, 0x42, 0x00, 0xFF, 0xF4, 0x7C, 0x00, 0x04, 0xAC,
0x38, 0xC0, 0x02, 0x00, 0x38, 0xA0, 0x00, 0x00, 0x38, 0x60, 0x00, 0x01, 0x4B, 0xFF, 0xFD, 0x39,
0x38, 0xA0, 0x00, 0xE4, 0x3C, 0x80, 0x80, 0x00, 0x38, 0x84, 0x1C, 0xC0, 0x38, 0x61, 0x00, 0x08,
0x4B, 0xFF, 0xFD, 0xA9, 0x3B, 0xE1, 0x00, 0x08, 0x7F, 0xFE, 0xFB, 0x78, 0x3B, 0xA0, 0x00, 0x07,
0x48, 0x00, 0x00, 0x10, 0x3B, 0xDE, 0x00, 0x04, 0x37, 0xBD, 0xFF, 0xFF, 0x41, 0x82, 0x00, 0x28,
0x80, 0x9E, 0x00, 0x90, 0x2C, 0x04, 0x00, 0x00, 0x41, 0xA2, 0xFF, 0xEC, 0x80, 0x7E, 0x00, 0x48,
0x28, 0x03, 0x00, 0xFF, 0x40, 0xA1, 0xFF, 0xE0, 0x80, 0xBE, 0x00, 0x00, 0x4B, 0xFF, 0xFD, 0x95,
0x4B, 0xFF, 0xFF, 0xD4, 0x3B, 0xC0, 0x00, 0x0B, 0x48, 0x00, 0x00, 0x10, 0x3B, 0xFF, 0x00, 0x04,
0x37, 0xDE, 0xFF, 0xFF, 0x41, 0x82, 0x00, 0x28, 0x80, 0x9F, 0x00, 0xAC, 0x2C, 0x04, 0x00, 0x00,
0x41, 0xA2, 0xFF, 0xEC, 0x80, 0x7F, 0x00, 0x64, 0x28, 0x03, 0x00, 0xFF, 0x40, 0xA1, 0xFF, 0xE0,
0x80, 0xBF, 0x00, 0x1C, 0x4B, 0xFF, 0xFD, 0x5D, 0x4B, 0xFF, 0xFF, 0xD4, 0x81, 0x21, 0x00, 0xE8,
0x7D, 0x28, 0x03, 0xA6, 0x4E, 0x80, 0x00, 0x20, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
0x01, 0x7A, 0x52, 0x00, 0x04, 0x7C, 0x41, 0x01, 0x1B, 0x0C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
0x00, 0x00, 0x00, 0x18, 0xFF, 0xFF, 0xFC, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x2C, 0xFF, 0xFF, 0xFC, 0x6C, 0x00, 0x00, 0x00, 0x64,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x40, 0xFF, 0xFF, 0xFC, 0xBC,
0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x54,
0xFF, 0xFF, 0xFC, 0xC8, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4C,
0x00, 0x00, 0x00, 0x68, 0xFF, 0xFF, 0xFC, 0xDC, 0x00, 0x00, 0x01, 0xC0, 0x00, 0x41, 0x0E, 0x30,
0x49, 0x11, 0x41, 0x7F, 0x9B, 0x05, 0x9C, 0x04, 0x9D, 0x03, 0x9E, 0x02, 0x9F, 0x01, 0x05, 0x46,
0x09, 0x48, 0x0A, 0x98, 0x08, 0x41, 0x99, 0x07, 0x41, 0x9A, 0x06, 0x4A, 0x0B, 0x66, 0x98, 0x08,
0x99, 0x07, 0x9A, 0x06, 0x5F, 0xD8, 0x41, 0xD9, 0x41, 0xDA, 0x42, 0x09, 0x46, 0x0C, 0x41, 0x06,
0x41, 0x46, 0x06, 0x46, 0x41, 0xDF, 0xDE, 0xDD, 0xDC, 0xDB, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x1C,
0x00, 0x00, 0x00, 0xB8, 0xFF, 0xFF, 0xFE, 0x4C, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x41, 0x0E, 0x90,
0x02, 0x45, 0x11, 0x41, 0x7F, 0x9D, 0x03, 0x9E, 0x02, 0x9F, 0x01, 0x00
};
Binary file added gc_payload/loader.tar.gz
Binary file not shown.
109 changes: 109 additions & 0 deletions gc_payload/memcard_loader.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
memcard_loader, a memory card boot.dol loader payload, for the robohaxx exploit
Copyright 2023 Emma / InvoxiPlayGames
This code is licensed to you under the terms of the GNU GPL, version 2;
see file LICENSE or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*/

#include "loader.h"

#define WORK_ADDR 0x80001800
#define VirtToPhys(x) (x & 0x017FFFFF)

#define CARD_A 0
#define CARD_B 1

typedef unsigned int u32;
typedef unsigned short u16;
typedef unsigned char u8;
typedef volatile unsigned int vu32;
typedef volatile unsigned short vu16;

// structure for an opened file from the card
typedef struct _CARDFileInfo {
int channel;
int file_num;
int offset;
int length;
u16 block;
} CARDFileInfo;
// structure for the file status returned by CARDGetStatus
typedef struct _CARDFileStatus {
char name[0x20];
int length;
char unk[0x2C];
} CARDFileStatus;

// funcs from the game that we need
extern u32 OSDisableInterrupts(void);
extern void __OSStopAudioSystem(void);
extern void GXDrawDone(void);
extern u32 DCFlushRange(void *address, u32 size);
extern int CARDGetStatus(int card, int file_num, CARDFileStatus *status);
extern int CARDFastOpen(int card, int file_num, CARDFileInfo *info);
extern int CARDRead(CARDFileInfo *info, void *address, int length, int offset);
extern int CARDClose(CARDFileInfo *info);
extern int CARDUnmount(int card);
extern void *_memcpy(void *dest, void *src, u32 size);
extern int _memcmp(void *buf1, void *buf2, u32 len);

// DMA to ARAM, this is inlined just to make my life easier
// it's only used in one loop, should be fine
static inline void ARAM_DMA(u32 direction, u32 mram, u32 aram, u32 len) {
*(vu16 *)0xCC005020 = (mram >> 16);
*(vu16 *)0xCC005022 = (mram & 0xFFFF);
*(vu16 *)0xCC005024 = (aram >> 16);
*(vu16 *)0xCC005026 = (aram & 0xFFFF);
*(vu16 *)0xCC005028 = (direction << 15) | (direction >> 16);
*(vu16 *)0xCC00502A = (len & 0xFFFF);
while (*(vu16 *)0xCC00500A & 0x200);
}

void _start() {
CARDFileInfo fileInfo;
CARDFileStatus fileStatus;
u32 readOffset = 0;
int i = 0;

// get game to shut up
OSDisableInterrupts();
__OSStopAudioSystem();
GXDrawDone();

// set gameid in RAM to DOLX00 so we can load the boot.dol save
*(vu32 *)0x80000000 = 0x444F4C58;
*(vu16 *)0x80000004 = 0x3030;
DCFlushRange((void*)0x80000000, 0x20);

// find boot.dol on the memory card and open it
for (i = 0; i < 127; i++) {
if (CARDGetStatus(CARD_A, i, &fileStatus) != 0)
continue;
if (_memcmp(fileStatus.name, "boot.dol", 9) == 0)
break;
}
CARDFastOpen(CARD_A, i, &fileInfo);
// continually read it until we get an error, copying into ARAM
while (CARDRead(&fileInfo, (void*)WORK_ADDR, 0x200, readOffset) == 0) {
DCFlushRange((void*)WORK_ADDR, 0x200);
ARAM_DMA(0, VirtToPhys(WORK_ADDR), readOffset, 0x200);
readOffset += 0x200;
}
// unmount the card, we're done
CARDClose(&fileInfo);
CARDUnmount(CARD_A);

// copy the DOL loader into the spare interrupt vectors
_memcpy((void*)WORK_ADDR, (void*)loader, loader_size);
DCFlushRange((void*)WORK_ADDR, loader_size);
// jump! (if WORK_ADDR is changed, change this too)
__asm__ volatile(
"lis 3, 0x8000\n"
"ori 3, 3, 0x1800\n"
"mtlr 3\n"
"blr\n"
);

// gcc, we shouldn't be here
__builtin_unreachable();
}
28 changes: 28 additions & 0 deletions gc_payload/robohaxx-EUR.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
OUTPUT_FORMAT("elf32-powerpc")
OUTPUT_ARCH(powerpc:common)

SECTIONS {
/* Game functions (GRBP6S) */
OSDisableInterrupts = 0x80026c6c;
__OSStopAudioSystem = 0x80024958;
GXDrawDone = 0x8001c8cc;
DCFlushRange = 0x80024a70;
CARDGetStatus = 0x80012ca4;
CARDFastOpen = 0x80011b4c;
CARDRead = 0x800124d0;
CARDClose = 0x80011cac;
CARDUnmount = 0x8001118c;
_memcpy = 0x80003490;
_memcmp = 0x80032350;

/* Space right after profile name in memory after save file is loaded. */
. = 0x80E37750;
.robohaxx 0x80E37750+0 :
{
*.o(.start)
*(.text)
*(.rodata .rodata.*)
*(.data)
*(.bss)
}
}
28 changes: 28 additions & 0 deletions gc_payload/robohaxx-USA.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
OUTPUT_FORMAT("elf32-powerpc")
OUTPUT_ARCH(powerpc:common)

SECTIONS {
/* Game functions (GRBE6S) */
OSDisableInterrupts = 0x800255B0;
__OSStopAudioSystem = 0x80023574;
GXDrawDone = 0x8001AD28;
DCFlushRange = 0x80023690;
CARDGetStatus = 0x80011920;
CARDFastOpen = 0x800107C8;
CARDRead = 0x8001114C;
CARDClose = 0x80010928;
CARDUnmount = 0x8000FDFC;
_memcpy = 0x80003490;
_memcmp = 0x8002F4FC;

/* Space right after profile name in memory after save file is loaded. */
. = 0x80E20370;
.robohaxx 0x80E20370+0 :
{
*.o(.start)
*(.text)
*(.rodata .rodata.*)
*(.data)
*(.bss)
}
}
Loading

0 comments on commit aaac11a

Please sign in to comment.