mirror of
https://github.com/ACreTeam/ac-decomp
synced 2026-05-23 06:34:18 -04:00
merge cuyler's PR
This commit is contained in:
@@ -197,6 +197,7 @@ ELF2REL = f"{PYTHON} {PPCDIS}/elf2rel.py"
|
||||
SLICES = f"{PYTHON} {PPCDIS}/slices.py"
|
||||
PROGRESS = f"{PYTHON} {PPCDIS}/progress.py"
|
||||
SYMBOLS = f"{PYTHON} {PPCDIS}/symbols.py"
|
||||
FORCEFILESGEN = f"{PYTHON} {PPCDIS}/forcefilesgen.py"
|
||||
|
||||
# Codewarrior
|
||||
TOOLS = "tools"
|
||||
@@ -258,6 +259,7 @@ REL_RELOCS = f"{BUILDDIR}/rel_relocs.pickle"
|
||||
|
||||
# Linker
|
||||
DOL_LCF_TEMPLATE = f"{CONFIG}/dol.lcf"
|
||||
DOL_LCF_TEMP = f"{BUILDDIR}/dol_temp.lcf"
|
||||
DOL_LCF = f"{BUILDDIR}/dol.lcf"
|
||||
REL_LCF = f"{CONFIG}/rel.lcf"
|
||||
|
||||
@@ -291,7 +293,7 @@ CPPFLAGS = ' '.join([
|
||||
f"-I {BUILD_INCDIR}"
|
||||
])
|
||||
|
||||
DOL_SDATA2_SIZE = 4
|
||||
DOL_SDATA2_SIZE = 8
|
||||
REL_SDATA2_SIZE = 0
|
||||
|
||||
CFLAGS = [
|
||||
@@ -305,7 +307,7 @@ CPLFLAGS =[
|
||||
]
|
||||
BASE_DOL_CFLAGS = CFLAGS + [
|
||||
"-inline all",
|
||||
"-sdata 4",
|
||||
"-sdata 8",
|
||||
f"-sdata2 {DOL_SDATA2_SIZE}"
|
||||
]
|
||||
BASE_REL_CFLAGS = CFLAGS + [
|
||||
@@ -325,10 +327,15 @@ LOCAL_CFLAGS = [
|
||||
f"-i {BUILD_INCDIR}"
|
||||
]
|
||||
|
||||
PREPROCESSOR_CFLAGS = [
|
||||
"-E",
|
||||
"-P"
|
||||
]
|
||||
|
||||
SDK_CFLAG = [
|
||||
"-O4,p",
|
||||
"-inline all",
|
||||
"-sdata 4",
|
||||
"-sdata 8",
|
||||
f"-sdata2 {DOL_SDATA2_SIZE}"
|
||||
]
|
||||
ALIGN16_CFLAG = [
|
||||
@@ -339,7 +346,7 @@ JSYSTEM_BASE = [
|
||||
"-inline on",
|
||||
"-fp fmadd",
|
||||
"-fp_contract on",
|
||||
"-pool off",
|
||||
#"-pool off", # this is wrong
|
||||
"-Cpp_exceptions off",
|
||||
"-RTTI on",
|
||||
"-char signed",
|
||||
@@ -356,6 +363,7 @@ DOL_CPPFLAGS = ' '.join(CPLFLAGS + BASE_DOL_CFLAGS + LOCAL_CFLAGS)
|
||||
REL_CFLAGS = ' '.join(BASE_REL_CFLAGS + LOCAL_CFLAGS)
|
||||
EXTERNAL_DOL_CFLAGS = ' '.join(BASE_DOL_CFLAGS)
|
||||
EXTERNAL_REL_CFLAGS = ' '.join(BASE_REL_CFLAGS)
|
||||
PREPROCESS_CFLAGS = ' '.join(PREPROCESSOR_CFLAGS)
|
||||
|
||||
LDFLAGS = ' '.join([
|
||||
"-maxerrors 1",
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
trim_ctors: true
|
||||
@@ -35,6 +35,12 @@ SECTIONS
|
||||
FORCEACTIVE {
|
||||
PPCDIS_FORCEACTIVE
|
||||
}
|
||||
|
||||
FORCEFILES
|
||||
{
|
||||
PPCDIS_FORCEFILES
|
||||
}
|
||||
|
||||
__dummy_str = 0;
|
||||
__dummy_float = 0;
|
||||
__dummy_double = 0;
|
||||
|
||||
@@ -20,4 +20,5 @@ section_defs:
|
||||
- name: .sdata2
|
||||
bss:
|
||||
- name: .bss
|
||||
balign: 4
|
||||
- name: .sbss
|
||||
+145
-95
@@ -1,95 +1,145 @@
|
||||
#dolphin/os/__start.c:
|
||||
# .init: [0x80003100, 0x80003354]
|
||||
#dolphin/os/__ppc_eabi_init.cpp:
|
||||
# .init: [0x80003354, 0x800033a8]
|
||||
# .text: [0x8007FDFC, 0x8007fe90]
|
||||
runtime/__mem.c:
|
||||
.init: [0x800033a8, 0x800034e0]
|
||||
TRK/mem_TRK.c:
|
||||
.init: [0x800034e0, 0x80003534]
|
||||
asm/__exception.s:
|
||||
.init: [0x80003534, 0x80005468]
|
||||
jaudio_NES/dummyprobe.c:
|
||||
.text: [0x800083f8, 0x80008400]
|
||||
#jaudio_NES/verysimple.c:
|
||||
# .text: [0x80008400, 0x80008480]
|
||||
# .sdata: [0x80217b80, 0x80217b88]
|
||||
libforest/ReconfigBATs.c:
|
||||
.text: [0x8005adac, 0x8005aed4]
|
||||
#libu64/debug.c: //not match
|
||||
# .text: [0x8005aed4, 0x8005af30]
|
||||
# .data: [0x800dc7c8, 0x800dc7f0]
|
||||
#libu64/gfxprint.c: specify ranges later
|
||||
libc64/aprintf.c:
|
||||
.text: [0x8005cbdc, 0x8005cc14]
|
||||
#libc64/math64.c: //not match
|
||||
# .text: [0x8005cc14, 0x8005cccc]
|
||||
# .sdata2: [0x80219118, 0x80219130]
|
||||
libc64/qrand.c:
|
||||
.text: [0x8005cccc, 0x8005cd64]
|
||||
.sdata: [0x80217de8, 0x80217df0]
|
||||
.sbss: [0x80218640, 0x80218648]
|
||||
.sdata2: [0x80219130, 0x80219138]
|
||||
#libc64/sprintf.c:
|
||||
# .text: [0x8005ce18, 0x8005cf08]
|
||||
#libc64/malloc.c:
|
||||
# .text: [0x8005cf08, 0x8005d01c]
|
||||
# .bss: [0x80206F30, 0x80206F60]
|
||||
#libultra/ultra.c: won't link
|
||||
# .text: [0x8005d01c, 0x8005d15c]
|
||||
# .bss: [0x80206f60, 0x80206fa0]
|
||||
#libultra/gu/scale.c:
|
||||
# .text: [0x8005e7d4, 0x8005e860]
|
||||
# .sdata2: [0x80219208, 0x80219210]
|
||||
#libultra/gu/translate.c:
|
||||
# .text: [0x8005e8ac, 0x8005e918]
|
||||
libultra/gu/sins.c:
|
||||
.text: [0x8005e860, 0x8005e8ac]
|
||||
.data: [0x800dd360, 0x800ddb60]
|
||||
#libultra/xldtob.c:
|
||||
# .text: [0x8005e918, 0x8005f2a0]
|
||||
# .rodata: [0x800ab110, 0x800ab158]
|
||||
# .sdata: [0x80217df8, 0x80217e08]
|
||||
# .sdata2: [0x80219210, 0x80219230]
|
||||
#libultra/xlitob.c:
|
||||
# .text: [0x8005f2a0, 0x8005f4cc]
|
||||
# .data: [0x800ddb60, 0x800ddb88]
|
||||
#libultra/xprintf.c:
|
||||
# .text: [0x8005f4cc, 0x8005ff74]
|
||||
# .rodata: [0x800ab158, 0x800ab170]
|
||||
# .data: [0x800ddb88, 0x800ddd20]
|
||||
# .sdata: [0x80217e08, 0x80217e10]
|
||||
# .sdata2: [0x80219230, 0x80219238]
|
||||
JSystem/JKernel/JKRHeap.cpp:
|
||||
.text: [0x80063748, 0x80064028]
|
||||
.data: [0x800ddf20, 0x800ddf98]
|
||||
.sdata: [0x80217e58, 0x80217e80]
|
||||
.sbss: [0x802186d8, 0x80218700]
|
||||
JSystem/JKernel/JKRDisposer.cpp:
|
||||
.text: [0x80065aa0, 0x80065b8c]
|
||||
.data: [0x800de3a8, 0x800de3c0]
|
||||
.sdata: [0x80217ec0, 0x80217ec8]
|
||||
dolphin/BASE/ppcarch.c:
|
||||
.text: [0x8007867c, 0x80078718]
|
||||
dolphin/os/OSArena.c:
|
||||
.text: [0x8007988c, 0x800798ac]
|
||||
.sdata: [0x80218178, 0x80218180]
|
||||
.sbss: [0x802188f8, 0x80218900]
|
||||
#dolphin/os/OSCache.c:
|
||||
# .text: [0x80079b40, 0x8007a01c]
|
||||
# .data: [0x800dfa00, 0x800dfc30]
|
||||
#dolphin/os/OSDisableInterrupts.c:
|
||||
# .text: [0x8007ac24, 0x8007ac38]
|
||||
dolphin/os/OSEnableInterrupts.c:
|
||||
.text: [0x8007ac38, 0x8007ac4c]
|
||||
dolphin/os/OSRestoreInterrupts.c:
|
||||
.text: [0x8007ac4c, 0x8007ac70]
|
||||
MSL_C/rand.c:
|
||||
.text: [0x8009f46c, 0x8009f494]
|
||||
.sdata: [0x80218260, 0x80218268]
|
||||
dolphin/odenotstub/odenotstub.c:
|
||||
.text: [0x800a9770, 0x800a9780]
|
||||
dolphin/amcstubs/AmcExi2Stubs.c:
|
||||
.text: [0x800a8cc0, 0x800a8cf0]
|
||||
dolphin/gx/GXStubs.c:
|
||||
.text: [0x800998d4, 0x800998d8]
|
||||
#dolphin/os/__start.c:
|
||||
# .init: [0x80003100, 0x80003354]
|
||||
dolphin/__ppc_eabi_init.cpp:
|
||||
.init: [0x80003354, 0x800033a8]
|
||||
.text: [0x8007fdfc, 0x8007fe90]
|
||||
runtime/__mem.c:
|
||||
.init: [0x800033a8, 0x800034e0]
|
||||
TRK/mem_TRK.c:
|
||||
.init: [0x800034e0, 0x80003534]
|
||||
asm/__exception.s:
|
||||
.init: [0x80003534, 0x80005468]
|
||||
jaudio_NES/dummyprobe.c:
|
||||
.text: [0x800083f8, 0x80008400]
|
||||
#jaudio_NES/verysimple.c:
|
||||
# .text: [0x80008400, 0x80008480]
|
||||
# .sdata: [0x80217b80, 0x80217b88]
|
||||
libforest/ReconfigBATs.c:
|
||||
.text: [0x8005adac, 0x8005aed4]
|
||||
#libu64/debug.c: //not match
|
||||
# .text: [0x8005aed4, 0x8005af30]
|
||||
# .data: [0x800dc7c8, 0x800dc7f0]
|
||||
#libu64/gfxprint.c: specify ranges later
|
||||
libc64/aprintf.c:
|
||||
.text: [0x8005cbdc, 0x8005cc14]
|
||||
#libc64/math64.c: //not match
|
||||
# .text: [0x8005cc14, 0x8005cccc]
|
||||
# .sdata2: [0x80219118, 0x80219130]
|
||||
libc64/qrand.c:
|
||||
.text: [0x8005cccc, 0x8005cd64]
|
||||
.sdata: [0x80217de8, 0x80217df0]
|
||||
.sbss: [0x80218640, 0x80218648]
|
||||
.sdata2: [0x80219130, 0x80219138]
|
||||
#libc64/sprintf.c:
|
||||
# .text: [0x8005ce18, 0x8005cf08]
|
||||
#libc64/malloc.c:
|
||||
# .text: [0x8005cf08, 0x8005d01c]
|
||||
# .bss: [0x80206F30, 0x80206F60]
|
||||
#libultra/ultra.c: won't link
|
||||
# .text: [0x8005d01c, 0x8005d15c]
|
||||
# .bss: [0x80206f60, 0x80206fa0]
|
||||
#libultra/gu/scale.c:
|
||||
# .text: [0x8005e7d4, 0x8005e860]
|
||||
# .sdata2: [0x80219208, 0x80219210]
|
||||
#libultra/gu/translate.c:
|
||||
# .text: [0x8005e8ac, 0x8005e918]
|
||||
libultra/gu/sins.c:
|
||||
.text: [0x8005e860, 0x8005e8ac]
|
||||
.data: [0x800dd360, 0x800ddb60]
|
||||
#libultra/xldtob.c:
|
||||
# .text: [0x8005e918, 0x8005f2a0]
|
||||
# .rodata: [0x800ab110, 0x800ab158]
|
||||
# .sdata: [0x80217df8, 0x80217e08]
|
||||
# .sdata2: [0x80219210, 0x80219230]
|
||||
#libultra/xlitob.c:
|
||||
# .text: [0x8005f2a0, 0x8005f4cc]
|
||||
# .data: [0x800ddb60, 0x800ddb88]
|
||||
#libultra/xprintf.c:
|
||||
# .text: [0x8005f4cc, 0x8005ff74]
|
||||
# .rodata: [0x800ab158, 0x800ab170]
|
||||
# .data: [0x800ddb88, 0x800ddd20]
|
||||
# .sdata: [0x80217e08, 0x80217e10]
|
||||
# .sdata2: [0x80219230, 0x80219238]
|
||||
JSystem/JKernel/JKRHeap.cpp:
|
||||
.text: [0x80063748, 0x80064028]
|
||||
.data: [0x800ddf20, 0x800ddf98]
|
||||
.sdata: [0x80217e58, 0x80217e80]
|
||||
.sbss: [0x802186d8, 0x80218700]
|
||||
JSystem/JKernel/JKRDisposer.cpp:
|
||||
.text: [0x80065aa0, 0x80065b8c]
|
||||
.data: [0x800de3a8, 0x800de3c0]
|
||||
.sdata: [0x80217ec0, 0x80217ec8]
|
||||
#JSystem/JKernel/JKRThread.cpp: # JKRThread linkage disabled until we can resolve the order of RTTI strings in .data
|
||||
# .text: [0x80065b8c, 0x80065ef0]
|
||||
# .ctors: [0x800a978c, 0x800a9790]
|
||||
# .data: [0x800de3c0, 0x800de3f8]
|
||||
# .bss: [0x80207008, 0x80207020]
|
||||
# .sdata: [0x80217ec8, 0x80217ed8]
|
||||
JSystem/JKernel/JKRThread2.cpp: # This exists to fix ordering. It is a hack. AC was likely compiled with CW GC 1.3.
|
||||
.text: [0x80065ef0, 0x80065ef8]
|
||||
JSystem/JKernel/JKRAramHeap.cpp:
|
||||
.text: [0x80066e84, 0x80067258]
|
||||
.ctors: [0x800a9794, 0x800a9798]
|
||||
.data: [0x800de4c0, 0x800de4f0]
|
||||
.bss: [0x80207038, 0x80207050]
|
||||
.sdata: [0x80217ef8, 0x80217f08]
|
||||
JSystem/JKernel/JKRAramBlock.cpp:
|
||||
.text: [0x80067258, 0x800674c8]
|
||||
.data: [0x800de4f0, 0x800de510]
|
||||
.sdata: [0x80217f08, 0x80217f10]
|
||||
JSystem/JKernel/JKRAramPiece.cpp:
|
||||
.text: [0x800674c8, 0x80067a88]
|
||||
.ctors: [0x800a9798, 0x800a979c]
|
||||
.data: [0x800de510, 0x800de568]
|
||||
.bss: [0x80207050, 0x80207080]
|
||||
.sdata: [0x80217f10, 0x80217f18]
|
||||
JSystem/JKernel/JKRDvdFile.cpp:
|
||||
.text: [0x8006b8a4, 0x8006be0c]
|
||||
.ctors: [0x800a97a0, 0x800a97a4]
|
||||
.data: [0x800deba8, 0x800dec30]
|
||||
.bss: [0x80207098, 0x802070b0]
|
||||
.sdata: [0x80218008, 0x80218028]
|
||||
JSystem/JKernel/JKRDvdRipper.cpp:
|
||||
.text: [0x8006be0c, 0x8006c8fc]
|
||||
.ctors: [0x800a97a4, 0x800a97a8]
|
||||
.data: [0x800dec30, 0x800dec90]
|
||||
.bss: [0x802070b0, 0x802070c8]
|
||||
.sdata: [0x80218028, 0x80218030]
|
||||
.sbss: [0x80218778, 0x802187a8]
|
||||
JSystem/JKernel/JKRDecomp.cpp:
|
||||
.text: [0x8006d608, 0x8006dd58]
|
||||
.data: [0x800dec90, 0x800ded18]
|
||||
.sdata: [0x80218038, 0x80218050]
|
||||
.sbss: [0x802187e8, 0x802187f0]
|
||||
JSystem/JSupport/JSUInputStream.cpp:
|
||||
.text: [0x8006e168, 0x8006e3e4]
|
||||
.data: [0x800ded18, 0x800dedb8]
|
||||
.sdata: [0x80218050, 0x80218068]
|
||||
#JSystem/JSupport/JSUFileStream.cpp: # JSUFileStream linkage disabled until we can resolve order of RTTI strings in .data
|
||||
# .text: [0x8006e3e4, 0x8006e604]
|
||||
# .data: [0x800dedb8, 0x800dee60]
|
||||
# .sdata: [0x80218068, 0x80218088]
|
||||
dolphin/BASE/ppcarch.c:
|
||||
.text: [0x8007867c, 0x80078718]
|
||||
dolphin/os/OSArena.c:
|
||||
.text: [0x8007988c, 0x800798ac]
|
||||
.sdata: [0x80218178, 0x80218180]
|
||||
.sbss: [0x802188f8, 0x80218900]
|
||||
#dolphin/os/OSCache.c:
|
||||
# .text: [0x80079b40, 0x8007a01c]
|
||||
# .data: [0x800dfa00, 0x800dfc30]
|
||||
#dolphin/os/OSDisableInterrupts.c:
|
||||
# .text: [0x8007ac24, 0x8007ac38]
|
||||
dolphin/os/OSEnableInterrupts.c:
|
||||
.text: [0x8007ac38, 0x8007ac4c]
|
||||
dolphin/os/OSRestoreInterrupts.c:
|
||||
.text: [0x8007ac4c, 0x8007ac70]
|
||||
MSL_C/rand.c:
|
||||
.text: [0x8009f46c, 0x8009f494]
|
||||
.sdata: [0x80218260, 0x80218268]
|
||||
dolphin/odenotstub/odenotstub.c:
|
||||
.text: [0x800a9770, 0x800a9780]
|
||||
dolphin/amcstubs/AmcExi2Stubs.c:
|
||||
.text: [0x800a8cc0, 0x800a8cf0]
|
||||
dolphin/gx/GXStubs.c:
|
||||
.text: [0x800998d4, 0x800998d8]
|
||||
|
||||
+15
-1
@@ -11,6 +11,7 @@ global:
|
||||
0x800034e0: TRK_memset
|
||||
0x80003510: TRK_memcpy
|
||||
0x80003534: gTRKInterruptVectorTable
|
||||
0x80003534: gTRKInterruptVectorTable
|
||||
0x80005468: __TRK_reset
|
||||
0x800056c0: soundArenaAlloc
|
||||
0x800056c8: search_partial_address
|
||||
@@ -29,6 +30,7 @@ global:
|
||||
0x80005dc0: fault_callback_scroll
|
||||
0x80006004: adjustOSArena
|
||||
0x800060f8: main
|
||||
0x800060f8: main
|
||||
0x8000663c: ReportDiskID__Fv
|
||||
0x8000665c: JW_UpdateVideoMode
|
||||
0x800067b4: JW_SetProgressiveMode
|
||||
@@ -2626,6 +2628,12 @@ global:
|
||||
0x8009ae00: __save_fpr
|
||||
0x8009ae4c: __restore_fpr
|
||||
0x8009ae98: __save_gpr
|
||||
0x8009ae9c: _savegpr_15
|
||||
0x8009aea0: _savegpr_16
|
||||
0x8009aea4: _savegpr_17
|
||||
0x8009aea8: _savegpr_18
|
||||
0x8009aeac: _savegpr_19
|
||||
0x8009aeb0: _savegpr_20
|
||||
0x8009aeb4: _savegpr_21
|
||||
0x8009aeb8: _savegpr_22
|
||||
0x8009aebc: _savegpr_23
|
||||
@@ -2636,7 +2644,13 @@ global:
|
||||
0x8009aed0: _savegpr_28
|
||||
0x8009aed4: _savegpr_29
|
||||
0x8009aee4: __restore_gpr
|
||||
0x8009af00: _restgpr_21
|
||||
0x8009aee8: _restgpr_15
|
||||
0x8009aeec: _restgpr_16
|
||||
0x8009aef0: _restgpr_17
|
||||
0x8009aef4: _restgpr_18
|
||||
0x8009aef8: _restgpr_19
|
||||
0x8009aefc: _restgpr_20
|
||||
0x8009af00: _restgpr_21
|
||||
0x8009af04: _restgpr_22
|
||||
0x8009af08: _restgpr_23
|
||||
0x8009af0c: _restgpr_24
|
||||
|
||||
+37
-2
@@ -88,6 +88,7 @@ n.variable("devkitppc", c.DEVKITPPC)
|
||||
n.variable("as", c.AS)
|
||||
n.variable("cpp", c.CPP)
|
||||
n.variable("iconv", c.ICONV)
|
||||
n.variable("forcefilesgen", c.FORCEFILESGEN)
|
||||
n.newline()
|
||||
|
||||
##############
|
||||
@@ -227,6 +228,12 @@ n.rule(
|
||||
description = "iconv $in",
|
||||
)
|
||||
|
||||
n.rule(
|
||||
"forcefiles",
|
||||
command = "$forcefilesgen $in $out $forcefiles",
|
||||
description = "LCF FORCEFILES generation $in"
|
||||
)
|
||||
|
||||
##########
|
||||
# Assets #
|
||||
##########
|
||||
@@ -484,6 +491,7 @@ class Source(ABC):
|
||||
self.src_path = src_path
|
||||
self.o_path = o_path
|
||||
self.o_stem = o_path[:-2]
|
||||
self.i_path = o_path[:-2] + ".i"
|
||||
self.gen_includes = gen_includes
|
||||
|
||||
def build(self):
|
||||
@@ -510,6 +518,10 @@ class GenAsmSource(Source):
|
||||
name = f"{section}_{start:x}_{end:x}.s"
|
||||
src_path = f"$builddir/asm/{name}"
|
||||
super().__init__(False, src_path, src_path + ".o")
|
||||
|
||||
# Add ctors to forcefiles
|
||||
if section == ".ctors":
|
||||
forcefiles.append(name + ".o")
|
||||
|
||||
|
||||
def build(self):
|
||||
@@ -577,7 +589,7 @@ class CSource(Source):
|
||||
if path.startswith("src/dolphin/"):
|
||||
self.cflags = c.SDK_FLAGS
|
||||
self.cc = c.OCC
|
||||
elif path.startswith("src/JSystem/JKernel/"):
|
||||
elif path.startswith("src/JSystem/"):
|
||||
self.cflags = c.JSYSTEM_CFLAGS
|
||||
self.cc = c.CC
|
||||
elif path.startswith("src/jaudio_NES"):
|
||||
@@ -601,6 +613,18 @@ class CSource(Source):
|
||||
rule="iconv",
|
||||
inputs=self.src_path
|
||||
)
|
||||
#n.build(
|
||||
# self.o_path,
|
||||
# rule = "cc",
|
||||
# inputs = self.iconv_path,
|
||||
# implicit = [inc.path for inc in self.gen_includes],
|
||||
# variables = {
|
||||
# "cc" : self.cc,
|
||||
# "cflags" : self.cflags + ' ' + c.PREPROCESS_CFLAGS
|
||||
# }
|
||||
#)
|
||||
#print(self.i_path)
|
||||
|
||||
n.build(
|
||||
self.o_path,
|
||||
rule = "cc",
|
||||
@@ -649,6 +673,8 @@ def make_asm_list(path: str, asm_includes: List[AsmInclude]):
|
||||
f
|
||||
)
|
||||
|
||||
forcefiles = []
|
||||
|
||||
dol_sources = load_sources(c.DOL_CTX)
|
||||
dol_gen_includes = find_gen_includes(dol_sources)
|
||||
make_asm_list(c.DOL_ASM_LIST, dol_gen_includes[AsmInclude])
|
||||
@@ -710,11 +736,20 @@ for source in rel_sources:
|
||||
GenAsmSource.batch_build(rel_gen_asm)
|
||||
|
||||
n.build(
|
||||
c.DOL_LCF,
|
||||
c.DOL_LCF_TEMP,
|
||||
rule="forceactivegen",
|
||||
inputs=[c.DOL_LCF_TEMPLATE, c.DOL_YML, c.DOL_LABELS, c.GAME_SYMBOLS, c.EXTERNS]
|
||||
)
|
||||
|
||||
n.build(
|
||||
c.DOL_LCF,
|
||||
rule="forcefiles",
|
||||
inputs=c.DOL_LCF_TEMP,
|
||||
variables={
|
||||
"forcefiles" : ' '.join(forcefiles)
|
||||
}
|
||||
)
|
||||
|
||||
n.build(
|
||||
c.DOL_ELF,
|
||||
rule="ld",
|
||||
|
||||
@@ -0,0 +1,177 @@
|
||||
#ifndef JKRARAM_H
|
||||
#define JKRARAM_H
|
||||
|
||||
#include "types.h"
|
||||
#include "dolphin/ar.h"
|
||||
#include "dolphin/os/OSMessage.h"
|
||||
#include "JSystem/JKernel/JKRDisposer.h"
|
||||
#include "JSystem/JKernel/JKRHeap.h"
|
||||
#include "JSystem/JKernel/JKRThread.h"
|
||||
#include "JSystem/JSupport/JSUList.h"
|
||||
|
||||
#define ALIGN_PREV(u, align) (u & (~(align-1)))
|
||||
#define ALIGN_NEXT(u, align) ((u + (align-1)) & (~(align-1)))
|
||||
|
||||
#define ARAM_GROUP_ID_ALL 0
|
||||
#define ARAM_GROUP_ID_DEFAULT 0xFF
|
||||
|
||||
#define ARAM_MESGBUF_COUNT 4
|
||||
|
||||
#define ARAMPIECE_DONE_CALLBACK 0
|
||||
#define ARAMPIECE_DONE_NONE 1
|
||||
#define ARAMPIECE_DONE_DECOMPRESS 2
|
||||
|
||||
class JKRAramHeap;
|
||||
class JKRDecompCommand;
|
||||
class JKRAMCommand;
|
||||
|
||||
class JKRAramBlock {
|
||||
JKRAramBlock(u32 address, u32 size, u32 freeSize, u8 groupID, bool tempMemory);
|
||||
|
||||
virtual ~JKRAramBlock();
|
||||
|
||||
JKRAramBlock* allocHead(u32 size, u8 groupID, JKRAramHeap* heap);
|
||||
JKRAramBlock* allocTail(u32 size, u8 groupID, JKRAramHeap* heap);
|
||||
|
||||
u32 getAddress() const { return this->mAddress; }
|
||||
u32 getSize() const { return this->mSize; }
|
||||
u32 getFreeSize() const { return this->mFreeSize; }
|
||||
bool isTempMemory() const { return this->mIsTempMemory; }
|
||||
void newGroupID(u8 groupID) { this->mGroupID = groupID; }
|
||||
|
||||
JSULink<JKRAramBlock> mLink;
|
||||
u32 mAddress;
|
||||
u32 mSize;
|
||||
u32 mFreeSize;
|
||||
u8 mGroupID;
|
||||
bool mIsTempMemory;
|
||||
|
||||
friend class JKRAramHeap;
|
||||
};
|
||||
|
||||
class JKRAram : public JKRThread {
|
||||
public:
|
||||
JKRAram(u32, u32, s32);
|
||||
|
||||
virtual ~JKRAram();
|
||||
virtual void* run();
|
||||
|
||||
static JKRAram* sAramObject;
|
||||
static const OSMessageQueue sMessageQueue;
|
||||
static JSUList<JKRAMCommand> sAramCommandList;
|
||||
static u32 sSZSBufferSize;
|
||||
static OSMessage sMessageBuffer[ARAM_MESGBUF_COUNT];
|
||||
|
||||
private:
|
||||
u32 mAudioMemoryPtr;
|
||||
u32 mAudioMemorySize;
|
||||
u32 mGraphMemoryPtr;
|
||||
u32 mGraphMemorySize;
|
||||
u32 mAramMemoryPtr;
|
||||
u32 mAramMemorySize;
|
||||
JKRAramHeap* mAramHeap;
|
||||
u32 mBlockLength;
|
||||
u8 _9C[4];
|
||||
};
|
||||
|
||||
class JKRAramHeap : public JKRDisposer {
|
||||
enum EAllocMode {
|
||||
Head = 0,
|
||||
Tail = 1
|
||||
};
|
||||
|
||||
JKRAramHeap(u32 baseAddress, u32 size);
|
||||
|
||||
virtual ~JKRAramHeap();
|
||||
|
||||
JKRAramBlock* alloc(u32 size, EAllocMode mode);
|
||||
void free(JKRAramBlock* block);
|
||||
JKRAramBlock* allocFromHead(u32 size);
|
||||
JKRAramBlock* allocFromTail(u32 size);
|
||||
u32 getFreeSize();
|
||||
u32 getTotalFreeSize();
|
||||
u32 getUsedSize(u8 groupID);
|
||||
void dump();
|
||||
|
||||
u8 getCurrentGroupID() const { return this->mGroupID; }
|
||||
JKRHeap* getMgrHeap() const { return this->mHeap; }
|
||||
|
||||
void lock() { OSLockMutex(&this->mMutex); }
|
||||
void unlock() { OSUnlockMutex(&this->mMutex); }
|
||||
|
||||
static JSUList<JKRAramBlock> sAramList;
|
||||
|
||||
OSMutex mMutex;
|
||||
JKRHeap* mHeap;
|
||||
u32 mHeadAddress;
|
||||
u32 mTailAddress;
|
||||
u32 mSize;
|
||||
u8 mGroupID;
|
||||
|
||||
friend class JKRAramBlock;
|
||||
};
|
||||
|
||||
class JKRAMCommand : public ARQRequest {
|
||||
public:
|
||||
typedef void (*AMCommandCallback)(u32);
|
||||
|
||||
JKRAMCommand();
|
||||
~JKRAMCommand();
|
||||
|
||||
JSULink<JKRAMCommand> mAramPieceCommandLink;
|
||||
JSULink<JKRAMCommand> mLink30;
|
||||
s32 mDirection;
|
||||
u32 mLength;
|
||||
u32 mSource;
|
||||
u32 mDestination;
|
||||
JKRAramBlock* mAramBlock;
|
||||
u8 _54[4];
|
||||
AMCommandCallback mCallback;
|
||||
OSMessageQueue* mCompletedMesgQueue;
|
||||
s32 mCallbackType;
|
||||
JKRDecompCommand* mDecompCommand;
|
||||
OSMessageQueue mMesgQueue;
|
||||
OSMessage mMesgBuffer[1];
|
||||
void* _8C;
|
||||
void* _90;
|
||||
void* _94;
|
||||
};
|
||||
|
||||
class JKRAramCommand {
|
||||
public:
|
||||
inline void setting(BOOL active, void* arg) {
|
||||
this->mActive = active;
|
||||
this->mArg = arg;
|
||||
}
|
||||
|
||||
BOOL mActive;
|
||||
void* mArg;
|
||||
};
|
||||
|
||||
class JKRAramPiece {
|
||||
public:
|
||||
static JKRAMCommand* prepareCommand(int direction, u32 source, u32 destination, u32 length, JKRAramBlock* aramBlock, JKRAMCommand::AMCommandCallback callback);
|
||||
static void sendCommand(JKRAMCommand* cmd);
|
||||
static JKRAMCommand* orderAsync(int direction, u32 source, u32 destination, u32 length, JKRAramBlock* aramBlock, JKRAMCommand::AMCommandCallback callback);
|
||||
static bool sync(JKRAMCommand* cmd, BOOL noBlock);
|
||||
static bool orderSync(int direction, u32 source, u32 destination, u32 length, JKRAramBlock* aramBlock);
|
||||
static void startDMA(JKRAMCommand* cmd);
|
||||
static void doneDMA(u32 arg);
|
||||
|
||||
static OSMutex mMutex;
|
||||
static JSUList<JKRAMCommand> sAramPieceCommandList;
|
||||
|
||||
private:
|
||||
static void lock() { OSLockMutex(&mMutex); }
|
||||
static void unlock() { OSUnlockMutex(&mMutex); }
|
||||
};
|
||||
|
||||
inline bool JKRAramPcs(int direction, u32 source, u32 destination, u32 length, JKRAramBlock* block) {
|
||||
return JKRAramPiece::orderSync(direction, source, destination, length, block);
|
||||
}
|
||||
|
||||
inline void JKRAramPcs_SendCommand(JKRAMCommand* cmd) {
|
||||
JKRAramPiece::sendCommand(cmd);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,93 @@
|
||||
#ifndef JKRDECOMP_H
|
||||
#define JKRDECOMP_H
|
||||
|
||||
#include "types.h"
|
||||
#include "dolphin/os/OSMessage.h"
|
||||
#include "JSystem/JKernel/JKRThread.h"
|
||||
#include "JSystem/JKernel/JKRAram.h"
|
||||
|
||||
#define JKRDECOMP_MSG_BUF_COUNT 4
|
||||
#define JKRDECOMP_STACK_SIZE 0x4000
|
||||
#define JKRDECOMP_THREAD_MSG_BUF_COUNT 16
|
||||
|
||||
#define JKRDECOMP_READU32BE(ptr, offset) (((u32)ptr[offset] << 24) | ((u32)ptr[offset + 1] << 16) | ((u32)ptr[offset + 2] << 8) | (u32)ptr[offset + 3])
|
||||
|
||||
#define SZ_MIN_BACKSIZE 3
|
||||
#define SZ_DEFAULT_BACKSIZE 15 + SZ_MIN_BACKSIZE
|
||||
|
||||
#define SZP_GETBACKOFS(buf) (((*((u8*)buf) & 0xF) << 8) | (*(((u8*)buf)+1)))
|
||||
#define SZP_GETCOUNT(buf) (*((u16*)buf) >> 12)
|
||||
|
||||
typedef void DecompCallback(u32);
|
||||
|
||||
class JKRDecompCommand {
|
||||
public:
|
||||
enum TransferType {
|
||||
MRAM = 0,
|
||||
ARAM = 1
|
||||
};
|
||||
|
||||
JKRDecompCommand();
|
||||
~JKRDecompCommand();
|
||||
|
||||
u8 _00[4];
|
||||
u8* mSrcBuffer;
|
||||
u8* mDstBuffer;
|
||||
u32 mSrcLength;
|
||||
u32 mSkipCount;
|
||||
DecompCallback* mCallback;
|
||||
JKRDecompCommand* mCmd;
|
||||
OSMessageQueue* pMesgQueue1C;
|
||||
TransferType transferType;
|
||||
JKRAMCommand* mAMCommand;
|
||||
OSMessageQueue mMesgQueue;
|
||||
OSMessage mMesgBuffer[1];
|
||||
};
|
||||
|
||||
class JKRDecomp : public JKRThread {
|
||||
public:
|
||||
enum CompressionMode {
|
||||
NONE = 0,
|
||||
SZP = 1,
|
||||
SZS = 2
|
||||
};
|
||||
|
||||
JKRDecomp(s32 decompPriority);
|
||||
|
||||
virtual ~JKRDecomp();
|
||||
|
||||
virtual void* run();
|
||||
|
||||
static JKRDecompCommand* prepareCommand(u8* srcBuffer, u8* dstBuffer, u32 srcLength, u32 skipCount, DecompCallback* callback);
|
||||
static CompressionMode checkCompressed(u8* buf);
|
||||
static JKRDecomp* create(s32 decompPriority);
|
||||
static void decode(u8* srcBuffer, u8* dstBuffer, u32 srcLength, u32 skipCount);
|
||||
static void decodeSZP(u8* srcBuffer, u8* dstBuffer, u32 srcLength, u32 skipCount);
|
||||
static void decodeSZS(u8* srcBuffer, u8* dstBuffer, u32 srcLength, u32 skipCount);
|
||||
static bool orderSync(u8* srcBuffer, u8* dstBuffer, u32 srcLength, u32 skipCount);
|
||||
static JKRDecompCommand* orderAsync(u8* srcBuffer, u8* dstBuffer, u32 srcLength, u32 skipCount, DecompCallback* callback);
|
||||
static bool sync(JKRDecompCommand* cmd, BOOL noBlock);
|
||||
static BOOL sendCommand(JKRDecompCommand* cmd);
|
||||
|
||||
static OSMessageQueue sMessageQueue;
|
||||
static OSMessage sMessageBuffer[JKRDECOMP_MSG_BUF_COUNT];
|
||||
static JKRDecomp* sDecompObject;
|
||||
};
|
||||
|
||||
inline JKRDecomp* JKRCreateDecompManager(s32 priority) {
|
||||
return JKRDecomp::create(priority);
|
||||
}
|
||||
|
||||
inline JKRDecomp::CompressionMode JKRCheckCompressed(u8* buf) {
|
||||
return JKRDecomp::checkCompressed(buf);
|
||||
}
|
||||
|
||||
inline u32 JKRDecompExpandSize(u8* buf) {
|
||||
return (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
|
||||
}
|
||||
|
||||
inline void JKRDecompress(u8* src, u8* dst, u32 srcLength, u32 skipCount) {
|
||||
JKRDecomp::orderSync(src, dst, srcLength, skipCount);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,79 @@
|
||||
#ifndef JKRDVDFILE_H
|
||||
#define JKRDVDFILE_H
|
||||
|
||||
#include "JSystem/JKernel/JKRFile.h"
|
||||
#include "JSystem/JSupport/JSUStream.h"
|
||||
|
||||
class JKRDvdFile;
|
||||
|
||||
struct JKRDvdFileInfo : public DVDFileInfo {
|
||||
JKRDvdFile* mFile;
|
||||
};
|
||||
|
||||
class JKRDvdFile : public JKRFile {
|
||||
public:
|
||||
JKRDvdFile();
|
||||
JKRDvdFile(const char* filename);
|
||||
JKRDvdFile(s32 entrynum);
|
||||
|
||||
virtual ~JKRDvdFile();
|
||||
|
||||
virtual bool open(const char* filename);
|
||||
virtual bool close();
|
||||
virtual int readData(void* data, s32 length, s32 ofs);
|
||||
virtual int writeData(const void* data, s32 length, s32 ofs);
|
||||
virtual u32 getFileSize() const { return this->mDvdFileInfo.length; }
|
||||
virtual bool open(s32 entrynum);
|
||||
|
||||
inline DVDFileInfo* getFileInfo() {
|
||||
return &this->mDvdFileInfo;
|
||||
}
|
||||
|
||||
inline int readDataAsync(void* addr, s32 length, s32 offset) {
|
||||
OSLockMutex(&this->mMutex1);
|
||||
s32 retAddr;
|
||||
|
||||
if (this->mThread2 != nullptr) {
|
||||
OSUnlockMutex(&this->mMutex1);
|
||||
retAddr = -1;
|
||||
}
|
||||
else {
|
||||
this->mThread2 = OSGetCurrentThread();
|
||||
retAddr = -1;
|
||||
if (DVDReadAsync(&this->mDvdFileInfo, addr, length, offset, JKRDvdFile::doneProcess)) {
|
||||
retAddr = this->sync();
|
||||
}
|
||||
|
||||
this->mThread2 = nullptr;
|
||||
OSUnlockMutex(&this->mMutex1);
|
||||
}
|
||||
|
||||
return retAddr;
|
||||
}
|
||||
|
||||
inline int writeDataAsync(const void* data, s32 length, s32 offset) { return -1; }
|
||||
|
||||
void initiate();
|
||||
s32 sync();
|
||||
|
||||
static void doneProcess(s32 result, DVDFileInfo* info);
|
||||
|
||||
static JSUList<JKRDvdFile> sDvdList;
|
||||
|
||||
protected:
|
||||
OSMutex mMutex1;
|
||||
OSMutex mMutex2;
|
||||
JKRAramBlock* mAramBlock;
|
||||
OSThread* mThread1;
|
||||
JSUFileInputStream* mInputStream;
|
||||
u32 _58;
|
||||
JKRDvdFileInfo mDvdFileInfo;
|
||||
OSMessageQueue mMessageQueue1;
|
||||
OSMessage mMsg1;
|
||||
OSMessageQueue mMessageQueue2;
|
||||
OSMessage mMsg2;
|
||||
JSULink<JKRDvdFile> mLink;
|
||||
OSThread* mThread2;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,47 @@
|
||||
#ifndef JKRDVDRIPPER_H
|
||||
#define JKRDVDRIPPER_H
|
||||
|
||||
#include "types.h"
|
||||
#include "JSystem/JKernel/JKRDvdFile.h"
|
||||
|
||||
#define SZP_BUFFERSIZE 1024
|
||||
#define REF_BUFFERSIZE 0x1120
|
||||
|
||||
enum JKRExpandSwitch {
|
||||
EXPAND_SWITCH_DEFAULT, /* Do nothing? treated same as 2 */
|
||||
EXPAND_SWITCH_DECOMPRESS, /* Check for compression and decompress */
|
||||
EXPAND_SWITCH_NONE /* Do nothing */
|
||||
};
|
||||
|
||||
struct SZPHeader {
|
||||
u32 magic;
|
||||
u32 decompSize;
|
||||
};
|
||||
|
||||
class JKRDMCommand {
|
||||
JKRDMCommand();
|
||||
~JKRDMCommand();
|
||||
};
|
||||
|
||||
class JKRDvdRipper {
|
||||
public:
|
||||
enum EAllocDirection {
|
||||
ALLOC_DIR_DEFAULT = 0,
|
||||
ALLOC_DIR_TOP = 1,
|
||||
ALLOC_DIR_BOTTOM = 2
|
||||
};
|
||||
|
||||
static void* loadToMainRAM(const char* file, u8* buf, JKRExpandSwitch expandSwitch, u32 maxDest, JKRHeap* heap, EAllocDirection allocDir, u32 offset, int* compressMode);
|
||||
static void* loadToMainRAM(s32 entrynum, u8* buf, JKRExpandSwitch expandSwitch, u32 maxDest, JKRHeap* heap, EAllocDirection allocDir, u32 offset, int* compressMode);
|
||||
static void* loadToMainRAM(JKRDvdFile* file, u8* buf, JKRExpandSwitch expandSwitch, u32 maxDest, JKRHeap* heap, EAllocDirection allocDir, u32 offset, int* compressMode);
|
||||
|
||||
static inline bool isErrorRetry() { return JKRDvdRipper::errorRetry; }
|
||||
|
||||
static JSUList<JKRDMCommand> sDvdAsyncList;
|
||||
|
||||
static bool errorRetry;
|
||||
};
|
||||
|
||||
static int JKRDecompressFromDVD(JKRDvdFile* srcFile, void* buf, u32 size, u32 maxDest, u32 fileOffset, u32 srcOffset);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,34 @@
|
||||
#ifndef JKRFILE_H
|
||||
#define JKRFILE_H
|
||||
|
||||
#include "types.h"
|
||||
#include "dolphin/dvd.h"
|
||||
#include "dolphin/os.h"
|
||||
#include "JSystem/JSupport/JSUList.h"
|
||||
#include "JSystem/JKernel/JKRAram.h"
|
||||
#include "JSystem/JKernel/JKRDisposer.h"
|
||||
#include "JSystem/JKernel/JKRMacro.h"
|
||||
|
||||
class JKRFile : public JKRDisposer {
|
||||
public:
|
||||
inline JKRFile()
|
||||
: JKRDisposer()
|
||||
, mFileOpen(false)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~JKRFile() { }
|
||||
virtual bool open(const char* path) = 0;
|
||||
virtual bool close() = 0;
|
||||
virtual int readData(void* data, s32 length, s32 ofs) = 0;
|
||||
virtual int writeData(const void* data, s32 length, s32 ofs) = 0;
|
||||
virtual u32 getFileSize() const = 0;
|
||||
|
||||
void read(void* data, s32 length, s32 ofs);
|
||||
bool isAvailable() { return this->mFileOpen; }
|
||||
|
||||
protected:
|
||||
bool mFileOpen;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,13 @@
|
||||
#ifndef JKRMARCO_H
|
||||
#define JKRMACRO_H
|
||||
|
||||
#define JKR_ISALIGNED(addr, alignment) ((((u32)addr) & (((u32)alignment)-1)) == 0)
|
||||
#define JKR_ISALIGNED32(addr) (JKR_ISALIGNED(addr, 32))
|
||||
|
||||
#define JKR_ISNOTALIGNED(addr, alignment) ((((u32)addr) & (((u32)alignment)-1)) != 0)
|
||||
#define JKR_ISNOTALIGNED32(addr) (JKR_ISNOTALIGNED(addr, 32))
|
||||
|
||||
#define JKR_ALIGN(addr, alignment) (((u32)addr) & (~(((u32)alignment)-1)))
|
||||
#define JKR_ALIGN32(addr) (JKR_ALIGN(addr, 32))
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,58 @@
|
||||
#ifndef JKRTHREAD_H
|
||||
#define JKRTHREAD_H
|
||||
|
||||
#include "types.h"
|
||||
#include "dolphin/os/OSMessage.h"
|
||||
#include "dolphin/os/OSThread.h"
|
||||
#include "dolphin/os/OSTime.h"
|
||||
#include "JSystem/JSupport/JSUList.h"
|
||||
#include "JSystem/JKernel/JKRHeap.h"
|
||||
#include "JSystem/JKernel/JKRDisposer.h"
|
||||
|
||||
class JKRThread : public JKRDisposer {
|
||||
public:
|
||||
JKRThread(u32 stackSize, int msgCount, int threadPrio);
|
||||
JKRThread(OSThread* osThread, int msgCount);
|
||||
|
||||
virtual ~JKRThread();
|
||||
__declspec(weak) virtual void* run();
|
||||
|
||||
static void* start(void* param);
|
||||
static JSUList<JKRThread>* getList() { return &JKRThread::sThreadList; }
|
||||
|
||||
OSThread* getThreadRecord() const { return this->mThreadRecord; }
|
||||
void* getStack() const { return this->mStackMemory; }
|
||||
|
||||
void resume() { OSResumeThread(this->mThreadRecord); }
|
||||
void jamMessageBlock(OSMessage msg) { OSJamMessage(&this->mMesgQueue, msg, OS_MESSAGE_BLOCK); }
|
||||
void sendMessage(OSMessage msg) { OSSendMessage(&this->mMesgQueue, msg, OS_MESSAGE_NOBLOCK); }
|
||||
|
||||
OSMessage waitMessage(int* received) {
|
||||
OSMessage mesg;
|
||||
BOOL retrieved = OSReceiveMessage(&this->mMesgQueue, &mesg, OS_MESSAGE_NOBLOCK);
|
||||
if (received != nullptr) {
|
||||
*received = retrieved;
|
||||
}
|
||||
return mesg;
|
||||
}
|
||||
|
||||
OSMessage waitMeessageBlock() {
|
||||
OSMessage mesg;
|
||||
OSReceiveMessage(&this->mMesgQueue, &mesg, OS_MESSAGE_BLOCK);
|
||||
return mesg;
|
||||
}
|
||||
|
||||
static JSUList<JKRThread> sThreadList;
|
||||
|
||||
protected:
|
||||
JSULink<JKRThread> mLink;
|
||||
JKRHeap* mHeap;
|
||||
OSThread* mThreadRecord;
|
||||
OSMessageQueue mMesgQueue;
|
||||
OSMessage* mMesgBuffer;
|
||||
int mMesgCount;
|
||||
void* mStackMemory;
|
||||
u32 mStackSize;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,27 @@
|
||||
#ifndef JSUFILEINPUTSTREAM_H
|
||||
#define JSUFILEINPUTSTREAM_H
|
||||
|
||||
#include "types.h"
|
||||
#include "JSystem/JKernel/JKRFile.h"
|
||||
#include "JSystem/JSupport/JSURandomInputStream.h"
|
||||
|
||||
class JSUFileInputStream : public JSURandomInputStream {
|
||||
public:
|
||||
JSUFileInputStream(JKRFile* file);
|
||||
|
||||
virtual ~JSUFileInputStream() { }
|
||||
virtual int readData(void* buf, s32 len);
|
||||
virtual int getLength() const { return ((JKRFile*)this->mObject)->getFileSize(); }
|
||||
virtual int getPosition() const { return this->mPosition; }
|
||||
virtual int seekPos(s32 offset, JSUStreamSeekFrom from);
|
||||
|
||||
/* These two functions are shown in the symbol map, but are unused. */
|
||||
// bool open(const char* path);
|
||||
// bool close();
|
||||
|
||||
protected:
|
||||
const void* mObject;
|
||||
s32 mPosition;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,110 @@
|
||||
#ifndef JSUINPUTSTREAM_H
|
||||
#define JSUINPUTSTREAM_H
|
||||
|
||||
#include "types.h"
|
||||
#include "JSystem/JSupport/JSUIosBase.h"
|
||||
|
||||
class JSUInputStream : public JSUIosBase {
|
||||
public:
|
||||
virtual ~JSUInputStream();
|
||||
virtual int getAvailable() const = 0;
|
||||
virtual int skip(s32 amount);
|
||||
virtual int readData(void* buf, s32 size) = 0;
|
||||
|
||||
int read(void* buf, s32 size);
|
||||
char* read(char* buf);
|
||||
char* readString();
|
||||
char* readString(char* buf, u16 len);
|
||||
|
||||
int read(s8& p) { return this->read(&p, sizeof(s8)); } /* @fabricated */
|
||||
int read(u8& p) { return this->read(&p, sizeof(u8)); }
|
||||
int read(bool& p) { return this->read(&p, sizeof(bool)); }
|
||||
int read(s16& p) { return this->read(&p, sizeof(s16)); } /* @fabricated */
|
||||
int read(u16& p) { return this->read(&p, sizeof(u16)); } /* @fabricated */
|
||||
int read(s32& p) { return this->read(&p, sizeof(s32)); } /* @fabricated */
|
||||
int read(u32& p) { return this->read(&p, sizeof(u32)); }
|
||||
int read(s64& p) { return this->read(&p, sizeof(s64)); } /* @fabricated */
|
||||
int read(u64& p) { return this->read(&p, sizeof(u64)); } /* @fabricated */
|
||||
|
||||
u8 read8b() {
|
||||
u8 b;
|
||||
this->read(&b, sizeof(u8));
|
||||
return b;
|
||||
}
|
||||
|
||||
u16 read16b() {
|
||||
u16 s;
|
||||
this->read(&s, sizeof(u16));
|
||||
return s;
|
||||
}
|
||||
|
||||
u32 read32b() {
|
||||
u32 i;
|
||||
this->read(&i, sizeof(u32));
|
||||
return i;
|
||||
}
|
||||
|
||||
/* @fabricated */
|
||||
s8 readS8() {
|
||||
s8 b;
|
||||
this->read(&b, sizeof(s8));
|
||||
return b;
|
||||
}
|
||||
|
||||
u8 readU8() {
|
||||
u8 b;
|
||||
this->read(&b, sizeof(u8));
|
||||
return b;
|
||||
}
|
||||
|
||||
s16 readS16() {
|
||||
s16 s;
|
||||
this->read(&s, sizeof(s16));
|
||||
return s;
|
||||
}
|
||||
|
||||
u16 readU16() {
|
||||
u16 s;
|
||||
this->read(&s, sizeof(u16));
|
||||
return s;
|
||||
}
|
||||
|
||||
s32 readS32() {
|
||||
s32 i;
|
||||
this->read(&i, sizeof(s32));
|
||||
return i;
|
||||
}
|
||||
|
||||
u32 readU32() {
|
||||
u32 i;
|
||||
this->read(&i, sizeof(u32));
|
||||
return i;
|
||||
}
|
||||
|
||||
JSUInputStream& operator>>(s8& p) {
|
||||
this->read(&p, sizeof(s8));
|
||||
return *this;
|
||||
}
|
||||
|
||||
JSUInputStream& operator>>(u8& p) {
|
||||
this->read(&p, sizeof(u8));
|
||||
return *this;
|
||||
}
|
||||
|
||||
JSUInputStream& operator>>(s16& p) {
|
||||
this->read(&p, sizeof(s16));
|
||||
return *this;
|
||||
}
|
||||
|
||||
JSUInputStream& operator>>(u16& p) {
|
||||
this->read(&p, sizeof(u16));
|
||||
return *this;
|
||||
}
|
||||
|
||||
JSUInputStream& operator>>(u32& p) {
|
||||
this->read(&p, sizeof(u32));
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,21 @@
|
||||
#ifndef JSUIOSBASE_H
|
||||
#define JSUIOSBASE_H
|
||||
|
||||
#include "types.h"
|
||||
#include "JSystem/JSupport/JSUStreamEnum.h"
|
||||
|
||||
class JSUIosBase {
|
||||
public:
|
||||
inline JSUIosBase() : mState(GOOD) { }
|
||||
|
||||
virtual ~JSUIosBase() { }
|
||||
|
||||
bool isGood() { return !this->mState; }
|
||||
void clrState(EIoState ioState) { this->mState &= ~ioState; }
|
||||
void setState(EIoState ioState) { this->mState |= ioState; }
|
||||
|
||||
u8 mState;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef JSURANDOMINPUTSTREAM_H
|
||||
#define JSURANDOMINPUTSTREAM_H
|
||||
|
||||
#include "types.h"
|
||||
#include "JSystem/JKernel/JKRFile.h"
|
||||
#include "JSystem/JSupport/JSUInputStream.h"
|
||||
|
||||
class JSURandomInputStream : public JSUInputStream {
|
||||
public:
|
||||
virtual ~JSURandomInputStream() { }
|
||||
|
||||
virtual int getAvailable() const { return this->getLength() - this->getPosition(); }
|
||||
virtual int skip(s32 amount);
|
||||
virtual int readData(void* buf, s32 count) = 0;
|
||||
virtual int getLength() const = 0;
|
||||
virtual int getPosition() const = 0;
|
||||
virtual int seekPos(s32 offset, JSUStreamSeekFrom from) = 0;
|
||||
|
||||
int align(s32 alignment);
|
||||
int peek(void* buf, s32 len);
|
||||
int seek(s32 offset, JSUStreamSeekFrom from);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,10 @@
|
||||
#ifndef JSUSTREAM_H
|
||||
#define JSUSTREAM_H
|
||||
|
||||
#include "JSystem/JSupport/JSUStreamEnum.h"
|
||||
#include "JSystem/JSupport/JSUIosBase.h"
|
||||
#include "JSystem/JSupport/JSUInputStream.h"
|
||||
#include "JSystem/JSupport/JSURandomInputStream.h"
|
||||
#include "JSystem/JSupport/JSUFileInputStream.h"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,15 @@
|
||||
#ifndef JSUSTREAMENUM_H
|
||||
#define JSUSTREAMENUM_H
|
||||
|
||||
enum JSUStreamSeekFrom {
|
||||
SEEK_SET = 0,
|
||||
SEEK_CUR = 1,
|
||||
SEEK_END = 2
|
||||
};
|
||||
|
||||
enum EIoState {
|
||||
GOOD = 0,
|
||||
EOF = 1
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,30 @@
|
||||
#ifndef JSYSTEM_H
|
||||
#define JSYSTEM_H
|
||||
|
||||
#include "dolphin/os.h"
|
||||
#include "JSystem/JKernel/JKRAram.h"
|
||||
//#include "JSystem/JUtility/JUTException.h"
|
||||
|
||||
#define JLOG(msg) (OSReport(msg))
|
||||
#define JLOGF(msg, ...) (OSReport(msg, __VA_ARGS__))
|
||||
|
||||
/* Macros which will remove debug OSReport calls when not compiled for debug */
|
||||
#ifdef JSYSTEM_DEBUG
|
||||
#define JREPORT(msg) OSReport(msg)
|
||||
#define JREPORTF(msg, ...) OSReport(msg, __VA_ARGS__)
|
||||
#else
|
||||
#define JREPORT(msg)
|
||||
#define JREPORTF(msg, ...)
|
||||
#endif
|
||||
|
||||
#ifdef JSYSTEM_DEBUG
|
||||
#define JPANICLINE(line) ()
|
||||
#define JPANIC(line, msg) () /* TODO: JUTException */
|
||||
#define JPANICF(line, msg, ...) () /* TODO: JUTException */
|
||||
#else
|
||||
#define JPANICLINE(line) (OSErrorLine(line, "Abort."))
|
||||
#define JPANIC(line, msg) (OSErrorLine(line, msg))
|
||||
#define JPANICF(line, msg, ...) (OSErrorLine(line, msg, __VA_ARGS__))
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,29 +1,29 @@
|
||||
#ifndef _JSYSTEM_JUT_JUTASSERTION_H
|
||||
#define _JSYSTEM_JUT_JUTASSERTION_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
void JC_JUTAssertion_changeDevice(u32);
|
||||
|
||||
#define JUT_PANIC(...)
|
||||
#define JUT_PANIC_F(...)
|
||||
#define JUT_CONFIRM_MESSAGE(...)
|
||||
#define JUT_WARNING(...)
|
||||
#define JUT_WARNING_F(...)
|
||||
#define JUT_ASSERT(...)
|
||||
#define JUT_ASSERT_F(...)
|
||||
#define JUT_ASSERT_MSG(...)
|
||||
#define JUT_MINMAX_ASSERT(...)
|
||||
#define JUT_MAX_ASSERT(...)
|
||||
#define JUT_LOG_F(...)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#ifndef _JSYSTEM_JUT_JUTASSERTION_H
|
||||
#define _JSYSTEM_JUT_JUTASSERTION_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
void JC_JUTAssertion_changeDevice(u32);
|
||||
|
||||
#define JUT_PANIC(...)
|
||||
#define JUT_PANIC_F(...)
|
||||
#define JUT_CONFIRM_MESSAGE(...)
|
||||
#define JUT_WARNING(...)
|
||||
#define JUT_WARNING_F(...)
|
||||
#define JUT_ASSERT(...)
|
||||
#define JUT_ASSERT_F(...)
|
||||
#define JUT_ASSERT_MSG(...)
|
||||
#define JUT_MINMAX_ASSERT(...)
|
||||
#define JUT_MAX_ASSERT(...)
|
||||
#define JUT_LOG_F(...)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,9 +1,9 @@
|
||||
#ifndef _JSYSTEM_JUT_JUTDBPRINT_H
|
||||
#define _JSYSTEM_JUT_JUTDBPRINT_H
|
||||
|
||||
void* JC_JUTDbPrint_getManager(void);
|
||||
void JC_JUTDbPrint_setVisible(void*, int); // I know these are C++ but these were used to match a c function so I'll fix these when I need them or fix zurumode update.
|
||||
|
||||
|
||||
|
||||
#ifndef _JSYSTEM_JUT_JUTDBPRINT_H
|
||||
#define _JSYSTEM_JUT_JUTDBPRINT_H
|
||||
|
||||
void* JC_JUTDbPrint_getManager(void);
|
||||
void JC_JUTDbPrint_setVisible(void*, int); // I know these are C++ but these were used to match a c function so I'll fix these when I need them or fix zurumode update.
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,73 @@
|
||||
#ifndef _DOLPHIN_PPCARCH_H
|
||||
#define _DOLPHIN_PPCARCH_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#define HID0 0x3f0
|
||||
#define HID0_ICE 0x8000
|
||||
#define HID0_ICFI 0x800
|
||||
#define HID0_DCE 0x4000
|
||||
#define HID2 0x398
|
||||
#define HID2_LCE_BIT 3
|
||||
#define MSR_ME 0x1000
|
||||
#define LC_BASE_PREFIX 0xE000
|
||||
#define DBAT3L 3
|
||||
#define DBAT3U 3
|
||||
#define DMA_U 0x39a
|
||||
#define DMA_L 0x39b
|
||||
#define DMA_L_STORE 0
|
||||
#define DMA_L_TRIGGER 2
|
||||
#define LC_MAX_DMA_BLOCKS 128
|
||||
#define LC_MAX_DMA_BYTES 0x1000
|
||||
|
||||
#define MSR_IR 0x00000020 // instruction relocate
|
||||
#define MSR_DR 0x00000010 // data relocate
|
||||
|
||||
#define HID2_DCHERR 0x00800000 // ERROR: dcbz_l cache hit
|
||||
#define HID2_DNCERR 0x00400000 // ERROR: DMA access to normal cache
|
||||
#define HID2_DCMERR 0x00200000 // ERROR: DMA cache miss error
|
||||
#define HID2_DQOERR 0x00100000 // ERROR: DMA queue overflow
|
||||
#define HID2_DCHEE 0x00080000 // dcbz_l cache hit error enable
|
||||
#define HID2_DNCEE 0x00040000 // DMA access to normal cache error enable
|
||||
#define HID2_DCMEE 0x00020000 // DMA cache miss error error enable
|
||||
#define HID2_DQOEE 0x00010000 // DMA queue overflow error enable
|
||||
|
||||
#define L2CR_L2E 0x80000000 // L2 Enable
|
||||
#define L2CR_L2I 0x00200000 // Global invalidate
|
||||
#define L2CR_L2IP 0x00000001 // L2 global invalidate in progress
|
||||
|
||||
#define SRR1_DMA_BIT 0x00200000
|
||||
#define SRR1_L2DP_BIT 0x00100000
|
||||
|
||||
u32 PPCMfmsr();
|
||||
void PPCMtmsr(u32 newMSR);
|
||||
// u32 PPCOrMsr(u32 value);
|
||||
void PPCOrMsr();
|
||||
u32 PPCMfhid0();
|
||||
void PPCMthid0(u32 newHID0);
|
||||
u32 PPCMfl2cr();
|
||||
void PPCMtl2cr(u32 newL2cr);
|
||||
void PPCMtdec(u32 newDec);
|
||||
void PPCSync();
|
||||
void PPCHalt();
|
||||
u32 PPCMffpscr();
|
||||
void PPCMtfpscr(u32 newFPSCR);
|
||||
u32 PPCMfhid2();
|
||||
void PPCMthid2(u32 newhid2);
|
||||
u32 PPCMfwpar();
|
||||
void PPCMtwpar(u32 newwpar);
|
||||
void PPCEnableSpeculation();
|
||||
void PPCDisableSpeculation();
|
||||
void PPCSetFpIEEEMode();
|
||||
void PPCSetFpNonIEEEMode();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,90 @@
|
||||
#ifndef _DOLPHIN_AR_H
|
||||
#define _DOLPHIN_AR_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // ifdef __cplusplus
|
||||
|
||||
///////////////// AR TYPES /////////////////
|
||||
typedef struct ARQRequest ARQRequest;
|
||||
|
||||
// AR callback function type.
|
||||
typedef void (*ARCallback)(void);
|
||||
|
||||
// ARQ callback function type.
|
||||
typedef void (*ARQCallback)(u32 ptrToRequest);
|
||||
|
||||
struct ARQRequest {
|
||||
ARQRequest* next; // _00
|
||||
u32 owner; // _04
|
||||
u32 type; // _08
|
||||
u32 priority; // _0C
|
||||
u32 source; // _10
|
||||
u32 dest; // _14
|
||||
u32 length; // _18
|
||||
ARQCallback callback; // _1C
|
||||
};
|
||||
|
||||
////////////////////////////////////////////
|
||||
|
||||
/////////////// AR FUNCTIONS ///////////////
|
||||
// ARQ functions.
|
||||
void ARQInit();
|
||||
void ARQPostRequest(ARQRequest* task, u32 owner, u32 type, u32 priority, u32 source, u32 dest, u32 length, ARQCallback callback);
|
||||
|
||||
// AR functions.
|
||||
ARCallback ARRegisterDMACallback(ARCallback callback);
|
||||
u32 ARGetDMAStatus();
|
||||
void ARStartDMA(u32 type, u32 mainmem_addr, u32 aram_addr, u32 length);
|
||||
u32 ARAlloc(u32 length);
|
||||
u32 ARInit(u32* stack_index_addr, u32 num_entries);
|
||||
u32 ARGetBaseAddress();
|
||||
u32 ARGetSize();
|
||||
|
||||
// Unused/inlined in P2.
|
||||
u32 ARFree(u32* length);
|
||||
BOOL ARCheckInit();
|
||||
void ARReset();
|
||||
void ARSetSize();
|
||||
u32 ARGetInternalSize();
|
||||
void ARClear(u32 flag);
|
||||
|
||||
////////////////////////////////////////////
|
||||
|
||||
//////////////// AR DEFINES ////////////////
|
||||
// AR defines.
|
||||
#define AR_STACK_INDEX_ENTRY_SIZE sizeof(u32)
|
||||
|
||||
#define ARAM_DIR_MRAM_TO_ARAM 0x00
|
||||
#define ARAM_DIR_ARAM_TO_MRAM 0x01
|
||||
|
||||
#define AR_CLEAR_INTERNAL_ALL 0x00
|
||||
#define AR_CLEAR_INTERNAL_USER 0x01
|
||||
#define AR_CLEAR_EXPANSION 0x02
|
||||
|
||||
#define __AR_ARAM_OS_BASE_ADDR 0x0000 // OS area at bottom of ARAM
|
||||
#define __AR_ARAM_USR_BASE_ADDR 0x4000 // USR area at 16KB (0x4000)
|
||||
|
||||
// AR macros.
|
||||
#define ARStartDMARead(mmem, aram, len) ARStartDMA(ARAM_DIR_ARAM_TO_MRAM, mmem, aram, len)
|
||||
#define ARStartDMAWrite(mmem, aram, len) ARStartDMA(ARAM_DIR_MRAM_TO_ARAM, mmem, aram, len)
|
||||
|
||||
// ARQ defines.
|
||||
#define ARQ_DMA_ALIGNMENT 32
|
||||
#define ARQ_CHUNK_SIZE_DEFAULT 4096
|
||||
|
||||
#define ARQ_TYPE_MRAM_TO_ARAM ARAM_DIR_MRAM_TO_ARAM
|
||||
#define ARQ_TYPE_ARAM_TO_MRAM ARAM_DIR_ARAM_TO_MRAM
|
||||
|
||||
#define ARQ_PRIORITY_LOW 0
|
||||
#define ARQ_PRIORITY_HIGH 1
|
||||
|
||||
////////////////////////////////////////////
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif // ifdef __cplusplus
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,202 @@
|
||||
#ifndef _DOLPHIN_DVD_H
|
||||
#define _DOLPHIN_DVD_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // ifdef __cplusplus
|
||||
|
||||
/////////// DVD TYPES ///////////
|
||||
typedef struct DVDCommandBlock DVDCommandBlock;
|
||||
typedef struct DVDFileInfo DVDFileInfo;
|
||||
|
||||
// Callback function types.
|
||||
typedef void (*DVDCallback)(s32 result, DVDFileInfo* fileInfo);
|
||||
typedef void (*DVDCBCallback)(s32 result, DVDCommandBlock* block);
|
||||
typedef void (*DVDLowCallback)(u32 intType);
|
||||
typedef void (*DVDDoneReadCallback)(s32, DVDFileInfo*);
|
||||
typedef void (*DVDOptionalCommandChecker)(DVDCommandBlock* block, DVDLowCallback callback);
|
||||
|
||||
typedef struct DVDDriveInfo {
|
||||
u16 revisionLevel; // _00
|
||||
u16 deviceCode; // _02
|
||||
u32 releaseDate; // _04
|
||||
u8 padding[24]; // _08
|
||||
} DVDDriveInfo;
|
||||
|
||||
// Struct for DVD information (size 0x20)
|
||||
typedef struct DVDDiskID {
|
||||
char gameName[4]; // _00
|
||||
char company[2]; // _04
|
||||
u8 diskNumber; // _06
|
||||
u8 gameVersion; // _07
|
||||
u8 streaming; // _08
|
||||
u8 streamBufSize; // _09, default = 0
|
||||
u8 padding[22]; // _0A, all 0s
|
||||
} DVDDiskID;
|
||||
|
||||
// Struct for command information (size 0x30).
|
||||
struct DVDCommandBlock {
|
||||
DVDCommandBlock* next; // _00
|
||||
DVDCommandBlock* prev; // _04
|
||||
u32 command; // _08
|
||||
s32 state; // _0C
|
||||
u32 offset; // _10
|
||||
u32 length; // _14
|
||||
void* addr; // _18
|
||||
u32 currTransferSize; // _1C
|
||||
u32 transferredSize; // _20
|
||||
DVDDiskID* id; // _24
|
||||
DVDCBCallback callback; // _28
|
||||
void* userData; // _2C
|
||||
};
|
||||
|
||||
// Struct for file information (size 0x3C).
|
||||
// NB: we had this as DVDPlayer previously.
|
||||
struct DVDFileInfo {
|
||||
DVDCommandBlock cBlock; // _00
|
||||
u32 startAddr; // _30
|
||||
u32 length; // _34
|
||||
DVDCallback callback; // _38
|
||||
};
|
||||
|
||||
// Struct for directory information (size 0xC).
|
||||
typedef struct DVDDir {
|
||||
u32 entryNum; // _00
|
||||
u32 location; // _04
|
||||
u32 next; // _08
|
||||
} DVDDir;
|
||||
|
||||
// Struct for directory entries (size 0xC).
|
||||
typedef struct DVDDirEntry {
|
||||
u32 entryNum; // _00
|
||||
BOOL isDir; // _04
|
||||
char* name; // _08
|
||||
} DVDDirEntry;
|
||||
|
||||
// Struct for handing queues.
|
||||
typedef struct DVDQueue DVDQueue;
|
||||
|
||||
struct DVDQueue {
|
||||
DVDQueue* mHead; // _00
|
||||
DVDQueue* mTail; // _04
|
||||
};
|
||||
|
||||
// DVD Boot information instructions.
|
||||
// Struct 1.
|
||||
typedef struct DVDBB1 {
|
||||
u32 appLoaderLength; // _00
|
||||
void* appLoaderFunc1; // _04
|
||||
void* appLoaderFunc2; // _08
|
||||
void* appLoaderFunc3; // _0C
|
||||
} DVDBB1;
|
||||
|
||||
// Struct 2.
|
||||
typedef struct DVDBB2 {
|
||||
u32 bootFilePosition; // _00
|
||||
u32 FSTPosition; // _04
|
||||
u32 FSTLength; // _08
|
||||
u32 FSTMaxLength; // _0C
|
||||
void* FSTAddress; // _10
|
||||
u32 userPosition; // _14
|
||||
u32 userLength; // _18
|
||||
u32 reserved_1C; // _1C
|
||||
} DVDBB2;
|
||||
|
||||
//////////////////////////////////
|
||||
|
||||
///////// DVD FUNCTIONS //////////
|
||||
// Basic DVD functions.
|
||||
void DVDInit();
|
||||
BOOL DVDOpen(char* filename, DVDFileInfo* fileInfo);
|
||||
BOOL DVDFastOpen(s32 entryNum, DVDFileInfo* fileInfo);
|
||||
s32 DVDReadPrio(DVDFileInfo* fileInfo, void* addr, s32 length, s32 offset, s32 prio);
|
||||
BOOL DVDReadAsyncPrio(DVDFileInfo* fileInfo, void* addr, s32 length, s32 offset, DVDCallback callback, s32 prio);
|
||||
BOOL DVDClose(DVDFileInfo* fileInfo);
|
||||
|
||||
void DVDResume();
|
||||
void DVDReset();
|
||||
|
||||
BOOL DVDCancelAsync(DVDCommandBlock* block, DVDCBCallback callback);
|
||||
s32 DVDCancel(DVDCommandBlock* block);
|
||||
|
||||
s32 DVDChangeDisk(DVDCommandBlock* block, DVDDiskID* id);
|
||||
BOOL DVDChangeDiskAsync(DVDCommandBlock* block, DVDDiskID* id, DVDCBCallback callback);
|
||||
|
||||
// Status functions.
|
||||
s32 DVDGetCommandBlockStatus(const DVDCommandBlock* block);
|
||||
s32 DVDGetDriveStatus();
|
||||
BOOL DVDSetAutoInvalidation(BOOL doAutoInval);
|
||||
void* DVDGetFSTLocation();
|
||||
|
||||
// DVD Dir functions.
|
||||
BOOL DVDOpenDir(char* dirName, DVDDir* dir);
|
||||
BOOL DVDReadDir(DVDDir* dir, DVDDirEntry* dirEntry);
|
||||
BOOL DVDCloseDir(DVDDir* dir);
|
||||
BOOL DVDGetCurrentDir(char* path, u32 maxLength);
|
||||
BOOL DVDChangeDir(char* dirName);
|
||||
s32 DVDConvertPathToEntrynum(char* path);
|
||||
|
||||
// Other disk functions.
|
||||
s32 DVDGetTransferredSize(DVDFileInfo* fileInfo);
|
||||
DVDDiskID* DVDGetCurrentDiskID();
|
||||
BOOL DVDCompareDiskID(DVDDiskID* id1, DVDDiskID* id2);
|
||||
DVDLowCallback DVDLowClearCallback();
|
||||
|
||||
BOOL DVDCheckDisk();
|
||||
|
||||
// Unused/inlined in P2.
|
||||
void DVDPause();
|
||||
s32 DVDSeekPrio(DVDFileInfo* fileInfo, s32 offset, s32 prio);
|
||||
BOOL DVDSeekAsyncPrio(DVDFileInfo* fileInfo, s32 offset, DVDCallback callback, s32 prio);
|
||||
s32 DVDGetFileInfoStatus(DVDFileInfo* fileInfo);
|
||||
BOOL DVDFastOpenDir(s32 entryNum, DVDDir* dir);
|
||||
BOOL DVDCancelAllAsync(DVDCBCallback callback);
|
||||
s32 DVDCancelAll();
|
||||
void DVDDumpWaitingQueue();
|
||||
|
||||
//////////////////////////////////
|
||||
|
||||
////// USEFUL DVD DEFINES ////////
|
||||
// Macro for reading.
|
||||
#define DVDReadAsync(fileInfo, addr, length, offset, callback) DVDReadAsyncPrio((fileInfo), (addr), (length), (offset), (callback), 2)
|
||||
#define DVDGetFileInfoStatus(fileInfo) DVDGetCommandBlockStatus(&(fileInfo)->cBlock)
|
||||
|
||||
// Minimum transfer size.
|
||||
#define DVD_MIN_TRANSFER_SIZE 32
|
||||
|
||||
// DVD states.
|
||||
#define DVD_STATE_FATAL_ERROR -1
|
||||
#define DVD_STATE_END 0
|
||||
#define DVD_STATE_BUSY 1
|
||||
#define DVD_STATE_WAITING 2
|
||||
#define DVD_STATE_COVER_CLOSED 3
|
||||
#define DVD_STATE_NO_DISK 4
|
||||
#define DVD_STATE_COVER_OPEN 5
|
||||
#define DVD_STATE_WRONG_DISK 6
|
||||
#define DVD_STATE_MOTOR_STOPPED 7
|
||||
#define DVD_STATE_PAUSING 8
|
||||
#define DVD_STATE_IGNORED 9
|
||||
#define DVD_STATE_CANCELED 10
|
||||
#define DVD_STATE_RETRY 11
|
||||
|
||||
// File info states.
|
||||
#define DVD_FILEINFO_READY 0
|
||||
#define DVD_FILEINFO_BUSY 1
|
||||
|
||||
// DVD results.
|
||||
#define DVD_RESULT_GOOD 0
|
||||
#define DVD_RESULT_FATAL_ERROR -1
|
||||
#define DVD_RESULT_IGNORED -2
|
||||
#define DVD_RESULT_CANCELED -3
|
||||
|
||||
#define DVD_AIS_SUCCESS 0
|
||||
|
||||
//////////////////////////////////
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif // ifdef __cplusplus
|
||||
|
||||
#endif
|
||||
@@ -3,11 +3,17 @@
|
||||
|
||||
#include "types.h"
|
||||
#include "dolphin/os/OSContext.h"
|
||||
#include "dolphin/os/OSMessage.h"
|
||||
#include "va_args.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// __ppc_eabi_init
|
||||
extern void __OSPSInit();
|
||||
extern void __OSFPRInit();
|
||||
extern void __OSCacheInit();
|
||||
|
||||
void OSPanic(const char *file, int line, const char *message, ...);
|
||||
void OSReport(const char*, ...);
|
||||
void OSVReport(const char* format, va_list list);
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
#ifndef _DOLPHIN_OS_OSMESSAGE_H
|
||||
#define _DOLPHIN_OS_OSMESSAGE_H
|
||||
|
||||
#include "types.h"
|
||||
#include "dolphin/os/OSUtil.h"
|
||||
#include "dolphin/os/OSThread.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // ifdef __cplusplus
|
||||
|
||||
///////// MESSAGE TYPES //////////
|
||||
typedef struct OSMessageQueue OSMessageQueue;
|
||||
|
||||
// Useful typedef for messages.
|
||||
typedef void* OSMessage;
|
||||
|
||||
// Struct for managing the message queue.
|
||||
struct OSMessageQueue {
|
||||
OSThreadQueue queueSend; // _00
|
||||
OSThreadQueue queueReceive; // _08
|
||||
OSMessage* msgArray; // _10, array of messages.
|
||||
int msgCount; // _14, array limit size.
|
||||
int firstIndex; // _18, first message index in array.
|
||||
int usedCount; // _1C, actual number of used messages.
|
||||
};
|
||||
|
||||
// Defines for message flags for sending/receiving.
|
||||
#define OS_MESSAGE_NOBLOCK (0)
|
||||
#define OS_MESSAGE_BLOCK (1)
|
||||
|
||||
typedef enum {
|
||||
OS_MSG_PERSISTENT = (1 << 0),
|
||||
} OSMessageFlags;
|
||||
|
||||
//////////////////////////////////
|
||||
|
||||
/////// MESSAGE FUNCTIONS ////////
|
||||
// Functions for handling messages.
|
||||
void OSInitMessageQueue(OSMessageQueue* queue, OSMessage* msgArray, int msgCount);
|
||||
BOOL OSSendMessage(OSMessageQueue* queue, OSMessage msg, int flags);
|
||||
BOOL OSJamMessage(OSMessageQueue* queue, OSMessage msg, int flags);
|
||||
BOOL OSReceiveMessage(OSMessageQueue* queue, OSMessage* msgPtr, int flags);
|
||||
|
||||
//////////////////////////////////
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif // ifdef __cplusplus
|
||||
|
||||
#endif
|
||||
@@ -8,26 +8,26 @@ extern "C"
|
||||
|
||||
#include "dolphin/os/OSThread.h"
|
||||
|
||||
struct OSMutex
|
||||
{
|
||||
OSThreadQueue queue;
|
||||
OSThread *thread; // the current owner
|
||||
s32 count; // lock count
|
||||
OSMutexLink link; // for OSThread.queueMutex
|
||||
};
|
||||
struct OSMutex
|
||||
{
|
||||
OSThreadQueue queue;
|
||||
OSThread *thread; // the current owner
|
||||
s32 count; // lock count
|
||||
OSMutexLink link; // for OSThread.queueMutex
|
||||
};
|
||||
|
||||
struct OSCond
|
||||
{
|
||||
OSThreadQueue queue;
|
||||
};
|
||||
struct OSCond
|
||||
{
|
||||
OSThreadQueue queue;
|
||||
};
|
||||
|
||||
void OSInitMutex(OSMutex *mutex);
|
||||
void OSLockMutex(OSMutex *mutex);
|
||||
void OSUnlockMutex(OSMutex *mutex);
|
||||
BOOL OSTryLockMutex(OSMutex *mutex);
|
||||
void OSInitCond(OSCond *cond);
|
||||
void OSWaitCond(OSCond *cond, OSMutex *mutex);
|
||||
void OSSignalCond(OSCond *cond);
|
||||
void OSInitMutex(OSMutex *mutex);
|
||||
void OSLockMutex(OSMutex *mutex);
|
||||
void OSUnlockMutex(OSMutex *mutex);
|
||||
BOOL OSTryLockMutex(OSMutex *mutex);
|
||||
void OSInitCond(OSCond *cond);
|
||||
void OSWaitCond(OSCond *cond, OSMutex *mutex);
|
||||
void OSSignalCond(OSCond *cond);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -8,75 +8,75 @@ extern "C"
|
||||
|
||||
#include "dolphin/os/OSContext.h"
|
||||
|
||||
typedef struct OSThread OSThread;
|
||||
typedef struct OSThreadQueue OSThreadQueue;
|
||||
typedef struct OSThreadLink OSThreadLink;
|
||||
typedef s32 OSPriority; // 0 highest, 31 lowest
|
||||
typedef struct OSThread OSThread;
|
||||
typedef struct OSThreadQueue OSThreadQueue;
|
||||
typedef struct OSThreadLink OSThreadLink;
|
||||
typedef s32 OSPriority; // 0 highest, 31 lowest
|
||||
|
||||
typedef struct OSMutex OSMutex;
|
||||
typedef struct OSMutexQueue OSMutexQueue;
|
||||
typedef struct OSMutexLink OSMutexLink;
|
||||
typedef struct OSCond OSCond;
|
||||
typedef struct OSMutex OSMutex;
|
||||
typedef struct OSMutexQueue OSMutexQueue;
|
||||
typedef struct OSMutexLink OSMutexLink;
|
||||
typedef struct OSCond OSCond;
|
||||
|
||||
typedef void (*OSIdleFunction)(void *param);
|
||||
typedef void (*OSIdleFunction)(void *param);
|
||||
|
||||
struct OSThreadQueue
|
||||
{
|
||||
OSThread *head;
|
||||
OSThread *tail;
|
||||
};
|
||||
struct OSThreadQueue
|
||||
{
|
||||
OSThread *head;
|
||||
OSThread *tail;
|
||||
};
|
||||
|
||||
struct OSThreadLink
|
||||
{
|
||||
OSThread *next;
|
||||
OSThread *prev;
|
||||
};
|
||||
struct OSThreadLink
|
||||
{
|
||||
OSThread *next;
|
||||
OSThread *prev;
|
||||
};
|
||||
|
||||
struct OSMutexQueue
|
||||
{
|
||||
OSMutex *head;
|
||||
OSMutex *tail;
|
||||
};
|
||||
struct OSMutexQueue
|
||||
{
|
||||
OSMutex *head;
|
||||
OSMutex *tail;
|
||||
};
|
||||
|
||||
struct OSMutexLink
|
||||
{
|
||||
OSMutex *next;
|
||||
OSMutex *prev;
|
||||
};
|
||||
struct OSMutexLink
|
||||
{
|
||||
OSMutex *next;
|
||||
OSMutex *prev;
|
||||
};
|
||||
|
||||
struct OSThread
|
||||
{
|
||||
OSContext context; // register context
|
||||
struct OSThread
|
||||
{
|
||||
OSContext context; // register context
|
||||
|
||||
u16 state; // OS_THREAD_STATE_*
|
||||
u16 attr; // OS_THREAD_ATTR_*
|
||||
s32 suspend; // suspended if the count is greater than zero
|
||||
OSPriority priority; // effective scheduling priority
|
||||
OSPriority base; // base scheduling priority
|
||||
void *val; // exit value
|
||||
u16 state; // OS_THREAD_STATE_*
|
||||
u16 attr; // OS_THREAD_ATTR_*
|
||||
s32 suspend; // suspended if the count is greater than zero
|
||||
OSPriority priority; // effective scheduling priority
|
||||
OSPriority base; // base scheduling priority
|
||||
void *val; // exit value
|
||||
|
||||
OSThreadQueue *queue; // queue thread is on
|
||||
OSThreadLink link; // queue link
|
||||
OSThreadQueue *queue; // queue thread is on
|
||||
OSThreadLink link; // queue link
|
||||
|
||||
OSThreadQueue queueJoin; // list of threads waiting for termination (join)
|
||||
OSThreadQueue queueJoin; // list of threads waiting for termination (join)
|
||||
|
||||
OSMutex *mutex; // mutex trying to lock
|
||||
OSMutexQueue queueMutex; // list of mutexes owned
|
||||
OSMutex *mutex; // mutex trying to lock
|
||||
OSMutexQueue queueMutex; // list of mutexes owned
|
||||
|
||||
OSThreadLink linkActive; // link of all threads for debugging
|
||||
OSThreadLink linkActive; // link of all threads for debugging
|
||||
|
||||
u8 *stackBase; // the thread's designated stack (high address)
|
||||
u32 *stackEnd; // last word of stack (low address)
|
||||
};
|
||||
u8 *stackBase; // the thread's designated stack (high address)
|
||||
u32 *stackEnd; // last word of stack (low address)
|
||||
};
|
||||
|
||||
// Thread states
|
||||
enum OS_THREAD_STATE
|
||||
{
|
||||
OS_THREAD_STATE_READY = 1,
|
||||
OS_THREAD_STATE_RUNNING = 2,
|
||||
OS_THREAD_STATE_WAITING = 4,
|
||||
OS_THREAD_STATE_MORIBUND = 8
|
||||
};
|
||||
// Thread states
|
||||
enum OS_THREAD_STATE
|
||||
{
|
||||
OS_THREAD_STATE_READY = 1,
|
||||
OS_THREAD_STATE_RUNNING = 2,
|
||||
OS_THREAD_STATE_WAITING = 4,
|
||||
OS_THREAD_STATE_MORIBUND = 8
|
||||
};
|
||||
|
||||
// Thread priorities
|
||||
#define OS_PRIORITY_MIN 0 // highest
|
||||
|
||||
@@ -5,8 +5,13 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define OSDiffTick(tick1, tick0) ((s32)(tick1) - (s32)(tick0))
|
||||
|
||||
typedef s64 OSTime;
|
||||
typedef u32 OSTick;
|
||||
|
||||
OSTime OSGetTime(void);
|
||||
OSTick OSGetTick(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
+11
-2
@@ -3,6 +3,15 @@
|
||||
|
||||
#include "types.h"
|
||||
|
||||
void VISetBlack(BOOL);
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#endif
|
||||
void VISetBlack(BOOL);
|
||||
extern void VIWaitForRetrace();
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -37,4 +37,8 @@ typedef u32 unknown;
|
||||
#define FALSE 0
|
||||
#define NULL ((void*)0)
|
||||
#define nullptr 0
|
||||
|
||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,9 @@
|
||||
#include "types.h"
|
||||
|
||||
#define IRQMGR_STACK_SIZE 0x1000
|
||||
#define PADMGR_STACK_SIZE 0x1000
|
||||
#define GRAPH_STACK_SIZE 0x2000
|
||||
|
||||
extern u8 irqmgrStack [IRQMGR_STACK_SIZE];
|
||||
extern u8 padmgrStack [PADMGR_STACK_SIZE];
|
||||
extern u8 graphStack[GRAPH_STACK_SIZE];
|
||||
@@ -0,0 +1,44 @@
|
||||
#include "JSystem/JKernel/JKRAram.h"
|
||||
|
||||
JKRAramBlock::JKRAramBlock(u32 address, u32 size, u32 freeSize, u8 groupID, bool tempMemory)
|
||||
: mLink(this)
|
||||
, mAddress(address)
|
||||
, mSize(size)
|
||||
, mFreeSize(freeSize)
|
||||
, mGroupID(groupID)
|
||||
, mIsTempMemory(tempMemory)
|
||||
{
|
||||
}
|
||||
|
||||
JKRAramBlock::~JKRAramBlock() {
|
||||
JSULink<JKRAramBlock>* prev = this->mLink.getPrev();
|
||||
JSUList<JKRAramBlock>* list = this->mLink.getList();
|
||||
|
||||
if (prev) {
|
||||
prev->getObject()->mFreeSize += this->mSize + this->mFreeSize;
|
||||
list->remove(&this->mLink);
|
||||
}
|
||||
else {
|
||||
this->mFreeSize += this->mSize;
|
||||
this->mSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
JKRAramBlock* JKRAramBlock::allocHead(u32 size, u8 groupID, JKRAramHeap* heap) {
|
||||
u32 address = this->mAddress + this->mSize;
|
||||
u32 freeSize = this->mFreeSize - size;
|
||||
|
||||
JKRAramBlock* block = new(heap->mHeap, nullptr) JKRAramBlock(address, size, freeSize, groupID, false);
|
||||
this->mFreeSize = 0;
|
||||
this->mLink.mPtrList->insert(this->mLink.mNext, &block->mLink);
|
||||
return block;
|
||||
}
|
||||
|
||||
JKRAramBlock* JKRAramBlock::allocTail(u32 size, u8 groupID, JKRAramHeap* heap) {
|
||||
u32 address = this->mAddress + this->mSize + this->mFreeSize - size;
|
||||
|
||||
JKRAramBlock* block = new(heap->mHeap, nullptr) JKRAramBlock(address, size, 0, groupID, true);
|
||||
this->mFreeSize -= size;
|
||||
this->mLink.mPtrList->insert(this->mLink.mNext, &block->mLink);
|
||||
return block;
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
#include "JSystem/JKernel/JKRAram.h"
|
||||
#include "JSystem/JSystem.h"
|
||||
#include "dolphin/os.h" /* TODO: OSReport is actually in libforest */
|
||||
|
||||
JSUList<JKRAramBlock> JKRAramHeap::sAramList;
|
||||
|
||||
JKRAramHeap::JKRAramHeap(u32 baseAddress, u32 size) : JKRDisposer() {
|
||||
OSInitMutex(&this->mMutex);
|
||||
this->mHeap = JKRHeap::findFromRoot(this);
|
||||
this->mSize = ALIGN_PREV(size, 0x20);
|
||||
this->mHeadAddress = ALIGN_NEXT(baseAddress, 0x20);
|
||||
this->mTailAddress = this->mHeadAddress + this->mSize;
|
||||
this->mGroupID = 0xFF;
|
||||
JKRAramBlock* block = new (this->mHeap, nullptr)
|
||||
JKRAramBlock(this->mHeadAddress, 0, this->mSize, 0xFF, false);
|
||||
sAramList.append(&block->mLink);
|
||||
}
|
||||
|
||||
JKRAramHeap::~JKRAramHeap() {
|
||||
for (JSUListIterator<JKRAramBlock> it = sAramList.getFirst();
|
||||
it != sAramList.getEnd();) {
|
||||
delete (it++).getObject();
|
||||
}
|
||||
}
|
||||
|
||||
JKRAramBlock* JKRAramHeap::alloc(u32 size, JKRAramHeap::EAllocMode mode) {
|
||||
JKRAramBlock* block;
|
||||
this->lock();
|
||||
|
||||
if (mode == Head) {
|
||||
block = this->allocFromHead(size);
|
||||
} else {
|
||||
block = this->allocFromTail(size);
|
||||
}
|
||||
|
||||
this->unlock();
|
||||
return block;
|
||||
}
|
||||
|
||||
/* Code retrieved from Twilight Princess Debug version & matched. Unused in AC. */
|
||||
void JKRAramHeap::free(JKRAramBlock* block) {
|
||||
delete block;
|
||||
}
|
||||
|
||||
JKRAramBlock* JKRAramHeap::allocFromHead(u32 size) {
|
||||
size = ALIGN_NEXT(size, 32);
|
||||
u32 min_size = 0xFFFFFFFFUL;
|
||||
JKRAramBlock* block = nullptr;
|
||||
|
||||
for (JSUListIterator<JKRAramBlock> it = sAramList.getFirst();
|
||||
it != sAramList.getEnd(); it++) {
|
||||
JKRAramBlock* n_block = it.getObject();
|
||||
if (n_block->mFreeSize >= size && min_size > n_block->mFreeSize) {
|
||||
min_size = n_block->mFreeSize;
|
||||
block = n_block;
|
||||
if (block->mFreeSize == size) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (block != nullptr) {
|
||||
return block->allocHead(size, this->mGroupID, this);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JKRAramBlock* JKRAramHeap::allocFromTail(u32 size) {
|
||||
JKRAramBlock* block = nullptr;
|
||||
size = ALIGN_NEXT(size, 32);
|
||||
|
||||
for (JSUListIterator<JKRAramBlock> it = sAramList.getLast();
|
||||
it != sAramList.getEnd(); it--) {
|
||||
JKRAramBlock* n_block = it.getObject();
|
||||
|
||||
if (n_block->mFreeSize >= size) {
|
||||
block = n_block;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (block != nullptr) {
|
||||
return block->allocTail(size, this->mGroupID, this);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* Debug code retrieved from Twilight Princess Debug version */
|
||||
void JKRAramHeap::dump() {
|
||||
this->lock();
|
||||
|
||||
int total_used = 0;
|
||||
JREPORT("\nJKRAramHeap dump\n");
|
||||
JREPORT(" attr address: size gid\n");
|
||||
|
||||
for (JSUListIterator<JKRAramBlock> listItr = sAramList.getFirst();
|
||||
listItr != sAramList.getEnd(); listItr++) {
|
||||
if (listItr->mSize != 0) {
|
||||
JREPORTF("%s %08x: %08x %3d\n",
|
||||
listItr->isTempMemory() ? " temp" : "alloc", listItr->mAddress,
|
||||
listItr->mSize, listItr->mGroupID);
|
||||
}
|
||||
|
||||
if (listItr->mFreeSize != 0) {
|
||||
JREPORTF(" free %08x: %08x 0\n", listItr->mAddress + listItr->mSize,
|
||||
listItr->mFreeSize);
|
||||
}
|
||||
|
||||
total_used += listItr->mSize;
|
||||
}
|
||||
|
||||
JREPORTF("%d / %d bytes (%6.2f%%) used\n", total_used, this->mSize,
|
||||
(f32)total_used / (f32)this->mSize);
|
||||
|
||||
this->unlock();
|
||||
}
|
||||
|
||||
/* Not present in AC, recreated from TP debug. TODO: Check for matching. */
|
||||
u32 JKRAramHeap::getFreeSize() {
|
||||
u32 max_free = 0;
|
||||
this->lock();
|
||||
|
||||
for (JSUListIterator<JKRAramBlock> it = sAramList.getFirst(); it != sAramList.getEnd(); it++) {
|
||||
if (it->mFreeSize > max_free) {
|
||||
max_free = it->mFreeSize;
|
||||
}
|
||||
}
|
||||
|
||||
this->unlock();
|
||||
return max_free;
|
||||
}
|
||||
|
||||
/* Not present in AC, recreated from TP debug. TODO: Check for matching. */
|
||||
u32 JKRAramHeap::getTotalFreeSize() {
|
||||
u32 total_free = 0;
|
||||
this->lock();
|
||||
|
||||
for (JSUListIterator<JKRAramBlock> it = sAramList.getFirst(); it != sAramList.getEnd(); it++) {
|
||||
total_free += it->mFreeSize;
|
||||
}
|
||||
|
||||
this->unlock();
|
||||
return total_free;
|
||||
}
|
||||
|
||||
/* Not present in AC, recreated from TP debug. TODO: Check for matching. */
|
||||
u32 JKRAramHeap::getUsedSize(u8 groupID) {
|
||||
u32 total_used = 0;
|
||||
this->lock();
|
||||
|
||||
if (groupID == ARAM_GROUP_ID_ALL) {
|
||||
total_used = this->mSize - this->getTotalFreeSize();
|
||||
}
|
||||
else {
|
||||
for (JSUListIterator<JKRAramBlock> it = sAramList.getFirst(); it != sAramList.getEnd(); it++) {
|
||||
if (groupID == it->mGroupID) {
|
||||
total_used += it->mSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this->unlock();
|
||||
return total_used;
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
#include "types.h"
|
||||
#include "dolphin/ar.h"
|
||||
#include "dolphin/os/OSCache.h"
|
||||
#include "dolphin/os/OSMessage.h"
|
||||
#include "dolphin/os.h" /* TODO: OSReport lives in libforest in AC */
|
||||
#include "JSystem/JKernel/JKRMacro.h"
|
||||
#include "JSystem/JKernel/JKRHeap.h"
|
||||
#include "JSystem/JKernel/JKRDecomp.h"
|
||||
#include "JSystem/JSystem.h"
|
||||
|
||||
#include "JSystem/JKernel/JKRAram.h"
|
||||
|
||||
JSUList<JKRAMCommand> JKRAramPiece::sAramPieceCommandList;
|
||||
OSMutex JKRAramPiece::mMutex;
|
||||
|
||||
JKRAMCommand* JKRAramPiece::prepareCommand(int direction, u32 source, u32 destination, u32 length, JKRAramBlock* aramBlock, JKRAMCommand::AMCommandCallback callback) {
|
||||
JKRAMCommand* cmd = new (JKRGetSystemHeap(), -4) JKRAMCommand();
|
||||
cmd->mDirection = direction;
|
||||
cmd->mSource = source;
|
||||
cmd->mDestination = destination;
|
||||
cmd->mAramBlock = aramBlock;
|
||||
cmd->mLength = length;
|
||||
cmd->mCallback = callback;
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
void JKRAramPiece::sendCommand(JKRAMCommand* cmd) {
|
||||
JKRAramPiece::startDMA(cmd);
|
||||
}
|
||||
|
||||
JKRAMCommand* JKRAramPiece::orderAsync(int direction, u32 source, u32 destination, u32 length, JKRAramBlock* aramBlock, JKRAMCommand::AMCommandCallback callback) {
|
||||
JKRAramPiece::lock();
|
||||
|
||||
if (!JKR_ISALIGNED32(source) || !JKR_ISALIGNED32(destination)) {
|
||||
JLOGF("direction = %x\n", direction);
|
||||
JLOGF("source = %x\n", source);
|
||||
JLOGF("destination = %x\n", destination);
|
||||
JLOGF("length = %x\n", length);
|
||||
JPANICLINE(102);
|
||||
}
|
||||
|
||||
JKRAramCommand* aramCmd = new (JKRGetSystemHeap(), -4) JKRAramCommand();
|
||||
JKRAMCommand* cmd = JKRAramPiece::prepareCommand(direction, source, destination, length, aramBlock, callback);
|
||||
aramCmd->setting(TRUE, cmd);
|
||||
OSSendMessage((OSMessageQueue*)&JKRAram::sMessageQueue, (OSMessage)aramCmd, OS_MESSAGE_BLOCK);
|
||||
if (cmd->mCallback != nullptr) {
|
||||
JKRAramPiece::sAramPieceCommandList.append(&cmd->mAramPieceCommandLink);
|
||||
}
|
||||
|
||||
JKRAramPiece::unlock();
|
||||
return cmd;
|
||||
}
|
||||
|
||||
bool JKRAramPiece::sync(JKRAMCommand* cmd, BOOL noBlock) {
|
||||
OSMessage msg[1];
|
||||
|
||||
JKRAramPiece::lock();
|
||||
|
||||
if (!noBlock) {
|
||||
OSReceiveMessage(&cmd->mMesgQueue, msg, OS_MESSAGE_BLOCK);
|
||||
JKRAramPiece::sAramPieceCommandList.remove(&cmd->mAramPieceCommandLink);
|
||||
JKRAramPiece::unlock();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
if (!OSReceiveMessage(&cmd->mMesgQueue, msg, OS_MESSAGE_NOBLOCK)) {
|
||||
JKRAramPiece::unlock();
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
JKRAramPiece::sAramPieceCommandList.remove(&cmd->mAramPieceCommandLink);
|
||||
JKRAramPiece::unlock();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool JKRAramPiece::orderSync(int direction, u32 source, u32 destination, u32 length, JKRAramBlock* aramBlock) {
|
||||
JKRAramPiece::lock();
|
||||
|
||||
JKRAMCommand* cmd = JKRAramPiece::orderAsync(direction, source, destination, length, aramBlock, nullptr);
|
||||
bool res = JKRAramPiece::sync(cmd, FALSE);
|
||||
delete cmd;
|
||||
|
||||
JKRAramPiece::unlock();
|
||||
return res;
|
||||
}
|
||||
|
||||
void JKRAramPiece::startDMA(JKRAMCommand* cmd) {
|
||||
if (cmd->mDirection == ARAM_DIR_ARAM_TO_MRAM) {
|
||||
DCInvalidateRange((u8*)cmd->mDestination, cmd->mLength);
|
||||
}
|
||||
else { /* cmd->mDirection == ARAM_DIR_MRAM_TO_ARAM */
|
||||
DCStoreRange((u8*)cmd->mSource, cmd->mLength);
|
||||
}
|
||||
|
||||
ARQPostRequest(cmd, 0, cmd->mDirection, 0, cmd->mSource, cmd->mDestination, cmd->mLength, JKRAramPiece::doneDMA);
|
||||
}
|
||||
|
||||
void JKRAramPiece::doneDMA(u32 param) {
|
||||
JKRAMCommand* cmd = (JKRAMCommand*)param;
|
||||
if (cmd->mDirection == ARAM_DIR_ARAM_TO_MRAM) {
|
||||
DCInvalidateRange((u8*)cmd->mDestination, cmd->mLength);
|
||||
}
|
||||
if (cmd->mCallbackType != ARAMPIECE_DONE_CALLBACK) {
|
||||
if (cmd->mCallbackType == ARAMPIECE_DONE_DECOMPRESS) {
|
||||
JKRDecomp::sendCommand(cmd->mDecompCommand);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (cmd->mCallback != nullptr) {
|
||||
(*cmd->mCallback)(param);
|
||||
}
|
||||
else {
|
||||
if (cmd->mCompletedMesgQueue != nullptr) {
|
||||
OSSendMessage(cmd->mCompletedMesgQueue, (OSMessage)cmd, OS_MESSAGE_NOBLOCK);
|
||||
}
|
||||
else {
|
||||
OSSendMessage(&cmd->mMesgQueue, (OSMessage)cmd, OS_MESSAGE_NOBLOCK);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JKRAMCommand::JKRAMCommand() : mAramPieceCommandLink(this), mLink30(this) {
|
||||
OSInitMessageQueue(&this->mMesgQueue, this->mMesgBuffer, 1);
|
||||
this->mCallback = nullptr;
|
||||
this->mCompletedMesgQueue = nullptr;
|
||||
this->mCallbackType = ARAMPIECE_DONE_CALLBACK;
|
||||
this->_8C = nullptr;
|
||||
this->_90 = nullptr;
|
||||
this->_94 = nullptr;
|
||||
}
|
||||
|
||||
JKRAMCommand::~JKRAMCommand() {
|
||||
if (this->_8C != nullptr) {
|
||||
delete this->_8C;
|
||||
}
|
||||
|
||||
if (this->_90 != nullptr) {
|
||||
delete this->_90;
|
||||
}
|
||||
|
||||
if (this->_94 != nullptr) {
|
||||
JKRFree(this->_94);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
#include "JKRAram.h"
|
||||
#include "JSUStream.h"
|
||||
|
||||
|
||||
@@ -0,0 +1,295 @@
|
||||
#include "types.h"
|
||||
#include "dolphin/os/OSMessage.h"
|
||||
#include "JSystem/JSystem.h"
|
||||
#include "JSystem/JKernel/JKRHeap.h"
|
||||
#include "JSystem/JKernel/JKRAram.h"
|
||||
|
||||
#include "JSystem/JKernel/JKRDecomp.h"
|
||||
|
||||
OSMessage JKRDecomp::sMessageBuffer[JKRDECOMP_MSG_BUF_COUNT] = { 0 };
|
||||
OSMessageQueue JKRDecomp::sMessageQueue = { 0 };
|
||||
JKRDecomp* JKRDecomp::sDecompObject;
|
||||
|
||||
JKRDecomp* JKRDecomp::create(s32 decompPriority) {
|
||||
if (JKRDecomp::sDecompObject == nullptr) {
|
||||
JKRDecomp::sDecompObject = new(JKRGetSystemHeap(), 0) JKRDecomp(decompPriority);
|
||||
}
|
||||
|
||||
return JKRDecomp::sDecompObject;
|
||||
}
|
||||
|
||||
JKRDecomp::JKRDecomp(s32 priority) : JKRThread(JKRDECOMP_STACK_SIZE, JKRDECOMP_THREAD_MSG_BUF_COUNT, priority) {
|
||||
OSResumeThread(this->mThreadRecord);
|
||||
}
|
||||
|
||||
JKRDecomp::~JKRDecomp() { }
|
||||
|
||||
void* JKRDecomp::run() {
|
||||
OSMessage recMesg;
|
||||
JKRDecompCommand* cmd;
|
||||
OSInitMessageQueue(&JKRDecomp::sMessageQueue, JKRDecomp::sMessageBuffer, JKRDECOMP_MSG_BUF_COUNT);
|
||||
|
||||
while (true) {
|
||||
while (true) {
|
||||
while (true) {
|
||||
OSReceiveMessage(&JKRDecomp::sMessageQueue, &recMesg, OS_MESSAGE_BLOCK);
|
||||
cmd = static_cast<JKRDecompCommand*>(recMesg);
|
||||
JKRDecomp::decode(cmd->mSrcBuffer, cmd->mDstBuffer, cmd->mSrcLength, cmd->mSkipCount);
|
||||
|
||||
if (cmd->transferType == JKRDecompCommand::MRAM) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (cmd->transferType == JKRDecompCommand::ARAM) {
|
||||
JKRAramPcs_SendCommand(cmd->mAMCommand);
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd->mCallback == nullptr) {
|
||||
break;
|
||||
}
|
||||
|
||||
cmd->mCallback((u32)cmd);
|
||||
}
|
||||
|
||||
if (cmd->pMesgQueue1C != nullptr) {
|
||||
OSSendMessage(cmd->pMesgQueue1C, (OSMessage)1, OS_MESSAGE_NOBLOCK);
|
||||
}
|
||||
else {
|
||||
OSSendMessage(&cmd->mMesgQueue, (OSMessage)1, OS_MESSAGE_NOBLOCK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JKRDecompCommand* JKRDecomp::prepareCommand(u8* srcBuffer, u8* dstBuffer, u32 srcLength, u32 skipCount, DecompCallback* callback) {
|
||||
JKRDecompCommand* cmd = new(JKRGetSystemHeap(), -4) JKRDecompCommand();
|
||||
|
||||
cmd->mSrcBuffer = srcBuffer;
|
||||
cmd->mDstBuffer = dstBuffer;
|
||||
cmd->mSrcLength = srcLength;
|
||||
cmd->mSkipCount = skipCount;
|
||||
cmd->mCallback = callback;
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
BOOL JKRDecomp::sendCommand(JKRDecompCommand* cmd) {
|
||||
BOOL res = OSSendMessage(&JKRDecomp::sMessageQueue, (OSMessage)cmd, OS_MESSAGE_BLOCK);
|
||||
|
||||
#ifdef JSYSTEM_DEBUG
|
||||
if (res == FALSE) {
|
||||
JPANIC(142, "Decomp MesgBuf FULL!");
|
||||
}
|
||||
#endif
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
JKRDecompCommand* JKRDecomp::orderAsync(u8* srcBuffer, u8* dstBuffer, u32 srcLength, u32 skipCount, DecompCallback* callback) {
|
||||
JKRDecompCommand* cmd = JKRDecomp::prepareCommand(srcBuffer, dstBuffer, srcLength, skipCount, callback);
|
||||
JKRDecomp::sendCommand(cmd);
|
||||
return cmd;
|
||||
}
|
||||
|
||||
bool JKRDecomp::sync(JKRDecompCommand* cmd, BOOL noBlock) {
|
||||
OSMessage msg;
|
||||
|
||||
if (!noBlock) {
|
||||
OSReceiveMessage(&cmd->mMesgQueue, &msg, OS_MESSAGE_BLOCK);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return OSReceiveMessage(&cmd->mMesgQueue, &msg, OS_MESSAGE_NOBLOCK) != FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
bool JKRDecomp::orderSync(u8* srcBuffer, u8* dstBuffer, u32 srcLength, u32 skipCount) {
|
||||
JKRDecompCommand* cmd = JKRDecomp::orderAsync(srcBuffer, dstBuffer, srcLength, skipCount, nullptr);
|
||||
bool res = JKRDecomp::sync(cmd, FALSE);
|
||||
delete cmd;
|
||||
return res;
|
||||
}
|
||||
|
||||
void JKRDecomp::decode(u8* srcBuffer, u8* dstBuffer, u32 srcLength, u32 skipCount) {
|
||||
CompressionMode mode = JKRDecomp::checkCompressed(srcBuffer);
|
||||
if (mode == SZP) {
|
||||
JKRDecomp::decodeSZP(srcBuffer, dstBuffer, srcLength, skipCount);
|
||||
}
|
||||
else if (mode == SZS) {
|
||||
JKRDecomp::decodeSZS(srcBuffer, dstBuffer, srcLength, skipCount);
|
||||
}
|
||||
}
|
||||
|
||||
void JKRDecomp::decodeSZP(u8 *src, u8 *dst, u32 srcLength, u32 skipCount)
|
||||
{
|
||||
int srcChunkOffset;
|
||||
int count;
|
||||
int dstOffset;
|
||||
u32 length;
|
||||
int linkInfo;
|
||||
int offset;
|
||||
int i;
|
||||
|
||||
int decodedSize = JKRDECOMP_READU32BE(src, 4);
|
||||
int linkTableOffset = JKRDECOMP_READU32BE(src, 8);
|
||||
int srcDataOffset = JKRDECOMP_READU32BE(src, 12);
|
||||
|
||||
dstOffset = 0;
|
||||
u32 counter = 0; // curently counter gets assembled before the READ_U32 operations
|
||||
srcChunkOffset = 16;
|
||||
|
||||
u32 chunkBits;
|
||||
if (srcLength == 0)
|
||||
return;
|
||||
if (skipCount > decodedSize)
|
||||
return;
|
||||
|
||||
length = srcLength;
|
||||
do
|
||||
{
|
||||
if (counter == 0)
|
||||
{
|
||||
chunkBits = JKRDECOMP_READU32BE(src, srcChunkOffset);
|
||||
srcChunkOffset += sizeof(u32);
|
||||
counter = sizeof(u32) * 8;
|
||||
}
|
||||
|
||||
if (chunkBits & 0x80000000)
|
||||
{
|
||||
if (skipCount == 0)
|
||||
{
|
||||
dst[dstOffset] = src[srcDataOffset];
|
||||
length--;
|
||||
if (length == 0)
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
skipCount--;
|
||||
}
|
||||
dstOffset++;
|
||||
srcDataOffset++;
|
||||
}
|
||||
else
|
||||
{
|
||||
linkInfo = src[linkTableOffset] << 8 | src[linkTableOffset + 1];
|
||||
linkTableOffset += sizeof(u16);
|
||||
|
||||
offset = dstOffset - (linkInfo & 0xFFF);
|
||||
count = (linkInfo >> 12);
|
||||
if (count == 0)
|
||||
{
|
||||
count = (u32)src[srcDataOffset++] + 0x12;
|
||||
}
|
||||
else
|
||||
count += 2;
|
||||
|
||||
if ((int)count > decodedSize - dstOffset)
|
||||
count = decodedSize - dstOffset;
|
||||
|
||||
for (i = 0; i < (int)count; i++, dstOffset++, offset++)
|
||||
{
|
||||
if (skipCount == 0)
|
||||
{
|
||||
dst[dstOffset] = dst[offset - 1];
|
||||
length--;
|
||||
if (length == 0)
|
||||
return;
|
||||
}
|
||||
else
|
||||
skipCount--;
|
||||
}
|
||||
}
|
||||
|
||||
chunkBits <<= 1;
|
||||
counter--;
|
||||
} while (dstOffset < decodedSize);
|
||||
}
|
||||
|
||||
void JKRDecomp::decodeSZS(u8 *src_buffer, u8 *dst_buffer, u32 srcSize, u32 skipCount) {
|
||||
|
||||
u8 *decompEnd = dst_buffer + *(u32 *)(src_buffer + 4) - skipCount;
|
||||
u8 *copyStart;
|
||||
s32 copyByteCount;
|
||||
s32 chunkBitsLeft = 0;
|
||||
s32 chunkBits;
|
||||
|
||||
if (srcSize == 0)
|
||||
return;
|
||||
if (skipCount > *(u32 *)src_buffer)
|
||||
return;
|
||||
|
||||
u8 *curSrcPos = src_buffer + 0x10;
|
||||
do {
|
||||
if (chunkBitsLeft == 0) {
|
||||
chunkBits = *curSrcPos++;
|
||||
chunkBitsLeft = 8;
|
||||
}
|
||||
if ((chunkBits & 0x80) != 0) {
|
||||
if (skipCount == 0)
|
||||
{
|
||||
*dst_buffer = *curSrcPos;
|
||||
srcSize--;
|
||||
dst_buffer++;
|
||||
if (srcSize == 0)
|
||||
return;
|
||||
}
|
||||
else {
|
||||
skipCount--;
|
||||
}
|
||||
curSrcPos++;
|
||||
}
|
||||
else {
|
||||
u8 curVal = *curSrcPos;
|
||||
copyStart = dst_buffer - (curSrcPos[1] | (curVal & 0xF) << 8);
|
||||
curSrcPos += 2;
|
||||
if (curVal >> 4 == 0) {
|
||||
copyByteCount = *curSrcPos + 0x12;
|
||||
curSrcPos++;
|
||||
}
|
||||
else {
|
||||
copyByteCount = (curVal >> 4) + 2;
|
||||
}
|
||||
do {
|
||||
if (skipCount == 0) {
|
||||
*dst_buffer = *(copyStart - 1);
|
||||
srcSize--;
|
||||
dst_buffer++;
|
||||
if (srcSize == 0)
|
||||
return;
|
||||
}
|
||||
else {
|
||||
skipCount--;
|
||||
}
|
||||
copyByteCount--;
|
||||
copyStart++;
|
||||
} while (copyByteCount != 0);
|
||||
}
|
||||
chunkBits <<= 1;
|
||||
chunkBitsLeft--;
|
||||
} while (dst_buffer != decompEnd);
|
||||
}
|
||||
|
||||
JKRDecomp::CompressionMode JKRDecomp::checkCompressed(u8* buf) {
|
||||
if (buf[0] == 'Y' && buf[1] == 'a' && buf[3] == '0') {
|
||||
if (buf[2] == 'y') {
|
||||
return SZP;
|
||||
}
|
||||
|
||||
if (buf[2] == 'z') {
|
||||
return SZS;
|
||||
}
|
||||
}
|
||||
|
||||
return NONE;
|
||||
}
|
||||
|
||||
JKRDecompCommand::JKRDecompCommand() {
|
||||
OSInitMessageQueue(&this->mMesgQueue, this->mMesgBuffer, 1);
|
||||
this->mCallback = nullptr;
|
||||
this->pMesgQueue1C = nullptr;
|
||||
this->mCmd = this;
|
||||
this->transferType = MRAM;
|
||||
}
|
||||
|
||||
JKRDecompCommand::~JKRDecompCommand() { }
|
||||
@@ -0,0 +1,114 @@
|
||||
#include "JSystem/JKernel/JKRDvdFile.h"
|
||||
|
||||
JSUList<JKRDvdFile> JKRDvdFile::sDvdList;
|
||||
|
||||
JKRDvdFile::JKRDvdFile() : JKRFile(), mLink(this) { this->initiate(); }
|
||||
|
||||
/* This method is confirmed to exist, but goes unused in AC. Retrieved from TP debug. */
|
||||
JKRDvdFile::JKRDvdFile(const char* filename) : JKRFile(), mLink(this) {
|
||||
this->initiate();
|
||||
this->mFileOpen = this->open(filename);
|
||||
|
||||
if (this->isAvailable()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
JKRDvdFile::JKRDvdFile(s32 entrynum) : JKRFile(), mLink(this) {
|
||||
this->initiate();
|
||||
this->mFileOpen = this->open(entrynum);
|
||||
|
||||
if (this->isAvailable()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
JKRDvdFile::~JKRDvdFile() { this->close(); }
|
||||
|
||||
void JKRDvdFile::initiate() {
|
||||
/* Reference to self. Used to retrieve reference in the DVDReadAsync
|
||||
* DVDCallback func. */
|
||||
this->mDvdFileInfo.mFile = this;
|
||||
OSInitMutex(&this->mMutex1);
|
||||
OSInitMutex(&this->mMutex2);
|
||||
OSInitMessageQueue(&this->mMessageQueue2, &this->mMsg2, 1);
|
||||
OSInitMessageQueue(&this->mMessageQueue1, &this->mMsg1, 1);
|
||||
this->mThread2 = nullptr;
|
||||
this->mThread1 = nullptr;
|
||||
this->_58 = 0;
|
||||
}
|
||||
|
||||
/* This method is confirmed to exist, but goes unused in AC. Retrieved from TP debug. */
|
||||
bool JKRDvdFile::open(const char* filename) {
|
||||
if (this->mFileOpen == false) {
|
||||
this->mFileOpen = DVDOpen((char*)filename, &this->mDvdFileInfo);
|
||||
if (this->mFileOpen) {
|
||||
sDvdList.append(&this->mLink);
|
||||
DVDGetFileInfoStatus(&this->mDvdFileInfo);
|
||||
}
|
||||
}
|
||||
|
||||
return this->mFileOpen;
|
||||
}
|
||||
|
||||
bool JKRDvdFile::open(s32 entrynum) {
|
||||
if (this->mFileOpen == false) {
|
||||
this->mFileOpen = DVDFastOpen(entrynum, &this->mDvdFileInfo);
|
||||
if (this->mFileOpen) {
|
||||
sDvdList.append(&this->mLink);
|
||||
DVDGetFileInfoStatus(&this->mDvdFileInfo);
|
||||
}
|
||||
}
|
||||
|
||||
return this->mFileOpen;
|
||||
}
|
||||
|
||||
bool JKRDvdFile::close() {
|
||||
if (this->mFileOpen) {
|
||||
if (DVDClose(&this->mDvdFileInfo)) {
|
||||
this->mFileOpen = false;
|
||||
return sDvdList.remove(&this->mLink);
|
||||
} else {
|
||||
OSErrorLine(212, "cannot close DVD file\n"); /* JKRDvdFile.cpp line 212 */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int JKRDvdFile::readData(void* data, s32 length, s32 ofs) {
|
||||
OSLockMutex(&this->mMutex1);
|
||||
s32 retAddr;
|
||||
|
||||
if (this->mThread2 != nullptr) {
|
||||
OSUnlockMutex(&this->mMutex1);
|
||||
return -1;
|
||||
} else {
|
||||
this->mThread2 = OSGetCurrentThread();
|
||||
retAddr = -1;
|
||||
if (DVDReadAsync(&this->mDvdFileInfo, data, length, ofs,
|
||||
JKRDvdFile::doneProcess)) {
|
||||
retAddr = this->sync();
|
||||
}
|
||||
|
||||
this->mThread2 = nullptr;
|
||||
OSUnlockMutex(&this->mMutex1);
|
||||
}
|
||||
|
||||
return retAddr;
|
||||
}
|
||||
|
||||
int JKRDvdFile::writeData(const void* data, s32 length, s32 ofs) { return -1; }
|
||||
|
||||
s32 JKRDvdFile::sync() {
|
||||
OSMessage m;
|
||||
|
||||
OSLockMutex(&this->mMutex1);
|
||||
OSReceiveMessage(&this->mMessageQueue2, &m, OS_MESSAGE_BLOCK);
|
||||
this->mThread2 = nullptr;
|
||||
OSUnlockMutex(&this->mMutex1);
|
||||
return (s32)m;
|
||||
}
|
||||
|
||||
void JKRDvdFile::doneProcess(s32 result, DVDFileInfo* info) {
|
||||
OSSendMessage(&static_cast<JKRDvdFileInfo*>(info)->mFile->mMessageQueue2,
|
||||
(OSMessage)result, OS_MESSAGE_NOBLOCK);
|
||||
}
|
||||
@@ -0,0 +1,466 @@
|
||||
#include <string.h>
|
||||
#include "types.h"
|
||||
#include "dolphin/vi.h"
|
||||
#include "JSystem/JSystem.h"
|
||||
#include "JSystem/JKernel/JKRMacro.h"
|
||||
#include "JSystem/JKernel/JKRDvdFile.h"
|
||||
#include "JSystem/JKernel/JKRDecomp.h"
|
||||
|
||||
#include "JSystem/JKernel/JKRDvdRipper.h"
|
||||
|
||||
JSUList<JKRDMCommand> JKRDvdRipper::sDvdAsyncList;
|
||||
bool JKRDvdRipper::errorRetry = true;
|
||||
|
||||
static int decompSZS_subroutine(u8* src, u8* dest);
|
||||
static u8* firstSrcData();
|
||||
static u8* nextSrcData(u8* nowData);
|
||||
|
||||
void* JKRDvdRipper::loadToMainRAM(const char* file, u8* buf, JKRExpandSwitch expandSwitch, u32 maxDest, JKRHeap* heap, EAllocDirection allocDir, u32 offset, int* compressMode) {
|
||||
JKRDvdFile dvdFile;
|
||||
|
||||
if (!dvdFile.open(file)) {
|
||||
return nullptr;
|
||||
}
|
||||
else {
|
||||
return JKRDvdRipper::loadToMainRAM(&dvdFile, buf, expandSwitch, maxDest, heap, allocDir, offset, compressMode);
|
||||
}
|
||||
}
|
||||
|
||||
void* JKRDvdRipper::loadToMainRAM(s32 entrynum, u8* buf, JKRExpandSwitch expandSwitch, u32 maxDest, JKRHeap* heap, EAllocDirection allocDir, u32 offset, int* compressMode) {
|
||||
JKRDvdFile dvdFile;
|
||||
|
||||
if (!dvdFile.open(entrynum)) {
|
||||
return nullptr;
|
||||
}
|
||||
else {
|
||||
return JKRDvdRipper::loadToMainRAM(&dvdFile, buf, expandSwitch, maxDest, heap, allocDir, offset, compressMode);
|
||||
}
|
||||
}
|
||||
|
||||
void* JKRDvdRipper::loadToMainRAM(JKRDvdFile* file, u8* buf, JKRExpandSwitch expandSwitch, u32 maxDest, JKRHeap* heap, EAllocDirection allocDir, u32 offset, int* compressMode) {
|
||||
u32 finalSize;
|
||||
|
||||
bool allocated = false;
|
||||
JKRDecomp::CompressionMode fileCompressMode = JKRDecomp::NONE;
|
||||
u8* mem = nullptr;
|
||||
u32 fileSize = ALIGN_NEXT(file->getFileSize(), 32);
|
||||
|
||||
if (expandSwitch == EXPAND_SWITCH_DECOMPRESS) {
|
||||
u8 buffer[64];
|
||||
u8* aligned_buf = (u8*)ALIGN_NEXT((u32)buffer, 32);
|
||||
while (true) {
|
||||
if (DVDReadPrio(file->getFileInfo(), aligned_buf, 32, 0, 2) >= 0) {
|
||||
break;
|
||||
}
|
||||
if (JKRDvdRipper::errorRetry == false) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
VIWaitForRetrace();
|
||||
}
|
||||
|
||||
fileCompressMode = JKRCheckCompressed(aligned_buf);
|
||||
finalSize = JKRDecompExpandSize(aligned_buf);
|
||||
}
|
||||
|
||||
if (compressMode != nullptr) {
|
||||
*compressMode = fileCompressMode;
|
||||
}
|
||||
|
||||
if (expandSwitch == EXPAND_SWITCH_DECOMPRESS && fileCompressMode != JKRDecomp::NONE) {
|
||||
if (maxDest != 0 && finalSize > maxDest) {
|
||||
finalSize = maxDest;
|
||||
}
|
||||
|
||||
if (buf == nullptr) {
|
||||
buf = (u8*)JKRAllocFromHeap(heap, finalSize, allocDir == ALLOC_DIR_TOP ? 32 : -32);
|
||||
allocated = true;
|
||||
}
|
||||
|
||||
if (buf == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (fileCompressMode == JKRDecomp::SZP) {
|
||||
mem = (u8*)JKRAllocFromHeap(heap, fileSize, 32);
|
||||
if (mem == nullptr && allocated == true) {
|
||||
JKRFree(buf);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (buf == nullptr) {
|
||||
buf = (u8*)JKRAllocFromHeap(heap, fileSize - offset, allocDir == ALLOC_DIR_TOP ? 32 : -32);
|
||||
allocated = true;
|
||||
}
|
||||
|
||||
if (buf == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (fileCompressMode == JKRDecomp::NONE) {
|
||||
JKRDecomp::CompressionMode subCompressMode = JKRDecomp::NONE;
|
||||
|
||||
if (offset != 0) {
|
||||
u8 buffer[64];
|
||||
u8* aligned_buf = (u8*)ALIGN_NEXT((u32)buffer, 32);
|
||||
while (true) {
|
||||
if (DVDReadPrio(file->getFileInfo(), aligned_buf, 32, offset, 2) >= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (JKRDvdRipper::errorRetry == false) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
VIWaitForRetrace();
|
||||
}
|
||||
|
||||
subCompressMode = JKRCheckCompressed(aligned_buf);
|
||||
}
|
||||
|
||||
if (subCompressMode == JKRDecomp::NONE || expandSwitch == EXPAND_SWITCH_NONE || expandSwitch == EXPAND_SWITCH_DEFAULT) {
|
||||
s32 readSize = fileSize - offset;
|
||||
if (maxDest != 0 && maxDest < readSize) {
|
||||
readSize = maxDest;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
if (DVDReadPrio(file->getFileInfo(), buf, readSize, offset, 2) >= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (JKRDvdRipper::errorRetry == false) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
VIWaitForRetrace();
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
if (subCompressMode == JKRDecomp::SZS) {
|
||||
JKRDecompressFromDVD(file, buf, fileSize, maxDest, 0, offset);
|
||||
}
|
||||
else {
|
||||
JPANIC(297, "Sorry, not prepared for SZP resource\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (fileCompressMode == JKRDecomp::SZP) {
|
||||
if (offset != 0) {
|
||||
JPANIC(306, ":::Not support SZP with offset read");
|
||||
}
|
||||
|
||||
/* Looks like a bug here */
|
||||
#ifndef FIXES
|
||||
if (DVDReadPrio(file->getFileInfo(), mem, fileSize, 0, 2) < 0) {
|
||||
if (JKRDvdRipper::errorRetry == false) {
|
||||
VIWaitForRetrace();
|
||||
}
|
||||
|
||||
JKRFree(mem);
|
||||
return nullptr;
|
||||
}
|
||||
else {
|
||||
JKRDecompress(mem, buf, finalSize, offset);
|
||||
JKRFree(mem);
|
||||
return buf;
|
||||
}
|
||||
#else
|
||||
while (DVDReadPrio(file->getFileInfo(), mem, fileSize, 0, 2) < 0) {
|
||||
if (JKRDvdRipper::errorRetry == false) {
|
||||
if (allocated) {
|
||||
JKRFree(buf);
|
||||
}
|
||||
|
||||
JKRFree(mem);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
VIWaitForRetrace();
|
||||
}
|
||||
|
||||
JKRDecompress(mem, buf, finalSize, 0);
|
||||
JKRFree(mem);
|
||||
#endif
|
||||
}
|
||||
else if (fileCompressMode == JKRDecomp::SZS) {
|
||||
JKRDecompressFromDVD(file, buf, fileSize, finalSize, offset, 0);
|
||||
return buf;
|
||||
}
|
||||
else {
|
||||
if (allocated) {
|
||||
JKRFree(buf);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static u8* szpBuf;
|
||||
static u8* szpEnd;
|
||||
static u8* refBuf;
|
||||
static u8* refEnd;
|
||||
static u8* refCurrent;
|
||||
|
||||
static u32 srcOffset;
|
||||
static u32 transLeft;
|
||||
static u8* srcLimit;
|
||||
static JKRDvdFile* srcFile;
|
||||
static u32 fileOffset;
|
||||
static u32 readCount;
|
||||
static u32 maxDest;
|
||||
|
||||
static int JKRDecompressFromDVD(JKRDvdFile* _srcFile, void* buf, u32 size, u32 _maxDest, u32 _fileOffset, u32 _srcOffset) {
|
||||
int res = 0;
|
||||
|
||||
szpBuf = (u8*)JKRAllocFromSysHeap(SZP_BUFFERSIZE, -32);
|
||||
szpEnd = szpBuf + SZP_BUFFERSIZE;
|
||||
|
||||
if (_fileOffset != 0) {
|
||||
refBuf = (u8*)JKRAllocFromSysHeap(REF_BUFFERSIZE, -4);
|
||||
refEnd = refBuf + REF_BUFFERSIZE;
|
||||
refCurrent = refBuf;
|
||||
}
|
||||
else {
|
||||
refBuf = nullptr;
|
||||
}
|
||||
|
||||
srcFile = _srcFile;
|
||||
srcOffset = _srcOffset;
|
||||
transLeft = size - _srcOffset;
|
||||
fileOffset = _fileOffset;
|
||||
readCount = 0;
|
||||
maxDest = _maxDest;
|
||||
|
||||
u8* src = firstSrcData();
|
||||
if (src != nullptr) {
|
||||
res = decompSZS_subroutine(src, (u8*)buf);
|
||||
}
|
||||
|
||||
JKRFree(szpBuf);
|
||||
|
||||
if (refBuf != nullptr) {
|
||||
JKRFree(refBuf);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int decompSZS_subroutine(u8* src, u8* dest) {
|
||||
u8 *endPtr;
|
||||
s32 validBitCount = 0;
|
||||
s32 currCodeByte = 0;
|
||||
u32 ts = 0;
|
||||
|
||||
if ((s32)src[0] != 'Y' || (s32)src[1] != 'a' || (s32)src[2] != 'z' || (s32)src[3] != '0')
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
SZPHeader *header = (SZPHeader *)src;
|
||||
endPtr = dest + (header->decompSize - fileOffset);
|
||||
if (endPtr > dest + maxDest)
|
||||
{
|
||||
endPtr = dest + maxDest;
|
||||
}
|
||||
|
||||
src += 0x10;
|
||||
do
|
||||
{
|
||||
if (validBitCount == 0)
|
||||
{
|
||||
if ((src > srcLimit) && transLeft)
|
||||
{
|
||||
src = nextSrcData(src);
|
||||
if (!src)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
currCodeByte = *src;
|
||||
validBitCount = 8;
|
||||
src++;
|
||||
}
|
||||
if (currCodeByte & 0x80)
|
||||
{
|
||||
if (fileOffset != 0)
|
||||
{
|
||||
if (readCount >= fileOffset)
|
||||
{
|
||||
*dest = *src;
|
||||
dest++;
|
||||
ts++;
|
||||
if (dest == endPtr)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
*(refCurrent++) = *src;
|
||||
if (refCurrent == refEnd)
|
||||
{
|
||||
refCurrent = refBuf;
|
||||
}
|
||||
src++;
|
||||
}
|
||||
else
|
||||
{
|
||||
*dest = *src;
|
||||
dest++;
|
||||
src++;
|
||||
ts++;
|
||||
if (dest == endPtr)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
readCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
u32 dist = src[1] | (src[0] & 0x0f) << 8;
|
||||
s32 numBytes = src[0] >> 4;
|
||||
src += 2;
|
||||
u8 *copySource;
|
||||
if (fileOffset != 0)
|
||||
{
|
||||
copySource = refCurrent - dist - 1;
|
||||
if (copySource < refBuf)
|
||||
{
|
||||
copySource += refEnd - refBuf;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
copySource = dest - dist - 1;
|
||||
}
|
||||
if (numBytes == 0)
|
||||
{
|
||||
numBytes = *src + 0x12;
|
||||
src += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
numBytes += 2;
|
||||
}
|
||||
if (fileOffset != 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (readCount >= fileOffset)
|
||||
{
|
||||
*dest = *copySource;
|
||||
dest++;
|
||||
ts++;
|
||||
if (dest == endPtr)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
*(refCurrent++) = *copySource;
|
||||
if (refCurrent == refEnd)
|
||||
{
|
||||
refCurrent = refBuf;
|
||||
}
|
||||
copySource++;
|
||||
if (copySource == refEnd)
|
||||
{
|
||||
copySource = refBuf;
|
||||
}
|
||||
readCount++;
|
||||
numBytes--;
|
||||
} while (numBytes != 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
*dest = *copySource;
|
||||
dest++;
|
||||
ts++;
|
||||
if (dest == endPtr)
|
||||
{
|
||||
break;
|
||||
}
|
||||
readCount++;
|
||||
numBytes--;
|
||||
copySource++;
|
||||
} while (numBytes != 0);
|
||||
}
|
||||
}
|
||||
currCodeByte <<= 1;
|
||||
validBitCount--;
|
||||
} while (dest < endPtr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u8* firstSrcData() {
|
||||
srcLimit = szpEnd - 0x19;
|
||||
u8* buf = szpBuf;
|
||||
u32 size = (szpEnd - szpBuf);
|
||||
u32 transSize = MIN(transLeft, size);
|
||||
|
||||
while (true) {
|
||||
if (DVDReadPrio(srcFile->getFileInfo(), buf, transSize, srcOffset, 2) < 0) {
|
||||
if (JKRDvdRipper::errorRetry == false) {
|
||||
return nullptr;
|
||||
}
|
||||
VIWaitForRetrace();
|
||||
}
|
||||
else {
|
||||
srcOffset += transSize;
|
||||
transLeft -= transSize;
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static u8* nextSrcData(u8* nowData) {
|
||||
u32 size = (szpEnd - nowData);
|
||||
u8* dst;
|
||||
if (JKR_ISNOTALIGNED32(size)) {
|
||||
dst = szpBuf + 32 - (size & 31);
|
||||
}
|
||||
else {
|
||||
dst = szpBuf;
|
||||
}
|
||||
|
||||
memcpy(dst, nowData, size);
|
||||
|
||||
u32 n_size = (szpEnd - (dst + size));
|
||||
if (n_size > transLeft) {
|
||||
n_size = transLeft;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
if (DVDReadPrio(srcFile->getFileInfo(), (dst + size), n_size, srcOffset, 2) >= 0) {
|
||||
break;
|
||||
}
|
||||
// Oopsies, forgot to call the function
|
||||
#ifndef FIXES
|
||||
if (JKRDvdRipper::isErrorRetry == false) {
|
||||
return nullptr;
|
||||
}
|
||||
#else
|
||||
if (JKRDvdRipper::isErrorRetry() == false) {
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
VIWaitForRetrace();
|
||||
}
|
||||
|
||||
srcOffset += n_size;
|
||||
transLeft -= n_size;
|
||||
|
||||
if (transLeft == 0) {
|
||||
srcLimit = (dst + size) + n_size;
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
#include "JSystem/JKernel/JKRFile.h"
|
||||
#include "dolphin/vi.h"
|
||||
|
||||
#ifdef JSYSTEM_DEBUG
|
||||
#include "JSystem/JUtility/JUTAssertion.h"
|
||||
#endif
|
||||
|
||||
/* Empty space for aligning line numbers */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Nonmatched function. Unused in Animal Crossing.
|
||||
*/
|
||||
void JKRFile::read(void* data, s32 length, s32 ofs) {
|
||||
#ifdef JSYSTEM_DEBUG
|
||||
if (!JKR_ISALIGNED(length, 32)) {
|
||||
JUTAssertion::showAssert(JUTAssertion::getSDevice(), __FILE__, __LINE__, "( length & 0x1f ) == 0");
|
||||
}
|
||||
#endif
|
||||
|
||||
while (true) {
|
||||
if (this->readData(data, length, ofs) == length) {
|
||||
return;
|
||||
}
|
||||
|
||||
VIWaitForRetrace();
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "JSystem/JUT/JUTAssertion.h"
|
||||
#include "JSystem/JUtility/JUTAssertion.h"
|
||||
#include "JSystem/JKernel/JKRHeap.h"
|
||||
#include "dolphin/os.h"
|
||||
#include "dolphin/os/OSArena.h"
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
#include "JSystem/JKernel/JKRThread.h"
|
||||
|
||||
#include "JSystem/JSupport/JSUList.h"
|
||||
#include "JSystem/JKernel/JKRHeap.h"
|
||||
#include "JSystem/JKernel/JKRMacro.h"
|
||||
|
||||
JSUList<JKRThread> JKRThread::sThreadList;
|
||||
|
||||
JKRThread::JKRThread(u32 stackSize, int msgCount, int threadPrio)
|
||||
: JKRDisposer(), mLink(this) {
|
||||
this->mHeap = JKRHeap::findFromRoot(this);
|
||||
if (this->mHeap == nullptr) {
|
||||
this->mHeap = JKRHeap::sSystemHeap;
|
||||
}
|
||||
|
||||
this->mStackSize = JKR_ALIGN32(stackSize);
|
||||
this->mStackMemory = JKRHeap::alloc(this->mStackSize, 32, this->mHeap);
|
||||
this->mThreadRecord =
|
||||
(OSThread *)JKRHeap::alloc(sizeof(OSThread), 32, this->mHeap);
|
||||
OSCreateThread(this->mThreadRecord, &JKRThread::start, this,
|
||||
(void *)((u32)this->mStackMemory + this->mStackSize),
|
||||
this->mStackSize, threadPrio, OS_THREAD_ATTR_DETACH);
|
||||
this->mMesgCount = msgCount;
|
||||
this->mMesgBuffer = (OSMessage *)JKRHeap::alloc(
|
||||
mMesgCount * sizeof(OSMessage), 0, this->mHeap);
|
||||
OSInitMessageQueue(&this->mMesgQueue, this->mMesgBuffer, this->mMesgCount);
|
||||
JKRThread::sThreadList.append(&this->mLink);
|
||||
}
|
||||
|
||||
JKRThread::JKRThread(OSThread *threadRecord, int msgCount)
|
||||
: JKRDisposer(), mLink(this) {
|
||||
this->mHeap = nullptr;
|
||||
this->mThreadRecord = threadRecord;
|
||||
this->mStackSize = (u32)threadRecord->stackEnd - (u32)threadRecord->stackBase;
|
||||
this->mStackMemory = threadRecord->stackBase;
|
||||
this->mMesgCount = msgCount;
|
||||
this->mMesgBuffer = (OSMessage *)JKRHeap::sSystemHeap->alloc(
|
||||
mMesgCount * sizeof(OSMessage), 4);
|
||||
OSInitMessageQueue(&this->mMesgQueue, this->mMesgBuffer, this->mMesgCount);
|
||||
JKRThread::sThreadList.append(&this->mLink);
|
||||
}
|
||||
|
||||
JKRThread::~JKRThread() {
|
||||
JKRThread::sThreadList.remove(&this->mLink);
|
||||
|
||||
if (this->mHeap != nullptr) {
|
||||
if (!OSIsThreadTerminated(this->mThreadRecord)) {
|
||||
OSDetachThread(this->mThreadRecord);
|
||||
OSCancelThread(this->mThreadRecord);
|
||||
}
|
||||
|
||||
JKRHeap::free(this->mStackMemory, this->mHeap);
|
||||
JKRHeap::free(this->mThreadRecord, this->mHeap);
|
||||
}
|
||||
|
||||
JKRHeap::free(this->mMesgBuffer, nullptr);
|
||||
}
|
||||
|
||||
void *JKRThread::start(void *thread) {
|
||||
return static_cast<JKRThread*>(thread)->run();
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
#include "JSystem/JKernel/JKRThread.h"
|
||||
|
||||
__declspec(weak) void* JKRThread::run() { return nullptr; }
|
||||
@@ -0,0 +1,51 @@
|
||||
#include "JSystem/JSupport/JSUStream.h"
|
||||
|
||||
JSUFileInputStream::JSUFileInputStream(JKRFile* file)
|
||||
: mObject(file), mPosition(0) {}
|
||||
|
||||
int JSUFileInputStream::readData(void* buf, s32 len) {
|
||||
int read = 0;
|
||||
|
||||
if (((JKRFile*)this->mObject)->isAvailable()) {
|
||||
/* Check if need to clamp length to EOF */
|
||||
if ((u32)(this->mPosition + len) >
|
||||
((JKRFile*)this->mObject)->getFileSize()) {
|
||||
len = ((JKRFile*)this->mObject)->getFileSize() - this->mPosition;
|
||||
}
|
||||
|
||||
if (len > 0) {
|
||||
read = ((JKRFile*)this->mObject)->readData(buf, len, this->mPosition);
|
||||
this->mPosition += read;
|
||||
}
|
||||
}
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
int JSUFileInputStream::seekPos(s32 offset, JSUStreamSeekFrom from) {
|
||||
int pos = this->mPosition;
|
||||
|
||||
switch (from) {
|
||||
case SEEK_SET:
|
||||
this->mPosition = offset;
|
||||
break;
|
||||
|
||||
case SEEK_END:
|
||||
this->mPosition = ((JKRFile*)this->mObject)->getFileSize() - offset;
|
||||
break;
|
||||
|
||||
case SEEK_CUR:
|
||||
this->mPosition = pos + offset;
|
||||
break;
|
||||
}
|
||||
|
||||
if (this->mPosition < 0) {
|
||||
this->mPosition = 0;
|
||||
}
|
||||
|
||||
if (this->mPosition > (s32)((JKRFile*)this->mObject)->getFileSize()) {
|
||||
this->mPosition = ((JKRFile*)this->mObject)->getFileSize();
|
||||
}
|
||||
|
||||
return this->mPosition - pos;
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
#include "JSystem/JSupport/JSUStream.h"
|
||||
|
||||
JSUInputStream::~JSUInputStream() { }
|
||||
|
||||
int JSUInputStream::read(void* buf, s32 size) {
|
||||
int len = this->readData(buf, size);
|
||||
if (len != size) {
|
||||
this->setState(EOF);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
char* JSUInputStream::read(char* str) {
|
||||
u16 size;
|
||||
int len = this->readData(&size, sizeof(size));
|
||||
if (len != sizeof(size)) {
|
||||
str[0] = '\0';
|
||||
this->setState(EOF);
|
||||
str = nullptr;
|
||||
}
|
||||
else {
|
||||
int strRead = this->readData(str, size);
|
||||
str[strRead] = '\0';
|
||||
if (strRead != size) {
|
||||
this->setState(EOF);
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/* @fabricated -- this method is confirmed to exist, but goes unused in AC */
|
||||
char* JSUInputStream::readString() {
|
||||
u16 len;
|
||||
int r = this->readData(&len, sizeof(len));
|
||||
if (r != sizeof(len)) {
|
||||
this->setState(EOF);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
char* buf = new char[len+1];
|
||||
r = this->readData(buf, len);
|
||||
if (r != len) {
|
||||
delete[] buf;
|
||||
this->setState(EOF);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
buf[len] = '\0';
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* @fabricated -- this method is confirmed to exist, but goes unused in AC */
|
||||
char* JSUInputStream::readString(char* buf, u16 len) {
|
||||
int r = this->readData(buf, len);
|
||||
if (r != len) {
|
||||
this->setState(EOF);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
buf[len] = '\0';
|
||||
return buf;
|
||||
}
|
||||
|
||||
int JSUInputStream::skip(s32 amount) {
|
||||
u8 _p;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < amount; i++) {
|
||||
if (this->readData(&_p, sizeof(_p)) != sizeof(_p)) {
|
||||
this->setState(EOF);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/* JSURandomInputStream */
|
||||
|
||||
int JSURandomInputStream::skip(s32 amount) {
|
||||
int s = this->seekPos(amount, SEEK_CUR);
|
||||
if (s != amount) {
|
||||
this->setState(EOF);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/* This method is confirmed to exist, but goes unused in AC. Retrieved from TP debug. */
|
||||
int JSURandomInputStream::align(s32 alignment) {
|
||||
int pos = this->getPosition();
|
||||
int aligned = ((alignment-1) + pos) & ~(alignment-1);
|
||||
int change = aligned - pos;
|
||||
|
||||
if (change != 0) {
|
||||
int s = this->seekPos(aligned, SEEK_SET);
|
||||
if (s != change) {
|
||||
this->setState(EOF);
|
||||
}
|
||||
}
|
||||
|
||||
return change;
|
||||
}
|
||||
|
||||
/* This method is confirmed to exist, but goes unused in AC. Retrieved from TP debug. */
|
||||
int JSURandomInputStream::peek(void* buf, s32 len) {
|
||||
int pos = this->getPosition();
|
||||
int r = this->read(buf, len);
|
||||
if (r != 0) {
|
||||
this->seekPos(pos, SEEK_SET);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int JSURandomInputStream::seek(s32 offset, JSUStreamSeekFrom from) {
|
||||
int s = this->seekPos(offset, from);
|
||||
this->clrState(EOF);
|
||||
return s;
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
#include "types.h"
|
||||
#include "dolphin/os.h"
|
||||
#include "dolphin/PPCArch.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
typedef void (*voidfunctionptr)(void); // pointer to function returning void
|
||||
__declspec(section ".ctors") extern voidfunctionptr _ctors[];
|
||||
__declspec(section ".dtors") extern voidfunctionptr _dtors[];
|
||||
|
||||
static void __init_cpp(void);
|
||||
|
||||
// clang-format off
|
||||
__declspec(section ".init") asm void __init_hardware(void) {
|
||||
nofralloc
|
||||
mfmsr r0
|
||||
ori r0,r0,0x2000
|
||||
mtmsr r0
|
||||
mflr r31
|
||||
bl __OSPSInit
|
||||
bl __OSCacheInit
|
||||
mtlr r31
|
||||
blr
|
||||
}
|
||||
|
||||
__declspec(section ".init") asm void __flush_cache(void) {
|
||||
nofralloc
|
||||
lis r5, 0xFFFFFFF1@h
|
||||
ori r5, r5, 0xFFFFFFF1@l
|
||||
and r5, r5, r3
|
||||
subf r3, r5, r3
|
||||
add r4, r4, r3
|
||||
loop:
|
||||
dcbst 0, r5
|
||||
sync
|
||||
icbi 0, r5
|
||||
addic r5, r5, 8
|
||||
addic. r4, r4, -8
|
||||
bge loop
|
||||
isync
|
||||
blr
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
|
||||
void __init_user(void) { __init_cpp(); }
|
||||
|
||||
static void __init_cpp(void)
|
||||
{
|
||||
voidfunctionptr* constructor;
|
||||
/*
|
||||
* call static initializers
|
||||
*/
|
||||
for (constructor = _ctors; *constructor; constructor++) {
|
||||
(*constructor)();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void __fini_cpp(void)
|
||||
{
|
||||
// UNUSED FUNCTION
|
||||
}
|
||||
|
||||
void _ExitProcess(void) { PPCHalt(); }
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user