diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index 34ce56fe..8c28ee59 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -338,6 +338,32 @@ nw4r/db/db_directPrint.cpp: .sbss start:0x805765E8 end:0x805765EC .bss start:0x80636B80 end:0x80636BA4 +nw4r/db/db_console.cpp: + .text start:0x80434EA0 end:0x8043598C + .data start:0x8056C010 end:0x8056C038 + .sdata start:0x80574DC8 end:0x80574DD0 + .sbss start:0x805765F0 end:0x805765F8 + .bss start:0x80636BA8 end:0x80636FC0 + +nw4r/db/db_exception.cpp: + .text start:0x80435990 end:0x80436A48 + .data start:0x8056C038 end:0x8056C5F0 + .sdata start:0x80574DD0 end:0x80574E10 + .sbss start:0x805765F8 end:0x80576600 + .sdata2 start:0x8057EBA8 end:0x8057EBAC + .bss start:0x80636FC0 end:0x8063B320 + +nw4r/db/db_mapFile.cpp: + .text start:0x80436A50 end:0x804373B4 + .data start:0x8056C5F0 end:0x8056C600 + .sdata start:0x80574E10 end:0x80574E24 + .sbss start:0x80576600 end:0x8057660C + .bss start:0x8063B320 end:0x8063B560 + +nw4r/db/db_assert.cpp: + .text start:0x804373C0 end:0x804373D0 + .sbss start:0x80576610 end:0x80576618 + egg/core/eggArchive.cpp: .text start:0x80493510 end:0x80494254 .data start:0x8056E820 end:0x8056E830 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 8f6bb548..00cb920a 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -21975,11 +21975,11 @@ OSLinkFixed = .text:0x803A9AF0; // type:function size:0x1C fn_803A9B10 = .text:0x803A9B10; // type:function size:0x240 OSUnlink = .text:0x803A9D50; // type:function size:0x1D4 __OSModuleInit = .text:0x803A9F30; // type:function size:0x18 scope:global -fn_803A9F50 = .text:0x803A9F50; // type:function size:0xA4 +OSSearchModule = .text:0x803A9F50; // type:function size:0xA4 OSInitMessageQueue = .text:0x803AA000; // type:function size:0x60 OSSendMessage = .text:0x803AA060; // type:function size:0xC8 OSReceiveMessage = .text:0x803AA130; // type:function size:0xDC -fn_803AA210 = .text:0x803AA210; // type:function size:0xC +OSGetPhysicalMem1Size = .text:0x803AA210; // type:function size:0xC OSGetPhysicalMem2Size = .text:0x803AA220; // type:function size:0xC scope:global OSGetConsoleSimulatedMem1Size = .text:0x803AA230; // type:function size:0xC scope:global OSGetConsoleSimulatedMem2Size = .text:0x803AA240; // type:function size:0xC scope:global @@ -24153,7 +24153,7 @@ DirectPrint_SetupFB__Q34nw4r2db6detailFPC16_GXRenderModeObj = .text:0x80434CB0; RemoveConsoleFromList___Q24nw4r2dbFPQ44nw4r2db6detail11ConsoleHead = .text:0x80434EA0; // type:function size:0xB0 Console_Create__Q24nw4r2dbFPvUsUsUsUsUs = .text:0x80434F50; // type:function size:0x1B0 Console_Destroy__Q24nw4r2dbFPQ44nw4r2db6detail11ConsoleHead = .text:0x80435100; // type:function size:0x30 -DoDrawConsole___Q24nw4r2dbFPQ44nw4r2db6detail11ConsoleHeadPQ34nw4r2ut17TextWriterBase = .text:0x80435130; // type:function size:0x1A4 +DoDrawConsole___Q24nw4r2dbFPQ44nw4r2db6detail11ConsoleHeadPQ34nw4r2ut17TextWriterBase = .text:0x80435130; // type:function size:0x1A4 Console_DrawDirect__Q24nw4r2dbFPQ44nw4r2db6detail11ConsoleHead = .text:0x804352E0; // type:function size:0x7C PrintToBuffer___Q24nw4r2dbFPQ44nw4r2db6detail11ConsoleHeadPCUc = .text:0x80435360; // type:function size:0x3B8 Console_VFPrintf__Q24nw4r2dbFQ34nw4r2db17ConsoleOutputTypePQ44nw4r2db6detail11ConsoleHeadPCcP16__va_list_struct = .text:0x80435720; // type:function size:0xD8 @@ -24179,10 +24179,10 @@ GetCharOnMem___Q24nw4r2dbFPCUc = .text:0x80436B40; // type:function size:0x8 GetCharOnDvd___Q24nw4r2dbFPCUc = .text:0x80436B50; // type:function size:0xFC SearchParam___Q24nw4r2dbFPUcUlUc = .text:0x80436C50; // type:function size:0xC4 XStrToU32___Q24nw4r2dbFPCUc = .text:0x80436D20; // type:function size:0xCC -CopySymbol___Q24nw4r2dbFPCUcPUcUlUc = .text:0x80436DF0; // type:function size:0x2DC -QuerySymbolToMapFile___Q24nw4r2dbFPUcPC12OSModuleInfoUlPUcUl = .text:0x804370D0; // type:function size:0xD8 +QuerySymbolToMapFile___Q24nw4r2dbFPUcPC12OSModuleInfoUlPUcUl = .text:0x80436DF0; // type:function size:0x2DC +UnkFunction___Q24nw4r2dbFPC12OSModuleInfoUlPUcUl = .text:0x804370D0; // type:function size:0xD8 QuerySymbolToSingleMapFile___Q24nw4r2dbFPQ34nw4r2db7MapFileUlPUcUl = .text:0x804371B0; // type:function size:0xF8 -MapFile_QuerySymbol__Q24nw4r2dbFPvPcUl = .text:0x804372B0; // type:function size:0x104 +MapFile_QuerySymbol__Q24nw4r2dbFUlPUcUl = .text:0x804372B0; // type:function size:0x104 Assertion_SetConsole__Q24nw4r2dbFPQ44nw4r2db6detail11ConsoleHead = .text:0x804373C0; // type:function size:0x10 FExp__Q34nw4r4math6detailFf = .text:0x804373D0; // type:function size:0xAC FLog__Q34nw4r4math6detailFf = .text:0x80437480; // type:function size:0xA4 @@ -27471,7 +27471,7 @@ _restgpr_29 = .text:0x804C6BE0; // type:label scope:global _restgpr_30 = .text:0x804C6BE4; // type:label scope:global _restgpr_31 = .text:0x804C6BE8; // type:label scope:global __div2u = .text:0x804C6BF0; // type:function size:0xEC scope:global -fn_804C6CDC = .text:0x804C6CDC; // type:function size:0x138 +__div2i = .text:0x804C6CDC; // type:function size:0x138 __mod2u = .text:0x804C6E14; // type:function size:0xE4 scope:global fn_804C6EF8 = .text:0x804C6EF8; // type:function size:0x10C fn_804C7004 = .text:0x804C7004; // type:function size:0x24 @@ -36957,21 +36957,66 @@ __vt__Q34nw4r2ut4Font = .data:0x8056BED8; // type:object size:0x5C scope:weak __vt__Q44nw4r2ut6detail11ResFontBase = .data:0x8056BF44; // type:object size:0x5C __vt__Q34nw4r2ut7ResFont = .data:0x8056BFA0; // type:object size:0x5C twiceBit__Q24nw4r2db = .data:0x8056C000; // type:object size:0x10 scope:local -lbl_8056C010 = .data:0x8056C010; // type:object size:0x10 -lbl_8056C020 = .data:0x8056C020; // type:object size:0x18 -lbl_8056C038 = .data:0x8056C038; // type:object size:0x10 -lbl_8056C048 = .data:0x8056C048; // type:object size:0x10 -lbl_8056C058 = .data:0x8056C058; // type:object size:0x14 -lbl_8056C06C = .data:0x8056C06C; // type:object size:0xC -lbl_8056C078 = .data:0x8056C078; // type:object size:0x10 +lbl_8056C010 = .data:0x8056C010; // type:object size:0xF data:string +lbl_8056C020 = .data:0x8056C020; // type:object size:0x17 data:string +lbl_8056C038 = .data:0x8056C038; // type:object size:0xD data:string +lbl_8056C048 = .data:0x8056C048; // type:object size:0xE data:string +lbl_8056C058 = .data:0x8056C058; // type:object size:0x13 data:string +lbl_8056C06C = .data:0x8056C06C; // type:object size:0xA data:string +lbl_8056C078 = .data:0x8056C078; // type:object size:0xF data:string lbl_8056C088 = .data:0x8056C088; // type:object size:0xC data:string lbl_8056C094 = .data:0x8056C094; // type:object size:0xC data:string -lbl_8056C0A0 = .data:0x8056C0A0; // type:object size:0x14 +lbl_8056C0A0 = .data:0x8056C0A0; // type:object size:0x13 data:string lbl_8056C0B4 = .data:0x8056C0B4; // type:object size:0xC data:string -lbl_8056C0C0 = .data:0x8056C0C0; // type:object size:0x14 -lbl_8056C0D4 = .data:0x8056C0D4; // type:object size:0x14 -lbl_8056C0E8 = .data:0x8056C0E8; // type:object size:0x508 -lbl_8056C5F0 = .data:0x8056C5F0; // type:object size:0x10 +lbl_8056C0C0 = .data:0x8056C0C0; // type:object size:0x11 data:string +lbl_8056C0D4 = .data:0x8056C0D4; // type:object size:0x12 data:string +lbl_8056C0E8 = .data:0x8056C0E8; // type:object size:0xB data:string +lbl_8056C0F4 = .data:0x8056C0F4; // type:object size:0x44 +lbl_8056C138 = .data:0x8056C138; // type:object size:0x37 data:string +lbl_8056C170 = .data:0x8056C170; // type:object size:0x2D data:string +lbl_8056C1A0 = .data:0x8056C1A0; // type:object size:0x10 data:string +lbl_8056C1B0 = .data:0x8056C1B0; // type:object size:0x1A data:string +lbl_8056C1CC = .data:0x8056C1CC; // type:object size:0x26 data:string +lbl_8056C1F4 = .data:0x8056C1F4; // type:object size:0x27 data:string +lbl_8056C21C = .data:0x8056C21C; // type:object size:0x1A data:string +lbl_8056C238 = .data:0x8056C238; // type:object size:0x1E data:string +lbl_8056C258 = .data:0x8056C258; // type:object size:0x2A data:string +lbl_8056C284 = .data:0x8056C284; // type:object size:0xD data:string +lbl_8056C294 = .data:0x8056C294; // type:object size:0x11 data:string +lbl_8056C2A8 = .data:0x8056C2A8; // type:object size:0x1D data:string +lbl_8056C2C8 = .data:0x8056C2C8; // type:object size:0x1A data:string +lbl_8056C2E4 = .data:0x8056C2E4; // type:object size:0x1C data:string +lbl_8056C300 = .data:0x8056C300; // type:object size:0x1C data:string +lbl_8056C320 = .data:0x8056C320; // type:object size:0x28 data:string +lbl_8056C348 = .data:0x8056C348; // type:object size:0x15 data:string +lbl_8056C360 = .data:0x8056C360; // type:object size:0x9 data:string +lbl_8056C36C = .data:0x8056C36C; // type:object size:0x22 data:string +lbl_8056C390 = .data:0x8056C390; // type:object size:0x1F data:string +lbl_8056C3B0 = .data:0x8056C3B0; // type:object size:0xF data:string +lbl_8056C3C0 = .data:0x8056C3C0; // type:object size:0x19 data:string +lbl_8056C3DC = .data:0x8056C3DC; // type:object size:0x16 data:string +lbl_8056C3F4 = .data:0x8056C3F4; // type:object size:0x16 data:string +lbl_8056C40C = .data:0x8056C40C; // type:object size:0xF data:string +lbl_8056C41C = .data:0x8056C41C; // type:object size:0x12 data:string +lbl_8056C430 = .data:0x8056C430; // type:object size:0x13 data:string +lbl_8056C444 = .data:0x8056C444; // type:object size:0x16 data:string +lbl_8056C45C = .data:0x8056C45C; // type:object size:0x1A data:string +lbl_8056C478 = .data:0x8056C478; // type:object size:0x10 data:string +lbl_8056C488 = .data:0x8056C488; // type:object size:0x11 data:string +lbl_8056C49C = .data:0x8056C49C; // type:object size:0x15 data:string +lbl_8056C4B4 = .data:0x8056C4B4; // type:object size:0x16 data:string +lbl_8056C4CC = .data:0x8056C4CC; // type:object size:0x1C data:string +lbl_8056C4E8 = .data:0x8056C4E8; // type:object size:0x1C data:string +lbl_8056C504 = .data:0x8056C504; // type:object size:0x29 data:string +lbl_8056C530 = .data:0x8056C530; // type:object size:0xE data:string +lbl_8056C540 = .data:0x8056C540; // type:object size:0x26 data:string +lbl_8056C568 = .data:0x8056C568; // type:object size:0x26 data:string +lbl_8056C590 = .data:0x8056C590; // type:object size:0x11 data:string +lbl_8056C5A4 = .data:0x8056C5A4; // type:object size:0x11 data:string +lbl_8056C5B8 = .data:0x8056C5B8; // type:object size:0x11 data:string +lbl_8056C5CC = .data:0x8056C5CC; // type:object size:0x11 data:string +lbl_8056C5E0 = .data:0x8056C5E0; // type:object size:0xC data:string +lbl_8056C5F0 = .data:0x8056C5F0; // type:object size:0xD data:string lbl_8056C600 = .data:0x8056C600; // type:object size:0x108 lbl_8056C708 = .data:0x8056C708; // type:object size:0x808 lbl_8056CF10 = .data:0x8056CF10; // type:object size:0x110 @@ -39549,21 +39594,21 @@ lbl_80574DB8 = .sdata:0x80574DB8; // type:object size:0x8 data:byte mFormatBufferSize__Q34nw4r2ut17TextWriterBase = .sdata:0x80574DC0; // type:object size:0x4 scope:weak data:4byte mFormatBufferSize__Q34nw4r2ut17TextWriterBase = .sdata:0x80574DC4; // type:object size:0x4 scope:weak data:4byte lbl_80574DC8 = .sdata:0x80574DC8; // type:object size:0x4 data:string -lbl_80574DCC = .sdata:0x80574DCC; // type:object size:0x4 +lbl_80574DCC = .sdata:0x80574DCC; // type:object size:0x3 data:string lbl_80574DD0 = .sdata:0x80574DD0; // type:object size:0x4 data:string lbl_80574DD4 = .sdata:0x80574DD4; // type:object size:0x4 data:string lbl_80574DD8 = .sdata:0x80574DD8; // type:object size:0x8 data:string -lbl_80574DE0 = .sdata:0x80574DE0; // type:object size:0x8 +lbl_80574DE0 = .sdata:0x80574DE0; // type:object size:0x6 data:string lbl_80574DE8 = .sdata:0x80574DE8; // type:object size:0x4 data:string -lbl_80574DEC = .sdata:0x80574DEC; // type:object size:0x8 -lbl_80574DF4 = .sdata:0x80574DF4; // type:object size:0x4 -lbl_80574DF8 = .sdata:0x80574DF8; // type:object size:0x8 +lbl_80574DEC = .sdata:0x80574DEC; // type:object size:0x6 data:string +lbl_80574DF4 = .sdata:0x80574DF4; // type:object size:0x2 data:string +lbl_80574DF8 = .sdata:0x80574DF8; // type:object size:0x7 data:string lbl_80574E00 = .sdata:0x80574E00; // type:object size:0x8 data:string -lbl_80574E08 = .sdata:0x80574E08; // type:object size:0x8 +lbl_80574E08 = .sdata:0x80574E08; // type:object size:0x2 data:string lbl_80574E10 = .sdata:0x80574E10; // type:object size:0x4 data:4byte lbl_80574E14 = .sdata:0x80574E14; // type:object size:0x4 data:4byte lbl_80574E18 = .sdata:0x80574E18; // type:object size:0x4 data:4byte -lbl_80574E1C = .sdata:0x80574E1C; // type:object size:0xC +lbl_80574E1C = .sdata:0x80574E1C; // type:object size:0x5 data:string lbl_80574E28 = .sdata:0x80574E28; // type:object size:0x8 data:float lbl_80574E30 = .sdata:0x80574E30; // type:object size:0x8 data:string lbl_80574E38 = .sdata:0x80574E38; // type:object size:0x8 @@ -40832,13 +40877,13 @@ mDefaultTagProcessor__Q34nw4r2ut17TextWriterBase = .sbss:0x805765DC; // type: @GUARD@mDefaultTagProcessor__Q34nw4r2ut17TextWriterBase = .sbss:0x805765E0; // type:object size:0x1 scope:weak data:byte @GUARD@mDefaultTagProcessor__Q34nw4r2ut17TextWriterBase = .sbss:0x805765E1; // type:object size:0x1 scope:weak data:byte sInitialized__Q24nw4r2db = .sbss:0x805765E8; // type:object size:0x4 scope:local data:4byte -lbl_805765F0 = .sbss:0x805765F0; // type:object size:0x4 data:4byte -lbl_805765F4 = .sbss:0x805765F4; // type:object size:0x1 data:byte -lbl_805765F8 = .sbss:0x805765F8; // type:object size:0x8 -lbl_80576600 = .sbss:0x80576600; // type:object size:0x4 data:4byte -lbl_80576604 = .sbss:0x80576604; // type:object size:0x4 data:4byte -lbl_80576608 = .sbss:0x80576608; // type:object size:0x8 data:4byte -lbl_80576610 = .sbss:0x80576610; // type:object size:0x8 data:4byte +sConsoleList__Q24nw4r2db = .sbss:0x805765F0; // type:object size:0x4 scope:local data:4byte +sInited__Q24nw4r2db = .sbss:0x805765F4; // type:object size:0x1 data:byte +sMessageBuffer__Q24nw4r2db = .sbss:0x805765F8; // type:object size:0x8 +sFileLength__Q24nw4r2db = .sbss:0x80576600; // type:object size:0x4 scope:local data:4byte +sMapFileList__Q24nw4r2db = .sbss:0x80576604; // type:object size:0x4 scope:local data:4byte +GetCharPtr___Q24nw4r2db = .sbss:0x80576608; // type:object size:0x4 scope:local data:4byte +sConsoleHandle__Q24nw4r2db = .sbss:0x80576610; // type:object size:0x4 scope:local data:4byte lbl_80576618 = .sbss:0x80576618; // type:object size:0x4 data:4byte lbl_8057661C = .sbss:0x8057661C; // type:object size:0x4 data:4byte lbl_80576620 = .sbss:0x80576620; // type:object size:0x4 data:4byte @@ -47248,7 +47293,7 @@ lbl_8057EB90 = .sdata2:0x8057EB90; // type:object size:0x4 scope:local data:floa lbl_8057EB94 = .sdata2:0x8057EB94; // type:object size:0x4 scope:local data:float lbl_8057EB98 = .sdata2:0x8057EB98; // type:object size:0x8 scope:local data:double lbl_8057EBA0 = .sdata2:0x8057EBA0; // type:object size:0x4 scope:local data:float -lbl_8057EBA8 = .sdata2:0x8057EBA8; // type:object size:0x8 data:float +lbl_8057EBA8 = .sdata2:0x8057EBA8; // type:object size:0x4 data:float lbl_8057EBB0 = .sdata2:0x8057EBB0; // type:object size:0x4 data:float lbl_8057EBB4 = .sdata2:0x8057EBB4; // type:object size:0x4 data:float lbl_8057EBB8 = .sdata2:0x8057EBB8; // type:object size:0x4 data:float @@ -49306,12 +49351,12 @@ mLoadingTexture__Q34nw4r2ut10CharWriter = .bss:0x80636B58; // type:object size:0 @3896 = .bss:0x80636B74; // type:object size:0xC scope:local sFrameBufferInfo__Q24nw4r2db = .bss:0x80636B80; // type:object size:0x10 data:4byte sFrameBufferColor__Q24nw4r2db = .bss:0x80636B90; // type:object size:0x14 data:byte -lbl_80636BA8 = .bss:0x80636BA8; // type:object size:0x18 -lbl_80636BC0 = .bss:0x80636BC0; // type:object size:0x400 -lbl_80636FC0 = .bss:0x80636FC0; // type:object size:0x360 -lbl_80637320 = .bss:0x80637320; // type:object size:0x4000 -lbl_8063B320 = .bss:0x8063B320; // type:object size:0x200 -lbl_8063B520 = .bss:0x8063B520; // type:object size:0x40 +sMutex__Q24nw4r2db = .bss:0x80636BA8; // type:object size:0x18 +sStrBuf__Q24nw4r2db = .bss:0x80636BC0; // type:object size:0x400 +sException__Q24nw4r2db = .bss:0x80636FC0; // type:object size:0x360 +sThreadBuffer__Q24nw4r2db = .bss:0x80637320; // type:object size:0x4000 +sMapBuf__Q24nw4r2db = .bss:0x8063B320; // type:object size:0x200 scope:local +sFileInfo__Q24nw4r2db = .bss:0x8063B520; // type:object size:0x3C scope:local lbl_8063B560 = .bss:0x8063B560; // type:object size:0x300 lbl_8063B860 = .bss:0x8063B860; // type:object size:0x140 lbl_8063B9A0 = .bss:0x8063B9A0; // type:object size:0xC data:byte diff --git a/configure.py b/configure.py index 62187b35..5552d000 100644 --- a/configure.py +++ b/configure.py @@ -330,7 +330,11 @@ config.libs = [ nw4rLib( "db", [ + Object(Matching, "nw4r/db/db_assert.cpp"), Object(Matching, "nw4r/db/db_directPrint.cpp"), + Object(Matching, "nw4r/db/db_console.cpp"), + Object(Matching, "nw4r/db/db_exception.cpp"), + Object(Matching, "nw4r/db/db_mapFile.cpp"), ], ), nw4rLib( diff --git a/include/DynamicLink.h b/include/DynamicLink.h index 1e9e3319..da4a5a21 100644 --- a/include/DynamicLink.h +++ b/include/DynamicLink.h @@ -3,17 +3,19 @@ #include #include +#include #include class DbMapFile { public: - DbMapFile(): unk_0(0) {} + DbMapFile(): mMapFileHandle(nullptr) {} ~DbMapFile(); void RegisterOnDvd(const char *, const OSModuleInfo *); void Unregister(); private: - UNKWORD unk_0; + nw4r::db::MapFileHandle mMapFileHandle; + nw4r::db::MapFile mMapFile; }; // https://github.com/zeldaret/tp/blob/main/include/DynamicLink.h @@ -75,11 +77,6 @@ struct DynamicModuleControl : DynamicModuleControlBase { /* 0x2C */ mDvd_callback_c *mDvdCallbackRequest; /* 0x30 */ EGG::ExpHeap *mHeap; /* 0x34 */ DbMapFile mpRelMapFile; - // Some of these might be members of DbMapFile - UNKWORD unk1; - UNKWORD unk2; - UNKWORD unk3; - UNKWORD unk4; static u32 sAllocBytes; static mDvd_toMainRam_base_c *sDvdFile; diff --git a/include/MSL_C/MSL_Common/Src/printf.h b/include/MSL_C/MSL_Common/Src/printf.h index 5b1a7ccd..5e35c0f4 100644 --- a/include/MSL_C/MSL_Common/Src/printf.h +++ b/include/MSL_C/MSL_Common/Src/printf.h @@ -10,8 +10,8 @@ extern "C" { int fprintf(FILE* stream, const char* format, ...); int printf(const char* format, ...); -int sprintf(const char* str, const char* format, ...); -int snprintf(const char* str, size_t n, const char* format, ...); +int sprintf(char* str, const char* format, ...); +int snprintf(char* str, size_t n, const char* format, ...); int vsnprintf(char* str, size_t n, const char* format, va_list arg); int vprintf(const char* format, va_list arg); diff --git a/include/nw4r/db/db_assert.h b/include/nw4r/db/db_assert.h new file mode 100644 index 00000000..ecc21922 --- /dev/null +++ b/include/nw4r/db/db_assert.h @@ -0,0 +1,16 @@ +#ifndef NW4R_DB_ASSERT_H +#define NW4R_DB_ASSERT_H + +#include + +namespace nw4r { +namespace db { + +typedef detail::ConsoleHead *ConsoleHandle; + +ConsoleHandle Assertion_SetConsole(ConsoleHandle handle); + +} // namespace db +} // namespace nw4r + +#endif diff --git a/include/nw4r/db/db_console.h b/include/nw4r/db/db_console.h new file mode 100644 index 00000000..01921110 --- /dev/null +++ b/include/nw4r/db/db_console.h @@ -0,0 +1,52 @@ +#ifndef NW4R_DB_CONSOLE_H +#define NW4R_DB_CONSOLE_H + +#include +#include + +namespace nw4r { +namespace db { + +namespace detail { +typedef struct ConsoleHead { + u8 *textBuf; + u16 width; + u16 height; + u16 priority; + u16 attr; + u16 printTop; + u16 printXPos; + u16 ringTop; + u32 ringTopLineCnt; + s32 viewTopLine; + s16 viewPosX; + s16 viewPosY; + u16 viewLines; + bool isVisible; + nw4r::ut::TextWriterBase *writer; + ConsoleHead *next; +} ConsoleHead; + +} // namespace detail + +typedef detail::ConsoleHead *ConsoleHandle; + +enum ConsoleOutputType { + CONSOLE_OUTPUT_NONE = 0, + CONSOLE_OUTPUT_DISPLAY = 1, + CONSOLE_OUTPUT_TERMINAL = 2, + CONSOLE_OUTPUT_ALL = CONSOLE_OUTPUT_DISPLAY | CONSOLE_OUTPUT_TERMINAL, +}; + +ConsoleHandle Console_Create(void *arg, u16, u16, u16, u16, u16); +ConsoleHandle Console_Destroy(ConsoleHandle console); +void Console_DrawDirect(ConsoleHandle console); +void Console_VFPrintf(ConsoleOutputType type, ConsoleHandle console, const char* format, va_list vlist); +void Console_Printf(ConsoleHandle console, const char* format, ...); +s32 Console_GetTotalLines(ConsoleHandle console); + +} // namespace db +} // namespace nw4r + + +#endif diff --git a/include/nw4r/db/db_directPrint.h b/include/nw4r/db/db_directPrint.h index c3e682ec..cd78ceac 100644 --- a/include/nw4r/db/db_directPrint.h +++ b/include/nw4r/db/db_directPrint.h @@ -1,5 +1,5 @@ -#ifndef DB_DIRECT_PRINT_H -#define DB_DIRECT_PRINT_H +#ifndef NW4R_DB_DIRECT_PRINT_H +#define NW4R_DB_DIRECT_PRINT_H #include #include diff --git a/include/nw4r/db/db_exception.h b/include/nw4r/db/db_exception.h new file mode 100644 index 00000000..34bc646d --- /dev/null +++ b/include/nw4r/db/db_exception.h @@ -0,0 +1,26 @@ +#ifndef NW4R_DB_EXCEPTION_H +#define NW4R_DB_EXCEPTION_H + +#include +#include + + +namespace nw4r { +namespace db { + +typedef struct { + u16 error; + OSContext *ctx; + u32 dsisr; + u32 dar; +} ExceptionCallbackParam; + +void Exception_Init(); +ConsoleHandle Exception_SetConsole(ConsoleHandle, const _GXRenderModeObj *); +ConsoleHandle Exception_GetConsole(); +void Exception_SetUserCallback(bool (*)(ConsoleHandle, void *), void *); + +} // namespace db +} // namespace nw4r + +#endif diff --git a/include/nw4r/db/db_mapFile.h b/include/nw4r/db/db_mapFile.h new file mode 100644 index 00000000..1576109f --- /dev/null +++ b/include/nw4r/db/db_mapFile.h @@ -0,0 +1,26 @@ +#ifndef NW4R_DB_MAPFILE_H +#define NW4R_DB_MAPFILE_H + +#include + +namespace nw4r { +namespace db { + +typedef struct MapFile { + u8 *mapBuf; + const OSModuleInfo *moduleInfo; + s32 fileEntry; + MapFile *next; +} MapFile; + +typedef MapFile *MapFileHandle; + +MapFileHandle MapFile_RegistOnDvd(void *, const char *, const OSModuleInfo *); +void MapFile_Unregist(MapFileHandle); +void MapFile_UnregistAll(); +bool MapFile_QuerySymbol(u32 address, u8 *strBuf, u32 strBufSize); + +} // namespace db +} // namespace nw4r + +#endif diff --git a/include/rvl/OS/OSError.h b/include/rvl/OS/OSError.h index ac9ece4b..76b5463f 100644 --- a/include/rvl/OS/OSError.h +++ b/include/rvl/OS/OSError.h @@ -36,7 +36,7 @@ typedef enum { OS_ERR_MAX } OSErrorType; -typedef void (*OSErrorHandler)(u8 error, OSContext *ctx, u32 dsisr, u32 dar, ...); +typedef void (*OSErrorHandler)(u16 error, OSContext *ctx, u32 dsisr, u32 dar); extern OSErrorHandler __OSErrorTable[OS_ERR_MAX]; extern u32 __OSFpscrEnableBits; diff --git a/include/rvl/OS/OSLink.h b/include/rvl/OS/OSLink.h index 8f6df8b0..0bc13dc3 100644 --- a/include/rvl/OS/OSLink.h +++ b/include/rvl/OS/OSLink.h @@ -105,6 +105,7 @@ BOOL OSLinkFixed(OSModuleInfo* newModule, void* bss); BOOL OSUnlink(OSModuleInfo* module); void OSSetStringTable(void* string_table); void __OSModuleInit(void); +OSModuleInfo* OSSearchModule(void* ptr, u32* section, u32* offset); #ifdef __cplusplus }; diff --git a/src/DynamicLink.cpp b/src/DynamicLink.cpp index 2c7947c0..ec9fd045 100644 --- a/src/DynamicLink.cpp +++ b/src/DynamicLink.cpp @@ -320,35 +320,25 @@ const char *DynamicModuleControl::getModuleTypeString() const { } DbMapFile::~DbMapFile() { - if (unk_0) { + if (mMapFileHandle != nullptr) { Unregister(); } } -namespace nw4r { -namespace db { -// TODO -typedef struct MapFile { -} MapFile; -extern MapFile *MapFile_RegistOnDvd(void *arg, const char *buf, const OSModuleInfo *info); -extern void *MapFile_Unregist(MapFile *); -} // namespace db -} // namespace nw4r - void DbMapFile::RegisterOnDvd(const char *path, const OSModuleInfo *info) { if (mDvd::IsExistPath(path)) { - unk_0 = (UNKWORD)nw4r::db::MapFile_RegistOnDvd(((int *)this) + 1, path, info); + mMapFileHandle = nw4r::db::MapFile_RegistOnDvd(&mMapFile, path, info); } else { - unk_0 = 0xffffffff; + mMapFileHandle = (nw4r::db::MapFileHandle)0xffffffff; } } void DbMapFile::Unregister() { - if (unk_0 != 0) { - if (unk_0 != 0xffffffff) { - nw4r::db::MapFile_Unregist((nw4r::db::MapFile *)unk_0); + if (mMapFileHandle != nullptr) { + if ((u32)mMapFileHandle != 0xffffffff) { + nw4r::db::MapFile_Unregist(mMapFileHandle); } - unk_0 = 0; + mMapFileHandle = nullptr; } } diff --git a/src/egg/prim/eggAssert.cpp b/src/egg/prim/eggAssert.cpp index dc9e44a3..bde46ca9 100644 --- a/src/egg/prim/eggAssert.cpp +++ b/src/egg/prim/eggAssert.cpp @@ -3,18 +3,11 @@ #include #include #include +#include #include #include #include - -namespace nw4r { -namespace db { -// TODO -extern s32 MapFile_QuerySymbol(void *arg, char *buf, u32 buf_size); -} // namespace db -} // namespace nw4r - namespace EGG { namespace Assert { @@ -62,7 +55,7 @@ bool sAssertOccurred; /* 80674c60 */ char buf[260]; /* 8049c100 */ const char *getMapSymbol(void *arg) { - u32 success = nw4r::db::MapFile_QuerySymbol(arg, buf, sizeof(buf)); + bool success = nw4r::db::MapFile_QuerySymbol((u32)arg, (u8*)buf, sizeof(buf)); return success ? buf : nullptr; } diff --git a/src/nw4r/db/db_assert.cpp b/src/nw4r/db/db_assert.cpp new file mode 100644 index 00000000..d466a61f --- /dev/null +++ b/src/nw4r/db/db_assert.cpp @@ -0,0 +1,16 @@ +#include +#include + +namespace nw4r { +namespace db { + +static ConsoleHandle sConsoleHandle = nullptr; + +ConsoleHandle Assertion_SetConsole(ConsoleHandle handle) { + ConsoleHandle oldHandle = sConsoleHandle; + sConsoleHandle = handle; + return oldHandle; +} + +} // namespace db +} // namespace nw4r diff --git a/src/nw4r/db/db_console.cpp b/src/nw4r/db/db_console.cpp new file mode 100644 index 00000000..cb1a3126 --- /dev/null +++ b/src/nw4r/db/db_console.cpp @@ -0,0 +1,375 @@ +#include +#include +#include +#include +#include + +namespace nw4r { +namespace db { + +static ConsoleHandle sConsoleList; +static OSMutex sMutex; +static u8 sStrBuf[0x400]; +bool sInited; + +static ConsoleHandle FindInsertionPosition_(u16 priority) { + ConsoleHandle cursor = sConsoleList; + + if (cursor == nullptr || cursor->priority < priority) { + return nullptr; + } + + while (cursor->next != nullptr) { + if (cursor->next->priority < priority) { + return cursor; + } + cursor = cursor->next; + } + return cursor; +} + +static void Console_Append_(ConsoleHandle console) { + OSLockMutex(&sMutex); + + ConsoleHandle cursor = FindInsertionPosition_(console->priority); + + if (cursor == nullptr) { + console->next = sConsoleList; + sConsoleList = console; + } else { + console->next = cursor->next; + cursor->next = console; + } + OSUnlockMutex(&sMutex); +} + +void RemoveConsoleFromList_(ConsoleHandle console) { + OSLockMutex(&sMutex); + + if (sConsoleList == console) { + sConsoleList = console->next; + console->next = nullptr; + } else { + ConsoleHandle cursor = sConsoleList; + while (cursor->next != nullptr) { + if (cursor->next == console) { + cursor->next = console->next; + console->next = nullptr; + goto end; + } + cursor = cursor->next; + } +#line 386 + OSError("illegal console handle"); + } + +end: + OSUnlockMutex(&sMutex); +} + +static bool TryLockMutex_(OSMutex *mutex) { + if (OSGetCurrentThread() != nullptr) { + OSLockMutex(&sMutex); + return true; + } + + if (mutex->thread == nullptr) { + return true; + } + + return false; +} + +static void UnlockMutex_(OSMutex *mutex) { + if (OSGetCurrentThread() != nullptr) { + OSUnlockMutex(&sMutex); + } +} + +ConsoleHandle Console_Create(void *arg, u16 width, u16 height, u16 viewLines, u16 priority, u16 attr) { + ConsoleHandle console = (ConsoleHandle)arg; + if (!sInited) { + OSInitMutex(&sMutex); + sInited = true; + } + console->textBuf = (u8 *)(console + 1); + console->width = width; + console->height = height; + console->priority = priority; + console->attr = attr; + console->isVisible = false; + console->printTop = 0; + console->printXPos = 0; + console->ringTop = 0; + console->ringTopLineCnt = 0; + console->viewTopLine = 0; + console->viewPosX = 0x1e; + console->viewPosY = 0x32; + console->viewLines = viewLines; + console->writer = nullptr; + + if (TryLockMutex_(&sMutex)) { + BOOL intr = OSDisableInterrupts(); + console->printTop = 0; + console->printXPos = 0; + console->ringTop = 0; + console->ringTopLineCnt = 0; + console->viewTopLine = 0; + OSRestoreInterrupts(intr); + UnlockMutex_(&sMutex); + } + + Console_Append_(console); + return console; +} + +ConsoleHandle Console_Destroy(ConsoleHandle console) { + RemoveConsoleFromList_(console); + return console; +} + +static u8 *GetTextPtr_(ConsoleHandle console, u16 line, u16 xPos) { + return &console->textBuf[(console->width + 1) * line + xPos]; +} + +static u16 GetRingUsedLines_(ConsoleHandle console) { + s32 lines = console->printTop - console->ringTop; + if (lines < 0) { + lines += console->height; + } + return lines; +} + +static u16 GetActiveLines_(ConsoleHandle console) { + u16 lines = GetRingUsedLines_(console); + if (console->printXPos != 0) { + lines += 1; + } + + return lines; +} + +static void DoDrawString_(ConsoleHandle console, u32 printLine, const u8 *str, nw4r::ut::TextWriterBase *writer) { + if (writer != nullptr) { + writer->Printf("%s\n", str); + } else { + s32 height = console->viewPosY + printLine * 10; + db::DirectPrint_DrawString(console->viewPosX, height, false, "%s\n", str); + } +} + +static void DoDrawConsole_(ConsoleHandle console, nw4r::ut::TextWriterBase *writer) { + // I guess we don't care if locking the mutex fails?? + TryLockMutex_(&sMutex); + + s32 viewOffset = console->viewTopLine - console->ringTopLineCnt; + u16 line; + u16 printLines = 0; + u16 topLine; + + if (viewOffset < 0) { + viewOffset = 0; + } else if (viewOffset > GetActiveLines_(console)) { + goto err; + } + + line = console->ringTop + viewOffset; + if (line >= console->height) { + line -= console->height; + } + + topLine = console->printTop + ((console->printXPos > 0) ? 1 : 0); + if (topLine == console->height) { + topLine = 0; + } + + while (line != topLine) { + DoDrawString_(console, printLines, GetTextPtr_(console, line, 0), writer); + printLines++; + line++; + if (line == console->height) { + if ((console->attr & 2) != 0) { + break; + } + line = 0; + } + if (printLines >= console->viewLines) { + break; + } + } + +err: + UnlockMutex_(&sMutex); +} + +void Console_DrawDirect(ConsoleHandle console) { + if (DirectPrint_IsActive() && console->isVisible) { + DirectPrint_EraseXfb(console->viewPosX - 6, console->viewPosY - 3, console->width * 6 + 12, + console->viewLines * 10 + 4); + DoDrawConsole_(console, nullptr); + DirectPrint_StoreCache(); + } +} + +static void TerminateLine_(ConsoleHandle console) { + *GetTextPtr_(console, console->printTop, console->printXPos) = '\0'; +} + +static u32 GetTabSize_(ConsoleHandle console) { + s32 tab = (console->attr & 12) >> 2; + return 2 << tab; +} + +static u32 CodeWidth_(const u8 *p) { + return (*p >= 0x81) ? 2 : 1; +} + +static u32 PutChar_(ConsoleHandle console, const u8 *str, u8 *dstPtr) { + u32 codeWidth; + u32 count; + + codeWidth = CodeWidth_(str); + if (console->printXPos + codeWidth > console->width) { + return 0; + } else { + console->printXPos += codeWidth; + for (count = codeWidth; count > 0; count--) { + *dstPtr++ = *str++; + } + return codeWidth; + } +} + +static u8 *PutTab_(ConsoleHandle console, u8 *dstPtr) { + u32 tabWidth = GetTabSize_(console); + do { + *dstPtr++ = ' '; + console->printXPos++; + if (console->printXPos >= console->width) { + break; + } + } while ((console->printXPos & (tabWidth - 1)) != 0); + return dstPtr; +} + +static u8 *SearchEndOfLine_(const u8 *str) { + while (*str != '\n' && *str != '\0') { + str++; + } + return (u8 *)str; +} + +static u8 *NextLine_(ConsoleHandle console) { + *GetTextPtr_(console, console->printTop, console->printXPos) = '\0'; + console->printXPos = 0; + console->printTop++; + if (console->printTop == console->height && (console->attr & 2) == 0) { + console->printTop = 0; + } + + if (console->printTop == console->ringTop) { + console->ringTopLineCnt++; + if (++console->ringTop == console->height) { + console->ringTop = 0; + } + } + + return GetTextPtr_(console, console->printTop, 0); +} + +static void PrintToBuffer_(ConsoleHandle console, const u8 *str) { + BOOL enabled = OSDisableInterrupts(); + u8 *storePtr = GetTextPtr_(console, console->printTop, console->printXPos); + + while (*str != '\0') { + if ((console->attr & 2) && console->printTop == console->height) { + break; + } + + while (*str != '\0') { + bool newLineFlag = false; + if (*str == '\n') { + str++; + storePtr = NextLine_(console); + break; + } else if (*str == '\t') { + str++; + storePtr = PutTab_(console, storePtr); + } else { + u32 bytes = PutChar_(console, str, storePtr); + if (bytes > 0) { + str += bytes; + storePtr += bytes; + } else { + newLineFlag = true; + } + } + + if (console->printXPos >= console->width) { + newLineFlag = true; + } + + if (newLineFlag) { + if ((console->attr & 1) != 0) { + str = SearchEndOfLine_(str); + } else { + if (*str == '\n') { + str++; + } + storePtr = NextLine_(console); + } + break; + } + + if (*str == '\0') { + TerminateLine_(console); + } + } + } + + OSRestoreInterrupts(enabled); +} + +static void Console_PrintString_(ConsoleOutputType type, ConsoleHandle console, const u8 *str) { + if ((type & CONSOLE_OUTPUT_TERMINAL) != 0) { + OSReport("%s", str); + } + if ((type & CONSOLE_OUTPUT_DISPLAY) != 0) { + PrintToBuffer_(console, str); + } +} + +void Console_VFPrintf(ConsoleOutputType type, ConsoleHandle console, const char *format, va_list vlist) { + if (TryLockMutex_(&sMutex)) { + vsnprintf((char *)sStrBuf, sizeof(sStrBuf), format, vlist); + Console_PrintString_(type, console, sStrBuf); + + UnlockMutex_(&sMutex); + } +} +void Console_Printf(ConsoleHandle console, const char *format, ...) { + va_list args; + va_start(args, format); + + if (TryLockMutex_(&sMutex)) { + vsnprintf((char *)sStrBuf, sizeof(sStrBuf), format, args); + OSReport("%s", sStrBuf); + PrintToBuffer_(console, sStrBuf); + + UnlockMutex_(&sMutex); + } +} + +s32 Console_GetTotalLines(ConsoleHandle console) { + s32 count; + BOOL enabled = OSDisableInterrupts(); + + count = console->ringTopLineCnt + GetActiveLines_(console); + + OSRestoreInterrupts(enabled); + + return count; +} + +} // namespace db +} // namespace nw4r diff --git a/src/nw4r/db/db_exception.cpp b/src/nw4r/db/db_exception.cpp new file mode 100644 index 00000000..6485f0a3 --- /dev/null +++ b/src/nw4r/db/db_exception.cpp @@ -0,0 +1,492 @@ +#include +#include +#include +#include +#include +#include + +namespace nw4r { +namespace db { + +struct ExceptionStruct { + OSThread thread; + OSMessageQueue queue; + void *frameMemory; + u32 stackAddress; + ConsoleHandle consoleHandle; + const GXRenderModeObj *exceptionRenderObj; + bool (*exceptionCallback)(detail::ConsoleHead *, void *); + void *exceptionCallbackArgs; + u32 MSR_COPY; + u32 FPCSR_COPY; + u16 exceptionDisplayInfo; +}; + +static OSMessage sMessageBuffer[1]; +static struct ExceptionStruct sException; + +static u8 sThreadBuffer[0x4000] ALIGN(0x20); + +extern "C" u32 lbl_80574960; + +const char *CPU_EXP_NAME[] = { + "SYSTEM RESET", + "MACHINE CHECK", + "DSI", + "ISI", + "EXTERNAL INTERRUPT", + "ALIGNMENT", + "PROGRAM", + "FLOATING POINT", + "DECREMENTER", + "SYSTEM CALL", + "TRACE", + "PERFORMACE MONITOR", + "BREAK POINT", + "SYSTEM INTERRUPT", + "THERMAL INTERRUPT", + "PROTECTION", + "FLOATING POINT", +}; + +void *RunThread_(void *); +// TODO u8 vs u16 +void ErrorHandler_(u16, OSContext *, u32, u32); + +void Exception_Init() { + memset(&sException, 0, sizeof(struct ExceptionStruct)); + sException.exceptionCallback = nullptr; + sException.consoleHandle = nullptr; + sException.exceptionDisplayInfo = 0x21; + sException.frameMemory = nullptr; + sException.exceptionRenderObj = nullptr; + OSCreateThread(&sException.thread, RunThread_, nullptr, sThreadBuffer + 0x4000, 0x4000, 0, 1); + OSInitMessageQueue(&sException.queue, sMessageBuffer, 1); + OSResumeThread(&sException.thread); + OSSetErrorHandler(2, ErrorHandler_); + OSSetErrorHandler(3, ErrorHandler_); + OSSetErrorHandler(5, ErrorHandler_); + OSSetErrorHandler(15, ErrorHandler_); + lbl_80574960 = 0; + OSSetErrorHandler(16, nullptr); +} +extern "C" u32 PPCMfmsr(); +extern "C" void PPCMtmsr(u32); +extern "C" void OSFillFPUContext(OSContext *ctx); +extern "C" void fn_803AA2E0(u32, u32, u32, u32); + +static void DumpException_(const ExceptionCallbackParam *); + +void ErrorHandler_(u16 error, OSContext *ctx, u32 dsisr, u32 dar) { + sException.MSR_COPY = PPCMfmsr(); + sException.FPCSR_COPY = ctx->fpscr; + OSFillFPUContext(ctx); + OSSetErrorHandler(error, nullptr); + if (error == 0xf) { + fn_803AA2E0(0, 0, 0, 3); + fn_803AA2E0(1, 0, 0, 3); + fn_803AA2E0(2, 0, 0, 3); + fn_803AA2E0(3, 0, 0, 3); + } + ExceptionCallbackParam param; + + param.error = error; + param.ctx = ctx; + param.dsisr = dsisr; + param.dar = dar; + OSSendMessage(&sException.queue, ¶m, 1); + if (OSGetCurrentThread() == nullptr) { + VISetPreRetraceCallback(nullptr); + VISetPostRetraceCallback(nullptr); + PPCMtmsr(PPCMfmsr() | 2); + DumpException_(¶m); + } + while (OSEnableScheduler() > 0) {} + OSYieldThread(); + OSDisableScheduler(); +} + +void *RunThread_(void *) { + OSMessage message; + + u32 msr = PPCMfmsr(); + PPCMtmsr(msr & ~(0x800 | 0x100)); + OSReceiveMessage(&sException.queue, &message, 1); + OSDisableInterrupts(); + VISetPreRetraceCallback(nullptr); + VISetPostRetraceCallback(nullptr); + if (sException.consoleHandle != nullptr) { + VISetBlack(false); + VIFlush(); + } + DumpException_((const ExceptionCallbackParam *)message); + return nullptr; +} + +static void PrintContext_(u16, const OSContext *, u32, u32); +static void WaitTime_(s32 time); +static void Console_SetVisible(ConsoleHandle, bool); +static void Console_SetViewBaseLine(ConsoleHandle, s32); +static u32 Console_GetBufferHeadLine(ConsoleHandle); + +static void DrawConsoleEndless_(ConsoleHandle console) { + s32 lineCnt = Console_GetBufferHeadLine(console); + while (true) { + if (lineCnt >= Console_GetTotalLines(console)) { + lineCnt = console->ringTopLineCnt; + } + Console_SetViewBaseLine(sException.consoleHandle, lineCnt); + Console_DrawDirect(console); + + WaitTime_(200); + + lineCnt++; + } +} + +static void DumpException_(const ExceptionCallbackParam *param) { + u16 error = param->error; + OSContext *ctx = param->ctx; + u32 dsisr = param->dsisr; + u32 dar = param->dar; + + if (error < 0x11) { + sException.stackAddress = ctx->gprs[1]; + } + if (sException.consoleHandle != nullptr) { + sException.frameMemory = detail::DirectPrint_SetupFB(sException.exceptionRenderObj); + } + + while (true) { + PrintContext_(error, ctx, dsisr, dar); + if (sException.consoleHandle != nullptr && DirectPrint_IsActive()) { + Console_DrawDirect(sException.consoleHandle); + } + + if (sException.exceptionCallback != nullptr) { + u16 info = sException.exceptionDisplayInfo; + do { + if (!(sException.exceptionCallback)(sException.consoleHandle, sException.exceptionCallbackArgs)) { + return; + } + } while (info == sException.exceptionDisplayInfo); + } else if (sException.consoleHandle != nullptr) { + DrawConsoleEndless_(sException.consoleHandle); + } else { + break; + } + } +} + +static void Exception_Printf_(const char *format, ...) { + const GXRenderModeObj *obj = sException.exceptionRenderObj; + + va_list args; + va_start(args, fmt); + OSVReport(format, args); + va_end(args); + + if (sException.consoleHandle != nullptr) { + void *frameBuf = VIGetCurrentFrameBuffer(); + DirectPrint_ChangeXfb(frameBuf, obj->fbWidth, obj->xfbHeight); + + va_list args; + va_start(args, fmt); + Console_VFPrintf(CONSOLE_OUTPUT_DISPLAY, sException.consoleHandle, format, args); + va_end(args); + } +} + +static void ShowStackTrace_(u32); +static void ShowMainInfo_(u16, const OSContext *, u32, u32); +static void ShowGPR_(const OSContext *); +static void ShowSRR0Map_(const OSContext *); +static void ShowGPRMap_(const OSContext *); +static void ShowFloat_(const OSContext *); +static bool ShowMapInfoSubroutine_(u32 address, bool arg); + +static void PrintContext_(u16 error, const OSContext *context, u32 dsisr, u32 dar) { + if (error < 0x11) { + Exception_Printf_("******** EXCEPTION OCCURRED! ********\nFrameMemory:%XH\n", sException.frameMemory); + } else { + Exception_Printf_("******** USER HALT ********\nFrameMemory:%XH\n", sException.frameMemory); + } + + if (sException.exceptionDisplayInfo & 0x1) { + Exception_Printf_("---MainInfo---\n"); + ShowMainInfo_(error, context, dsisr, dar); + } + + if (sException.exceptionDisplayInfo & 0x2) { + Exception_Printf_("---EXCEPTION_INFO_GPR---\n"); + ShowGPR_(context); + } + + if (sException.exceptionDisplayInfo & 0x8) { + Exception_Printf_("---EXCEPTION_INFO_SRR0MAP---\n"); + ShowSRR0Map_(context); + } + + if (sException.exceptionDisplayInfo & 0x4) { + Exception_Printf_("---EXCEPTION_INFO_GPRMAP---\n"); + ShowGPRMap_(context); + } + + if (sException.exceptionDisplayInfo & 0x10) { + Exception_Printf_("---EXCEPTION_INFO_FPR---\n"); + ShowFloat_(context); + Exception_Printf_(" MSR:%08XH FPSCR:%08XH\n", sException.MSR_COPY, sException.FPCSR_COPY); + } + + if (sException.exceptionDisplayInfo & 0x20) { + Exception_Printf_("---EXCEPTION_INFO_TRACE---\n"); + ShowStackTrace_(sException.stackAddress); + } + + Exception_Printf_("--------------------------------\n"); +} + +static bool IsValidStackAddr_(u32 stackAddress) { + if (stackAddress == 0 || stackAddress == 0xFFFFFFFF) { + return false; + } else if (OS_MEM_IS_MEM1(stackAddress)) { + if ((stackAddress & 0x0fffffff) >= OSGetPhysicalMem1Size()) { + return false; + } + } else if (OS_MEM_IS_MEM2(stackAddress)) { + if ((stackAddress & 0x0fffffff) >= OSGetPhysicalMem2Size()) { + return false; + } + } else { + return false; + } + + return true; +} + +static void ShowStackTrace_(u32 stackAddress) { + Exception_Printf_("-------------------------------- TRACE\n"); + Exception_Printf_("Stack Address: %08X\n", stackAddress); + Exception_Printf_("LR save\n"); + + u32 i; + u32 *ptr = (u32 *)stackAddress; + for (i = 0; i < 16; i++) { + if (!IsValidStackAddr_((u32)ptr)) { + break; + } + Exception_Printf_("%08X ", ptr[1]); + u32 fp = ptr[1]; + // TODO arg + if (!ShowMapInfoSubroutine_(fp, true)) { + Exception_Printf_("\n"); + } + ptr = (u32 *)*ptr; + } +} + +void ShowMainInfo_(u16 error, const OSContext *context, u32 dsisr, u32 dar) { + if (error < 0x11) { + Exception_Printf_("CONTEXT:%08XH (%s EXCEPTION)\n", context, CPU_EXP_NAME[error]); + } else { + Exception_Printf_("CONTEXT:%08XH\n", context); + } + /* floating point error */ + if (error == 0x10) { + u32 uVar1 = sException.FPCSR_COPY; + uVar1 &= (((uVar1 & 0xf8) << 0x16) | 0x01f80700); + if ((uVar1 & 0x20000000) != 0) { + Exception_Printf_(" FPE: Invalid operation\n"); + if ((sException.FPCSR_COPY & 0x1000000) != 0) { + Exception_Printf_(" SNaN\n"); + } + if ((sException.FPCSR_COPY & 0x800000) != 0) { + Exception_Printf_(" Infinity - Infinity\n"); + } + if ((sException.FPCSR_COPY & 0x400000) != 0) { + Exception_Printf_(" Infinity / Infinity\n"); + } + if ((sException.FPCSR_COPY & 0x200000) != 0) { + Exception_Printf_(" 0 / 0\n"); + } + if ((sException.FPCSR_COPY & 0x100000) != 0) { + Exception_Printf_(" Infinity * 0\n"); + } + if ((sException.FPCSR_COPY & 0x80000) != 0) { + Exception_Printf_(" Invalid compare\n"); + } + if ((sException.FPCSR_COPY & 0x400) != 0) { + Exception_Printf_(" Software request\n"); + } + if ((sException.FPCSR_COPY & 0x200) != 0) { + Exception_Printf_(" Invalid square root\n"); + } + if ((sException.FPCSR_COPY & 0x100) != 0) { + Exception_Printf_(" Invalid integer convert\n"); + } + } + if ((uVar1 & 0x10000000) != 0) { + Exception_Printf_(" FPE: Overflow\n"); + } + if ((uVar1 & 0x8000000) != 0) { + Exception_Printf_(" FPE: Underflow\n"); + } + if ((uVar1 & 0x4000000) != 0) { + Exception_Printf_(" FPE: Zero division\n"); + } + if ((uVar1 & 0x2000000) != 0) { + Exception_Printf_(" FPE: Inexact result\n"); + } + } + Exception_Printf_("SRR0: %08XH SRR1:%08XH\n", context->srr0, context->srr1); + Exception_Printf_("DSISR: %08XH DAR: %08XH\n", dsisr, dar); +} + +void ShowGPR_(const OSContext *ctx) { + Exception_Printf_("-------------------------------- GPR\n"); + for (int i = 0; i < 10; i++) { + Exception_Printf_("R%02d:%08XH R%02d:%08XH R%02d:%08XH\n", i, ctx->gprs[i], i + 11, ctx->gprs[i + 11], i + 22, + ctx->gprs[i + 22]); + } + Exception_Printf_("R%02d:%08XH R%02d:%08XH\n", 10, ctx->gprs[10], 21, ctx->gprs[21]); +} + +void ShowGPRMap_(const OSContext *ctx) { + bool shownAny = false; + Exception_Printf_("-------------------------------- GPRMAP\n"); + for (int i = 0; i <= 31; i++) { + u32 address = ctx->gprs[i]; + if ((address < 0x80000000) || (0x82ffffff < address)) { + continue; + } + shownAny = true; + Exception_Printf_("R%02d: %08XH ", i, address); + // TODO arg + if (!ShowMapInfoSubroutine_(address, true)) { + Exception_Printf_(" no information\n"); + } + } + + if (!shownAny) { + Exception_Printf_(" no register which seem to address.\n"); + } +} + +void ShowSRR0Map_(const OSContext *ctx) { + Exception_Printf_("-------------------------------- SRR0MAP\n"); + u32 address = ctx->srr0; + if (!((address < 0x80000000) || (0x82ffffff < address))) { + Exception_Printf_("SRR0: %08XH ", address); + // TODO arg + if (!ShowMapInfoSubroutine_(address, true)) { + Exception_Printf_(" no information\n"); + } + } +} + +// 804ca0e4 +extern "C" int __fpclassifyf(float val); + +static void ShowFloatSub_(s32 reg, f32 val); + +void ShowFloat_(const OSContext *ctx) { + Exception_Printf_("-------------------------------- FPR\n"); + for (int i = 0; i < 10; i++) { + ShowFloatSub_(i, ctx->fprs[i]); + Exception_Printf_(" "); + ShowFloatSub_(i + 11, ctx->fprs[i + 11]); + Exception_Printf_(" "); + ShowFloatSub_(i + 22, ctx->fprs[i + 22]); + Exception_Printf_("\n"); + } + ShowFloatSub_(10, ctx->fprs[10]); + Exception_Printf_(" "); + ShowFloatSub_(21, ctx->fprs[21]); + + Exception_Printf_("\n"); +} + +void ShowFloatSub_(s32 reg, f32 val) { + if (__fpclassifyf(val) == 1) { + Exception_Printf_("F%02d: Nan ", reg); + } else { + if (__fpclassifyf(val) == 2) { + if ((reinterpret_cast(val) & 0x80) != 0) { + Exception_Printf_("F%02d:+Inf ", reg); + } else { + Exception_Printf_("F%02d:-Inf ", reg); + } + } else if (val == 0.0f) { + Exception_Printf_("F%02d: 0.0 ", reg); + } else { + Exception_Printf_("F%02d:%+.3E", reg, val); + } + } +} + +static void SetFPException_(u32) { + // TODO +} + +bool ShowMapInfoSubroutine_(u32 address, bool arg) { + if ((address < 0x80000000) || (0x82ffffff < address)) { + return false; + } else { + u8 acStack_124[260]; + if (nw4r::db::MapFile_QuerySymbol(address, acStack_124, sizeof(acStack_124))) { + Exception_Printf_("%s\n", acStack_124); + return true; + } else { + return false; + } + } +} + +ConsoleHandle Exception_SetConsole(ConsoleHandle console, const GXRenderModeObj *renderObj) { + ConsoleHandle old = sException.consoleHandle; + sException.exceptionRenderObj = renderObj; + sException.consoleHandle = console; + return old; +} + +ConsoleHandle Exception_GetConsole() { + return sException.consoleHandle; +} + +void Exception_SetUserCallback(bool (*callback)(detail::ConsoleHead *, void *), void *args) { + sException.exceptionCallback = callback; + sException.exceptionCallbackArgs = args; +} + +u16 Exception_SetDisplayInfo(u16 newInfo) { + u16 old = sException.exceptionDisplayInfo; + sException.exceptionDisplayInfo = newInfo; + return old; +} + +static void WaitTime_(s32 time) { + s64 t1 = OSGetTime(); + s64 t2; + do { + t2 = OSGetTime(); + } while ((t2 - t1) / ((OS_BUS_CLOCK_SPEED / 4) / 1000) < time); +} +/* +void DrawConsoleEndless_(detail::ConsoleHead *) { + // TODO +} +*/ +static void Console_SetVisible(detail::ConsoleHead *, bool) { + // TODO +} + +static void Console_SetViewBaseLine(detail::ConsoleHead *console, s32 line) { + console->viewTopLine = line; +} + +static u32 Console_GetBufferHeadLine(detail::ConsoleHead *console) { + return console->ringTopLineCnt; +} + +} // namespace db +} // namespace nw4r diff --git a/src/nw4r/db/db_mapFile.cpp b/src/nw4r/db/db_mapFile.cpp new file mode 100644 index 00000000..6b73fbc0 --- /dev/null +++ b/src/nw4r/db/db_mapFile.cpp @@ -0,0 +1,342 @@ +#include +#include +#include +#include + +namespace nw4r { +namespace db { + +static u32 sFileLength; +static MapFile *sMapFileList = nullptr; +static u8 (*GetCharPtr_)(const u8 *) = nullptr; + +static u8 sMapBuf[512] ALIGN(32); +static DVDFileInfo sFileInfo; + +static s32 sMapBufMaxSize = 0x200; +static u8 *sDvdBuf = sMapBuf; +static s32 sMapBufOffset = -1; + +static void MapFile_Append_(MapFile *file) { + if (sMapFileList == nullptr) { + sMapFileList = file; + return; + } + + if (file->moduleInfo != nullptr) { + file->next = sMapFileList->next; + sMapFileList->next = file; + } else { + file->next = sMapFileList; + sMapFileList = file; + } +} + +/** 80436a50 */ +MapFileHandle MapFile_RegistOnDvd(void *buf, const char *path, const OSModuleInfo *info) { + MapFile *file = (MapFile *)buf; + file->mapBuf = nullptr; + file->moduleInfo = info; + file->fileEntry = DVDConvertPathToEntrynum(path); + file->next = nullptr; + + MapFile_Append_(file); + return file; +} + +/** 80436ae0 */ +void MapFile_Unregist(MapFileHandle file) { + if (file == sMapFileList) { + sMapFileList = sMapFileList->next; + return; + } + + MapFile *cursor = sMapFileList; + for (; cursor != nullptr; cursor = cursor->next) { + if (cursor->next == file) { + cursor->next = file->next; + return; + } + } +} + +/** 80436b30 */ +void MapFile_UnregistAll() { + sMapFileList = nullptr; +} + +/** 80436b40 */ +static u8 GetCharOnMem_(const u8 *arg) { + return *arg; +} + +/** 80436b50 */ +static u8 GetCharOnDvd_(const u8 *buf) { + s32 address = (u32)buf & 0x7fffffff; + s32 offset = address - sMapBufOffset; + if (address >= sFileLength) { + return 0; + } + + if (sMapBufOffset < 0 || offset < 0 || offset >= sMapBufMaxSize) { + sMapBufOffset = ROUND_DOWN(address, 32); + offset = address - sMapBufOffset; + address = sMapBufMaxSize; + if (sMapBufOffset + sMapBufMaxSize >= sFileLength) { + address = ROUND_UP(sFileLength - sMapBufOffset, 32); + } + BOOL enabled = OSEnableInterrupts(); + BOOL read = DVDReadAsyncPrio(&sFileInfo, sDvdBuf, address, sMapBufOffset, nullptr, 2); + while (DVDGetCommandBlockStatus(&sFileInfo.block)) {} + + OSRestoreInterrupts(enabled); + if (read <= 0) { + return 0; + } + } + return *(sDvdBuf + offset); +} + +static u8 *SearchNextLine_(u8 *buf, s32 lines) { + u8 c; + + if (buf == nullptr) { + return nullptr; + } + + while ((c = (GetCharPtr_)(buf)) != '\0') { + if (c == '\n') { + if (--lines <= 0) { + return buf + 1; + } + } + buf++; + } + + return nullptr; +} + +static u8 *SearchNextSection_(u8 *buf) { + do { + buf = SearchNextLine_(buf, 1); + if (buf == nullptr) { + return nullptr; + } + } while ((GetCharPtr_)(buf) != '.'); + return buf; +} + +static u8 *SearchParam_(u8 *lineTop, u32 argNum, u8 splitter) { + bool inArg = false; + u8 *buf = lineTop; + + if (buf == nullptr) { + return nullptr; + } + while (true) { + u8 c = (GetCharPtr_)(buf); + if (c == '\0' || c == '\n') { + return 0; + } + if (inArg) { + if (c == splitter) { + inArg = false; + } + } else if (c != splitter) { + if (argNum-- == 0) { + return buf; + } + inArg = true; + } + buf++; + } +} + +static u32 XStrToU32_(const u8 *str) { + u32 val = 0; + + while (true) { + u32 num; + u8 c = (GetCharPtr_)(str); + if ('0' <= c && c <= '9') { + num = c - '0'; + } else if ('a' <= c && c <= 'z') { + num = c - 'a' + 10; + } else if ('A' <= c && c <= 'Z') { + num = c - 'A' + 10; + } else { + return val; + } + + if (val >= 0x10000000) { + return 0; + } + val = num + val * 16; + str++; + } +} + +static u32 CopySymbol_(const u8 *buf, u8 *str, u32 strLenMax, u8 splitter) { + u32 cnt = 0; + + while (true) { + u8 c = (GetCharPtr_)(buf++); + if (c == splitter || c == '\0' || c == '\n') { + *str = '\0'; + return cnt; + } + *str++ = c; + if (++cnt >= strLenMax - 1) { + *str = '\0'; + return cnt; + } + } +} + +bool QuerySymbolToMapFile_(u8 *buf, const OSModuleInfo *moduleInfo, u32 address, u8 *strBuf, u32 strBufSize) { + OSSectionInfo *sectionInfo = nullptr; + u32 sectionCnt; + + if (moduleInfo != nullptr) { + sectionInfo = OSGetSectionInfo(moduleInfo); + sectionCnt = moduleInfo->numSections; + } + + while (true) { + u32 offset = 0; + buf = SearchNextSection_(buf); + buf = SearchNextLine_(buf, 3); + if (sectionInfo != nullptr) { + offset = ROUND_DOWN(sectionInfo->offset, 2); + if (address < offset || address >= offset + sectionInfo->size) { + goto next; + } + } + + while (true) { + u8 *param; + u32 startAddr; + u32 size; + buf = SearchNextLine_(buf, 1); + if (buf == nullptr) { + return false; + } + param = SearchParam_(buf, 1, ' '); + if (param == nullptr) { + goto next; + } + size = XStrToU32_(param); + param = SearchParam_(buf, 2, ' '); + if (param == nullptr) { + goto next; + } + startAddr = XStrToU32_(param); + if (startAddr == 0) { + continue; + } + startAddr += offset; + if (address < startAddr || startAddr + size <= address) { + continue; + } + + param = SearchParam_(buf, 5, ' '); + if (param == nullptr) { + strBuf[0] = '\0'; + return true; + } + if ((GetCharPtr_)(param) == '.') { + continue; + } + + CopySymbol_(param, strBuf, strBufSize, '\t'); + return true; + } + next: + if (sectionInfo != nullptr) { + if (--sectionCnt == 0) { + return 0; + } + sectionInfo++; + } + } +} + +// No idea, doesn't appear in the DWARF +/** 804370d0 */ +bool UnkFunction_(const OSModuleInfo *moduleInfo, u32 address, u8 *strBuf, u32 strBufSize) { + if (moduleInfo == nullptr) { + if (address < (u32)_stack_end) { + snprintf((char *)strBuf, strBufSize, "[%p]", address); + return true; + } else { + return false; + } + } else { + u32 sectionIdx = 0; + OSSectionInfo *sectionInfo = OSGetSectionInfo(moduleInfo); + for (u32 sectionCnt = 0; sectionCnt < moduleInfo->numSections; sectionCnt++) { + u32 offset = ROUND_DOWN(sectionInfo->offset, 2); + if (offset <= address && address < offset + sectionInfo->size) { + snprintf((char *)strBuf, strBufSize, "[%d:%d:%06x]", moduleInfo->id, sectionIdx, address - offset); + return true; + } + sectionInfo++; + sectionIdx++; + } + return false; + } +} + +bool QuerySymbolToSingleMapFile_(MapFileHandle pMapFile, u32 address, u8 *strBuf, u32 strBufSize) { + if (pMapFile->mapBuf != nullptr) { + GetCharPtr_ = GetCharOnMem_; + return QuerySymbolToMapFile_(pMapFile->mapBuf, pMapFile->moduleInfo, address, strBuf, strBufSize); + } else if (pMapFile->fileEntry >= 0) { + u8 *buf = (u8 *)0x80000000; + bool ret; + if (!DVDFastOpen(pMapFile->fileEntry, &sFileInfo)) { + goto err; + } + sMapBufOffset = -1; + sFileLength = sFileInfo.size; + GetCharPtr_ = GetCharOnDvd_; + ret = QuerySymbolToMapFile_(buf, pMapFile->moduleInfo, address, strBuf, strBufSize); + DVDClose(&sFileInfo); + return ret; + } else { + return UnkFunction_(pMapFile->moduleInfo, address, strBuf, strBufSize); + } + +err: + strBuf[0] = '\0'; + return false; +} + +bool MapFile_QuerySymbol(u32 address, u8 *strBuf, u32 strBufSize) { + if (sMapFileList == nullptr) { + if (address < (u32)_stack_end) { + snprintf((char *)strBuf, strBufSize, "[%p]", address); + return true; + } else { + u32 offset; + u32 section; + OSModuleInfo *info = OSSearchModule((void *)address, §ion, &offset); + if (info) { + snprintf((char *)strBuf, strBufSize, "[%d:%d:%06x]", info->id, section, offset); + return true; + } + return false; + } + } else { + for (MapFile *pMap = sMapFileList; pMap != nullptr; pMap = pMap->next) { + if (QuerySymbolToSingleMapFile_(pMap, address, strBuf, strBufSize)) { + return true; + } + } + + return false; + } +} + +} // namespace db +} // namespace nw4r