-
Notifications
You must be signed in to change notification settings - Fork 4
EzFlash
My emulation of the ezflash omega
and omega DE
. All information is derived from the opensource ezflash kernel, which i want to say a huge huge thank you to the ezflash team for doing such a thing. i would love fo move flash carts to open source their kernel <3
Some information is derived from mini tests i wrote for the ezflash hw, this includes reading from various ezflash registers, as the kernel only ever writes to them.
The names and layout of this doc is copied directly from my emulator, as such, feel free to pr better names for registers / addresses / values.
- S71GL064A08 8MB NOR flash with 1MB ram
- S98WS512PE0 64MB NOR flash with 32MB ram
- rtc (not covered, uses gpio, works the same as rtc used in games)
- sd card slot
- fpga (not covered)
- FM28V100 FRAM [DE]
start | end | name | comment |
---|---|---|---|
0x08000000 | 0x08040000 | BootLoader | ROMPAGE == 0x8000 |
0x08040000 | 0x087FFFFF | Kernel | ROMPAGE == 0x8002 |
0x08800000 | 0x08FFFFFF | PSRAM | |
0x09000000 | 0x097FFFFF | NOR | |
0x09E00000 | MicroSD | read and write buffer address | |
0x0E000000 | 0x0E00FFFF | SRAM | RAMPAGE == 0x00...0x10 |
0x0E020000 | 0x0E020000 | VRAM buffer | RAMPAGE == 0x20...0x30 |
0x0E020000 | 0x0E020000 | RTS | RAMPAGE == 0x40...0xB0 |
- BootLoader is closed source.
- Kernel is open source and is loaded after the bootloader. for emulation sake, load the kernel to
0x08000000
and setROMPAGE
to 0x8002. - PSRAM is where the rom is loaded into (if not installed to NOR). this PSRAM is then mapped to the
0x08000000
range when exiting game mode. - NOR is where games are installed to when selecting "install to NOR". when installing to NOR with patch, the game is first copied to NOR and then the patch is applied, meaning that launching the patched game from NOR doesn't need the patch to be applied again.
- SRAM is where the games save is copied to, including if the save type is eeprom. It is not clear how SRAM is then mapped to the eeprom region or how it emulates the eeprom commands. My guess is that's something the fpga handles. Any writes to SRAM in
GameMode
cause the ezflash to slowly write the data to the sd card. This is very slow and is a common cause for save corruption. - VRAM buffer is used whilst in game with patch support and entering ezflash menu (L+R+START). it copies the contents of vram to the buffer on menu load and reads back that data into vram when exiting the menu.
- RTS is ezflash savestate format (Real Time Save). This doesn't work in the majority of games on the ezflash, not due to some registers being read only, but due to how slow/bugged the sd card flush is. I know this because RTS works perfectly in almost all games in my emulation of it (i instantly flush the sd card, correctly as well).
The ezflash has a number of settings which are stored in S71GL064A08
NOR flash. Changing the settings causes a sector erase of the entire setting region and writes back each setting.
addr | size | name | comment |
---|---|---|---|
0x7B0000 | 2 | SetInfoLang | language (english or chinease) |
0x7B0002 | 2 | SetInfoReset | enable reset patch |
0x7B0004 | 2 | SetInfoRts | enable rts patch |
0x7B0006 | 2 | SetInfoSleep | enable sleep patch |
0x7B0008 | 2 | SetInfoCheat | enable cheat patch |
0x7B000A | 2 | SetInfoSleepKey0 | key0 used for sleep |
0x7B000C | 2 | SetInfoSleepKey1 | key1 used for sleep |
0x7B000E | 2 | SetInfoSleepKey2 | key2 used for sleep |
0x7B0010 | 2 | SetInfoMenuKey0 | key0 used for menu |
0x7B0012 | 2 | SetInfoMenuKey1 | key1 used for menu |
0x7B0014 | 2 | SetInfoMenuKey2 | key2 used for menu |
0x7B0016 | 2 | SetInfoEngine | enable on-the-fly patching |
0x7B0018 | 2 | SetInfoShowThumbnail | show game-art in menu |
0x7B001A | 2 | SetInfoRtcOpenStatus | enables rtc in game (leave this enabled) |
0x7B001C | 2 | SetInfoAutoSaveSel | [DE] auto write saves on restarting |
0x7B001E | 2 | SetInfoModeBInit | [DE] can't remember |
0x7B0020 | 2 | SetInfoLedOpenSel | [DE] can't remember |
0x7B0022 | 2 | SetInfoBreathingR | [DE] can't remember |
0x7B0024 | 2 | SetInfoBreathingG | [DE] can't remember |
0x7B0026 | 2 | SetInfoBreathingB | [DE] can't remember |
0x7B0028 | 2 | SetInfoSdR | [DE] can't remember |
0x7B002A | 2 | SetInfoSdG | [DE] can't remember |
0x7B002C | 2 | SetInfoSdB | [DE] can't remember |
value | name | comment |
---|---|---|
0xE1E1 | SET_INFO_LANG_ENGLISH | english (default) |
0xE1E2 | SET_INFO_LANG_CHINEASE | chinease |
value | name | comment |
---|---|---|
0x0 | SET_INFO_RESET_DISABLE | (default) |
0x1 | SET_INFO_RESET_ENABLE |
value | name | comment |
---|---|---|
0x0 | SET_INFO_RTS_DISABLE | (default) |
0x1 | SET_INFO_RTS_ENABLE |
value | name | comment |
---|---|---|
0x0 | SET_INFO_SLEEP_DISABLE | (default) |
0x1 | SET_INFO_SLEEP_ENABLE |
value | name | comment |
---|---|---|
0x0 | SET_INFO_CHEAT_DISABLE | (default) |
0x1 | SET_INFO_CHEAT_ENABLE |
value | name | comment |
---|---|---|
0x0 | SET_INFO_SLEEP_KEY0_A | |
0x1 | SET_INFO_SLEEP_KEY0_B | |
0x2 | SET_INFO_SLEEP_KEY0_SELECT | |
0x3 | SET_INFO_SLEEP_KEY0_START | |
0x4 | SET_INFO_SLEEP_KEY0_RIGHT | |
0x5 | SET_INFO_SLEEP_KEY0_LEFT | |
0x6 | SET_INFO_SLEEP_KEY0_UP | |
0x7 | SET_INFO_SLEEP_KEY0_DOWN | |
0x8 | SET_INFO_SLEEP_KEY0_R | |
0x9 | SET_INFO_SLEEP_KEY0_L | (default) |
value | name | comment |
---|---|---|
0x0 | SET_INFO_SLEEP_KEY1_A | |
0x1 | SET_INFO_SLEEP_KEY1_B | |
0x2 | SET_INFO_SLEEP_KEY1_SELECT | |
0x3 | SET_INFO_SLEEP_KEY1_START | |
0x4 | SET_INFO_SLEEP_KEY1_RIGHT | |
0x5 | SET_INFO_SLEEP_KEY1_LEFT | |
0x6 | SET_INFO_SLEEP_KEY1_UP | |
0x7 | SET_INFO_SLEEP_KEY1_DOWN | |
0x8 | SET_INFO_SLEEP_KEY1_R | (default) |
0x9 | SET_INFO_SLEEP_KEY1_L |
value | name | comment |
---|---|---|
0x0 | SET_INFO_SLEEP_KEY2_A | |
0x1 | SET_INFO_SLEEP_KEY2_B | |
0x2 | SET_INFO_SLEEP_KEY2_SELECT | (default) |
0x3 | SET_INFO_SLEEP_KEY2_START | |
0x4 | SET_INFO_SLEEP_KEY2_RIGHT | |
0x5 | SET_INFO_SLEEP_KEY2_LEFT | |
0x6 | SET_INFO_SLEEP_KEY2_UP | |
0x7 | SET_INFO_SLEEP_KEY2_DOWN | |
0x8 | SET_INFO_SLEEP_KEY2_R | |
0x9 | SET_INFO_SLEEP_KEY2_L |
value | name | comment |
---|---|---|
0x0 | SET_INFO_MENU_KEY0_A | |
0x1 | SET_INFO_MENU_KEY0_B | |
0x2 | SET_INFO_MENU_KEY0_SELECT | |
0x3 | SET_INFO_MENU_KEY0_START | |
0x4 | SET_INFO_MENU_KEY0_RIGHT | |
0x5 | SET_INFO_MENU_KEY0_LEFT | |
0x6 | SET_INFO_MENU_KEY0_UP | |
0x7 | SET_INFO_MENU_KEY0_DOWN | |
0x8 | SET_INFO_MENU_KEY0_R | |
0x9 | SET_INFO_MENU_KEY0_L | (default) |
value | name | comment |
---|---|---|
0x0 | SET_INFO_MENU_KEY1_A | |
0x1 | SET_INFO_MENU_KEY1_B | |
0x2 | SET_INFO_MENU_KEY1_SELECT | |
0x3 | SET_INFO_MENU_KEY1_START | |
0x4 | SET_INFO_MENU_KEY1_RIGHT | |
0x5 | SET_INFO_MENU_KEY1_LEFT | |
0x6 | SET_INFO_MENU_KEY1_UP | |
0x7 | SET_INFO_MENU_KEY1_DOWN | |
0x8 | SET_INFO_MENU_KEY1_R | (default) |
0x9 | SET_INFO_MENU_KEY1_L |
value | name | comment |
---|---|---|
0x0 | SET_INFO_MENU_KEY2_A | |
0x1 | SET_INFO_MENU_KEY2_B | |
0x2 | SET_INFO_MENU_KEY2_SELECT | |
0x3 | SET_INFO_MENU_KEY2_START | (default) |
0x4 | SET_INFO_MENU_KEY2_RIGHT | |
0x5 | SET_INFO_MENU_KEY2_LEFT | |
0x6 | SET_INFO_MENU_KEY2_UP | |
0x7 | SET_INFO_MENU_KEY2_DOWN | |
0x8 | SET_INFO_MENU_KEY2_R | |
0x9 | SET_INFO_MENU_KEY2_L |
value | name | comment |
---|---|---|
0x0 | SET_INFO_ENGINE_DISABLE | |
0x1 | SET_INFO_ENGINE_ENABLE | (default) |
value | name | comment |
---|---|---|
0x0 | SET_INFO_THUMBNAIL_DISABLE | (default) |
0x1 | SET_INFO_THUMBNAIL_ENABLE |
value | name | comment |
---|---|---|
0x0 | SET_INFO_RTC_OPEN_STATUS_DISABLE | |
0x1 | SET_INFO_RTC_OPEN_STATUS_ENABLE | (default) |
value | name | comment |
---|---|---|
0x0 | SET_INFO_AUTO_SAVE_SEL_DISABLE | (default) |
0x1 | SET_INFO_AUTO_SAVE_SEL_ENABLE |
value | name | comment |
---|---|---|
0x0 | SET_INFO_MODE_B_INIT_RUMBLE | |
0x1 | SET_INFO_MODE_B_INIT_RAM | |
0x2 | SET_INFO_MODE_B_INIT_LINK | (default) |
value | name | comment |
---|---|---|
0x0 | SET_INFO_AUTO_SAVE_SEL_DISABLE | (default) |
0x1 | SET_INFO_AUTO_SAVE_SEL_ENABLE |
Commands are issues as part of a sequence. usually it goes like this: start sequence -> command -> end sequence. The commands are just that, commands. they are not registers that can be read! So yes sadly there is no way to query ROMPAGE.
I believe all commands are still accessible even in GameMode
. ROMPAGE
and RAMPAGE
certainly are.
addr | value | name |
---|---|---|
0x9fe0000 | 0xD200 | COMMAND_SEQ1_ADDR |
0x8000000 | 0x1500 | COMMAND_SEQ2_ADDR |
0x8020000 | 0xD200 | COMMAND_SEQ3_ADDR |
0x8040000 | 0x1500 | COMMAND_SEQ4_ADDR |
0x9fc0000 | 0x1500 | COMMAND_END_ADDR |
addr | size | name | comment |
---|---|---|---|
0x9400000 | 2 | SD_CONTROL | controls whether or not the sd card is accessible. there is a special mode for reading the sd status. this is used to poll the sd card to see if its finished the transfer |
0x9420000 | 2 | BUFFER_CONTROL | |
0x9880000 | 2 | ROMPAGE | also controls whether the ezflash is OSMode or GameMode . if bit-15 is set, then it's OSMode otherwise it's GameMode
|
0x9860000 | 2 | PS_RAMPAGE | sets PSRAM mapped region for 0x08800000...0x08FFFFFF
|
0x9C00000 | 2 | RAMPAGE | controls the page of norS71 ram mapped at 0x0E000000...0x0E00FFFF
|
0x9660000 | 2 | SPI_CONTROL | |
0x9680000 | 2 | SPI_WRITE | this is only used when doing an update, as such i think having SPI_WRITE_DISABLE makes the kernel read only (maybe execute only?), otherwise its writeable. WARNING: DO NOT MESS WITH THIS! doing so WILL lead to a permanently bricked EZO! |
0x96A0000 | 2 | RTC_STATUS | I think this enables/disables the RTC. TODO: verify this. |
0x96C0000 | 2 | AUTO_SAVE_MODE | ??? |
0x9600000 | 2 | SD_ADDR_LOW | low 16 bits |
0x9620000 | 2 | SD_ADDR_HIGH | upper 16 bits |
0x9640000 | 2 | SD_BLOCKS | number of blocks to transfer |
0x96E0000 | 2 | LED_CONTROL | [DE] master flag for the led being enabled |
0x9E20000 | 2 | RUMBLE_CONTROL | [DE] |
NOTE: SD_ADDR_LOW
, SD_ADDR_HIGH
, SD_BLOCKS
are used all at once, so the sequence looks like: seq1->seq2->seq3->se4->low->high->blocks->end
.
NOTE: because of the above, it may be possible to combine more commands into one after seq4
. this has yet to be tested!
value | name | comment |
---|---|---|
0x0 | ROMPAGE_NOR_START | used for gamemode. can be any value < ROMPAGE_PSRAM which maps norS98 flash into rom region. norS98 is what holds installed nor flash games. |
0x200 | ROMPAGE_PSRAM | used for gamemode and for mapping psram to rom region |
0x8000 | ROMPAGE_BOOTLOADER | |
0x8002 | ROMPAGE_KERNEL |
value | name | comment |
---|---|---|
0x0000 | PS_RAMPAGE_UNK0 | |
0x1000 | PS_RAMPAGE_UNK1 | |
0x2000 | PS_RAMPAGE_UNK2 | |
0x3000 | PS_RAMPAGE_UNK3 |
value | name | comment |
---|---|---|
0x00 | RAMPAGE_SAVE1 | |
0x10 | RAMPAGE_SAVE2 | |
0x20 | RAMPAGE_VRAM_BUFFER1 | |
0x30 | RAMPAGE_VRAM_BUFFER2 | |
0x40 | RAMPAGE_RTS_EWRAM1 | alias RAMPAGE_RTS_START as this is the starting point for rts data |
0x50 | RAMPAGE_RTS_EWRAM2 | |
0x60 | RAMPAGE_RTS_EWRAM3 | |
0x70 | RAMPAGE_RTS_EWRAM4 | |
0x80 | RAMPAGE_RTS_IWRAM_PRAM | |
0x90 | RAMPAGE_RTS_VRAM1 | |
0xA0 | RAMPAGE_RTS_VRAM2_OAM_R4R11_IO | lots of stuff written here. last bit of vram, oam, cpu registers and io |
0xB0 | RAMPAGE_RTS_UNK | iirc this is used for the magic string at the end of the file |
0x20 | RAMPAGE_RTS |
RAMPAGE_VRAM_BUFFERX: this is used when loading the ezflash in game menu the contents of vram are copied to this region and then read back into vram when leaving the menu.
value | name | comment |
---|---|---|
0 | SD_CONTROL_DISABLE | |
1 | SD_CONTROL_ENABLE | |
3 | SD_CONTROL_READ_STATE |
value | name | comment |
---|---|---|
0 | SPI_CONTROL_DISABLE | |
1 | SPI_CONTROL_ENABLE |
value | name | comment |
---|---|---|
0 | SPI_WRITE_DISABLE | |
1 | SPI_WRITE_ENABLE | NEVER MESS WITH THIS, YOU WILL BRICK YOUR EZO!!! |
value | name | comment |
---|---|---|
0 | BUFFER_CONTROL_DISABLE | |
1 | BUFFER_CONTROL_ENABLE | |
3 | BUFFER_CONTROL_READ_STATE |
value | name | comment |
---|---|---|
0 | RTC_STATUS_DISABLE | |
1 | RTC_STATUS_ENABLE |
value | name | comment |
---|---|---|
0 | AUTO_SAVE_MODE_DISABLE | |
1 | AUTO_SAVE_MODE_ENABLE |
value | name | comment |
---|---|---|
0x0000 | SD_RESPONSE_UN0 | ok? |
0x0001 | SD_RESPONSE_UN1 | busy? error? |
0xEEE1 | SD_RESPONSE_UN2 | busy? |
todo: give examples of transfers, polling for response, write an example rom etc.
| 0x9E00000 | 2 | SD_RESPONSE | this is used for many things depending on spi control. If spi control is enabled then this is used for fpga version otherwise, it is used for getting sd response |
todo: explain fat transfers, explain difference between EZO and EZODE, explain update process
addr | size | name | comment |
---|---|---|---|
0x004 | 4 | rom_cluster_start | start data cluster of rom |
0x1F0 | 4 | gamefile_size | size of game in bytes |
0x1F4 | 4 | mode | mode for fat (psram or nor) |
0x1F8 | 4 | cluster_size | usually 8 for most fat sd cards |
0x1FC | 4 | savefile_size_and_type | upper 24 bits are size, low 8 bits are save type |
0x204 | 4 | save_cluster_start | start data cluster of save |
0x304 | 4 | rts_cluster_start | start data cluster of rts |
value | name | comment |
---|---|---|
0x1 | FAT_TABLE_MODE_ROM_COPY_PSRAM | the game is loaded into psram |
0x2 | FAT_TABLE_MODE_PARAMATER | the game is in nor and thus mapped in rom region |