diff --git a/core/reios/gdrom_hle.cpp b/core/reios/gdrom_hle.cpp index 37a6495db..e74d0d058 100644 --- a/core/reios/gdrom_hle.cpp +++ b/core/reios/gdrom_hle.cpp @@ -33,6 +33,30 @@ void GDROM_HLE_ReadTOC(u32 Addr) libGDR_GetToc((u32*)pDst, s); } +void read_sectors_to(u32 addr, u32 sector, u32 count) { + u8 * pDst = GetMemPtr(addr, 0); + + if (pDst) { + libGDR_ReadSector(pDst, sector, count, 2048); + } + else { + u8 temp[2048]; + + while (count > 0) { + libGDR_ReadSector(temp, sector, 1, 2048); + + for (int i = 0; i < 2048 / 4; i += 4) { + WriteMem32(addr, temp[i]); + addr += 4; + } + + sector++; + count--; + } + } + +} + void GDROM_HLE_ReadDMA(u32 addr) { u32 s = ReadMem32(addr + 0x00); @@ -40,10 +64,10 @@ void GDROM_HLE_ReadDMA(u32 addr) u32 b = ReadMem32(addr + 0x08); u32 u = ReadMem32(addr + 0x0C); - u8 * pDst = GetMemPtr(b, 0); + //printf("GDROM:\tPIO READ Sector=%d, Num=%d, Buffer=0x%08X, Unk01=0x%08X\n", s, n, b, u); - libGDR_ReadSector(pDst, s, n, 2048); + read_sectors_to(b, s, n); } void GDROM_HLE_ReadPIO(u32 addr) @@ -53,11 +77,9 @@ void GDROM_HLE_ReadPIO(u32 addr) u32 b = ReadMem32(addr + 0x08); u32 u = ReadMem32(addr + 0x0C); - u8 * pDst = GetMemPtr(b, 0); - //printf("GDROM:\tPIO READ Sector=%d, Num=%d, Buffer=0x%08X, Unk01=0x%08X\n", s, n, b, u); - libGDR_ReadSector(pDst, s, n, 2048); + read_sectors_to(b, s, n); } void GDCC_HLE_GETSCD(u32 addr) { @@ -74,7 +96,7 @@ void GDCC_HLE_GETSCD(u32 addr) { u32 SecMode[4]; -inline static void GD_HLE_Command(u32 cc, u32 prm) +void GD_HLE_Command(u32 cc, u32 prm) { switch(cc) { diff --git a/core/reios/gdrom_hle.h b/core/reios/gdrom_hle.h index 8ba8e6025..06b30a919 100644 --- a/core/reios/gdrom_hle.h +++ b/core/reios/gdrom_hle.h @@ -33,4 +33,5 @@ #define CTOC_CTRL(n) (n<<28) #define CTOC_TRACK(n) (n<<16) -void gdrom_hle_op(); \ No newline at end of file +void gdrom_hle_op(); +void GD_HLE_Command(u32 cc, u32 prm); \ No newline at end of file diff --git a/core/reios/reios.cpp b/core/reios/reios.cpp index 03332b5f5..caec53d7b 100644 --- a/core/reios/reios.cpp +++ b/core/reios/reios.cpp @@ -1,5 +1,10 @@ /* Extremely primitive bios replacement + + Many thanks to Lars Olsson (jlo@ludd.luth.se) for bios decompile work + http://www.ludd.luth.se/~jlo/dc/bootROM.c + http://www.ludd.luth.se/~jlo/dc/bootROM.h + http://www.ludd.luth.se/~jlo/dc/security_stuff.c */ #include "reios.h" @@ -10,11 +15,14 @@ #include -#define dc_bios_syscall_system 0x8C0000B0 -#define dc_bios_syscall_font 0x8C0000B4 -#define dc_bios_syscall_flashrom 0x8C0000B8 -#define dc_bios_syscall_gd 0x8C0000BC -#define dc_bios_syscall_misc 0x8c0000E0 +#define dc_bios_syscall_system 0x8C0000B0 +#define dc_bios_syscall_font 0x8C0000B4 +#define dc_bios_syscall_flashrom 0x8C0000B8 +#define dc_bios_syscall_gd 0x8C0000BC +#define dc_bios_syscall_misc 0x8c0000E0 + +//At least one game (ooga) uses this directly +#define dc_bios_entrypoint_gd_do_bioscall 0x8c0010F0 #define SYSINFO_ID_ADDR 0x8C001010 @@ -224,6 +232,59 @@ void reios_sys_gd() { gdrom_hle_op(); } +/* + - gdGdcReqCmd, 0 + - gdGdcGetCmdStat, 1 + - gdGdcExecServer, 2 + - gdGdcInitSystem, 3 + - gdGdcGetDrvStat, 4 +*/ +void gd_do_bioscall() +{ + //looks like the "real" entrypoint for this on a dreamcast + gdrom_hle_op(); + return; + + /* + int func1, func2, arg1, arg2; + */ + + switch (Sh4cntx.r[7]) { + case 0: //gdGdcReqCmd, wth is r6 ? + GD_HLE_Command(Sh4cntx.r[4], Sh4cntx.r[5]); + Sh4cntx.r[0] = 0xf344312e; + break; + + case 1: //gdGdcGetCmdStat, r4 -> id as returned by gdGdcReqCmd, r5 -> buffer to get status in ram, r6 ? + Sh4cntx.r[0] = 0; //All good, no status info + break; + + case 2: //gdGdcExecServer + //nop? returns something, though. + //Bios seems to be based on a cooperative threading model + //this is the "context" switch entry point + break; + + case 3: //gdGdcInitSystem + //nop? returns something, though. + break; + case 4: //gdGdcGetDrvStat + /* + Looks to same as GDROM_CHECK_DRIVE + */ + WriteMem32(Sh4cntx.r[4] + 0, 0x02); // STANDBY + WriteMem32(Sh4cntx.r[4] + 4, 0x80); // CDROM | 0x80 for GDROM + Sh4cntx.r[0] = 0; // RET SUCCESS + break; + + default: + printf("gd_do_bioscall: (%d) %d, %d, %d\n", Sh4cntx.r[4], Sh4cntx.r[5], Sh4cntx.r[6], Sh4cntx.r[7]); + break; + } + + //gdGdcInitSystem +} + void reios_sys_misc() { printf("reios_sys_misc - r7: 0x%08X, r4 0x%08X, r5 0x%08X, r6 0x%08X\n", Sh4cntx.r[7], Sh4cntx.r[4], Sh4cntx.r[5], Sh4cntx.r[6]); Sh4cntx.r[0] = 0; @@ -250,6 +311,7 @@ void reios_boot() { setup_syscall(hook_addr(&reios_sys_gd), dc_bios_syscall_gd); setup_syscall(hook_addr(&reios_sys_misc), dc_bios_syscall_misc); + WriteMem32(dc_bios_entrypoint_gd_do_bioscall, REIOS_OPCODE); //Infinitive loop for arm ! WriteMem32(0x80800000, 0xEAFFFFFE); @@ -299,6 +361,7 @@ bool reios_init(u8* rom, u8* flash) { register_hook(0x8C001006, reios_sys_gd); register_hook(0x8C001008, reios_sys_misc); + register_hook(dc_bios_entrypoint_gd_do_bioscall, &gd_do_bioscall); return true; }