mirror of https://github.com/zeldaret/tp.git
1219 lines
38 KiB
C
1219 lines
38 KiB
C
//
|
|
// Generated By: dol2asm
|
|
// Translation Unit: vi
|
|
//
|
|
|
|
#include "dolphin/vi.h"
|
|
#include "dol2asm.h"
|
|
#include "dolphin/gx.h"
|
|
#include "dolphin/os.h"
|
|
|
|
#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)))
|
|
|
|
#define VI_VERT_TIMING (0)
|
|
#define VI_DISP_CONFIG (1)
|
|
#define VI_HORIZ_TIMING_0L (2)
|
|
#define VI_HORIZ_TIMING_0U (3)
|
|
#define VI_HORIZ_TIMING_1L (4)
|
|
#define VI_HORIZ_TIMING_1U (5)
|
|
#define VI_VERT_TIMING_ODD (6)
|
|
#define VI_VERT_TIMING_ODD_U (7)
|
|
#define VI_VERT_TIMING_EVEN (8)
|
|
#define VI_VERT_TIMING_EVEN_U (9)
|
|
|
|
#define VI_BBI_ODD (10) // burst blanking interval
|
|
#define VI_BBI_ODD_U (11) // burst blanking interval
|
|
#define VI_BBI_EVEN (12) // burst blanking interval
|
|
#define VI_BBI_EVEN_U (13) // burst blanking interval
|
|
|
|
#define VI_TOP_FIELD_BASE_LEFT (14) // top in 2d, top of left pic in 3d
|
|
#define VI_TOP_FIELD_BASE_LEFT_U (15) // top in 2d, top of left pic in 3d
|
|
|
|
#define VI_TOP_FIELD_BASE_RIGHT (16) // top of right pic in 3d
|
|
#define VI_TOP_FIELD_BASE_RIGHT_U (17) // top of right pic in 3d
|
|
|
|
#define VI_BTTM_FIELD_BASE_LEFT (18) // bottom in 2d, bottom of left pic in 3d
|
|
#define VI_BTTM_FIELD_BASE_LEFT_U (19) // bottom in 2d, bottom of left pic in 3d
|
|
|
|
#define VI_BTTM_FIELD_BASE_RIGHT (20) // bottom of right pic in 3d
|
|
#define VI_BTTM_FIELD_BASE_RIGHT_U (21) // bottom of right pic in 3d
|
|
|
|
#define VI_VERT_COUNT (22) // vertical display position
|
|
#define VI_HORIZ_COUNT (23) // horizontal display position
|
|
|
|
#define VI_DISP_INT_0 (24) // display interrupt 0L
|
|
#define VI_DISP_INT_0U (25) // display interrupt 0U
|
|
#define VI_DISP_INT_1 (26) // display interrupt 1L
|
|
#define VI_DISP_INT_1U (27) // display interrupt 1U
|
|
#define VI_DISP_INT_2 (28) // display interrupt 2L
|
|
#define VI_DISP_INT_2U (29) // display interrupt 2U
|
|
#define VI_DISP_INT_3 (30) // display interrupt 3L
|
|
#define VI_DISP_INT_3U (31) // display interrupt 3U
|
|
|
|
#define VI_HSW (36) // horizontal scaling width
|
|
#define VI_HSR (37) // horizontal scaling register
|
|
|
|
#define VI_FCT_0 (38) // filter coefficient table 0L
|
|
#define VI_FCT_0U (39) // filter coefficient table 0U
|
|
#define VI_FCT_1 (40) // filter coefficient table 1L
|
|
#define VI_FCT_1U (41) // filter coefficient table 1U
|
|
#define VI_FCT_2 (42) // filter coefficient table 2L
|
|
#define VI_FCT_2U (43) // filter coefficient table 2U
|
|
#define VI_FCT_3 (44) // filter coefficient table 3L
|
|
#define VI_FCT_3U (45) // filter coefficient table 3U
|
|
#define VI_FCT_4 (46) // filter coefficient table 4L
|
|
#define VI_FCT_4U (47) // filter coefficient table 4U
|
|
#define VI_FCT_5 (48) // filter coefficient table 5L
|
|
#define VI_FCT_5U (49) // filter coefficient table 5U
|
|
#define VI_FCT_6 (50) // filter coefficient table 6L
|
|
#define VI_FCT_6U (51) // filter coefficient table 6U
|
|
|
|
#define VI_CLOCK_SEL (54) // clock select
|
|
#define VI_DTV_STAT (55) // DTV status
|
|
|
|
#define VI_WIDTH (56)
|
|
|
|
void __VIGetCurrentPosition(s16* x, s16* y);
|
|
static u32 getCurrentFieldEvenOdd();
|
|
|
|
//
|
|
// External References:
|
|
//
|
|
|
|
void SIRefreshSamplingRate();
|
|
void __shl2i();
|
|
void __shr2u();
|
|
|
|
//
|
|
// Declarations:
|
|
//
|
|
|
|
/* ############################################################################################## */
|
|
/* 8044CA28-8044CAA0 079748 0076+02 8/8 0/0 0/0 .bss regs */
|
|
static vu16 regs[59];
|
|
|
|
/* 804517E0-804517E4 000CE0 0004+00 1/1 0/0 0/0 .sbss IsInitialized */
|
|
static BOOL IsInitialized;
|
|
|
|
/* 804517E4-804517E8 000CE4 0004+00 4/3 0/0 0/0 .sbss retraceCount */
|
|
static vu32 retraceCount;
|
|
|
|
/* 804517E8-804517EC 000CE8 0004+00 3/3 0/0 0/0 .sbss flushFlag */
|
|
static u32 flushFlag;
|
|
|
|
/* 804517EC-804517F4 000CEC 0008+00 3/3 0/0 0/0 .sbss retraceQueue */
|
|
static OSThreadQueue retraceQueue;
|
|
|
|
/* 804517F4-804517F8 000CF4 0004+00 3/3 0/0 0/0 .sbss PreCB */
|
|
static VIRetraceCallback PreCB;
|
|
|
|
/* 804517F8-804517FC 000CF8 0004+00 3/3 0/0 0/0 .sbss PostCB */
|
|
static VIRetraceCallback PostCB;
|
|
|
|
/* 804517FC-80451800 000CFC 0004+00 1/1 0/0 0/0 .sbss PositionCallback */
|
|
static VIPositionCallback PositionCallback;
|
|
|
|
/* 80451800-80451804 000D00 0004+00 2/2 0/0 0/0 .sbss encoderType */
|
|
static u32 encoderType;
|
|
|
|
/* 80451804 0002+00 data_80451804 displayOffsetH */
|
|
static s16 displayOffsetH;
|
|
|
|
/* 80451806 0002+00 data_80451806 displayOffsetV */
|
|
static s16 displayOffsetV;
|
|
|
|
/* 80451808-80451810 000D08 0004+04 3/3 0/0 0/0 .sbss changeMode */
|
|
static vu32 changeMode;
|
|
|
|
/* 80451810-80451814 000D10 0004+00 5/5 0/0 0/0 .sbss changed */
|
|
static vu64 changed;
|
|
|
|
/* 80451818-80451820 000D18 0004+04 3/3 0/0 0/0 .sbss shdwChangeMode */
|
|
static vu32 shdwChangeMode;
|
|
|
|
/* 80451820-80451824 000D20 0004+00 3/3 0/0 0/0 .sbss shdwChanged */
|
|
static vu64 shdwChanged;
|
|
|
|
/* 80451828-8045182C 000D28 0004+00 6/6 0/0 0/0 .sbss CurrTiming */
|
|
static VITimingInfo* CurrTiming;
|
|
|
|
/* 8045182C-80451830 000D2C 0004+00 3/3 0/0 0/0 .sbss CurrTvMode */
|
|
static u32 CurrTvMode;
|
|
|
|
/* 80451830-80451834 000D30 0004+00 3/2 0/0 0/0 .sbss NextBufAddr */
|
|
static u32 NextBufAddr;
|
|
|
|
/* 80451834-80451838 000D34 0004+00 2/1 0/0 0/0 .sbss CurrBufAddr */
|
|
static u32 CurrBufAddr;
|
|
|
|
/* ############################################################################################## */
|
|
/* 8044CAA0-8044CB18 0797C0 0076+02 0/0 0/0 0/0 .bss shdwRegs */
|
|
#pragma push
|
|
#pragma force_active on
|
|
static vu16 shdwRegs[59];
|
|
#pragma pop
|
|
|
|
/* 8044CB18-8044CB70 079838 0058+00 2/5 0/0 0/0 .bss HorVer */
|
|
static VIPositionInfo HorVer;
|
|
|
|
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;
|
|
CurrBufAddr = NextBufAddr;
|
|
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/* 8034BF6C-8034C1E0 3468AC 0274+00 1/1 0/0 0/0 .text __VIRetraceHandler */
|
|
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)) {
|
|
OSClearContext(&exceptionContext);
|
|
OSSetCurrentContext(&exceptionContext);
|
|
if (PositionCallback) {
|
|
s16 x, y;
|
|
__VIGetCurrentPosition(&x, &y);
|
|
(*PositionCallback)(x, y);
|
|
}
|
|
OSClearContext(&exceptionContext);
|
|
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);
|
|
}
|
|
|
|
/* 8034C1E0-8034C224 346B20 0044+00 0/0 4/4 0/0 .text VISetPreRetraceCallback */
|
|
VIRetraceCallback VISetPreRetraceCallback(VIRetraceCallback cb) {
|
|
VIRetraceCallback prevCb = PreCB;
|
|
BOOL enable = OSDisableInterrupts();
|
|
PreCB = cb;
|
|
OSRestoreInterrupts(enable);
|
|
return prevCb;
|
|
}
|
|
|
|
/* 8034C224-8034C268 346B64 0044+00 0/0 4/4 2/2 .text VISetPostRetraceCallback */
|
|
VIRetraceCallback VISetPostRetraceCallback(VIRetraceCallback cb) {
|
|
VIRetraceCallback prevCb = PostCB;
|
|
BOOL enable = OSDisableInterrupts();
|
|
PostCB = cb;
|
|
OSRestoreInterrupts(enable);
|
|
return prevCb;
|
|
}
|
|
|
|
/* ############################################################################################## */
|
|
/* 803D1760-803D17A4 02E880 0044+00 4/3 0/0 0/0 .data @1 */
|
|
SECTION_DATA static char lit_1[] =
|
|
"<< Dolphin SDK - VI\trelease build: Apr 7 2004 04:13:59 (0x2301) >>";
|
|
|
|
/* 803D17A4-803D1920 02E8C4 017C+00 0/1 0/0 0/0 .data timing */
|
|
static VITimingInfo timing[10] = {
|
|
{
|
|
// 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,
|
|
},
|
|
{
|
|
// GCA INT
|
|
6, 241, 24, 25, 1, 0, 12, 13, 12, 13, 520, 519,
|
|
520, 519, 525, 429, 64, 71, 105, 159, 370, 122, 412,
|
|
},
|
|
{
|
|
// GCA DS
|
|
12, 480, 48, 48, 6, 6, 24, 24, 24, 24, 1038, 1038,
|
|
1038, 1038, 1050, 429, 64, 71, 105, 180, 391, 122, 412,
|
|
},
|
|
};
|
|
|
|
/* 803D1920-803D1954 02EA40 0032+02 0/1 0/0 0/0 .data taps */
|
|
#pragma push
|
|
#pragma force_active on
|
|
static u16 taps[26] = {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, 0};
|
|
#pragma pop
|
|
|
|
/* 80451838-8045183C 000D38 0004+00 2/2 0/0 0/0 .sbss FBSet */
|
|
static u32 FBSet;
|
|
|
|
/* 8045183C-80451840 000D3C 0004+00 1/1 0/0 0/0 .sbss timingExtra */
|
|
static VITimingInfo* timingExtra;
|
|
|
|
/* 8034C268-8034C310 346BA8 00A8+00 4/3 0/0 0/0 .text getTiming */
|
|
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];
|
|
|
|
case VI_TVMODE_GCA_INT:
|
|
return &timing[8];
|
|
case VI_TVMODE_GCA_PROG:
|
|
return &timing[9];
|
|
|
|
case 29:
|
|
case 30:
|
|
case 28:
|
|
return timingExtra;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/* 8034C310-8034C514 346C50 0204+00 1/1 0/0 0/0 .text __VIInit */
|
|
#ifdef NONMATCHING
|
|
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 && mode != VI_TVMODE_GCA_PROG) {
|
|
__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;
|
|
}
|
|
}
|
|
#else
|
|
#pragma push
|
|
#pragma optimization_level 0
|
|
#pragma optimizewithasm off
|
|
asm void __VIInit() {
|
|
nofralloc
|
|
#include "asm/dolphin/vi/vi/__VIInit.s"
|
|
}
|
|
#pragma pop
|
|
#endif
|
|
|
|
/* 80450A10-80450A14 -00001 0004+00 1/1 0/0 0/0 .sdata __VIVersion */
|
|
SECTION_SDATA static void* __VIVersion = (void*)&lit_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);
|
|
}
|
|
|
|
/* 8034C514-8034C9C4 346E54 04B0+00 0/0 1/1 0/0 .text VIInit */
|
|
void VIInit(void) {
|
|
u16 dspCfg;
|
|
u32 value, tv, tvInBootrom;
|
|
|
|
if (IsInitialized) {
|
|
return;
|
|
}
|
|
|
|
OSRegisterVersion(__VIVersion);
|
|
IsInitialized = TRUE;
|
|
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();
|
|
tvInBootrom = *(u32*)OSPhysicalToCached(0xCC);
|
|
dspCfg = __VIRegs[VI_DISP_CONFIG];
|
|
|
|
HorVer.nonInter = ((((u32)(dspCfg)) >> 2 & 0x00000001));
|
|
HorVer.tv = ((((u32)(dspCfg)) & 0x00000300) >> 8);
|
|
|
|
if ((tvInBootrom == VI_PAL) && (HorVer.tv == VI_NTSC)) {
|
|
HorVer.tv = VI_EURGB60;
|
|
}
|
|
|
|
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 = NULL;
|
|
PostCB = NULL;
|
|
|
|
__OSSetInterruptHandler(24, __VIRetraceHandler);
|
|
__OSUnmaskInterrupts((0x80000000u >> (24)));
|
|
}
|
|
|
|
/* 8034C9C4-8034CA18 347304 0054+00 0/0 10/10 0/0 .text VIWaitForRetrace */
|
|
void VIWaitForRetrace() {
|
|
BOOL enable = OSDisableInterrupts();
|
|
u32 startVal = retraceCount;
|
|
|
|
do {
|
|
OSSleepThread(&retraceQueue);
|
|
} while (startVal == retraceCount);
|
|
|
|
OSRestoreInterrupts(enable);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
/* 8034CA18-8034CCEC 347358 02D4+00 2/2 0/0 0/0 .text setFbbRegs */
|
|
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);
|
|
}
|
|
|
|
/* 8034CCEC-8034CE8C 34762C 01A0+00 2/2 0/0 0/0 .text setVerticalRegs */
|
|
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 (regs[VI_CLOCK_SEL] & 1) {
|
|
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);
|
|
}
|
|
|
|
/* 80451840-80451848 000D40 0004+04 1/1 0/0 0/0 .sbss message$351 */
|
|
static u32 message;
|
|
|
|
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");
|
|
}
|
|
}
|
|
|
|
/* 803D1AD8-803D1B24 02EBF8 004B+01 0/1 0/0 0/0 .data @538 */
|
|
#pragma push
|
|
#pragma force_active on
|
|
SECTION_DATA static char lit_538[] =
|
|
"VIConfigure(): Tried to change mode from (%d) to (%d), which is forbidden\n";
|
|
#pragma pop
|
|
|
|
/* 80450A14-80450A1C 000494 0005+03 1/1 0/0 0/0 .sdata @537 */
|
|
SECTION_SDATA static char lit_537[] = "vi.c";
|
|
|
|
/* 8034CE8C-8034D694 3477CC 0808+00 0/0 2/2 0/0 .text VIConfigure */
|
|
#ifdef NONMATCHING
|
|
void VIConfigure(const GXRenderModeObj* obj) {
|
|
VITimingInfo* tm;
|
|
u32 regDspCfg;
|
|
BOOL enabled;
|
|
u32 newNonInter, tvInBootrom, tvInGame;
|
|
|
|
enabled = OSDisableInterrupts();
|
|
newNonInter = (u32)obj->vi_tv_mode & 3;
|
|
|
|
if (HorVer.nonInter != newNonInter) {
|
|
changeMode = 1;
|
|
HorVer.nonInter = newNonInter;
|
|
}
|
|
|
|
tvInGame = (u32)obj->vi_tv_mode >> 2;
|
|
tvInBootrom = *(u32*)OSPhysicalToCached(0xCC);
|
|
|
|
if (tvInGame == VI_DEBUG_PAL) {
|
|
PrintDebugPalCaution();
|
|
}
|
|
|
|
switch (tvInBootrom) {
|
|
case VI_MPAL:
|
|
case VI_NTSC:
|
|
case VI_GCA:
|
|
case 7:
|
|
if (tvInGame == VI_NTSC || tvInGame == VI_MPAL || tvInGame == VI_GCA) {
|
|
break;
|
|
}
|
|
goto panic;
|
|
case VI_PAL:
|
|
case VI_EURGB60:
|
|
if (tvInGame == VI_PAL || tvInGame == VI_EURGB60) {
|
|
break;
|
|
}
|
|
default:
|
|
panic:
|
|
OSPanic(__FILE__, 1979,
|
|
"VIConfigure(): Tried to change mode from (%d) to (%d), which is forbidden\n",
|
|
tvInBootrom, tvInGame);
|
|
}
|
|
|
|
if ((tvInGame == VI_NTSC) || (tvInGame == VI_MPAL)) {
|
|
HorVer.tv = tvInBootrom;
|
|
} else {
|
|
HorVer.tv = tvInGame;
|
|
}
|
|
|
|
HorVer.dispPosX = obj->vi_x_origin;
|
|
HorVer.dispPosY = (u16)((HorVer.nonInter == VI_NON_INTERLACE) ? (u16)(obj->vi_y_origin * 2) :
|
|
obj->vi_y_origin);
|
|
HorVer.dispSizeX = obj->vi_width;
|
|
HorVer.fbSizeX = obj->fb_width;
|
|
HorVer.fbSizeY = obj->xfb_height;
|
|
HorVer.xfbMode = obj->xfb_mode;
|
|
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];
|
|
// TODO: USE BIT MACROS OR SOMETHING
|
|
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) || (HorVer.tv == VI_GCA)) {
|
|
regDspCfg = (((u32)(regDspCfg)) & ~0x00000300);
|
|
} 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->vi_tv_mode == VI_TVMODE_NTSC_PROG || obj->vi_tv_mode == VI_TVMODE_NTSC_3D ||
|
|
obj->vi_tv_mode == VI_TVMODE_GCA_PROG)
|
|
{
|
|
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);
|
|
}
|
|
#else
|
|
#pragma push
|
|
#pragma optimization_level 0
|
|
#pragma optimizewithasm off
|
|
asm void VIConfigure(const GXRenderModeObj*) {
|
|
nofralloc
|
|
#include "asm/dolphin/vi/vi/VIConfigure.s"
|
|
}
|
|
#pragma pop
|
|
#endif
|
|
|
|
/* 8034D694-8034D7C4 347FD4 0130+00 0/0 9/9 0/0 .text VIFlush */
|
|
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;
|
|
NextBufAddr = HorVer.bufAddr;
|
|
OSRestoreInterrupts(enabled);
|
|
}
|
|
|
|
/* 8034D7C4-8034D830 348104 006C+00 0/0 3/3 0/0 .text VISetNextFrameBuffer */
|
|
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);
|
|
}
|
|
|
|
/* 8034D830-8034D838 -00001 0008+00 0/0 0/0 0/0 .text VIGetNextFrameBuffer */
|
|
void* VIGetNextFrameBuffer() {
|
|
return *(void**)(&NextBufAddr);
|
|
}
|
|
|
|
/* 8034D838-8034D840 -00001 0008+00 0/0 0/0 0/0 .text VIGetCurrentFrameBuffer */
|
|
void* VIGetCurrentFrameBuffer() {
|
|
return *(void**)(&CurrBufAddr);
|
|
}
|
|
|
|
/* 8034D840-8034D8BC 348180 007C+00 0/0 7/7 0/0 .text VISetBlack */
|
|
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);
|
|
}
|
|
|
|
/* 8034D8BC-8034D8C4 -00001 0008+00 0/0 0/0 0/0 .text VIGetRetraceCount */
|
|
u32 VIGetRetraceCount() {
|
|
return retraceCount;
|
|
}
|
|
|
|
/* 8034D8C4-8034D900 348204 003C+00 1/1 0/0 0/0 .text GetCurrentDisplayPosition */
|
|
static void GetCurrentDisplayPosition(u32* hct, u32* vct) {
|
|
u32 hcount, vcount0, vcount;
|
|
vcount = __VIRegs[VI_VERT_COUNT] & 0x7FF;
|
|
|
|
do {
|
|
vcount0 = vcount;
|
|
hcount = __VIRegs[VI_HORIZ_COUNT] & 0x7FF;
|
|
vcount = __VIRegs[VI_VERT_COUNT] & 0x7FF;
|
|
} while (vcount0 != vcount);
|
|
|
|
*hct = hcount;
|
|
*vct = vcount;
|
|
}
|
|
|
|
static u32 getCurrentHalfLine(void) {
|
|
u32 hcount, vcount;
|
|
GetCurrentDisplayPosition(&hcount, &vcount);
|
|
|
|
return ((vcount - 1) << 1) + ((hcount - 1) / CurrTiming->hlw);
|
|
}
|
|
|
|
/* 8034D900-8034D968 348240 0068+00 1/1 0/0 0/0 .text getCurrentFieldEvenOdd */
|
|
static u32 getCurrentFieldEvenOdd() {
|
|
return (getCurrentHalfLine() < CurrTiming->numHalfLines) ? 1 : 0;
|
|
}
|
|
|
|
/* 8034D968-8034DA04 3482A8 009C+00 0/0 0/0 2/2 .text VIGetNextField */
|
|
u32 VIGetNextField(void) {
|
|
u32 nextField;
|
|
int interrupt;
|
|
|
|
interrupt = OSDisableInterrupts();
|
|
nextField = getCurrentFieldEvenOdd() ^ 1;
|
|
OSRestoreInterrupts(interrupt);
|
|
return nextField ^ (HorVer.adjDispPosY & 1);
|
|
}
|
|
|
|
/* 8034DA04-8034DA9C 348344 0098+00 0/0 1/1 0/0 .text VIGetCurrentLine */
|
|
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);
|
|
}
|
|
|
|
/* 8034DA9C-8034DB04 3483DC 0068+00 1/0 2/2 1/1 .text VIGetTvFormat */
|
|
u32 VIGetTvFormat(void) {
|
|
u32 fmt;
|
|
int interrupt;
|
|
|
|
interrupt = OSDisableInterrupts();
|
|
|
|
switch (CurrTvMode) {
|
|
case VI_NTSC:
|
|
case VI_DEBUG:
|
|
case VI_GCA:
|
|
case 7:
|
|
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;
|
|
}
|
|
|
|
/* 8034DB04-8034DB40 348444 003C+00 0/0 2/2 0/0 .text VIGetDTVStatus */
|
|
u32 VIGetDTVStatus() {
|
|
u32 val;
|
|
BOOL enable = OSDisableInterrupts();
|
|
val = __VIRegs[55] & 3;
|
|
OSRestoreInterrupts(enable);
|
|
return val & 1;
|
|
}
|
|
|
|
/* 8034DB40-8034DD5C 348480 021C+00 1/1 0/0 0/0 .text __VIDisplayPositionToXY */
|
|
void __VIDisplayPositionToXY(u32 hcount, u32 vcount, s16* x, s16* y) {
|
|
u32 halfLine = ((vcount - 1) << 1) + ((hcount - 1) / CurrTiming->hlw);
|
|
|
|
if (HorVer.nonInter == VI_INTERLACE) {
|
|
if (halfLine < CurrTiming->numHalfLines) {
|
|
if (halfLine < CurrTiming->equ * 3 + CurrTiming->prbOdd) {
|
|
*y = -1;
|
|
} else if (halfLine >= CurrTiming->numHalfLines - CurrTiming->psbOdd) {
|
|
*y = -1;
|
|
} else {
|
|
*y = (s16)((halfLine - CurrTiming->equ * 3 - CurrTiming->prbOdd) & ~1);
|
|
}
|
|
} else {
|
|
halfLine -= CurrTiming->numHalfLines;
|
|
|
|
if (halfLine < CurrTiming->equ * 3 + CurrTiming->prbEven) {
|
|
*y = -1;
|
|
} else if (halfLine >= CurrTiming->numHalfLines - CurrTiming->psbEven) {
|
|
*y = -1;
|
|
} else {
|
|
*y = (s16)(((halfLine - CurrTiming->equ * 3 - CurrTiming->prbEven) & ~1) + 1);
|
|
}
|
|
}
|
|
} else if (HorVer.nonInter == VI_NON_INTERLACE) {
|
|
if (halfLine >= CurrTiming->numHalfLines) {
|
|
halfLine -= CurrTiming->numHalfLines;
|
|
}
|
|
|
|
if (halfLine < CurrTiming->equ * 3 + CurrTiming->prbOdd) {
|
|
*y = -1;
|
|
} else if (halfLine >= CurrTiming->numHalfLines - CurrTiming->psbOdd) {
|
|
*y = -1;
|
|
} else {
|
|
*y = (s16)((halfLine - CurrTiming->equ * 3 - CurrTiming->prbOdd) & ~1);
|
|
}
|
|
} else if (HorVer.nonInter == VI_PROGRESSIVE) {
|
|
if (halfLine < CurrTiming->numHalfLines) {
|
|
if (halfLine < CurrTiming->equ * 3 + CurrTiming->prbOdd) {
|
|
*y = -1;
|
|
} else if (halfLine >= CurrTiming->numHalfLines - CurrTiming->psbOdd) {
|
|
*y = -1;
|
|
} else {
|
|
*y = (s16)(halfLine - CurrTiming->equ * 3 - CurrTiming->prbOdd);
|
|
}
|
|
} else {
|
|
halfLine -= CurrTiming->numHalfLines;
|
|
|
|
if (halfLine < CurrTiming->equ * 3 + CurrTiming->prbEven) {
|
|
*y = -1;
|
|
} else if (halfLine >= CurrTiming->numHalfLines - CurrTiming->psbEven) {
|
|
*y = -1;
|
|
} else
|
|
*y = (s16)((halfLine - CurrTiming->equ * 3 - CurrTiming->prbEven) & ~1);
|
|
}
|
|
}
|
|
|
|
*x = (s16)(hcount - 1);
|
|
}
|
|
|
|
/* 8034DD5C-8034DDBC 34869C 0060+00 1/1 0/0 0/0 .text __VIGetCurrentPosition */
|
|
void __VIGetCurrentPosition(s16* x, s16* y) {
|
|
u32 h, v;
|
|
GetCurrentDisplayPosition(&h, &v);
|
|
__VIDisplayPositionToXY(h, v, x, y);
|
|
}
|