Matched PPCArch.c, ai.c, db.c and got 99% on vi.c
This commit is contained in:
parent
692c9d32ec
commit
e2db9694ef
8 changed files with 2017 additions and 14 deletions
|
|
@ -2192,8 +2192,8 @@ __init_user = .text:0x800BB280; // type:function size:0x20 scope:global
|
||||||
__init_cpp = .text:0x800BB2A0; // type:function size:0x54 scope:local
|
__init_cpp = .text:0x800BB2A0; // type:function size:0x54 scope:local
|
||||||
_ExitProcess = .text:0x800BB2F4; // type:function size:0x20 scope:global
|
_ExitProcess = .text:0x800BB2F4; // type:function size:0x20 scope:global
|
||||||
DBInit = .text:0x800BB314; // type:function size:0x28 scope:global
|
DBInit = .text:0x800BB314; // type:function size:0x28 scope:global
|
||||||
__DBExceptionDestinationAux = .text:0x800BB33C; // type:function size:0x48 scope:local
|
__DBExceptionDestinationAux = .text:0x800BB33C; // type:function size:0x48 scope:global
|
||||||
__DBExceptionDestination = .text:0x800BB384; // type:function size:0x10 scope:global
|
__DBExceptionDestination = .text:0x800BB384; // type:function size:0x10 scope:local
|
||||||
__DBIsExceptionMarked = .text:0x800BB394; // type:function size:0x1C scope:global
|
__DBIsExceptionMarked = .text:0x800BB394; // type:function size:0x1C scope:global
|
||||||
DBPrintf = .text:0x800BB3B0; // type:function size:0x50 scope:global
|
DBPrintf = .text:0x800BB3B0; // type:function size:0x50 scope:global
|
||||||
PSMTXIdentity = .text:0x800BB400; // type:function size:0x2C
|
PSMTXIdentity = .text:0x800BB400; // type:function size:0x2C
|
||||||
|
|
@ -2321,7 +2321,7 @@ __fstLoad = .text:0x800C0A04; // type:function size:0x168 scope:global
|
||||||
__VIRetraceHandler = .text:0x800C0B6C; // type:function size:0x228 scope:local
|
__VIRetraceHandler = .text:0x800C0B6C; // type:function size:0x228 scope:local
|
||||||
VISetPreRetraceCallback = .text:0x800C0D94; // type:function size:0x44
|
VISetPreRetraceCallback = .text:0x800C0D94; // type:function size:0x44
|
||||||
VISetPostRetraceCallback = .text:0x800C0DD8; // type:function size:0x44
|
VISetPostRetraceCallback = .text:0x800C0DD8; // type:function size:0x44
|
||||||
getTiming = .text:0x800C0E1C; // type:function size:0x90
|
getTiming = .text:0x800C0E1C; // type:function size:0x90 scope:local
|
||||||
__VIInit = .text:0x800C0EAC; // type:function size:0x1F8
|
__VIInit = .text:0x800C0EAC; // type:function size:0x1F8
|
||||||
VIInit = .text:0x800C10A4; // type:function size:0x478
|
VIInit = .text:0x800C10A4; // type:function size:0x478
|
||||||
VIWaitForRetrace = .text:0x800C151C; // type:function size:0x54
|
VIWaitForRetrace = .text:0x800C151C; // type:function size:0x54
|
||||||
|
|
@ -4344,7 +4344,7 @@ ResetFunctionInfo = .data:0x8013C2E0; // type:object size:0x10 scope:local
|
||||||
lbl_8013C2F0 = .data:0x8013C2F0; // type:object size:0x78
|
lbl_8013C2F0 = .data:0x8013C2F0; // type:object size:0x78
|
||||||
YearDays = .data:0x8013C368; // type:object size:0x30 scope:local
|
YearDays = .data:0x8013C368; // type:object size:0x30 scope:local
|
||||||
LeapYearDays = .data:0x8013C398; // type:object size:0x30 scope:local
|
LeapYearDays = .data:0x8013C398; // type:object size:0x30 scope:local
|
||||||
lbl_8013C3C8 = .data:0x8013C3C8; // type:object size:0x18 data:string
|
lbl_8013C3C8 = .data:0x8013C3C8; // type:object size:0x18 scope:local data:string
|
||||||
lbl_8013C3E0 = .data:0x8013C3E0; // type:object size:0xC8 data:string
|
lbl_8013C3E0 = .data:0x8013C3E0; // type:object size:0xC8 data:string
|
||||||
lbl_8013C4A8 = .data:0x8013C4A8; // type:object size:0x38
|
lbl_8013C4A8 = .data:0x8013C4A8; // type:object size:0x38
|
||||||
lbl_8013C4E0 = .data:0x8013C4E0; // type:object size:0x34 data:string
|
lbl_8013C4E0 = .data:0x8013C4E0; // type:object size:0x34 data:string
|
||||||
|
|
@ -4359,12 +4359,12 @@ ErrorTable = .data:0x8013C660; // type:object size:0x48 scope:local data:4byte
|
||||||
timing = .data:0x8013C718; // type:object size:0x130 scope:local
|
timing = .data:0x8013C718; // type:object size:0x130 scope:local
|
||||||
taps = .data:0x8013C848; // type:object size:0x32 scope:local
|
taps = .data:0x8013C848; // type:object size:0x32 scope:local
|
||||||
jumptable_8013C87C = .data:0x8013C87C; // type:object size:0x58 scope:local
|
jumptable_8013C87C = .data:0x8013C87C; // type:object size:0x58 scope:local
|
||||||
lbl_8013C8D4 = .data:0x8013C8D4; // type:object size:0x29 data:string
|
lbl_8013C8D4 = .data:0x8013C8D4; // type:object size:0x29 scope:local data:string
|
||||||
lbl_8013C900 = .data:0x8013C900; // type:object size:0x29 data:string
|
lbl_8013C900 = .data:0x8013C900; // type:object size:0x29 scope:local data:string
|
||||||
lbl_8013C92C = .data:0x8013C92C; // type:object size:0x29 data:string
|
lbl_8013C92C = .data:0x8013C92C; // type:object size:0x29 scope:local data:string
|
||||||
lbl_8013C958 = .data:0x8013C958; // type:object size:0x29 data:string
|
lbl_8013C958 = .data:0x8013C958; // type:object size:0x29 scope:local data:string
|
||||||
lbl_8013C984 = .data:0x8013C984; // type:object size:0x29 data:string
|
lbl_8013C984 = .data:0x8013C984; // type:object size:0x29 scope:local data:string
|
||||||
lbl_8013C9B0 = .data:0x8013C9B0; // type:object size:0x29 data:string
|
lbl_8013C9B0 = .data:0x8013C9B0; // type:object size:0x29 scope:local data:string
|
||||||
DEMOFontBitmap = .data:0x8013C9E0; // type:object size:0xC00 align:32
|
DEMOFontBitmap = .data:0x8013C9E0; // type:object size:0xC00 align:32
|
||||||
lbl_8013D5E0 = .data:0x8013D5E0; // type:object size:0xC data:string
|
lbl_8013D5E0 = .data:0x8013D5E0; // type:object size:0xC data:string
|
||||||
lbl_8013D5EC = .data:0x8013D5EC; // type:object size:0x28
|
lbl_8013D5EC = .data:0x8013D5EC; // type:object size:0x28
|
||||||
|
|
|
||||||
|
|
@ -303,7 +303,7 @@ config.rel_empty_file = "REL/empty.c"
|
||||||
def DolphinLib(lib_name, objects):
|
def DolphinLib(lib_name, objects):
|
||||||
return {
|
return {
|
||||||
"lib": lib_name,
|
"lib": lib_name,
|
||||||
"mw_version": "GC/2.6",
|
"mw_version": "GC/1.2.5n",
|
||||||
"cflags": cflags_base,
|
"cflags": cflags_base,
|
||||||
"host": False,
|
"host": False,
|
||||||
"objects": objects,
|
"objects": objects,
|
||||||
|
|
@ -442,7 +442,7 @@ config.libs = [
|
||||||
DolphinLib(
|
DolphinLib(
|
||||||
"base",
|
"base",
|
||||||
[
|
[
|
||||||
Object(NonMatching, "dolphin/PPCArch.c"),
|
Object(Matching, "dolphin/PPCArch.c"),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
DolphinLib(
|
DolphinLib(
|
||||||
|
|
@ -477,7 +477,7 @@ config.libs = [
|
||||||
DolphinLib(
|
DolphinLib(
|
||||||
"db",
|
"db",
|
||||||
[
|
[
|
||||||
Object(NonMatching, "dolphin/db.c"),
|
Object(Matching, "dolphin/db.c"),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
DolphinLib(
|
DolphinLib(
|
||||||
|
|
@ -527,7 +527,7 @@ config.libs = [
|
||||||
DolphinLib(
|
DolphinLib(
|
||||||
"ai",
|
"ai",
|
||||||
[
|
[
|
||||||
Object(NonMatching, "dolphin/ai.c"),
|
Object(Matching, "dolphin/ai.c"),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
DolphinLib(
|
DolphinLib(
|
||||||
|
|
|
||||||
84
include/asm_types.h
Normal file
84
include/asm_types.h
Normal file
|
|
@ -0,0 +1,84 @@
|
||||||
|
#ifndef _ASM_TYPES
|
||||||
|
#define _ASM_TYPES
|
||||||
|
|
||||||
|
// Special Purpose Registers (SPRs)
|
||||||
|
#define XER 1
|
||||||
|
#define LR 8
|
||||||
|
#define CTR 9
|
||||||
|
#define DSISR 18
|
||||||
|
#define DAR 19
|
||||||
|
#define DEC 22
|
||||||
|
#define SDR1 25
|
||||||
|
#define SRR0 26
|
||||||
|
#define SRR1 27
|
||||||
|
#define SPRG0 272
|
||||||
|
#define SPRG1 273
|
||||||
|
#define SPRG2 274
|
||||||
|
#define SPRG3 275
|
||||||
|
#define EAR 282
|
||||||
|
#define PVR 287
|
||||||
|
#define IBAT0U 528
|
||||||
|
#define IBAT0L 529
|
||||||
|
#define IBAT1U 530
|
||||||
|
#define IBAT1L 531
|
||||||
|
#define IBAT2U 532
|
||||||
|
#define IBAT2L 533
|
||||||
|
#define IBAT3U 534
|
||||||
|
#define IBAT3L 535
|
||||||
|
#define DBAT0U 536
|
||||||
|
#define DBAT0L 537
|
||||||
|
#define DBAT1U 538
|
||||||
|
#define DBAT1L 539
|
||||||
|
#define DBAT2U 540
|
||||||
|
#define DBAT2L 541
|
||||||
|
#define DBAT3U 542
|
||||||
|
#define DBAT3L 543
|
||||||
|
#define GQR0 912
|
||||||
|
#define GQR1 913
|
||||||
|
#define GQR2 914
|
||||||
|
#define GQR3 915
|
||||||
|
#define GQR4 916
|
||||||
|
#define GQR5 917
|
||||||
|
#define GQR6 918
|
||||||
|
#define GQR7 919
|
||||||
|
#define HID2 920
|
||||||
|
#define WPAR 921
|
||||||
|
#define DMA_U 922
|
||||||
|
#define DMA_L 923
|
||||||
|
#define UMMCR0 936
|
||||||
|
#define UPMC1 937
|
||||||
|
#define UPMC2 938
|
||||||
|
#define USIA 939
|
||||||
|
#define UMMCR1 940
|
||||||
|
#define UPMC3 941
|
||||||
|
#define UPMC4 942
|
||||||
|
#define USDA 943
|
||||||
|
#define MMCR0 952
|
||||||
|
#define PMC1 953
|
||||||
|
#define PMC2 954
|
||||||
|
#define SIA 955
|
||||||
|
#define MMCR1 956
|
||||||
|
#define PMC3 957
|
||||||
|
#define PMC4 958
|
||||||
|
#define SDA 959
|
||||||
|
#define HID0 1008
|
||||||
|
#define HID1 1009
|
||||||
|
#define IABR 1010
|
||||||
|
#define DABR 1013
|
||||||
|
#define L2CR 1017
|
||||||
|
#define ICTC 1019
|
||||||
|
#define THRM1 1020
|
||||||
|
#define THRM2 1021
|
||||||
|
#define THRM3 1022
|
||||||
|
|
||||||
|
// Condition Registers (CRs)
|
||||||
|
#define cr0 0
|
||||||
|
#define cr1 1
|
||||||
|
#define cr2 2
|
||||||
|
#define cr3 3
|
||||||
|
#define cr4 4
|
||||||
|
#define cr5 5
|
||||||
|
#define cr6 6
|
||||||
|
#define cr7 7
|
||||||
|
|
||||||
|
#endif // _ASM_TYPES
|
||||||
|
|
@ -9,6 +9,12 @@ extern "C" {
|
||||||
typedef void (*AISCallback)(u32 count);
|
typedef void (*AISCallback)(u32 count);
|
||||||
typedef void (*AIDCallback)();
|
typedef void (*AIDCallback)();
|
||||||
|
|
||||||
|
#define AI_STREAM_START 1
|
||||||
|
#define AI_STREAM_STOP 0
|
||||||
|
|
||||||
|
#define AI_SAMPLERATE_32KHZ 0
|
||||||
|
#define AI_SAMPLERATE_48KHZ 1
|
||||||
|
|
||||||
AIDCallback AIRegisterDMACallback(AIDCallback callback);
|
AIDCallback AIRegisterDMACallback(AIDCallback callback);
|
||||||
void AIInitDMA(u32 start_addr, u32 length);
|
void AIInitDMA(u32 start_addr, u32 length);
|
||||||
BOOL AIGetDMAEnableFlag();
|
BOOL AIGetDMAEnableFlag();
|
||||||
|
|
|
||||||
565
src/dolphin/PPCArch.c
Normal file
565
src/dolphin/PPCArch.c
Normal file
|
|
@ -0,0 +1,565 @@
|
||||||
|
#include "types.h"
|
||||||
|
#include "asm_types.h"
|
||||||
|
|
||||||
|
/* clang-format off */
|
||||||
|
|
||||||
|
union FpscrUnion
|
||||||
|
{
|
||||||
|
f64 f;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
u32 fpscr_pad;
|
||||||
|
u32 fpscr;
|
||||||
|
} u;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define HID0_SPD 0x00000200 // Speculative cache access enable (0 enable)
|
||||||
|
|
||||||
|
void PPCMthid0 ( u32 newHID0 );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: 8036F7D4
|
||||||
|
* Size: 000008
|
||||||
|
*/
|
||||||
|
asm u32 PPCMfmsr (void)
|
||||||
|
{
|
||||||
|
nofralloc
|
||||||
|
mfmsr r3
|
||||||
|
blr
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: 8036F7DC
|
||||||
|
* Size: 000008
|
||||||
|
*/
|
||||||
|
asm void PPCMtmsr (register u32 newMSR)
|
||||||
|
{
|
||||||
|
nofralloc
|
||||||
|
mtmsr newMSR
|
||||||
|
blr
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: ........
|
||||||
|
* Size: 00000C
|
||||||
|
*/
|
||||||
|
void PPCOrMsr(void)
|
||||||
|
{
|
||||||
|
// UNUSED FUNCTION
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: ........
|
||||||
|
* Size: 00000C
|
||||||
|
*/
|
||||||
|
void PPCAndMsr(void)
|
||||||
|
{
|
||||||
|
// UNUSED FUNCTION
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: ........
|
||||||
|
* Size: 00000C
|
||||||
|
*/
|
||||||
|
void PPCAndCMsr(void)
|
||||||
|
{
|
||||||
|
// UNUSED FUNCTION
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: 8036F7E4
|
||||||
|
* Size: 000008
|
||||||
|
*/
|
||||||
|
asm u32 PPCMfhid0 (void)
|
||||||
|
{
|
||||||
|
nofralloc
|
||||||
|
mfspr r3, HID0
|
||||||
|
blr
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: 8036F7EC
|
||||||
|
* Size: 000008
|
||||||
|
*/
|
||||||
|
asm void PPCMthid0 (register u32 newHID0)
|
||||||
|
{
|
||||||
|
nofralloc
|
||||||
|
mtspr HID0, newHID0
|
||||||
|
blr
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: ........
|
||||||
|
* Size: 000008
|
||||||
|
*/
|
||||||
|
void PPCMfhid1(void)
|
||||||
|
{
|
||||||
|
// UNUSED FUNCTION
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: 8036F7F4
|
||||||
|
* Size: 000008
|
||||||
|
*/
|
||||||
|
asm u32 PPCMfl2cr (void)
|
||||||
|
{
|
||||||
|
nofralloc
|
||||||
|
mfspr r3, L2CR
|
||||||
|
blr
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: 8036F7FC
|
||||||
|
* Size: 000008
|
||||||
|
*/
|
||||||
|
asm void PPCMtl2cr (register u32 newL2cr)
|
||||||
|
{
|
||||||
|
nofralloc
|
||||||
|
mtspr L2CR, newL2cr
|
||||||
|
blr
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: 8036F804
|
||||||
|
* Size: 000008
|
||||||
|
*/
|
||||||
|
__declspec ( weak ) asm void PPCMtdec ( register u32 newDec )
|
||||||
|
{
|
||||||
|
nofralloc
|
||||||
|
mtdec newDec
|
||||||
|
blr
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: ........
|
||||||
|
* Size: 000008
|
||||||
|
*/
|
||||||
|
void PPCMfdec(void)
|
||||||
|
{
|
||||||
|
// UNUSED FUNCTION
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: 8036F80C
|
||||||
|
* Size: 000008
|
||||||
|
*/
|
||||||
|
asm void PPCSync (void)
|
||||||
|
{
|
||||||
|
nofralloc
|
||||||
|
sc
|
||||||
|
blr
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: ........
|
||||||
|
* Size: 000034
|
||||||
|
*/
|
||||||
|
asm void PPCEieio(void) {
|
||||||
|
nofralloc
|
||||||
|
mfmsr r5
|
||||||
|
rlwinm r6, r5, 0, 0x11, 0xf
|
||||||
|
mtmsr r6
|
||||||
|
mfspr r3, hid0
|
||||||
|
ori r4, r3, 8
|
||||||
|
mtspr hid0, r4
|
||||||
|
isync
|
||||||
|
eieio
|
||||||
|
isync
|
||||||
|
|
||||||
|
mtspr hid0, r3
|
||||||
|
mtmsr r5
|
||||||
|
isync
|
||||||
|
|
||||||
|
blr
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: 8036F814
|
||||||
|
* Size: 000014
|
||||||
|
*/
|
||||||
|
__declspec ( weak ) asm void PPCHalt (void) //spins infinitely
|
||||||
|
{
|
||||||
|
nofralloc
|
||||||
|
|
||||||
|
sync
|
||||||
|
|
||||||
|
_spin:
|
||||||
|
nop
|
||||||
|
li r3, 0
|
||||||
|
nop
|
||||||
|
b _spin
|
||||||
|
|
||||||
|
// NEVER REACHED
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: ........
|
||||||
|
* Size: 000008
|
||||||
|
*/
|
||||||
|
asm void PPCMfmmcr0(void)
|
||||||
|
{
|
||||||
|
nofralloc
|
||||||
|
mfspr r3, MMCR0
|
||||||
|
blr
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: ........
|
||||||
|
* Size: 000008
|
||||||
|
* UNUSED
|
||||||
|
*/
|
||||||
|
asm void PPCMtmmcr0 (register u32 newMmcr0)
|
||||||
|
{
|
||||||
|
nofralloc
|
||||||
|
mtspr MMCR0, newMmcr0
|
||||||
|
blr
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: ........
|
||||||
|
* Size: 000008
|
||||||
|
*/
|
||||||
|
asm void PPCMfmmcr1(void)
|
||||||
|
{
|
||||||
|
nofralloc
|
||||||
|
mfspr r3, MMCR1
|
||||||
|
blr}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: ........
|
||||||
|
* Size: 000008
|
||||||
|
* UNUSED
|
||||||
|
*/
|
||||||
|
asm void PPCMtmmcr1 (register u32 newMmcr1)
|
||||||
|
{
|
||||||
|
nofralloc
|
||||||
|
mtspr MMCR1, newMmcr1
|
||||||
|
blr
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: ........
|
||||||
|
* Size: 000008
|
||||||
|
*/
|
||||||
|
asm void PPCMfpmc1(void)
|
||||||
|
{
|
||||||
|
nofralloc
|
||||||
|
mfspr r3, PMC1
|
||||||
|
blr
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: ........
|
||||||
|
* Size: 000008
|
||||||
|
* UNUSED
|
||||||
|
*/
|
||||||
|
asm void PPCMtpmc1 (register u32 newPmc1)
|
||||||
|
{
|
||||||
|
nofralloc
|
||||||
|
mtspr PMC1, newPmc1
|
||||||
|
blr
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: ........
|
||||||
|
* Size: 000008
|
||||||
|
*/
|
||||||
|
asm void PPCMfpmc2(void)
|
||||||
|
{
|
||||||
|
nofralloc
|
||||||
|
mfspr r3, PMC2
|
||||||
|
blr
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: ........
|
||||||
|
* Size: 000008
|
||||||
|
* UNUSED
|
||||||
|
*/
|
||||||
|
asm void PPCMtpmc2 (register u32 newPmc2)
|
||||||
|
{
|
||||||
|
nofralloc
|
||||||
|
mtspr PMC2, newPmc2
|
||||||
|
blr
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: ........
|
||||||
|
* Size: 000008
|
||||||
|
*/
|
||||||
|
asm void PPCMfpmc3(void)
|
||||||
|
{
|
||||||
|
nofralloc
|
||||||
|
mfspr r3, PMC2
|
||||||
|
blr}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: ........
|
||||||
|
* Size: 000008
|
||||||
|
* UNUSED
|
||||||
|
*/
|
||||||
|
asm void PPCMtpmc3 (register u32 newPmc3)
|
||||||
|
{
|
||||||
|
nofralloc
|
||||||
|
mtspr PMC3, newPmc3
|
||||||
|
blr
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: ........
|
||||||
|
* Size: 000008
|
||||||
|
*/
|
||||||
|
asm void PPCMfpmc4(void)
|
||||||
|
{
|
||||||
|
nofralloc
|
||||||
|
mfspr r3, PMC4
|
||||||
|
blr
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: ........
|
||||||
|
* Size: 000008
|
||||||
|
* UNUSED
|
||||||
|
*/
|
||||||
|
asm void PPCMtpmc4 (register u32 newPmc4)
|
||||||
|
{
|
||||||
|
nofralloc
|
||||||
|
mtspr PMC4, newPmc4
|
||||||
|
blr
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: ........
|
||||||
|
* Size: 000008
|
||||||
|
*/
|
||||||
|
asm void PPCMfsia(void)
|
||||||
|
{
|
||||||
|
nofralloc
|
||||||
|
mfspr r3, SIA
|
||||||
|
blr}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: ........
|
||||||
|
* Size: 000008
|
||||||
|
*/
|
||||||
|
asm void PPCMtsia(register u32 newSia)
|
||||||
|
{
|
||||||
|
nofralloc
|
||||||
|
mtspr SIA, newSia
|
||||||
|
blr
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: 8036F828
|
||||||
|
* Size: 000020
|
||||||
|
*/
|
||||||
|
u32 PPCMffpscr(void)
|
||||||
|
{
|
||||||
|
union FpscrUnion m;
|
||||||
|
|
||||||
|
|
||||||
|
asm
|
||||||
|
{
|
||||||
|
mffs fp31
|
||||||
|
stfd fp31, m.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return m.u.fpscr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: 8036F848
|
||||||
|
* Size: 000028
|
||||||
|
*/
|
||||||
|
void PPCMtfpscr(register u32 newFPSCR)
|
||||||
|
{
|
||||||
|
union FpscrUnion m;
|
||||||
|
|
||||||
|
asm
|
||||||
|
{
|
||||||
|
li r4, 0
|
||||||
|
stw r4, m.u.fpscr_pad;
|
||||||
|
stw newFPSCR, m.u.fpscr
|
||||||
|
lfd fp31, m.f
|
||||||
|
mtfsf 0xff, fp31
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: 8036F870
|
||||||
|
* Size: 000008
|
||||||
|
*/
|
||||||
|
asm u32 PPCMfhid2 ( void )
|
||||||
|
{
|
||||||
|
nofralloc
|
||||||
|
mfspr r3, HID2
|
||||||
|
blr
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: 8036F878
|
||||||
|
* Size: 000008
|
||||||
|
*/
|
||||||
|
asm void PPCMthid2 ( register u32 newhid2 )
|
||||||
|
{
|
||||||
|
nofralloc
|
||||||
|
mtspr HID2, newhid2
|
||||||
|
blr
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: 8036F880
|
||||||
|
* Size: 00000C
|
||||||
|
*/
|
||||||
|
asm u32 PPCMfwpar(void)
|
||||||
|
{
|
||||||
|
nofralloc
|
||||||
|
sync
|
||||||
|
mfspr r3, WPAR
|
||||||
|
blr
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: 8036F88C
|
||||||
|
* Size: 000008
|
||||||
|
*/
|
||||||
|
asm void PPCMtwpar ( register u32 newwpar )
|
||||||
|
{
|
||||||
|
nofralloc
|
||||||
|
mtspr WPAR, newwpar
|
||||||
|
blr
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: ........
|
||||||
|
* Size: 000008
|
||||||
|
*/
|
||||||
|
asm void PPCMfdmaU(void)
|
||||||
|
{
|
||||||
|
nofralloc
|
||||||
|
mfspr r3, DMA_U
|
||||||
|
blr
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: ........
|
||||||
|
* Size: 000008
|
||||||
|
*/
|
||||||
|
asm void PPCMfdmaL(void)
|
||||||
|
{
|
||||||
|
nofralloc
|
||||||
|
mfspr r3, DMA_L
|
||||||
|
blr
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: ........
|
||||||
|
* Size: 000008
|
||||||
|
*/
|
||||||
|
void PPCMtdmaU(void)
|
||||||
|
{
|
||||||
|
// UNUSED FUNCTION
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: ........
|
||||||
|
* Size: 000008
|
||||||
|
*/
|
||||||
|
void PPCMtdmaL(void)
|
||||||
|
{
|
||||||
|
// UNUSED FUNCTION
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: ........
|
||||||
|
* Size: 000008
|
||||||
|
*/
|
||||||
|
void PPCMfpvr(void)
|
||||||
|
{
|
||||||
|
// UNUSED FUNCTION
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: ........
|
||||||
|
* Size: 000028
|
||||||
|
*/
|
||||||
|
void PPCEnableSpeculation(void)
|
||||||
|
{
|
||||||
|
// UNUSED FUNCTION
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: 8036F894
|
||||||
|
* Size: 000028
|
||||||
|
*/
|
||||||
|
void PPCDisableSpeculation (void)
|
||||||
|
{
|
||||||
|
PPCMthid0(PPCMfhid0() | HID0_SPD);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: 8036F8BC
|
||||||
|
* Size: 000008
|
||||||
|
*/
|
||||||
|
asm void PPCSetFpIEEEMode(void)
|
||||||
|
{
|
||||||
|
nofralloc
|
||||||
|
mtfsb0 4*7+1
|
||||||
|
blr
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: 8036F8C4
|
||||||
|
* Size: 000008
|
||||||
|
*/
|
||||||
|
asm void PPCSetFpNonIEEEMode (void)
|
||||||
|
{
|
||||||
|
nofralloc
|
||||||
|
mtfsb1 4*7+1
|
||||||
|
blr
|
||||||
|
}
|
||||||
|
|
||||||
|
/* clang-format on */
|
||||||
362
src/dolphin/ai.c
Normal file
362
src/dolphin/ai.c
Normal file
|
|
@ -0,0 +1,362 @@
|
||||||
|
#include "dolphin/ai.h"
|
||||||
|
#include "dolphin/hw_regs.h"
|
||||||
|
#include "dolphin/os.h"
|
||||||
|
|
||||||
|
const char *__AIVersion = "<< Dolphin SDK - AI\trelease build: Sep 5 2002 05:34:25 (0x2301) >>";
|
||||||
|
|
||||||
|
static AISCallback __AIS_Callback = NULL;
|
||||||
|
static AIDCallback __AID_Callback = NULL;
|
||||||
|
static u8 *__CallbackStack;
|
||||||
|
static u8 *__OldStack;
|
||||||
|
static volatile s32 __AI_init_flag = FALSE;
|
||||||
|
static volatile s32 __AID_Active = FALSE;
|
||||||
|
|
||||||
|
static OSTime bound_32KHz;
|
||||||
|
static OSTime bound_48KHz;
|
||||||
|
static OSTime min_wait;
|
||||||
|
static OSTime max_wait;
|
||||||
|
static OSTime buffer;
|
||||||
|
|
||||||
|
void __AISHandler(s16 interrupt, OSContext *context);
|
||||||
|
void __AIDHandler(s16 interrupt, OSContext *context);
|
||||||
|
void __AICallbackStackSwitch(register AIDCallback cb);
|
||||||
|
void __AI_SRC_INIT(void);
|
||||||
|
|
||||||
|
AIDCallback AIRegisterDMACallback(AIDCallback callback)
|
||||||
|
{
|
||||||
|
s32 oldInts;
|
||||||
|
AIDCallback ret;
|
||||||
|
|
||||||
|
ret = __AID_Callback;
|
||||||
|
oldInts = OSDisableInterrupts();
|
||||||
|
__AID_Callback = callback;
|
||||||
|
OSRestoreInterrupts(oldInts);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AIInitDMA(u32 addr, u32 length)
|
||||||
|
{
|
||||||
|
s32 oldInts;
|
||||||
|
oldInts = OSDisableInterrupts();
|
||||||
|
__DSPRegs[24] = (u16)((__DSPRegs[24] & ~0x3FF) | (addr >> 16));
|
||||||
|
__DSPRegs[25] = (u16)((__DSPRegs[25] & ~0xFFE0) | (0xffff & addr));
|
||||||
|
__DSPRegs[27] = (u16)((__DSPRegs[27] & ~0x7FFF) | (u16)((length >> 5) & 0xFFFF));
|
||||||
|
OSRestoreInterrupts(oldInts);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AIStartDMA()
|
||||||
|
{
|
||||||
|
__DSPRegs[27] |= 0x8000;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AIStopDMA(void)
|
||||||
|
{
|
||||||
|
__DSPRegs[27] &= ~0x8000;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 AIGetDMAStartAddr(void)
|
||||||
|
{
|
||||||
|
return (u32)((__DSPRegs[24] & 0x03ff) << 16) | (__DSPRegs[25] & 0xffe0);
|
||||||
|
}
|
||||||
|
|
||||||
|
AISCallback AIRegisterStreamCallback(AISCallback callback)
|
||||||
|
{
|
||||||
|
AISCallback ret;
|
||||||
|
s32 oldInts;
|
||||||
|
|
||||||
|
ret = __AIS_Callback;
|
||||||
|
oldInts = OSDisableInterrupts();
|
||||||
|
__AIS_Callback = callback;
|
||||||
|
OSRestoreInterrupts(oldInts);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AIResetStreamSampleCount(void)
|
||||||
|
{
|
||||||
|
__AIRegs[0] = (__AIRegs[0] & ~0x20) | 0x20;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AISetStreamTrigger(u32 trigger)
|
||||||
|
{
|
||||||
|
__AIRegs[3] = trigger;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AISetStreamPlayState(u32 state)
|
||||||
|
{
|
||||||
|
s32 oldInts;
|
||||||
|
u8 volRight;
|
||||||
|
u8 volLeft;
|
||||||
|
|
||||||
|
if (state == AIGetStreamPlayState()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ((AIGetStreamSampleRate() == 0U) && (state == 1)) {
|
||||||
|
volRight = AIGetStreamVolRight();
|
||||||
|
volLeft = AIGetStreamVolLeft();
|
||||||
|
AISetStreamVolRight(0);
|
||||||
|
AISetStreamVolLeft(0);
|
||||||
|
oldInts = OSDisableInterrupts();
|
||||||
|
__AI_SRC_INIT();
|
||||||
|
__AIRegs[0] = (__AIRegs[0] & ~0x20) | 0x20;
|
||||||
|
__AIRegs[0] = (__AIRegs[0] & ~1) | 1;
|
||||||
|
OSRestoreInterrupts(oldInts);
|
||||||
|
AISetStreamVolLeft(volRight);
|
||||||
|
AISetStreamVolRight(volLeft);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
__AIRegs[0] = (__AIRegs[0] & ~1) | state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 AIGetStreamPlayState()
|
||||||
|
{
|
||||||
|
return __AIRegs[0] & 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AISetDSPSampleRate(u32 rate)
|
||||||
|
{
|
||||||
|
u32 state;
|
||||||
|
s32 oldInts;
|
||||||
|
u8 left;
|
||||||
|
u8 right;
|
||||||
|
u32 sampleRate;
|
||||||
|
|
||||||
|
if (rate == AIGetDSPSampleRate()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
__AIRegs[0] &= ~0x40;
|
||||||
|
if (rate == 0) {
|
||||||
|
left = AIGetStreamVolLeft();
|
||||||
|
right = AIGetStreamVolRight();
|
||||||
|
state = AIGetStreamPlayState();
|
||||||
|
sampleRate = AIGetStreamSampleRate();
|
||||||
|
AISetStreamVolLeft(0);
|
||||||
|
AISetStreamVolRight(0);
|
||||||
|
oldInts = OSDisableInterrupts();
|
||||||
|
__AI_SRC_INIT();
|
||||||
|
__AIRegs[0] = (__AIRegs[0] & ~0x20) | 0x20;
|
||||||
|
__AIRegs[0] = (__AIRegs[0] & ~2) | (sampleRate * 2);
|
||||||
|
__AIRegs[0] = (__AIRegs[0] & ~1) | state;
|
||||||
|
__AIRegs[0] |= 0x40;
|
||||||
|
OSRestoreInterrupts(oldInts);
|
||||||
|
AISetStreamVolLeft(left);
|
||||||
|
AISetStreamVolRight(right);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 AIGetDSPSampleRate()
|
||||||
|
{
|
||||||
|
return ((__AIRegs[0] >> 6) & 1) ^ 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void __AI_set_stream_sample_rate(u32 rate)
|
||||||
|
{
|
||||||
|
s32 oldInts;
|
||||||
|
s32 state;
|
||||||
|
u8 left;
|
||||||
|
u8 right;
|
||||||
|
s32 temp_r26;
|
||||||
|
|
||||||
|
if (rate == AIGetStreamSampleRate()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
state = AIGetStreamPlayState();
|
||||||
|
left = AIGetStreamVolLeft();
|
||||||
|
right = AIGetStreamVolRight();
|
||||||
|
AISetStreamVolRight(0);
|
||||||
|
AISetStreamVolLeft(0);
|
||||||
|
temp_r26 = __AIRegs[0] & 0x40;
|
||||||
|
__AIRegs[0] &= ~0x40;
|
||||||
|
oldInts = OSDisableInterrupts();
|
||||||
|
__AI_SRC_INIT();
|
||||||
|
__AIRegs[0] |= temp_r26;
|
||||||
|
__AIRegs[0] = (__AIRegs[0] & ~0x20) | 0x20;
|
||||||
|
__AIRegs[0] = (__AIRegs[0] & ~2) | (rate * 2);
|
||||||
|
OSRestoreInterrupts(oldInts);
|
||||||
|
AISetStreamPlayState(state);
|
||||||
|
AISetStreamVolLeft(left);
|
||||||
|
AISetStreamVolRight(right);
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 AIGetStreamSampleRate()
|
||||||
|
{
|
||||||
|
return (__AIRegs[0] >> 1) & 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AISetStreamVolLeft(u8 volume)
|
||||||
|
{
|
||||||
|
__AIRegs[1] = (__AIRegs[1] & ~0xFF) | (volume & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 AIGetStreamVolLeft()
|
||||||
|
{
|
||||||
|
return __AIRegs[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
void AISetStreamVolRight(u8 volume)
|
||||||
|
{
|
||||||
|
__AIRegs[1] = (__AIRegs[1] & ~0xFF00) | ((volume & 0xFF) << 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 AIGetStreamVolRight()
|
||||||
|
{
|
||||||
|
return __AIRegs[1] >> 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AIInit(u8 *stack)
|
||||||
|
{
|
||||||
|
if (__AI_init_flag == TRUE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bound_32KHz = OSNanosecondsToTicks(31524);
|
||||||
|
bound_48KHz = OSNanosecondsToTicks(42024);
|
||||||
|
min_wait = OSNanosecondsToTicks(42000);
|
||||||
|
max_wait = OSNanosecondsToTicks(63000);
|
||||||
|
buffer = OSNanosecondsToTicks(3000);
|
||||||
|
|
||||||
|
AISetStreamVolRight(0);
|
||||||
|
AISetStreamVolLeft(0);
|
||||||
|
AISetStreamTrigger(0);
|
||||||
|
AIResetStreamSampleCount();
|
||||||
|
__AI_set_stream_sample_rate(1);
|
||||||
|
AISetDSPSampleRate(0);
|
||||||
|
__AIS_Callback = 0;
|
||||||
|
__AID_Callback = 0;
|
||||||
|
__CallbackStack = stack;
|
||||||
|
__OSSetInterruptHandler(5, __AIDHandler);
|
||||||
|
__OSUnmaskInterrupts(0x04000000);
|
||||||
|
__OSSetInterruptHandler(8, __AISHandler);
|
||||||
|
__OSUnmaskInterrupts(0x800000);
|
||||||
|
__AI_init_flag = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void __AISHandler(s16 interrupt, OSContext *context)
|
||||||
|
{
|
||||||
|
OSContext tmpContext;
|
||||||
|
__AIRegs[0] |= 8;
|
||||||
|
OSClearContext(&tmpContext);
|
||||||
|
OSSetCurrentContext(&tmpContext);
|
||||||
|
if (__AIS_Callback != NULL) {
|
||||||
|
__AIS_Callback(__AIRegs[2]);
|
||||||
|
}
|
||||||
|
OSClearContext(&tmpContext);
|
||||||
|
OSSetCurrentContext(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __AIDHandler(s16 interrupt, OSContext *context)
|
||||||
|
{
|
||||||
|
OSContext tempContext;
|
||||||
|
u16 temp = __DSPRegs[5];
|
||||||
|
__DSPRegs[5] = (temp & ~0xA0) | 8;
|
||||||
|
OSClearContext(&tempContext);
|
||||||
|
OSSetCurrentContext(&tempContext);
|
||||||
|
if (__AID_Callback) {
|
||||||
|
if (__CallbackStack) {
|
||||||
|
__AICallbackStackSwitch(__AID_Callback);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
__AID_Callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OSClearContext(&tempContext);
|
||||||
|
OSSetCurrentContext(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
asm void __AICallbackStackSwitch(register AIDCallback cb) {
|
||||||
|
// Allocate stack frame
|
||||||
|
fralloc
|
||||||
|
|
||||||
|
// Store current stack
|
||||||
|
lis r5, __OldStack@ha
|
||||||
|
addi r5, r5, __OldStack@l
|
||||||
|
stw r1, 0(r5)
|
||||||
|
|
||||||
|
// Load stack for callback
|
||||||
|
lis r5, __CallbackStack@ha
|
||||||
|
addi r5, r5, __CallbackStack@l
|
||||||
|
lwz r1,0(r5)
|
||||||
|
|
||||||
|
// Move stack down 8 bytes
|
||||||
|
subi r1, r1, 8
|
||||||
|
// Call callback
|
||||||
|
mtlr cb
|
||||||
|
blrl
|
||||||
|
|
||||||
|
// Restore old stack
|
||||||
|
lis r5, __OldStack @ha
|
||||||
|
addi r5, r5, __OldStack@l
|
||||||
|
lwz r1,0(r5)
|
||||||
|
|
||||||
|
// Free stack frame
|
||||||
|
frfree
|
||||||
|
|
||||||
|
blr
|
||||||
|
}
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
void __AI_SRC_INIT(void)
|
||||||
|
{
|
||||||
|
OSTime rise32 = 0;
|
||||||
|
OSTime rise48 = 0;
|
||||||
|
OSTime diff = 0;
|
||||||
|
OSTime unused1 = 0;
|
||||||
|
OSTime temp = 0;
|
||||||
|
u32 temp0 = 0;
|
||||||
|
u32 temp1 = 0;
|
||||||
|
u32 done = 0;
|
||||||
|
u32 walking = 0;
|
||||||
|
u32 unused2 = 0;
|
||||||
|
u32 initCnt = 0;
|
||||||
|
|
||||||
|
walking = 0;
|
||||||
|
initCnt = 0;
|
||||||
|
temp = 0;
|
||||||
|
|
||||||
|
while (!done) {
|
||||||
|
__AIRegs[0] = (__AIRegs[0] & ~0x20) | 0x20;
|
||||||
|
__AIRegs[0] &= ~2;
|
||||||
|
__AIRegs[0] = (__AIRegs[0] & ~1) | 1;
|
||||||
|
|
||||||
|
temp0 = __AIRegs[2];
|
||||||
|
|
||||||
|
while (temp0 == __AIRegs[2])
|
||||||
|
;
|
||||||
|
rise32 = OSGetTime();
|
||||||
|
|
||||||
|
__AIRegs[0] = (__AIRegs[0] & ~2) | 2;
|
||||||
|
__AIRegs[0] = (__AIRegs[0] & ~1) | 1;
|
||||||
|
|
||||||
|
temp1 = __AIRegs[2];
|
||||||
|
while (temp1 == __AIRegs[2])
|
||||||
|
;
|
||||||
|
|
||||||
|
rise48 = OSGetTime();
|
||||||
|
|
||||||
|
diff = rise48 - rise32;
|
||||||
|
__AIRegs[0] &= ~2;
|
||||||
|
__AIRegs[0] &= ~1;
|
||||||
|
|
||||||
|
if (diff < (bound_32KHz - buffer)) {
|
||||||
|
temp = min_wait;
|
||||||
|
done = 1;
|
||||||
|
++initCnt;
|
||||||
|
}
|
||||||
|
else if (diff >= (bound_32KHz + buffer) && diff < (bound_48KHz - buffer)) {
|
||||||
|
temp = max_wait;
|
||||||
|
done = 1;
|
||||||
|
++initCnt;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
done = 0;
|
||||||
|
walking = 1;
|
||||||
|
++initCnt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((rise48 + temp) > OSGetTime())
|
||||||
|
;
|
||||||
|
}
|
||||||
43
src/dolphin/db.c
Normal file
43
src/dolphin/db.c
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
#include <dolphin/db.h>
|
||||||
|
#include <dolphin/os.h>
|
||||||
|
|
||||||
|
DBInterface* __DBInterface = NULL;
|
||||||
|
int DBVerbose;
|
||||||
|
|
||||||
|
extern void __DBExceptionStart();
|
||||||
|
extern void __DBExceptionEnd();
|
||||||
|
extern void __DBExceptionSetNumber();
|
||||||
|
|
||||||
|
void DBInit(void) {
|
||||||
|
__DBInterface = (DBInterface*)OSPhysicalToCached(OS_DBINTERFACE_ADDR);
|
||||||
|
__DBInterface->ExceptionDestination = (void (*)())OSCachedToPhysical(__DBExceptionDestination);
|
||||||
|
DBVerbose = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void __DBExceptionDestinationAux(void) {
|
||||||
|
u32* contextAddr = (void*)0x00C0;
|
||||||
|
OSContext* context = (OSContext*)OSPhysicalToCached(*contextAddr);
|
||||||
|
|
||||||
|
OSReport("DBExceptionDestination\n");
|
||||||
|
OSDumpContext(context);
|
||||||
|
PPCHalt();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* clang-format off */
|
||||||
|
asm void __DBExceptionDestination(void) {
|
||||||
|
nofralloc
|
||||||
|
mfmsr r3
|
||||||
|
ori r3, r3, 0x10|0x20
|
||||||
|
mtmsr r3
|
||||||
|
|
||||||
|
b __DBExceptionDestinationAux
|
||||||
|
}
|
||||||
|
/* clang-format on */
|
||||||
|
|
||||||
|
BOOL __DBIsExceptionMarked(__OSException exception) {
|
||||||
|
u32 mask = 1 << exception;
|
||||||
|
|
||||||
|
return (BOOL)(__DBInterface->exceptionMask & mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DBPrintf(char* format, ...) {}
|
||||||
943
src/dolphin/vi.c
Normal file
943
src/dolphin/vi.c
Normal file
|
|
@ -0,0 +1,943 @@
|
||||||
|
#include "dolphin/vi.h"
|
||||||
|
#include "dolphin/OSRtcPriv.h"
|
||||||
|
#include "dolphin/hw_regs.h"
|
||||||
|
#include "dolphin/os.h"
|
||||||
|
|
||||||
|
// Useful macros.
|
||||||
|
#define CLAMP(x, l, h) (((x) > (h)) ? (h) : (((x) < (l)) ? (l) : (x)))
|
||||||
|
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||||
|
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||||
|
#define IS_LOWER_16MB(x) ((x) < 16 * 1024 * 1024)
|
||||||
|
#define ToPhysical(fb) (u32)(((u32)(fb)) & 0x3FFFFFFF)
|
||||||
|
#define ONES(x) ((1 << (x)) - 1)
|
||||||
|
#define VI_BITMASK(index) (1ull << (63 - (index)))
|
||||||
|
|
||||||
|
static BOOL IsInitialized;
|
||||||
|
static vu32 retraceCount;
|
||||||
|
static u32 flushFlag;
|
||||||
|
static OSThreadQueue retraceQueue;
|
||||||
|
static VIRetraceCallback PreCB;
|
||||||
|
static VIRetraceCallback PostCB;
|
||||||
|
static u32 encoderType;
|
||||||
|
|
||||||
|
static s16 displayOffsetH;
|
||||||
|
static s16 displayOffsetV;
|
||||||
|
|
||||||
|
static vu32 changeMode;
|
||||||
|
static vu64 changed;
|
||||||
|
|
||||||
|
static vu32 shdwChangeMode;
|
||||||
|
static vu64 shdwChanged;
|
||||||
|
|
||||||
|
static VITimingInfo *CurrTiming;
|
||||||
|
static u32 CurrTvMode;
|
||||||
|
|
||||||
|
static u32 NextBufAddr;
|
||||||
|
static u32 CurrBufAddr;
|
||||||
|
|
||||||
|
static u32 FBSet;
|
||||||
|
|
||||||
|
static vu16 regs[60];
|
||||||
|
static vu16 shdwRegs[60];
|
||||||
|
|
||||||
|
static VIPositionInfo HorVer;
|
||||||
|
// clang-format off
|
||||||
|
static VITimingInfo timing[8] = {
|
||||||
|
{ // NTSC INT
|
||||||
|
6, 240, 24, 25, 3, 2, 12, 13, 12, 13, 520, 519, 520, 519, 525, 429, 64, 71, 105, 162, 373, 122, 412,
|
||||||
|
},
|
||||||
|
{ // NTSC DS
|
||||||
|
6, 240, 24, 24, 4, 4, 12, 12, 12, 12, 520, 520, 520, 520, 526, 429, 64, 71, 105, 162, 373, 122, 412,
|
||||||
|
},
|
||||||
|
{ // PAL INT
|
||||||
|
5, 287, 35, 36, 1, 0, 13, 12, 11, 10, 619, 618, 617, 620, 625, 432, 64, 75, 106, 172, 380, 133, 420,
|
||||||
|
},
|
||||||
|
{ // PAL DS
|
||||||
|
5, 287, 33, 33, 2, 2, 13, 11, 13, 11, 619, 621, 619, 621, 624, 432, 64, 75, 106, 172, 380, 133, 420,
|
||||||
|
},
|
||||||
|
{ // MPAL INT
|
||||||
|
6, 240, 24, 25, 3, 2, 16, 15, 14, 13, 518, 517, 516, 519, 525, 429, 64, 78, 112, 162, 373, 122, 412,
|
||||||
|
},
|
||||||
|
{ // MPAL DS
|
||||||
|
6, 240, 24, 24, 4, 4, 16, 14, 16, 14, 518, 520, 518, 520, 526, 429, 64, 78, 112, 162, 373, 122, 412,
|
||||||
|
},
|
||||||
|
{ // NTSC PRO
|
||||||
|
12, 480, 48, 48, 6, 6, 24, 24, 24, 24, 1038, 1038, 1038, 1038, 1050, 429, 64, 71, 105, 162, 373, 122, 412,
|
||||||
|
},
|
||||||
|
{ // NTSC 3D
|
||||||
|
12, 480, 44, 44, 10, 10, 24, 24, 24, 24, 1038, 1038, 1038, 1038, 1050, 429, 64, 71, 105, 168, 379, 122, 412,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
static u16 taps[25] = { 496, 476, 430, 372, 297, 219, 142, 70, 12, 226, 203, 192, 196, 207, 222, 236, 252, 8, 15, 19, 19, 15, 12, 8, 1 };
|
||||||
|
|
||||||
|
// forward declaring statics
|
||||||
|
static u32 getCurrentFieldEvenOdd();
|
||||||
|
|
||||||
|
static void getEncoderType(void)
|
||||||
|
{
|
||||||
|
// UNUSED FUNCTION
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cntlzd(u64 bit)
|
||||||
|
{
|
||||||
|
u32 hi, lo;
|
||||||
|
int value;
|
||||||
|
|
||||||
|
hi = (u32)(bit >> 32);
|
||||||
|
lo = (u32)(bit & 0xFFFFFFFF);
|
||||||
|
value = __cntlzw(hi);
|
||||||
|
|
||||||
|
if (value < 32) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (32 + __cntlzw(lo));
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL VISetRegs(void)
|
||||||
|
{
|
||||||
|
int regIndex;
|
||||||
|
|
||||||
|
if (!((shdwChangeMode == 1) && (getCurrentFieldEvenOdd() == 0))) {
|
||||||
|
while (shdwChanged) {
|
||||||
|
regIndex = cntlzd(shdwChanged);
|
||||||
|
__VIRegs[regIndex] = shdwRegs[regIndex];
|
||||||
|
shdwChanged &= ~(VI_BITMASK(regIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
shdwChangeMode = 0;
|
||||||
|
CurrTiming = HorVer.timing;
|
||||||
|
CurrTvMode = HorVer.tv;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __VIRetraceHandler(__OSInterrupt interrupt, OSContext *context)
|
||||||
|
{
|
||||||
|
OSContext exceptionContext;
|
||||||
|
u16 viReg;
|
||||||
|
u32 inter = 0;
|
||||||
|
|
||||||
|
viReg = __VIRegs[VI_DISP_INT_0];
|
||||||
|
if (viReg & 0x8000) {
|
||||||
|
__VIRegs[VI_DISP_INT_0] = (u16)(viReg & ~0x8000);
|
||||||
|
inter |= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
viReg = __VIRegs[VI_DISP_INT_1];
|
||||||
|
if (viReg & 0x8000) {
|
||||||
|
__VIRegs[VI_DISP_INT_1] = (u16)(viReg & ~0x8000);
|
||||||
|
inter |= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
viReg = __VIRegs[VI_DISP_INT_2];
|
||||||
|
if (viReg & 0x8000) {
|
||||||
|
__VIRegs[VI_DISP_INT_2] = (u16)(viReg & ~0x8000);
|
||||||
|
inter |= 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
viReg = __VIRegs[VI_DISP_INT_3];
|
||||||
|
if (viReg & 0x8000) {
|
||||||
|
__VIRegs[VI_DISP_INT_3] = (u16)(viReg & ~0x8000);
|
||||||
|
inter |= 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((inter & 4) || (inter & 8)) {
|
||||||
|
OSSetCurrentContext(context);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
retraceCount++;
|
||||||
|
|
||||||
|
OSClearContext(&exceptionContext);
|
||||||
|
OSSetCurrentContext(&exceptionContext);
|
||||||
|
if (PreCB) {
|
||||||
|
(*PreCB)(retraceCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flushFlag) {
|
||||||
|
if (VISetRegs()) {
|
||||||
|
flushFlag = 0;
|
||||||
|
SIRefreshSamplingRate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PostCB) {
|
||||||
|
OSClearContext(&exceptionContext);
|
||||||
|
(*PostCB)(retraceCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
OSWakeupThread(&retraceQueue);
|
||||||
|
OSClearContext(&exceptionContext);
|
||||||
|
OSSetCurrentContext(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
VIRetraceCallback VISetPreRetraceCallback(VIRetraceCallback callback)
|
||||||
|
{
|
||||||
|
int interrupt;
|
||||||
|
VIRetraceCallback oldCallback;
|
||||||
|
|
||||||
|
oldCallback = PreCB;
|
||||||
|
|
||||||
|
interrupt = OSDisableInterrupts();
|
||||||
|
PreCB = callback;
|
||||||
|
OSRestoreInterrupts(interrupt);
|
||||||
|
|
||||||
|
return oldCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
VIRetraceCallback VISetPostRetraceCallback(VIRetraceCallback callback)
|
||||||
|
{
|
||||||
|
int interrupt;
|
||||||
|
VIRetraceCallback oldCallback;
|
||||||
|
|
||||||
|
oldCallback = PostCB;
|
||||||
|
|
||||||
|
interrupt = OSDisableInterrupts();
|
||||||
|
PostCB = callback;
|
||||||
|
OSRestoreInterrupts(interrupt);
|
||||||
|
|
||||||
|
return oldCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma dont_inline on
|
||||||
|
static VITimingInfo *getTiming(VITVMode mode)
|
||||||
|
{
|
||||||
|
switch (mode) {
|
||||||
|
case VI_TVMODE_NTSC_INT:
|
||||||
|
return &timing[0];
|
||||||
|
case VI_TVMODE_NTSC_DS:
|
||||||
|
return &timing[1];
|
||||||
|
|
||||||
|
case VI_TVMODE_PAL_INT:
|
||||||
|
return &timing[2];
|
||||||
|
case VI_TVMODE_PAL_DS:
|
||||||
|
return &timing[3];
|
||||||
|
|
||||||
|
case VI_TVMODE_EURGB60_INT:
|
||||||
|
return &timing[0];
|
||||||
|
case VI_TVMODE_EURGB60_DS:
|
||||||
|
return &timing[1];
|
||||||
|
|
||||||
|
case VI_TVMODE_MPAL_INT:
|
||||||
|
return &timing[4];
|
||||||
|
case VI_TVMODE_MPAL_DS:
|
||||||
|
return &timing[5];
|
||||||
|
|
||||||
|
case VI_TVMODE_NTSC_PROG:
|
||||||
|
return &timing[6];
|
||||||
|
case VI_TVMODE_NTSC_3D:
|
||||||
|
return &timing[7];
|
||||||
|
|
||||||
|
case VI_TVMODE_DEBUG_PAL_INT:
|
||||||
|
return &timing[2];
|
||||||
|
case VI_TVMODE_DEBUG_PAL_DS:
|
||||||
|
return &timing[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
#pragma dont_inline off
|
||||||
|
|
||||||
|
void __VIInit(VITVMode mode)
|
||||||
|
{
|
||||||
|
VITimingInfo *tm;
|
||||||
|
u32 nonInter;
|
||||||
|
vu32 a;
|
||||||
|
u32 tv, tvForReg;
|
||||||
|
|
||||||
|
u16 hct, vct;
|
||||||
|
|
||||||
|
nonInter = mode & 2;
|
||||||
|
tv = (u32)mode >> 2;
|
||||||
|
|
||||||
|
*(u32 *)OSPhysicalToCached(0xCC) = tv;
|
||||||
|
|
||||||
|
tm = getTiming(mode);
|
||||||
|
|
||||||
|
__VIRegs[VI_DISP_CONFIG] = 2;
|
||||||
|
for (a = 0; a < 1000; a++) {
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
__VIRegs[VI_DISP_CONFIG] = 0;
|
||||||
|
|
||||||
|
__VIRegs[VI_HORIZ_TIMING_0U] = tm->hlw << 0;
|
||||||
|
__VIRegs[VI_HORIZ_TIMING_0L] = (tm->hce << 0) | (tm->hcs << 8);
|
||||||
|
|
||||||
|
__VIRegs[VI_HORIZ_TIMING_1U] = (tm->hsy << 0) | ((tm->hbe640 & ((1 << 9) - 1)) << 7);
|
||||||
|
__VIRegs[VI_HORIZ_TIMING_1L] = ((tm->hbe640 >> 9) << 0) | (tm->hbs640 << 1);
|
||||||
|
|
||||||
|
__VIRegs[VI_VERT_TIMING] = (tm->equ << 0) | (0 << 4);
|
||||||
|
|
||||||
|
__VIRegs[VI_VERT_TIMING_ODD_U] = (tm->prbOdd + tm->acv * 2 - 2) << 0;
|
||||||
|
__VIRegs[VI_VERT_TIMING_ODD] = tm->psbOdd + 2 << 0;
|
||||||
|
|
||||||
|
__VIRegs[VI_VERT_TIMING_EVEN_U] = (tm->prbEven + tm->acv * 2 - 2) << 0;
|
||||||
|
__VIRegs[VI_VERT_TIMING_EVEN] = tm->psbEven + 2 << 0;
|
||||||
|
|
||||||
|
__VIRegs[VI_BBI_ODD_U] = (tm->bs1 << 0) | (tm->be1 << 5);
|
||||||
|
__VIRegs[VI_BBI_ODD] = (tm->bs3 << 0) | (tm->be3 << 5);
|
||||||
|
|
||||||
|
__VIRegs[VI_BBI_EVEN_U] = (tm->bs2 << 0) | (tm->be2 << 5);
|
||||||
|
__VIRegs[VI_BBI_EVEN] = (tm->bs4 << 0) | (tm->be4 << 5);
|
||||||
|
|
||||||
|
__VIRegs[VI_HSW] = (40 << 0) | (40 << 8);
|
||||||
|
|
||||||
|
__VIRegs[VI_DISP_INT_1U] = 1;
|
||||||
|
__VIRegs[VI_DISP_INT_1] = (1 << 0) | (1 << 12) | (0 << 15);
|
||||||
|
|
||||||
|
hct = (tm->hlw + 1);
|
||||||
|
vct = (tm->numHalfLines / 2 + 1) | (1 << 12) | (0 << 15);
|
||||||
|
__VIRegs[VI_DISP_INT_0U] = hct << 0;
|
||||||
|
__VIRegs[VI_DISP_INT_0] = vct;
|
||||||
|
|
||||||
|
if (mode != VI_TVMODE_NTSC_PROG && mode != VI_TVMODE_NTSC_3D) {
|
||||||
|
__VIRegs[VI_DISP_CONFIG] = (1 << 0) | (0 << 1) | (nonInter << 2) | (0 << 3) | (0 << 4) | (0 << 6) | (tv << 8);
|
||||||
|
__VIRegs[VI_CLOCK_SEL] = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
__VIRegs[VI_DISP_CONFIG] = (1 << 0) | (0 << 1) | (1 << 2) | (0 << 3) | (0 << 4) | (0 << 6) | (tv << 8);
|
||||||
|
__VIRegs[VI_CLOCK_SEL] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void AdjustPosition(u16 acv)
|
||||||
|
{
|
||||||
|
s32 coeff, frac;
|
||||||
|
|
||||||
|
HorVer.adjDispPosX = (u16)CLAMP((s16)HorVer.dispPosX + displayOffsetH, 0, 720 - HorVer.dispSizeX);
|
||||||
|
|
||||||
|
coeff = (HorVer.xfbMode == VI_XFBMODE_SF) ? 2 : 1;
|
||||||
|
frac = HorVer.dispPosY & 1;
|
||||||
|
|
||||||
|
HorVer.adjDispPosY = (u16)MAX((s16)HorVer.dispPosY + displayOffsetV, frac);
|
||||||
|
|
||||||
|
HorVer.adjDispSizeY = (u16)(HorVer.dispSizeY + MIN((s16)HorVer.dispPosY + displayOffsetV - frac, 0)
|
||||||
|
- MAX((s16)HorVer.dispPosY + (s16)HorVer.dispSizeY + displayOffsetV - ((s16)acv * 2 - frac), 0));
|
||||||
|
|
||||||
|
HorVer.adjPanPosY = (u16)(HorVer.panPosY - MIN((s16)HorVer.dispPosY + displayOffsetV - frac, 0) / coeff);
|
||||||
|
|
||||||
|
HorVer.adjPanSizeY = (u16)(HorVer.panSizeY + MIN((s16)HorVer.dispPosY + displayOffsetV - frac, 0) / coeff
|
||||||
|
- MAX((s16)HorVer.dispPosY + (s16)HorVer.dispSizeY + displayOffsetV - ((s16)acv * 2 - frac), 0) / coeff);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ImportAdjustingValues(void)
|
||||||
|
{
|
||||||
|
displayOffsetH = __OSLockSram()->displayOffsetH;
|
||||||
|
displayOffsetV = 0;
|
||||||
|
__OSUnlockSram(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VIInit(void)
|
||||||
|
{
|
||||||
|
u16 dspCfg;
|
||||||
|
u32 value, tv;
|
||||||
|
|
||||||
|
encoderType = 1;
|
||||||
|
|
||||||
|
if (!(__VIRegs[VI_DISP_CONFIG] & 1)) {
|
||||||
|
__VIInit(VI_TVMODE_NTSC_INT);
|
||||||
|
}
|
||||||
|
|
||||||
|
retraceCount = 0;
|
||||||
|
changed = 0;
|
||||||
|
shdwChanged = 0;
|
||||||
|
changeMode = 0;
|
||||||
|
shdwChangeMode = 0;
|
||||||
|
flushFlag = 0;
|
||||||
|
|
||||||
|
__VIRegs[VI_FCT_0U] = ((((taps[0])) << 0) | (((taps[1] & ((1 << (6)) - 1))) << 10));
|
||||||
|
__VIRegs[VI_FCT_0] = ((((taps[1] >> 6)) << 0) | (((taps[2])) << 4));
|
||||||
|
__VIRegs[VI_FCT_1U] = ((((taps[3])) << 0) | (((taps[4] & ((1 << (6)) - 1))) << 10));
|
||||||
|
__VIRegs[VI_FCT_1] = ((((taps[4] >> 6)) << 0) | (((taps[5])) << 4));
|
||||||
|
__VIRegs[VI_FCT_2U] = ((((taps[6])) << 0) | (((taps[7] & ((1 << (6)) - 1))) << 10));
|
||||||
|
__VIRegs[VI_FCT_2] = ((((taps[7] >> 6)) << 0) | (((taps[8])) << 4));
|
||||||
|
__VIRegs[VI_FCT_3U] = ((((taps[9])) << 0) | (((taps[10])) << 8));
|
||||||
|
__VIRegs[VI_FCT_3] = ((((taps[11])) << 0) | (((taps[12])) << 8));
|
||||||
|
__VIRegs[VI_FCT_4U] = ((((taps[13])) << 0) | (((taps[14])) << 8));
|
||||||
|
__VIRegs[VI_FCT_4] = ((((taps[15])) << 0) | (((taps[16])) << 8));
|
||||||
|
__VIRegs[VI_FCT_5U] = ((((taps[17])) << 0) | (((taps[18])) << 8));
|
||||||
|
__VIRegs[VI_FCT_5] = ((((taps[19])) << 0) | (((taps[20])) << 8));
|
||||||
|
__VIRegs[VI_FCT_6U] = ((((taps[21])) << 0) | (((taps[22])) << 8));
|
||||||
|
__VIRegs[VI_FCT_6] = ((((taps[23])) << 0) | (((taps[24])) << 8));
|
||||||
|
|
||||||
|
__VIRegs[VI_WIDTH] = 640;
|
||||||
|
ImportAdjustingValues();
|
||||||
|
dspCfg = __VIRegs[VI_DISP_CONFIG];
|
||||||
|
|
||||||
|
HorVer.nonInter = ((((u32)(dspCfg)) >> 2 & 0x00000001));
|
||||||
|
HorVer.tv = ((((u32)(dspCfg)) & 0x00000300) >> 8);
|
||||||
|
|
||||||
|
tv = (HorVer.tv == VI_DEBUG) ? VI_NTSC : HorVer.tv;
|
||||||
|
HorVer.timing = getTiming((VITVMode)VI_TVMODE(tv, HorVer.nonInter));
|
||||||
|
regs[VI_DISP_CONFIG] = dspCfg;
|
||||||
|
|
||||||
|
CurrTiming = HorVer.timing;
|
||||||
|
CurrTvMode = HorVer.tv;
|
||||||
|
|
||||||
|
HorVer.dispSizeX = 640;
|
||||||
|
HorVer.dispSizeY = (u16)(CurrTiming->acv * 2);
|
||||||
|
HorVer.dispPosX = (u16)((720 - HorVer.dispSizeX) / 2);
|
||||||
|
HorVer.dispPosY = 0;
|
||||||
|
|
||||||
|
AdjustPosition(CurrTiming->acv);
|
||||||
|
|
||||||
|
HorVer.fbSizeX = 640;
|
||||||
|
HorVer.fbSizeY = (u16)(CurrTiming->acv * 2);
|
||||||
|
HorVer.panPosX = 0;
|
||||||
|
HorVer.panPosY = 0;
|
||||||
|
HorVer.panSizeX = 640;
|
||||||
|
HorVer.panSizeY = (u16)(CurrTiming->acv * 2);
|
||||||
|
HorVer.xfbMode = VI_XFBMODE_SF;
|
||||||
|
HorVer.wordPerLine = 40;
|
||||||
|
HorVer.std = 40;
|
||||||
|
HorVer.wpl = 40;
|
||||||
|
HorVer.xof = 0;
|
||||||
|
HorVer.isBlack = TRUE;
|
||||||
|
HorVer.is3D = FALSE;
|
||||||
|
|
||||||
|
OSInitThreadQueue(&retraceQueue);
|
||||||
|
|
||||||
|
value = __VIRegs[VI_DISP_INT_0];
|
||||||
|
value = (((u32)(value)) & ~0x00008000) | (((0)) << 15);
|
||||||
|
__VIRegs[VI_DISP_INT_0] = value;
|
||||||
|
|
||||||
|
value = __VIRegs[VI_DISP_INT_1];
|
||||||
|
value = (((u32)(value)) & ~0x00008000) | (((0)) << 15);
|
||||||
|
__VIRegs[VI_DISP_INT_1] = value;
|
||||||
|
|
||||||
|
PreCB = nullptr;
|
||||||
|
PostCB = nullptr;
|
||||||
|
|
||||||
|
__OSSetInterruptHandler(24, __VIRetraceHandler);
|
||||||
|
__OSUnmaskInterrupts((0x80000000u >> (24)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void VIWaitForRetrace(void)
|
||||||
|
{
|
||||||
|
int interrupt;
|
||||||
|
u32 startCount;
|
||||||
|
|
||||||
|
interrupt = OSDisableInterrupts();
|
||||||
|
startCount = retraceCount;
|
||||||
|
do {
|
||||||
|
OSSleepThread(&retraceQueue);
|
||||||
|
} while (startCount == retraceCount);
|
||||||
|
OSRestoreInterrupts(interrupt);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setInterruptRegs(VITimingInfo *tm)
|
||||||
|
{
|
||||||
|
u16 vct, hct, borrow;
|
||||||
|
|
||||||
|
vct = (u16)(tm->numHalfLines / 2);
|
||||||
|
borrow = (u16)(tm->numHalfLines % 2);
|
||||||
|
hct = (u16)((borrow) ? tm->hlw : (u16)0);
|
||||||
|
|
||||||
|
vct++;
|
||||||
|
hct++;
|
||||||
|
|
||||||
|
regs[VI_DISP_INT_0U] = (u16)hct;
|
||||||
|
changed |= VI_BITMASK(VI_DISP_INT_0U);
|
||||||
|
|
||||||
|
regs[VI_DISP_INT_0] = (u16)((((u32)(vct))) | (((u32)(1)) << 12) | (((u32)(0)) << 15));
|
||||||
|
changed |= VI_BITMASK(VI_DISP_INT_0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setPicConfig(u16 fbSizeX, VIXFBMode xfbMode, u16 panPosX, u16 panSizeX, u8 *wordPerLine, u8 *std, u8 *wpl, u8 *xof)
|
||||||
|
{
|
||||||
|
*wordPerLine = (u8)((fbSizeX + 15) / 16);
|
||||||
|
*std = (u8)((xfbMode == VI_XFBMODE_SF) ? *wordPerLine : (u8)(2 * *wordPerLine));
|
||||||
|
*xof = (u8)(panPosX % 16);
|
||||||
|
*wpl = (u8)((*xof + panSizeX + 15) / 16);
|
||||||
|
|
||||||
|
regs[VI_HSW] = (u16)((((u32)(*std))) | (((u32)(*wpl)) << 8));
|
||||||
|
changed |= VI_BITMASK(VI_HSW);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setBBIntervalRegs(VITimingInfo *tm)
|
||||||
|
{
|
||||||
|
u16 val;
|
||||||
|
|
||||||
|
val = (u16)((((u32)(tm->bs1))) | (((u32)(tm->be1)) << 5));
|
||||||
|
regs[VI_BBI_ODD_U] = val;
|
||||||
|
changed |= VI_BITMASK(VI_BBI_ODD_U);
|
||||||
|
|
||||||
|
val = (u16)((((u32)(tm->bs3))) | (((u32)(tm->be3)) << 5));
|
||||||
|
regs[VI_BBI_ODD] = val;
|
||||||
|
changed |= VI_BITMASK(VI_BBI_ODD);
|
||||||
|
|
||||||
|
val = (u16)((((u32)(tm->bs2))) | (((u32)(tm->be2)) << 5));
|
||||||
|
regs[VI_BBI_EVEN_U] = val;
|
||||||
|
changed |= VI_BITMASK(VI_BBI_EVEN_U);
|
||||||
|
|
||||||
|
val = (u16)((((u32)(tm->bs4))) | (((u32)(tm->be4)) << 5));
|
||||||
|
regs[VI_BBI_EVEN] = val;
|
||||||
|
changed |= VI_BITMASK(VI_BBI_EVEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setScalingRegs(u16 panSizeX, u16 dispSizeX, BOOL is3D)
|
||||||
|
{
|
||||||
|
u32 scale;
|
||||||
|
|
||||||
|
panSizeX = (u16)(is3D ? panSizeX * 2 : panSizeX);
|
||||||
|
|
||||||
|
if (panSizeX < dispSizeX) {
|
||||||
|
scale = (256 * (u32)panSizeX + (u32)dispSizeX - 1) / (u32)dispSizeX;
|
||||||
|
|
||||||
|
regs[VI_HSR] = (u16)((((u32)(scale))) | (((u32)(1)) << 12));
|
||||||
|
changed |= VI_BITMASK(VI_HSR);
|
||||||
|
|
||||||
|
regs[VI_WIDTH] = (u16)((((u32)(panSizeX))));
|
||||||
|
changed |= VI_BITMASK(VI_WIDTH);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
regs[VI_HSR] = (u16)((((u32)(256))) | (((u32)(0)) << 12));
|
||||||
|
changed |= VI_BITMASK(VI_HSR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void calcFbbs(u32 bufAddr, u16 panPosX, u16 panPosY, u8 wordPerLine, VIXFBMode xfbMode, u16 dispPosY, u32 *tfbb, u32 *bfbb)
|
||||||
|
{
|
||||||
|
u32 bytesPerLine, xoffInWords;
|
||||||
|
xoffInWords = (u32)panPosX / 16;
|
||||||
|
bytesPerLine = (u32)wordPerLine * 32;
|
||||||
|
|
||||||
|
*tfbb = bufAddr + xoffInWords * 32 + bytesPerLine * panPosY;
|
||||||
|
*bfbb = (xfbMode == VI_XFBMODE_SF) ? *tfbb : (*tfbb + bytesPerLine);
|
||||||
|
|
||||||
|
if (dispPosY % 2 == 1) {
|
||||||
|
u32 tmp = *tfbb;
|
||||||
|
*tfbb = *bfbb;
|
||||||
|
*bfbb = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
*tfbb = ToPhysical(*tfbb);
|
||||||
|
*bfbb = ToPhysical(*bfbb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setFbbRegs(VIPositionInfo *hv, u32 *tfbb, u32 *bfbb, u32 *rtfbb, u32 *rbfbb)
|
||||||
|
{
|
||||||
|
u32 shifted;
|
||||||
|
calcFbbs(hv->bufAddr, hv->panPosX, hv->adjPanPosY, hv->wordPerLine, hv->xfbMode, hv->adjDispPosY, tfbb, bfbb);
|
||||||
|
|
||||||
|
if (hv->is3D) {
|
||||||
|
calcFbbs(hv->rbufAddr, hv->panPosX, hv->adjPanPosY, hv->wordPerLine, hv->xfbMode, hv->adjDispPosY, rtfbb, rbfbb);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IS_LOWER_16MB(*tfbb) && IS_LOWER_16MB(*bfbb) && IS_LOWER_16MB(*rtfbb) && IS_LOWER_16MB(*rbfbb)) {
|
||||||
|
shifted = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
shifted = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shifted) {
|
||||||
|
*tfbb >>= 5;
|
||||||
|
*bfbb >>= 5;
|
||||||
|
*rtfbb >>= 5;
|
||||||
|
*rbfbb >>= 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
regs[VI_TOP_FIELD_BASE_LEFT_U] = (u16)(*tfbb & 0xFFFF);
|
||||||
|
changed |= VI_BITMASK(VI_TOP_FIELD_BASE_LEFT_U);
|
||||||
|
|
||||||
|
regs[VI_TOP_FIELD_BASE_LEFT] = (u16)((((*tfbb >> 16))) | hv->xof << 8 | shifted << 12);
|
||||||
|
changed |= VI_BITMASK(VI_TOP_FIELD_BASE_LEFT);
|
||||||
|
|
||||||
|
regs[VI_BTTM_FIELD_BASE_LEFT_U] = (u16)(*bfbb & 0xFFFF);
|
||||||
|
changed |= VI_BITMASK(VI_BTTM_FIELD_BASE_LEFT_U);
|
||||||
|
|
||||||
|
regs[VI_BTTM_FIELD_BASE_LEFT] = (u16)(*bfbb >> 16);
|
||||||
|
changed |= VI_BITMASK(VI_BTTM_FIELD_BASE_LEFT);
|
||||||
|
|
||||||
|
if (hv->is3D) {
|
||||||
|
regs[VI_TOP_FIELD_BASE_RIGHT_U] = *rtfbb & 0xffff;
|
||||||
|
changed |= VI_BITMASK(VI_TOP_FIELD_BASE_RIGHT_U);
|
||||||
|
|
||||||
|
regs[VI_TOP_FIELD_BASE_RIGHT] = *rtfbb >> 16;
|
||||||
|
changed |= VI_BITMASK(VI_TOP_FIELD_BASE_RIGHT);
|
||||||
|
|
||||||
|
regs[VI_BTTM_FIELD_BASE_RIGHT_U] = *rbfbb & 0xFFFF;
|
||||||
|
changed |= VI_BITMASK(VI_BTTM_FIELD_BASE_RIGHT_U);
|
||||||
|
|
||||||
|
regs[VI_BTTM_FIELD_BASE_RIGHT] = *rbfbb >> 16;
|
||||||
|
changed |= VI_BITMASK(VI_BTTM_FIELD_BASE_RIGHT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setHorizontalRegs(VITimingInfo *tm, u16 dispPosX, u16 dispSizeX)
|
||||||
|
{
|
||||||
|
u32 hbe, hbs, hbeLo, hbeHi;
|
||||||
|
|
||||||
|
regs[VI_HORIZ_TIMING_0U] = (u16)tm->hlw;
|
||||||
|
changed |= VI_BITMASK(VI_HORIZ_TIMING_0U);
|
||||||
|
|
||||||
|
regs[VI_HORIZ_TIMING_0L] = (u16)(tm->hce | tm->hcs << 8);
|
||||||
|
changed |= VI_BITMASK(VI_HORIZ_TIMING_0L);
|
||||||
|
|
||||||
|
hbe = (u32)(tm->hbe640 - 40 + dispPosX);
|
||||||
|
hbs = (u32)(tm->hbs640 + 40 + dispPosX - (720 - dispSizeX));
|
||||||
|
|
||||||
|
hbeLo = hbe & ONES(9);
|
||||||
|
hbeHi = hbe >> 9;
|
||||||
|
|
||||||
|
regs[VI_HORIZ_TIMING_1U] = (u16)(tm->hsy | hbeLo << 7);
|
||||||
|
changed |= VI_BITMASK(VI_HORIZ_TIMING_1U);
|
||||||
|
|
||||||
|
regs[VI_HORIZ_TIMING_1L] = (u16)(hbeHi | hbs << 1);
|
||||||
|
changed |= VI_BITMASK(VI_HORIZ_TIMING_1L);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setVerticalRegs(u16 dispPosY, u16 dispSizeY, u8 equ, u16 acv, u16 prbOdd, u16 prbEven, u16 psbOdd, u16 psbEven, BOOL black)
|
||||||
|
{
|
||||||
|
u16 actualPrbOdd, actualPrbEven, actualPsbOdd, actualPsbEven, actualAcv, c, d;
|
||||||
|
|
||||||
|
if (equ >= 10) {
|
||||||
|
c = 1;
|
||||||
|
d = 2;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
c = 2;
|
||||||
|
d = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dispPosY % 2 == 0) {
|
||||||
|
actualPrbOdd = (u16)(prbOdd + d * dispPosY);
|
||||||
|
actualPsbOdd = (u16)(psbOdd + d * ((c * acv - dispSizeY) - dispPosY));
|
||||||
|
actualPrbEven = (u16)(prbEven + d * dispPosY);
|
||||||
|
actualPsbEven = (u16)(psbEven + d * ((c * acv - dispSizeY) - dispPosY));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
actualPrbOdd = (u16)(prbEven + d * dispPosY);
|
||||||
|
actualPsbOdd = (u16)(psbEven + d * ((c * acv - dispSizeY) - dispPosY));
|
||||||
|
actualPrbEven = (u16)(prbOdd + d * dispPosY);
|
||||||
|
actualPsbEven = (u16)(psbOdd + d * ((c * acv - dispSizeY) - dispPosY));
|
||||||
|
}
|
||||||
|
|
||||||
|
actualAcv = (u16)(dispSizeY / c);
|
||||||
|
|
||||||
|
if (black) {
|
||||||
|
actualPrbOdd += 2 * actualAcv - 2;
|
||||||
|
actualPsbOdd += 2;
|
||||||
|
actualPrbEven += 2 * actualAcv - 2;
|
||||||
|
actualPsbEven += 2;
|
||||||
|
actualAcv = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
regs[VI_VERT_TIMING] = (u16)(equ | actualAcv << 4);
|
||||||
|
changed |= VI_BITMASK(VI_VERT_TIMING);
|
||||||
|
|
||||||
|
regs[VI_VERT_TIMING_ODD_U] = (u16)actualPrbOdd << 0;
|
||||||
|
changed |= VI_BITMASK(VI_VERT_TIMING_ODD_U);
|
||||||
|
|
||||||
|
regs[VI_VERT_TIMING_ODD] = (u16)actualPsbOdd << 0;
|
||||||
|
changed |= VI_BITMASK(VI_VERT_TIMING_ODD);
|
||||||
|
|
||||||
|
regs[VI_VERT_TIMING_EVEN_U] = (u16)actualPrbEven << 0;
|
||||||
|
changed |= VI_BITMASK(VI_VERT_TIMING_EVEN_U);
|
||||||
|
|
||||||
|
regs[VI_VERT_TIMING_EVEN] = (u16)actualPsbEven << 0;
|
||||||
|
changed |= VI_BITMASK(VI_VERT_TIMING_EVEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PrintDebugPalCaution(void)
|
||||||
|
{
|
||||||
|
static u32 message = 0;
|
||||||
|
|
||||||
|
if (message == 0) {
|
||||||
|
message = 1;
|
||||||
|
OSReport("***************************************\n");
|
||||||
|
OSReport(" ! ! ! C A U T I O N ! ! ! \n");
|
||||||
|
OSReport("This TV format \"DEBUG_PAL\" is only for \n");
|
||||||
|
OSReport("temporary solution until PAL DAC board \n");
|
||||||
|
OSReport("is available. Please do NOT use this \n");
|
||||||
|
OSReport("mode in real games!!! \n");
|
||||||
|
OSReport("***************************************\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VIConfigure(const GXRenderModeObj *obj)
|
||||||
|
{
|
||||||
|
VITimingInfo *tm;
|
||||||
|
u32 regDspCfg;
|
||||||
|
BOOL enabled;
|
||||||
|
u32 newNonInter, tvInBootrom, tvInGame;
|
||||||
|
|
||||||
|
enabled = OSDisableInterrupts();
|
||||||
|
newNonInter = (u32)obj->viTVmode & 3;
|
||||||
|
|
||||||
|
if (HorVer.nonInter != newNonInter) {
|
||||||
|
changeMode = 1;
|
||||||
|
HorVer.nonInter = newNonInter;
|
||||||
|
}
|
||||||
|
|
||||||
|
tvInGame = (u32)obj->viTVmode >> 2;
|
||||||
|
tvInBootrom = *(u32 *)OSPhysicalToCached(0xCC);
|
||||||
|
|
||||||
|
if (tvInGame == VI_DEBUG_PAL) {
|
||||||
|
PrintDebugPalCaution();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((tvInGame == VI_NTSC) || (tvInGame == VI_MPAL)) {
|
||||||
|
HorVer.tv = tvInBootrom;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
HorVer.tv = tvInGame;
|
||||||
|
}
|
||||||
|
|
||||||
|
HorVer.dispPosX = obj->viXOrigin;
|
||||||
|
HorVer.dispPosY = (u16)((HorVer.nonInter == VI_NON_INTERLACE) ? (u16)(obj->viYOrigin * 2) : obj->viYOrigin);
|
||||||
|
HorVer.dispSizeX = obj->viWidth;
|
||||||
|
HorVer.fbSizeX = obj->fbWidth;
|
||||||
|
HorVer.fbSizeY = obj->xfbHeight;
|
||||||
|
HorVer.xfbMode = obj->xFBmode;
|
||||||
|
HorVer.panSizeX = HorVer.fbSizeX;
|
||||||
|
HorVer.panSizeY = HorVer.fbSizeY;
|
||||||
|
HorVer.panPosX = 0;
|
||||||
|
HorVer.panPosY = 0;
|
||||||
|
|
||||||
|
HorVer.dispSizeY = (u16)((HorVer.nonInter == VI_PROGRESSIVE) ? HorVer.panSizeY
|
||||||
|
: (HorVer.nonInter == VI_3D) ? HorVer.panSizeY
|
||||||
|
: (HorVer.xfbMode == VI_XFBMODE_SF) ? (u16)(2 * HorVer.panSizeY)
|
||||||
|
: HorVer.panSizeY);
|
||||||
|
|
||||||
|
HorVer.is3D = (HorVer.nonInter == VI_3D) ? TRUE : FALSE;
|
||||||
|
|
||||||
|
tm = getTiming((VITVMode)VI_TVMODE(HorVer.tv, HorVer.nonInter));
|
||||||
|
HorVer.timing = tm;
|
||||||
|
|
||||||
|
AdjustPosition(tm->acv);
|
||||||
|
if (encoderType == 0) {
|
||||||
|
HorVer.tv = VI_DEBUG;
|
||||||
|
}
|
||||||
|
setInterruptRegs(tm);
|
||||||
|
|
||||||
|
regDspCfg = regs[VI_DISP_CONFIG];
|
||||||
|
|
||||||
|
if ((HorVer.nonInter == VI_PROGRESSIVE) || (HorVer.nonInter == VI_3D)) {
|
||||||
|
regDspCfg = (((u32)(regDspCfg)) & ~0x00000004) | (((u32)(1)) << 2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
regDspCfg = (((u32)(regDspCfg)) & ~0x00000004) | (((u32)(HorVer.nonInter & 1)) << 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
regDspCfg = (((u32)(regDspCfg)) & ~0x00000008) | (((u32)(HorVer.is3D)) << 3);
|
||||||
|
|
||||||
|
if ((HorVer.tv == VI_DEBUG_PAL) || (HorVer.tv == VI_EURGB60)) {
|
||||||
|
regDspCfg = (((u32)(regDspCfg)) & ~0x00000300) | (((u32)(0)) << 8);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
regDspCfg = (((u32)(regDspCfg)) & ~0x00000300) | (((u32)(HorVer.tv)) << 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
regs[VI_DISP_CONFIG] = (u16)regDspCfg;
|
||||||
|
changed |= VI_BITMASK(0x01);
|
||||||
|
|
||||||
|
regDspCfg = regs[VI_CLOCK_SEL];
|
||||||
|
if (obj->viTVmode == VI_TVMODE_NTSC_PROG || obj->viTVmode == VI_TVMODE_NTSC_3D) {
|
||||||
|
regDspCfg = (u32)(regDspCfg & ~0x1) | 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
regDspCfg = (u32)(regDspCfg & ~0x1);
|
||||||
|
}
|
||||||
|
|
||||||
|
regs[VI_CLOCK_SEL] = (u16)regDspCfg;
|
||||||
|
|
||||||
|
changed |= 0x200;
|
||||||
|
|
||||||
|
setScalingRegs(HorVer.panSizeX, HorVer.dispSizeX, HorVer.is3D);
|
||||||
|
setHorizontalRegs(tm, HorVer.adjDispPosX, HorVer.dispSizeX);
|
||||||
|
setBBIntervalRegs(tm);
|
||||||
|
setPicConfig(HorVer.fbSizeX, HorVer.xfbMode, HorVer.panPosX, HorVer.panSizeX, &HorVer.wordPerLine, &HorVer.std, &HorVer.wpl, &HorVer.xof);
|
||||||
|
|
||||||
|
if (FBSet) {
|
||||||
|
setFbbRegs(&HorVer, &HorVer.tfbb, &HorVer.bfbb, &HorVer.rtfbb, &HorVer.rbfbb);
|
||||||
|
}
|
||||||
|
|
||||||
|
setVerticalRegs(HorVer.adjDispPosY, HorVer.adjDispSizeY, tm->equ, tm->acv, tm->prbOdd, tm->prbEven, tm->psbOdd, tm->psbEven, HorVer.isBlack);
|
||||||
|
OSRestoreInterrupts(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VIConfigurePan(u16 xOrg, u16 yOrg, u16 width, u16 height)
|
||||||
|
{
|
||||||
|
BOOL enabled;
|
||||||
|
VITimingInfo *tm;
|
||||||
|
|
||||||
|
enabled = OSDisableInterrupts();
|
||||||
|
HorVer.panPosX = xOrg;
|
||||||
|
HorVer.panPosY = yOrg;
|
||||||
|
HorVer.panSizeX = width;
|
||||||
|
HorVer.panSizeY = height;
|
||||||
|
HorVer.dispSizeY = (HorVer.nonInter == 2) ? HorVer.panSizeY
|
||||||
|
: (HorVer.nonInter == 3) ? HorVer.panSizeY
|
||||||
|
: (HorVer.xfbMode == VI_XFBMODE_SF) ? (u16)(HorVer.panSizeY * 2)
|
||||||
|
: HorVer.panSizeY;
|
||||||
|
tm = HorVer.timing;
|
||||||
|
AdjustPosition(tm->acv);
|
||||||
|
setScalingRegs(HorVer.panSizeX, HorVer.dispSizeX, HorVer.is3D);
|
||||||
|
setPicConfig(HorVer.fbSizeX, HorVer.xfbMode, HorVer.panPosX, HorVer.panSizeX, &HorVer.wordPerLine, &HorVer.std, &HorVer.wpl, &HorVer.xof);
|
||||||
|
if (FBSet != 0) {
|
||||||
|
setFbbRegs(&HorVer, &HorVer.tfbb, &HorVer.bfbb, &HorVer.rtfbb, &HorVer.rbfbb);
|
||||||
|
}
|
||||||
|
setVerticalRegs(HorVer.adjDispPosY, HorVer.dispSizeY, tm->equ, tm->acv, tm->prbOdd, tm->prbEven, tm->psbOdd, tm->psbEven, HorVer.isBlack);
|
||||||
|
OSRestoreInterrupts(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VIFlush(void)
|
||||||
|
{
|
||||||
|
BOOL enabled;
|
||||||
|
s32 regIndex;
|
||||||
|
u32 val; // for stack.
|
||||||
|
|
||||||
|
enabled = OSDisableInterrupts();
|
||||||
|
shdwChangeMode |= changeMode;
|
||||||
|
changeMode = 0;
|
||||||
|
shdwChanged |= changed;
|
||||||
|
|
||||||
|
while (changed) {
|
||||||
|
regIndex = cntlzd(changed);
|
||||||
|
shdwRegs[regIndex] = regs[regIndex];
|
||||||
|
changed &= ~VI_BITMASK(regIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
flushFlag = 1;
|
||||||
|
OSRestoreInterrupts(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VISetNextFrameBuffer(void *fb)
|
||||||
|
{
|
||||||
|
BOOL enabled = OSDisableInterrupts();
|
||||||
|
HorVer.bufAddr = (u32)fb;
|
||||||
|
FBSet = 1;
|
||||||
|
setFbbRegs(&HorVer, &HorVer.tfbb, &HorVer.bfbb, &HorVer.rtfbb, &HorVer.rbfbb);
|
||||||
|
OSRestoreInterrupts(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *VIGetNextFrameBuffer()
|
||||||
|
{
|
||||||
|
// UNUSED FUNCTION
|
||||||
|
}
|
||||||
|
|
||||||
|
void *VIGetCurrentFrameBuffer(void)
|
||||||
|
{
|
||||||
|
return (void *)CurrBufAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VISetNextRightFrameBuffer(void *fb)
|
||||||
|
{
|
||||||
|
// UNUSED FUNCTION
|
||||||
|
}
|
||||||
|
|
||||||
|
void VISetBlack(BOOL isBlack)
|
||||||
|
{
|
||||||
|
int interrupt;
|
||||||
|
VITimingInfo *tm;
|
||||||
|
|
||||||
|
interrupt = OSDisableInterrupts();
|
||||||
|
HorVer.isBlack = isBlack;
|
||||||
|
tm = HorVer.timing;
|
||||||
|
setVerticalRegs(HorVer.adjDispPosY, HorVer.dispSizeY, tm->equ, tm->acv, tm->prbOdd, tm->prbEven, tm->psbOdd, tm->psbEven, HorVer.isBlack);
|
||||||
|
OSRestoreInterrupts(interrupt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VISet3D(void)
|
||||||
|
{
|
||||||
|
// UNUSED FUNCTION
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 VIGetRetraceCount(void)
|
||||||
|
{
|
||||||
|
return retraceCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 getCurrentHalfLine(void)
|
||||||
|
{
|
||||||
|
u32 hcount;
|
||||||
|
u32 vcount0;
|
||||||
|
u32 vcount;
|
||||||
|
|
||||||
|
vcount = __VIRegs[22] & 0x7FF;
|
||||||
|
do {
|
||||||
|
vcount0 = vcount;
|
||||||
|
hcount = __VIRegs[23] & 0x7FF;
|
||||||
|
vcount = __VIRegs[22] & 0x7FF;
|
||||||
|
} while (vcount0 != vcount);
|
||||||
|
return ((vcount - 1) * 2) + ((hcount - 1) / CurrTiming->hlw);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 getCurrentFieldEvenOdd()
|
||||||
|
{
|
||||||
|
return (getCurrentHalfLine() < CurrTiming->numHalfLines) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 VIGetNextField(void)
|
||||||
|
{
|
||||||
|
u32 nextField;
|
||||||
|
int interrupt;
|
||||||
|
|
||||||
|
interrupt = OSDisableInterrupts();
|
||||||
|
nextField = getCurrentFieldEvenOdd() ^ 1;
|
||||||
|
OSRestoreInterrupts(interrupt);
|
||||||
|
return nextField ^ (HorVer.adjDispPosY & 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 VIGetCurrentLine(void)
|
||||||
|
{
|
||||||
|
u32 line;
|
||||||
|
VITimingInfo *tm;
|
||||||
|
int interrupt;
|
||||||
|
|
||||||
|
tm = CurrTiming;
|
||||||
|
interrupt = OSDisableInterrupts();
|
||||||
|
line = getCurrentHalfLine();
|
||||||
|
OSRestoreInterrupts(interrupt);
|
||||||
|
|
||||||
|
if (line >= tm->numHalfLines) {
|
||||||
|
line -= tm->numHalfLines;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (line >> 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 VIGetTvFormat(void)
|
||||||
|
{
|
||||||
|
u32 fmt;
|
||||||
|
int interrupt;
|
||||||
|
|
||||||
|
interrupt = OSDisableInterrupts();
|
||||||
|
|
||||||
|
switch (CurrTvMode) {
|
||||||
|
case VI_NTSC:
|
||||||
|
case VI_DEBUG:
|
||||||
|
fmt = VI_NTSC;
|
||||||
|
break;
|
||||||
|
case VI_PAL:
|
||||||
|
case VI_DEBUG_PAL:
|
||||||
|
fmt = VI_PAL;
|
||||||
|
break;
|
||||||
|
case VI_EURGB60:
|
||||||
|
case VI_MPAL:
|
||||||
|
fmt = CurrTvMode;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
OSRestoreInterrupts(interrupt);
|
||||||
|
return fmt;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 VIGetDTVStatus(void)
|
||||||
|
{
|
||||||
|
u32 stat;
|
||||||
|
int interrupt;
|
||||||
|
|
||||||
|
interrupt = OSDisableInterrupts();
|
||||||
|
stat = (__VIRegs[VI_DTV_STAT] & 3);
|
||||||
|
OSRestoreInterrupts(interrupt);
|
||||||
|
return (stat & 1);
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue