Last active
February 15, 2024 19:48
-
-
Save ITotalJustice/b6c2f630c6ac5fff1e8b117681e27abd to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
io_ezfo.c | |
Hardware Routines for reading the EZ Flash Omega filesystem | |
*/ | |
#include "io_ezfo.h" | |
#include <gba_dma.h> | |
// SOURCE: https://github.com/ez-flash/omega-de-kernel/blob/main/source/Ezcard_OP.c | |
static void EWRAM_CODE delay(u32 R0) | |
{ | |
int volatile i; | |
for ( i = R0; i; --i ); | |
return; | |
} | |
// -------------------------------------------------------------------- | |
static void EWRAM_CODE SetSDControl(u16 control) | |
{ | |
*(vu16 *)0x9fe0000 = 0xd200; | |
*(vu16 *)0x8000000 = 0x1500; | |
*(vu16 *)0x8020000 = 0xd200; | |
*(vu16 *)0x8040000 = 0x1500; | |
*(vu16 *)0x9400000 = control; | |
*(vu16 *)0x9fc0000 = 0x1500; | |
} | |
// -------------------------------------------------------------------- | |
static void EWRAM_CODE SD_Enable(void) | |
{ | |
SetSDControl(1); | |
} | |
// -------------------------------------------------------------------- | |
static void EWRAM_CODE SD_Read_state(void) | |
{ | |
SetSDControl(3); | |
} | |
// -------------------------------------------------------------------- | |
static void EWRAM_CODE SD_Disable(void) | |
{ | |
SetSDControl(0); | |
} | |
// -------------------------------------------------------------------- | |
static u16 EWRAM_CODE SD_Response(void) | |
{ | |
return *(vu16 *)0x9E00000; | |
} | |
// -------------------------------------------------------------------- | |
static u32 EWRAM_CODE Wait_SD_Response() | |
{ | |
vu16 res; | |
u32 count=0; | |
while(1) | |
{ | |
res = SD_Response(); | |
if(res != 0xEEE1) | |
{ | |
return 0; | |
} | |
count++; | |
if(count>0x100000) | |
{ | |
//DEBUG_printf("time out %x",res); | |
//wait_btn(); | |
return 1; | |
} | |
} | |
} | |
// -------------------------------------------------------------------- | |
static u32 EWRAM_CODE Read_SD_sectors(u32 address,u16 count,u8* SDbuffer) | |
{ | |
SD_Enable(); | |
u16 i; | |
u16 blocks; | |
u32 res; | |
u32 times=2; | |
for(i=0;i<count;i+=4) | |
{ | |
blocks = (count-i>4)?4:(count-i); | |
read_again: | |
*(vu16 *)0x9fe0000 = 0xd200; | |
*(vu16 *)0x8000000 = 0x1500; | |
*(vu16 *)0x8020000 = 0xd200; | |
*(vu16 *)0x8040000 = 0x1500; | |
*(vu16 *)0x9600000 = ((address+i)&0x0000FFFF) ; | |
*(vu16 *)0x9620000 = ((address+i)&0xFFFF0000) >>16; | |
*(vu16 *)0x9640000 = blocks; | |
*(vu16 *)0x9fc0000 = 0x1500; | |
SD_Read_state(); | |
res = Wait_SD_Response(); | |
SD_Enable(); | |
if(res==1) | |
{ | |
times--; | |
if(times) | |
{ | |
delay(5000); | |
goto read_again; | |
} | |
} | |
dmaCopy((void*)0x9E00000, SDbuffer+i*512, blocks*512); | |
} | |
SD_Disable(); | |
return 0; | |
} | |
// -------------------------------------------------------------------- | |
static u32 EWRAM_CODE Write_SD_sectors(u32 address,u16 count, const u8* SDbuffer) | |
{ | |
SD_Enable(); | |
SD_Read_state(); | |
u16 i; | |
u16 blocks; | |
u32 res; | |
for(i=0;i<count;i+=4) | |
{ | |
blocks = (count-i>4)?4:(count-i); | |
dmaCopy( SDbuffer+i*512,(void*)0x9E00000, blocks*512); | |
*(vu16 *)0x9fe0000 = 0xd200; | |
*(vu16 *)0x8000000 = 0x1500; | |
*(vu16 *)0x8020000 = 0xd200; | |
*(vu16 *)0x8040000 = 0x1500; | |
*(vu16 *)0x9600000 = ((address+i)&0x0000FFFF); | |
*(vu16 *)0x9620000 = ((address+i)&0xFFFF0000) >>16; | |
*(vu16 *)0x9640000 = 0x8000+blocks; | |
*(vu16 *)0x9fc0000 = 0x1500; | |
res = Wait_SD_Response(); | |
if(res==1) | |
return 1; | |
} | |
delay(3000); | |
SD_Disable(); | |
return 0; | |
} | |
// -------------------------------------------------------------------- | |
static void EWRAM_CODE SetRompage(u16 page) | |
{ | |
*(vu16 *)0x9fe0000 = 0xd200; | |
*(vu16 *)0x8000000 = 0x1500; | |
*(vu16 *)0x8020000 = 0xd200; | |
*(vu16 *)0x8040000 = 0x1500; | |
*(vu16 *)0x9880000 = page;//C4 | |
*(vu16 *)0x9fc0000 = 0x1500; | |
} | |
// -------------------------------------------------------------------- | |
#define ROMPAGE_BOOTLOADER 0x8000 | |
#define ROMPAGE_PSRAM 0x200 | |
#define S98WS512PE0_FLASH_PAGE_MAX 0x200 | |
#define ROM_HEADER_CHECKSUM *(vu16*)(0x8000000 + 188) | |
static u16 EWRAM_BSS ROMPAGE_ROM; | |
// returns true if the data is a match | |
static bool EWRAM_CODE _EZFO_TestRompage(u16 wanted, u16 page) | |
{ | |
SetRompage(page); | |
if (wanted == ROM_HEADER_CHECKSUM) | |
{ | |
ROMPAGE_ROM = page; | |
return true; | |
} | |
return false; | |
} | |
static bool EWRAM_CODE _EZFO_startUp(void) | |
{ | |
const u16 complement = ROM_HEADER_CHECKSUM; | |
// unmap rom, if the data matches, then this is not an ezflash | |
if (_EZFO_TestRompage(complement, ROMPAGE_BOOTLOADER)) | |
{ | |
return false; | |
} | |
// find where the rom is mapped, try psram first | |
if (_EZFO_TestRompage(complement, ROMPAGE_PSRAM)) | |
{ | |
return true; | |
} | |
// try and find it within norflash, test each 1MiB page (512 pages) | |
for (int i = 0; i < S98WS512PE0_FLASH_PAGE_MAX; i++) | |
{ | |
if (_EZFO_TestRompage(complement, i)) | |
{ | |
return true; | |
} | |
} | |
// this literally shouldn't happen, contact me if you hit this! | |
return false; | |
} | |
static bool EWRAM_CODE _EZFO_readSectors(u32 address, u32 count, void * buffer) | |
{ | |
SetRompage(ROMPAGE_BOOTLOADER); | |
const u32 result = Read_SD_sectors(address, count, buffer); | |
SetRompage(ROMPAGE_ROM); | |
return result == 0; | |
} | |
static bool EWRAM_CODE _EZFO_writeSectors(u32 address, u32 count, const void * buffer) | |
{ | |
SetRompage(ROMPAGE_BOOTLOADER); | |
const u32 result = Write_SD_sectors(address, count, buffer); | |
SetRompage(ROMPAGE_ROM); | |
return result == 0; | |
} | |
static bool _EZFO_nop(void) | |
{ | |
return true; | |
} | |
const DISC_INTERFACE _io_ezfo = { | |
DEVICE_TYPE_EZFO, | |
FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_SLOT_GBA, | |
( FN_MEDIUM_STARTUP )&_EZFO_startUp, | |
( FN_MEDIUM_ISINSERTED )&_EZFO_nop, | |
( FN_MEDIUM_READSECTORS )&_EZFO_readSectors, | |
( FN_MEDIUM_WRITESECTORS )&_EZFO_writeSectors, | |
( FN_MEDIUM_CLEARSTATUS )&_EZFO_nop, | |
( FN_MEDIUM_SHUTDOWN )&_EZFO_nop | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment