diff --git a/.vscode/settings.json b/.vscode/settings.json index ad567b1..c0d76da 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -37,5 +37,6 @@ ], "C/C++ Include Guard.Auto Update Path Blocklist": [ "include/zlib" - ] + ], + "search.useIgnoreFiles": false } diff --git a/config/G2ME01/splits.txt b/config/G2ME01/splits.txt index f5570bd..dcfc6b0 100644 --- a/config/G2ME01/splits.txt +++ b/config/G2ME01/splits.txt @@ -74,3 +74,18 @@ Runtime/Gecko_ExceptionPPC.cp: .rodata start:0x803B03B0 end:0x803B0448 .data start:0x803BBFD8 end:0x803BC0C0 .bss start:0x803E0640 end:0x803E0650 + +Dolphin/ar/ar.c: + .text start:0x8035512C end:0x80356C7C + .data start:0x803BCCB8 end:0x803BCD00 + .sdata start:0x80418D18 end:0x80418D20 + .sbss start:0x80419D68 end:0x80419D88 + +Dolphin/ar/arq.c: + .text start:0x80356C7C end:0x80357020 + .data start:0x803BCD00 end:0x803BCD48 + .sdata start:0x80418D20 end:0x80418D24 + .sbss start:0x80419D88 end:0x80419DB0 + +Dolphin/PPCArch.c: + .text start:0x80357020 end:0x8035713C diff --git a/config/G2ME01/symbols.txt b/config/G2ME01/symbols.txt index acf3cee..ab62396 100644 --- a/config/G2ME01/symbols.txt +++ b/config/G2ME01/symbols.txt @@ -15698,29 +15698,29 @@ VIGetTvFormat = .text:0x80354E0C; // type:function size:0x68 scope:global fn_80354E74 = .text:0x80354E74; // type:function size:0x3C align:0x4 fn_80354EB0 = .text:0x80354EB0; // type:function size:0x21C fn_803550CC = .text:0x803550CC; // type:function size:0x60 -fn_8035512C = .text:0x8035512C; // type:function size:0x44 -fn_80355170 = .text:0x80355170; // type:function size:0xF0 -fn_80355260 = .text:0x80355260; // type:function size:0x68 -fn_803552C8 = .text:0x803552C8; // type:function size:0x74 -fn_8035533C = .text:0x8035533C; // type:function size:0xC4 -fn_80355400 = .text:0x80355400; // type:function size:0x8 -fn_80355408 = .text:0x80355408; // type:function size:0x8 -fn_80355410 = .text:0x80355410; // type:function size:0x78 align:0x4 -fn_80355488 = .text:0x80355488; // type:function size:0x17F4 -fn_80356C7C = .text:0x80356C7C; // type:function size:0x100 -fn_80356D7C = .text:0x80356D7C; // type:function size:0x4 align:0x4 -fn_80356D80 = .text:0x80356D80; // type:function size:0xCC align:0x4 -fn_80356E4C = .text:0x80356E4C; // type:function size:0x70 -fn_80356EBC = .text:0x80356EBC; // type:function size:0x15C -fn_80357018 = .text:0x80357018; // type:function size:0x8 align:0x4 +ARRegisterDMACallback = .text:0x8035512C; // type:function size:0x44 +ARStartDMA = .text:0x80355170; // type:function size:0xF0 +ARAlloc = .text:0x80355260; // type:function size:0x68 +ARFree = .text:0x803552C8; // type:function size:0x74 +ARInit = .text:0x8035533C; // type:function size:0xC4 +ARGetBaseAddress = .text:0x80355400; // type:function size:0x8 +ARGetSize = .text:0x80355408; // type:function size:0x8 +__ARHandler = .text:0x80355410; // type:function size:0x78 align:0x4 +__ARChecksize = .text:0x80355488; // type:function size:0x17F4 +__ARQServiceQueueLo = .text:0x80356C7C; // type:function size:0x100 +__ARQCallbackHack = .text:0x80356D7C; // type:function size:0x4 align:0x4 +__ARQInterruptServiceRoutine = .text:0x80356D80; // type:function size:0xCC align:0x4 +ARQInit = .text:0x80356E4C; // type:function size:0x70 +ARQPostRequest = .text:0x80356EBC; // type:function size:0x15C +ARQGetChunkSize = .text:0x80357018; // type:function size:0x8 align:0x4 PPCMfmsr = .text:0x80357020; // type:function size:0x8 scope:global PPCMtmsr = .text:0x80357028; // type:function size:0x8 scope:global PPCMfhid0 = .text:0x80357030; // type:function size:0x8 scope:global -fn_80357038 = .text:0x80357038; // type:function size:0x8 +PPCMthid0 = .text:0x80357038; // type:function size:0x8 PPCMfl2cr = .text:0x80357040; // type:function size:0x8 scope:global PPCMtl2cr = .text:0x80357048; // type:function size:0x8 scope:global PPCMtdec = .text:0x80357050; // type:function size:0x8 scope:weak -fn_80357058 = .text:0x80357058; // type:function size:0x8 +PPCSync = .text:0x80357058; // type:function size:0x8 PPCHalt = .text:0x80357060; // type:function size:0x14 scope:weak PPCMtmmcr0 = .text:0x80357074; // type:function size:0x8 scope:global PPCMtmmcr1 = .text:0x8035707C; // type:function size:0x8 scope:global @@ -15732,9 +15732,9 @@ PPCMffpscr = .text:0x803570A4; // type:function size:0x20 scope:global PPCMtfpscr = .text:0x803570C4; // type:function size:0x28 scope:global PPCMfhid2 = .text:0x803570EC; // type:function size:0x8 scope:global PPCMthid2 = .text:0x803570F4; // type:function size:0x8 scope:global -fn_803570FC = .text:0x803570FC; // type:function size:0x8 +PPCMtwpar = .text:0x803570FC; // type:function size:0x8 PPCDisableSpeculation = .text:0x80357104; // type:function size:0x28 scope:global -fn_8035712C = .text:0x8035712C; // type:function size:0x8 +PPCSetFpIEEEMode = .text:0x8035712C; // type:function size:0x8 PPCSetFpNonIEEEMode = .text:0x80357134; // type:function size:0x8 scope:global fn_8035713C = .text:0x8035713C; // type:function size:0x4 align:0x4 fn_80357140 = .text:0x80357140; // type:function size:0x34 align:0x4 @@ -20085,8 +20085,8 @@ lbl_80418CF8 = .sdata:0x80418CF8; // type:object size:0x8 data:double lbl_80418D00 = .sdata:0x80418D00; // type:object size:0x8 data:float lbl_80418D08 = .sdata:0x80418D08; // type:object size:0x4 data:4byte lbl_80418D0C = .sdata:0x80418D0C; // type:object size:0xC -lbl_80418D18 = .sdata:0x80418D18; // type:object size:0x8 data:4byte -lbl_80418D20 = .sdata:0x80418D20; // type:object size:0x8 data:4byte +__ARVersion = .sdata:0x80418D18; // type:object size:0x8 data:4byte +__ARQVersion = .sdata:0x80418D20; // type:object size:0x8 data:4byte lbl_80418D28 = .sdata:0x80418D28; // type:object size:0x8 data:4byte lbl_80418D30 = .sdata:0x80418D30; // type:object size:0x8 data:4byte lbl_80418D38 = .sdata:0x80418D38; // type:object size:0x2 data:2byte @@ -20952,24 +20952,24 @@ lbl_80419D54 = .sbss:0x80419D54; // type:object size:0x4 data:4byte lbl_80419D58 = .sbss:0x80419D58; // type:object size:0x4 data:4byte lbl_80419D5C = .sbss:0x80419D5C; // type:object size:0x4 data:4byte lbl_80419D60 = .sbss:0x80419D60; // type:object size:0x8 data:4byte -lbl_80419D68 = .sbss:0x80419D68; // type:object size:0x4 data:4byte -lbl_80419D6C = .sbss:0x80419D6C; // type:object size:0x4 data:4byte -lbl_80419D70 = .sbss:0x80419D70; // type:object size:0x4 data:4byte -lbl_80419D74 = .sbss:0x80419D74; // type:object size:0x4 data:4byte -lbl_80419D78 = .sbss:0x80419D78; // type:object size:0x4 data:4byte -lbl_80419D7C = .sbss:0x80419D7C; // type:object size:0x4 data:4byte -lbl_80419D80 = .sbss:0x80419D80; // type:object size:0x4 data:4byte -lbl_80419D84 = .sbss:0x80419D84; // type:object size:0x4 data:4byte -lbl_80419D88 = .sbss:0x80419D88; // type:object size:0x4 data:4byte -lbl_80419D8C = .sbss:0x80419D8C; // type:object size:0x4 data:4byte -lbl_80419D90 = .sbss:0x80419D90; // type:object size:0x4 data:4byte -lbl_80419D94 = .sbss:0x80419D94; // type:object size:0x4 data:4byte -lbl_80419D98 = .sbss:0x80419D98; // type:object size:0x4 data:4byte -lbl_80419D9C = .sbss:0x80419D9C; // type:object size:0x4 data:4byte -lbl_80419DA0 = .sbss:0x80419DA0; // type:object size:0x4 data:4byte -lbl_80419DA4 = .sbss:0x80419DA4; // type:object size:0x4 data:4byte -lbl_80419DA8 = .sbss:0x80419DA8; // type:object size:0x4 data:4byte -lbl_80419DAC = .sbss:0x80419DAC; // type:object size:0x4 data:4byte +__AR_Callback = .sbss:0x80419D68; // type:object size:0x4 data:4byte +__AR_Size = .sbss:0x80419D6C; // type:object size:0x4 data:4byte +__AR_InternalSize = .sbss:0x80419D70; // type:object size:0x4 data:4byte +__AR_ExpansionSize = .sbss:0x80419D74; // type:object size:0x4 data:4byte +__AR_StackPointer = .sbss:0x80419D78; // type:object size:0x4 data:4byte +__AR_FreeBlocks = .sbss:0x80419D7C; // type:object size:0x4 data:4byte +__AR_BlockLength = .sbss:0x80419D80; // type:object size:0x4 data:4byte +__AR_init_flag = .sbss:0x80419D84; // type:object size:0x4 data:4byte +__ARQRequestQueueHi = .sbss:0x80419D88; // type:object size:0x4 data:4byte +__ARQRequestTailHi = .sbss:0x80419D8C; // type:object size:0x4 data:4byte +__ARQRequestQueueLo = .sbss:0x80419D90; // type:object size:0x4 data:4byte +__ARQRequestTailLo = .sbss:0x80419D94; // type:object size:0x4 data:4byte +__ARQRequestPendingHi = .sbss:0x80419D98; // type:object size:0x4 data:4byte +__ARQRequestPendingLo = .sbss:0x80419D9C; // type:object size:0x4 data:4byte +__ARQCallbackHi = .sbss:0x80419DA0; // type:object size:0x4 data:4byte +__ARQCallbackLo = .sbss:0x80419DA4; // type:object size:0x4 data:4byte +__ARQChunkSize = .sbss:0x80419DA8; // type:object size:0x4 data:4byte +__ARQ_init_flag = .sbss:0x80419DAC; // type:object size:0x4 data:4byte lbl_80419DB0 = .sbss:0x80419DB0; // type:object size:0x2 data:2byte lbl_80419DB2 = .sbss:0x80419DB2; // type:object size:0x6 data:2byte __DBInterface = .sbss:0x80419DB8; // type:object size:0x4 scope:global data:4byte diff --git a/configure.py b/configure.py index 4c93b9c..f7a7bb4 100644 --- a/configure.py +++ b/configure.py @@ -42,7 +42,26 @@ LIBS = [ ["Kyoto/Math/CVector3f.cpp", False], ["Kyoto/Math/CVector3i.cpp", False], ] - } + }, + { + "lib": "ar", + "mw_version": "1.2.5n", + "cflags": "$cflags_base", + "host": False, + "objects": [ + ["Dolphin/ar/ar.c", False], + ["Dolphin/ar/arq.c", False], + ], + }, + { + "lib": "base", + "mw_version": "1.2.5", + "cflags": "$cflags_base", + "host": False, + "objects": [ + ["Dolphin/PPCArch.c", False], + ], + }, ] VERSIONS = [ "G2ME01", # 0 diff --git a/include/asm_types.h b/include/asm_types.h new file mode 100644 index 0000000..02d75dc --- /dev/null +++ b/include/asm_types.h @@ -0,0 +1,84 @@ +#ifndef _ASM_TYPES +#define _ASM_TYPES + +// Special Purpose Registers (SPRs) +#define XER 1 +#define LR 8 +#define CTR 9 +#define DSISR 18 +#define DAR 19 +#define DEC 22 +#define SDR1 25 +#define SRR0 26 +#define SRR1 27 +#define SPRG0 272 +#define SPRG1 273 +#define SPRG2 274 +#define SPRG3 275 +#define EAR 282 +#define PVR 287 +#define IBAT0U 528 +#define IBAT0L 529 +#define IBAT1U 530 +#define IBAT1L 531 +#define IBAT2U 532 +#define IBAT2L 533 +#define IBAT3U 534 +#define IBAT3L 535 +#define DBAT0U 536 +#define DBAT0L 537 +#define DBAT1U 538 +#define DBAT1L 539 +#define DBAT2U 540 +#define DBAT2L 541 +#define DBAT3U 542 +#define DBAT3L 543 +#define GQR0 912 +#define GQR1 913 +#define GQR2 914 +#define GQR3 915 +#define GQR4 916 +#define GQR5 917 +#define GQR6 918 +#define GQR7 919 +#define HID2 920 +#define WPAR 921 +#define DMA_U 922 +#define DMA_L 923 +#define UMMCR0 936 +#define UPMC1 937 +#define UPMC2 938 +#define USIA 939 +#define UMMCR1 940 +#define UPMC3 941 +#define UPMC4 942 +#define USDA 943 +#define MMCR0 952 +#define PMC1 953 +#define PMC2 954 +#define SIA 955 +#define MMCR1 956 +#define PMC3 957 +#define PMC4 958 +#define SDA 959 +#define HID0 1008 +#define HID1 1009 +#define IABR 1010 +#define DABR 1013 +#define L2CR 1017 +#define ICTC 1019 +#define THRM1 1020 +#define THRM2 1021 +#define THRM3 1022 + +// Condition Registers (CRs) +#define cr0 0 +#define cr1 1 +#define cr2 2 +#define cr3 3 +#define cr4 4 +#define cr5 5 +#define cr6 6 +#define cr7 7 + +#endif // _ASM_TYPES diff --git a/src/Dolphin/PPCArch.c b/src/Dolphin/PPCArch.c new file mode 100644 index 0000000..404d702 --- /dev/null +++ b/src/Dolphin/PPCArch.c @@ -0,0 +1,565 @@ +#include "types.h" +#include "asm_types.h" +// clang-format off + +union FpscrUnion +{ + f64 f; + struct + { + u32 fpscr_pad; + u32 fpscr; + } u; +}; + +#define HID0_SPD 0x00000200 // Speculative cache access enable (0 enable) + +/* + * --INFO-- + * Address: 8036F7D4 + * Size: 000008 + */ +asm u32 PPCMfmsr (void) +{ + nofralloc + mfmsr r3 + blr +} + +/* + * --INFO-- + * Address: 8036F7DC + * Size: 000008 + */ +asm void PPCMtmsr (register u32 newMSR) +{ + nofralloc + mtmsr newMSR + blr +} + +/* + * --INFO-- + * Address: ........ + * Size: 00000C + */ +void PPCOrMsr(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: ........ + * Size: 00000C + */ +void PPCAndMsr(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: ........ + * Size: 00000C + */ +void PPCAndCMsr(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: 8036F7E4 + * Size: 000008 + */ +asm u32 PPCMfhid0 (void) +{ + nofralloc + mfspr r3, HID0 + blr +} + +/* + * --INFO-- + * Address: 8036F7EC + * Size: 000008 + */ +asm void PPCMthid0 (register u32 newHID0) +{ + nofralloc + mtspr HID0, newHID0 + blr +} + +/* + * --INFO-- + * Address: ........ + * Size: 000008 + */ +asm void PPCMfhid1(void) +{ + nofralloc + mfspr r3, HID1 + blr +} + +/* + * --INFO-- + * Address: 8036F7F4 + * Size: 000008 + */ +asm u32 PPCMfl2cr (void) +{ + nofralloc + mfspr r3, L2CR + blr +} + +/* + * --INFO-- + * Address: 8036F7FC + * Size: 000008 + */ +asm void PPCMtl2cr (register u32 newL2cr) +{ + nofralloc + mtspr L2CR, newL2cr + blr +} + +/* + * --INFO-- + * Address: 8036F804 + * Size: 000008 + */ +__declspec ( weak ) asm void PPCMtdec ( register u32 newDec ) +{ + nofralloc + mtdec newDec + blr +} + +/* + * --INFO-- + * Address: ........ + * Size: 000008 + */ +asm void PPCMfdec(void) +{ + nofralloc + mfdec r3 + blr +} + +/* + * --INFO-- + * Address: 8036F80C + * Size: 000008 + */ +asm void PPCSync (void) +{ + nofralloc + sc + blr +} + +/* + * --INFO-- + * Address: ........ + * Size: 000034 + */ +asm void PPCEieio(void) { + nofralloc + mfmsr r5 + rlwinm r6, r5, 0, 0x11, 0xf + mtmsr r6 + mfspr r3, hid0 + ori r4, r3, 8 + mtspr hid0, r4 + isync + eieio + isync + + mtspr hid0, r3 + mtmsr r5 + isync + + blr +} + +/* + * --INFO-- + * Address: 8036F814 + * Size: 000014 + */ +__declspec ( weak ) asm void PPCHalt (void) //spins infinitely +{ + nofralloc + + sync + +_spin: + nop + li r3, 0 + nop + b _spin + + // NEVER REACHED +} + +/* + * --INFO-- + * Address: ........ + * Size: 000008 + */ +asm void PPCMfmmcr0(void) +{ + nofralloc + mfspr r3, MMCR0 + blr +} + +/* + * --INFO-- + * Address: ........ + * Size: 000008 + * UNUSED + */ +asm void PPCMtmmcr0 (register u32 newMmcr0) +{ + nofralloc + mtspr MMCR0, newMmcr0 + blr +} + +/* + * --INFO-- + * Address: ........ + * Size: 000008 + */ +asm void PPCMfmmcr1(void) +{ + nofralloc + mfspr r3, MMCR1 + blr} + +/* + * --INFO-- + * Address: ........ + * Size: 000008 + * UNUSED + */ +asm void PPCMtmmcr1 (register u32 newMmcr1) +{ + nofralloc + mtspr MMCR1, newMmcr1 + blr +} + +/* + * --INFO-- + * Address: ........ + * Size: 000008 + */ +asm void PPCMfpmc1(void) +{ + nofralloc + mfspr r3, PMC1 + blr +} + +/* + * --INFO-- + * Address: ........ + * Size: 000008 + * UNUSED + */ +asm void PPCMtpmc1 (register u32 newPmc1) +{ + nofralloc + mtspr PMC1, newPmc1 + blr +} + +/* + * --INFO-- + * Address: ........ + * Size: 000008 + */ +asm void PPCMfpmc2(void) +{ + nofralloc + mfspr r3, PMC2 + blr +} + +/* + * --INFO-- + * Address: ........ + * Size: 000008 + * UNUSED + */ +asm void PPCMtpmc2 (register u32 newPmc2) +{ + nofralloc + mtspr PMC2, newPmc2 + blr +} + +/* + * --INFO-- + * Address: ........ + * Size: 000008 + */ +asm void PPCMfpmc3(void) +{ + nofralloc + mfspr r3, PMC2 + blr} + +/* + * --INFO-- + * Address: ........ + * Size: 000008 + * UNUSED + */ +asm void PPCMtpmc3 (register u32 newPmc3) +{ + nofralloc + mtspr PMC3, newPmc3 + blr +} + +/* + * --INFO-- + * Address: ........ + * Size: 000008 + */ +asm void PPCMfpmc4(void) +{ + nofralloc + mfspr r3, PMC4 + blr +} + +/* + * --INFO-- + * Address: ........ + * Size: 000008 + * UNUSED + */ +asm void PPCMtpmc4 (register u32 newPmc4) +{ + nofralloc + mtspr PMC4, newPmc4 + blr +} + +/* + * --INFO-- + * Address: ........ + * Size: 000008 + */ +asm void PPCMfsia(void) +{ + nofralloc + mfspr r3, SIA + blr} + +/* + * --INFO-- + * Address: ........ + * Size: 000008 + */ +asm void PPCMtsia(register u32 newSia) +{ + nofralloc + mtspr SIA, newSia + blr +} + +/* + * --INFO-- + * Address: 8036F828 + * Size: 000020 + */ +u32 PPCMffpscr(void) +{ + union FpscrUnion m; + + + asm + { + mffs fp31 + stfd fp31, m.f; + } + + return m.u.fpscr; +} + +/* + * --INFO-- + * Address: 8036F848 + * Size: 000028 + */ +void PPCMtfpscr(register u32 newFPSCR) +{ + union FpscrUnion m; + + asm + { + li r4, 0 + stw r4, m.u.fpscr_pad; + stw newFPSCR, m.u.fpscr + lfd fp31, m.f + mtfsf 0xff, fp31 + } +} + +/* + * --INFO-- + * Address: 8036F870 + * Size: 000008 + */ +asm u32 PPCMfhid2 ( void ) +{ + nofralloc + mfspr r3, HID2 + blr +} + +/* + * --INFO-- + * Address: 8036F878 + * Size: 000008 + */ +asm void PPCMthid2 ( register u32 newhid2 ) +{ + nofralloc + mtspr HID2, newhid2 + blr +} + +/* + * --INFO-- + * Address: 8036F880 + * Size: 00000C + */ +asm u32 PPCMfwpar(void) +{ + nofralloc + sync + mfspr r3, WPAR + blr +} + +/* + * --INFO-- + * Address: 8036F88C + * Size: 000008 + */ +asm void PPCMtwpar ( register u32 newwpar ) +{ + nofralloc + mtspr WPAR, newwpar + blr +} + +/* + * --INFO-- + * Address: ........ + * Size: 000008 + */ +asm void PPCMfdmaU(void) +{ + nofralloc + mfspr r3, DMA_U + blr +} + +/* + * --INFO-- + * Address: ........ + * Size: 000008 + */ +asm void PPCMfdmaL(void) +{ + nofralloc + mfspr r3, DMA_L + blr +} + +/* + * --INFO-- + * Address: ........ + * Size: 000008 + */ +void PPCMtdmaU(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: ........ + * Size: 000008 + */ +void PPCMtdmaL(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: ........ + * Size: 000008 + */ +void PPCMfpvr(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: ........ + * Size: 000028 + */ +void PPCEnableSpeculation(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: 8036F894 + * Size: 000028 + */ +void PPCDisableSpeculation (void) +{ + PPCMthid0(PPCMfhid0() | HID0_SPD); +} + +/* + * --INFO-- + * Address: 8036F8BC + * Size: 000008 + */ +asm void PPCSetFpIEEEMode(void) +{ + nofralloc + mtfsb0 4*7+1 + blr +} +/* + * --INFO-- + * Address: 8036F8C4 + * Size: 000008 + */ +asm void PPCSetFpNonIEEEMode (void) +{ + nofralloc + mtfsb1 4*7+1 + blr +} +// clang-format on diff --git a/src/Dolphin/ar/ar.c b/src/Dolphin/ar/ar.c new file mode 100644 index 0000000..6f1de96 --- /dev/null +++ b/src/Dolphin/ar/ar.c @@ -0,0 +1,385 @@ +#include "dolphin/ar.h" + +#include "dolphin/hw_regs.h" +#include "dolphin/os.h" + +// static const char* __ARVersion = +// "<< Dolphin SDK - AR\trelease build: Sep 5 2002 05:34:27 (0x2301) >>"; +static const char* __ARVersion = + "<< Dolphin SDK - AR\trelease build: Apr 5 2004 04:15:03 (0x2301) >>"; + +static ARCallback __AR_Callback; +static u32 __AR_Size; +static u32 __AR_InternalSize; +static u32 __AR_ExpansionSize; + +static u32 __AR_StackPointer; +static u32 __AR_FreeBlocks; +static u32* __AR_BlockLength; + +static volatile BOOL __AR_init_flag = FALSE; + +static void __ARHandler(__OSInterrupt interrupt, OSContext* context); +static void __ARChecksize(void); +static void __ARClearArea(u32 start_addr, u32 length); + +ARCallback ARRegisterDMACallback(ARCallback callback) { + ARCallback oldCb; + BOOL enabled; + oldCb = __AR_Callback; + enabled = OSDisableInterrupts(); + __AR_Callback = callback; + OSRestoreInterrupts(enabled); + return oldCb; +} + +u32 ARGetDMAStatus() { + BOOL enabled; + u32 val; + enabled = OSDisableInterrupts(); + val = __DSPRegs[5] & 0x0200; + OSRestoreInterrupts(enabled); + return val; +} + +void ARStartDMA(u32 type, u32 mainmem_addr, u32 aram_addr, u32 length) { + BOOL enabled; + + enabled = OSDisableInterrupts(); + + __DSPRegs[16] = (u16)(__DSPRegs[16] & ~0x3ff) | (u16)(mainmem_addr >> 16); + __DSPRegs[17] = (u16)(__DSPRegs[17] & ~0xffe0) | (u16)(mainmem_addr & 0xffff); + __DSPRegs[18] = (u16)(__DSPRegs[18] & ~0x3ff) | (u16)(aram_addr >> 16); + __DSPRegs[19] = (u16)(__DSPRegs[19] & ~0xffe0) | (u16)(aram_addr & 0xffff); + __DSPRegs[20] = (u16)((__DSPRegs[20] & ~0x8000) | (type << 15)); + __DSPRegs[20] = (u16)(__DSPRegs[20] & ~0x3ff) | (u16)(length >> 16); + __DSPRegs[21] = (u16)(__DSPRegs[21] & ~0xffe0) | (u16)(length & 0xffff); + OSRestoreInterrupts(enabled); +} + +u32 ARAlloc(u32 length) { + u32 tmp; + BOOL enabled; + + enabled = OSDisableInterrupts(); + tmp = __AR_StackPointer; + __AR_StackPointer += length; + *__AR_BlockLength = length; + __AR_BlockLength++; + __AR_FreeBlocks--; + OSRestoreInterrupts(enabled); + + return tmp; +} + +u32 ARFree(u32* length) { + BOOL old; + + old = OSDisableInterrupts(); + + __AR_BlockLength--; + + if (length) { + *length = *__AR_BlockLength; + } + + __AR_StackPointer -= *__AR_BlockLength; + + __AR_FreeBlocks++; + + OSRestoreInterrupts(old); + + return __AR_StackPointer; +} + +BOOL ARCheckInit() { return __AR_init_flag; } + +u32 ARInit(u32* stack_index_addr, u32 num_entries) { + + BOOL old; + u16 refresh; + + if (__AR_init_flag == TRUE) { + return 0x4000; + } + + OSRegisterVersion(__ARVersion); + + old = OSDisableInterrupts(); + + __AR_Callback = NULL; + + __OSSetInterruptHandler(__OS_INTERRUPT_DSP_ARAM, __ARHandler); + __OSUnmaskInterrupts(OS_INTERRUPTMASK_DSP_ARAM); + + __AR_StackPointer = 0x4000; + __AR_FreeBlocks = num_entries; + __AR_BlockLength = stack_index_addr; + + refresh = (u16)(__DSPRegs[13] & 0x000000ff); + + __DSPRegs[13] = (u16)((__DSPRegs[13] & ~0x000000ff) | (refresh & 0x000000ff)); + + __ARChecksize(); + + __AR_init_flag = TRUE; + + OSRestoreInterrupts(old); + + return __AR_StackPointer; +} + +u32 ARGetBaseAddress(void) { return 0x4000; } + +u32 ARGetSize() { return __AR_Size; } + +static void __ARHandler(__OSInterrupt interrupt, OSContext* context) { + + OSContext exceptionContext; + u16 tmp; + + tmp = __DSPRegs[5]; + tmp = (u16)((tmp & ~0x00000088) | 0x20); + __DSPRegs[5] = tmp; + + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + + if (__AR_Callback) { + (*__AR_Callback)(); + } + + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); +} + +#define RoundUP32(x) (((u32)(x) + 32 - 1) & ~(32 - 1)) + +void __ARClearInterrupt(void) { + + u16 tmp; + tmp = __DSPRegs[5]; + tmp = (u16)((tmp & ~(0x00000080 | 0x00000008)) | 0x00000020); + __DSPRegs[5] = tmp; +} +u16 __ARGetInterruptStatus(void) { return ((u16)(__DSPRegs[5] & 0x0200)); } + +static void __ARWaitForDMA(void) { + + while (__DSPRegs[5] & 0x0200) { + } +} + +static void __ARWriteDMA(u32 mmem_addr, u32 aram_addr, u32 length) { + + __DSPRegs[16] = (u16)((__DSPRegs[16] & ~0x03ff) | (u16)(mmem_addr >> 16)); + __DSPRegs[16 + 1] = (u16)((__DSPRegs[16 + 1] & ~0xffe0) | (u16)(mmem_addr & 0xffff)); + + __DSPRegs[18] = (u16)((__DSPRegs[18] & ~0x03ff) | (u16)(aram_addr >> 16)); + __DSPRegs[18 + 1] = (u16)((__DSPRegs[18 + 1] & ~0xffe0) | (u16)(aram_addr & 0xffff)); + + __DSPRegs[20] = (u16)(__DSPRegs[20] & ~0x8000); + + __DSPRegs[20] = (u16)((__DSPRegs[20] & ~0x03ff) | (u16)(length >> 16)); + __DSPRegs[20 + 1] = (u16)((__DSPRegs[20 + 1] & ~0xffe0) | (u16)(length & 0xffff)); + + __ARWaitForDMA(); + + __ARClearInterrupt(); +} + +static void __ARReadDMA(u32 mmem_addr, u32 aram_addr, u32 length) { + + __DSPRegs[16] = (u16)((__DSPRegs[16] & ~0x03ff) | (u16)(mmem_addr >> 16)); + __DSPRegs[16 + 1] = (u16)((__DSPRegs[16 + 1] & ~0xffe0) | (u16)(mmem_addr & 0xffff)); + + __DSPRegs[18] = (u16)((__DSPRegs[18] & ~0x03ff) | (u16)(aram_addr >> 16)); + __DSPRegs[18 + 1] = (u16)((__DSPRegs[18 + 1] & ~0xffe0) | (u16)(aram_addr & 0xffff)); + + __DSPRegs[20] = (u16)(__DSPRegs[20] | 0x8000); + + __DSPRegs[20] = (u16)((__DSPRegs[20] & ~0x03ff) | (u16)(length >> 16)); + __DSPRegs[20 + 1] = (u16)((__DSPRegs[20 + 1] & ~0xffe0) | (u16)(length & 0xffff)); + + __ARWaitForDMA(); + + __ARClearInterrupt(); +} + +static void __ARChecksize(void) { + + u8 test_data_pad[0x20 + 31]; + u8 dummy_data_pad[0x20 + 31]; + u8 buffer_pad[0x20 + 31]; + + u8 save_pad_1[0x20 + 31]; + u8 save_pad_2[0x20 + 31]; + u8 save_pad_3[0x20 + 31]; + u8 save_pad_4[0x20 + 31]; + u8 save_pad_5[0x20 + 31]; + + u32* test_data; + u32* dummy_data; + u32* buffer; + u32* save1; + u32* save2; + u32* save3; + u32* save4; + u32* save5; + + u16 ARAM_mode = 0; + u32 ARAM_size = 0; + + u32 i; + + while (!(__DSPRegs[11] & 1)) + ; + + ARAM_mode = 3; + ARAM_size = __AR_InternalSize = 0x1000000; + __DSPRegs[9] = (u16)((__DSPRegs[9] & ~(0x00000007 | 0x00000038)) | 0x20 | 2 | 1); + + test_data = (u32*)(RoundUP32((u32)(test_data_pad))); + dummy_data = (u32*)(RoundUP32((u32)(dummy_data_pad))); + buffer = (u32*)(RoundUP32((u32)(buffer_pad))); + + save1 = (u32*)(RoundUP32((u32)(save_pad_1))); + save2 = (u32*)(RoundUP32((u32)(save_pad_2))); + save3 = (u32*)(RoundUP32((u32)(save_pad_3))); + save4 = (u32*)(RoundUP32((u32)(save_pad_4))); + save5 = (u32*)(RoundUP32((u32)(save_pad_5))); + + for (i = 0; i < 8; i++) { + *(test_data + i) = 0xdeadbeef; + *(dummy_data + i) = 0xbad0bad0; + } + + DCFlushRange((void*)test_data, 0x20); + DCFlushRange((void*)dummy_data, 0x20); + + __AR_ExpansionSize = 0; + + DCInvalidateRange((void*)save1, 0x20); + __ARReadDMA((u32)save1, ARAM_size + 0, 0x20); + PPCSync(); + + __ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20); + + memset((void*)buffer, 0, 0x20); + DCFlushRange((void*)buffer, 0x20); + + __ARReadDMA((u32)buffer, ARAM_size + 0x0000000, 0x20); + PPCSync(); + + if (buffer[0] == test_data[0]) { + + DCInvalidateRange((void*)save2, 0x20); + __ARReadDMA((u32)save2, ARAM_size + 0x0200000, 0x20); + PPCSync(); + + DCInvalidateRange((void*)save3, 0x20); + __ARReadDMA((u32)save3, ARAM_size + 0x1000000, 0x20); + PPCSync(); + + DCInvalidateRange((void*)save4, 0x20); + __ARReadDMA((u32)save4, ARAM_size + 0x0000200, 0x20); + PPCSync(); + + DCInvalidateRange((void*)save5, 0x20); + __ARReadDMA((u32)save5, ARAM_size + 0x0400000, 0x20); + PPCSync(); + + __ARWriteDMA((u32)dummy_data, ARAM_size + 0x0200000, 0x20); + + __ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20); + + memset((void*)buffer, 0, 0x20); + DCFlushRange((void*)buffer, 0x20); + + __ARReadDMA((u32)buffer, ARAM_size + 0x0200000, 0x20); + PPCSync(); + + if (buffer[0] == test_data[0]) { + __ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20); + + ARAM_mode |= 0 << 1; + ARAM_size += 0x0200000; + __AR_ExpansionSize = 0x0200000; + } else { + __ARWriteDMA((u32)dummy_data, ARAM_size + 0x1000000, 0x20); + + __ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20); + + memset((void*)buffer, 0, 0x20); + DCFlushRange((void*)buffer, 0x20); + + __ARReadDMA((u32)buffer, ARAM_size + 0x1000000, 0x20); + PPCSync(); + + if (buffer[0] == test_data[0]) { + __ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20); + __ARWriteDMA((u32)save2, ARAM_size + 0x0200000, 0x20); + + ARAM_mode |= 4 << 1; + ARAM_size += 0x0400000; + __AR_ExpansionSize = 0x0400000; + } else { + __ARWriteDMA((u32)dummy_data, ARAM_size + 0x0000200, 0x20); + + __ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20); + + memset((void*)buffer, 0, 0x20); + DCFlushRange((void*)buffer, 0x20); + + __ARReadDMA((u32)buffer, ARAM_size + 0x0000200, 0x20); + PPCSync(); + + if (buffer[0] == test_data[0]) { + __ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20); + __ARWriteDMA((u32)save2, ARAM_size + 0x0200000, 0x20); + __ARWriteDMA((u32)save3, ARAM_size + 0x1000000, 0x20); + + ARAM_mode |= 8 << 1; + ARAM_size += 0x0800000; + __AR_ExpansionSize = 0x0800000; + } else { + __ARWriteDMA((u32)dummy_data, ARAM_size + 0x0400000, 0x20); + + __ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20); + + memset((void*)buffer, 0, 0x20); + DCFlushRange((void*)buffer, 0x20); + + __ARReadDMA((u32)buffer, ARAM_size + 0x0400000, 0x20); + PPCSync(); + + if (buffer[0] == test_data[0]) { + __ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20); + __ARWriteDMA((u32)save2, ARAM_size + 0x0200000, 0x20); + __ARWriteDMA((u32)save3, ARAM_size + 0x1000000, 0x20); + __ARWriteDMA((u32)save4, ARAM_size + 0x0000200, 0x20); + + ARAM_mode |= 12 << 1; + ARAM_size += 0x1000000; + __AR_ExpansionSize = 0x1000000; + } else { + __ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20); + __ARWriteDMA((u32)save2, ARAM_size + 0x0200000, 0x20); + __ARWriteDMA((u32)save3, ARAM_size + 0x1000000, 0x20); + __ARWriteDMA((u32)save4, ARAM_size + 0x0000200, 0x20); + __ARWriteDMA((u32)save5, ARAM_size + 0x0400000, 0x20); + + ARAM_mode |= 16 << 1; + ARAM_size += 0x2000000; + __AR_ExpansionSize = 0x2000000; + } + } + } + } + __DSPRegs[9] = (u16)((__DSPRegs[9] & ~(0x07 | 0x38)) | ARAM_mode); + } + + *(u32*)OSPhysicalToUncached(0x00D0) = ARAM_size; + + __AR_Size = ARAM_size; +} diff --git a/src/Dolphin/ar/arq.c b/src/Dolphin/ar/arq.c new file mode 100644 index 0000000..57c636b --- /dev/null +++ b/src/Dolphin/ar/arq.c @@ -0,0 +1,171 @@ +#include "dolphin/arq.h" +#include "dolphin/os.h" + +//const char* __ARQVersion = "<< Dolphin SDK - ARQ\trelease build: Sep 5 2002 05:34:29 (0x2301) >>"; +const char* __ARQVersion = "<< Dolphin SDK - ARQ\trelease build: Apr 5 2004 04:15:04 (0x2301) >>"; +static ARQRequest* __ARQRequestQueueHi; +static ARQRequest* __ARQRequestTailHi; +static ARQRequest* __ARQRequestQueueLo; +static ARQRequest* __ARQRequestTailLo; +static ARQRequest* __ARQRequestPendingHi; +static ARQRequest* __ARQRequestPendingLo; +static ARQCallback __ARQCallbackHi; +static ARQCallback __ARQCallbackLo; +static u32 __ARQChunkSize; + +static volatile BOOL __ARQ_init_flag = FALSE; + +void __ARQPopTaskQueueHi(void); +void __ARQServiceQueueLo(void); +void __ARQCallbackHack(void); +void __ARQInterruptServiceRoutine(void); +void __ARQInitTempQueue(void); +void __ARQPushTempQueue(ARQRequest* task); + +void __ARQPopTaskQueueHi(void) { + + if (__ARQRequestQueueHi) { + if (__ARQRequestQueueHi->type == ARQ_TYPE_MRAM_TO_ARAM) { + ARStartDMA(__ARQRequestQueueHi->type, __ARQRequestQueueHi->source, __ARQRequestQueueHi->dest, + __ARQRequestQueueHi->length); + } else { + ARStartDMA(__ARQRequestQueueHi->type, __ARQRequestQueueHi->dest, __ARQRequestQueueHi->source, + __ARQRequestQueueHi->length); + } + + __ARQCallbackHi = __ARQRequestQueueHi->callback; + + __ARQRequestPendingHi = __ARQRequestQueueHi; + + __ARQRequestQueueHi = __ARQRequestQueueHi->next; + } +} + +void __ARQServiceQueueLo(void) { + + if ((__ARQRequestPendingLo == NULL) && (__ARQRequestQueueLo)) { + __ARQRequestPendingLo = __ARQRequestQueueLo; + + __ARQRequestQueueLo = __ARQRequestQueueLo->next; + } + + if (__ARQRequestPendingLo) { + if (__ARQRequestPendingLo->length <= __ARQChunkSize) { + if (__ARQRequestPendingLo->type == ARQ_TYPE_MRAM_TO_ARAM) + ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->source, + __ARQRequestPendingLo->dest, __ARQRequestPendingLo->length); + else + ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->dest, + __ARQRequestPendingLo->source, __ARQRequestPendingLo->length); + + __ARQCallbackLo = __ARQRequestPendingLo->callback; + } else { + if (__ARQRequestPendingLo->type == ARQ_TYPE_MRAM_TO_ARAM) + ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->source, + __ARQRequestPendingLo->dest, __ARQChunkSize); + else + ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->dest, + __ARQRequestPendingLo->source, __ARQChunkSize); + } + + __ARQRequestPendingLo->length -= __ARQChunkSize; + __ARQRequestPendingLo->source += __ARQChunkSize; + __ARQRequestPendingLo->dest += __ARQChunkSize; + } +} +void __ARQCallbackHack(void) { return; } + +void __ARQInterruptServiceRoutine(void) { + + if (__ARQCallbackHi) { + (*__ARQCallbackHi)((u32)__ARQRequestPendingHi); + __ARQRequestPendingHi = NULL; + __ARQCallbackHi = NULL; + } + + else if (__ARQCallbackLo) { + (*__ARQCallbackLo)((u32)__ARQRequestPendingLo); + __ARQRequestPendingLo = NULL; + __ARQCallbackLo = NULL; + } + + __ARQPopTaskQueueHi(); + + if (__ARQRequestPendingHi == NULL) + __ARQServiceQueueLo(); +} + +void ARQInit(void) { + + if (TRUE == __ARQ_init_flag) { + return; + } + + OSRegisterVersion(__ARQVersion); + __ARQRequestQueueHi = __ARQRequestQueueLo = NULL; + __ARQChunkSize = ARQ_CHUNK_SIZE_DEFAULT; + ARRegisterDMACallback(&__ARQInterruptServiceRoutine); + __ARQRequestPendingHi = NULL; + __ARQRequestPendingLo = NULL; + __ARQCallbackHi = NULL; + __ARQCallbackLo = NULL; + __ARQ_init_flag = TRUE; +} + +void ARQPostRequest(ARQRequest* request, u32 owner, u32 type, u32 priority, u32 source, u32 dest, + u32 length, ARQCallback callback) { + + BOOL enabled; + + request->next = NULL; + request->owner = owner; + request->type = type; + request->source = source; + request->dest = dest; + request->length = length; + + if (callback) { + request->callback = callback; + } else { + request->callback = (ARQCallback)&__ARQCallbackHack; + } + + enabled = OSDisableInterrupts(); + + switch (priority) { + case ARQ_PRIORITY_LOW: + + if (__ARQRequestQueueLo) { + __ARQRequestTailLo->next = request; + } else { + __ARQRequestQueueLo = request; + } + __ARQRequestTailLo = request; + + break; + + case ARQ_PRIORITY_HIGH: + + if (__ARQRequestQueueHi) { + __ARQRequestTailHi->next = request; + } else { + __ARQRequestQueueHi = request; + } + + __ARQRequestTailHi = request; + + break; + } + + if ((__ARQRequestPendingHi == NULL) && (__ARQRequestPendingLo == NULL)) { + __ARQPopTaskQueueHi(); + + if (__ARQRequestPendingHi == NULL) { + __ARQServiceQueueLo(); + } + } + + OSRestoreInterrupts(enabled); +} + +u32 ARQGetChunkSize(void) { return __ARQChunkSize; }