diff options
author | red031000 <rubenru09@aol.com> | 2020-05-29 22:11:36 +0100 |
---|---|---|
committer | red031000 <rubenru09@aol.com> | 2020-05-29 22:11:36 +0100 |
commit | d49c4d84a4e86c64c73f60ae0d882529734743b9 (patch) | |
tree | 8ef968231cf46a19a83160354b208967a9672351 /arm9/lib/src | |
parent | e6c0d16a679663e816130ca7bc793cab682f911c (diff) |
OSi_ReadCardRom32
Diffstat (limited to 'arm9/lib/src')
-rw-r--r-- | arm9/lib/src/OS_reset.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/arm9/lib/src/OS_reset.c b/arm9/lib/src/OS_reset.c index 6389fe45..dd3cc073 100644 --- a/arm9/lib/src/OS_reset.c +++ b/arm9/lib/src/OS_reset.c @@ -121,4 +121,68 @@ _01FF8284: blt _01FF8284 bx lr } + +void OSi_ReadCardRom32(u32 src, void *dst, s32 len) //should be static, can't mark as such +{ + vu32 *const hdr_GAME_BUF = (vu32 *)(HW_ROM_HEADER_BUF + 0x60); + + enum + { + CARD_MASTER_SELECT_ROM = 0x0, + CARD_MASTER_ENABLE = 0x80, + CARD_CMD_READ_PAGE = 0xb7, + CARD_CTRL_CMD_MASK = 0x07000000, + CARD_CTRL_CMD_PAGE = 0x01000000, + CARD_CTRL_READ = 0x00000000, + CARD_CTRL_RESET_HI = 0x20000000, + CARD_CTRL_START = 0x80000000, + CARD_CTRL_READY = 0x00800000, + CARD_ENUM_END + }; + + const u32 ctrl_start = (u32)((*hdr_GAME_BUF &~CARD_CTRL_CMD_MASK) + | (CARD_CTRL_CMD_PAGE | CARD_CTRL_READ + | CARD_CTRL_START | CARD_CTRL_RESET_HI)); + + s32 pos = -(s32)(src & 511); + + while ((reg_CARD_CNT & CARD_CTRL_START)) + {} + reg_CARD_MASTERCNT = (u32)(CARD_MASTER_SELECT_ROM | CARD_MASTER_ENABLE); + + for (src = (u32)(src + pos); pos < len; src += 512) + { + (®_CARD_CMD)[0] = (u8)(CARD_CMD_READ_PAGE); + (®_CARD_CMD)[1] = (u8)(src >> 24); + (®_CARD_CMD)[2] = (u8)(src >> 16); + (®_CARD_CMD)[3] = (u8)(src >> 8); + (®_CARD_CMD)[4] = (u8)(src >> 0); + (®_CARD_CMD)[5] = 0; + (®_CARD_CMD)[6] = 0; + (®_CARD_CMD)[7] = 0; + + reg_CARD_CNT = ctrl_start; + for (;;) + { + u32 ctrl = reg_CARD_CNT; + + if ((ctrl & CARD_CTRL_READY)) + { + const u32 data = reg_CARD_DATA; + + if ((pos >= 0) && (pos < len)) + { + *(u32 *)((u32)dst + pos) = data; + } + + pos += sizeof(u32); + } + + if (!(ctrl & CARD_CTRL_START)) + { + break; + } + } + } +} #pragma section ITCM end |