diff --git a/Makefile b/Makefile index 858df44..ddeddc3 100644 --- a/Makefile +++ b/Makefile @@ -183,7 +183,9 @@ $(shell touch $(CURDIR)/../$(SOURCES)/version.h) %.gba: %.elf @$(OBJCOPY) -O binary $< $@ @gbafix $@ "-tLK MULTIMENU" "-cAGBJ" "-mLK" "-r0" + @echo Copying to ROM builder folder @cp $@ "$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))/rom_builder/lk_multimenu.gba" + @echo Done! #--------------------------------------------------------------------------------------- endif diff --git a/README.md b/README.md index e3449c1..aece7ce 100644 --- a/README.md +++ b/README.md @@ -20,8 +20,9 @@ The following section must be edited in order to specify the cartridge type to u }, ``` Set `type` to `1` or `2`: -- `1` = MSP55LV100S (e.g. The Legend of Zelda Collection - Classic Edition 7-in-1) -- `2` = 6600M0U0BE (e.g. 369IN1 2048M) +- `1` = MSP55LV100S (e.g. The Legend of Zelda Collection - Classic Edition 7-in-1, 64 MiB) +- `2` = 6600M0U0BE (e.g. 369IN1 2048M, 256 MiB) +- `3` = MSP54LV100 (e.g. The Legend of Zelda Collection - Classic Edition 7-in-1, 128 MiB) Set `battery_present` to `true` or `false`. This will enable enhanced save data handling which will only be functional with a working battery. @@ -76,13 +77,14 @@ If the cartridge has no battery installed, the ROMs must be patched for batteryl ## Compatibility Tested repro cartridges: -- 100BS6600_48BALL_V4 with 6600M0U0BE - 100SOP with MSP55LV100S +- 100BS6600_48BALL_V4 with 6600M0U0BE +- SUN100S_MSP54_XXX_BGA48 with MSP54LV100 The generated compilation ROM can be written and read using a [GBxCart RW v1.4+](https://www.gbxcart.com/) device by insideGadgets and the [FlashGBX](https://github.com/lesserkuma/FlashGBX) software. ## Thanks -Thanks to FraX, Ausar, liuyunx, BennVenn +Thanks to FraX, Ausar, liuyunx, BennVenn, Jenetrix ## Screenshots diff --git a/rom_builder/rom_builder.py b/rom_builder/rom_builder.py index 3774b8a..8d28d62 100644 --- a/rom_builder/rom_builder.py +++ b/rom_builder/rom_builder.py @@ -5,7 +5,7 @@ import sys, os, glob, json, math, re, struct, hashlib, argparse, datetime # Configuration -app_version = "0.7" +app_version = "0.8" default_file = "LK_MULTIMENU_.gba" ################################ @@ -51,6 +51,12 @@ cartridge_types = [ "sector_size":0x40000, "block_size":0x80000, }, + { + "name":"MSP54LV100", + "flash_size":0x8000000, + "sector_size":0x20000, + "block_size":0x80000, + }, ] now = datetime.datetime.now() log = "" diff --git a/source/flash.c b/source/flash.c index ff4e59b..5f50709 100644 --- a/source/flash.c +++ b/source/flash.c @@ -66,6 +66,22 @@ IWRAM_CODE void FlashDetectType(void) return; } + // 1G cart with MSP54LV100S (Zelda Classic Collection 7-in-1) + _FLASH_WRITE(0, 0xF0); + _FLASH_WRITE(0xAAA, 0xA9); + _FLASH_WRITE(0x555, 0x56); + _FLASH_WRITE(0xAAA, 0x90); + data = *(vu32 *)AGB_ROM; + _FLASH_WRITE(0, 0xF0); + if (data == 0x227D0002) + { + REG_IE = ie; + flash_type = 3; + flash_sector_size = 0x20000; + FlashCalcOffsets(); + return; + } + // Unknown type REG_IE = ie; flash_type = 0; @@ -119,6 +135,24 @@ IWRAM_CODE void FlashEraseSector(u32 address) } _FLASH_WRITE(address, 0xF0F0); } + else if (_flash_type == 3) + { + _FLASH_WRITE(0xAAA, 0xA9); + _FLASH_WRITE(0x555, 0x56); + _FLASH_WRITE(0xAAA, 0x80); + _FLASH_WRITE(0xAAA, 0xA9); + _FLASH_WRITE(0x555, 0x56); + _FLASH_WRITE(address, 0x30); + while (1) + { + __asm("nop"); + if ((*((vu16 *)(AGB_ROM + address))) == 0xFFFF) + { + break; + } + } + _FLASH_WRITE(address, 0xF0); + } REG_IE = ie; } @@ -191,6 +225,33 @@ IWRAM_CODE void FlashWriteData(u32 address, u32 length) } _FLASH_WRITE(address, 0xF0F0); } + else if (_flash_type == 3) + { + for (int j = 0; j < (int)(length / 0x40); j++) + { + _FLASH_WRITE(0xAAA, 0xA9); + _FLASH_WRITE(0x555, 0x56); + _FLASH_WRITE(address + (j * 0x40), 0x26); + _FLASH_WRITE(address + (j * 0x40), 0x1F); + u16 data = 0; + for (int i = 0; i < 0x40; i += 2) + { + __asm("nop"); + data = data_buffer[(j * 0x40) + i + 1] << 8 | data_buffer[(j * 0x40) + i]; + _FLASH_WRITE(address + (j * 0x40) + i, data); + } + _FLASH_WRITE(address + (j * 0x40), 0x2A); + while (1) + { + __asm("nop"); + if (p_rom[(j * 0x20) + 0x1F] == data) + { + break; + } + } + } + _FLASH_WRITE(address, 0xF0); + } REG_IE = ie; }