Split and link PPCArch, ar and arq

This commit is contained in:
Phillip Stephens 2023-08-08 20:09:48 -07:00
parent b8ce31b658
commit 677afd2b27
8 changed files with 1281 additions and 41 deletions

View File

@ -37,5 +37,6 @@
],
"C/C++ Include Guard.Auto Update Path Blocklist": [
"include/zlib"
]
],
"search.useIgnoreFiles": false
}

View File

@ -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

View File

@ -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

View File

@ -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

84
include/asm_types.h Normal file
View File

@ -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

565
src/Dolphin/PPCArch.c Normal file
View File

@ -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

385
src/Dolphin/ar/ar.c Normal file
View File

@ -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;
}

171
src/Dolphin/ar/arq.c Normal file
View File

@ -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; }