#ifndef _FINALROM #include "PR/os_internal.h" #include "PR/rcp.h" #include "PRinternal/osint.h" #include "PRinternal/macros.h" typedef struct { /* 0x0 */ unsigned int inst1; /* 0x4 */ unsigned int inst2; /* 0x8 */ unsigned int inst3; /* 0xC */ unsigned int inst4; } __osExceptionVector; extern __osExceptionVector __isExpJP; void MonitorInitBreak(void); #define ISV_BASE gISVDbgPrnAdrs #define ISV_MAGIC_ADDR (ISV_BASE + 0x00) #define ISV_GET_ADDR (ISV_BASE + 0x04) #define ISV_PUT_ADDR (ISV_BASE + 0x14) #define ISV_BUFFER (ISV_BASE + 0x20) #define ISV_BUFFER_LEN (0x10000 - 0x20) #define IS64_MAGIC 'IS64' __osExceptionVector ramOldVector ALIGNED(0x8); u32 gISVFlag; u16 gISVChk; u32 gISVDbgPrnAdrs; u32 leoComuBuffAdd; static OSPiHandle* is_Handle; void isPrintfInit(void) { is_Handle = osCartRomInit(); osEPiWriteIo(is_Handle, ISV_PUT_ADDR, 0); osEPiWriteIo(is_Handle, ISV_GET_ADDR, 0); osEPiWriteIo(is_Handle, ISV_MAGIC_ADDR, IS64_MAGIC); } static void* is_proutSyncPrintf(void* arg, const u8* str, u32 count) { u32 data; s32 p; s32 start; s32 end; if (gISVDbgPrnAdrs == 0) { return 0; } osEPiReadIo(is_Handle, ISV_MAGIC_ADDR, &data); if (data != IS64_MAGIC) { return 1; } osEPiReadIo(is_Handle, ISV_GET_ADDR, &data); p = data; osEPiReadIo(is_Handle, ISV_PUT_ADDR, &data); start = data; end = start + count; if (end >= ISV_BUFFER_LEN) { end -= ISV_BUFFER_LEN; if (p < end || start < p) { return 1; } } else { if (start < p && p < end) { return 1; } } while (count) { if (*str != '\0') { s32 shift = start & 3; u32 addr = ISV_BUFFER + (start & 0xFFFFFFC); shift = (3 - shift) * 8; osEPiReadIo(is_Handle, addr, &data); osEPiWriteIo(is_Handle, addr, (data & ~(0xff << shift)) | (*str << shift)); start++; if (start >= ISV_BUFFER_LEN) { start -= ISV_BUFFER_LEN; } } count--; str++; } osEPiWriteIo(is_Handle, ISV_PUT_ADDR, start); return 1; } int __checkHardware_isv(void) { u32 i = 0; u32 data; u32 save[4]; OSPiHandle* hnd = osCartRomInit(); gISVDbgPrnAdrs = 0; leoComuBuffAdd = 0; gISVFlag = IS64_MAGIC; gISVChk = 0; for (i = 0; i < 4; i++) { osEPiReadIo(hnd, 0xB0000100 + i * 4, &save[i]); } #ifndef __GNU__ // BUG: data is used uninitialized for GCC data = 0; #endif osEPiWriteIo(hnd, 0xB000010C, data); data = IS64_MAGIC; osEPiWriteIo(hnd, 0xB0000100, IS64_MAGIC); for (i = 0; i < 0x20000; i++) { osEPiReadIo(hnd, 0xB000010C, &data); if (data == IS64_MAGIC) { data = 0; osEPiWriteIo(hnd, 0xB0000100, data); gISVChk |= 1; osEPiReadIo(hnd, 0xB0000104, &gISVDbgPrnAdrs); osEPiReadIo(hnd, 0xB0000108, &leoComuBuffAdd); break; } } for (i = 0; i < 4; i++) { osEPiWriteIo(hnd, 0xB0000100 + i * 4, save[i]); } osEPiReadIo(hnd, 0xBFF00000, &data); gISVChk |= ((data == IS64_MAGIC) ? 2 : 0); return (gISVChk != 0) ? TRUE : FALSE; } void __osInitialize_isv(void) { void (*fn)(void); OSPiHandle* hnd; s32 pad; s32 pad2; if (gISVFlag == IS64_MAGIC || __checkHardware_isv()) { if (gISVDbgPrnAdrs != 0) { __printfunc = is_proutSyncPrintf; isPrintfInit(); } if (gISVChk & 2) { hnd = osCartRomInit(); ramOldVector = *(__osExceptionVector*)E_VEC; *(__osExceptionVector*)E_VEC = __isExpJP; osWritebackDCache(&ramOldVector, 0x10); osInvalICache(&ramOldVector, 0x10); osWritebackDCache(0x80000000, 0x190); osInvalICache(0x80000000, 0x190); osEPiReadIo(hnd, 0xBFF00010, (u32*)&fn); fn(); } if (gISVChk & 2) { MonitorInitBreak(); } } } #endif