#include "gba/gba.h" #include "gba/flash_internal.h" u16 EraseFlashChip_MX(void) { u16 result; u16 readFlash1Buffer[0x20]; REG_WAITCNT = (REG_WAITCNT & ~WAITCNT_SRAM_MASK) | gFlash->wait[0]; FLASH_WRITE(0x5555, 0xAA); FLASH_WRITE(0x2AAA, 0x55); FLASH_WRITE(0x5555, 0x80); FLASH_WRITE(0x5555, 0xAA); FLASH_WRITE(0x2AAA, 0x55); FLASH_WRITE(0x5555, 0x10); SetReadFlash1(readFlash1Buffer); result = WaitForFlashWrite(3, FLASH_BASE, 0xFF); REG_WAITCNT = (REG_WAITCNT & ~WAITCNT_SRAM_MASK) | WAITCNT_SRAM_8; return result; } u16 EraseFlashSector_MX(u16 sectorNum) { u16 numTries; u16 result; u8 *addr; u16 readFlash1Buffer[0x20]; if (sectorNum >= gFlash->sector.count) return 0x80FF; SwitchFlashBank(sectorNum / SECTORS_PER_BANK); sectorNum %= SECTORS_PER_BANK; numTries = 0; try_erase: REG_WAITCNT = (REG_WAITCNT & ~WAITCNT_SRAM_MASK) | gFlash->wait[0]; addr = FLASH_BASE + (sectorNum << gFlash->sector.shift); FLASH_WRITE(0x5555, 0xAA); FLASH_WRITE(0x2AAA, 0x55); FLASH_WRITE(0x5555, 0x80); FLASH_WRITE(0x5555, 0xAA); FLASH_WRITE(0x2AAA, 0x55); *addr = 0x30; SetReadFlash1(readFlash1Buffer); result = WaitForFlashWrite(2, addr, 0xFF); if (!(result & 0xA000) || numTries > 3) goto done; numTries++; goto try_erase; done: REG_WAITCNT = (REG_WAITCNT & ~WAITCNT_SRAM_MASK) | WAITCNT_SRAM_8; return result; } u16 ProgramFlashByte_MX(u16 sectorNum, u32 offset, u8 data) { u8 *addr; u16 readFlash1Buffer[0x20]; if (offset >= gFlash->sector.size) return 0x8000; SwitchFlashBank(sectorNum / SECTORS_PER_BANK); sectorNum %= SECTORS_PER_BANK; addr = FLASH_BASE + (sectorNum << gFlash->sector.shift) + offset; SetReadFlash1(readFlash1Buffer); REG_WAITCNT = (REG_WAITCNT & ~WAITCNT_SRAM_MASK) | gFlash->wait[0]; FLASH_WRITE(0x5555, 0xAA); FLASH_WRITE(0x2AAA, 0x55); FLASH_WRITE(0x5555, 0xA0); *addr = data; return WaitForFlashWrite(1, addr, data); } static u16 ProgramByte(u8 *src, u8 *dest) { FLASH_WRITE(0x5555, 0xAA); FLASH_WRITE(0x2AAA, 0x55); FLASH_WRITE(0x5555, 0xA0); *dest = *src; return WaitForFlashWrite(1, dest, *src); } u16 ProgramFlashSector_MX(u16 sectorNum, u8 *src) { u16 result; u8 *dest; u16 readFlash1Buffer[0x20]; if (sectorNum >= gFlash->sector.count) return 0x80FF; result = EraseFlashSector_MX(sectorNum); if (result != 0) return result; SwitchFlashBank(sectorNum / SECTORS_PER_BANK); sectorNum %= SECTORS_PER_BANK; SetReadFlash1(readFlash1Buffer); REG_WAITCNT = (REG_WAITCNT & ~WAITCNT_SRAM_MASK) | gFlash->wait[0]; gFlashNumRemainingBytes = gFlash->sector.size; dest = FLASH_BASE + (sectorNum << gFlash->sector.shift); while (gFlashNumRemainingBytes > 0) { result = ProgramByte(src, dest); if (result != 0) break; gFlashNumRemainingBytes--; src++; dest++; } return result; }