most of shieldD revo sdk matching (#2951)

* shieldD revo wpad done

* shieldD revo hio2 done

* shieldD revo aralt, ppcarch, gf done

* shieldD revo exi done

* shieldD revo SI done

* shieldD revo vi done

* shieldD revo mtx done

* shieldD revo GX mostly done

* shieldD revo ai/dsp done

* shieldD revo sc mostly done

* shieldD revo esp/euart/wenc mostly done

* build fixes
This commit is contained in:
TakaRikka 2025-12-13 08:21:32 -08:00 committed by GitHub
parent 25dfef320b
commit 4e6dffff5a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
103 changed files with 33893 additions and 85 deletions

View File

@ -4154,7 +4154,7 @@ revolution/vi/vi3in1.c:
.text start:0x805D28D0 end:0x805D3610
.data start:0x8072CE20 end:0x8072D460
.sdata start:0x8074BE80 end:0x8074BE90
.sbss start:0x8074D3B0 end:0x8074D3CC
.sbss start:0x8074D3B0 end:0x8074D3C8
.bss start:0x807FAAE0 end:0x807FAB00
revolution/mtx/mtx.c:
@ -4189,14 +4189,14 @@ revolution/gx/GXInit.c:
.text start:0x805D7340 end:0x805D8E80
.data start:0x8072ED20 end:0x8072EFD0
.sdata start:0x8074BEB8 end:0x8074BEC0
.sbss start:0x8074D3CC end:0x8074D3F4
.sbss start:0x8074D3C8 end:0x8074D3F0
.sdata2 start:0x80752D00 end:0x80752D28
.bss start:0x807FAB00 end:0x807FB180
revolution/gx/GXFifo.c:
.text start:0x805D8E80 end:0x805DA790
.data start:0x8072EFD0 end:0x8072F4C0
.sbss start:0x8074D3F4 end:0x8074D410
.sbss start:0x8074D3F0 end:0x8074D410
.bss start:0x807FB180 end:0x807FB1C8
revolution/gx/GXAttr.c:
@ -4404,7 +4404,7 @@ revolution/nand/NANDErrorMessage.c:
.text start:0x8060F6A0 end:0x8060F960
.rodata start:0x8065EC00 end:0x8065EE18
.data start:0x8073BED8 end:0x8073DB08
.sbss start:0x8074D5E0 end:0x8074D5EC
.sbss start:0x8074D5E0 end:0x8074D5E8
.sdata2 start:0x80752E38 end:0x80752E68
revolution/sc/scsystem.c:
@ -4412,7 +4412,7 @@ revolution/sc/scsystem.c:
.rodata start:0x8065EE18 end:0x8065EE70
.data start:0x8073DB08 end:0x8073DDB0
.sdata start:0x8074C078 end:0x8074C1C0
.sbss start:0x8074D5EC end:0x8074D600
.sbss start:0x8074D5E8 end:0x8074D600
.bss start:0x80801DC0 end:0x80809F60
revolution/sc/scapi.c:
@ -4467,13 +4467,14 @@ revolution/pad/Pad.c:
.text start:0x80616840 end:0x80618AB0
.data start:0x8073DE70 end:0x8073E0B0
.sdata start:0x8074C1F8 end:0x8074C220
.sbss start:0x8074D648 end:0x8074D680
.sbss start:0x8074D648 end:0x8074D678
.bss start:0x8080DBA0 end:0x8080DC20
revolution/wpad/WPAD.c:
.text start:0x80618AB0 end:0x80619BD0
.data start:0x8073E0B0 end:0x8073E1F0
.sdata start:0x8074C220 end:0x8074C228
.sbss start:0x8074D678 end:0x8074D680
.sdata2 start:0x80752E78 end:0x80752E80
.bss start:0x8080DC20 end:0x8080DC40

View File

@ -1461,6 +1461,27 @@ config.libs = [
Object(MatchingFor(ALL_GCN), "dolphin/gd/GDGeometry.c"),
],
),
RevolutionLib(
"gf",
[
Object(NonMatching, "revolution/gf/GFGeometry.cpp"),
Object(NonMatching, "revolution/gf/GFLight.cpp"),
Object(NonMatching, "revolution/gf/GFPixel.cpp"),
Object(NonMatching, "revolution/gf/GFTev.cpp"),
],
),
RevolutionLib(
"aralt",
[
Object(NonMatching, "revolution/aralt/aralt.c"),
],
),
RevolutionLib(
"base",
[
Object(NonMatching, "revolution/base/PPCArch.c"),
],
),
RevolutionLib(
"os",
[
@ -1500,6 +1521,64 @@ config.libs = [
Object(MatchingFor("ShieldD"), "revolution/os/__ppc_eabi_init.cpp"),
],
),
RevolutionLib(
"exi",
[
Object(NonMatching, "revolution/exi/EXIBios.c"),
Object(NonMatching, "revolution/exi/EXIUart.c"),
Object(NonMatching, "revolution/exi/EXICommon.c"),
],
),
RevolutionLib(
"si",
[
Object(NonMatching, "revolution/si/SIBios.c"),
Object(NonMatching, "revolution/si/SISamplingRate.c"),
],
),
RevolutionLib(
"vi",
[
Object(NonMatching, "revolution/vi/vi.c"),
Object(NonMatching, "revolution/vi/i2c.c"),
Object(NonMatching, "revolution/vi/vi3in1.c"),
],
),
RevolutionLib(
"mtx",
[
Object(NonMatching, "revolution/mtx/mtx.c"),
Object(NonMatching, "revolution/mtx/mtxvec.c"),
Object(NonMatching, "revolution/mtx/mtx44.c"),
Object(NonMatching, "revolution/mtx/vec.c"),
Object(NonMatching, "revolution/mtx/quat.c"),
],
),
RevolutionLib(
"gx",
[
Object(NonMatching, "revolution/gx/GXInit.c", extra_cflags=["-opt nopeephole"]),
Object(NonMatching, "revolution/gx/GXFifo.c"),
Object(NonMatching, "revolution/gx/GXAttr.c"),
Object(NonMatching, "revolution/gx/GXMisc.c"),
Object(NonMatching, "revolution/gx/GXGeometry.c"),
Object(NonMatching, "revolution/gx/GXFrameBuf.c"),
Object(NonMatching, "revolution/gx/GXLight.c", extra_cflags=["-fp_contract off"]),
Object(NonMatching, "revolution/gx/GXTexture.c"),
Object(NonMatching, "revolution/gx/GXBump.c"),
Object(NonMatching, "revolution/gx/GXTev.c"),
Object(NonMatching, "revolution/gx/GXPixel.c"),
Object(NonMatching, "revolution/gx/GXDraw.c"),
Object(NonMatching, "revolution/gx/GXDisplayList.c"),
Object(NonMatching, "revolution/gx/GXVert.c"),
Object(NonMatching, "revolution/gx/GXTransform.c", extra_cflags=["-fp_contract off"]),
Object(NonMatching, "revolution/gx/GXVerify.c"),
Object(NonMatching, "revolution/gx/GXVerifXF.c"),
Object(NonMatching, "revolution/gx/GXVerifRAS.c"),
Object(NonMatching, "revolution/gx/GXSave.c"),
Object(NonMatching, "revolution/gx/GXPerf.c"),
],
),
RevolutionLib(
"dvd",
[
@ -1513,6 +1592,26 @@ config.libs = [
Object(NonMatching, "revolution/dvd/dvd_broadway.c", extra_cflags=["-char signed"]),
],
),
RevolutionLib(
"ai",
[
Object(NonMatching, "revolution/ai/ai.c"),
],
),
RevolutionLib(
"dsp",
[
Object(NonMatching, "revolution/dsp/dsp.c"),
Object(NonMatching, "revolution/dsp/dsp_debug.c"),
Object(NonMatching, "revolution/dsp/dsp_task.c"),
],
),
RevolutionLib(
"hio2",
[
Object(NonMatching, "revolution/hio2/hio2.c"),
],
),
RevolutionLib(
"nand",
[
@ -1525,9 +1624,23 @@ config.libs = [
],
),
RevolutionLib(
"fs",
"sc",
[
Object(NonMatching, "revolution/fs/fs.c"),
Object(NonMatching, "revolution/sc/scsystem.c"),
Object(NonMatching, "revolution/sc/scapi.c"),
Object(NonMatching, "revolution/sc/scapi_prdinfo.c"),
],
),
RevolutionLib(
"wenc",
[
Object(NonMatching, "revolution/wenc/wenc.c"),
],
),
RevolutionLib(
"esp",
[
Object(NonMatching, "revolution/esp/esp.c"),
],
),
RevolutionLib(
@ -1539,6 +1652,12 @@ config.libs = [
Object(NonMatching, "revolution/ipc/ipcProfile.c"),
],
),
RevolutionLib(
"fs",
[
Object(NonMatching, "revolution/fs/fs.c"),
],
),
RevolutionLib(
"pad",
[
@ -1546,6 +1665,26 @@ config.libs = [
Object(NonMatching, "revolution/pad/Pad.c"),
],
),
RevolutionLib(
"wpad",
[
Object(NonMatching, "revolution/wpad/WPAD.c"),
Object(NonMatching, "revolution/wpad/WUD.c"),
],
),
RevolutionLib(
"euart",
[
Object(NonMatching, "revolution/euart/euart.c"),
],
),
RevolutionLib(
"gd",
[
Object(NonMatching, "revolution/gd/GDBase.c"),
Object(NonMatching, "revolution/gd/GDGeometry.c"),
],
),
{
"lib": "Runtime.PPCEABI.H",
"mw_version": MWVersion(config.version),

View File

@ -70,6 +70,13 @@ extern int __rlwimi(int, int, int, int, int);
extern void __dcbz(void*, int);
extern void __sync();
extern int __abs(int);
#else
// to stop clangd errors
#define __cntlzw
#define __rlwimi
#define __dcbz
#define __sync
#define __abs
#endif
#ifndef __MWERKS__

View File

@ -25,21 +25,8 @@ u32 AIGetDMABytesLeft(void);
u32 AIGetDMAStartAddr(void);
u32 AIGetDMALength(void);
BOOL AICheckInit(void);
AISCallback AIRegisterStreamCallback(AISCallback callback);
u32 AIGetStreamSampleCount(void);
void AIResetStreamSampleCount(void);
void AISetStreamTrigger(u32 trigger);
u32 AIGetStreamTrigger(void);
void AISetStreamPlayState(u32 state);
u32 AIGetStreamPlayState(void);
void AISetDSPSampleRate(u32 rate);
u32 AIGetDSPSampleRate(void);
void AISetStreamSampleRate(u32 rate);
u32 AIGetStreamSampleRate(void);
void AISetStreamVolLeft(u8 vol);
u8 AIGetStreamVolLeft(void);
void AISetStreamVolRight(u8 vol);
u8 AIGetStreamVolRight(void);
void AIInit(u8* stack);
void AIReset(void);

View File

@ -0,0 +1,56 @@
#ifndef _REVOLUTION_ARALT_H_
#define _REVOLUTION_ARALT_H_
#include <revolution/types.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef void (*ARQCallback)(u32 pointerToARQRequest);
struct ARQRequest {
/* 0x00 */ struct ARQRequest *next;
/* 0x04 */ u32 owner;
/* 0x08 */ u32 type;
/* 0x0C */ u32 priority;
/* 0x10 */ u32 source;
/* 0x14 */ u32 dest;
/* 0x18 */ u32 length;
/* 0x1C */ ARQCallback callback;
};
#define ARQ_DMA_ALIGNMENT 32
#define ARAM_DIR_MRAM_TO_ARAM 0x00
#define ARAM_DIR_ARAM_TO_MRAM 0x01
#define ARStartDMARead(mmem, aram, len) \
ARStartDMA(ARAM_DIR_ARAM_TO_MRAM, mmem, aram, len)
#define ARStartDMAWrite(mmem, aram, len) \
ARStartDMA(ARAM_DIR_MRAM_TO_ARAM, mmem, aram, len)
typedef struct ARQRequest ARQRequest;
#define ARQ_TYPE_MRAM_TO_ARAM ARAM_DIR_MRAM_TO_ARAM
#define ARQ_TYPE_ARAM_TO_MRAM ARAM_DIR_ARAM_TO_MRAM
#define ARQ_PRIORITY_LOW 0
#define ARQ_PRIORITY_HIGH 1
// AR
ARQCallback ARRegisterDMACallback(ARQCallback callback);
void ARStartDMA(u32 type, u32 mainmem_addr, u32 aram_addr, u32 length);
u32 ARAlloc(u32 length);
u32 ARInit(u32* stack_index_addr, u32 num_entries);
u32 ARGetBaseAddress(void);
u32 ARGetSize(void);
// ARQ
void ARQInit(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,5 +1,5 @@
#ifndef ESP_H
#define ESP_H
#ifndef _REVOLUTION_ESP_H_
#define _REVOLUTION_ESP_H_
#ifdef __cplusplus
extern "C" {
@ -122,17 +122,17 @@ typedef struct {
s32 ESP_InitLib(void);
s32 ESP_CloseLib(void);
s32 ESP_LaunchTitle(u64, ESTicketView*);
s32 ESP_GetTicketViews(ESTitleId, ESTicketView*, u32*);
s32 ESP_DiGetTicketView(const void*, ESTicketView*);
s32 ESP_DiGetTmd(ESTitleMeta*, u32*);
s32 ESP_GetTmdView(ESTitleId, ESTmdView*, u32*);
s32 ESP_GetDataDir(ESTitleId, char*);
s32 ESP_GetTitleId(ESTitleId*);
s32 ESP_GetConsumption(ESTicketId, ESLpEntry*, u32*);
s32 ESP_LaunchTitle(u64 titleID, ESTicketView* pTicketView);
s32 ESP_GetTicketViews(ESTitleId titleId, ESTicketView* ticketViewList, u32* ticketViewCnt);
s32 ESP_DiGetTicketView(const void* ticket, ESTicketView* ticketView);
s32 ESP_DiGetTmd(ESTitleMeta* tmd, u32* tmdSize);
s32 ESP_GetTmdView(ESTitleId titleId, ESTmdView* tmdView, u32* size);
s32 ESP_GetDataDir(ESTitleId titleId, char* dataDir);
s32 ESP_GetTitleId(ESTitleId* titleId);
s32 ESP_GetConsumption(ESTicketId ticketId, ESLpEntry* entries, u32* nEntries);
#ifdef __cplusplus
}
#endif
#endif // ESP_H
#endif // _REVOLUTION_ESP_H_

View File

@ -0,0 +1,61 @@
#ifndef _REVOLUTION_EUART_H_
#define _REVOLUTION_EUART_H_
#include <revolution/types.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef int UARTError;
typedef enum {
kBaudHWSet = -1,
kBaud300 = 300,
kBaud600 = 600,
kBaud1200 = 1200,
kBaud1800 = 1800,
kBaud2000 = 2000,
kBaud2400 = 2400,
kBaud3600 = 3600,
kBaud4800 = 4800,
kBaud7200 = 7200,
kBaud9600 = 9600,
kBaud19200 = 19200,
kBaud38400 = 38400,
kBaud57600 = 57600,
kBaud115200 = 115200,
kBaud230400 = 230400
} UARTBaudRate;
enum {
kUARTDataError = -1,
kUARTNoError = 0,
kUARTUnknownBaudRate,
kUARTConfigurationError,
kUARTBufferOverflow,
kUARTNoData
};
typedef enum {
EUART_ERROR_NONE = 0,
EUART_ERROR_UNINITIALIZED,
EUART_ERROR_CANNOT_USE,
EUART_ERROR_CHANNEL_FULL,
EUART_ERROR_NOT_FIND,
EUART_ERROR_INTERNAL,
EUART_ERROR_INVALID_PARAMETER,
EUART_ERROR_INVALID_HANDLE,
EUART_ERROR_COM_OPEN,
EUART_ERROR_COMM
} EUARTError;
UARTError InitializeUART(UARTBaudRate);
UARTError WriteUARTN(const void *, unsigned long);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -74,6 +74,8 @@ typedef struct EXIControl {
} queue[3];
} EXIControl;
extern const u32 __EXIFreq;
EXICallback EXISetExiCallback(s32 channel, EXICallback callback);
void EXIInit(void);
@ -96,6 +98,12 @@ int EXISelectSD(s32 chan, u32 dev, u32 freq);
s32 EXIGetType(s32 chan, u32 dev, u32* type);
char* EXIGetTypeString(u32 type);
s32 EXIGetConsoleType(void);
void EXIWait(void);
BOOL EXIWriteReg(s32 chan, u32 dev, u32 exiCmd, void* reg, s32 size);
BOOL EXIReadRam(s32 chan, u32 dev, u32 exiCmd, void* buffer, s32 size, EXICallback callback);
BOOL EXIWriteRam(s32 chan, u32 dev, u32 exiCmd, void* buffer, s32 size, EXICallback callback);
#ifdef __cplusplus
}
#endif

44
include/revolution/hio2.h Normal file
View File

@ -0,0 +1,44 @@
#ifndef _REVOLUTION_HIO2_H_
#define _REVOLUTION_HIO2_H_
#include <revolution/types.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
HIO2_DEVICE_INVALID = -1,
HIO2_DEVICE_UNK_0 = 0,
HIO2_DEVICE_UNK_1 = 1,
HIO2_DEVICE_UNK_2 = 2,
} HIO2DeviceType;
typedef BOOL (*HIO2EnumCallback)(HIO2DeviceType);
typedef void (*HIO2UnkCallback)(s32);
typedef void (*HIO2DisconnectCallback)(s32);
typedef struct HIO2Control {
/* 0x00 */ HIO2DeviceType type;
/* 0x04 */ s32 chan;
/* 0x08 */ u32 _0x8;
/* 0x0C */ HIO2UnkCallback exiCallback;
/* 0x10 */ HIO2UnkCallback _0x10;
/* 0x14 */ HIO2UnkCallback _0x14;
/* 0x18 */ HIO2DisconnectCallback disconnectCb;
} HIO2Control; // size 0x1C
BOOL HIO2Init(void);
BOOL HIO2EnumDevices(HIO2EnumCallback callback);
s32 HIO2Open(HIO2DeviceType type, HIO2UnkCallback exiCb, HIO2DisconnectCallback disconnectCb);
BOOL HIO2Close(s32 handle);
BOOL HIO2Read(s32 handle, u32 addr, void* buffer, s32 size);
BOOL HIO2Write(s32 handle, u32 addr, void* buffer, s32 size);
void HIO2Exit(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -9,7 +9,7 @@ volatile u32 __PIRegs[12] AT_ADDRESS(0xCC003000);
volatile u16 __MEMRegs[64] AT_ADDRESS(0xCC004000);
volatile u16 __DSPRegs[] AT_ADDRESS(0xCC005000);
volatile u32 __DIRegs[] AT_ADDRESS(0xCD006000);
volatile u32 __SIRegs[0x100] AT_ADDRESS(0xCC006400);
volatile u32 __SIRegs[0x100] AT_ADDRESS(0xCD006400);
volatile u32 __EXIRegs[0x40] AT_ADDRESS(0xCD006800);
volatile u32 __AIRegs[8] AT_ADDRESS(0xCD006C00);
volatile u32 __IPCRegs[4] AT_ADDRESS(0xCD000000);
@ -19,7 +19,7 @@ volatile u32 __IPCRegs[4] AT_ADDRESS(0xCD000000);
#define __MEMRegs ((volatile u16 *)0xCC004000)
#define __DSPRegs ((volatile u16 *)0xCC005000)
#define __DIRegs ((volatile u32 *)0xCD006000)
#define __SIRegs ((volatile u32 *)0xCC006400)
#define __SIRegs ((volatile u32 *)0xCD006400)
#define __EXIRegs ((volatile u32 *)0xCD006800)
#define __AIRegs ((volatile u32 *)0xCD006C00)
#define __IPCRegs ((volatile u32 *)0xCD000000)

View File

@ -0,0 +1,263 @@
#ifndef GXFDLSHORTCUT_H
#define GXFDLSHORTCUT_H
#if __MWERKS__
#define FAST_GPFLAGSET(line, regOrg, newFlag, regName) \
do { \
ASSERTMSGLINE(line, ((u32)(newFlag) & ~((1 << (regName ## _SIZE)) - 1)) == 0, "GX Internal: Register field out of range"); \
(regOrg) = (u32) __rlwimi((int) (regOrg), \
(int) (newFlag), \
(regName ## _SHIFT), \
(32-(regName ## _SHIFT)-(regName ## _SIZE)), \
(31-(regName ## _SHIFT))); \
} while (0)
#else
#define FAST_GPFLAGSET(line, regOrg, newFlag, regName)
#endif
#define CP_VCD_REG_HI_TEXALL_MASK ((1UL<<CP_VCD_REG_HI_TOTAL_SIZE)-1)
#define CP_VCD_REG_HI_TEXALL_SHIFT CP_VCD_REG_HI_TEX0_SHIFT
#define CP_VCD_REG_LO_COLALL_MASK (CP_VCD_REG_LO_COL0_MASK|CP_VCD_REG_LO_COL1_MASK)
#define CP_VCD_REG_LO_COLALL_SHIFT CP_VCD_REG_LO_COL0_SHIFT
#define TEV_REGISTERL_R8_SIZE TEV_KREGISTERL_R_SIZE
#define TEV_REGISTERL_R8_SHIFT TEV_KREGISTERL_R_SHIFT
#define TEV_REGISTERL_R8_MASK TEV_KREGISTERL_R_MASK
#define SC_TEV_REGISTERL_SET_R8(line, tev_registerl, r8) \
FAST_GPFLAGSET(line, tev_registerl, r8, TEV_REGISTERL_R8)
#define TEV_REGISTERL_A8_SIZE TEV_KREGISTERL_A_SIZE
#define TEV_REGISTERL_A8_SHIFT TEV_KREGISTERL_A_SHIFT
#define TEV_REGISTERL_A8_MASK TEV_KREGISTERL_A_MASK
#define SC_TEV_REGISTERL_SET_A8(line, tev_registerl, a8) \
FAST_GPFLAGSET(line, tev_registerl, a8, TEV_REGISTERL_A8)
#define TEV_REGISTERH_B8_SIZE TEV_KREGISTERH_B_SIZE
#define TEV_REGISTERH_B8_SHIFT TEV_KREGISTERH_B_SHIFT
#define TEV_REGISTERH_B8_MASK TEV_KREGISTERH_B_MASK
#define SC_TEV_REGISTERH_SET_B8(line, tev_registerh, b8) \
FAST_GPFLAGSET(line, tev_registerh, b8, TEV_REGISTERH_B8)
#define TEV_REGISTERH_G8_SIZE TEV_KREGISTERH_G_SIZE
#define TEV_REGISTERH_G8_SHIFT TEV_KREGISTERH_G_SHIFT
#define TEV_REGISTERH_G8_MASK TEV_KREGISTERH_G_MASK
#define SC_TEV_REGISTERH_SET_G8(line, tev_registerh, g8) \
FAST_GPFLAGSET(line, tev_registerh, g8, TEV_REGISTERH_G8)
#define TEV_REGISTERL_R8_SIZE TEV_KREGISTERL_R_SIZE
#define TEV_REGISTERL_R8_SHIFT TEV_KREGISTERL_R_SHIFT
#define TEV_REGISTERL_R8_MASK TEV_KREGISTERL_R_MASK
#define SC_TEV_REGISTERL_SET_R8(line, tev_registerl, r8) \
FAST_GPFLAGSET(line, tev_registerl, r8, TEV_REGISTERL_R8)
#define TEV_REGISTERL_A8_SIZE TEV_KREGISTERL_A_SIZE
#define TEV_REGISTERL_A8_SHIFT TEV_KREGISTERL_A_SHIFT
#define TEV_REGISTERL_A8_MASK TEV_KREGISTERL_A_MASK
#define SC_TEV_REGISTERL_SET_A8(line, tev_registerl, a8) \
FAST_GPFLAGSET(line, tev_registerl, a8, TEV_REGISTERL_A8)
#define TEV_REGISTERH_B8_SIZE TEV_KREGISTERH_B_SIZE
#define TEV_REGISTERH_B8_SHIFT TEV_KREGISTERH_B_SHIFT
#define TEV_REGISTERH_B8_MASK TEV_KREGISTERH_B_MASK
#define SC_TEV_REGISTERH_SET_B8(line, tev_registerh, b8) \
FAST_GPFLAGSET(line, tev_registerh, b8, TEV_REGISTERH_B8)
#define TEV_REGISTERH_G8_SIZE TEV_KREGISTERH_G_SIZE
#define TEV_REGISTERH_G8_SHIFT TEV_KREGISTERH_G_SHIFT
#define TEV_REGISTERH_G8_MASK TEV_KREGISTERH_G_MASK
#define SC_TEV_REGISTERH_SET_G8(line, tev_registerh, g8) \
FAST_GPFLAGSET(line, tev_registerh, g8, TEV_REGISTERH_G8)
#define XF_AMBIENT0_F_RGBA_SIZE \
((XF_AMBIENT0_F_ALPHA_SIZE)+(XF_AMBIENT0_F_BLUE_SIZE)+ \
(XF_AMBIENT0_F_GREEN_SIZE)+(XF_AMBIENT0_F_RED_SIZE))
#define XF_AMBIENT0_F_RGBA_SHIFT \
XF_AMBIENT0_F_ALPHA_SHIFT
#define XF_AMBIENT0_F_RGBA_MASK \
((XF_AMBIENT0_F_ALPHA_MASK)|(XF_AMBIENT0_F_BLUE_MASK)| \
(XF_AMBIENT0_F_GREEN_MASK)|(XF_AMBIENT0_F_RED_MASK))
#define SC_XF_AMBIENT0_F_SET_RGBA(xf_ambient0_f, rgba) { \
xf_ambient0_f = (((unsigned long)(xf_ambient0_f)) & ~XF_AMBIENT0_F_RGBA_MASK) | (((unsigned long)(rgba)) << XF_AMBIENT0_F_RGBA_SHIFT);\
}
#define XF_AMBIENT0_F_ALPHA_SIZE 8
#define XF_AMBIENT0_F_ALPHA_SHIFT 0
#define XF_AMBIENT0_F_ALPHA_MASK 0x000000ff
#define XF_AMBIENT0_F_GET_ALPHA(xf_ambient0_f) \
((((unsigned long)(xf_ambient0_f)) & XF_AMBIENT0_F_ALPHA_MASK) >> XF_AMBIENT0_F_ALPHA_SHIFT)
#define XF_AMBIENT0_F_SET_ALPHA(xf_ambient0_f, alpha) { \
xf_ambient0_f = (((unsigned long)(xf_ambient0_f)) & ~XF_AMBIENT0_F_ALPHA_MASK) | (((unsigned long)(alpha)) << XF_AMBIENT0_F_ALPHA_SHIFT);\
}
#define XF_AMBIENT0_F_BLUE_SIZE 8
#define XF_AMBIENT0_F_BLUE_SHIFT 8
#define XF_AMBIENT0_F_BLUE_MASK 0x0000ff00
#define XF_AMBIENT0_F_GET_BLUE(xf_ambient0_f) \
((((unsigned long)(xf_ambient0_f)) & XF_AMBIENT0_F_BLUE_MASK) >> XF_AMBIENT0_F_BLUE_SHIFT)
#define XF_AMBIENT0_F_SET_BLUE(xf_ambient0_f, blue) { \
xf_ambient0_f = (((unsigned long)(xf_ambient0_f)) & ~XF_AMBIENT0_F_BLUE_MASK) | (((unsigned long)(blue)) << XF_AMBIENT0_F_BLUE_SHIFT);\
}
#define XF_AMBIENT0_F_GREEN_SIZE 8
#define XF_AMBIENT0_F_GREEN_SHIFT 16
#define XF_AMBIENT0_F_GREEN_MASK 0x00ff0000
#define XF_AMBIENT0_F_GET_GREEN(xf_ambient0_f) \
((((unsigned long)(xf_ambient0_f)) & XF_AMBIENT0_F_GREEN_MASK) >> XF_AMBIENT0_F_GREEN_SHIFT)
#define XF_AMBIENT0_F_SET_GREEN(xf_ambient0_f, green) { \
xf_ambient0_f = (((unsigned long)(xf_ambient0_f)) & ~XF_AMBIENT0_F_GREEN_MASK) | (((unsigned long)(green)) << XF_AMBIENT0_F_GREEN_SHIFT);\
}
#define XF_AMBIENT0_F_RED_SIZE 8
#define XF_AMBIENT0_F_RED_SHIFT 24
#define XF_AMBIENT0_F_RED_MASK 0xff000000
#define XF_AMBIENT0_F_GET_RED(xf_ambient0_f) \
((((unsigned long)(xf_ambient0_f)) & XF_AMBIENT0_F_RED_MASK) >> XF_AMBIENT0_F_RED_SHIFT)
#define XF_AMBIENT0_F_SET_RED(xf_ambient0_f, red) { \
xf_ambient0_f = (((unsigned long)(xf_ambient0_f)) & ~XF_AMBIENT0_F_RED_MASK) | (((unsigned long)(red)) << XF_AMBIENT0_F_RED_SHIFT);\
}
#define XF_AMBIENT0_F_RGB_SIZE \
((XF_AMBIENT0_F_BLUE_SIZE)+(XF_AMBIENT0_F_GREEN_SIZE)+(XF_AMBIENT0_F_RED_SIZE))
#define XF_AMBIENT0_F_RGB_SHIFT \
XF_AMBIENT0_F_BLUE_SHIFT
#define XF_AMBIENT0_F_RGB_MASK \
((XF_AMBIENT0_F_BLUE_MASK)|(XF_AMBIENT0_F_GREEN_MASK)|(XF_AMBIENT0_F_RED_MASK))
#define SC_XF_AMBIENT0_F_SET_RGB(line, xf_ambient0_f, rgb) \
FAST_GPFLAGSET(line, xf_ambient0_f, rgb, XF_AMBIENT0_F_RGB)
#define XF_AMBIENT1_F_RGBA_SIZE \
((XF_AMBIENT1_F_ALPHA_SIZE)+(XF_AMBIENT1_F_BLUE_SIZE)+ \
(XF_AMBIENT1_F_GREEN_SIZE)+(XF_AMBIENT1_F_RED_SIZE))
#define XF_AMBIENT1_F_RGBA_SHIFT \
XF_AMBIENT1_F_ALPHA_SHIFT
#define XF_AMBIENT1_F_RGBA_MASK \
((XF_AMBIENT1_F_ALPHA_MASK)|(XF_AMBIENT1_F_BLUE_MASK)| \
(XF_AMBIENT1_F_GREEN_MASK)|(XF_AMBIENT1_F_RED_MASK))
#define SC_XF_AMBIENT1_F_SET_RGBA(xf_ambient1_f, rgba) { \
xf_ambient1_f = (((unsigned long)(xf_ambient1_f)) & ~XF_AMBIENT1_F_RGBA_MASK) | (((unsigned long)(rgba)) << XF_AMBIENT1_F_RGBA_SHIFT);\
}
#define XF_AMBIENT1_F_ALPHA_SIZE 8
#define XF_AMBIENT1_F_ALPHA_SHIFT 0
#define XF_AMBIENT1_F_ALPHA_MASK 0x000000ff
#define XF_AMBIENT1_F_GET_ALPHA(xf_ambient1_f) \
((((unsigned long)(xf_ambient1_f)) & XF_AMBIENT1_F_ALPHA_MASK) >> XF_AMBIENT1_F_ALPHA_SHIFT)
#define XF_AMBIENT1_F_SET_ALPHA(xf_ambient1_f, alpha) { \
xf_ambient1_f = (((unsigned long)(xf_ambient1_f)) & ~XF_AMBIENT1_F_ALPHA_MASK) | (((unsigned long)(alpha)) << XF_AMBIENT1_F_ALPHA_SHIFT);\
}
#define XF_AMBIENT1_F_BLUE_SIZE 8
#define XF_AMBIENT1_F_BLUE_SHIFT 8
#define XF_AMBIENT1_F_BLUE_MASK 0x0000ff00
#define XF_AMBIENT1_F_GET_BLUE(xf_ambient1_f) \
((((unsigned long)(xf_ambient1_f)) & XF_AMBIENT1_F_BLUE_MASK) >> XF_AMBIENT1_F_BLUE_SHIFT)
#define XF_AMBIENT1_F_SET_BLUE(xf_ambient1_f, blue) { \
xf_ambient1_f = (((unsigned long)(xf_ambient1_f)) & ~XF_AMBIENT1_F_BLUE_MASK) | (((unsigned long)(blue)) << XF_AMBIENT1_F_BLUE_SHIFT);\
}
#define XF_AMBIENT1_F_GREEN_SIZE 8
#define XF_AMBIENT1_F_GREEN_SHIFT 16
#define XF_AMBIENT1_F_GREEN_MASK 0x00ff0000
#define XF_AMBIENT1_F_GET_GREEN(xf_ambient1_f) \
((((unsigned long)(xf_ambient1_f)) & XF_AMBIENT1_F_GREEN_MASK) >> XF_AMBIENT1_F_GREEN_SHIFT)
#define XF_AMBIENT1_F_SET_GREEN(xf_ambient1_f, green) { \
xf_ambient1_f = (((unsigned long)(xf_ambient1_f)) & ~XF_AMBIENT1_F_GREEN_MASK) | (((unsigned long)(green)) << XF_AMBIENT1_F_GREEN_SHIFT);\
}
#define XF_AMBIENT1_F_RED_SIZE 8
#define XF_AMBIENT1_F_RED_SHIFT 24
#define XF_AMBIENT1_F_RED_MASK 0xff000000
#define XF_AMBIENT1_F_GET_RED(xf_ambient1_f) \
((((unsigned long)(xf_ambient1_f)) & XF_AMBIENT1_F_RED_MASK) >> XF_AMBIENT1_F_RED_SHIFT)
#define XF_AMBIENT1_F_SET_RED(xf_ambient1_f, red) { \
xf_ambient1_f = (((unsigned long)(xf_ambient1_f)) & ~XF_AMBIENT1_F_RED_MASK) | (((unsigned long)(red)) << XF_AMBIENT1_F_RED_SHIFT);\
}
#define XF_AMBIENT1_F_RGB_SIZE \
((XF_AMBIENT1_F_BLUE_SIZE)+(XF_AMBIENT1_F_GREEN_SIZE)+(XF_AMBIENT1_F_RED_SIZE))
#define XF_AMBIENT1_F_RGB_SHIFT \
XF_AMBIENT1_F_BLUE_SHIFT
#define XF_AMBIENT1_F_RGB_MASK \
((XF_AMBIENT1_F_BLUE_MASK)|(XF_AMBIENT1_F_GREEN_MASK)|(XF_AMBIENT1_F_RED_MASK))
#define SC_XF_AMBIENT1_F_SET_RGB(line, xf_ambient1_f, rgb) \
FAST_GPFLAGSET(line, xf_ambient1_f, rgb, XF_AMBIENT1_F_RGB)
#define XF_MATERIAL0_F_RGBA_SIZE \
((XF_MATERIAL0_F_ALPHA_SIZE)+(XF_MATERIAL0_F_BLUE_SIZE)+ \
(XF_MATERIAL0_F_GREEN_SIZE)+(XF_MATERIAL0_F_RED_SIZE))
#define XF_MATERIAL0_F_RGBA_SHIFT \
XF_MATERIAL0_F_ALPHA_SHIFT
#define XF_MATERIAL0_F_RGBA_MASK \
((XF_MATERIAL0_F_ALPHA_MASK)|(XF_MATERIAL0_F_BLUE_MASK)| \
(XF_MATERIAL0_F_GREEN_MASK)|(XF_MATERIAL0_F_RED_MASK))
#define SC_XF_MATERIAL0_F_SET_RGBA(xf_material0_f, rgba) { \
xf_material0_f = (((unsigned long)(xf_material0_f)) & ~XF_MATERIAL0_F_RGBA_MASK) | (((unsigned long)(rgba)) << XF_MATERIAL0_F_RGBA_SHIFT);\
}
#define XF_MATERIAL0_F_RGBA_SIZE \
((XF_MATERIAL0_F_ALPHA_SIZE)+(XF_MATERIAL0_F_BLUE_SIZE)+ \
(XF_MATERIAL0_F_GREEN_SIZE)+(XF_MATERIAL0_F_RED_SIZE))
#define XF_MATERIAL0_F_RGBA_SHIFT \
XF_MATERIAL0_F_ALPHA_SHIFT
#define XF_MATERIAL0_F_RGBA_MASK \
((XF_MATERIAL0_F_ALPHA_MASK)|(XF_MATERIAL0_F_BLUE_MASK)| \
(XF_MATERIAL0_F_GREEN_MASK)|(XF_MATERIAL0_F_RED_MASK))
#define XF_MATERIAL0_F_RGB_SIZE \
((XF_MATERIAL0_F_BLUE_SIZE)+(XF_MATERIAL0_F_GREEN_SIZE)+(XF_MATERIAL0_F_RED_SIZE))
#define XF_MATERIAL0_F_RGB_SHIFT \
XF_MATERIAL0_F_BLUE_SHIFT
#define XF_MATERIAL0_F_RGB_MASK \
((XF_MATERIAL0_F_BLUE_MASK)|(XF_MATERIAL0_F_GREEN_MASK)|(XF_MATERIAL0_F_RED_MASK))
#define SC_XF_MATERIAL0_F_SET_RGB(line, xf_material0_f, rgb) \
FAST_GPFLAGSET(line, xf_material0_f, rgb, XF_MATERIAL0_F_RGB)
#define XF_MATERIAL0_F_RGB_SIZE \
((XF_MATERIAL0_F_BLUE_SIZE)+(XF_MATERIAL0_F_GREEN_SIZE)+(XF_MATERIAL0_F_RED_SIZE))
#define XF_MATERIAL0_F_RGB_SHIFT \
XF_MATERIAL0_F_BLUE_SHIFT
#define XF_MATERIAL0_F_RGB_MASK \
((XF_MATERIAL0_F_BLUE_MASK)|(XF_MATERIAL0_F_GREEN_MASK)|(XF_MATERIAL0_F_RED_MASK))
#define SC_XF_MATERIAL0_F_SET_RGB(line, xf_material0_f, rgb) \
FAST_GPFLAGSET(line, xf_material0_f, rgb, XF_MATERIAL0_F_RGB)
#define XF_MATERIAL1_F_RGBA_SIZE \
((XF_MATERIAL1_F_ALPHA_SIZE)+(XF_MATERIAL1_F_BLUE_SIZE)+ \
(XF_MATERIAL1_F_GREEN_SIZE)+(XF_MATERIAL1_F_RED_SIZE))
#define XF_MATERIAL1_F_RGBA_SHIFT \
XF_MATERIAL1_F_ALPHA_SHIFT
#define XF_MATERIAL1_F_RGBA_MASK \
((XF_MATERIAL1_F_ALPHA_MASK)|(XF_MATERIAL1_F_BLUE_MASK)| \
(XF_MATERIAL1_F_GREEN_MASK)|(XF_MATERIAL1_F_RED_MASK))
#define SC_XF_MATERIAL1_F_SET_RGBA(xf_material1_f, rgba) { \
xf_material1_f = (((unsigned long)(xf_material1_f)) & ~XF_MATERIAL1_F_RGBA_MASK) | (((unsigned long)(rgba)) << XF_MATERIAL1_F_RGBA_SHIFT);\
}
#define XF_MATERIAL1_F_RGB_SIZE \
((XF_MATERIAL1_F_BLUE_SIZE)+(XF_MATERIAL1_F_GREEN_SIZE)+(XF_MATERIAL1_F_RED_SIZE))
#define XF_MATERIAL1_F_RGB_SHIFT \
XF_MATERIAL1_F_BLUE_SHIFT
#define XF_MATERIAL1_F_RGB_MASK \
((XF_MATERIAL1_F_BLUE_MASK)|(XF_MATERIAL1_F_GREEN_MASK)|(XF_MATERIAL1_F_RED_MASK))
#define SC_XF_MATERIAL1_F_SET_RGB(line, xf_material1_f, rgb) \
FAST_GPFLAGSET(line, xf_material1_f, rgb, XF_MATERIAL1_F_RGB)
#define XF_COLOR0CNTRL_F_LIGHT0123_SIZE \
((XF_COLOR0CNTRL_F_LIGHT0_SIZE)+(XF_COLOR0CNTRL_F_LIGHT1_SIZE)+ \
(XF_COLOR0CNTRL_F_LIGHT2_SIZE)+(XF_COLOR0CNTRL_F_LIGHT3_SIZE))
#define XF_COLOR0CNTRL_F_LIGHT0123_SHIFT \
XF_COLOR0CNTRL_F_LIGHT0_SHIFT
#define XF_COLOR0CNTRL_F_LIGHT0123_MASK \
((XF_COLOR0CNTRL_F_LIGHT0_MASK)|(XF_COLOR0CNTRL_F_LIGHT1_MASK)| \
(XF_COLOR0CNTRL_F_LIGHT2_MASK)|(XF_COLOR0CNTRL_F_LIGHT3_MASK))
#define SC_XF_COLOR0CNTRL_F_SET_LIGHT0123(line, xf_color0cntrl_f, light0123) \
FAST_GPFLAGSET(line, xf_color0cntrl_f, light0123, XF_COLOR0CNTRL_F_LIGHT0123)
#define XF_COLOR0CNTRL_F_LIGHT4567_SIZE \
((XF_COLOR0CNTRL_F_LIGHT4_SIZE)+(XF_COLOR0CNTRL_F_LIGHT5_SIZE)+ \
(XF_COLOR0CNTRL_F_LIGHT6_SIZE)+(XF_COLOR0CNTRL_F_LIGHT7_SIZE))
#define XF_COLOR0CNTRL_F_LIGHT4567_SHIFT \
XF_COLOR0CNTRL_F_LIGHT4_SHIFT
#define XF_COLOR0CNTRL_F_LIGHT4567_MASK \
((XF_COLOR0CNTRL_F_LIGHT4_MASK)|(XF_COLOR0CNTRL_F_LIGHT5_MASK)| \
(XF_COLOR0CNTRL_F_LIGHT6_MASK)|(XF_COLOR0CNTRL_F_LIGHT7_MASK))
#define SC_XF_COLOR0CNTRL_F_SET_LIGHT4567(line, xf_color0cntrl_f, light4567) \
FAST_GPFLAGSET(line, xf_color0cntrl_f, light4567, XF_COLOR0CNTRL_F_LIGHT4567)
#endif // GXFDLSHORTCUT_H

View File

@ -0,0 +1,186 @@
#ifndef GXREGS_H
#define GXREGS_H
#include <revolution/gx.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <revolution/private/bp_reg.h>
#include <revolution/private/cp_reg.h>
#include <revolution/private/gen_reg.h>
#include <revolution/private/pe_reg.h>
#include <revolution/private/pi_reg.h>
#include <revolution/private/ras_reg.h>
#include <revolution/private/su_reg.h>
#include <revolution/private/tev_reg.h>
#include <revolution/private/tx_reg.h>
#include <revolution/private/xf_mem.h>
extern volatile void* __piReg;
extern volatile void* __cpReg;
extern volatile void* __peReg;
extern volatile void* __memReg;
#define MEM_PE_REQCOUNTH_IDX 0x27
#define MEM_PE_REQCOUNTL_IDX 0x28
/* GX fifo write helpers */
#define GX_WRITE_U8(ub) \
GXWGFifo.u8 = (u8)(ub)
#define GX_WRITE_U16(us) \
GXWGFifo.u16 = (u16)(us)
#define GX_WRITE_U32(ui) \
GXWGFifo.u32 = (u32)(ui)
#define GX_WRITE_F32(f) \
GXWGFifo.f32 = (f32)(f);
#define GX_PI_REG_WRITE_U32(a, d) *(vu32*)((vu8*)__piReg + (a)) = (u32)(d)
#define GX_PI_REG_READ_U32(a) *(vu32*)((vu8*)__piReg + (a))
#define GX_CP_REG_WRITE_U16(a, d) *(vu16*)((vu16*)__cpReg + (a)) = (u16)(d)
#define GX_CP_REG_READ_U16(a) *(vu16*)((vu16*)__cpReg + (a))
#define GX_CP_REG_WRITE_U32(a, d) *(vu32*)((vu16*)__cpReg + (a)) = (u32)(d)
#define GX_CP_REG_READ_U32(a) *(vu32*)((vu16*)__cpReg + (a))
#define GX_MEM_REG_WRITE_U16(a, d) *(vu16*)((vu16*)__memReg + (a)) = (u16)(d)
#define GX_MEM_REG_READ_U16(a) *(vu16*)((vu16*)__memReg + (a))
#define GX_PE_REG_WRITE_U16(a, d) *(vu16*)((vu16*)__peReg + (a)) = (u16)(d)
#define GX_PE_REG_READ_U16(a) *(vu16*)((vu16*)__peReg + (a))
#define GX_CP_IDLE_REG_READ_U16(a) GX_CP_REG_READ_U16(a)
#define GX_PI_REG_WRITE_U32(a, d) *(vu32*)((vu8*)__piReg + (a)) = (u32)(d)
#define GX_PI_REG_READ_U32(a) *(vu32*)((vu8*)__piReg + (a))
#define GX_CP_REG_WRITE_U16(a, d) *(vu16*)((vu16*)__cpReg + (a)) = (u16)(d)
#define GX_CP_REG_READ_U16(a) *(vu16*)((vu16*)__cpReg + (a))
#define GX_CP_REG_WRITE_U32(a, d) *(vu32*)((vu16*)__cpReg + (a)) = (u32)(d)
#define GX_CP_REG_READ_U32(a) *(vu32*)((vu16*)__cpReg + (a))
#define GX_MEM_REG_WRITE_U16(a, d) *(vu16*)((vu16*)__memReg + (a)) = (u16)(d)
#define GX_MEM_REG_READ_U16(a) *(vu16*)((vu16*)__memReg + (a))
#define GX_PE_REG_WRITE_U16(a, d) *(vu16*)((vu16*)__peReg + (a)) = (u16)(d)
#define GX_PE_REG_READ_U16(a) *(vu16*)((vu16*)__peReg + (a))
#define GX_CP_IDLE_REG_READ_U16(a) GX_CP_REG_READ_U16(a)
#define GX_WRITE_CP_STRM_REG(addr, vtxfmt, data) \
{ \
GX_WRITE_U8(CP_OPCODE(0, 1)); \
GX_WRITE_U8(CP_STREAM_REG((vtxfmt), (addr))); \
GX_WRITE_U32((data)); \
}
// needed to match some places
#define GX_WRITE_CP_STRM_REG_alt(addr, vtxfmt, data, rAddr) \
{ \
s32 regAddr; \
GX_WRITE_U8(CP_OPCODE(0, 1)); \
GX_WRITE_U8(CP_STREAM_REG((vtxfmt), (addr))); \
GX_WRITE_U32((data)); \
regAddr = rAddr; \
}
// needed to match some places
#if DEBUG
#define GX_WRITE_CP_STRM_REG_alt2(addr, vtxfmt, data, rAddr) \
{ \
s32 regAddr; \
GX_WRITE_U8(CP_OPCODE(0, 1)); \
GX_WRITE_U8(CP_STREAM_REG((vtxfmt), (addr))); \
GX_WRITE_U32((data)); \
regAddr = rAddr; \
if (regAddr >= 0 && regAddr < 4) { \
__GXData->indexBase[regAddr] = data; \
} \
}
#else
#define GX_WRITE_CP_STRM_REG_alt2(addr, vtxfmt, data, rAddr) GX_WRITE_CP_STRM_REG(addr, vtxfmt, data)
#endif
// needed to match some places
#if DEBUG
#define GX_WRITE_CP_STRM_REG_alt3(addr, vtxfmt, data, rAddr) \
{ \
s32 regAddr; \
GX_WRITE_U8(CP_OPCODE(0, 1)); \
GX_WRITE_U8(CP_STREAM_REG((vtxfmt), (addr))); \
GX_WRITE_U32((data)); \
regAddr = rAddr; \
if (regAddr >= 0 && regAddr < 4) { \
__GXData->indexStride[regAddr] = data; \
} \
}
#else
#define GX_WRITE_CP_STRM_REG_alt3(addr, vtxfmt, data, rAddr) GX_WRITE_CP_STRM_REG(addr, vtxfmt, data)
#endif
#define GX_WRITE_XF_REG(addr, data, cnt) \
{ \
GX_WRITE_U8(CP_OPCODE(0, 0x2)); \
GX_WRITE_U32(CP_XF_LOADREGS((addr), (cnt))); \
GX_WRITE_U32((data)); \
VERIF_XF_REG(addr, data); \
}
#define GX_WRITE_XF_MEM_U32(addr, data) GX_WRITE_U32(data)
#define GX_WRITE_XF_MEM_F32(addr, data) GX_WRITE_F32(data)
#define GX_WRITE_RA_REG(reg) \
{ \
GX_WRITE_U8(CP_OPCODE(1, 0xC)); \
GX_WRITE_U32((reg)); \
VERIF_RAS_REG(reg); \
}
#ifdef __MWERKS__
#define GX_DEFINE_GX_READ_COUNTER(unit) \
inline u32 __GXRead##unit##CounterU32(u32 regAddrL, u32 regAddrH) { \
u32 ctrH0, ctrH1, ctrL; \
ctrH0 = GX_##unit##_REG_READ_U16(regAddrH); \
do { \
ctrH1 = ctrH0; \
ctrL = GX_##unit##_REG_READ_U16(regAddrL); \
ctrH0 = GX_##unit##_REG_READ_U16(regAddrH); \
} while (ctrH0 != ctrH1); \
return ((ctrH0 << 16) | ctrL); \
}
#else
#define GX_DEFINE_GX_READ_COUNTER(unit)
#endif
#ifdef __MWERKS__
#define FAST_FLAG_SET(regOrg, newFlag, shift, size) \
do { \
(regOrg) = (u32)__rlwimi((int)(regOrg), (int)(newFlag), (shift), (32 - (shift) - (size)), (31 - (shift))); \
} while (0);
#else
#define FAST_FLAG_SET(regOrg, newFlag, shift, size)
#endif
#ifdef __cplusplus
}
#endif
#endif // GXREGS_H

View File

@ -0,0 +1,229 @@
#ifndef BP_REG_H
#define BP_REG_H
#include <revolution/private/GXFDLShortcut.h>
#define BP_IMASK_RID_SIZE 8
#define BP_IMASK_RID_SHIFT 24
#define BP_IMASK_RID_MASK 0xff000000
#define BP_IMASK_GET_RID(bp_imask) \
((((unsigned long)(bp_imask)) & BP_IMASK_RID_MASK) >> BP_IMASK_RID_SHIFT)
#define BP_CMD_BT_SIZE 2
#define BP_CMD_BT_SHIFT 0
#define BP_CMD_BT_MASK 0x00000003
#define BP_CMD_GET_BT(bp_cmd) \
((((unsigned long)(bp_cmd)) & BP_CMD_BT_MASK) >> BP_CMD_BT_SHIFT)
#define BP_CMD_FMT_SIZE 2
#define BP_CMD_FMT_SHIFT 2
#define BP_CMD_FMT_MASK 0x0000000c
#define BP_CMD_GET_FMT(bp_cmd) \
((((unsigned long)(bp_cmd)) & BP_CMD_FMT_MASK) >> BP_CMD_FMT_SHIFT)
#define BP_CMD_BIAS_SIZE 3
#define BP_CMD_BIAS_SHIFT 4
#define BP_CMD_BIAS_MASK 0x00000070
#define BP_CMD_GET_BIAS(bp_cmd) \
((((unsigned long)(bp_cmd)) & BP_CMD_BIAS_MASK) >> BP_CMD_BIAS_SHIFT)
#define BP_CMD_BS_SIZE 2
#define BP_CMD_BS_SHIFT 7
#define BP_CMD_BS_MASK 0x00000180
#define BP_CMD_GET_BS(bp_cmd) \
((((unsigned long)(bp_cmd)) & BP_CMD_BS_MASK) >> BP_CMD_BS_SHIFT)
#define BP_CMD_M_SIZE 4
#define BP_CMD_M_SHIFT 9
#define BP_CMD_M_MASK 0x00001e00
#define BP_CMD_GET_M(bp_cmd) \
((((unsigned long)(bp_cmd)) & BP_CMD_M_MASK) >> BP_CMD_M_SHIFT)
#define BP_CMD_SW_SIZE 3
#define BP_CMD_SW_SHIFT 13
#define BP_CMD_SW_MASK 0x0000e000
#define BP_CMD_GET_SW(bp_cmd) \
((((unsigned long)(bp_cmd)) & BP_CMD_SW_MASK) >> BP_CMD_SW_SHIFT)
#define BP_CMD_TW_SIZE 3
#define BP_CMD_TW_SHIFT 16
#define BP_CMD_TW_MASK 0x00070000
#define BP_CMD_GET_TW(bp_cmd) \
((((unsigned long)(bp_cmd)) & BP_CMD_TW_MASK) >> BP_CMD_TW_SHIFT)
#define BP_CMD_LB_SIZE 1
#define BP_CMD_LB_SHIFT 19
#define BP_CMD_LB_MASK 0x00080000
#define BP_CMD_GET_LB(bp_cmd) \
((((unsigned long)(bp_cmd)) & BP_CMD_LB_MASK) >> BP_CMD_LB_SHIFT)
#define BP_CMD_FB_SIZE 1
#define BP_CMD_FB_SHIFT 20
#define BP_CMD_FB_MASK 0x00100000
#define BP_CMD_GET_FB(bp_cmd) \
((((unsigned long)(bp_cmd)) & BP_CMD_FB_MASK) >> BP_CMD_FB_SHIFT)
#define BP_CMD_PAD0_SIZE 3
#define BP_CMD_PAD0_SHIFT 21
#define BP_CMD_PAD0_MASK 0x00e00000
#define BP_CMD_GET_PAD0(bp_cmd) \
((((unsigned long)(bp_cmd)) & BP_CMD_PAD0_MASK) >> BP_CMD_PAD0_SHIFT)
#define BP_CMD_RID_SIZE 8
#define BP_CMD_RID_SHIFT 24
#define BP_CMD_RID_MASK 0xff000000
#define BP_CMD_GET_RID(bp_cmd) \
((((unsigned long)(bp_cmd)) & BP_CMD_RID_MASK) >> BP_CMD_RID_SHIFT)
#define BP_MTXA_MA_SIZE 11
#define BP_MTXA_MA_SHIFT 0
#define BP_MTXA_MA_MASK 0x000007ff
#define BP_MTXA_GET_MA(bp_mtxa) \
((((unsigned long)(bp_mtxa)) & BP_MTXA_MA_MASK) >> BP_MTXA_MA_SHIFT)
#define BP_MTXA_MB_SIZE 11
#define BP_MTXA_MB_SHIFT 11
#define BP_MTXA_MB_MASK 0x003ff800
#define BP_MTXA_GET_MB(bp_mtxa) \
((((unsigned long)(bp_mtxa)) & BP_MTXA_MB_MASK) >> BP_MTXA_MB_SHIFT)
#define BP_MTXA_S_SIZE 2
#define BP_MTXA_S_SHIFT 22
#define BP_MTXA_S_MASK 0x00c00000
#define BP_MTXA_GET_S(bp_mtxa) \
((((unsigned long)(bp_mtxa)) & BP_MTXA_S_MASK) >> BP_MTXA_S_SHIFT)
#define BP_MTXA_RID_SIZE 8
#define BP_MTXA_RID_SHIFT 24
#define BP_MTXA_RID_MASK 0xff000000
#define BP_MTXA_GET_RID(bp_mtxa) \
((((unsigned long)(bp_mtxa)) & BP_MTXA_RID_MASK) >> BP_MTXA_RID_SHIFT)
#define BP_MTXB_MC_SIZE 11
#define BP_MTXB_MC_SHIFT 0
#define BP_MTXB_MC_MASK 0x000007ff
#define BP_MTXB_GET_MC(bp_mtxb) \
((((unsigned long)(bp_mtxb)) & BP_MTXB_MC_MASK) >> BP_MTXB_MC_SHIFT)
#define BP_MTXB_MD_SIZE 11
#define BP_MTXB_MD_SHIFT 11
#define BP_MTXB_MD_MASK 0x003ff800
#define BP_MTXB_GET_MD(bp_mtxb) \
((((unsigned long)(bp_mtxb)) & BP_MTXB_MD_MASK) >> BP_MTXB_MD_SHIFT)
#define BP_MTXB_S_SIZE 2
#define BP_MTXB_S_SHIFT 22
#define BP_MTXB_S_MASK 0x00c00000
#define BP_MTXB_GET_S(bp_mtxb) \
((((unsigned long)(bp_mtxb)) & BP_MTXB_S_MASK) >> BP_MTXB_S_SHIFT)
#define BP_MTXB_RID_SIZE 8
#define BP_MTXB_RID_SHIFT 24
#define BP_MTXB_RID_MASK 0xff000000
#define BP_MTXB_GET_RID(bp_mtxb) \
((((unsigned long)(bp_mtxb)) & BP_MTXB_RID_MASK) >> BP_MTXB_RID_SHIFT)
#define BP_MTXC_ME_SIZE 11
#define BP_MTXC_ME_SHIFT 0
#define BP_MTXC_ME_MASK 0x000007ff
#define BP_MTXC_GET_ME(bp_mtxc) \
((((unsigned long)(bp_mtxc)) & BP_MTXC_ME_MASK) >> BP_MTXC_ME_SHIFT)
#define BP_MTXC_MF_SIZE 11
#define BP_MTXC_MF_SHIFT 11
#define BP_MTXC_MF_MASK 0x003ff800
#define BP_MTXC_GET_MF(bp_mtxc) \
((((unsigned long)(bp_mtxc)) & BP_MTXC_MF_MASK) >> BP_MTXC_MF_SHIFT)
#define BP_MTXC_S_SIZE 2
#define BP_MTXC_S_SHIFT 22
#define BP_MTXC_S_MASK 0x00c00000
#define BP_MTXC_GET_S(bp_mtxc) \
((((unsigned long)(bp_mtxc)) & BP_MTXC_S_MASK) >> BP_MTXC_S_SHIFT)
#define BP_MTXC_RID_SIZE 8
#define BP_MTXC_RID_SHIFT 24
#define BP_MTXC_RID_MASK 0xff000000
#define BP_MTXC_GET_RID(bp_mtxc) \
((((unsigned long)(bp_mtxc)) & BP_MTXC_RID_MASK) >> BP_MTXC_RID_SHIFT)
#define SC_BP_MTXA_SET_MA(line, bp_mtxa,ma) \
FAST_GPFLAGSET(line, bp_mtxa,ma,BP_MTXA_MA)
#define SC_BP_MTXA_SET_MB(line, bp_mtxa,mb) \
FAST_GPFLAGSET(line, bp_mtxa,mb,BP_MTXA_MB)
#define SC_BP_MTXA_SET_S(line, bp_mtxa,s) \
FAST_GPFLAGSET(line, bp_mtxa,s,BP_MTXA_S)
#define SC_BP_MTXA_SET_RID(line, bp_mtxa,rid) \
FAST_GPFLAGSET(line, bp_mtxa,rid,BP_MTXA_RID)
#define SC_BP_MTXB_SET_MC(line, bp_mtxb,mc) \
FAST_GPFLAGSET(line, bp_mtxb,mc,BP_MTXB_MC)
#define SC_BP_MTXB_SET_MD(line, bp_mtxb,md) \
FAST_GPFLAGSET(line, bp_mtxb,md,BP_MTXB_MD)
#define SC_BP_MTXB_SET_S(line, bp_mtxb,s) \
FAST_GPFLAGSET(line, bp_mtxb,s,BP_MTXB_S)
#define SC_BP_MTXB_SET_RID(line, bp_mtxb,rid) \
FAST_GPFLAGSET(line, bp_mtxb,rid,BP_MTXB_RID)
#define SC_BP_MTXC_SET_ME(line, bp_mtxc,me) \
FAST_GPFLAGSET(line, bp_mtxc,me,BP_MTXC_ME)
#define SC_BP_MTXC_SET_MF(line, bp_mtxc,mf) \
FAST_GPFLAGSET(line, bp_mtxc,mf,BP_MTXC_MF)
#define SC_BP_MTXC_SET_S(line, bp_mtxc,s) \
FAST_GPFLAGSET(line, bp_mtxc,s,BP_MTXC_S)
#define SC_BP_MTXC_SET_RID(line, bp_mtxc,rid) \
FAST_GPFLAGSET(line, bp_mtxc,rid,BP_MTXC_RID)
#define SC_BP_CMD_SET_BT(line, bp_cmd,bt) \
FAST_GPFLAGSET(line, bp_cmd,bt,BP_CMD_BT)
#define SC_BP_CMD_SET_FMT(line, bp_cmd,fmt) \
FAST_GPFLAGSET(line, bp_cmd,fmt,BP_CMD_FMT)
#define SC_BP_CMD_SET_BIAS(line, bp_cmd,bias) \
FAST_GPFLAGSET(line, bp_cmd,bias,BP_CMD_BIAS)
#define SC_BP_CMD_SET_BS(line, bp_cmd,bs) \
FAST_GPFLAGSET(line, bp_cmd,bs,BP_CMD_BS)
#define SC_BP_CMD_SET_M(line, bp_cmd,m) \
FAST_GPFLAGSET(line, bp_cmd,m,BP_CMD_M)
#define SC_BP_CMD_SET_SW(line, bp_cmd,sw) \
FAST_GPFLAGSET(line, bp_cmd,sw,BP_CMD_SW)
#define SC_BP_CMD_SET_TW(line, bp_cmd,tw) \
FAST_GPFLAGSET(line, bp_cmd,tw,BP_CMD_TW)
#define SC_BP_CMD_SET_LB(line, bp_cmd,lb) \
FAST_GPFLAGSET(line, bp_cmd,lb,BP_CMD_LB)
#define SC_BP_CMD_SET_FB(line, bp_cmd,fb) \
FAST_GPFLAGSET(line, bp_cmd,fb,BP_CMD_FB)
#define SC_BP_CMD_SET_PAD0(line, bp_cmd,pad0) \
FAST_GPFLAGSET(line, bp_cmd,pad0,BP_CMD_PAD0)
#define SC_BP_CMD_SET_RID(line, bp_cmd,rid) \
FAST_GPFLAGSET(line, bp_cmd,rid,BP_CMD_RID)
#define SC_BP_IMASK_SET_IMASK(line, bp_imask,imask) \
FAST_GPFLAGSET(line, bp_imask,imask,BP_IMASK_IMASK)
#define SC_BP_IMASK_SET_PAD0(line, bp_imask,pad0) \
FAST_GPFLAGSET(line, bp_imask,pad0,BP_IMASK_PAD0)
#define SC_BP_IMASK_SET_RID(line, bp_imask,rid) \
FAST_GPFLAGSET(line, bp_imask,rid,BP_IMASK_RID)
#endif // BP_REG_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,163 @@
#ifndef GEN_REG_H
#define GEN_REG_H
#include <revolution/private/GXFDLShortcut.h>
#define GEN_MODE_RID_SIZE 8
#define GEN_MODE_RID_SHIFT 24
#define GEN_MODE_RID_MASK 0xff000000
#define GEN_MODE_GET_RID(gen_mode) \
((((unsigned long)(gen_mode)) & GEN_MODE_RID_MASK) >> GEN_MODE_RID_SHIFT)
#define GEN_MODE_NTEX_SIZE 4
#define GEN_MODE_NTEX_SHIFT 0
#define GEN_MODE_NTEX_MASK 0x0000000f
#define GEN_MODE_GET_NTEX(gen_mode) \
((((unsigned long)(gen_mode)) & GEN_MODE_NTEX_MASK) >> GEN_MODE_NTEX_SHIFT)
#define GEN_MODE_NTEX_SIZE 4
#define GEN_MODE_NTEX_SHIFT 0
#define GEN_MODE_NTEX_MASK 0x0000000f
#define GEN_MODE_GET_NTEX(gen_mode) \
((((unsigned long)(gen_mode)) & GEN_MODE_NTEX_MASK) >> GEN_MODE_NTEX_SHIFT)
#define GEN_MODE_NCOL_SIZE 3
#define GEN_MODE_NCOL_SHIFT 4
#define GEN_MODE_NCOL_MASK 0x00000070
#define GEN_MODE_GET_NCOL(gen_mode) \
((((unsigned long)(gen_mode)) & GEN_MODE_NCOL_MASK) >> GEN_MODE_NCOL_SHIFT)
#define GEN_MODE_PAD0_SIZE 1
#define GEN_MODE_PAD0_SHIFT 7
#define GEN_MODE_PAD0_MASK 0x00000080
#define GEN_MODE_GET_PAD0(gen_mode) \
((((unsigned long)(gen_mode)) & GEN_MODE_PAD0_MASK) >> GEN_MODE_PAD0_SHIFT)
#define GEN_MODE_FLAT_EN_SIZE 1
#define GEN_MODE_FLAT_EN_SHIFT 8
#define GEN_MODE_FLAT_EN_MASK 0x00000100
#define GEN_MODE_GET_FLAT_EN(gen_mode) \
((((unsigned long)(gen_mode)) & GEN_MODE_FLAT_EN_MASK) >> GEN_MODE_FLAT_EN_SHIFT)
#define GEN_MODE_MS_EN_SIZE 1
#define GEN_MODE_MS_EN_SHIFT 9
#define GEN_MODE_MS_EN_MASK 0x00000200
#define GEN_MODE_GET_MS_EN(gen_mode) \
((((unsigned long)(gen_mode)) & GEN_MODE_MS_EN_MASK) >> GEN_MODE_MS_EN_SHIFT)
#define GEN_MODE_NTEV_SIZE 4
#define GEN_MODE_NTEV_SHIFT 10
#define GEN_MODE_NTEV_MASK 0x00003c00
#define GEN_MODE_GET_NTEV(gen_mode) \
((((unsigned long)(gen_mode)) & GEN_MODE_NTEV_MASK) >> GEN_MODE_NTEV_SHIFT)
#define GEN_MODE_REJECT_EN_SIZE 2
#define GEN_MODE_REJECT_EN_SHIFT 14
#define GEN_MODE_REJECT_EN_MASK 0x0000c000
#define GEN_MODE_GET_REJECT_EN(gen_mode) \
((((unsigned long)(gen_mode)) & GEN_MODE_REJECT_EN_MASK) >> GEN_MODE_REJECT_EN_SHIFT)
#define GEN_MODE_NBMP_SIZE 3
#define GEN_MODE_NBMP_SHIFT 16
#define GEN_MODE_NBMP_MASK 0x00070000
#define GEN_MODE_GET_NBMP(gen_mode) \
((((unsigned long)(gen_mode)) & GEN_MODE_NBMP_MASK) >> GEN_MODE_NBMP_SHIFT)
#define GEN_MODE_ZFREEZE_SIZE 1
#define GEN_MODE_ZFREEZE_SHIFT 19
#define GEN_MODE_ZFREEZE_MASK 0x00080000
#define GEN_MODE_GET_ZFREEZE(gen_mode) \
((((unsigned long)(gen_mode)) & GEN_MODE_ZFREEZE_MASK) >> GEN_MODE_ZFREEZE_SHIFT)
#define GEN_MODE_PAD1_SIZE 4
#define GEN_MODE_PAD1_SHIFT 20
#define GEN_MODE_PAD1_MASK 0x00f00000
#define GEN_MODE_GET_PAD1(gen_mode) \
((((unsigned long)(gen_mode)) & GEN_MODE_PAD1_MASK) >> GEN_MODE_PAD1_SHIFT)
#define GEN_MODE_RID_SIZE 8
#define GEN_MODE_RID_SHIFT 24
#define GEN_MODE_RID_MASK 0xff000000
#define GEN_MODE_GET_RID(gen_mode) \
((((unsigned long)(gen_mode)) & GEN_MODE_RID_MASK) >> GEN_MODE_RID_SHIFT)
#define SC_GEN_MODE_SET_NTEX(line, gen_mode,ntex) \
FAST_GPFLAGSET(line, gen_mode,ntex,GEN_MODE_NTEX)
#define SC_GEN_MODE_SET_NCOL(line, gen_mode,ncol) \
FAST_GPFLAGSET(line, gen_mode,ncol,GEN_MODE_NCOL)
#define SC_GEN_MODE_SET_PAD0(line, gen_mode,pad0) \
FAST_GPFLAGSET(line, gen_mode,pad0,GEN_MODE_PAD0)
#define SC_GEN_MODE_SET_FLAT_EN(line, gen_mode,flat_en) \
FAST_GPFLAGSET(line, gen_mode,flat_en,GEN_MODE_FLAT_EN)
#define SC_GEN_MODE_SET_MS_EN(line, gen_mode,ms_en) \
FAST_GPFLAGSET(line, gen_mode,ms_en,GEN_MODE_MS_EN)
#define SC_GEN_MODE_SET_NTEV(line, gen_mode,ntev) \
FAST_GPFLAGSET(line, gen_mode,ntev,GEN_MODE_NTEV)
#define SC_GEN_MODE_SET_REJECT_EN(line, gen_mode,reject_en) \
FAST_GPFLAGSET(line, gen_mode,reject_en,GEN_MODE_REJECT_EN)
#define SC_GEN_MODE_SET_NBMP(line, gen_mode,nbmp) \
FAST_GPFLAGSET(line, gen_mode,nbmp,GEN_MODE_NBMP)
#define SC_GEN_MODE_SET_ZFREEZE(line, gen_mode,zfreeze) \
FAST_GPFLAGSET(line, gen_mode,zfreeze,GEN_MODE_ZFREEZE)
#define SC_GEN_MODE_SET_PAD1(line, gen_mode,pad1) \
FAST_GPFLAGSET(line, gen_mode,pad1,GEN_MODE_PAD1)
#define SC_GEN_MODE_SET_RID(line, gen_mode,rid) \
FAST_GPFLAGSET(line, gen_mode,rid,GEN_MODE_RID)
#define SC_GEN_MSLOC_SET_XS0(line, gen_msloc,xs0) \
FAST_GPFLAGSET(line, gen_msloc,xs0,GEN_MSLOC_XS0)
#define SC_GEN_MSLOC_SET_YS0(line, gen_msloc,ys0) \
FAST_GPFLAGSET(line, gen_msloc,ys0,GEN_MSLOC_YS0)
#define SC_GEN_MSLOC_SET_XS1(line, gen_msloc,xs1) \
FAST_GPFLAGSET(line, gen_msloc,xs1,GEN_MSLOC_XS1)
#define SC_GEN_MSLOC_SET_YS1(line, gen_msloc,ys1) \
FAST_GPFLAGSET(line, gen_msloc,ys1,GEN_MSLOC_YS1)
#define SC_GEN_MSLOC_SET_XS2(line, gen_msloc,xs2) \
FAST_GPFLAGSET(line, gen_msloc,xs2,GEN_MSLOC_XS2)
#define SC_GEN_MSLOC_SET_YS2(line, gen_msloc,ys2) \
FAST_GPFLAGSET(line, gen_msloc,ys2,GEN_MSLOC_YS2)
#define SC_GEN_MSLOC_SET_RID(line, gen_msloc,rid) \
FAST_GPFLAGSET(line, gen_msloc,rid,GEN_MSLOC_RID)
#define SC_GEN_COLOR_SET_ALPHA(line, gen_color,alpha) \
FAST_GPFLAGSET(line, gen_color,alpha,GEN_COLOR_ALPHA)
#define SC_GEN_COLOR_SET_BLUE(line, gen_color,blue) \
FAST_GPFLAGSET(line, gen_color,blue,GEN_COLOR_BLUE)
#define SC_GEN_COLOR_SET_GREEN(line, gen_color,green) \
FAST_GPFLAGSET(line, gen_color,green,GEN_COLOR_GREEN)
#define SC_GEN_COLOR_SET_RED(line, gen_color,red) \
FAST_GPFLAGSET(line, gen_color,red,GEN_COLOR_RED)
#define SC_GEN_Z24_COLOR_SET_BLUE(line, gen_z24_color,blue) \
FAST_GPFLAGSET(line, gen_z24_color,blue,GEN_Z24_COLOR_BLUE)
#define SC_GEN_Z24_COLOR_SET_GREEN(line, gen_z24_color,green) \
FAST_GPFLAGSET(line, gen_z24_color,green,GEN_Z24_COLOR_GREEN)
#define SC_GEN_Z24_COLOR_SET_RED(line, gen_z24_color,red) \
FAST_GPFLAGSET(line, gen_z24_color,red,GEN_Z24_COLOR_RED)
#define SC_GEN_Z24_COLOR_SET_PAD0(line, gen_z24_color,pad0) \
FAST_GPFLAGSET(line, gen_z24_color,pad0,GEN_Z24_COLOR_PAD0)
#endif // GEN_REG_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,73 @@
#ifndef PI_REG_H
#define PI_REG_H
#include <revolution/private/GXFDLShortcut.h>
#define PI_REG_INTSR 0x000
#define PI_REG_INTMSK 0x004
#define PI_REG_CPBAS 0x00C
#define PI_REG_CPTOP 0x010
#define PI_REG_CPWRT 0x014
#define PI_REG_CPABT 0x018
#define PI_REG_PIESR 0x01C
#define PI_REG_PIEAR 0x020
#define PI_REG_CONFIG 0x024
#define PI_REG_DURAR 0x028
#define PI_REG_CHIPID 0x02C
#define PI_REG_STRGTH 0x030
#define PI_REG_CPUDBB 0x034
#define PI_REGSP_CP 0x0C000000
#define PI_REGSP_PE 0x0C001000
#define PI_REGSP_VI 0x0C002000
#define PI_REGSP_PI 0x0C003000
#define PI_REGSP_MEM 0x0C004000
#define PI_REGSP_DSP 0x0C005000
#define PI_REGSP_IO 0x0C006000
#define PI_GFXSP 0x0C008000
#define PI_CPWRT_REG_CPWRT_SIZE 24
#define PI_CPWRT_REG_CPWRT_SHIFT 5
#define PI_CPWRT_REG_CPWRT_MASK 0x1fffffe0
#define PI_CPWRT_REG_GET_CPWRT(pi_cpwrt_reg) \
((((unsigned long)(pi_cpwrt_reg)) & PI_CPWRT_REG_CPWRT_MASK) >> PI_CPWRT_REG_CPWRT_SHIFT)
#define XF_PERF0_F_PERF_B_SIZE 5
#define XF_PERF0_F_PERF_B_SHIFT 5
#define XF_PERF0_F_PERF_B_MASK 0x000003e0
#define XF_PERF0_F_GET_PERF_B(xf_perf0_f) \
((((unsigned long)(xf_perf0_f)) & XF_PERF0_F_PERF_B_MASK) >> XF_PERF0_F_PERF_B_SHIFT)
#define XF_PERF0_F_PERF_C_SIZE 5
#define XF_PERF0_F_PERF_C_SHIFT 10
#define XF_PERF0_F_PERF_C_MASK 0x00007c00
#define XF_PERF0_F_GET_PERF_C(xf_perf0_f) \
((((unsigned long)(xf_perf0_f)) & XF_PERF0_F_PERF_C_MASK) >> XF_PERF0_F_PERF_C_SHIFT)
#define XF_PERF0_F_PERF_D_SIZE 5
#define XF_PERF0_F_PERF_D_SHIFT 15
#define XF_PERF0_F_PERF_D_MASK 0x000f8000
#define XF_PERF0_F_GET_PERF_D(xf_perf0_f) \
((((unsigned long)(xf_perf0_f)) & XF_PERF0_F_PERF_D_MASK) >> XF_PERF0_F_PERF_D_SHIFT)
#define XF_PERF0_F_PERF_A_SIZE 5
#define XF_PERF0_F_PERF_A_SHIFT 0
#define XF_PERF0_F_PERF_A_MASK 0x0000001f
#define XF_PERF0_F_GET_PERF_A(xf_perf0_f) \
((((unsigned long)(xf_perf0_f)) & XF_PERF0_F_PERF_A_MASK) >> XF_PERF0_F_PERF_A_SHIFT)
#define PI_CPWRT_REG_CPWRAP_SIZE 1
#define PI_CPWRT_REG_CPWRAP_SHIFT 29
#define PI_CPWRT_REG_CPWRAP_MASK 0x20000000
#define PI_CPWRT_REG_GET_CPWRAP(pi_cpwrt_reg) \
((((unsigned long)(pi_cpwrt_reg)) & PI_CPWRT_REG_CPWRAP_MASK) >> PI_CPWRT_REG_CPWRAP_SHIFT)
#define SC_PI_CPWRT_REG_SET_CPWRT(line, pi_cpwrt_reg,cpwrt) \
FAST_GPFLAGSET(line, pi_cpwrt_reg,cpwrt,PI_CPWRT_REG_CPWRT)
#define SC_PI_CPWRT_REG_SET_CPWRAP(line, pi_cpwrt_reg,cpwrap) \
FAST_GPFLAGSET(line, pi_cpwrt_reg,cpwrap,PI_CPWRT_REG_CPWRAP)
#endif // PI_REG_H

View File

@ -0,0 +1,232 @@
#ifndef RAS_REG
#define RAS_REG
#define RAS1_TREF_RID_SIZE 8
#define RAS1_TREF_RID_SHIFT 24
#define RAS1_TREF_RID_MASK 0xff000000
#define RAS1_TREF_GET_RID(ras1_tref) \
((((unsigned long)(ras1_tref)) & RAS1_TREF_RID_MASK) >> RAS1_TREF_RID_SHIFT)
#define RAS1_IREF_RID_SIZE 8
#define RAS1_IREF_RID_SHIFT 24
#define RAS1_IREF_RID_MASK 0xff000000
#define RAS1_IREF_GET_RID(ras1_iref) \
((((unsigned long)(ras1_iref)) & RAS1_IREF_RID_MASK) >> RAS1_IREF_RID_SHIFT)
#define RAS_PERF_SELA_SIZE 5
#define RAS_PERF_SELA_SHIFT 0
#define RAS_PERF_SELA_MASK 0x0000001f
#define RAS_PERF_GET_SELA(ras_perf) \
((((unsigned long)(ras_perf)) & RAS_PERF_SELA_MASK) >> RAS_PERF_SELA_SHIFT)
#define RAS_PERF_SELB_SIZE 5
#define RAS_PERF_SELB_SHIFT 5
#define RAS_PERF_SELB_MASK 0x000003e0
#define RAS_PERF_GET_SELB(ras_perf) \
((((unsigned long)(ras_perf)) & RAS_PERF_SELB_MASK) >> RAS_PERF_SELB_SHIFT)
#define RAS_PERF_NTEV_SIZE 5
#define RAS_PERF_NTEV_SHIFT 10
#define RAS_PERF_NTEV_MASK 0x00007c00
#define RAS_PERF_GET_NTEV(ras_perf) \
((((unsigned long)(ras_perf)) & RAS_PERF_NTEV_MASK) >> RAS_PERF_NTEV_SHIFT)
#define RAS_PERF_NBMP_SIZE 3
#define RAS_PERF_NBMP_SHIFT 15
#define RAS_PERF_NBMP_MASK 0x00038000
#define RAS_PERF_GET_NBMP(ras_perf) \
((((unsigned long)(ras_perf)) & RAS_PERF_NBMP_MASK) >> RAS_PERF_NBMP_SHIFT)
#define RAS_PERF_NBR_SIZE 3
#define RAS_PERF_NBR_SHIFT 18
#define RAS_PERF_NBR_MASK 0x001c0000
#define RAS_PERF_GET_NBR(ras_perf) \
((((unsigned long)(ras_perf)) & RAS_PERF_NBR_MASK) >> RAS_PERF_NBR_SHIFT)
#define RAS_PERF_PAD0_SIZE 3
#define RAS_PERF_PAD0_SHIFT 21
#define RAS_PERF_PAD0_MASK 0x00e00000
#define RAS_PERF_GET_PAD0(ras_perf) \
((((unsigned long)(ras_perf)) & RAS_PERF_PAD0_MASK) >> RAS_PERF_PAD0_SHIFT)
#define RAS_PERF_RID_SIZE 8
#define RAS_PERF_RID_SHIFT 24
#define RAS_PERF_RID_MASK 0xff000000
#define RAS_PERF_GET_RID(ras_perf) \
((((unsigned long)(ras_perf)) & RAS_PERF_RID_MASK) >> RAS_PERF_RID_SHIFT)
#define RAS_PERF_TOTAL_SIZE 32
#define RAS_PERF(selA, selB, ntev, nbmp, nbr, rid) \
((((unsigned long)(selA)) << RAS_PERF_SELA_SHIFT) | \
(((unsigned long)(selB)) << RAS_PERF_SELB_SHIFT) | \
(((unsigned long)(ntev)) << RAS_PERF_NTEV_SHIFT) | \
(((unsigned long)(nbmp)) << RAS_PERF_NBMP_SHIFT) | \
(((unsigned long)(nbr)) << RAS_PERF_NBR_SHIFT) | \
(((unsigned long)(rid)) << RAS_PERF_RID_SHIFT))
#define RAS1_TREF_TI0_SIZE 3
#define RAS1_TREF_TI0_SHIFT 0
#define RAS1_TREF_TI0_MASK 0x00000007
#define RAS1_TREF_GET_TI0(ras1_tref) \
((((unsigned long)(ras1_tref)) & RAS1_TREF_TI0_MASK) >> RAS1_TREF_TI0_SHIFT)
#define RAS1_TREF_TC0_SIZE 3
#define RAS1_TREF_TC0_SHIFT 3
#define RAS1_TREF_TC0_MASK 0x00000038
#define RAS1_TREF_GET_TC0(ras1_tref) \
((((unsigned long)(ras1_tref)) & RAS1_TREF_TC0_MASK) >> RAS1_TREF_TC0_SHIFT)
#define RAS1_TREF_TE0_SIZE 1
#define RAS1_TREF_TE0_SHIFT 6
#define RAS1_TREF_TE0_MASK 0x00000040
#define RAS1_TREF_GET_TE0(ras1_tref) \
((((unsigned long)(ras1_tref)) & RAS1_TREF_TE0_MASK) >> RAS1_TREF_TE0_SHIFT)
#define RAS1_TREF_CC0_SIZE 3
#define RAS1_TREF_CC0_SHIFT 7
#define RAS1_TREF_CC0_MASK 0x00000380
#define RAS1_TREF_GET_CC0(ras1_tref) \
((((unsigned long)(ras1_tref)) & RAS1_TREF_CC0_MASK) >> RAS1_TREF_CC0_SHIFT)
#define RAS1_TREF_PAD0_SIZE 2
#define RAS1_TREF_PAD0_SHIFT 10
#define RAS1_TREF_PAD0_MASK 0x00000c00
#define RAS1_TREF_GET_PAD0(ras1_tref) \
((((unsigned long)(ras1_tref)) & RAS1_TREF_PAD0_MASK) >> RAS1_TREF_PAD0_SHIFT)
#define RAS1_TREF_TI1_SIZE 3
#define RAS1_TREF_TI1_SHIFT 12
#define RAS1_TREF_TI1_MASK 0x00007000
#define RAS1_TREF_GET_TI1(ras1_tref) \
((((unsigned long)(ras1_tref)) & RAS1_TREF_TI1_MASK) >> RAS1_TREF_TI1_SHIFT)
#define RAS1_TREF_TC1_SIZE 3
#define RAS1_TREF_TC1_SHIFT 15
#define RAS1_TREF_TC1_MASK 0x00038000
#define RAS1_TREF_GET_TC1(ras1_tref) \
((((unsigned long)(ras1_tref)) & RAS1_TREF_TC1_MASK) >> RAS1_TREF_TC1_SHIFT)
#define RAS1_TREF_TE1_SIZE 1
#define RAS1_TREF_TE1_SHIFT 18
#define RAS1_TREF_TE1_MASK 0x00040000
#define RAS1_TREF_GET_TE1(ras1_tref) \
((((unsigned long)(ras1_tref)) & RAS1_TREF_TE1_MASK) >> RAS1_TREF_TE1_SHIFT)
#define RAS1_TREF_CC1_SIZE 3
#define RAS1_TREF_CC1_SHIFT 19
#define RAS1_TREF_CC1_MASK 0x00380000
#define RAS1_TREF_GET_CC1(ras1_tref) \
((((unsigned long)(ras1_tref)) & RAS1_TREF_CC1_MASK) >> RAS1_TREF_CC1_SHIFT)
#define RAS1_TREF_PAD1_SIZE 2
#define RAS1_TREF_PAD1_SHIFT 22
#define RAS1_TREF_PAD1_MASK 0x00c00000
#define RAS1_TREF_GET_PAD1(ras1_tref) \
((((unsigned long)(ras1_tref)) & RAS1_TREF_PAD1_MASK) >> RAS1_TREF_PAD1_SHIFT)
#define RAS1_TREF_RID_SIZE 8
#define RAS1_TREF_RID_SHIFT 24
#define RAS1_TREF_RID_MASK 0xff000000
#define RAS1_TREF_GET_RID(ras1_tref) \
((((unsigned long)(ras1_tref)) & RAS1_TREF_RID_MASK) >> RAS1_TREF_RID_SHIFT)
#define SC_RAS1_SS_SET_SS0(line, ras1_ss,ss0) \
FAST_GPFLAGSET(line, ras1_ss,ss0,RAS1_SS_SS0)
#define SC_RAS1_SS_SET_TS0(line, ras1_ss,ts0) \
FAST_GPFLAGSET(line, ras1_ss,ts0,RAS1_SS_TS0)
#define SC_RAS1_SS_SET_SS1(line, ras1_ss,ss1) \
FAST_GPFLAGSET(line, ras1_ss,ss1,RAS1_SS_SS1)
#define SC_RAS1_SS_SET_TS1(line, ras1_ss,ts1) \
FAST_GPFLAGSET(line, ras1_ss,ts1,RAS1_SS_TS1)
#define SC_RAS1_SS_SET_PAD0(line, ras1_ss,pad0) \
FAST_GPFLAGSET(line, ras1_ss,pad0,RAS1_SS_PAD0)
#define SC_RAS1_SS_SET_RID(line, ras1_ss,rid) \
FAST_GPFLAGSET(line, ras1_ss,rid,RAS1_SS_RID)
#define SC_RAS1_IREF_SET_BI0(line, ras1_iref,bi0) \
FAST_GPFLAGSET(line, ras1_iref,bi0,RAS1_IREF_BI0)
#define SC_RAS1_IREF_SET_BC0(line, ras1_iref,bc0) \
FAST_GPFLAGSET(line, ras1_iref,bc0,RAS1_IREF_BC0)
#define SC_RAS1_IREF_SET_BI1(line, ras1_iref,bi1) \
FAST_GPFLAGSET(line, ras1_iref,bi1,RAS1_IREF_BI1)
#define SC_RAS1_IREF_SET_BC1(line, ras1_iref,bc1) \
FAST_GPFLAGSET(line, ras1_iref,bc1,RAS1_IREF_BC1)
#define SC_RAS1_IREF_SET_BI2(line, ras1_iref,bi2) \
FAST_GPFLAGSET(line, ras1_iref,bi2,RAS1_IREF_BI2)
#define SC_RAS1_IREF_SET_BC2(line, ras1_iref,bc2) \
FAST_GPFLAGSET(line, ras1_iref,bc2,RAS1_IREF_BC2)
#define SC_RAS1_IREF_SET_BI3(line, ras1_iref,bi3) \
FAST_GPFLAGSET(line, ras1_iref,bi3,RAS1_IREF_BI3)
#define SC_RAS1_IREF_SET_BC3(line, ras1_iref,bc3) \
FAST_GPFLAGSET(line, ras1_iref,bc3,RAS1_IREF_BC3)
#define SC_RAS1_IREF_SET_RID(line, ras1_iref,rid) \
FAST_GPFLAGSET(line, ras1_iref,rid,RAS1_IREF_RID)
#define SC_RAS1_TREF_SET_TI0(line, ras1_tref,ti0) \
FAST_GPFLAGSET(line, ras1_tref,ti0,RAS1_TREF_TI0)
#define SC_RAS1_TREF_SET_TC0(line, ras1_tref,tc0) \
FAST_GPFLAGSET(line, ras1_tref,tc0,RAS1_TREF_TC0)
#define SC_RAS1_TREF_SET_TE0(line, ras1_tref,te0) \
FAST_GPFLAGSET(line, ras1_tref,te0,RAS1_TREF_TE0)
#define SC_RAS1_TREF_SET_CC0(line, ras1_tref,cc0) \
FAST_GPFLAGSET(line, ras1_tref,cc0,RAS1_TREF_CC0)
#define SC_RAS1_TREF_SET_PAD0(line, ras1_tref,pad0) \
FAST_GPFLAGSET(line, ras1_tref,pad0,RAS1_TREF_PAD0)
#define SC_RAS1_TREF_SET_TI1(line, ras1_tref,ti1) \
FAST_GPFLAGSET(line, ras1_tref,ti1,RAS1_TREF_TI1)
#define SC_RAS1_TREF_SET_TC1(line, ras1_tref,tc1) \
FAST_GPFLAGSET(line, ras1_tref,tc1,RAS1_TREF_TC1)
#define SC_RAS1_TREF_SET_TE1(line, ras1_tref,te1) \
FAST_GPFLAGSET(line, ras1_tref,te1,RAS1_TREF_TE1)
#define SC_RAS1_TREF_SET_CC1(line, ras1_tref,cc1) \
FAST_GPFLAGSET(line, ras1_tref,cc1,RAS1_TREF_CC1)
#define SC_RAS1_TREF_SET_PAD1(line, ras1_tref,pad1) \
FAST_GPFLAGSET(line, ras1_tref,pad1,RAS1_TREF_PAD1)
#define SC_RAS1_TREF_SET_RID(line, ras1_tref,rid) \
FAST_GPFLAGSET(line, ras1_tref,rid,RAS1_TREF_RID)
#define SC_RAS_PERF_SET_SELA(line, ras_perf,selA) \
FAST_GPFLAGSET(line, ras_perf,selA,RAS_PERF_SELA)
#define SC_RAS_PERF_SET_SELB(line, ras_perf,selB) \
FAST_GPFLAGSET(line, ras_perf,selB,RAS_PERF_SELB)
#define SC_RAS_PERF_SET_NTEV(line, ras_perf,ntev) \
FAST_GPFLAGSET(line, ras_perf,ntev,RAS_PERF_NTEV)
#define SC_RAS_PERF_SET_NBMP(line, ras_perf,nbmp) \
FAST_GPFLAGSET(line, ras_perf,nbmp,RAS_PERF_NBMP)
#define SC_RAS_PERF_SET_NBR(line, ras_perf,nbr) \
FAST_GPFLAGSET(line, ras_perf,nbr,RAS_PERF_NBR)
#define SC_RAS_PERF_SET_PAD0(line, ras_perf,pad0) \
FAST_GPFLAGSET(line, ras_perf,pad0,RAS_PERF_PAD0)
#define SC_RAS_PERF_SET_RID(line, ras_perf,rid) \
FAST_GPFLAGSET(line, ras_perf,rid,RAS_PERF_RID)
#endif // RAS_REG

View File

@ -0,0 +1,387 @@
#ifndef SU_REG_H
#define SU_REG_H
#define SU_LPSIZE_RID_SIZE 8
#define SU_LPSIZE_RID_SHIFT 24
#define SU_LPSIZE_RID_MASK 0xff000000
#define SU_LPSIZE_GET_RID(su_lpsize) \
((((unsigned long)(su_lpsize)) & SU_LPSIZE_RID_MASK) >> SU_LPSIZE_RID_SHIFT)
#define SU_TS0_RID_SIZE 8
#define SU_TS0_RID_SHIFT 24
#define SU_TS0_RID_MASK 0xff000000
#define SU_TS0_GET_RID(su_ts0) \
((((unsigned long)(su_ts0)) & SU_TS0_RID_MASK) >> SU_TS0_RID_SHIFT)
#define SU_TS1_RID_SIZE 8
#define SU_TS1_RID_SHIFT 24
#define SU_TS1_RID_MASK 0xff000000
#define SU_TS1_GET_RID(su_ts1) \
((((unsigned long)(su_ts1)) & SU_TS1_RID_MASK) >> SU_TS1_RID_SHIFT)
#define SU_SCIS0_RID_SIZE 8
#define SU_SCIS0_RID_SHIFT 24
#define SU_SCIS0_RID_MASK 0xff000000
#define SU_SCIS0_GET_RID(su_scis0) \
((((unsigned long)(su_scis0)) & SU_SCIS0_RID_MASK) >> SU_SCIS0_RID_SHIFT)
#define SU_PERF_SELA_SIZE 3
#define SU_PERF_SELA_SHIFT 0
#define SU_PERF_SELA_MASK 0x00000007
#define SU_PERF_GET_SELA(su_perf) \
((((unsigned long)(su_perf)) & SU_PERF_SELA_MASK) >> SU_PERF_SELA_SHIFT)
#define SU_SCIS1_RID_SIZE 8
#define SU_SCIS1_RID_SHIFT 24
#define SU_SCIS1_RID_MASK 0xff000000
#define SU_SCIS1_GET_RID(su_scis1) \
((((unsigned long)(su_scis1)) & SU_SCIS1_RID_MASK) >> SU_SCIS1_RID_SHIFT)
#define SU_PERF_NTEX_SIZE 4
#define SU_PERF_NTEX_SHIFT 6
#define SU_PERF_NTEX_MASK 0x000003c0
#define SU_PERF_GET_NTEX(su_perf) \
((((unsigned long)(su_perf)) & SU_PERF_NTEX_MASK) >> SU_PERF_NTEX_SHIFT)
#define SU_PERF_NCOL_SIZE 2
#define SU_PERF_NCOL_SHIFT 10
#define SU_PERF_NCOL_MASK 0x00000c00
#define SU_PERF_GET_NCOL(su_perf) \
((((unsigned long)(su_perf)) & SU_PERF_NCOL_MASK) >> SU_PERF_NCOL_SHIFT)
#define SU_PERF_SELB_SIZE 3
#define SU_PERF_SELB_SHIFT 3
#define SU_PERF_SELB_MASK 0x00000038
#define SU_PERF_GET_SELB(su_perf) \
((((unsigned long)(su_perf)) & SU_PERF_SELB_MASK) >> SU_PERF_SELB_SHIFT)
#define SU_PERF_REJF_SIZE 2
#define SU_PERF_REJF_SHIFT 12
#define SU_PERF_REJF_MASK 0x00003000
#define SU_PERF_GET_REJF(su_perf) \
((((unsigned long)(su_perf)) & SU_PERF_REJF_MASK) >> SU_PERF_REJF_SHIFT)
#define SU_PERF_REJS_SIZE 2
#define SU_PERF_REJS_SHIFT 14
#define SU_PERF_REJS_MASK 0x0000c000
#define SU_PERF_GET_REJS(su_perf) \
((((unsigned long)(su_perf)) & SU_PERF_REJS_MASK) >> SU_PERF_REJS_SHIFT)
#define SU_PERF_CMD_SIZE 2
#define SU_PERF_CMD_SHIFT 16
#define SU_PERF_CMD_MASK 0x00030000
#define SU_PERF_GET_CMD(su_perf) \
((((unsigned long)(su_perf)) & SU_PERF_CMD_MASK) >> SU_PERF_CMD_SHIFT)
#define SU_PERF_PAD0_SIZE 2
#define SU_PERF_PAD0_SHIFT 18
#define SU_PERF_PAD0_MASK 0x000c0000
#define SU_PERF_GET_PAD0(su_perf) \
((((unsigned long)(su_perf)) & SU_PERF_PAD0_MASK) >> SU_PERF_PAD0_SHIFT)
#define SU_PERF_EN_SIZE 2
#define SU_PERF_EN_SHIFT 20
#define SU_PERF_EN_MASK 0x00300000
#define SU_PERF_GET_EN(su_perf) \
((((unsigned long)(su_perf)) & SU_PERF_EN_MASK) >> SU_PERF_EN_SHIFT)
#define SU_PERF_PWR_EN_SIZE 2
#define SU_PERF_PWR_EN_SHIFT 22
#define SU_PERF_PWR_EN_MASK 0x00c00000
#define SU_PERF_GET_PWR_EN(su_perf) \
((((unsigned long)(su_perf)) & SU_PERF_PWR_EN_MASK) >> SU_PERF_PWR_EN_SHIFT)
#define SU_PERF_RID_SIZE 8
#define SU_PERF_RID_SHIFT 24
#define SU_PERF_RID_MASK 0xff000000
#define SU_PERF_GET_RID(su_perf) \
((((unsigned long)(su_perf)) & SU_PERF_RID_MASK) >> SU_PERF_RID_SHIFT)
#define SU_PERF_TOTAL_SIZE 32
#define SU_PERF(selA, selB, ntex, ncol, rejf, rejs, cmd, en, pwr_en, rid) \
((((unsigned long)(selA)) << SU_PERF_SELA_SHIFT) | \
(((unsigned long)(selB)) << SU_PERF_SELB_SHIFT) | \
(((unsigned long)(ntex)) << SU_PERF_NTEX_SHIFT) | \
(((unsigned long)(ncol)) << SU_PERF_NCOL_SHIFT) | \
(((unsigned long)(rejf)) << SU_PERF_REJF_SHIFT) | \
(((unsigned long)(rejs)) << SU_PERF_REJS_SHIFT) | \
(((unsigned long)(cmd)) << SU_PERF_CMD_SHIFT) | \
(((unsigned long)(en)) << SU_PERF_EN_SHIFT) | \
(((unsigned long)(pwr_en)) << SU_PERF_PWR_EN_SHIFT) | \
(((unsigned long)(rid)) << SU_PERF_RID_SHIFT))
#define SU_LPSIZE_LSIZE_SIZE 8
#define SU_LPSIZE_LSIZE_SHIFT 0
#define SU_LPSIZE_LSIZE_MASK 0x000000ff
#define SU_LPSIZE_GET_LSIZE(su_lpsize) \
((((unsigned long)(su_lpsize)) & SU_LPSIZE_LSIZE_MASK) >> SU_LPSIZE_LSIZE_SHIFT)
#define SU_LPSIZE_PSIZE_SIZE 8
#define SU_LPSIZE_PSIZE_SHIFT 8
#define SU_LPSIZE_PSIZE_MASK 0x0000ff00
#define SU_LPSIZE_GET_PSIZE(su_lpsize) \
((((unsigned long)(su_lpsize)) & SU_LPSIZE_PSIZE_MASK) >> SU_LPSIZE_PSIZE_SHIFT)
#define SU_LPSIZE_LTOFF_SIZE 3
#define SU_LPSIZE_LTOFF_SHIFT 16
#define SU_LPSIZE_LTOFF_MASK 0x00070000
#define SU_LPSIZE_GET_LTOFF(su_lpsize) \
((((unsigned long)(su_lpsize)) & SU_LPSIZE_LTOFF_MASK) >> SU_LPSIZE_LTOFF_SHIFT)
#define SU_LPSIZE_PTOFF_SIZE 3
#define SU_LPSIZE_PTOFF_SHIFT 19
#define SU_LPSIZE_PTOFF_MASK 0x00380000
#define SU_LPSIZE_GET_PTOFF(su_lpsize) \
((((unsigned long)(su_lpsize)) & SU_LPSIZE_PTOFF_MASK) >> SU_LPSIZE_PTOFF_SHIFT)
#define SU_LPSIZE_FIELDMODE_SIZE 1
#define SU_LPSIZE_FIELDMODE_SHIFT 22
#define SU_LPSIZE_FIELDMODE_MASK 0x00400000
#define SU_LPSIZE_GET_FIELDMODE(su_lpsize) \
((((unsigned long)(su_lpsize)) & SU_LPSIZE_FIELDMODE_MASK) >> SU_LPSIZE_FIELDMODE_SHIFT)
#define SU_LPSIZE_PAD0_SIZE 1
#define SU_LPSIZE_PAD0_SHIFT 23
#define SU_LPSIZE_PAD0_MASK 0x00800000
#define SU_LPSIZE_GET_PAD0(su_lpsize) \
((((unsigned long)(su_lpsize)) & SU_LPSIZE_PAD0_MASK) >> SU_LPSIZE_PAD0_SHIFT)
#define SU_LPSIZE_RID_SIZE 8
#define SU_LPSIZE_RID_SHIFT 24
#define SU_LPSIZE_RID_MASK 0xff000000
#define SU_LPSIZE_GET_RID(su_lpsize) \
((((unsigned long)(su_lpsize)) & SU_LPSIZE_RID_MASK) >> SU_LPSIZE_RID_SHIFT)
#define SU_TS0_SSIZE_SIZE 16
#define SU_TS0_SSIZE_SHIFT 0
#define SU_TS0_SSIZE_MASK 0x0000ffff
#define SU_TS0_GET_SSIZE(su_ts0) \
((((unsigned long)(su_ts0)) & SU_TS0_SSIZE_MASK) >> SU_TS0_SSIZE_SHIFT)
#define SU_TS0_BS_SIZE 1
#define SU_TS0_BS_SHIFT 16
#define SU_TS0_BS_MASK 0x00010000
#define SU_TS0_GET_BS(su_ts0) \
((((unsigned long)(su_ts0)) & SU_TS0_BS_MASK) >> SU_TS0_BS_SHIFT)
#define SU_TS0_WS_SIZE 1
#define SU_TS0_WS_SHIFT 17
#define SU_TS0_WS_MASK 0x00020000
#define SU_TS0_GET_WS(su_ts0) \
((((unsigned long)(su_ts0)) & SU_TS0_WS_MASK) >> SU_TS0_WS_SHIFT)
#define SU_TS0_LF_SIZE 1
#define SU_TS0_LF_SHIFT 18
#define SU_TS0_LF_MASK 0x00040000
#define SU_TS0_GET_LF(su_ts0) \
((((unsigned long)(su_ts0)) & SU_TS0_LF_MASK) >> SU_TS0_LF_SHIFT)
#define SU_TS0_PF_SIZE 1
#define SU_TS0_PF_SHIFT 19
#define SU_TS0_PF_MASK 0x00080000
#define SU_TS0_GET_PF(su_ts0) \
((((unsigned long)(su_ts0)) & SU_TS0_PF_MASK) >> SU_TS0_PF_SHIFT)
#define SU_TS0_PAD0_SIZE 4
#define SU_TS0_PAD0_SHIFT 20
#define SU_TS0_PAD0_MASK 0x00f00000
#define SU_TS0_GET_PAD0(su_ts0) \
((((unsigned long)(su_ts0)) & SU_TS0_PAD0_MASK) >> SU_TS0_PAD0_SHIFT)
#define SU_TS0_RID_SIZE 8
#define SU_TS0_RID_SHIFT 24
#define SU_TS0_RID_MASK 0xff000000
#define SU_TS0_GET_RID(su_ts0) \
((((unsigned long)(su_ts0)) & SU_TS0_RID_MASK) >> SU_TS0_RID_SHIFT)
#define SU_SSMASK_SSMASK_SIZE 24
#define SU_SSMASK_SSMASK_SHIFT 0
#define SU_SSMASK_SSMASK_MASK 0x00ffffff
#define SU_SSMASK_GET_SSMASK(su_ssmask) \
((((unsigned long)(su_ssmask)) & SU_SSMASK_SSMASK_MASK) >> SU_SSMASK_SSMASK_SHIFT)
#define SU_SSMASK_RID_SIZE 8
#define SU_SSMASK_RID_SHIFT 24
#define SU_SSMASK_RID_MASK 0xff000000
#define SU_SSMASK_GET_RID(su_ssmask) \
((((unsigned long)(su_ssmask)) & SU_SSMASK_RID_MASK) >> SU_SSMASK_RID_SHIFT)
#define SU_SSMASK_TOTAL_SIZE 32
#define SU_SSMASK(ssmask, rid) \
((((unsigned long)(ssmask)) << SU_SSMASK_SSMASK_SHIFT) | \
(((unsigned long)(rid)) << SU_SSMASK_RID_SHIFT))
#define SU_SCIS0_SY0_SIZE 11
#define SU_SCIS0_SY0_SHIFT 0
#define SU_SCIS0_SY0_MASK 0x000007ff
#define SU_SCIS0_GET_SY0(su_scis0) \
((((unsigned long)(su_scis0)) & SU_SCIS0_SY0_MASK) >> SU_SCIS0_SY0_SHIFT)
#define SU_SCIS0_SET_SY0(su_scis0, sy0) { \
su_scis0 = (((unsigned long)(su_scis0)) & ~SU_SCIS0_SY0_MASK) | (((unsigned long)(sy0)) << SU_SCIS0_SY0_SHIFT);\
}
#define SU_SCIS0_SX0_SIZE 11
#define SU_SCIS0_SX0_SHIFT 12
#define SU_SCIS0_SX0_MASK 0x007ff000
#define SU_SCIS0_GET_SX0(su_scis0) \
((((unsigned long)(su_scis0)) & SU_SCIS0_SX0_MASK) >> SU_SCIS0_SX0_SHIFT)
#define SU_SCIS0_SET_SX0(su_scis0, sx0) { \
su_scis0 = (((unsigned long)(su_scis0)) & ~SU_SCIS0_SX0_MASK) | (((unsigned long)(sx0)) << SU_SCIS0_SX0_SHIFT);\
}
#define SU_SCIS0_PAD1_SIZE 1
#define SU_SCIS0_PAD1_SHIFT 23
#define SU_SCIS0_PAD1_MASK 0x00800000
#define SU_SCIS0_GET_PAD1(su_scis0) \
((((unsigned long)(su_scis0)) & SU_SCIS0_PAD1_MASK) >> SU_SCIS0_PAD1_SHIFT)
#define SU_SCIS0_SET_PAD1(su_scis0, pad1) { \
su_scis0 = (((unsigned long)(su_scis0)) & ~SU_SCIS0_PAD1_MASK) | (((unsigned long)(pad1)) << SU_SCIS0_PAD1_SHIFT);\
}
#define SU_SCIS1_SY1_SIZE 11
#define SU_SCIS1_SY1_SHIFT 0
#define SU_SCIS1_SY1_MASK 0x000007ff
#define SU_SCIS1_GET_SY1(su_scis1) \
((((unsigned long)(su_scis1)) & SU_SCIS1_SY1_MASK) >> SU_SCIS1_SY1_SHIFT)
#define SU_SCIS1_SET_SY1(su_scis1, sy1) { \
su_scis1 = (((unsigned long)(su_scis1)) & ~SU_SCIS1_SY1_MASK) | (((unsigned long)(sy1)) << SU_SCIS1_SY1_SHIFT);\
}
#define SU_SCIS1_SX1_SIZE 11
#define SU_SCIS1_SX1_SHIFT 12
#define SU_SCIS1_SX1_MASK 0x007ff000
#define SU_SCIS1_GET_SX1(su_scis1) \
((((unsigned long)(su_scis1)) & SU_SCIS1_SX1_MASK) >> SU_SCIS1_SX1_SHIFT)
#define SU_SCIS1_SET_SX1(su_scis1, sx1) { \
su_scis1 = (((unsigned long)(su_scis1)) & ~SU_SCIS1_SX1_MASK) | (((unsigned long)(sx1)) << SU_SCIS1_SX1_SHIFT);\
}
#define SC_SU_SCIS0_SET_SY0(line, su_scis0,sy0) \
FAST_GPFLAGSET(line, su_scis0,sy0,SU_SCIS0_SY0)
#define SC_SU_SCIS0_SET_PAD0(line, su_scis0,pad0) \
FAST_GPFLAGSET(line, su_scis0,pad0,SU_SCIS0_PAD0)
#define SC_SU_SCIS0_SET_SX0(line, su_scis0,sx0) \
FAST_GPFLAGSET(line, su_scis0,sx0,SU_SCIS0_SX0)
#define SC_SU_SCIS0_SET_PAD1(line, su_scis0,pad1) \
FAST_GPFLAGSET(line, su_scis0,pad1,SU_SCIS0_PAD1)
#define SC_SU_SCIS0_SET_RID(line, su_scis0,rid) \
FAST_GPFLAGSET(line, su_scis0,rid,SU_SCIS0_RID)
#define SC_SU_SCIS1_SET_SY1(line, su_scis1,sy1) \
FAST_GPFLAGSET(line, su_scis1,sy1,SU_SCIS1_SY1)
#define SC_SU_SCIS1_SET_PAD0(line, su_scis1,pad0) \
FAST_GPFLAGSET(line, su_scis1,pad0,SU_SCIS1_PAD0)
#define SC_SU_SCIS1_SET_SX1(line, su_scis1,sx1) \
FAST_GPFLAGSET(line, su_scis1,sx1,SU_SCIS1_SX1)
#define SC_SU_SCIS1_SET_PAD1(line, su_scis1,pad1) \
FAST_GPFLAGSET(line, su_scis1,pad1,SU_SCIS1_PAD1)
#define SC_SU_SCIS1_SET_RID(line, su_scis1,rid) \
FAST_GPFLAGSET(line, su_scis1,rid,SU_SCIS1_RID)
#define SC_SU_LPSIZE_SET_LSIZE(line, su_lpsize,lsize) \
FAST_GPFLAGSET(line, su_lpsize,lsize,SU_LPSIZE_LSIZE)
#define SC_SU_LPSIZE_SET_PSIZE(line, su_lpsize,psize) \
FAST_GPFLAGSET(line, su_lpsize,psize,SU_LPSIZE_PSIZE)
#define SC_SU_LPSIZE_SET_LTOFF(line, su_lpsize,ltoff) \
FAST_GPFLAGSET(line, su_lpsize,ltoff,SU_LPSIZE_LTOFF)
#define SC_SU_LPSIZE_SET_PTOFF(line, su_lpsize,ptoff) \
FAST_GPFLAGSET(line, su_lpsize,ptoff,SU_LPSIZE_PTOFF)
#define SC_SU_LPSIZE_SET_FIELDMODE(line, su_lpsize,fieldmode) \
FAST_GPFLAGSET(line, su_lpsize,fieldmode,SU_LPSIZE_FIELDMODE)
#define SC_SU_LPSIZE_SET_PAD0(line, su_lpsize,pad0) \
FAST_GPFLAGSET(line, su_lpsize,pad0,SU_LPSIZE_PAD0)
#define SC_SU_LPSIZE_SET_RID(line, su_lpsize,rid) \
FAST_GPFLAGSET(line, su_lpsize,rid,SU_LPSIZE_RID)
#define SC_SU_TS0_SET_SSIZE(line, su_ts0,ssize) \
FAST_GPFLAGSET(line, su_ts0,ssize,SU_TS0_SSIZE)
#define SC_SU_TS0_SET_BS(line, su_ts0,bs) \
FAST_GPFLAGSET(line, su_ts0,bs,SU_TS0_BS)
#define SC_SU_TS0_SET_WS(line, su_ts0,ws) \
FAST_GPFLAGSET(line, su_ts0,ws,SU_TS0_WS)
#define SC_SU_TS0_SET_LF(line, su_ts0,lf) \
FAST_GPFLAGSET(line, su_ts0,lf,SU_TS0_LF)
#define SC_SU_TS0_SET_PF(line, su_ts0,pf) \
FAST_GPFLAGSET(line, su_ts0,pf,SU_TS0_PF)
#define SC_SU_TS0_SET_PAD0(line, su_ts0,pad0) \
FAST_GPFLAGSET(line, su_ts0,pad0,SU_TS0_PAD0)
#define SC_SU_TS0_SET_RID(line, su_ts0,rid) \
FAST_GPFLAGSET(line, su_ts0,rid,SU_TS0_RID)
#define SC_SU_TS1_SET_TSIZE(line, su_ts1,tsize) \
FAST_GPFLAGSET(line, su_ts1,tsize,SU_TS1_TSIZE)
#define SC_SU_TS1_SET_BT(line, su_ts1,bt) \
FAST_GPFLAGSET(line, su_ts1,bt,SU_TS1_BT)
#define SC_SU_TS1_SET_WT(line, su_ts1,wt) \
FAST_GPFLAGSET(line, su_ts1,wt,SU_TS1_WT)
#define SC_SU_TS1_SET_PAD0(line, su_ts1,pad0) \
FAST_GPFLAGSET(line, su_ts1,pad0,SU_TS1_PAD0)
#define SC_SU_TS1_SET_RID(line, su_ts1,rid) \
FAST_GPFLAGSET(line, su_ts1,rid,SU_TS1_RID)
#define SC_SU_PERF_SET_SELA(line, su_perf,selA) \
FAST_GPFLAGSET(line, su_perf,selA,SU_PERF_SELA)
#define SC_SU_PERF_SET_SELB(line, su_perf,selB) \
FAST_GPFLAGSET(line, su_perf,selB,SU_PERF_SELB)
#define SC_SU_PERF_SET_NTEX(line, su_perf,ntex) \
FAST_GPFLAGSET(line, su_perf,ntex,SU_PERF_NTEX)
#define SC_SU_PERF_SET_NCOL(line, su_perf,ncol) \
FAST_GPFLAGSET(line, su_perf,ncol,SU_PERF_NCOL)
#define SC_SU_PERF_SET_REJF(line, su_perf,rejf) \
FAST_GPFLAGSET(line, su_perf,rejf,SU_PERF_REJF)
#define SC_SU_PERF_SET_REJS(line, su_perf,rejs) \
FAST_GPFLAGSET(line, su_perf,rejs,SU_PERF_REJS)
#define SC_SU_PERF_SET_CMD(line, su_perf,cmd) \
FAST_GPFLAGSET(line, su_perf,cmd,SU_PERF_CMD)
#define SC_SU_PERF_SET_PAD0(line, su_perf,pad0) \
FAST_GPFLAGSET(line, su_perf,pad0,SU_PERF_PAD0)
#define SC_SU_PERF_SET_EN(line, su_perf,en) \
FAST_GPFLAGSET(line, su_perf,en,SU_PERF_EN)
#define SC_SU_PERF_SET_PWR_EN(line, su_perf,pwr_en) \
FAST_GPFLAGSET(line, su_perf,pwr_en,SU_PERF_PWR_EN)
#define SC_SU_PERF_SET_RID(line, su_perf,rid) \
FAST_GPFLAGSET(line, su_perf,rid,SU_PERF_RID)
#define SC_SU_SSMASK_SET_SSMASK(line, su_ssmask,ssmask) \
FAST_GPFLAGSET(line, su_ssmask,ssmask,SU_SSMASK_SSMASK)
#define SC_SU_SSMASK_SET_RID(line, su_ssmask,rid) \
FAST_GPFLAGSET(line, su_ssmask,rid,SU_SSMASK_RID)
#endif // SU_REG_H

View File

@ -0,0 +1,729 @@
#ifndef TEV_REG_H
#define TEV_REG_H
#define TEV_COLOR_ENV_RID_SIZE 8
#define TEV_COLOR_ENV_RID_SHIFT 24
#define TEV_COLOR_ENV_RID_MASK 0xff000000
#define TEV_COLOR_ENV_GET_RID(tev_color_env) \
((((unsigned long)(tev_color_env)) & TEV_COLOR_ENV_RID_MASK) >> TEV_COLOR_ENV_RID_SHIFT)
#define TEV_ALPHA_ENV_RID_SIZE 8
#define TEV_ALPHA_ENV_RID_SHIFT 24
#define TEV_ALPHA_ENV_RID_MASK 0xff000000
#define TEV_ALPHA_ENV_GET_RID(tev_alpha_env) \
((((unsigned long)(tev_alpha_env)) & TEV_ALPHA_ENV_RID_MASK) >> TEV_ALPHA_ENV_RID_SHIFT)
#define TEV_KSEL_RID_SIZE 8
#define TEV_KSEL_RID_SHIFT 24
#define TEV_KSEL_RID_MASK 0xff000000
#define TEV_KSEL_GET_RID(tev_ksel) \
((((unsigned long)(tev_ksel)) & TEV_KSEL_RID_MASK) >> TEV_KSEL_RID_SHIFT)
#define TEV_ALPHA_ENV_SELD_SIZE 3
#define TEV_ALPHA_ENV_SELD_SHIFT 4
#define TEV_ALPHA_ENV_SELD_MASK 0x00000070
#define TEV_ALPHA_ENV_GET_SELD(tev_alpha_env) \
((((unsigned long)(tev_alpha_env)) & TEV_ALPHA_ENV_SELD_MASK) >> TEV_ALPHA_ENV_SELD_SHIFT)
#define TEV_ALPHA_ENV_SELC_SIZE 3
#define TEV_ALPHA_ENV_SELC_SHIFT 7
#define TEV_ALPHA_ENV_SELC_MASK 0x00000380
#define TEV_ALPHA_ENV_GET_SELC(tev_alpha_env) \
((((unsigned long)(tev_alpha_env)) & TEV_ALPHA_ENV_SELC_MASK) >> TEV_ALPHA_ENV_SELC_SHIFT)
#define TEV_ALPHA_ENV_SELB_SIZE 3
#define TEV_ALPHA_ENV_SELB_SHIFT 10
#define TEV_ALPHA_ENV_SELB_MASK 0x00001c00
#define TEV_ALPHA_ENV_GET_SELB(tev_alpha_env) \
((((unsigned long)(tev_alpha_env)) & TEV_ALPHA_ENV_SELB_MASK) >> TEV_ALPHA_ENV_SELB_SHIFT)
#define TEV_ALPHA_ENV_SELA_SIZE 3
#define TEV_ALPHA_ENV_SELA_SHIFT 13
#define TEV_ALPHA_ENV_SELA_MASK 0x0000e000
#define TEV_ALPHA_ENV_GET_SELA(tev_alpha_env) \
((((unsigned long)(tev_alpha_env)) & TEV_ALPHA_ENV_SELA_MASK) >> TEV_ALPHA_ENV_SELA_SHIFT)
#define TEV_COLOR_ENV_SELD_SIZE 4
#define TEV_COLOR_ENV_SELD_SHIFT 0
#define TEV_COLOR_ENV_SELD_MASK 0x0000000f
#define TEV_COLOR_ENV_GET_SELD(tev_color_env) \
((((unsigned long)(tev_color_env)) & TEV_COLOR_ENV_SELD_MASK) >> TEV_COLOR_ENV_SELD_SHIFT)
#define TEV_COLOR_ENV_SELC_SIZE 4
#define TEV_COLOR_ENV_SELC_SHIFT 4
#define TEV_COLOR_ENV_SELC_MASK 0x000000f0
#define TEV_COLOR_ENV_GET_SELC(tev_color_env) \
((((unsigned long)(tev_color_env)) & TEV_COLOR_ENV_SELC_MASK) >> TEV_COLOR_ENV_SELC_SHIFT)
#define TEV_COLOR_ENV_SELB_SIZE 4
#define TEV_COLOR_ENV_SELB_SHIFT 8
#define TEV_COLOR_ENV_SELB_MASK 0x00000f00
#define TEV_COLOR_ENV_GET_SELB(tev_color_env) \
((((unsigned long)(tev_color_env)) & TEV_COLOR_ENV_SELB_MASK) >> TEV_COLOR_ENV_SELB_SHIFT)
#define TEV_COLOR_ENV_SELA_SIZE 4
#define TEV_COLOR_ENV_SELA_SHIFT 12
#define TEV_COLOR_ENV_SELA_MASK 0x0000f000
#define TEV_COLOR_ENV_GET_SELA(tev_color_env) \
((((unsigned long)(tev_color_env)) & TEV_COLOR_ENV_SELA_MASK) >> TEV_COLOR_ENV_SELA_SHIFT)
#define TEV_COLOR_ENV_BIAS_SIZE 2
#define TEV_COLOR_ENV_BIAS_SHIFT 16
#define TEV_COLOR_ENV_BIAS_MASK 0x00030000
#define TEV_COLOR_ENV_GET_BIAS(tev_color_env) \
((((unsigned long)(tev_color_env)) & TEV_COLOR_ENV_BIAS_MASK) >> TEV_COLOR_ENV_BIAS_SHIFT)
#define TEV_COLOR_ENV_SUB_SIZE 1
#define TEV_COLOR_ENV_SUB_SHIFT 18
#define TEV_COLOR_ENV_SUB_MASK 0x00040000
#define TEV_COLOR_ENV_GET_SUB(tev_color_env) \
((((unsigned long)(tev_color_env)) & TEV_COLOR_ENV_SUB_MASK) >> TEV_COLOR_ENV_SUB_SHIFT)
#define TEV_COLOR_ENV_CLAMP_SIZE 1
#define TEV_COLOR_ENV_CLAMP_SHIFT 19
#define TEV_COLOR_ENV_CLAMP_MASK 0x00080000
#define TEV_COLOR_ENV_GET_CLAMP(tev_color_env) \
((((unsigned long)(tev_color_env)) & TEV_COLOR_ENV_CLAMP_MASK) >> TEV_COLOR_ENV_CLAMP_SHIFT)
#define TEV_COLOR_ENV_SHIFT_SIZE 2
#define TEV_COLOR_ENV_SHIFT_SHIFT 20
#define TEV_COLOR_ENV_SHIFT_MASK 0x00300000
#define TEV_COLOR_ENV_GET_SHIFT(tev_color_env) \
((((unsigned long)(tev_color_env)) & TEV_COLOR_ENV_SHIFT_MASK) >> TEV_COLOR_ENV_SHIFT_SHIFT)
#define TEV_COLOR_ENV_DEST_SIZE 2
#define TEV_COLOR_ENV_DEST_SHIFT 22
#define TEV_COLOR_ENV_DEST_MASK 0x00c00000
#define TEV_COLOR_ENV_GET_DEST(tev_color_env) \
((((unsigned long)(tev_color_env)) & TEV_COLOR_ENV_DEST_MASK) >> TEV_COLOR_ENV_DEST_SHIFT)
#define TEV_COLOR_ENV_RID_SIZE 8
#define TEV_COLOR_ENV_RID_SHIFT 24
#define TEV_COLOR_ENV_RID_MASK 0xff000000
#define TEV_COLOR_ENV_GET_RID(tev_color_env) \
((((unsigned long)(tev_color_env)) & TEV_COLOR_ENV_RID_MASK) >> TEV_COLOR_ENV_RID_SHIFT)
#define TEV_ALPHA_ENV_MODE_SIZE 2
#define TEV_ALPHA_ENV_MODE_SHIFT 0
#define TEV_ALPHA_ENV_MODE_MASK 0x00000003
#define TEV_ALPHA_ENV_GET_MODE(tev_alpha_env) \
((((unsigned long)(tev_alpha_env)) & TEV_ALPHA_ENV_MODE_MASK) >> TEV_ALPHA_ENV_MODE_SHIFT)
#define TEV_ALPHA_ENV_SWAP_SIZE 2
#define TEV_ALPHA_ENV_SWAP_SHIFT 2
#define TEV_ALPHA_ENV_SWAP_MASK 0x0000000c
#define TEV_ALPHA_ENV_GET_SWAP(tev_alpha_env) \
((((unsigned long)(tev_alpha_env)) & TEV_ALPHA_ENV_SWAP_MASK) >> TEV_ALPHA_ENV_SWAP_SHIFT)
#define TEV_ALPHA_ENV_SELD_SIZE 3
#define TEV_ALPHA_ENV_SELD_SHIFT 4
#define TEV_ALPHA_ENV_SELD_MASK 0x00000070
#define TEV_ALPHA_ENV_GET_SELD(tev_alpha_env) \
((((unsigned long)(tev_alpha_env)) & TEV_ALPHA_ENV_SELD_MASK) >> TEV_ALPHA_ENV_SELD_SHIFT)
#define TEV_ALPHA_ENV_SELC_SIZE 3
#define TEV_ALPHA_ENV_SELC_SHIFT 7
#define TEV_ALPHA_ENV_SELC_MASK 0x00000380
#define TEV_ALPHA_ENV_GET_SELC(tev_alpha_env) \
((((unsigned long)(tev_alpha_env)) & TEV_ALPHA_ENV_SELC_MASK) >> TEV_ALPHA_ENV_SELC_SHIFT)
#define TEV_ALPHA_ENV_SELB_SIZE 3
#define TEV_ALPHA_ENV_SELB_SHIFT 10
#define TEV_ALPHA_ENV_SELB_MASK 0x00001c00
#define TEV_ALPHA_ENV_GET_SELB(tev_alpha_env) \
((((unsigned long)(tev_alpha_env)) & TEV_ALPHA_ENV_SELB_MASK) >> TEV_ALPHA_ENV_SELB_SHIFT)
#define TEV_ALPHA_ENV_SELA_SIZE 3
#define TEV_ALPHA_ENV_SELA_SHIFT 13
#define TEV_ALPHA_ENV_SELA_MASK 0x0000e000
#define TEV_ALPHA_ENV_GET_SELA(tev_alpha_env) \
((((unsigned long)(tev_alpha_env)) & TEV_ALPHA_ENV_SELA_MASK) >> TEV_ALPHA_ENV_SELA_SHIFT)
#define TEV_ALPHA_ENV_BIAS_SIZE 2
#define TEV_ALPHA_ENV_BIAS_SHIFT 16
#define TEV_ALPHA_ENV_BIAS_MASK 0x00030000
#define TEV_ALPHA_ENV_GET_BIAS(tev_alpha_env) \
((((unsigned long)(tev_alpha_env)) & TEV_ALPHA_ENV_BIAS_MASK) >> TEV_ALPHA_ENV_BIAS_SHIFT)
#define TEV_ALPHA_ENV_SUB_SIZE 1
#define TEV_ALPHA_ENV_SUB_SHIFT 18
#define TEV_ALPHA_ENV_SUB_MASK 0x00040000
#define TEV_ALPHA_ENV_GET_SUB(tev_alpha_env) \
((((unsigned long)(tev_alpha_env)) & TEV_ALPHA_ENV_SUB_MASK) >> TEV_ALPHA_ENV_SUB_SHIFT)
#define TEV_ALPHA_ENV_CLAMP_SIZE 1
#define TEV_ALPHA_ENV_CLAMP_SHIFT 19
#define TEV_ALPHA_ENV_CLAMP_MASK 0x00080000
#define TEV_ALPHA_ENV_GET_CLAMP(tev_alpha_env) \
((((unsigned long)(tev_alpha_env)) & TEV_ALPHA_ENV_CLAMP_MASK) >> TEV_ALPHA_ENV_CLAMP_SHIFT)
#define TEV_ALPHA_ENV_SHIFT_SIZE 2
#define TEV_ALPHA_ENV_SHIFT_SHIFT 20
#define TEV_ALPHA_ENV_SHIFT_MASK 0x00300000
#define TEV_ALPHA_ENV_GET_SHIFT(tev_alpha_env) \
((((unsigned long)(tev_alpha_env)) & TEV_ALPHA_ENV_SHIFT_MASK) >> TEV_ALPHA_ENV_SHIFT_SHIFT)
#define TEV_ALPHA_ENV_DEST_SIZE 2
#define TEV_ALPHA_ENV_DEST_SHIFT 22
#define TEV_ALPHA_ENV_DEST_MASK 0x00c00000
#define TEV_ALPHA_ENV_GET_DEST(tev_alpha_env) \
((((unsigned long)(tev_alpha_env)) & TEV_ALPHA_ENV_DEST_MASK) >> TEV_ALPHA_ENV_DEST_SHIFT)
#define TEV_ALPHA_ENV_RID_SIZE 8
#define TEV_ALPHA_ENV_RID_SHIFT 24
#define TEV_ALPHA_ENV_RID_MASK 0xff000000
#define TEV_ALPHA_ENV_GET_RID(tev_alpha_env) \
((((unsigned long)(tev_alpha_env)) & TEV_ALPHA_ENV_RID_MASK) >> TEV_ALPHA_ENV_RID_SHIFT)
#define TEV_REGISTERL_R_SIZE 11
#define TEV_REGISTERL_R_SHIFT 0
#define TEV_REGISTERL_R_MASK 0x000007ff
#define TEV_REGISTERL_GET_R(tev_registerl) \
((((unsigned long)(tev_registerl)) & TEV_REGISTERL_R_MASK) >> TEV_REGISTERL_R_SHIFT)
#define TEV_REGISTERL_PAD0_SIZE 1
#define TEV_REGISTERL_PAD0_SHIFT 11
#define TEV_REGISTERL_PAD0_MASK 0x00000800
#define TEV_REGISTERL_GET_PAD0(tev_registerl) \
((((unsigned long)(tev_registerl)) & TEV_REGISTERL_PAD0_MASK) >> TEV_REGISTERL_PAD0_SHIFT)
#define TEV_REGISTERL_A_SIZE 11
#define TEV_REGISTERL_A_SHIFT 12
#define TEV_REGISTERL_A_MASK 0x007ff000
#define TEV_REGISTERL_GET_A(tev_registerl) \
((((unsigned long)(tev_registerl)) & TEV_REGISTERL_A_MASK) >> TEV_REGISTERL_A_SHIFT)
#define TEV_REGISTERL_PAD1_SIZE 1
#define TEV_REGISTERL_PAD1_SHIFT 23
#define TEV_REGISTERL_PAD1_MASK 0x00800000
#define TEV_REGISTERL_GET_PAD1(tev_registerl) \
((((unsigned long)(tev_registerl)) & TEV_REGISTERL_PAD1_MASK) >> TEV_REGISTERL_PAD1_SHIFT)
#define TEV_REGISTERL_RID_SIZE 8
#define TEV_REGISTERL_RID_SHIFT 24
#define TEV_REGISTERL_RID_MASK 0xff000000
#define TEV_REGISTERL_GET_RID(tev_registerl) \
((((unsigned long)(tev_registerl)) & TEV_REGISTERL_RID_MASK) >> TEV_REGISTERL_RID_SHIFT)
#define TEV_REGISTERL_TOTAL_SIZE 32
#define TEV_REGISTERL(r, a, rid) \
((((unsigned long)(r)) << TEV_REGISTERL_R_SHIFT) | \
(((unsigned long)(a)) << TEV_REGISTERL_A_SHIFT) | \
(((unsigned long)(rid)) << TEV_REGISTERL_RID_SHIFT))
#define TEV_KREGISTERL_R_SIZE 8
#define TEV_KREGISTERL_R_SHIFT 0
#define TEV_KREGISTERL_R_MASK 0x000000ff
#define TEV_KREGISTERL_GET_R(tev_kregisterl) \
((((unsigned long)(tev_kregisterl)) & TEV_KREGISTERL_R_MASK) >> TEV_KREGISTERL_R_SHIFT)
#define TEV_KREGISTERL_PAD0_SIZE 4
#define TEV_KREGISTERL_PAD0_SHIFT 8
#define TEV_KREGISTERL_PAD0_MASK 0x00000f00
#define TEV_KREGISTERL_GET_PAD0(tev_kregisterl) \
((((unsigned long)(tev_kregisterl)) & TEV_KREGISTERL_PAD0_MASK) >> TEV_KREGISTERL_PAD0_SHIFT)
#define TEV_KREGISTERL_A_SIZE 8
#define TEV_KREGISTERL_A_SHIFT 12
#define TEV_KREGISTERL_A_MASK 0x000ff000
#define TEV_KREGISTERL_GET_A(tev_kregisterl) \
((((unsigned long)(tev_kregisterl)) & TEV_KREGISTERL_A_MASK) >> TEV_KREGISTERL_A_SHIFT)
#define TEV_KREGISTERL_PAD1_SIZE 4
#define TEV_KREGISTERL_PAD1_SHIFT 20
#define TEV_KREGISTERL_PAD1_MASK 0x00f00000
#define TEV_KREGISTERL_GET_PAD1(tev_kregisterl) \
((((unsigned long)(tev_kregisterl)) & TEV_KREGISTERL_PAD1_MASK) >> TEV_KREGISTERL_PAD1_SHIFT)
#define TEV_KREGISTERL_RID_SIZE 8
#define TEV_KREGISTERL_RID_SHIFT 24
#define TEV_KREGISTERL_RID_MASK 0xff000000
#define TEV_KREGISTERL_GET_RID(tev_kregisterl) \
((((unsigned long)(tev_kregisterl)) & TEV_KREGISTERL_RID_MASK) >> TEV_KREGISTERL_RID_SHIFT)
#define TEV_KREGISTERL_TOTAL_SIZE 32
#define TEV_KREGISTERL(r, a, rid) \
((((unsigned long)(r)) << TEV_KREGISTERL_R_SHIFT) | \
(((unsigned long)(a)) << TEV_KREGISTERL_A_SHIFT) | \
(((unsigned long)(rid)) << TEV_KREGISTERL_RID_SHIFT))
#define TEV_REGISTERH_B_SIZE 11
#define TEV_REGISTERH_B_SHIFT 0
#define TEV_REGISTERH_B_MASK 0x000007ff
#define TEV_REGISTERH_GET_B(tev_registerh) \
((((unsigned long)(tev_registerh)) & TEV_REGISTERH_B_MASK) >> TEV_REGISTERH_B_SHIFT)
#define TEV_REGISTERH_PAD0_SIZE 1
#define TEV_REGISTERH_PAD0_SHIFT 11
#define TEV_REGISTERH_PAD0_MASK 0x00000800
#define TEV_REGISTERH_GET_PAD0(tev_registerh) \
((((unsigned long)(tev_registerh)) & TEV_REGISTERH_PAD0_MASK) >> TEV_REGISTERH_PAD0_SHIFT)
#define TEV_REGISTERH_G_SIZE 11
#define TEV_REGISTERH_G_SHIFT 12
#define TEV_REGISTERH_G_MASK 0x007ff000
#define TEV_REGISTERH_GET_G(tev_registerh) \
((((unsigned long)(tev_registerh)) & TEV_REGISTERH_G_MASK) >> TEV_REGISTERH_G_SHIFT)
#define TEV_REGISTERH_PAD1_SIZE 1
#define TEV_REGISTERH_PAD1_SHIFT 23
#define TEV_REGISTERH_PAD1_MASK 0x00800000
#define TEV_REGISTERH_GET_PAD1(tev_registerh) \
((((unsigned long)(tev_registerh)) & TEV_REGISTERH_PAD1_MASK) >> TEV_REGISTERH_PAD1_SHIFT)
#define TEV_REGISTERH_RID_SIZE 8
#define TEV_REGISTERH_RID_SHIFT 24
#define TEV_REGISTERH_RID_MASK 0xff000000
#define TEV_REGISTERH_GET_RID(tev_registerh) \
((((unsigned long)(tev_registerh)) & TEV_REGISTERH_RID_MASK) >> TEV_REGISTERH_RID_SHIFT)
#define TEV_REGISTERH_TOTAL_SIZE 32
#define TEV_REGISTERH(b, g, rid) \
((((unsigned long)(b)) << TEV_REGISTERH_B_SHIFT) | \
(((unsigned long)(g)) << TEV_REGISTERH_G_SHIFT) | \
(((unsigned long)(rid)) << TEV_REGISTERH_RID_SHIFT))
#define TEV_KREGISTERH_B_SIZE 8
#define TEV_KREGISTERH_B_SHIFT 0
#define TEV_KREGISTERH_B_MASK 0x000000ff
#define TEV_KREGISTERH_GET_B(tev_kregisterh) \
((((unsigned long)(tev_kregisterh)) & TEV_KREGISTERH_B_MASK) >> TEV_KREGISTERH_B_SHIFT)
#define TEV_KREGISTERH_PAD0_SIZE 4
#define TEV_KREGISTERH_PAD0_SHIFT 8
#define TEV_KREGISTERH_PAD0_MASK 0x00000f00
#define TEV_KREGISTERH_GET_PAD0(tev_kregisterh) \
((((unsigned long)(tev_kregisterh)) & TEV_KREGISTERH_PAD0_MASK) >> TEV_KREGISTERH_PAD0_SHIFT)
#define TEV_KREGISTERH_G_SIZE 8
#define TEV_KREGISTERH_G_SHIFT 12
#define TEV_KREGISTERH_G_MASK 0x000ff000
#define TEV_KREGISTERH_GET_G(tev_kregisterh) \
((((unsigned long)(tev_kregisterh)) & TEV_KREGISTERH_G_MASK) >> TEV_KREGISTERH_G_SHIFT)
#define TEV_KREGISTERH_PAD1_SIZE 4
#define TEV_KREGISTERH_PAD1_SHIFT 20
#define TEV_KREGISTERH_PAD1_MASK 0x00f00000
#define TEV_KREGISTERH_GET_PAD1(tev_kregisterh) \
((((unsigned long)(tev_kregisterh)) & TEV_KREGISTERH_PAD1_MASK) >> TEV_KREGISTERH_PAD1_SHIFT)
#define TEV_KREGISTERH_RID_SIZE 8
#define TEV_KREGISTERH_RID_SHIFT 24
#define TEV_KREGISTERH_RID_MASK 0xff000000
#define TEV_KREGISTERH_GET_RID(tev_kregisterh) \
((((unsigned long)(tev_kregisterh)) & TEV_KREGISTERH_RID_MASK) >> TEV_KREGISTERH_RID_SHIFT)
#define TEV_KREGISTERH_TOTAL_SIZE 32
#define TEV_KREGISTERH(b, g, rid) \
((((unsigned long)(b)) << TEV_KREGISTERH_B_SHIFT) | \
(((unsigned long)(g)) << TEV_KREGISTERH_G_SHIFT) | \
(((unsigned long)(rid)) << TEV_KREGISTERH_RID_SHIFT))
#define TEV_KSEL_XRB_SIZE 2
#define TEV_KSEL_XRB_SHIFT 0
#define TEV_KSEL_XRB_MASK 0x00000003
#define TEV_KSEL_GET_XRB(tev_ksel) \
((((unsigned long)(tev_ksel)) & TEV_KSEL_XRB_MASK) >> TEV_KSEL_XRB_SHIFT)
#define TEV_KSEL_XGA_SIZE 2
#define TEV_KSEL_XGA_SHIFT 2
#define TEV_KSEL_XGA_MASK 0x0000000c
#define TEV_KSEL_GET_XGA(tev_ksel) \
((((unsigned long)(tev_ksel)) & TEV_KSEL_XGA_MASK) >> TEV_KSEL_XGA_SHIFT)
#define TEV_KSEL_KCSEL0_SIZE 5
#define TEV_KSEL_KCSEL0_SHIFT 4
#define TEV_KSEL_KCSEL0_MASK 0x000001f0
#define TEV_KSEL_GET_KCSEL0(tev_ksel) \
((((unsigned long)(tev_ksel)) & TEV_KSEL_KCSEL0_MASK) >> TEV_KSEL_KCSEL0_SHIFT)
#define TEV_KSEL_KASEL0_SIZE 5
#define TEV_KSEL_KASEL0_SHIFT 9
#define TEV_KSEL_KASEL0_MASK 0x00003e00
#define TEV_KSEL_GET_KASEL0(tev_ksel) \
((((unsigned long)(tev_ksel)) & TEV_KSEL_KASEL0_MASK) >> TEV_KSEL_KASEL0_SHIFT)
#define TEV_KSEL_KCSEL1_SIZE 5
#define TEV_KSEL_KCSEL1_SHIFT 14
#define TEV_KSEL_KCSEL1_MASK 0x0007c000
#define TEV_KSEL_GET_KCSEL1(tev_ksel) \
((((unsigned long)(tev_ksel)) & TEV_KSEL_KCSEL1_MASK) >> TEV_KSEL_KCSEL1_SHIFT)
#define TEV_KSEL_KASEL1_SIZE 5
#define TEV_KSEL_KASEL1_SHIFT 19
#define TEV_KSEL_KASEL1_MASK 0x00f80000
#define TEV_KSEL_GET_KASEL1(tev_ksel) \
((((unsigned long)(tev_ksel)) & TEV_KSEL_KASEL1_MASK) >> TEV_KSEL_KASEL1_SHIFT)
#define TEV_KSEL_RID_SIZE 8
#define TEV_KSEL_RID_SHIFT 24
#define TEV_KSEL_RID_MASK 0xff000000
#define TEV_KSEL_GET_RID(tev_ksel) \
((((unsigned long)(tev_ksel)) & TEV_KSEL_RID_MASK) >> TEV_KSEL_RID_SHIFT)
#define TEV_ALPHAFUNC_A0_SIZE 8
#define TEV_ALPHAFUNC_A0_SHIFT 0
#define TEV_ALPHAFUNC_A0_MASK 0x000000ff
#define TEV_ALPHAFUNC_GET_A0(tev_alphafunc) \
((((unsigned long)(tev_alphafunc)) & TEV_ALPHAFUNC_A0_MASK) >> TEV_ALPHAFUNC_A0_SHIFT)
#define TEV_ALPHAFUNC_A1_SIZE 8
#define TEV_ALPHAFUNC_A1_SHIFT 8
#define TEV_ALPHAFUNC_A1_MASK 0x0000ff00
#define TEV_ALPHAFUNC_GET_A1(tev_alphafunc) \
((((unsigned long)(tev_alphafunc)) & TEV_ALPHAFUNC_A1_MASK) >> TEV_ALPHAFUNC_A1_SHIFT)
#define TEV_ALPHAFUNC_OP0_SIZE 3
#define TEV_ALPHAFUNC_OP0_SHIFT 16
#define TEV_ALPHAFUNC_OP0_MASK 0x00070000
#define TEV_ALPHAFUNC_GET_OP0(tev_alphafunc) \
((((unsigned long)(tev_alphafunc)) & TEV_ALPHAFUNC_OP0_MASK) >> TEV_ALPHAFUNC_OP0_SHIFT)
#define TEV_ALPHAFUNC_OP1_SIZE 3
#define TEV_ALPHAFUNC_OP1_SHIFT 19
#define TEV_ALPHAFUNC_OP1_MASK 0x00380000
#define TEV_ALPHAFUNC_GET_OP1(tev_alphafunc) \
((((unsigned long)(tev_alphafunc)) & TEV_ALPHAFUNC_OP1_MASK) >> TEV_ALPHAFUNC_OP1_SHIFT)
#define TEV_ALPHAFUNC_LOGIC_SIZE 2
#define TEV_ALPHAFUNC_LOGIC_SHIFT 22
#define TEV_ALPHAFUNC_LOGIC_MASK 0x00c00000
#define TEV_ALPHAFUNC_GET_LOGIC(tev_alphafunc) \
((((unsigned long)(tev_alphafunc)) & TEV_ALPHAFUNC_LOGIC_MASK) >> TEV_ALPHAFUNC_LOGIC_SHIFT)
#define TEV_ALPHAFUNC_RID_SIZE 8
#define TEV_ALPHAFUNC_RID_SHIFT 24
#define TEV_ALPHAFUNC_RID_MASK 0xff000000
#define TEV_ALPHAFUNC_GET_RID(tev_alphafunc) \
((((unsigned long)(tev_alphafunc)) & TEV_ALPHAFUNC_RID_MASK) >> TEV_ALPHAFUNC_RID_SHIFT)
#define TEV_Z_ENV_0_ZOFF_SIZE 24
#define TEV_Z_ENV_0_ZOFF_SHIFT 0
#define TEV_Z_ENV_0_ZOFF_MASK 0x00ffffff
#define TEV_Z_ENV_0_GET_ZOFF(tev_z_env_0) \
((((unsigned long)(tev_z_env_0)) & TEV_Z_ENV_0_ZOFF_MASK) >> TEV_Z_ENV_0_ZOFF_SHIFT)
#define TEV_Z_ENV_0_RID_SIZE 8
#define TEV_Z_ENV_0_RID_SHIFT 24
#define TEV_Z_ENV_0_RID_MASK 0xff000000
#define TEV_Z_ENV_0_GET_RID(tev_z_env_0) \
((((unsigned long)(tev_z_env_0)) & TEV_Z_ENV_0_RID_MASK) >> TEV_Z_ENV_0_RID_SHIFT)
#define TEV_Z_ENV_1_TYPE_SIZE 2
#define TEV_Z_ENV_1_TYPE_SHIFT 0
#define TEV_Z_ENV_1_TYPE_MASK 0x00000003
#define TEV_Z_ENV_1_GET_TYPE(tev_z_env_1) \
((((unsigned long)(tev_z_env_1)) & TEV_Z_ENV_1_TYPE_MASK) >> TEV_Z_ENV_1_TYPE_SHIFT)
#define TEV_Z_ENV_1_OP_SIZE 2
#define TEV_Z_ENV_1_OP_SHIFT 2
#define TEV_Z_ENV_1_OP_MASK 0x0000000c
#define TEV_Z_ENV_1_GET_OP(tev_z_env_1) \
((((unsigned long)(tev_z_env_1)) & TEV_Z_ENV_1_OP_MASK) >> TEV_Z_ENV_1_OP_SHIFT)
#define TEV_Z_ENV_1_PAD0_SIZE 20
#define TEV_Z_ENV_1_PAD0_SHIFT 4
#define TEV_Z_ENV_1_PAD0_MASK 0x00fffff0
#define TEV_Z_ENV_1_GET_PAD0(tev_z_env_1) \
((((unsigned long)(tev_z_env_1)) & TEV_Z_ENV_1_PAD0_MASK) >> TEV_Z_ENV_1_PAD0_SHIFT)
#define TEV_Z_ENV_1_RID_SIZE 8
#define TEV_Z_ENV_1_RID_SHIFT 24
#define TEV_Z_ENV_1_RID_MASK 0xff000000
#define TEV_Z_ENV_1_GET_RID(tev_z_env_1) \
((((unsigned long)(tev_z_env_1)) & TEV_Z_ENV_1_RID_MASK) >> TEV_Z_ENV_1_RID_SHIFT)
typedef struct {
unsigned long rid : 8;
unsigned long dest : 2;
unsigned long shift : 2;
unsigned long clamp : 1;
unsigned long sub : 1;
unsigned long bias : 2;
unsigned long sela : 4;
unsigned long selb : 4;
unsigned long selc : 4;
unsigned long seld : 4;
} tev_color_env_t;
typedef struct {
unsigned long rid : 8;
unsigned long dest : 2;
unsigned long shift : 2;
unsigned long clamp : 1;
unsigned long sub : 1;
unsigned long bias : 2;
unsigned long sela : 3;
unsigned long selb : 3;
unsigned long selc : 3;
unsigned long seld : 3;
unsigned long swap : 2;
unsigned long mode : 2;
} tev_alpha_env_t;
#define SC_TEV_COLOR_ENV_SET_SELD(line, tev_color_env,seld) \
FAST_GPFLAGSET(line, tev_color_env,seld,TEV_COLOR_ENV_SELD)
#define SC_TEV_COLOR_ENV_SET_SELC(line, tev_color_env,selc) \
FAST_GPFLAGSET(line, tev_color_env,selc,TEV_COLOR_ENV_SELC)
#define SC_TEV_COLOR_ENV_SET_SELB(line, tev_color_env,selb) \
FAST_GPFLAGSET(line, tev_color_env,selb,TEV_COLOR_ENV_SELB)
#define SC_TEV_COLOR_ENV_SET_SELA(line, tev_color_env,sela) \
FAST_GPFLAGSET(line, tev_color_env,sela,TEV_COLOR_ENV_SELA)
#define SC_TEV_COLOR_ENV_SET_BIAS(line, tev_color_env,bias) \
FAST_GPFLAGSET(line, tev_color_env,bias,TEV_COLOR_ENV_BIAS)
#define SC_TEV_COLOR_ENV_SET_SUB(line, tev_color_env,sub) \
FAST_GPFLAGSET(line, tev_color_env,sub,TEV_COLOR_ENV_SUB)
#define SC_TEV_COLOR_ENV_SET_CLAMP(line, tev_color_env,clamp) \
FAST_GPFLAGSET(line, tev_color_env,clamp,TEV_COLOR_ENV_CLAMP)
#define SC_TEV_COLOR_ENV_SET_SHIFT(line, tev_color_env,shift) \
FAST_GPFLAGSET(line, tev_color_env,shift,TEV_COLOR_ENV_SHIFT)
#define SC_TEV_COLOR_ENV_SET_DEST(line, tev_color_env,dest) \
FAST_GPFLAGSET(line, tev_color_env,dest,TEV_COLOR_ENV_DEST)
#define SC_TEV_COLOR_ENV_SET_RID(line, tev_color_env,rid) \
FAST_GPFLAGSET(line, tev_color_env,rid,TEV_COLOR_ENV_RID)
#define SC_TEV_ALPHA_ENV_SET_MODE(line, tev_alpha_env,mode) \
FAST_GPFLAGSET(line, tev_alpha_env,mode,TEV_ALPHA_ENV_MODE)
#define SC_TEV_ALPHA_ENV_SET_SWAP(line, tev_alpha_env,swap) \
FAST_GPFLAGSET(line, tev_alpha_env,swap,TEV_ALPHA_ENV_SWAP)
#define SC_TEV_ALPHA_ENV_SET_SELD(line, tev_alpha_env,seld) \
FAST_GPFLAGSET(line, tev_alpha_env,seld,TEV_ALPHA_ENV_SELD)
#define SC_TEV_ALPHA_ENV_SET_SELC(line, tev_alpha_env,selc) \
FAST_GPFLAGSET(line, tev_alpha_env,selc,TEV_ALPHA_ENV_SELC)
#define SC_TEV_ALPHA_ENV_SET_SELB(line, tev_alpha_env,selb) \
FAST_GPFLAGSET(line, tev_alpha_env,selb,TEV_ALPHA_ENV_SELB)
#define SC_TEV_ALPHA_ENV_SET_SELA(line, tev_alpha_env,sela) \
FAST_GPFLAGSET(line, tev_alpha_env,sela,TEV_ALPHA_ENV_SELA)
#define SC_TEV_ALPHA_ENV_SET_BIAS(line, tev_alpha_env,bias) \
FAST_GPFLAGSET(line, tev_alpha_env,bias,TEV_ALPHA_ENV_BIAS)
#define SC_TEV_ALPHA_ENV_SET_SUB(line, tev_alpha_env,sub) \
FAST_GPFLAGSET(line, tev_alpha_env,sub,TEV_ALPHA_ENV_SUB)
#define SC_TEV_ALPHA_ENV_SET_CLAMP(line, tev_alpha_env,clamp) \
FAST_GPFLAGSET(line, tev_alpha_env,clamp,TEV_ALPHA_ENV_CLAMP)
#define SC_TEV_ALPHA_ENV_SET_SHIFT(line, tev_alpha_env,shift) \
FAST_GPFLAGSET(line, tev_alpha_env,shift,TEV_ALPHA_ENV_SHIFT)
#define SC_TEV_ALPHA_ENV_SET_DEST(line, tev_alpha_env,dest) \
FAST_GPFLAGSET(line, tev_alpha_env,dest,TEV_ALPHA_ENV_DEST)
#define SC_TEV_ALPHA_ENV_SET_RID(line, tev_alpha_env,rid) \
FAST_GPFLAGSET(line, tev_alpha_env,rid,TEV_ALPHA_ENV_RID)
#define SC_TEV_REGISTERL_SET_R(line, tev_registerl,r) \
FAST_GPFLAGSET(line, tev_registerl,r,TEV_REGISTERL_R)
#define SC_TEV_REGISTERL_SET_PAD0(line, tev_registerl,pad0) \
FAST_GPFLAGSET(line, tev_registerl,pad0,TEV_REGISTERL_PAD0)
#define SC_TEV_REGISTERL_SET_A(line, tev_registerl,a) \
FAST_GPFLAGSET(line, tev_registerl,a,TEV_REGISTERL_A)
#define SC_TEV_REGISTERL_SET_PAD1(line, tev_registerl,pad1) \
FAST_GPFLAGSET(line, tev_registerl,pad1,TEV_REGISTERL_PAD1)
#define SC_TEV_REGISTERL_SET_RID(line, tev_registerl,rid) \
FAST_GPFLAGSET(line, tev_registerl,rid,TEV_REGISTERL_RID)
#define SC_TEV_REGISTERH_SET_B(line, tev_registerh,b) \
FAST_GPFLAGSET(line, tev_registerh,b,TEV_REGISTERH_B)
#define SC_TEV_REGISTERH_SET_PAD0(line, tev_registerh,pad0) \
FAST_GPFLAGSET(line, tev_registerh,pad0,TEV_REGISTERH_PAD0)
#define SC_TEV_REGISTERH_SET_G(line, tev_registerh,g) \
FAST_GPFLAGSET(line, tev_registerh,g,TEV_REGISTERH_G)
#define SC_TEV_REGISTERH_SET_PAD1(line, tev_registerh,pad1) \
FAST_GPFLAGSET(line, tev_registerh,pad1,TEV_REGISTERH_PAD1)
#define SC_TEV_REGISTERH_SET_RID(line, tev_registerh,rid) \
FAST_GPFLAGSET(line, tev_registerh,rid,TEV_REGISTERH_RID)
#define SC_TEV_KREGISTERL_SET_R(line, tev_kregisterl,r) \
FAST_GPFLAGSET(line, tev_kregisterl,r,TEV_KREGISTERL_R)
#define SC_TEV_KREGISTERL_SET_PAD0(line, tev_kregisterl,pad0) \
FAST_GPFLAGSET(line, tev_kregisterl,pad0,TEV_KREGISTERL_PAD0)
#define SC_TEV_KREGISTERL_SET_A(line, tev_kregisterl,a) \
FAST_GPFLAGSET(line, tev_kregisterl,a,TEV_KREGISTERL_A)
#define SC_TEV_KREGISTERL_SET_PAD1(line, tev_kregisterl,pad1) \
FAST_GPFLAGSET(line, tev_kregisterl,pad1,TEV_KREGISTERL_PAD1)
#define SC_TEV_KREGISTERL_SET_RID(line, tev_kregisterl,rid) \
FAST_GPFLAGSET(line, tev_kregisterl,rid,TEV_KREGISTERL_RID)
#define SC_TEV_KREGISTERH_SET_B(line, tev_kregisterh,b) \
FAST_GPFLAGSET(line, tev_kregisterh,b,TEV_KREGISTERH_B)
#define SC_TEV_KREGISTERH_SET_PAD0(line, tev_kregisterh,pad0) \
FAST_GPFLAGSET(line, tev_kregisterh,pad0,TEV_KREGISTERH_PAD0)
#define SC_TEV_KREGISTERH_SET_G(line, tev_kregisterh,g) \
FAST_GPFLAGSET(line, tev_kregisterh,g,TEV_KREGISTERH_G)
#define SC_TEV_KREGISTERH_SET_PAD1(line, tev_kregisterh,pad1) \
FAST_GPFLAGSET(line, tev_kregisterh,pad1,TEV_KREGISTERH_PAD1)
#define SC_TEV_KREGISTERH_SET_RID(line, tev_kregisterh,rid) \
FAST_GPFLAGSET(line, tev_kregisterh,rid,TEV_KREGISTERH_RID)
#define SC_TEV_FOG_PARAM_0_SET_A_MANT(line, tev_fog_param_0,a_mant) \
FAST_GPFLAGSET(line, tev_fog_param_0,a_mant,TEV_FOG_PARAM_0_A_MANT)
#define SC_TEV_FOG_PARAM_0_SET_A_EXPN(line, tev_fog_param_0,a_expn) \
FAST_GPFLAGSET(line, tev_fog_param_0,a_expn,TEV_FOG_PARAM_0_A_EXPN)
#define SC_TEV_FOG_PARAM_0_SET_A_SIGN(line, tev_fog_param_0,a_sign) \
FAST_GPFLAGSET(line, tev_fog_param_0,a_sign,TEV_FOG_PARAM_0_A_SIGN)
#define SC_TEV_FOG_PARAM_0_SET_PAD0(line, tev_fog_param_0,pad0) \
FAST_GPFLAGSET(line, tev_fog_param_0,pad0,TEV_FOG_PARAM_0_PAD0)
#define SC_TEV_FOG_PARAM_0_SET_RID(line, tev_fog_param_0,rid) \
FAST_GPFLAGSET(line, tev_fog_param_0,rid,TEV_FOG_PARAM_0_RID)
#define SC_TEV_FOG_PARAM_1_SET_B_MAG(line, tev_fog_param_1,b_mag) \
FAST_GPFLAGSET(line, tev_fog_param_1,b_mag,TEV_FOG_PARAM_1_B_MAG)
#define SC_TEV_FOG_PARAM_1_SET_RID(line, tev_fog_param_1,rid) \
FAST_GPFLAGSET(line, tev_fog_param_1,rid,TEV_FOG_PARAM_1_RID)
#define SC_TEV_FOG_PARAM_2_SET_B_SHF(line, tev_fog_param_2,b_shf) \
FAST_GPFLAGSET(line, tev_fog_param_2,b_shf,TEV_FOG_PARAM_2_B_SHF)
#define SC_TEV_FOG_PARAM_2_SET_PAD0(line, tev_fog_param_2,pad0) \
FAST_GPFLAGSET(line, tev_fog_param_2,pad0,TEV_FOG_PARAM_2_PAD0)
#define SC_TEV_FOG_PARAM_2_SET_RID(line, tev_fog_param_2,rid) \
FAST_GPFLAGSET(line, tev_fog_param_2,rid,TEV_FOG_PARAM_2_RID)
#define SC_TEV_FOG_PARAM_3_SET_C_MANT(line, tev_fog_param_3,c_mant) \
FAST_GPFLAGSET(line, tev_fog_param_3,c_mant,TEV_FOG_PARAM_3_C_MANT)
#define SC_TEV_FOG_PARAM_3_SET_C_EXPN(line, tev_fog_param_3,c_expn) \
FAST_GPFLAGSET(line, tev_fog_param_3,c_expn,TEV_FOG_PARAM_3_C_EXPN)
#define SC_TEV_FOG_PARAM_3_SET_C_SIGN(line, tev_fog_param_3,c_sign) \
FAST_GPFLAGSET(line, tev_fog_param_3,c_sign,TEV_FOG_PARAM_3_C_SIGN)
#define SC_TEV_FOG_PARAM_3_SET_PROJ(line, tev_fog_param_3,proj) \
FAST_GPFLAGSET(line, tev_fog_param_3,proj,TEV_FOG_PARAM_3_PROJ)
#define SC_TEV_FOG_PARAM_3_SET_FSEL(line, tev_fog_param_3,fsel) \
FAST_GPFLAGSET(line, tev_fog_param_3,fsel,TEV_FOG_PARAM_3_FSEL)
#define SC_TEV_FOG_PARAM_3_SET_RID(line, tev_fog_param_3,rid) \
FAST_GPFLAGSET(line, tev_fog_param_3,rid,TEV_FOG_PARAM_3_RID)
#define SC_TEV_RANGE_ADJ_C_SET_CENTER(line, tev_range_adj_c,center) \
FAST_GPFLAGSET(line, tev_range_adj_c,center,TEV_RANGE_ADJ_C_CENTER)
#define SC_TEV_RANGE_ADJ_C_SET_ENB(line, tev_range_adj_c,enb) \
FAST_GPFLAGSET(line, tev_range_adj_c,enb,TEV_RANGE_ADJ_C_ENB)
#define SC_TEV_RANGE_ADJ_C_SET_PAD0(line, tev_range_adj_c,pad0) \
FAST_GPFLAGSET(line, tev_range_adj_c,pad0,TEV_RANGE_ADJ_C_PAD0)
#define SC_TEV_RANGE_ADJ_C_SET_RID(line, tev_range_adj_c,rid) \
FAST_GPFLAGSET(line, tev_range_adj_c,rid,TEV_RANGE_ADJ_C_RID)
#define SC_TEV_RANGE_ADJ_SET_R0(line, tev_range_adj,r0) \
FAST_GPFLAGSET(line, tev_range_adj,r0,TEV_RANGE_ADJ_R0)
#define SC_TEV_RANGE_ADJ_SET_R1(line, tev_range_adj,r1) \
FAST_GPFLAGSET(line, tev_range_adj,r1,TEV_RANGE_ADJ_R1)
#define SC_TEV_RANGE_ADJ_SET_RID(line, tev_range_adj,rid) \
FAST_GPFLAGSET(line, tev_range_adj,rid,TEV_RANGE_ADJ_RID)
#define SC_TEV_FOG_COLOR_SET_B(line, tev_fog_color,b) \
FAST_GPFLAGSET(line, tev_fog_color,b,TEV_FOG_COLOR_B)
#define SC_TEV_FOG_COLOR_SET_G(line, tev_fog_color,g) \
FAST_GPFLAGSET(line, tev_fog_color,g,TEV_FOG_COLOR_G)
#define SC_TEV_FOG_COLOR_SET_R(line, tev_fog_color,r) \
FAST_GPFLAGSET(line, tev_fog_color,r,TEV_FOG_COLOR_R)
#define SC_TEV_FOG_COLOR_SET_RID(line, tev_fog_color,rid) \
FAST_GPFLAGSET(line, tev_fog_color,rid,TEV_FOG_COLOR_RID)
#define SC_TEV_ALPHAFUNC_SET_A0(line, tev_alphafunc,a0) \
FAST_GPFLAGSET(line, tev_alphafunc,a0,TEV_ALPHAFUNC_A0)
#define SC_TEV_ALPHAFUNC_SET_A1(line, tev_alphafunc,a1) \
FAST_GPFLAGSET(line, tev_alphafunc,a1,TEV_ALPHAFUNC_A1)
#define SC_TEV_ALPHAFUNC_SET_OP0(line, tev_alphafunc,op0) \
FAST_GPFLAGSET(line, tev_alphafunc,op0,TEV_ALPHAFUNC_OP0)
#define SC_TEV_ALPHAFUNC_SET_OP1(line, tev_alphafunc,op1) \
FAST_GPFLAGSET(line, tev_alphafunc,op1,TEV_ALPHAFUNC_OP1)
#define SC_TEV_ALPHAFUNC_SET_LOGIC(line, tev_alphafunc,logic) \
FAST_GPFLAGSET(line, tev_alphafunc,logic,TEV_ALPHAFUNC_LOGIC)
#define SC_TEV_ALPHAFUNC_SET_RID(line, tev_alphafunc,rid) \
FAST_GPFLAGSET(line, tev_alphafunc,rid,TEV_ALPHAFUNC_RID)
#define SC_TEV_Z_ENV_0_SET_ZOFF(line, tev_z_env_0,zoff) \
FAST_GPFLAGSET(line, tev_z_env_0,zoff,TEV_Z_ENV_0_ZOFF)
#define SC_TEV_Z_ENV_0_SET_RID(line, tev_z_env_0,rid) \
FAST_GPFLAGSET(line, tev_z_env_0,rid,TEV_Z_ENV_0_RID)
#define SC_TEV_Z_ENV_1_SET_TYPE(line, tev_z_env_1,type) \
FAST_GPFLAGSET(line, tev_z_env_1,type,TEV_Z_ENV_1_TYPE)
#define SC_TEV_Z_ENV_1_SET_OP(line, tev_z_env_1,op) \
FAST_GPFLAGSET(line, tev_z_env_1,op,TEV_Z_ENV_1_OP)
#define SC_TEV_Z_ENV_1_SET_PAD0(line, tev_z_env_1,pad0) \
FAST_GPFLAGSET(line, tev_z_env_1,pad0,TEV_Z_ENV_1_PAD0)
#define SC_TEV_Z_ENV_1_SET_RID(line, tev_z_env_1,rid) \
FAST_GPFLAGSET(line, tev_z_env_1,rid,TEV_Z_ENV_1_RID)
#define SC_TEV_KSEL_SET_XRB(line, tev_ksel,xrb) \
FAST_GPFLAGSET(line, tev_ksel,xrb,TEV_KSEL_XRB)
#define SC_TEV_KSEL_SET_XGA(line, tev_ksel,xga) \
FAST_GPFLAGSET(line, tev_ksel,xga,TEV_KSEL_XGA)
#define SC_TEV_KSEL_SET_KCSEL0(line, tev_ksel,kcsel0) \
FAST_GPFLAGSET(line, tev_ksel,kcsel0,TEV_KSEL_KCSEL0)
#define SC_TEV_KSEL_SET_KASEL0(line, tev_ksel,kasel0) \
FAST_GPFLAGSET(line, tev_ksel,kasel0,TEV_KSEL_KASEL0)
#define SC_TEV_KSEL_SET_KCSEL1(line, tev_ksel,kcsel1) \
FAST_GPFLAGSET(line, tev_ksel,kcsel1,TEV_KSEL_KCSEL1)
#define SC_TEV_KSEL_SET_KASEL1(line, tev_ksel,kasel1) \
FAST_GPFLAGSET(line, tev_ksel,kasel1,TEV_KSEL_KASEL1)
#define SC_TEV_KSEL_SET_RID(line, tev_ksel,rid) \
FAST_GPFLAGSET(line, tev_ksel,rid,TEV_KSEL_RID)
#endif // TEV_REG_H

View File

@ -0,0 +1,125 @@
#ifndef TX_REG_H
#define TX_REG_H
#define TX_REFRESH_INTERVAL_SIZE 10
#define TX_REFRESH_INTERVAL_SHIFT 0
#define TX_REFRESH_INTERVAL_MASK 0x000003ff
#define TX_REFRESH_GET_INTERVAL(tx_refresh) \
((((unsigned long)(tx_refresh)) & TX_REFRESH_INTERVAL_MASK) >> TX_REFRESH_INTERVAL_SHIFT)
#define TX_REFRESH_ENABLE_SIZE 1
#define TX_REFRESH_ENABLE_SHIFT 10
#define TX_REFRESH_ENABLE_MASK 0x00000400
#define TX_REFRESH_GET_ENABLE(tx_refresh) \
((((unsigned long)(tx_refresh)) & TX_REFRESH_ENABLE_MASK) >> TX_REFRESH_ENABLE_SHIFT)
#define TX_REFRESH_PAD0_SIZE 13
#define TX_REFRESH_PAD0_SHIFT 11
#define TX_REFRESH_PAD0_MASK 0x00fff800
#define TX_REFRESH_GET_PAD0(tx_refresh) \
((((unsigned long)(tx_refresh)) & TX_REFRESH_PAD0_MASK) >> TX_REFRESH_PAD0_SHIFT)
#define TX_REFRESH_SET_PAD0(tx_refresh, pad0) { \
FDL_ASSERT(!((pad0) & ~((1 << TX_REFRESH_PAD0_SIZE)-1))); \
tx_refresh = (((unsigned long)(tx_refresh)) & ~TX_REFRESH_PAD0_MASK) | (((unsigned long)(pad0)) << TX_REFRESH_PAD0_SHIFT);\
}
#define TX_REFRESH_RID_SIZE 8
#define TX_REFRESH_RID_SHIFT 24
#define TX_REFRESH_RID_MASK 0xff000000
#define TX_REFRESH_GET_RID(tx_refresh) \
((((unsigned long)(tx_refresh)) & TX_REFRESH_RID_MASK) >> TX_REFRESH_RID_SHIFT)
#define TX_REFRESH_SET_RID(tx_refresh, rid) { \
FDL_ASSERT(!((rid) & ~((1 << TX_REFRESH_RID_SIZE)-1))); \
tx_refresh = (((unsigned long)(tx_refresh)) & ~TX_REFRESH_RID_MASK) | (((unsigned long)(rid)) << TX_REFRESH_RID_SHIFT);\
}
#define TX_REFRESH_TOTAL_SIZE 32
#define TX_REFRESH(interval, enable, rid) \
((((unsigned long)(interval)) << TX_REFRESH_INTERVAL_SHIFT) | \
(((unsigned long)(enable)) << TX_REFRESH_ENABLE_SHIFT) | \
(((unsigned long)(rid)) << TX_REFRESH_RID_SHIFT))
#define TX_PERFMODE_SEL3_SIZE 5
#define TX_PERFMODE_SEL3_SHIFT 0
#define TX_PERFMODE_SEL3_MASK 0x0000001f
#define TX_PERFMODE_GET_SEL3(tx_perfmode) \
((((unsigned long)(tx_perfmode)) & TX_PERFMODE_SEL3_MASK) >> TX_PERFMODE_SEL3_SHIFT)
#define TX_PERFMODE_SEL2_SIZE 5
#define TX_PERFMODE_SEL2_SHIFT 5
#define TX_PERFMODE_SEL2_MASK 0x000003e0
#define TX_PERFMODE_GET_SEL2(tx_perfmode) \
((((unsigned long)(tx_perfmode)) & TX_PERFMODE_SEL2_MASK) >> TX_PERFMODE_SEL2_SHIFT)
#define TX_PERFMODE_SEL1_SIZE 5
#define TX_PERFMODE_SEL1_SHIFT 10
#define TX_PERFMODE_SEL1_MASK 0x00007c00
#define TX_PERFMODE_GET_SEL1(tx_perfmode) \
((((unsigned long)(tx_perfmode)) & TX_PERFMODE_SEL1_MASK) >> TX_PERFMODE_SEL1_SHIFT)
#define TX_PERFMODE_SEL0_SIZE 5
#define TX_PERFMODE_SEL0_SHIFT 15
#define TX_PERFMODE_SEL0_MASK 0x000f8000
#define TX_PERFMODE_GET_SEL0(tx_perfmode) \
((((unsigned long)(tx_perfmode)) & TX_PERFMODE_SEL0_MASK) >> TX_PERFMODE_SEL0_SHIFT)
#define TX_PERFMODE_PAD0_SIZE 4
#define TX_PERFMODE_PAD0_SHIFT 20
#define TX_PERFMODE_PAD0_MASK 0x00f00000
#define TX_PERFMODE_GET_PAD0(tx_perfmode) \
((((unsigned long)(tx_perfmode)) & TX_PERFMODE_PAD0_MASK) >> TX_PERFMODE_PAD0_SHIFT)
#define TX_PERFMODE_RID_SIZE 8
#define TX_PERFMODE_RID_SHIFT 24
#define TX_PERFMODE_RID_MASK 0xff000000
#define TX_PERFMODE_GET_RID(tx_perfmode) \
((((unsigned long)(tx_perfmode)) & TX_PERFMODE_RID_MASK) >> TX_PERFMODE_RID_SHIFT)
#define TX_PERFMODE_TOTAL_SIZE 32
#define TX_PERFMODE(sel3, sel2, sel1, sel0, rid) \
((((unsigned long)(sel3)) << TX_PERFMODE_SEL3_SHIFT) | \
(((unsigned long)(sel2)) << TX_PERFMODE_SEL2_SHIFT) | \
(((unsigned long)(sel1)) << TX_PERFMODE_SEL1_SHIFT) | \
(((unsigned long)(sel0)) << TX_PERFMODE_SEL0_SHIFT) | \
(((unsigned long)(rid)) << TX_PERFMODE_RID_SHIFT))
#define TX_LOADBLOCK3_COUNT_SIZE 15
#define TX_LOADBLOCK3_COUNT_SHIFT 0
#define TX_LOADBLOCK3_COUNT_MASK 0x00007fff
#define TX_LOADBLOCK3_GET_COUNT(tx_loadblock3) \
((((unsigned long)(tx_loadblock3)) & TX_LOADBLOCK3_COUNT_MASK) >> TX_LOADBLOCK3_COUNT_SHIFT)
#define TX_LOADBLOCK3_SET_COUNT(tx_loadblock3, count) { \
FDL_ASSERT(!((count) & ~((1 << TX_LOADBLOCK3_COUNT_SIZE)-1))); \
tx_loadblock3 = (((unsigned long)(tx_loadblock3)) & ~TX_LOADBLOCK3_COUNT_MASK) | (((unsigned long)(count)) << TX_LOADBLOCK3_COUNT_SHIFT);\
}
#define TX_LOADBLOCK3_FORMAT_SIZE 2
#define TX_LOADBLOCK3_FORMAT_SHIFT 15
#define TX_LOADBLOCK3_FORMAT_MASK 0x00018000
#define TX_LOADBLOCK3_GET_FORMAT(tx_loadblock3) \
((((unsigned long)(tx_loadblock3)) & TX_LOADBLOCK3_FORMAT_MASK) >> TX_LOADBLOCK3_FORMAT_SHIFT)
#define TX_LOADBLOCK3_SET_FORMAT(tx_loadblock3, format) { \
FDL_ASSERT(!((format) & ~((1 << TX_LOADBLOCK3_FORMAT_SIZE)-1))); \
tx_loadblock3 = (((unsigned long)(tx_loadblock3)) & ~TX_LOADBLOCK3_FORMAT_MASK) | (((unsigned long)(format)) << TX_LOADBLOCK3_FORMAT_SHIFT);\
}
#define TX_LOADBLOCK3_PAD0_SIZE 7
#define TX_LOADBLOCK3_PAD0_SHIFT 17
#define TX_LOADBLOCK3_PAD0_MASK 0x00fe0000
#define TX_LOADBLOCK3_GET_PAD0(tx_loadblock3) \
((((unsigned long)(tx_loadblock3)) & TX_LOADBLOCK3_PAD0_MASK) >> TX_LOADBLOCK3_PAD0_SHIFT)
#define TX_LOADBLOCK3_SET_PAD0(tx_loadblock3, pad0) { \
FDL_ASSERT(!((pad0) & ~((1 << TX_LOADBLOCK3_PAD0_SIZE)-1))); \
tx_loadblock3 = (((unsigned long)(tx_loadblock3)) & ~TX_LOADBLOCK3_PAD0_MASK) | (((unsigned long)(pad0)) << TX_LOADBLOCK3_PAD0_SHIFT);\
}
#define TX_LOADBLOCK3_RID_SIZE 8
#define TX_LOADBLOCK3_RID_SHIFT 24
#define TX_LOADBLOCK3_RID_MASK 0xff000000
#define TX_LOADBLOCK3_GET_RID(tx_loadblock3) \
((((unsigned long)(tx_loadblock3)) & TX_LOADBLOCK3_RID_MASK) >> TX_LOADBLOCK3_RID_SHIFT)
#define TX_LOADBLOCK3_SET_RID(tx_loadblock3, rid) { \
FDL_ASSERT(!((rid) & ~((1 << TX_LOADBLOCK3_RID_SIZE)-1))); \
tx_loadblock3 = (((unsigned long)(tx_loadblock3)) & ~TX_LOADBLOCK3_RID_MASK) | (((unsigned long)(rid)) << TX_LOADBLOCK3_RID_SHIFT);\
}
#define TX_LOADBLOCK3_TOTAL_SIZE 32
#define TX_LOADBLOCK3(count, format, rid) \
((((unsigned long)(count)) << TX_LOADBLOCK3_COUNT_SHIFT) | \
(((unsigned long)(format)) << TX_LOADBLOCK3_FORMAT_SHIFT) | \
(((unsigned long)(rid)) << TX_LOADBLOCK3_RID_SHIFT))
#endif // TX_REG_H

View File

@ -0,0 +1,749 @@
#ifndef XF_MEM_H
#define XF_MEM_H
#define XF_TEXGEN_REGULAR 0x00000000
#define XF_TEXGEN_BUMP_MAP 0x00000001
#define XF_TEXGEN_COLOR_STRGBC0 0x00000002
#define XF_TEXGEN_COLOR_STRGBC1 0x00000003
#define XF_TEX_TEXGEN_TYPE_F_UNUSED_4 0x00000004
#define XF_TEX_TEXGEN_TYPE_F_UNUSED_5 0x00000005
#define XF_TEX_TEXGEN_TYPE_F_UNUSED_6 0x00000006
#define XF_TEX_TEXGEN_TYPE_F_UNUSED_7 0x00000007
#define XF_ERROR_F_CTEX_BUG_ENABLE_SIZE 1
#define XF_ERROR_F_CTEX_BUG_ENABLE_SHIFT 0
#define XF_ERROR_F_CTEX_BUG_ENABLE_MASK 0x00000001
#define XF_ERROR_F_GET_CTEX_BUG_ENABLE(xf_error_f) \
((((unsigned long)(xf_error_f)) & XF_ERROR_F_CTEX_BUG_ENABLE_MASK) >> XF_ERROR_F_CTEX_BUG_ENABLE_SHIFT)
#define XF_ERROR_F_TFAN4_BUG_ENABLE_SIZE 1
#define XF_ERROR_F_TFAN4_BUG_ENABLE_SHIFT 1
#define XF_ERROR_F_TFAN4_BUG_ENABLE_MASK 0x00000002
#define XF_ERROR_F_GET_TFAN4_BUG_ENABLE(xf_error_f) \
((((unsigned long)(xf_error_f)) & XF_ERROR_F_TFAN4_BUG_ENABLE_MASK) >> XF_ERROR_F_TFAN4_BUG_ENABLE_SHIFT)
#define XF_ERROR_F_TFAN16_BUG_ENABLE_SIZE 1
#define XF_ERROR_F_TFAN16_BUG_ENABLE_SHIFT 2
#define XF_ERROR_F_TFAN16_BUG_ENABLE_MASK 0x00000004
#define XF_ERROR_F_GET_TFAN16_BUG_ENABLE(xf_error_f) \
((((unsigned long)(xf_error_f)) & XF_ERROR_F_TFAN16_BUG_ENABLE_MASK) >> XF_ERROR_F_TFAN16_BUG_ENABLE_SHIFT)
#define XF_ERROR_F_DUALTRAN_REG_ENABLE_SIZE 1
#define XF_ERROR_F_DUALTRAN_REG_ENABLE_SHIFT 3
#define XF_ERROR_F_DUALTRAN_REG_ENABLE_MASK 0x00000008
#define XF_ERROR_F_GET_DUALTRAN_REG_ENABLE(xf_error_f) \
((((unsigned long)(xf_error_f)) & XF_ERROR_F_DUALTRAN_REG_ENABLE_MASK) >> XF_ERROR_F_DUALTRAN_REG_ENABLE_SHIFT)
#define XF_ERROR_F_BYPASS_BUG_ENABLE_SIZE 1
#define XF_ERROR_F_BYPASS_BUG_ENABLE_SHIFT 4
#define XF_ERROR_F_BYPASS_BUG_ENABLE_MASK 0x00000010
#define XF_ERROR_F_GET_BYPASS_BUG_ENABLE(xf_error_f) \
((((unsigned long)(xf_error_f)) & XF_ERROR_F_BYPASS_BUG_ENABLE_MASK) >> XF_ERROR_F_BYPASS_BUG_ENABLE_SHIFT)
#define XF_ERROR_F_FAST_MATRIX_ENABLE_SIZE 1
#define XF_ERROR_F_FAST_MATRIX_ENABLE_SHIFT 5
#define XF_ERROR_F_FAST_MATRIX_ENABLE_MASK 0x00000020
#define XF_ERROR_F_GET_FAST_MATRIX_ENABLE(xf_error_f) \
((((unsigned long)(xf_error_f)) & XF_ERROR_F_FAST_MATRIX_ENABLE_MASK) >> XF_ERROR_F_FAST_MATRIX_ENABLE_SHIFT)
#define XF_DUALTEXTRAN_F_DUALTEXTRAN_ENABLE_SIZE 1
#define XF_DUALTEXTRAN_F_DUALTEXTRAN_ENABLE_SHIFT 0
#define XF_DUALTEXTRAN_F_DUALTEXTRAN_ENABLE_MASK 0x00000001
#define XF_DUALTEXTRAN_F_GET_DUALTEXTRAN_ENABLE(xf_dualtextran_f) \
((((unsigned long)(xf_dualtextran_f)) & XF_DUALTEXTRAN_F_DUALTEXTRAN_ENABLE_MASK) >> XF_DUALTEXTRAN_F_DUALTEXTRAN_ENABLE_SHIFT)
#define XF_PERF0_F(perf_a, perf_b, perf_c, perf_d) \
((((unsigned long)(perf_a)) << XF_PERF0_F_PERF_A_SHIFT) | \
(((unsigned long)(perf_b)) << XF_PERF0_F_PERF_B_SHIFT) | \
(((unsigned long)(perf_c)) << XF_PERF0_F_PERF_C_SHIFT) | \
(((unsigned long)(perf_d)) << XF_PERF0_F_PERF_D_SHIFT))
#define XF_INVERTEXSPEC_F_HOST_COLORS_SIZE 2
#define XF_INVERTEXSPEC_F_HOST_COLORS_SHIFT 0
#define XF_INVERTEXSPEC_F_HOST_COLORS_MASK 0x00000003
#define XF_INVERTEXSPEC_F_GET_HOST_COLORS(xf_invertexspec_f) \
((((unsigned long)(xf_invertexspec_f)) & XF_INVERTEXSPEC_F_HOST_COLORS_MASK) >> XF_INVERTEXSPEC_F_HOST_COLORS_SHIFT)
#define XF_INVERTEXSPEC_F_HOST_NORMAL_SIZE 2
#define XF_INVERTEXSPEC_F_HOST_NORMAL_SHIFT 2
#define XF_INVERTEXSPEC_F_HOST_NORMAL_MASK 0x0000000c
#define XF_INVERTEXSPEC_F_GET_HOST_NORMAL(xf_invertexspec_f) \
((((unsigned long)(xf_invertexspec_f)) & XF_INVERTEXSPEC_F_HOST_NORMAL_MASK) >> XF_INVERTEXSPEC_F_HOST_NORMAL_SHIFT)
#define XF_INVERTEXSPEC_F_HOST_TEXTURES_SIZE 4
#define XF_INVERTEXSPEC_F_HOST_TEXTURES_SHIFT 4
#define XF_INVERTEXSPEC_F_HOST_TEXTURES_MASK 0x000000f0
#define XF_INVERTEXSPEC_F_GET_HOST_TEXTURES(xf_invertexspec_f) \
((((unsigned long)(xf_invertexspec_f)) & XF_INVERTEXSPEC_F_HOST_TEXTURES_MASK) >> XF_INVERTEXSPEC_F_HOST_TEXTURES_SHIFT)
#define XF_INVERTEXSPEC_F_TOTAL_SIZE 8
#define XF_INVERTEXSPEC_F_UNUSED_SIZE 24
#define XF_INVERTEXSPEC_F(host_colors, host_normal, host_textures) \
((((unsigned long)(host_colors)) << XF_INVERTEXSPEC_F_HOST_COLORS_SHIFT) | \
(((unsigned long)(host_normal)) << XF_INVERTEXSPEC_F_HOST_NORMAL_SHIFT) | \
(((unsigned long)(host_textures)) << XF_INVERTEXSPEC_F_HOST_TEXTURES_SHIFT))
#define XF_TEX_RESERVED0_SIZE 1
#define XF_TEX_RESERVED0_SHIFT 0
#define XF_TEX_RESERVED0_MASK 0x00000001
#define XF_TEX_GET_RESERVED0(xf_tex) \
((((unsigned long)(xf_tex)) & XF_TEX_RESERVED0_MASK) >> XF_TEX_RESERVED0_SHIFT)
#define XF_TEX_PROJECTION_SIZE 1
#define XF_TEX_PROJECTION_SHIFT 1
#define XF_TEX_PROJECTION_MASK 0x00000002
#define XF_TEX_GET_PROJECTION(xf_tex) \
((((unsigned long)(xf_tex)) & XF_TEX_PROJECTION_MASK) >> XF_TEX_PROJECTION_SHIFT)
#define XF_TEX_INPUT_FORM_SIZE 1
#define XF_TEX_INPUT_FORM_SHIFT 2
#define XF_TEX_INPUT_FORM_MASK 0x00000004
#define XF_TEX_GET_INPUT_FORM(xf_tex) \
((((unsigned long)(xf_tex)) & XF_TEX_INPUT_FORM_MASK) >> XF_TEX_INPUT_FORM_SHIFT)
#define XF_TEX_RESERVED1_SIZE 1
#define XF_TEX_RESERVED1_SHIFT 3
#define XF_TEX_RESERVED1_MASK 0x00000008
#define XF_TEX_GET_RESERVED1(xf_tex) \
((((unsigned long)(xf_tex)) & XF_TEX_RESERVED1_MASK) >> XF_TEX_RESERVED1_SHIFT)
#define XF_TEX_TEXGEN_TYPE_SIZE 3
#define XF_TEX_TEXGEN_TYPE_SHIFT 4
#define XF_TEX_TEXGEN_TYPE_MASK 0x00000070
#define XF_TEX_GET_TEXGEN_TYPE(xf_tex) \
((((unsigned long)(xf_tex)) & XF_TEX_TEXGEN_TYPE_MASK) >> XF_TEX_TEXGEN_TYPE_SHIFT)
#define XF_TEX_SOURCE_ROW_SIZE 5
#define XF_TEX_SOURCE_ROW_SHIFT 7
#define XF_TEX_SOURCE_ROW_MASK 0x00000f80
#define XF_TEX_GET_SOURCE_ROW(xf_tex) \
((((unsigned long)(xf_tex)) & XF_TEX_SOURCE_ROW_MASK) >> XF_TEX_SOURCE_ROW_SHIFT)
#define XF_TEX_BUMP_MAP_SOURCE_SIZE 3
#define XF_TEX_BUMP_MAP_SOURCE_SHIFT 12
#define XF_TEX_BUMP_MAP_SOURCE_MASK 0x00007000
#define XF_TEX_GET_BUMP_MAP_SOURCE(xf_tex) \
((((unsigned long)(xf_tex)) & XF_TEX_BUMP_MAP_SOURCE_MASK) >> XF_TEX_BUMP_MAP_SOURCE_SHIFT)
#define XF_TEX_BUMP_MAP_LIGHT_SIZE 3
#define XF_TEX_BUMP_MAP_LIGHT_SHIFT 15
#define XF_TEX_BUMP_MAP_LIGHT_MASK 0x00038000
#define XF_TEX_GET_BUMP_MAP_LIGHT(xf_tex) \
((((unsigned long)(xf_tex)) & XF_TEX_BUMP_MAP_LIGHT_MASK) >> XF_TEX_BUMP_MAP_LIGHT_SHIFT)
#define XF_TEX_TOTAL_SIZE 18
#define XF_TEX_UNUSED_SIZE 14
#define XF_TEX(reserved0, projection, input_form, reserved1, texgen_type, source_row, bump_map_source, bump_map_light) \
((((unsigned long)(reserved0)) << XF_TEX_RESERVED0_SHIFT) | \
(((unsigned long)(projection)) << XF_TEX_PROJECTION_SHIFT) | \
(((unsigned long)(input_form)) << XF_TEX_INPUT_FORM_SHIFT) | \
(((unsigned long)(reserved1)) << XF_TEX_RESERVED1_SHIFT) | \
(((unsigned long)(texgen_type)) << XF_TEX_TEXGEN_TYPE_SHIFT) | \
(((unsigned long)(source_row)) << XF_TEX_SOURCE_ROW_SHIFT) | \
(((unsigned long)(bump_map_source)) << XF_TEX_BUMP_MAP_SOURCE_SHIFT) | \
(((unsigned long)(bump_map_light)) << XF_TEX_BUMP_MAP_LIGHT_SHIFT))
#define XF_DUALTEX_F_DUALMATRIX_ADRS_SIZE 6
#define XF_DUALTEX_F_DUALMATRIX_ADRS_SHIFT 0
#define XF_DUALTEX_F_DUALMATRIX_ADRS_MASK 0x0000003f
#define XF_DUALTEX_F_GET_DUALMATRIX_ADRS(xf_dualtex_f) \
((((unsigned long)(xf_dualtex_f)) & XF_DUALTEX_F_DUALMATRIX_ADRS_MASK) >> XF_DUALTEX_F_DUALMATRIX_ADRS_SHIFT)
#define XF_DUALTEX_F_RESERVED0_SIZE 2
#define XF_DUALTEX_F_RESERVED0_SHIFT 6
#define XF_DUALTEX_F_RESERVED0_MASK 0x000000c0
#define XF_DUALTEX_F_GET_RESERVED0(xf_dualtex_f) \
((((unsigned long)(xf_dualtex_f)) & XF_DUALTEX_F_RESERVED0_MASK) >> XF_DUALTEX_F_RESERVED0_SHIFT)
#define XF_DUALTEX_F_NORMAL_ENABLE_SIZE 1
#define XF_DUALTEX_F_NORMAL_ENABLE_SHIFT 8
#define XF_DUALTEX_F_NORMAL_ENABLE_MASK 0x00000100
#define XF_DUALTEX_F_GET_NORMAL_ENABLE(xf_dualtex_f) \
((((unsigned long)(xf_dualtex_f)) & XF_DUALTEX_F_NORMAL_ENABLE_MASK) >> XF_DUALTEX_F_NORMAL_ENABLE_SHIFT)
#define XF_DUALTEX_F_TOTAL_SIZE 9
#define XF_DUALTEX_F_UNUSED_SIZE 23
#define XF_DUALTEX_F(dualmatrix_adrs, reserved0, normal_enable) \
((((unsigned long)(dualmatrix_adrs)) << XF_DUALTEX_F_DUALMATRIX_ADRS_SHIFT) | \
(((unsigned long)(reserved0)) << XF_DUALTEX_F_RESERVED0_SHIFT) | \
(((unsigned long)(normal_enable)) << XF_DUALTEX_F_NORMAL_ENABLE_SHIFT))
#define XF_PERF0_F_PERF_A_SIZE 5
#define XF_PERF0_F_PERF_A_SHIFT 0
#define XF_PERF0_F_PERF_A_MASK 0x0000001f
#define XF_PERF0_F_GET_PERF_A(xf_perf0_f) \
((((unsigned long)(xf_perf0_f)) & XF_PERF0_F_PERF_A_MASK) >> XF_PERF0_F_PERF_A_SHIFT)
#define XF_PERF0_F_PERF_B_SIZE 5
#define XF_PERF0_F_PERF_B_SHIFT 5
#define XF_PERF0_F_PERF_B_MASK 0x000003e0
#define XF_PERF0_F_GET_PERF_B(xf_perf0_f) \
((((unsigned long)(xf_perf0_f)) & XF_PERF0_F_PERF_B_MASK) >> XF_PERF0_F_PERF_B_SHIFT)
#define XF_PERF0_F_PERF_C_SIZE 5
#define XF_PERF0_F_PERF_C_SHIFT 10
#define XF_PERF0_F_PERF_C_MASK 0x00007c00
#define XF_PERF0_F_GET_PERF_C(xf_perf0_f) \
((((unsigned long)(xf_perf0_f)) & XF_PERF0_F_PERF_C_MASK) >> XF_PERF0_F_PERF_C_SHIFT)
#define XF_PERF0_F_PERF_D_SIZE 5
#define XF_PERF0_F_PERF_D_SHIFT 15
#define XF_PERF0_F_PERF_D_MASK 0x000f8000
#define XF_PERF0_F_GET_PERF_D(xf_perf0_f) \
((((unsigned long)(xf_perf0_f)) & XF_PERF0_F_PERF_D_MASK) >> XF_PERF0_F_PERF_D_SHIFT)
#define XF_PERF0_F_TOTAL_SIZE 20
#define XF_PERF0_F_UNUSED_SIZE 12
#define XF_PERF0_F(perf_a, perf_b, perf_c, perf_d) \
((((unsigned long)(perf_a)) << XF_PERF0_F_PERF_A_SHIFT) | \
(((unsigned long)(perf_b)) << XF_PERF0_F_PERF_B_SHIFT) | \
(((unsigned long)(perf_c)) << XF_PERF0_F_PERF_C_SHIFT) | \
(((unsigned long)(perf_d)) << XF_PERF0_F_PERF_D_SHIFT))
#define XF_PERF1_F_PERF_TARGET_SIZE 7
#define XF_PERF1_F_PERF_TARGET_SHIFT 0
#define XF_PERF1_F_PERF_TARGET_MASK 0x0000007f
#define XF_PERF1_F_GET_PERF_TARGET(xf_perf1_f) \
((((unsigned long)(xf_perf1_f)) & XF_PERF1_F_PERF_TARGET_MASK) >> XF_PERF1_F_PERF_TARGET_SHIFT)
#define XF_PERF1_F_TOTAL_SIZE 7
#define XF_PERF1_F_UNUSED_SIZE 25
#define XF_PERF1_F(perf_target) \
((((unsigned long)(perf_target)) << XF_PERF1_F_PERF_TARGET_SHIFT))
#define XF_MATERIAL0_F_ALPHA_SIZE 8
#define XF_MATERIAL0_F_ALPHA_SHIFT 0
#define XF_MATERIAL0_F_ALPHA_MASK 0x000000ff
#define XF_MATERIAL0_F_GET_ALPHA(xf_material0_f) \
((((unsigned long)(xf_material0_f)) & XF_MATERIAL0_F_ALPHA_MASK) >> XF_MATERIAL0_F_ALPHA_SHIFT)
#define XF_MATERIAL0_F_SET_ALPHA(xf_material0_f, alpha) { \
xf_material0_f = (((unsigned long)(xf_material0_f)) & ~XF_MATERIAL0_F_ALPHA_MASK) | (((unsigned long)(alpha)) << XF_MATERIAL0_F_ALPHA_SHIFT);\
}
#define XF_MATERIAL0_F_BLUE_SIZE 8
#define XF_MATERIAL0_F_BLUE_SHIFT 8
#define XF_MATERIAL0_F_BLUE_MASK 0x0000ff00
#define XF_MATERIAL0_F_GET_BLUE(xf_material0_f) \
((((unsigned long)(xf_material0_f)) & XF_MATERIAL0_F_BLUE_MASK) >> XF_MATERIAL0_F_BLUE_SHIFT)
#define XF_MATERIAL0_F_SET_BLUE(xf_material0_f, blue) { \
xf_material0_f = (((unsigned long)(xf_material0_f)) & ~XF_MATERIAL0_F_BLUE_MASK) | (((unsigned long)(blue)) << XF_MATERIAL0_F_BLUE_SHIFT);\
#define XF_MATERIAL0_F_GREEN_SIZE 8
#define XF_MATERIAL0_F_GREEN_SHIFT 16
#define XF_MATERIAL0_F_GREEN_MASK 0x00ff0000
#define XF_MATERIAL0_F_GET_GREEN(xf_material0_f) \
((((unsigned long)(xf_material0_f)) & XF_MATERIAL0_F_GREEN_MASK) >> XF_MATERIAL0_F_GREEN_SHIFT)
#define XF_MATERIAL0_F_SET_GREEN(xf_material0_f, green) { \
xf_material0_f = (((unsigned long)(xf_material0_f)) & ~XF_MATERIAL0_F_GREEN_MASK) | (((unsigned long)(green)) << XF_MATERIAL0_F_GREEN_SHIFT);\
}
#define XF_MATERIAL0_F_RED_SIZE 8
#define XF_MATERIAL0_F_RED_SHIFT 24
#define XF_MATERIAL0_F_RED_MASK 0xff000000
#define XF_MATERIAL0_F_GET_RED(xf_material0_f) \
((((unsigned long)(xf_material0_f)) & XF_MATERIAL0_F_RED_MASK) >> XF_MATERIAL0_F_RED_SHIFT)
#define XF_MATERIAL0_F_SET_RED(xf_material0_f, red) { \
xf_material0_f = (((unsigned long)(xf_material0_f)) & ~XF_MATERIAL0_F_RED_MASK) | (((unsigned long)(red)) << XF_MATERIAL0_F_RED_SHIFT);\
}
#define XF_MATERIAL0_F_TOTAL_SIZE 32
#define XF_MATERIAL0_F(alpha, blue, green, red) \
((((unsigned long)(alpha)) << XF_MATERIAL0_F_ALPHA_SHIFT) | \
(((unsigned long)(blue)) << XF_MATERIAL0_F_BLUE_SHIFT) | \
(((unsigned long)(green)) << XF_MATERIAL0_F_GREEN_SHIFT) | \
(((unsigned long)(red)) << XF_MATERIAL0_F_RED_SHIFT))
#define XF_MATERIAL1_F_ALPHA_SIZE 8
#define XF_MATERIAL1_F_ALPHA_SHIFT 0
#define XF_MATERIAL1_F_ALPHA_MASK 0x000000ff
#define XF_MATERIAL1_F_GET_ALPHA(xf_material1_f) \
((((unsigned long)(xf_material1_f)) & XF_MATERIAL1_F_ALPHA_MASK) >> XF_MATERIAL1_F_ALPHA_SHIFT)
#define XF_MATERIAL1_F_SET_ALPHA(xf_material1_f, alpha) { \
xf_material1_f = (((unsigned long)(xf_material1_f)) & ~XF_MATERIAL1_F_ALPHA_MASK) | (((unsigned long)(alpha)) << XF_MATERIAL1_F_ALPHA_SHIFT);\
}
#define XF_MATERIAL1_F_BLUE_SIZE 8
#define XF_MATERIAL1_F_BLUE_SHIFT 8
#define XF_MATERIAL1_F_BLUE_MASK 0x0000ff00
#define XF_MATERIAL1_F_GET_BLUE(xf_material1_f) \
((((unsigned long)(xf_material1_f)) & XF_MATERIAL1_F_BLUE_MASK) >> XF_MATERIAL1_F_BLUE_SHIFT)
#define XF_MATERIAL1_F_SET_BLUE(xf_material1_f, blue) { \
xf_material1_f = (((unsigned long)(xf_material1_f)) & ~XF_MATERIAL1_F_BLUE_MASK) | (((unsigned long)(blue)) << XF_MATERIAL1_F_BLUE_SHIFT);\
}
#define XF_MATERIAL1_F_GREEN_SIZE 8
#define XF_MATERIAL1_F_GREEN_SHIFT 16
#define XF_MATERIAL1_F_GREEN_MASK 0x00ff0000
#define XF_MATERIAL1_F_GET_GREEN(xf_material1_f) \
((((unsigned long)(xf_material1_f)) & XF_MATERIAL1_F_GREEN_MASK) >> XF_MATERIAL1_F_GREEN_SHIFT)
#define XF_MATERIAL1_F_SET_GREEN(xf_material1_f, green) { \
xf_material1_f = (((unsigned long)(xf_material1_f)) & ~XF_MATERIAL1_F_GREEN_MASK) | (((unsigned long)(green)) << XF_MATERIAL1_F_GREEN_SHIFT);\
}
#define XF_MATERIAL1_F_RED_SIZE 8
#define XF_MATERIAL1_F_RED_SHIFT 24
#define XF_MATERIAL1_F_RED_MASK 0xff000000
#define XF_MATERIAL1_F_GET_RED(xf_material1_f) \
((((unsigned long)(xf_material1_f)) & XF_MATERIAL1_F_RED_MASK) >> XF_MATERIAL1_F_RED_SHIFT)
#define XF_MATERIAL1_F_SET_RED(xf_material1_f, red) { \
xf_material1_f = (((unsigned long)(xf_material1_f)) & ~XF_MATERIAL1_F_RED_MASK) | (((unsigned long)(red)) << XF_MATERIAL1_F_RED_SHIFT);\
}
#define XF_MATERIAL1_F_TOTAL_SIZE 32
#define XF_MATERIAL1_F(alpha, blue, green, red) \
((((unsigned long)(alpha)) << XF_MATERIAL1_F_ALPHA_SHIFT) | \
(((unsigned long)(blue)) << XF_MATERIAL1_F_BLUE_SHIFT) | \
(((unsigned long)(green)) << XF_MATERIAL1_F_GREEN_SHIFT) | \
(((unsigned long)(red)) << XF_MATERIAL1_F_RED_SHIFT))
#define XF_COLOR0CNTRL_F_MATERIAL_SRC_SIZE 1
#define XF_COLOR0CNTRL_F_MATERIAL_SRC_SHIFT 0
#define XF_COLOR0CNTRL_F_MATERIAL_SRC_MASK 0x00000001
#define XF_COLOR0CNTRL_F_GET_MATERIAL_SRC(xf_color0cntrl_f) \
((((unsigned long)(xf_color0cntrl_f)) & XF_COLOR0CNTRL_F_MATERIAL_SRC_MASK) >> XF_COLOR0CNTRL_F_MATERIAL_SRC_SHIFT)
#define XF_COLOR0CNTRL_F_SET_MATERIAL_SRC(xf_color0cntrl_f, material_src) { \
xf_color0cntrl_f = (((unsigned long)(xf_color0cntrl_f)) & ~XF_COLOR0CNTRL_F_MATERIAL_SRC_MASK) | (((unsigned long)(material_src)) << XF_COLOR0CNTRL_F_MATERIAL_SRC_SHIFT);\
}
#define XF_COLOR0CNTRL_F_LIGHTFUNC_SIZE 1
#define XF_COLOR0CNTRL_F_LIGHTFUNC_SHIFT 1
#define XF_COLOR0CNTRL_F_LIGHTFUNC_MASK 0x00000002
#define XF_COLOR0CNTRL_F_GET_LIGHTFUNC(xf_color0cntrl_f) \
((((unsigned long)(xf_color0cntrl_f)) & XF_COLOR0CNTRL_F_LIGHTFUNC_MASK) >> XF_COLOR0CNTRL_F_LIGHTFUNC_SHIFT)
#define XF_COLOR0CNTRL_F_SET_LIGHTFUNC(xf_color0cntrl_f, lightfunc) { \
xf_color0cntrl_f = (((unsigned long)(xf_color0cntrl_f)) & ~XF_COLOR0CNTRL_F_LIGHTFUNC_MASK) | (((unsigned long)(lightfunc)) << XF_COLOR0CNTRL_F_LIGHTFUNC_SHIFT);\
}
#define XF_COLOR0CNTRL_F_AMBIENT_SRC_SIZE 1
#define XF_COLOR0CNTRL_F_AMBIENT_SRC_SHIFT 6
#define XF_COLOR0CNTRL_F_AMBIENT_SRC_MASK 0x00000040
#define XF_COLOR0CNTRL_F_GET_AMBIENT_SRC(xf_color0cntrl_f) \
((((unsigned long)(xf_color0cntrl_f)) & XF_COLOR0CNTRL_F_AMBIENT_SRC_MASK) >> XF_COLOR0CNTRL_F_AMBIENT_SRC_SHIFT)
#define XF_COLOR0CNTRL_F_SET_AMBIENT_SRC(xf_color0cntrl_f, ambient_src) { \
xf_color0cntrl_f = (((unsigned long)(xf_color0cntrl_f)) & ~XF_COLOR0CNTRL_F_AMBIENT_SRC_MASK) | (((unsigned long)(ambient_src)) << XF_COLOR0CNTRL_F_AMBIENT_SRC_SHIFT);\
}
#define XF_COLOR0CNTRL_F_DIFFUSEATTEN_SIZE 2
#define XF_COLOR0CNTRL_F_DIFFUSEATTEN_SHIFT 7
#define XF_COLOR0CNTRL_F_DIFFUSEATTEN_MASK 0x00000180
#define XF_COLOR0CNTRL_F_GET_DIFFUSEATTEN(xf_color0cntrl_f) \
((((unsigned long)(xf_color0cntrl_f)) & XF_COLOR0CNTRL_F_DIFFUSEATTEN_MASK) >> XF_COLOR0CNTRL_F_DIFFUSEATTEN_SHIFT)
#define XF_COLOR0CNTRL_F_SET_DIFFUSEATTEN(xf_color0cntrl_f, diffuseatten) { \
xf_color0cntrl_f = (((unsigned long)(xf_color0cntrl_f)) & ~XF_COLOR0CNTRL_F_DIFFUSEATTEN_MASK) | (((unsigned long)(diffuseatten)) << XF_COLOR0CNTRL_F_DIFFUSEATTEN_SHIFT);\
}
#define XF_COLOR0CNTRL_F_LIGHT0_SIZE 1
#define XF_COLOR0CNTRL_F_LIGHT0_SHIFT 2
#define XF_COLOR0CNTRL_F_LIGHT0_MASK 0x00000004
#define XF_COLOR0CNTRL_F_GET_LIGHT0(xf_color0cntrl_f) \
((((unsigned long)(xf_color0cntrl_f)) & XF_COLOR0CNTRL_F_LIGHT0_MASK) >> XF_COLOR0CNTRL_F_LIGHT0_SHIFT)
#define XF_COLOR0CNTRL_F_SET_LIGHT0(xf_color0cntrl_f, light0) { \
xf_color0cntrl_f = (((unsigned long)(xf_color0cntrl_f)) & ~XF_COLOR0CNTRL_F_LIGHT0_MASK) | (((unsigned long)(light0)) << XF_COLOR0CNTRL_F_LIGHT0_SHIFT);\
}
#define XF_COLOR0CNTRL_F_LIGHT1_SIZE 1
#define XF_COLOR0CNTRL_F_LIGHT1_SHIFT 3
#define XF_COLOR0CNTRL_F_LIGHT1_MASK 0x00000008
#define XF_COLOR0CNTRL_F_GET_LIGHT1(xf_color0cntrl_f) \
((((unsigned long)(xf_color0cntrl_f)) & XF_COLOR0CNTRL_F_LIGHT1_MASK) >> XF_COLOR0CNTRL_F_LIGHT1_SHIFT)
#define XF_COLOR0CNTRL_F_SET_LIGHT1(xf_color0cntrl_f, light1) { \
xf_color0cntrl_f = (((unsigned long)(xf_color0cntrl_f)) & ~XF_COLOR0CNTRL_F_LIGHT1_MASK) | (((unsigned long)(light1)) << XF_COLOR0CNTRL_F_LIGHT1_SHIFT);\
}
#define XF_COLOR0CNTRL_F_LIGHT2_SIZE 1
#define XF_COLOR0CNTRL_F_LIGHT2_SHIFT 4
#define XF_COLOR0CNTRL_F_LIGHT2_MASK 0x00000010
#define XF_COLOR0CNTRL_F_GET_LIGHT2(xf_color0cntrl_f) \
((((unsigned long)(xf_color0cntrl_f)) & XF_COLOR0CNTRL_F_LIGHT2_MASK) >> XF_COLOR0CNTRL_F_LIGHT2_SHIFT)
#define XF_COLOR0CNTRL_F_SET_LIGHT2(xf_color0cntrl_f, light2) { \
xf_color0cntrl_f = (((unsigned long)(xf_color0cntrl_f)) & ~XF_COLOR0CNTRL_F_LIGHT2_MASK) | (((unsigned long)(light2)) << XF_COLOR0CNTRL_F_LIGHT2_SHIFT);\
}
#define XF_COLOR0CNTRL_F_LIGHT3_SIZE 1
#define XF_COLOR0CNTRL_F_LIGHT3_SHIFT 5
#define XF_COLOR0CNTRL_F_LIGHT3_MASK 0x00000020
#define XF_COLOR0CNTRL_F_GET_LIGHT3(xf_color0cntrl_f) \
((((unsigned long)(xf_color0cntrl_f)) & XF_COLOR0CNTRL_F_LIGHT3_MASK) >> XF_COLOR0CNTRL_F_LIGHT3_SHIFT)
#define XF_COLOR0CNTRL_F_SET_LIGHT3(xf_color0cntrl_f, light3) { \
xf_color0cntrl_f = (((unsigned long)(xf_color0cntrl_f)) & ~XF_COLOR0CNTRL_F_LIGHT3_MASK) | (((unsigned long)(light3)) << XF_COLOR0CNTRL_F_LIGHT3_SHIFT);\
}
#define XF_COLOR0CNTRL_F_LIGHT4_SIZE 1
#define XF_COLOR0CNTRL_F_LIGHT4_SHIFT 11
#define XF_COLOR0CNTRL_F_LIGHT4_MASK 0x00000800
#define XF_COLOR0CNTRL_F_GET_LIGHT4(xf_color0cntrl_f) \
((((unsigned long)(xf_color0cntrl_f)) & XF_COLOR0CNTRL_F_LIGHT4_MASK) >> XF_COLOR0CNTRL_F_LIGHT4_SHIFT)
#define XF_COLOR0CNTRL_F_SET_LIGHT4(xf_color0cntrl_f, light4) { \
xf_color0cntrl_f = (((unsigned long)(xf_color0cntrl_f)) & ~XF_COLOR0CNTRL_F_LIGHT4_MASK) | (((unsigned long)(light4)) << XF_COLOR0CNTRL_F_LIGHT4_SHIFT);\
}
#define XF_COLOR0CNTRL_F_LIGHT5_SIZE 1
#define XF_COLOR0CNTRL_F_LIGHT5_SHIFT 12
#define XF_COLOR0CNTRL_F_LIGHT5_MASK 0x00001000
#define XF_COLOR0CNTRL_F_GET_LIGHT5(xf_color0cntrl_f) \
((((unsigned long)(xf_color0cntrl_f)) & XF_COLOR0CNTRL_F_LIGHT5_MASK) >> XF_COLOR0CNTRL_F_LIGHT5_SHIFT)
#define XF_COLOR0CNTRL_F_SET_LIGHT5(xf_color0cntrl_f, light5) { \
xf_color0cntrl_f = (((unsigned long)(xf_color0cntrl_f)) & ~XF_COLOR0CNTRL_F_LIGHT5_MASK) | (((unsigned long)(light5)) << XF_COLOR0CNTRL_F_LIGHT5_SHIFT);\
}
#define XF_COLOR0CNTRL_F_LIGHT6_SIZE 1
#define XF_COLOR0CNTRL_F_LIGHT6_SHIFT 13
#define XF_COLOR0CNTRL_F_LIGHT6_MASK 0x00002000
#define XF_COLOR0CNTRL_F_GET_LIGHT6(xf_color0cntrl_f) \
((((unsigned long)(xf_color0cntrl_f)) & XF_COLOR0CNTRL_F_LIGHT6_MASK) >> XF_COLOR0CNTRL_F_LIGHT6_SHIFT)
#define XF_COLOR0CNTRL_F_SET_LIGHT6(xf_color0cntrl_f, light6) { \
xf_color0cntrl_f = (((unsigned long)(xf_color0cntrl_f)) & ~XF_COLOR0CNTRL_F_LIGHT6_MASK) | (((unsigned long)(light6)) << XF_COLOR0CNTRL_F_LIGHT6_SHIFT);\
}
#define XF_COLOR0CNTRL_F_LIGHT7_SIZE 1
#define XF_COLOR0CNTRL_F_LIGHT7_SHIFT 14
#define XF_COLOR0CNTRL_F_LIGHT7_MASK 0x00004000
#define XF_COLOR0CNTRL_F_GET_LIGHT7(xf_color0cntrl_f) \
((((unsigned long)(xf_color0cntrl_f)) & XF_COLOR0CNTRL_F_LIGHT7_MASK) >> XF_COLOR0CNTRL_F_LIGHT7_SHIFT)
#define XF_COLOR0CNTRL_F_SET_LIGHT7(xf_color0cntrl_f, light7) { \
xf_color0cntrl_f = (((unsigned long)(xf_color0cntrl_f)) & ~XF_COLOR0CNTRL_F_LIGHT7_MASK) | (((unsigned long)(light7)) << XF_COLOR0CNTRL_F_LIGHT7_SHIFT);\
}
#define XF_COLOR0CNTRL_F_ATTENENABLE_SIZE 1
#define XF_COLOR0CNTRL_F_ATTENENABLE_SHIFT 9
#define XF_COLOR0CNTRL_F_ATTENENABLE_MASK 0x00000200
#define XF_COLOR0CNTRL_F_GET_ATTENENABLE(xf_color0cntrl_f) \
((((unsigned long)(xf_color0cntrl_f)) & XF_COLOR0CNTRL_F_ATTENENABLE_MASK) >> XF_COLOR0CNTRL_F_ATTENENABLE_SHIFT)
#define XF_COLOR0CNTRL_F_SET_ATTENENABLE(xf_color0cntrl_f, attenenable) { \
xf_color0cntrl_f = (((unsigned long)(xf_color0cntrl_f)) & ~XF_COLOR0CNTRL_F_ATTENENABLE_MASK) | (((unsigned long)(attenenable)) << XF_COLOR0CNTRL_F_ATTENENABLE_SHIFT);\
}
#define XF_COLOR0CNTRL_F_ATTENSELECT_SIZE 1
#define XF_COLOR0CNTRL_F_ATTENSELECT_SHIFT 10
#define XF_COLOR0CNTRL_F_ATTENSELECT_MASK 0x00000400
#define XF_COLOR0CNTRL_F_GET_ATTENSELECT(xf_color0cntrl_f) \
((((unsigned long)(xf_color0cntrl_f)) & XF_COLOR0CNTRL_F_ATTENSELECT_MASK) >> XF_COLOR0CNTRL_F_ATTENSELECT_SHIFT)
#define XF_COLOR0CNTRL_F_SET_ATTENSELECT(xf_color0cntrl_f, attenselect) { \
xf_color0cntrl_f = (((unsigned long)(xf_color0cntrl_f)) & ~XF_COLOR0CNTRL_F_ATTENSELECT_MASK) | (((unsigned long)(attenselect)) << XF_COLOR0CNTRL_F_ATTENSELECT_SHIFT);\
}
#define SC_XF_AMBIENT0_F_SET_ALPHA(line, xf_ambient0_f,alpha) \
FAST_GPFLAGSET(line, xf_ambient0_f,alpha,XF_AMBIENT0_F_ALPHA)
#define SC_XF_AMBIENT0_F_SET_BLUE(line, xf_ambient0_f,blue) \
FAST_GPFLAGSET(line, xf_ambient0_f,blue,XF_AMBIENT0_F_BLUE)
#define SC_XF_AMBIENT0_F_SET_GREEN(line, xf_ambient0_f,green) \
FAST_GPFLAGSET(line, xf_ambient0_f,green,XF_AMBIENT0_F_GREEN)
#define SC_XF_AMBIENT0_F_SET_RED(line, xf_ambient0_f,red) \
FAST_GPFLAGSET(line, xf_ambient0_f,red,XF_AMBIENT0_F_RED)
#define SC_XF_AMBIENT1_F_SET_ALPHA(line, xf_ambient1_f,alpha) \
FAST_GPFLAGSET(line, xf_ambient1_f,alpha,XF_AMBIENT1_F_ALPHA)
#define SC_XF_AMBIENT1_F_SET_BLUE(line, xf_ambient1_f,blue) \
FAST_GPFLAGSET(line, xf_ambient1_f,blue,XF_AMBIENT1_F_BLUE)
#define SC_XF_AMBIENT1_F_SET_GREEN(line, xf_ambient1_f,green) \
FAST_GPFLAGSET(line, xf_ambient1_f,green,XF_AMBIENT1_F_GREEN)
#define SC_XF_AMBIENT1_F_SET_RED(line, xf_ambient1_f,red) \
FAST_GPFLAGSET(line, xf_ambient1_f,red,XF_AMBIENT1_F_RED)
#define SC_XF_MATERIAL0_F_SET_ALPHA(line, xf_material0_f,alpha) \
FAST_GPFLAGSET(line, xf_material0_f,alpha,XF_MATERIAL0_F_ALPHA)
#define SC_XF_MATERIAL0_F_SET_BLUE(line, xf_material0_f,blue) \
FAST_GPFLAGSET(line, xf_material0_f,blue,XF_MATERIAL0_F_BLUE)
#define SC_XF_MATERIAL0_F_SET_GREEN(line, xf_material0_f,green) \
FAST_GPFLAGSET(line, xf_material0_f,green,XF_MATERIAL0_F_GREEN)
#define SC_XF_MATERIAL0_F_SET_RED(line, xf_material0_f,red) \
FAST_GPFLAGSET(line, xf_material0_f,red,XF_MATERIAL0_F_RED)
#define SC_XF_MATERIAL1_F_SET_ALPHA(line, xf_material1_f,alpha) \
FAST_GPFLAGSET(line, xf_material1_f,alpha,XF_MATERIAL1_F_ALPHA)
#define SC_XF_MATERIAL1_F_SET_BLUE(line, xf_material1_f,blue) \
FAST_GPFLAGSET(line, xf_material1_f,blue,XF_MATERIAL1_F_BLUE)
#define SC_XF_MATERIAL1_F_SET_GREEN(line, xf_material1_f,green) \
FAST_GPFLAGSET(line, xf_material1_f,green,XF_MATERIAL1_F_GREEN)
#define SC_XF_MATERIAL1_F_SET_RED(line, xf_material1_f,red) \
FAST_GPFLAGSET(line, xf_material1_f,red,XF_MATERIAL1_F_RED)
#define SC_XF_MATRIXINDEX0_F_SET_GEOM(line, xf_matrixindex0_f,geom) \
FAST_GPFLAGSET(line, xf_matrixindex0_f,geom,XF_MATRIXINDEX0_F_GEOM)
#define SC_XF_MATRIXINDEX0_F_SET_TEX0(line, xf_matrixindex0_f,tex0) \
FAST_GPFLAGSET(line, xf_matrixindex0_f,tex0,XF_MATRIXINDEX0_F_TEX0)
#define SC_XF_MATRIXINDEX0_F_SET_TEX1(line, xf_matrixindex0_f,tex1) \
FAST_GPFLAGSET(line, xf_matrixindex0_f,tex1,XF_MATRIXINDEX0_F_TEX1)
#define SC_XF_MATRIXINDEX0_F_SET_TEX2(line, xf_matrixindex0_f,tex2) \
FAST_GPFLAGSET(line, xf_matrixindex0_f,tex2,XF_MATRIXINDEX0_F_TEX2)
#define SC_XF_MATRIXINDEX0_F_SET_TEX3(line, xf_matrixindex0_f,tex3) \
FAST_GPFLAGSET(line, xf_matrixindex0_f,tex3,XF_MATRIXINDEX0_F_TEX3)
#define SC_XF_MATRIXINDEX1_F_SET_TEX4(line, xf_matrixindex1_f,tex4) \
FAST_GPFLAGSET(line, xf_matrixindex1_f,tex4,XF_MATRIXINDEX1_F_TEX4)
#define SC_XF_MATRIXINDEX1_F_SET_TEX5(line, xf_matrixindex1_f,tex5) \
FAST_GPFLAGSET(line, xf_matrixindex1_f,tex5,XF_MATRIXINDEX1_F_TEX5)
#define SC_XF_MATRIXINDEX1_F_SET_TEX6(line, xf_matrixindex1_f,tex6) \
FAST_GPFLAGSET(line, xf_matrixindex1_f,tex6,XF_MATRIXINDEX1_F_TEX6)
#define SC_XF_MATRIXINDEX1_F_SET_TEX7(line, xf_matrixindex1_f,tex7) \
FAST_GPFLAGSET(line, xf_matrixindex1_f,tex7,XF_MATRIXINDEX1_F_TEX7)
#define SC_XF_INVERTEXSPEC_F_SET_HOST_COLORS(line, xf_invertexspec_f,host_colors) \
FAST_GPFLAGSET(line, xf_invertexspec_f,host_colors,XF_INVERTEXSPEC_F_HOST_COLORS)
#define SC_XF_INVERTEXSPEC_F_SET_HOST_NORMAL(line, xf_invertexspec_f,host_normal) \
FAST_GPFLAGSET(line, xf_invertexspec_f,host_normal,XF_INVERTEXSPEC_F_HOST_NORMAL)
#define SC_XF_INVERTEXSPEC_F_SET_HOST_TEXTURES(line, xf_invertexspec_f,host_textures) \
FAST_GPFLAGSET(line, xf_invertexspec_f,host_textures,XF_INVERTEXSPEC_F_HOST_TEXTURES)
#define SC_XF_NUMCOLORS_F_SET_GEN_NUMCOLORS(line, xf_numcolors_f,gen_numcolors) \
FAST_GPFLAGSET(line, xf_numcolors_f,gen_numcolors,XF_NUMCOLORS_F_GEN_NUMCOLORS)
#define SC_XF_COLOR0CNTRL_F_SET_MATERIAL_SRC(line, xf_color0cntrl_f,material_src) \
FAST_GPFLAGSET(line, xf_color0cntrl_f,material_src,XF_COLOR0CNTRL_F_MATERIAL_SRC)
#define SC_XF_COLOR0CNTRL_F_SET_LIGHTFUNC(line, xf_color0cntrl_f,lightfunc) \
FAST_GPFLAGSET(line, xf_color0cntrl_f,lightfunc,XF_COLOR0CNTRL_F_LIGHTFUNC)
#define SC_XF_COLOR0CNTRL_F_SET_LIGHT0(line, xf_color0cntrl_f,light0) \
FAST_GPFLAGSET(line, xf_color0cntrl_f,light0,XF_COLOR0CNTRL_F_LIGHT0)
#define SC_XF_COLOR0CNTRL_F_SET_LIGHT1(line, xf_color0cntrl_f,light1) \
FAST_GPFLAGSET(line, xf_color0cntrl_f,light1,XF_COLOR0CNTRL_F_LIGHT1)
#define SC_XF_COLOR0CNTRL_F_SET_LIGHT2(line, xf_color0cntrl_f,light2) \
FAST_GPFLAGSET(line, xf_color0cntrl_f,light2,XF_COLOR0CNTRL_F_LIGHT2)
#define SC_XF_COLOR0CNTRL_F_SET_LIGHT3(line, xf_color0cntrl_f,light3) \
FAST_GPFLAGSET(line, xf_color0cntrl_f,light3,XF_COLOR0CNTRL_F_LIGHT3)
#define SC_XF_COLOR0CNTRL_F_SET_AMBIENT_SRC(line, xf_color0cntrl_f,ambient_src) \
FAST_GPFLAGSET(line, xf_color0cntrl_f,ambient_src,XF_COLOR0CNTRL_F_AMBIENT_SRC)
#define SC_XF_COLOR0CNTRL_F_SET_DIFFUSEATTEN(line, xf_color0cntrl_f,diffuseatten) \
FAST_GPFLAGSET(line, xf_color0cntrl_f,diffuseatten,XF_COLOR0CNTRL_F_DIFFUSEATTEN)
#define SC_XF_COLOR0CNTRL_F_SET_ATTENENABLE(line, xf_color0cntrl_f,attenenable) \
FAST_GPFLAGSET(line, xf_color0cntrl_f,attenenable,XF_COLOR0CNTRL_F_ATTENENABLE)
#define SC_XF_COLOR0CNTRL_F_SET_ATTENSELECT(line, xf_color0cntrl_f,attenselect) \
FAST_GPFLAGSET(line, xf_color0cntrl_f,attenselect,XF_COLOR0CNTRL_F_ATTENSELECT)
#define SC_XF_COLOR0CNTRL_F_SET_LIGHT4(line, xf_color0cntrl_f,light4) \
FAST_GPFLAGSET(line, xf_color0cntrl_f,light4,XF_COLOR0CNTRL_F_LIGHT4)
#define SC_XF_COLOR0CNTRL_F_SET_LIGHT5(line, xf_color0cntrl_f,light5) \
FAST_GPFLAGSET(line, xf_color0cntrl_f,light5,XF_COLOR0CNTRL_F_LIGHT5)
#define SC_XF_COLOR0CNTRL_F_SET_LIGHT6(line, xf_color0cntrl_f,light6) \
FAST_GPFLAGSET(line, xf_color0cntrl_f,light6,XF_COLOR0CNTRL_F_LIGHT6)
#define SC_XF_COLOR0CNTRL_F_SET_LIGHT7(line, xf_color0cntrl_f,light7) \
FAST_GPFLAGSET(line, xf_color0cntrl_f,light7,XF_COLOR0CNTRL_F_LIGHT7)
#define SC_XF_COLOR1CNTRL_F_SET_MATERIAL_SRC(line, xf_color1cntrl_f,material_src) \
FAST_GPFLAGSET(line, xf_color1cntrl_f,material_src,XF_COLOR1CNTRL_F_MATERIAL_SRC)
#define SC_XF_COLOR1CNTRL_F_SET_LIGHTFUNC(line, xf_color1cntrl_f,lightfunc) \
FAST_GPFLAGSET(line, xf_color1cntrl_f,lightfunc,XF_COLOR1CNTRL_F_LIGHTFUNC)
#define SC_XF_COLOR1CNTRL_F_SET_LIGHT0(line, xf_color1cntrl_f,light0) \
FAST_GPFLAGSET(line, xf_color1cntrl_f,light0,XF_COLOR1CNTRL_F_LIGHT0)
#define SC_XF_COLOR1CNTRL_F_SET_LIGHT1(line, xf_color1cntrl_f,light1) \
FAST_GPFLAGSET(line, xf_color1cntrl_f,light1,XF_COLOR1CNTRL_F_LIGHT1)
#define SC_XF_COLOR1CNTRL_F_SET_LIGHT2(line, xf_color1cntrl_f,light2) \
FAST_GPFLAGSET(line, xf_color1cntrl_f,light2,XF_COLOR1CNTRL_F_LIGHT2)
#define SC_XF_COLOR1CNTRL_F_SET_LIGHT3(line, xf_color1cntrl_f,light3) \
FAST_GPFLAGSET(line, xf_color1cntrl_f,light3,XF_COLOR1CNTRL_F_LIGHT3)
#define SC_XF_COLOR1CNTRL_F_SET_AMBIENT_SRC(line, xf_color1cntrl_f,ambient_src) \
FAST_GPFLAGSET(line, xf_color1cntrl_f,ambient_src,XF_COLOR1CNTRL_F_AMBIENT_SRC)
#define SC_XF_COLOR1CNTRL_F_SET_DIFFUSEATTEN(line, xf_color1cntrl_f,diffuseatten) \
FAST_GPFLAGSET(line, xf_color1cntrl_f,diffuseatten,XF_COLOR1CNTRL_F_DIFFUSEATTEN)
#define SC_XF_COLOR1CNTRL_F_SET_ATTENENABLE(line, xf_color1cntrl_f,attenenable) \
FAST_GPFLAGSET(line, xf_color1cntrl_f,attenenable,XF_COLOR1CNTRL_F_ATTENENABLE)
#define SC_XF_COLOR1CNTRL_F_SET_ATTENSELECT(line, xf_color1cntrl_f,attenselect) \
FAST_GPFLAGSET(line, xf_color1cntrl_f,attenselect,XF_COLOR1CNTRL_F_ATTENSELECT)
#define SC_XF_COLOR1CNTRL_F_SET_LIGHT4(line, xf_color1cntrl_f,light4) \
FAST_GPFLAGSET(line, xf_color1cntrl_f,light4,XF_COLOR1CNTRL_F_LIGHT4)
#define SC_XF_COLOR1CNTRL_F_SET_LIGHT5(line, xf_color1cntrl_f,light5) \
FAST_GPFLAGSET(line, xf_color1cntrl_f,light5,XF_COLOR1CNTRL_F_LIGHT5)
#define SC_XF_COLOR1CNTRL_F_SET_LIGHT6(line, xf_color1cntrl_f,light6) \
FAST_GPFLAGSET(line, xf_color1cntrl_f,light6,XF_COLOR1CNTRL_F_LIGHT6)
#define SC_XF_COLOR1CNTRL_F_SET_LIGHT7(line, xf_color1cntrl_f,light7) \
FAST_GPFLAGSET(line, xf_color1cntrl_f,light7,XF_COLOR1CNTRL_F_LIGHT7)
#define SC_XF_ALPHA0CNTRL_F_SET_MATERIAL_SRC(line, xf_alpha0cntrl_f,material_src) \
FAST_GPFLAGSET(line, xf_alpha0cntrl_f,material_src,XF_ALPHA0CNTRL_F_MATERIAL_SRC)
#define SC_XF_ALPHA0CNTRL_F_SET_LIGHTFUNC(line, xf_alpha0cntrl_f,lightfunc) \
FAST_GPFLAGSET(line, xf_alpha0cntrl_f,lightfunc,XF_ALPHA0CNTRL_F_LIGHTFUNC)
#define SC_XF_ALPHA0CNTRL_F_SET_LIGHT0(line, xf_alpha0cntrl_f,light0) \
FAST_GPFLAGSET(line, xf_alpha0cntrl_f,light0,XF_ALPHA0CNTRL_F_LIGHT0)
#define SC_XF_ALPHA0CNTRL_F_SET_LIGHT1(line, xf_alpha0cntrl_f,light1) \
FAST_GPFLAGSET(line, xf_alpha0cntrl_f,light1,XF_ALPHA0CNTRL_F_LIGHT1)
#define SC_XF_ALPHA0CNTRL_F_SET_LIGHT2(line, xf_alpha0cntrl_f,light2) \
FAST_GPFLAGSET(line, xf_alpha0cntrl_f,light2,XF_ALPHA0CNTRL_F_LIGHT2)
#define SC_XF_ALPHA0CNTRL_F_SET_LIGHT3(line, xf_alpha0cntrl_f,light3) \
FAST_GPFLAGSET(line, xf_alpha0cntrl_f,light3,XF_ALPHA0CNTRL_F_LIGHT3)
#define SC_XF_ALPHA0CNTRL_F_SET_AMBIENT_SRC(line, xf_alpha0cntrl_f,ambient_src) \
FAST_GPFLAGSET(line, xf_alpha0cntrl_f,ambient_src,XF_ALPHA0CNTRL_F_AMBIENT_SRC)
#define SC_XF_ALPHA0CNTRL_F_SET_DIFFUSEATTEN(line, xf_alpha0cntrl_f,diffuseatten) \
FAST_GPFLAGSET(line, xf_alpha0cntrl_f,diffuseatten,XF_ALPHA0CNTRL_F_DIFFUSEATTEN)
#define SC_XF_ALPHA0CNTRL_F_SET_ATTENENABLE(line, xf_alpha0cntrl_f,attenenable) \
FAST_GPFLAGSET(line, xf_alpha0cntrl_f,attenenable,XF_ALPHA0CNTRL_F_ATTENENABLE)
#define SC_XF_ALPHA0CNTRL_F_SET_ATTENSELECT(line, xf_alpha0cntrl_f,attenselect) \
FAST_GPFLAGSET(line, xf_alpha0cntrl_f,attenselect,XF_ALPHA0CNTRL_F_ATTENSELECT)
#define SC_XF_ALPHA0CNTRL_F_SET_LIGHT4(line, xf_alpha0cntrl_f,light4) \
FAST_GPFLAGSET(line, xf_alpha0cntrl_f,light4,XF_ALPHA0CNTRL_F_LIGHT4)
#define SC_XF_ALPHA0CNTRL_F_SET_LIGHT5(line, xf_alpha0cntrl_f,light5) \
FAST_GPFLAGSET(line, xf_alpha0cntrl_f,light5,XF_ALPHA0CNTRL_F_LIGHT5)
#define SC_XF_ALPHA0CNTRL_F_SET_LIGHT6(line, xf_alpha0cntrl_f,light6) \
FAST_GPFLAGSET(line, xf_alpha0cntrl_f,light6,XF_ALPHA0CNTRL_F_LIGHT6)
#define SC_XF_ALPHA0CNTRL_F_SET_LIGHT7(line, xf_alpha0cntrl_f,light7) \
FAST_GPFLAGSET(line, xf_alpha0cntrl_f,light7,XF_ALPHA0CNTRL_F_LIGHT7)
#define SC_XF_ALPHA1CNTRL_F_SET_MATERIAL_SRC(line, xf_alpha1cntrl_f,material_src) \
FAST_GPFLAGSET(line, xf_alpha1cntrl_f,material_src,XF_ALPHA1CNTRL_F_MATERIAL_SRC)
#define SC_XF_ALPHA1CNTRL_F_SET_LIGHTFUNC(line, xf_alpha1cntrl_f,lightfunc) \
FAST_GPFLAGSET(line, xf_alpha1cntrl_f,lightfunc,XF_ALPHA1CNTRL_F_LIGHTFUNC)
#define SC_XF_ALPHA1CNTRL_F_SET_LIGHT0(line, xf_alpha1cntrl_f,light0) \
FAST_GPFLAGSET(line, xf_alpha1cntrl_f,light0,XF_ALPHA1CNTRL_F_LIGHT0)
#define SC_XF_ALPHA1CNTRL_F_SET_LIGHT1(line, xf_alpha1cntrl_f,light1) \
FAST_GPFLAGSET(line, xf_alpha1cntrl_f,light1,XF_ALPHA1CNTRL_F_LIGHT1)
#define SC_XF_ALPHA1CNTRL_F_SET_LIGHT2(line, xf_alpha1cntrl_f,light2) \
FAST_GPFLAGSET(line, xf_alpha1cntrl_f,light2,XF_ALPHA1CNTRL_F_LIGHT2)
#define SC_XF_ALPHA1CNTRL_F_SET_LIGHT3(line, xf_alpha1cntrl_f,light3) \
FAST_GPFLAGSET(line, xf_alpha1cntrl_f,light3,XF_ALPHA1CNTRL_F_LIGHT3)
#define SC_XF_ALPHA1CNTRL_F_SET_AMBIENT_SRC(line, xf_alpha1cntrl_f,ambient_src) \
FAST_GPFLAGSET(line, xf_alpha1cntrl_f,ambient_src,XF_ALPHA1CNTRL_F_AMBIENT_SRC)
#define SC_XF_ALPHA1CNTRL_F_SET_DIFFUSEATTEN(line, xf_alpha1cntrl_f,diffuseatten) \
FAST_GPFLAGSET(line, xf_alpha1cntrl_f,diffuseatten,XF_ALPHA1CNTRL_F_DIFFUSEATTEN)
#define SC_XF_ALPHA1CNTRL_F_SET_ATTENENABLE(line, xf_alpha1cntrl_f,attenenable) \
FAST_GPFLAGSET(line, xf_alpha1cntrl_f,attenenable,XF_ALPHA1CNTRL_F_ATTENENABLE)
#define SC_XF_ALPHA1CNTRL_F_SET_ATTENSELECT(line, xf_alpha1cntrl_f,attenselect) \
FAST_GPFLAGSET(line, xf_alpha1cntrl_f,attenselect,XF_ALPHA1CNTRL_F_ATTENSELECT)
#define SC_XF_ALPHA1CNTRL_F_SET_LIGHT4(line, xf_alpha1cntrl_f,light4) \
FAST_GPFLAGSET(line, xf_alpha1cntrl_f,light4,XF_ALPHA1CNTRL_F_LIGHT4)
#define SC_XF_ALPHA1CNTRL_F_SET_LIGHT5(line, xf_alpha1cntrl_f,light5) \
FAST_GPFLAGSET(line, xf_alpha1cntrl_f,light5,XF_ALPHA1CNTRL_F_LIGHT5)
#define SC_XF_ALPHA1CNTRL_F_SET_LIGHT6(line, xf_alpha1cntrl_f,light6) \
FAST_GPFLAGSET(line, xf_alpha1cntrl_f,light6,XF_ALPHA1CNTRL_F_LIGHT6)
#define SC_XF_ALPHA1CNTRL_F_SET_LIGHT7(line, xf_alpha1cntrl_f,light7) \
FAST_GPFLAGSET(line, xf_alpha1cntrl_f,light7,XF_ALPHA1CNTRL_F_LIGHT7)
#define SC_XF_TEX_SET_RESERVED0(line, xf_tex,reserved0) \
FAST_GPFLAGSET(line, xf_tex,reserved0,XF_TEX_RESERVED0)
#define SC_XF_TEX_SET_PROJECTION(line, xf_tex,projection) \
FAST_GPFLAGSET(line, xf_tex,projection,XF_TEX_PROJECTION)
#define SC_XF_TEX_SET_INPUT_FORM(line, xf_tex,input_form) \
FAST_GPFLAGSET(line, xf_tex,input_form,XF_TEX_INPUT_FORM)
#define SC_XF_TEX_SET_RESERVED1(line, xf_tex,reserved1) \
FAST_GPFLAGSET(line, xf_tex,reserved1,XF_TEX_RESERVED1)
#define SC_XF_TEX_SET_TEXGEN_TYPE(line, xf_tex,texgen_type) \
FAST_GPFLAGSET(line, xf_tex,texgen_type,XF_TEX_TEXGEN_TYPE)
#define SC_XF_TEX_SET_SOURCE_ROW(line, xf_tex,source_row) \
FAST_GPFLAGSET(line, xf_tex,source_row,XF_TEX_SOURCE_ROW)
#define SC_XF_TEX_SET_BUMP_MAP_SOURCE(line, xf_tex,bump_map_source) \
FAST_GPFLAGSET(line, xf_tex,bump_map_source,XF_TEX_BUMP_MAP_SOURCE)
#define SC_XF_TEX_SET_BUMP_MAP_LIGHT(line, xf_tex,bump_map_light) \
FAST_GPFLAGSET(line, xf_tex,bump_map_light,XF_TEX_BUMP_MAP_LIGHT)
#define SC_XF_PERF0_F_SET_PERF_A(line, xf_perf0_f,perf_a) \
FAST_GPFLAGSET(line, xf_perf0_f,perf_a,XF_PERF0_F_PERF_A)
#define SC_XF_PERF0_F_SET_PERF_B(line, xf_perf0_f,perf_b) \
FAST_GPFLAGSET(line, xf_perf0_f,perf_b,XF_PERF0_F_PERF_B)
#define SC_XF_PERF0_F_SET_PERF_C(line, xf_perf0_f,perf_c) \
FAST_GPFLAGSET(line, xf_perf0_f,perf_c,XF_PERF0_F_PERF_C)
#define SC_XF_PERF0_F_SET_PERF_D(line, xf_perf0_f,perf_d) \
FAST_GPFLAGSET(line, xf_perf0_f,perf_d,XF_PERF0_F_PERF_D)
#define SC_XF_PERF1_F_SET_PERF_TARGET(line, xf_perf1_f,perf_target) \
FAST_GPFLAGSET(line, xf_perf1_f,perf_target,XF_PERF1_F_PERF_TARGET)
#define SC_XF_ERROR_F_SET_CTEX_BUG_ENABLE(line, xf_error_f,ctex_bug_enable) \
FAST_GPFLAGSET(line, xf_error_f,ctex_bug_enable,XF_ERROR_F_CTEX_BUG_ENABLE)
#define SC_XF_ERROR_F_SET_TFAN4_BUG_ENABLE(line, xf_error_f,tfan4_bug_enable) \
FAST_GPFLAGSET(line, xf_error_f,tfan4_bug_enable,XF_ERROR_F_TFAN4_BUG_ENABLE)
#define SC_XF_ERROR_F_SET_TFAN16_BUG_ENABLE(line, xf_error_f,tfan16_bug_enable) \
FAST_GPFLAGSET(line, xf_error_f,tfan16_bug_enable,XF_ERROR_F_TFAN16_BUG_ENABLE)
#define SC_XF_ERROR_F_SET_DUALTRAN_REG_ENABLE(line, xf_error_f,dualtran_reg_enable) \
FAST_GPFLAGSET(line, xf_error_f,dualtran_reg_enable,XF_ERROR_F_DUALTRAN_REG_ENABLE)
#define SC_XF_ERROR_F_SET_BYPASS_BUG_ENABLE(line, xf_error_f,bypass_bug_enable) \
FAST_GPFLAGSET(line, xf_error_f,bypass_bug_enable,XF_ERROR_F_BYPASS_BUG_ENABLE)
#define SC_XF_ERROR_F_SET_FAST_MATRIX_ENABLE(line, xf_error_f,fast_matrix_enable) \
FAST_GPFLAGSET(line, xf_error_f,fast_matrix_enable,XF_ERROR_F_FAST_MATRIX_ENABLE)
#define SC_XF_DUALTEXTRAN_F_SET_DUALTEXTRAN_ENABLE(line, xf_dualtextran_f,dualtextran_enable) \
FAST_GPFLAGSET(line, xf_dualtextran_f,dualtextran_enable,XF_DUALTEXTRAN_F_DUALTEXTRAN_ENABLE)
#define SC_XF_DUALTEX_F_SET_DUALMATRIX_ADRS(line, xf_dualtex_f,dualmatrix_adrs) \
FAST_GPFLAGSET(line, xf_dualtex_f,dualmatrix_adrs,XF_DUALTEX_F_DUALMATRIX_ADRS)
#define SC_XF_DUALTEX_F_SET_RESERVED0(line, xf_dualtex_f,reserved0) \
FAST_GPFLAGSET(line, xf_dualtex_f,reserved0,XF_DUALTEX_F_RESERVED0)
#define SC_XF_DUALTEX_F_SET_NORMAL_ENABLE(line, xf_dualtex_f,normal_enable) \
FAST_GPFLAGSET(line, xf_dualtex_f,normal_enable,XF_DUALTEX_F_NORMAL_ENABLE)
#endif // XF_MEM_H

View File

@ -77,6 +77,9 @@ typedef enum {
SC_ITEM_ID_BT_SENSOR_BAR_POSITION,
SC_ITEM_ID_DVD_CONFIG,
SC_ITEM_ID_WWW_RESTRICTION,
SC_ITEM_ID_MOTION_PLUS_MOVIE,
SC_ITEM_ID_TEMPORARY_TITLE_ID,
SC_ITEM_ID_MAX_PLUS1
} SCItemID;
@ -104,8 +107,6 @@ typedef struct {
u32 flushSize;
} SCControl;
#define SC_LANG_JAPANESE 0u
#define SC_LANG_ENGLISH 1u
#define SC_LANG_GERMAN 2u
@ -117,26 +118,35 @@ typedef struct {
#define SC_LANG_TRAD_CHINESE 8u
#define SC_LANG_KOREAN 9u
void SCInit(void);
u32 SCCheckStatus(void);
s32 SCReloadConfFileAsync(u8* bufp, u32 bufSize, SCReloadConfFileCallback);
BOOL SCFindByteArrayItem(void* data, u32, SCItemID itemID);
BOOL SCFindIntegerItem(int* data, SCItemID itemID, u8 type);
BOOL SCFindU8Item(u8* data, SCItemID itemID);
BOOL SCFindS8Item(s8* data, SCItemID itemID);
BOOL SCFindU32Item(u32* data, SCItemID itemID);
// scapi
u8 SCGetAspectRatio(void);
s8 SCGetDisplayOffsetH(void);
u8 SCGetEuRgb60Mode(void);
BOOL SCGetIdleMode(SCIdleModeInfo* data);
u8 SCGetLanguage(void);
u8 SCGetProgressiveMode(void);
u8 SCGetScreenSaverMode(void);
u8 SCGetSoundMode(void);
u32 SCGetCounterBias(void);
BOOL SCGetProductAreaString(const char*, int);
// scapi_prdinfo
BOOL SCGetProductAreaString(char* buf, u32 bufSize);
s8 SCGetProductArea(void);
s8 SCGetProductGameRegion(void);
// scsystem
void SCInit(void);
BOOL SCFindByteArrayItem(void* data, u32 size, SCItemID id);
BOOL SCReplaceByteArrayItem(const void* data, u32 size, SCItemID id);
BOOL SCFindIntegerItem(void* data, SCItemID id, SCType type);
BOOL SCReplaceIntegerItem(const void* data, SCItemID id, SCType type);
BOOL SCFindU8Item(u8* data, SCItemID id);
BOOL SCFindS8Item(s8* data, SCItemID id);
BOOL SCFindU32Item(u32* data, SCItemID id);
BOOL SCReplaceU8Item(u8 data, SCItemID id);
u32 SCCheckStatus(void);
s32 SCReloadConfFileAsync(u8* bufp, u32 bufSize, SCReloadConfFileCallback callback);
#ifdef __cplusplus
}
#endif

View File

@ -30,8 +30,10 @@ u32 VIGetScanMode(void);
u32 VIGetDTVStatus(void);
void VISetTrapFilter(u8);
void VIEnableDimming(BOOL);
void VISetGamma(int);
BOOL VIEnableDimming(BOOL);
void VISetGamma(VIGamma);
void VISetRGBModeImm(void);
BOOL VIEnableDVDStopMotor(BOOL enable);
#ifdef __cplusplus
}

View File

@ -13,8 +13,18 @@
#define VI_PAL 1
#define VI_MPAL 2
#define VI_DEBUG 3
#define VI_3D 3
#define VI_DEBUG_PAL 4
#define VI_EURGB60 5
#define VI_GCA 6
#define VI_EXTRA 7
#define VI_HD720 8
typedef u8 VIBool;
#define VI_FALSE ((VIBool)0)
#define VI_TRUE ((VIBool)1)
#define VI_DISABLE ((VIBool)0)
#define VI_ENABLE ((VIBool)1)
typedef enum {
VI_TVMODE_NTSC_INT = VI_TVMODE(VI_NTSC, VI_INTERLACE),
@ -27,9 +37,18 @@ typedef enum {
VI_TVMODE_EURGB60_PROG = VI_TVMODE(VI_EURGB60, VI_PROGRESSIVE),
VI_TVMODE_MPAL_INT = VI_TVMODE(VI_MPAL, VI_INTERLACE),
VI_TVMODE_MPAL_DS = VI_TVMODE(VI_MPAL, VI_NON_INTERLACE),
VI_TVMODE_MPAL_PROG = VI_TVMODE(VI_MPAL, VI_PROGRESSIVE),
VI_TVMODE_DEBUG_INT = VI_TVMODE(VI_DEBUG, VI_INTERLACE),
VI_TVMODE_DEBUG_PAL_INT = VI_TVMODE(VI_DEBUG_PAL, VI_INTERLACE),
VI_TVMODE_DEBUG_PAL_DS = VI_TVMODE(VI_DEBUG_PAL, VI_NON_INTERLACE)
VI_TVMODE_DEBUG_PAL_DS = VI_TVMODE(VI_DEBUG_PAL, VI_NON_INTERLACE),
VI_TVMODE_NTSC_3D = VI_TVMODE(VI_NTSC, VI_3D),
VI_TVMODE_GCA_INT = VI_TVMODE(VI_GCA, VI_INTERLACE),
VI_TVMODE_GCA_PROG = VI_TVMODE(VI_GCA, VI_PROGRESSIVE),
VI_TVMODE_PAL_PROG = 6,
VI_TVMODE_EXTRA_INT = VI_TVMODE(VI_EXTRA, VI_INTERLACE),
VI_TVMODE_EXTRA_DS = VI_TVMODE(VI_EXTRA, VI_NON_INTERLACE),
VI_TVMODE_EXTRA_PROG = VI_TVMODE(VI_EXTRA, VI_PROGRESSIVE),
VI_TVMODE_HD720_PROG = VI_TVMODE(VI_HD720, VI_PROGRESSIVE)
} VITVMode;
typedef enum {
@ -37,6 +56,83 @@ typedef enum {
VI_XFBMODE_DF
} VIXFBMode;
typedef enum _VITimeToDIM {
VI_DM_DEFAULT = 0,
VI_DM_10M,
VI_DM_15M
} VITimeToDIM;
typedef enum _VIVideo {
VI_VMODE_NTSC = 0,
VI_VMODE_MPAL = 1,
VI_VMODE_PAL = 2,
VI_VMODE_RGB = 3
} VIVideo;
typedef enum _VIACPType {
VI_ACP_OFF = 1,
VI_ACP_TYPE1 = 2,
VI_ACP_TYPE2 = 3,
VI_ACP_TYPE3 = 4
} VIACPType;
typedef enum _VIGamma {
VI_GM_0_1 = 1,
VI_GM_0_2,
VI_GM_0_3,
VI_GM_0_4,
VI_GM_0_5,
VI_GM_0_6,
VI_GM_0_7,
VI_GM_0_8,
VI_GM_0_9,
VI_GM_1_0,
VI_GM_1_1,
VI_GM_1_2,
VI_GM_1_3,
VI_GM_1_4,
VI_GM_1_5,
VI_GM_1_6,
VI_GM_1_7,
VI_GM_1_8,
VI_GM_1_9,
VI_GM_2_0,
VI_GM_2_1,
VI_GM_2_2,
VI_GM_2_3,
VI_GM_2_4,
VI_GM_2_5,
VI_GM_2_6,
VI_GM_2_7,
VI_GM_2_8,
VI_GM_2_9,
VI_GM_3_0
} VIGamma;
typedef enum _VITiming {
VI_TMG_GAME = 0,
VI_TMG_DVD = 1
} VITiming;
typedef enum _VIOverDrive {
VI_ODV_L1 = 0,
VI_ODV_L2 = 1,
VI_ODV_L3 = 2,
VI_ODV_L4 = 3,
VI_ODV_L5 = 4,
VI_ODV_L6 = 5
} VIOverDrive;
typedef void (*VIRetraceCallback)(u32 retraceCount);
typedef struct VIGammaObj {
u16 a[6];
u8 yin[7];
u16 yout[7];
} VIGammaObj;
typedef struct VIMacroVisionObj {
u8 m[26];
} VIMacroVisionObj;
#endif

30
include/revolution/wenc.h Normal file
View File

@ -0,0 +1,30 @@
#ifndef _REVOLUTION_WENC_H_
#define _REVOLUTION_WENC_H_
#include <revolution/types.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
WENC_FLAG_USER_INFO = (1 << 0),
} WENCFlag;
typedef struct WENCInfo {
/* 0x00 */ s32 xn;
/* 0x04 */ s32 dl;
/* 0x08 */ s32 qn;
/* 0x0C */ s32 dn;
/* 0x10 */ s32 dlh;
/* 0x14 */ s32 dlq;
/* 0x18 */ u8 padding[8];
} WENCInfo;
s32 WENCGetEncodeData(WENCInfo* info, u32 flag, const s16* pcmData, s32 samples, u8* adpcmData);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -21,23 +21,209 @@ extern "C" {
#define WPAD_BUTTON_C 0x4000
#define WPAD_BUTTON_HOME 0x8000
typedef s32 WPADResult;
typedef s32 WPADChannel;
typedef u32 WPADDeviceType;
#define WPAD_MAX_DPD_OBJECTS 4
typedef void WPADExtensionCallback(WPADChannel chan, s32 devType);
#define WPAD_CHAN0 0
#define WPAD_CHAN1 1
#define WPAD_CHAN2 2
#define WPAD_CHAN3 3
#define WPAD_CHAN_INVALID -1
// for ease of use in for loops
enum WPADChannel_et {
WPAD_CHAN0,
WPAD_CHAN1,
WPAD_CHAN2,
WPAD_CHAN3,
#define WPAD_MAX_CONTROLLERS 4
WPAD_MAX_CONTROLLERS,
WPAD_CHAN_INVALID = -1,
enum WPADResult_et {
WPAD_ERR_OK = 0,
WPAD_ERR_NO_CONTROLLER = -1,
WPAD_ERR_BUSY = -2,
WPAD_ERR_TRANSFER = -3,
WPAD_ERR_INVALID = -4,
WPAD_ERR_5 = -5,
WPAD_ERR_6 = -6,
WPAD_ERR_CORRUPTED = -7,
};
#define WPAD_ESUCCESS WPAD_ERR_OK
#define WPAD_ENODEV WPAD_ERR_NO_CONTROLLER
#define WPAD_EBUSY WPAD_ERR_BUSY
#define WPAD_ETRANSFER WPAD_ERR_TRANSFER // I don't know what the POSIX equivalent is
#define WPAD_EINVAL WPAD_ERR_INVALID
#define WPAD_E5 WPAD_ERR_5
#define WPAD_E6 WPAD_ERR_6
#define WPAD_EBADE WPAD_ERR_CORRUPTED
// apparently enum vs constant is a thing. cool
#define WPAD_CESUCCESS (WPAD_ESUCCESS + 0)
#define WPAD_CENODEV (WPAD_ENODEV + 0)
#define WPAD_CEBUSY (WPAD_EBUSY + 0)
#define WPAD_CETRANSFER (WPAD_ETRANSFER + 0)
#define WPAD_CEINVAL (WPAD_EINVAL + 0)
#define WPAD_CE5 (WPAD_E5 + 0)
#define WPAD_CE6 (WPAD_E6 + 0)
#define WPAD_CEBADE (WPAD_EBADE + 0)
typedef void WPADInitFunc(void);
typedef void WPADCallback(s32 chan, s32 result);
typedef void WPADExtensionCallback(s32 chan, s32 devType);
typedef void WPADSamplingCallback(s32 chan);
typedef void WPADConnectCallback(s32 chan, s32 result);
typedef struct DPDObject {
/* 0x00 */ s16 x;
/* 0x02 */ s16 y;
/* 0x04 */ u16 size;
/* 0x06 */ u8 traceId;
} DPDObject;
typedef struct WPADStatus {
/* 0x00 */ u16 button;
/* 0x02 */ s16 accX;
/* 0x04 */ s16 accY;
/* 0x06 */ s16 accZ;
/* 0x08 */ DPDObject obj[WPAD_MAX_DPD_OBJECTS];
/* 0x28 */ u8 dev;
/* 0x29 */ s8 err;
} WPADStatus;
typedef struct DPDObjEx {
/* 0x00 */ s16 range_x1;
/* 0x02 */ s16 range_y1;
/* 0x04 */ s16 range_x2;
/* 0x06 */ s16 range_y2;
/* 0x08 */ u16 pixel;
/* 0x0A */ s8 radius;
} DPDObjEx;
typedef struct WPADStatusEx {
/* 0x00 */ u16 button;
/* 0x02 */ s16 accX;
/* 0x04 */ s16 accY;
/* 0x06 */ s16 accZ;
/* 0x08 */ DPDObject obj[WPAD_MAX_DPD_OBJECTS];
/* 0x28 */ u8 dev;
/* 0x29 */ s8 err;
/* 0x2a */ DPDObjEx exp[WPAD_MAX_DPD_OBJECTS];
} WPADStatusEx;
typedef struct WPADFSStatus {
/* 0x00 */ u16 button;
/* 0x02 */ s16 accX;
/* 0x04 */ s16 accY;
/* 0x06 */ s16 accZ;
/* 0x08 */ DPDObject obj[WPAD_MAX_DPD_OBJECTS];
/* 0x28 */ u8 dev;
/* 0x29 */ s8 err;
/* 0x2a */ s16 fsAccX;
/* 0x2c */ s16 fsAccY;
/* 0x2e */ s16 fsAccZ;
/* 0x30 */ s8 fsStickX;
/* 0x31 */ s8 fsStickY;
} WPADFSStatus;
typedef struct WPADCLStatus {
/* 0x00 */ u16 button;
/* 0x02 */ s16 accX;
/* 0x04 */ s16 accY;
/* 0x06 */ s16 accZ;
/* 0x08 */ DPDObject obj[WPAD_MAX_DPD_OBJECTS];
/* 0x28 */ u8 dev;
/* 0x29 */ s8 err;
/* 0x2a */ u16 clButton;
/* 0x2c */ s16 clLStickX;
/* 0x2e */ s16 clLStickY;
/* 0x30 */ s16 clRStickX;
/* 0x32 */ s16 clRStickY;
/* 0x34 */ u8 clTriggerL;
/* 0x35 */ u8 clTriggerR;
} WPADCLStatus;
typedef struct WPADBKStatus {
/* 0x00 */ u16 button;
/* 0x02 */ s16 accX;
/* 0x04 */ s16 accY;
/* 0x06 */ s16 accZ;
/* 0x08 */ DPDObject obj[WPAD_MAX_DPD_OBJECTS];
/* 0x28 */ u8 dev;
/* 0x29 */ s8 err;
/* 0x2a */ u8 bulk[21];
/* 0x3f */ u8 padding[1];
} WPADBKStatus;
typedef struct WPADTRStatus {
/* 0x00 */ u16 button;
/* 0x02 */ s16 accX;
/* 0x04 */ s16 accY;
/* 0x06 */ s16 accZ;
/* 0x08 */ DPDObject obj[WPAD_MAX_DPD_OBJECTS];
/* 0x28 */ u8 dev;
/* 0x29 */ s8 err;
/* 0x2a */ u16 trButton;
/* 0x2c */ u8 brake;
/* 0x2d */ u8 mascon;
} WPADTRStatus;
typedef struct WPADVSStatus {
/* 0x00 */ u16 button;
/* 0x02 */ s16 accX;
/* 0x04 */ s16 accY;
/* 0x06 */ s16 accZ;
/* 0x08 */ DPDObject obj[WPAD_MAX_DPD_OBJECTS];
/* 0x28 */ u8 dev;
/* 0x29 */ s8 err;
/* 0x2a */ u16 at_0x2a[5];
/* 0x34 */ u8 at_0x34;
/* 0x36 */ u16 at_0x36[5];
/* 0x40 */ u8 at_0x40;
/* 0x42 */ u16 at_0x42;
/* 0x44 */ u8 at_0x44;
} WPADVSStatus;
typedef struct WPADMPStatus {
/* 0x00 */ u16 button;
/* 0x02 */ s16 accX;
/* 0x04 */ s16 accY;
/* 0x06 */ s16 accZ;
/* 0x08 */ DPDObject obj[WPAD_MAX_DPD_OBJECTS];
/* 0x28 */ u8 dev;
/* 0x29 */ s8 err;
union {
struct {
/* 0x00 */ s16 fsAccX;
/* 0x02 */ s16 fsAccY;
/* 0x04 */ s16 fsAccZ;
/* 0x06 */ s8 fsStickX;
/* 0x07 */ s8 fsStickY;
} fs;
struct {
/* 0x00 */ u16 clButton;
/* 0x02 */ s16 clLStickX;
/* 0x04 */ s16 clLStickY;
/* 0x06 */ s16 clRStickX;
/* 0x08 */ s16 clRStickY;
/* 0x0a */ u8 clTriggerL;
/* 0x0b */ u8 clTriggerR;
} cl;
} ext;
/* 0x36 */ u8 stat;
/* 0x37 */ u8 reserved;
/* 0x38 */ s16 pitch;
/* 0x3a */ s16 yaw;
/* 0x3c */ s16 roll;
} WPADMPStatus;
typedef struct WPADBLStatus {
/* 0x00 */ u16 button;
/* 0x02 */ s16 accX;
/* 0x04 */ s16 accY;
/* 0x06 */ s16 accZ;
/* 0x08 */ DPDObject obj[WPAD_MAX_DPD_OBJECTS];
/* 0x28 */ u8 dev;
/* 0x29 */ s8 err;
/* 0x2a */ u16 press[4];
/* 0x32 */ s8 temp;
/* 0x33 */ u8 battery;
} WPADBLStatus;
typedef struct WPADInfo {
/* 0x00 */ BOOL dpd;
/* 0x04 */ BOOL speaker;
@ -48,11 +234,44 @@ typedef struct WPADInfo {
/* 0x15 */ u8 led;
/* 0x16 */ u8 protocol;
/* 0x17 */ u8 firmware;
} WPADInfo; // size 0x18
} WPADInfo;
WPADResult WPADProbe(WPADChannel chan, WPADDeviceType* devType);
#define WPAD_FMT_CORE_BTN 0
#define WPAD_FMT_CORE_BTN_ACC 1
#define WPAD_FMT_CORE_BTN_ACC_DPD 2
#define WPAD_FMT_FS_BTN 3
#define WPAD_FMT_FS_BTN_ACC 4
#define WPAD_FMT_FS_BTN_ACC_DPD 5
#define WPAD_FMT_CLASSIC_BTN 6
#define WPAD_FMT_CLASSIC_BTN_ACC 7
#define WPAD_FMT_CLASSIC_BTN_ACC_DPD 8
#define WPAD_FMT_BTN_ACC_DPD_EXTENDED 9
// extensions
#define WPAD_FMT_TRAIN 10
#define WPAD_FMT_GUITAR 11
#define WPAD_FMT_BALANCE_CHECKER 12
#define WPAD_FMT_VSM 13
#define WPAD_FMT_DRUM 15
#define WPAD_FMT_MOTION_PLUS 16
#define WPAD_FMT_TAIKO 17
#define WPAD_FMT_TURNTABLE 18
#define WPAD_FMT_BULK 19
WPADExtensionCallback* WPADSetExtensionCallback(WPADChannel chan, WPADExtensionCallback* cb);
#define WPAD_SPEAKER_DISABLE 0
#define WPAD_SPEAKER_ENABLE 1 // might be ON? see HBMRemoteSpk.cpp
#define WPAD_SPEAKER_MUTE 2
#define WPAD_SPEAKER_UNMUTE 3
#define WPAD_SPEAKER_PLAY 4
#define WPAD_SPEAKER_CMD_05 5 // does the same thing as ENABLE? unless i'm missing something. not used so i don't know the context
s32 WPADProbe(s32 chan, u32* devType);
u8 WPADGetRadioSensitivity(s32 chan);
void WPADRead(s32 chan, WPADStatus* status);
BOOL WPADIsSpeakerEnabled(s32 chan);
s32 WPADControlSpeaker(s32 chan, u32 command, WPADCallback* cb);
s32 WPADSendStreamData(s32 chan, void* p_buf, u16 len);
WPADExtensionCallback* WPADSetExtensionCallback(s32 chan, WPADExtensionCallback* cb);
#ifdef __cplusplus
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,53 @@
#ifndef _REVOLUTION_WUD_H_
#define _REVOLUTION_WUD_H_
#include <revolution/types.h>
#include <revolution/wpad/bte.h>
#ifdef __cplusplus
extern "C" {
#endif
#define WUD_CHAN0 0
#define WUD_CHAN1 1
#define WUD_CHAN2 2
#define WUD_CHAN3 3
#define WUD_MAX_CHANNELS 4
#define WUD_CHAN_INVALID -1
typedef void* WUDAllocFunc(u32 size);
typedef int WUDFreeFunc(void* ptr); // signature from petari. not sure what the int is, though
typedef void WUDSyncDeviceCallback(s32 result, s32 num); // what is result?
typedef void WUDClearDeviceCallback(signed);
typedef struct WUDDevInfo WUDDevInfo;
typedef void WUDHidConnectCallback(WUDDevInfo* devInfo, u8 isOpenEvent);
typedef void WUDHidReceiveCallback(u8 dev_handle, u8* p_rpt, u16 len);
struct WUDDevInfo {
/* 0x00 */ struct small_dev_info small;
/* 0x40 */ BD_ADDR devAddr;
/* 0x46 */ LINK_KEY linkKey;
/* 0x56 */ u8 devHandle;
/* 0x57 */ u8 subclass;
/* 0x58 */ u8 appID;
/* 0x59 */ u8 at_0x59;
/* 0x5a */ u8 at_0x5a; /* unknown */
/* 0x5b */ u8 at_0x5b;
/* 0x5c */ u8 at_0x5c;
u8 at_0x5d[1]; // padding?
/* 0x5e */ tBTA_HH_ATTR_MASK hhAttrMask;
}; // size 0x60
u8 WUDGetBufferStatus(void);
u8 _WUDGetLinkNumber(void);
u16 _WUDGetQueuedSize(s8 dev_handle);
u16 _WUDGetNotAckedSize(s8 dev_handle);
#ifdef __cplusplus
}
#endif
#endif // _REVOLUTION_WUD_H_

View File

@ -147,8 +147,8 @@ void dHomeButton_c::initCursorPos() {
void dHomeButton_c::calcCursorPos() {
for (u32 i = 0; i < 4; i++) {
WPADDeviceType sp8;
WPADResult result = WPADProbe(i, &sp8);
u32 sp8;
s32 result = WPADProbe(i, &sp8);
if (result == -2 || result == -3 || result == 0) {
m_controllerData.wiiCon[i].kpad = &mReCPd::m_pad[i].field_0x4[0];

View File

@ -338,7 +338,7 @@ static bool data_80450BE8;
void mDoGph_gInf_c::beginRender() {
#if PLATFORM_WII || PLATFORM_SHIELD
VISetTrapFilter(fapGmHIO_getTrapFilter() ? 1 : 0);
VISetGamma(fapGmHIO_getGamma());
VISetGamma((VIGamma)fapGmHIO_getGamma());
#endif
if (data_80450BE8) {

273
src/revolution/ai/ai.c Normal file
View File

@ -0,0 +1,273 @@
#include <revolution/ai.h>
#include <revolution/gx.h>
#include <revolution/os.h>
#include <revolution/hw_regs.h>
#include "__gx.h"
#ifdef SDK_AUG2010
#define BUILD_DATE "Aug 23 2010"
#if DEBUG
#define BUILD_TIME "17:24:31"
#else
#define BUILD_TIME "17:33:06"
#endif
#elif SDK_SEP2006
#define BUILD_DATE "Sep 21 2006"
#define BUILD_TIME "14:32:13"
#endif
#ifdef SDK_AUG2010
#if DEBUG
const char* __AIVersion = "<< RVL_SDK - AI \tdebug build: "BUILD_DATE" "BUILD_TIME" (0x4302_145) >>";
#else
const char* __AIVersion = "<< RVL_SDK - AI \trelease build: "BUILD_DATE" "BUILD_TIME" (0x4302_145) >>";
#endif
#elif SDK_SEP2006
const char* __AIVersion = "<< RVL_SDK - AI \trelease build: "BUILD_DATE" "BUILD_TIME" (0x4200_60422) >>";
#endif
static AIDCallback __AID_Callback;
static u8* __CallbackStack;
static u8* __OldStack;
static BOOL __AI_init_flag;
static BOOL __AID_Active;
static OSTime bound_32KHz;
static OSTime bound_48KHz;
static OSTime min_wait;
static OSTime max_wait;
static OSTime buffer;
typedef struct {
OSTime t_start;
OSTime t1;
OSTime t2;
OSTime t3;
OSTime t4;
OSTime t_end;
} STRUCT_TIMELOG;
STRUCT_TIMELOG __AIprofile;
OSTime __ai_src_time_start;
OSTime __ai_src_time_end;
// prototypes
STRUCT_TIMELOG* __ai_src_get_time(void);
static void __AIDHandler(__OSInterrupt interrupt, OSContext* context);
static void __AICallbackStackSwitch(void* cb);
static void __AI_SRC_INIT(void);
AIDCallback AIRegisterDMACallback(AIDCallback callback) {
AIDCallback old_callback;
BOOL old;
old_callback = __AID_Callback;
old = OSDisableInterrupts();
__AID_Callback = callback;
OSRestoreInterrupts(old);
return old_callback;
}
void AIInitDMA(u32 start_addr, u32 length) {
BOOL old;
old = OSDisableInterrupts();
__DSPRegs[24] = (__DSPRegs[24] & ~0x1FFF) | (start_addr >> 16);
__DSPRegs[25] = (__DSPRegs[25] & ~0xFFE0) | (start_addr & 0xFFFF);
ASSERTMSGLINE(342, (length & 0x1F) == 0, "AIStartDMA: length must be multiple of 32 bytes");
__DSPRegs[27] = (__DSPRegs[27] & ~0x7FFF) | (u16)((length >> 5) & 0xFFFF);
OSRestoreInterrupts(old);
}
BOOL AIGetDMAEnableFlag(void) {
return (__DSPRegs[27] & (1 << 15)) >> 15;
}
void AIStartDMA(void) {
__DSPRegs[27] = __DSPRegs[27] | 0x8000;
}
void AIStopDMA(void) {
__DSPRegs[27] = __DSPRegs[27] & ~0x8000;
}
u32 AIGetDMABytesLeft(void) {
return (__DSPRegs[29] & 0x7FFF) << 5;
}
u32 AIGetDMAStartAddr(void) {
return (((__DSPRegs[24] & 0x1FFF) << 16) | (__DSPRegs[25] & 0xFFE0));
}
u32 AIGetDMALength(void) {
return (__DSPRegs[27] & 0x7FFF) << 5;
}
BOOL AICheckInit(void) {
return __AI_init_flag;
}
void AISetDSPSampleRate(u32 rate) {
BOOL old;
if (rate != AIGetDSPSampleRate()) {
__AIRegs[0] = (__AIRegs[0] & ~0x40);
if (rate == AI_SAMPLERATE_32KHZ) {
old = OSDisableInterrupts();
__AI_SRC_INIT();
__AIRegs[0] |= 0x40;
OSRestoreInterrupts(old);
}
}
}
u32 AIGetDSPSampleRate(void) {
return GET_REG_FIELD(__AIRegs[0], 1, 6) ^ 1;
}
void AIInit(u8* stack) {
u32 reg;
if (__AI_init_flag != TRUE) {
OSRegisterVersion(__AIVersion);
bound_32KHz = OSNanosecondsToTicks(31524);
bound_48KHz = OSNanosecondsToTicks(42024);
min_wait = OSNanosecondsToTicks(42000);
max_wait = OSNanosecondsToTicks(63000);
buffer = OSNanosecondsToTicks(3000);
reg = __AIRegs[0];
reg &= ~(0x1 | 0x4 | 0x10);
__AIRegs[0] = reg;
__AIRegs[1] = 0;
__AIRegs[3] = 0;
__AIRegs[0] = (__AIRegs[0] & ~0x20) | (0x1 << 5);
AISetDSPSampleRate(AI_SAMPLERATE_32KHZ);
#if DEBUG
OSReport("AIInit(): DSP is 32KHz\n");
#endif
__AID_Callback = NULL;
__CallbackStack = stack;
ASSERTMSGLINE(663, !stack || ((u32)stack & 7) == 0, "AIInit: stack must be 8-byte aligned");
__OSSetInterruptHandler(5, __AIDHandler);
__OSUnmaskInterrupts(0x04000000);
__AI_init_flag = TRUE;
}
}
void AIReset(void) {
__AI_init_flag = FALSE;
}
static void __AIDHandler(__OSInterrupt interrupt, OSContext* context) {
OSContext exceptionContext;
u16 tmp;
tmp = __DSPRegs[5];
tmp = (tmp & ~0xA0) | 8;
__DSPRegs[5] = tmp;
OSClearContext(&exceptionContext);
OSSetCurrentContext(&exceptionContext);
if (__AID_Callback && !__AID_Active) {
__AID_Active = TRUE;
if (__CallbackStack) {
__AICallbackStackSwitch(__AID_Callback);
} else {
__AID_Callback();
}
__AID_Active = FALSE;
}
OSClearContext(&exceptionContext);
OSSetCurrentContext(context);
}
static asm void __AICallbackStackSwitch(__REGISTER void* cb) {
fralloc
lis r5, __OldStack@ha
addi r5, r5, __OldStack@l
stw r1, 0x0(r5)
lis r5, __CallbackStack@ha
addi r5, r5, __CallbackStack@l
lwz r1, 0x0(r5)
subi r1, r1, 0x8
mtlr cb
blrl
lis r5, __OldStack@ha
addi r5, r5, __OldStack@l
lwz r1, 0x0(r5)
frfree
blr
}
void __AI_SRC_INIT(void) {
OSTime rising_32khz = 0;
OSTime rising_48khz = 0;
OSTime diff = 0;
OSTime t1 = 0;
OSTime temp;
u32 temp0;
u32 temp1;
u32 done = 0;
u32 volume = 0;
u32 Init_Cnt = 0;
u32 walking = 0;
walking = 0;
Init_Cnt = 0;
temp = 0;
#if DEBUG
__AIprofile.t_start = OSGetTime();
#endif
while (!done) {
OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 5, 1);
OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 1, 0);
OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 0, AI_STREAM_START);
temp0 = __AIRegs[2] & 0x7FFFFFFF;
while (temp0 == (__AIRegs[2] & 0x7FFFFFFF)) {
}
rising_32khz = OSGetTime();
OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 1, 1);
OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 0, AI_STREAM_START);
temp1 = __AIRegs[2] & 0x7FFFFFFF;
while (temp1 == (__AIRegs[2] & 0x7FFFFFFF)) {
}
rising_48khz = OSGetTime();
diff = rising_48khz - rising_32khz;
OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 1, 0);
OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 0, AI_STREAM_STOP);
if (diff < bound_32KHz - buffer) {
temp = min_wait;
done = 1;
Init_Cnt++;
} else if (diff >= bound_32KHz + buffer && diff < bound_48KHz - buffer) {
temp = max_wait;
done = 1;
Init_Cnt++;
} else {
done = 0;
walking = 1;
Init_Cnt++;
}
}
while (rising_48khz + temp > OSGetTime()) {
}
#if DEBUG
__AIprofile.t_end = OSGetTime();
#endif
}
STRUCT_TIMELOG* __ai_src_get_time(void) {
#if DEBUG
return &__AIprofile;
#else
return NULL;
#endif
}

View File

@ -0,0 +1,18 @@
#ifndef _REVOLUTION_AR_INTERNAL_H_
#define _REVOLUTION_AR_INTERNAL_H_
#include <revolution/aralt.h>
#ifdef __cplusplus
extern "C" {
#endif
void __ARQPopTaskQueueHi(void);
void __ARQServiceQueueLo(void);
void __ARQInterruptServiceRoutine(u32);
#ifdef __cplusplus
}
#endif
#endif // _REVOLUTION_AR_INTERNAL_H_

View File

@ -0,0 +1,175 @@
#include <revolution.h>
#include <revolution/aralt.h>
#include "fake_tgmath.h"
#include <string.h>
#include "__ar.h"
static void (*__AR_Callback)();
static u32 __AR_Size;
static u32 __AR_InternalSize;
static u32 __ARH_BaseAdr;
static ARQRequest* __ARQRequestQueueHi;
static ARQRequest* __ARQRequestQueueLo;
static ARQRequest* __ARQRequestPendingHi;
static ARQRequest* __ARQRequestPendingLo;
static ARQCallback __ARQCallbackHi;
static ARQCallback __ARQCallbackLo;
static u32 __ARQChunkSize;
static BOOL __ARQ_init_flag;
static BOOL __AR_init_flag;
static u32 __ARALT_AramStartAdr = 0x90000000;
static u32 __ARH_MemoryTop = 0x90000000;
ARQCallback ARRegisterDMACallback(ARQCallback callback) {
ARQCallback old_callback;
BOOL old;
old_callback = __AR_Callback;
old = OSDisableInterrupts();
__AR_Callback = callback;
OSRestoreInterrupts(old);
return old_callback;
}
void ARStartDMA(u32 type, u32 mainmem_addr, u32 aram_addr, u32 length) {
OSDisableScheduler();
if (type == 0) {
aram_addr += __ARH_BaseAdr;
DCInvalidateRange((u32*)mainmem_addr, length);
memcpy((u32*)aram_addr, (u32*)mainmem_addr, length);
DCFlushRange((u32*)aram_addr, length);
} else if (type == 1) {
mainmem_addr += __ARH_BaseAdr;
DCFlushRange((u32*)mainmem_addr, length);
memcpy((u32*)aram_addr, (u32*)mainmem_addr, length);
DCFlushRange((u32*)aram_addr, length);
}
OSEnableScheduler();
if (__AR_Callback != NULL) {
(*__AR_Callback)();
}
}
u32 ARAlloc(u32 length) {
u32 tmp;
BOOL old;
old = OSDisableInterrupts();
tmp = __ARH_MemoryTop;
OSRestoreInterrupts(old);
__ARH_MemoryTop += length;
return tmp - __ARH_BaseAdr;
}
u32 ARInit(u32* stack_index_addr, u32 num_entries) {
BOOL old;
if (__AR_init_flag) {
return ARGetBaseAddress();
}
old = OSDisableInterrupts();
__AR_Callback = NULL;
__AR_init_flag = TRUE;
OSRestoreInterrupts(old);
{
u32 start;
u32 end;
start = __ARALT_AramStartAdr;
end = start + 0x1100000;
__ARH_MemoryTop = ARGetBaseAddress() + start;
__ARH_BaseAdr = start;
OSReport("ARInit : Dummy ARAM enabled (RVL), area %p -> %p (size 0x%x)\n", start, end, end - start);
__AR_Size = end - start;
__AR_InternalSize = __AR_Size;
}
return ARGetBaseAddress();
}
u32 ARGetBaseAddress(void) {
return 0x4000;
}
u32 ARGetSize(void) {
return __AR_Size;
}
void __ARQPopTaskQueueHi(void) {
if (__ARQRequestQueueHi) {
if (__ARQRequestQueueHi->type == 0) {
ARStartDMA(__ARQRequestQueueHi->type, __ARQRequestQueueHi->source, __ARQRequestQueueHi->dest, __ARQRequestQueueHi->length);
} else {
ARStartDMA(__ARQRequestQueueHi->type, __ARQRequestQueueHi->dest, __ARQRequestQueueHi->source, __ARQRequestQueueHi->length);
}
__ARQCallbackHi = __ARQRequestQueueHi->callback;
__ARQRequestPendingHi = __ARQRequestQueueHi;
__ARQRequestQueueHi = __ARQRequestQueueHi->next;
}
}
void __ARQServiceQueueLo(void) {
if (__ARQRequestPendingLo == NULL && __ARQRequestQueueLo) {
__ARQRequestPendingLo = __ARQRequestQueueLo;
__ARQRequestQueueLo = __ARQRequestQueueLo->next;
}
if (__ARQRequestPendingLo) {
if (__ARQRequestPendingLo->length <= __ARQChunkSize) {
if (__ARQRequestPendingLo->type == 0) {
ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->source, __ARQRequestPendingLo->dest, __ARQRequestPendingLo->length);
} else {
ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->dest, __ARQRequestPendingLo->source, __ARQRequestPendingLo->length);
}
__ARQCallbackLo = __ARQRequestPendingLo->callback;
} else if (__ARQRequestPendingLo->type == 0) {
ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->source, __ARQRequestPendingLo->dest, __ARQChunkSize);
} else {
ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->dest, __ARQRequestPendingLo->source, __ARQChunkSize);
}
__ARQRequestPendingLo->length -= __ARQChunkSize;
__ARQRequestPendingLo->source += __ARQChunkSize;
__ARQRequestPendingLo->dest += __ARQChunkSize;
}
}
void __ARQInterruptServiceRoutine(u32) {
if (__ARQCallbackHi) {
__ARQCallbackHi((u32)__ARQRequestPendingHi);
__ARQRequestPendingHi = NULL;
__ARQCallbackHi = NULL;
} else if (__ARQCallbackLo) {
__ARQCallbackLo((u32)__ARQRequestPendingLo);
__ARQRequestPendingLo = NULL;
__ARQCallbackLo = NULL;
}
__ARQPopTaskQueueHi();
if (__ARQRequestPendingHi == NULL) {
__ARQServiceQueueLo();
}
}
void ARQInit(void) {
if (__ARQ_init_flag != TRUE) {
__ARQRequestQueueHi = __ARQRequestQueueLo = NULL;
__ARQChunkSize = 0x1000;
ARRegisterDMACallback(__ARQInterruptServiceRoutine);
__ARQRequestPendingHi = NULL;
__ARQRequestPendingLo = NULL;
__ARQCallbackHi = NULL;
__ARQCallbackLo = NULL;
__ARQ_init_flag = TRUE;
}
}

View File

@ -0,0 +1,306 @@
#include <revolution.h>
#include <revolution/base/PPCArch.h>
asm u32 PPCMfmsr() {
nofralloc
mfmsr r3
blr
}
asm void PPCMtmsr(__REGISTER u32 newMSR) {
nofralloc
mtmsr newMSR
blr
}
asm u32 PPCOrMsr(__REGISTER u32 value) {
nofralloc
mfmsr r4
or value, r4, value
blr
}
asm u32 PPCAndMsr(__REGISTER u32 value) {
nofralloc
mfmsr r4
and value, r4, value
blr
}
asm u32 PPCAndCMsr(__REGISTER u32 value) {
nofralloc
mfmsr r4
andc value, r4, value
blr
}
asm u32 PPCMfhid0() {
nofralloc
mfspr r3, HID0
blr
}
asm void PPCMthid0(__REGISTER u32 newHID0) {
nofralloc
mtspr HID0, newHID0
blr
}
asm u32 PPCMfhid1() {
nofralloc
mfspr r3, HID1
blr
}
asm u32 PPCMfl2cr() {
nofralloc
mfspr r3, L2CR
blr
}
asm void PPCMtl2cr(__REGISTER u32 newL2cr) {
nofralloc
mtspr L2CR, newL2cr
blr
}
asm void PPCMtdec(__REGISTER u32 newDec) {
nofralloc
mtdec newDec
blr
}
asm u32 PPCMfdec() {
nofralloc
mfdec r3
blr
}
asm void PPCSync() {
nofralloc
sc
blr
}
asm void PPCEieio() {
nofralloc
mfmsr r5
rlwinm r6, r5, 0, 17, 15
mtmsr r6
mfspr r3, HID0
ori r4, r3, 0x8
mtspr HID0, r4
isync
eieio
isync
mtspr HID0, r3
mtmsr r5
isync
blr
}
asm void PPCHalt() {
nofralloc
sync
loop:
nop
li r3, 0
nop
b loop
}
asm u32 PPCMfmmcr0() {
nofralloc
mfspr r3, MMCR0
blr
}
asm void PPCMtmmcr0(__REGISTER u32 newMmcr0) {
nofralloc
mtspr MMCR0, newMmcr0
blr
}
asm u32 PPCMfmmcr1() {
nofralloc
mfspr r3, MMCR1
blr
}
asm void PPCMtmmcr1(__REGISTER u32 newMmcr1) {
nofralloc
mtspr MMCR1, newMmcr1
blr
}
asm u32 PPCMfpmc1() {
nofralloc
mfspr r3, PMC1
blr
}
asm void PPCMtpmc1(__REGISTER u32 newPmc1) {
nofralloc
mtspr PMC1, newPmc1
blr
}
asm u32 PPCMfpmc2() {
nofralloc
mfspr r3, PMC2
blr
}
asm void PPCMtpmc2(__REGISTER u32 newPmc2) {
nofralloc
mtspr PMC2, newPmc2
blr
}
asm u32 PPCMfpmc3() {
nofralloc
mfspr r3, PMC3
blr
}
asm void PPCMtpmc3(__REGISTER u32 newPmc3) {
nofralloc
mtspr PMC3, newPmc3
blr
}
asm u32 PPCMfpmc4() {
nofralloc
mfspr r3, PMC4
blr
}
asm void PPCMtpmc4(__REGISTER u32 newPmc4) {
nofralloc
mtspr PMC4, newPmc4
blr
}
asm u32 PPCMfsia() {
nofralloc
mfspr r3, SIA
blr
}
asm void PPCMtsia(__REGISTER u32 newSia) {
nofralloc
mtspr SIA, newSia
blr
}
u32 PPCMffpscr() {
union FpscrUnion m;
asm {
mffs fp31
stfd fp31, m.f;
}
return m.u.fpscr;
}
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
}
}
asm u32 PPCMfhid2() {
nofralloc
mfspr r3, HID2
blr
}
asm void PPCMthid2(__REGISTER u32 newhid2) {
nofralloc
mtspr HID2, newhid2
blr
}
asm u32 PPCMfwpar() {
nofralloc
sync
mfspr r3, WPAR
blr
}
asm void PPCMtwpar(__REGISTER u32 newwpar) {
nofralloc
mtspr WPAR, newwpar
blr
}
asm u32 PPCMfdmaU() {
nofralloc
mfspr r3, DMA_U
blr
}
asm u32 PPCMfdmaL() {
nofralloc
mfspr r3, DMA_L
blr
}
asm void PPCMtdmaU(__REGISTER u32 newdmau) {
nofralloc
mtspr DMA_U, newdmau
blr
}
asm void PPCMtdmaL(__REGISTER u32 newdmal) {
nofralloc
mtspr DMA_L, newdmal
blr
}
asm u32 PPCMfpvr() {
nofralloc
mfspr r3, PVR
blr
}
void PPCEnableSpeculation(void) {
PPCMthid0(PPCMfhid0() & ~HID0_SPD);
}
void PPCDisableSpeculation(void) {
PPCMthid0(PPCMfhid0() | HID0_SPD);
}
asm void PPCSetFpIEEEMode() {
nofralloc
mtfsb0 29
blr
}
asm void PPCSetFpNonIEEEMode() {
nofralloc
mtfsb1 29
blr
}
void PPCMthid4(__REGISTER u32 newhid4) {
if (newhid4 & 0x80000000) {
asm {
mtspr 1011, newhid4
}
} else {
OSReport("H4A should not be cleared because of Broadway errata.\n");
asm {
oris newhid4, newhid4, 0x8000
mtspr 1011, newhid4
}
}
}

View File

@ -0,0 +1,34 @@
#include <revolution.h>
#include <revolution/base/PPCArch.h>
void PMBegin(void) {
PPCMtmmcr0(0);
PPCMtmmcr1(0);
PPCMtpmc1(0);
PPCMtpmc2(0);
PPCMtpmc3(0);
PPCMtpmc4(0);
PPCMtmmcr0(0x4F);
PPCMtmmcr1(0x78800000);
}
void PMEnd(void) {
PPCMtmmcr0(0);
PPCMtmmcr1(0);
}
void PMCycles(void) {
PPCMfpmc1();
}
void PML1FetchMisses(void) {
PPCMfpmc2();
}
void PML1MissCycles(void) {
PPCMfpmc3();
}
void PMInstructions(void) {
PPCMfpmc4();
}

View File

@ -0,0 +1,27 @@
#ifndef _REVOLUTION_DSP_INTERNAL_H_
#define _REVOLUTION_DSP_INTERNAL_H_
#include <revolution/dsp.h>
#ifdef __cplusplus
extern "C" {
#endif
extern DSPTaskInfo* __DSP_first_task;
extern DSPTaskInfo* __DSP_last_task;
extern DSPTaskInfo* __DSP_curr_task;
extern DSPTaskInfo* __DSP_tmp_task;
DECL_WEAK void __DSPHandler(__OSInterrupt, OSContext*);
void __DSP_exec_task(DSPTaskInfo*, DSPTaskInfo*);
void __DSP_boot_task(DSPTaskInfo*);
void __DSP_insert_task(DSPTaskInfo*);
void __DSP_add_task(DSPTaskInfo* task);
void __DSP_remove_task(DSPTaskInfo* task);
void __DSP_debug_printf(const char* fmt, ...);
#ifdef __cplusplus
}
#endif
#endif

194
src/revolution/dsp/dsp.c Normal file
View File

@ -0,0 +1,194 @@
#include <stddef.h>
#include <revolution.h>
#include <revolution/hw_regs.h>
#include "__dsp.h"
#ifdef SDK_AUG2010
#define BUILD_DATE "Aug 23 2010"
#if DEBUG
#define BUILD_TIME "17:24:48"
#else
#define BUILD_TIME "17:33:06"
#endif
#elif SDK_SEP2006
#define BUILD_DATE "Sep 21 2006"
#define BUILD_TIME "14:32:13"
#endif
#ifdef SDK_AUG2010
#if DEBUG
const char* __DSPVersion = "<< RVL_SDK - DSP \tdebug build: "BUILD_DATE" "BUILD_TIME" (0x4302_145) >>";
#else
const char* __DSPVersion = "<< RVL_SDK - DSP \trelease build: "BUILD_DATE" "BUILD_TIME" (0x4302_145) >>";
#endif
#elif SDK_SEP2006
const char* __DSPVersion = "<< RVL_SDK - DSP \trelease build: "BUILD_DATE" "BUILD_TIME" (0x4200_60422) >>";
#endif
extern DSPTaskInfo* __DSP_rude_task;
extern int __DSP_rude_task_pending;
static BOOL __DSP_init_flag;
u32 DSPCheckMailToDSP(void) {
return (__DSPRegs[0] & (1 << 15)) >> 15;
}
u32 DSPCheckMailFromDSP(void) {
return (__DSPRegs[2] & (1 << 15)) >> 15;
}
u32 DSPReadCPUToDSPMbox(void) {
return (__DSPRegs[0] << 16) | __DSPRegs[1];
}
u32 DSPReadMailFromDSP(void) {
return (__DSPRegs[2] << 16) | __DSPRegs[3];
}
void DSPSendMailToDSP(u32 mail) {
__DSPRegs[0] = mail >> 16;
__DSPRegs[1] = mail & 0xFFFF;
}
void DSPAssertInt(void) {
BOOL old;
u16 tmp;
old = OSDisableInterrupts();
tmp = __DSPRegs[5];
tmp = (tmp & ~0xA8) | 2;
__DSPRegs[5] = tmp;
OSRestoreInterrupts(old);
}
void DSPInit(void) {
BOOL old;
u16 tmp;
__DSP_debug_printf("DSPInit(): Build Date: %s %s\n", BUILD_DATE, BUILD_TIME);
if (__DSP_init_flag == 1)
return;
OSRegisterVersion(__DSPVersion);
old = OSDisableInterrupts();
__OSSetInterruptHandler(7, __DSPHandler);
__OSUnmaskInterrupts(OS_INTERRUPTMASK_DSP_DSP);
tmp = __DSPRegs[5];
tmp = (tmp & ~0xA8) | 0x800;
__DSPRegs[5] = tmp;
tmp = __DSPRegs[5];
__DSPRegs[5] = tmp = tmp & ~0xAC;
__DSP_first_task = __DSP_last_task = __DSP_curr_task = __DSP_tmp_task = NULL;
__DSP_init_flag = 1;
OSRestoreInterrupts(old);
}
BOOL DSPCheckInit(void) {
return __DSP_init_flag;
}
void DSPReset(void) {
BOOL old;
u16 tmp;
old = OSDisableInterrupts();
tmp = __DSPRegs[5];
tmp = (tmp & ~0xA8) | 0x800 | 1;
__DSPRegs[5] = tmp;
__DSP_init_flag = 0;
OSRestoreInterrupts(old);
}
void DSPHalt(void) {
BOOL old;
u16 tmp;
old = OSDisableInterrupts();
tmp = __DSPRegs[5];
tmp = (tmp & ~0xA8) | 4;
__DSPRegs[5] = tmp;
OSRestoreInterrupts(old);
}
void DSPUnhalt(void) {
BOOL old;
u16 tmp;
old = OSDisableInterrupts();
tmp = __DSPRegs[5];
tmp = (tmp & ~0xAC);
__DSPRegs[5] = tmp;
OSRestoreInterrupts(old);
}
u32 DSPGetDMAStatus(void) {
return (__DSPRegs[5] & (1 << 9));
}
DSPTaskInfo* DSPAddTask(DSPTaskInfo* task) {
BOOL old;
ASSERTMSGLINE(556, __DSP_init_flag == 1, "DSPAddTask(): DSP driver not initialized!\n");
old = OSDisableInterrupts();
__DSP_insert_task(task);
task->state = 0;
task->flags = 1;
OSRestoreInterrupts(old);
if (task == __DSP_first_task)
__DSP_boot_task(task);
return task;
}
DSPTaskInfo* DSPCancelTask(DSPTaskInfo* task) {
BOOL old;
ASSERTMSGLINE(592, __DSP_init_flag == 1, "DSPCancelTask(): DSP driver not initialized!\n");
old = OSDisableInterrupts();
task->flags |= 2;
OSRestoreInterrupts(old);
return task;
}
DSPTaskInfo* DSPAssertTask(DSPTaskInfo* task) {
s32 old;
ASSERTMSGLINE(623, __DSP_init_flag == 1, "DSPAssertTask(): DSP driver not initialized!\n");
ASSERTMSGLINE(624, task->flags & 1, "DSPAssertTask(): Specified task not in active task list!\n");
old = OSDisableInterrupts();
if (__DSP_curr_task == task) {
__DSP_rude_task = task;
__DSP_rude_task_pending = 1;
OSRestoreInterrupts(old);
return task;
}
if (task->priority < __DSP_curr_task->priority) {
__DSP_rude_task = task;
__DSP_rude_task_pending = 1;
if (__DSP_curr_task->state == 1) {
DSPAssertInt();
}
OSRestoreInterrupts(old);
return task;
}
OSRestoreInterrupts(old);
return NULL;
}

View File

@ -0,0 +1,9 @@
#include <revolution/dsp.h>
#include "__dsp.h"
void __DSP_debug_printf(const char* fmt, ...) {}
DSPTaskInfo* __DSPGetCurrentTask(void) {
return __DSP_curr_task;
}

View File

@ -0,0 +1,363 @@
#include <stddef.h>
#include <revolution.h>
#include <revolution/hw_regs.h>
#include "__dsp.h"
static u32 t0, t1, t2; // unused
DSPTaskInfo* __DSP_curr_task;
DSPTaskInfo* __DSP_first_task;
DSPTaskInfo* __DSP_last_task;
DSPTaskInfo* __DSP_tmp_task;
DSPTaskInfo* __DSP_rude_task;
int __DSP_rude_task_pending;
void __DSPHandler(__OSInterrupt intr, OSContext* context) {
u8 unused[4];
OSContext exceptionContext;
u16 tmp;
u32 mail;
tmp = __DSPRegs[5];
tmp = (tmp & ~0x28) | 0x80;
__DSPRegs[5] = tmp;
OSClearContext(&exceptionContext);
OSSetCurrentContext(&exceptionContext);
ASSERTMSGLINE(143, __DSP_curr_task != NULL, "__DSPHandler(): No current task! Someone set us up the bomb!\n");
while (DSPCheckMailFromDSP() == 0)
;
mail = DSPReadMailFromDSP();
if ((__DSP_curr_task->flags & (1<<(31-0x1E))) && (mail + 0x232F0000) == 2)
mail = 0xDCD10003;
switch (mail) {
case 0xDCD10000:
__DSP_curr_task->state = 1;
if (__DSP_curr_task->init_cb != NULL)
__DSP_curr_task->init_cb(__DSP_curr_task);
break;
case 0xDCD10001:
__DSP_curr_task->state = 1;
if (__DSP_curr_task->res_cb != NULL)
__DSP_curr_task->res_cb(__DSP_curr_task);
break;
case 0xDCD10002:
if (__DSP_rude_task_pending) {
if (__DSP_curr_task == __DSP_rude_task) {
DSPSendMailToDSP(0xCDD10003);
while (DSPCheckMailToDSP() != 0)
;
__DSP_rude_task = NULL;
__DSP_rude_task_pending = 0;
if (__DSP_curr_task->res_cb != NULL)
__DSP_curr_task->res_cb(__DSP_curr_task);
} else {
DSPSendMailToDSP(0xCDD10001);
while (DSPCheckMailToDSP() != 0)
;
__DSP_exec_task(__DSP_curr_task, __DSP_rude_task);
__DSP_curr_task->state = 2;
__DSP_curr_task = __DSP_rude_task;
__DSP_rude_task = NULL;
__DSP_rude_task_pending = 0;
}
} else {
if (__DSP_curr_task->next == NULL) {
if (__DSP_curr_task == __DSP_first_task) {
DSPSendMailToDSP(0xCDD10003);
while (DSPCheckMailToDSP() != 0)
;
if (__DSP_curr_task->res_cb != NULL)
__DSP_curr_task->res_cb(__DSP_curr_task);
} else {
DSPSendMailToDSP(0xCDD10001);
while (DSPCheckMailToDSP() != 0)
;
__DSP_exec_task(__DSP_curr_task, __DSP_first_task);
__DSP_curr_task->state = 2;
__DSP_curr_task = __DSP_first_task;
}
} else {
DSPSendMailToDSP(0xCDD10001);
while (DSPCheckMailToDSP() != 0)
;
__DSP_exec_task(__DSP_curr_task, __DSP_curr_task->next);
__DSP_curr_task->state = 2;
__DSP_curr_task = __DSP_curr_task->next;
}
}
break;
case 0xDCD10003:
if (__DSP_rude_task_pending) {
if (__DSP_curr_task->done_cb != NULL)
__DSP_curr_task->done_cb(__DSP_curr_task);
DSPSendMailToDSP(0xCDD10001);
while (DSPCheckMailToDSP() != 0)
;
__DSP_exec_task(NULL, __DSP_rude_task);
__DSP_remove_task(__DSP_curr_task);
__DSP_curr_task = __DSP_rude_task;
__DSP_rude_task = NULL;
__DSP_rude_task_pending = 0;
} else {
if (__DSP_curr_task->next == NULL) {
if (__DSP_curr_task == __DSP_first_task) {
if (__DSP_curr_task->done_cb != NULL)
__DSP_curr_task->done_cb(__DSP_curr_task);
DSPSendMailToDSP(0xCDD10002);
while (DSPCheckMailToDSP() != 0)
;
__DSP_curr_task->state = 3;
__DSP_remove_task(__DSP_curr_task);
} else {
if (__DSP_curr_task->done_cb != NULL)
__DSP_curr_task->done_cb(__DSP_curr_task);
DSPSendMailToDSP(0xCDD10001);
while (DSPCheckMailToDSP() != 0)
;
__DSP_curr_task->state = 3;
__DSP_exec_task(NULL, __DSP_first_task);
__DSP_curr_task = __DSP_first_task;
__DSP_remove_task(__DSP_last_task);
}
} else {
if (__DSP_curr_task->done_cb != NULL)
__DSP_curr_task->done_cb(__DSP_curr_task);
DSPSendMailToDSP(0xCDD10001);
while (DSPCheckMailToDSP() != 0)
;
__DSP_curr_task->state = 3;
__DSP_exec_task(NULL, __DSP_curr_task->next);
__DSP_curr_task = __DSP_curr_task->next;
__DSP_remove_task(__DSP_curr_task->prev);
}
}
break;
case 0xDCD10004:
if (__DSP_curr_task->req_cb != NULL)
__DSP_curr_task->req_cb(__DSP_curr_task);
break;
default:
ASSERTMSGLINEV(519, 0, "__DSPHandler(): Unknown msg from DSP 0x%08X - task sync failed!\n", mail);
}
OSClearContext(&exceptionContext);
OSSetCurrentContext(context);
}
void __DSP_exec_task(DSPTaskInfo* curr, DSPTaskInfo* next) {
ASSERTMSGLINE(555, next != NULL, "__DSP_exec_task(): NULL task. It is to weep.\n");
if (curr != NULL) {
DSPSendMailToDSP((u32)curr->dram_mmem_addr);
while (DSPCheckMailToDSP() != 0)
;
DSPSendMailToDSP(curr->dram_length);
while (DSPCheckMailToDSP() != 0)
;
DSPSendMailToDSP(curr->dram_addr);
while (DSPCheckMailToDSP() != 0)
;
} else {
DSPSendMailToDSP(0);
while (DSPCheckMailToDSP() != 0)
;
DSPSendMailToDSP(0);
while (DSPCheckMailToDSP() != 0)
;
DSPSendMailToDSP(0);
while (DSPCheckMailToDSP() != 0)
;
}
DSPSendMailToDSP((u32)next->iram_mmem_addr);
while (DSPCheckMailToDSP() != 0)
;
DSPSendMailToDSP(next->iram_length);
while (DSPCheckMailToDSP() != 0)
;
DSPSendMailToDSP(next->iram_addr);
while (DSPCheckMailToDSP() != 0)
;
if (next->state == 0) {
DSPSendMailToDSP(next->dsp_init_vector);
while (DSPCheckMailToDSP() != 0)
;
DSPSendMailToDSP(0);
while (DSPCheckMailToDSP() != 0)
;
DSPSendMailToDSP(0);
while (DSPCheckMailToDSP() != 0)
;
DSPSendMailToDSP(0);
while (DSPCheckMailToDSP() != 0)
;
} else {
DSPSendMailToDSP(next->dsp_resume_vector);
while (DSPCheckMailToDSP() != 0)
;
DSPSendMailToDSP((u32)next->dram_mmem_addr);
while (DSPCheckMailToDSP() != 0)
;
DSPSendMailToDSP(next->dram_length);
while (DSPCheckMailToDSP() != 0)
;
DSPSendMailToDSP(next->dram_addr);
while (DSPCheckMailToDSP() != 0)
;
}
}
void __DSP_boot_task(DSPTaskInfo* task) {
volatile u32 mail;
ASSERTMSGLINE(637, task != NULL, "__DSP_boot_task(): NULL task!\n");
while (DSPCheckMailFromDSP() == 0)
;
mail = DSPReadMailFromDSP();
ASSERTMSGLINEV(643, mail == 0x8071FEED, "__DSP_boot_task(): Failed to sync DSP on boot! (0x%08X)\n", mail);
DSPSendMailToDSP(0x80F3A001);
while (DSPCheckMailToDSP() != 0)
;
DSPSendMailToDSP((u32)task->iram_mmem_addr);
while (DSPCheckMailToDSP() != 0)
;
DSPSendMailToDSP(0x80F3C002);
while (DSPCheckMailToDSP() != 0)
;
DSPSendMailToDSP(task->iram_addr & 0xFFFF);
while (DSPCheckMailToDSP() != 0)
;
DSPSendMailToDSP(0x80F3A002);
while (DSPCheckMailToDSP() != 0)
;
DSPSendMailToDSP(task->iram_length);
while (DSPCheckMailToDSP() != 0)
;
DSPSendMailToDSP(0x80F3B002);
while (DSPCheckMailToDSP() != 0)
;
DSPSendMailToDSP(0);
while (DSPCheckMailToDSP() != 0)
;
DSPSendMailToDSP(0x80F3D001);
while (DSPCheckMailToDSP() != 0)
;
DSPSendMailToDSP(task->dsp_init_vector & 0xFFFF);
while (DSPCheckMailToDSP() != 0)
;
__DSP_debug_printf("DSP is booting task: 0x%08X\n", (u32)task);
__DSP_debug_printf("__DSP_boot_task() : IRAM MMEM ADDR: 0x%08X\n", (u32)task->iram_mmem_addr);
__DSP_debug_printf("__DSP_boot_task() : IRAM DSP ADDR : 0x%08X\n", task->iram_addr);
__DSP_debug_printf("__DSP_boot_task() : IRAM LENGTH : 0x%08X\n", task->iram_length);
__DSP_debug_printf("__DSP_boot_task() : DRAM MMEM ADDR: 0x%08X\n", task->dram_length);
__DSP_debug_printf("__DSP_boot_task() : Start Vector : 0x%08X\n", task->dsp_init_vector);
}
void __DSP_insert_task(DSPTaskInfo* task) {
DSPTaskInfo* temp;
if (__DSP_first_task == NULL) {
__DSP_curr_task = task;
__DSP_first_task = __DSP_last_task = task;
task->next = task->prev = NULL;
return;
}
temp = __DSP_first_task;
while (temp != NULL) {
if (task->priority < temp->priority) {
task->prev = temp->prev;
temp->prev = task;
task->next = temp;
if (task->prev == NULL)
__DSP_first_task = task;
else
task->prev->next = task;
break;
}
temp = temp->next;
}
if (temp == NULL) {
__DSP_last_task->next = task;
task->next = NULL;
task->prev = __DSP_last_task;
__DSP_last_task = task;
}
}
void __DSP_add_task(DSPTaskInfo* task) {
ASSERTMSGLINE(771, task != NULL, "__DSP_add_task(): Why are you adding a NULL task?\n");
if (__DSP_last_task == NULL) {
__DSP_curr_task = task;
__DSP_last_task = task;
__DSP_first_task = task;
task->next = task->prev = NULL;
} else {
__DSP_last_task->next = task;
task->next = NULL;
task->prev = __DSP_last_task;
__DSP_last_task = task;
}
task->state = 0;
__DSP_debug_printf("__DSP_add_task() : Added task : 0x%08X\n", (u32)task);
}
void __DSP_remove_task(DSPTaskInfo* task) {
ASSERTMSGLINE(816, task != NULL, "__DSP_remove_task(): NULL task! Why? WHY?!?!\n");
task->flags = 0;
task->state = 3;
if (__DSP_first_task == task) {
if (task->next != NULL) {
__DSP_first_task = task->next;
task->next->prev = NULL;
return;
}
__DSP_first_task = __DSP_last_task = __DSP_curr_task = NULL;
return;
}
if (__DSP_last_task == task) {
__DSP_last_task = task->prev;
task->prev->next = NULL;
__DSP_curr_task = __DSP_first_task;
return;
}
__DSP_curr_task = task->next;
task->prev->next = task->next;
task->next->prev = task->prev;
}

320
src/revolution/esp/esp.c Normal file
View File

@ -0,0 +1,320 @@
#include <revolution/esp.h>
#include <revolution/ipc/ipcclt.h>
#include <revolution/private/iosrestypes.h>
static s32 __esFd = -1;
s32 ESP_InitLib(void) {
s32 ret = 0;
if (__esFd < 0) {
__esFd = IOS_Open("/dev/es", 0);
if (__esFd < 0) {
ret = __esFd;
}
}
return ret;
}
s32 ESP_CloseLib(void) {
s32 ret = 0;
if (__esFd >= 0) {
ret = IOS_Close(__esFd);
if (ret == 0) {
__esFd = -1;
}
}
return ret;
}
s32 ESP_LaunchTitle(u64 titleID, ESTicketView* pTicketView) {
s32 ret = 0;
u8 buf[256] ATTRIBUTE_ALIGN(32);
IOSIoVector* vec = (IOSIoVector*)(buf + 208);
u64* id = (u64*)buf;
if (__esFd < 0) {
ret = -0x3F9;
goto out;
}
// check if ptr is aligned to 0x20
if ((u32)pTicketView & 31) {
ret = -0x3F9;
goto out;
}
*id = titleID;
vec[0].base = (u8*)id;
vec[0].length = 8;
vec[1].base = (u8*)pTicketView;
vec[1].length = 0xD8;
ret = IOS_IoctlvReboot(__esFd, 8, 2, 0, vec);
__esFd = -1;
out:
return ret;
}
s32 ESP_GetTicketViews(ESTitleId titleId, ESTicketView* ticketViewList, u32* ticketViewCnt) {
s32 rv = 0;
u8 __esBuf[256] ATTRIBUTE_ALIGN(32);
IOSIoVector* v = (IOSIoVector*)(__esBuf + 256 - 6 * sizeof(IOSIoVector));
ESTitleId* p1 = (ESTitleId*)__esBuf;
u32* p2 = (u32*)(__esBuf + 32);
if (__esFd < 0 || ticketViewCnt == NULL) {
rv = -1017;
goto out;
}
if (((u32)ticketViewList & 31)) {
rv = -1017;
goto out;
}
*p1 = titleId;
if (ticketViewList == NULL) {
v[0].base = (u8*)p1;
v[0].length = sizeof(ESTitleId);
v[1].base = (u8*)p2;
v[1].length = 4;
rv = IOS_Ioctlv(__esFd, 18, 1, 1, v);
if (rv == 0) {
*ticketViewCnt = *p2;
}
} else {
if (*ticketViewCnt == 0) {
rv = -1017;
goto out;
}
*p2 = *ticketViewCnt;
v[0].base = (u8*)p1;
v[0].length = sizeof(ESTitleId);
v[1].base = (u8*)p2;
v[1].length = 4;
v[2].base = (u8*)ticketViewList;
v[2].length = sizeof(ESTicketView) * (*ticketViewCnt);
rv = IOS_Ioctlv(__esFd, 19, 2, 1, v);
}
out:
return rv;
}
s32 ESP_DiGetTicketView(const void* ticket, ESTicketView* ticketView) {
s32 rv = 0;
u8 __esBuf[256] ATTRIBUTE_ALIGN(32);
IOSIoVector* v = (IOSIoVector*)(__esBuf + 256 - 6 * sizeof(IOSIoVector));
if (__esFd < 0 || ticketView == NULL) {
rv = -1017;
goto out;
}
if (((u32)ticket & 31) || ((u32)ticketView & 31)) {
rv = -1017;
goto out;
}
v[0].base = (u8*)ticket;
if (ticket == NULL) {
v[0].length = 0;
} else {
v[0].length = sizeof(ESTicket);
}
v[1].base = (u8*)ticketView;
v[1].length = sizeof(ESTicketView);
rv = IOS_Ioctlv(__esFd, 27, 1, 1, v);
out:
return rv;
}
s32 ESP_DiGetTmd(ESTitleMeta* tmd, u32* tmdSize) {
s32 rv = 0;
u8 __esBuf[256] ATTRIBUTE_ALIGN(32);
IOSIoVector* v = (IOSIoVector*)(__esBuf + 256 - 6 * sizeof(IOSIoVector));
u32* p1 = (u32*)__esBuf;
if (__esFd < 0 || tmdSize == NULL) {
rv = -1017;
goto out;
}
if (((u32)tmd & 31)) {
rv = -1017;
goto out;
}
if (tmd == NULL) {
v[0].base = (u8*)p1;
v[0].length = 4;
rv = IOS_Ioctlv(__esFd, 57, 0, 1, v);
if (rv == 0) {
*tmdSize = *p1;
}
} else {
if (*tmdSize == 0) {
rv = -1017;
goto out;
}
*p1 = *tmdSize;
v[0].base = (u8*)p1;
v[0].length = 4;
v[1].base = (u8*)tmd;
v[1].length = *tmdSize;
rv = IOS_Ioctlv(__esFd, 58, 1, 1, v);
}
out:
return rv;
}
s32 ESP_GetTmdView(ESTitleId titleId, ESTmdView* tmdView, u32* size) {
s32 rv = 0;
u8 __esBuf[256] ATTRIBUTE_ALIGN(32);
IOSIoVector* v = (IOSIoVector*)(__esBuf + 256 - 6 * sizeof(IOSIoVector));
ESTitleId* p1 = (ESTitleId*)__esBuf;
u32* p2 = (u32*)(__esBuf + 32);
if (__esFd < 0 || size == NULL) {
rv = -1017;
goto out;
}
if (((u32)tmdView & 31)) {
rv = -1017;
goto out;
}
*p1 = titleId;
if (tmdView == NULL) {
v[0].base = (u8*)p1;
v[0].length = sizeof(ESTitleId);
v[1].base = (u8*)p2;
v[1].length = 4;
rv = IOS_Ioctlv(__esFd, 20, 1, 1, v);
if (rv == 0) {
*size = *p2;
}
} else {
if (*size == 0) {
rv = -1017;
goto out;
}
*p2 = *size;
v[0].base = (u8*)p1;
v[0].length = sizeof(ESTitleId);
v[1].base = (u8*)p2;
v[1].length = 4;
v[2].base = (u8*)tmdView;
v[2].length = *size;
rv = IOS_Ioctlv(__esFd, 21, 2, 1, v);
}
out:
return rv;
}
s32 ESP_GetDataDir(ESTitleId titleId, char* dataDir) {
s32 rv = 0;
u8 __esBuf[256] ATTRIBUTE_ALIGN(32);
IOSIoVector* v = (IOSIoVector*)(__esBuf + 256 - 6 * sizeof(IOSIoVector));
ESTitleId* p1 = (ESTitleId*)__esBuf;
if (__esFd < 0 || dataDir == NULL) {
rv = -1017;
goto out;
}
if (((u32)dataDir & 31)) {
rv = -1017;
goto out;
}
*p1 = titleId;
v[0].base = (u8*)p1;
v[0].length = sizeof(ESTitleId);
v[1].base = (u8*)dataDir;
v[1].length = 0x1E;
rv = IOS_Ioctlv(__esFd, 29, 1, 1, v);
out:
return rv;
}
s32 ESP_GetTitleId(ESTitleId* titleId) {
s32 rv = 0;
u8 __esBuf[256] ATTRIBUTE_ALIGN(32);
IOSIoVector* v = (IOSIoVector*)(__esBuf + 256 - 6 * sizeof(IOSIoVector));
if (__esFd < 0 || titleId == NULL) {
rv = -1017;
goto out;
}
v[0].base = __esBuf;
v[0].length = sizeof(ESTitleId);
rv = IOS_Ioctlv(__esFd, 32, 0, 1, v);
if (rv == 0) {
*titleId = *(ESTitleId*)__esBuf;
}
out:
return rv;
}
s32 ESP_GetConsumption(ESTicketId ticketId, ESLpEntry* entries, u32* nEntries) {
s32 rv = 0;
u8 __esBuf[256] ATTRIBUTE_ALIGN(32);
IOSIoVector* v = (IOSIoVector*)(__esBuf + 256 - 6 * sizeof(IOSIoVector));
ESTicketId* p1 = (ESTicketId*)__esBuf;
u32* p2 = (u32*)(__esBuf + 32);
if (__esFd < 0) {
rv = -1017;
goto out;
}
if (((u32)entries & 31)) {
rv = -1017;
goto out;
}
*p1 = ticketId;
v[0].base = (u8*)p1;
v[0].length = sizeof(ESTicketId);
if (entries == NULL) {
v[1].base = NULL;
v[1].length = 0;
} else {
v[1].base = (u8*)entries;
v[1].length = sizeof(ESLpEntry) * (*nEntries);
*p2 = *nEntries;
}
v[2].base = (u8*)p2;
v[2].length = 4;
rv = IOS_Ioctlv(__esFd, 22, 1, 2, v);
*nEntries = *p2;
out:
return rv;
}

View File

@ -0,0 +1,148 @@
#include <revolution/euart.h>
#include <revolution/exi.h>
#include <revolution/os.h>
static BOOL __EUARTInitialized = FALSE;
static EUARTError __EUARTLastErrorCode = EUART_ERROR_NONE;
static BOOL __EUARTSendStop = FALSE;
static u32 Enabled = 0;
BOOL EUARTInit(void) {
BOOL enabled;
u8 val;
if (__EUARTInitialized) {
return TRUE;
}
if (!(OSGetConsoleType() & 0x10000000)) {
__EUARTLastErrorCode = EUART_ERROR_CANNOT_USE;
return FALSE;
}
enabled = OSDisableInterrupts();
val = -14;
if (!EXIWriteReg(0, 1, 0xB0000000, &val, 1)) {
__EUARTLastErrorCode = EUART_ERROR_INTERNAL;
OSRestoreInterrupts(enabled);
return FALSE;
}
val = -13;
if (!EXIWriteReg(0, 1, 0xB0000000, &val, 1)) {
__EUARTLastErrorCode = EUART_ERROR_INTERNAL;
OSRestoreInterrupts(enabled);
return FALSE;
}
OSRestoreInterrupts(enabled);
__EUARTInitialized = TRUE;
__EUARTLastErrorCode = EUART_ERROR_NONE;
__EUARTSendStop = FALSE;
return TRUE;
}
UARTError InitializeUART(UARTBaudRate rate) {
if (!(OSGetConsoleType() & 0x10000000)) {
Enabled = 0;
return kUARTConfigurationError;
} else {
Enabled = 0xA5FF005A;
return kUARTNoError;
}
}
static int QueueLength(void) {
u32 cmd, txCnt;
if (!EXISelect(0, 1, __EXIFreq)) {
return -1;
}
cmd = 0x30000100;
EXIImm(0, &cmd, 4, 1, NULL);
EXISync(0);
EXIImm(0, &txCnt, sizeof(txCnt), 0, NULL);
EXISync(0);
EXIDeselect(0);
return 32 - (u8)((txCnt >> 24) & 0x3F);
}
UARTError WriteUARTN(const void* buf, unsigned long len) {
u32 cmd;
int qLen;
UARTError error;
char* sendData = (char*)buf;
u32 uart_txd;
if (Enabled != 0xA5FF005A) {
return kUARTConfigurationError;
}
if (!__EUARTInitialized) {
if (!EUARTInit()) {
return kUARTConfigurationError;
}
}
if (!__EUARTInitialized) {
__EUARTLastErrorCode = EUART_ERROR_UNINITIALIZED;
return kUARTConfigurationError;
}
if (!EXILock(0, 1, 0)) {
return kUARTNoError;
}
{
char* p;
for (p = sendData; (p - buf) < len; p++) {
if (*p == '\n') {
*p = '\r';
}
}
}
error = kUARTNoError;
cmd = 0xB0000100;
while (len != 0) {
qLen = QueueLength();
if (qLen < 0) {
error = kUARTBufferOverflow;
break;
}
if (qLen != 32) {
continue;
}
if (!EXISelect(0, 1, __EXIFreq)) {
error = kUARTBufferOverflow;
break;
}
EXIImm(0, &cmd, 4, 1, NULL);
EXISync(0);
while ((qLen > 0) && (len > 0)) {
uart_txd = (u32)((*sendData & 0xFF) << 24);
EXIImm(0, &uart_txd, 4, 1, NULL);
EXISync(0);
sendData++;
qLen--;
len--;
}
EXIDeselect(0);
}
EXIUnlock(0);
return error;
}

View File

@ -0,0 +1,876 @@
#include <revolution.h>
#define REG_MAX 5
#define REG(chan, idx) (__EXIRegs[((chan) * REG_MAX) + (idx)])
#define STATE_IDLE 0
#define STATE_DMA 1
#define STATE_IMM 2
#define STATE_BUSY 3
#define STATE_SELECTED 4
#define STATE_ATTACHED 8
#define STATE_LOCKED 16
#define MAX_CHAN 3
#define MAX_IMM 4
#define MAX_TYPE 3
#define MAX_DEV 3
#define MAX_FREQ 6
#define EXI_0LENGTH_EXILENGTH_MASK 0xFFFFFFE0
#ifdef SDK_AUG2010
#define BUILD_DATE "Aug 23 2010"
#if DEBUG
#define BUILD_TIME "17:24:52"
#else
#define BUILD_TIME "17:33:06"
#endif
#elif SDK_SEP2006
#define BUILD_DATE "Sep 21 2006"
#define BUILD_TIME "14:32:13"
#endif
#ifdef SDK_AUG2010
#if DEBUG
const char* __EXIVersion = "<< RVL_SDK - EXI \tdebug build: "BUILD_DATE" "BUILD_TIME" (0x4302_145) >>";
#else
const char* __EXIVersion = "<< RVL_SDK - EXI \trelease build: "BUILD_DATE" "BUILD_TIME" (0x4302_145) >>";
#endif
#elif SDK_SEP2006
const char* __EXIVersion = "<< RVL_SDK - EXI \trelease build: "BUILD_DATE" "BUILD_TIME" (0x4200_60422) >>";
#endif
static EXIControl Ecb[3];
static u32 IDSerialPort1;
// external functions
extern void __OSEnableBarnacle(s32 chan, u32 dev);
// prototypes
u32 EXIClearInterrupts(s32 chan, int exi, int tc, int ext);
static int __EXIProbe(s32 chan);
static void SetExiInterruptMask(s32 chan, EXIControl* exi) {
EXIControl* exi2;
exi2 = &Ecb[2];
switch (chan) {
case 0:
if ((exi->exiCallback == 0 && exi2->exiCallback == 0) || (exi->state & STATE_LOCKED)) {
__OSMaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXI | OS_INTERRUPTMASK_EXI_2_EXI);
} else {
__OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXI | OS_INTERRUPTMASK_EXI_2_EXI);
}
break;
case 1:
if (exi->exiCallback == 0 || (exi->state & STATE_LOCKED)) {
__OSMaskInterrupts(OS_INTERRUPTMASK_EXI_1_EXI);
} else {
__OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_1_EXI);
}
break;
case 2:
if (__OSGetInterruptHandler(__OS_INTERRUPT_PI_DEBUG) == 0 || (exi->state & STATE_LOCKED)) {
__OSMaskInterrupts(OS_INTERRUPTMASK_PI_DEBUG);
} else {
__OSUnmaskInterrupts(OS_INTERRUPTMASK_PI_DEBUG);
}
break;
}
}
static void CompleteTransfer(s32 chan) {
EXIControl* exi;
u8* buf;
u32 data;
int i;
int len;
exi = &Ecb[chan];
ASSERTLINE(395, 0 <= chan && chan < MAX_CHAN);
if (exi->state & STATE_BUSY) {
if (exi->state & STATE_IMM) {
if (exi->immLen != 0) {
len = exi->immLen;
buf = exi->immBuf;
data = __EXIRegs[(chan * 5) + 4];
for(i = 0; i < len; i++) {
*buf++ = data >> ((3 - i) * 8);
}
}
}
exi->state &= ~STATE_BUSY;
}
}
int EXIImm(s32 chan, void* buf, s32 len, u32 type, EXICallback callback) {
EXIControl* exi;
BOOL enabled;
exi = &Ecb[chan];
ASSERTLINE(434, exi->state & STATE_SELECTED);
ASSERTLINE(435, 0 <= chan && chan < MAX_CHAN);
ASSERTLINE(436, 0 < len && len <= MAX_IMM);
ASSERTLINE(437, type < MAX_TYPE);
enabled = OSDisableInterrupts();
if ((exi->state & STATE_BUSY) || !(exi->state & STATE_SELECTED)) {
OSRestoreInterrupts(enabled);
return 0;
}
exi->tcCallback = callback;
if (exi->tcCallback) {
EXIClearInterrupts(chan, 0, 1, 0);
__OSUnmaskInterrupts(0x200000U >> (chan * 3));
}
exi->state |= STATE_IMM;
if (type != 0) {
u32 data;
int i;
data = 0;
for(i = 0; i < len; i++) {
data |= ((u8*)buf)[i] << ((3 - i) * 8);
}
__EXIRegs[(chan * 5) + 4] = data;
}
exi->immBuf = buf;
exi->immLen = (type != 1) ? len : 0;
__EXIRegs[(chan * 5) + 3] = (type << 2) | 1 | ((len - 1) << 4);
OSRestoreInterrupts(enabled);
return 1;
}
int EXIImmEx(s32 chan, void* buf, s32 len, u32 mode) {
s32 xLen;
while (len) {
xLen = (len < 4) ? len : 4;
if (EXIImm(chan, buf, xLen, mode, 0) == 0) {
return 0;
}
if (EXISync(chan) == 0) {
return 0;
}
((u8*)buf) += xLen;
len -= xLen;
}
return 1;
}
int EXIDma(s32 chan, void* buf, s32 len, u32 type, EXICallback callback) {
EXIControl* exi;
BOOL enabled;
exi = &Ecb[chan];
ASSERTLINE(539, exi->state & STATE_SELECTED);
ASSERTLINE(540, OFFSET(buf, 32) == 0);
ASSERTLINE(541, 0 < len && OFFSET(len, 32) == 0);
ASSERTLINE(543, ((u32) len & ~EXI_0LENGTH_EXILENGTH_MASK) == 0);
ASSERTLINE(545, type == EXI_READ || type == EXI_WRITE);
enabled = OSDisableInterrupts();
if ((exi->state & STATE_BUSY) || !(exi->state & STATE_SELECTED)) {
OSRestoreInterrupts(enabled);
return 0;
}
exi->tcCallback = callback;
if ((u32)exi->tcCallback) {
EXIClearInterrupts(chan, 0, 1, 0);
__OSUnmaskInterrupts(0x200000U >> (chan * 3));
}
exi->state |= STATE_DMA;
__EXIRegs[(chan * 5) + 1] = (u32)buf & EXI_0LENGTH_EXILENGTH_MASK;
__EXIRegs[(chan * 5) + 2] = len;
__EXIRegs[(chan * 5) + 3] = (type * 4) | 3;
OSRestoreInterrupts(enabled);
return 1;
}
int EXISync(s32 chan) {
EXIControl* exi;
int rc;
BOOL enabled;
exi = &Ecb[chan];
rc = 0;
ASSERTLINE(595, 0 <= chan && chan < MAX_CHAN);
while ((exi->state & STATE_SELECTED)) {
if (!(__EXIRegs[(chan * 5) + 3] & 1)) {
enabled = OSDisableInterrupts();
if (exi->state & STATE_SELECTED) {
CompleteTransfer(chan);
if (__OSGetDIConfig() != 0xFF || (OSGetConsoleType() & 0xf0000000) == 0x20000000 || exi->immLen != 4 || (__EXIRegs[chan * 5] & 0x70) || (__EXIRegs[(chan * 5) + 4] != 0x01010000 && __EXIRegs[(chan * 5) + 4] != 0x05070000 && __EXIRegs[(chan * 5) + 4] != 0x04220001) || __OSDeviceCode == 0x8200) {
rc = 1;
}
}
OSRestoreInterrupts(enabled);
break;
}
}
ASSERTLINE(623, !(exi->state & STATE_BUSY));
return rc;
}
u32 EXIClearInterrupts(s32 chan, int exi, int tc, int ext) {
u32 cpr;
u32 prev;
ASSERTLINE(644, 0 <= chan && chan < MAX_CHAN);
cpr = prev = __EXIRegs[(chan * 5)];
prev &= 0x7F5;
if (exi != 0) {
prev |= 2;
}
if (tc != 0) {
prev |= 8;
}
if (ext != 0) {
prev |= 0x800;
}
__EXIRegs[(chan * 5)] = prev;
return cpr;
}
EXICallback EXISetExiCallback(s32 chan, EXICallback exiCallback) {
EXIControl* exi;
EXICallback prev;
BOOL enabled;
exi = &Ecb[chan];
ASSERTLINE(678, 0 <= chan && chan < MAX_CHAN);
enabled = OSDisableInterrupts();
prev = exi->exiCallback;
exi->exiCallback = exiCallback;
if (chan != 2) {
SetExiInterruptMask(chan, exi);
} else {
SetExiInterruptMask(0, &Ecb[0]);
}
OSRestoreInterrupts(enabled);
return prev;
}
void EXIProbeReset() {
__gUnknown800030C0[0] = __gUnknown800030C0[1] = 0;
Ecb[0].idTime = Ecb[1].idTime = 0;
__EXIProbe(0);
__EXIProbe(1);
}
static int __EXIProbe(s32 chan) {
EXIControl* exi;
BOOL enabled;
int rc;
u32 cpr;
s32 t;
exi = &Ecb[chan];
ASSERTLINE(733, 0 <= chan && chan < MAX_CHAN);
if (chan == 2) {
return 1;
}
rc = 1;
enabled = OSDisableInterrupts();
cpr = __EXIRegs[(chan * 5)];
if (!(exi->state & STATE_ATTACHED)) {
if (cpr & 0x800) {
EXIClearInterrupts(chan, 0, 0, 1);
__gUnknown800030C0[chan] = exi->idTime = 0;
}
if (cpr & 0x1000) {
t = ((s32)(OSTicksToMilliseconds(OSGetTime()) / 100) + 1);
if (__gUnknown800030C0[chan] == 0) {
__gUnknown800030C0[chan] = t;
}
if (t - (s32)__gUnknown800030C0[chan] < 3) {
rc = 0;
}
} else {
__gUnknown800030C0[chan] = exi->idTime = 0;
rc = 0;
}
} else if(!(cpr & 0x1000) || (cpr & 0x800)) {
__gUnknown800030C0[chan] = exi->idTime = 0;
rc = 0;
}
OSRestoreInterrupts(enabled);
return rc;
}
int EXIProbe(s32 chan) {
EXIControl* exi = &Ecb[chan];
int rc;
u32 id;
rc = __EXIProbe(chan);
if (rc && !exi->idTime) {
rc = EXIGetID(chan, 0, &id) ? 1 : 0;
}
return rc;
}
s32 EXIProbeEx(s32 chan) {
if (EXIProbe(chan)) {
return 1;
}
if (__gUnknown800030C0[chan]) {
return 0;
}
return -1;
}
static int __EXIAttach(s32 chan, EXICallback extCallback) {
EXIControl* exi;
BOOL enabled;
exi = &Ecb[chan];
ASSERTLINE(838, 0 <= chan && chan < 2);
enabled = OSDisableInterrupts();
if ((exi->state & STATE_ATTACHED) || !__EXIProbe(chan)) {
OSRestoreInterrupts(enabled);
return 0;
}
EXIClearInterrupts(chan, 1, 0, 0);
exi->extCallback = extCallback;
__OSUnmaskInterrupts(0x100000U >> (chan * 3));
exi->state |= STATE_ATTACHED;
OSRestoreInterrupts(enabled);
return 1;
}
int EXIAttach(s32 chan, EXICallback extCallback) {
EXIControl* exi;
BOOL enabled;
int rc;
exi = &Ecb[chan];
ASSERTLINE(864, 0 <= chan && chan < 2);
EXIProbe(chan);
enabled = OSDisableInterrupts();
if (exi->idTime == 0) {
OSRestoreInterrupts(enabled);
return 0;
}
rc = __EXIAttach(chan, extCallback);
OSRestoreInterrupts(enabled);
return rc;
}
int EXIDetach(s32 chan) {
EXIControl* exi;
BOOL enabled;
exi = &Ecb[chan];
ASSERTLINE(898, 0 <= chan && chan < 2);
enabled = OSDisableInterrupts();
if (!(exi->state & STATE_ATTACHED)) {
OSRestoreInterrupts(enabled);
return 1;
}
if ((exi->state & STATE_LOCKED) && (exi->dev == 0)) {
OSRestoreInterrupts(enabled);
return 0;
}
exi->state &= ~STATE_ATTACHED;
__OSMaskInterrupts(0x500000U >> (chan * 3));
OSRestoreInterrupts(enabled);
return 1;
}
int EXISelectSD(s32 chan, u32 dev, u32 freq) {
EXIControl* exi;
u32 cpr;
BOOL enabled;
exi = &Ecb[chan];
ASSERTLINE(908, 0 <= chan && chan < MAX_CHAN);
ASSERTLINE(909, chan == 0 && dev < MAX_DEV || dev == 0);
ASSERTLINE(910, freq < MAX_FREQ);
ASSERTLINE(911, !(exi->state & STATE_SELECTED));
enabled = OSDisableInterrupts();
if ((exi->state & STATE_SELECTED) || ((chan != 2) && (((dev == 0) && !(exi->state & STATE_ATTACHED) && (EXIProbe(chan) == 0)) || !(exi->state & STATE_LOCKED) || (exi->dev != dev)))) {
OSRestoreInterrupts(enabled);
return 0;
}
exi->state |= STATE_SELECTED;
cpr = __EXIRegs[(chan * 5)];
cpr &= 0x405;
cpr |= freq * 0x10;
__EXIRegs[(chan * 5)] = cpr;
if (exi->state & STATE_ATTACHED) {
switch (chan) {
case 0:
__OSMaskInterrupts(0x100000U);
break;
case 1:
__OSMaskInterrupts(0x20000U);
break;
}
}
OSRestoreInterrupts(enabled);
return 1;
}
int EXISelect(s32 chan, u32 dev, u32 freq) {
EXIControl* exi;
u32 cpr;
BOOL enabled;
exi = &Ecb[chan];
ASSERTLINE(996, 0 <= chan && chan < MAX_CHAN);
ASSERTLINE(997, chan == 0 && dev < MAX_DEV || dev == 0);
ASSERTLINE(998, freq < MAX_FREQ);
ASSERTLINE(999, !(exi->state & STATE_SELECTED));
enabled = OSDisableInterrupts();
if ((exi->state & STATE_SELECTED) || ((chan != 2) && (((dev == 0) && !(exi->state & STATE_ATTACHED) && (__EXIProbe(chan) == 0)) || !(exi->state & STATE_LOCKED) || (exi->dev != dev)))) {
OSRestoreInterrupts(enabled);
return 0;
}
exi->state |= STATE_SELECTED;
cpr = __EXIRegs[(chan * 5)];
cpr &= 0x405;
cpr |= (((1 << dev) << 7) | (freq * 0x10));
__EXIRegs[(chan * 5)] = cpr;
if (exi->state & STATE_ATTACHED) {
switch (chan) {
case 0:
__OSMaskInterrupts(0x100000U);
break;
case 1:
__OSMaskInterrupts(0x20000U);
break;
}
}
OSRestoreInterrupts(enabled);
return 1;
}
int EXIDeselect(s32 chan) {
EXIControl* exi;
u32 cpr;
BOOL enabled;
exi = &Ecb[chan];
ASSERTLINE(1077, 0 <= chan && chan < MAX_CHAN);
enabled = OSDisableInterrupts();
if (!(exi->state & STATE_SELECTED)) {
OSRestoreInterrupts(enabled);
return 0;
}
exi->state &= ~STATE_SELECTED;
cpr = __EXIRegs[(chan * 5)];
__EXIRegs[(chan * 5)] = cpr & 0x405;
if (exi->state & STATE_ATTACHED) {
switch (chan) {
case 0:
__OSUnmaskInterrupts(0x100000U);
break;
case 1:
__OSUnmaskInterrupts(0x20000U);
break;
}
}
OSRestoreInterrupts(enabled);
if ((chan != 2) && (cpr & 0x80)) {
return __EXIProbe(chan) ? TRUE : FALSE;
}
return 1;
}
static void EXIIntrruptHandler(__OSInterrupt interrupt, OSContext* context) {
s32 chan;
EXIControl* exi;
EXICallback callback;
chan = (interrupt - 9) / 3;
ASSERTLINE(1150, 0 <= chan && chan < MAX_CHAN);
exi = &Ecb[chan];
EXIClearInterrupts(chan, 1, 0, 0);
callback = exi->exiCallback;
if (callback) {
OSContext exceptionContext;
OSClearContext(&exceptionContext);
OSSetCurrentContext(&exceptionContext);
callback(chan, context);
OSClearContext(&exceptionContext);
OSSetCurrentContext(context);
}
}
static void TCIntrruptHandler(__OSInterrupt interrupt, OSContext* context) {
s32 chan;
EXIControl* exi;
EXICallback callback;
chan = (interrupt - 10) / 3;
ASSERTLINE(1186, 0 <= chan && chan < MAX_CHAN);
exi = &Ecb[chan];
__OSMaskInterrupts(0x80000000U >> interrupt);
EXIClearInterrupts(chan, 0, 1, 0);
callback = exi->tcCallback;
if (callback) {
OSContext exceptionContext;
exi->tcCallback = NULL;
CompleteTransfer(chan);
OSClearContext(&exceptionContext);
OSSetCurrentContext(&exceptionContext);
callback(chan, context);
OSClearContext(&exceptionContext);
OSSetCurrentContext(context);
}
}
static void EXTIntrruptHandler(__OSInterrupt interrupt, OSContext* context) {
s32 chan;
EXIControl* exi;
EXICallback callback;
chan = (interrupt - 11) / 3;
ASSERTLINE(1226, 0 <= chan && chan < 2);
__OSMaskInterrupts(0x500000U >> (chan * 3));
exi = &Ecb[chan];
callback = exi->extCallback;
exi->state &= ~STATE_ATTACHED;
if (callback) {
OSContext exceptionContext;
OSClearContext(&exceptionContext);
OSSetCurrentContext(&exceptionContext);
exi->extCallback = NULL;
callback(chan, context);
OSClearContext(&exceptionContext);
OSSetCurrentContext(context);
}
}
void EXIInit() {
u32 id;
while (((REG(0, 3) & 1) == 1) || ((REG(1, 3) & 1) == 1) || ((REG(2, 3) & 1) == 1)) {}
__OSMaskInterrupts(0x7F8000U);
__EXIRegs[0] = 0;
__EXIRegs[5] = 0;
__EXIRegs[10] = 0;
__EXIRegs[0] = 0x2000;
__OSSetInterruptHandler(9, EXIIntrruptHandler);
__OSSetInterruptHandler(10, TCIntrruptHandler);
__OSSetInterruptHandler(11, EXTIntrruptHandler);
__OSSetInterruptHandler(12, EXIIntrruptHandler);
__OSSetInterruptHandler(13, TCIntrruptHandler);
__OSSetInterruptHandler(14, EXTIntrruptHandler);
__OSSetInterruptHandler(15, EXIIntrruptHandler);
__OSSetInterruptHandler(16, TCIntrruptHandler);
EXIGetID(0, 2, &IDSerialPort1);
if (__OSInIPL) {
EXIProbeReset();
} else if (EXIGetID(0, 0, &id) && id == 0x7010000) {
__OSEnableBarnacle(1, 0);
} else if (EXIGetID(1, 0, &id) && id == 0x7010000) {
__OSEnableBarnacle(0, 2);
}
OSRegisterVersion(__EXIVersion);
}
int EXILock(s32 chan, u32 dev, EXICallback unlockedCallback) {
EXIControl* exi;
BOOL enabled;
int i;
exi = &Ecb[chan];
ASSERTLINE(1338, 0 <= chan && chan < MAX_CHAN);
ASSERTLINE(1339, chan == 0 && dev < MAX_DEV || dev == 0);
enabled = OSDisableInterrupts();
if (exi->state & STATE_LOCKED) {
if (unlockedCallback) {
ASSERTLINE(1345, chan == 0 && exi->items < (MAX_DEV - 1) || exi->items == 0);
for(i = 0; i < exi->items; i++) {
if (exi->queue[i].dev == dev) {
OSRestoreInterrupts(enabled);
return 0;
}
}
exi->queue[exi->items].callback = unlockedCallback;
exi->queue[exi->items].dev = dev;
exi->items++;
}
OSRestoreInterrupts(enabled);
return 0;
}
ASSERTLINE(1361, exi->items == 0);
exi->state |= STATE_LOCKED;
exi->dev = dev;
SetExiInterruptMask(chan, exi);
OSRestoreInterrupts(enabled);
return 1;
}
int EXIUnlock(s32 chan) {
EXIControl* exi;
BOOL enabled;
EXICallback unlockedCallback;
exi = &Ecb[chan];
ASSERTLINE(1385, 0 <= chan && chan < MAX_CHAN);
enabled = OSDisableInterrupts();
if (!(exi->state & STATE_LOCKED)) {
OSRestoreInterrupts(enabled);
return 0;
}
exi->state &= ~STATE_LOCKED;
SetExiInterruptMask(chan, exi);
if (exi->items > 0) {
unlockedCallback = exi->queue[0].callback;
if (--exi->items > 0) {
memmove(&exi->queue[0], &exi->queue[1], exi->items * 8);
}
unlockedCallback(chan, 0);
}
OSRestoreInterrupts(enabled);
return 1;
}
u32 EXIGetState(s32 chan) {
EXIControl* exi;
exi = &Ecb[chan];
ASSERTLINE(1343, 0 <= chan && chan < MAX_CHAN);
return exi->state;
}
static void UnlockedHandler(s32 chan, OSContext* context) {
u32 id;
EXIGetID(chan, 0, &id);
}
s32 EXIGetID(s32 chan, u32 dev, u32* id) {
EXIControl* exi = &Ecb[chan];
int err;
u32 cmd;
s32 startTime;
BOOL enabled;
ASSERTLINE(1459, 0 <= chan && chan < MAX_CHAN);
if (chan == 0 && dev == 2 && IDSerialPort1 != 0) {
*id = IDSerialPort1;
return 1;
}
if ((chan < 2) && (dev == 0)) {
if ((__EXIProbe(chan) == 0)) {
return 0;
}
if (exi->idTime == __gUnknown800030C0[chan]) {
*id = exi->id;
return exi->idTime;
}
if (!__EXIAttach(chan, NULL)) {
return 0;
}
startTime = __gUnknown800030C0[chan];
}
enabled = OSDisableInterrupts();
err = !EXILock(chan, dev, (chan < 2 && dev == 0) ? &UnlockedHandler : NULL);
if (err == 0) {
err = !EXISelect(chan, dev, 0);
if (err == 0) {
cmd = 0;
err |= !EXIImm(chan, &cmd, 2, 1, 0);
err |= !EXISync(chan);
err |= !EXIImm(chan, id, 4, 0, 0);
err |= !EXISync(chan);
err |= !EXIDeselect(chan);
}
EXIUnlock(chan);
}
OSRestoreInterrupts(enabled);
if ((chan < 2) && (dev == 0)) {
EXIDetach(chan);
enabled = OSDisableInterrupts();
err |= __gUnknown800030C0[chan] != startTime;
if (!err) {
exi->id = *id;
exi->idTime = startTime;
}
OSRestoreInterrupts(enabled);
return err ? 0 : exi->idTime;
}
return err ? 0 : 1;
}
s32 EXIGetType(s32 chan, u32 dev, u32* type) {
u32 _type;
s32 probe;
probe = EXIGetID(chan, dev, &_type);
if (!probe) {
return probe;
}
switch (_type & ~0xFF) {
case 0x04020300:
case EXI_ETHER:
case 0x04020100:
case EXI_MIC:
*type = (_type & ~0xFF);
return probe;
default:
switch (_type & ~0xFFFF) {
case 0x00000000:
if (!(_type & 0x3803)) {
switch (_type & 0xFC) {
case EXI_MEMORY_CARD_59:
case EXI_MEMORY_CARD_123:
case EXI_MEMORY_CARD_251:
case EXI_MEMORY_CARD_507:
case EXI_MEMORY_CARD_1019:
case EXI_MEMORY_CARD_2043:
*type = _type & 0xFC;
return probe;
}
}
break;
case EXI_IS_VIEWER:
*type = EXI_IS_VIEWER;
return probe;
}
*type = _type;
return probe;
}
}
char* EXIGetTypeString(u32 type) {
switch (type) {
case EXI_MEMORY_CARD_59:
return "Memory Card 59";
case EXI_MEMORY_CARD_123:
return "Memory Card 123";
case EXI_MEMORY_CARD_251:
return "Memory Card 251";
case EXI_MEMORY_CARD_507:
return "Memory Card 507";
case EXI_MEMORY_CARD_1019:
return "Memory Card 1019";
case EXI_MEMORY_CARD_2043:
return "Memory Card 2043";
case EXI_USB_ADAPTER:
return "USB Adapter";
case EXI_NPDP_GDEV:
return "GDEV";
case EXI_MODEM:
return "Modem";
case EXI_MARLIN:
return "Marlin";
case EXI_AD16:
return "AD16";
case EXI_RS232C:
return "RS232C";
case 0x80000020:
case 0x80000080:
case 0x80000040:
case 0x80000008:
case 0x80000010:
case 0x80000004:
return "Net Card";
case EXI_ETHER_VIEWER:
return "Artist Ether";
case 0x4020100:
case 0x4020300:
case EXI_ETHER:
case 0x4220000:
return "Broadband Adapter";
case EXI_MIC:
return "Mic";
case EXI_STREAM_HANGER:
return "Stream Hanger";
case EXI_IS_VIEWER:
return "IS-DOL-VIEWER";
default:
return "Unknown";
}
}

View File

@ -0,0 +1,113 @@
#include <revolution/types.h>
#include <revolution/os.h>
#include <revolution/exi.h>
const u32 __EXIFreq = 4;
s32 EXIGetConsoleType(void) {
return 1;
}
void EXIWait(void) {
while (__OSDeviceCode == 0) {}
}
static u32 __EXISwap32(u32 val) {
return val >> 24 & 0x000000FF | val >> 8 & 0x0000FF00 | val << 8 & 0x00FF0000 | val << 24 & 0xFF000000;
}
BOOL EXIWriteReg(s32 chan, u32 dev, u32 exiCmd, void* reg, s32 size) {
BOOL ret = FALSE;
u32 reg32;
switch (size) {
case 1:
reg32 = (u32)((*((u8*)reg) & 0xFF) << 24);
break;
case 2:
reg32 = (u32)(((*((u16*)reg) & 0xFF) << 24) | ((*((u16*)reg) & 0xFF00) << 8));
break;
default:
reg32 = __EXISwap32(*((u32*)reg));
break;
}
ret |= !EXILock(chan, dev, 0);
if (ret) {
return FALSE;
}
ret |= !EXISelect(chan, dev, 4);
if (ret) {
EXIUnlock(chan);
return FALSE;
}
ret |= !EXIImm(chan, &exiCmd, 4, 1, NULL);
ret |= !EXISync(chan);
ret |= !EXIImm(chan, &reg32, 4, 1, NULL);
ret |= !EXISync(chan);
ret |= !EXIDeselect(chan);
ret |= !EXIUnlock(chan);
return !ret;
}
BOOL EXIReadRam(s32 chan, u32 dev, u32 exiCmd, void* buffer, s32 size, EXICallback callback) {
BOOL ret = FALSE;
ret |= !EXILock(chan, dev, NULL);
if (ret) {
return FALSE;
}
ret |= !EXISelect(chan, dev, 4);
if (ret) {
EXIUnlock(chan);
return FALSE;
}
ret |= !EXIImm(chan, &exiCmd, 4, 1, NULL);
ret |= !EXISync(chan);
ret |= !EXIDma(chan, buffer, size, EXI_READ, callback);
if (callback == NULL) {
ret |= !EXISync(chan);
ret |= !EXIDeselect(chan);
ret |= !EXIUnlock(chan);
}
return !ret;
}
BOOL EXIWriteRam(s32 chan, u32 dev, u32 exiCmd, void* buffer, s32 size, EXICallback callback) {
BOOL ret = FALSE;
ret |= !EXILock(chan, dev, NULL);
if (ret) {
return FALSE;
}
ret |= !EXISelect(chan, dev, 4);
if (ret) {
EXIUnlock(chan);
return FALSE;
}
ret |= !EXIImm(chan, &exiCmd, 4, 1, NULL);
ret |= !EXISync(chan);
ret |= !EXIDma(chan, buffer, size, EXI_WRITE, callback);
if (callback == NULL) {
ret |= !EXISync(chan);
ret |= !EXIDeselect(chan);
ret |= !EXIUnlock(chan);
}
return !ret;
}

View File

@ -0,0 +1,190 @@
#include <revolution/exi.h>
#include <revolution/os.h>
#include "__os.h"
static s32 Chan;
static u32 Dev;
static u32 BarnacleEnabled;
static u32 Enabled;
// prototypes
int InitializeUART(void);
int ReadUARTN(void);
int WriteUARTN(void *buf, u32 len);
void __OSEnableBarnacle(s32 chan, u32 dev);
static BOOL ProbeBarnacle(s32 chan, u32 dev, u32* revision) {
int err;
u32 cmd;
if (chan != 2 && dev == 0 && !EXIAttach(chan, NULL)) {
return FALSE;
}
err = !EXILock(chan, dev, NULL);
if (!err) {
err = !EXISelect(chan, dev, EXI_FREQ_1M);
if (!err) {
cmd = 0x20011300;
err = FALSE;
err |= !EXIImm(chan, &cmd, sizeof(cmd), EXI_WRITE, NULL);
err |= !EXISync(chan);
err |= !EXIImm(chan, revision, sizeof(revision), EXI_READ, NULL);
err |= !EXISync(chan);
err |= !EXIDeselect(chan);
}
EXIUnlock(chan);
}
if (chan != 2 && dev == 0) {
EXIDetach(chan);
}
if (err) {
return FALSE;
}
return (*revision != 0xFFFFFFFF) ? TRUE : FALSE;
}
void __OSEnableBarnacle(s32 chan, u32 dev) {
u32 id;
if (!EXIGetID(chan, dev, &id)) {
return;
}
switch (id) {
case EXI_MEMORY_CARD_59:
case EXI_MEMORY_CARD_123:
case EXI_MEMORY_CARD_251:
case EXI_MEMORY_CARD_507:
case EXI_USB_ADAPTER:
case EXI_NPDP_GDEV:
case EXI_MODEM:
case 0x03010000:
case 0x04020100:
case EXI_ETHER:
case 0x04020300:
case 0x04220000:
case EXI_RS232C:
case EXI_MIC:
case EXI_AD16:
case EXI_STREAM_HANGER:
case 0x80000004:
case 0x80000008:
case 0x80000010:
case 0x80000020:
case 0xFFFFFFFF:
break;
default:
if (ProbeBarnacle(chan, dev, &id)) {
Chan = chan;
Dev = dev;
Enabled = BarnacleEnabled = 0xA5FF005A;
break;
}
}
}
int InitializeUART(void) {
if (BarnacleEnabled == 0xA5FF005A) {
return 0;
}
if ((OSGetConsoleType() & 0x10000000) == 0) {
Enabled = 0;
return 2;
}
Chan = 0;
Dev = 1;
Enabled = 0xA5FF005A;
return 0;
}
int ReadUARTN(void) {
return 4;
}
static int QueueLength(void) {
u32 cmd;
if (EXISelect(Chan, Dev, 3) == 0) {
return -1;
}
cmd = 0x20010000;
EXIImm(Chan, &cmd, sizeof(cmd), EXI_WRITE, 0);
EXISync(Chan);
EXIImm(Chan, &cmd, 1, EXI_READ, 0);
EXISync(Chan);
EXIDeselect(Chan);
return 0x10 - (cmd >> 0x18);
}
int WriteUARTN(void *buf, u32 len) {
u32 cmd;
s32 xLen;
int qLen;
char* ptr;
int locked;
int error;
if ((Enabled - 0xA5FF0000) != 0x5A) {
return 2;
}
locked = EXILock(Chan, Dev, 0);
if (locked == 0) {
return 0;
} else {
ptr = (char*)buf;
}
while ((u32)ptr - (u32)buf < len) {
if (*(s8*)ptr == 0xA) {
*ptr = 0xD;
}
ptr++;
}
error = 0;
cmd = 0xA0010000;
while (len != 0) {
qLen = QueueLength();
if (qLen < 0) {
error = 3;
break;
}
if ((qLen >= 0xC) || (qLen >= len)) {
if (EXISelect(Chan, Dev, EXI_FREQ_8M) == 0) {
error = 3;
break;
}
EXIImm(Chan, &cmd, sizeof(cmd), EXI_WRITE, 0);
EXISync(Chan);
while((qLen != 0) && (len != 0)) {
if ((qLen < 4) && (qLen < len)) {
break;
}
xLen = len < 4 ? (long)len : 4;
EXIImm(Chan, buf, xLen, EXI_WRITE, 0);
(char*)buf += xLen;
len -= xLen;
qLen -= xLen;
EXISync(Chan);
}
EXIDeselect(Chan);
}
}
EXIUnlock(Chan);
return error;
}

View File

@ -0,0 +1,45 @@
#include <revolution/gd.h>
#include <revolution/os.h>
GDLObj* __GDCurrentDL = NULL;
static GDOverflowCb overflowcb = NULL;
void GDInitGDLObj(GDLObj* dl, void* start, u32 length) {
ASSERTMSGLINE(49, !((u32)start & 0x1F), "start must be aligned to 32 bytes");
ASSERTMSGLINE(50, !((u32)length & 0x1F), "length must be aligned to 32 bytes");
dl->start = start;
dl->ptr = start;
dl->top = (u8*)start + length;
dl->length = length;
}
void GDFlushCurrToMem(void) {
DCFlushRange(__GDCurrentDL->start, __GDCurrentDL->length);
}
void GDPadCurr32(void) {
u32 n;
n = (u32)__GDCurrentDL->ptr & 0x1F;
if (n != 0) {
for (; n < 32; n = n + 1) {
__GDWrite(0);
}
}
}
void GDOverflowed(void) {
if (overflowcb) {
(*overflowcb)();
} else {
ASSERTMSGLINE(86, 0, "GDWrite: display list overflowed");
}
}
void GDSetOverflowCallback(GDOverflowCb callback) {
overflowcb = callback;
}
GDOverflowCb GDGetOverflowCallback(void) {
return overflowcb;
}

View File

@ -0,0 +1,64 @@
#include <revolution/gd.h>
#include <revolution/os.h>
#define ROUND(n, a) (((u32)(n) + (a)-1) & ~((a)-1))
s32 GDReadDLFile(const char* fName, u32* numDLs, u32* numPLs, GDGList** DLDescArray, GDGList** PLDescArray) {
DVDFileInfo finfo;
u32 length;
u32 i;
u8* buf;
GDFileHeader* hdr;
*numDLs = *numPLs = 0;
*DLDescArray = *PLDescArray = NULL;
if (!DVDOpen(fName, &finfo)) {
OSReport("Can't open file %s\n", fName);
return -3;
}
length = finfo.length;
if (NULL == (buf = OSAlloc(ROUND(length, 0x20)))) {
OSReport("Alloc failed\n");
DVDClose(&finfo);
return -5;
}
if (DVDReadPrio(&finfo, buf, ROUND(length, 0x20), 0, 2) != ROUND(length, 0x20)) {
OSReport("Error occurred when reading %s\n", fName);
DVDClose(&finfo);
OSFree(buf);
return -2;
}
DVDClose(&finfo);
hdr = (GDFileHeader*)buf;
if (hdr->versionNumber != GD_FILE_VERSION_NUMBER) {
OSReport("Bad version number for GDL file %s\n", fName);
OSFree(buf);
return -4;
}
*numDLs = hdr->numDLs;
*numPLs = hdr->numPLs;
// Loaded pointers are relative to disc start, remap
// them to be relative to RAM start
*DLDescArray = (GDGList*)((u32)hdr->DLDescArray + (u32)hdr);
*PLDescArray = (GDGList*)((u32)hdr->PLDescArray + (u32)hdr);
// And internal pointers too
for (i = 0; i < *numDLs; ++i) {
(*DLDescArray)[i].ptr = (void*)((u32)hdr + (u32)(*DLDescArray)[i].ptr);
}
for (i = 0; i < *numPLs; ++i) {
(*PLDescArray)[i].ptr = (void*)((u32)hdr + (u32)(*PLDescArray)[i].ptr);
}
return 0;
}

View File

@ -0,0 +1,418 @@
#include <revolution/gd.h>
#include <revolution/os.h>
void GDSetVtxDescv(const GXVtxDescList* attrPtr) {
u32 nnorms = 0;
u32 ncols = 0;
u32 ntexs = 0;
u32 pnMtxIdx = GX_NONE;
u32 txMtxIdxMask = 0;
u32 posn = GX_DIRECT;
u32 norm = GX_NONE;
u32 col0 = GX_NONE;
u32 col1 = GX_NONE;
u32 tex0 = GX_NONE;
u32 tex1 = GX_NONE;
u32 tex2 = GX_NONE;
u32 tex3 = GX_NONE;
u32 tex4 = GX_NONE;
u32 tex5 = GX_NONE;
u32 tex6 = GX_NONE;
u32 tex7 = GX_NONE;
for (; attrPtr->attr != GX_VA_NULL; ++attrPtr) {
ASSERTMSGLINE(103, attrPtr->attr >= GX_VA_PNMTXIDX && attrPtr->attr <= GX_VA_MAX_ATTR, "GDSetVtxDescv: invalid attribute");
ASSERTMSGLINE(107, attrPtr->type >= GX_NONE && attrPtr->type <= GX_INDEX16, "GDSetVtxDescv: invalid type");
ASSERTMSGLINE(113, attrPtr->attr >= GX_VA_PNMTXIDX && attrPtr->attr <= GX_VA_TEX7MTXIDX ? (attrPtr->type == 0 || attrPtr->type == 1) : TRUE, "GDSetVtxDescv: invalid type for given attribute");
switch (attrPtr->attr) {
case GX_VA_PNMTXIDX:
pnMtxIdx = attrPtr->type;
break;
case GX_VA_TEX0MTXIDX:
txMtxIdxMask = (txMtxIdxMask & ~0x1) | (attrPtr->type << 0);
break;
case GX_VA_TEX1MTXIDX:
txMtxIdxMask = (txMtxIdxMask & ~0x2) | (attrPtr->type << 1);
break;
case GX_VA_TEX2MTXIDX:
txMtxIdxMask = (txMtxIdxMask & ~0x4) | (attrPtr->type << 2);
break;
case GX_VA_TEX3MTXIDX:
txMtxIdxMask = (txMtxIdxMask & ~0x8) | (attrPtr->type << 3);
break;
case GX_VA_TEX4MTXIDX:
txMtxIdxMask = (txMtxIdxMask & ~0x10) | (attrPtr->type << 4);
break;
case GX_VA_TEX5MTXIDX:
txMtxIdxMask = (txMtxIdxMask & ~0x20) | (attrPtr->type << 5);
break;
case GX_VA_TEX6MTXIDX:
txMtxIdxMask = (txMtxIdxMask & ~0x40) | (attrPtr->type << 6);
break;
case GX_VA_TEX7MTXIDX:
txMtxIdxMask = (txMtxIdxMask & ~0x80) | (attrPtr->type << 7);
break;
case GX_VA_POS:
posn = attrPtr->type;
break;
case GX_VA_NRM:
if (attrPtr->type != GX_NONE) {
norm = attrPtr->type;
nnorms = 1;
}
break;
case GX_VA_NBT:
if (attrPtr->type != GX_NONE) {
norm = attrPtr->type;
nnorms = 2;
}
break;
case GX_VA_CLR0:
col0 = attrPtr->type;
ncols += (col0 != GX_NONE);
break;
case GX_VA_CLR1:
col1 = attrPtr->type;
ncols += (col1 != GX_NONE);
break;
case GX_VA_TEX0:
tex0 = attrPtr->type;
ntexs += (tex0 != GX_NONE);
break;
case GX_VA_TEX1:
tex1 = attrPtr->type;
ntexs += (tex1 != GX_NONE);
break;
case GX_VA_TEX2:
tex2 = attrPtr->type;
ntexs += (tex2 != GX_NONE);
break;
case GX_VA_TEX3:
tex3 = attrPtr->type;
ntexs += (tex3 != GX_NONE);
break;
case GX_VA_TEX4:
tex4 = attrPtr->type;
ntexs += (tex4 != GX_NONE);
break;
case GX_VA_TEX5:
tex5 = attrPtr->type;
ntexs += (tex5 != GX_NONE);
break;
case GX_VA_TEX6:
tex6 = attrPtr->type;
ntexs += (tex6 != GX_NONE);
break;
case GX_VA_TEX7:
tex7 = attrPtr->type;
ntexs += (tex7 != GX_NONE);
break;
}
}
GDWriteCPCmd(CP_REG_VCD_LO_ID, CP_REG_VCD_LO(pnMtxIdx, txMtxIdxMask, posn, norm, col0, col1));
GDWriteCPCmd(CP_REG_VCD_HI_ID, CP_REG_VCD_HI(tex0, tex1, tex2, tex3, tex4, tex5, tex6, tex7));
GDWriteXFCmd(XF_REG_INVERTEXSPEC_ID, XF_REG_INVTXSPEC(ncols, nnorms, ntexs));
}
void GDSetVtxAttrFmtv(GXVtxFmt vtxfmt, const GXVtxAttrFmtList* list) {
u32 posCnt = GX_POS_XYZ;
u32 posType = GX_F32;
u32 posFrac = 0;
u32 nrmCnt = GX_NRM_XYZ;
u32 nrmType = GX_F32;
u32 nrmIdx3 = 0;
u32 c0Cnt = GX_CLR_RGBA;
u32 c0Type = GX_RGBA8;
u32 c1Cnt = GX_CLR_RGBA;
u32 c1Type = GX_RGBA8;
u32 tx0Cnt = GX_TEX_ST;
u32 tx0Type = GX_F32;
u32 tx0Frac = 0;
u32 tx1Cnt = GX_TEX_ST;
u32 tx1Type = GX_F32;
u32 tx1Frac = 0;
u32 tx2Cnt = GX_TEX_ST;
u32 tx2Type = GX_F32;
u32 tx2Frac = 0;
u32 tx3Cnt = GX_TEX_ST;
u32 tx3Type = GX_F32;
u32 tx3Frac = 0;
u32 tx4Cnt = GX_TEX_ST;
u32 tx4Type = GX_F32;
u32 tx4Frac = 0;
u32 tx5Cnt = GX_TEX_ST;
u32 tx5Type = GX_F32;
u32 tx5Frac = 0;
u32 tx6Cnt = GX_TEX_ST;
u32 tx6Type = GX_F32;
u32 tx6Frac = 0;
u32 tx7Cnt = GX_TEX_ST;
u32 tx7Type = GX_F32;
u32 tx7Frac = 0;
ASSERTMSGLINE(233, vtxfmt < GX_MAX_VTXFMT, "GDSetVtxAttrFmtv: invalid vtx fmt");
for (; list->attr != GX_VA_NULL; ++list) {
ASSERTMSGLINE(239, (list->attr >= GX_VA_POS && list->attr <= GX_VA_TEX7) || list->attr == GX_VA_NBT, "GDSetVtxAttrFmtv: invalid attribute");
ASSERTMSGLINE(240, list->frac < 32, "GDSetVtxAttrFmtv: invalid frac value");
switch (list->attr) {
case GX_VA_POS:
posCnt = list->cnt;
posType = list->type;
posFrac = list->frac;
break;
case GX_VA_NRM:
case GX_VA_NBT:
nrmType = list->type;
if (list->cnt == GX_NRM_NBT3) {
nrmCnt = GX_NRM_NBT;
nrmIdx3 = 1;
} else {
nrmCnt = list->cnt;
nrmIdx3 = 0;
}
break;
case GX_VA_CLR0:
c0Cnt = list->cnt;
c0Type = list->type;
break;
case GX_VA_CLR1:
c1Cnt = list->cnt;
c1Type = list->type;
break;
case GX_VA_TEX0:
tx0Cnt = list->cnt;
tx0Type = list->type;
tx0Frac = list->frac;
break;
case GX_VA_TEX1:
tx1Cnt = list->cnt;
tx1Type = list->type;
tx1Frac = list->frac;
break;
case GX_VA_TEX2:
tx2Cnt = list->cnt;
tx2Type = list->type;
tx2Frac = list->frac;
break;
case GX_VA_TEX3:
tx3Cnt = list->cnt;
tx3Type = list->type;
tx3Frac = list->frac;
break;
case GX_VA_TEX4:
tx4Cnt = list->cnt;
tx4Type = list->type;
tx4Frac = list->frac;
break;
case GX_VA_TEX5:
tx5Cnt = list->cnt;
tx5Type = list->type;
tx5Frac = list->frac;
break;
case GX_VA_TEX6:
tx6Cnt = list->cnt;
tx6Type = list->type;
tx6Frac = list->frac;
break;
case GX_VA_TEX7:
tx7Cnt = list->cnt;
tx7Type = list->type;
tx7Frac = list->frac;
}
}
GDWriteCPCmd(vtxfmt + CP_REG_VAT_GRP0_ID, CP_REG_VAT_GRP0(posCnt, posType, posFrac, nrmCnt, nrmType, c0Cnt, c0Type, c1Cnt, c1Type, tx0Cnt, tx0Type, tx0Frac, 1, nrmIdx3));
GDWriteCPCmd(vtxfmt + CP_REG_VAT_GRP1_ID, CP_REG_VAT_GRP1(tx1Cnt, tx1Type, tx1Frac, tx2Cnt, tx2Type, tx2Frac, tx3Cnt, tx3Type, tx3Frac, tx4Cnt, tx4Type, 1));
GDWriteCPCmd(vtxfmt + CP_REG_VAT_GRP2_ID, CP_REG_VAT_GRP2(tx4Frac, tx5Cnt, tx5Type, tx5Frac, tx6Cnt, tx6Type, tx6Frac, tx7Cnt, tx7Type, tx7Frac));
}
void GDSetArray(GXAttr attr, void* base_ptr, u8 stride) {
s32 cpAttr = attr == GX_VA_NBT ? GX_VA_TEX0MTXIDX : attr - GX_VA_POS;
GDWriteCPCmd(cpAttr + CP_REG_ARRAYBASE_ID, OSCachedToPhysical(base_ptr));
GDWriteCPCmd(cpAttr + CP_REG_ARRAYSTRIDE_ID, stride);
}
void GDSetArrayRaw(GXAttr attr, u32 base_ptr_raw, u8 stride) {
s32 cpAttr = attr == GX_VA_NBT ? GX_VA_TEX0MTXIDX : attr - GX_VA_POS;
GDWriteCPCmd(cpAttr + CP_REG_ARRAYBASE_ID, base_ptr_raw);
GDWriteCPCmd(cpAttr + CP_REG_ARRAYSTRIDE_ID, stride);
}
void GDPatchArrayPtr(void* base_ptr) {
GDWrite_u32(OSCachedToPhysical(base_ptr));
}
void GDSetTexCoordGen(GXTexCoordID dst_coord, GXTexGenType func, GXTexGenSrc src_param, u8 normalize, u32 postmtx) {
u32 form;
u32 tgType;
u32 proj;
u32 row;
u32 embossRow;
u32 embossLit;
form = 0;
proj = 0;
row = 5;
embossRow = 5;
embossLit = 0;
ASSERTMSGLINE(445, dst_coord < GX_MAX_TEXCOORD, "GDSetTexCoordGen: invalid texcoord ID");
switch(src_param) {
case GX_TG_POS:
row = 0;
form = 1;
break;
case GX_TG_NRM:
row = 1;
form = 1;
break;
case GX_TG_BINRM:
row = 3;
form = 1;
break;
case GX_TG_TANGENT:
row = 4;
form = 1;
break;
case GX_TG_COLOR0:
row = 2;
break;
case GX_TG_COLOR1:
row = 2;
break;
case GX_TG_TEX0:
row = 5;
break;
case GX_TG_TEX1:
row = 6;
break;
case GX_TG_TEX2:
row = 7;
break;
case GX_TG_TEX3:
row = 8;
break;
case GX_TG_TEX4:
row = 9;
break;
case GX_TG_TEX5:
row = 10;
break;
case GX_TG_TEX6:
row = 11;
break;
case GX_TG_TEX7:
row = 12;
break;
case GX_TG_TEXCOORD0:
embossRow = 0;
break;
case GX_TG_TEXCOORD1:
embossRow = 1;
break;
case GX_TG_TEXCOORD2:
embossRow = 2;
break;
case GX_TG_TEXCOORD3:
embossRow = 3;
break;
case GX_TG_TEXCOORD4:
embossRow = 4;
break;
case GX_TG_TEXCOORD5:
embossRow = 5;
break;
case GX_TG_TEXCOORD6:
embossRow = 6;
break;
default:
ASSERTMSGLINE(470, 0, "GDSetTexCoordGen: invalid texgen source");
break;
}
switch (func) {
case GX_TG_MTX2x4:
tgType = 0;
break;
case GX_TG_MTX3x4:
tgType = 0;
proj = 1;
break;
case GX_TG_BUMP0:
case GX_TG_BUMP1:
case GX_TG_BUMP2:
case GX_TG_BUMP3:
case GX_TG_BUMP4:
case GX_TG_BUMP5:
case GX_TG_BUMP6:
case GX_TG_BUMP7:
ASSERTMSGLINE(494, src_param >= GX_TG_TEXCOORD0 && src_param <= GX_TG_TEXCOORD6, "GDSetTexCoordGen: invalid emboss source");
tgType = 1;
embossLit = func - GX_TG_BUMP0;
break;
case GX_TG_SRTG:
if (src_param == GX_TG_COLOR0) {
tgType = 2;
} else {
tgType = 3;
}
break;
default:
ASSERTMSGLINE(508, 0, "GDSetTexCoordGen: invalid texgen function");
break;
}
GDWriteXFCmd(dst_coord + XF_REG_TEX0_ID, XF_REG_TEX(proj, form, tgType, row, embossRow, embossLit));
GDWriteXFCmd(dst_coord + XF_REG_DUALTEX0_ID, XF_REG_DUALTEX(postmtx - 0x40, normalize));
}
void GDSetCullMode(GXCullMode mode) {
static u8 cm2hw[4] = { 0, 2, 1, 3 };
GDWriteBPCmd(0xFE00C000);
GDWriteBPCmd(cm2hw[mode] << 14);
}
void GDSetGenMode(u8 nTexGens, u8 nChans, u8 nTevs) {
GDWriteBPCmd(0xFE003C3F);
GDWriteBPCmd(BP_GEN_MODE(nTexGens, nChans, nTevs - 1, 0, 0));
GDWriteXFCmd(XF_REG_NUMCOLORS_ID, nChans);
GDWriteXFCmd(XF_REG_NUMTEX_ID, nTexGens);
}
void GDSetGenMode2(u8 nTexGens, u8 nChans, u8 nTevs, u8 nInds, GXCullMode cm) {
static u8 cm2hw[4] = { 0, 2, 1, 3 };
GDWriteBPCmd(0xFE07FC3F);
GDWriteBPCmd(BP_GEN_MODE(nTexGens, nChans, nTevs - 1, cm2hw[cm], nInds));
GDWriteXFCmd(XF_REG_NUMCOLORS_ID, nChans);
GDWriteXFCmd(XF_REG_NUMTEX_ID, nTexGens);
}
void GDSetLPSize(u8 lineWidth, u8 pointSize, GXTexOffset lineOffset, GXTexOffset pointOffset, u8 lineHalfAspect) {
GDWriteBPCmd(BP_LP_SIZE(lineWidth, pointSize, lineOffset, pointOffset, lineHalfAspect, 0x22));
}
void GDSetCoPlanar(u8 enable) {
GDWriteBPCmd(0xFE080000);
GDWriteBPCmd(enable << 19);
}

View File

@ -0,0 +1,270 @@
#include <revolution/gd.h>
#include <revolution/os.h>
void GDSetTevIndirect(GXTevStageID tev_stage, GXIndTexStageID ind_stage,
GXIndTexFormat format, GXIndTexBiasSel bias_sel,
GXIndTexMtxID matrix_sel, GXIndTexWrap wrap_s,
GXIndTexWrap wrap_t, u8 add_prev, u8 utc_lod,
GXIndTexAlphaSel alpha_sel) {
GDWriteBPCmd(BP_TEV_INDIRECT(
ind_stage & 3,
format & 3,
bias_sel & 7,
alpha_sel & 3,
matrix_sel & 0xF,
wrap_s & 7,
wrap_t & 7,
utc_lod & 1,
add_prev & 1,
0x10 + (tev_stage & 0xF)
));
}
void GDSetIndTexMtx(GXIndTexMtxID mtx_id, const f32 offset[2][3], s8 scale_exp) {
u32 id_offset;
switch (mtx_id) {
case GX_ITM_0:
id_offset = 0;
break;
case GX_ITM_1:
id_offset = 3;
break;
case GX_ITM_2:
id_offset = 6;
break;
default:
ASSERTMSGLINE(111, 0, "GDSetIndTexMtx: Invalid matrix id");
break;
}
scale_exp += 17;
GDWriteBPCmd(BP_IND_MTX(
(s32)(offset[0][0] * 0x400) & 0x7FF,
(s32)(offset[1][0] * 0x400) & 0x7FF,
scale_exp & 3,
6 + id_offset
));
GDWriteBPCmd(BP_IND_MTX(
(s32)(offset[0][1] * 0x400) & 0x7FF,
(s32)(offset[1][1] * 0x400) & 0x7FF,
(scale_exp >> 2) & 3,
7 + id_offset
));
GDWriteBPCmd(BP_IND_MTX(
(s32)(offset[0][2] * 0x400) & 0x7FF,
(s32)(offset[1][2] * 0x400) & 0x7FF,
(scale_exp >> 4) & 3,
8 + id_offset
));
}
void GDSetIndTexCoordScale(GXIndTexStageID indStageEven, GXIndTexScale scaleS0,
GXIndTexScale scaleT0, GXIndTexScale scaleS1,
GXIndTexScale scaleT1) {
GDWriteBPCmd(BP_IND_TEXCOORD_SCALE(
scaleS0 & 0xF,
scaleT0 & 0xF,
scaleS1 & 0xF,
scaleT1 & 0xF,
0x25 + ((indStageEven >> 1) & 1)
));
}
void GDSetIndTexOrder(GXTexCoordID texCoord0, GXTexMapID texMap0,
GXTexCoordID texCoord1, GXTexMapID texMap1,
GXTexCoordID texCoord2, GXTexMapID texMap2,
GXTexCoordID texCoord3, GXTexMapID texMap3) {
GDWriteBPCmd(BP_IND_TEX_ORDER(
texMap0 & 7,
texCoord0 & 7,
texMap1 & 7,
texCoord1 & 7,
texMap2 & 7,
texCoord2 & 7,
texMap3 & 7,
texCoord3 & 7,
0x27
));
}
void GDSetTevDirect(GXTevStageID tev_stage) {
GDSetTevIndirect(tev_stage, GX_INDTEXSTAGE0, GX_ITF_8, GX_ITB_NONE, GX_ITM_OFF, GX_ITW_OFF, GX_ITW_OFF, 0, 0, GX_ITBA_OFF);
}
void GDSetTevIndWarp(GXTevStageID tev_stage, GXIndTexStageID ind_stage, u8 signed_offset, u8 replace_mode, GXIndTexMtxID matrix_sel) {
GXIndTexWrap wrap;
wrap = replace_mode ? GX_ITW_0 : GX_ITW_OFF;
GDSetTevIndirect(tev_stage,
ind_stage,
GX_ITF_8,
signed_offset ? GX_ITB_STU : GX_ITB_NONE,
matrix_sel,
wrap,
wrap,
0,
0,
GX_ITBA_OFF);
}
void GDSetTevIndTile(GXTevStageID tev_stage, GXIndTexStageID ind_stage,
u16 tilesize_s, u16 tilesize_t, u16 tilespacing_s,
u16 tilespacing_t, GXIndTexFormat format,
GXIndTexMtxID matrix_sel, GXIndTexBiasSel bias_sel,
GXIndTexAlphaSel alpha_sel) {
GXIndTexWrap wrap_s;
GXIndTexWrap wrap_t;
f32 mtx[2][3];
switch (tilesize_s) {
case 256:
wrap_s = GX_ITW_256;
break;
case 128:
wrap_s = GX_ITW_128;
break;
case 64:
wrap_s = GX_ITW_64;
break;
case 32:
wrap_s = GX_ITW_32;
break;
case 16:
wrap_s = GX_ITW_16;
break;
default:
ASSERTMSGLINE(268, 0, "GDSetTevIndTile: Invalid tilesize for S coordinate");
wrap_s = GX_ITW_OFF;
break;
}
switch (tilesize_t) {
case 256:
wrap_t = GX_ITW_256;
break;
case 128:
wrap_t = GX_ITW_128;
break;
case 64:
wrap_t = GX_ITW_64;
break;
case 32:
wrap_t = GX_ITW_32;
break;
case 16:
wrap_t = GX_ITW_16;
break;
default:
ASSERTMSGLINE(280, 0, "GDSetTevIndTile: Invalid tilesize for T coordinate");
wrap_t = GX_ITW_OFF;
break;
}
mtx[0][0] = (f32)tilespacing_s / 0x400;
mtx[0][1] = mtx[0][2] = 0.0f;
mtx[1][1] = (f32)tilespacing_t / 0x400;
mtx[1][0] = mtx[1][2] = 0.0f;
GDSetIndTexMtx(matrix_sel, mtx, 10);
GDSetTevIndirect(tev_stage,
ind_stage,
format,
bias_sel,
matrix_sel,
wrap_s,
wrap_t,
0,
1,
alpha_sel);
}
void GDSetTevIndBumpST(GXTevStageID tev_stage, GXIndTexStageID ind_stage, GXIndTexMtxID matrix_sel) {
GXIndTexMtxID sm;
GXIndTexMtxID tm;
switch(matrix_sel) {
case GX_ITM_0:
sm = GX_ITM_S0;
tm = GX_ITM_T0;
break;
case GX_ITM_1:
sm = GX_ITM_S1;
tm = GX_ITM_T1;
break;
case GX_ITM_2:
sm = GX_ITM_S2;
tm = GX_ITM_T2;
break;
default:
ASSERTMSGLINE(332, 0, "GDSetTevIndBumpST: Invalid matrix selection");
break;
}
GDSetTevIndirect(tev_stage,
ind_stage,
GX_ITF_8,
GX_ITB_ST,
sm,
GX_ITW_0,
GX_ITW_0,
0,
0,
GX_ITBA_OFF);
GDSetTevIndirect(tev_stage + 1,
ind_stage,
GX_ITF_8,
GX_ITB_ST,
tm,
GX_ITW_0,
GX_ITW_0,
1,
0,
GX_ITBA_OFF);
GDSetTevIndirect(tev_stage + 2,
ind_stage,
GX_ITF_8,
GX_ITB_NONE,
GX_ITM_OFF,
GX_ITW_OFF,
GX_ITW_OFF,
1,
0,
GX_ITBA_OFF);
}
void GDSetTevIndBumpXYZ(GXTevStageID tev_stage, GXIndTexStageID ind_stage, GXIndTexMtxID matrix_sel) {
GDSetTevIndirect(tev_stage,
ind_stage,
GX_ITF_8,
GX_ITB_STU,
matrix_sel,
GX_ITW_OFF,
GX_ITW_OFF,
0,
0,
GX_ITBA_OFF);
}
void GDSetTevIndRepeat(GXTevStageID tev_stage) {
GDSetTevIndirect(tev_stage,
GX_INDTEXSTAGE0,
GX_ITF_8,
GX_ITB_NONE,
GX_ITM_OFF,
GX_ITW_0,
GX_ITW_0,
1,
0,
GX_ITBA_OFF);
}
void __GDSetIndTexMask(u32 mask) {
GDWriteBPCmd(BP_IND_MASK(mask & 0xFF, 0xF));
}

206
src/revolution/gd/GDLight.c Normal file
View File

@ -0,0 +1,206 @@
#include <revolution/gd.h>
#include <math.h>
void GDSetLightAttn(GXLightID light, f32 a0, f32 a1, f32 a2, f32 k0, f32 k1, f32 k2) {
GDWriteXFCmdHdr(__GDLightID2Offset(light) + XF_LIGHT_ATTN_ID, 6);
GDWrite_f32(a0);
GDWrite_f32(a1);
GDWrite_f32(a2);
GDWrite_f32(k0);
GDWrite_f32(k1);
GDWrite_f32(k2);
}
void GDSetLightSpot(GXLightID light, f32 cutoff, GXSpotFn spot_func) {
f32 a0;
f32 a1;
f32 a2;
f32 r;
f32 d;
f32 cr;
if (cutoff <= 0.0f || cutoff > 90.0f) {
spot_func = 0;
}
r = M_PI * cutoff / 180.0f;
cr = cosf(r);
switch(spot_func) {
case GX_SP_FLAT:
a0 = -1000.0f * cr;
a1 = 1000.0f;
a2 = 0.0f;
break;
case GX_SP_COS:
a0 = -cr / (1.0f - cr);
a1 = 1.0f / (1.0f - cr);
a2 = 0.0f;
break;
case GX_SP_COS2:
a0 = 0.0f;
a1 = -cr / (1.0f - cr);
a2 = 1.0f / (1.0f - cr);
break;
case GX_SP_SHARP:
d = (1.0f - cr) * (1.0f - cr);
a0 = (cr * (cr - 2.0f)) / d;
a1 = 2.0f / d;
a2 = -1.0f / d;
break;
case GX_SP_RING1:
d = (1.0f - cr) * (1.0f - cr);
a0 = (-4.0f * cr) / d;
a1 = (4.0f * (1.0f + cr)) / d;
a2 = -4.0f / d;
break;
case GX_SP_RING2:
d = (1.0f - cr) * (1.0f - cr);
a0 = 1.0f - (2.0f * cr * cr) / d;
a1 = (4.0f * cr) / d;
a2 = -2.0f / d;
break;
case GX_SP_OFF:
default:
a0 = 1.0f;
a1 = 0.0f;
a2 = 0.0f;
break;
}
GDWriteXFCmdHdr(__GDLightID2Offset(light) + XF_LIGHT_ATTN_ID, 3);
GDWrite_f32(a0);
GDWrite_f32(a1);
GDWrite_f32(a2);
}
void GDSetLightDistAttn(GXLightID light, f32 ref_dist, f32 ref_br, GXDistAttnFn dist_func) {
f32 k0;
f32 k1;
f32 k2;
if (ref_dist < 0.0f || ref_br <= 0.0f || ref_br >= 1.0f) {
dist_func = 0;
}
switch (dist_func) {
case GX_DA_GENTLE:
k0 = 1.0f;
k1 = (1.0f - ref_br) / (ref_br * ref_dist);
k2 = 0.0f;
break;
case GX_DA_MEDIUM:
k0 = 1.0f;
k1 = (0.5f * (1.0f - ref_br)) / (ref_br * ref_dist);
k2 = (0.5f * (1.0f - ref_br)) / (ref_dist * (ref_br * ref_dist));
break;
case GX_DA_STEEP:
k0 = 1.0f;
k1 = 0.0f;
k2 = (1.0f - ref_br) / (ref_dist * (ref_br * ref_dist));
break;
case GX_DA_OFF:
default:
k0 = 1.0f;
k1 = 0.0f;
k2 = 0.0f;
break;
}
GDWriteXFCmdHdr(__GDLightID2Offset(light) + XF_LIGHT_DISTATTN_ID, 3);
GDWrite_f32(k0);
GDWrite_f32(k1);
GDWrite_f32(k2);
}
void GDSetLightColor(GXLightID light, GXColor color) {
GDWriteXFCmd(__GDLightID2Offset(light) + XF_LIGHT_COLOR_ID, color.r << 24 | color.g << 16 | color.b << 8 | color.a);
}
void GDSetLightPos(GXLightID light, f32 x, f32 y, f32 z) {
GDWriteXFCmdHdr(__GDLightID2Offset(light) + XF_LIGHT_POS_ID, 3);
GDWrite_f32(x);
GDWrite_f32(y);
GDWrite_f32(z);
}
void GDSetLightDir(GXLightID light, f32 nx, f32 ny, f32 nz) {
GDWriteXFCmdHdr(__GDLightID2Offset(light) + XF_LIGHT_DIR_ID, 3);
GDWrite_f32(nx);
GDWrite_f32(ny);
GDWrite_f32(nz);
}
void GDSetSpecularDirHA(GXLightID light, f32 nx, f32 ny, f32 nz, f32 hx, f32 hy, f32 hz) {
f32 px;
f32 py;
f32 pz;
px = 1000000000000000000.0f * -nx;
py = 1000000000000000000.0f * -ny;
pz = 1000000000000000000.0f * -nz;
GDWriteXFCmdHdr(__GDLightID2Offset(light) + XF_LIGHT_SPEC_DIR_ID, 6);
GDWrite_f32(px);
GDWrite_f32(py);
GDWrite_f32(pz);
GDWrite_f32(hx);
GDWrite_f32(hy);
GDWrite_f32(hz);
}
void GDSetSpecularDir(GXLightID light, f32 nx, f32 ny, f32 nz) {
f32 px;
f32 py;
f32 pz;
f32 hx;
f32 hy;
f32 hz;
f32 mag;
hx = -nx;
hy = -ny;
hz = 1.0f + -nz;
mag = hx * hx + hy * hy + hz * hz;
if (mag != 0.0f) {
mag = 1.0f / sqrtf(mag);
}
hx = hx * mag;
hy = hy * mag;
hz = hz * mag;
px = 1000000000000000000.0f * -nx;
py = 1000000000000000000.0f * -ny;
pz = 1000000000000000000.0f * -nz;
GDWriteXFCmdHdr(__GDLightID2Offset(light) + XF_LIGHT_SPEC_DIR_ID, 6);
GDWrite_f32(px);
GDWrite_f32(py);
GDWrite_f32(pz);
GDWrite_f32(hx);
GDWrite_f32(hy);
GDWrite_f32(hz);
}
void GDLoadLightObjIndx(u32 lt_obj_indx, GXLightID light) {
GDWriteXFIndxDCmd(__GDLightID2Offset(light) + XF_LIGHT_ID, 0x10, lt_obj_indx);
}
void GDSetChanAmbColor(GXChannelID chan, GXColor color) {
GDWriteXFCmd((chan & 1) + XF_REG_AMBIENT0_ID, color.r << 24 | color.g << 16 | color.b << 8 | color.a);
}
void GDSetChanMatColor(GXChannelID chan, GXColor color) {
GDWriteXFCmd((chan & 1) + XF_REG_MATERIAL0_ID, color.r << 24 | color.g << 16 | color.b << 8 | color.a);
}
void GDSetChanCtrl(GXChannelID chan, u8 enable, GXColorSrc amb_src, GXColorSrc mat_src, u32 light_mask, GXDiffuseFn diff_fn, GXAttnFn attn_fn) {
u32 reg;
reg = XF_REG_CHAN_CTRL(mat_src, enable, light_mask & 0xF, amb_src, attn_fn == GX_AF_SPEC ? GX_DF_NONE : diff_fn, attn_fn != GX_AF_NONE, attn_fn != GX_AF_SPEC, (light_mask >> 4) & 0xF);
GDWriteXFCmd((chan & 3) + XF_REG_COLOR0CNTRL_ID, reg);
if (chan == 4 || chan == 5) {
GDWriteXFCmd(chan + XF_REG_MATERIAL0_ID, reg);
}
}

118
src/revolution/gd/GDPixel.c Normal file
View File

@ -0,0 +1,118 @@
#include <revolution/gd.h>
#include <revolution/os.h>
void GDSetFog(GXFogType type, f32 startz, f32 endz, f32 nearz, f32 farz, GXColor color) {
f32 A;
f32 B;
f32 B_mant;
f32 C;
f32 A_f;
u32 b_expn;
u32 b_m;
u32 a_hex;
u32 c_hex;
u32 fsel;
u32 proj;
ASSERTMSGLINE(62, farz >= 0.0f, "GDSetFog: The farz should be positive value");
ASSERTMSGLINE(63, farz >= nearz, "GDSetFog: The farz should be larger than nearz");
fsel = type & 7;
proj = (type >> 3) & 1;
if (proj != 0) {
if (farz == nearz || endz == startz) {
A_f = 0.0f;
C = 0.0f;
} else {
A = 1.0f / (endz - startz);
A_f = (farz - nearz) * A;
C = (startz - nearz) * A;
}
b_expn = 0;
b_m = 0;
} else {
if (farz == nearz || endz == startz) {
A = 0.0f;
B = 0.5f;
C = 0.0f;
} else {
A = (farz * nearz) / ((farz - nearz) * (endz - startz));
B = farz / (farz - nearz);
C = startz / (endz - startz);
}
B_mant = B;
b_expn = 1;
while (B_mant > 1.0) {
B_mant *= 0.5f;
b_expn++;
}
while (B_mant > 0.0f && B_mant < 0.5) {
B_mant *= 2.0f;
b_expn--;
}
A_f = A / (1 << b_expn);
b_m = (u32) (8388638.0f * B_mant);
}
a_hex = *(u32*)&A_f;
c_hex = *(u32*)&C;
GDWriteBPCmd(BP_FOG_UNK0(a_hex >> 12, 0xEE));
GDWriteBPCmd(BP_FOG_UNK1(b_m, 0xEF));
GDWriteBPCmd(BP_FOG_UNK2(b_expn, 0xF0));
GDWriteBPCmd(BP_FOG_UNK3(c_hex >> 12, proj, fsel, 0xF1));
GDWriteBPCmd(BP_FOG_COLOR(color.r, color.g, color.b, 0xF2));
}
void GDSetBlendMode(GXBlendMode type, GXBlendFactor src_factor, GXBlendFactor dst_factor, GXLogicOp logic_op) {
GDWriteBPCmd(0xFE00FFE3);
GDWriteBPCmd(BP_BLEND_MODE(
type == GX_BM_BLEND || type == GX_BM_SUBTRACT,
type == GX_BM_LOGIC,
0,
0,
0,
dst_factor,
src_factor,
type == GX_BM_SUBTRACT,
logic_op,
0x41
));
}
void GDSetBlendModeEtc(GXBlendMode type, GXBlendFactor src_factor,
GXBlendFactor dst_factor, GXLogicOp logic_op,
u8 color_update_enable, u8 alpha_update_enable,
u8 dither_enable) {
GDWriteBPCmd(BP_BLEND_MODE(
type == GX_BM_BLEND || type == GX_BM_SUBTRACT,
type == GX_BM_LOGIC,
dither_enable,
color_update_enable,
alpha_update_enable,
dst_factor,
src_factor,
type == GX_BM_SUBTRACT,
logic_op,
0x41
));
}
void GDSetZMode(u8 compare_enable, GXCompare func, u8 update_enable) {
GDWriteBPCmd(BP_Z_MODE(compare_enable, func, update_enable, 0x40));
}
void GDSetDstAlpha(u8 enable, u8 alpha) {
GDWriteBPCmd(BP_DST_ALPHA(alpha, enable, 0x42));
}
void GDSetDrawSync(u16 token) {
GDWriteBPCmd(BP_TOKEN(token, 0x48));
GDWriteBPCmd(BP_TOKEN(token, 0x47));
}

159
src/revolution/gd/GDTev.c Normal file
View File

@ -0,0 +1,159 @@
#include <revolution/gd.h>
#include <revolution/os.h>
void GDSetTevOp(GXTevStageID stage, GXTevMode mode) {
GXTevColorArg carg = GX_CC_RASC;
GXTevAlphaArg aarg = GX_CA_RASA;
if (stage != GX_TEVSTAGE0) {
carg = GX_CC_CPREV;
aarg = GX_CA_APREV;
}
switch (mode) {
case GX_MODULATE:
GDSetTevColorCalc(stage, GX_CC_ZERO, GX_CC_TEXC, carg, GX_CC_ZERO, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV);
GDSetTevAlphaCalcAndSwap(stage, GX_CA_ZERO, GX_CA_TEXA, aarg, GX_CA_ZERO, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV, GX_TEV_SWAP0, GX_TEV_SWAP0);
break;
case GX_DECAL:
GDSetTevColorCalc(stage, carg, GX_CC_TEXC, GX_CC_TEXA, GX_CC_ZERO, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV);
GDSetTevAlphaCalcAndSwap(stage, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, aarg, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV, GX_TEV_SWAP0, GX_TEV_SWAP0);
break;
case GX_BLEND:
GDSetTevColorCalc(stage, carg, GX_CC_ONE, GX_CC_TEXC, GX_CC_ZERO, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV);
GDSetTevAlphaCalcAndSwap(stage, GX_CA_ZERO, GX_CA_TEXA, aarg, GX_CA_ZERO, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV, GX_TEV_SWAP0, GX_TEV_SWAP0);
break;
case GX_REPLACE:
GDSetTevColorCalc(stage, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_TEXC, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV);
GDSetTevAlphaCalcAndSwap(stage, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_TEXA, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV, GX_TEV_SWAP0, GX_TEV_SWAP0);
break;
case GX_PASSCLR:
GDSetTevColorCalc(stage, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, carg, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV);
GDSetTevAlphaCalcAndSwap(stage, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, aarg, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV, GX_TEV_SWAP0, GX_TEV_SWAP0);
break;
default:
ASSERTMSGLINE(110, 0, "GDSetTevOp: Invalid Tev Mode");
break;
}
}
void GDSetTevColorCalc(GXTevStageID stage, GXTevColorArg a, GXTevColorArg b,
GXTevColorArg c, GXTevColorArg d, GXTevOp op,
GXTevBias bias, GXTevScale scale, u8 clamp,
GXTevRegID out_reg) {
if (op <= GX_TEV_SUB) {
GDWriteBPCmd(BP_TEV_COLOR(d, c, b, a, bias, op & 1, clamp, scale, out_reg, stage * 2 + 0xC0));
} else {
GDWriteBPCmd(BP_TEV_COLOR(d, c, b, a, 3, op & 1, clamp, (op >> 1) & 3, out_reg, stage * 2 + 0xC0));
}
}
void GDSetTevAlphaCalcAndSwap(GXTevStageID stage, GXTevAlphaArg a,
GXTevAlphaArg b, GXTevAlphaArg c, GXTevAlphaArg d,
GXTevOp op, GXTevBias bias, GXTevScale scale,
u8 clamp, GXTevRegID out_reg,
GXTevSwapSel ras_sel, GXTevSwapSel tex_sel) {
if (op <= GX_TEV_SUB) {
GDWriteBPCmd(BP_TEV_ALPHA(ras_sel, tex_sel, d, c, b, a, bias, op & 1, clamp, scale, out_reg, stage * 2 + 0xC1));
} else {
GDWriteBPCmd(BP_TEV_ALPHA(ras_sel, tex_sel, d, c, b, a, 3, op & 1, clamp, (op >> 1) & 3, out_reg, stage * 2 + 0xC1));
}
}
void GDSetTevColor(GXTevRegID reg, GXColor color) {
u32 regRA;
u32 regBG;
regRA = BP_TEV_COLOR_REG_RA(color.r, color.a, 0, 0xE0 + reg * 2);
regBG = BP_TEV_COLOR_REG_BG(color.b, color.g, 0, 0xE1 + reg * 2);
GDWriteBPCmd(regRA);
GDWriteBPCmd(regBG);
GDWriteBPCmd(regBG);
GDWriteBPCmd(regBG);
}
void GDSetTevColorS10(GXTevRegID reg, GXColorS10 color) {
u32 regRA;
u32 regBG;
regRA = BP_TEV_COLOR_REG_RA(color.r & 0x7FF, color.a & 0x7FF, 0, 0xE0 + reg * 2);
regBG = BP_TEV_COLOR_REG_BG(color.b & 0x7FF, color.g & 0x7FF, 0, 0xE1 + reg * 2);
GDWriteBPCmd(regRA);
GDWriteBPCmd(regBG);
GDWriteBPCmd(regBG);
GDWriteBPCmd(regBG);
}
void GDSetTevKColor(GXTevKColorID reg, GXColor color) {
u32 regRA;
u32 regBG;
regRA = BP_TEV_COLOR_REG_RA(color.r, color.a, 1, 0xE0 + reg * 2);
regBG = BP_TEV_COLOR_REG_BG(color.b, color.g, 1, 0xE1 + reg * 2);
GDWriteBPCmd(regRA);
GDWriteBPCmd(regBG);
}
void GDSetTevKonstantSel(GXTevStageID evenStage, GXTevKColorSel kcsel0,
GXTevKAlphaSel kasel0, GXTevKColorSel kcsel1,
GXTevKAlphaSel kasel1) {
GDWriteBPCmd(0xFEFFFFF0);
GDWriteBPCmd(BP_TEV_KSEL(0, 0, kcsel0, kasel0, kcsel1, kasel1, evenStage / 2 + 0xF6));
}
void GDSetTevSwapModeTable(GXTevSwapSel table, GXTevColorChan red,
GXTevColorChan green, GXTevColorChan blue,
GXTevColorChan alpha) {
GDWriteBPCmd(0xFE00000F);
GDWriteBPCmd(BP_TEV_KSEL(red, green, 0, 0, 0, 0, table * 2 + 0xF6));
GDWriteBPCmd(0xFE00000F);
GDWriteBPCmd(BP_TEV_KSEL(blue, alpha, 0, 0, 0, 0, table * 2 + 0xF7));
}
void GDSetAlphaCompare(GXCompare comp0, u8 ref0, GXAlphaOp op, GXCompare comp1, u8 ref1) {
GDWriteBPCmd(BP_ALPHA_COMPARE(ref0, ref1, comp0, comp1, op, 0xF3));
}
void GDSetZTexture(GXZTexOp op, GXTexFmt fmt, u32 bias) {
u32 zfmt;
switch (fmt) {
case GX_TF_Z8:
zfmt = 0;
break;
case GX_TF_Z16:
zfmt = 1;
break;
case GX_TF_Z24X8:
zfmt = 2;
break;
default:
ASSERTMSGLINE(399, 0, "GDSetZTexture: Invalid format");
zfmt = 2;
break;
}
GDWriteBPCmd(BP_ZTEX_PARAMS_0(bias, 0xF4));
GDWriteBPCmd(BP_ZTEX_PARAMS_1(zfmt, op, 0xF5));
}
void GDSetTevOrder(GXTevStageID evenStage, GXTexCoordID coord0, GXTexMapID map0,
GXChannelID color0, GXTexCoordID coord1, GXTexMapID map1,
GXChannelID color1) {
static u8 c2r[] = { 0, 1, 0, 1, 0, 1, 7, 5, 6, 0, 0, 0, 0, 0, 0, 7 };
GDWriteBPCmd(BP_TEV_ORDER(
map0 & 7,
coord0 & 7,
map0 != GX_TEXMAP_NULL && !(map0 & GX_TEX_DISABLE),
c2r[color0 & 0xF],
map1 & 7,
coord1 & 7,
map1 != GX_TEXMAP_NULL && !(map1 & GX_TEX_DISABLE),
c2r[color1 & 0xF],
evenStage / 2 + 0x28
));
}

View File

@ -0,0 +1,104 @@
#include <revolution/gd.h>
#include <revolution/os.h>
u8 GD2HWFiltConv[] = {0, 4, 1, 5, 2, 6};
u8 GDTexMode0Ids[8] = {128, 129, 130, 131, 160, 161, 162, 163};
u8 GDTexMode1Ids[8] = {132, 133, 134, 135, 164, 165, 166, 167};
u8 GDTexImage0Ids[8] = {136, 137, 138, 139, 168, 169, 170, 171};
u8 GDTexImage1Ids[8] = {140, 141, 142, 143, 172, 173, 174, 175};
u8 GDTexImage2Ids[8] = {144, 145, 146, 147, 176, 177, 178, 179};
u8 GDTexImage3Ids[8] = {148, 149, 150, 151, 180, 181, 182, 183};
u8 GDTexTlutIds[8] = {152, 153, 154, 155, 184, 185, 186, 187};
void GDSetTexLookupMode(GXTexMapID id, GXTexWrapMode wrap_s,
GXTexWrapMode wrap_t, GXTexFilter min_filt,
GXTexFilter mag_filt, f32 min_lod, f32 max_lod,
f32 lod_bias, u8 bias_clamp, u8 do_edge_lod,
GXAnisotropy max_aniso) {
GDWriteBPCmd(BP_TEX_MODE0(wrap_s, wrap_t, mag_filt == TRUE, GD2HWFiltConv[min_filt], !do_edge_lod, (u8)(32.0f * lod_bias), max_aniso, bias_clamp, GDTexMode0Ids[id]));
GDWriteBPCmd(BP_TEX_MODE1((u8)(16.0f * min_lod), (u8)(16.0f * max_lod), GDTexMode1Ids[id]));
}
void GDSetTexImgAttr(GXTexMapID id, u16 width, u16 height, GXTexFmt format) {
GDWriteBPCmd(BP_IMAGE_ATTR(width - 1, height - 1, format, GDTexImage0Ids[id]));
}
void GDSetTexImgPtr(GXTexMapID id, void* image_ptr) {
GDWriteBPCmd(BP_IMAGE_PTR(OSCachedToPhysical(image_ptr) >> 5, GDTexImage3Ids[id]));
}
void GDSetTexImgPtrRaw(GXTexMapID id, u32 image_ptr_raw) {
GDWriteBPCmd(BP_IMAGE_PTR(image_ptr_raw, GDTexImage3Ids[id]));
}
void GDPatchTexImgPtr(void* image_ptr) {
GDWrite_u24(OSCachedToPhysical(image_ptr) >> 5);
}
void GDSetTexCached(GXTexMapID id, u32 tmem_even, GXTexCacheSize size_even,
u32 tmem_odd, GXTexCacheSize size_odd) {
GDWriteBPCmd(BP_TEX_CACHE_EVEN(tmem_even >> 5, size_even + 3, size_even + 3, 0, GDTexImage1Ids[id]));
if (size_odd != 3 && tmem_odd < 0x100000) {
GDWriteBPCmd(BP_TEX_CACHE_ODD(tmem_odd >> 5, size_odd + 3, size_odd + 3, GDTexImage2Ids[id]));
}
}
void GDSetTexPreLoaded(GXTexMapID id, u32 tmem_even, u32 tmem_odd) {
GDWriteBPCmd(BP_TEX_CACHE_EVEN(tmem_even >> 5, 0, 0, 1, GDTexImage1Ids[id]));
if (tmem_odd < 0x100000) {
GDWriteBPCmd(BP_TEX_CACHE_ODD(tmem_odd >> 5, 0, 0, GDTexImage2Ids[id]));
}
}
void GDSetTexTlut(GXTexMapID id, u32 tmem_addr, GXTlutFmt format) {
GDWriteBPCmd(BP_TEX_TLUT((tmem_addr - 0x80000) >> 9, format, GDTexTlutIds[id]));
}
void GDSetTexCoordScale(GXTexCoordID coord, u16 s_scale, u16 t_scale) {
GDWriteBPCmd(0xFE00FFFF);
GDWriteBPCmd(BP_TEXCOORD_S_SCALE(s_scale - 1, 0, 0, 0, 0, coord * 2 + 0x30));
GDWriteBPCmd(0xFE00FFFF);
GDWriteBPCmd(BP_TEXCOORD_T_SCALE(t_scale - 1, 0, 0, coord * 2 + 0x31));
}
void GDSetTexCoordScale2(GXTexCoordID coord, u16 s_scale, u8 s_bias,
u8 s_wrap, u16 t_scale, u8 t_bias, u8 t_wrap) {
GDWriteBPCmd(0xFE03FFFF);
GDWriteBPCmd(BP_TEXCOORD_S_SCALE(s_scale - 1, s_bias, s_wrap, 0, 0, coord * 2 + 0x30));
GDWriteBPCmd(BP_TEXCOORD_T_SCALE(t_scale - 1, t_bias, t_wrap, coord * 2 + 0x31));
}
void GDSetTexCoordScaleAndTOEs(GXTexCoordID coord, u16 s_scale, u8 s_bias,
u8 s_wrap, u16 t_scale, u8 t_bias, u8 t_wrap,
u8 line_offset, u8 point_offset) {
GDWriteBPCmd(BP_TEXCOORD_S_SCALE(s_scale - 1, s_bias, s_wrap, line_offset, point_offset, coord * 2 + 0x30));
GDWriteBPCmd(BP_TEXCOORD_T_SCALE(t_scale - 1, t_bias, t_wrap, coord * 2 + 0x31));
}
void GDLoadTlut(void* tlut_ptr, u32 tmem_addr, GXTlutSize size) {
ASSERTMSGLINE(488, !(tmem_addr & 0x1ff), "GDLoadTlut: invalid TMEM pointer");
ASSERTMSGLINE(489, size <= 0x400, "GDLoadTlut: invalid TLUT size");
GDWriteBPCmd(0xFEFFFF00);
GDWriteBPCmd(0xF000000);
GDWriteBPCmd(BP_LOAD_TLUT0(OSCachedToPhysical(tlut_ptr) >> 5, 0x64));
GDWriteBPCmd(BP_LOAD_TLUT1((tmem_addr - 0x80000) >> 9, size, 0x65));
GDWriteBPCmd(0xFEFFFF00);
GDWriteBPCmd(0xF000000);
}
void GDLoadTlutRaw(u32 tlut_ptr_raw, u32 tmem_addr, GXTlutSize size) {
ASSERTMSGLINE(527, size <= 0x400, "GDLoadTlut: invalid TLUT size");
GDWriteBPCmd(0xFEFFFF00);
GDWriteBPCmd(0xF000000);
GDWriteBPCmd(BP_LOAD_TLUT0(tlut_ptr_raw, 0x64));
GDWriteBPCmd(BP_LOAD_TLUT1((tmem_addr - 0x80000) >> 9, size, 0x65));
GDWriteBPCmd(0xFEFFFF00);
GDWriteBPCmd(0xF000000);
}

View File

@ -0,0 +1,127 @@
#include <revolution/gd.h>
#include <revolution/os.h>
void GDLoadPosMtxImm(const Mtx mtx, u32 id) {
GDWriteXFCmdHdr(4 * id, 12);
GDWrite_f32(mtx[0][0]);
GDWrite_f32(mtx[0][1]);
GDWrite_f32(mtx[0][2]);
GDWrite_f32(mtx[0][3]);
GDWrite_f32(mtx[1][0]);
GDWrite_f32(mtx[1][1]);
GDWrite_f32(mtx[1][2]);
GDWrite_f32(mtx[1][3]);
GDWrite_f32(mtx[2][0]);
GDWrite_f32(mtx[2][1]);
GDWrite_f32(mtx[2][2]);
GDWrite_f32(mtx[2][3]);
}
void GDLoadPosMtxIndx(u16 mtx_indx, u32 id) {
GDWriteXFIndxACmd(4 * id, 12, mtx_indx);
}
void GDLoadNrmMtxImm(const Mtx mtx, u32 id) {
GDWriteXFCmdHdr(id * 3 + 0x400, 9);
GDWrite_f32(mtx[0][0]);
GDWrite_f32(mtx[0][1]);
GDWrite_f32(mtx[0][2]);
GDWrite_f32(mtx[1][0]);
GDWrite_f32(mtx[1][1]);
GDWrite_f32(mtx[1][2]);
GDWrite_f32(mtx[2][0]);
GDWrite_f32(mtx[2][1]);
GDWrite_f32(mtx[2][2]);
}
void GDLoadNrmMtxImm3x3(const f32 mtx[3][3], u32 id) {
GDWriteXFCmdHdr(id * 3 + 0x400, 9);
GDWrite_f32(mtx[0][0]);
GDWrite_f32(mtx[0][1]);
GDWrite_f32(mtx[0][2]);
GDWrite_f32(mtx[1][0]);
GDWrite_f32(mtx[1][1]);
GDWrite_f32(mtx[1][2]);
GDWrite_f32(mtx[2][0]);
GDWrite_f32(mtx[2][1]);
GDWrite_f32(mtx[2][2]);
}
void GDLoadNrmMtxIndx3x3(u16 mtx_indx, u32 id) {
GDWriteXFIndxBCmd(id * 3 + 0x400, 9, mtx_indx);
}
void GDLoadTexMtxImm(const Mtx mtx, u32 id, GXTexMtxType type) {
u16 addr;
u8 count;
if (id >= 0x40) {
ASSERTMSGLINE(178, type == GX_MTX3x4, "GDLoadTexMtxImm: invalid matrix type");
addr = ((id - 0x40) << 2) + 0x500;
count = 12;
} else {
addr = 4 * id;
count = type == GX_MTX2x4 ? 8 : 12;
}
GDWriteXFCmdHdr(addr,count);
GDWrite_f32(mtx[0][0]);
GDWrite_f32(mtx[0][1]);
GDWrite_f32(mtx[0][2]);
GDWrite_f32(mtx[0][3]);
GDWrite_f32(mtx[1][0]);
GDWrite_f32(mtx[1][1]);
GDWrite_f32(mtx[1][2]);
GDWrite_f32(mtx[1][3]);
if (type == GX_MTX3x4) {
GDWrite_f32(mtx[2][0]);
GDWrite_f32(mtx[2][1]);
GDWrite_f32(mtx[2][2]);
GDWrite_f32(mtx[2][3]);
}
}
void GDLoadTexMtxIndx(u16 mtx_indx, u32 id, GXTexMtxType type) {
u16 addr;
u8 count;
if (id >= 0x40) {
ASSERTMSGLINE(227, type == GX_MTX3x4, "GDLoadTexMtxIndx: invalid matrix type");
addr = ((id - 0x40) << 2) + 0x500;
count = 12;
} else {
addr = 4 * id;
count = type == GX_MTX2x4 ? 8 : 12;
}
GDWriteXFIndxCCmd(addr, count, mtx_indx);
}
void GDSetCurrentMtx(u32 pn, u32 t0, u32 t1, u32 t2, u32 t3, u32 t4, u32 t5, u32 t6, u32 t7) {
u32 regA;
u32 regB;
regA = CP_MTX_REG_A(pn, t0, t1, t2, t3);
regB = CP_MTX_REG_B(t4, t5, t6, t7);
GDWriteCPCmd(CP_MTX_REG_A_ID, regA);
GDWriteCPCmd(CP_MTX_REG_B_ID, regB);
GDWriteXFCmdHdr(XF_REG_MATRIXINDEX0_ID, 2);
GDWrite_u32(regA);
GDWrite_u32(regB);
}
void GDSetProjection(const Mtx44 mtx, GXProjectionType type) {
u32 c;
c = type == GX_ORTHOGRAPHIC ? 3 : 2;
GDWriteXFCmdHdr(XF_REG_PROJECTIONA_ID, 7);
GDWrite_f32(mtx[0][0]);
GDWrite_f32(mtx[0][c]);
GDWrite_f32(mtx[1][1]);
GDWrite_f32(mtx[1][c]);
GDWrite_f32(mtx[2][2]);
GDWrite_f32(mtx[2][3]);
GDWrite_u32(type);
}

View File

@ -0,0 +1,10 @@
#include <revolution/gf.h>
#include <revolution/gd.h>
void GFSetGenMode2(u8 nTexGens, u8 nChans, u8 nTevs, u8 nInds, GXCullMode cm) {
static u8 cm2hw[4] = {0, 2, 1, 3};
GFWriteBPCmd(0xFE07FC3F);
GFWriteBPCmd(GF_GEN_MODE(nTexGens, nChans, nTevs - 1, cm2hw[cm], nInds));
GFWriteXFCmd(XF_REG_NUMCOLORS_ID, nChans);
GFWriteXFCmd(XF_REG_NUMTEX_ID, nTexGens);
}

View File

@ -0,0 +1,6 @@
#include <revolution/gf.h>
#include <revolution/gd.h>
void GFSetChanAmbColor(GXChannelID chan, GXColor color) {
GFWriteXFCmd((chan & 1) + XF_REG_AMBIENT0_ID, color.r << 0x18 | color.g << 0x10 | color.b << 8 | color.a);
}

View File

@ -0,0 +1,74 @@
#include <revolution/gf.h>
#include <revolution/gd.h>
void GFSetFog(GXFogType type, f32 startz, f32 endz, f32 nearz, f32 farz, GXColor color) {
f32 A;
f32 B;
f32 B_mant;
f32 C;
f32 A_f;
u32 b_expn;
u32 b_m;
u32 a_hex;
u32 c_hex;
ASSERTMSGLINE(62, farz >= 0.0f, "GFSetFog: The farz should be positive value");
ASSERTMSGLINE(63, farz >= nearz, "GFSetFog: The farz should be larger than nearz");
if (farz == nearz || endz == startz) {
A = 0.0f;
B = 0.5f;
C = 0.0f;
} else {
A = (farz * nearz) / ((farz - nearz) * (endz - startz));
B = farz / (farz - nearz);
C = startz / (endz - startz);
}
B_mant = B;
b_expn = 1;
while (B_mant > 1.0) {
B_mant *= 0.5f;
b_expn++;
}
while (B_mant > 0.0f && B_mant < 0.5) {
B_mant *= 2.0f;
b_expn--;
}
A_f = A / (1 << b_expn);
b_m = (u32) (8388638.0f * B_mant);
a_hex = *(u32*)&A_f;
c_hex = *(u32*)&C;
GFWriteBPCmd(BP_FOG_UNK0(a_hex >> 12, 0xEE));
GFWriteBPCmd(BP_FOG_UNK1(b_m, 0xEF));
GFWriteBPCmd(BP_FOG_UNK2(b_expn, 0xF0));
GFWriteBPCmd(BP_FOG_UNK3(c_hex >> 12, 0, type, 0xF1));
GFWriteBPCmd(BP_FOG_COLOR(color.r, color.g, color.b, 0xF2));
}
void GFSetBlendModeEtc(GXBlendMode type, GXBlendFactor src_factor,
GXBlendFactor dst_factor, GXLogicOp logic_op,
u8 color_update_enable, u8 alpha_update_enable,
u8 dither_enable) {
GFWriteBPCmd(BP_BLEND_MODE(
type == GX_BM_BLEND || type == GX_BM_SUBTRACT,
type == GX_BM_LOGIC,
dither_enable,
color_update_enable,
alpha_update_enable,
dst_factor,
src_factor,
type == GX_BM_SUBTRACT,
logic_op,
0x41
));
}
void GFSetZMode(u8 compare_enable, GXCompare func, u8 update_enable) {
GFWriteBPCmd(BP_Z_MODE(compare_enable, func, update_enable, 0x40));
}

View File

@ -0,0 +1,15 @@
#include <revolution/gf.h>
#include <revolution/gd.h>
void GFSetTevColorS10(GXTevRegID reg, GXColorS10 color) {
u32 regRA;
u32 regBG;
regRA = BP_TEV_COLOR_REG_RA(color.r & 0x7FF, color.a & 0x7FF, 0, 0xE0 + reg * 2);
regBG = BP_TEV_COLOR_REG_BG(color.b & 0x7FF, color.g & 0x7FF, 0, 0xE1 + reg * 2);
GFWriteBPCmd(regRA);
GFWriteBPCmd(regBG);
GFWriteBPCmd(regBG);
GFWriteBPCmd(regBG);
}

637
src/revolution/gx/GXAttr.c Normal file
View File

@ -0,0 +1,637 @@
#include <revolution/gx.h>
#include <revolution/os.h>
#include "__gx.h"
#define CHECK_ATTRPTR(line, attrPtr) ASSERTMSGLINE(line, (attrPtr) != NULL, "GXSetVtxDescv: attrPtr is NULL")
#define CHECK_ATTRNAME(line, attr) ASSERTMSGLINE(line, (attr) >= GX_VA_PNMTXIDX, "GXSetVtxDesc: Invalid vertex attribute name")
#define CHECK_ATTRNAME2(line, attr) ASSERTMSGLINE(line, (attr) <= GX_VA_TEX7 || (attr) == GX_VA_NBT, "GXSetVtxDesc: Invalid vertex attribute name")
#define CHECK_ATTRNAME3(line, attr) ASSERTMSGLINE(line, (attr) >= GX_VA_PNMTXIDX && (attr) < GX_VA_MAX_ATTR, "GXSetVtxDesc: Invalid vertex attribute name")
#define CHECK_ATTRNAME4(line, attr) ASSERTMSGLINE(line, ((attr) >= GX_VA_POS && (attr) <= GX_VA_TEX7) || (attr) == GX_VA_NBT, "GXSetVtxAttrFmt: Invalid vertex attribute name")
#define CHECK_ATTRNAME5(line, attr) ASSERTMSGLINE(line, (attr) >= GX_VA_POS && (attr) <= GX_LIGHT_ARRAY, "GXSetArray: Invalid vertex attribute name")
#define CHECK_ATTRTYPE(line, type) ASSERTMSGLINE(line, (type) >= GX_NONE && (type) <= GX_INDEX16, "GXSetVtxDesc: Invalid vertex attribute type")
#define CHECK_VTXFMT(line, vtxfmt) ASSERTMSGLINE(line, (vtxfmt) < GX_MAX_VTXFMT, "GXSetVtxAttrFmt: Format Index is out of range")
#define CHECK_FRAC(line, frac) ASSERTMSGLINE(line, (frac) < 32, "GXSetVtxAttrFmt: Frac value is >= 32")
#define CHECK_LISTPTR(line, list) ASSERTMSGLINE(line, (list) != NULL, "GXSetVtxAttrFmt: list pointer is NULL")
#define CHECK_MTXIDX(line, attr, type) ASSERTMSGLINE(line, (attr) > GX_VA_TEX7MTXIDX || (type) <= GX_VA_TEX0MTXIDX, "GXSetVtxDesc: GX_VA_*MTXIDX accepts GX_NONE or GX_DIRECT only")
static void __GXXfVtxSpecs(void) {
u32 nCols;
u32 nNrm;
u32 nTex;
u32 reg;
nNrm = __GXData->hasBiNrms ? 2 : __GXData->hasNrms ? 1 : 0;
#if DEBUG
nCols = CP_VCD_REG_LO_GET_COL0(__GXData->vcdLo) ? 1 : 0;
nCols += CP_VCD_REG_LO_GET_COL1(__GXData->vcdLo) ? 1 : 0;
#else
nCols = (u32)__cntlzw((__GXData->vcdLo & CP_VCD_REG_LO_COLALL_MASK)>>CP_VCD_REG_LO_COLALL_SHIFT);
nCols = (33 - nCols) >> 1;
#endif
#if DEBUG
nTex = 0;
nTex += CP_VCD_REG_HI_GET_TEX0(__GXData->vcdHi) ? 1 : 0;
nTex += CP_VCD_REG_HI_GET_TEX1(__GXData->vcdHi) ? 1 : 0;
nTex += CP_VCD_REG_HI_GET_TEX2(__GXData->vcdHi) ? 1 : 0;
nTex += CP_VCD_REG_HI_GET_TEX3(__GXData->vcdHi) ? 1 : 0;
nTex += CP_VCD_REG_HI_GET_TEX4(__GXData->vcdHi) ? 1 : 0;
nTex += CP_VCD_REG_HI_GET_TEX5(__GXData->vcdHi) ? 1 : 0;
nTex += CP_VCD_REG_HI_GET_TEX6(__GXData->vcdHi) ? 1 : 0;
nTex += CP_VCD_REG_HI_GET_TEX7(__GXData->vcdHi) ? 1 : 0;
#else
nTex = (u32)__cntlzw((__GXData->vcdHi & CP_VCD_REG_HI_TEXALL_MASK)>>CP_VCD_REG_HI_TEXALL_SHIFT);
nTex = (33 - nTex) >> 1;
#endif
reg = XF_INVERTEXSPEC_F(nCols, nNrm, nTex);
GX_WRITE_XF_REG(0x1008, reg, 0);
__GXData->bpSentNot = 1;
}
static inline void SETVCDATTR(GXAttr Attr, GXAttrType Type) {
switch (Attr) {
case GX_VA_PNMTXIDX: SC_CP_VCD_REG_LO_SET_PMIDX(219, __GXData->vcdLo, Type); break;
case GX_VA_TEX0MTXIDX: SC_CP_VCD_REG_LO_SET_T0MIDX(220, __GXData->vcdLo, Type); break;
case GX_VA_TEX1MTXIDX: SC_CP_VCD_REG_LO_SET_T1MIDX(221, __GXData->vcdLo, Type); break;
case GX_VA_TEX2MTXIDX: SC_CP_VCD_REG_LO_SET_T2MIDX(222, __GXData->vcdLo, Type); break;
case GX_VA_TEX3MTXIDX: SC_CP_VCD_REG_LO_SET_T3MIDX(223, __GXData->vcdLo, Type); break;
case GX_VA_TEX4MTXIDX: SC_CP_VCD_REG_LO_SET_T4MIDX(224, __GXData->vcdLo, Type); break;
case GX_VA_TEX5MTXIDX: SC_CP_VCD_REG_LO_SET_T5MIDX(225, __GXData->vcdLo, Type); break;
case GX_VA_TEX6MTXIDX: SC_CP_VCD_REG_LO_SET_T6MIDX(226, __GXData->vcdLo, Type); break;
case GX_VA_TEX7MTXIDX: SC_CP_VCD_REG_LO_SET_T7MIDX(227, __GXData->vcdLo, Type); break;
case GX_VA_POS: SC_CP_VCD_REG_LO_SET_POS(228, __GXData->vcdLo, Type); break;
case GX_VA_NRM:
if (Type != GX_NONE) {
__GXData->hasNrms = 1;
__GXData->hasBiNrms = 0;
__GXData->nrmType = Type;
} else {
__GXData->hasNrms = 0;
}
break;
case GX_VA_NBT:
if (Type != GX_NONE) {
__GXData->hasBiNrms = 1;
__GXData->hasNrms = 0;
__GXData->nrmType = Type;
} else {
__GXData->hasBiNrms = 0;
}
break;
case GX_VA_CLR0: SC_CP_VCD_REG_LO_SET_COL0(253, __GXData->vcdLo, Type); break;
case GX_VA_CLR1: SC_CP_VCD_REG_LO_SET_COL1(254, __GXData->vcdLo, Type); break;
case GX_VA_TEX0: SC_CP_VCD_REG_HI_SET_TEX0(255, __GXData->vcdHi, Type); break;
case GX_VA_TEX1: SC_CP_VCD_REG_HI_SET_TEX1(256, __GXData->vcdHi, Type); break;
case GX_VA_TEX2: SC_CP_VCD_REG_HI_SET_TEX2(257, __GXData->vcdHi, Type); break;
case GX_VA_TEX3: SC_CP_VCD_REG_HI_SET_TEX3(258, __GXData->vcdHi, Type); break;
case GX_VA_TEX4: SC_CP_VCD_REG_HI_SET_TEX4(259, __GXData->vcdHi, Type); break;
case GX_VA_TEX5: SC_CP_VCD_REG_HI_SET_TEX5(260, __GXData->vcdHi, Type); break;
case GX_VA_TEX6: SC_CP_VCD_REG_HI_SET_TEX6(261, __GXData->vcdHi, Type); break;
case GX_VA_TEX7: SC_CP_VCD_REG_HI_SET_TEX7(262, __GXData->vcdHi, Type); break;
}
}
void GXSetVtxDesc(GXAttr attr, GXAttrType type) {
CHECK_GXBEGIN(271, "GXSetVtxDesc");
CHECK_ATTRNAME(274, attr);
CHECK_ATTRNAME2(276, attr);
CHECK_ATTRTYPE(278, type);
CHECK_MTXIDX(281, attr, type);
SETVCDATTR(attr, type);
if (__GXData->hasNrms || __GXData->hasBiNrms) {
SC_CP_VCD_REG_LO_SET_NRM(287, __GXData->vcdLo, __GXData->nrmType);
} else {
SC_CP_VCD_REG_LO_SET_NRM(0, __GXData->vcdLo, 0);
}
__GXData->dirtyState |= 8;
}
void GXSetVtxDescv(const GXVtxDescList *attrPtr) {
CHECK_GXBEGIN(313, "GXSetVtxDescv");
CHECK_ATTRPTR(314, attrPtr);
while (attrPtr->attr != GX_VA_NULL) {
CHECK_ATTRNAME(318, attrPtr->attr);
CHECK_ATTRNAME2(321, attrPtr->attr);
CHECK_ATTRTYPE(324, attrPtr->type);
SETVCDATTR(attrPtr->attr, attrPtr->type);
attrPtr++;
}
if (__GXData->hasNrms || __GXData->hasBiNrms) {
SC_CP_VCD_REG_LO_SET_NRM(333, __GXData->vcdLo, __GXData->nrmType);
} else {
SC_CP_VCD_REG_LO_SET_NRM(0, __GXData->vcdLo, 0);
}
__GXData->dirtyState |= 8;
}
void __GXSetVCD(void) {
GX_WRITE_CP_STRM_REG_alt(CP_VCD_LO, 0, __GXData->vcdLo, -12);
GX_WRITE_CP_STRM_REG_alt(CP_VCD_HI, 0, __GXData->vcdHi, -12);
__GXXfVtxSpecs();
}
void __GXCalculateVLim(void) {
static u8 tbl1[] = { 0, 4, 1, 2 };
static u8 tbl2[] = { 0, 8, 1, 2 };
static u8 tbl3[] = { 0, 12, 1, 2 };
if (__GXData->vNum != 0) {
GXCompCnt nc;
u32 vlm;
u32 b;
u32 vl;
u32 vh;
u32 va;
vl = __GXData->vcdLo;
vh = __GXData->vcdHi;
va = __GXData->vatA[0];
nc = CP_VAT_REG_A_GET_NRMCNT(va);
vlm = ((vl >> 0) & 0x1);
vlm += ((vl >> 1) & 0x1);
vlm += ((vl >> 2) & 0x1);
vlm += ((vl >> 3) & 0x1);
vlm += ((vl >> 4) & 0x1);
vlm += ((vl >> 5) & 0x1);
vlm += ((vl >> 6) & 0x1);
vlm += ((vl >> 7) & 0x1);
vlm += ((vl >> 8) & 0x1);
vlm += tbl3[((vl >> 9) & 0x3)];
b = (u32)((nc == GX_NRM_NBT) ? 3 : 1);
vlm += tbl3[((vl >> 11) & 0x3)] * b;
vlm += tbl1[((vl >> 13) & 0x3)];
vlm += tbl1[((vl >> 15) & 0x3)];
vlm += tbl2[((vh >> (0*2)) & 0x3)];
vlm += tbl2[((vh >> (1*2)) & 0x3)];
vlm += tbl2[((vh >> (2*2)) & 0x3)];
vlm += tbl2[((vh >> (3*2)) & 0x3)];
vlm += tbl2[((vh >> (4*2)) & 0x3)];
vlm += tbl2[((vh >> (5*2)) & 0x3)];
vlm += tbl2[((vh >> (6*2)) & 0x3)];
vlm += tbl2[((vh >> (7*2)) & 0x3)];
__GXData->vLim = (u16)vlm;
}
}
void GXGetVtxDesc(GXAttr attr, GXAttrType* type) {
u32 cpType;
CHECK_GXBEGIN(465, "GXGetVtxDesc");
CHECK_ATTRNAME3(467, attr);
switch (attr) {
case GX_VA_PNMTXIDX: cpType = CP_VCD_REG_LO_GET_PMIDX(__GXData->vcdLo); break;
case GX_VA_TEX0MTXIDX: cpType = CP_VCD_REG_LO_GET_T0MIDX(__GXData->vcdLo); break;
case GX_VA_TEX1MTXIDX: cpType = CP_VCD_REG_LO_GET_T1MIDX(__GXData->vcdLo); break;
case GX_VA_TEX2MTXIDX: cpType = CP_VCD_REG_LO_GET_T2MIDX(__GXData->vcdLo); break;
case GX_VA_TEX3MTXIDX: cpType = CP_VCD_REG_LO_GET_T3MIDX(__GXData->vcdLo); break;
case GX_VA_TEX4MTXIDX: cpType = CP_VCD_REG_LO_GET_T4MIDX(__GXData->vcdLo); break;
case GX_VA_TEX5MTXIDX: cpType = CP_VCD_REG_LO_GET_T5MIDX(__GXData->vcdLo); break;
case GX_VA_TEX6MTXIDX: cpType = CP_VCD_REG_LO_GET_T6MIDX(__GXData->vcdLo); break;
case GX_VA_TEX7MTXIDX: cpType = CP_VCD_REG_LO_GET_T7MIDX(__GXData->vcdLo); break;
case GX_VA_POS: cpType = CP_VCD_REG_LO_GET_POS(__GXData->vcdLo); break;
case GX_VA_NRM: cpType = __GXData->hasNrms ? CP_VCD_REG_LO_GET_NRM(__GXData->vcdLo) : 0; break;
case GX_VA_NBT: cpType = __GXData->hasBiNrms ? CP_VCD_REG_LO_GET_NRM(__GXData->vcdLo) : 0; break;
case GX_VA_CLR0: cpType = CP_VCD_REG_LO_GET_COL0(__GXData->vcdLo); break;
case GX_VA_CLR1: cpType = CP_VCD_REG_LO_GET_COL1(__GXData->vcdLo); break;
case GX_VA_TEX0: cpType = CP_VCD_REG_HI_GET_TEX0(__GXData->vcdHi); break;
case GX_VA_TEX1: cpType = CP_VCD_REG_HI_GET_TEX1(__GXData->vcdHi); break;
case GX_VA_TEX2: cpType = CP_VCD_REG_HI_GET_TEX2(__GXData->vcdHi); break;
case GX_VA_TEX3: cpType = CP_VCD_REG_HI_GET_TEX3(__GXData->vcdHi); break;
case GX_VA_TEX4: cpType = CP_VCD_REG_HI_GET_TEX4(__GXData->vcdHi); break;
case GX_VA_TEX5: cpType = CP_VCD_REG_HI_GET_TEX5(__GXData->vcdHi); break;
case GX_VA_TEX6: cpType = CP_VCD_REG_HI_GET_TEX6(__GXData->vcdHi); break;
case GX_VA_TEX7: cpType = CP_VCD_REG_HI_GET_TEX7(__GXData->vcdHi); break;
default: cpType = 0; break;
}
*type = cpType;
}
void GXGetVtxDescv(GXVtxDescList* vcd) {
GXAttr attr;
CHECK_GXBEGIN(518, "GXGetVtxDescv");
CHECK_ATTRPTR(520, vcd);
for (attr = GX_VA_PNMTXIDX; attr <= GX_VA_TEX7; attr++) {
vcd[attr].attr = attr;
GXGetVtxDesc(attr, &vcd[attr].type);
}
vcd[attr].attr = GX_VA_NBT;
GXGetVtxDesc(GX_VA_NBT, &vcd[attr].type);
attr++;
vcd[attr].attr = GX_VA_NULL;
}
void GXClearVtxDesc(void) {
CHECK_GXBEGIN(550, "GXClearVtxDesc");
__GXData->vcdLo = 0;
SC_CP_VCD_REG_LO_SET_POS(0, __GXData->vcdLo, GX_DIRECT);
__GXData->vcdHi = 0;
__GXData->hasNrms = 0;
__GXData->hasBiNrms = 0;
__GXData->dirtyState |= 8;
}
static inline void SETVAT(u32* va, u32* vb, u32* vc, GXAttr attr, GXCompCnt cnt, GXCompType type, u8 shft) {
switch (attr) {
case GX_VA_POS:
SC_CP_VAT_REG_A_SET_POSCNT(590, *va, cnt);
SC_CP_VAT_REG_A_SET_POSFMT(591, *va, type);
SC_CP_VAT_REG_A_SET_POSSHFT(592, *va, shft);
break;
case GX_VA_NRM:
case GX_VA_NBT:
SC_CP_VAT_REG_A_SET_NRMFMT(600, *va, type);
if (cnt == GX_NRM_NBT3) {
SC_CP_VAT_REG_A_SET_NRMCNT(0, *va, 1);
SC_CP_VAT_REG_A_SET_NORMALINDEX3(0, *va, 1);
} else {
SC_CP_VAT_REG_A_SET_NRMCNT(606, *va, cnt);
SC_CP_VAT_REG_A_SET_NORMALINDEX3(606, *va, 0);
}
break;
case GX_VA_CLR0:
SC_CP_VAT_REG_A_SET_COL0CNT(612, *va, cnt);
SC_CP_VAT_REG_A_SET_COL0FMT(613, *va, type);
break;
case GX_VA_CLR1:
SC_CP_VAT_REG_A_SET_COL1CNT(616, *va, cnt);
SC_CP_VAT_REG_A_SET_COL1FMT(617, *va, type);
break;
case GX_VA_TEX0:
SC_CP_VAT_REG_A_SET_TEX0CNT(620, *va, cnt);
SC_CP_VAT_REG_A_SET_TEX0FMT(621, *va, type);
SC_CP_VAT_REG_A_SET_TEX0SHFT(622, *va, shft);
break;
case GX_VA_TEX1:
SC_CP_VAT_REG_B_SET_TEX1CNT(625, *vb, cnt);
SC_CP_VAT_REG_B_SET_TEX1FMT(626, *vb, type);
SC_CP_VAT_REG_B_SET_TEX1SHFT(627, *vb, shft);
break;
case GX_VA_TEX2:
SC_CP_VAT_REG_B_SET_TEX2CNT(630, *vb, cnt);
SC_CP_VAT_REG_B_SET_TEX2FMT(631, *vb, type);
SC_CP_VAT_REG_B_SET_TEX2SHFT(632, *vb, shft);
break;
case GX_VA_TEX3:
SC_CP_VAT_REG_B_SET_TEX3CNT(635, *vb, cnt);
SC_CP_VAT_REG_B_SET_TEX3FMT(636, *vb, type);
SC_CP_VAT_REG_B_SET_TEX3SHFT(637, *vb, shft);
break;
case GX_VA_TEX4:
SC_CP_VAT_REG_B_SET_TEX4CNT(640, *vb, cnt);
SC_CP_VAT_REG_B_SET_TEX4FMT(641, *vb, type);
SC_CP_VAT_REG_C_SET_TEX4SHFT(642, *vc, shft);
break;
case GX_VA_TEX5:
SC_CP_VAT_REG_C_SET_TEX5CNT(645, *vc, cnt);
SC_CP_VAT_REG_C_SET_TEX5FMT(646, *vc, type);
SC_CP_VAT_REG_C_SET_TEX5SHFT(647, *vc, shft);
break;
case GX_VA_TEX6:
SC_CP_VAT_REG_C_SET_TEX6CNT(650, *vc, cnt);
SC_CP_VAT_REG_C_SET_TEX6FMT(651, *vc, type);
SC_CP_VAT_REG_C_SET_TEX6SHFT(652, *vc, shft);
break;
case GX_VA_TEX7:
SC_CP_VAT_REG_C_SET_TEX7CNT(655, *vc, cnt);
SC_CP_VAT_REG_C_SET_TEX7FMT(656, *vc, type);
SC_CP_VAT_REG_C_SET_TEX7SHFT(657, *vc, shft);
break;
}
}
void GXSetVtxAttrFmt(GXVtxFmt vtxfmt, GXAttr attr, GXCompCnt cnt, GXCompType type, u8 frac) {
u32* va;
u32* vb;
u32* vc;
CHECK_GXBEGIN(673, "GXSetVtxAttrFmt");
CHECK_VTXFMT(674, vtxfmt);
CHECK_ATTRNAME4(678, attr);
CHECK_FRAC(679, frac);
va = &__GXData->vatA[vtxfmt];
vb = &__GXData->vatB[vtxfmt];
vc = &__GXData->vatC[vtxfmt];
SETVAT(va, vb, vc, attr, cnt, type, frac);
#if DEBUG
__GXVerifyVATImm(attr, cnt, type, frac);
#endif
__GXData->dirtyState |= 0x10;
__GXData->dirtyVAT |= (u8)(1 << (u8)vtxfmt);
}
void GXSetVtxAttrFmtv(GXVtxFmt vtxfmt, const GXVtxAttrFmtList* list) {
u32* va;
u32* vb;
u32* vc;
CHECK_GXBEGIN(720, "GXSetVtxAttrFmtv");
CHECK_LISTPTR(721, list);
CHECK_VTXFMT(722, vtxfmt);
va = &__GXData->vatA[vtxfmt];
vb = &__GXData->vatB[vtxfmt];
vc = &__GXData->vatC[vtxfmt];
while (list->attr != GX_VA_NULL) {
CHECK_ATTRNAME4(732, list->attr);
CHECK_FRAC(733, list->frac);
SETVAT(va, vb, vc, list->attr, list->cnt, list->type, list->frac);
#if DEBUG
__GXVerifyVATImm(list->attr, list->cnt, list->type, list->frac);
#endif
list++;
}
__GXData->dirtyState |= 0x10;
__GXData->dirtyVAT |= (u8)(1 << (u8)vtxfmt);
}
void __GXSetVAT(void) {
s32 i;
u32 dirty = __GXData->dirtyVAT;
i = 0;
do {
if (dirty & 1) {
GX_WRITE_SOME_REG4(8, i | 0x70, __GXData->vatA[i], i - 12);
GX_WRITE_SOME_REG4(8, i | 0x80, __GXData->vatB[i], i - 12);
GX_WRITE_SOME_REG4(8, i | 0x90, __GXData->vatC[i], i - 12);
}
dirty >>= 1;
i++;
} while (dirty != 0);
GX_WRITE_U8(0);
__GXData->dirtyVAT = 0;
}
static inline u8 GetFracForNrm(GXCompType type) {
u8 frac;
switch (type) {
case GX_S8:
frac = 6;
break;
case GX_S16:
frac = 14;
break;
default:
case GX_U16:
frac = 0;
break;
}
return frac;
}
void GXGetVtxAttrFmt(GXVtxFmt fmt, GXAttr attr, GXCompCnt* cnt, GXCompType* type, u8* frac) {
u32* va;
u32* vb;
u32* vc;
CHECK_GXBEGIN(844, "GXGetVtxAttrFmt");
CHECK_VTXFMT(845, fmt);
va = &__GXData->vatA[fmt];
vb = &__GXData->vatB[fmt];
vc = &__GXData->vatC[fmt];
switch (attr) {
case GX_VA_POS:
*cnt = CP_VAT_REG_A_GET_POSCNT(*va);
*type = CP_VAT_REG_A_GET_POSFMT(*va);
*frac = CP_VAT_REG_A_GET_POSSHFT(*va);
return;
case GX_VA_NRM:
case GX_VA_NBT:
*cnt = CP_VAT_REG_A_GET_NRMCNT(*va);
if (*cnt == GX_TEX_ST && CP_VAT_REG_A_GET_NORMALINDEX3(*va)) {
*cnt = GX_NRM_NBT3;
}
*type = CP_VAT_REG_A_GET_NRMFMT(*va);
*frac = GetFracForNrm(*type);
return;
case GX_VA_CLR0:
*cnt = CP_VAT_REG_A_GET_COL0CNT(*va);
*type = CP_VAT_REG_A_GET_COL0FMT(*va);
*frac = 0;
return;
case GX_VA_CLR1:
*cnt = CP_VAT_REG_A_GET_COL1CNT(*va);
*type = CP_VAT_REG_A_GET_COL1FMT(*va);
*frac = 0;
return;
case GX_VA_TEX0:
*cnt = CP_VAT_REG_A_GET_TEX0CNT(*va);
*type = CP_VAT_REG_A_GET_TEX0FMT(*va);
*frac = CP_VAT_REG_A_GET_TEX0SHFT(*va);
return;
case GX_VA_TEX1:
*cnt = CP_VAT_REG_B_GET_TEX1CNT(*vb);
*type = CP_VAT_REG_B_GET_TEX1FMT(*vb);
*frac = CP_VAT_REG_B_GET_TEX1SHFT(*vb);
return;
case GX_VA_TEX2:
*cnt = CP_VAT_REG_B_GET_TEX2CNT(*vb);
*type = CP_VAT_REG_B_GET_TEX2FMT(*vb);
*frac = CP_VAT_REG_B_GET_TEX2SHFT(*vb);
return;
case GX_VA_TEX3:
*cnt = CP_VAT_REG_B_GET_TEX3CNT(*vb);
*type = CP_VAT_REG_B_GET_TEX3FMT(*vb);
*frac = CP_VAT_REG_B_GET_TEX3SHFT(*vb);
return;
case GX_VA_TEX4:
*cnt = CP_VAT_REG_B_GET_TEX4CNT(*vb);
*type = CP_VAT_REG_B_GET_TEX4FMT(*vb);
*frac = CP_VAT_REG_C_GET_TEX4SHFT(*vc);
return;
case GX_VA_TEX5:
*cnt = CP_VAT_REG_C_GET_TEX5CNT(*vc);
*type = CP_VAT_REG_C_GET_TEX5FMT(*vc);
*frac = CP_VAT_REG_C_GET_TEX5SHFT(*vc);
return;
case GX_VA_TEX6:
*cnt = CP_VAT_REG_C_GET_TEX6CNT(*vc);
*type = CP_VAT_REG_C_GET_TEX6FMT(*vc);
*frac = CP_VAT_REG_C_GET_TEX6SHFT(*vc);
return;
case GX_VA_TEX7:
*cnt = CP_VAT_REG_C_GET_TEX7CNT(*vc);
*type = CP_VAT_REG_C_GET_TEX7FMT(*vc);
*frac = CP_VAT_REG_C_GET_TEX7SHFT(*vc);
return;
default:
*cnt = GX_POS_XYZ;
*type = GX_U8;
*frac = 0;
return;
}
}
void GXGetVtxAttrFmtv(GXVtxFmt fmt, GXVtxAttrFmtList* vat) {
GXAttr attr;
CHECK_GXBEGIN(941, "GXGetVtxAttrFmtv");
CHECK_LISTPTR(942, vat);
CHECK_VTXFMT(943, fmt);
for (attr = GX_VA_POS; attr <= GX_VA_TEX7; attr++) {
vat->attr = attr;
GXGetVtxAttrFmt(fmt, attr, &vat->cnt, &vat->type, &vat->frac);
vat++;
}
vat->attr = GX_VA_NULL;
}
void GXSetArray(GXAttr attr, void* base_ptr, u8 stride) {
GXAttr cpAttr;
u32 phyAddr;
CHECK_GXBEGIN(974, "GXSetArray");
attr = (attr == GX_VA_NBT) ? GX_VA_NRM : attr;
CHECK_ATTRNAME5(977, attr);
cpAttr = (GXAttr)(attr - GX_VA_POS);
phyAddr = GX_PHY_ADDR(base_ptr);
GX_WRITE_CP_STRM_REG_alt2(CP_ARRAY_BASE, cpAttr, phyAddr, cpAttr - 12);
GX_WRITE_CP_STRM_REG_alt3(CP_ARRAY_STRIDE, cpAttr, (u32)stride, cpAttr - 12);
}
void GXInvalidateVtxCache(void) {
CHECK_GXBEGIN(999, "GXInvalidateVtxCache");
GX_WRITE_U8(0x48);
}
void GXSetTexCoordGen2(GXTexCoordID dst_coord, GXTexGenType func, GXTexGenSrc src_param, u32 mtx, GXBool normalize, u32 pt_texmtx) {
u32 reg = 0;
u32 row;
u32 bumprow;
u32 form;
GXAttr mtxIdAttr;
CHECK_GXBEGIN(1041, "GXSetTexCoordGen");
ASSERTMSGLINE(1042, dst_coord < GX_MAX_TEXCOORD, "GXSetTexCoordGen: Invalid coordinate Id");
form = 0;
row = bumprow = 5;
switch (src_param) {
case GX_TG_POS: row = 0; form = 1; break;
case GX_TG_NRM: row = 1; form = 1; break;
case GX_TG_BINRM: row = 3; form = 1; break;
case GX_TG_TANGENT: row = 4; form = 1; break;
case GX_TG_COLOR0: row = 2; break;
case GX_TG_COLOR1: row = 2; break;
case GX_TG_TEX0: row = 5; break;
case GX_TG_TEX1: row = 6; break;
case GX_TG_TEX2: row = 7; break;
case GX_TG_TEX3: row = 8; break;
case GX_TG_TEX4: row = 9; break;
case GX_TG_TEX5: row = 10; break;
case GX_TG_TEX6: row = 11; break;
case GX_TG_TEX7: row = 12; break;
case GX_TG_TEXCOORD0: bumprow = 5; break;
case GX_TG_TEXCOORD1: bumprow = 6; break;
case GX_TG_TEXCOORD2: bumprow = 7; break;
case GX_TG_TEXCOORD3: bumprow = 8; break;
case GX_TG_TEXCOORD4: bumprow = 9; break;
case GX_TG_TEXCOORD5: bumprow = 10; break;
case GX_TG_TEXCOORD6: bumprow = 11; break;
default:
ASSERTMSGLINE(1070, 0, "GXSetTexCoordGen: Invalid source parameter");
break;
}
switch (func) {
case GX_TG_MTX2x4:
SC_XF_TEX_SET_PROJECTION(1080, reg, 0);
SC_XF_TEX_SET_INPUT_FORM(1080, reg, form);
SC_XF_TEX_SET_TEXGEN_TYPE(1082, reg, 0);
SC_XF_TEX_SET_SOURCE_ROW(1082, reg, row);
break;
case GX_TG_MTX3x4:
SC_XF_TEX_SET_PROJECTION(1087, reg, 1);
SC_XF_TEX_SET_INPUT_FORM(1087, reg, form);
SC_XF_TEX_SET_TEXGEN_TYPE(1087, reg, 0);
SC_XF_TEX_SET_SOURCE_ROW(1089, reg, row);
break;
case GX_TG_BUMP0:
case GX_TG_BUMP1:
case GX_TG_BUMP2:
case GX_TG_BUMP3:
case GX_TG_BUMP4:
case GX_TG_BUMP5:
case GX_TG_BUMP6:
case GX_TG_BUMP7:
ASSERTMSGLINE(1102, src_param >= 12 && src_param <= 18, "GXSetTexCoordGen: Bump source texture value is invalid");
SC_XF_TEX_SET_PROJECTION(1104, reg, 0);
SC_XF_TEX_SET_INPUT_FORM(1104, reg, form);
SC_XF_TEX_SET_TEXGEN_TYPE(1106, reg, 1);
SC_XF_TEX_SET_SOURCE_ROW(1106, reg, row);
SC_XF_TEX_SET_BUMP_MAP_SOURCE(1107, reg, src_param - 12);
SC_XF_TEX_SET_BUMP_MAP_LIGHT(1108, reg, func - 2);
break;
case GX_TG_SRTG:
SC_XF_TEX_SET_PROJECTION(1113, reg, 0);
SC_XF_TEX_SET_INPUT_FORM(1113, reg, form);
if (src_param == GX_TG_COLOR0) {
SC_XF_TEX_SET_TEXGEN_TYPE(0, reg, 2);
} else {
SC_XF_TEX_SET_TEXGEN_TYPE(0, reg, 3);
}
SC_XF_TEX_SET_SOURCE_ROW(0, reg, 2);
break;
default:
ASSERTMSGLINE(1124, 0, "GXSetTexCoordGen: Invalid function");
break;
}
__GXData->texGenCtrl[dst_coord] = reg;
__GXData->dirtyState |= (0x10000 << dst_coord);
reg = 0;
SC_XF_DUALTEX_F_SET_DUALMATRIX_ADRS(1143, reg, pt_texmtx - 64);
SC_XF_DUALTEX_F_SET_NORMAL_ENABLE(1144, reg, normalize);
__GXData->texGenCtrl2[dst_coord] = reg;
switch (dst_coord) {
case GX_TEXCOORD0: SC_CP_MATIDX_REG_A_SET_TEX0IDX(1158, __GXData->matIdxA, mtx); break;
case GX_TEXCOORD1: SC_CP_MATIDX_REG_A_SET_TEX1IDX(1159, __GXData->matIdxA, mtx); break;
case GX_TEXCOORD2: SC_CP_MATIDX_REG_A_SET_TEX2IDX(1160, __GXData->matIdxA, mtx); break;
case GX_TEXCOORD3: SC_CP_MATIDX_REG_A_SET_TEX3IDX(1161, __GXData->matIdxA, mtx); break;
case GX_TEXCOORD4: SC_CP_MATIDX_REG_B_SET_TEX4IDX(1162, __GXData->matIdxB, mtx); break;
case GX_TEXCOORD5: SC_CP_MATIDX_REG_B_SET_TEX5IDX(1163, __GXData->matIdxB, mtx); break;
case GX_TEXCOORD6: SC_CP_MATIDX_REG_B_SET_TEX6IDX(1164, __GXData->matIdxB, mtx); break;
default: SC_CP_MATIDX_REG_B_SET_TEX7IDX(1165, __GXData->matIdxB, mtx); break;
}
mtxIdAttr = dst_coord + 1;
__GXData->dirtyState |= 0x4000000;
}
void GXSetNumTexGens(u8 nTexGens) {
CHECK_GXBEGIN(1183, "GXSetNumTexGens");
SC_GEN_MODE_SET_NTEX(1185, __GXData->genMode, nTexGens);
__GXData->dirtyState |= 0x2000004;
}

308
src/revolution/gx/GXBump.c Normal file
View File

@ -0,0 +1,308 @@
#include <revolution/gx.h>
#include <revolution/os.h>
#include "__gx.h"
#if DEBUG
#define GX_WRITE_SOME_REG5(a, b) \
do { \
GX_WRITE_U8(a); \
GX_WRITE_U32(b); \
__gxVerif->rasRegs[(b & 0xFF000000) >> 24] = b; \
} while (0)
#else
#define GX_WRITE_SOME_REG5(a, b) \
do { \
GX_WRITE_U8(a); \
GX_WRITE_U32(b); \
} while (0)
#endif
void GXSetTevIndirect(GXTevStageID tev_stage, GXIndTexStageID ind_stage, GXIndTexFormat format, GXIndTexBiasSel bias_sel, GXIndTexMtxID matrix_sel, GXIndTexWrap wrap_s, GXIndTexWrap wrap_t, GXBool add_prev, GXBool utc_lod, GXIndTexAlphaSel alpha_sel) {
u32 reg;
CHECK_GXBEGIN(150, "GXInitIndTexture");
reg = 0;
SC_BP_CMD_SET_BT(152, reg, ind_stage);
SC_BP_CMD_SET_FMT(153, reg, format);
SC_BP_CMD_SET_BIAS(154, reg, bias_sel);
SC_BP_CMD_SET_BS(155, reg, alpha_sel);
SC_BP_CMD_SET_M(156, reg, matrix_sel);
SC_BP_CMD_SET_SW(157, reg, wrap_s);
SC_BP_CMD_SET_TW(158, reg, wrap_t);
SC_BP_CMD_SET_LB(159, reg, utc_lod);
SC_BP_CMD_SET_FB(160, reg, add_prev);
SC_BP_CMD_SET_RID(161, reg, (0x10 + tev_stage));
GX_WRITE_SOME_REG5(GX_LOAD_BP_REG, reg);
__GXData->bpSentNot = 0;
}
void GXSetIndTexMtx(GXIndTexMtxID mtx_id, const f32 offset[2][3], s8 scale_exp) {
s32 mtx[6];
u32 reg;
u32 id;
CHECK_GXBEGIN(190, "GXSetIndTexMtx");
switch (mtx_id) {
case GX_ITM_0:
case GX_ITM_1:
case GX_ITM_2:
id = mtx_id - 1;
break;
case GX_ITM_S0:
case GX_ITM_S1:
case GX_ITM_S2:
id = mtx_id - 5;
break;
case GX_ITM_T0:
case GX_ITM_T1:
case GX_ITM_T2:
id = mtx_id - 9;
break;
default:
id = 0;
break;
}
mtx[0] = (int)(1024.0f * offset[0][0]) & 0x7FF;
mtx[1] = (int)(1024.0f * offset[1][0]) & 0x7FF;
scale_exp += 17;
reg = 0;
SC_BP_MTXA_SET_MA(212, reg, mtx[0]);
SC_BP_MTXA_SET_MB(213, reg, mtx[1]);
SC_BP_MTXA_SET_S(214, reg, scale_exp & 3);
SC_BP_MTXA_SET_RID(215, reg, id * 3 + 6);
GX_WRITE_SOME_REG5(GX_LOAD_BP_REG, reg);
mtx[2] = (int)(1024.0f * offset[0][1]) & 0x7FF;
mtx[3] = (int)(1024.0f * offset[1][1]) & 0x7FF;
reg = 0;
SC_BP_MTXB_SET_MC(221, reg, mtx[2]);
SC_BP_MTXB_SET_MD(222, reg, mtx[3]);
SC_BP_MTXB_SET_S(223, reg, (scale_exp >> 2) & 3);
SC_BP_MTXB_SET_RID(224, reg, id * 3 + 7);
GX_WRITE_SOME_REG5(GX_LOAD_BP_REG, reg);
mtx[4] = (int)(1024.0f * offset[0][2]) & 0x7FF;
mtx[5] = (int)(1024.0f * offset[1][2]) & 0x7FF;
reg = 0;
SC_BP_MTXC_SET_ME(230, reg, mtx[4]);
SC_BP_MTXC_SET_MF(231, reg, mtx[5]);
SC_BP_MTXC_SET_S(232, reg, (scale_exp >> 4) & 3);
SC_BP_MTXC_SET_RID(233, reg, id * 3 + 8);
GX_WRITE_SOME_REG5(GX_LOAD_BP_REG, reg);
__GXData->bpSentNot = 0;
}
void GXSetIndTexCoordScale(GXIndTexStageID ind_state, GXIndTexScale scale_s, GXIndTexScale scale_t) {
CHECK_GXBEGIN(253, "GXSetIndTexScale");
switch (ind_state) {
case GX_INDTEXSTAGE0:
SET_REG_FIELD(257, __GXData->IndTexScale0, 4, 0, scale_s);
SET_REG_FIELD(258, __GXData->IndTexScale0, 4, 4, scale_t);
SET_REG_FIELD(258, __GXData->IndTexScale0, 8, 24, 0x25);
GX_WRITE_SOME_REG5(GX_LOAD_BP_REG, __GXData->IndTexScale0);
break;
case GX_INDTEXSTAGE1:
SET_REG_FIELD(263, __GXData->IndTexScale0, 4, 8, scale_s);
SET_REG_FIELD(264, __GXData->IndTexScale0, 4, 12, scale_t);
SET_REG_FIELD(264, __GXData->IndTexScale0, 8, 24, 0x25);
GX_WRITE_SOME_REG5(GX_LOAD_BP_REG, __GXData->IndTexScale0);
break;
case GX_INDTEXSTAGE2:
SET_REG_FIELD(269, __GXData->IndTexScale1, 4, 0, scale_s);
SET_REG_FIELD(270, __GXData->IndTexScale1, 4, 4, scale_t);
SET_REG_FIELD(270, __GXData->IndTexScale1, 8, 24, 0x26);
GX_WRITE_SOME_REG5(GX_LOAD_BP_REG, __GXData->IndTexScale1);
break;
case GX_INDTEXSTAGE3:
SET_REG_FIELD(275, __GXData->IndTexScale1, 4, 8, scale_s);
SET_REG_FIELD(276, __GXData->IndTexScale1, 4, 12, scale_t);
SET_REG_FIELD(276, __GXData->IndTexScale1, 8, 24, 0x26);
GX_WRITE_SOME_REG5(GX_LOAD_BP_REG, __GXData->IndTexScale1);
break;
default:
ASSERTMSGLINE(281, 0, "GXSetIndTexCoordScale: Invalid Indirect Stage Id");
break;
}
__GXData->bpSentNot = 0;
}
void GXSetIndTexOrder(GXIndTexStageID ind_stage, GXTexCoordID tex_coord, GXTexMapID tex_map) {
CHECK_GXBEGIN(306, "GXSetIndTexOrder");
if (tex_map == GX_TEXMAP_NULL) {
tex_map = GX_TEXMAP0;
}
if (tex_coord == GX_TEXCOORD_NULL) {
tex_coord = GX_TEXCOORD0;
}
ASSERTMSGLINE(318, tex_map < GX_MAX_TEXMAP, "GXSetIndTexOrder: Invalid direct texture Id");
ASSERTMSGLINE(319, tex_coord < GX_MAX_TEXCOORD, "GXSetIndTexOrder: Invalid texture coord");
switch (ind_stage) {
case GX_INDTEXSTAGE0:
SET_REG_FIELD(323, __GXData->iref, 3, 0, tex_map);
SET_REG_FIELD(324, __GXData->iref, 3, 3, tex_coord);
break;
case GX_INDTEXSTAGE1:
SET_REG_FIELD(327, __GXData->iref, 3, 6, tex_map);
SET_REG_FIELD(328, __GXData->iref, 3, 9, tex_coord);
break;
case GX_INDTEXSTAGE2:
SET_REG_FIELD(331, __GXData->iref, 3, 12, tex_map);
SET_REG_FIELD(332, __GXData->iref, 3, 15, tex_coord);
break;
case GX_INDTEXSTAGE3:
SET_REG_FIELD(335, __GXData->iref, 3, 18, tex_map);
SET_REG_FIELD(336, __GXData->iref, 3, 21, tex_coord);
break;
default:
ASSERTMSGLINE(339, 0, "GXSetIndTexOrder: Invalid Indirect Stage Id");
break;
}
GX_WRITE_SOME_REG5(GX_LOAD_BP_REG, __GXData->iref);
__GXData->dirtyState |= 3;
__GXData->bpSentNot = 0;
}
void GXSetNumIndStages(u8 nIndStages) {
CHECK_GXBEGIN(357, "GXSetNumIndStages");
ASSERTMSGLINE(359, nIndStages <= 4, "GXSetNumIndStages: Exceeds max. number of indirect texture stages");
SET_REG_FIELD(360, __GXData->genMode, 3, 16, nIndStages);
__GXData->dirtyState |= 6;
}
void GXSetTevDirect(GXTevStageID tev_stage) {
CHECK_GXBEGIN(377, "GXSetTevDirect");
GXSetTevIndirect(tev_stage, GX_INDTEXSTAGE0, GX_ITF_8, GX_ITB_NONE, GX_ITM_OFF, GX_ITW_OFF, GX_ITW_OFF, GX_FALSE, GX_FALSE, GX_ITBA_OFF);
}
void GXSetTevIndWarp(GXTevStageID tev_stage, GXIndTexStageID ind_stage, u8 signed_offset, u8 replace_mode, GXIndTexMtxID matrix_sel) {
GXIndTexWrap wrap = (replace_mode != 0) ? GX_ITW_0 : GX_ITW_OFF;
CHECK_GXBEGIN(395, "GXSetTevIndWarp");
GXSetTevIndirect(tev_stage, ind_stage, GX_ITF_8, (signed_offset != 0) ? GX_ITB_STU : GX_ITB_NONE, matrix_sel, wrap, wrap, GX_FALSE, GX_FALSE, GX_ITBA_OFF);
}
void GXSetTevIndTile(GXTevStageID tev_stage, GXIndTexStageID ind_stage, u16 tilesize_s,
u16 tilesize_t, u16 tilespacing_s, u16 tilespacing_t, GXIndTexFormat format,
GXIndTexMtxID matrix_sel, GXIndTexBiasSel bias_sel, GXIndTexAlphaSel alpha_sel)
{
GXIndTexWrap wrap_s;
GXIndTexWrap wrap_t;
f32 mtx[2][3];
CHECK_GXBEGIN(429, "GXSetTevIndTile");
ASSERTMSGLINE(430, tev_stage < GX_MAX_TEVSTAGE, "GXSetTevIndTile: Invalid tev stage id");
ASSERTMSGLINE(431, ind_stage < GX_MAX_INDTEXSTAGE, "GXSetTevIndTile: Invalid indirect stage id");
switch (tilesize_s) {
case 256:
wrap_s = GX_ITW_256;
break;
case 128:
wrap_s = GX_ITW_128;
break;
case 64:
wrap_s = GX_ITW_64;
break;
case 32:
wrap_s = GX_ITW_32;
break;
case 16:
wrap_s = GX_ITW_16;
break;
default:
ASSERTMSGLINE(440, 0, "GXSetTevIndTile: Invalid tilesize for S coordinate");
wrap_s = GX_ITW_OFF;
break;
}
switch (tilesize_t) {
case 256:
wrap_t = GX_ITW_256;
break;
case 128:
wrap_t = GX_ITW_128;
break;
case 64:
wrap_t = GX_ITW_64;
break;
case 32:
wrap_t = GX_ITW_32;
break;
case 16:
wrap_t = GX_ITW_16;
break;
default:
ASSERTMSGLINE(452, 0, "GXSetTevIndTile: Invalid tilesize for T coordinate");
wrap_t = GX_ITW_OFF;
break;
}
mtx[0][0] = tilespacing_s / 1024.0f;
mtx[0][1] = mtx[0][2] = 0.0f;
mtx[1][1] = tilespacing_t / 1024.0f;
mtx[1][0] = mtx[1][2] = 0.0f;
GXSetIndTexMtx(matrix_sel, mtx, 10);
GXSetTevIndirect(tev_stage, ind_stage, format, bias_sel, matrix_sel, wrap_s, wrap_t, GX_FALSE, GX_TRUE, alpha_sel);
}
void GXSetTevIndBumpST(GXTevStageID tev_stage, GXIndTexStageID ind_stage, GXIndTexMtxID matrix_sel) {
GXIndTexMtxID sm;
GXIndTexMtxID tm;
CHECK_GXBEGIN(492, "GXSetTevIndBumpST");
switch (matrix_sel) {
case GX_ITM_0:
sm = GX_ITM_S0;
tm = GX_ITM_T0;
break;
case GX_ITM_1:
sm = GX_ITM_S1;
tm = GX_ITM_T1;
break;
case GX_ITM_2:
sm = GX_ITM_S2;
tm = GX_ITM_T2;
break;
default:
ASSERTMSGLINE(509, 0, "GXSetTevIndBumpST: Invalid matrix selection");
break;
}
GXSetTevIndirect(tev_stage, ind_stage, GX_ITF_8, GX_ITB_ST, sm, GX_ITW_0, GX_ITW_0, GX_FALSE, GX_FALSE, GX_ITBA_OFF);
GXSetTevIndirect(tev_stage + 1, ind_stage, GX_ITF_8, GX_ITB_ST, tm, GX_ITW_0, GX_ITW_0, GX_TRUE, GX_FALSE, GX_ITBA_OFF);
GXSetTevIndirect(tev_stage + 2, ind_stage, GX_ITF_8, GX_ITB_NONE, GX_ITM_OFF, GX_ITW_OFF, GX_ITW_OFF, GX_TRUE, GX_FALSE, GX_ITBA_OFF);
}
void GXSetTevIndBumpXYZ(GXTevStageID tev_stage, GXIndTexStageID ind_stage, GXIndTexMtxID matrix_sel) {
CHECK_GXBEGIN(561, "GXSetTevIndBumpXYZ");
GXSetTevIndirect(tev_stage, ind_stage, GX_ITF_8, GX_ITB_STU, matrix_sel, GX_ITW_OFF, GX_ITW_OFF, GX_FALSE, GX_FALSE, GX_ITBA_OFF);
}
void GXSetTevIndRepeat(GXTevStageID tev_stage) {
CHECK_GXBEGIN(590, "GXSetTevIndRepeat");
GXSetTevIndirect(tev_stage, GX_INDTEXSTAGE0, GX_ITF_8, GX_ITB_NONE, GX_ITM_OFF, GX_ITW_0, GX_ITW_0, GX_TRUE, GX_FALSE, GX_ITBA_OFF);
}
void __GXUpdateBPMask(void) {}
void __GXSetIndirectMask(u32 mask) {
SET_REG_FIELD(668, __GXData->bpMask, 8, ~0xFF, mask);
GX_WRITE_SOME_REG5(GX_LOAD_BP_REG, __GXData->bpMask);
__GXData->bpSentNot = 0;
}
void __GXFlushTextureState(void) {
GX_WRITE_SOME_REG5(GX_LOAD_BP_REG, __GXData->bpMask);
__GXData->bpSentNot = 0;
}

View File

@ -0,0 +1,99 @@
#include <string.h>
#include <revolution/gx.h>
#include <revolution/os.h>
#include "__gx.h"
static __GXFifoObj DisplayListFifo;
static volatile __GXFifoObj* OldCPUFifo;
static GXData __savedGXdata;
void GXBeginDisplayList(void* list, u32 size) {
__GXFifoObj* CPUFifo = (__GXFifoObj*)GXGetCPUFifo();
CHECK_GXBEGIN(137, "GXBeginDisplayList");
ASSERTMSGLINE(138, !__GXData->inDispList, "GXBeginDisplayList: display list already in progress");
ASSERTMSGLINE(139, (size & 0x1F) == 0, "GXBeginDisplayList: size is not 32 byte aligned");
ASSERTMSGLINE(140, ((u32)list & 0x1F) == 0, "GXBeginDisplayList: list is not 32 byte aligned");
if (__GXData->dirtyState != 0) {
__GXSetDirtyState();
}
if (__GXData->dlSaveContext != 0) {
memcpy(&__savedGXdata, __GXData, sizeof(__savedGXdata));
}
DisplayListFifo.base = (u8*)list;
DisplayListFifo.top = (u8*)list + size - 4;
DisplayListFifo.size = size;
DisplayListFifo.count = 0;
DisplayListFifo.rdPtr = list;
DisplayListFifo.wrPtr = list;
__GXData->inDispList = 1;
GXSaveCPUFifo((GXFifoObj*)CPUFifo);
OldCPUFifo = CPUFifo;
GXSetCPUFifo((GXFifoObj*)&DisplayListFifo);
GXResetWriteGatherPipe();
}
u32 GXEndDisplayList(void) {
u32 ov;
#if DEBUG
u32 reg;
#endif
BOOL enabled;
u32 cpenable;
CHECK_GXBEGIN(195, "GXEndDisplayList");
ASSERTMSGLINE(196, __GXData->inDispList == TRUE, "GXEndDisplayList: no display list in progress");
GXFlush();
#if DEBUG
reg = GX_GET_PI_REG(5);
ov = (reg >> 26) & 1;
#else
ov = (GX_GET_PI_REG(5) >> 26) & 1;
#endif
__GXSaveCPUFifoAux(&DisplayListFifo);
ASSERTMSGLINE(213, !ov, "GXEndDisplayList: display list commands overflowed buffer");
GXSetCPUFifo((GXFifoObj*)OldCPUFifo);
if (__GXData->dlSaveContext != 0) {
enabled = OSDisableInterrupts();
cpenable = __GXData->cpEnable;
memcpy(__GXData, &__savedGXdata, sizeof(*__GXData));
__GXData->cpEnable = cpenable;
OSRestoreInterrupts(enabled);
}
__GXData->inDispList = 0;
if (!ov) {
return DisplayListFifo.count;
}
return 0;
}
void GXCallDisplayList(void* list, u32 nbytes) {
CHECK_GXBEGIN(272, "GXCallDisplayList");
ASSERTMSGLINE(273, !__GXData->inDispList, "GXCallDisplayList: display list already in progress");
ASSERTMSGLINE(274, (nbytes & 0x1F) == 0, "GXCallDisplayList: nbytes is not 32 byte aligned");
ASSERTMSGLINE(275, ((u32)list & 0x1F) == 0, "GXCallDisplayList: list is not 32 byte aligned");
if (__GXData->dirtyState != 0) {
__GXSetDirtyState();
}
#if DEBUG
__GXShadowDispList(list, nbytes);
#endif
if (*(u32*)&__GXData->vNumNot == 0) { // checks both vNum and bpSent
__GXSendFlushPrim();
}
GX_WRITE_U8(GX_CMD_CALL_DL);
GX_WRITE_U32(list);
GX_WRITE_U32(nbytes);
}

551
src/revolution/gx/GXDraw.c Normal file
View File

@ -0,0 +1,551 @@
#include <math.h>
#include <revolution/gx.h>
#include <revolution/os.h>
#include "__gx.h"
static GXVtxDescList vcd[27];
static GXVtxAttrFmtList vat[27];
static void GetVertState(void) {
GXGetVtxDescv(vcd);
GXGetVtxAttrFmtv(GX_VTXFMT3, vat);
GXClearVtxDesc();
GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
GXSetVtxDesc(GX_VA_NRM, GX_DIRECT);
GXSetVtxAttrFmt(GX_VTXFMT3, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
GXSetVtxAttrFmt(GX_VTXFMT3, GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0);
}
static void RestoreVertState(void) {
GXSetVtxDescv(vcd);
GXSetVtxAttrFmtv(GX_VTXFMT3, vat);
}
static void vsub(f32 p1[3], f32 p2[3], f32 u[3]) {
u32 i;
for (i = 0; i < 3; i++) {
u[i] = p2[i] - p1[i];
}
}
static void vcross(f32 u[3], f32 v[3], f32 n[3]) {
f32 n1[3];
n1[0] = (u[1] * v[2]) - (u[2] * v[1]);
n1[1] = (u[2] * v[0]) - (u[0] * v[2]);
n1[2] = (u[0] * v[1]) - (u[1] * v[0]);
n[0] = n1[0];
n[1] = n1[1];
n[2] = n1[2];
}
static void normalize(f32 v[3]) {
f32 d = sqrtf((v[0] * v[0]) + (v[1] * v[1]) + (v[2] * v[2]));
ASSERTMSGLINE(137, d != 0.0f, "normalize: zero length vector");
v[0] /= d;
v[1] /= d;
v[2] /= d;
}
static void myvertex(f32 v[3], f32 n[3]) {
GXPosition3f32(v[0], v[1], v[2]);
GXNormal3f32(n[0], n[1], n[2]);
}
static void DumpTriangle(f32 v0[3], f32 v1[3], f32 v2[3]) {
GXBegin(GX_TRIANGLES, GX_VTXFMT3, 3);
myvertex(v0, v0);
myvertex(v1, v1);
myvertex(v2, v2);
GXEnd();
}
static void Subdivide(u8 depth, f32 v0[3], f32 v1[3], f32 v2[3]) {
f32 v01[3];
f32 v12[3];
f32 v20[3];
u32 i;
if (depth == 0) {
DumpTriangle(v0, v1, v2);
return;
}
for (i = 0; i < 3; i++) {
v01[i] = v0[i] + v1[i];
v12[i] = v1[i] + v2[i];
v20[i] = v2[i] + v0[i];
}
normalize(v01);
normalize(v12);
normalize(v20);
Subdivide(depth - 1, v0, v01, v20);
Subdivide(depth - 1, v1, v12, v01);
Subdivide(depth - 1, v2, v20, v12);
Subdivide(depth - 1, v01, v12, v20);
}
static void SubDivTriangle(u8 depth, u8 i, f32 (*data)[3], u8 (*ndx)[3]) {
f32 *x0 = data[ndx[i][0]];
f32 *x1 = data[ndx[i][1]];
f32 *x2 = data[ndx[i][2]];
Subdivide(depth, x0, x1, x2);
}
void GXDrawCylinder(u8 numEdges) {
s32 i;
f32 top;
f32 bottom;
f32 x[100];
f32 y[100];
f32 angle;
top = 1.0f;
bottom = -top;
ASSERTMSGLINE(222, numEdges <= 99, "GXDrawCylinder: too many edges");
GetVertState();
for (i = 0; i <= numEdges; i++) {
angle = (3.1415927f * (2.0f * i)) / numEdges;
x[i] = cosf(angle);
y[i] = sinf(angle);
}
GXBegin(GX_TRIANGLESTRIP, GX_VTXFMT3, (numEdges + 1) * 2);
for (i = 0; i <= numEdges; i++) {
GXPosition3f32(x[i], y[i], bottom);
GXNormal3f32(x[i], y[i], 0.0f);
GXPosition3f32(x[i], y[i], top);
GXNormal3f32(x[i], y[i], 0.0f);
}
GXEnd();
GXBegin(GX_TRIANGLEFAN, GX_VTXFMT3, numEdges + 2);
GXPosition3f32(0.0f, 0.0f, top);
GXNormal3f32(0.0f, 0.0f, 1.0f);
for (i = 0; i <= numEdges; i++) {
GXPosition3f32(x[i], -y[i], top);
GXNormal3f32(0.0f, 0.0f, 1.0f);
}
GXEnd();
GXBegin(GX_TRIANGLEFAN, GX_VTXFMT3, numEdges + 2);
GXPosition3f32(0.0f, 0.0f, bottom);
GXNormal3f32(0.0f, 0.0f, -1.0f);
for (i = 0; i <= numEdges; i++) {
GXPosition3f32(x[i], y[i], bottom);
GXNormal3f32(0.0f, 0.0f, -1.0f);
}
GXEnd();
RestoreVertState();
}
void GXDrawTorus(f32 rc, u8 numc, u8 numt) {
GXAttrType ttype;
s32 i, j, k;
f32 s, t;
f32 x, y, z;
f32 twopi = 6.2831855f;
f32 rt;
ASSERTMSGLINE(316, rc < 1.0f, "GXDrawTorus: doughnut too fat");
rt = 1.0f - rc;
GXGetVtxDesc(GX_VA_TEX0, &ttype);
GetVertState();
if (ttype != GX_NONE) {
GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
GXSetVtxAttrFmt(GX_VTXFMT3, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
}
for (i = 0; i < numc; i++) {
GXBegin(GX_TRIANGLESTRIP, GX_VTXFMT3, (numt + 1) * 2);
for (j = 0; j <= numt; j++) {
for (k = 1; k >= 0; k--) {
s = (i + k) % numc;
t = j % numt;
x = (rt - rc * cosf(s * twopi / numc)) * cosf(t * twopi / numt);
y = (rt - rc * cosf(s * twopi / numc)) * sinf(t * twopi / numt);
z = rc * sinf(s * twopi / numc);
GXPosition3f32(x, y, z);
x = -cosf(t * twopi / numt) * cosf(s * twopi / numc);
y = -sinf(t * twopi / numt) * cosf(s * twopi / numc);
z = sinf(s * twopi / numc);
GXNormal3f32(x, y, z);
if (ttype != GX_NONE) {
GXTexCoord2f32((i + k) / (f32)numc, j / (f32)numt);
}
}
}
GXEnd();
}
RestoreVertState();
}
void GXDrawSphere(u8 numMajor, u8 numMinor) {
GXAttrType ttype;
f32 radius = 1.0f;
f32 majorStep = 3.1415927f / numMajor;
f32 minorStep = 6.2831855f / numMinor;
s32 i, j;
f32 a, b;
f32 r0, r1;
f32 z0, z1;
f32 c;
GXGetVtxDesc(GX_VA_TEX0, &ttype);
GetVertState();
if (ttype != GX_NONE) {
GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
GXSetVtxAttrFmt(GX_VTXFMT3, GX_VA_TEX0, GX_TEX_ST, GX_RGBA6, 0);
}
for (i = 0; i < numMajor; i++) {
a = i * majorStep;
b = a + majorStep;
r0 = radius * sinf(a);
r1 = radius * sinf(b);
z0 = radius * cosf(a);
z1 = radius * cosf(b);
GXBegin(GX_TRIANGLESTRIP, GX_VTXFMT3, (numMinor + 1) * 2);
for (j = 0; j <= numMinor; j++) {
f32 x, y;
c = j * minorStep;
x = cosf(c);
y = sinf(c);
GXPosition3f32(x * r1, y * r1, z1);
GXNormal3f32((x * r1) / radius, (y * r1) / radius, z1 / radius);
if (ttype != GX_NONE) {
GXTexCoord2f32((f32)j / (f32)numMinor, (f32)(i + 1) / (f32)numMajor);
}
GXPosition3f32(x * r0, y * r0, z0);
GXNormal3f32((x * r0) / radius, (y * r0) / radius, z0 / radius);
if (ttype != GX_NONE) {
GXTexCoord2f32((f32)j / (f32)numMinor, (f32)i / (f32)numMajor);
}
}
GXEnd();
}
RestoreVertState();
}
static void GXDrawCubeFace(f32 nx, f32 ny, f32 nz, f32 tx, f32 ty, f32 tz, f32 bx, f32 by, f32 bz, GXAttrType binormal, GXAttrType texture) {
GXPosition3f32(0.57735026f * (nx + tx + bx), 0.57735026f * (ny + ty + by), 0.57735026f * (nz + tz + bz));
GXNormal3f32(nx, ny, nz);
if (binormal != GX_NONE) {
GXNormal3f32(tx, ty, tz);
GXNormal3f32(bx, by, bz);
}
if (texture != GX_NONE) {
GXTexCoord2s8(1, 1);
}
GXPosition3f32(0.57735026f * (nx - tx + bx), 0.57735026f * (ny - ty + by), 0.57735026f * (nz - tz + bz));
GXNormal3f32(nx, ny, nz);
if (binormal != GX_NONE) {
GXNormal3f32(tx, ty, tz);
GXNormal3f32(bx, by, bz);
}
if (texture != GX_NONE) {
GXTexCoord2s8(0, 1);
}
GXPosition3f32(0.57735026f * (nx - tx - bx), 0.57735026f * (ny - ty - by), 0.57735026f * (nz - tz - bz));
GXNormal3f32(nx, ny, nz);
if (binormal != GX_NONE) {
GXNormal3f32(tx, ty, tz);
GXNormal3f32(bx, by, bz);
}
if (texture != GX_NONE) {
GXTexCoord2s8(0, 0);
}
GXPosition3f32(0.57735026f * (nx + tx - bx), 0.57735026f * (ny + ty - by), 0.57735026f * (nz + tz - bz));
GXNormal3f32(nx, ny, nz);
if (binormal != GX_NONE) {
GXNormal3f32(tx, ty, tz);
GXNormal3f32(bx, by, bz);
}
if (texture != GX_NONE) {
GXTexCoord2s8(1, 0);
}
}
void GXDrawCube(void) {
GXAttrType ntype;
GXAttrType ttype;
GXGetVtxDesc(GX_VA_NBT, &ntype);
GXGetVtxDesc(GX_VA_TEX0, &ttype);
GetVertState();
if (ntype != GX_NONE) {
GXSetVtxDesc(GX_VA_NBT, GX_DIRECT);
GXSetVtxAttrFmt(GX_VTXFMT3, GX_VA_NBT, GX_TEX_ST, GX_RGBA6, 0);
}
if (ttype != GX_NONE) {
GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
GXSetVtxAttrFmt(GX_VTXFMT3, GX_VA_TEX0, GX_TEX_ST, GX_RGB8, 0);
}
GXBegin(GX_QUADS, GX_VTXFMT3, 24);
GXDrawCubeFace(-1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, ntype, ttype);
GXDrawCubeFace(1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f, ntype, ttype);
GXDrawCubeFace(0.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, ntype, ttype);
GXDrawCubeFace(0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, ntype, ttype);
GXDrawCubeFace(0.0f, 0.0f, -1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, ntype, ttype);
GXDrawCubeFace(0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, ntype, ttype);
GXEnd();
RestoreVertState();
}
static u32 polygons[12][5] = {
{ 0, 12, 10, 11, 16 },
{ 1, 17, 8, 9, 13 },
{ 2, 14, 9, 8, 18 },
{ 3, 19, 11, 10, 15 },
{ 4, 14, 2, 3, 15 },
{ 5, 12, 0, 1, 13 },
{ 6, 17, 1, 0, 16 },
{ 7, 19, 3, 2, 18 },
{ 8, 17, 6, 7, 18 },
{ 9, 14, 4, 5, 13 },
{ 10, 12, 5, 4, 15 },
{ 11, 19, 7, 6, 16 },
};
static f32 verts[20][3] = {
{ -0.809015f, 0.0f, 0.309015f },
{ -0.809015f, 0.0f, -0.309015f },
{ 0.809015f, 0.0f, -0.309015f },
{ 0.809015f, 0.0f, 0.309015f },
{ 0.309015f, -0.809015f, 0.0f },
{ -0.309015f, -0.809015f, 0.0f },
{ -0.309015f, 0.809015f, 0 },
{ 0.309015f, 0.809015f, 0 },
{ 0.0f, 0.309015f, -0.809015f },
{ 0.0f, -0.309015f, -0.809015f },
{ 0.0f, -0.309015f, 0.809015f },
{ 0.0f, 0.309015f, 0.809015f },
{ -0.5f, -0.5f, 0.5 },
{ -0.5f, -0.5f, -0.5 },
{ 0.5f, -0.5f, -0.5 },
{ 0.5f, -0.5f, 0.5 },
{ -0.5f, 0.5f, 0.5 },
{ -0.5f, 0.5f, -0.5 },
{ 0.5f, 0.5f, -0.5 },
{ 0.5f, 0.5f, 0.5 },
};
void GXDrawDodeca(void) {
u32 i;
f32 *p0;
f32 *p1;
f32 *p2;
f32 u[3];
f32 v[3];
f32 n[3];
GetVertState();
for (i = 0; i < 12; i++) {
p0 = verts[polygons[i][0]];
p1 = verts[polygons[i][1]];
p2 = verts[polygons[i][2]];
vsub(p1, p2, u);
vsub(p1, p0, v);
vcross(u, v, n);
normalize(n);
GXBegin(GX_TRIANGLEFAN, GX_VTXFMT3, 5);
myvertex(verts[polygons[i][4]], n);
myvertex(verts[polygons[i][3]], n);
myvertex(p2, n);
myvertex(p1, n);
myvertex(p0, n);
GXEnd();
}
RestoreVertState();
}
static f32 odata[6][3] = {
{ 1.0f, 0.0f, 0.0f },
{ -1.0f, 0.0f, 0.0f },
{ 0.0f, 1.0f, 0.0f },
{ 0.0f, -1.0f, 0.0f },
{ 0.0f, 0.0f, 1.0f },
{ 0.0f, 0.0f, -1.0f },
};
static u8 ondex[8][3] = {
{ 0, 4, 2 },
{ 1, 2, 4 },
{ 0, 3, 4 },
{ 1, 4, 3 },
{ 0, 2, 5 },
{ 1, 5, 2 },
{ 0, 5, 3 },
{ 1, 3, 5 },
};
void GXDrawOctahedron(void) {
s32 i;
GetVertState();
for (i = 7; i >= 0; i--) {
SubDivTriangle(0, i, odata, ondex);
}
RestoreVertState();
}
static f32 idata[12][3] = {
{ -0.5257311f, 0.0f, 0.8506508f },
{ 0.5257311f, 0.0f, 0.8506508f },
{ -0.5257311f, 0.0f, -0.8506508f },
{ 0.5257311f, 0.0f, -0.8506508f },
{ 0.0f, 0.8506508f, 0.5257311f },
{ 0.0f, 0.8506508f, -0.5257311f },
{ 0.0f, -0.8506508f, 0.5257311f },
{ 0.0f, -0.8506508f, -0.5257311f },
{ 0.8506508f, 0.5257311f, 0.0f },
{ -0.8506508f, 0.5257311f, 0.0f },
{ 0.8506508f, -0.5257311f, 0.0f },
{ -0.8506508f, -0.5257311f, 0.0f },
};
static u8 index[20][3] = {
{ 0, 4, 1 },
{ 0, 9, 4 },
{ 9, 5, 4 },
{ 4, 5, 8 },
{ 4, 8, 1 },
{ 8, 10, 1 },
{ 8, 3, 10 },
{ 5, 3, 8 },
{ 5, 2, 3 },
{ 2, 7, 3 },
{ 7, 10, 3 },
{ 7, 6, 10 },
{ 7, 11, 6 },
{ 11, 0, 6 },
{ 0, 1, 6 },
{ 6, 1, 10 },
{ 9, 0, 11 },
{ 9, 11, 2 },
{ 9, 2, 5 },
{ 7, 2, 11 },
};
void GXDrawIcosahedron(void) {
s32 i;
GetVertState();
for (i = 19; i >= 0; i--) {
SubDivTriangle(0, i, idata, index);
}
RestoreVertState();
}
void GXDrawSphere1(u8 depth) {
s32 i;
GetVertState();
for (i = 19; i >= 0; i--) {
SubDivTriangle(depth, i, idata, index);
}
RestoreVertState();
}
static u32 CmpNormal32(f32 n1[3], f32 n2[3]) {
u32 i;
for (i = 0; i < 3; i++) {
if (n1[i] != n2[i])
return FALSE;
}
return TRUE;
}
static u32 nrm_cnt;
static f32* nrm_tab;
static void AddNormal(f32 n[3]) {
u32 indx;
u32 i;
for (i = 0; i < nrm_cnt; i++) {
if (CmpNormal32(n, &nrm_tab[i * 3]))
return;
}
indx = nrm_cnt * 3;
nrm_tab[indx + 0] = n[0];
nrm_tab[indx + 1] = n[1];
nrm_tab[indx + 2] = n[2];
nrm_cnt++;
}
static void SubdivideNrm(u8 depth, f32 v0[3], f32 v1[3], f32 v2[3]) {
f32 v01[3];
f32 v12[3];
f32 v20[3];
u32 i;
if (depth == 0) {
AddNormal(v0);
AddNormal(v1);
AddNormal(v2);
return;
}
for (i = 0; i < 3; i++) {
v01[i] = v0[i] + v1[i];
v12[i] = v1[i] + v2[i];
v20[i] = v2[i] + v0[i];
}
normalize(v01);
normalize(v12);
normalize(v20);
SubdivideNrm(depth - 1, v0, v01, v20);
SubdivideNrm(depth - 1, v1, v12, v01);
SubdivideNrm(depth - 1, v2, v20, v12);
SubdivideNrm(depth - 1, v01, v12, v20);
}
static void SubDivNrm(u8 depth, u8 i, f32 (*data)[3], u8 (*ndx)[3]) {
f32* x0 = data[ndx[i][0]];
f32* x1 = data[ndx[i][1]];
f32* x2 = data[ndx[i][2]];
SubdivideNrm(depth, x0, x1, x2);
}
u32 GXGenNormalTable(u8 depth, f32* table) {
s32 i;
nrm_cnt = 0;
nrm_tab = table;
for (i = 7; i >= 0; i--) {
SubDivNrm(depth, i, odata, ondex);
}
return nrm_cnt;
}

614
src/revolution/gx/GXFifo.c Normal file
View File

@ -0,0 +1,614 @@
#include <revolution/base/PPCArch.h>
#include <revolution/gx.h>
#include <revolution/os.h>
#include "__gx.h"
#define TOPHYSICAL(a) (((u32)a) & 0x3FFFFFFF)
static __GXFifoObj CPUFifo;
static __GXFifoObj GPFifo;
static GXBool CPUFifoReady = FALSE;
static GXBool GPFifoReady = FALSE;
static GXBool CPGPLinked;
static OSThread* __GXCurrentThread;
static BOOL GXOverflowSuspendInProgress;
static GXBreakPtCallback BreakPointCB;
void* __GXCurrentBP;
static u32 __GXOverflowCount;
#if DEBUG
static BOOL IsWGPipeRedirected;
#endif
static void __GXFifoReadEnable(void);
static void __GXFifoReadDisable(void);
static void __GXFifoLink(u8 en);
static void __GXWriteFifoIntEnable(u8 hiWatermarkEn, u8 loWatermarkEn);
static void __GXWriteFifoIntReset(u8 hiWatermarkClr, u8 loWatermarkClr);
GXBool CPGPLinkCheck(void);
static void GXOverflowHandler(__OSInterrupt interrupt, OSContext* context) {
#if DEBUG
if (__gxVerif->verifyLevel > GX_WARN_SEVERE) {
OSReport("[GXOverflowHandler]");
}
#endif
ASSERTLINE(417, !GXOverflowSuspendInProgress);
__GXOverflowCount++;
__GXWriteFifoIntEnable(0, 1);
__GXWriteFifoIntReset(1, 0);
GXOverflowSuspendInProgress = TRUE;
#if DEBUG
if (__gxVerif->verifyLevel > GX_WARN_SEVERE) {
OSReport("[GXOverflowHandler Sleeping]");
}
#endif
OSSuspendThread(__GXCurrentThread);
}
static void GXUnderflowHandler(s16 interrupt, OSContext* context) {
#if DEBUG
if (__gxVerif->verifyLevel > GX_WARN_SEVERE) {
OSReport("[GXUnderflowHandler]");
}
#endif
ASSERTLINE(459, GXOverflowSuspendInProgress);
OSResumeThread(__GXCurrentThread);
GXOverflowSuspendInProgress = FALSE;
__GXWriteFifoIntReset(1, 1);
__GXWriteFifoIntEnable(1, 0);
}
static void GXBreakPointHandler(__OSInterrupt interrupt, OSContext* context) {
OSContext exceptionContext;
SC_CP_REG_ENABLE_SET_FIFOBRKINT(0, __GXData->cpEnable, 0);
GX_CP_REG_WRITE_U16(CP_ENABLE, __GXData->cpEnable);
if (BreakPointCB != 0) {
OSClearContext(&exceptionContext);
OSSetCurrentContext(&exceptionContext);
BreakPointCB();
OSClearContext(&exceptionContext);
OSSetCurrentContext(context);
}
}
static void GXCPInterruptHandler(__OSInterrupt interrupt, OSContext* context) {
__GXData->cpStatus = GX_GET_CP_REG(0);
if (CP_REG_ENABLE_GET_UNFLINT(__GXData->cpEnable) && CP_REG_STATUS_GET_UNFL(__GXData->cpStatus)) {
GXUnderflowHandler(interrupt, context);
}
if (CP_REG_ENABLE_GET_OVFLINT(__GXData->cpEnable) && CP_REG_STATUS_GET_OVFL(__GXData->cpStatus)) {
GXOverflowHandler(interrupt, context);
}
if (CP_REG_ENABLE_GET_FIFOBRKINT(__GXData->cpEnable) && CP_REG_STATUS_GET_FIFOBRK(__GXData->cpStatus)) {
GXBreakPointHandler(interrupt, context);
}
}
void GXInitFifoBase(GXFifoObj* fifo, void* base, u32 size) {
__GXFifoObj* realFifo = (__GXFifoObj*)fifo;
ASSERTMSGLINE(582, ((u32)base & 0x1F) == 0, "GXInitFifoBase: base must be 32B aligned");
ASSERTMSGLINE(584, base != 0, "GXInitFifoBase: base pointer is NULL");
ASSERTMSGLINE(586, (size & 0x1F) == 0, "GXInitFifoBase: size must be 32B aligned");
ASSERTMSGLINE(588, size >= 0x10000, "GXInitFifoBase: fifo is not large enough");
realFifo->base = base;
realFifo->top = (u8*)base + size - 4;
realFifo->size = size;
realFifo->count = 0;
GXInitFifoLimits(fifo, size - 0x4000, (size >> 1) & ~0x1F);
GXInitFifoPtrs(fifo, base, base);
}
void GXInitFifoPtrs(GXFifoObj* fifo, void* readPtr, void* writePtr) {
__GXFifoObj* realFifo = (__GXFifoObj *)fifo;
BOOL enabled;
ASSERTMSGLINE(628, ((u32)readPtr & 0x1F) == 0, "GXInitFifoPtrs: readPtr not 32B aligned");
ASSERTMSGLINE(630, ((u32)writePtr & 0x1F) == 0, "GXInitFifoPtrs: writePtr not 32B aligned");
ASSERTMSGLINE(633, realFifo->base <= readPtr && readPtr < realFifo->top, "GXInitFifoPtrs: readPtr not in fifo range");
ASSERTMSGLINE(636, realFifo->base <= writePtr && writePtr < realFifo->top, "GXInitFifoPtrs: writePtr not in fifo range");
enabled = OSDisableInterrupts();
realFifo->rdPtr = readPtr;
realFifo->wrPtr = writePtr;
realFifo->count = (u8*)writePtr - (u8*)readPtr;
if (realFifo->count < 0) {
realFifo->count += realFifo->size;
}
OSRestoreInterrupts(enabled);
}
void GXInitFifoLimits(GXFifoObj* fifo, u32 hiWatermark, u32 loWatermark) {
__GXFifoObj* realFifo = (__GXFifoObj*)fifo;
ASSERTMSGLINE(674, (hiWatermark & 0x1F) == 0, "GXInitFifoLimits: hiWatermark not 32B aligned");
ASSERTMSGLINE(676, (loWatermark & 0x1F) == 0, "GXInitFifoLimits: loWatermark not 32B aligned");
ASSERTMSGLINE(678, hiWatermark < realFifo->top - realFifo->base, "GXInitFifoLimits: hiWatermark too large");
ASSERTMSGLINE(680, loWatermark < hiWatermark, "GXInitFifoLimits: hiWatermark below lo watermark");
realFifo->hiWatermark = hiWatermark;
realFifo->loWatermark = loWatermark;
}
GXBool CPGPLinkCheck(void) {
u32 check = 0;
s32 range1, range2, overlap;
if (!CPUFifoReady || !GPFifoReady) {
return GX_FALSE;
}
if (CPUFifo.base == GPFifo.base) {
++check;
}
if (CPUFifo.top == GPFifo.top) {
++check;
}
if (check == 2) {
if (CPUFifo.hiWatermark == GPFifo.hiWatermark) {
++check;
}
if (CPUFifo.loWatermark == GPFifo.loWatermark) {
++check;
}
ASSERTMSGLINE(722, check == 4, "GXSetGPFifo/GXSetCPUFifo: mismatch of watermark parameter");
return GX_TRUE;
}
range1 = (s32)((u8*)CPUFifo.top - (u8*)GPFifo.base);
range2 = (s32)((u8*)GPFifo.top - (u8*)CPUFifo.base);
overlap = ((range1 > 0) && (range2 > 0) || (range1 < 0 && (range2 < 0)));
if (overlap) {
OSReport("CPUFifo: %08X - %08X\n", (u32)CPUFifo.base, (u32)CPUFifo.top);
OSReport("GP Fifo: %08X - %08X\n", (u32)GPFifo.base, (u32)GPFifo.top);
}
ASSERTMSGLINE(736, !overlap, "GXSetGPFifo/GXSetCPUFifo: invalid overlap of both buffers");
return GX_FALSE;
}
// NONMATCHING DEBUG
void GXSetCPUFifo(GXFifoObj* fifo) {
__GXFifoObj* realFifo = (__GXFifoObj*)fifo;
BOOL enabled = OSDisableInterrupts();
u32 reg;
if (fifo == NULL) {
CPUFifoReady = GX_FALSE;
CPGPLinked = GX_FALSE;
CPUFifo.bind_cpu = CPUFifo.bind_gp = GX_FALSE;
OSRestoreInterrupts(enabled);
return;
}
CPUFifo = *realFifo;
CPUFifoReady = GX_TRUE;
CPUFifo.bind_cpu = GX_TRUE;
if (CPGPLinkCheck()) {
CPGPLinked = GX_TRUE;
CPUFifo.bind_gp = GX_TRUE;
reg = 0;
GX_PI_REG_WRITE_U32(PI_REG_CPBAS, TOPHYSICAL(CPUFifo.base));
GX_PI_REG_WRITE_U32(PI_REG_CPTOP, TOPHYSICAL(CPUFifo.top));
SC_PI_CPWRT_REG_SET_CPWRT(787, reg, (GX_PHY_ADDR(TOPHYSICAL(CPUFifo.wrPtr)) >> 5));
SC_PI_CPWRT_REG_SET_CPWRAP(0, reg, 0);
GX_PI_REG_WRITE_U32(PI_REG_CPWRT, reg);
__GXWriteFifoIntReset(1, 1);
__GXWriteFifoIntEnable(1, 0);
__GXFifoLink(1);
} else {
CPUFifo.bind_gp = GX_FALSE;
if (CPGPLinked) {
__GXFifoLink(0);
CPGPLinked = GX_FALSE;
}
__GXWriteFifoIntEnable(0, 0);
reg = 0;
GX_PI_REG_WRITE_U32(PI_REG_CPBAS, TOPHYSICAL(CPUFifo.base));
GX_PI_REG_WRITE_U32(PI_REG_CPTOP, TOPHYSICAL(CPUFifo.top));
SC_PI_CPWRT_REG_SET_CPWRT(819, reg, (GX_PHY_ADDR(TOPHYSICAL(CPUFifo.wrPtr)) >> 5));
SC_PI_CPWRT_REG_SET_CPWRAP(0, reg, 0);
GX_PI_REG_WRITE_U32(PI_REG_CPWRT, reg);
}
PPCSync();
OSRestoreInterrupts(enabled);
}
void GXSetGPFifo(GXFifoObj* fifo) {
__GXFifoObj* realFifo = (__GXFifoObj*)fifo;
BOOL enabled;
u32 stbtmp;
ASSERTMSGLINE(850, ((u32)realFifo->base & 0x30000000) == 0, "GXSetGPFifo: GX Fifo should be located on MEM1 memory region");
enabled = OSDisableInterrupts();
__GXFifoReadDisable();
__GXWriteFifoIntEnable(0, 0);
if (fifo == NULL) {
GPFifoReady = GX_FALSE;
CPGPLinked = GX_FALSE;
__GXFifoLink(GX_FALSE);
GPFifo.bind_gp = GPFifo.bind_cpu = GX_FALSE;
OSRestoreInterrupts(enabled);
return;
}
GPFifo = *realFifo;
GPFifoReady = GX_TRUE;
GPFifo.bind_gp = GX_TRUE;
GX_CP_REG_WRITE_U16(CP_FIFO_BASEL, TOPHYSICAL(GPFifo.base));
GX_CP_REG_WRITE_U16(CP_FIFO_TOPL, TOPHYSICAL(GPFifo.top));
GX_CP_REG_WRITE_U16(CP_FIFO_COUNTL, GPFifo.count);
GX_CP_REG_WRITE_U16(CP_FIFO_WPTRL, TOPHYSICAL(GPFifo.wrPtr));
GX_CP_REG_WRITE_U16(CP_FIFO_RPTRL, TOPHYSICAL(GPFifo.rdPtr));
GX_CP_REG_WRITE_U16(CP_FIFO_HICNTL, GPFifo.hiWatermark);
GX_CP_REG_WRITE_U16(CP_FIFO_LOCNTL, GPFifo.loWatermark);
GX_CP_REG_WRITE_U16(CP_FIFO_BASEH, TOPHYSICAL(GPFifo.base) >> 16);
GX_CP_REG_WRITE_U16(CP_FIFO_TOPH, TOPHYSICAL(GPFifo.top) >> 16);
GX_CP_REG_WRITE_U16(CP_FIFO_COUNTH, GPFifo.count >> 16);
GX_CP_REG_WRITE_U16(CP_FIFO_WPTRH, TOPHYSICAL(GPFifo.wrPtr) >> 16);
GX_CP_REG_WRITE_U16(CP_FIFO_RPTRH, TOPHYSICAL(GPFifo.rdPtr) >> 16);
GX_CP_REG_WRITE_U16(CP_FIFO_HICNTH, GPFifo.hiWatermark >> 16);
GX_CP_REG_WRITE_U16(CP_FIFO_LOCNTH, GPFifo.loWatermark >> 16);
PPCSync();
if (CPGPLinkCheck()) {
CPGPLinked = GX_TRUE;
GPFifo.bind_cpu = GX_TRUE;
__GXWriteFifoIntEnable(GX_TRUE, GX_FALSE);
__GXFifoLink(GX_TRUE);
} else {
CPGPLinked = GX_FALSE;
GPFifo.bind_cpu = GX_FALSE;
__GXWriteFifoIntEnable(GX_FALSE, GX_FALSE);
__GXFifoLink(GX_FALSE);
}
stbtmp = __GXData->cpEnable;
SC_CP_REG_ENABLE_SET_FIFOBRK(0, stbtmp, 0);
SC_CP_REG_ENABLE_SET_FIFOBRKINT(0, stbtmp, 0);
GX_CP_REG_WRITE_U16(CP_ENABLE, stbtmp);
GX_CP_REG_WRITE_U16(CP_ENABLE, __GXData->cpEnable);
__GXWriteFifoIntReset(GX_TRUE, GX_TRUE);
__GXFifoReadEnable();
OSRestoreInterrupts(enabled);
}
#define CP_READ_2U16(dest,reg,type) \
{\
u32 temp; \
temp = (u32)GX_CP_REG_READ_U16(reg##H)<<16; \
temp |= (u32)GX_CP_REG_READ_U16(reg##L); \
dest = (type)OSPhysicalToCached(temp); \
}
#define CP_READ_2U16_INT(dest,reg,type) \
{\
u32 temp; \
temp = (u32)GX_CP_REG_READ_U16(reg##H)<<16; \
temp |= (u32)GX_CP_REG_READ_U16(reg##L); \
dest = (type)temp; \
}
static void __GXSaveFifoCPStat(void) {
CP_READ_2U16(GPFifo.rdPtr, CP_FIFO_RPTR, void*);
CP_READ_2U16_INT(GPFifo.count, CP_FIFO_COUNT, s32);
}
static void __GXSaveFifoPIStat(void) {
u32 reg = GX_PI_REG_READ_U32(PI_REG_CPWRT);
CPUFifo.wrPtr = OSPhysicalToCached(reg & PI_CPWRT_REG_CPWRT_MASK);
CPUFifo.wrap = (GXBool)((reg & PI_CPWRT_REG_CPWRAP_MASK) ? GX_TRUE : GX_FALSE);
}
void __GXSaveFifo(void) {
BOOL enabled = OSDisableInterrupts();
if (CPUFifoReady) {
__GXSaveFifoPIStat();
}
if (GPFifoReady) {
__GXSaveFifoCPStat();
}
if (CPGPLinked) {
CPUFifo.rdPtr = GPFifo.rdPtr;
CPUFifo.count = GPFifo.count;
GPFifo.wrPtr = CPUFifo.wrPtr;
GPFifo.wrap = CPUFifo.wrap;
} else if (CPUFifoReady) {
CPUFifo.count = (s32)CPUFifo.wrPtr - (s32)CPUFifo.rdPtr;
if (CPUFifo.count < 0) {
CPUFifo.count += CPUFifo.size;
}
}
OSRestoreInterrupts(enabled);
}
GXBool __GXIsGPFifoReady(void) {
return GPFifoReady;
}
void GXGetGPStatus(GXBool* overhi, GXBool* underlow, GXBool* readIdle, GXBool* cmdIdle, GXBool* brkpt) {
__GXData->cpStatus = GX_CP_REG_READ_U16(CP_STATUS);
*overhi = (u8)CP_REG_STATUS_GET_OVFL(__GXData->cpStatus);
*underlow = (u8)CP_REG_STATUS_GET_UNFL(__GXData->cpStatus);
*readIdle = (u8)CP_REG_STATUS_GET_FIFO_RDIDLE(__GXData->cpStatus);
*cmdIdle = (u8)CP_REG_STATUS_GET_CPIDLE(__GXData->cpStatus);
*brkpt = (u8)CP_REG_STATUS_GET_FIFOBRK(__GXData->cpStatus);
}
void GXGetFifoPtrs(GXFifoObj* fifo, void** readPtr, void** writePtr) {
__GXFifoObj* realFifo = (__GXFifoObj*)fifo;
*readPtr = realFifo->rdPtr;
*writePtr = realFifo->wrPtr;
}
void* GXGetFifoBase(const GXFifoObj* fifo) {
__GXFifoObj* realFifo = (__GXFifoObj*)fifo;
return realFifo->base;
}
u32 GXGetFifoSize(const GXFifoObj* fifo) {
__GXFifoObj* realFifo = (__GXFifoObj*)fifo;
return realFifo->size;
}
void GXGetFifoLimits(const GXFifoObj* fifo, u32* hi, u32* lo) {
__GXFifoObj* realFifo = (__GXFifoObj*)fifo;
*hi = realFifo->hiWatermark;
*lo = realFifo->loWatermark;
}
GXBreakPtCallback GXSetBreakPtCallback(GXBreakPtCallback cb) {
GXBreakPtCallback oldcb = BreakPointCB;
BOOL enabled = OSDisableInterrupts();
BreakPointCB = cb;
OSRestoreInterrupts(enabled);
return oldcb;
}
void* __GXCurrentBP;
void GXEnableBreakPt(void* break_pt) {
BOOL enabled = OSDisableInterrupts();
__GXFifoReadDisable();
GX_CP_REG_WRITE_U16(CP_FIFO_BRKL, TOPHYSICAL(break_pt));
GX_CP_REG_WRITE_U16(CP_FIFO_BRKH, TOPHYSICAL(break_pt) >> 16);
SC_CP_REG_ENABLE_SET_FIFOBRK(0, __GXData->cpEnable, 0);
SC_CP_REG_ENABLE_SET_FIFOBRKINT(0, __GXData->cpEnable, 0);
GX_CP_REG_WRITE_U16(CP_ENABLE, __GXData->cpEnable);
SC_CP_REG_ENABLE_SET_FIFOBRK(0, __GXData->cpEnable, 1);
SC_CP_REG_ENABLE_SET_FIFOBRKINT(0, __GXData->cpEnable, 1);
GX_CP_REG_WRITE_U16(CP_ENABLE, __GXData->cpEnable);
__GXCurrentBP = break_pt;
__GXFifoReadEnable();
OSRestoreInterrupts(enabled);
}
void GXDisableBreakPt(void) {
BOOL enabled = OSDisableInterrupts();
SC_CP_REG_ENABLE_SET_FIFOBRK(0, __GXData->cpEnable, 0);
SC_CP_REG_ENABLE_SET_FIFOBRKINT(0, __GXData->cpEnable, 0);
GX_CP_REG_WRITE_U16(CP_ENABLE, __GXData->cpEnable);
__GXCurrentBP = NULL;
OSRestoreInterrupts(enabled);
}
void __GXFifoInit(void) {
__OSSetInterruptHandler(0x11, GXCPInterruptHandler);
__OSUnmaskInterrupts(0x4000);
__GXCurrentThread = OSGetCurrentThread();
GXOverflowSuspendInProgress = FALSE;
memset(&CPUFifo, 0, sizeof(__GXFifoObj));
memset(&GPFifo, 0, sizeof(__GXFifoObj));
CPUFifoReady = GX_FALSE;
GPFifoReady = GX_FALSE;
}
static void __GXFifoReadEnable(void) {
SC_CP_REG_ENABLE_SET_FIFORD(0, __GXData->cpEnable, 1);
GX_CP_REG_WRITE_U16(CP_ENABLE, (u16)__GXData->cpEnable);
}
static void __GXFifoReadDisable(void) {
SC_CP_REG_ENABLE_SET_FIFORD(0, __GXData->cpEnable, 0);
GX_CP_REG_WRITE_U16(CP_ENABLE, (u16)__GXData->cpEnable);
}
static void __GXFifoLink(u8 en) {
SC_CP_REG_ENABLE_SET_WRPTRINC(1385, __GXData->cpEnable, (en ? 0x1 : 0));
GX_CP_REG_WRITE_U16(CP_ENABLE, (u16)__GXData->cpEnable);
}
static void __GXWriteFifoIntEnable(u8 hiWatermarkEn, u8 loWatermarkEn) {
SC_CP_REG_ENABLE_SET_OVFLINT(1407, __GXData->cpEnable, hiWatermarkEn);
SC_CP_REG_ENABLE_SET_UNFLINT(1408, __GXData->cpEnable, loWatermarkEn);
GX_CP_REG_WRITE_U16(CP_ENABLE, (u16)__GXData->cpEnable);
}
static void __GXWriteFifoIntReset(u8 hiWatermarkClr, u8 loWatermarkClr) {
SC_CP_REG_CLR_SET_OVFLINT(1431, __GXData->cpClr, hiWatermarkClr);
SC_CP_REG_CLR_SET_UNFLINT(1432, __GXData->cpClr, loWatermarkClr);
GX_CP_REG_WRITE_U16(CP_CLR, (u16)__GXData->cpClr);
}
void __GXCleanGPFifo(void) {
BOOL enabled;
if ( !GPFifoReady) {
return;
}
enabled = OSDisableInterrupts();
__GXFifoReadDisable();
__GXWriteFifoIntEnable(GX_FALSE, GX_FALSE);
GPFifo.rdPtr = GPFifo.wrPtr;
GPFifo.count = 0;
GX_CP_REG_WRITE_U16(CP_FIFO_COUNTL, GPFifo.count);
GX_CP_REG_WRITE_U16(CP_FIFO_WPTRL, TOPHYSICAL(GPFifo.wrPtr));
GX_CP_REG_WRITE_U16(CP_FIFO_RPTRL, TOPHYSICAL(GPFifo.rdPtr));
GX_CP_REG_WRITE_U16(CP_FIFO_COUNTH, GPFifo.count>>16);
GX_CP_REG_WRITE_U16(CP_FIFO_WPTRH, TOPHYSICAL(GPFifo.wrPtr)>>16);
GX_CP_REG_WRITE_U16(CP_FIFO_RPTRH, TOPHYSICAL(GPFifo.rdPtr)>>16);
PPCSync();
if (CPGPLinked) {
u32 reg = 0;
CPUFifo.rdPtr = GPFifo.rdPtr;
CPUFifo.wrPtr = GPFifo.wrPtr;
CPUFifo.count = GPFifo.count;
SC_PI_CPWRT_REG_SET_CPWRT(1501, reg, (GX_PHY_ADDR(TOPHYSICAL(CPUFifo.wrPtr)) >> 5));
SC_PI_CPWRT_REG_SET_CPWRAP(0, reg, 0);
GX_PI_REG_WRITE_U32(PI_REG_CPWRT, reg);
__GXWriteFifoIntEnable(GX_TRUE, GX_FALSE);
__GXFifoLink(GX_TRUE);
}
SC_CP_REG_ENABLE_SET_FIFOBRK(0, __GXData->cpEnable, 0);
SC_CP_REG_ENABLE_SET_FIFOBRKINT(0, __GXData->cpEnable, 0);
GX_CP_REG_WRITE_U16(CP_ENABLE, __GXData->cpEnable);
__GXCurrentBP = 0;
__GXWriteFifoIntReset(GX_TRUE, GX_TRUE);
__GXFifoReadEnable();
OSRestoreInterrupts(enabled);
}
OSThread* GXSetCurrentGXThread(void) {
BOOL enabled;
OSThread* prev;
enabled = OSDisableInterrupts();
prev = __GXCurrentThread;
ASSERTMSGLINE(1541, !GXOverflowSuspendInProgress, "GXSetCurrentGXThread: Two threads cannot generate GX commands at the same time!");
__GXCurrentThread = OSGetCurrentThread();
OSRestoreInterrupts(enabled);
return prev;
}
OSThread* GXGetCurrentGXThread(void) {
return __GXCurrentThread;
}
GXFifoObj* GXGetCPUFifo(void) {
return (GXFifoObj*)&CPUFifo;
}
GXFifoObj* GXGetGPFifo(void) {
return (GXFifoObj*)&GPFifo;
}
u32 GXGetOverflowCount(void) {
return __GXOverflowCount;
}
u32 GXResetOverflowCount(void) {
u32 oldcount;
oldcount = __GXOverflowCount;
__GXOverflowCount = 0;
return oldcount;
}
// NONMATCHING
volatile void* GXRedirectWriteGatherPipe(void* ptr) {
u32 reg = 0;
BOOL enabled = OSDisableInterrupts();
CHECK_GXBEGIN(0, "GXRedirectWriteGatherPipe");
ASSERTLINE(0, OFFSET(ptr, 32) == 0);
ASSERTLINE(0, !IsWGPipeRedirected);
#if DEBUG
IsWGPipeRedirected = TRUE;
#endif
GXFlush();
while (PPCMfwpar() & 1) {}
PPCMtwpar((u32)OSUncachedToPhysical((void*)GXFIFO_ADDR));
if (CPGPLinked) {
__GXFifoLink(0);
__GXWriteFifoIntEnable(0, 0);
}
CPUFifo.wrPtr = OSPhysicalToCached(GX_GET_PI_REG(5) & 0xFBFFFFFF);
GX_SET_PI_REG(3, 0);
GX_SET_PI_REG(4, 0x04000000);
SET_REG_FIELD(0, reg, 21, 5, ((u32)ptr & 0x3FFFFFFF) >> 5);
reg &= 0xFBFFFFFF;
GX_SET_PI_REG(5, reg);
PPCSync();
OSRestoreInterrupts(enabled);
return (volatile void *)GXFIFO_ADDR;
}
// NONMATCHING
void GXRestoreWriteGatherPipe(void) {
u32 reg = 0;
u32 i;
BOOL enabled;
ASSERTLINE(1552, IsWGPipeRedirected);
#if DEBUG
IsWGPipeRedirected = FALSE;
#endif
enabled = OSDisableInterrupts();
for (i = 0; i < 31; i++) {
GXWGFifo.u8 = 0;
}
PPCSync();
while (PPCMfwpar() & 1) {}
PPCMtwpar((u32)OSUncachedToPhysical((void *)GXFIFO_ADDR));
GX_SET_PI_REG(3, (u32)CPUFifo.base & 0x3FFFFFFF);
GX_SET_PI_REG(4, (u32)CPUFifo.top & 0x3FFFFFFF);
SET_REG_FIELD(1578, reg, 21, 5, ((u32)CPUFifo.wrPtr & 0x3FFFFFFF) >> 5);
reg &= 0xFBFFFFFF;
GX_SET_PI_REG(5, reg);
if (CPGPLinked) {
__GXWriteFifoIntReset(1, 1);
__GXWriteFifoIntEnable(1, 0);
__GXFifoLink(1);
}
PPCSync();
OSRestoreInterrupts(enabled);
}

View File

@ -0,0 +1,677 @@
#include <revolution/gx.h>
#include <revolution/os.h>
#include "__gx.h"
GXRenderModeObj GXNtsc240Ds = {
1,
640, 240, 240,
40, 0,
640, 480,
0,
0,
0,
{ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 },
{ 0, 0, 21, 22, 21, 0, 0 }
};
GXRenderModeObj GXNtsc240DsAa = {
1, 640, 240, 240, 40, 0, 640, 480, 0, 0, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 0, 0, 21, 22, 21, 0, 0 }
};
GXRenderModeObj GXNtsc240Int = {
0, 640, 240, 240, 40, 0, 640, 480, 0, 1, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 }
};
GXRenderModeObj GXNtsc240IntAa = {
0, 640, 240, 240, 40, 0, 640, 480, 0, 1, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 0, 0, 21, 22, 21, 0, 0 }
};
GXRenderModeObj GXNtsc480IntDf = {
0, 640, 480, 480, 40, 0, 640, 480, 1, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 8, 8, 10, 12, 10, 8, 8 }
};
GXRenderModeObj GXNtsc480Int = {
0, 640, 480, 480, 40, 0, 640, 480, 1, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 }
};
GXRenderModeObj GXNtsc480IntAa = {
0, 640, 242, 480, 40, 0, 640, 480, 1, 0, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 4, 8, 12, 16, 12, 8, 4 }
};
GXRenderModeObj GXNtsc480Prog = {
2, 640, 480, 480, 40, 0, 640, 480, 0, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 }
};
GXRenderModeObj GXNtsc480ProgSoft = {
2, 640, 480, 480, 40, 0, 640, 480, 0, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 8, 8, 10, 12, 10, 8, 8 }
};
GXRenderModeObj GXNtsc480ProgAa = {
2, 640, 242, 480, 40, 0, 640, 480, 0, 0, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 4, 8, 12, 16, 12, 8, 4 }
};
GXRenderModeObj GXMpal240Ds = {9, 640, 240, 240, 40, 0, 640, 480, 0, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } };
GXRenderModeObj GXMpal240DsAa = {9, 640, 240, 240, 40, 0, 640, 480, 0, 0, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 0, 0, 21, 22, 21, 0, 0 } };
GXRenderModeObj GXMpal240Int = {8, 640, 240, 240, 40, 0, 640, 480, 0, 1, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } };
GXRenderModeObj GXMpal240IntAa = {8, 640, 240, 240, 40, 0, 640, 480, 0, 1, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 0, 0, 21, 22, 21, 0, 0 } };
GXRenderModeObj GXMpal480IntDf = {8, 640, 480, 480, 40, 0, 640, 480, 1, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 8, 8, 10, 12, 10, 8, 8 } };
GXRenderModeObj GXMpal480Int = {8, 640, 480, 480, 40, 0, 640, 480, 1, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } };
GXRenderModeObj GXMpal480IntAa = {8, 640, 242, 480, 40, 0, 640, 480, 1, 0, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 4, 8, 12, 16, 12, 8, 4 } };
GXRenderModeObj GXMpal480Prog = {
10,
640, 480, 480,
40, 0,
640, 480,
0,
0,
0,
{ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 },
{ 0, 0, 21, 22, 21, 0, 0 }
};
GXRenderModeObj GXMpal480ProgSoft = {
10,
640, 480, 480,
40, 0,
640, 480,
0,
0,
0,
{ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 },
{ 8, 8, 10, 12, 10, 8, 8 }
};
GXRenderModeObj GXMpal480ProgAa = {
10,
640, 242, 480,
40, 0,
640, 480,
0,
0,
1,
{ 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 },
{ 4, 8, 12, 16, 12, 8, 4 }
};
GXRenderModeObj GXPal264Ds = {5, 640, 264, 264, 40, 11, 640, 528, 0, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } };
GXRenderModeObj GXPal264DsAa = {5, 640, 264, 264, 40, 11, 640, 528, 0, 0, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 0, 0, 21, 22, 21, 0, 0 } };
GXRenderModeObj GXPal264Int = {4, 640, 264, 264, 40, 23, 640, 528, 0, 1, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } };
GXRenderModeObj GXPal264IntAa = {4, 640, 264, 264, 40, 23, 640, 528, 0, 1, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 0, 0, 21, 22, 21, 0, 0 } };
GXRenderModeObj GXPal528IntDf = {4, 640, 528, 528, 40, 23, 640, 528, 1, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 8, 8, 10, 12, 10, 8, 8 } };
GXRenderModeObj GXPal528Int = {4, 640, 528, 528, 40, 23, 640, 528, 1, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } };
GXRenderModeObj GXPal524IntAa = {4, 640, 264, 524, 40, 23, 640, 524, 1, 0, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 4, 8, 12, 16, 12, 8, 4 } };
GXRenderModeObj GXEurgb60Hz240Ds = {21, 640, 240, 240, 40, 0, 640, 480, 0, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } };
GXRenderModeObj GXEurgb60Hz240DsAa = {21, 640, 240, 240, 40, 0, 640, 480, 0, 0, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 0, 0, 21, 22, 21, 0, 0 } };
GXRenderModeObj GXEurgb60Hz240Int = {20, 640, 240, 240, 40, 0, 640, 480, 0, 1, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } };
GXRenderModeObj GXEurgb60Hz240IntAa = {20, 640, 240, 240, 40, 0, 640, 480, 0, 1, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 0, 0, 21, 22, 21, 0, 0 } };
GXRenderModeObj GXEurgb60Hz480IntDf = {20, 640, 480, 480, 40, 0, 640, 480, 1, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 8, 8, 10, 12, 10, 8, 8 } };
GXRenderModeObj GXEurgb60Hz480Int = {20, 640, 480, 480, 40, 0, 640, 480, 1, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } };
GXRenderModeObj GXEurgb60Hz480IntAa = {20, 640, 242, 480, 40, 0, 640, 480, 1, 0, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 4, 8, 12, 16, 12, 8, 4 } };
GXRenderModeObj GXEurgb60Hz480Prog = {
22,
640, 480, 480,
40, 0,
640, 480,
0,
0,
0,
{ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 },
{ 0, 0, 21, 22, 21, 0, 0 }
};
GXRenderModeObj GXEurgb60Hz480ProgSoft = {
22,
640, 480, 480,
40, 0,
640, 480,
0,
0,
0,
{ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 },
{ 8, 8, 10, 12, 10, 8, 8 }
};
GXRenderModeObj GXEurgb60Hz480ProgAa = {
22,
640, 242, 480,
40, 0,
640, 480,
0,
0,
1,
{ 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 },
{ 4, 8, 12, 16, 12, 8, 4 }
};
GXRenderModeObj GXRmHW = {1, 320, 240, 240, 40, 0, 640, 480, 0, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } };
void GXAdjustForOverscan(const GXRenderModeObj* rmin, GXRenderModeObj* rmout, u16 hor, u16 ver) {
u16 hor2 = hor * 2;
u16 ver2 = ver * 2;
u32 verf;
u32 mode;
if (rmin != rmout) {
*rmout = *rmin;
}
mode = rmin->viTVmode & 3;
rmout->fbWidth = rmin->fbWidth - hor2;
verf = (ver2 * rmin->efbHeight) / (u32)rmin->xfbHeight;
rmout->efbHeight = rmin->efbHeight - verf;
if (rmin->xFBmode == VI_XFBMODE_SF && mode == 0) {
rmout->xfbHeight = rmin->xfbHeight - ver2 / 2;
} else {
rmout->xfbHeight = rmin->xfbHeight - ver2;
}
rmout->viWidth = rmin->viWidth - hor2;
if (mode == 1) {
rmout->viHeight = rmin->viHeight - (ver2 * 2);
} else {
rmout->viHeight = rmin->viHeight - ver2;
}
rmout->viXOrigin = rmin->viXOrigin + hor;
rmout->viYOrigin = rmin->viYOrigin + ver;
}
void GXSetDispCopySrc(u16 left, u16 top, u16 wd, u16 ht) {
CHECK_GXBEGIN(1510, "GXSetDispCopySrc");
__GXData->cpDispSrc = 0;
SET_REG_FIELD(1513, __GXData->cpDispSrc, 10, 0, left);
SET_REG_FIELD(1514, __GXData->cpDispSrc, 10, 10, top);
SET_REG_FIELD(1514, __GXData->cpDispSrc, 8, 24, 0x49);
__GXData->cpDispSize = 0;
SET_REG_FIELD(1518, __GXData->cpDispSize, 10, 0, wd - 1);
SET_REG_FIELD(1519, __GXData->cpDispSize, 10, 10, ht - 1);
SET_REG_FIELD(1519, __GXData->cpDispSize, 8, 24, 0x4A);
}
void GXSetTexCopySrc(u16 left, u16 top, u16 wd, u16 ht) {
CHECK_GXBEGIN(1538, "GXSetTexCopySrc");
__GXData->cpTexSrc = 0;
SET_REG_FIELD(1541, __GXData->cpTexSrc, 10, 0, left);
SET_REG_FIELD(1542, __GXData->cpTexSrc, 10, 10, top);
SET_REG_FIELD(1542, __GXData->cpTexSrc, 8, 24, 0x49);
__GXData->cpTexSize = 0;
SET_REG_FIELD(1546, __GXData->cpTexSize, 10, 0, wd - 1);
SET_REG_FIELD(1547, __GXData->cpTexSize, 10, 10, ht - 1);
SET_REG_FIELD(1547, __GXData->cpTexSize, 8, 24, 0x4A);
}
void GXSetDispCopyDst(u16 wd, u16 ht) {
u16 stride;
ASSERTMSGLINE(1568, (wd & 15) == 0, "GXSetDispCopyDst: Width must be a multiple of 16");
CHECK_GXBEGIN(1569, "GXSetDispCopyDst");
stride = (int)wd * 2;
__GXData->cpDispStride = 0;
SET_REG_FIELD(1575, __GXData->cpDispStride, 10, 0, (stride >> 5) );
SET_REG_FIELD(1575, __GXData->cpDispStride, 8, 24, 0x4D);
}
void GXSetTexCopyDst(u16 wd, u16 ht, GXTexFmt fmt, GXBool mipmap) {
u32 rowTiles;
u32 colTiles;
u32 cmpTiles;
u32 peTexFmt;
u32 peTexFmtH;
CHECK_GXBEGIN(1602, "GXSetTexCopyDst");
__GXData->cpTexZ = 0;
peTexFmt = fmt & 0xF;
ASSERTMSGLINEV(1633, peTexFmt < 13, "%s: invalid texture format", "GXSetTexCopyDst");
if (fmt == GX_TF_Z16) {
peTexFmt = 0xB;
}
switch (fmt) {
case GX_TF_I4:
case GX_TF_I8:
case GX_TF_IA4:
case GX_TF_IA8:
case GX_CTF_YUVA8:
SET_REG_FIELD(0, __GXData->cpTex, 2, 15, 3);
break;
default:
SET_REG_FIELD(0, __GXData->cpTex, 2, 15, 2);
break;
}
__GXData->cpTexZ = (fmt & _GX_TF_ZTF) == _GX_TF_ZTF;
peTexFmtH = (peTexFmt & 8) >> 3;
SET_REG_FIELD(1656, __GXData->cpTex, 1, 3, peTexFmtH);
peTexFmt = peTexFmt & 7;
__GetImageTileCount(fmt, wd, ht, &rowTiles, &colTiles, &cmpTiles);
__GXData->cpTexStride = 0;
SET_REG_FIELD(1665, __GXData->cpTexStride, 10, 0, rowTiles * cmpTiles);
SET_REG_FIELD(1667, __GXData->cpTexStride, 8, 24, 0x4D);
SET_REG_FIELD(1667, __GXData->cpTex, 1, 9, mipmap);
SET_REG_FIELD(1668, __GXData->cpTex, 3, 4, peTexFmt);
}
void GXSetDispCopyFrame2Field(GXCopyMode mode) {
CHECK_GXBEGIN(1685, "GXSetDispCopyFrame2Field");
SET_REG_FIELD(1686, __GXData->cpDisp, 2, 12, mode);
SET_REG_FIELD(1686, __GXData->cpTex, 2, 12, 0);
}
void GXSetCopyClamp(GXFBClamp clamp) {
u8 clmpB;
u8 clmpT;
CHECK_GXBEGIN(1706, "GXSetCopyClamp");
clmpT = (clamp & GX_CLAMP_TOP) == 1;
clmpB = (clamp & GX_CLAMP_BOTTOM) == 2;
SET_REG_FIELD(1710, __GXData->cpDisp, 1, 0, clmpT);
SET_REG_FIELD(1711, __GXData->cpDisp, 1, 1, clmpB);
SET_REG_FIELD(1713, __GXData->cpTex, 1, 0, clmpT);
SET_REG_FIELD(1714, __GXData->cpTex, 1, 1, clmpB);
}
static u32 __GXGetNumXfbLines(u32 efbHt, u32 iScale) {
u32 count;
u32 realHt;
u32 iScaleD;
count = (efbHt - 1) * 0x100;
realHt = (count / iScale) + 1;
iScaleD = iScale;
if (iScaleD > 0x80 && iScaleD < 0x100) {
while (iScaleD % 2 == 0) {
iScaleD /= 2;
}
if (efbHt % iScaleD == 0) {
realHt++;
}
}
if (realHt > 0x400) {
realHt = 0x400;
}
return realHt;
}
u16 GXGetNumXfbLines(u16 efbHeight, f32 yScale) {
u32 iScale;
ASSERTMSGLINE(1761, yScale >= 1.0f, "GXGetNumXfbLines: Vertical scale must be >= 1.0");
iScale = (u32)(256.0f / yScale) & 0x1FF;
return __GXGetNumXfbLines(efbHeight, iScale);
}
f32 GXGetYScaleFactor(u16 efbHeight, u16 xfbHeight) {
f32 fScale;
f32 yScale;
u32 iScale;
u32 tgtHt;
u32 realHt;
ASSERTMSGLINE(1785, xfbHeight <= 1024, "GXGetYScaleFactor: Display copy only supports up to 1024 lines.\n");
ASSERTMSGLINE(1787, efbHeight <= xfbHeight, "GXGetYScaleFactor: EFB height should not be greater than XFB height.\n");
tgtHt = xfbHeight;
yScale = (f32)xfbHeight / (f32)efbHeight;
iScale = (u32)(256.0f / yScale) & 0x1FF;
realHt = __GXGetNumXfbLines(efbHeight, iScale);
while (realHt > xfbHeight) {
tgtHt--;
yScale = (f32)tgtHt / (f32)efbHeight;
iScale = (u32)(256.0f / yScale) & 0x1FF;
realHt = __GXGetNumXfbLines(efbHeight, iScale);
}
fScale = yScale;
while (realHt < xfbHeight) {
fScale = yScale;
tgtHt++;
yScale = (f32)tgtHt / (f32)efbHeight;
iScale = (u32)(256.0f / yScale) & 0x1FF;
realHt = __GXGetNumXfbLines(efbHeight, iScale);
}
return fScale;
}
u32 GXSetDispCopyYScale(f32 vscale) {
u8 enable;
u32 iScale;
u32 ht;
u32 reg;
CHECK_GXBEGIN(1832, "GXSetDispCopyYScale");
ASSERTMSGLINE(1834, vscale >= 1.0f, "GXSetDispCopyYScale: Vertical scale must be >= 1.0");
iScale = (u32) (256.0f / vscale) & 0x1FF;
enable = (iScale != 256);
reg = 0;
SET_REG_FIELD(1841, reg, 9, 0, iScale);
SET_REG_FIELD(1841, reg, 8, 24, 0x4E);
GX_WRITE_RAS_REG(reg);
__GXData->bpSentNot = 0;
SET_REG_FIELD(1846, __GXData->cpDisp, 1, 10, enable);
ht = (u32)GET_REG_FIELD(__GXData->cpDispSize, 10, 10) + 1;
return __GXGetNumXfbLines(ht, iScale);
}
void GXSetCopyClear(GXColor clear_clr, u32 clear_z) {
u32 reg;
CHECK_GXBEGIN(1871, "GXSetCopyClear");
ASSERTMSGLINE(1873, clear_z <= 0xFFFFFF, "GXSetCopyClear: Z clear value is out of range");
reg = 0;
SET_REG_FIELD(1876, reg, 8, 0, clear_clr.r);
SET_REG_FIELD(1877, reg, 8, 8, clear_clr.a);
SET_REG_FIELD(1877, reg, 8, 24, 0x4F);
GX_WRITE_RAS_REG(reg);
reg = 0;
SET_REG_FIELD(1882, reg, 8, 0, clear_clr.b);
SET_REG_FIELD(1883, reg, 8, 8, clear_clr.g);
SET_REG_FIELD(1883, reg, 8, 24, 0x50);
GX_WRITE_RAS_REG(reg);
reg = 0;
SET_REG_FIELD(1888, reg, 24, 0, clear_z);
SET_REG_FIELD(1888, reg, 8, 24, 0x51);
GX_WRITE_RAS_REG(reg);
__GXData->bpSentNot = 0;
}
void GXSetCopyFilter(GXBool aa, const u8 sample_pattern[12][2], GXBool vf, const u8 vfilter[7]) {
u32 msLoc[4];
u32 coeff0;
u32 coeff1;
CHECK_GXBEGIN(1916, "GXSetCopyFilter");
if (aa != 0) {
msLoc[0] = 0;
SET_REG_FIELD(1920, msLoc[0], 4, 0, sample_pattern[0][0]);
SET_REG_FIELD(1921, msLoc[0], 4, 4, sample_pattern[0][1]);
SET_REG_FIELD(1922, msLoc[0], 4, 8, sample_pattern[1][0]);
SET_REG_FIELD(1923, msLoc[0], 4, 12, sample_pattern[1][1]);
SET_REG_FIELD(1924, msLoc[0], 4, 16, sample_pattern[2][0]);
SET_REG_FIELD(1925, msLoc[0], 4, 20, sample_pattern[2][1]);
SET_REG_FIELD(1926, msLoc[0], 8, 24, 1);
msLoc[1] = 0;
SET_REG_FIELD(1929, msLoc[1], 4, 0, sample_pattern[3][0]);
SET_REG_FIELD(1930, msLoc[1], 4, 4, sample_pattern[3][1]);
SET_REG_FIELD(1931, msLoc[1], 4, 8, sample_pattern[4][0]);
SET_REG_FIELD(1932, msLoc[1], 4, 12, sample_pattern[4][1]);
SET_REG_FIELD(1933, msLoc[1], 4, 16, sample_pattern[5][0]);
SET_REG_FIELD(1934, msLoc[1], 4, 20, sample_pattern[5][1]);
SET_REG_FIELD(1935, msLoc[1], 8, 24, 2);
msLoc[2] = 0;
SET_REG_FIELD(1938, msLoc[2], 4, 0, sample_pattern[6][0]);
SET_REG_FIELD(1939, msLoc[2], 4, 4, sample_pattern[6][1]);
SET_REG_FIELD(1940, msLoc[2], 4, 8, sample_pattern[7][0]);
SET_REG_FIELD(1941, msLoc[2], 4, 12, sample_pattern[7][1]);
SET_REG_FIELD(1942, msLoc[2], 4, 16, sample_pattern[8][0]);
SET_REG_FIELD(1943, msLoc[2], 4, 20, sample_pattern[8][1]);
SET_REG_FIELD(1944, msLoc[2], 8, 24, 3);
msLoc[3] = 0;
SET_REG_FIELD(1947, msLoc[3], 4, 0, sample_pattern[9][0]);
SET_REG_FIELD(1948, msLoc[3], 4, 4, sample_pattern[9][1]);
SET_REG_FIELD(1949, msLoc[3], 4, 8, sample_pattern[10][0]);
SET_REG_FIELD(1950, msLoc[3], 4, 12, sample_pattern[10][1]);
SET_REG_FIELD(1951, msLoc[3], 4, 16, sample_pattern[11][0]);
SET_REG_FIELD(1952, msLoc[3], 4, 20, sample_pattern[11][1]);
SET_REG_FIELD(1953, msLoc[3], 8, 24, 4);
} else {
msLoc[0] = 0x01666666;
msLoc[1] = 0x02666666;
msLoc[2] = 0x03666666;
msLoc[3] = 0x04666666;
}
GX_WRITE_RAS_REG(msLoc[0]);
GX_WRITE_RAS_REG(msLoc[1]);
GX_WRITE_RAS_REG(msLoc[2]);
GX_WRITE_RAS_REG(msLoc[3]);
coeff0 = 0;
SET_REG_FIELD(0, coeff0, 8, 24, 0x53);
coeff1 = 0;
SET_REG_FIELD(0, coeff1, 8, 24, 0x54);
if (vf != 0) {
SET_REG_FIELD(1977, coeff0, 6, 0, vfilter[0]);
SET_REG_FIELD(1978, coeff0, 6, 6, vfilter[1]);
SET_REG_FIELD(1979, coeff0, 6, 12, vfilter[2]);
SET_REG_FIELD(1980, coeff0, 6, 18, vfilter[3]);
SET_REG_FIELD(1981, coeff1, 6, 0, vfilter[4]);
SET_REG_FIELD(1982, coeff1, 6, 6, vfilter[5]);
SET_REG_FIELD(1983, coeff1, 6, 12, vfilter[6]);
} else {
SET_REG_FIELD(0, coeff0, 6, 0, 0);
SET_REG_FIELD(0, coeff0, 6, 6, 0);
SET_REG_FIELD(0, coeff0, 6, 12, 21);
SET_REG_FIELD(0, coeff0, 6, 18, 22);
SET_REG_FIELD(0, coeff1, 6, 0, 21);
SET_REG_FIELD(0, coeff1, 6, 6, 0);
SET_REG_FIELD(0, coeff1, 6, 12, 0);
}
GX_WRITE_RAS_REG(coeff0);
GX_WRITE_RAS_REG(coeff1);
__GXData->bpSentNot = 0;
}
void GXSetDispCopyGamma(GXGamma gamma) {
CHECK_GXBEGIN(2016, "GXSetDispCopyGamma");
SET_REG_FIELD(2017, __GXData->cpDisp, 2, 7, gamma);
}
#if DEBUG
static void __GXVerifCopy(void* dest, u8 clear) {
u8 clmpT;
u8 clmpB;
u32 x0;
u32 y0;
u32 dx;
u32 dy;
CHECK_GXBEGIN(2037, "GXCopyDisp");
clmpT = GET_REG_FIELD(__GXData->cpDisp, 1, 0);
clmpB = (u32)GET_REG_FIELD(__GXData->cpDisp, 1, 1);
x0 = GET_REG_FIELD(__GXData->cpDispSrc, 10, 0);
dx = GET_REG_FIELD(__GXData->cpDispSize, 10, 0) + 1;
y0 = GET_REG_FIELD(__GXData->cpDispSrc, 10, 10);
dy = GET_REG_FIELD(__GXData->cpDispSize, 10, 10) + 1;
ASSERTMSGLINE(2047, clmpT || y0 != 0, "GXCopy: Have to set GX_CLAMP_TOP if source top == 0");
ASSERTMSGLINE(2049, clmpB || y0 + dy <= 528, "GXCopy: Have to set GX_CLAMP_BOTTOM if source bottom > 528");
ASSERTMSGLINE(2054, (__GXData->peCtrl & 7) != 3 || clear == 0, "GXCopy: Can not do clear while pixel type is Z");
if ((u32) (__GXData->peCtrl & 7) == 5) {
ASSERTMSGLINE(2060, clear == 0, "GXCopy: Can not clear YUV framebuffer");
ASSERTMSGLINE(2062, (x0 & 3) == 0, "GXCopy: Source x is not multiple of 4 for YUV copy");
ASSERTMSGLINE(2064, (y0 & 3) == 0, "GXCopy: Source y is not multiple of 4 for YUV copy");
ASSERTMSGLINE(2066, (dx & 3) == 0, "GXCopy: Source width is not multiple of 4 for YUV copy");
ASSERTMSGLINE(2068, (dy & 3) == 0, "GXCopy: Source height is not multiple of 4 for YUV copy");
} else {
ASSERTMSGLINE(2072, (x0 & 1) == 0, "GXCopy: Source x is not multiple of 2 for RGB copy");
ASSERTMSGLINE(2074, (y0 & 1) == 0, "GXCopy: Source y is not multiple of 2 for RGB copy");
ASSERTMSGLINE(2076, (dx & 1) == 0, "GXCopy: Source width is not multiple of 2 for RGB copy");
ASSERTMSGLINE(2078, (dy & 1) == 0, "GXCopy: Source height is not multiple of 2 for RGB copy");
}
ASSERTMSGLINE(2082, ((u32)dest & 0x1F) == 0, "GXCopy: Display destination address not 32B aligned");
}
#endif
void GXCopyDisp(void* dest, GXBool clear) {
u32 reg;
u32 tempPeCtrl;
u32 phyAddr;
u8 changePeCtrl;
CHECK_GXBEGIN(2108, "GXCopyDisp");
#if DEBUG
__GXVerifCopy(dest, clear);
#endif
if (clear) {
reg = __GXData->zmode;
SET_REG_FIELD(0, reg, 1, 0, 1);
SET_REG_FIELD(0, reg, 3, 1, 7);
GX_WRITE_RAS_REG(reg);
reg = __GXData->cmode0;
SET_REG_FIELD(0, reg, 1, 0, 0);
SET_REG_FIELD(0, reg, 1, 1, 0);
GX_WRITE_RAS_REG(reg);
}
changePeCtrl = FALSE;
if ((clear || (u32)GET_REG_FIELD(__GXData->peCtrl, 3, 0) == 3) && (u32)GET_REG_FIELD(__GXData->peCtrl, 1, 6) == 1) {
changePeCtrl = TRUE;
tempPeCtrl = __GXData->peCtrl;
SET_REG_FIELD(0, tempPeCtrl, 1, 6, 0);
GX_WRITE_RAS_REG(tempPeCtrl);
}
GX_WRITE_RAS_REG(__GXData->cpDispSrc);
GX_WRITE_RAS_REG(__GXData->cpDispSize);
GX_WRITE_RAS_REG(__GXData->cpDispStride);
phyAddr = (u32)dest & 0x3FFFFFFF;
reg = 0;
SET_REG_FIELD(2147, reg, 24, 0, phyAddr >> 5);
SET_REG_FIELD(2147, reg, 8, 24, 0x4B);
GX_WRITE_RAS_REG(reg);
SET_REG_FIELD(2151, __GXData->cpDisp, 1, 11, clear);
SET_REG_FIELD(2151, __GXData->cpDisp, 1, 14, 1);
SET_REG_FIELD(2151, __GXData->cpDisp, 8, 24, 0x52);
GX_WRITE_RAS_REG(__GXData->cpDisp);
if (clear) {
GX_WRITE_RAS_REG(__GXData->zmode);
GX_WRITE_RAS_REG(__GXData->cmode0);
}
if (changePeCtrl) {
GX_WRITE_RAS_REG(__GXData->peCtrl);
}
__GXData->bpSentNot = 0;
}
void GXCopyTex(void* dest, GXBool clear) {
u32 reg;
u32 tempPeCtrl;
u32 phyAddr;
u8 changePeCtrl;
CHECK_GXBEGIN(2191, "GXCopyTex");
#if DEBUG
__GXVerifCopy(dest, clear);
#endif
if (clear) {
reg = __GXData->zmode;
SET_REG_FIELD(0, reg, 1, 0, 1);
SET_REG_FIELD(0, reg, 3, 1, 7);
GX_WRITE_RAS_REG(reg);
reg = __GXData->cmode0;
SET_REG_FIELD(0, reg, 1, 0, 0);
SET_REG_FIELD(0, reg, 1, 1, 0);
GX_WRITE_RAS_REG(reg);
}
changePeCtrl = 0;
tempPeCtrl = __GXData->peCtrl;
if (__GXData->cpTexZ && ((tempPeCtrl & 7) != 3)) {
changePeCtrl = 1;
SET_REG_FIELD(0, tempPeCtrl, 3, 0, 3);
}
if ((clear || ((u32) (tempPeCtrl & 7) == 3)) && ((u32) ((tempPeCtrl & 0x40) >> 6) == 1)) {
changePeCtrl = 1;
SET_REG_FIELD(0, tempPeCtrl, 1, 6, 0);
}
if (changePeCtrl) {
GX_WRITE_RAS_REG(tempPeCtrl);
}
GX_WRITE_RAS_REG(__GXData->cpTexSrc);
GX_WRITE_RAS_REG(__GXData->cpTexSize);
GX_WRITE_RAS_REG(__GXData->cpTexStride);
phyAddr = (u32)dest & 0x3FFFFFFF;
reg = 0;
SET_REG_FIELD(2240, reg, 24, 0, phyAddr >> 5);
SET_REG_FIELD(2240, reg, 8, 24, 0x4B);
GX_WRITE_RAS_REG(reg);
SET_REG_FIELD(2244, __GXData->cpTex, 1, 11, clear);
SET_REG_FIELD(2244, __GXData->cpTex, 1, 14, 0);
SET_REG_FIELD(2244, __GXData->cpTex, 8, 24, 0x52);
GX_WRITE_RAS_REG(__GXData->cpTex);
if (clear) {
GX_WRITE_RAS_REG(__GXData->zmode);
GX_WRITE_RAS_REG(__GXData->cmode0);
}
if (changePeCtrl) {
GX_WRITE_RAS_REG(__GXData->peCtrl);
}
__GXData->bpSentNot = 0;
}
void GXClearBoundingBox(void) {
u32 reg;
CHECK_GXBEGIN(2278, "GXClearBoundingBox");
reg = 0x550003FF;
GX_WRITE_RAS_REG(reg);
reg = 0x560003FF;
GX_WRITE_RAS_REG(reg);
__GXData->bpSentNot = 0;
}
void GXReadBoundingBox(u16* left, u16* top, u16* right, u16* bottom) {
*left = GX_GET_PE_REG(8);
*top = GX_GET_PE_REG(10);
*right = GX_GET_PE_REG(9);
*bottom = GX_GET_PE_REG(11);
}

View File

@ -0,0 +1,267 @@
#include <stddef.h>
#include <revolution/gx.h>
#include <revolution/os.h>
#include "__gx.h"
static void __GXSetTexGen(u32 tgState);
static void __GXSetLightChan(u32 chState);
static void __GXSetAmbMat(u32 amState);
void __GXSetDirtyState(void) {
u32 dState = __GXData->dirtyState;
if (dState & 1) {
__GXSetSUTexRegs();
}
if (dState & 2) {
__GXUpdateBPMask();
}
if (dState & 4) {
__GXSetGenMode();
}
if (dState & 8) {
__GXSetVCD();
}
if (dState & 0x10) {
__GXSetVAT();
}
if (dState & 0x18) {
__GXCalculateVLim();
}
dState &= 0xFFFFFF00;
if (dState) {
u32 dStateLocal;
dStateLocal = dState & 0x00000F00;
if (dStateLocal) {
__GXSetAmbMat(dStateLocal);
}
dStateLocal = dState & (0x01000000|0x0000F000);
if (dStateLocal) {
__GXSetLightChan(dStateLocal);
}
dStateLocal = dState & (0x02000000|0x00FF0000);
if (dStateLocal) {
__GXSetTexGen(dStateLocal);
}
dStateLocal = dState & 0x04000000;
if (dStateLocal) {
__GXSetMatrixIndex(GX_VA_PNMTXIDX);
__GXSetMatrixIndex(GX_VA_TEX4MTXIDX);
}
dStateLocal = dState & 0x10000000;
if (dStateLocal) {
__GXSetViewport();
}
dStateLocal = dState & 0x8000000;
if (dStateLocal) {
__GXSetProjection();
}
__GXData->bpSentNot = GX_TRUE;
}
__GXData->dirtyState = 0;
}
static void __GXSetTexGen(u32 tgState) {
u32 d, i, tgIndx = 0x1040;
u32 dtgIndx = 0x1050;
if (tgState & 0x2000000) {
d = __GXData->genMode & 0xF;
GX_WRITE_XF_REG(0x103F, d, 0);
}
d = (tgState & 0xFF0000) >> 16;
i = 0;
while (d) {
if (d & 0x1) {
GX_WRITE_XF_REG(tgIndx, __GXData->texGenCtrl[i], 0);
GX_WRITE_XF_REG(dtgIndx, __GXData->texGenCtrl2[i], 0);
}
dtgIndx++;
tgIndx++;
i++;
d >>= 1;
}
}
static void __GXSetLightChan(u32 chState) {
u32 d, i, chIndx = 0x100E;
if (chState & 0x1000000) {
d = ((__GXData->genMode & 0x70) >> 4);
GX_WRITE_XF_REG(0x1009, d, 0);
}
d = (chState & 0xF000) >> 12;
i = 0;
while (d) {
if (d & 0x1) {
GX_WRITE_XF_REG(chIndx, __GXData->chanCtrl[i], 0);
}
i++;
chIndx++;
d >>= 1;
}
}
static void __GXSetAmbMat(u32 amState) {
if (amState & 0x100) {
GX_WRITE_XF_REG(0x100A, __GXData->ambColor[0], 0);
}
if (amState & 0x200) {
GX_WRITE_XF_REG(0x100B, __GXData->ambColor[1], 0);
}
if (amState & 0x400) {
GX_WRITE_XF_REG(0x100C, __GXData->matColor[0], 0);
}
if (amState & 0x800) {
GX_WRITE_XF_REG(0x100D, __GXData->matColor[1], 0);
}
}
void GXBegin(GXPrimitive type, GXVtxFmt vtxfmt, u16 nverts) {
ASSERTMSGLINE(368, vtxfmt < GX_MAX_VTXFMT, "GXBegin: Format Index is out of range");
ASSERTMSGLINE(369, !__GXinBegin, "GXBegin: called inside another GXBegin/GXEnd");
if (__GXData->dirtyState != 0) {
__GXSetDirtyState();
}
#if DEBUG
if (!__GXData->inDispList) {
__GXVerifyState(vtxfmt);
}
__GXinBegin = 1;
#endif
if (*(u32*)&__GXData->vNumNot == 0) { // checks both vNum and bpSentNot
__GXSendFlushPrim();
}
GX_WRITE_U8(vtxfmt | type);
GX_WRITE_U16(nverts);
}
void __GXSendFlushPrim(void) {
u32 i;
u32 numD = __GXData->vNum * __GXData->vLim;
GX_WRITE_U8(0x98);
GX_WRITE_U16(__GXData->vNum);
for (i = 0; i < numD; i += 4) {
GX_WRITE_U32(0);
}
__GXData->bpSentNot = 1;
}
void GXSetLineWidth(u8 width, GXTexOffset texOffsets) {
CHECK_GXBEGIN(447, "GXSetLineWidth");
SC_SU_LPSIZE_SET_LSIZE(448, __GXData->lpSize, width);
SC_SU_LPSIZE_SET_LTOFF(449, __GXData->lpSize, texOffsets);
GX_WRITE_RAS_REG(__GXData->lpSize);
__GXData->bpSentNot = 0;
}
void GXGetLineWidth(u8* width, GXTexOffset* texOffsets) {
ASSERTMSGLINE(463, width != NULL && texOffsets != NULL, "GXGet*: invalid null pointer");
*width = SU_LPSIZE_GET_LSIZE(__GXData->lpSize);
*texOffsets = SU_LPSIZE_GET_LTOFF(__GXData->lpSize);
}
void GXSetPointSize(u8 pointSize, GXTexOffset texOffsets) {
CHECK_GXBEGIN(491, "GXSetPointSize");
SC_SU_LPSIZE_SET_PSIZE(492, __GXData->lpSize, pointSize);
SC_SU_LPSIZE_SET_PTOFF(493, __GXData->lpSize, texOffsets);
GX_WRITE_RAS_REG(__GXData->lpSize);
__GXData->bpSentNot = 0;
}
void GXGetPointSize(u8* pointSize, GXTexOffset* texOffsets) {
ASSERTMSGLINE(507, pointSize != NULL && texOffsets != NULL, "GXGet*: invalid null pointer");
*pointSize = SU_LPSIZE_GET_PSIZE(__GXData->lpSize);
*texOffsets = SU_LPSIZE_GET_PTOFF(__GXData->lpSize);
}
void GXEnableTexOffsets(GXTexCoordID coord, u8 line_enable, u8 point_enable) {
CHECK_GXBEGIN(536, "GXEnableTexOffsets");
ASSERTMSGLINE(538, coord < GX_MAX_TEXCOORD, "GXEnableTexOffsets: Invalid coordinate Id");
SC_SU_TS0_SET_LF(540, __GXData->suTs0[coord], line_enable);
SC_SU_TS0_SET_PF(541, __GXData->suTs0[coord], point_enable);
GX_WRITE_RAS_REG(__GXData->suTs0[coord]);
__GXData->bpSentNot = 0;
}
void GXSetCullMode(GXCullMode mode) {
GXCullMode hwMode;
CHECK_GXBEGIN(564, "GXSetCullMode");
#if DEBUG
switch (mode) {
case GX_CULL_FRONT: hwMode = GX_CULL_BACK; break;
case GX_CULL_BACK: hwMode = GX_CULL_FRONT; break;
default: hwMode = mode; break;
}
#else
hwMode = (mode >> 1) & 1;
__rlwimi(hwMode, mode, 1, 30, 30);
#endif
SC_GEN_MODE_SET_REJECT_EN(577, __GXData->genMode, hwMode);
__GXData->dirtyState |= 4;
}
void GXGetCullMode(GXCullMode* mode) {
#if DEBUG
GXCullMode hwMode = GEN_MODE_GET_REJECT_EN(__GXData->genMode);
switch (hwMode) {
case GX_CULL_FRONT: *mode = GX_CULL_BACK; break;
case GX_CULL_BACK: *mode = GX_CULL_FRONT; break;
default: *mode = hwMode; break;
}
#else
// fake match?
GXCullMode hwMode = __GXData->genMode;
*mode = ((hwMode >> 0xD) & 0x2) | (((((int)hwMode >> 0xE) & 0x2) >> 0x1));
#endif
}
void GXSetCoPlanar(GXBool enable) {
u32 reg;
CHECK_GXBEGIN(620, "GXSetCoPlanar");
SC_GEN_MODE_SET_ZFREEZE(622, __GXData->genMode, enable);
reg = 0xFE080000;
GX_WRITE_RAS_REG(reg);
GX_WRITE_RAS_REG(__GXData->genMode);
__GXData->bpSentNot = 0;
}
void __GXSetGenMode(void) {
GX_WRITE_RAS_REG(__GXData->genMode);
__GXData->bpSentNot = 0;
}

567
src/revolution/gx/GXInit.c Normal file
View File

@ -0,0 +1,567 @@
#include <string.h>
#include <revolution/base/PPCArch.h>
#include <revolution/gx.h>
#include <revolution/os.h>
#include <revolution/vi.h>
#include "__gx.h"
#ifdef SDK_AUG2010
#define BUILD_DATE "Aug 23 2010"
#if DEBUG
#define BUILD_TIME "17:27:30"
#else
#define BUILD_TIME "17:33:06"
#endif
#elif SDK_SEP2006
#define BUILD_DATE "Sep 21 2006"
#define BUILD_TIME "14:32:13"
#endif
#ifdef SDK_AUG2010
#if DEBUG
const char* __GXVersion = "<< RVL_SDK - GX \tdebug build: "BUILD_DATE" "BUILD_TIME" (0x4302_145) >>";
#else
const char* __GXVersion = "<< RVL_SDK - GX \trelease build: "BUILD_DATE" "BUILD_TIME" (0x4302_145) >>";
#endif
#elif SDK_SEP2006
const char* __GXVersion = "<< RVL_SDK - GX \trelease build: "BUILD_DATE" "BUILD_TIME" (0x4200_60422) >>";
#endif
static GXFifoObj FifoObj;
static GXData gxData;
GXData* const __GXData = &gxData;
// these are supposed to be in-function static, but it messed up sbss order
u32 shutdownFuncRegistered;
u32 calledOnce;
OSTime time;
u32 peCount;
volatile void* __memReg;
volatile void* __peReg;
volatile void* __cpReg;
volatile void* __piReg;
#if DEBUG
GXBool __GXinBegin;
#endif
static u16 DefaultTexData[] ATTRIBUTE_ALIGN(32) = {
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
};
static GXVtxAttrFmtList GXDefaultVATList[] = {
{GX_VA_POS, GX_POS_XYZ, GX_F32, 0},
{GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0},
{GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0},
{GX_VA_CLR1, GX_CLR_RGBA, GX_RGBA8, 0},
{GX_VA_TEX0, GX_TEX_ST, GX_F32, 0},
{GX_VA_TEX1, GX_TEX_ST, GX_F32, 0},
{GX_VA_TEX2, GX_TEX_ST, GX_F32, 0},
{GX_VA_TEX3, GX_TEX_ST, GX_F32, 0},
{GX_VA_TEX4, GX_TEX_ST, GX_F32, 0},
{GX_VA_TEX5, GX_TEX_ST, GX_F32, 0},
{GX_VA_TEX6, GX_TEX_ST, GX_F32, 0},
{GX_VA_TEX7, GX_TEX_ST, GX_F32, 0},
{GX_VA_NULL, 0, 0, 0},
};
static f32 GXDefaultProjData[] = {1.0f, 0.0f, 1.0f, 0.0f, -1.0f, -2.0f, 0.0f};
static u32 GXTexRegionAddrTable[] = {
0x00000, 0x10000, 0x20000, 0x30000, 0x40000, 0x50000, 0x60000, 0x70000, 0x08000, 0x18000,
0x28000, 0x38000, 0x48000, 0x58000, 0x68000, 0x78000, 0x00000, 0x90000, 0x20000, 0xB0000,
0x40000, 0x98000, 0x60000, 0xB8000, 0x80000, 0x10000, 0xA0000, 0x30000, 0x88000, 0x50000,
0xA8000, 0x70000, 0x00000, 0x90000, 0x20000, 0xB0000, 0x40000, 0x90000, 0x60000, 0xB0000,
0x80000, 0x10000, 0xA0000, 0x30000, 0x80000, 0x50000, 0xA0000, 0x70000,
};
// prototypes
static int __GXShutdown(int final, u32);
static OSShutdownFunctionInfo GXShutdownFuncInfo = {__GXShutdown, 0x7F, NULL, NULL};
asm BOOL IsWriteGatherBufferEmpty(void) {
sync
mfspr r3, WPAR
andi. r3, r3, 1
}
static void EnableWriteGatherPipe(void) {
u32 hid2 = PPCMfhid2();
PPCMtwpar(OSUncachedToPhysical((void*)GXFIFO_ADDR));
hid2 |= 0x40000000;
PPCMthid2(hid2);
}
static void DisableWriteGatherPipe(void) {
u32 hid2 = PPCMfhid2();
hid2 &= ~0x40000000;
PPCMthid2(hid2);
}
static GXTexRegion*__GXDefaultTexRegionCallback(const GXTexObj* t_obj, GXTexMapID id) {
GXTexFmt fmt;
u8 mm;
fmt = GXGetTexObjFmt(t_obj);
mm = GXGetTexObjMipMap(t_obj);
id = (GXTexMapID)(id % GX_MAX_TEXMAP);
switch (fmt) {
case GX_TF_RGBA8:
if (mm) {
return &__GXData->TexRegions2[id];
}
return &__GXData->TexRegions1[id];
case GX_TF_C4:
case GX_TF_C8:
case GX_TF_C14X2:
return &__GXData->TexRegions0[id];
default:
if (mm) {
return &__GXData->TexRegions1[id];
}
return &__GXData->TexRegions0[id];
}
}
static GXTlutRegion* __GXDefaultTlutRegionCallback(u32 idx) {
if (idx >= 20) {
return NULL;
}
return &__GXData->TlutRegions[idx];
}
#if DEBUG
static void __GXDefaultVerifyCallback(GXWarningLevel level, u32 id, const char* msg) {
OSReport("Level %1d, Warning %3d: %s\n", level, id, msg);
}
#endif
static int __GXShutdown(BOOL final, u32) {
u32 reg;
u32 peCountNew;
OSTime timeNew;
if (!final) {
if (!calledOnce) {
peCount = __GXReadMEMCounterU32(0x28, 0x27);
time = OSGetTime();
calledOnce = 1;
return 0;
}
timeNew = OSGetTime();
peCountNew = __GXReadMEMCounterU32(0x28, 0x27);
if (timeNew - time < 10) {
return 0;
}
if (peCountNew != peCount) {
peCount = peCountNew;
time = timeNew;
return 0;
}
} else {
GXSetBreakPtCallback(NULL);
GXSetDrawSyncCallback(NULL);
GXSetDrawDoneCallback(NULL);
GX_WRITE_U32(0);
GX_WRITE_U32(0);
GX_WRITE_U32(0);
GX_WRITE_U32(0);
GX_WRITE_U32(0);
GX_WRITE_U32(0);
GX_WRITE_U32(0);
GX_WRITE_U32(0);
PPCSync();
reg = CP_REG_ENABLE(0, 0, 0, 0, 0, 0);
GX_CP_REG_WRITE_U16(CP_ENABLE, (u16)reg);
reg = CP_REG_CLR(1, 1, 0);
GX_CP_REG_WRITE_U16(CP_CLR, (u16)reg);
__GXData->abtWaitPECopy = 1;
__GXAbort();
}
return 1;
}
#define SOME_SET_REG_MACRO(reg, size, shift, val) \
do { \
(reg) = (u32)__rlwimi((u32)(reg), (val), (shift), (32 - (shift) - (size)), (31 - (shift))); \
} while (0);
void __GXInitRevisionBits(void) {
u32 i;
for (i = 0; i < 8; i++) {
s32 regAddr;
SC_CP_VAT_REG_A_SET_BYTEDEQUANT(0, __GXData->vatA[i], 1);
SC_CP_VAT_REG_B_SET_VCACHE_ENHANCE(0, __GXData->vatB[i], 1);
GX_WRITE_CP_STRM_REG(CP_VAT_B, (s32) i, __GXData->vatB[i]);
regAddr = i - 12;
}
{
u32 reg1 = 0;
u32 reg2 = 0;
SC_XF_ERROR_F_SET_CTEX_BUG_ENABLE(0, reg1, 1);
SC_XF_ERROR_F_SET_TFAN4_BUG_ENABLE(0, reg1, 1);
SC_XF_ERROR_F_SET_TFAN16_BUG_ENABLE(0, reg1, 1);
SC_XF_ERROR_F_SET_DUALTRAN_REG_ENABLE(0, reg1, 1);
SC_XF_ERROR_F_SET_BYPASS_BUG_ENABLE(0, reg1, 1);
SC_XF_ERROR_F_SET_FAST_MATRIX_ENABLE(0, reg1, 1);
GX_WRITE_XF_REG(0x1000, reg1, 0);
SC_XF_DUALTEXTRAN_F_SET_DUALTEXTRAN_ENABLE(0, reg2, 1);
GX_WRITE_XF_REG(0x1012, reg2, 0);
#if DEBUG
__gxVerif->xfRegsDirty[0] = 0;
#endif
}
{
u32 reg = 0;
SC_PE_CHICKEN_SET_PIWR(0, reg, 1);
SC_PE_CHICKEN_SET_TXCPY_FMT(0, reg, 1);
SC_PE_CHICKEN_SET_TXCPY_CCV(0, reg, 1);
SC_PE_CHICKEN_SET_BLENDOP(0, reg, 1);
SC_PE_CHICKEN_SET_RID(0, reg, 0x58);
GX_WRITE_RA_REG(reg);
}
}
GXFifoObj* GXInit(void* base, u32 size) {
u32 i;
u32 reg;
u32 freqBase;
OSRegisterVersion(__GXVersion);
__GXData->inDispList = FALSE;
__GXData->dlSaveContext = TRUE;
__GXData->abtWaitPECopy = 1;
#if DEBUG
__GXinBegin = FALSE;
#endif
__GXData->tcsManEnab = FALSE;
__GXData->tevTcEnab = FALSE;
GXSetMisc(GX_MT_XF_FLUSH, 0);
__piReg = OSPhysicalToUncached(0xC003000);
__cpReg = OSPhysicalToUncached(0xC000000);
__peReg = OSPhysicalToUncached(0xC001000);
__memReg = OSPhysicalToUncached(0xC004000);
__GXFifoInit();
GXInitFifoBase(&FifoObj, base, size);
GXSetCPUFifo(&FifoObj);
GXSetGPFifo(&FifoObj);
if (!shutdownFuncRegistered) {
OSRegisterShutdownFunction(&GXShutdownFuncInfo);
shutdownFuncRegistered = 1;
}
__GXPEInit();
EnableWriteGatherPipe();
__GXData->genMode = 0;
SC_GEN_MODE_SET_RID(0, __GXData->genMode, 0);
__GXData->bpMask = 255;
SC_BP_IMASK_SET_RID(0, __GXData->bpMask, 0xF);
__GXData->lpSize = 0;
SC_SU_LPSIZE_SET_RID(0, __GXData->lpSize, 0x22);
for (i = 0; i < 16; ++i) {
__GXData->tevc[i] = 0;
__GXData->teva[i] = 0;
__GXData->tref[i / 2] = 0;
__GXData->texmapId[i] = GX_TEXMAP_NULL;
SC_TEV_COLOR_ENV_SET_RID(970, __GXData->tevc[i], (0xC0 + i * 2));
SC_TEV_ALPHA_ENV_SET_RID(971, __GXData->teva[i], (0xC1 + i * 2));
SC_TEV_KSEL_SET_RID(973, __GXData->tevKsel[i/2], (0xF6 + i / 2));
SC_RAS1_TREF_SET_RID(975, __GXData->tref[i/2], (0x28 + i / 2));
}
__GXData->iref = 0;
SC_RAS1_IREF_SET_RID(0, __GXData->iref, 0x27);
for (i = 0; i < 8; ++i) {
__GXData->suTs0[i] = 0;
__GXData->suTs1[i] = 0;
SC_SU_TS0_SET_RID(984, __GXData->suTs0[i], 0x30 + i * 2);
SC_SU_TS1_SET_RID(985, __GXData->suTs1[i], 0x31 + i * 2);
}
SC_SU_SCIS0_SET_RID(0, __GXData->suScis0, 0x20);
SC_SU_SCIS1_SET_RID(0, __GXData->suScis1, 0x21);
SC_PE_CMODE0_SET_RID(0, __GXData->cmode0, 0x41);
SC_PE_CMODE1_SET_RID(0, __GXData->cmode1, 0x42);
SC_PE_ZMODE_SET_RID(0, __GXData->zmode, 0x40);
SC_PE_CONTROL_SET_RID(0, __GXData->peCtrl, 0x43);
SC_PE_COPY_CMD_SET_GAMMA(0, __GXData->cpTex, 0);
__GXData->zScale = (f32)(0xFFFFFF + 1);
__GXData->zOffset = 0.0f;
__GXData->dirtyState = 0;
__GXData->dirtyVAT = FALSE;
#if DEBUG
__gxVerif->verifyLevel = GX_WARN_NONE;
GXSetVerifyCallback((GXVerifyCallback)__GXDefaultVerifyCallback);
for (i = 0; i < 256; i++) {
SET_REG_FIELD(0, __gxVerif->rasRegs[i], 8, 24, 0xFF);
}
memset(__gxVerif->xfRegsDirty, 0, 0x50);
memset(__gxVerif->xfMtxDirty, 0, 0x100);
memset(__gxVerif->xfNrmDirty, 0, 0x60);
memset(__gxVerif->xfLightDirty, 0, 0x80);
#endif
freqBase = __OSBusClock / 500;
__GXFlushTextureState();
reg = (freqBase >> 11) | 0x400 | 0x69000000;
GX_WRITE_RAS_REG(reg);
__GXFlushTextureState();
reg = (freqBase / 0x1080) | 0x200 | 0x46000000;
GX_WRITE_RAS_REG(reg);
__GXInitRevisionBits();
for (i = 0; i < 8; i++) {
GXInitTexCacheRegion(&__GXData->TexRegions0[i], GX_FALSE, GXTexRegionAddrTable[i],
GX_TEXCACHE_32K, GXTexRegionAddrTable[i + 8], GX_TEXCACHE_32K);
GXInitTexCacheRegion(&__GXData->TexRegions1[i], GX_FALSE, GXTexRegionAddrTable[i + 16],
GX_TEXCACHE_32K, GXTexRegionAddrTable[i + 24], GX_TEXCACHE_32K);
GXInitTexCacheRegion(&__GXData->TexRegions2[i], GX_TRUE, GXTexRegionAddrTable[i + 32],
GX_TEXCACHE_32K, GXTexRegionAddrTable[i + 40], GX_TEXCACHE_32K);
}
for (i = 0; i < 16; i++) {
GXInitTlutRegion(&__GXData->TlutRegions[i], 0xC0000 + 0x2000 * i, GX_TLUT_256);
}
for (i = 0; i < 4; i++) {
GXInitTlutRegion(&__GXData->TlutRegions[i + 16], 0xE0000 + 0x8000 * i, GX_TLUT_1K);
}
{
u32 reg = CP_REG_MEMPERFSEL(MEMPERF_ZERO);
#if DEBUG
s32 regAddr;
#endif
GX_CP_REG_WRITE_U16(CP_MEMPERF_SEL, reg);
SC_CP_STAT_SEL_REG_SET_STALLPERF_SEL(0, __GXData->perfSel, STALLPERF_ZERO);
GX_WRITE_CP_STRM_REG(CP_STAT_SEL, 0, __GXData->perfSel);
#if DEBUG
regAddr = -12;
#endif
reg = XF_PERF0_F(0, 0, 0, 0);
GX_WRITE_XF_REG(0x1006, reg, 0);
reg = SU_PERF(0, 0, 0, 0, 0, 0, 0, 0, 0, 0x23);
GX_WRITE_RA_REG(reg);
reg = RAS_PERF(0, 0, 0, 0, 0, 0x24);
GX_WRITE_RA_REG(reg);
reg = TX_PERFMODE(0, 0, 0, 0, 0x67);
GX_WRITE_RA_REG(reg);
}
__GXSetIndirectMask(0);
__GXSetTmemConfig(2);
__GXInitGX();
return &FifoObj;
}
void __GXInitGX(void) {
GXRenderModeObj* rmode;
GXTexObj tex_obj;
float identity_mtx[3][4];
GXColor clear = {64, 64, 64, 255};
GXColor black = {0, 0, 0, 0};
GXColor white = {255, 255, 255, 255};
u32 i;
switch (VIGetTvFormat()) {
case VI_NTSC: rmode = &GXNtsc480IntDf; break;
case VI_PAL: rmode = &GXPal528IntDf; break;
case VI_EURGB60: rmode = &GXEurgb60Hz480IntDf; break;
case VI_MPAL: rmode = &GXMpal480IntDf; break;
default:
ASSERTMSGLINE(1177, 0, "GXInit: invalid TV format");
rmode = &GXNtsc480IntDf;
break;
}
GXSetCopyClear(clear, 0xFFFFFF);
GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, 0x3C);
GXSetTexCoordGen(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX1, 0x3C);
GXSetTexCoordGen(GX_TEXCOORD2, GX_TG_MTX2x4, GX_TG_TEX2, 0x3C);
GXSetTexCoordGen(GX_TEXCOORD3, GX_TG_MTX2x4, GX_TG_TEX3, 0x3C);
GXSetTexCoordGen(GX_TEXCOORD4, GX_TG_MTX2x4, GX_TG_TEX4, 0x3C);
GXSetTexCoordGen(GX_TEXCOORD5, GX_TG_MTX2x4, GX_TG_TEX5, 0x3C);
GXSetTexCoordGen(GX_TEXCOORD6, GX_TG_MTX2x4, GX_TG_TEX6, 0x3C);
GXSetTexCoordGen(GX_TEXCOORD7, GX_TG_MTX2x4, GX_TG_TEX7, 0x3C);
GXSetNumTexGens(1);
GXClearVtxDesc();
GXInvalidateVtxCache();
for (i = GX_VA_POS; i <= GX_LIGHT_ARRAY; i++) {
GXSetArray(i, __GXData, 0);
}
for (i = GX_VTXFMT0; i < GX_MAX_VTXFMT; i++) {
GXSetVtxAttrFmtv(i, GXDefaultVATList);
}
GXSetLineWidth(6, GX_TO_ZERO);
GXSetPointSize(6, GX_TO_ZERO);
GXEnableTexOffsets(GX_TEXCOORD0, 0, 0);
GXEnableTexOffsets(GX_TEXCOORD1, 0, 0);
GXEnableTexOffsets(GX_TEXCOORD2, 0, 0);
GXEnableTexOffsets(GX_TEXCOORD3, 0, 0);
GXEnableTexOffsets(GX_TEXCOORD4, 0, 0);
GXEnableTexOffsets(GX_TEXCOORD5, 0, 0);
GXEnableTexOffsets(GX_TEXCOORD6, 0, 0);
GXEnableTexOffsets(GX_TEXCOORD7, 0, 0);
identity_mtx[0][0] = 1.0f;
identity_mtx[0][1] = 0.0f;
identity_mtx[0][2] = 0.0f;
identity_mtx[0][3] = 0.0f;
identity_mtx[1][0] = 0.0f;
identity_mtx[1][1] = 1.0f;
identity_mtx[1][2] = 0.0f;
identity_mtx[1][3] = 0.0f;
identity_mtx[2][0] = 0.0f;
identity_mtx[2][1] = 0.0f;
identity_mtx[2][2] = 1.0f;
identity_mtx[2][3] = 0.0f;
GXLoadPosMtxImm(identity_mtx, GX_PNMTX0);
GXLoadNrmMtxImm(identity_mtx, GX_PNMTX0);
GXSetCurrentMtx(GX_PNMTX0);
GXLoadTexMtxImm(identity_mtx, GX_IDENTITY, GX_MTX3x4);
GXLoadTexMtxImm(identity_mtx, GX_PTIDENTITY, GX_MTX3x4);
GXSetViewport(0.0f, 0.0f, rmode->fbWidth, rmode->xfbHeight, 0.0f, 1.0f);
GXSetProjectionv(GXDefaultProjData);
__GXSetGenMode();
GXSetCoPlanar(GX_DISABLE);
GXSetCullMode(GX_CULL_BACK);
GXSetClipMode(GX_CLIP_ENABLE);
GXSetScissor(0, 0, rmode->fbWidth, rmode->efbHeight);
GXSetScissorBoxOffset(0, 0);
GXSetNumChans(0);
GXSetChanCtrl(GX_COLOR0A0, GX_DISABLE, GX_SRC_REG, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE);
GXSetChanAmbColor(GX_COLOR0A0, black);
GXSetChanMatColor(GX_COLOR0A0, white);
GXSetChanCtrl(GX_COLOR1A1, GX_DISABLE, GX_SRC_REG, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE);
GXSetChanAmbColor(GX_COLOR1A1, black);
GXSetChanMatColor(GX_COLOR1A1, white);
GXInvalidateTexAll();
GXSetTexRegionCallback((GXTexRegionCallback)__GXDefaultTexRegionCallback);
GXSetTlutRegionCallback(__GXDefaultTlutRegionCallback);
GXInitTexObj(&tex_obj, DefaultTexData, 4, 4, GX_TF_IA8, GX_CLAMP, GX_CLAMP, 0);
GXLoadTexObj(&tex_obj, GX_TEXMAP0);
GXLoadTexObj(&tex_obj, GX_TEXMAP1);
GXLoadTexObj(&tex_obj, GX_TEXMAP2);
GXLoadTexObj(&tex_obj, GX_TEXMAP3);
GXLoadTexObj(&tex_obj, GX_TEXMAP4);
GXLoadTexObj(&tex_obj, GX_TEXMAP5);
GXLoadTexObj(&tex_obj, GX_TEXMAP6);
GXLoadTexObj(&tex_obj, GX_TEXMAP7);
GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD1, GX_TEXMAP1, GX_COLOR0A0);
GXSetTevOrder(GX_TEVSTAGE2, GX_TEXCOORD2, GX_TEXMAP2, GX_COLOR0A0);
GXSetTevOrder(GX_TEVSTAGE3, GX_TEXCOORD3, GX_TEXMAP3, GX_COLOR0A0);
GXSetTevOrder(GX_TEVSTAGE4, GX_TEXCOORD4, GX_TEXMAP4, GX_COLOR0A0);
GXSetTevOrder(GX_TEVSTAGE5, GX_TEXCOORD5, GX_TEXMAP5, GX_COLOR0A0);
GXSetTevOrder(GX_TEVSTAGE6, GX_TEXCOORD6, GX_TEXMAP6, GX_COLOR0A0);
GXSetTevOrder(GX_TEVSTAGE7, GX_TEXCOORD7, GX_TEXMAP7, GX_COLOR0A0);
GXSetTevOrder(GX_TEVSTAGE8, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetTevOrder(GX_TEVSTAGE9, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetTevOrder(GX_TEVSTAGE10, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetTevOrder(GX_TEVSTAGE11, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetTevOrder(GX_TEVSTAGE12, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetTevOrder(GX_TEVSTAGE13, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetTevOrder(GX_TEVSTAGE14, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetTevOrder(GX_TEVSTAGE15, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetNumTevStages(1);
GXSetTevOp(GX_TEVSTAGE0, GX_REPLACE);
GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0);
GXSetZTexture(GX_ZT_DISABLE, GX_TF_Z8, 0);
for (i = GX_TEVSTAGE0; i < GX_MAX_TEVSTAGE; i++) {
GXSetTevKColorSel((GXTevStageID)i, GX_TEV_KCSEL_1_4);
GXSetTevKAlphaSel((GXTevStageID)i, GX_TEV_KASEL_1);
GXSetTevSwapMode((GXTevStageID)i, GX_TEV_SWAP0, GX_TEV_SWAP0);
}
GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA);
GXSetTevSwapModeTable(GX_TEV_SWAP1, GX_CH_RED, GX_CH_RED, GX_CH_RED, GX_CH_ALPHA);
GXSetTevSwapModeTable(GX_TEV_SWAP2, GX_CH_GREEN, GX_CH_GREEN, GX_CH_GREEN, GX_CH_ALPHA);
GXSetTevSwapModeTable(GX_TEV_SWAP3, GX_CH_BLUE, GX_CH_BLUE, GX_CH_BLUE, GX_CH_ALPHA);
for (i = GX_TEVSTAGE0; i < GX_MAX_TEVSTAGE; i++)
GXSetTevDirect((GXTevStageID)i);
GXSetNumIndStages(0);
GXSetIndTexCoordScale(GX_INDTEXSTAGE0, GX_ITS_1, GX_ITS_1);
GXSetIndTexCoordScale(GX_INDTEXSTAGE1, GX_ITS_1, GX_ITS_1);
GXSetIndTexCoordScale(GX_INDTEXSTAGE2, GX_ITS_1, GX_ITS_1);
GXSetIndTexCoordScale(GX_INDTEXSTAGE3, GX_ITS_1, GX_ITS_1);
GXSetFog(GX_FOG_NONE, 0.0f, 1.0f, 0.1f, 1.0f, black);
GXSetFogRangeAdj(GX_DISABLE, 0, NULL);
GXSetBlendMode(GX_BM_NONE, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR);
GXSetColorUpdate(GX_ENABLE);
GXSetAlphaUpdate(GX_ENABLE);
GXSetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
GXSetZCompLoc(GX_TRUE);
GXSetDither(GX_ENABLE);
GXSetDstAlpha(GX_DISABLE, 0);
GXSetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR);
GXSetFieldMask(GX_ENABLE, GX_ENABLE);
GXSetFieldMode((u8)rmode->field_rendering,
((rmode->viHeight == 2 * rmode->xfbHeight) ? GX_ENABLE : GX_DISABLE));
GXSetDispCopySrc(0, 0, rmode->fbWidth, rmode->efbHeight);
GXSetDispCopyDst(rmode->fbWidth, rmode->efbHeight);
GXSetDispCopyYScale((f32)(rmode->xfbHeight) / (f32)(rmode->efbHeight));
GXSetCopyClamp((GXFBClamp)(GX_CLAMP_TOP | GX_CLAMP_BOTTOM));
GXSetCopyFilter(rmode->aa, rmode->sample_pattern, GX_TRUE, rmode->vfilter);
GXSetDispCopyGamma(GX_GM_1_0);
GXSetDispCopyFrame2Field(GX_COPY_PROGRESSIVE);
GXClearBoundingBox();
GXPokeColorUpdate(GX_TRUE);
GXPokeAlphaUpdate(GX_TRUE);
GXPokeDither(GX_FALSE);
GXPokeBlendMode(GX_BM_NONE, GX_BL_ZERO, GX_BL_ONE, GX_LO_SET);
GXPokeAlphaMode(GX_ALWAYS, 0);
GXPokeAlphaRead(GX_READ_FF);
GXPokeDstAlpha(GX_DISABLE, 0);
GXPokeZMode(GX_TRUE, GX_ALWAYS, GX_TRUE);
GXSetGPMetric(GX_PERF0_NONE, GX_PERF1_NONE);
GXClearGPMetric();
}

571
src/revolution/gx/GXLight.c Normal file
View File

@ -0,0 +1,571 @@
#include <math.h>
#include <revolution/gx.h>
#include <revolution/os.h>
#include "__gx.h"
// GXLightObj private data
typedef struct {
u32 reserved[3];
u32 Color;
f32 a[3];
f32 k[3];
f32 lpos[3];
f32 ldir[3];
} __GXLightObjInt_struct;
void GXInitLightAttn(GXLightObj* lt_obj, f32 a0, f32 a1, f32 a2, f32 k0, f32 k1, f32 k2) {
__GXLightObjInt_struct* obj;
ASSERTMSGLINE(135, lt_obj != NULL, "Light Object Pointer is null");
obj = (__GXLightObjInt_struct*)lt_obj;
CHECK_GXBEGIN(136, "GXInitLightAttn");
obj->a[0] = a0;
obj->a[1] = a1;
obj->a[2] = a2;
obj->k[0] = k0;
obj->k[1] = k1;
obj->k[2] = k2;
}
void GXInitLightAttnA(GXLightObj* lt_obj, f32 a0, f32 a1, f32 a2) {
__GXLightObjInt_struct* obj;
ASSERTMSGLINE(143, lt_obj != NULL, "Light Object Pointer is null");
obj = (__GXLightObjInt_struct*)lt_obj;
CHECK_GXBEGIN(144, "GXInitLightAttnA");
obj->a[0] = a0;
obj->a[1] = a1;
obj->a[2] = a2;
}
void GXGetLightAttnA(const GXLightObj* lt_obj, f32* a0, f32* a1, f32* a2) {
__GXLightObjInt_struct* obj;
ASSERTMSGLINE(153, lt_obj != NULL, "Light Object Pointer is null");
obj = (__GXLightObjInt_struct*)lt_obj;
CHECK_GXBEGIN(154, "GXGetLightAttnA");
*a0 = obj->a[0];
*a1 = obj->a[1];
*a2 = obj->a[2];
}
void GXInitLightAttnK(GXLightObj* lt_obj, f32 k0, f32 k1, f32 k2) {
__GXLightObjInt_struct* obj;
ASSERTMSGLINE(163, lt_obj != NULL, "Light Object Pointer is null");
obj = (__GXLightObjInt_struct*)lt_obj;
CHECK_GXBEGIN(164, "GXInitLightAttnK");
obj->k[0] = k0;
obj->k[1] = k1;
obj->k[2] = k2;
}
void GXGetLightAttnK(const GXLightObj* lt_obj, f32* k0, f32* k1, f32* k2) {
__GXLightObjInt_struct* obj;
ASSERTMSGLINE(173, lt_obj != NULL, "Light Object Pointer is null");
obj = (__GXLightObjInt_struct*)lt_obj;
CHECK_GXBEGIN(174, "GXGetLightAttnK");
*k0 = obj->k[0];
*k1 = obj->k[1];
*k2 = obj->k[2];
}
void GXInitLightSpot(GXLightObj* lt_obj, f32 cutoff, GXSpotFn spot_func) {
f32 a0, a1, a2;
f32 r;
f32 d;
f32 cr;
__GXLightObjInt_struct* obj;
ASSERTMSGLINE(204, lt_obj != NULL, "Light Object Pointer is null");
obj = (__GXLightObjInt_struct*)lt_obj;
CHECK_GXBEGIN(206, "GXInitLightSpot");
if (cutoff <= 0.0f || cutoff > 90.0f)
spot_func = GX_SP_OFF;
r = (3.1415927f * cutoff) / 180.0f;
cr = cosf(r);
switch (spot_func) {
case GX_SP_FLAT:
a0 = -1000.0f * cr;
a1 = 1000.0f;
a2 = 0.0f;
break;
case GX_SP_COS:
a1 = 1.0f / (1.0f - cr);
a0 = -cr * a1;
a2 = 0.0f;
break;
case GX_SP_COS2:
a2 = 1.0f / (1.0f - cr);
a0 = 0.0f;
a1 = -cr * a2;
break;
case GX_SP_SHARP:
d = 1.0f / ((1.0f - cr) * (1.0f - cr));
a0 = (cr * (cr - 2.0f)) * d;
a1 = 2.0f * d;
a2 = -d;
break;
case GX_SP_RING1:
d = 1.0f / ((1.0f - cr) * (1.0f - cr));
a2 = -4.0f * d;
a0 = a2 * cr;
a1 = (4.0f * (1.0f + cr)) * d;
break;
case GX_SP_RING2:
d = 1.0f / ((1.0f - cr) * (1.0f - cr));
a0 = 1.0f - ((2.0f * cr * cr) * d);
a1 = (4.0f * cr) * d;
a2 = -2.0f * d;
break;
case GX_SP_OFF:
default:
a0 = 1.0f;
a1 = 0.0f;
a2 = 0.0f;
break;
}
obj->a[0] = a0;
obj->a[1] = a1;
obj->a[2] = a2;
}
void GXInitLightDistAttn(GXLightObj* lt_obj, f32 ref_dist, f32 ref_br, GXDistAttnFn dist_func) {
f32 k0, k1, k2;
__GXLightObjInt_struct* obj;
ASSERTMSGLINE(279, lt_obj != NULL, "Light Object Pointer is null");
obj = (__GXLightObjInt_struct*)lt_obj;
CHECK_GXBEGIN(281, "GXInitLightDistAttn");
if (ref_dist < 0.0f)
dist_func = GX_DA_OFF;
if (ref_br <= 0.0f || ref_br >= 1.0f)
dist_func = GX_DA_OFF;
switch (dist_func) {
case GX_DA_GENTLE:
k0 = 1.0f;
k1 = (1.0f - ref_br) / (ref_br * ref_dist);
k2 = 0.0f;
break;
case GX_DA_MEDIUM:
k0 = 1.0f;
k1 = (0.5f * (1.0f - ref_br)) / (ref_br * ref_dist);
k2 = (0.5f * (1.0f - ref_br)) / (ref_br * ref_dist * ref_dist);
break;
case GX_DA_STEEP:
k0 = 1.0f;
k1 = 0.0f;
k2 = (1.0f - ref_br) / (ref_br * ref_dist * ref_dist);
break;
case GX_DA_OFF:
default:
k0 = 1.0f;
k1 = 0.0f;
k2 = 0.0f;
break;
}
obj->k[0] = k0;
obj->k[1] = k1;
obj->k[2] = k2;
}
void GXInitLightPos(GXLightObj* lt_obj, f32 x, f32 y, f32 z) {
__GXLightObjInt_struct* obj;
ASSERTMSGLINE(334, lt_obj != NULL, "Light Object Pointer is null");
obj = (__GXLightObjInt_struct*)lt_obj;
CHECK_GXBEGIN(336, "GXInitLightPos");
obj->lpos[0] = x;
obj->lpos[1] = y;
obj->lpos[2] = z;
}
void GXGetLightPos(const GXLightObj* lt_obj, f32* x, f32* y, f32* z) {
__GXLightObjInt_struct* obj;
ASSERTMSGLINE(339, lt_obj != NULL, "Light Object Pointer is null");
obj = (__GXLightObjInt_struct*)lt_obj;
CHECK_GXBEGIN(341, "GXGetLightPos");
*x = obj->lpos[0];
*y = obj->lpos[1];
*z = obj->lpos[2];
}
void GXInitLightDir(GXLightObj* lt_obj, f32 nx, f32 ny, f32 nz) {
__GXLightObjInt_struct* obj;
ASSERTMSGLINE(366, lt_obj != NULL, "Light Object Pointer is null");
obj = (__GXLightObjInt_struct*)lt_obj;
obj->ldir[0] = -nx;
obj->ldir[1] = -ny;
obj->ldir[2] = -nz;
}
void GXGetLightDir(const GXLightObj* lt_obj, f32* nx, f32* ny, f32* nz) {
__GXLightObjInt_struct* obj;
ASSERTMSGLINE(372, lt_obj != NULL, "Light Object Pointer is null");
obj = (__GXLightObjInt_struct*)lt_obj;
*nx = -obj->ldir[0];
*ny = -obj->ldir[1];
*nz = -obj->ldir[2];
}
void GXInitSpecularDir(GXLightObj* lt_obj, f32 nx, f32 ny, f32 nz) {
f32 mag;
f32 vx;
f32 vy;
f32 vz;
__GXLightObjInt_struct* obj;
ASSERTMSGLINE(398, lt_obj != NULL, "Light Object Pointer is null");
obj = (__GXLightObjInt_struct*)lt_obj;
CHECK_GXBEGIN(399, "GXInitSpecularDir");
vx = -nx;
vy = -ny;
vz = -nz + 1.0f;
mag = (vx * vx) + (vy * vy) + (vz * vz);
if (mag != 0.0f) {
mag = 1.0f / sqrtf(mag);
}
obj->ldir[0] = vx * mag;
obj->ldir[1] = vy * mag;
obj->ldir[2] = vz * mag;
obj->lpos[0] = nx * -1000000000000000000.0f;
obj->lpos[1] = ny * -1000000000000000000.0f;
obj->lpos[2] = nz * -1000000000000000000.0f;
}
void GXInitSpecularDirHA(GXLightObj* lt_obj, f32 nx, f32 ny, f32 nz, f32 hx, f32 hy, f32 hz) {
__GXLightObjInt_struct* obj;
ASSERTMSGLINE(436, lt_obj != NULL, "Light Object Pointer is null");
obj = (__GXLightObjInt_struct*)lt_obj;
CHECK_GXBEGIN(437, "GXInitSpecularHA");
obj->ldir[0] = hx;
obj->ldir[1] = hy;
obj->ldir[2] = hz;
obj->lpos[0] = nx * -1000000000000000000.0f;
obj->lpos[1] = ny * -1000000000000000000.0f;
obj->lpos[2] = nz * -1000000000000000000.0f;
}
void GXInitLightColor(GXLightObj* lt_obj, GXColor color) {
__GXLightObjInt_struct* obj;
ASSERTMSGLINE(468, lt_obj != NULL, "Light Object Pointer is null");
obj = (__GXLightObjInt_struct*)lt_obj;
CHECK_GXBEGIN(469, "GXInitLightColor");
obj->Color = *(u32*)&color;
}
void GXGetLightColor(const GXLightObj* lt_obj, GXColor* color) {
__GXLightObjInt_struct* obj;
ASSERTMSGLINE(476, lt_obj != NULL, "Light Object Pointer is null");
obj = (__GXLightObjInt_struct*)lt_obj;
CHECK_GXBEGIN(477, "GXGetLightColor");
*(u32*)color = *(u32*)&obj->Color;
}
#if DEBUG
#define WRITE_SOME_LIGHT_REG1(val, addr) \
do { \
u32 xfData = val; \
GX_WRITE_U32(val); \
VERIF_MTXLIGHT(addr, xfData); \
} while (0)
#define WRITE_SOME_LIGHT_REG2(val, addr) \
do { \
f32 xfData = val; \
GX_WRITE_F32(val); \
VERIF_MTXLIGHT(addr, *(u32 *)&xfData); \
} while (0)
#else
#define WRITE_SOME_LIGHT_REG1(val, addr) GX_WRITE_U32(val)
#define WRITE_SOME_LIGHT_REG2(val, addr) GX_WRITE_F32(val)
#endif
static inline u32 ConvLightID2Num(GXLightID id) {
switch (id) {
case GX_LIGHT0: return 0;
case GX_LIGHT1: return 1;
case GX_LIGHT2: return 2;
case GX_LIGHT3: return 3;
case GX_LIGHT4: return 4;
case GX_LIGHT5: return 5;
case GX_LIGHT6: return 6;
case GX_LIGHT7: return 7;
default: return 8;
}
}
static inline void PushLight(const __REGISTER GXLightObj* lt_obj, __REGISTER void* dest) {
__REGISTER u32 zero, color;
__REGISTER f32 a0_a1, a2_k0, k1_k2;
__REGISTER f32 px_py, pz_dx, dy_dz;
#ifdef __MWERKS__ // clang-format off
asm {
lwz color, 12(lt_obj)
xor zero, zero, zero
psq_l a0_a1, 16(lt_obj), 0, 0
psq_l a2_k0, 24(lt_obj), 0, 0
psq_l k1_k2, 32(lt_obj), 0, 0
psq_l px_py, 40(lt_obj), 0, 0
psq_l pz_dx, 48(lt_obj), 0, 0
psq_l dy_dz, 56(lt_obj), 0, 0
stw zero, 0(dest)
stw zero, 0(dest)
stw zero, 0(dest)
stw color, 0(dest)
psq_st a0_a1, 0(dest), 0, 0
psq_st a2_k0, 0(dest), 0, 0
psq_st k1_k2, 0(dest), 0, 0
psq_st px_py, 0(dest), 0, 0
psq_st pz_dx, 0(dest), 0, 0
psq_st dy_dz, 0(dest), 0, 0
}
#endif // clang-format on
}
void GXLoadLightObjImm(const GXLightObj* lt_obj, GXLightID light) {
u32 addr;
u32 idx;
__GXLightObjInt_struct* obj;
ASSERTMSGLINE(579, lt_obj != NULL, "Light Object Pointer is null");
obj = (__GXLightObjInt_struct*)lt_obj;
CHECK_GXBEGIN(580, "GXLoadLightObjImm");
#if DEBUG
idx = ConvLightID2Num(light);
#else
idx = 31 - __cntlzw(light);
#endif
ASSERTMSGLINE(586, idx < 8, "GXLoadLightObjImm: Invalid Light Id");
idx &= 7;
addr = idx * 0x10 + 0x600;
GX_WRITE_U8(0x10);
GX_WRITE_U32(addr | 0xF0000);
#if DEBUG
WRITE_SOME_LIGHT_REG1(0, addr);
WRITE_SOME_LIGHT_REG1(0, addr + 1);
WRITE_SOME_LIGHT_REG1(0, addr + 2);
WRITE_SOME_LIGHT_REG1(obj->Color, addr + 3);
WRITE_SOME_LIGHT_REG2(obj->a[0], addr + 4);
WRITE_SOME_LIGHT_REG2(obj->a[1], addr + 5);
WRITE_SOME_LIGHT_REG2(obj->a[2], addr + 6);
WRITE_SOME_LIGHT_REG2(obj->k[0], addr + 7);
WRITE_SOME_LIGHT_REG2(obj->k[1], addr + 8);
WRITE_SOME_LIGHT_REG2(obj->k[2], addr + 9);
WRITE_SOME_LIGHT_REG2(obj->lpos[0], addr + 10);
WRITE_SOME_LIGHT_REG2(obj->lpos[1], addr + 11);
WRITE_SOME_LIGHT_REG2(obj->lpos[2], addr + 12);
WRITE_SOME_LIGHT_REG2(obj->ldir[0], addr + 13);
WRITE_SOME_LIGHT_REG2(obj->ldir[1], addr + 14);
WRITE_SOME_LIGHT_REG2(obj->ldir[2], addr + 15);
#else
PushLight(lt_obj, (void*)GXFIFO_ADDR);
#endif
__GXData->bpSentNot = 1;
}
void GXLoadLightObjIndx(u32 lt_obj_indx, GXLightID light) {
u32 reg;
u32 addr;
u32 idx;
CHECK_GXBEGIN(624, "GXLoadLightObjIndx");
#if DEBUG
idx = ConvLightID2Num(light);
#else
idx = 31 - __cntlzw(light);
#endif
ASSERTMSGLINE(627, idx < 8, "GXLoadLightObjIndx: Invalid Light Id");
idx &= 7;
addr = idx * 0x10 + 0x600;
reg = 0;
SET_REG_FIELD(632, reg, 12, 0, addr);
SET_REG_FIELD(634, reg, 4, 12, 0xF);
SET_REG_FIELD(634, reg, 16, 16, lt_obj_indx);
GX_WRITE_U8(0x38);
GX_WRITE_U32(reg);
#if DEBUG
__GXShadowIndexState(7, reg);
#endif
__GXData->bpSentNot = 1;
}
#define GXCOLOR_AS_U32(color) (*((u32*)&(color)))
void GXSetChanAmbColor(GXChannelID chan, GXColor amb_color) {
u32 reg = 0;
u32 rgb;
u32 colIdx;
CHECK_GXBEGIN(675, "GXSetChanAmbColor");
switch (chan) {
case GX_COLOR0:
reg = __GXData->ambColor[GX_COLOR0];
rgb = GXCOLOR_AS_U32(amb_color) >> 8;
SC_XF_AMBIENT0_F_SET_RGB(689, reg, rgb);
colIdx = 0;
break;
case GX_COLOR1:
reg = __GXData->ambColor[GX_COLOR1];
rgb = GXCOLOR_AS_U32(amb_color) >> 8;
SC_XF_AMBIENT1_F_SET_RGB(704, reg, rgb);
colIdx = 1;
break;
case GX_ALPHA0:
reg = __GXData->ambColor[GX_COLOR0];
SC_XF_AMBIENT0_F_SET_ALPHA(710, reg, amb_color.a);
colIdx = 0;
break;
case GX_ALPHA1:
reg = __GXData->ambColor[GX_COLOR1];
SC_XF_AMBIENT1_F_SET_ALPHA(716, reg, amb_color.a);
colIdx = 1;
break;
case GX_COLOR0A0:
reg = GXCOLOR_AS_U32(amb_color);
colIdx = 0;
break;
case GX_COLOR1A1:
reg = GXCOLOR_AS_U32(amb_color);
colIdx = 1;
break;
default:
ASSERTMSGLINE(745, 0, "GXSetChanAmbColor: Invalid Channel Id");
return;
}
__GXData->dirtyState |= (0x100 << colIdx);
__GXData->ambColor[colIdx] = reg;
}
void GXSetChanMatColor(GXChannelID chan, GXColor mat_color) {
u32 reg = 0;
u32 rgb;
u32 colIdx;
CHECK_GXBEGIN(776, "GXSetChanMatColor");
switch (chan) {
case GX_COLOR0:
reg = __GXData->matColor[GX_COLOR0];
rgb = GXCOLOR_AS_U32(mat_color) >> 8;
SC_XF_MATERIAL0_F_SET_RGB(790, reg, rgb);
colIdx = 0;
break;
case GX_COLOR1:
reg = __GXData->matColor[GX_COLOR1];
rgb = GXCOLOR_AS_U32(mat_color) >> 8;
SC_XF_MATERIAL1_F_SET_RGB(805, reg, rgb);
colIdx = 1;
break;
case GX_ALPHA0:
reg = __GXData->matColor[GX_COLOR0];
SC_XF_MATERIAL0_F_SET_ALPHA(811, reg, mat_color.a);
colIdx = 0;
break;
case GX_ALPHA1:
reg = __GXData->matColor[GX_COLOR1];
SC_XF_MATERIAL1_F_SET_ALPHA(817, reg, mat_color.a);
colIdx = 1;
break;
case GX_COLOR0A0:
reg = GXCOLOR_AS_U32(mat_color);
colIdx = 0;
break;
case GX_COLOR1A1:
reg = GXCOLOR_AS_U32(mat_color);
colIdx = 1;
break;
default:
ASSERTMSGLINE(846, 0, "GXSetChanMatColor: Invalid Channel Id");
return;
}
__GXData->dirtyState |= (0x400 << colIdx);
__GXData->matColor[colIdx] = reg;
}
void GXSetNumChans(u8 nChans) {
CHECK_GXBEGIN(871, "GXSetNumChans");
ASSERTMSGLINE(872, nChans <= 2, "GXSetNumChans: nChans > 2");
SC_GEN_MODE_SET_NCOL(874, __GXData->genMode, nChans);
__GXData->dirtyState |= 0x1000004;
}
void GXSetChanCtrl(GXChannelID chan, GXBool enable, GXColorSrc amb_src, GXColorSrc mat_src, u32 light_mask, GXDiffuseFn diff_fn, GXAttnFn attn_fn) {
u32 reg;
u32 idx;
CHECK_GXBEGIN(906, "GXSetChanCtrl");
ASSERTMSGLINE(909, chan >= GX_COLOR0 && chan <= GX_COLOR1A1, "GXSetChanCtrl: Invalid Channel Id");
#if DEBUG
if (chan == GX_COLOR0A0)
idx = 0;
else if (chan == GX_COLOR1A1)
idx = 1;
else
idx = chan;
#else
idx = chan & 0x3;
#endif
reg = 0;
SC_XF_COLOR0CNTRL_F_SET_LIGHTFUNC(921, reg, enable);
SC_XF_COLOR0CNTRL_F_SET_MATERIAL_SRC(922, reg, mat_src);
SC_XF_COLOR0CNTRL_F_SET_AMBIENT_SRC(923, reg, amb_src);
SC_XF_COLOR0CNTRL_F_SET_DIFFUSEATTEN(925, reg, (attn_fn == 0) ? 0 : diff_fn);
SC_XF_COLOR0CNTRL_F_SET_ATTENENABLE(926, reg, (attn_fn != 2));
SC_XF_COLOR0CNTRL_F_SET_ATTENSELECT(927, reg, (attn_fn != 0));
SC_XF_COLOR0CNTRL_F_SET_LIGHT0123(939, reg, light_mask & 0xF);
SC_XF_COLOR0CNTRL_F_SET_LIGHT4567(940, reg, (light_mask & 0xF0) >> 4);
__GXData->chanCtrl[idx] = reg;
__GXData->dirtyState |= (0x1000<<idx);
if (chan == GX_COLOR0A0) {
__GXData->chanCtrl[GX_ALPHA0] = reg;
__GXData->dirtyState |= (0x00001000|0x00004000);
} else if (chan == GX_COLOR1A1) {
__GXData->chanCtrl[GX_ALPHA1] = reg;
__GXData->dirtyState |= (0x00002000|0x00008000);
}
}

482
src/revolution/gx/GXMisc.c Normal file
View File

@ -0,0 +1,482 @@
#include <stddef.h>
#include <revolution/base/PPCArch.h>
#include <revolution/gx.h>
#include <revolution/os.h>
#include "__gx.h"
static GXDrawSyncCallback TokenCB;
static GXDrawDoneCallback DrawDoneCB;
static u8 DrawDone;
static OSThreadQueue FinishQueue;
void GXSetMisc(GXMiscToken token, u32 val) {
switch (token) {
case GX_MT_XF_FLUSH:
__GXData->vNum = val;
__GXData->vNumNot = !__GXData->vNum;
__GXData->bpSentNot = 1;
if (__GXData->vNum != 0) {
__GXData->dirtyState |= 8;
}
break;
case GX_MT_DL_SAVE_CONTEXT:
ASSERTMSGLINE(235, !__GXData->inDispList, "GXSetMisc: Cannot change DL context setting while making a display list");
__GXData->dlSaveContext = (val != 0);
break;
case GX_MT_ABORT_WAIT_COPYOUT:
__GXData->abtWaitPECopy = (val != 0);
break;
case GX_MT_NULL:
break;
default:
#if DEBUG
OSReport("GXSetMisc: bad token %d (val %d)\n", token, val);
#endif
break;
}
}
void GXFlush(void) {
CHECK_GXBEGIN(284, "GXFlush");
if (__GXData->dirtyState) {
__GXSetDirtyState();
}
GX_WRITE_U32(0);
GX_WRITE_U32(0);
GX_WRITE_U32(0);
GX_WRITE_U32(0);
GX_WRITE_U32(0);
GX_WRITE_U32(0);
GX_WRITE_U32(0);
GX_WRITE_U32(0);
PPCSync();
}
void GXResetWriteGatherPipe(void) {
while (PPCMfwpar() & 1) {
}
PPCMtwpar(OSUncachedToPhysical((void*)GXFIFO_ADDR));
}
static void __GXAbortWait(u32 clocks) {
OSTime time0;
OSTime time1;
time0 = OSGetTime();
do {
time1 = OSGetTime();
} while (time1 - time0 <= (clocks / 4));
}
static void __GXAbortWaitPECopyDone(void) {
u32 peCnt0;
u32 peCnt1;
peCnt0 = __GXReadMEMCounterU32(0x28, 0x27);
do {
peCnt1 = peCnt0;
__GXAbortWait(32);
peCnt0 = __GXReadMEMCounterU32(0x28, 0x27);
} while (peCnt0 != peCnt1);
}
void __GXAbort(void) {
if (__GXData->abtWaitPECopy && __GXIsGPFifoReady()) {
__GXAbortWaitPECopyDone();
}
__PIRegs[0x18 / 4] = 1;
__GXAbortWait(200);
__PIRegs[0x18 / 4] = 0;
__GXAbortWait(20);
}
void GXAbortFrame(void) {
__GXAbort();
if (__GXIsGPFifoReady()) {
__GXCleanGPFifo();
__GXInitRevisionBits();
__GXData->dirtyState = 0;
GXFlush();
}
}
void GXSetDrawSync(u16 token) {
BOOL enabled;
u32 reg;
CHECK_GXBEGIN(489, "GXSetDrawSync");
enabled = OSDisableInterrupts();
reg = token | 0x48000000;
GX_WRITE_RA_REG(reg);
SC_PE_TOKEN_SET_TOKEN(443, reg, token);
SC_PE_TOKEN_SET_RID(443, reg, 0x47);
GX_WRITE_RA_REG(reg);
GXFlush();
OSRestoreInterrupts(enabled);
__GXData->bpSentNot = 0;
}
u16 GXReadDrawSync(void) {
u16 token = GX_GET_PE_REG(7);
return token;
}
void GXSetDrawDone(void) {
u32 reg;
BOOL enabled;
CHECK_GXBEGIN(489, "GXSetDrawDone");
enabled = OSDisableInterrupts();
reg = 0x45000002;
GX_WRITE_RA_REG(reg);
GXFlush();
DrawDone = GX_FALSE;
OSRestoreInterrupts(enabled);
__GXData->bpSentNot = GX_FALSE;
}
void GXWaitDrawDone(void) {
BOOL enabled;
CHECK_GXBEGIN(527, "GXWaitDrawDone");
enabled = OSDisableInterrupts();
while (!DrawDone) {
OSSleepThread(&FinishQueue);
}
OSRestoreInterrupts(enabled);
}
void GXDrawDone(void) {
CHECK_GXBEGIN(558, "GXDrawDone");
GXSetDrawDone();
GXWaitDrawDone();
}
void GXPixModeSync(void) {
CHECK_GXBEGIN(580, "GXPixModeSync");
GX_WRITE_RA_REG(__GXData->peCtrl);
__GXData->bpSentNot = 0;
}
void GXTexModeSync(void) {
u32 reg;
CHECK_GXBEGIN(625, "GXTexModeSync");
reg = 0x63000000;
GX_WRITE_RA_REG(reg);
__GXData->bpSentNot = 0;
}
#if DEBUG
void __GXBypass(u32 reg) {
CHECK_GXBEGIN(647, "__GXBypass");
GX_WRITE_RA_REG(reg);
__GXData->bpSentNot = 0;
}
u16 __GXReadPEReg(u32 reg) {
return GX_GET_PE_REG(reg);
}
#endif
void GXPokeAlphaMode(GXCompare func, u8 threshold) {
u32 reg;
reg = (func << 8) | threshold;
GX_SET_PE_REG(3, reg);
}
void GXPokeAlphaRead(GXAlphaReadMode mode) {
u32 reg;
reg = 0;
SC_PE_PI_CTL_SET_AFMT(672, reg, mode);
SC_PE_PI_CTL_SET_ZFMT(672, reg, 1);
GX_SET_PE_REG(4, reg);
}
void GXPokeAlphaUpdate(GXBool update_enable) {
u32 reg;
reg = GX_GET_PE_REG(1);
SC_PE_CMODE0_SET_ALPHA_MASK(683, reg, update_enable);
GX_SET_PE_REG(1, reg);
}
void GXPokeBlendMode(GXBlendMode type, GXBlendFactor src_factor, GXBlendFactor dst_factor, GXLogicOp op) {
u32 reg;
reg = GX_GET_PE_REG(1);
SC_PE_CMODE0_SET_BLEND_ENABLE(699, reg, ((type == GX_BM_BLEND) || (type == GX_BM_SUBTRACT)));
SC_PE_CMODE0_SET_BLENDOP(700, reg, (type == GX_BM_SUBTRACT));
SC_PE_CMODE0_SET_LOGICOP_ENABLE(702, reg, (type == GX_BM_LOGIC));
SC_PE_CMODE0_SET_LOGICOP(703, reg, op);
SC_PE_CMODE0_SET_SFACTOR(704, reg, src_factor);
SC_PE_CMODE0_SET_DFACTOR(705, reg, dst_factor);
SC_PE_CMODE0_SET_RID(706, reg, 0x41);
GX_SET_PE_REG(1, reg);
}
void GXPokeColorUpdate(GXBool update_enable) {
u32 reg;
reg = GX_GET_PE_REG(1);
SC_PE_CMODE0_SET_COLOR_MASK(717, reg, update_enable);
GX_SET_PE_REG(1, reg);
}
void GXPokeDstAlpha(GXBool enable, u8 alpha) {
u32 reg = 0;
SC_PE_CMODE1_SET_CONSTANT_ALPHA(726, reg, alpha);
SC_PE_CMODE1_SET_CONSTANT_ALPHA_ENABLE(727, reg, enable);
GX_SET_PE_REG(2, reg);
}
void GXPokeDither(GXBool dither) {
u32 reg;
reg = GX_GET_PE_REG(1);
SC_PE_CMODE0_SET_DITHER_ENABLE(737, reg, dither);
GX_SET_PE_REG(1, reg);
}
void GXPokeZMode(GXBool compare_enable, GXCompare func, GXBool update_enable) {
u32 reg = 0;
SC_PE_ZMODE_SET_ENABLE(746, reg, compare_enable);
SC_PE_ZMODE_SET_FUNC(747, reg, func);
SC_PE_ZMODE_SET_MASK(748, reg, update_enable);
GX_SET_PE_REG(0, reg);
}
void GXPeekARGB(u16 x, u16 y, u32* color) {
u32 addr = (u32)OSPhysicalToUncached(0x08000000);
SC_PE_PI_EFB_ADDR_SET_X(771, addr, x);
SC_PE_PI_EFB_ADDR_SET_Y(772, addr, y);
SC_PE_PI_EFB_ADDR_SET_TYPE(773, addr, 0);
*color = *(u32*)addr;
}
void GXPokeARGB(u16 x, u16 y, u32 color) {
u32 addr = (u32)OSPhysicalToUncached(0x08000000);
SC_PE_PI_EFB_ADDR_SET_X(771, addr, x);
SC_PE_PI_EFB_ADDR_SET_Y(772, addr, y);
SC_PE_PI_EFB_ADDR_SET_TYPE(773, addr, 0);
*(u32*)addr = color;
}
void GXPeekZ(u16 x, u16 y, u32* z) {
u32 addr = (u32)OSPhysicalToUncached(0x08000000);
SC_PE_PI_EFB_ADDR_SET_X(791, addr, x);
SC_PE_PI_EFB_ADDR_SET_Y(792, addr, y);
SC_PE_PI_EFB_ADDR_SET_TYPE(793, addr, 1);
*z = *(u32*)addr;
}
void GXPokeZ(u16 x, u16 y, u32 z) {
u32 addr = (u32)OSPhysicalToUncached(0x08000000);
SC_PE_PI_EFB_ADDR_SET_X(791, addr, x);
SC_PE_PI_EFB_ADDR_SET_Y(792, addr, y);
SC_PE_PI_EFB_ADDR_SET_TYPE(793, addr, 1);
*(u32*)addr = z;
}
GXDrawSyncCallback GXSetDrawSyncCallback(GXDrawSyncCallback cb) {
GXDrawSyncCallback oldcb;
BOOL enabled;
oldcb = TokenCB;
enabled = OSDisableInterrupts();
TokenCB = cb;
OSRestoreInterrupts(enabled);
return oldcb;
}
static void GXTokenInterruptHandler(__OSInterrupt interrupt, OSContext* context) {
u16 token;
OSContext exceptionContext;
u32 reg;
token = GX_GET_PE_REG(7);
if (TokenCB != NULL) {
OSClearContext(&exceptionContext);
OSSetCurrentContext(&exceptionContext);
TokenCB(token);
OSClearContext(&exceptionContext);
OSSetCurrentContext(context);
}
reg = GX_GET_PE_REG(5);
SC_PE_INTRCTL_SET_INT0CLR(0, reg, 1);
GX_SET_PE_REG(5, reg);
}
GXDrawDoneCallback GXSetDrawDoneCallback(GXDrawDoneCallback cb) {
GXDrawDoneCallback oldcb;
BOOL enabled;
oldcb = DrawDoneCB;
enabled = OSDisableInterrupts();
DrawDoneCB = cb;
OSRestoreInterrupts(enabled);
return oldcb;
}
static void GXFinishInterruptHandler(__OSInterrupt interrupt, OSContext* context) {
OSContext exceptionContext;
u32 reg = 0;
reg = GX_GET_PE_REG(5);
SC_PE_INTRCTL_SET_INT1CLR(0, reg, 1);
GX_SET_PE_REG(5, reg);
DrawDone = 1;
if (DrawDoneCB != NULL) {
OSClearContext(&exceptionContext);
OSSetCurrentContext(&exceptionContext);
DrawDoneCB();
OSClearContext(&exceptionContext);
OSSetCurrentContext(context);
}
OSWakeupThread(&FinishQueue);
}
void __GXPEInit(void) {
u32 reg;
__OSSetInterruptHandler(0x12, GXTokenInterruptHandler);
__OSSetInterruptHandler(0x13, GXFinishInterruptHandler);
OSInitThreadQueue(&FinishQueue);
__OSUnmaskInterrupts(0x2000);
__OSUnmaskInterrupts(0x1000);
reg = GX_GET_PE_REG(5);
SC_PE_INTRCTL_SET_INT0CLR(0, reg, 1);
SC_PE_INTRCTL_SET_INT1CLR(0, reg, 1);
SC_PE_INTRCTL_SET_INT0EN(0, reg, 1);
SC_PE_INTRCTL_SET_INT1EN(0, reg, 1);
GX_SET_PE_REG(5, reg);
}
u32 GXCompressZ16(u32 z24, GXZFmt16 zfmt) {
u32 z16;
u32 z24n;
s32 exp;
s32 shift;
#if DEBUG
#define temp exp
#else
s32 temp;
u8 unused[4];
#endif
z24n = ~(z24 << 8);
temp = __cntlzw(z24n);
switch (zfmt) {
case GX_ZC_LINEAR:
z16 = (z24 >> 8) & 0xFFFF;
break;
case GX_ZC_NEAR:
if (temp > 3) {
exp = 3;
} else {
exp = temp;
}
if (exp == 3) {
shift = 7;
} else {
shift = 9 - exp;
}
z16 = ((z24 >> shift) & 0x3FFF & ~0xFFFFC000) | (exp << 14);
break;
case GX_ZC_MID:
if (temp > 7) {
exp = 7;
} else {
exp = temp;
}
if (exp == 7) {
shift = 4;
} else {
shift = 10 - exp;
}
z16 = ((z24 >> shift) & 0x1FFF & ~0xFFFFE000) | (exp << 13);
break;
case GX_ZC_FAR:
if (temp > 12) {
exp = 12;
} else {
exp = temp;
}
if (exp == 12) {
shift = 0;
} else {
shift = 11 - exp;
}
z16 = ((z24 >> shift) & 0xFFF & ~0xFFFFF000) | (exp << 12);
break;
default:
OSPanic(__FILE__, 1004, "GXCompressZ16: Invalid Z format\n");
break;
}
return z16;
}
u32 GXDecompressZ16(u32 z16, GXZFmt16 zfmt) {
u32 z24;
u32 cb1;
s32 exp;
s32 shift;
cb1; cb1; cb1; z16; z16; z16; // needed to match
switch (zfmt) {
case GX_ZC_LINEAR:
z24 = (z16 << 8) & 0xFFFF00;
break;
case GX_ZC_NEAR:
exp = (z16 >> 14) & 3;
if (exp == 3) {
shift = 7;
} else {
shift = 9 - exp;
}
cb1 = -1 << (24 - exp);
z24 = (cb1 | ((z16 & 0x3FFF) << shift)) & 0xFFFFFF;
break;
case GX_ZC_MID:
exp = (z16 >> 13) & 7;
if (exp == 7) {
shift = 4;
} else {
shift = 10 - exp;
}
cb1 = -1 << (24 - exp);
z24 = (cb1 | ((z16 & 0x1FFF) << shift)) & 0xFFFFFF;
break;
case GX_ZC_FAR:
exp = (z16 >> 12) & 0xF;
if (exp == 12) {
shift = 0;
} else {
shift = 11 - exp;
}
cb1 = -1 << (24 - exp);
z24 = (cb1 | ((z16 & 0xFFF) << shift)) & 0xFFFFFF;
break;
default:
OSPanic(__FILE__, 1054, "GXDecompressZ16: Invalid Z format\n");
break;
}
return z24;
}

431
src/revolution/gx/GXPerf.c Normal file
View File

@ -0,0 +1,431 @@
#include <revolution/gx.h>
#include <revolution/os.h>
#include "__gx.h"
void GXSetGPMetric(GXPerf0 perf0, GXPerf1 perf1) {
u32 reg;
CHECK_GXBEGIN(142, "GXSetGPMetric");
switch (__GXData->perf0) {
case GX_PERF0_VERTICES:
case GX_PERF0_CLIP_VTX:
case GX_PERF0_CLIP_CLKS:
case GX_PERF0_XF_WAIT_IN:
case GX_PERF0_XF_WAIT_OUT:
case GX_PERF0_XF_XFRM_CLKS:
case GX_PERF0_XF_LIT_CLKS:
case GX_PERF0_XF_BOT_CLKS:
case GX_PERF0_XF_REGLD_CLKS:
case GX_PERF0_XF_REGRD_CLKS:
case GX_PERF0_CLIP_RATIO:
case GX_PERF0_CLOCKS:
reg = 0;
GX_WRITE_XF_REG(0x1006, reg, 0);
break;
case GX_PERF0_TRIANGLES:
case GX_PERF0_TRIANGLES_CULLED:
case GX_PERF0_TRIANGLES_PASSED:
case GX_PERF0_TRIANGLES_SCISSORED:
case GX_PERF0_TRIANGLES_0TEX:
case GX_PERF0_TRIANGLES_1TEX:
case GX_PERF0_TRIANGLES_2TEX:
case GX_PERF0_TRIANGLES_3TEX:
case GX_PERF0_TRIANGLES_4TEX:
case GX_PERF0_TRIANGLES_5TEX:
case GX_PERF0_TRIANGLES_6TEX:
case GX_PERF0_TRIANGLES_7TEX:
case GX_PERF0_TRIANGLES_8TEX:
case GX_PERF0_TRIANGLES_0CLR:
case GX_PERF0_TRIANGLES_1CLR:
case GX_PERF0_TRIANGLES_2CLR:
reg = 0x23000000;
GX_WRITE_RAS_REG(reg);
break;
case GX_PERF0_QUAD_0CVG:
case GX_PERF0_QUAD_NON0CVG:
case GX_PERF0_QUAD_1CVG:
case GX_PERF0_QUAD_2CVG:
case GX_PERF0_QUAD_3CVG:
case GX_PERF0_QUAD_4CVG:
case GX_PERF0_AVG_QUAD_CNT:
reg = 0x24000000;
GX_WRITE_RAS_REG(reg);
break;
case GX_PERF0_NONE:
break;
default:
ASSERTMSGLINE(202, 0, "GXSetGPMetric: Invalid GXPerf0 metric name");
break;
}
switch (__GXData->perf1) {
case GX_PERF1_TEXELS:
case GX_PERF1_TX_IDLE:
case GX_PERF1_TX_REGS:
case GX_PERF1_TX_MEMSTALL:
case GX_PERF1_TC_CHECK1_2:
case GX_PERF1_TC_CHECK3_4:
case GX_PERF1_TC_CHECK5_6:
case GX_PERF1_TC_CHECK7_8:
case GX_PERF1_TC_MISS:
case GX_PERF1_CLOCKS:
reg = 0x67000000;
GX_WRITE_RAS_REG(reg);
break;
case GX_PERF1_VC_ELEMQ_FULL:
case GX_PERF1_VC_MISSQ_FULL:
case GX_PERF1_VC_MEMREQ_FULL:
case GX_PERF1_VC_STATUS7:
case GX_PERF1_VC_MISSREP_FULL:
case GX_PERF1_VC_STREAMBUF_LOW:
case GX_PERF1_VC_ALL_STALLS:
case GX_PERF1_VERTICES:
SET_REG_FIELD(0, __GXData->perfSel, 4, 4, 0);
GX_WRITE_SOME_REG4(8, 0x20, __GXData->perfSel, -12);
break;
case GX_PERF1_FIFO_REQ:
case GX_PERF1_CALL_REQ:
case GX_PERF1_VC_MISS_REQ:
case GX_PERF1_CP_ALL_REQ:
reg = 0;
GX_SET_CP_REG(3, reg);
break;
case GX_PERF1_NONE:
break;
default:
ASSERTMSGLINE(252, 0, "GXSetGPMetric: Invalid GXPerf1 metric name");
break;
}
__GXData->perf0 = perf0;
switch (__GXData->perf0) {
case GX_PERF0_VERTICES:
ASSERTMSGLINE(266, 0, "The use of GX_PERF0_VERTICES is prohibited. Use GX_PERF1_VERTICES instead.\n");
reg = 0x273;
GX_WRITE_XF_REG(0x1006, reg, 0);
break;
case GX_PERF0_CLIP_VTX: reg = 0x14A; GX_WRITE_XF_REG(0x1006, reg, 0); break;
case GX_PERF0_CLIP_CLKS: reg = 0x16B; GX_WRITE_XF_REG(0x1006, reg, 0); break;
case GX_PERF0_XF_WAIT_IN: reg = 0x84; GX_WRITE_XF_REG(0x1006, reg, 0); break;
case GX_PERF0_XF_WAIT_OUT: reg = 0xC6; GX_WRITE_XF_REG(0x1006, reg, 0); break;
case GX_PERF0_XF_XFRM_CLKS: reg = 0x210; GX_WRITE_XF_REG(0x1006, reg, 0); break;
case GX_PERF0_XF_LIT_CLKS: reg = 0x252; GX_WRITE_XF_REG(0x1006, reg, 0); break;
case GX_PERF0_XF_BOT_CLKS: reg = 0x231; GX_WRITE_XF_REG(0x1006, reg, 0); break;
case GX_PERF0_XF_REGLD_CLKS: reg = 0x1AD; GX_WRITE_XF_REG(0x1006, reg, 0); break;
case GX_PERF0_XF_REGRD_CLKS: reg = 0x1CE; GX_WRITE_XF_REG(0x1006, reg, 0); break;
case GX_PERF0_CLOCKS: reg = 0x21; GX_WRITE_XF_REG(0x1006, reg, 0); break;
case GX_PERF0_CLIP_RATIO: reg = 0x153; GX_WRITE_XF_REG(0x1006, reg, 0); break;
case GX_PERF0_TRIANGLES: reg = 0x2300AE7F; GX_WRITE_RAS_REG(reg); break;
case GX_PERF0_TRIANGLES_CULLED: reg = 0x23008E7F; GX_WRITE_RAS_REG(reg); break;
case GX_PERF0_TRIANGLES_PASSED: reg = 0x23009E7F; GX_WRITE_RAS_REG(reg); break;
case GX_PERF0_TRIANGLES_SCISSORED: reg = 0x23001E7F; GX_WRITE_RAS_REG(reg); break;
case GX_PERF0_TRIANGLES_0TEX: reg = 0x2300AC3F; GX_WRITE_RAS_REG(reg); break;
case GX_PERF0_TRIANGLES_1TEX: reg = 0x2300AC7F; GX_WRITE_RAS_REG(reg); break;
case GX_PERF0_TRIANGLES_2TEX: reg = 0x2300ACBF; GX_WRITE_RAS_REG(reg); break;
case GX_PERF0_TRIANGLES_3TEX: reg = 0x2300ACFF; GX_WRITE_RAS_REG(reg); break;
case GX_PERF0_TRIANGLES_4TEX: reg = 0x2300AD3F; GX_WRITE_RAS_REG(reg); break;
case GX_PERF0_TRIANGLES_5TEX: reg = 0x2300AD7F; GX_WRITE_RAS_REG(reg); break;
case GX_PERF0_TRIANGLES_6TEX: reg = 0x2300ADBF; GX_WRITE_RAS_REG(reg); break;
case GX_PERF0_TRIANGLES_7TEX: reg = 0x2300ADFF; GX_WRITE_RAS_REG(reg); break;
case GX_PERF0_TRIANGLES_8TEX: reg = 0x2300AE3F; GX_WRITE_RAS_REG(reg); break;
case GX_PERF0_TRIANGLES_0CLR: reg = 0x2300A27F; GX_WRITE_RAS_REG(reg); break;
case GX_PERF0_TRIANGLES_1CLR: reg = 0x2300A67F; GX_WRITE_RAS_REG(reg); break;
case GX_PERF0_TRIANGLES_2CLR: reg = 0x2300AA7F; GX_WRITE_RAS_REG(reg); break;
case GX_PERF0_QUAD_0CVG: reg = 0x2402C0C6; GX_WRITE_RAS_REG(reg); break;
case GX_PERF0_QUAD_NON0CVG: reg = 0x2402C16B; GX_WRITE_RAS_REG(reg); break;
case GX_PERF0_QUAD_1CVG: reg = 0x2402C0E7; GX_WRITE_RAS_REG(reg); break;
case GX_PERF0_QUAD_2CVG: reg = 0x2402C108; GX_WRITE_RAS_REG(reg); break;
case GX_PERF0_QUAD_3CVG: reg = 0x2402C129; GX_WRITE_RAS_REG(reg); break;
case GX_PERF0_QUAD_4CVG: reg = 0x2402C14A; GX_WRITE_RAS_REG(reg); break;
case GX_PERF0_AVG_QUAD_CNT: reg = 0x2402C1AD; GX_WRITE_RAS_REG(reg); break;
case GX_PERF0_NONE: break;
default:
ASSERTMSGLINE(512, 0, "GXSetGPMetric: Invalid GXPerf0 metric name");
break;
}
__GXData->perf1 = perf1;
switch (__GXData->perf1) {
case GX_PERF1_TEXELS: reg = 0x67000042; GX_WRITE_RAS_REG(reg); break;
case GX_PERF1_TX_IDLE: reg = 0x67000084; GX_WRITE_RAS_REG(reg); break;
case GX_PERF1_TX_REGS: reg = 0x67000063; GX_WRITE_RAS_REG(reg); break;
case GX_PERF1_TX_MEMSTALL: reg = 0x67000129; GX_WRITE_RAS_REG(reg); break;
case GX_PERF1_TC_MISS: reg = 0x67000252; GX_WRITE_RAS_REG(reg); break;
case GX_PERF1_CLOCKS: reg = 0x67000021; GX_WRITE_RAS_REG(reg); break;
case GX_PERF1_TC_CHECK1_2: reg = 0x6700014B; GX_WRITE_RAS_REG(reg); break;
case GX_PERF1_TC_CHECK3_4: reg = 0x6700018D; GX_WRITE_RAS_REG(reg); break;
case GX_PERF1_TC_CHECK5_6: reg = 0x670001CF; GX_WRITE_RAS_REG(reg); break;
case GX_PERF1_TC_CHECK7_8: reg = 0x67000211; GX_WRITE_RAS_REG(reg); break;
case GX_PERF1_VC_ELEMQ_FULL: SET_REG_FIELD(0, __GXData->perfSel, 4, 4, 2); GX_WRITE_SOME_REG4(8, 0x20, __GXData->perfSel, -12); break;
case GX_PERF1_VC_MISSQ_FULL: SET_REG_FIELD(0, __GXData->perfSel, 4, 4, 3); GX_WRITE_SOME_REG4(8, 0x20, __GXData->perfSel, -12); break;
case GX_PERF1_VC_MEMREQ_FULL: SET_REG_FIELD(0, __GXData->perfSel, 4, 4, 4); GX_WRITE_SOME_REG4(8, 0x20, __GXData->perfSel, -12); break;
case GX_PERF1_VC_STATUS7: SET_REG_FIELD(0, __GXData->perfSel, 4, 4, 5); GX_WRITE_SOME_REG4(8, 0x20, __GXData->perfSel, -12); break;
case GX_PERF1_VC_MISSREP_FULL: SET_REG_FIELD(0, __GXData->perfSel, 4, 4, 6); GX_WRITE_SOME_REG4(8, 0x20, __GXData->perfSel, -12); break;
case GX_PERF1_VC_STREAMBUF_LOW: SET_REG_FIELD(0, __GXData->perfSel, 4, 4, 7); GX_WRITE_SOME_REG4(8, 0x20, __GXData->perfSel, -12); break;
case GX_PERF1_VC_ALL_STALLS: SET_REG_FIELD(0, __GXData->perfSel, 4, 4, 9); GX_WRITE_SOME_REG4(8, 0x20, __GXData->perfSel, -12); break;
case GX_PERF1_VERTICES: SET_REG_FIELD(0, __GXData->perfSel, 4, 4, 8); GX_WRITE_SOME_REG4(8, 0x20, __GXData->perfSel, -12); break;
case GX_PERF1_FIFO_REQ: reg = 2; GX_SET_CP_REG(3, reg); break;
case GX_PERF1_CALL_REQ: reg = 3; GX_SET_CP_REG(3, reg); break;
case GX_PERF1_VC_MISS_REQ: reg = 4; GX_SET_CP_REG(3, reg); break;
case GX_PERF1_CP_ALL_REQ: reg = 5; GX_SET_CP_REG(3, reg); break;
case GX_PERF1_NONE: break;
default:
ASSERTMSGLINE(657, 0, "GXSetGPMetric: Invalid GXPerf1 metric name");
break;
}
__GXData->bpSentNot = 0;
}
#pragma scheduling off
void GXReadGPMetric(u32* cnt0, u32* cnt1) {
u32 cpCtr0, cpCtr1, cpCtr2, cpCtr3;
cpCtr0 = __GXReadCPCounterU32(32, 33);
cpCtr1 = __GXReadCPCounterU32(34, 35);
cpCtr2 = __GXReadCPCounterU32(36, 37);
cpCtr3 = __GXReadCPCounterU32(38, 39);
switch (__GXData->perf0) {
case GX_PERF0_CLIP_RATIO:
*cnt0 = cpCtr1 * 1000 / cpCtr0;
break;
case GX_PERF0_VERTICES:
case GX_PERF0_CLIP_VTX:
case GX_PERF0_CLIP_CLKS:
case GX_PERF0_XF_WAIT_IN:
case GX_PERF0_XF_WAIT_OUT:
case GX_PERF0_XF_XFRM_CLKS:
case GX_PERF0_XF_LIT_CLKS:
case GX_PERF0_XF_BOT_CLKS:
case GX_PERF0_XF_REGLD_CLKS:
case GX_PERF0_XF_REGRD_CLKS:
case GX_PERF0_TRIANGLES:
case GX_PERF0_TRIANGLES_CULLED:
case GX_PERF0_TRIANGLES_PASSED:
case GX_PERF0_TRIANGLES_SCISSORED:
case GX_PERF0_TRIANGLES_0TEX:
case GX_PERF0_TRIANGLES_1TEX:
case GX_PERF0_TRIANGLES_2TEX:
case GX_PERF0_TRIANGLES_3TEX:
case GX_PERF0_TRIANGLES_4TEX:
case GX_PERF0_TRIANGLES_5TEX:
case GX_PERF0_TRIANGLES_6TEX:
case GX_PERF0_TRIANGLES_7TEX:
case GX_PERF0_TRIANGLES_8TEX:
case GX_PERF0_TRIANGLES_0CLR:
case GX_PERF0_TRIANGLES_1CLR:
case GX_PERF0_TRIANGLES_2CLR:
case GX_PERF0_QUAD_0CVG:
case GX_PERF0_QUAD_NON0CVG:
case GX_PERF0_QUAD_1CVG:
case GX_PERF0_QUAD_2CVG:
case GX_PERF0_QUAD_3CVG:
case GX_PERF0_QUAD_4CVG:
case GX_PERF0_AVG_QUAD_CNT:
case GX_PERF0_CLOCKS:
*cnt0 = cpCtr0;
break;
case GX_PERF0_NONE:
*cnt0 = 0;
break;
default:
ASSERTMSGLINE(765, 0, "GXReadGPMetric: Invalid GXPerf0 metric name");
*cnt0 = 0;
break;
}
switch (__GXData->perf1) {
case GX_PERF1_TEXELS:
*cnt1 = cpCtr3 * 4;
break;
case GX_PERF1_TC_CHECK1_2:
*cnt1 = cpCtr2 + (cpCtr3 * 2);
break;
case GX_PERF1_TC_CHECK3_4:
*cnt1 = (cpCtr2 * 3) + (cpCtr3 * 4);
break;
case GX_PERF1_TC_CHECK5_6:
*cnt1 = (cpCtr2 * 5) + (cpCtr3 * 6);
break;
case GX_PERF1_TC_CHECK7_8:
*cnt1 = (cpCtr2 * 7) + (cpCtr3 * 8);
break;
case GX_PERF1_TX_IDLE:
case GX_PERF1_TX_REGS:
case GX_PERF1_TX_MEMSTALL:
case GX_PERF1_TC_MISS:
case GX_PERF1_VC_ELEMQ_FULL:
case GX_PERF1_VC_MISSQ_FULL:
case GX_PERF1_VC_MEMREQ_FULL:
case GX_PERF1_VC_STATUS7:
case GX_PERF1_VC_MISSREP_FULL:
case GX_PERF1_VC_STREAMBUF_LOW:
case GX_PERF1_VC_ALL_STALLS:
case GX_PERF1_VERTICES:
case GX_PERF1_CLOCKS:
*cnt1 = cpCtr3;
break;
case GX_PERF1_FIFO_REQ:
case GX_PERF1_CALL_REQ:
case GX_PERF1_VC_MISS_REQ:
case GX_PERF1_CP_ALL_REQ:
*cnt1 = cpCtr2;
break;
case GX_PERF1_NONE:
*cnt1 = 0;
break;
default:
ASSERTMSGLINE(824, 0, "GXReadGPMetric: Invalid GXPerf1 metric name");
*cnt1 = 0;
break;
}
}
#pragma scheduling reset
void GXClearGPMetric(void) {
u32 reg;
reg = 4;
GX_SET_CP_REG(2, reg);
}
u32 GXReadGP0Metric(void) {
u32 cnt0, cnt1;
GXReadGPMetric(&cnt0, &cnt1);
return cnt0;
}
u32 GXReadGP1Metric(void) {
u32 cnt0, cnt1;
GXReadGPMetric(&cnt0, &cnt1);
return cnt1;
}
#pragma scheduling off
void GXReadMemMetric(u32* cp_req, u32* tc_req, u32* cpu_rd_req, u32* cpu_wr_req, u32* dsp_req, u32* io_req, u32* vi_req, u32* pe_req, u32* rf_req, u32* fi_req) {
*cp_req = __GXReadMEMCounterU32(26, 25);
*tc_req = __GXReadMEMCounterU32(28, 27);
*cpu_rd_req = __GXReadMEMCounterU32(30, 29);
*cpu_wr_req = __GXReadMEMCounterU32(32, 31);
*dsp_req = __GXReadMEMCounterU32(34, 33);
*io_req = __GXReadMEMCounterU32(36, 35);
*vi_req = __GXReadMEMCounterU32(38, 37);
*pe_req = __GXReadMEMCounterU32(40, 39);
*rf_req = __GXReadMEMCounterU32(42, 41);
*fi_req = __GXReadMEMCounterU32(44, 43);
}
#pragma scheduling reset
void GXClearMemMetric(void) {
GX_SET_MEM_REG(25, 0);
GX_SET_MEM_REG(26, 0);
GX_SET_MEM_REG(27, 0);
GX_SET_MEM_REG(28, 0);
GX_SET_MEM_REG(30, 0);
GX_SET_MEM_REG(29, 0);
GX_SET_MEM_REG(32, 0);
GX_SET_MEM_REG(31, 0);
GX_SET_MEM_REG(34, 0);
GX_SET_MEM_REG(33, 0);
GX_SET_MEM_REG(36, 0);
GX_SET_MEM_REG(35, 0);
GX_SET_MEM_REG(38, 0);
GX_SET_MEM_REG(37, 0);
GX_SET_MEM_REG(40, 0);
GX_SET_MEM_REG(39, 0);
GX_SET_MEM_REG(42, 0);
GX_SET_MEM_REG(41, 0);
GX_SET_MEM_REG(44, 0);
GX_SET_MEM_REG(43, 0);
}
#pragma scheduling off
void GXReadPixMetric(u32* top_pixels_in, u32* top_pixels_out, u32* bot_pixels_in, u32* bot_pixels_out, u32* clr_pixels_in, u32* copy_clks) {
*top_pixels_in = __GXReadPECounterU32(12, 13) * 4;
*top_pixels_out = __GXReadPECounterU32(14, 15) * 4;
*bot_pixels_in = __GXReadPECounterU32(16, 17) * 4;
*bot_pixels_out = __GXReadPECounterU32(18, 19) * 4;
*clr_pixels_in = __GXReadPECounterU32(20, 21) * 4;
*copy_clks = __GXReadPECounterU32(22, 23);
}
#pragma scheduling reset
void GXClearPixMetric(void) {
u32 reg;
CHECK_GXBEGIN(1163, "GXClearPixMetric");
reg = 0x57000000;
GX_WRITE_RAS_REG(reg);
reg = 0x57000AAA;
GX_WRITE_RAS_REG(reg);
__GXData->bpSentNot = 0;
}
void GXSetVCacheMetric(GXVCachePerf attr) {
u32 reg;
SET_REG_FIELD(1194, __GXData->perfSel, 4, 0, attr);
GX_WRITE_SOME_REG4(8, 0x20, __GXData->perfSel, -12);
reg = 1;
GX_WRITE_SOME_REG4(8, 0x10, reg, -12);
}
#pragma scheduling off
void GXReadVCacheMetric(u32* check, u32* miss, u32* stall) {
*check = __GXReadCPCounterU32(40, 41);
*miss = __GXReadCPCounterU32(42, 43);
*stall = __GXReadCPCounterU32(44, 45);
}
#pragma scheduling reset
void GXClearVCacheMetric(void) {
GX_WRITE_SOME_REG4(8, 0, 0, -12);
}
void GXInitXfRasMetric(void) {
u32 reg;
CHECK_GXBEGIN(1293, "GXInitXfRasMetric");
reg = 0x2402C022;
GX_WRITE_RAS_REG(reg);
reg = 0x31000;
GX_WRITE_XF_REG(6, reg, 0);
__GXData->bpSentNot = 1;
}
#pragma scheduling off
void GXReadXfRasMetric(u32* xf_wait_in, u32* xf_wait_out, u32* ras_busy, u32* clocks) {
*ras_busy = __GXReadCPCounterU32(32, 33);
*clocks = __GXReadCPCounterU32(34, 35);
*xf_wait_in = __GXReadCPCounterU32(36, 37);
*xf_wait_out = __GXReadCPCounterU32(38, 39);
}
#pragma scheduling reset
u32 GXReadClksPerVtx(void) {
u32 perfCnt;
u32 ctrh;
GXDrawDone();
GX_SET_CP_REG(49, 0x1007);
GX_SET_CP_REG(48, 0x1007);
ctrh = GX_GET_CP_REG(50);
perfCnt = ctrh >> 8;
return perfCnt;
}
void __GXSetBWDials(u16 cpDial, u16 tcDial, u16 peDial, u16 cpuRdDial, u16 cpuWrDial) {
__MEMRegs[9] = cpDial;
__MEMRegs[10] = tcDial;
__MEMRegs[11] = peDial;
__MEMRegs[12] = cpuRdDial;
__MEMRegs[13] = cpuWrDial;
}

332
src/revolution/gx/GXPixel.c Normal file
View File

@ -0,0 +1,332 @@
#include <math.h>
#include <revolution/gx.h>
#include <revolution/os.h>
#include "__gx.h"
void GXSetFog(GXFogType type, f32 startz, f32 endz, f32 nearz, f32 farz, GXColor color) {
u32 fogclr;
u32 fog0;
u32 fog1;
u32 fog2;
u32 fog3;
f32 A;
f32 B;
f32 B_mant;
f32 C;
f32 a;
f32 c;
u32 B_expn;
u32 b_m;
u32 b_s;
u32 a_hex;
u32 c_hex;
u32 fsel;
u32 proj;
u32 rgba;
fogclr = 0;
fog0 = 0;
fog1 = 0;
fog2 = 0;
fog3 = 0;
CHECK_GXBEGIN(152, "GXSetFog");
ASSERTMSGLINE(154, farz >= 0.0f, "GXSetFog: The farz should be positive value");
ASSERTMSGLINE(155, farz >= nearz, "GXSetFog: The farz should be larger than nearz");
fsel = type & 7;
proj = (type >> 3) & 1;
if (proj) {
if (farz == nearz || endz == startz) {
a = 0.0f;
c = 0.0f;
} else {
A = (1.0f / (endz - startz));
a = A * (farz - nearz);
c = A * (startz - nearz);
}
} else {
if (farz == nearz || endz == startz) {
A = 0.0f;
B = 0.5f;
C = 0.0f;
} else {
A = (farz * nearz) / ((farz - nearz) * (endz - startz));
B = farz / (farz - nearz);
C = startz / (endz - startz);
}
B_mant = B;
B_expn = 0;
while (B_mant > 1.0) {
B_mant /= 2.0f;
B_expn++;
}
while (B_mant > 0.0f && B_mant < 0.5) {
B_mant *= 2.0f;
B_expn--;
}
a = A / (f32) (1 << (B_expn + 1));
b_m = 8.388638e6f * B_mant;
b_s = B_expn + 1;
c = C;
SET_REG_FIELD(212, fog1, 24, 0, b_m);
SET_REG_FIELD(212, fog1, 8, 24, 0xEF);
SET_REG_FIELD(215, fog2, 5, 0, b_s);
SET_REG_FIELD(215, fog2, 8, 24, 0xF0);
GX_WRITE_RAS_REG(fog1);
GX_WRITE_RAS_REG(fog2);
}
a_hex = *(u32*)&a;
c_hex = *(u32*)&c;
SET_REG_FIELD(226, fog0, 11, 0, (a_hex >> 12) & 0x7FF);
SET_REG_FIELD(227, fog0, 8, 11, (a_hex >> 23) & 0xFF);
SET_REG_FIELD(228, fog0, 1, 19, (a_hex >> 31));
SET_REG_FIELD(228, fog0, 8, 24, 0xEE);
SET_REG_FIELD(231, fog3, 11, 0, (c_hex >> 12) & 0x7FF);
SET_REG_FIELD(232, fog3, 8, 11, (c_hex >> 23) & 0xFF);
SET_REG_FIELD(233, fog3, 1, 19, (c_hex >> 31));
SET_REG_FIELD(234, fog3, 1, 20, proj);
SET_REG_FIELD(235, fog3, 3, 21, fsel);
SET_REG_FIELD(236, fog3, 8, 24, 0xF1);
rgba = *(u32*)&color;
SET_REG_FIELD(239, fogclr, 24, 0, rgba >> 8);
SET_REG_FIELD(240, fogclr, 8, 24, 0xF2);
GX_WRITE_RAS_REG(fog0);
GX_WRITE_RAS_REG(fog3);
GX_WRITE_RAS_REG(fogclr);
__GXData->bpSentNot = 0;
}
void GXSetFogColor(GXColor color) {
u32 rgba;
u32 fogclr = 0xF2000000;
rgba = *(u32*)&color;
SET_REG_FIELD(250, fogclr, 24, 0, rgba >> 8);
GX_WRITE_RAS_REG(fogclr);
__GXData->bpSentNot = 0;
}
void GXInitFogAdjTable(GXFogAdjTable *table, u16 width, const f32 projmtx[4][4]) {
f32 xi;
f32 iw;
f32 rangeVal;
f32 nearZ;
f32 sideX;
u32 i;
CHECK_GXBEGIN(275, "GXInitFogAdjTable");
ASSERTMSGLINE(276, table != NULL, "GXInitFogAdjTable: table pointer is null");
ASSERTMSGLINE(277, width <= 640, "GXInitFogAdjTable: invalid width value");
if (0.0 == projmtx[3][3]) {
nearZ = projmtx[2][3] / (projmtx[2][2] - 1.0f);
sideX = nearZ / projmtx[0][0];
} else {
sideX = 1.0f / projmtx[0][0];
nearZ = 1.73205f * sideX;
}
iw = 2.0f / width;
for (i = 0; i < 10; i++) {
xi = (i + 1) << 5;
xi *= iw;
xi *= sideX;
rangeVal = sqrtf(1.0f + ((xi * xi) / (nearZ * nearZ)));
table->r[i] = (u32)(256.0f * rangeVal) & 0xFFF;
}
}
void GXSetFogRangeAdj(GXBool enable, u16 center, const GXFogAdjTable *table) {
u32 i;
u32 range_adj;
u32 range_c;
CHECK_GXBEGIN(347, "GXSetFogRangeAdj");
if (enable) {
ASSERTMSGLINE(350, table != NULL, "GXSetFogRangeAdj: table pointer is null");
for (i = 0; i < 10; i += 2) {
range_adj = 0;
SET_REG_FIELD(354, range_adj, 12, 0, table->r[i]);
SET_REG_FIELD(355, range_adj, 12, 12, table->r[i + 1]);
SET_REG_FIELD(356, range_adj, 8, 24, (i >> 1) + 0xE9);
GX_WRITE_RAS_REG(range_adj);
}
}
range_c = 0;
SET_REG_FIELD(362, range_c, 10, 0, center + 342);
SET_REG_FIELD(363, range_c, 1, 10, enable);
SET_REG_FIELD(364, range_c, 8, 24, 0xE8);
GX_WRITE_RAS_REG(range_c);
__GXData->bpSentNot = 0;
}
void GXSetBlendMode(GXBlendMode type, GXBlendFactor src_factor, GXBlendFactor dst_factor, GXLogicOp op) {
u32 reg;
u32 blend_en;
CHECK_GXBEGIN(391, "GXSetBlendMode");
reg = __GXData->cmode0;
#if DEBUG
blend_en = type == GX_BM_BLEND || type == GX_BM_SUBTRACT;
#endif
SET_REG_FIELD(405, reg, 1, 11, (type == GX_BM_SUBTRACT));
#if DEBUG
SET_REG_FIELD(408, reg, 1, 0, blend_en);
#else
SET_REG_FIELD(408, reg, 1, 0, type);
#endif
SET_REG_FIELD(409, reg, 1, 1, (type == GX_BM_LOGIC));
SET_REG_FIELD(410, reg, 4, 12, op);
SET_REG_FIELD(411, reg, 3, 8, src_factor);
SET_REG_FIELD(412, reg, 3, 5, dst_factor);
GX_WRITE_RAS_REG(reg);
__GXData->cmode0 = reg;
__GXData->bpSentNot = 0;
}
void GXSetColorUpdate(GXBool update_enable) {
u32 reg;
CHECK_GXBEGIN(435, "GXSetColorUpdate");
reg = __GXData->cmode0;
SET_REG_FIELD(437, reg, 1, 3, update_enable);
GX_WRITE_RAS_REG(reg);
__GXData->cmode0 = reg;
__GXData->bpSentNot = 0;
}
void GXSetAlphaUpdate(GXBool update_enable) {
u32 reg;
CHECK_GXBEGIN(474, "GXSetAlphaUpdate");
reg = __GXData->cmode0;
SET_REG_FIELD(476, reg, 1, 4, update_enable);
GX_WRITE_RAS_REG(reg);
__GXData->cmode0 = reg;
__GXData->bpSentNot = 0;
}
void GXSetZMode(GXBool compare_enable, GXCompare func, GXBool update_enable) {
u32 reg;
CHECK_GXBEGIN(517, "GXSetZMode");
reg = __GXData->zmode;
SET_REG_FIELD(520, reg, 1, 0, compare_enable);
SET_REG_FIELD(521, reg, 3, 1, func);
SET_REG_FIELD(522, reg, 1, 4, update_enable);
GX_WRITE_RAS_REG(reg);
__GXData->zmode = reg;
__GXData->bpSentNot = 0;
}
void GXSetZCompLoc(GXBool before_tex) {
CHECK_GXBEGIN(532, "GXSetZCompLoc");
SET_REG_FIELD(533, __GXData->peCtrl, 1, 6, before_tex);
GX_WRITE_RAS_REG(__GXData->peCtrl);
__GXData->bpSentNot = 0;
}
void GXSetPixelFmt(GXPixelFmt pix_fmt, GXZFmt16 z_fmt) {
u32 oldPeCtrl;
u8 aa;
static u32 p2f[8] = { 0, 1, 2, 3, 4, 4, 4, 5 };
CHECK_GXBEGIN(569, "GXSetPixelFmt");
oldPeCtrl = __GXData->peCtrl;
ASSERTMSGLINE(573, pix_fmt >= GX_PF_RGB8_Z24 && pix_fmt <= GX_PF_YUV420, "Invalid Pixel format");
SET_REG_FIELD(575, __GXData->peCtrl, 3, 0, p2f[pix_fmt]);
SET_REG_FIELD(576, __GXData->peCtrl, 3, 3, z_fmt);
if (oldPeCtrl != __GXData->peCtrl) {
GX_WRITE_RAS_REG(__GXData->peCtrl);
aa = ((pix_fmt == GX_PF_RGB565_Z16) ? GX_TRUE : GX_FALSE);
SET_REG_FIELD(585, __GXData->genMode, 1, 9, aa);
__GXData->dirtyState |= 4;
}
if (p2f[pix_fmt] == 4) {
SET_REG_FIELD(592, __GXData->cmode1, 2, 9, (pix_fmt - 4) & 0x3);
SET_REG_FIELD(592, __GXData->cmode1, 8, 24, 0x42);
GX_WRITE_RAS_REG(__GXData->cmode1);
}
__GXData->bpSentNot = 0;
}
void GXSetDither(GXBool dither) {
u32 reg;
CHECK_GXBEGIN(634, "GXSetDither");
reg = __GXData->cmode0;
SET_REG_FIELD(637, reg, 1, 2, dither);
GX_WRITE_RAS_REG(reg);
__GXData->cmode0 = reg;
__GXData->bpSentNot = 0;
}
void GXSetDstAlpha(GXBool enable, u8 alpha) {
u32 reg;
CHECK_GXBEGIN(675, "GXSetDstAlpha");
reg = __GXData->cmode1;
SET_REG_FIELD(678, reg, 8, 0, alpha);
SET_REG_FIELD(679, reg, 1, 8, enable);
GX_WRITE_RAS_REG(reg);
__GXData->cmode1 = reg;
__GXData->bpSentNot = 0;
}
void GXSetFieldMask(GXBool odd_mask, GXBool even_mask) {
u32 reg;
CHECK_GXBEGIN(702, "GXSetFieldMask");
reg = 0;
SET_REG_FIELD(704, reg, 1, 0, even_mask);
SET_REG_FIELD(705, reg, 1, 1, odd_mask);
SET_REG_FIELD(705, reg, 8, 24, 0x44);
GX_WRITE_RAS_REG(reg);
__GXData->bpSentNot = 0;
}
void GXSetFieldMode(GXBool field_mode, GXBool half_aspect_ratio) {
u32 reg;
CHECK_GXBEGIN(731, "GXSetFieldMode");
SET_REG_FIELD(735, __GXData->lpSize, 1, 22, half_aspect_ratio);
GX_WRITE_RAS_REG(__GXData->lpSize);
__GXFlushTextureState();
reg = field_mode | 0x68000000;
GX_WRITE_RAS_REG(reg);
__GXFlushTextureState();
}

528
src/revolution/gx/GXSave.c Normal file
View File

@ -0,0 +1,528 @@
#if DEBUG
#include <revolution/gx.h>
#include <revolution/os.h>
#include "__gx.h"
static const u8* dlist;
static u32 dlistSize;
static u32 bytesRead;
// prototypes
void __GXShadowIndexState(u32 idx_reg, u32 reg_data);
static u8 __ReadMem(void* ptr, u32 sz) {
const u8* src;
u8* dst;
u32 i;
if (sz > dlistSize - bytesRead) {
return FALSE;
}
src = dlist;
dst = ptr;
for (i = 0; i < sz; i++) {
*dst++ = *src++;
}
bytesRead += sz;
dlist += sz;
return TRUE;
}
inline void DPF(char*, ...) {
u8 unused[4];
}
static void __SaveCPRegs(u8 reg, u8 vatIdx, u32 data) {
s32 idx;
DPF("\tCP Stream Reg[0x%x] = 0x%x\n", reg, data);
switch (reg) {
case 0:
case 1:
case 2:
case 3:
case 4:
break;
case 5:
__GXData->vcdLo = data;
break;
case 6:
__GXData->vcdHi = data;
break;
case 7:
__GXData->vatA[vatIdx] = data;
break;
case 8:
__GXData->vatB[vatIdx] = data;
break;
case 9:
__GXData->vatC[vatIdx] = data;
break;
case 10:
idx = vatIdx - 0x15;
if ((idx >= 0) && (idx < 4)) {
__GXData->indexBase[idx] = data;
}
break;
case 11:
idx = vatIdx - 0x15;
if ((idx >= 0) && (idx < 4)) {
__GXData->indexStride[idx] = data;
}
break;
default:
if (__gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_DL_INV_CMD]) {
__GX_WARN(GXWARN_DL_INV_CMD);
}
OSReport("[Invalid CP Stream Register Address 0x%x\n]", reg);
break;
}
}
static void __ReconstVtxStatus(u8 vatIdx) {
u32 vat;
if (GET_REG_FIELD(__GXData->vcdLo, 2, 11) & 3) {
vat = __GXData->vatA[vatIdx];
if ((vat >> 9) & 1) {
__GXData->hasNrms = 0;
__GXData->hasBiNrms = 1;
} else {
__GXData->hasNrms = 1;
__GXData->hasBiNrms = 0;
}
}
}
static u32 vtxCompSize[5] = { 1, 1, 2, 2, 4 };
static int clrCompSize[6] = { 2, 3, 4, 2, 3, 4 };
static u32 GetAttrSize(u8 vatIdx, u32 attrIdx) {
u32 vcd;
u32 vat;
u32 nc;
switch (attrIdx) {
case 0:
return GET_REG_FIELD(__GXData->vcdLo, 1, 0) ? 1 : 0;
case 1:
return GET_REG_FIELD(__GXData->vcdLo, 1, 1) ? 1 : 0;
case 2:
return GET_REG_FIELD(__GXData->vcdLo, 1, 2) ? 1 : 0;
case 3:
return GET_REG_FIELD(__GXData->vcdLo, 1, 3) ? 1 : 0;
case 4:
return GET_REG_FIELD(__GXData->vcdLo, 1, 4) ? 1 : 0;
case 5:
return GET_REG_FIELD(__GXData->vcdLo, 1, 5) ? 1 : 0;
case 6:
return GET_REG_FIELD(__GXData->vcdLo, 1, 6) ? 1 : 0;
case 7:
return GET_REG_FIELD(__GXData->vcdLo, 1, 7) ? 1 : 0;
case 8:
return GET_REG_FIELD(__GXData->vcdLo, 1, 8) ? 1 : 0;
case 9:
vcd = __GXData->vcdLo;
vat = __GXData->vatA[vatIdx & 0xFF];
switch (GET_REG_FIELD(vcd, 2, 9)) {
case 0:
return 0;
case 2:
return 1;
case 3:
return 2;
case 1:
return ((vat & 1) + 2) * vtxCompSize[(vat >> 1) & 7];
}
break;
case 10:
vcd = __GXData->vcdLo;
vat = __GXData->vatA[vatIdx & 0xFF];
switch (GET_REG_FIELD(vcd, 2, 11)) {
case 0:
return 0;
case 2:
if ((vat >> 9) & 1 && vat >> 31) {
nc = 3;
} else {
nc = 1;
}
return nc;
case 3:
if ((vat >> 9) & 1 && vat >> 31) {
nc = 6;
} else {
nc = 2;
}
return nc;
case 1:
if ((vat >> 9) & 1) {
nc = 9;
} else {
nc = 3;
}
return nc * vtxCompSize[(vat >> 10) & 7];
}
break;
case 11:
switch (GET_REG_FIELD(__GXData->vcdLo, 2, 13)) {
case 0:
return 0;
case 2:
return 1;
case 3:
return 2;
case 1:
vat = __GXData->vatA[vatIdx];
return clrCompSize[(vat >> 14) & 7];
}
break;
case 12:
switch (GET_REG_FIELD(__GXData->vcdLo, 2, 15)) {
case 0:
return 0;
case 2:
return 1;
case 3:
return 2;
case 1:
vat = __GXData->vatA[vatIdx];
return clrCompSize[(vat >> 18) & 7];
}
break;
case 13:
vcd = __GXData->vcdHi;
vat = __GXData->vatA[vatIdx & 0xFF];
switch (GET_REG_FIELD(vcd, 2, 0)) {
case 0:
return 0;
case 2:
return 1;
case 3:
return 2;
case 1:
return (((vat >> 21) & 1) + 1) * vtxCompSize[(vat >> 22) & 7];
}
break;
case 14:
vcd = __GXData->vcdHi;
vat = __GXData->vatB[vatIdx & 0xFF];
switch (GET_REG_FIELD(vcd, 2, 2)) {
case 0:
return 0;
case 2:
return 1;
case 3:
return 2;
case 1:
return (((vat >> 0) & 1) + 1) * vtxCompSize[(vat >> 1) & 7];
}
break;
case 15:
vcd = __GXData->vcdHi;
vat = __GXData->vatB[vatIdx & 0xFF];
switch (GET_REG_FIELD(vcd, 2, 4)) {
case 0:
return 0;
case 2:
return 1;
case 3:
return 2;
case 1:
return (((vat >> 9) & 1) + 1) * vtxCompSize[(vat >> 10) & 7];
}
break;
case 16:
vcd = __GXData->vcdHi;
vat = __GXData->vatB[vatIdx & 0xFF];
switch (GET_REG_FIELD(vcd, 2, 6)) {
case 0:
return 0;
case 2:
return 1;
case 3:
return 2;
case 1:
return (((vat >> 18) & 1) + 1) * vtxCompSize[(vat >> 19) & 7];
}
break;
case 17:
vcd = __GXData->vcdHi;
vat = __GXData->vatB[vatIdx & 0xFF];
switch (GET_REG_FIELD(vcd, 2, 8)) {
case 0:
return 0;
case 2:
return 1;
case 3:
return 2;
case 1:
return (((vat >> 27) & 1) + 1) * vtxCompSize[(vat >> 28) & 7];
}
break;
case 18:
vcd = __GXData->vcdHi;
vat = __GXData->vatC[vatIdx & 0xFF];
switch (GET_REG_FIELD(vcd, 2, 10)) {
case 0:
return 0;
case 2:
return 1;
case 3:
return 2;
case 1:
return (((vat >> 5) & 1) + 1) * vtxCompSize[(vat >> 6) & 7];
}
break;
case 19:
vcd = __GXData->vcdHi;
vat = __GXData->vatC[vatIdx & 0xFF];
switch (GET_REG_FIELD(vcd, 2, 12)) {
case 0:
return 0;
case 2:
return 1;
case 3:
return 2;
case 1:
return (((vat >> 14) & 1) + 1) * vtxCompSize[(vat >> 15) & 7];
}
break;
case 20:
vcd = __GXData->vcdHi;
vat = __GXData->vatC[vatIdx & 0xFF];
switch (GET_REG_FIELD(vcd, 2, 14)) {
case 0:
return 0;
case 2:
return 1;
case 3:
return 2;
case 1:
return (((vat >> 23) & 1) + 1) * vtxCompSize[(vat >> 24) & 7];
}
break;
}
return 0;
}
static void __ParseVertexData(u8 vatIdx) {
u16 vcnt;
GXAttr attrIdx;
u32 vsize;
if (__ReadMem(&vcnt, 2)) {
vsize = 0;
for (attrIdx = 0; attrIdx < GX_VA_MAX_ATTR; attrIdx++) {
if (attrIdx != GX_VA_NBT) {
vsize += GetAttrSize(vatIdx, attrIdx);
}
}
vsize *= vcnt;
dlist += vsize;
bytesRead += vsize;
}
}
void __GXShadowDispList(void* list, u32 nbytes) {
u8 cmd;
u8 cmdOp;
u8 vatIdx;
u32 reg32;
u32 d32;
u8 reg8;
u8 cpAddr;
u32 i;
u32 addr;
u32 cnt;
if (__gxVerif->verifyLevel == GX_WARN_NONE) {
return;
}
dlist = list;
dlistSize = nbytes;
bytesRead = 0;
DPF("Displaylist IN\n");
while (dlistSize > bytesRead) {
if (!__ReadMem(&cmd, 1)) {
break;
}
cmdOp = (u32)GET_REG_FIELD((u32)cmd, 5, 3);
vatIdx = cmd & 7;
switch (cmdOp) {
case 0:
case 9:
break;
case 16:
case 18:
case 19:
case 20:
case 21:
case 22:
case 23:
__ReconstVtxStatus(vatIdx);
__GXVerifyState(vatIdx);
__ParseVertexData(vatIdx);
break;
case 1:
if (__ReadMem(&reg8, 1) && __ReadMem(&d32, 4)) {
vatIdx = reg8 & 0xF;
cpAddr = (reg8& 0xF0) >> 4;
__SaveCPRegs(cpAddr, vatIdx, d32);
}
break;
case 2:
if (__ReadMem(&reg32, 4)) {
cnt = GET_REG_FIELD(reg32, 4, 16) + 1;
addr = (u16)reg32;
DPF("\tXFReg = 0x%x, Cnt = %d\n", addr, cnt);
for (i = 0; i < cnt; i++) {
if (__ReadMem(&d32, 4)) {
DPF("\tXFData = 0x%x\n", d32);
VERIF_MTXLIGHT(addr, d32);
addr++;
}
}
}
break;
case 4:
case 5:
case 6:
case 7:
if (__ReadMem(&reg32, 4)) {
DPF("\tXF_INDEX_LOAD: = 0x%x\n", reg32);
__GXShadowIndexState(cmdOp, reg32);
}
break;
case 8:
if (__gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_DL_NESTED]) {
__GX_WARN(GXWARN_DL_NESTED);
}
return;
case 12:
case 13:
if (__ReadMem(&reg32, 4)) {
DPF("\tSU Bypass = 0x%x\n", reg32);
__gxVerif->rasRegs[(reg32 >> 24) & 0xFF] = reg32;
}
break;
default:
if (__gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_DL_INV_CMD]) {
__GX_WARN(GXWARN_DL_INV_CMD);
}
OSReport("[Bad Display List Command: 0x%02X\n]", cmdOp);
break;
}
}
DPF("Displaylist OUT\n");
}
void __GXShadowIndexState(u32 idx_reg, u32 reg_data) {
u32* basePtr;
u32* memAddr;
u32 cnt;
u32 stride;
u32 addr;
u32 data;
u32 index;
u32 i;
i = idx_reg - 4;
basePtr = OSPhysicalToCached(__GXData->indexBase[i]);
stride = __GXData->indexStride[i];
addr = reg_data & 0xFFF;
cnt = (reg_data >> 12) & 0xF;
index = reg_data >> 16;
memAddr = (u32*)((u8*)basePtr + (index * stride));
cnt++;
while (cnt-- != 0) {
data = *memAddr;
VERIF_MTXLIGHT(addr, data);
memAddr = (u32*)((u8*)memAddr + stride);
addr++;
}
&data; // needed to match
}
void __GXPrintShadowState(void) {
u32 i;
u32 j;
OSReport("CP State:\n");
OSReport("\tvcdLo = 0x%x\n", __GXData->vcdLo);
OSReport("\tvcdHi = 0x%x\n", __GXData->vcdHi);
OSReport("\thasBiNrms = 0x%x\n", __GXData->hasBiNrms);
for (i = 0; i < 8; i++) {
OSReport("\tVertex Format %d:\n", i);
OSReport("\t\tvatA = 0x%x\n", __GXData->vatA[i]);
OSReport("\t\tvatB = 0x%x\n", __GXData->vatB[i]);
OSReport("\t\tvatC = 0x%x\n", __GXData->vatC[i]);
}
OSReport("\n-------------------------------------\n");
OSReport("XF Pos/Tex Matrix State:\n");
for (i = 0; i < 256; i += 4) {
if (__gxVerif->xfMtxDirty[i]) {
OSReport("\tXF_MATRIX[%d] = ", i);
OSReport("%f, %f, %f, %f\n", *(f32*)&__gxVerif->xfMtx[i], *(f32*)&__gxVerif->xfMtx[i + 1], *(f32*)&__gxVerif->xfMtx[i + 2], *(f32*)&__gxVerif->xfMtx[i + 3]);
}
}
OSReport("\n-------------------------------------\n");
OSReport("XF Normal Matrix State:\n");
for (i = 0; i < 96; i += 3) {
if (__gxVerif->xfNrmDirty[i]) {
OSReport("\tXF_NRM_MTX[%d] = ", i);
OSReport("%f, %f, %f\n", *(f32*)&__gxVerif->xfMtx[i], *(f32*)&__gxVerif->xfMtx[i + 1], *(f32*)&__gxVerif->xfMtx[i + 2]);
}
}
OSReport("\n-------------------------------------\n");
OSReport("XF Light State:\n");
for (i = 0; i < 128; i += 16) {
if (__gxVerif->xfLightDirty[i]) {
OSReport("\tXF_LIGHT[%d]:\n", i >> 4);
for (j = 0; j < 4; j++) {
OSReport("\t\tparam[%d] = 0x%x\n", j, __gxVerif->xfLight[i + j]);
}
for (j = 4; j < 16; j++) {
OSReport("\t\tparam[%d] = %Lg\n", j, *(f32*)&__gxVerif->xfLight[i + j]);
}
}
}
OSReport("\n-------------------------------------\n");
OSReport("XF Register State:\n");
for (i = 0; i < 80; i++) {
if (__gxVerif->xfRegsDirty[i]) {
OSReport("\tXF_REG[0x%x] = 0x%x (%f)\n", i, __gxVerif->xfRegs[i], *(f32*)&__gxVerif->xfRegs[i]);
}
}
OSReport("\n-------------------------------------\n");
OSReport("Raster Registers State:\n");
for (i = 0; i < 256; i++) {
OSReport("\tRAS_REG[0x%x] = 0x%x\n", i, __gxVerif->rasRegs[i]);
}
OSReport("\n-------------------------------------\n");
}
#endif

View File

@ -0,0 +1,5 @@
#include <revolution/gx.h>
#include "__gx.h"
void __GXSetRange(f32 nearz, f32 fgSideX) {}

465
src/revolution/gx/GXTev.c Normal file
View File

@ -0,0 +1,465 @@
#include <revolution/gx.h>
#include <revolution/os.h>
#include "__gx.h"
static struct {
u32 rid : 8;
u32 dest : 2;
u32 shift : 2;
u32 clamp : 1;
u32 sub : 1;
u32 bias : 2;
u32 sela : 4;
u32 selb : 4;
u32 selc : 4;
u32 seld : 4;
} TEVCOpTableST0[5] = {
{192, 0, 0, 1, 0, 0, 15, 8, 10, 15}, // modulate
{192, 0, 0, 1, 0, 0, 10, 8, 9, 15}, // decal
{192, 0, 0, 1, 0, 0, 10, 12, 8, 15}, // blend
{192, 0, 0, 1, 0, 0, 15, 15, 15, 8}, // replace
{192, 0, 0, 1, 0, 0, 15, 15, 15, 10}, // passclr
};
static struct {
u32 rid : 8;
u32 dest : 2;
u32 shift : 2;
u32 clamp : 1;
u32 sub : 1;
u32 bias : 2;
u32 sela : 4;
u32 selb : 4;
u32 selc : 4;
u32 seld : 4;
} TEVCOpTableST1[5] = {
{192, 0, 0, 1, 0, 0, 15, 8, 0, 15}, // modulate
{192, 0, 0, 1, 0, 0, 0, 8, 9, 15}, // decal
{192, 0, 0, 1, 0, 0, 0, 12, 8, 15}, // blend
{192, 0, 0, 1, 0, 0, 15, 15, 15, 8}, // replace
{192, 0, 0, 1, 0, 0, 15, 15, 15, 0}, // passclr
};
static struct {
u32 rid : 8;
u32 dest : 2;
u32 shift : 2;
u32 clamp : 1;
u32 sub : 1;
u32 bias : 2;
u32 sela : 3;
u32 selb : 3;
u32 selc : 3;
u32 seld : 3;
u32 swap : 2;
u32 mode : 2;
} TEVAOpTableST0[5] = {
{193, 0, 0, 1, 0, 0, 7, 4, 5, 7, 0, 0}, // modulate
{193, 0, 0, 1, 0, 0, 7, 7, 7, 5, 0, 0}, // decal
{193, 0, 0, 1, 0, 0, 7, 4, 5, 7, 0, 0}, // blend
{193, 0, 0, 1, 0, 0, 7, 7, 7, 4, 0, 0}, // replace
{193, 0, 0, 1, 0, 0, 7, 7, 7, 5, 0, 0}, // passclr
};
static struct {
u32 rid : 8;
u32 dest : 2;
u32 shift : 2;
u32 clamp : 1;
u32 sub : 1;
u32 bias : 2;
u32 sela : 3;
u32 selb : 3;
u32 selc : 3;
u32 seld : 3;
u32 swap : 2;
u32 mode : 2;
} TEVAOpTableST1[5] = {
{193, 0, 0, 1, 0, 0, 7, 4, 0, 7, 0, 0}, // modulate
{193, 0, 0, 1, 0, 0, 7, 7, 7, 0, 0, 0}, // decal
{193, 0, 0, 1, 0, 0, 7, 4, 0, 7, 0, 0}, // blend
{193, 0, 0, 1, 0, 0, 7, 7, 7, 4, 0, 0}, // replace
{193, 0, 0, 1, 0, 0, 7, 7, 7, 0, 0, 0}, // passclr
};
void GXSetTevOp(GXTevStageID id, GXTevMode mode) {
u32* ctmp;
u32* atmp;
u32 tevReg;
CHECK_GXBEGIN(425, "GXSetTevOp");
ASSERTMSGLINE(426, id < GX_MAX_TEVSTAGE, "GXSetTevColor*: Invalid Tev Stage Index");
ASSERTMSGLINE(427, mode <= GX_PASSCLR, "GXSetTevOp: Invalid Tev Mode");
if (id == GX_TEVSTAGE0) {
ctmp = (u32*)TEVCOpTableST0 + mode;
atmp = (u32*)TEVAOpTableST0 + mode;
} else {
ctmp = (u32*)TEVCOpTableST1 + mode;
atmp = (u32*)TEVAOpTableST1 + mode;
}
tevReg = __GXData->tevc[id];
tevReg = (*ctmp & ~0xFF000000) | (tevReg & 0xFF000000);
GX_WRITE_RAS_REG(tevReg);
__GXData->tevc[id] = tevReg;
tevReg = __GXData->teva[id];
tevReg = (*atmp & ~0xFF00000F) | (tevReg & 0xFF00000F);
GX_WRITE_RAS_REG(tevReg);
__GXData->teva[id] = tevReg;
__GXData->bpSentNot = 0;
}
void GXSetTevColorIn(GXTevStageID stage, GXTevColorArg a, GXTevColorArg b, GXTevColorArg c, GXTevColorArg d) {
u32 tevReg;
CHECK_GXBEGIN(583, "GXSetTevColorIn");
ASSERTMSGLINE(584, stage < GX_MAX_TEVSTAGE, "GXSetTevColor*: Invalid Tev Stage Index");
ASSERTMSGLINE(585, a <= GX_CC_ZERO, "GXSetTev*In: A/B/C/D argument out of range");
ASSERTMSGLINE(586, b <= GX_CC_ZERO, "GXSetTev*In: A/B/C/D argument out of range");
ASSERTMSGLINE(587, c <= GX_CC_ZERO, "GXSetTev*In: A/B/C/D argument out of range");
ASSERTMSGLINE(588, d <= GX_CC_ZERO, "GXSetTev*In: A/B/C/D argument out of range");
tevReg = __GXData->tevc[stage];
SC_TEV_COLOR_ENV_SET_SELA(591, tevReg, a);
SC_TEV_COLOR_ENV_SET_SELB(592, tevReg, b);
SC_TEV_COLOR_ENV_SET_SELC(593, tevReg, c);
SC_TEV_COLOR_ENV_SET_SELD(594, tevReg, d);
GX_WRITE_RAS_REG(tevReg);
__GXData->tevc[stage] = tevReg;
__GXData->bpSentNot = 0;
}
void GXSetTevAlphaIn(GXTevStageID stage, GXTevAlphaArg a, GXTevAlphaArg b, GXTevAlphaArg c, GXTevAlphaArg d) {
u32 tevReg;
CHECK_GXBEGIN(619, "GXSetTevAlphaIn");
ASSERTMSGLINE(620, stage < GX_MAX_TEVSTAGE, "GXSetTevAlpha*: Invalid Tev Stage Index");
ASSERTMSGLINE(621, a <= GX_CA_ZERO, "GXSetTev*In: A/B/C/D argument out of range");
ASSERTMSGLINE(622, b <= GX_CA_ZERO, "GXSetTev*In: A/B/C/D argument out of range");
ASSERTMSGLINE(623, c <= GX_CA_ZERO, "GXSetTev*In: A/B/C/D argument out of range");
ASSERTMSGLINE(624, d <= GX_CA_ZERO, "GXSetTev*In: A/B/C/D argument out of range");
tevReg = __GXData->teva[stage];
SC_TEV_ALPHA_ENV_SET_SELA(627, tevReg, a);
SC_TEV_ALPHA_ENV_SET_SELB(628, tevReg, b);
SC_TEV_ALPHA_ENV_SET_SELC(629, tevReg, c);
SC_TEV_ALPHA_ENV_SET_SELD(630, tevReg, d);
GX_WRITE_RAS_REG(tevReg);
__GXData->teva[stage] = tevReg;
__GXData->bpSentNot = 0;
}
void GXSetTevColorOp(GXTevStageID stage, GXTevOp op, GXTevBias bias, GXTevScale scale, GXBool clamp, GXTevRegID out_reg) {
u32 tevReg;
CHECK_GXBEGIN(658, "GXSetTevColorOp");
ASSERTMSGLINE(659, stage < GX_MAX_TEVSTAGE, "GXSetTevColor*: Invalid Tev Stage Index");
tevReg = __GXData->tevc[stage];
SC_TEV_COLOR_ENV_SET_SUB(668, tevReg, op & 1);
if (op <= 1) {
SC_TEV_COLOR_ENV_SET_SHIFT(670, tevReg, scale);
SC_TEV_COLOR_ENV_SET_BIAS(671, tevReg, bias);
} else {
SC_TEV_COLOR_ENV_SET_SHIFT(673, tevReg, (op >> 1) & 3);
SC_TEV_COLOR_ENV_SET_BIAS(674, tevReg, 3);
}
SC_TEV_COLOR_ENV_SET_CLAMP(677, tevReg, clamp);
SC_TEV_COLOR_ENV_SET_DEST(678, tevReg, out_reg);
GX_WRITE_RAS_REG(tevReg);
__GXData->tevc[stage] = tevReg;
__GXData->bpSentNot = 0;
}
void GXSetTevAlphaOp(GXTevStageID stage, GXTevOp op, GXTevBias bias, GXTevScale scale, GXBool clamp, GXTevRegID out_reg) {
u32 tevReg;
CHECK_GXBEGIN(704, "GXSetTevAlphaOp");
ASSERTMSGLINE(705, stage < GX_MAX_TEVSTAGE, "GXSetTevAlpha*: Invalid Tev Stage Index");
tevReg = __GXData->teva[stage];
SC_TEV_ALPHA_ENV_SET_SUB(713, tevReg, op & 1);
if (op <= 1) {
SC_TEV_ALPHA_ENV_SET_SHIFT(715, tevReg, scale);
SC_TEV_ALPHA_ENV_SET_BIAS(716, tevReg, bias);
} else {
SC_TEV_ALPHA_ENV_SET_SHIFT(718, tevReg, (op >> 1) & 3);
SC_TEV_ALPHA_ENV_SET_BIAS(719, tevReg, 3);
}
SC_TEV_ALPHA_ENV_SET_CLAMP(722, tevReg, clamp);
SC_TEV_ALPHA_ENV_SET_DEST(723, tevReg, out_reg);
GX_WRITE_RAS_REG(tevReg);
__GXData->teva[stage] = tevReg;
__GXData->bpSentNot = 0;
}
void GXSetTevColor(GXTevRegID id, GXColor color) {
u32 rgba;
u32 regRA;
u32 regBG;
CHECK_GXBEGIN(745, "GXSetTevColor");
rgba = *(u32*)&color;
regRA = (0xE0 + id * 2) << 24;
SC_TEV_REGISTERL_SET_R8(750, regRA, rgba >> 24);
SC_TEV_REGISTERL_SET_A8(751, regRA, rgba & 0xFF);
regBG = (0xE1 + id * 2) << 24;
SC_TEV_REGISTERH_SET_B8(754, regBG, (rgba >> 8) & 0xFF);
SC_TEV_REGISTERH_SET_G8(755, regBG, (rgba >> 16) & 0xFF);
GX_WRITE_RAS_REG(regRA);
GX_WRITE_RAS_REG(regBG);
GX_WRITE_RAS_REG(regBG);
GX_WRITE_RAS_REG(regBG);
__GXData->bpSentNot = 0;
}
void GXSetTevColorS10(GXTevRegID id, GXColorS10 color) {
u32 sRG;
u32 sBA;
u32 regRA;
u32 regBG;
ASSERTMSGLINE(782, color.r >= -1024 && color.r < 1024, "GXSetTevColorS10: Color not in range -1024 to +1023");
ASSERTMSGLINE(783, color.g >= -1024 && color.g < 1024, "GXSetTevColorS10: Color not in range -1024 to +1023");
ASSERTMSGLINE(784, color.b >= -1024 && color.b < 1024, "GXSetTevColorS10: Color not in range -1024 to +1023");
ASSERTMSGLINE(785, color.a >= -1024 && color.a < 1024, "GXSetTevColorS10: Color not in range -1024 to +1023");
CHECK_GXBEGIN(787, "GXSetTevColorS10");
sRG = *(u32*)&color;
sBA = *((u32*)&color + 1);
regRA = (0xE0 + id * 2) << 24;
SC_TEV_REGISTERL_SET_R(794, regRA, (sRG >> 16) & 0x7FF);
SC_TEV_REGISTERL_SET_A(795, regRA, sBA & 0x7FF);
regBG = (0xE1 + id * 2) << 24;
SC_TEV_REGISTERH_SET_B(798, regBG, (sBA >> 16) & 0x7FF);
SC_TEV_REGISTERH_SET_G(799, regBG, sRG & 0x7FF);
GX_WRITE_RAS_REG(regRA);
GX_WRITE_RAS_REG(regBG);
GX_WRITE_RAS_REG(regBG);
GX_WRITE_RAS_REG(regBG);
__GXData->bpSentNot = 0;
}
void GXSetTevKColor(GXTevKColorID id, GXColor color) {
u32 rgba;
u32 regRA;
u32 regBG;
CHECK_GXBEGIN(838, "GXSetTevKColor");
rgba = *(u32*)&color;
regRA = (0xE0 + id * 2) << 24;
SC_TEV_KREGISTERL_SET_R(843, regRA, rgba >> 24);
SC_TEV_KREGISTERL_SET_A(844, regRA, rgba & 0xFF);
SC_TEV_KREGISTERL_SET_PAD1(845, regRA, 8);
regBG = (0xE1 + id * 2) << 24;
SC_TEV_KREGISTERH_SET_B(848, regBG, (rgba >> 8) & 0xFF);
SC_TEV_KREGISTERH_SET_G(849, regBG, (rgba >> 16) & 0xFF);
SC_TEV_KREGISTERH_SET_PAD1(850, regBG, 8);
GX_WRITE_RAS_REG(regRA);
GX_WRITE_RAS_REG(regBG);
__GXData->bpSentNot = 0;
}
void GXSetTevKColorSel(GXTevStageID stage, GXTevKColorSel sel) {
u32* Kreg;
CHECK_GXBEGIN(877, "GXSetTevKColorSel");
ASSERTMSGLINE(878, stage < GX_MAX_TEVSTAGE, "GXSetTevKColor*: Invalid Tev Stage Index");
Kreg = &__GXData->tevKsel[stage >> 1];
if (stage & 1) {
SC_TEV_KSEL_SET_KCSEL1(883, *Kreg, sel);
} else {
SC_TEV_KSEL_SET_KCSEL0(885, *Kreg, sel);
}
GX_WRITE_RAS_REG(*Kreg);
__GXData->bpSentNot = 0;
}
void GXSetTevKAlphaSel(GXTevStageID stage, GXTevKAlphaSel sel) {
u32* Kreg;
CHECK_GXBEGIN(910, "GXSetTevKAlphaSel");
ASSERTMSGLINE(911, stage < GX_MAX_TEVSTAGE, "GXSetTevKColor*: Invalid Tev Stage Index");
Kreg = &__GXData->tevKsel[stage >> 1];
if (stage & 1) {
SC_TEV_KSEL_SET_KASEL1(916, *Kreg, sel);
} else {
SC_TEV_KSEL_SET_KASEL0(918, *Kreg, sel);
}
GX_WRITE_RAS_REG(*Kreg);
__GXData->bpSentNot = 0;
}
void GXSetTevSwapMode(GXTevStageID stage, GXTevSwapSel ras_sel, GXTevSwapSel tex_sel) {
u32* pTevReg;
CHECK_GXBEGIN(947, "GXSetTevSwapMode");
ASSERTMSGLINE(948, stage < GX_MAX_TEVSTAGE, "GXSetTevSwapMode: Invalid Tev Stage Index");
pTevReg = &__GXData->teva[stage];
SC_TEV_ALPHA_ENV_SET_MODE(951, *pTevReg, ras_sel);
SC_TEV_ALPHA_ENV_SET_SWAP(952, *pTevReg, tex_sel);
GX_WRITE_RAS_REG(*pTevReg);
__GXData->bpSentNot = 0;
}
void GXSetTevSwapModeTable(GXTevSwapSel table, GXTevColorChan red, GXTevColorChan green, GXTevColorChan blue, GXTevColorChan alpha) {
u32* Kreg;
#if !DEBUG
// not a real variable, but needed to match release
int index = table * 2;
#endif
CHECK_GXBEGIN(983, "GXSetTevSwapModeTable");
ASSERTMSGLINE(984, table < GX_MAX_TEVSWAP, "GXSetTevSwapModeTable: Invalid Swap Selection Index");
#if DEBUG
Kreg = &__GXData->tevKsel[table * 2];
#else
Kreg = &__GXData->tevKsel[index];
#endif
SC_TEV_KSEL_SET_XRB(987, *Kreg, red);
SC_TEV_KSEL_SET_XGA(988, *Kreg, green);
GX_WRITE_RAS_REG(*Kreg);
Kreg = &__GXData->tevKsel[table * 2 + 1];
SC_TEV_KSEL_SET_XRB(992, *Kreg, blue);
SC_TEV_KSEL_SET_XGA(993, *Kreg, alpha);
GX_WRITE_RAS_REG(*Kreg);
__GXData->bpSentNot = 0;
}
void GXSetTevClampMode(void) {
ASSERTMSGLINE(1012, 0, "GXSetTevClampMode: not available on this hardware");
}
void GXSetAlphaCompare(GXCompare comp0, u8 ref0, GXAlphaOp op, GXCompare comp1, u8 ref1) {
u32 reg;
CHECK_GXBEGIN(1051, "GXSetAlphaCompare");
reg = 0xF3000000;
SC_TEV_ALPHAFUNC_SET_A0(1054, reg, ref0);
SC_TEV_ALPHAFUNC_SET_A1(1055, reg, ref1);
SC_TEV_ALPHAFUNC_SET_OP0(1056, reg, comp0);
SC_TEV_ALPHAFUNC_SET_OP1(1057, reg, comp1);
SC_TEV_ALPHAFUNC_SET_LOGIC(1058, reg, op);
GX_WRITE_RAS_REG(reg);
__GXData->bpSentNot = 0;
}
void GXSetZTexture(GXZTexOp op, GXTexFmt fmt, u32 bias) {
u32 zenv0;
u32 zenv1;
u32 type;
CHECK_GXBEGIN(1082, "GXSetZTexture");
zenv0 = 0;
SC_TEV_Z_ENV_0_SET_ZOFF(1085, zenv0, bias);
SC_TEV_Z_ENV_0_SET_RID(1086, zenv0, 0xF4);
zenv1 = 0;
switch (fmt) {
case GX_TF_Z8:
type = 0;
break;
case GX_TF_Z16:
type = 1;
break;
case GX_TF_Z24X8:
type = 2;
break;
default:
ASSERTMSGLINE(1094, 0, "GXSetZTexture: Invalid z-texture format");
type = 2;
break;
}
SC_TEV_Z_ENV_1_SET_TYPE(1097, zenv1, type);
SC_TEV_Z_ENV_1_SET_OP(1098, zenv1, op);
SC_TEV_Z_ENV_1_SET_RID(1099, zenv1, 0xF5);
GX_WRITE_RAS_REG(zenv0);
GX_WRITE_RAS_REG(zenv1);
__GXData->bpSentNot = 0;
}
void GXSetTevOrder(GXTevStageID stage, GXTexCoordID coord, GXTexMapID map, GXChannelID color) {
u32* ptref;
u32 tmap;
u32 tcoord;
static int c2r[] = { 0, 1, 0, 1, 0, 1, 7, 5, 6 };
CHECK_GXBEGIN(1136, "GXSetTevOrder");
ASSERTMSGLINE(1137, stage < GX_MAX_TEVSTAGE, "GXSetTevOrder: Invalid Tev Stage Index");
ASSERTMSGLINE(1139, coord < GX_MAX_TEXCOORD || coord == GX_TEXCOORD_NULL, "GXSetTevOrder: Invalid Texcoord");
ASSERTMSGLINE(1141, (map & ~GX_TEX_DISABLE) < GX_MAX_TEXMAP || map == GX_TEXMAP_NULL, "GXSetTevOrder: Invalid Tex Map");
ASSERTMSGLINE(1143, color >= GX_COLOR0A0 && color <= GX_COLOR_NULL, "GXSetTevOrder: Invalid Color Channel ID");
ptref = &__GXData->tref[stage / 2];
__GXData->texmapId[stage] = map;
tmap = map & ~GX_TEX_DISABLE;
tmap = (tmap >= GX_MAX_TEXMAP) ? GX_TEXMAP0 : tmap;
if (coord >= GX_MAX_TEXCOORD) {
tcoord = GX_TEXCOORD0;
__GXData->tevTcEnab = __GXData->tevTcEnab & ~(1 << stage);
} else {
tcoord = coord;
__GXData->tevTcEnab = __GXData->tevTcEnab | (1 << stage);
}
if (stage & 1) {
SC_RAS1_TREF_SET_TI1(1163, *ptref, tmap);
SC_RAS1_TREF_SET_TC1(1164, *ptref, tcoord);
SC_RAS1_TREF_SET_CC1(1166, *ptref, (color == GX_COLOR_NULL) ? 7 : c2r[color]);
SC_RAS1_TREF_SET_TE1(1168, *ptref, (map != GX_TEXMAP_NULL && !(map & GX_TEX_DISABLE)));
} else {
SC_RAS1_TREF_SET_TI0(1171, *ptref, tmap);
SC_RAS1_TREF_SET_TC0(1172, *ptref, tcoord);
SC_RAS1_TREF_SET_CC0(1174, *ptref, (color == GX_COLOR_NULL) ? 7 : c2r[color]);
SC_RAS1_TREF_SET_TE0(1176, *ptref, (map != GX_TEXMAP_NULL && !(map & GX_TEX_DISABLE)));
}
GX_WRITE_RAS_REG(*ptref);
__GXData->bpSentNot = 0;
__GXData->dirtyState |= 1;
}
void GXSetNumTevStages(u8 nStages) {
CHECK_GXBEGIN(1192, "GXSetNumTevStages");
ASSERTMSGLINE(1194, nStages != 0 && nStages <= 16, "GXSetNumTevStages: Exceed max number of tex stages");
SC_GEN_MODE_SET_NTEV(1195, __GXData->genMode, nStages - 1);
__GXData->dirtyState |= 4;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,607 @@
#include <revolution/gx.h>
#include <revolution/mtx.h>
#include <revolution/os.h>
#include "__gx.h"
void GXProject(f32 x, f32 y, f32 z, const Mtx mtx, const f32* pm, const f32* vp, f32* sx, f32* sy, f32* sz) {
Vec peye;
f32 xc;
f32 yc;
f32 zc;
f32 wc;
ASSERTMSGLINE(181, pm && vp && sx && sy && sz, "GXGet*: invalid null pointer");
peye.x = mtx[0][3] + ((mtx[0][2] * z) + ((mtx[0][0] * x) + (mtx[0][1] * y)));
peye.y = mtx[1][3] + ((mtx[1][2] * z) + ((mtx[1][0] * x) + (mtx[1][1] * y)));
peye.z = mtx[2][3] + ((mtx[2][2] * z) + ((mtx[2][0] * x) + (mtx[2][1] * y)));
if (pm[0] == 0.0f) {
xc = (peye.x * pm[1]) + (peye.z * pm[2]);
yc = (peye.y * pm[3]) + (peye.z * pm[4]);
zc = pm[6] + (peye.z * pm[5]);
wc = 1.0f / -peye.z;
} else {
xc = pm[2] + (peye.x * pm[1]);
yc = pm[4] + (peye.y * pm[3]);
zc = pm[6] + (peye.z * pm[5]);
wc = 1.0f;
}
*sx = (vp[2] / 2.0f) + (vp[0] + (wc * (xc * vp[2] / 2.0f)));
*sy = (vp[3] / 2.0f) + (vp[1] + (wc * (-yc * vp[3] / 2.0f)));
*sz = vp[5] + (wc * (zc * (vp[5] - vp[4])));
}
static void WriteProjPS(const __REGISTER f32 proj[6], __REGISTER volatile void* dest) {
__REGISTER f32 p01, p23, p45;
#ifdef __MWERKS__
asm {
psq_l p01, 0(proj), 0, 0
psq_l p23, 8(proj), 0, 0
psq_l p45, 16(proj), 0, 0
psq_st p01, 0(dest), 0, 0
psq_st p23, 0(dest), 0, 0
psq_st p45, 0(dest), 0, 0
}
#endif
}
static void Copy6Floats(const __REGISTER f32 src[6], __REGISTER volatile f32* dest) {
__REGISTER f32 ps01, ps23, ps45;
asm {
psq_l ps01, 0(src), 0, 0
psq_l ps23, 8(src), 0, 0
psq_l ps45, 16(src), 0, 0
psq_st ps01, 0(dest), 0, 0
psq_st ps23, 8(dest), 0, 0
psq_st ps45, 16(dest), 0, 0
}
}
void __GXSetProjection(void) {
u32 reg = 0x00061020;
GX_WRITE_U8(0x10);
GX_WRITE_U32(reg);
#if DEBUG
GX_WRITE_XF_REG_F(32, __GXData->projMtx[0]);
GX_WRITE_XF_REG_F(33, __GXData->projMtx[1]);
GX_WRITE_XF_REG_F(34, __GXData->projMtx[2]);
GX_WRITE_XF_REG_F(35, __GXData->projMtx[3]);
GX_WRITE_XF_REG_F(36, __GXData->projMtx[4]);
GX_WRITE_XF_REG_F(37, __GXData->projMtx[5]);
GX_WRITE_XF_REG_2(38, __GXData->projType);
#else
WriteProjPS(__GXData->projMtx, (volatile void*)GXFIFO_ADDR);
GX_WRITE_U32(__GXData->projType);
#endif
}
void GXSetProjection(const Mtx44 mtx, GXProjectionType type) {
CHECK_GXBEGIN(307, "GXSetProjection");
__GXData->projType = type;
__GXData->projMtx[0] = mtx[0][0];
__GXData->projMtx[2] = mtx[1][1];
__GXData->projMtx[4] = mtx[2][2];
__GXData->projMtx[5] = mtx[2][3];
if (type == GX_ORTHOGRAPHIC) {
__GXData->projMtx[1] = mtx[0][3];
__GXData->projMtx[3] = mtx[1][3];
} else {
__GXData->projMtx[1] = mtx[0][2];
__GXData->projMtx[3] = mtx[1][2];
}
__GXData->dirtyState |= 0x8000000;
}
void GXSetProjectionv(const f32* ptr) {
CHECK_GXBEGIN(351, "GXSetProjectionv");
__GXData->projType = ptr[0] == 0.0f ? GX_PERSPECTIVE : GX_ORTHOGRAPHIC;
#if DEBUG
__GXData->projMtx[0] = ptr[1];
__GXData->projMtx[1] = ptr[2];
__GXData->projMtx[2] = ptr[3];
__GXData->projMtx[3] = ptr[4];
__GXData->projMtx[4] = ptr[5];
__GXData->projMtx[5] = ptr[6];
#else
Copy6Floats(&ptr[1], __GXData->projMtx);
#endif
__GXData->dirtyState |= 0x8000000;
}
#define qr0 0
void GXGetProjectionv(f32* ptr) {
ASSERTMSGLINE(382, ptr, "GXGet*: invalid null pointer");
ptr[0] = (u32)__GXData->projType != GX_PERSPECTIVE ? 1.0f : 0.0f;
#if DEBUG
ptr[1] = __GXData->projMtx[0];
ptr[2] = __GXData->projMtx[1];
ptr[3] = __GXData->projMtx[2];
ptr[4] = __GXData->projMtx[3];
ptr[5] = __GXData->projMtx[4];
ptr[6] = __GXData->projMtx[5];
#else
Copy6Floats(__GXData->projMtx, &ptr[1]);
#endif
}
static void WriteMTXPS4x3(const __REGISTER f32 mtx[3][4], __REGISTER volatile f32* dest) {
__REGISTER f32 a00_a01;
__REGISTER f32 a02_a03;
__REGISTER f32 a10_a11;
__REGISTER f32 a12_a13;
__REGISTER f32 a20_a21;
__REGISTER f32 a22_a23;
asm {
psq_l a00_a01, 0x00(mtx), 0, qr0
psq_l a02_a03, 0x08(mtx), 0, qr0
psq_l a10_a11, 0x10(mtx), 0, qr0
psq_l a12_a13, 0x18(mtx), 0, qr0
psq_l a20_a21, 0x20(mtx), 0, qr0
psq_l a22_a23, 0x28(mtx), 0, qr0
psq_st a00_a01, 0(dest), 0, qr0
psq_st a02_a03, 0(dest), 0, qr0
psq_st a10_a11, 0(dest), 0, qr0
psq_st a12_a13, 0(dest), 0, qr0
psq_st a20_a21, 0(dest), 0, qr0
psq_st a22_a23, 0(dest), 0, qr0
}
}
static void WriteMTXPS3x3from3x4(__REGISTER f32 mtx[3][4], __REGISTER volatile f32* dest) {
__REGISTER f32 a00_a01;
__REGISTER f32 a02_a03;
__REGISTER f32 a10_a11;
__REGISTER f32 a12_a13;
__REGISTER f32 a20_a21;
__REGISTER f32 a22_a23;
asm {
psq_l a00_a01, 0x00(mtx), 0, qr0
lfs a02_a03, 0x08(mtx)
psq_l a10_a11, 0x10(mtx), 0, qr0
lfs a12_a13, 0x18(mtx)
psq_l a20_a21, 0x20(mtx), 0, qr0
lfs a22_a23, 0x28(mtx)
psq_st a00_a01, 0(dest), 0, qr0
stfs a02_a03, 0(dest)
psq_st a10_a11, 0(dest), 0, qr0
stfs a12_a13, 0(dest)
psq_st a20_a21, 0(dest), 0, qr0
stfs a22_a23, 0(dest)
}
}
static void WriteMTXPS3x3(__REGISTER f32 mtx[3][3], __REGISTER volatile f32* dest) {
__REGISTER f32 a00_a01;
__REGISTER f32 a02_a10;
__REGISTER f32 a11_a12;
__REGISTER f32 a20_a21;
__REGISTER f32 a22_nnn;
asm {
psq_l a00_a01, 0x00(mtx), 0, qr0
psq_l a02_a10, 0x08(mtx), 0, qr0
psq_l a11_a12, 0x10(mtx), 0, qr0
psq_l a20_a21, 0x18(mtx), 0, qr0
lfs a22_nnn, 0x20(mtx)
psq_st a00_a01, 0(dest), 0, qr0
psq_st a02_a10, 0(dest), 0, qr0
psq_st a11_a12, 0(dest), 0, qr0
psq_st a20_a21, 0(dest), 0, qr0
stfs a22_nnn, 0(dest)
}
}
static void WriteMTXPS4x2(const __REGISTER f32 mtx[2][4], __REGISTER volatile f32* dest) {
__REGISTER f32 a00_a01;
__REGISTER f32 a02_a03;
__REGISTER f32 a10_a11;
__REGISTER f32 a12_a13;
asm {
psq_l a00_a01, 0x00(mtx), 0, qr0
psq_l a02_a03, 0x08(mtx), 0, qr0
psq_l a10_a11, 0x10(mtx), 0, qr0
psq_l a12_a13, 0x18(mtx), 0, qr0
psq_st a00_a01, 0(dest), 0, qr0
psq_st a02_a03, 0(dest), 0, qr0
psq_st a10_a11, 0(dest), 0, qr0
psq_st a12_a13, 0(dest), 0, qr0
}
}
#define GX_WRITE_MTX_ELEM(addr, value) \
do { \
f32 xfData = (value); \
GX_WRITE_F32(value); \
VERIF_MTXLIGHT((addr), *(u32 *)&xfData); \
} while (0)
void GXLoadPosMtxImm(const Mtx mtx, u32 id) {
u32 reg;
u32 addr;
CHECK_GXBEGIN(516, "GXLoadPosMtxImm");
addr = id * 4;
reg = addr | 0xB0000;
GX_WRITE_U8(0x10);
GX_WRITE_U32(reg);
#if DEBUG
GX_WRITE_MTX_ELEM(addr + 0, mtx[0][0]);
GX_WRITE_MTX_ELEM(addr + 1, mtx[0][1]);
GX_WRITE_MTX_ELEM(addr + 2, mtx[0][2]);
GX_WRITE_MTX_ELEM(addr + 3, mtx[0][3]);
GX_WRITE_MTX_ELEM(addr + 4, mtx[1][0]);
GX_WRITE_MTX_ELEM(addr + 5, mtx[1][1]);
GX_WRITE_MTX_ELEM(addr + 6, mtx[1][2]);
GX_WRITE_MTX_ELEM(addr + 7, mtx[1][3]);
GX_WRITE_MTX_ELEM(addr + 8, mtx[2][0]);
GX_WRITE_MTX_ELEM(addr + 9, mtx[2][1]);
GX_WRITE_MTX_ELEM(addr + 10, mtx[2][2]);
GX_WRITE_MTX_ELEM(addr + 11, mtx[2][3]);
#else
WriteMTXPS4x3(mtx, &GXWGFifo.f32);
#endif
}
void GXLoadPosMtxIndx(u16 mtx_indx, u32 id) {
u32 offset;
u32 reg;
CHECK_GXBEGIN(555, "GXLoadPosMtxIndx");
offset = id * 4;
reg = 0;
SET_REG_FIELD(561, reg, 12, 0, offset);
SET_REG_FIELD(563, reg, 4, 12, 11);
SET_REG_FIELD(563, reg, 16, 16, mtx_indx);
GX_WRITE_U8(0x20);
GX_WRITE_U32(reg);
#if DEBUG
__GXShadowIndexState(4, reg);
#endif
}
void GXLoadNrmMtxImm(const Mtx mtx, u32 id) {
u32 reg;
u32 addr;
CHECK_GXBEGIN(597, "GXLoadNrmMtxImm");
addr = id * 3 + 0x400;
reg = addr | 0x80000;
GX_WRITE_U8(0x10);
GX_WRITE_U32(reg);
#if DEBUG
GX_WRITE_MTX_ELEM(addr + 0, mtx[0][0]);
GX_WRITE_MTX_ELEM(addr + 1, mtx[0][1]);
GX_WRITE_MTX_ELEM(addr + 2, mtx[0][2]);
GX_WRITE_MTX_ELEM(addr + 3, mtx[1][0]);
GX_WRITE_MTX_ELEM(addr + 4, mtx[1][1]);
GX_WRITE_MTX_ELEM(addr + 5, mtx[1][2]);
GX_WRITE_MTX_ELEM(addr + 6, mtx[2][0]);
GX_WRITE_MTX_ELEM(addr + 7, mtx[2][1]);
GX_WRITE_MTX_ELEM(addr + 8, mtx[2][2]);
#else
WriteMTXPS3x3from3x4((void*)mtx, &GXWGFifo.f32);
#endif
}
void GXLoadNrmMtxImm3x3(const f32 mtx[3][3], u32 id) {
u32 reg;
u32 addr;
CHECK_GXBEGIN(633, "GXLoadNrmMtxImm3x3");
addr = id * 3 + 0x400;
reg = addr | 0x80000;
GX_WRITE_U8(0x10);
GX_WRITE_U32(reg);
#if DEBUG
GX_WRITE_MTX_ELEM(addr + 0, mtx[0][0]);
GX_WRITE_MTX_ELEM(addr + 1, mtx[0][1]);
GX_WRITE_MTX_ELEM(addr + 2, mtx[0][2]);
GX_WRITE_MTX_ELEM(addr + 3, mtx[1][0]);
GX_WRITE_MTX_ELEM(addr + 4, mtx[1][1]);
GX_WRITE_MTX_ELEM(addr + 5, mtx[1][2]);
GX_WRITE_MTX_ELEM(addr + 6, mtx[2][0]);
GX_WRITE_MTX_ELEM(addr + 7, mtx[2][1]);
GX_WRITE_MTX_ELEM(addr + 8, mtx[2][2]);
#else
WriteMTXPS3x3((void*)mtx, &GXWGFifo.f32);
#endif
}
void GXLoadNrmMtxIndx3x3(u16 mtx_indx, u32 id) {
u32 offset;
u32 reg;
CHECK_GXBEGIN(679, "GXLoadNrmMtxIndx3x3");
offset = id * 3 + 0x400;
reg = 0;
SET_REG_FIELD(685, reg, 12, 0, offset);
SET_REG_FIELD(687, reg, 4, 12, 8);
SET_REG_FIELD(687, reg, 16, 16, mtx_indx);
GX_WRITE_U8(0x28);
GX_WRITE_U32(reg);
#if DEBUG
__GXShadowIndexState(5, reg);
#endif
}
void GXSetCurrentMtx(u32 id) {
CHECK_GXBEGIN(717, "GXSetCurrentMtx");
SET_REG_FIELD(721, __GXData->matIdxA, 6, 0, id);
__GXData->dirtyState |= 0x4000000;
}
void GXLoadTexMtxImm(const f32 mtx[][4], u32 id, GXTexMtxType type) {
u32 reg;
u32 addr;
u32 count;
CHECK_GXBEGIN(750, "GXLoadTexMtxImm");
if (id >= GX_PTTEXMTX0) {
addr = (id - GX_PTTEXMTX0) * 4 + 0x500;
ASSERTMSGLINE(760, type == GX_MTX3x4, "GXLoadTexMtx: Invalid matrix type");
} else {
addr = id * 4;
}
count = (type == GX_MTX2x4) ? 8 : 12;
reg = addr | ((count - 1) << 16);
GX_WRITE_U8(0x10);
GX_WRITE_U32(reg);
#if DEBUG
GX_WRITE_MTX_ELEM(addr + 0, mtx[0][0]);
GX_WRITE_MTX_ELEM(addr + 1, mtx[0][1]);
GX_WRITE_MTX_ELEM(addr + 2, mtx[0][2]);
GX_WRITE_MTX_ELEM(addr + 3, mtx[0][3]);
GX_WRITE_MTX_ELEM(addr + 4, mtx[1][0]);
GX_WRITE_MTX_ELEM(addr + 5, mtx[1][1]);
GX_WRITE_MTX_ELEM(addr + 6, mtx[1][2]);
GX_WRITE_MTX_ELEM(addr + 7, mtx[1][3]);
if (type == GX_MTX3x4) {
GX_WRITE_MTX_ELEM(addr + 8, mtx[2][0]);
GX_WRITE_MTX_ELEM(addr + 9, mtx[2][1]);
GX_WRITE_MTX_ELEM(addr + 10, mtx[2][2]);
GX_WRITE_MTX_ELEM(addr + 11, mtx[2][3]);
}
#else
if (type == GX_MTX3x4) {
WriteMTXPS4x3(mtx, &GXWGFifo.f32);
} else {
WriteMTXPS4x2(mtx, &GXWGFifo.f32);
}
#endif
}
void GXLoadTexMtxIndx(u16 mtx_indx, u32 id, GXTexMtxType type) {
u32 offset;
u32 reg;
u32 count;
CHECK_GXBEGIN(813, "GXLoadTexMtxIndx");
if (id >= GX_PTTEXMTX0) {
offset = (id - GX_PTTEXMTX0) * 4 + 0x500;
ASSERTMSGLINE(0x337, type == GX_MTX3x4, "GXLoadTexMtx: Invalid matrix type");
} else {
offset = id * 4;
}
count = (type == GX_MTX2x4) ? 8 : 12;
reg = 0;
SET_REG_FIELD(830, reg, 12, 0, offset);
SET_REG_FIELD(831, reg, 4, 12, (count - 1));
SET_REG_FIELD(832, reg, 16, 16, mtx_indx);
GX_WRITE_U8(0x30);
GX_WRITE_U32(reg);
#if DEBUG
__GXShadowIndexState(6, reg);
#endif
}
void __GXSetViewport(void) {
f32 sx;
f32 sy;
f32 sz;
f32 ox;
f32 oy;
f32 oz;
f32 zmin;
f32 zmax;
u32 reg;
sx = __GXData->vpWd / 2.0f;
sy = -__GXData->vpHt / 2.0f;
ox = 342.0f + (__GXData->vpLeft + (__GXData->vpWd / 2.0f));
oy = 342.0f + (__GXData->vpTop + (__GXData->vpHt / 2.0f));
zmin = __GXData->vpNearz * __GXData->zScale;
zmax = __GXData->vpFarz * __GXData->zScale;
sz = zmax - zmin;
oz = zmax + __GXData->zOffset;
reg = 0x5101A;
GX_WRITE_U8(0x10);
GX_WRITE_U32(reg);
GX_WRITE_XF_REG_F(26, sx);
GX_WRITE_XF_REG_F(27, sy);
GX_WRITE_XF_REG_F(28, sz);
GX_WRITE_XF_REG_F(29, ox);
GX_WRITE_XF_REG_F(30, oy);
GX_WRITE_XF_REG_F(31, oz);
}
void GXSetViewportJitter(f32 left, f32 top, f32 wd, f32 ht, f32 nearz, f32 farz, u32 field) {
CHECK_GXBEGIN(912, "GXSetViewport"); // not the correct function name
if (field == 0) {
top -= 0.5f;
}
__GXData->vpLeft = left;
__GXData->vpTop = top;
__GXData->vpWd = wd;
__GXData->vpHt = ht;
__GXData->vpNearz = nearz;
__GXData->vpFarz = farz;
__GXData->dirtyState |= 0x10000000;
}
void GXSetViewport(f32 left, f32 top, f32 wd, f32 ht, f32 nearz, f32 farz) {
GXSetViewportJitter(left, top, wd, ht, nearz, farz, 1);
}
void GXGetViewportv(f32* vp) {
ASSERTMSGLINE(977, vp, "GXGet*: invalid null pointer");
#if DEBUG
vp[0] = __GXData->vpLeft;
vp[1] = __GXData->vpTop;
vp[2] = __GXData->vpWd;
vp[3] = __GXData->vpHt;
vp[4] = __GXData->vpNearz;
vp[5] = __GXData->vpFarz;
#else
Copy6Floats(&__GXData->vpLeft, vp);
#endif
}
#define GX_WRITE_XF_REG_F_(addr, value) \
do { \
GX_WRITE_U8(0x10); \
GX_WRITE_U32(0x1000 + (addr)); \
{ \
f32 xfData = (value); \
GX_WRITE_F32(value); \
VERIF_XF_REG_alt(addr, *(u32 *)&xfData); \
} \
} while (0)
void GXSetZScaleOffset(f32 scale, f32 offset) {
f32 sz;
f32 oz;
f32 zmin;
f32 zmax;
CHECK_GXBEGIN(996, "GXSetZScaleOffset");
oz = offset * 1.6777215e7f;
__GXData->zOffset = oz;
sz = (scale * 1.6777215e7f) + 1.0f;
__GXData->zScale = sz;
zmin = __GXData->vpNearz * sz;
zmax = __GXData->vpFarz * sz;
sz = zmax - zmin;
oz = oz + zmax;
GX_WRITE_XF_REG_F_(0x1C, sz);
GX_WRITE_XF_REG_F_(0x1F, oz);
__GXData->bpSentNot = 1;
}
void GXSetScissor(u32 left, u32 top, u32 wd, u32 ht) {
u32 tp;
u32 lf;
u32 bm;
u32 rt;
CHECK_GXBEGIN(1057, "GXSetScissor");
ASSERTMSGLINE(1058, left < 1706, "GXSetScissor: Left origin > 1708");
ASSERTMSGLINE(1059, top < 1706, "GXSetScissor: top origin > 1708");
ASSERTMSGLINE(1060, left + wd < 1706, "GXSetScissor: right edge > 1708");
ASSERTMSGLINE(1061, top + ht < 1706, "GXSetScissor: bottom edge > 1708");
tp = top + 342;
lf = left + 342;
bm = tp + ht - 1;
rt = lf + wd - 1;
SET_REG_FIELD(1068, __GXData->suScis0, 11, 0, tp);
SET_REG_FIELD(1069, __GXData->suScis0, 11, 12, lf);
SET_REG_FIELD(1071, __GXData->suScis1, 11, 0, bm);
SET_REG_FIELD(1072, __GXData->suScis1, 11, 12, rt);
GX_WRITE_RAS_REG(__GXData->suScis0);
GX_WRITE_RAS_REG(__GXData->suScis1);
__GXData->bpSentNot = 0;
}
void GXGetScissor(u32* left, u32* top, u32* wd, u32* ht) {
u32 tp;
u32 lf;
u32 bm;
u32 rt;
ASSERTMSGLINE(1098, left && top && wd && ht, "GXGet*: invalid null pointer");
tp = __GXData->suScis0 & 0x7FF;
lf = (__GXData->suScis0 & 0x7FF000) >> 12;
bm = __GXData->suScis1 & 0x7FF;
rt = (__GXData->suScis1 & 0x7FF000) >> 12;
*left = lf - 342;
*top = tp - 342;
*wd = rt - lf + 1;
*ht = bm - tp + 1;
}
void GXSetScissorBoxOffset(s32 x_off, s32 y_off) {
u32 reg = 0;
u32 hx;
u32 hy;
CHECK_GXBEGIN(1128, "GXSetScissorBoxOffset");
ASSERTMSGLINE(1131, !!((u32)(x_off + 342) < 2048), "GXSetScissorBoxOffset: Invalid X offset");
ASSERTMSGLINE(1133, !!((u32)(y_off + 342) < 2048), "GXSetScissorBoxOffset: Invalid Y offset");
hx = (u32)(x_off + 342) >> 1;
hy = (u32)(y_off + 342) >> 1;
SET_REG_FIELD(1138, reg, 10, 0, hx);
SET_REG_FIELD(1139, reg, 10, 10, hy);
SET_REG_FIELD(1131, reg, 8, 24, 0x59);
GX_WRITE_RAS_REG(reg);
__GXData->bpSentNot = 0;
}
void GXSetClipMode(GXClipMode mode) {
CHECK_GXBEGIN(1160, "GXSetClipMode");
GX_WRITE_XF_REG(0x1005, mode, 0);
__GXData->bpSentNot = 1;
}
void __GXSetMatrixIndex(GXAttr matIdxAttr) {
if (matIdxAttr < GX_VA_TEX4MTXIDX) {
GX_WRITE_SOME_REG4(8, 0x30, __GXData->matIdxA, -12);
GX_WRITE_XF_REG(0x1018, __GXData->matIdxA, 0);
} else {
GX_WRITE_SOME_REG4(8, 0x40, __GXData->matIdxB, -12);
GX_WRITE_XF_REG(0x1019, __GXData->matIdxB, 0);
}
__GXData->bpSentNot = 1;
}

View File

@ -0,0 +1,628 @@
#if DEBUG
#include <stdio.h>
#include <revolution/gx.h>
#include "__gx.h"
static char __data_0[] = "RGB multisample";
static char _305[] = "GX_TEVPREV(color)";
static char _306[] = "GX_TEVPREV(alpha)";
static char _307[] = "GX_TEVREG0(color)";
static char _308[] = "GX_TEVREG0(alpha)";
static char _309[] = "GX_TEVREG1(color)";
static char _310[] = "GX_TEVREG1(alpha)";
static char _311[] = "GX_TEVREG2(color)";
static char _312[] = "GX_TEVREG2(alpha)";
static char* TevRegNames[8] = {0};
#define SOME_GET_REG_MACRO(reg, size, shift) ((u32)((reg) << (shift)) & ((1 << (size)) - 2))
#define SOME_GET_REG_MACRO2(reg, size, shift) ((u32)((reg) >> (shift)) & ((1 << (size)) - 2))
void __GXVerifySU(void) {
s32 scis_l;
s32 scis_r;
s32 scis_t;
s32 scis_b;
scis_l = (u32)GET_REG_FIELD(__gxVerif->rasRegs[32], 11, 12);
scis_t = (u32)GET_REG_FIELD(__gxVerif->rasRegs[32], 11, 0);
scis_r = (u32)GET_REG_FIELD(__gxVerif->rasRegs[33], 11, 12);
scis_b = (u32)GET_REG_FIELD(__gxVerif->rasRegs[33], 11, 0);
scis_l = scis_l - (u32)SOME_GET_REG_MACRO(__gxVerif->rasRegs[89], 11, 1);
scis_r = scis_r - (u32)SOME_GET_REG_MACRO(__gxVerif->rasRegs[89], 11, 1);
scis_t = scis_t - (u32)SOME_GET_REG_MACRO2(__gxVerif->rasRegs[89], 11, 9);
scis_b = scis_b - (u32)SOME_GET_REG_MACRO2(__gxVerif->rasRegs[89], 11, 9);
if (scis_l < 0 && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_SCISSOR_RECT_LEFT]) {
__GX_WARNF(GXWARN_SCISSOR_RECT_LEFT, 0);
}
if (scis_t < 0 && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_SCISSOR_RECT_TOP]) {
__GX_WARNF(GXWARN_SCISSOR_RECT_TOP, 0);
}
switch (__gxVerif->rasRegs[67] & 7) {
case 4:
case 5:
if (scis_r > 719 && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_SCISSOR_RECT_RIGHT]) {
__GX_WARNF(GXWARN_SCISSOR_RECT_RIGHT, 719, "YUV");
}
if (scis_b > 575 && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_SCISSOR_RECT_BOT]) {
__GX_WARNF(GXWARN_SCISSOR_RECT_BOT, 575, "YUV");
}
break;
case 0:
case 1:
case 3:
if (scis_r > 639 && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_SCISSOR_RECT_RIGHT]) {
__GX_WARNF(GXWARN_SCISSOR_RECT_RIGHT, 639, "RGB");
}
if (scis_b > 527 && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_SCISSOR_RECT_BOT]) {
__GX_WARNF(GXWARN_SCISSOR_RECT_BOT, 527, "RGB");
}
break;
case 2:
if (scis_r > 639 && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_SCISSOR_RECT_RIGHT]) {
__GX_WARNF(GXWARN_SCISSOR_RECT_RIGHT, 639, __data_0);
}
if (scis_b > 263 && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_SCISSOR_RECT_BOT]) {
__GX_WARNF(GXWARN_SCISSOR_RECT_BOT, 263, __data_0);
}
break;
}
}
void __GXVerifyBUMP(void) {
u32 i;
u32 nBmp;
u32 nTev;
u32 nTex;
u32 matrix;
nBmp = GET_REG_FIELD(__gxVerif->rasRegs[0], 3, 16);
nTex = GET_REG_FIELD(__gxVerif->rasRegs[0], 4, 0);
nTev = GET_REG_FIELD(__gxVerif->rasRegs[0], 4, 10) + 1;
for (i = 0; i < nTev; i++) {
matrix = GET_REG_FIELD(__gxVerif->rasRegs[16 + i], 4, 9);
if (__gxVerif->verifyLevel >= GX_WARN_SEVERE) {
if ((u32)(__gxVerif->rasRegs[16 + i] & 0xFF000000) + 0x01000000 == 0U && __gxVerif->verifyLevel >= __gxvWarnLev[7]) {
sprintf(__gxvDummyStr, __gxvWarnings[7], i);
__gxVerif->cb(__gxvWarnLev[7], 7U, __gxvDummyStr);
}
if ((GET_REG_FIELD(__gxVerif->rasRegs[16 + i], 2, 7) != 0 || matrix != 0)
&& GET_REG_FIELD(__gxVerif->rasRegs[16 + i], 2, 0) >= nBmp && __gxVerif->verifyLevel >= __gxvWarnLev[8]) {
sprintf(__gxvDummyStr, __gxvWarnings[8], i);
__gxVerif->cb(__gxvWarnLev[8], 8U, __gxvDummyStr);
}
if (matrix != 0) {
matrix = (matrix & 3) - 1;
if (((u32)(__gxVerif->rasRegs[(matrix * 3) + 6] & 0xFF000000) + 0x01000000 == 0
|| (u32)(__gxVerif->rasRegs[(matrix * 3) + 7] & 0xFF000000) + 0x01000000 == 0U
|| (u32)(__gxVerif->rasRegs[(matrix * 3) + 8] & 0xFF000000) + 0x01000000 == 0U) && __gxVerif->verifyLevel >= __gxvWarnLev[9]) {
sprintf(__gxvDummyStr, __gxvWarnings[9], matrix, i);
__gxVerif->cb(__gxvWarnLev[9], 9U, __gxvDummyStr);
}
}
}
}
if (__gxVerif->verifyLevel >= GX_WARN_SEVERE) {
if (nBmp != 0 && (u32)(__gxVerif->rasRegs[0x27] & 0xFF000000) + 0x01000000 == 0 && __gxVerif->verifyLevel >= __gxvWarnLev[10]) {
__gxVerif->cb(__gxvWarnLev[10], 0xAU, __gxvWarnings[10]);
}
if (nBmp != 0 && (u32)(__gxVerif->rasRegs[0x25] & 0xFF000000) + 0x01000000 == 0 && __gxVerif->verifyLevel >= __gxvWarnLev[11]) {
sprintf(__gxvDummyStr, __gxvWarnings[11], 0U, 1);
__gxVerif->cb(__gxvWarnLev[11], 0xBU, __gxvDummyStr);
}
if (nBmp > 2U && (u32)(__gxVerif->rasRegs[0x26] & 0xFF000000) + 0x01000000 == 0 && __gxVerif->verifyLevel >= __gxvWarnLev[11]) {
sprintf(__gxvDummyStr, __gxvWarnings[11], 2U, 3);
__gxVerif->cb(__gxvWarnLev[11], 0xBU, __gxvDummyStr);
}
if (nBmp != 0 && GET_REG_FIELD(__gxVerif->rasRegs[0x27], 3, 3) >= nTex && __gxVerif->verifyLevel >= __gxvWarnLev[12]) {
sprintf(__gxvDummyStr, __gxvWarnings[12], 0U);
__gxVerif->cb(__gxvWarnLev[12], 0xCU, __gxvDummyStr);
}
if (nBmp > 1U && GET_REG_FIELD(__gxVerif->rasRegs[0x27], 3, 9) >= nTex && __gxVerif->verifyLevel >= __gxvWarnLev[12]) {
sprintf(__gxvDummyStr, __gxvWarnings[12], 1U);
__gxVerif->cb(__gxvWarnLev[12], 0xCU, __gxvDummyStr);
}
if (nBmp > 2U && GET_REG_FIELD(__gxVerif->rasRegs[0x27], 3, 15) >= nTex && __gxVerif->verifyLevel >= __gxvWarnLev[12]) {
sprintf(__gxvDummyStr, __gxvWarnings[12], 2U);
__gxVerif->cb(__gxvWarnLev[12], 0xCU, __gxvDummyStr);
}
if (nBmp > 3U && GET_REG_FIELD(__gxVerif->rasRegs[0x27], 3, 21) >= nTex && __gxVerif->verifyLevel >= __gxvWarnLev[12]) {
sprintf(__gxvDummyStr, __gxvWarnings[12], 3U);
__gxVerif->cb(__gxvWarnLev[12], 0xCU, __gxvDummyStr);
}
if (nBmp != 0 && GET_REG_FIELD(__gxVerif->rasRegs[0x10], 1, 20) && __gxVerif->verifyLevel >= __gxvWarnLev[13]) {
__gxVerif->cb(__gxvWarnLev[13], 0xDU, __gxvWarnings[13]);
}
if (nBmp != 0 && GET_REG_FIELD(__gxVerif->rasRegs[0x10], 2, 7) != 0 && __gxVerif->verifyLevel >= __gxvWarnLev[14]) {
__gxVerif->cb(__gxvWarnLev[14], 0xEU, __gxvWarnings[14]);
}
if ((u32)(__gxVerif->rasRegs[0xF] & 0xFF000000) + 0x01000000 == 0 && (nTex != 0 || nBmp != 0) && __gxVerif->verifyLevel >= __gxvWarnLev[15]) {
__gxVerif->cb(__gxvWarnLev[15], 0xFU, __gxvWarnings[15]);
}
}
}
#define SOMEINDEX(index) (index & 3) + ((index * 8) & ~0x1F)
#define MAX(a, b) ((a) > (b) ? (a) : (b))
void __GXVerifyTEX(void) {
u32 i;
u32 nBmp;
u32 nTev;
u32 nTex;
u32 enabled;
u32 texId;
u32 direct[8];
u32 indirect[8];
u32 h2;
u32 w2;
u32 nlevels;
nBmp = GET_REG_FIELD(__gxVerif->rasRegs[0], 3, 16);
nTex = GET_REG_FIELD(__gxVerif->rasRegs[0], 4, 0);
nTev = GET_REG_FIELD(__gxVerif->rasRegs[0], 4, 10) + 1;
for (i = 0; i < 8; i++) {
direct[i] = 0;
indirect[i] = 0;
}
for (i = 0; i < nTev + nBmp; i++) {
if (i < nTev) {
if (__gxVerif->verifyLevel >= 1) {
if ((__gxVerif->rasRegs[(i >> 1U) + 0x28] & 0xFF000000) + 0x01000000 == 0U && __gxVerif->verifyLevel >= __gxvWarnLev[16]) {
sprintf(__gxvDummyStr, __gxvWarnings[16], i);
__gxVerif->cb(__gxvWarnLev[16], 16, __gxvDummyStr);
}
if (i & 1) {
enabled = GET_REG_FIELD(__gxVerif->rasRegs[(i >> 1U) + 0x28], 1, 18);
if (enabled && (GET_REG_FIELD(__gxVerif->rasRegs[(i >> 1U) + 0x28], 3, 15) >= nTex) && __gxVerif->verifyLevel >= __gxvWarnLev[17]) {
sprintf(__gxvDummyStr, __gxvWarnings[17], i);
__gxVerif->cb(__gxvWarnLev[17], 17, __gxvDummyStr);
}
texId = GET_REG_FIELD(__gxVerif->rasRegs[(i >> 1U) + 0x28], 3, 12);
} else {
enabled = GET_REG_FIELD(__gxVerif->rasRegs[(i >> 1U) + 0x28], 1, 6);
if (enabled && (GET_REG_FIELD(__gxVerif->rasRegs[(i >> 1U) + 0x28], 3, 3) >= nTex) && __gxVerif->verifyLevel >= __gxvWarnLev[17]) {
sprintf(__gxvDummyStr, __gxvWarnings[17], i);
__gxVerif->cb(__gxvWarnLev[17], 17, __gxvDummyStr);
}
texId = GET_REG_FIELD(__gxVerif->rasRegs[(i >> 1U) + 0x28], 3, 0);
}
if (enabled) {
direct[texId] = 1;
}
}
} else {
enabled = 1;
if ((i - nTev) == 0) {
texId = GET_REG_FIELD(__gxVerif->rasRegs[0x27], 3, 0);
} else if ((i - nTev) == 1U) {
texId = GET_REG_FIELD(__gxVerif->rasRegs[0x27], 3, 6);
} else if ((i - nTev) == 2U) {
texId = GET_REG_FIELD(__gxVerif->rasRegs[0x27], 3, 12);
} else {
texId = GET_REG_FIELD(__gxVerif->rasRegs[0x27], 3, 18);
}
if (!indirect[texId] && direct[texId] && __gxVerif->verifyLevel >= __gxvWarnLev[18]) {
sprintf(__gxvDummyStr, __gxvWarnings[18], texId);
__gxVerif->cb(__gxvWarnLev[18], 18, __gxvDummyStr);
}
indirect[texId] = 1;
}
if (enabled) {
if (__gxVerif->verifyLevel >= GX_WARN_SEVERE) {
if (((u32)(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)] & 0xFF000000) + 0x01000000 == 0
|| (u32)(__gxVerif->rasRegs[0x84 + SOMEINDEX(texId)] & 0xFF000000) + 0x01000000 == 0
|| (u32)(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)] & 0xFF000000) + 0x01000000 == 0
|| (u32)(__gxVerif->rasRegs[0x8C + SOMEINDEX(texId)] & 0xFF000000) + 0x01000000 == 0
|| (u32)(__gxVerif->rasRegs[0x90 + SOMEINDEX(texId)] & 0xFF000000) + 0x01000000 == 0) && __gxVerif->verifyLevel >= __gxvWarnLev[19]) {
sprintf(__gxvDummyStr, __gxvWarnings[19], texId);
__gxVerif->cb(__gxvWarnLev[19], 19, __gxvDummyStr);
}
if (GET_REG_FIELD(__gxVerif->rasRegs[0x8C + SOMEINDEX(texId)], 1, 21) == 0
&& (u32)(__gxVerif->rasRegs[0x94 + SOMEINDEX(texId)] & 0xFF000000) + 0x01000000 == 0 && __gxVerif->verifyLevel >= __gxvWarnLev[20]) {
sprintf(__gxvDummyStr, __gxvWarnings[20], texId);
__gxVerif->cb(__gxvWarnLev[20], 20, __gxvDummyStr);
}
if (((u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 8
|| (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 9
|| (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 10)
&& (__gxVerif->rasRegs[0x98 + SOMEINDEX(texId)] & 0xFF000000) + 0x01000000 == 0U && __gxVerif->verifyLevel >= __gxvWarnLev[21]) {
sprintf(__gxvDummyStr, __gxvWarnings[21], texId);
__gxVerif->cb(__gxvWarnLev[21], 21, __gxvDummyStr);
}
if (GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 10, 0) + 1 == 0) {
w2 = 1;
} else {
w2 = 1;
while (!(w2 & (GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 10, 0) + 1))) {
w2 *= 2;
}
w2 = (GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 10, 0) + 1) == w2;
}
if (GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 10, 10) + 1 == 0) {
h2 = 1;
} else {
h2 = 1;
while (!(h2 & (GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 10, 10) + 1))) {
h2 *= 2;
}
h2 = (GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 10, 10) + 1) == h2;
}
if (GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)] & 0xFFFF, 2, 5) && !w2 && __gxVerif->verifyLevel >= __gxvWarnLev[22]) {
sprintf(__gxvDummyStr, __gxvWarnings[22], "Width", texId);
__gxVerif->cb(__gxvWarnLev[22], 22, __gxvDummyStr);
}
if (GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)] & 0xFFFF, 2, 5) && !h2 && __gxVerif->verifyLevel >= __gxvWarnLev[22]) {
sprintf(__gxvDummyStr, __gxvWarnings[22], "Height", texId);
__gxVerif->cb(__gxvWarnLev[22], 22, __gxvDummyStr);
}
if (GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 2, 0) && !w2 && __gxVerif->verifyLevel >= __gxvWarnLev[23]) {
sprintf(__gxvDummyStr, __gxvWarnings[23], "S", texId);
__gxVerif->cb(__gxvWarnLev[23], 23, __gxvDummyStr);
}
if (GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 2, 2) && !h2 && __gxVerif->verifyLevel >= __gxvWarnLev[23]) {
sprintf(__gxvDummyStr, __gxvWarnings[23], "T", texId);
__gxVerif->cb(__gxvWarnLev[23], 23, __gxvDummyStr);
}
if (GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)] & 0xFFFF, 2, 5) != 0
&& ((u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 8
|| (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 9
|| (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 10)
&& (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 3, 5) != 1
&& (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 3, 5) != 5 && __gxVerif->verifyLevel >= __gxvWarnLev[24]) {
sprintf(__gxvDummyStr, __gxvWarnings[24], texId);
__gxVerif->cb(__gxvWarnLev[24], 24, __gxvDummyStr);
}
if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[0x84 + SOMEINDEX(texId)], 8, 0) > (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x84 + SOMEINDEX(texId)], 8, 8) && __gxVerif->verifyLevel >= __gxvWarnLev[25]) {
sprintf(__gxvDummyStr, __gxvWarnings[25], texId);
__gxVerif->cb(__gxvWarnLev[25], 25, __gxvDummyStr);
}
for (
nlevels = 0;
(
MAX((u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 10, 0) + 1,
(u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 10, 10) + 1) >> nlevels
) != 0;
nlevels++) {
}
if (GET_REG_FIELD(__gxVerif->rasRegs[0x84 + SOMEINDEX(texId)], 8, 8) > (nlevels - 1) * 16 && __gxVerif->verifyLevel >= __gxvWarnLev[26]) {
sprintf(__gxvDummyStr, __gxvWarnings[26], texId);
__gxVerif->cb(__gxvWarnLev[26], 26, __gxvDummyStr);
}
if (GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 1, 21) && GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 1, 8) && __gxVerif->verifyLevel >= __gxvWarnLev[27]) {
sprintf(__gxvDummyStr, __gxvWarnings[27], texId);
__gxVerif->cb(__gxvWarnLev[27], 27, __gxvDummyStr);
}
if (GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 2, 19)
&& (GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)] & 0xFFFF, 2, 5) == 0
|| (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 3, 5) != 6
|| (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 1, 4) != 1
|| (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 8
|| (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 9
|| (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 10
|| (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 1, 8) != 0
|| (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 1, 21)) && __gxVerif->verifyLevel >= __gxvWarnLev[28]) {
sprintf(__gxvDummyStr, __gxvWarnings[28], texId);
__gxVerif->cb(__gxvWarnLev[28], 28, __gxvDummyStr);
}
}
if (GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 1, 18) != 0) {
if (((u32)GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 3, 5) != 4 || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 1, 4) != 1) && __gxVerif->verifyLevel >= __gxvWarnLev[29]) {
sprintf(__gxvDummyStr, __gxvWarnings[29], texId);
__gxVerif->cb(__gxvWarnLev[29], 29, __gxvDummyStr);
}
if ((!GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 1, 17) || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) != 1 || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 2, 19) != 0) && __gxVerif->verifyLevel >= __gxvWarnLev[30]) {
sprintf(__gxvDummyStr, __gxvWarnings[30], texId);
__gxVerif->cb(__gxvWarnLev[30], 30, __gxvDummyStr);
}
}
if (GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 1, 17) != 0) {
if (((u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 8 || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 9 || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 10) && __gxVerif->verifyLevel >= __gxvWarnLev[31]) {
sprintf(__gxvDummyStr, __gxvWarnings[31], texId);
__gxVerif->cb(__gxvWarnLev[31], 31, __gxvDummyStr);
}
if ((!GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 1, 18) || 0) && __gxVerif->verifyLevel >= __gxvWarnLev[30]) {
sprintf(__gxvDummyStr, __gxvWarnings[30], texId);
__gxVerif->cb(__gxvWarnLev[30], 30, __gxvDummyStr);
}
}
}
}
}
void __GXVerifyTEV(void) {
u32 i; // r31
u32 nTev; // r29
u32 nCol; // r28
u32 enabled; // r30
u32 color; // r27
u32 Clh[4]; // r1+0x38
u32 Alh[4]; // r1+0x28
u32 Cwritten[4]; // r1+0x18
u32 Awritten[4]; // r1+0x8
nTev = GET_REG_FIELD(__gxVerif->rasRegs[0], 4, 10) + 1;
nCol = GET_REG_FIELD(__gxVerif->rasRegs[0], 3, 4);
nCol;
for (i = 0; i < 4; i++) {
Clh[i] = 0;
Alh[i] = 0;
Cwritten[i] = 0;
Awritten[i] = 0;
}
for (i = 0; i < nTev; i++) {
if (__gxVerif->verifyLevel >= GX_WARN_SEVERE
&& (((u32) ((__gxVerif->rasRegs[(i * 2) + 0xC0] & 0xFF000000) + 0x01000000) == 0U) || ((u32) ((__gxVerif->rasRegs[(i * 2) + 0xC1] & 0xFF000000) + 0x01000000) == 0U))) {
sprintf(__gxvDummyStr, __gxvWarnings[32], i);
__gxVerif->cb(1, 0x20U, __gxvDummyStr);
}
if (i & 1) {
color = GET_REG_FIELD(__gxVerif->rasRegs[(i >> 1U) + 0x28], 3, 19);
} else {
color = GET_REG_FIELD(__gxVerif->rasRegs[(i >> 1U) + 0x28], 3, 7);
}
if (__gxVerif->verifyLevel >= GX_WARN_MEDIUM && ((color == 0 && nCol < 1) || (color == 1 && nCol < 2))) {
sprintf(__gxvDummyStr, __gxvWarnings[33], i);
__gxVerif->cb(1, 0x21U, __gxvDummyStr);
}
if (i & 1) {
enabled = GET_REG_FIELD(__gxVerif->rasRegs[(i >> 1U) + 0x28], 1, 18);
} else {
enabled = GET_REG_FIELD(__gxVerif->rasRegs[(i >> 1U) + 0x28], 1, 6);
}
if (__gxVerif->verifyLevel >= GX_WARN_SEVERE) {
if (!enabled && ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 12) == 8 || (u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 12) == 9)) {
sprintf(__gxvDummyStr, __gxvWarnings[0x22], "A", i);
__gxVerif->cb(1, 0x22U, __gxvDummyStr);
}
if (!enabled && ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 8) == 8 || (u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 8) == 9)) {
sprintf(__gxvDummyStr, __gxvWarnings[0x22], "B", i);
__gxVerif->cb(1, 0x22U, __gxvDummyStr);
}
if (!enabled && ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 4) == 8 || (u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 4) == 9)) {
sprintf(__gxvDummyStr, __gxvWarnings[0x22], "C", i);
__gxVerif->cb(1, 0x22U, __gxvDummyStr);
}
if (!enabled && ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 0) == 8 || (u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 0) == 9)) {
sprintf(__gxvDummyStr, __gxvWarnings[0x22], "D", i);
__gxVerif->cb(1, 0x22U, __gxvDummyStr);
}
if (!enabled && (u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 13) == 4) {
sprintf(__gxvDummyStr, __gxvWarnings[0x23], "A", i);
__gxVerif->cb(1, 0x23U, __gxvDummyStr);
}
if (!enabled && (u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 10) == 4) {
sprintf(__gxvDummyStr, __gxvWarnings[0x23], "B", i);
__gxVerif->cb(1, 0x23U, __gxvDummyStr);
}
if (!enabled && (u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 7) == 4) {
sprintf(__gxvDummyStr, __gxvWarnings[0x23], "C", i);
__gxVerif->cb(1, 0x23U, __gxvDummyStr);
}
if (!enabled && (u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 4) == 4) {
sprintf(__gxvDummyStr, __gxvWarnings[0x23], "D", i);
__gxVerif->cb(1, 0x23U, __gxvDummyStr);
}
if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 12) <= 7 && ((__gxVerif->rasRegs[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 12) + 0xE1] & 0xFF000000) + 0x01000000) == 0U) {
if (GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 12) ? !Awritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 13)] : !Cwritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 13)]) {
sprintf(__gxvDummyStr, __gxvWarnings[0x24], "A", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 0xCU) ? "alpha" : "color", (__gxVerif->rasRegs[(i * 2) + 0xC0] >> 0xDU) & 7);
__gxVerif->cb(1, 0x24U, __gxvDummyStr);
}
}
if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 8) <= 7 && ((__gxVerif->rasRegs[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 8) + 0xE1] & 0xFF000000) + 0x01000000) == 0U) {
if (GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 8) ? !Awritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 9)] : !Cwritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 9)]) {
sprintf(__gxvDummyStr, __gxvWarnings[0x24], "B", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 8U) ? "alpha" : "color", (__gxVerif->rasRegs[(i * 2) + 0xC0] >> 9U) & 7);
__gxVerif->cb(1, 0x24U, __gxvDummyStr);
}
}
if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 4) <= 7 && ((__gxVerif->rasRegs[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 4) + 0xE1] & 0xFF000000) + 0x01000000) == 0U) {
if (GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 4) ? !Awritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 5)] : !Cwritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 5)]) {
sprintf(__gxvDummyStr, __gxvWarnings[0x24], "C", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 4U) ? "alpha" : "color", (__gxVerif->rasRegs[(i * 2) + 0xC0] >> 5U) & 7);
__gxVerif->cb(1, 0x24U, __gxvDummyStr);
}
}
if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 0) <= 7 && ((__gxVerif->rasRegs[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 0) + 0xE1] & 0xFF000000) + 0x01000000) == 0U) {
if (GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 0) ? !Awritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 1)] : !Cwritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 1)]) {
sprintf(__gxvDummyStr, __gxvWarnings[0x24], "D", i, (__gxVerif->rasRegs[(i * 2) + 0xC0] & 1) ? "alpha" : "color", (__gxVerif->rasRegs[(i * 2) + 0xC0] >> 1U) & 7);
__gxVerif->cb(1, 0x24U, __gxvDummyStr);
}
}
if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 13) <= 3 && ((__gxVerif->rasRegs[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 4, 14) + 0xE0] & 0xFF000000) + 0x01000000) == 0U && Awritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 13)] == 0U) {
sprintf(__gxvDummyStr, __gxvWarnings[0x25], "A", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 13));
__gxVerif->cb(1, 0x25U, __gxvDummyStr);
}
if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 10) <= 3 && ((__gxVerif->rasRegs[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 11) + 0xE0] & 0xFF000000) + 0x01000000) == 0U && Awritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 10)] == 0U) {
sprintf(__gxvDummyStr, __gxvWarnings[0x25], "B", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 10));
__gxVerif->cb(1, 0x25U, __gxvDummyStr);
}
if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 7) <= 3 && ((__gxVerif->rasRegs[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 8) + 0xE0] & 0xFF000000) + 0x01000000) == 0U && Awritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 7)] == 0U) {
sprintf(__gxvDummyStr, __gxvWarnings[0x25], "C", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 7));
__gxVerif->cb(1, 0x25U, __gxvDummyStr);
}
if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 4) <= 3 && ((__gxVerif->rasRegs[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 3) + 0xE0] & 0xFF000000) + 0x01000000) == 0U && Awritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 4)] == 0U) {
sprintf(__gxvDummyStr, __gxvWarnings[0x25], "D", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 4));
__gxVerif->cb(1, 0x25U, __gxvDummyStr);
}
}
if (__gxVerif->verifyLevel >= GX_WARN_ALL) {
if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 12) <= 7) {
if (GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 12) ? Alh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 13)] : Clh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 13)]) {
sprintf(__gxvDummyStr, __gxvWarnings[0x26], "A", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 12) ? "alpha" : "color", GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 13));
__gxVerif->cb(3, 0x26U, __gxvDummyStr);
}
}
if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 8) <= 7) {
if (GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 8) ? Alh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 9)] : Clh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 9)]) {
sprintf(__gxvDummyStr, __gxvWarnings[0x26], "B", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 8) ? "alpha" : "color", GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 9));
__gxVerif->cb(3, 0x26U, __gxvDummyStr);
}
}
if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 4) <= 7) {
if (GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 4) ? Alh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 5)] : Clh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 5)]) {
sprintf(__gxvDummyStr, __gxvWarnings[0x26], "C", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 4) ? "alpha" : "color", GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 5));
__gxVerif->cb(3, 0x26U, __gxvDummyStr);
}
}
if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 13) <= 3 && (u32)Alh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 13)] != 0) {
sprintf(__gxvDummyStr, __gxvWarnings[0x27], "A", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 0xDU));
__gxVerif->cb(3, 0x27U, __gxvDummyStr);
}
if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 10) <= 3 && (u32)Alh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 10)] != 0) {
sprintf(__gxvDummyStr, __gxvWarnings[0x27], "B", i, ((__gxVerif->rasRegs[(i * 2) + 0xC1] >> 0xAU) & 7));
__gxVerif->cb(3, 0x27U, __gxvDummyStr);
}
if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 7) <= 3 && (u32)Alh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 7)] != 0) {
sprintf(__gxvDummyStr, __gxvWarnings[0x27], "C", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 7U));
__gxVerif->cb(3, 0x27U, __gxvDummyStr);
}
}
Cwritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 2, 22)] = 1;
Awritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 2, 22)] = 1;
Clh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 2, 22)] = (!GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 2, 0) && !GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 19));
Alh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 2, 22)] = (!GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 2, 0) && !GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 1, 19));
}
for (i = 0; i < 4; i++) {
if (Cwritten[i] != 0U) {
__gxVerif->rasRegs[(i * 2) + 0xE1] = (__gxVerif->rasRegs[(i * 2) + 0xE1] & 0xFFFFFF) | 0xFF000000;
}
if (Awritten[i] != 0U) {
__gxVerif->rasRegs[(i * 2) + 0xE0] = (__gxVerif->rasRegs[(i * 2) + 0xE0] & 0xFFFFFF) | 0xFF000000;
}
}
if (GET_REG_FIELD(__gxVerif->rasRegs[0xF5], 2, 2) && __gxVerif->verifyLevel >= 1) {
if ((u32) ((__gxVerif->rasRegs[0xF4] & 0xFF000000) + 0x01000000) == 0U) {
__gxVerif->cb(1, 0x28U, __gxvWarnings[0x28]);
}
if (!enabled) {
__gxVerif->cb(1, 0x29U, __gxvWarnings[0x29]);
}
}
if (__gxVerif->verifyLevel >= GX_WARN_MEDIUM) {
if (GET_REG_FIELD(__gxVerif->rasRegs[((nTev - 1) * 2) + 0xC0], 2, 22)) {
__gxVerif->cb(2, 0x2AU, __gxvWarnings[0x2A]);
}
if (GET_REG_FIELD(__gxVerif->rasRegs[((nTev - 1) * 2) + 0xC1], 2, 22)) {
__gxVerif->cb(2, 0x2BU, __gxvWarnings[0x2B]);
}
}
if (__gxVerif->verifyLevel >= GX_WARN_ALL) {
if (!GET_REG_FIELD(__gxVerif->rasRegs[((nTev - 1) * 2) + 0xC1], 2, 0) && !GET_REG_FIELD(__gxVerif->rasRegs[((nTev - 1) * 2) + 0xC0], 1, 19)) {
__gxVerif->cb(3, 0x2CU, __gxvWarnings[0x2C]);
}
if (!GET_REG_FIELD(__gxVerif->rasRegs[((nTev - 1) * 2) + 0xC1], 2, 0) && !GET_REG_FIELD(__gxVerif->rasRegs[((nTev - 1) * 2) + 0xC1], 1, 19)) {
__gxVerif->cb(3, 0x2DU, __gxvWarnings[0x2D]);
}
}
if (__gxVerif->verifyLevel >= GX_WARN_MEDIUM && GET_REG_FIELD(__gxVerif->rasRegs[0x43], 1, 6) && (GET_REG_FIELD(__gxVerif->rasRegs[0xF3], 2, 22) || ((u32) GET_REG_FIELD(__gxVerif->rasRegs[0xF3], 3, 16) != 7) || ((u32) GET_REG_FIELD(__gxVerif->rasRegs[0xF3], 3, 19) != 7))) {
__gxVerif->cb(2, 0x2EU, __gxvWarnings[0x2E]);
}
}
void __GXVerifyPE(void) {
u32 i;
if (__gxVerif->verifyLevel >= GX_WARN_SEVERE && GET_REG_FIELD(__gxVerif->rasRegs[0x41], 1, 0) && GET_REG_FIELD(__gxVerif->rasRegs[0x41], 1, 1) && __gxVerif->verifyLevel >= __gxvWarnLev[0x2F]) {
__gxVerif->cb(__gxvWarnLev[0x2F], 0x2FU, __gxvWarnings[0x2F]);
}
if (__gxVerif->verifyLevel >= GX_WARN_MEDIUM) {
if (GET_REG_FIELD(__gxVerif->rasRegs[0], 1, 9) && (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x43], 3, 0) != 2 && __gxVerif->verifyLevel >= __gxvWarnLev[0x31]) {
__gxVerif->cb(__gxvWarnLev[0x31], 0x31U, __gxvWarnings[0x31]);
}
if (!GET_REG_FIELD(__gxVerif->rasRegs[0], 1, 9) && (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x43], 3, 0) == 2 && __gxVerif->verifyLevel >= __gxvWarnLev[0x32]) {
__gxVerif->cb(__gxvWarnLev[0x32], 0x32U, __gxvWarnings[0x32]);
}
}
if (__gxVerif->verifyLevel >= GX_WARN_ALL) {
for (i = 0; i < 4; i++) {
if (((u32)GET_REG_FIELD(__gxVerif->rasRegs[i + 1], 4, 4) > GET_REG_FIELD(__gxVerif->rasRegs[i + 1], 4, 12) || (u32)GET_REG_FIELD(__gxVerif->rasRegs[i + 1], 4, 12) > (u32)GET_REG_FIELD(__gxVerif->rasRegs[i + 1], 4, 20))
&& (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x43], 3, 0) == 2 && __gxVerif->verifyLevel >= __gxvWarnLev[0x33]) {
sprintf(__gxvDummyStr, __gxvWarnings[0x33], i);
__gxVerif->cb(__gxvWarnLev[0x33], 0x33U, __gxvDummyStr);
}
}
}
}
#endif

View File

@ -0,0 +1,946 @@
#if DEBUG
#include <stdio.h>
#include <revolution/gx.h>
#include "__gx.h"
static u32 DumpCount;
static s8 XFBuf[128];
static u32 numRegularTextures;
static u32 numBumpmapTextures;
static u32 numColor0Textures;
static u32 numColor1Textures;
static u32 numColorTextures;
static s32 XFChannel = -1;
static GXAttr TextureEnums[8] = {
GX_VA_TEX0,
GX_VA_TEX1,
GX_VA_TEX2,
GX_VA_TEX3,
GX_VA_TEX4,
GX_VA_TEX5,
GX_VA_TEX6,
GX_VA_TEX7,
};
static GXAttr MtxIdxEnums[9] = {
GX_VA_PNMTXIDX,
GX_VA_TEX0MTXIDX,
GX_VA_TEX1MTXIDX,
GX_VA_TEX2MTXIDX,
GX_VA_TEX3MTXIDX,
GX_VA_TEX4MTXIDX,
GX_VA_TEX5MTXIDX,
GX_VA_TEX6MTXIDX,
GX_VA_TEX7MTXIDX,
};
static u8 lightRegisterNames[13][256] = {
"Light Color RGBA",
"Cosine Attenuation A0",
"Cosine Attenuation A1",
"Cosine Attenuation A2",
"Distance Attenuation K0",
"Distance Attenuation K1",
"Distance Attenuation K2",
"X Light Position / Infinite Light X Direction",
"Y Light Position / Infinite Light Y Direction",
"Z Light Position / Infinite Light Z Direction",
"X Light Direction / Half Angle X Component",
"Y Light Direction / Half Angle Y Component",
"Z Light Direction / Half Angle Z Component",
};
#define LOWORD(var) (((u16 *)&(var))[0])
#define HIWORD(var) (((u16 *)&(var))[1])
#define BYTE0(var) (((u8 *)&(var))[0])
#define BYTE1(var) (((u8 *)&(var))[1])
#define BYTE2(var) (((u8 *)&(var))[2])
#define BYTE3(var) (((u8 *)&(var))[3])
static void CountTextureTypes(void) {
u32 i;
u32 texgen_type;
numRegularTextures = 0;
numBumpmapTextures = 0;
numColor0Textures = 0;
numColor1Textures = 0;
for (i = 0; i < __gxVerif->xfRegs[0x3F]; i++) {
texgen_type = (__gxVerif->xfRegs[i + 64] >> 4) & 7;
if (texgen_type == 0) {
numRegularTextures++;
} else if (texgen_type == 1) {
numBumpmapTextures++;
} else if (texgen_type == 2) {
numColor0Textures++;
} else if (texgen_type == 3) {
numColor1Textures++;
} else {
if (__gxVerif->verifyLevel >= __gxvWarnLev[52]) {
__GX_WARNF(GXWARN_INVALID_TG_TYPE, texgen_type, i);
}
}
}
numColorTextures = numColor0Textures + numColor1Textures;
}
static void InitializeXFVerifyData(void) {
CountTextureTypes();
}
static void CheckDirty(u32 index, const char* name) {
if (!__gxVerif->xfRegsDirty[index - 0x1000] && __gxVerif->verifyLevel >= __gxvWarnLev[53]) {
__GX_WARNF(GXWARN_XF_CTRL_UNINIT, index, name);
}
}
static void CheckClean(u32 index, const char* name) {
if (__gxVerif->xfRegsDirty[index - 0x1000] && __gxVerif->verifyLevel >= __gxvWarnLev[54]) {
__GX_WARNF(GXWARN_XF_CTRL_INIT, index, name);
}
}
static void CheckCTGColors(void) {
if ((u32)(__gxVerif->xfRegs[9] & 3) > 2 && __gxVerif->verifyLevel >= __gxvWarnLev[121]) {
__GX_WARNF(121, __gxVerif->xfRegs[9] & 3);
}
}
static GXBool __GXVertexPacketHas(GXAttr attr) {
switch (attr) {
case GX_VA_POS: return GET_REG_FIELD(__GXData->vcdLo, 2, 9) != 0;
case GX_VA_NRM: return __GXData->hasNrms ? GET_REG_FIELD(__GXData->vcdLo, 2, 11) != 0 : GX_FALSE;
case GX_VA_NBT: return __GXData->hasBiNrms ? GET_REG_FIELD(__GXData->vcdLo, 2, 11) != 0 : GX_FALSE;
case GX_VA_CLR0: return GET_REG_FIELD(__GXData->vcdLo, 2, 13) != 0;
case GX_VA_CLR1: return GET_REG_FIELD(__GXData->vcdLo, 2, 15) != 0;
case GX_VA_TEX0: return GET_REG_FIELD(__GXData->vcdHi, 2, 0) != 0;
case GX_VA_TEX1: return GET_REG_FIELD(__GXData->vcdHi, 2, 2) != 0;
case GX_VA_TEX2: return GET_REG_FIELD(__GXData->vcdHi, 2, 4) != 0;
case GX_VA_TEX3: return GET_REG_FIELD(__GXData->vcdHi, 2, 6) != 0;
case GX_VA_TEX4: return GET_REG_FIELD(__GXData->vcdHi, 2, 8) != 0;
case GX_VA_TEX5: return GET_REG_FIELD(__GXData->vcdHi, 2, 10) != 0;
case GX_VA_TEX6: return GET_REG_FIELD(__GXData->vcdHi, 2, 12) != 0;
case GX_VA_TEX7: return GET_REG_FIELD(__GXData->vcdHi, 2, 14) != 0;
case GX_VA_PNMTXIDX: return GET_REG_FIELD(__GXData->vcdLo, 1, 0) != 0;
case GX_VA_TEX0MTXIDX: return GET_REG_FIELD(__GXData->vcdLo, 1, 1) != 0;
case GX_VA_TEX1MTXIDX: return GET_REG_FIELD(__GXData->vcdLo, 1, 2) != 0;
case GX_VA_TEX2MTXIDX: return GET_REG_FIELD(__GXData->vcdLo, 1, 3) != 0;
case GX_VA_TEX3MTXIDX: return GET_REG_FIELD(__GXData->vcdLo, 1, 4) != 0;
case GX_VA_TEX4MTXIDX: return GET_REG_FIELD(__GXData->vcdLo, 1, 5) != 0;
case GX_VA_TEX5MTXIDX: return GET_REG_FIELD(__GXData->vcdLo, 1, 6) != 0;
case GX_VA_TEX6MTXIDX: return GET_REG_FIELD(__GXData->vcdLo, 1, 7) != 0;
case GX_VA_TEX7MTXIDX: return GET_REG_FIELD(__GXData->vcdLo, 1, 8) != 0;
default:
return GX_FALSE;
}
}
static void CheckVertexPacket(void) {
u32 numHostTextures;
u32 numHostTexAbsent;
u32 i;
if (!__GXVertexPacketHas(GX_VA_POS) && __gxVerif->verifyLevel >= __gxvWarnLev[57]) {
__GX_WARN(GXWARN_VTX_NO_GEOM);
}
if (__GXVertexPacketHas(GX_VA_CLR1) && !__GXVertexPacketHas(GX_VA_CLR0) &&__gxVerif->verifyLevel >= __gxvWarnLev[70]) {
__GX_WARN(GXWARN_VCD_CLR_ORDER);
}
numHostTextures = 0;
numHostTexAbsent = 0;
for (i = 0; i < 8; i++) {
if (__GXVertexPacketHas(TextureEnums[i])) {
numHostTextures += 1;
numHostTexAbsent = 0;
} else {
numHostTexAbsent += 1;
}
}
if (numHostTextures + numHostTexAbsent != 8 && __gxVerif->verifyLevel >= __gxvWarnLev[71]) {
__GX_WARN(GXWARN_VCD_TEX_ORDER);
}
if ((__gxVerif->xfRegs[8] & 3) == 0 && ((__gxVerif->xfRegs[8] >> 2) & 3) == 0 && (u32)((__gxVerif->xfRegs[8] >> 4) & 0xF) == 0) {
u32 numMatrixIndices = 0;
for (i = 0; i <= 8; i++) {
if (__GXVertexPacketHas(MtxIdxEnums[i])) {
numMatrixIndices += 1;
}
}
if (numMatrixIndices != 0 && __gxVerif->verifyLevel >= __gxvWarnLev[69]) {
__GX_WARN(GXWARN_VCD_FMT_UNSUP);
}
}
}
static void CheckSourceRows(void) {
u32 i;
for (i = 0; i < numRegularTextures; i++) {
switch ((__gxVerif->xfRegs[i + 64] >> 7) & 0x1F) {
case 0:
if (!__GXVertexPacketHas(GX_VA_POS) && __gxVerif->verifyLevel >= __gxvWarnLev[72]) {
__GX_WARNF(GXWARN_TEX_SRC_NPOS, i);
}
break;
case 1:
if (!__GXVertexPacketHas(GX_VA_NRM) && !__GXVertexPacketHas(GX_VA_NBT)&& __gxVerif->verifyLevel >= __gxvWarnLev[73]) {
__GX_WARNF(GXWARN_TEX_SRC_NNRM, i);
}
break;
case 2:
if (!__GXVertexPacketHas(GX_VA_CLR0) && __gxVerif->verifyLevel >= __gxvWarnLev[74]) {
__GX_WARNF(GXWARN_TEX_SRC_NCLR0, i);
}
if (!__GXVertexPacketHas(GX_VA_CLR1) && __gxVerif->verifyLevel >= __gxvWarnLev[75]) {
__GX_WARNF(GXWARN_TEX_SRC_NCLR1, i);
}
break;
case 3:
case 4:
if (!__GXVertexPacketHas(GX_VA_NBT) && __gxVerif->verifyLevel >= __gxvWarnLev[76]) {
__GX_WARNF(GXWARN_TEX_SRC_NNBT, i);
}
break;
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
case 12:
if (!__GXVertexPacketHas(TextureEnums[((__gxVerif->xfRegs[i + 64] >> 7) & 0x1F) - 5]) && __gxVerif->verifyLevel >= __gxvWarnLev[77]) {
__GX_WARNF(GXWARN_TEX_SRC_NTEX, i, ((__gxVerif->xfRegs[i + 64] >> 7) & 0x1F) - 5);
}
break;
default:
if (__gxVerif->verifyLevel >= __gxvWarnLev[78]) {
__GX_WARNF(GXWARN_INV_TEX_SRC, i, (__gxVerif->xfRegs[i + 64] >> 7) & 0x1F);
}
break;
}
}
}
static void CheckTextureOrder(void) {
u8 done = 0;
u32 count = 0;
while (!done) {
if (count == __gxVerif->xfRegs[0x3F] || ((__gxVerif->xfRegs[count + 64] >> 4) & 7)) {
done = 1;
} else {
count += 1;
}
}
done = 0;
while (done == 0) {
if (count == __gxVerif->xfRegs[0x3F]) {
done = 1;
} else if ((u32)((__gxVerif->xfRegs[count + 64] >> 4) & 7) != 1) {
if (!((__gxVerif->xfRegs[count + 64] >> 4) & 7) && __gxVerif->verifyLevel >= __gxvWarnLev[79]) {
__GX_WARN(GXWARN_INV_TG_ORDER);
}
done = 1;
} else {
count += 1;
}
}
done = 0;
while (done == 0) {
if (count == __gxVerif->xfRegs[0x3F]) {
done = 1;
} else if (!((__gxVerif->xfRegs[count + 64] >> 4) & 7) || (u32)((__gxVerif->xfRegs[count + 64] >> 4) & 7) == 1) {
if (__gxVerif->verifyLevel >= __gxvWarnLev[79]) {
__GX_WARN(GXWARN_INV_TG_ORDER);
}
done = 1;
} else {
count += 1;
}
}
}
static void CheckRAM(u8 Normal, u32 StartingAddress, u32 Count, GXWarnID WarnID, char* Str) {
u32 i;
u8 printedPreamble;
u8 dirtyBit;
printedPreamble = 0;
for (i = StartingAddress; i < StartingAddress + Count; i++) {
dirtyBit = Normal != 0 ? __gxVerif->xfMtxDirty[i - 0x300] : __gxVerif->xfMtxDirty[i];
if (dirtyBit == 0) {
if (printedPreamble == 0) {
if (__gxVerif->verifyLevel >= __gxvWarnLev[WarnID]) {
__gxVerif->cb(__gxvWarnLev[WarnID], WarnID, Str);
}
printedPreamble = 1;
}
}
}
}
static void CheckBumpmapTextures(void) {
u32 i;
u32 BumpMapSource;
u32 BumpMapLight;
u32 lightRAMOffset;
char Preamble[256];
if (!__GXVertexPacketHas(GX_VA_PNMTXIDX)) {
if ((u32)(__gxVerif->xfRegs[24] & 0x3F) > 30 && __gxVerif->verifyLevel >= __gxvWarnLev[0x50]) {
__GX_WARNF(0x50, __gxVerif->xfRegs[24] & 0x3F);
}
sprintf(Preamble, __gxvWarnings[0x6A], __gxVerif->xfRegs[24] & 0x3F);
CheckRAM(1, ((__gxVerif->xfRegs[24] & 0x3F) * 3) + 0x400, 9U, 0x6A, Preamble);
}
for (i = 0; i < numBumpmapTextures; i++) {
BumpMapSource = (__gxVerif->xfRegs[numRegularTextures + i + 64] >> 12) & 7;
if ((__gxVerif->xfRegs[BumpMapSource + 64] >> 4) & 7 && __gxVerif->verifyLevel >= __gxvWarnLev[0x51]) {
__GX_WARNF(0x51, i + numRegularTextures, BumpMapSource);
}
BumpMapLight = (__gxVerif->xfRegs[numRegularTextures + i + 0x40] >> 15) & 7;
lightRAMOffset = (BumpMapLight * 0x10) + 0x60A;
if (!__gxVerif->xfLightDirty[lightRAMOffset - 0x600 + 0] && __gxVerif->verifyLevel >= __gxvWarnLev[0x52]) {
__GX_WARNF(0x52, i + numRegularTextures, BumpMapLight, "X");
}
if (!__gxVerif->xfLightDirty[lightRAMOffset - 0x600 + 1] && __gxVerif->verifyLevel >= __gxvWarnLev[0x52]) {
__GX_WARNF(0x52, i + numRegularTextures, BumpMapLight, "Y");
}
if (!__gxVerif->xfLightDirty[lightRAMOffset - 0x600 + 2] && __gxVerif->verifyLevel >= __gxvWarnLev[0x52]) {
__GX_WARNF(0x52, i + numRegularTextures, BumpMapLight, "Z");
}
if (!__GXVertexPacketHas(GX_VA_NBT) && __gxVerif->verifyLevel >= __gxvWarnLev[0x53]) {
__GX_WARNF(0x53, i);
}
}
lightRAMOffset; lightRAMOffset; // needed to match
}
static void CheckTextureTransformMatrices(void) {
u32 i;
u32 StartingAddress;
u8 MtxIndexInVertexPacket;
char Preamble[256];
u32 Val;
for (i = 0; i < numRegularTextures; i++) {
MtxIndexInVertexPacket = 0;
switch (i) {
case 0:
StartingAddress = ((__gxVerif->xfRegs[0x18] >> 6U) & 0x3F) << 2;
Val = (__gxVerif->xfRegs[0x18] >> 6) & 0x3F;
MtxIndexInVertexPacket = __GXVertexPacketHas(GX_VA_TEX0MTXIDX);
break;
case 1:
StartingAddress = ((__gxVerif->xfRegs[0x18] >> 12) & 0x3F) << 2;
Val = (__gxVerif->xfRegs[0x18] >> 12) & 0x3F;
MtxIndexInVertexPacket = __GXVertexPacketHas(GX_VA_TEX1MTXIDX);
break;
case 2:
StartingAddress = ((__gxVerif->xfRegs[0x18] >> 18) & 0x3F) << 2;
Val = (__gxVerif->xfRegs[0x18] >> 18) & 0x3F;
MtxIndexInVertexPacket = __GXVertexPacketHas(GX_VA_TEX2MTXIDX);
break;
case 3:
StartingAddress = ((__gxVerif->xfRegs[0x18] >> 24) & 0x3F) << 2;
Val = (__gxVerif->xfRegs[0x18] >> 24) & 0x3F;
MtxIndexInVertexPacket = __GXVertexPacketHas(GX_VA_TEX3MTXIDX);
break;
case 4:
StartingAddress = (__gxVerif->xfRegs[0x19] & 0x3F) << 2;
Val = __gxVerif->xfRegs[0x19] & 0x3F;
MtxIndexInVertexPacket = __GXVertexPacketHas(GX_VA_TEX4MTXIDX);
break;
case 5:
StartingAddress = ((__gxVerif->xfRegs[0x19] >> 6) & 0x3F) << 2;
Val = (__gxVerif->xfRegs[0x19] >> 6) & 0x3F;
MtxIndexInVertexPacket = __GXVertexPacketHas(GX_VA_TEX5MTXIDX);
break;
case 6:
StartingAddress = ((__gxVerif->xfRegs[0x19] >> 12) & 0x3F) << 2;
Val = (__gxVerif->xfRegs[0x19] >> 12) & 0x3F;
MtxIndexInVertexPacket = __GXVertexPacketHas(GX_VA_TEX6MTXIDX);
break;
case 7:
StartingAddress = ((__gxVerif->xfRegs[0x19] >> 18) & 0x3F) << 2;
Val = (__gxVerif->xfRegs[0x19] >> 18) & 0x3F;
MtxIndexInVertexPacket = __GXVertexPacketHas(GX_VA_TEX7MTXIDX);
break;
default:
if (__gxVerif->verifyLevel >= __gxvWarnLev[0x54]) {
__GX_WARNF(0x54, i);
}
break;
}
if (MtxIndexInVertexPacket == 0) {
u32 Size;
sprintf(Preamble, __gxvWarnings[0x6B], i, i, Val);
Size = !((__gxVerif->xfRegs[i + 64] >> 1) & 1) ? 8 : 12;
CheckRAM(0U, StartingAddress, Size, 0x6B, Preamble);
}
}
}
static void CheckInputForms(void) {
u32 i;
for (i = 0; i < numRegularTextures; i++) {
switch ((__gxVerif->xfRegs[i + 64] >> 7) & 0x1F) {
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
case 12:
if ((__gxVerif->xfRegs[i + 64] >> 2) & 1 && __gxVerif->verifyLevel >= __gxvWarnLev[122]) {
__GX_WARNF(122, i, (__gxVerif->xfRegs[i + 64] >> 7) & 0x1F);
}
}
}
}
static void CheckLight(u32 lightSource) {
u32 lightRAMOffset;
u8 printedPreamble;
u32 i;
printedPreamble = 0;
lightRAMOffset = (lightSource * 0x10) + 0x603;
for (i = 0; i < 13; i++) {
if (!__gxVerif->xfLightDirty[lightRAMOffset + i - 0x600]) {
if (!printedPreamble) {
if (__gxVerif->verifyLevel >= __gxvWarnLev[0x6C]) {
__GX_WARNF(0x6C, lightSource);
}
printedPreamble = 1;
}
}
}
}
// NONMATCHING
static void CheckColor0(void) {
char Preamble[256];
u8 haveLight;
u32 i;
u8 lightUsed;
if ((u8)(BYTE3(__gxVerif->xfRegs[9]) & 3) || numColorTextures != 0) {
if (!__gxVerif->xfRegsDirty[14] && __gxVerif->verifyLevel >= __gxvWarnLev[0x7A]) {
__GX_WARNF(0x7A, 0x100E, "Color 0 control register");
}
if (!__gxVerif->xfRegsDirty[16] && __gxVerif->verifyLevel >= __gxvWarnLev[0x7A]) {
__GX_WARNF(0x7A, 0x1010, "Alpha 0 control register");
}
if (!(BYTE3(__gxVerif->xfRegs[14]) & 1) && !__gxVerif->xfRegsDirty[12] && __gxVerif->verifyLevel >= __gxvWarnLev[0x7B]) {
__GX_WARNF(0x7B, 0, 0, 0x100C);
}
if (!((BYTE3(__gxVerif->xfRegs[14]) >> 6) & 1) && !__gxVerif->xfRegsDirty[10] && __gxVerif->verifyLevel >= __gxvWarnLev[0x7C]) {
__GX_WARNF(0x7C, 0, 0, 0x100A);
}
if ((u32)((BYTE3(__gxVerif->xfRegs[14]) >> 1) & 1) == 1 || (u32)((BYTE3(__gxVerif->xfRegs[16]) >> 1) & 1) == 1) {
haveLight = 0;
for (i = 0; i < 8; i++) {
lightUsed = 0;
switch (i) {
case 0:
if ((u8)((BYTE3(__gxVerif->xfRegs[14]) >> 2) & 1) || (u8)((BYTE3(__gxVerif->xfRegs[16]) >> 2) & 1)) {
lightUsed = 1;
}
break;
case 1:
if ((u8)((BYTE3(__gxVerif->xfRegs[14]) >> 3) & 1) || (u8)((BYTE3(__gxVerif->xfRegs[16]) >> 3) & 1)) {
lightUsed = 1;
}
break;
case 2:
if ((u8)((BYTE3(__gxVerif->xfRegs[14]) >> 4) & 1) || (u8)((BYTE3(__gxVerif->xfRegs[16]) >> 4) & 1)) {
lightUsed = 1;
}
break;
case 3:
if ((u8)((BYTE3(__gxVerif->xfRegs[14]) >> 5) & 1) || (u8)((BYTE3(__gxVerif->xfRegs[16]) >> 5) & 1)) {
lightUsed = 1;
}
break;
case 4:
if ((u8)((BYTE2(__gxVerif->xfRegs[14]) >> 3) & 1) || (u8)((BYTE2(__gxVerif->xfRegs[16]) >> 3) & 1)) {
lightUsed = 1;
}
break;
case 5:
if ((u8)((BYTE2(__gxVerif->xfRegs[14]) >> 4) & 1) || (u8)((BYTE2(__gxVerif->xfRegs[16]) >> 4) & 1)) {
lightUsed = 1;
}
break;
case 6:
if ((u8)((BYTE2(__gxVerif->xfRegs[14]) >> 5) & 1) || (u8)((BYTE2(__gxVerif->xfRegs[16]) >> 5) & 1)) {
lightUsed = 1;
}
break;
case 7:
if ((u8)((BYTE2(__gxVerif->xfRegs[14]) >> 6) & 1) || (u8)((BYTE2(__gxVerif->xfRegs[16]) >> 6) & 1)) {
lightUsed = 1;
}
break;
}
if (lightUsed != 0) {
CheckLight(i);
haveLight = 1;
}
}
if (haveLight != 0) {
if (!((BYTE2(__gxVerif->xfRegs[14]) >> 2) & 1) && ((HIWORD(__gxVerif->xfRegs[14]) >> 7) & 3) && __gxVerif->verifyLevel >= __gxvWarnLev[0x59]) {
__GX_WARNF(0x59, "COLOR0", "COLOR0");
}
if (!((BYTE2(__gxVerif->xfRegs[16]) >> 2) & 1) && ((HIWORD(__gxVerif->xfRegs[16]) >> 7) & 3) && __gxVerif->verifyLevel >= __gxvWarnLev[0x59]) {
__GX_WARNF(0x59, "ALPHA0", "ALPHA0");
}
if (((HIWORD(__gxVerif->xfRegs[14]) >> 7) & 3)
|| ((u8)((BYTE2(__gxVerif->xfRegs[14]) >> 1) & 1) && ((u32)((BYTE2(__gxVerif->xfRegs[14]) >> 2) & 1) == 1))
|| ((HIWORD(__gxVerif->xfRegs[16]) >> 7) & 3)
|| ((u8)((BYTE2(__gxVerif->xfRegs[16]) >> 1) & 1) && ((u32)((BYTE2(__gxVerif->xfRegs[16]) >> 2) & 1) == 1))) {
if ((__GXVertexPacketHas(GX_VA_NRM) == 0) && (__GXVertexPacketHas(GX_VA_NBT) == 0) && __gxVerif->verifyLevel >= __gxvWarnLev[0x5A]) {
__GX_WARNF(0x5A, 0);
}
if (__GXVertexPacketHas(GX_VA_PNMTXIDX) == 0) {
if ((u32)(BYTE3(__gxVerif->xfRegs[24]) & 0x3F) > 30 && __gxVerif->verifyLevel >= __gxvWarnLev[0x5B]) {
__GX_WARNF(0x5B, 0, (BYTE3(__gxVerif->xfRegs[24]) & 0x3F));
}
sprintf(Preamble, __gxvWarnings[0x6D], 0, (u8)(BYTE3(__gxVerif->xfRegs[24]) & 0x3F));
CheckRAM(1, ((BYTE3(__gxVerif->xfRegs[24]) & 0x3F) * 3) + 0x400, 9, 0x6D, Preamble);
}
}
}
}
}
}
// NONMATCHING
static void CheckColor1(void) {
u8 usingColor1;
char Preamble[256];
u8 haveLight;
u32 i;
u8 lightUsed;
if (numColorTextures > 1 && ((u32)((BYTE3(__gxVerif->xfRegs[numRegularTextures + numBumpmapTextures + 1 + 64]) >> 4) & 7) == 3)) {
usingColor1 = 1;
} else {
usingColor1 = 0;
}
if ((u32)(BYTE3(__gxVerif->xfRegs[9]) & 3) == 2 || usingColor1) {
if (!__gxVerif->xfRegsDirty[15] && __gxVerif->verifyLevel >= __gxvWarnLev[0x7A]) {
__GX_WARNF(0x7A, 0x100F, "Color 1 control register");
}
if (!__gxVerif->xfRegsDirty[17] && __gxVerif->verifyLevel >= __gxvWarnLev[0x7A]) {
__GX_WARNF(0x7A, 0x1011, "Alpha 1 control register");
}
if (!(BYTE3(__gxVerif->xfRegs[15]) & 1) && !__gxVerif->xfRegsDirty[13] && __gxVerif->verifyLevel >= __gxvWarnLev[0x7B]) {
__GX_WARNF(0x7B, 1, 1, 0x100D);
}
if (!((BYTE3(__gxVerif->xfRegs[15]) >> 6) & 1) && !__gxVerif->xfRegsDirty[11] && __gxVerif->verifyLevel >= __gxvWarnLev[0x7C]) {
__GX_WARNF(0x7C, 1, 1, 0x100B);
}
if ((u32)((BYTE3(__gxVerif->xfRegs[15]) >> 1) & 1) == 1 || (u32)((BYTE3(__gxVerif->xfRegs[17]) >> 1) & 1) == 1) {
haveLight = 0;
for (i = 0; i < 8; i++) {
lightUsed = 0;
switch (i) {
case 0:
if ((u8)((BYTE3(__gxVerif->xfRegs[15]) >> 2) & 1) || (u8)((BYTE3(__gxVerif->xfRegs[17]) >> 2) & 1)) {
lightUsed = 1;
}
break;
case 1:
if ((u8)((BYTE3(__gxVerif->xfRegs[15]) >> 3) & 1) || (u8)((BYTE3(__gxVerif->xfRegs[17]) >> 3) & 1)) {
lightUsed = 1;
}
break;
case 2:
if ((u8)((BYTE3(__gxVerif->xfRegs[15]) >> 4) & 1) || (u8)((BYTE3(__gxVerif->xfRegs[17]) >> 4) & 1)) {
lightUsed = 1;
}
break;
case 3:
if ((u8)((BYTE3(__gxVerif->xfRegs[15]) >> 5) & 1) || (u8)((BYTE3(__gxVerif->xfRegs[17]) >> 5) & 1)) {
lightUsed = 1;
}
break;
case 4:
if ((u8)((BYTE2(__gxVerif->xfRegs[15]) >> 3) & 1) || (u8)((BYTE2(__gxVerif->xfRegs[17]) >> 3) & 1)) {
lightUsed = 1;
}
break;
case 5:
if ((u8)((BYTE2(__gxVerif->xfRegs[15]) >> 4) & 1) || (u8)((BYTE2(__gxVerif->xfRegs[17]) >> 4) & 1)) {
lightUsed = 1;
}
break;
case 6:
if ((u8)((BYTE2(__gxVerif->xfRegs[15]) >> 5) & 1) || (u8)((BYTE2(__gxVerif->xfRegs[17]) >> 5) & 1)) {
lightUsed = 1;
}
break;
case 7:
if ((u8)((BYTE2(__gxVerif->xfRegs[15]) >> 6) & 1) || (u8)((BYTE2(__gxVerif->xfRegs[17]) >> 6) & 1)) {
lightUsed = 1;
}
break;
}
if (lightUsed != 0) {
CheckLight(i);
haveLight = 1;
}
}
if (haveLight != 0) {
if (!((BYTE2(__gxVerif->xfRegs[15]) >> 2) & 1) && ((HIWORD(__gxVerif->xfRegs[15]) >> 7) & 3) && __gxVerif->verifyLevel >= __gxvWarnLev[0x59]) {
__GX_WARNF(0x59, "COLOR1", "COLOR1");
}
if (!((BYTE2(__gxVerif->xfRegs[17]) >> 2) & 1) && ((HIWORD(__gxVerif->xfRegs[17]) >> 7) & 3) && __gxVerif->verifyLevel >= __gxvWarnLev[0x59]) {
__GX_WARNF(0x59, "ALPHA1", "ALPHA1");
}
if (((HIWORD(__gxVerif->xfRegs[15]) >> 7) & 3)
|| ((u8)((BYTE2(__gxVerif->xfRegs[15]) >> 1) & 1) && ((u32)((BYTE2(__gxVerif->xfRegs[15]) >> 2) & 1) == 1))
|| ((HIWORD(__gxVerif->xfRegs[17]) >> 7) & 3)
|| ((u8)((BYTE2(__gxVerif->xfRegs[17]) >> 1) & 1) && ((u32)((BYTE2(__gxVerif->xfRegs[17]) >> 2) & 1) == 1))) {
if ((__GXVertexPacketHas(GX_VA_NRM) == 0) && (__GXVertexPacketHas(GX_VA_NBT) == 0) && __gxVerif->verifyLevel >= __gxvWarnLev[0x5A]) {
__GX_WARNF(0x5A, 1);
}
if (__GXVertexPacketHas(GX_VA_PNMTXIDX) == 0) {
if ((u32)(BYTE3(__gxVerif->xfRegs[24]) & 0x3F) > 30 && __gxVerif->verifyLevel >= __gxvWarnLev[0x5B]) {
__GX_WARNF(0x5B, 1, (u8)(BYTE3(__gxVerif->xfRegs[24]) & 0x3F));
}
sprintf(Preamble, __gxvWarnings[0x6D], 1, (u8)(BYTE3(__gxVerif->xfRegs[24]) & 0x3F));
CheckRAM(1, ((BYTE3(__gxVerif->xfRegs[24]) & 0x3F) * 3) + 0x400, 9, 0x6D, Preamble);
}
}
}
}
}
}
static void CheckViewport(void) {
f32 vl;
f32 vr;
f32 vt;
f32 vb;
vl = (*(f32*)&__gxVerif->xfRegs[29] - *(f32*)&__gxVerif->xfRegs[26]) - 342.0f;
vt = (*(f32*)&__gxVerif->xfRegs[30] + *(f32*)&__gxVerif->xfRegs[27]) - 342.0f;
vr = (*(f32*)&__gxVerif->xfRegs[29] + *(f32*)&__gxVerif->xfRegs[26]) - 342.0f;
vb = (*(f32*)&__gxVerif->xfRegs[30] - *(f32*)&__gxVerif->xfRegs[27]) - 342.0f;
if ((vt < -0.5f || vt > 528.0f) && __gxVerif->verifyLevel >= __gxvWarnLev[0x55]) {
__GX_WARNF(0x55, vt);
}
if ((vb < 0.0f || vb > 528.0f) && __gxVerif->verifyLevel >= __gxvWarnLev[0x56]) {
__GX_WARNF(0x56, vb);
}
if ((vl < 0.0f || vl > 640.0f) && __gxVerif->verifyLevel >= __gxvWarnLev[0x57]) {
__GX_WARNF(0x57, vl);
}
if ((vr < 0.0f || vr > 640.0f) && __gxVerif->verifyLevel >= __gxvWarnLev[0x58]) {
__GX_WARNF(0x58, vr);
}
}
static void ComputeSignExponentMantissa(f32 floatVal, u32* sign, u32* exponent, u32* mantissa) {
u32 intVal = *(u32*)&floatVal;
*sign = (intVal >> 31) & 1;
*exponent = (intVal >> 23) & 0xFF;
*mantissa = intVal & 0x7FFFFF;
}
static void CheckFloatingPointValue(u8 dirtyBit, u32 value, char* label) {
u32 sign;
u32 exponent;
u32 mantissa;
f32 valuef;
&valuef;
if ((dirtyBit == 0)) {
return;
}
valuef = *(f32 *)&value;
ComputeSignExponentMantissa(valuef, &sign, &exponent, &mantissa);
if (exponent == 0 && mantissa == 0) {
return;
}
if (exponent == 0xFF) {
if (__gxVerif->verifyLevel >= 2) {
if (mantissa == 0) {
if (sign != 0) {
if (__gxVerif->verifyLevel >= __gxvWarnLev[0x5C]) {
__GX_WARNF(0x5C, label, "-", *(u32 *)&valuef);
}
} else {
if (__gxVerif->verifyLevel >= __gxvWarnLev[0x5C]) {
__GX_WARNF(0x5C, label, "+", *(u32 *)&valuef);
}
}
} else {
if (__gxVerif->verifyLevel >= __gxvWarnLev[0x5D]) {
__GX_WARNF(0x5D, label, *(u32 *)&valuef);
}
}
}
} else if (__gxVerif->verifyLevel >= 3) {
if (exponent < 0x6BU) {
if (__gxVerif->verifyLevel >= __gxvWarnLev[0x5E]) {
__GX_WARNF(0x5E, label, valuef, *(u32 *)&valuef);
}
} else if (exponent > 0x96U) {
if (__gxVerif->verifyLevel >= __gxvWarnLev[0x5F]) {
__GX_WARNF(0x5F, label, valuef, *(u32 *)&valuef);
}
}
}
}
static void CheckMatrixRAMRanges(void) {
u32 i;
char label[256];
for (i = 0; i <= 255; i++) {
sprintf(label, "Geometry/Texture Matrix ram address 0x%04x", i);
CheckFloatingPointValue(__gxVerif->xfMtxDirty[i], __gxVerif->xfMtx[i], label);
}
}
static void CheckNormalRAMRanges(void) {
u32 i;
char label[256];
for (i = 1024; i <= 1119; i++) {
sprintf(label, "Normal Matrix ram address 0x%04x", i);
CheckFloatingPointValue(__gxVerif->xfNrmDirty[i - 1024], __gxVerif->xfNrm[i - 1024], label);
}
}
static void CheckDMatrixRAMRanges(void) {
u32 i;
char label[256];
for (i = 1280; i <= 1535; i++) {
sprintf(label, "Dual Texture Matrix ram address 0x%04x", i);
CheckFloatingPointValue(__gxVerif->xfDMtxDirty[i - 1280], __gxVerif->xfDMtx[i - 1280], label);
}
}
static void CheckLightRAMRanges(void) {
u32 lightSource;
u32 lightRAMOffset;
char label[256];
u32 i;
for (lightSource = 0; lightSource < 8; lightSource++) {
for (i = 1; i < 13; i++) {
lightRAMOffset = ((lightSource << 4) + i) + 0x603;
sprintf(label, "Light %d %s (address 0x%04x)", lightSource, lightRegisterNames[i], lightRAMOffset);
CheckFloatingPointValue(__gxVerif->xfLightDirty[lightRAMOffset - 0x600], __gxVerif->xfLight[(s32) (lightRAMOffset - 0x600)], label);
}
}
i; lightSource; // needed to match
}
static void CheckControlRAMRanges(void) {
CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x1A], __gxVerif->xfRegs[0x1A], "Viewport Scale X");
CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x1B], __gxVerif->xfRegs[0x1B], "Viewport Scale Y");
CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x1C], __gxVerif->xfRegs[0x1C], "Viewport Scale Z");
CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x1D], __gxVerif->xfRegs[0x1D], "Viewport Offset X");
CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x1E], __gxVerif->xfRegs[0x1E], "Viewport Offset Y");
CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x1F], __gxVerif->xfRegs[0x1F], "Viewport Offset Z");
CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x20], __gxVerif->xfRegs[0x20], "Projection Matrix A Value");
CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x21], __gxVerif->xfRegs[0x21], "Projection Matrix B Value");
CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x22], __gxVerif->xfRegs[0x22], "Projection Matrix C Value");
CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x23], __gxVerif->xfRegs[0x23], "Projection Matrix D Value");
CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x24], __gxVerif->xfRegs[0x24], "Projection Matrix E Value");
CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x25], __gxVerif->xfRegs[0x25], "Projection Matrix F Value");
}
static void CheckFloatingPointRanges(void) {
CheckMatrixRAMRanges();
CheckNormalRAMRanges();
CheckDMatrixRAMRanges();
CheckLightRAMRanges();
CheckControlRAMRanges();
}
static void CheckMatrixIndices(void) {
if (!__GXVertexPacketHas(GX_VA_PNMTXIDX)
|| !__GXVertexPacketHas(GX_VA_TEX0MTXIDX)
|| !__GXVertexPacketHas(GX_VA_TEX1MTXIDX)
|| !__GXVertexPacketHas(GX_VA_TEX2MTXIDX)
|| !__GXVertexPacketHas(GX_VA_TEX3MTXIDX))
{
CheckDirty(0x1018U, "Geometry & Textures [0-3] transform matrix indices");
}
if (__gxVerif->verifyLevel >= 1 && !__GXVertexPacketHas(GX_VA_PNMTXIDX)) {
CheckRAM(0U, (__gxVerif->xfRegs[24] * 4) & 0xFC, 0xCU, 0x6E, __gxvWarnings[0x6E]);
}
if ((!__GXVertexPacketHas(GX_VA_TEX4MTXIDX)
|| !__GXVertexPacketHas(GX_VA_TEX5MTXIDX)
|| !__GXVertexPacketHas(GX_VA_TEX6MTXIDX)
|| !__GXVertexPacketHas(GX_VA_TEX7MTXIDX))
&& numRegularTextures > 4
&& __gxVerif->verifyLevel >= 1
&& !__gxVerif->xfRegsDirty[0x19] && __gxVerif->verifyLevel >= __gxvWarnLev[0x60]) {
__GX_WARNF(0x60, numRegularTextures, 0x1019U);
}
}
static void CheckErrors(void) {
u32 i;
char registerName[80];
CheckDirty(0x103FU, "Number of XF output textures");
CheckDirty(0x1009U, "Number of XF output colors");
CheckDirty(0x1008U, "InVertexSpec");
CheckDirty(0x101AU, "Viewport ScaleX");
CheckDirty(0x101BU, "Viewport ScaleY");
CheckDirty(0x101CU, "Viewport ScaleZ");
CheckDirty(0x101DU, "Viewport OffsetX");
CheckDirty(0x101EU, "Viewport OffsetY");
CheckDirty(0x101FU, "Viewport OffsetZ");
CheckDirty(0x1020U, "Projection matrix 'A' value");
CheckDirty(0x1021U, "Projection matrix 'B' value");
CheckDirty(0x1022U, "Projection matrix 'C' value");
CheckDirty(0x1023U, "Projection matrix 'D' value");
CheckDirty(0x1024U, "Projection matrix 'E' value");
CheckDirty(0x1025U, "Projection matrix 'F' value");
CheckDirty(0x1026U, "Projection matrix orthographic/perspective select");
CheckMatrixIndices();
if (__gxVerif->verifyLevel >= 1) {
if (!(u32)(BYTE3(__gxVerif->xfRegs[9]) & 3) && !__gxVerif->xfRegs[0x3F] && __gxVerif->verifyLevel >= __gxvWarnLev[0x38]) {
__GX_WARN(0x38);
}
CheckCTGColors();
if (__gxVerif->xfRegs[0x3F] > 8 && __gxVerif->verifyLevel >= __gxvWarnLev[0x64]) {
__GX_WARNF(0x64, __gxVerif->xfRegs[0x3F], 8);
}
if (numRegularTextures > 8 && __gxVerif->verifyLevel >= __gxvWarnLev[0x65]) {
__GX_WARNF(0x65, numRegularTextures, 8);
}
if (numBumpmapTextures > 3 && __gxVerif->verifyLevel >= __gxvWarnLev[0x66]) {
__GX_WARNF(0x66, numBumpmapTextures, 3);
}
if (numColorTextures > 2 && __gxVerif->verifyLevel >= __gxvWarnLev[0x67]) {
__GX_WARNF(0x67, numColorTextures, 2);
}
if (numColor0Textures > 1 && __gxVerif->verifyLevel >= __gxvWarnLev[0x69]) {
__GX_WARNF(0x69, 0);
}
if (numColor1Textures > 1 && __gxVerif->verifyLevel >= __gxvWarnLev[0x69]) {
__GX_WARNF(0x69, 1);
}
CheckVertexPacket();
for (i = 0; i < __gxVerif->xfRegs[0x3F]; i++) {
sprintf(registerName, "Texture %d settings", i);
CheckDirty(i + 0x1040, registerName);
}
CheckSourceRows();
CheckTextureOrder();
if (numBumpmapTextures != 0) {
CheckBumpmapTextures();
}
CheckTextureTransformMatrices();
if (numColorTextures != 0 && (u32)((BYTE3(__gxVerif->xfRegs[numRegularTextures + numBumpmapTextures + 64]) >> 4) & 7) != 2 && __gxVerif->verifyLevel >= __gxvWarnLev[0x68]) {
__GX_WARN(0x68U);
}
CheckColor0();
CheckColor1();
CheckViewport();
}
}
static void CheckWarnings(void) {
if (__gxVerif->verifyLevel >= 1) {
CheckInputForms();
}
CheckClean(0x1000U, "Internal error register");
CheckClean(0x1001U, "Internal diagnostic register");
CheckClean(0x1002U, "Internal state register 0");
CheckClean(0x1003U, "Internal state register 1");
CheckClean(0x1004U, "Power savings register");
if (__gxVerif->verifyLevel >= 2) {
CheckFloatingPointRanges();
}
}
static void DumpXFRegisters(void) {
static u8 firstTime = 1;
}
void __GXVerifyXF(void) {
InitializeXFVerifyData();
CheckErrors();
CheckWarnings();
DumpCount++;
}
#endif

View File

@ -0,0 +1,372 @@
#if DEBUG
#include <revolution/gx.h>
#include "__gx.h"
static __GXVerifyData __gxVerifData;
struct __GXVerifyData* __gxVerif = &__gxVerifData;
char* __gxvWarnings[126] = {
"Invalid Vertex Format. Normal count must be set to %s.",
"Texture size %ld not initialized.",
"Left edge of scissor rectangle is less than %d.",
"Top edge of scissor rectangle is less than %d.",
"Right edge of scissor rectangle is greater than %d in %s mode.",
"Bottom edge of scissor rectangle is greater than %d in %s mode.",
"%s value for subsample %d in pixel %ld is not 6 when single-sampling.",
"Indirect texture command for stage %ld is not set.",
"Invalid indirect texture request in TEV stage %ld.",
"Indirect matrix %ld requested in stage %d not set.",
"Requested indirect textures never initialized.",
"Indirect texture coordinate scales %d and %d not set.",
"Invalid texture coordinate specified for indirect stage %d.",
"Indirect texture feedback accumulation is on in TEV stage 0.",
"Indirect bump alpha is enabled in TEV stage 0.",
"Indirect vs. direct mask byte never set.",
"Texture reference never written for TEV stage %ld.",
"Invalid texture coordinate specified for TEV stage %ld.",
"Texture %ld is used as both indirect and direct.",
"Texture %ld not configured.",
"Base pointer for cached texture %ld is not specified.",
"TLUT for indexed texture %ld was never set up.",
"%s is not a power of 2 for mipmapped texture %ld.",
"%s is not GX_CLAMP for non-power-of-2 width in texture %ld.",
"Minification filter for texture %ld is not compatible with color index texture format.",
"Minimum LOD is greater than maximum LOD in texture %ld.",
"Maximum LOD is greater than image's maximum LOD for texture %ld.",
"LOD bias clamp shold be used with edge LOD for texture %ld.",
"Texture %ld does not meet requirements for anisotropic mipmapping.",
"Filters are not linear for field prediction in texture %ld.",
"Incomplete rounding mode configuration for texture %ld.",
"Rounding color indexed texture %ld.",
"Environment for TEV stage %ld not fully set up.",
"Invalid color channel selected in TEV stage %ld.",
"Argument %s selects null texture in TEV color stage %ld.",
"Argument %s selects null texture in TEV alpha stage %ld.",
"Color arg %s in TEV stage %ld accesses register %s, which may be dirty.",
"Alpha arg %s in TEV stage %ld accesses register %s, which may be dirty.",
"Color arg %s in TEV stage %ld accesses register %s, which was last unclamped. Possible wrap-around effect.",
"Alpha arg %s in TEV stage %ld accesses register %s, which was last unclamped. Possible wrap-around effect.",
"Z texturing enabled, but no Z offset specified.",
"Z texturing enabled, but no texture specified for final TEV stage.",
"Final TEV stage doesn't write color to register GX_TEVPREV.",
"Final TEV stage doesn't write alpha to register GX_TEVPREV.",
"Final TEV color stage has no clamping. Possible color wrap-around effect.",
"Final TEV alpha stage has no clamping. Possible alpha wrap-around effect.",
"Z buffering is before texture, but alpha compare operation is active.",
"PE blend and logicop are both on.",
"Selected pixel format does not support dithering.",
"Multisample enabled but pixel type is not RGB565.",
"Pixel type is RGB565 but multisample is not enabled.",
"Multisample locations for pixel %ld are not ordered correctly for antialias filter.",
"Invalid texgen_type %d for texture %d.",
"Register address 0x%04x uninitialized (%s).",
"Register address 0x%04x modified (%s), probably should not be.",
"Invalid combination of %d output color channels and %d color texgen textures.",
"Number of color channels and number of texgens are both zero.",
"Vertex packet does not contain position values.",
"Mismatched argument setting in vertex attribute. %s should be used with %s.",
"GXSetVtxAttrFmt: Normals only support signed types.",
"GXSetVtxAttrFmt: Number of fractional bits is fixed for normals. %s uses %d. Your setting will be ignored.",
"GXSetVtxAttrFmt: GX_F32 type doesn't refer the frac argument. Your setting will be ignored.",
"GXSetVtxAttrFmt: Colors don't refer the frac argument. Your setting will be ignored.",
"Invalid value (%d) for INVERTEXSPEC_REG.host_colors.",
"XF is not expecting host normals but cp is sending them.",
"XF is not expecting host normals, binormals and tangents but cp is sending them.",
"XF is expecting host normals but cp is not sending them.",
"XF is expecting host normals but cp is sending normals, binormals, and tangents.",
"XF is expecting host normals, binormals and tangents but cp is only sending normals.",
"This vertex format (Position + Matrix Indices only) is not supported.",
"VCD for GX_VA_CLR1 is activated though GX_VA_CLR0 is set to GX_NONE. GX_VA_CLR0 should be used first.",
"VCDs for input texture coordinates are not used sequentially from smaller IDs.",
"GX_TEXCOORD%d specifies source row of position, but this is not getting sent.",
"GX_TEXCOORD%d specifies source row of normal, but this is not getting sent.",
"GX_TEXCOORD%d specifies source row of color0, but color0 is not getting sent.",
"GX_TEXCOORD%d specifies source row of color1, but color1 is not getting sent.",
"GX_TEXCOORD%d specifies source row of binormal or tangent, but this is not getting sent.",
"GX_TEXCOORD%d specifies source row of input texture coordinate %d, but this is not getting sent.",
"GX_TEXCOORD%d is specifying an invalid source row of %d.",
"TexCoordGen types are out of order. GX_TG_MTX2x4/3x4 should come first (if any), followed by GX_TG_BUMP (if any), then GX_TG_SRTG (if any).",
"Bumpmap texgen is defined, which requires that binormals and tangents be transformed by a normal matrix, but current matrix index is set to an invalid value (%d) for normal transform.",
"GX_TEXCOORD%d (texgen type bumpmap) is referencing texture %d as a source texture, which is not of texgen type regular.",
"GX_TEXCOORD%d (texgen type bumpmap) using light source %d, but light's %c position is not defined.",
"GX_TEXCOORD%d is defined as texgen type bumpmap, but binormals and tangents are not getting sent.",
"Invalid regular texture number (%d)",
"Top edge of viewport (%f) is out of recommended range. It may cause incorrect clipping.",
"Bottom edge of viewport (%f) is out of recommended range. It may cause incorrect clipping.",
"Left edge of viewport (%f) is out of recommended range. It may cause incorrect clipping.",
"Right edge of viewport (%f) is out of recommended range. It may cause incorrect clipping.",
"Channel %s uses specular function (GX_AF_SPEC), but diffuse function is not GX_DF_NONE.",
"Channel %d performs lighting which requires a normal, but this is not getting sent.",
"Channel %d performs lighting which requires the normal to be transformed by a normal matrix, but current matrix index is (%d), which may be invalid.",
"%s has a value of %sinfinity (%08x), which is probably not intended.",
"%s has a value of NaN (%08x), which is probably not intended.",
"%s has a value of (%f 0x%08x), which might be unintentionally small.",
"%s has a value of (%f 0x%08x), which might be unintentionally large.",
"%d regular textures active, but MatrixIndex1 register (0x%04x) uninitialized.",
"gen_mode register not initialized.",
"Number of XF output textures does not match what downstream units are expecting.",
"Number of XF output colors does not match what downstream units are expecting.",
"Number of all texgens (%d) > max allowed %d.",
"Number of regular(2x4/3x4) type texgens (%d) > max allowed %d.",
"Number of bumpmap type texgens (%d) > max allowed %d.",
"Number of color texgens (%d) > max allowed %d.",
"First color texgen is not referencing COLOR0.",
"Color texgen from COLOR%d is used more than once.",
"Bumpmap texgen is defined, which requires the normal matrix values pointed by current matrix index (%d) to be loaded, however it may not be loaded yet.",
"GX_TEXCOORD%d requires the matrix values pointed by current texture matrix index %d (%d), however it may not be loaded yet.",
"GX_LIGHT%d is being referenced, however it may not be loaded yet.",
"Channel %d performs lighting which requires the normal matrix values pointed to by the current matrix index (%d), however these values may not be loaded yet.",
"Position matrix values pointed to by the current matrix index must be loaded, however they may not be loaded yet.",
"Address 0x%04x is uninitialized.",
"Register (0x%04x) (%s) is not initialized.",
"Display list contains invalid command.",
"Nested display list.",
"GXGetCPUFifo/GXGetGPFifo: GP FIFO read pointer is not idle. Value may be unstable.",
"XF is not expecting host colors but cp is sending some.",
"XF is expecting a host color but cp is not sending one.",
"XF is expecting a single host color but cp is sending two.",
"XF is expecting two host colors but cp is not sending first color.",
"XF is expecting two host colors but cp is not sending second color.",
"Invalid number of output colors, %d.",
"Regular texture %d specifying a source row of %d which only has 2 elements, but an input form of ABC1.",
"Output XF colors or color textures enabled, but register address 0x%04x uninitialized (%s).",
"Output XF colors or color textures enabled, COLOR%dCNTRL_REG.material_src == REGISTER, but Material %d register (0x%04x) is not initialized.",
"Output XF colors or color textures enabled, COLOR%dCNTRL_REG.ambient_src == REGISTER, but Ambient %d register (0x%04x) is not initialized."
};
GXWarningLevel __gxvWarnLev[126] = {
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
4,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
4,
4,
GX_WARN_SEVERE,
GX_WARN_ALL,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
4,
4,
4,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_ALL,
GX_WARN_ALL,
4,
GX_WARN_SEVERE,
GX_WARN_MEDIUM,
GX_WARN_MEDIUM,
GX_WARN_ALL,
GX_WARN_ALL,
GX_WARN_MEDIUM,
4,
4,
4,
4,
GX_WARN_ALL,
4,
4,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_ALL,
GX_WARN_ALL,
GX_WARN_ALL,
4,
4,
4,
4,
4,
4,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
4,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
4,
GX_WARN_MEDIUM,
GX_WARN_MEDIUM,
GX_WARN_MEDIUM,
GX_WARN_MEDIUM,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_MEDIUM,
GX_WARN_MEDIUM,
GX_WARN_MEDIUM,
GX_WARN_ALL,
GX_WARN_ALL,
GX_WARN_SEVERE,
4,
4,
4,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_MEDIUM,
GX_WARN_MEDIUM,
GX_WARN_MEDIUM,
GX_WARN_MEDIUM,
GX_WARN_MEDIUM,
GX_WARN_MEDIUM,
GX_WARN_MEDIUM,
GX_WARN_SEVERE,
GX_WARN_SEVERE,
GX_WARN_MEDIUM,
4,
4,
4,
4,
4,
4,
4,
4,
4,
4,
};
char __gxvDummyStr[256];
static void __GXVerifyGlobal(void) {}
static void __GXVerifyCP(GXVtxFmt fmt) {
u32 nrmCnt = GET_REG_FIELD(__GXData->vatA[fmt], 1, 9);
if (__gxVerif->verifyLevel >= GX_WARN_SEVERE) {
if (__GXData->hasNrms && nrmCnt != 0) {
if (__gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_INVALID_VTX_FMT]) {
__GX_WARNF(GXWARN_INVALID_VTX_FMT, "GX_NRM_XYZ");
}
}
else if (__GXData->hasBiNrms && nrmCnt != 1) {
if (__gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_INVALID_VTX_FMT]) {
__GX_WARNF(GXWARN_INVALID_VTX_FMT, "GX_NRM_NBT or GX_NRM_NBT3");
}
}
}
}
void __GXVerifyState(GXVtxFmt vtxfmt) {
if (__gxVerif->verifyLevel != GX_WARN_NONE) {
__GXVerifyGlobal();
__GXVerifyCP(vtxfmt);
__GXVerifyXF();
__GXVerifySU();
__GXVerifyBUMP();
__GXVerifyTEX();
__GXVerifyTEV();
__GXVerifyPE();
}
}
void __GXVerifyVATImm(GXAttr attr, GXCompCnt cnt, GXCompType type, u8 frac) {
if (__gxVerif->verifyLevel != GX_WARN_NONE) {
if (attr == GX_VA_CLR0 || attr == GX_VA_CLR1) {
switch (type) {
case GX_RGB565:
case GX_RGB8:
case GX_RGBX8:
if (cnt != GX_CLR_RGB && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_VAT_MISMATCH]) {
__GX_WARNF(GXWARN_VAT_MISMATCH, "RGB format type", "GX_CLR_RGB");
}
break;
case GX_RGBA4:
case GX_RGBA6:
case GX_RGBA8:
if (cnt != GX_CLR_RGBA && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_VAT_MISMATCH]) {
__GX_WARNF(GXWARN_VAT_MISMATCH, "RGBA format type", "GX_CLR_RGBA");
}
break;
}
}
if (frac != 0) {
if (attr == GX_VA_CLR0 || attr == GX_VA_CLR1) {
if (__gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_VAT_CLR_FRAC]) {
__GX_WARN(GXWARN_VAT_CLR_FRAC);
}
} else if (type == GX_F32) {
if (__gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_VAT_F32_FRAC]) {
__GX_WARN(GXWARN_VAT_F32_FRAC);
}
}
}
if (attr == GX_VA_NRM || attr == GX_VA_NBT) {
switch (type) {
case GX_S8:
if (frac != 6 && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_VAT_NRM_FRAC]) {
__GX_WARNF(GXWARN_VAT_NRM_FRAC, "GX_S8", 6);
}
break;
case GX_S16:
if (frac != 14 && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_VAT_NRM_FRAC]) {
__GX_WARNF(GXWARN_VAT_NRM_FRAC, "GX_S16", 14);
}
break;
case GX_F32:
break;
default:
if (__gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_VAT_NRM_TYPE]) {
__GX_WARN(GXWARN_VAT_NRM_TYPE);
}
break;
}
}
}
}
void GXSetVerifyLevel(GXWarningLevel level) {
__gxVerif->verifyLevel = level;
}
GXVerifyCallback GXSetVerifyCallback(GXVerifyCallback cb) {
GXVerifyCallback old_cb = __gxVerif->cb;
__gxVerif->cb = cb;
return old_cb;
}
#endif // DEBUG

View File

@ -0,0 +1,86 @@
#if DEBUG
#include <revolution/gx.h>
#include "__gx.h"
#define FUNC_1PARAM(name, T) \
void name##1##T(T x) { GXWGFifo.T = x; }
#define FUNC_2PARAM(name, T) \
void name##2##T(T x, T y) { GXWGFifo.T = x; GXWGFifo.T = y; }
#define FUNC_3PARAM(name, T) \
void name##3##T(T x, T y, T z) { GXWGFifo.T = x; GXWGFifo.T = y; GXWGFifo.T = z; }
#define FUNC_4PARAM(name, T) \
void name##4##T(T x, T y, T z, T w) { GXWGFifo.T = x; GXWGFifo.T = y; GXWGFifo.T = z; GXWGFifo.T = w; }
#define FUNC_INDEX8(name) \
void name##1x8(u8 x) { GXWGFifo.u8 = x; }
#define FUNC_INDEX16(name) \
void name##1x16(u16 x) { GXWGFifo.u16 = x; }
// GXCmd
FUNC_1PARAM(GXCmd, u8)
FUNC_1PARAM(GXCmd, u16)
FUNC_1PARAM(GXCmd, u32)
// GXParam
FUNC_1PARAM(GXParam, u8)
FUNC_1PARAM(GXParam, u16)
FUNC_1PARAM(GXParam, u32)
FUNC_1PARAM(GXParam, s8)
FUNC_1PARAM(GXParam, s16)
FUNC_1PARAM(GXParam, s32)
FUNC_1PARAM(GXParam, f32)
FUNC_3PARAM(GXParam, f32)
FUNC_4PARAM(GXParam, f32)
// GXPosition
FUNC_3PARAM(GXPosition, f32)
FUNC_3PARAM(GXPosition, u8)
FUNC_3PARAM(GXPosition, s8)
FUNC_3PARAM(GXPosition, u16)
FUNC_3PARAM(GXPosition, s16)
FUNC_2PARAM(GXPosition, f32)
FUNC_2PARAM(GXPosition, u8)
FUNC_2PARAM(GXPosition, s8)
FUNC_2PARAM(GXPosition, u16)
FUNC_2PARAM(GXPosition, s16)
FUNC_INDEX16(GXPosition)
FUNC_INDEX8(GXPosition)
// GXNormal
FUNC_3PARAM(GXNormal, f32)
FUNC_3PARAM(GXNormal, s16)
FUNC_3PARAM(GXNormal, s8)
FUNC_INDEX16(GXNormal)
FUNC_INDEX8(GXNormal)
// GXColor
FUNC_4PARAM(GXColor, u8)
FUNC_1PARAM(GXColor, u32)
FUNC_3PARAM(GXColor, u8)
FUNC_1PARAM(GXColor, u16)
FUNC_INDEX16(GXColor)
FUNC_INDEX8(GXColor)
// GXTexCoord
FUNC_2PARAM(GXTexCoord, f32)
FUNC_2PARAM(GXTexCoord, s16)
FUNC_2PARAM(GXTexCoord, u16)
FUNC_2PARAM(GXTexCoord, s8)
FUNC_2PARAM(GXTexCoord, u8)
FUNC_1PARAM(GXTexCoord, f32)
FUNC_1PARAM(GXTexCoord, s16)
FUNC_1PARAM(GXTexCoord, u16)
FUNC_1PARAM(GXTexCoord, s8)
FUNC_1PARAM(GXTexCoord, u8)
FUNC_INDEX16(GXTexCoord)
FUNC_INDEX8(GXTexCoord)
// GXMatrixIndex
FUNC_1PARAM(GXMatrixIndex, u8)
#endif // DEBUG

573
src/revolution/gx/__gx.h Normal file
View File

@ -0,0 +1,573 @@
#ifndef _REVOLUTION_GX_INTERNAL_H_
#define _REVOLUTION_GX_INTERNAL_H_
#include <revolution/gx.h>
#include <revolution/private/GXRegs.h>
#include "global.h" // IWYU pragma: export
#ifdef __cplusplus
extern "C" {
#endif
#define PHY_ADDR_MASK ~((~0x3FFF) << 16)
#define GX_PHY_ADDR(a) ((u32)a & PHY_ADDR_MASK)
// REG VERIF
#if DEBUG
#define VERIF_XF_REG(addr, value) \
do { \
s32 regAddr = (addr - 0x1000); \
if (regAddr >= 0 && regAddr < 0x50) { \
__gxVerif->xfRegs[regAddr] = (value); \
__gxVerif->xfRegsDirty[regAddr] = 1; \
} \
} while (0)
#define VERIF_XF_REG_alt(addr, value) \
do { \
s32 xfAddr = (addr); \
if (xfAddr >= 0 && xfAddr < 0x50) { \
__gxVerif->xfRegs[xfAddr] = (value); \
__gxVerif->xfRegsDirty[xfAddr] = 1; \
} \
} while (0)
#define VERIF_RAS_REG(value) (__gxVerif->rasRegs[((value) & 0xFF000000) >> 24] = value)
#define VERIF_MTXLIGHT(addr, data) \
do { \
s32 xfAddr; \
if (addr < 0x400U) { \
__gxVerif->xfMtx[addr] = data; \
__gxVerif->xfMtxDirty[addr] = 1; \
} else if (addr < 0x500U) { \
xfAddr = addr - 0x400; \
__gxVerif->xfNrm[xfAddr] = data; \
__gxVerif->xfNrmDirty[xfAddr] = 1; \
} else if (addr < 0x600U) { \
xfAddr = addr - 0x500; \
__gxVerif->xfDMtx[xfAddr] = data; \
__gxVerif->xfDMtxDirty[xfAddr] = 1; \
} else if (addr < 0x680U) { \
xfAddr = addr - 0x600; \
__gxVerif->xfLight[xfAddr] = data; \
__gxVerif->xfLightDirty[xfAddr] = 1; \
} else { \
xfAddr = addr - 0x1000; \
if ((xfAddr >= 0) && (xfAddr < 0x50)) { \
__gxVerif->xfRegs[xfAddr] = data; \
__gxVerif->xfRegsDirty[xfAddr] = 1; \
} \
} \
} while (0)
#else
#define VERIF_XF_REG(addr, value) ((void)0)
#define VERIF_XF_REG_alt(addr, value) ((void)0)
#define VERIF_RAS_REG(value) ((void)0)
#endif
// WRITE REG
#if DEBUG
#define GX_WRITE_XF_REG_2(addr, value) \
do { \
u32 xfData = (value); &xfData; \
GX_WRITE_U32(value); \
VERIF_XF_REG_alt(addr, xfData); \
} while (0)
#define GX_WRITE_XF_REG_F(addr, value) \
do { \
f32 xfData = (value); \
GX_WRITE_F32(value); \
VERIF_XF_REG_alt(addr, *(u32 *)&xfData); \
} while (0)
#else
#define GX_WRITE_XF_REG_2(addr, value) \
do { \
GX_WRITE_U32(value); \
} while (0)
#define GX_WRITE_XF_REG_F(addr, value) \
do { \
GX_WRITE_F32(value); \
} while (0)
#endif
#define GX_WRITE_RAS_REG(value) \
do { \
GX_WRITE_U8(0x61); \
GX_WRITE_U32(value); \
VERIF_RAS_REG(value); \
} while (0)
#if DEBUG
#define GX_WRITE_SOME_REG2(a, b, c, addr) \
do { \
long regAddr; \
GX_WRITE_U8(a); \
GX_WRITE_U8(b); \
GX_WRITE_U32(c); \
regAddr = addr; \
if (regAddr >= 0 && regAddr < 4) { \
__GXData->indexBase[regAddr] = c; \
} \
} while (0)
#else
#define GX_WRITE_SOME_REG2(a, b, c, addr) \
do { \
GX_WRITE_U8(a); \
GX_WRITE_U8(b); \
GX_WRITE_U32(c); \
} while (0)
#endif
#if DEBUG
#define GX_WRITE_SOME_REG3(a, b, c, addr) \
do { \
long regAddr; \
GX_WRITE_U8(a); \
GX_WRITE_U8(b); \
GX_WRITE_U32(c); \
regAddr = addr; \
if (regAddr >= 0 && regAddr < 4) { \
__GXData->indexStride[regAddr] = c; \
} \
} while (0)
#else
#define GX_WRITE_SOME_REG3(a, b, c, addr) \
do { \
GX_WRITE_U8(a); \
GX_WRITE_U8(b); \
GX_WRITE_U32(c); \
} while (0)
#endif
#define GX_WRITE_SOME_REG4(a, b, c, addr) \
do { \
long regAddr; \
GX_WRITE_U8(a); \
GX_WRITE_U8(b); \
GX_WRITE_U32(c); \
regAddr = addr; \
} while (0)
// REG MACROS
#define GET_REG_FIELD(reg, size, shift) ((((unsigned long)(reg)) & (((1 << (size)) - 1) << (shift))) >> (shift))
// TODO: reconcile reg macro differences
// this one is needed to match non GX libs
#define OLD_SET_REG_FIELD(line, reg, size, shift, val) \
do { \
ASSERTMSGLINE(line, ((u32)(val) & ~((1 << (size)) - 1)) == 0, "GX Internal: Register field out of range"); \
(reg) = ((u32)(reg) & ~(((1 << (size)) - 1) << (shift))) | ((u32)(val) << (shift)); \
} while (0)
// above doesn't seem to work with GX, only can get it to work with this
#define SET_REG_FIELD(line, reg, size, shift, val) \
do { \
ASSERTMSGLINE(line, ((u32)(val) & ~((1 << (size)) - 1)) == 0, "GX Internal: Register field out of range"); \
(reg) = ((u32)__rlwimi((u32)(reg), (val), (shift), 32 - (shift) - (size), 31 - (shift))); \
} while (0)
#define CHECK_GXBEGIN(line, name) ASSERTMSGLINE(line, !__GXinBegin, "'" name "' is not allowed between GXBegin/GXEnd")
/* GXAttr */
void __GXSetVCD(void);
void __GXSetVAT(void);
/* GXBump */
void __GXUpdateBPMask(void);
void __GXFlushTextureState(void);
/* GXFifo */
// GXFifoObj private data
typedef struct __GXFifoObj {
u8* base;
u8* top;
u32 size;
u32 hiWatermark;
u32 loWatermark;
void* rdPtr;
void* wrPtr;
s32 count;
u8 wrap;
u8 bind_cpu;
u8 bind_gp;
} __GXFifoObj;
void __GXFifoInit(void);
void __GXCleanGPFifo(void);
GXBool __GXIsGPFifoReady(void);
/* GXGeometry */
void __GXSetDirtyState(void);
void __GXSendFlushPrim(void);
void __GXSetGenMode(void);
/* GXInit */
void __GXInitGX();
void __GXInitRevisionBits(void);
typedef struct __GXData_struct {
u16 vNumNot;
u16 bpSentNot;
u16 vNum;
u16 vLim;
u32 cpEnable;
u32 cpStatus;
u32 cpClr;
u32 vcdLo;
u32 vcdHi;
u32 vatA[8];
u32 vatB[8];
u32 vatC[8];
u32 lpSize;
u32 matIdxA;
u32 matIdxB;
u32 indexBase[4];
u32 indexStride[4];
u32 ambColor[2];
u32 matColor[2];
u32 chanCtrl[4];
u32 texGenCtrl[8];
u32 texGenCtrl2[8];
u32 suTs0[8];
u32 suTs1[8];
u32 suScis0;
u32 suScis1;
u32 tref[8];
u32 iref;
u32 bpMask;
u32 IndTexScale0;
u32 IndTexScale1;
u32 tevc[16];
u32 teva[16];
u32 tevKsel[8];
u32 cmode0;
u32 cmode1;
u32 zmode;
u32 peCtrl;
u32 cpDispSrc;
u32 cpDispSize;
u32 cpDispStride;
u32 cpDisp;
u32 cpTexSrc;
u32 cpTexSize;
u32 cpTexStride;
u32 cpTex;
u8 cpTexZ;
u32 genMode;
GXTexRegion TexRegions0[8];
GXTexRegion TexRegions1[8];
GXTexRegion TexRegions2[8];
GXTlutRegion TlutRegions[20];
GXTexRegion* (*texRegionCallback)(GXTexObj*, GXTexMapID);
GXTlutRegion* (*tlutRegionCallback)(u32);
GXAttrType nrmType;
u8 hasNrms;
u8 hasBiNrms;
u32 projType;
f32 projMtx[6];
f32 vpLeft;
f32 vpTop;
f32 vpWd;
f32 vpHt;
f32 vpNearz;
f32 vpFarz;
f32 zOffset;
f32 zScale;
u32 tImage0[8];
u32 tMode0[8];
u32 texmapId[16];
u32 tcsManEnab;
u32 tevTcEnab;
GXPerf0 perf0;
GXPerf1 perf1;
u32 perfSel;
u8 inDispList;
u8 dlSaveContext;
u8 abtWaitPECopy;
u8 dirtyVAT;
u32 dirtyState;
} GXData;
extern GXData* const __GXData;
#if DEBUG
extern GXBool __GXinBegin;
#endif
#define GX_GET_MEM_REG(offset) (*(volatile u16*)((volatile u16*)(__memReg) + (offset)))
#define GX_GET_CP_REG(offset) (*(volatile u16*)((volatile u16*)(__cpReg) + (offset)))
#define GX_GET_PE_REG(offset) (*(volatile u16*)((volatile u16*)(__peReg) + (offset)))
#define GX_GET_PI_REG(offset) (*(volatile u32*)((volatile u32*)(__piReg) + (offset)))
#define GX_SET_MEM_REG(offset, val) (*(volatile u16*)((volatile u16*)(__memReg) + (offset)) = val)
#define GX_SET_CP_REG(offset, val) (*(volatile u16*)((volatile u16*)(__cpReg) + (offset)) = val)
#define GX_SET_PE_REG(offset, val) (*(volatile u16*)((volatile u16*)(__peReg) + (offset)) = val)
#define GX_SET_PI_REG(offset, val) (*(volatile u32*)((volatile u32*)(__piReg) + (offset)) = val)
/* GXMisc */
void __GXBypass(u32 reg);
u16 __GXReadPEReg(u32 reg);
void __GXPEInit(void);
void __GXAbort();
/* GXPerf */
void __GXSetBWDials(u16 cpDial, u16 tcDial, u16 peDial, u16 cpuRdDial, u16 cpuWrDial);
static inline u32 __GXReadCPCounterU32(u32 regAddrL, u32 regAddrH) {
u32 ctrH0;
u32 ctrH1;
u32 ctrL;
ctrH0 = GX_GET_CP_REG(regAddrH);
do {
ctrH1 = ctrH0;
ctrL = GX_GET_CP_REG(regAddrL);
ctrH0 = GX_GET_CP_REG(regAddrH);
} while (ctrH0 != ctrH1);
return (ctrH0 << 0x10) | ctrL;
}
static inline u32 __GXReadMEMCounterU32(u32 regAddrL, u32 regAddrH) {
u32 ctrH0;
u32 ctrH1;
u32 ctrL;
ctrH0 = GX_GET_MEM_REG(regAddrH);
do {
ctrH1 = ctrH0;
ctrL = GX_GET_MEM_REG(regAddrL);
ctrH0 = GX_GET_MEM_REG(regAddrH);
} while (ctrH0 != ctrH1);
return (ctrH0 << 0x10) | ctrL;
}
static inline u32 __GXReadPECounterU32(u32 regAddrL, u32 regAddrH) {
u32 ctrH0;
u32 ctrH1;
u32 ctrL;
ctrH0 = GX_GET_PE_REG(regAddrH);
do {
ctrH1 = ctrH0;
ctrL = GX_GET_PE_REG(regAddrL);
ctrH0 = GX_GET_PE_REG(regAddrH);
} while (ctrH0 != ctrH1);
return (ctrH0 << 0x10) | ctrL;
}
/* GXSave */
void __GXShadowDispList(void* list, u32 nbytes);
void __GXShadowIndexState(u32 idx_reg, u32 reg_data);
void __GXPrintShadowState(void);
/* GXStubs */
void __GXSetRange(f32 nearz, f32 fgSideX);
/* GXTexture */
void __GetImageTileCount(GXTexFmt fmt, u16 wd, u16 ht, u32* rowTiles, u32* colTiles, u32* cmpTiles);
void __GXSetSUTexRegs(void);
void __GXGetSUTexSize(GXTexCoordID coord, u16* width, u16* height);
void __GXSetTmemConfig(u32 config);
/* GXTransform */
void __GXSetMatrixIndex(GXAttr matIdxAttr);
void __GXSetProjection(void);
void __GXSetViewport();
/* GXVerifRAS */
void __GXVerifySU(void);
void __GXVerifyBUMP(void);
void __GXVerifyTEX(void);
void __GXVerifyTEV(void);
void __GXVerifyPE(void);
/* GXVerif */
typedef enum {
GXWARN_INVALID_VTX_FMT = 0,
GXWARN_TEX_SIZE_INIT = 1,
GXWARN_SCISSOR_RECT_LEFT = 2,
GXWARN_SCISSOR_RECT_TOP = 3,
GXWARN_SCISSOR_RECT_RIGHT = 4,
GXWARN_SCISSOR_RECT_BOT = 5,
GXWARN_SAMPLE_VALUE = 6,
GXWARN_BUMP_CMD = 7,
GXWARN_INVALID_INDIRECT = 8,
GXWARN_INDIRECT_MTX = 9,
GXWARN_IND_TEX_NO_INIT = 10,
GXWARN_IND_TEX_NO_SCALE = 11,
GXWARN_IND_TEX_BUMP = 12,
GXWARN_BUMP_ACCUMULATION = 13,
GXWARN_BUMP_ALPHA_EN = 14,
GXWARN_IND_DIR_MASK = 15,
GXWARN_TEV_TEX_REF = 16,
GXWARN_TEV_INV_TEX_COORD = 17,
GXWARN_IND_DIR_BOTH = 18,
GXWARN_TEX_CONFIG = 19,
GXWARN_TEX_BASE = 20,
GXWARN_TLUT_CONFIG = 21,
GXWARN_TEX_POW2 = 22,
GXWARN_TEX_CLAMP = 23,
GXWARN_TEX_MIN_FILT = 24,
GXWARN_MIN_LOD = 25,
GXWARN_MAX_LOD = 26,
GXWARN_DIAG_LOD = 27,
GXWARN_TEX_ANISO = 28,
GXWARN_TEX_FIELD = 29,
GXWARN_TEX_RND_FP = 30,
GXWARN_RND_CLR_INDX = 31,
GXWARN_TEV_ENV = 32,
GXWARN_TEV_INV_CHAN = 33,
GXWARN_TEV_NULL_TEX = 34,
GXWARN_TEV_NULL_TEX_A = 35,
GXWARN_TEV_DIRTY_REG = 36,
GXWARN_TEV_DIRTY_REG_A = 37,
GXWARN_TEV_CLR_CLAMP = 38,
GXWARN_TEV_A_CLAMP = 39,
GXWARN_ZTEX_OFFSET = 40,
GXWARN_ZTEX_INVALID = 41,
GXWARN_TEV_LAST_CLR = 42,
GXWARN_TEV_LAST_A = 43,
GXWARN_TEV_LAST_CLR_WRAP = 44,
GXWARN_TEV_LAST_A_WRAP = 45,
GXWARN_Z_BEFORE_T_A = 46,
GXWARN_BLEND_LOGICOP = 47,
GXWARN_DITHER_MODE = 48,
GXWARN_MULTISAMP0 = 49,
GXWARN_MULTISAMP1 = 50,
GXWARN_SAMP_ORDER = 51,
GXWARN_INVALID_TG_TYPE = 52,
GXWARN_XF_CTRL_UNINIT = 53,
GXWARN_XF_CTRL_INIT = 54,
GXWARN_INV_COLOR_TG_COMB = 55,
GXWARN_XF_NO_CLR_TEX = 56,
GXWARN_VTX_NO_GEOM = 57,
GXWARN_VAT_MISMATCH = 58,
GXWARN_VAT_NRM_TYPE = 59,
GXWARN_VAT_NRM_FRAC = 60,
GXWARN_VAT_F32_FRAC = 61,
GXWARN_VAT_CLR_FRAC = 62,
GXWARN_INV_IVS_CLR = 63,
GXWARN_NRM_XF0_CP1 = 64,
GXWARN_NRM_XF0_CP3 = 65,
GXWARN_NRM_XF1_CP0 = 66,
GXWARN_NRM_XF1_CP3 = 67,
GXWARN_NRM_XF3_CP1 = 68,
GXWARN_VCD_FMT_UNSUP = 69,
GXWARN_VCD_CLR_ORDER = 70,
GXWARN_VCD_TEX_ORDER = 71,
GXWARN_TEX_SRC_NPOS = 72,
GXWARN_TEX_SRC_NNRM = 73,
GXWARN_TEX_SRC_NCLR0 = 74,
GXWARN_TEX_SRC_NCLR1 = 75,
GXWARN_TEX_SRC_NNBT = 76,
GXWARN_TEX_SRC_NTEX = 77,
GXWARN_INV_TEX_SRC = 78,
GXWARN_INV_TG_ORDER = 79,
GXWARN_BM_INV_MTX_NDX = 80,
GXWARN_BM_INV_TEX = 81,
GXWARN_BM_INV_LIT_POS = 82,
GXWARN_BM_NO_NBT = 83,
GXWARN_INV_TEX_NUM = 84,
GXWARN_VIEWPORT_TOP = 85,
GXWARN_VIEWPORT_BOTTOM = 86,
GXWARN_VIEWPORT_LEFT = 87,
GXWARN_VIEWPORT_RIGHT = 88,
GXWARN_CLR_INV_SPEC = 89,
GXWARN_CLR_NO_NRM = 90,
GXWARN_CLR_INV_MTX_NDX = 91,
GXWARN_VAL_INFINITY = 92,
GXWARN_VAL_NAN = 93,
GXWARN_VAL_SMALL = 94,
GXWARN_VAL_LARGE = 95,
GXWARN_MTX1_UNINIT = 96,
GXWARN_GM_UNINIT = 97,
GXWARN_TEX_XFN_SUM = 98,
GXWARN_CLR_XFN_SUM = 99,
GXWARN_INV_NUM_ANY_TEX = 100,
GXWARN_INV_NUM_REG_TEX = 101,
GXWARN_INV_NUM_BM_TEX = 102,
GXWARN_INV_NUM_CLR_TEX = 103,
GXWARN_INV_CLR_TEX = 104,
GXWARN_DUP_CLR_TEX = 105,
GXWARN_BM_INV_MTX_VAL = 106,
GXWARN_TEX_INV_MTX_VAL = 107,
GXWARN_LIT_INV_REG = 108,
GXWARN_CLR_INV_MTX_VAL = 109,
GXWARN_INV_MTX_VAL = 110,
GXWARN_ADDR_UNINIT = 111,
GXWARN_REG_UNINIT = 112,
GXWARN_DL_INV_CMD = 113,
GXWARN_DL_NESTED = 114,
GXWARN_CLR_XF0_CP1 = 115,
GXWARN_CLR_XF1_CP0 = 116,
GXWARN_CLR_XF1_CP2 = 117,
GXWARN_CLR_XF2_CPN1 = 118,
GXWARN_CLR_XF2_CPN2 = 119,
GXWARN_INV_NUM_COLORS = 120,
GXWARN_INV_TG_SRC = 121,
GXWARN_CLR_ADDR_UNINIT = 122,
GXWARN_CLR_MAT_UNINIT = 123,
GXWARN_CLR_AMB_UNINIT = 124,
GXWARN_MAX = 125,
} GXWarnID;
#define __GX_WARN(id) (__gxVerif->cb(__gxvWarnLev[(id)], (id), __gxvWarnings[(id)]))
#define __GX_WARNF(id, ...) \
do { \
sprintf(__gxvDummyStr, __gxvWarnings[(id)], __VA_ARGS__); \
__gxVerif->cb(__gxvWarnLev[(id)], (id), __gxvDummyStr); \
} while (0)
#define __GX_WARN2(level, id) (__gxVerif->cb(level, (id), __gxvWarnings[(id)]))
#define __GX_WARN2F(level, id, ...) \
do { \
sprintf(__gxvDummyStr, __gxvWarnings[(id)], __VA_ARGS__); \
__gxVerif->cb(level, (id), __gxvDummyStr); \
} while (0)
typedef struct __GXVerifyData {
GXVerifyCallback cb;
GXWarningLevel verifyLevel;
u32 xfRegs[80];
u32 xfMtx[256];
u32 xfNrm[96];
u32 xfDMtx[256];
u32 xfLight[128];
u32 rasRegs[256];
u8 xfRegsDirty[80];
u8 xfMtxDirty[256];
u8 xfNrmDirty[96];
u8 xfDMtxDirty[256];
u8 xfLightDirty[128];
} __GXVerifyData;
extern __GXVerifyData* __gxVerif;
extern char* __gxvWarnings[126];
extern char __gxvDummyStr[256];
extern GXWarningLevel __gxvWarnLev[];
void __GXVerifyGlobal(void);
void __GXVerifyCP(GXVtxFmt fmt);
void __GXVerifyState(GXVtxFmt vtxfmt);
/* GXVerifXF */
void __GXVerifyXF(void);
#ifdef __cplusplus
}
#endif
#endif

273
src/revolution/hio2/hio2.c Normal file
View File

@ -0,0 +1,273 @@
#include <revolution/types.h>
#include <revolution/os.h>
#include <revolution/exi.h>
#include <revolution/hio2.h>
#include <revolution/hw_regs.h>
#ifdef SDK_AUG2010
#define BUILD_DATE "Aug 23 2010"
#if DEBUG
#define BUILD_TIME "17:28:30"
#else
#define BUILD_TIME "17:33:06"
#endif
#elif SDK_SEP2006
#define BUILD_DATE "Sep 21 2006"
#define BUILD_TIME "14:32:13"
#endif
#ifdef SDK_AUG2010
#if DEBUG
const char* __HIO2Version = "<< RVL_SDK - HIO2 \tdebug build: "BUILD_DATE" "BUILD_TIME" (0x4302_145) >>";
#else
const char* __HIO2Version = "<< RVL_SDK - HIO2 \trelease build: "BUILD_DATE" "BUILD_TIME" (0x4302_145) >>";
#endif
#elif SDK_SEP2006
const char* __HIO2Version = "<< RVL_SDK - HIO2 \trelease build: "BUILD_DATE" "BUILD_TIME" (0x4200_60422) >>";
#endif
HIO2Control __HIO2Control[2] = {
{HIO2_DEVICE_INVALID, -1, 0, NULL, NULL, NULL, NULL},
{HIO2_DEVICE_INVALID, -1, 0, NULL, NULL, NULL, NULL},
};
static u32 __HIO2ConsoleType;
static BOOL __HIO2Initialized;
static int __HIO2LastErrorCode;
static BOOL __HIO2IsInitialized();
static void __HIO2ClearChanInfo(s32 chan) {
__HIO2Control[chan].type = HIO2_DEVICE_INVALID;
__HIO2Control[chan].chan = -1;
__HIO2Control[chan]._0x8 = 0;
__HIO2Control[chan].exiCallback =
__HIO2Control[chan]._0x10 =
__HIO2Control[chan]._0x14 =
__HIO2Control[chan].disconnectCb = NULL;
}
static void __HIO2ExtHandler(s32 chan, OSContext* context) {
if (__HIO2Control[chan].disconnectCb != NULL) {
__HIO2Control[chan].disconnectCb(chan);
}
__HIO2ClearChanInfo(chan);
EXISetExiCallback(chan, NULL);
}
static void __HIO2ExiHandler(s32 chan, OSContext* context) {
if (chan == 2) {
chan = 0;
}
if (__HIO2Control[chan].exiCallback != NULL) {
__HIO2Control[chan].exiCallback(chan);
}
}
BOOL HIO2Init(void) {
if (__HIO2Initialized) {
HIO2Exit();
}
EXIWait();
__HIO2ConsoleType = EXIGetConsoleType();
if (!(__HIO2ConsoleType & 7)) {
__HIO2LastErrorCode = 6;
return FALSE;
}
__HIO2LastErrorCode = 0;
OSRegisterVersion(__HIO2Version);
return __HIO2Initialized = TRUE;
}
BOOL HIO2EnumDevices(HIO2EnumCallback callback) {
s32 chan;
u32 id;
ASSERTLINE(275, callback != NULL);
if (!__HIO2IsInitialized()) {
return FALSE;
}
if (__HIO2Control[0].chan != -1 && __HIO2Control[1].chan != -1) {
__HIO2LastErrorCode = 5;
return FALSE;
}
for (chan = 0; chan < 2; chan++) {
while (EXIProbeEx(chan) == 0) {}
if (EXIGetID(chan, 0, &id) != 0 && id == 0 && !callback(chan)) {
return TRUE;
}
}
if (__HIO2ConsoleType & 1) {
callback(2);
}
return TRUE;
}
static BOOL __HIO2IsInitialized(void) {
if (!__HIO2Initialized) {
__HIO2LastErrorCode = 1;
}
return __HIO2Initialized;
}
s32 HIO2Open(HIO2DeviceType type, HIO2UnkCallback exiCb, HIO2DisconnectCallback disconnectCb) {
s32 chan;
s32 device;
BOOL enabled;
u8 reg;
if (!__HIO2IsInitialized()) {
return -1;
}
switch (type) {
case HIO2_DEVICE_UNK_0:
case HIO2_DEVICE_UNK_1:
chan = type;
device = 0;
break;
case HIO2_DEVICE_UNK_2:
if (__HIO2ConsoleType & 1) {
chan = 0;
device = 1;
} else {
__HIO2LastErrorCode = 6;
return -1;
}
break;
default:
__HIO2LastErrorCode = 3;
return -1;
}
if (__HIO2Control[chan].chan != -1) {
__HIO2LastErrorCode = 4;
return -1;
}
if (device == 0) {
u32 id = 0;
while (EXIProbeEx(chan) == 0) {}
if (!EXIAttach(chan, __HIO2ExtHandler) || EXIGetID(chan, 0, &id) == 0 || id != 0) {
__HIO2LastErrorCode = 7;
return -1;
}
}
reg = 0xD8;
enabled = OSDisableInterrupts();
if (!EXIWriteReg(chan, device, 0xB4000000, &reg, 1)) {
if (device == 0) {
EXIDetach(chan);
}
__HIO2LastErrorCode = 8;
OSRestoreInterrupts(enabled);
return -1;
}
OSRestoreInterrupts(enabled);
__HIO2Control[chan].type = type;
__HIO2Control[chan]._0x8 = device;
__HIO2Control[chan].chan = chan;
__HIO2Control[chan].exiCallback = exiCb;
__HIO2Control[chan]._0x10 = NULL;
__HIO2Control[chan]._0x14 = NULL;
__HIO2Control[chan].disconnectCb = disconnectCb;
if (exiCb != NULL) {
if (type == HIO2_DEVICE_UNK_2) {
EXISetExiCallback(2, __HIO2ExiHandler);
} else {
EXISetExiCallback(chan, __HIO2ExiHandler);
}
}
return chan;
}
BOOL __HIO2IsValidHandle(s32 handle) {
if ((handle == 0 || handle == 1) && __HIO2Control[handle].chan != -1) {
return TRUE;
}
__HIO2LastErrorCode = 2;
return FALSE;
}
BOOL HIO2Close(s32 handle) {
if (!__HIO2IsInitialized() || !__HIO2IsValidHandle(handle)) {
return FALSE;
}
EXISetExiCallback(__HIO2Control[handle].chan, NULL);
if (__HIO2Control[handle]._0x8 == 0) {
EXIDetach(__HIO2Control[handle].chan);
}
__HIO2ClearChanInfo(handle);
return TRUE;
}
BOOL HIO2Read(s32 handle, u32 addr, void* buffer, s32 size) {
BOOL rt;
if (!__HIO2IsInitialized() || !__HIO2IsValidHandle(handle)) {
return FALSE;
}
ASSERTLINE(564, (addr & 3) == 0);
rt = EXIReadRam(handle, __HIO2Control[handle]._0x8, ((addr + 0xD10000) << 6) & 0x3FFFFF00, buffer, size, NULL);
if (rt == 0) {
__HIO2LastErrorCode = 8;
}
return rt;
}
BOOL HIO2Write(s32 handle, u32 addr, void* buffer, s32 size) {
BOOL rt;
if (!__HIO2IsInitialized() || !__HIO2IsValidHandle(handle)) {
return FALSE;
}
ASSERTLINE(593, (addr & 3) == 0);
rt = EXIWriteRam(handle, __HIO2Control[handle]._0x8, (((addr + 0xD10000) << 6) & 0x3FFFFF00) | 0x80000000, buffer, size, NULL);
if (rt == 0) {
__HIO2LastErrorCode = 8;
}
return rt;
}
void HIO2Exit(void) {
s32 handle;
for (handle = 0; handle < 2; handle++) {
if (__HIO2Control[handle].chan != -1) {
HIO2Close(handle);
}
}
__HIO2Initialized = FALSE;
__HIO2ConsoleType = 0;
}

1197
src/revolution/mtx/mtx.c Normal file

File diff suppressed because it is too large Load Diff

888
src/revolution/mtx/mtx44.c Normal file
View File

@ -0,0 +1,888 @@
#include <revolution.h>
#include <revolution/mtx.h>
#include <math.h>
f32 mtxUnit[] = {0.0f, 1.0f, 0.5f, 3.0f};
void C_MTXFrustum(Mtx44 m, f32 t, f32 b, f32 l, f32 r, f32 n, f32 f) {
f32 tmp;
ASSERTMSGLINE(105, m, "MTXFrustum(): NULL Mtx44Ptr 'm' ");
ASSERTMSGLINE(106, t != b, "MTXFrustum(): 't' and 'b' clipping planes are equal ");
ASSERTMSGLINE(107, l != r, "MTXFrustum(): 'l' and 'r' clipping planes are equal ");
ASSERTMSGLINE(108, n != f, "MTXFrustum(): 'n' and 'f' clipping planes are equal ");
tmp = 1 / (r - l);
m[0][0] = (2 * n * tmp);
m[0][1] = 0;
m[0][2] = (tmp * (r + l));
m[0][3] = 0;
tmp = 1 / (t - b);
m[1][0] = 0;
m[1][1] = (2 * n * tmp);
m[1][2] = (tmp * (t + b));
m[1][3] = 0;
m[2][0] = 0;
m[2][1] = 0;
tmp = 1 / (f - n);
m[2][2] = (-n * tmp);
m[2][3] = (tmp * -(f * n));
m[3][0] = 0;
m[3][1] = 0;
m[3][2] = -1;
m[3][3] = 0;
}
void C_MTXPerspective(Mtx44 m, f32 fovY, f32 aspect, f32 n, f32 f) {
f32 angle;
f32 cot;
f32 tmp;
ASSERTMSGLINE(184, m, "MTXPerspective(): NULL Mtx44Ptr 'm' ");
ASSERTMSGLINE(185, (fovY > 0.0) && (fovY < 180.0), "MTXPerspective(): 'fovY' out of range ");
ASSERTMSGLINE(186, 0.0f != aspect, "MTXPerspective(): 'aspect' is 0 ");
angle = (0.5f * fovY);
angle = MTXDegToRad(angle);
cot = 1 / tanf(angle);
m[0][0] = (cot / aspect);
m[0][1] = 0;
m[0][2] = 0;
m[0][3] = 0;
m[1][0] = 0;
m[1][1] = (cot);
m[1][2] = 0;
m[1][3] = 0;
m[2][0] = 0;
m[2][1] = 0;
tmp = 1 / (f - n);
m[2][2] = (-n * tmp);
m[2][3] = (tmp * -(f * n));
m[3][0] = 0;
m[3][1] = 0;
m[3][2] = -1;
m[3][3] = 0;
}
void C_MTXOrtho(Mtx44 m, f32 t, f32 b, f32 l, f32 r, f32 n, f32 f) {
f32 tmp;
ASSERTMSGLINE(254, m, "MTXOrtho(): NULL Mtx44Ptr 'm' ");
ASSERTMSGLINE(255, t != b, "MTXOrtho(): 't' and 'b' clipping planes are equal ");
ASSERTMSGLINE(256, l != r, "MTXOrtho(): 'l' and 'r' clipping planes are equal ");
ASSERTMSGLINE(257, n != f, "MTXOrtho(): 'n' and 'f' clipping planes are equal ");
tmp = 1 / (r - l);
m[0][0] = 2 * tmp;
m[0][1] = 0;
m[0][2] = 0;
m[0][3] = (tmp * -(r + l));
tmp = 1 / (t - b);
m[1][0] = 0;
m[1][1] = 2 * tmp;
m[1][2] = 0;
m[1][3] = (tmp * -(t + b));
m[2][0] = 0;
m[2][1] = 0;
tmp = 1 / (f - n);
m[2][2] = (-1 * tmp);
m[2][3] = (-f * tmp);
m[3][0] = 0;
m[3][1] = 0;
m[3][2] = 0;
m[3][3] = 1;
}
void C_MTX44Identity(Mtx44 m) {
ASSERTMSGLINE(324, m != 0, "MTX44Identity(): NULL Mtx44 'm' ");
m[0][0] = 1.0f;
m[0][1] = 0.0f;
m[0][2] = 0.0f;
m[0][3] = 0.0f;
m[1][0] = 0.0f;
m[1][1] = 1.0f;
m[1][2] = 0.0f;
m[1][3] = 0.0f;
m[2][0] = 0.0f;
m[2][1] = 0.0f;
m[2][2] = 1.0f;
m[2][3] = 0.0f;
m[3][0] = 0.0f;
m[3][1] = 0.0f;
m[3][2] = 0.0f;
m[3][3] = 1.0f;
}
void PSMTX44Identity(__REGISTER Mtx44 m) {
__REGISTER f32 c1 = 1.0f;
__REGISTER f32 c0 = 0.0f;
asm {
stfs c1, 0x0(m)
psq_st c0, 0x4(m), 0, 0
psq_st c0, 0xc(m), 0, 0
stfs c1, 0x14(m)
psq_st c0, 0x18(m), 0, 0
psq_st c0, 0x20(m), 0, 0
stfs c1, 0x28(m)
psq_st c0, 0x2c(m), 0, 0
psq_st c0, 0x34(m), 0, 0
stfs c1, 0x3c(m)
}
}
void C_MTX44Copy(const Mtx44 src, Mtx44 dst) {
ASSERTMSGLINE(382, src != 0, "MTX44Copy(): NULL Mtx44Ptr 'src' ");
ASSERTMSGLINE(383, dst != 0, "MTX44Copy(): NULL Mtx44Ptr 'dst' ");
if (src != dst) {
dst[0][0] = src[0][0];
dst[0][1] = src[0][1];
dst[0][2] = src[0][2];
dst[0][3] = src[0][3];
dst[1][0] = src[1][0];
dst[1][1] = src[1][1];
dst[1][2] = src[1][2];
dst[1][3] = src[1][3];
dst[2][0] = src[2][0];
dst[2][1] = src[2][1];
dst[2][2] = src[2][2];
dst[2][3] = src[2][3];
dst[3][0] = src[3][0];
dst[3][1] = src[3][1];
dst[3][2] = src[3][2];
dst[3][3] = src[3][3];
}
}
asm void PSMTX44Copy(const __REGISTER Mtx44 src, __REGISTER Mtx44 dst) {
nofralloc
psq_l f1, 0x0(src), 0, 0
psq_st f1, 0x0(dst), 0, 0
psq_l f1, 0x8(src), 0, 0
psq_st f1, 0x8(dst), 0, 0
psq_l f1, 0x10(src), 0, 0
psq_st f1, 0x10(dst), 0, 0
psq_l f1, 0x18(src), 0, 0
psq_st f1, 0x18(dst), 0, 0
psq_l f1, 0x20(src), 0, 0
psq_st f1, 0x20(dst), 0, 0
psq_l f1, 0x28(src), 0, 0
psq_st f1, 0x28(dst), 0, 0
psq_l f1, 0x30(src), 0, 0
psq_st f1, 0x30(dst), 0, 0
psq_l f1, 0x38(src), 0, 0
psq_st f1, 0x38(dst), 0, 0
blr
}
void C_MTX44Concat(const Mtx44 a, const Mtx44 b, Mtx44 ab) {
Mtx44 mTmp;
Mtx44Ptr m;
ASSERTMSGLINE(454, a, "MTX44Concat(): NULL Mtx44Ptr 'a' ");
ASSERTMSGLINE(455, b, "MTX44Concat(): NULL Mtx44Ptr 'b' ");
ASSERTMSGLINE(456, ab, "MTX44Concat(): NULL Mtx44Ptr 'ab' ");
if (ab == a || ab == b) {
m = mTmp;
} else {
m = ab;
}
m[0][0] = (a[0][0] * b[0][0]) + (a[0][1] * b[1][0]) + (a[0][2] * b[2][0]) + (a[0][3] * b[3][0]);
m[0][1] = (a[0][0] * b[0][1]) + (a[0][1] * b[1][1]) + (a[0][2] * b[2][1]) + (a[0][3] * b[3][1]);
m[0][2] = (a[0][0] * b[0][2]) + (a[0][1] * b[1][2]) + (a[0][2] * b[2][2]) + (a[0][3] * b[3][2]);
m[0][3] = (a[0][0] * b[0][3]) + (a[0][1] * b[1][3]) + (a[0][2] * b[2][3]) + (a[0][3] * b[3][3]);
m[1][0] = (a[1][0] * b[0][0]) + (a[1][1] * b[1][0]) + (a[1][2] * b[2][0]) + (a[1][3] * b[3][0]);
m[1][1] = (a[1][0] * b[0][1]) + (a[1][1] * b[1][1]) + (a[1][2] * b[2][1]) + (a[1][3] * b[3][1]);
m[1][2] = (a[1][0] * b[0][2]) + (a[1][1] * b[1][2]) + (a[1][2] * b[2][2]) + (a[1][3] * b[3][2]);
m[1][3] = (a[1][0] * b[0][3]) + (a[1][1] * b[1][3]) + (a[1][2] * b[2][3]) + (a[1][3] * b[3][3]);
m[2][0] = (a[2][0] * b[0][0]) + (a[2][1] * b[1][0]) + (a[2][2] * b[2][0]) + (a[2][3] * b[3][0]);
m[2][1] = (a[2][0] * b[0][1]) + (a[2][1] * b[1][1]) + (a[2][2] * b[2][1]) + (a[2][3] * b[3][1]);
m[2][2] = (a[2][0] * b[0][2]) + (a[2][1] * b[1][2]) + (a[2][2] * b[2][2]) + (a[2][3] * b[3][2]);
m[2][3] = (a[2][0] * b[0][3]) + (a[2][1] * b[1][3]) + (a[2][2] * b[2][3]) + (a[2][3] * b[3][3]);
m[3][0] = (a[3][0] * b[0][0]) + (a[3][1] * b[1][0]) + (a[3][2] * b[2][0]) + (a[3][3] * b[3][0]);
m[3][1] = (a[3][0] * b[0][1]) + (a[3][1] * b[1][1]) + (a[3][2] * b[2][1]) + (a[3][3] * b[3][1]);
m[3][2] = (a[3][0] * b[0][2]) + (a[3][1] * b[1][2]) + (a[3][2] * b[2][2]) + (a[3][3] * b[3][2]);
m[3][3] = (a[3][0] * b[0][3]) + (a[3][1] * b[1][3]) + (a[3][2] * b[2][3]) + (a[3][3] * b[3][3]);
if (m == mTmp) {
C_MTX44Copy(mTmp, ab);
}
}
asm void PSMTX44Concat(const __REGISTER Mtx44 a, const __REGISTER Mtx44 b, __REGISTER Mtx44 ab) {
nofralloc
psq_l f0, 0x0(a), 0, 0
psq_l f2, 0x0(b), 0, 0
ps_muls0 f6, f2, f0
psq_l f3, 0x10(b), 0, 0
psq_l f4, 0x20(b), 0, 0
ps_madds1 f6, f3, f0, f6
psq_l f1, 0x8(a), 0, 0
psq_l f5, 0x30(b), 0, 0
ps_madds0 f6, f4, f1, f6
psq_l f0, 0x10(a), 0, 0
ps_madds1 f6, f5, f1, f6
psq_l f1, 0x18(a), 0, 0
ps_muls0 f8, f2, f0
ps_madds1 f8, f3, f0, f8
psq_l f0, 0x20(a), 0, 0
ps_madds0 f8, f4, f1, f8
ps_madds1 f8, f5, f1, f8
psq_l f1, 0x28(a), 0, 0
ps_muls0 f10, f2, f0
ps_madds1 f10, f3, f0, f10
psq_l f0, 0x30(a), 0, 0
ps_madds0 f10, f4, f1, f10
ps_madds1 f10, f5, f1, f10
psq_l f1, 0x38(a), 0, 0
ps_muls0 f12, f2, f0
psq_l f2, 0x8(b), 0, 0
ps_madds1 f12, f3, f0, f12
psq_l f0, 0x0(a), 0, 0
ps_madds0 f12, f4, f1, f12
psq_l f3, 0x18(b), 0, 0
ps_madds1 f12, f5, f1, f12
psq_l f1, 0x8(a), 0, 0
ps_muls0 f7, f2, f0
psq_l f4, 0x28(b), 0, 0
ps_madds1 f7, f3, f0, f7
psq_l f5, 0x38(b), 0, 0
ps_madds0 f7, f4, f1, f7
psq_l f0, 0x10(a), 0, 0
ps_madds1 f7, f5, f1, f7
psq_l f1, 0x18(a), 0, 0
ps_muls0 f9, f2, f0
psq_st f6, 0x0(ab), 0, 0
ps_madds1 f9, f3, f0, f9
psq_l f0, 0x20(a), 0, 0
ps_madds0 f9, f4, f1, f9
psq_st f8, 0x10(ab), 0, 0
ps_madds1 f9, f5, f1, f9
psq_l f1, 0x28(a), 0, 0
ps_muls0 f11, f2, f0
psq_st f10, 0x20(ab), 0, 0
ps_madds1 f11, f3, f0, f11
psq_l f0, 0x30(a), 0, 0
ps_madds0 f11, f4, f1, f11
psq_st f12, 0x30(ab), 0, 0
ps_madds1 f11, f5, f1, f11
psq_l f1, 0x38(a), 0, 0
ps_muls0 f13, f2, f0
psq_st f7, 0x8(ab), 0, 0
ps_madds1 f13, f3, f0, f13
psq_st f9, 0x18(ab), 0, 0
ps_madds0 f13, f4, f1, f13
psq_st f11, 0x28(ab), 0, 0
ps_madds1 f13, f5, f1, f13
psq_st f13, 0x38(ab), 0, 0
blr
}
void C_MTX44Transpose(const Mtx44 src, Mtx44 xPose) {
Mtx44 mTmp;
Mtx44Ptr m;
ASSERTMSGLINE(637, src, "MTX44Transpose(): NULL Mtx44Ptr 'src' ");
ASSERTMSGLINE(638, xPose, "MTX44Transpose(): NULL Mtx44Ptr 'xPose' ");
if (src == xPose) {
m = mTmp;
} else {
m = xPose;
}
m[0][0] = src[0][0];
m[0][1] = src[1][0];
m[0][2] = src[2][0];
m[0][3] = src[3][0];
m[1][0] = src[0][1];
m[1][1] = src[1][1];
m[1][2] = src[2][1];
m[1][3] = src[3][1];
m[2][0] = src[0][2];
m[2][1] = src[1][2];
m[2][2] = src[2][2];
m[2][3] = src[3][2];
m[3][0] = src[0][3];
m[3][1] = src[1][3];
m[3][2] = src[2][3];
m[3][3] = src[3][3];
if (m == mTmp) {
MTX44Copy(mTmp, xPose);
}
}
asm void PSMTX44Transpose(const __REGISTER Mtx44 src, __REGISTER Mtx44 xPose) {
nofralloc
psq_l f0, 0x0(src), 0, 0
psq_l f1, 0x10(src), 0, 0
ps_merge00 f4, f0, f1
psq_l f2, 0x8(src), 0, 0
psq_st f4, 0x0(xPose), 0, 0
ps_merge11 f5, f0, f1
psq_l f3, 0x18(src), 0, 0
psq_st f5, 0x10(xPose), 0, 0
ps_merge00 f4, f2, f3
psq_l f0, 0x20(src), 0, 0
psq_st f4, 0x20(xPose), 0, 0
ps_merge11 f5, f2, f3
psq_l f1, 0x30(src), 0, 0
psq_st f5, 0x30(xPose), 0, 0
ps_merge00 f4, f0, f1
psq_l f2, 0x28(src), 0, 0
psq_st f4, 0x8(xPose), 0, 0
ps_merge11 f5, f0, f1
psq_l f3, 0x38(src), 0, 0
psq_st f5, 0x18(xPose), 0, 0
ps_merge00 f4, f2, f3
psq_st f4, 0x28(xPose), 0, 0
ps_merge11 f5, f2, f3
psq_st f5, 0x38(xPose), 0, 0
blr
}
#define SWAP(a, b) \
{ \
f32 tmp; \
tmp = a; \
a = b; \
b = tmp; \
}
u32 C_MTX44Inverse(const Mtx44 src, Mtx44 inv) {
Mtx44 gjm;
s32 i;
s32 j;
s32 k;
f32 w;
f32 max;
s32 swp;
f32 ftmp;
ASSERTMSGLINE(734, src, "MTX44Inverse(): NULL Mtx44Ptr 'src' ");
ASSERTMSGLINE(735, inv, "MTX44Inverse(): NULL Mtx44Ptr 'inv' ");
MTX44Copy(src, gjm);
MTX44Identity(inv);
for (i = 0; i < 4; i++) {
max = 0.0f;
swp = i;
for (k = i; k < 4; k++) {
ftmp = fabsf(gjm[k][i]);
if (ftmp > max) {
max = ftmp;
swp = k;
}
}
if (max == 0.0f) {
return 0;
}
if (swp != i) {
for (k = 0; k < 4; k++) {
SWAP(gjm[i][k], gjm[swp][k]);
SWAP(inv[i][k], inv[swp][k]);
}
}
w = 1.0f / gjm[i][i];
for (j = 0; j < 4; j++) {
gjm[i][j] *= w;
inv[i][j] *= w;
}
for (k = 0; k < 4; k++) {
if (k != i) {
w = gjm[k][i];
for (j = 0; j < 4; j++) {
gjm[k][j] -= gjm[i][j] * w;
inv[k][j] -= inv[i][j] * w;
}
}
}
}
return 1;
}
void C_MTX44Trans(Mtx44 m, f32 xT, f32 yT, f32 zT) {
ASSERTMSGLINE(835, m, "MTX44Trans(): NULL Mtx44Ptr 'm' ");
m[0][0] = 1.0f;
m[0][1] = 0.0f;
m[0][2] = 0.0f;
m[0][3] = xT;
m[1][0] = 0.0f;
m[1][1] = 1.0f;
m[1][2] = 0.0f;
m[1][3] = yT;
m[2][0] = 0.0f;
m[2][1] = 0.0f;
m[2][2] = 1.0f;
m[2][3] = zT;
m[3][0] = 0.0f;
m[3][1] = 0.0f;
m[3][2] = 0.0f;
m[3][3] = 1.0f;
}
void PSMTX44Trans(__REGISTER Mtx44 m, __REGISTER f32 xT, __REGISTER f32 yT, __REGISTER f32 zT) {
__REGISTER f32 c_zero = 0.0f;
__REGISTER f32 c_one = 1.0f;
__REGISTER f32 c_01;
asm {
stfs xT, 0xc(m)
stfs yT, 0x1c(m)
ps_merge00 c_01, c_zero, c_one
stfs zT, 0x2c(m)
psq_st c_one, 0x0(m), 1, 0
psq_st c_zero, 0x4(m), 0, 0
psq_st c_01, 0x10(m), 0, 0
psq_st c_zero, 0x18(m), 1, 0
psq_st c_zero, 0x20(m), 0, 0
psq_st c_one, 0x28(m), 1, 0
psq_st c_zero, 0x30(m), 0, 0
psq_st c_01, 0x38(m), 0, 0
}
}
void C_MTX44TransApply(const Mtx44 src, Mtx44 dst, f32 xT, f32 yT, f32 zT) {
ASSERTMSGLINE(899, src, "MTX44TransApply(): NULL Mtx44Ptr 'src' ");
ASSERTMSGLINE(900, dst, "MTX44TransApply(): NULL Mtx44Ptr 'src' "); //! wrong assert string
if (src != dst) {
dst[0][0] = src[0][0];
dst[0][1] = src[0][1];
dst[0][2] = src[0][2];
dst[1][0] = src[1][0];
dst[1][1] = src[1][1];
dst[1][2] = src[1][2];
dst[2][0] = src[2][0];
dst[2][1] = src[2][1];
dst[2][2] = src[2][2];
dst[3][0] = src[3][0];
dst[3][1] = src[3][1];
dst[3][2] = src[3][2];
dst[3][3] = src[3][3];
}
dst[0][3] = (src[0][3] + xT);
dst[1][3] = (src[1][3] + yT);
dst[2][3] = (src[2][3] + zT);
}
asm void PSMTX44TransApply(const __REGISTER Mtx44 src, __REGISTER Mtx44 dst, __REGISTER f32 xT, __REGISTER f32 yT, __REGISTER f32 zT) {
nofralloc
psq_l f4, 0x0(src), 0, 0
frsp xT, xT
psq_l f5, 0x8(src), 0, 0
frsp yT, yT
psq_l f6, 0x10(src), 0, 0
frsp zT, zT
psq_l f7, 0x18(src), 0, 0
psq_st f4, 0x0(dst), 0, 0
ps_sum1 f5, xT, f5, f5
psq_l f4, 0x28(src), 0, 0
psq_st f6, 0x10(dst), 0, 0
ps_sum1 f7, yT, f7, f7
psq_l f8, 0x20(src), 0, 0
psq_st f5, 0x8(dst), 0, 0
ps_sum1 f4, zT, f4, f4
psq_st f7, 0x18(dst), 0, 0
psq_st f8, 0x20(dst), 0, 0
psq_l f5, 0x30(src), 0, 0
psq_l f6, 0x38(src), 0, 0
psq_st f4, 0x28(dst), 0, 0
psq_st f5, 0x30(dst), 0, 0
psq_st f6, 0x38(dst), 0, 0
blr
}
void C_MTX44Scale(Mtx44 m, f32 xS, f32 yS, f32 zS) {
ASSERTMSGLINE(976, m, "MTX44Scale(): NULL Mtx44Ptr 'm' ");
m[0][0] = xS;
m[0][1] = 0.0f;
m[0][2] = 0.0f;
m[0][3] = 0.0f;
m[1][0] = 0.0f;
m[1][1] = yS;
m[1][2] = 0.0f;
m[1][3] = 0.0f;
m[2][0] = 0.0f;
m[2][1] = 0.0f;
m[2][2] = zS;
m[2][3] = 0.0f;
m[3][0] = 0.0f;
m[3][1] = 0.0f;
m[3][2] = 0.0f;
m[3][3] = 1.0f;
}
void PSMTX44Scale(__REGISTER Mtx44 m, __REGISTER f32 xS, __REGISTER f32 yS, __REGISTER f32 zS) {
__REGISTER f32 c_zero = 0.0f;
__REGISTER f32 c_one = 1.0f;
asm {
stfs xS, 0x0(m)
psq_st c_zero, 0x4(m), 0, 0
psq_st c_zero, 0xc(m), 0, 0
stfs yS, 0x14(m)
psq_st c_zero, 0x18(m), 0, 0
psq_st c_zero, 0x20(m), 0, 0
stfs zS, 0x28(m)
psq_st c_zero, 0x2c(m), 0, 0
psq_st c_zero, 0x34(m), 0, 0
stfs c_one, 0x3c(m)
}
}
void C_MTX44ScaleApply(const Mtx44 src, Mtx44 dst, f32 xS, f32 yS, f32 zS) {
ASSERTMSGLINE(1036, src, "MTX44ScaleApply(): NULL Mtx44Ptr 'src' ");
ASSERTMSGLINE(1037, dst, "MTX44ScaleApply(): NULL Mtx44Ptr 'dst' ");
dst[0][0] = (src[0][0] * xS);
dst[0][1] = (src[0][1] * xS);
dst[0][2] = (src[0][2] * xS);
dst[0][3] = (src[0][3] * xS);
dst[1][0] = (src[1][0] * yS);
dst[1][1] = (src[1][1] * yS);
dst[1][2] = (src[1][2] * yS);
dst[1][3] = (src[1][3] * yS);
dst[2][0] = (src[2][0] * zS);
dst[2][1] = (src[2][1] * zS);
dst[2][2] = (src[2][2] * zS);
dst[2][3] = (src[2][3] * zS);
dst[3][0] = src[3][0];
dst[3][1] = src[3][1];
dst[3][2] = src[3][2];
dst[3][3] = src[3][3];
}
asm void PSMTX44ScaleApply(const __REGISTER Mtx44 src, __REGISTER Mtx44 dst, __REGISTER f32 xS, __REGISTER f32 yS, __REGISTER f32 zS) {
nofralloc
psq_l f4, 0x0(src), 0, 0
frsp xS, xS
psq_l f5, 0x8(src), 0, 0
frsp yS, yS
psq_l f6, 0x10(src), 0, 0
ps_muls0 f4, f4, xS
psq_l f7, 0x18(src), 0, 0
ps_muls0 f5, f5, xS
psq_l f8, 0x20(src), 0, 0
frsp zS, zS
psq_st f4, 0x0(dst), 0, 0
ps_muls0 f6, f6, yS
psq_l f9, 0x28(src), 0, 0
psq_st f5, 0x8(dst), 0, 0
ps_muls0 f7, f7, yS
psq_l f10, 0x30(src), 0, 0
psq_st f6, 0x10(dst), 0, 0
ps_muls0 f8, f8, zS
psq_l f11, 0x38(src), 0, 0
psq_st f7, 0x18(dst), 0, 0
ps_muls0 f9, f9, zS
psq_st f8, 0x20(dst), 0, 0
psq_st f9, 0x28(dst), 0, 0
psq_st f10, 0x30(dst), 0, 0
psq_st f11, 0x38(dst), 0, 0
blr
}
void C_MTX44RotRad(Mtx44 m, char axis, f32 rad) {
f32 sinA;
f32 cosA;
ASSERTMSGLINE(1118, m, "MTX44RotRad(): NULL Mtx44Ptr 'm' ");
sinA = sinf(rad);
cosA = cosf(rad);
C_MTX44RotTrig(m, axis, sinA, cosA);
}
void PSMTX44RotRad(Mtx44 m, char axis, f32 rad) {
f32 sinA;
f32 cosA;
sinA = sinf(rad);
cosA = cosf(rad);
PSMTX44RotTrig(m, axis, sinA, cosA);
}
void C_MTX44RotTrig(Mtx44 m, char axis, f32 sinA, f32 cosA) {
ASSERTMSGLINE(1163, m, "MTX44RotTrig(): NULL Mtx44Ptr 'm' ");
axis |= 0x20;
switch(axis) {
case 'x':
m[0][0] = 1.0f;
m[0][1] = 0.0f;
m[0][2] = 0.0f;
m[0][3] = 0.0f;
m[1][0] = 0.0f;
m[1][1] = cosA;
m[1][2] = -sinA;
m[1][3] = 0.0f;
m[2][0] = 0.0f;
m[2][1] = sinA;
m[2][2] = cosA;
m[2][3] = 0.0f;
m[3][0] = 0.0f;
m[3][1] = 0.0f;
m[3][2] = 0.0f;
m[3][3] = 1.0f;
break;
case 'y':
m[0][0] = cosA;
m[0][1] = 0.0f;
m[0][2] = sinA;
m[0][3] = 0.0f;
m[1][0] = 0.0f;
m[1][1] = 1.0f;
m[1][2] = 0.0f;
m[1][3] = 0.0f;
m[2][0] = -sinA;
m[2][1] = 0.0f;
m[2][2] = cosA;
m[2][3] = 0.0f;
m[3][0] = 0.0f;
m[3][1] = 0.0f;
m[3][2] = 0.0f;
m[3][3] = 1.0f;
break;
case 'z':
m[0][0] = cosA;
m[0][1] = -sinA;
m[0][2] = 0.0f;
m[0][3] = 0.0f;
m[1][0] = sinA;
m[1][1] = cosA;
m[1][2] = 0.0f;
m[1][3] = 0.0f;
m[2][0] = 0.0f;
m[2][1] = 0.0f;
m[2][2] = 1.0f;
m[2][3] = 0.0f;
m[3][0] = 0.0f;
m[3][1] = 0.0f;
m[3][2] = 0.0f;
m[3][3] = 1.0f;
break;
default:
ASSERTMSGLINE(1191, FALSE, "MTX44RotTrig(): invalid 'axis' value ");
break;
}
}
void PSMTX44RotTrig(__REGISTER Mtx44 m, __REGISTER char axis, __REGISTER f32 sinA, __REGISTER f32 cosA) {
__REGISTER f32 ftmp0;
__REGISTER f32 ftmp1;
__REGISTER f32 ftmp2;
__REGISTER f32 ftmp3;
__REGISTER f32 ftmp4;
__REGISTER f32 c_zero = 0.0f;
__REGISTER f32 c_one = 1.0f;
asm {
frsp sinA, sinA
ori axis, axis, 0x20
frsp cosA, cosA
cmplwi axis, 'x'
beq L_00001AB4
cmplwi axis, 'y'
beq L_00001AE8
cmplwi axis, 'z'
beq L_00001B20
b L_00001B54
L_00001AB4:
psq_st c_one, 0x0(m), 1, 0
psq_st c_zero, 0x4(m), 0, 0
ps_neg ftmp0, sinA
psq_st c_zero, 0xc(m), 0, 0
ps_merge00 ftmp1, sinA, cosA
psq_st c_zero, 0x1c(m), 0, 0
ps_merge00 ftmp0, cosA, ftmp0
psq_st c_zero, 0x2c(m), 0, 0
psq_st c_zero, 0x34(m), 0, 0
psq_st ftmp1, 0x24(m), 0, 0
psq_st ftmp0, 0x14(m), 0, 0
psq_st c_one, 0x3c(m), 1, 0
b L_00001B54
L_00001AE8:
ps_merge00 ftmp1, cosA, c_zero
psq_st c_zero, 0x30(m), 0, 0
ps_neg ftmp0, sinA
psq_st c_zero, 0x18(m), 0, 0
ps_merge00 ftmp3, c_zero, c_one
psq_st ftmp1, 0x0(m), 0, 0
ps_merge00 ftmp4, ftmp0, c_zero
ps_merge00 ftmp2, sinA, c_zero
psq_st ftmp3, 0x10(m), 0, 0
psq_st ftmp2, 0x8(m), 0, 0
psq_st ftmp4, 0x20(m), 0, 0
psq_st ftmp1, 0x28(m), 0, 0
psq_st ftmp3, 0x38(m), 0, 0
b L_00001B54
L_00001B20:
psq_st c_zero, 0x8(m), 0, 0
ps_neg ftmp0, sinA
psq_st c_zero, 0x18(m), 0, 0
ps_merge00 ftmp1, sinA, cosA
psq_st c_zero, 0x20(m), 0, 0
ps_merge00 ftmp2, c_one, c_zero
psq_st c_zero, 0x30(m), 0, 0
ps_merge00 ftmp3, c_zero, c_one
psq_st ftmp1, 0x10(m), 0, 0
ps_merge00 ftmp4, cosA, ftmp0
psq_st ftmp2, 0x28(m), 0, 0
psq_st ftmp3, 0x38(m), 0, 0
psq_st ftmp4, 0x0(m), 0, 0
L_00001B54:
}
}
void C_MTX44RotAxisRad(Mtx44 m, const Vec* axis, f32 rad) {
Vec vN;
f32 s;
f32 c;
f32 t;
f32 x;
f32 y;
f32 z;
f32 xSq;
f32 ySq;
f32 zSq;
ASSERTMSGLINE(1300, m, "MTX44RotAxisRad(): NULL Mtx44Ptr 'm' ");
ASSERTMSGLINE(1301, axis, "MTX44RotAxisRad(): NULL VecPtr 'axis' ");
s = sinf(rad);
c = cosf(rad);
t = 1 - c;
C_VECNormalize(axis, &vN);
x = vN.x;
y = vN.y;
z = vN.z;
xSq = (x * x);
ySq = (y * y);
zSq = (z * z);
m[0][0] = (c + (t * xSq));
m[0][1] = (y * (t * x)) - (s * z);
m[0][2] = (z * (t * x)) + (s * y);
m[0][3] = 0.0f;
m[1][0] = ((y * (t * x)) + (s * z));
m[1][1] = (c + (t * ySq));
m[1][2] = ((z * (t * y)) - (s * x));
m[1][3] = 0.0f;
m[2][0] = ((z * (t * x)) - (s * y));
m[2][1] = ((z * (t * y)) + (s * x));
m[2][2] = (c + (t * zSq));
m[2][3] = 0.0f;
m[3][0] = 0.0f;
m[3][1] = 0.0f;
m[3][2] = 0.0f;
m[3][3] = 1.0f;
}
static void __PSMTX44RotAxisRadInternal(__REGISTER Mtx44 m, const __REGISTER Vec* axis, __REGISTER f32 sT, __REGISTER f32 cT) {
__REGISTER f32 tT;
__REGISTER f32 fc0;
__REGISTER f32 tmp0;
__REGISTER f32 tmp1;
__REGISTER f32 tmp2;
__REGISTER f32 tmp3;
__REGISTER f32 tmp4;
__REGISTER f32 tmp5;
__REGISTER f32 tmp6;
__REGISTER f32 tmp7;
__REGISTER f32 tmp8;
__REGISTER f32 tmp9;
tmp9 = 0.5f;
tmp8 = 3.0f;
asm {
frsp cT, cT
psq_l tmp0, 0x0(axis), 0, 0
frsp sT, sT
lfs tmp1, 0x8(axis)
ps_mul tmp2, tmp0, tmp0
fadds tmp7, tmp9, tmp9
ps_madd tmp3, tmp1, tmp1, tmp2
fsubs fc0, tmp9, tmp9
ps_sum0 tmp4, tmp3, tmp1, tmp2
fsubs tT, tmp7, cT
frsqrte tmp5, tmp4
ps_merge00 tmp7, fc0, tmp7
fmuls tmp2, tmp5, tmp5
fmuls tmp3, tmp5, tmp9
psq_st fc0, 0x30(m), 0, 0
fnmsubs tmp2, tmp2, tmp4, tmp8
fmuls tmp5, tmp2, tmp3
psq_st tmp7, 0x38(m), 0, 0
ps_merge00 cT, cT, cT
ps_muls0 tmp0, tmp0, tmp5
ps_muls0 tmp1, tmp1, tmp5
ps_muls0 tmp4, tmp0, tT
ps_muls0 tmp9, tmp0, sT
ps_muls0 tmp5, tmp1, tT
ps_muls1 tmp3, tmp4, tmp0
ps_muls0 tmp2, tmp4, tmp0
ps_muls0 tmp4, tmp4, tmp1
fnmsubs tmp6, tmp1, sT, tmp3
fmadds tmp7, tmp1, sT, tmp3
ps_neg tmp0, tmp9
ps_sum0 tmp8, tmp4, fc0, tmp9
ps_sum0 tmp2, tmp2, tmp6, cT
ps_sum1 tmp3, cT, tmp7, tmp3
ps_sum0 tmp6, tmp0, fc0, tmp4
psq_st tmp8, 0x8(m), 0, 0
ps_sum0 tmp0, tmp4, tmp4, tmp0
psq_st tmp2, 0x0(m), 0, 0
ps_muls0 tmp5, tmp5, tmp1
psq_st tmp3, 0x10(m), 0, 0
ps_sum1 tmp4, tmp9, tmp0, tmp4
psq_st tmp6, 0x18(m), 0, 0
ps_sum0 tmp5, tmp5, fc0, cT
psq_st tmp4, 0x20(m), 0, 0
psq_st tmp5, 0x28(m), 0, 0
}
}
void PSMTX44RotAxisRad(Mtx44 m, const Vec* axis, f32 rad) {
f32 sinT, cosT;
sinT = sinf(rad);
cosT = cosf(rad);
__PSMTX44RotAxisRadInternal(m, axis, sinT, cosT);
}

View File

@ -0,0 +1,247 @@
#include <revolution.h>
#include <revolution/mtx.h>
#include "fake_tgmath.h"
void C_MTX44MultVec(const Mtx44 m, const Vec* src, Vec* dst) {
Vec vTmp;
f32 w;
ASSERTMSGLINE(67, m, "MTX44MultVec(): NULL Mtx44Ptr 'm' ");
ASSERTMSGLINE(68, src, "MTX44MultVec(): NULL VecPtr 'src' ");
ASSERTMSGLINE(69, dst, "MTX44MultVec(): NULL VecPtr 'dst' ");
vTmp.x = m[0][0] * src->x + m[0][1] * src->y + m[0][2] * src->z + m[0][3];
vTmp.y = m[1][0] * src->x + m[1][1] * src->y + m[1][2] * src->z + m[1][3];
vTmp.z = m[2][0] * src->x + m[2][1] * src->y + m[2][2] * src->z + m[2][3];
w = m[3][0] * src->x + m[3][1] * src->y + m[3][2] * src->z + m[3][3];
w = 1.0f / w;
dst->x = vTmp.x * w;
dst->y = vTmp.y * w;
dst->z = vTmp.z * w;
}
asm void PSMTX44MultVec(const __REGISTER Mtx44 m, const __REGISTER Vec* src, __REGISTER Vec* dst) {
nofralloc
psq_l f0, 0x0(src), 0, 0
psq_l f2, 0x30(m), 0, 0
psq_l f1, 0x8(src), 1, 0
ps_mul f4, f0, f2
psq_l f3, 0x38(m), 0, 0
ps_madd f5, f1, f3, f4
ps_merge11 f12, f1, f1
ps_sum0 f13, f5, f5, f5
psq_l f4, 0x0(m), 0, 0
ps_merge00 f13, f13, f13
psq_l f5, 0x8(m), 0, 0
ps_div f13, f12, f13
psq_l f6, 0x10(m), 0, 0
psq_l f7, 0x18(m), 0, 0
psq_l f8, 0x20(m), 0, 0
psq_l f9, 0x28(m), 0, 0
ps_mul f4, f0, f4
ps_madd f2, f1, f5, f4
ps_mul f6, f0, f6
ps_madd f3, f1, f7, f6
ps_mul f8, f0, f8
ps_sum0 f2, f2, f2, f2
ps_madd f9, f1, f9, f8
ps_sum1 f2, f3, f2, f3
ps_sum0 f3, f9, f9, f9
ps_mul f2, f2, f13
psq_st f2, 0x0(dst), 0, 0
ps_mul f3, f3, f13
psq_st f3, 0x8(dst), 1, 0
blr
}
void C_MTX44MultVecArray(const Mtx44 m, const Vec* srcBase, Vec* dstBase, u32 count) {
u32 i;
Vec vTmp;
f32 w;
ASSERTMSGLINE(154, m, "MTX44MultVecArray(): NULL Mtx44Ptr 'm' ");
ASSERTMSGLINE(155, srcBase, "MTX44MultVecArray(): NULL VecPtr 'srcBase' ");
ASSERTMSGLINE(156, dstBase, "MTX44MultVecArray(): NULL VecPtr 'dstBase' ");
for(i = 0; i < count; i++) {
vTmp.x = m[0][0] * srcBase->x + m[0][1] * srcBase->y + m[0][2] * srcBase->z + m[0][3];
vTmp.y = m[1][0] * srcBase->x + m[1][1] * srcBase->y + m[1][2] * srcBase->z + m[1][3];
vTmp.z = m[2][0] * srcBase->x + m[2][1] * srcBase->y + m[2][2] * srcBase->z + m[2][3];
w = m[3][0] * srcBase->x + m[3][1] * srcBase->y + m[3][2] * srcBase->z + m[3][3];
w = 1.0f / w;
dstBase->x = vTmp.x * w;
dstBase->y = vTmp.y * w;
dstBase->z = vTmp.z * w;
srcBase++;
dstBase++;
}
}
asm void PSMTX44MultVecArray(const __REGISTER Mtx44 m, const __REGISTER Vec* srcBase, __REGISTER Vec* dstBase, __REGISTER u32 count) {
nofralloc
stwu r1, -0x10(r1)
subi count, count, 0x1
psq_l f6, 0x30(m), 0, 0
mtctr count
psq_l f8, 0x0(srcBase), 0, 0
subi dstBase, dstBase, 0x4
psq_l f7, 0x38(m), 0, 0
psq_lu f9, 0x8(srcBase), 1, 0
ps_mul f13, f6, f8
psq_l f0, 0x0(m), 0, 0
stfd f14, 0x8(r1)
ps_madd f13, f7, f9, f13
psq_l f2, 0x10(m), 0, 0
ps_merge11 f14, f9, f9
ps_mul f10, f0, f8
psq_l f4, 0x20(m), 0, 0
ps_mul f11, f2, f8
psq_l f1, 0x8(m), 0, 0
ps_mul f12, f4, f8
psq_l f3, 0x18(m), 0, 0
ps_sum0 f13, f13, f13, f13
psq_l f5, 0x28(m), 0, 0
L_00000468:
ps_madd f10, f1, f9, f10
ps_madd f11, f3, f9, f11
ps_madd f12, f5, f9, f12
ps_sum0 f10, f10, f10, f10
ps_sum0 f11, f11, f11, f11
ps_sum0 f12, f12, f12, f12
ps_div f13, f14, f13
psq_lu f8, 0x4(srcBase), 0, 0
psq_lu f9, 0x8(srcBase), 1, 0
ps_mul f10, f10, f13
psq_stu f10, 0x4(dstBase), 1, 0
ps_mul f11, f11, f13
psq_stu f11, 0x4(dstBase), 1, 0
ps_mul f12, f12, f13
psq_stu f12, 0x4(dstBase), 1, 0
ps_mul f13, f6, f8
ps_mul f10, f0, f8
ps_mul f11, f2, f8
ps_madd f13, f7, f9, f13
ps_mul f12, f4, f8
ps_sum0 f13, f13, f13, f13
bdnz L_00000468
ps_madd f10, f1, f9, f10
ps_madd f11, f3, f9, f11
ps_madd f12, f5, f9, f12
ps_sum0 f10, f10, f10, f10
ps_sum0 f11, f11, f11, f11
ps_sum0 f12, f12, f12, f12
ps_div f13, f14, f13
ps_mul f10, f10, f13
psq_st f10, 0x4(dstBase), 1, 0
ps_mul f11, f11, f13
psq_st f11, 0x8(dstBase), 1, 0
ps_mul f12, f12, f13
psq_st f12, 0xc(dstBase), 1, 0
lfd f14, 0x8(r1)
addi r1, r1, 0x10
blr
}
void C_MTX44MultVecSR(const Mtx44 m, const Vec* src, Vec* dst) {
Vec vTmp;
ASSERTMSGLINE(288, m, "MTX44MultVecSR(): NULL Mtx44Ptr 'm' ");
ASSERTMSGLINE(289, src, "MTX44MultVecSR(): NULL VecPtr 'src' ");
ASSERTMSGLINE(290, dst, "MTX44MultVecSR(): NULL VecPtr 'dst' ");
vTmp.x = (m[0][2] * src->z) + ((m[0][0] * src->x) + (m[0][1] * src->y));
vTmp.y = (m[1][2] * src->z) + ((m[1][0] * src->x) + (m[1][1] * src->y));
vTmp.z = (m[2][2] * src->z) + ((m[2][0] * src->x) + (m[2][1] * src->y));
dst->x = vTmp.x;
dst->y = vTmp.y;
dst->z = vTmp.z;
}
asm void PSMTX44MultVecSR(const __REGISTER Mtx m, const __REGISTER Vec* src, __REGISTER Vec* dst) {
nofralloc
psq_l f0, 0x0(m), 0, 0
psq_l f6, 0x0(src), 0, 0
psq_l f2, 0x10(m), 0, 0
ps_mul f8, f0, f6
psq_l f4, 0x20(m), 0, 0
ps_mul f10, f2, f6
psq_l f7, 0x8(src), 1, 0
ps_mul f12, f4, f6
psq_l f3, 0x18(m), 0, 0
ps_sum0 f8, f8, f8, f8
psq_l f5, 0x28(m), 0, 0
ps_sum0 f10, f10, f10, f10
psq_l f1, 0x8(m), 0, 0
ps_sum0 f12, f12, f12, f12
ps_madd f9, f1, f7, f8
psq_st f9, 0x0(dst), 1, 0
ps_madd f11, f3, f7, f10
psq_st f11, 0x4(dst), 1, 0
ps_madd f13, f5, f7, f12
psq_st f13, 0x8(dst), 1, 0
blr
}
void C_MTX44MultVecArraySR(const Mtx44 m, const Vec* srcBase, Vec* dstBase, u32 count) {
u32 i;
Vec vTmp;
ASSERTMSGLINE(379, m, "MTX44MultVecArraySR(): NULL Mtx44Ptr 'm' ");
ASSERTMSGLINE(380, srcBase, "MTX44MultVecArraySR(): NULL VecPtr 'srcBase' ");
ASSERTMSGLINE(381, dstBase, "MTX44MultVecArraySR(): NULL VecPtr 'dstBase' ");
for(i = 0; i < count; i++) {
vTmp.x = (m[0][2] * srcBase->z) + ((m[0][0] * srcBase->x) + (m[0][1] * srcBase->y));
vTmp.y = (m[1][2] * srcBase->z) + ((m[1][0] * srcBase->x) + (m[1][1] * srcBase->y));
vTmp.z = (m[2][2] * srcBase->z) + ((m[2][0] * srcBase->x) + (m[2][1] * srcBase->y));
dstBase->x = vTmp.x;
dstBase->y = vTmp.y;
dstBase->z = vTmp.z;
srcBase++;
dstBase++;
}
}
asm void PSMTX44MultVecArraySR(const __REGISTER Mtx44 m, const __REGISTER Vec* srcBase, __REGISTER Vec* dstBase, __REGISTER u32 count) {
nofralloc
psq_l f0, 0x0(m), 0, 0
subi count, count, 0x1
psq_l f6, 0x0(srcBase), 0, 0
ps_mul f8, f0, f6
psq_l f2, 0x10(m), 0, 0
ps_mul f9, f2, f6
psq_l f4, 0x20(m), 0, 0
psq_lu f7, 0x8(srcBase), 1, 0
ps_mul f10, f4, f6
psq_l f1, 0x8(m), 1, 0
mtctr count
psq_l f3, 0x18(m), 1, 0
subi dstBase, dstBase, 0x4
psq_l f5, 0x28(m), 1, 0
L_00000890:
ps_madd f11, f1, f7, f8
psq_lu f6, 0x4(srcBase), 0, 0
ps_madd f12, f3, f7, f9
ps_madd f13, f5, f7, f10
psq_lu f7, 0x8(srcBase), 1, 0
ps_sum0 f11, f11, f8, f8
psq_stu f11, 0x4(dstBase), 1, 0
ps_sum0 f12, f12, f9, f9
psq_stu f12, 0x4(dstBase), 1, 0
ps_sum0 f13, f13, f10, f10
psq_stu f13, 0x4(dstBase), 1, 0
ps_mul f8, f0, f6
ps_mul f9, f2, f6
ps_mul f10, f4, f6
bdnz L_00000890
ps_madd f11, f1, f7, f8
ps_madd f12, f3, f7, f9
ps_madd f13, f5, f7, f10
ps_sum0 f11, f11, f8, f8
psq_stu f11, 0x4(dstBase), 1, 0
ps_sum0 f12, f12, f9, f9
psq_stu f12, 0x4(dstBase), 1, 0
ps_sum0 f13, f13, f10, f10
psq_stu f13, 0x4(dstBase), 1, 0
blr
}

View File

@ -0,0 +1,108 @@
#include <revolution.h>
#include <revolution/mtx.h>
#include "fake_tgmath.h"
void MTXInitStack(MTXStack* sPtr, u32 numMtx) {
ASSERTMSGLINE(74, sPtr, "MTXInitStack(): NULL MtxStackPtr 'sPtr' ");
ASSERTMSGLINE(75, sPtr->stackBase, "MTXInitStack(): 'sPtr' contains a NULL ptr to stack memory ");
ASSERTMSGLINE(76, numMtx, "MTXInitStack(): 'numMtx' is 0 ");
sPtr->numMtx = numMtx;
sPtr->stackPtr = 0;
}
MtxPtr MTXPush(MTXStack* sPtr, const Mtx m) {
ASSERTMSGLINE(104, sPtr, "MTXPush(): NULL MtxStackPtr 'sPtr' ");
ASSERTMSGLINE(105, sPtr->stackBase, "MTXPush(): 'sPtr' contains a NULL ptr to stack memory ");
ASSERTMSGLINE(106, m, "MTXPush(): NULL MtxPtr 'm' ");
if (sPtr->stackPtr == NULL) {
sPtr->stackPtr = sPtr->stackBase;
MTXCopy(m, sPtr->stackPtr);
} else {
ASSERTMSGLINE(121, ((((s32)sPtr->stackPtr - (s32)sPtr->stackBase) / 16) / 3) < (sPtr->numMtx - 1), "MTXPush(): stack overflow ");
MTXCopy(m, sPtr->stackPtr + 3);
sPtr->stackPtr += 3;
}
return sPtr->stackPtr;
}
MtxPtr MTXPushFwd(MTXStack* sPtr, const Mtx m) {
ASSERTMSGLINE(157, sPtr, "MTXPushFwd(): NULL MtxStackPtr 'sPtr' ");
ASSERTMSGLINE(158, sPtr->stackBase, "MTXPushFwd(): 'sPtr' contains a NULL ptr to stack memory ");
ASSERTMSGLINE(159, m, "MTXPushFwd(): NULL MtxPtr 'm' ");
if (sPtr->stackPtr == NULL) {
sPtr->stackPtr = sPtr->stackBase;
MTXCopy(m, sPtr->stackPtr);
} else {
ASSERTMSGLINE(174, ((((s32)sPtr->stackPtr - (s32)sPtr->stackBase) / 16) / 3) < (sPtr->numMtx - 1), "MTXPushFwd(): stack overflow");
MTXConcat(sPtr->stackPtr, m, sPtr->stackPtr + 3);
sPtr->stackPtr += 3;
}
return sPtr->stackPtr;
}
MtxPtr MTXPushInv(MTXStack* sPtr, const Mtx m) {
Mtx mInv;
ASSERTMSGLINE(216, sPtr, "MTXPushInv(): NULL MtxStackPtr 'sPtr' ");
ASSERTMSGLINE(217, sPtr->stackBase, "MTXPushInv(): 'sPtr' contains a NULL ptr to stack memory ");
ASSERTMSGLINE(218, m, "MTXPushInv(): NULL MtxPtr 'm' ");
MTXInverse(m, mInv);
if (sPtr->stackPtr == NULL) {
sPtr->stackPtr = sPtr->stackBase;
MTXCopy(mInv, sPtr->stackPtr);
} else {
ASSERTMSGLINE(236, ((((s32)sPtr->stackPtr - (s32)sPtr->stackBase) / 16) / 3) < (sPtr->numMtx - 1), "MTXPushInv(): stack overflow");
MTXConcat(mInv, sPtr->stackPtr, sPtr->stackPtr + 3);
sPtr->stackPtr += 3;
}
return sPtr->stackPtr;
}
MtxPtr MTXPushInvXpose(MTXStack* sPtr, const Mtx m) {
Mtx mIT;
ASSERTMSGLINE(279, sPtr, "MTXPushInvXpose(): NULL MtxStackPtr 'sPtr' ");
ASSERTMSGLINE(280, sPtr->stackBase, "MTXPushInvXpose(): 'sPtr' contains a NULL ptr to stack memory ");
ASSERTMSGLINE(281, m, "MTXPushInvXpose(): NULL MtxPtr 'm' ");
MTXInverse(m, mIT);
MTXTranspose(mIT, mIT);
if (sPtr->stackPtr == NULL) {
sPtr->stackPtr = sPtr->stackBase;
MTXCopy(mIT, sPtr->stackPtr);
} else {
ASSERTMSGLINE(300, ((((s32)sPtr->stackPtr - (s32)sPtr->stackBase) / 16) / 3) < (sPtr->numMtx - 1), "MTXPushInvXpose(): stack overflow ");
MTXConcat(sPtr->stackPtr, mIT, sPtr->stackPtr + 3);
sPtr->stackPtr += 3;
}
return sPtr->stackPtr;
}
MtxPtr MTXPop(MTXStack* sPtr) {
ASSERTMSGLINE(328, sPtr, "MTXPop(): NULL MtxStackPtr 'sPtr' ");
ASSERTMSGLINE(329, sPtr->stackBase, "MTXPop(): 'sPtr' contains a NULL ptr to stack memory ");
if (sPtr->stackPtr == NULL) {
return NULL;
}
if (sPtr->stackBase == sPtr->stackPtr) {
sPtr->stackPtr = NULL;
return NULL;
}
sPtr->stackPtr -= 3;
return sPtr->stackPtr;
}
MtxPtr MTXGetStackPtr(const MTXStack* sPtr) {
ASSERTMSGLINE(366, sPtr, "MTXGetStackPtr(): NULL MtxStackPtr 'sPtr' ");
ASSERTMSGLINE(367, sPtr->stackBase, "MTXGetStackPtr(): 'sPtr' contains a NULL ptr to stack memory ");
return sPtr->stackPtr;
}

204
src/revolution/mtx/mtxvec.c Normal file
View File

@ -0,0 +1,204 @@
#include <revolution.h>
#include <revolution/mtx.h>
#include <math.h>
void C_MTXMultVec(const Mtx m, const Vec* src, Vec* dst) {
Vec vTmp;
ASSERTMSGLINE(72, m, "MTXMultVec(): NULL MtxPtr 'm' ");
ASSERTMSGLINE(73, src, "MTXMultVec(): NULL VecPtr 'src' ");
ASSERTMSGLINE(74, dst, "MTXMultVec(): NULL VecPtr 'dst' ");
vTmp.x = m[0][3] + ((m[0][2] * src->z) + ((m[0][0] * src->x) + (m[0][1] * src->y)));
vTmp.y = m[1][3] + ((m[1][2] * src->z) + ((m[1][0] * src->x) + (m[1][1] * src->y)));
vTmp.z = m[2][3] + ((m[2][2] * src->z) + ((m[2][0] * src->x) + (m[2][1] * src->y)));
dst->x = vTmp.x;
dst->y = vTmp.y;
dst->z = vTmp.z;
}
asm void PSMTXMultVec(const __REGISTER Mtx m, const __REGISTER Vec* src, __REGISTER Vec* dst) {
nofralloc
psq_l f0, Vec.x(src), 0, 0
psq_l f2, 0(m), 0, 0
psq_l f1, Vec.z(src), 1, 0
ps_mul f4, f2, f0
psq_l f3, 8(m), 0, 0
ps_madd f5, f3, f1, f4
psq_l f8, 16(m), 0, 0
ps_sum0 f6, f5, f6, f5
psq_l f9, 24(m), 0, 0
ps_mul f10, f8, f0
psq_st f6, Vec.x(dst), 1, 0
ps_madd f11, f9, f1, f10
psq_l f2, 32(m), 0, 0
ps_sum0 f12, f11, f12, f11
psq_l f3, 40(m), 0, 0
ps_mul f4, f2, f0
psq_st f12, Vec.y(dst), 1, 0
ps_madd f5, f3, f1, f4
ps_sum0 f6, f5, f6, f5
psq_st f6, Vec.z(dst), 1, 0
blr
}
void C_MTXMultVecArray(const Mtx m, const Vec* srcBase, Vec* dstBase, u32 count) {
u32 i;
Vec vTmp;
ASSERTMSGLINE(168, m, "MTXMultVecArray(): NULL MtxPtr 'm' ");
ASSERTMSGLINE(169, srcBase, "MTXMultVecArray(): NULL VecPtr 'srcBase' ");
ASSERTMSGLINE(170, dstBase, "MTXMultVecArray(): NULL VecPtr 'dstBase' ");
ASSERTMSGLINE(171, count > 1, "MTXMultVecArray(): count must be greater than 1.");
for(i = 0; i < count; i++) {
vTmp.x = m[0][3] + ((m[0][2] * srcBase->z) + ((m[0][0] * srcBase->x) + (m[0][1] * srcBase->y)));
vTmp.y = m[1][3] + ((m[1][2] * srcBase->z) + ((m[1][0] * srcBase->x) + (m[1][1] * srcBase->y)));
vTmp.z = m[2][3] + ((m[2][2] * srcBase->z) + ((m[2][0] * srcBase->x) + (m[2][1] * srcBase->y)));
dstBase->x = vTmp.x;
dstBase->y = vTmp.y;
dstBase->z = vTmp.z;
srcBase++;
dstBase++;
}
}
asm void PSMTXMultVecArray(const __REGISTER Mtx m, const __REGISTER Vec* srcBase, __REGISTER Vec* dstBase, __REGISTER u32 count) {
nofralloc
psq_l f13, 0x0(m), 0, 0
psq_l f12, 0x10(m), 0, 0
subi count, count, 0x1
psq_l f11, 0x8(m), 0, 0
ps_merge00 f0, f13, f12
subi dstBase, dstBase, 0x4
psq_l f10, 0x18(m), 0, 0
ps_merge11 f1, f13, f12
mtctr count
psq_l f4, 0x20(m), 0, 0
ps_merge00 f2, f11, f10
psq_l f5, 0x28(m), 0, 0
ps_merge11 f3, f11, f10
psq_l f6, 0x0(srcBase), 0, 0
psq_lu f7, 0x8(srcBase), 1, 0
ps_madds0 f8, f0, f6, f3
ps_mul f9, f4, f6
ps_madds1 f8, f1, f6, f8
ps_madd f10, f5, f7, f9
L_000003C4:
psq_lu f6, 0x4(srcBase), 0, 0
ps_madds0 f12, f2, f7, f8
psq_lu f7, 0x8(srcBase), 1, 0
ps_sum0 f13, f10, f9, f10
ps_madds0 f8, f0, f6, f3
ps_mul f9, f4, f6
psq_stu f12, 0x4(dstBase), 0, 0
ps_madds1 f8, f1, f6, f8
psq_stu f13, 0x8(dstBase), 1, 0
ps_madd f10, f5, f7, f9
bdnz L_000003C4
ps_madds0 f12, f2, f7, f8
ps_sum0 f13, f10, f9, f10
psq_stu f12, 0x4(dstBase), 0, 0
psq_stu f13, 0x8(dstBase), 1, 0
blr
}
void C_MTXMultVecSR(const Mtx m, const Vec* src, Vec* dst) {
Vec vTmp;
ASSERTMSGLINE(319, m, "MTXMultVecSR(): NULL MtxPtr 'm' ");
ASSERTMSGLINE(320, src, "MTXMultVecSR(): NULL VecPtr 'src' ");
ASSERTMSGLINE(321, dst, "MTXMultVecSR(): NULL VecPtr 'dst' ");
vTmp.x = (m[0][2] * src->z) + ((m[0][0] * src->x) + (m[0][1] * src->y));
vTmp.y = (m[1][2] * src->z) + ((m[1][0] * src->x) + (m[1][1] * src->y));
vTmp.z = (m[2][2] * src->z) + ((m[2][0] * src->x) + (m[2][1] * src->y));
dst->x = vTmp.x;
dst->y = vTmp.y;
dst->z = vTmp.z;
}
asm void PSMTXMultVecSR(const __REGISTER Mtx m, const __REGISTER Vec* src, __REGISTER Vec* dst) {
nofralloc
psq_l f0, 0x0(m), 0, 0
psq_l f6, 0x0(src), 0, 0
psq_l f2, 0x10(m), 0, 0
ps_mul f8, f0, f6
psq_l f4, 0x20(m), 0, 0
ps_mul f10, f2, f6
psq_l f7, 0x8(src), 1, 0
ps_mul f12, f4, f6
psq_l f3, 0x18(m), 0, 0
ps_sum0 f8, f8, f8, f8
psq_l f5, 0x28(m), 0, 0
ps_sum0 f10, f10, f10, f10
psq_l f1, 0x8(m), 0, 0
ps_sum0 f12, f12, f12, f12
ps_madd f9, f1, f7, f8
psq_st f9, 0x0(dst), 1, 0
ps_madd f11, f3, f7, f10
psq_st f11, 0x4(dst), 1, 0
ps_madd f13, f5, f7, f12
psq_st f13, 0x8(dst), 1, 0
blr
}
void C_MTXMultVecArraySR(const Mtx m, const Vec* srcBase, Vec* dstBase, u32 count) {
u32 i;
Vec vTmp;
ASSERTMSGLINE(416, m, "MTXMultVecArraySR(): NULL MtxPtr 'm' ");
ASSERTMSGLINE(417, srcBase, "MTXMultVecArraySR(): NULL VecPtr 'srcBase' ");
ASSERTMSGLINE(418, dstBase, "MTXMultVecArraySR(): NULL VecPtr 'dstBase' ");
ASSERTMSGLINE(419, count > 1, "MTXMultVecArraySR(): count must be greater than 1.");
for(i = 0; i < count; i++) {
vTmp.x = (m[0][2] * srcBase->z) + ((m[0][0] * srcBase->x) + (m[0][1] * srcBase->y));
vTmp.y = (m[1][2] * srcBase->z) + ((m[1][0] * srcBase->x) + (m[1][1] * srcBase->y));
vTmp.z = (m[2][2] * srcBase->z) + ((m[2][0] * srcBase->x) + (m[2][1] * srcBase->y));
dstBase->x = vTmp.x;
dstBase->y = vTmp.y;
dstBase->z = vTmp.z;
srcBase++;
dstBase++;
}
}
asm void PSMTXMultVecArraySR(const __REGISTER Mtx m, const __REGISTER Vec* srcBase, __REGISTER Vec* dstBase, __REGISTER u32 count) {
nofralloc
psq_l f13, 0x0(m), 0, 0
psq_l f12, 0x10(m), 0, 0
subi count, count, 0x1
psq_l f11, 0x8(m), 1, 0
ps_merge00 f0, f13, f12
subi dstBase, dstBase, 0x4
psq_l f10, 0x18(m), 1, 0
ps_merge11 f1, f13, f12
mtctr count
psq_l f3, 0x20(m), 0, 0
ps_merge00 f2, f11, f10
psq_l f4, 0x28(m), 1, 0
psq_l f6, 0x0(srcBase), 0, 0
psq_lu f7, 0x8(srcBase), 1, 0
ps_muls0 f8, f0, f6
ps_mul f9, f3, f6
ps_madds1 f8, f1, f6, f8
ps_madd f10, f4, f7, f9
L_000007D0:
psq_lu f6, 0x4(srcBase), 0, 0
ps_madds0 f12, f2, f7, f8
psq_lu f7, 0x8(srcBase), 1, 0
ps_sum0 f13, f10, f9, f9
ps_muls0 f8, f0, f6
ps_mul f9, f3, f6
psq_stu f12, 0x4(dstBase), 0, 0
ps_madds1 f8, f1, f6, f8
psq_stu f13, 0x8(dstBase), 1, 0
ps_madd f10, f4, f7, f9
bdnz L_000007D0
ps_madds0 f12, f2, f7, f8
ps_sum0 f13, f10, f9, f9
psq_stu f12, 0x4(dstBase), 0, 0
psq_stu f13, 0x8(dstBase), 1, 0
blr
}

336
src/revolution/mtx/psmtx.c Normal file
View File

@ -0,0 +1,336 @@
#include <revolution.h>
#include <revolution/mtx.h>
#include "fake_tgmath.h"
asm void PSMTXReorder(const __REGISTER Mtx src, __REGISTER ROMtx dest) {
psq_l f0, 0(src), 0, 0
psq_l f2, 16(src), 0, 0
psq_l f4, 32(src), 0, 0
psq_l f1, 8(src), 0, 0
ps_merge00 f6, f0, f2
psq_l f3, 24(src), 0, 0
ps_merge01 f12, f4, f0
psq_l f5, 40(src), 0, 0
ps_merge11 f7, f2, f4
psq_st f6, 0(dest), 0, 0
ps_merge00 f8, f1, f3
psq_st f12, 8(dest), 0, 0
ps_merge01 f9, f5, f1
psq_st f7, 16(dest), 0, 0
ps_merge11 f10, f3, f5
psq_st f8, 24(dest), 0, 0
psq_st f9, 32(dest), 0, 0
psq_st f10, 40(dest), 0, 0
}
asm void PSMTXROMultVecArray(const __REGISTER ROMtx m, const __REGISTER Vec* srcBase, __REGISTER Vec* dstBase, __REGISTER u32 count) {
nofralloc
stwu r1, -64(r1)
stfd f14, 8(r1)
subi r7, count, 1
stfd f15, 16(r1)
srwi r7, r7, 1
stfd f16, 24(r1)
stfd f17, 32(r1)
stfd f18, 40(r1)
mtctr r7
psq_l f0, 0(m), 0, 0
subi srcBase, srcBase, 8
psq_l f1, 8(m), 1, 0
subi dstBase, dstBase, 4
psq_l f6, 36(m), 0, 0
psq_lu f8, 8(srcBase), 0, 0
psq_l f7, 44(m), 1, 0
psq_lu f9, 8(srcBase), 0, 0
ps_madds0 f11, f0, f8, f6
psq_l f2, 12(m), 0, 0
ps_madds0 f12, f1, f8, f7
psq_l f3, 20(m), 1, 0
ps_madds1 f13, f0, f9, f6
psq_lu f10, 8(srcBase), 0, 0
ps_madds1 f14, f1, f9, f7
psq_l f5, 32(m), 1, 0
ps_madds1 f11, f2, f8, f11
ps_madds1 f12, f3, f8, f12
psq_l f4, 24(m), 0, 0
ps_madds0 f13, f2, f10, f13
psq_lu f8, 8(srcBase), 0, 0
ps_madds0 f14, f3, f10, f14
ps_madds0 f15, f4, f9, f11
ps_madds0 f16, f5, f9, f12
psq_lu f9, 8(srcBase), 0, 0
ps_madds1 f17, f4, f10, f13
ps_madds1 f18, f5, f10, f14
psq_lu f10, 8(srcBase), 0, 0
loop:
ps_madds0 f11, f0, f8, f6
psq_stu f15, 4(dstBase), 0, 0
ps_madds0 f12, f1, f8, f7
psq_stu f16, 8(dstBase), 1, 0
ps_madds1 f13, f0, f9, f6
psq_stu f17, 4(dstBase), 0, 0
ps_madds1 f14, f1, f9, f7
psq_stu f18, 8(dstBase), 1, 0
ps_madds1 f11, f2, f8, f11
ps_madds1 f12, f3, f8, f12
psq_lu f8, 8(srcBase), 0, 0
ps_madds0 f13, f2, f10, f13
ps_madds0 f14, f3, f10, f14
ps_madds0 f15, f4, f9, f11
ps_madds0 f16, f5, f9, f12
psq_lu f9, 8(srcBase), 0, 0
ps_madds1 f17, f4, f10, f13
ps_madds1 f18, f5, f10, f14
psq_lu f10, 8(srcBase), 0, 0
bdnz loop
psq_stu f15, 4(dstBase), 0, 0
clrlwi. r7, count, 31
psq_stu f16, 8(dstBase), 1, 0
bne exit
psq_stu f17, 4(dstBase), 0, 0
psq_stu f18, 8(dstBase), 1, 0
exit:
lfd f14, 8(r1)
lfd f15, 16(r1)
lfd f16, 24(r1)
lfd f17, 32(r1)
lfd f18, 40(r1)
addi r1, r1, 64
blr
}
asm void PSMTXROSkin2VecArray(const __REGISTER ROMtx m0, const __REGISTER ROMtx m1, const __REGISTER f32* wtBase, const __REGISTER Vec* srcBase, __REGISTER Vec* dstBase, __REGISTER u32 count) {
nofralloc
stwu r1, -160(r1)
stfd f14, 8(r1)
stfd f15, 16(r1)
stfd f16, 24(r1)
stfd f17, 32(r1)
stfd f18, 40(r1)
stfd f19, 48(r1)
stfd f20, 56(r1)
stfd f21, 64(r1)
stfd f22, 72(r1)
stfd f23, 80(r1)
stfd f24, 88(r1)
stfd f25, 96(r1)
stfd f26, 104(r1)
stfd f27, 112(r1)
stfd f28, 120(r1)
stfd f29, 128(r1)
stfd f30, 136(r1)
subi r9, r8, 1
mtctr r9
subi srcBase, srcBase, 4
subi dstBase, dstBase, 4
subi wtBase, wtBase, 4
psq_l f14, 0(m0), 0, 0
psq_l f22, 0(m1), 0, 0
psq_l f15, 8(m0), 1, 0
psq_l f23, 8(m1), 1, 0
psq_l f16, 12(m0), 0, 0
psq_l f24, 12(m1), 0, 0
ps_sub f22, f22, f14
psq_l f17, 20(m0), 1, 0
psq_l f25, 20(m1), 1, 0
ps_sub f23, f23, f15
psq_l f18, 24(m0), 0, 0
psq_l f26, 24(m1), 0, 0
ps_sub f24, f24, f16
psq_l f19, 32(m0), 1, 0
psq_l f27, 32(m1), 1, 0
ps_sub f25, f25, f17
psq_l f20, 36(m0), 0, 0
psq_l f28, 36(m1), 0, 0
ps_sub f26, f26, f18
psq_l f21, 44(m0), 1, 0
psq_l f29, 44(m1), 1, 0
ps_sub f27, f27, f19
ps_sub f28, f28, f20
ps_sub f29, f29, f21
psq_lu f30, 4(wtBase), 1, 0
psq_lu f8, 4(srcBase), 0, 0
psq_lu f9, 8(srcBase), 1, 0
ps_madds0 f0, f22, f30, f14
ps_madds0 f1, f23, f30, f15
ps_madds0 f2, f24, f30, f16
ps_madds0 f3, f25, f30, f17
ps_madds0 f4, f26, f30, f18
ps_madds0 f5, f27, f30, f19
ps_madds0 f6, f28, f30, f20
ps_madds0 f7, f29, f30, f21
ps_madds0 f12, f0, f8, f6
ps_madds0 f13, f1, f8, f7
psq_lu f30, 4(wtBase), 1, 0
loop:
ps_madds1 f12, f2, f8, f12
ps_madds1 f13, f3, f8, f13
psq_lu f8, 4(srcBase), 0, 0
ps_madds0 f10, f4, f9, f12
ps_madds0 f11, f5, f9, f13
psq_lu f9, 8(srcBase), 1, 0
ps_madds0 f0, f22, f30, f14
ps_madds0 f1, f23, f30, f15
ps_madds0 f2, f24, f30, f16
ps_madds0 f3, f25, f30, f17
ps_madds0 f4, f26, f30, f18
ps_madds0 f5, f27, f30, f19
ps_madds0 f6, f28, f30, f20
ps_madds0 f7, f29, f30, f21
psq_stu f10, 4(dstBase), 0, 0
ps_madds0 f12, f0, f8, f6
ps_madds0 f13, f1, f8, f7
psq_stu f11, 8(dstBase), 1, 0
psq_lu f30, 4(wtBase), 1, 0
bdnz loop
ps_madds1 f12, f2, f8, f12
ps_madds1 f13, f3, f8, f13
ps_madds0 f10, f4, f9, f12
psq_stu f10, 4(dstBase), 0, 0
ps_madds0 f11, f5, f9, f13
psq_stu f11, 8(dstBase), 1, 0
lfd f14, 8(r1)
lfd f15, 16(r1)
lfd f16, 24(r1)
lfd f17, 32(r1)
lfd f18, 40(r1)
lfd f19, 48(r1)
lfd f20, 56(r1)
lfd f21, 64(r1)
lfd f22, 72(r1)
lfd f23, 80(r1)
lfd f24, 88(r1)
lfd f25, 96(r1)
lfd f26, 104(r1)
lfd f27, 112(r1)
lfd f28, 120(r1)
lfd f29, 128(r1)
lfd f30, 136(r1)
addi r1, r1, 160
blr
}
asm void PSMTXROMultS16VecArray(const __REGISTER Mtx m, const __REGISTER S16Vec* srcBase, __REGISTER Vec* dstBase, __REGISTER u32 count) {
nofralloc
stwu r1, -64(r1)
stfd f14, 8(r1)
subi r7, count, 1
stfd f15, 16(r1)
srwi r7, r7, 1
stfd f16, 24(r1)
lis r8, 7
stfd f17, 32(r1)
mtspr GQR6, r8
stfd f18, 40(r1)
mtctr r7
psq_l f0, 0(m), 0, 0
subi srcBase, srcBase, 4
psq_l f1, 8(m), 1, 0
subi dstBase, dstBase, 4
psq_l f6, 36(m), 0, 0
psq_lu f8, 4(srcBase), 0, 6
psq_l f7, 44(m), 1, 0
psq_lu f9, 4(srcBase), 0, 6
ps_madds0 f11, f0, f8, f6
psq_l f2, 12(m), 0, 0
ps_madds0 f12, f1, f8, f7
psq_l f3, 20(m), 1, 0
ps_madds1 f13, f0, f9, f6
psq_lu f10, 4(srcBase), 0, 6
ps_madds1 f14, f1, f9, f7
psq_l f5, 32(m), 1, 0
ps_madds1 f11, f2, f8, f11
ps_madds1 f12, f3, f8, f12
psq_l f4, 24(m), 0, 0
ps_madds0 f13, f2, f10, f13
psq_lu f8, 4(srcBase), 0, 6
ps_madds0 f14, f3, f10, f14
ps_madds0 f15, f4, f9, f11
ps_madds0 f16, f5, f9, f12
psq_lu f9, 4(srcBase), 0, 6
ps_madds1 f17, f4, f10, f13
ps_madds1 f18, f5, f10, f14
psq_lu f10, 4(srcBase), 0, 6
loop:
ps_madds0 f11, f0, f8, f6
psq_stu f15, 4(dstBase), 0, 0
ps_madds0 f12, f1, f8, f7
psq_stu f16, 8(dstBase), 1, 0
ps_madds1 f13, f0, f9, f6
psq_stu f17, 4(dstBase), 0, 0
ps_madds1 f14, f1, f9, f7
psq_stu f18, 8(dstBase), 1, 0
ps_madds1 f11, f2, f8, f11
ps_madds1 f12, f3, f8, f12
psq_lu f8, 4(srcBase), 0, 6
ps_madds0 f13, f2, f10, f13
ps_madds0 f14, f3, f10, f14
ps_madds0 f15, f4, f9, f11
ps_madds0 f16, f5, f9, f12
psq_lu f9, 4(srcBase), 0, 6
ps_madds1 f17, f4, f10, f13
ps_madds1 f18, f5, f10, f14
psq_lu f10, 4(srcBase), 0, 6
bdnz loop
psq_stu f15, 4(dstBase), 0, 0
clrlwi. r7, count, 31
psq_stu f16, 8(dstBase), 1, 0
bne exit
psq_stu f17, 4(dstBase), 0, 0
psq_stu f18, 8(dstBase), 1, 0
exit:
lfd f14, 8(r1)
lfd f15, 16(r1)
lfd f16, 24(r1)
lfd f17, 32(r1)
lfd f18, 40(r1)
addi r1, r1, 64
blr
}
asm void PSMTXMultS16VecArray(const __REGISTER ROMtx* m, const __REGISTER S16Vec* srcBase, __REGISTER Vec* dstBase, __REGISTER u32 count) {
psq_l f0, 0(m), 0, 0
lis r7, 7
mtspr GQR6, r7
psq_l f6, 0(srcBase), 0, 6
subi count, count, 1
psq_l f7, 4(srcBase), 1, 6
mtctr count
psq_l f1, 8(m), 0, 0
addi srcBase, srcBase, 4
psq_l f2, 16(m), 0, 0
subi dstBase, dstBase, 4
psq_l f3, 24(m), 0, 0
ps_mul f8, f0, f6
psq_l f4, 32(m), 0, 0
ps_mul f10, f2, f6
psq_l f5, 40(m), 0, 0
ps_mul f12, f4, f6
psq_lu f6, 2(srcBase), 0, 6
ps_madd f8, f1, f7, f8
ps_madd f10, f3, f7, f10
ps_madd f12, f5, f7, f12
psq_lu f7, 4(srcBase), 1, 6
ps_sum0 f9, f8, f8, f8
loop:
ps_sum0 f11, f10, f10, f10
ps_mul f8, f0, f6
ps_sum0 f13, f12, f12, f12
ps_mul f10, f2, f6
psq_stu f9, 4(dstBase), 1, 0
ps_mul f12, f4, f6
psq_stu f11, 4(dstBase), 1, 0
ps_madd f8, f1, f7, f8
psq_stu f13, 4(dstBase), 1, 0
ps_madd f10, f3, f7, f10
psq_lu f6, 2(srcBase), 0, 6
ps_madd f12, f5, f7, f12
psq_lu f7, 4(srcBase), 1, 6
ps_sum0 f9, f8, f8, f8
bdnz loop
ps_sum0 f11, f10, f10, f10
ps_sum0 f13, f12, f12, f12
psq_stu f9, 4(dstBase), 1, 0
psq_stu f11, 4(dstBase), 1, 0
psq_stu f13, 4(dstBase), 1, 0
}

486
src/revolution/mtx/quat.c Normal file
View File

@ -0,0 +1,486 @@
#include <revolution.h>
#include <revolution/mtx.h>
#include <math.h>
void C_QUATAdd(const Quaternion* p, const Quaternion* q, Quaternion* r) {
ASSERTMSGLINE(77, p, "QUATAdd(): NULL QuaternionPtr 'p' ");
ASSERTMSGLINE(78, q, "QUATAdd(): NULL QuaternionPtr 'q' ");
ASSERTMSGLINE(79, r, "QUATAdd(): NULL QuaternionPtr 'r' ");
r->x = p->x + q->x;
r->y = p->y + q->y;
r->z = p->z + q->z;
r->w = p->w + q->w;
}
void PSQUATAdd(const __REGISTER Quaternion* p, const __REGISTER Quaternion* q, __REGISTER Quaternion* r) {
__REGISTER f32 pxy, qxy, rxy, pzw, qzw, rzw;
asm {
psq_l pxy, 0(p), 0, 0
psq_l qxy, 0(q), 0, 0
ps_add rxy, pxy, qxy
psq_st rxy, 0(r), 0, 0
psq_l pzw, 8(p), 0, 0
psq_l qzw, 8(q), 0, 0
ps_add rzw, pzw, qzw
psq_st rzw, 8(r), 0, 0
}
}
void C_QUATSubtract(const Quaternion* p, const Quaternion* q, Quaternion* r) {
ASSERTMSGLINE(133, p, "QUATSubtract(): NULL QuaternionPtr 'p' ");
ASSERTMSGLINE(134, q, "QUATSubtract(): NULL QuaternionPtr 'q' ");
ASSERTMSGLINE(135, r, "QUATSubtract(): NULL QuaternionPtr 'r' ");
r->x = p->x - q->x;
r->y = p->y - q->y;
r->z = p->z - q->z;
r->w = p->w - q->w;
}
void PSQUATSubtract(const __REGISTER Quaternion* p, const __REGISTER Quaternion* q, __REGISTER Quaternion* r) {
__REGISTER f32 pxy, qxy, rxy, pzw, qzw, rzw;
asm {
psq_l pxy, 0(p), 0, 0
psq_l qxy, 0(q), 0, 0
ps_sub rxy, pxy, qxy
psq_st rxy, 0(r), 0, 0
psq_l pzw, 8(p), 0, 0
psq_l qzw, 8(q), 0, 0
ps_sub rzw, pzw, qzw
psq_st rzw, 8(r), 0, 0
}
}
void C_QUATMultiply(const Quaternion* p, const Quaternion* q, Quaternion* pq) {
Quaternion* r;
Quaternion pqTmp;
ASSERTMSGLINE(193, p, "QUATMultiply(): NULL QuaternionPtr 'p' ");
ASSERTMSGLINE(194, q, "QUATMultiply(): NULL QuaternionPtr 'q' ");
ASSERTMSGLINE(195, pq, "QUATMultiply(): NULL QuaternionPtr 'pq' ");
if (p == pq || q == pq){
r = &pqTmp;
} else {
r = pq;
}
r->w = (p->w * q->w) - (p->x * q->x) - (p->y * q->y) - (p->z * q->z);
r->x = (p->w * q->x) + (p->x * q->w) + (p->y * q->z) - (p->z * q->y);
r->y = (p->w * q->y) + (p->y * q->w) + (p->z * q->x) - (p->x * q->z);
r->z = (p->w * q->z) + (p->z * q->w) + (p->x * q->y) - (p->y * q->x);
if (r == &pqTmp) {
*pq = pqTmp;
}
}
void PSQUATMultiply(const __REGISTER Quaternion* p, const __REGISTER Quaternion* q, __REGISTER Quaternion* pq) {
__REGISTER f32 pxy, pzw;
__REGISTER f32 qxy, qzw;
__REGISTER f32 pnxy, pnzw, pnxny, pnznw;
__REGISTER f32 rxy, rzw;
__REGISTER f32 sxy, szw;
asm {
psq_l pxy, 0x0(p), 0, 0
psq_l pzw, 0x8(p), 0, 0
psq_l qxy, 0x0(q), 0, 0
ps_neg pnxny, pxy
psq_l qzw, 0x8(q), 0, 0
ps_neg pnznw, pzw
ps_merge01 pnxy, pnxny, pxy
ps_muls0 rxy, pzw, qxy
ps_muls0 rzw, pnxny, qxy
ps_merge01 pnzw, pnznw, pzw
ps_muls1 szw, pnxy, qxy
ps_madds0 rxy, pnxy, qzw, rxy
ps_muls1 sxy, pnzw, qxy
ps_madds0 rzw, pnzw, qzw, rzw
ps_madds1 szw, pnznw, qzw, szw
ps_merge10 rxy, rxy, rxy
ps_madds1 sxy, pxy, qzw, sxy
ps_merge10 rzw, rzw, rzw
ps_add rxy, rxy, sxy
psq_st rxy, 0x0(pq), 0, 0
ps_sub rzw, rzw, szw
psq_st rzw, 0x8(pq), 0, 0
}
}
void C_QUATScale(const Quaternion* q, Quaternion* r, f32 scale) {
ASSERTMSGLINE(306, q, "QUATScale(): NULL QuaternionPtr 'q' ");
ASSERTMSGLINE(307, r, "QUATScale(): NULL QuaternionPtr 'r' ");
r->x = q->x * scale;
r->y = q->y * scale;
r->z = q->z * scale;
r->w = q->w * scale;
}
void PSQUATScale(const __REGISTER Quaternion* q, __REGISTER Quaternion* r, __REGISTER f32 scale) {
__REGISTER f32 rxy, rzw;
asm {
psq_l rxy, 0(q), 0, 0
psq_l rzw, 8(q), 0, 0
ps_muls0 rxy, rxy, scale
psq_st rxy, 0(r), 0, 0
ps_muls0 rzw, rzw, scale
psq_st rzw, 8(r), 0, 0
}
}
f32 C_QUATDotProduct(const Quaternion* p, const Quaternion* q) {
ASSERTMSGLINE(357, p, "QUATDotProduct(): NULL QuaternionPtr 'p' ");
ASSERTMSGLINE(358, q, "QUATDotProduct(): NULL QuaternionPtr 'q' ");
return (q->x * p->x) + (q->y * p->y) + (q->z * p->z) + (q->w * p->w);
}
f32 PSQUATDotProduct(const __REGISTER Quaternion* p, const __REGISTER Quaternion* q) {
__REGISTER f32 pxy, pzw, qxy, qzw, dp;
asm {
psq_l pxy, 0(p), 0, 0
psq_l qxy, 0(q), 0, 0
ps_mul dp, pxy, qxy
psq_l pzw, 8(p), 0, 0
psq_l qzw, 8(q), 0, 0
ps_madd dp, pzw, qzw, dp
ps_sum0 dp, dp, dp, dp
}
return dp;
}
void C_QUATNormalize(const Quaternion* src, Quaternion* unit) {
f32 mag;
ASSERTMSGLINE(407, src, "QUATNormalize(): NULL QuaternionPtr 'src' ");
ASSERTMSGLINE(408, unit, "QUATNormalize(): NULL QuaternionPtr 'unit' ");
mag = (src->x * src->x) + (src->y * src->y) + (src->z * src->z) + (src->w * src->w);
if (mag >= 0.00001f) {
mag = 1.0f / sqrtf(mag);
unit->x = src->x * mag;
unit->y = src->y * mag;
unit->z = src->z * mag;
unit->w = src->w * mag;
} else {
unit->x = unit->y = unit->z = unit->w = 0.0f;
}
}
void PSQUATNormalize(const __REGISTER Quaternion* src, __REGISTER Quaternion* unit) {
__REGISTER f32 sxy, szw;
__REGISTER f32 mag, rsqmag;
__REGISTER f32 diff;
__REGISTER f32 c_zero;
__REGISTER f32 nwork0, nwork1;
__REGISTER f32 epsilon = 0.00001f;
__REGISTER f32 c_half = 0.5f;
__REGISTER f32 c_three = 3.0f;
asm {
psq_l sxy, 0x0(src), 0, 0
ps_mul mag, sxy, sxy
psq_l szw, 0x8(src), 0, 0
ps_sub c_zero, epsilon, epsilon
ps_madd mag, szw, szw, mag
ps_sum0 mag, mag, mag, mag
frsqrte rsqmag, mag
ps_sub diff, mag, epsilon
fmul nwork0, rsqmag, rsqmag
fmul nwork1, rsqmag, c_half
fnmsub nwork0, nwork0, mag, c_three
fmul rsqmag, nwork0, nwork1
ps_sel rsqmag, diff, rsqmag, c_zero
ps_muls0 sxy, sxy, rsqmag
ps_muls0 szw, szw, rsqmag
psq_st sxy, 0x0(unit), 0, 0
psq_st szw, 0x8(unit), 0, 0
}
}
void C_QUATInverse(const Quaternion* src, Quaternion* inv) {
f32 mag, norminv;
ASSERTMSGLINE(498, src, "QUATInverse(): NULL QuaternionPtr 'src' ");
ASSERTMSGLINE(499, inv, "QUATInverse(): NULL QuaternionPtr 'inv' ");
mag = (src->x * src->x) + (src->y * src->y) + (src->z * src->z) + (src->w * src->w);
if (mag == 0.0f) {
mag = 1.0f;
}
norminv = 1.0f / mag;
inv->x = -src->x * norminv;
inv->y = -src->y * norminv;
inv->z = -src->z * norminv;
inv->w = src->w * norminv;
}
void PSQUATInverse(const __REGISTER Quaternion* src, __REGISTER Quaternion* inv) {
__REGISTER f32 sxy, szw;
__REGISTER f32 izz, iww;
__REGISTER f32 mag, nmag;
__REGISTER f32 norminv, nninv;
__REGISTER f32 nwork0;
__REGISTER f32 c_two;
__REGISTER f32 c_zero;
__REGISTER f32 c_one = 1.0f;
asm {
psq_l sxy, 0x0(src), 0, 0
ps_mul mag, sxy, sxy
ps_sub c_zero, c_one, c_one
psq_l szw, 0x8(src), 0, 0
ps_madd mag, szw, szw, mag
ps_add c_two, c_one, c_one
ps_sum0 mag, mag, mag, mag
fcmpu cr0, mag, c_zero
beq L_00000948
fres norminv, mag
ps_neg nmag, mag
ps_nmsub nwork0, mag, norminv, c_two
ps_mul norminv, norminv, nwork0
b L_0000094C
L_00000948:
fmr norminv, c_one
L_0000094C:
ps_neg nninv, norminv
ps_muls1 iww, norminv, szw
ps_muls0 sxy, sxy, nninv
psq_st iww, 0xc(inv), 1, 0
ps_muls0 izz, szw, nninv
psq_st sxy, 0x0(inv), 0, 0
psq_st izz, 0x8(inv), 1, 0
}
}
void C_QUATDivide(const Quaternion* p, const Quaternion* q, Quaternion* r) {
Quaternion qtmp;
ASSERTMSGLINE(606, p, "QUATDivide(): NULL QuaternionPtr 'p' ");
ASSERTMSGLINE(607, q, "QUATDivide(): NULL QuaternionPtr 'q' ");
ASSERTMSGLINE(608, r, "QUATDivide(): NULL QuaternionPtr 'r' ");
C_QUATInverse(q, &qtmp);
C_QUATMultiply(&qtmp, p, r);
}
void PSQUATDivide(const Quaternion* p, const Quaternion* q, Quaternion* r) {
Quaternion qtmp;
PSQUATInverse(q, &qtmp);
PSQUATMultiply(&qtmp, p, r);
}
void C_QUATExp(const Quaternion* q, Quaternion* r) {
f32 theta, scale;
ASSERTMSGLINE(643, q, "QUATExp(): NULL QuaternionPtr 'q' ");
ASSERTMSGLINE(644, r, "QUATExp(): NULL QuaternionPtr 'r' ");
ASSERTMSGLINE(647, q->w == 0.0f, "QUATExp(): 'q' is not a pure quaternion. ");
theta = sqrtf((q->x * q->x) + (q->y * q->y) + (q->z * q->z));
scale = 1.0f;
if (theta > 0.00001f) {
scale = sinf(theta) / theta;
}
r->x = scale * q->x;
r->y = scale * q->y;
r->z = scale * q->z;
r->w = cosf(theta);
}
void C_QUATLogN(const Quaternion* q, Quaternion* r) {
f32 theta, scale, mag;
ASSERTMSGLINE(676, q, "QUATLogN(): NULL QuaternionPtr 'q' ");
ASSERTMSGLINE(677, r, "QUATLogN(): NULL QuaternionPtr 'r' ");
scale = (q->x * q->x) + (q->y * q->y) + (q->z * q->z);
#if DEBUG
mag = scale + (q->z * q->z);
if (mag < 1.0f - 0.00001f || mag > 1.0f + 0.00001f || mag > 1.00001f) {}
#endif
scale = sqrtf(scale);
theta = atan2f(scale, q->w);
if (scale > 0.0f) {
scale = theta / scale;
}
r->x = scale * q->x;
r->y = scale * q->y;
r->z = scale * q->z;
r->w = 0.0f;
}
void C_QUATMakeClosest(const Quaternion* q, const Quaternion* qto, Quaternion* r) {
f32 dot;
ASSERTMSGLINE(722, q, "QUATMakeClosest(): NULL QuaternionPtr 'q' ");
ASSERTMSGLINE(723, qto, "QUATMakeClosest(): NULL QuaternionPtr 'qto' ");
ASSERTMSGLINE(724, r, "QUATMakeClosest(): NULL QuaternionPtr 'r' ");
dot = (q->x * qto->x) + (q->y * qto->y) + (q->z * qto->z) + (q->w * qto->w);
if (dot < 0.0f) {
r->x = -q->x;
r->y = -q->y;
r->z = -q->z;
r->w = -q->w;
} else {
*r = *q;
}
}
void C_QUATRotAxisRad(Quaternion* r, const Vec* axis, f32 rad) {
f32 half, sh, ch;
Vec nAxis;
ASSERTMSGLINE(763, r, "QUATRotAxisRad(): NULL QuaternionPtr 'r' ");
ASSERTMSGLINE(764, axis, "QUATRotAxisRad(): NULL VecPtr 'axis' ");
VECNormalize(axis, &nAxis);
half = rad * 0.5f;
sh = sinf(half);
ch = cosf(half);
r->x = sh * nAxis.x;
r->y = sh * nAxis.y;
r->z = sh * nAxis.z;
r->w = ch;
}
void C_QUATMtx(Quaternion* r, const Mtx m) {
f32 tr,s;
s32 i, j, k;
s32 nxt[3] = {1, 2, 0};
f32 q[3];
ASSERTMSGLINE(791, r, "QUATMtx(): NULL QuaternionPtr 'r' ");
ASSERTMSGLINE(792, m, "QUATMtx(): NULL MtxPtr 'm' ");
tr = m[0][0] + m[1][1] + m[2][2];
if (tr > 0.0f) {
s = sqrtf(tr + 1.0f);
r->w = s * 0.5f;
s = 0.5f / s;
r->x = (m[2][1] - m[1][2]) * s;
r->y = (m[0][2] - m[2][0]) * s;
r->z = (m[1][0] - m[0][1]) * s;
} else {
i = 0;
if (m[1][1] > m[0][0]) {
i = 1;
}
if (m[2][2] > m[i][i]) {
i = 2;
}
j = nxt[i];
k = nxt[j];
s = sqrtf((m[i][i] - (m[j][j] + m[k][k])) + 1.0f);
q[i] = s * 0.5f;
if (s != 0.0f) {
s = 0.5f / s;
}
r->w = (m[k][j] - m[j][k]) * s;
q[j] = (m[i][j] + m[j][i]) * s;
q[k] = (m[i][k] + m[k][i]) * s;
r->x = q[0];
r->y = q[1];
r->z = q[2];
}
}
void C_QUATLerp(const Quaternion* p, const Quaternion* q, Quaternion* r, f32 t) {
ASSERTMSGLINE(842, p, "QUATLerp(): NULL QuaternionPtr 'p' ");
ASSERTMSGLINE(843, q, "QUATLerp(): NULL QuaternionPtr 'q' ");
ASSERTMSGLINE(844, r, "QUATLerp(): NULL QuaternionPtr 'r' ");
r->x = t * (q->x - p->x) + p->x;
r->y = t * (q->y - p->y) + p->y;
r->z = t * (q->z - p->z) + p->z;
r->w = t * (q->w - p->w) + p->w;
}
void C_QUATSlerp(const Quaternion* p, const Quaternion* q, Quaternion* r, f32 t) {
f32 theta, sin_th, cos_th;
f32 tp, tq;
ASSERTMSGLINE(874, p, "QUATSlerp(): NULL QuaternionPtr 'p' ");
ASSERTMSGLINE(875, q, "QUATSlerp(): NULL QuaternionPtr 'q' ");
ASSERTMSGLINE(876, r, "QUATSlerp(): NULL QuaternionPtr 'r' ");
cos_th = p->x * q->x + p->y * q->y + p->z * q->z + p->w * q->w;
tq = 1.0f;
if (cos_th < 0.0f) {
cos_th = -cos_th;
tq = -tq;
}
if (cos_th <= 0.99999f) {
theta = acosf(cos_th);
sin_th = sinf(theta);
tp = sinf((1.0f - t) * theta) / sin_th;
tq *= sinf(t * theta) / sin_th;
} else {
tp = 1.0f - t;
tq *= t;
}
r->x = (tp * p->x) + (tq * q->x);
r->y = (tp * p->y) + (tq * q->y);
r->z = (tp * p->z) + (tq * q->z);
r->w = (tp * p->w) + (tq * q->w);
}
void C_QUATSquad(const Quaternion* p, const Quaternion* a, const Quaternion* b, const Quaternion* q, Quaternion* r, f32 t) {
Quaternion pq, ab;
f32 t2;
ASSERTMSGLINE(927, p, "QUATSquad(): NULL QuaternionPtr 'p' ");
ASSERTMSGLINE(928, a, "QUATSquad(): NULL QuaternionPtr 'a' ");
ASSERTMSGLINE(929, b, "QUATSquad(): NULL QuaternionPtr 'b' ");
ASSERTMSGLINE(930, q, "QUATSquad(): NULL QuaternionPtr 'q' ");
ASSERTMSGLINE(931, r, "QUATSquad(): NULL QuaternionPtr 'r' ");
t2 = 2.0f * t * (1.0f - t);
C_QUATSlerp(p, q, &pq, t);
C_QUATSlerp(a, b, &ab, t);
C_QUATSlerp(&pq, &ab, r, t2);
}
void C_QUATCompA(const Quaternion* qprev, const Quaternion* q, const Quaternion* qnext, Quaternion* a) {
Quaternion qm, qp, lqm, lqp, qpqm, exq;
ASSERTMSGLINE(958, qprev, "QUATCompA(): NULL QuaternionPtr 'qprev' ");
ASSERTMSGLINE(959, q, "QUATCompA(): NULL QuaternionPtr 'q' ");
ASSERTMSGLINE(960, qnext, "QUATCompA(): NULL QuaternionPtr 'qnext' ");
ASSERTMSGLINE(961, a, "QUATCompA(): NULL QuaternionPtr 'a' ");
C_QUATDivide(qprev, q, &qm);
C_QUATLogN(&qm, &lqm);
C_QUATDivide(qnext, q, &qp);
C_QUATLogN(&qp, &lqp);
C_QUATAdd(&lqp, &lqm, &qpqm);
C_QUATScale(&qpqm, &qpqm, -0.25f);
C_QUATExp(&qpqm, &exq);
C_QUATMultiply(q, &exq, a);
}

344
src/revolution/mtx/vec.c Normal file
View File

@ -0,0 +1,344 @@
#include <revolution.h>
#include <revolution/mtx.h>
#include <math.h>
void C_VECAdd(const Vec* a, const Vec* b, Vec* ab) {
ASSERTMSGLINE(114, a, "VECAdd(): NULL VecPtr 'a' ");
ASSERTMSGLINE(115, b, "VECAdd(): NULL VecPtr 'b' ");
ASSERTMSGLINE(116, ab, "VECAdd(): NULL VecPtr 'ab' ");
ab->x = a->x + b->x;
ab->y = a->y + b->y;
ab->z = a->z + b->z;
}
asm void PSVECAdd(const __REGISTER Vec* a, const __REGISTER Vec* b, __REGISTER Vec* ab) {
psq_l f2, Vec.x(a), 0, 0
psq_l f4, Vec.x(b), 0, 0
ps_add f6, f2, f4
psq_st f6, Vec.x(ab), 0, 0
psq_l f3, Vec.z(a), 1, 0
psq_l f5, Vec.z(b), 1, 0
ps_add f7, f3, f5
psq_st f7, Vec.z(ab), 1, 0
}
void C_VECSubtract(const Vec* a, const Vec* b, Vec* a_b) {
ASSERTMSGLINE(183, a, "VECSubtract(): NULL VecPtr 'a' ");
ASSERTMSGLINE(184, b, "VECSubtract(): NULL VecPtr 'b' ");
ASSERTMSGLINE(185, a_b, "VECSubtract(): NULL VecPtr 'a_b' ");
a_b->x = a->x - b->x;
a_b->y = a->y - b->y;
a_b->z = a->z - b->z;
}
asm void PSVECSubtract(const __REGISTER Vec* a, const __REGISTER Vec* b, __REGISTER Vec* a_b) {
psq_l f2, Vec.x(a), 0, 0
psq_l f4, Vec.x(b), 0, 0
ps_sub f6, f2, f4
psq_st f6, Vec.x(a_b), 0, 0
psq_l f3, Vec.z(a), 1, 0
psq_l f5, Vec.z(b), 1, 0
ps_sub f7, f3, f5
psq_st f7, Vec.z(a_b), 1, 0
}
void C_VECScale(const Vec* src, Vec* dst, f32 scale) {
ASSERTMSGLINE(253, src, "VECScale(): NULL VecPtr 'src' ");
ASSERTMSGLINE(254, dst, "VECScale(): NULL VecPtr 'dst' ");
dst->x = (src->x * scale);
dst->y = (src->y * scale);
dst->z = (src->z * scale);
}
void PSVECScale(const __REGISTER Vec* src, __REGISTER Vec* dst, __REGISTER f32 scale) {
__REGISTER f32 vxy, vz, rxy, rz;
asm {
psq_l vxy, 0x0(src), 0, 0
psq_l vz, 0x8(src), 1, 0
ps_muls0 rxy, vxy, scale
psq_st rxy, 0x0(dst), 0, 0
ps_muls0 rz, vz, scale
psq_st rz, 0x8(dst), 1, 0
}
}
void C_VECNormalize(const Vec* src, Vec* unit) {
f32 mag;
ASSERTMSGLINE(321, src, "VECNormalize(): NULL VecPtr 'src' ");
ASSERTMSGLINE(322, unit, "VECNormalize(): NULL VecPtr 'unit' ");
mag = (src->z * src->z) + ((src->x * src->x) + (src->y * src->y));
ASSERTMSGLINE(327, 0.0f != mag, "VECNormalize(): zero magnitude vector ");
mag = 1.0f/ sqrtf(mag);
unit->x = src->x * mag;
unit->y = src->y * mag;
unit->z = src->z * mag;
}
void PSVECNormalize(const __REGISTER Vec* src, __REGISTER Vec* unit) {
__REGISTER float c_half = 0.5f;
__REGISTER float c_three = 3.0f;
__REGISTER float v1_xy;
__REGISTER float v1_z;
__REGISTER float xx_zz;
__REGISTER float xx_yy;
__REGISTER float sqsum;
__REGISTER float rsqrt;
__REGISTER float nwork0;
__REGISTER float nwork1;
asm {
psq_l v1_xy, 0x0(src), 0, 0
ps_mul xx_yy, v1_xy, v1_xy
psq_l v1_z, 0x8(src), 1, 0
ps_madd xx_zz, v1_z, v1_z, xx_yy
ps_sum0 sqsum, xx_zz, v1_z, xx_yy
frsqrte rsqrt, sqsum
fmuls nwork0, rsqrt, rsqrt
fmuls nwork1, rsqrt, c_half
fnmsubs nwork0, nwork0, sqsum, c_three
fmuls rsqrt, nwork0, nwork1
ps_muls0 v1_xy, v1_xy, rsqrt
psq_st v1_xy, 0x0(unit), 0, 0
ps_muls0 v1_z, v1_z, rsqrt
psq_st v1_z, 0x8(unit), 1, 0
}
}
f32 C_VECSquareMag(const Vec* v) {
f32 sqmag;
ASSERTMSGLINE(411, v, "VECMag(): NULL VecPtr 'v' ");
sqmag = v->z * v->z + ((v->x * v->x) + (v->y * v->y));
return sqmag;
}
f32 PSVECSquareMag(const __REGISTER Vec* v) {
__REGISTER f32 vxy, vzz, sqmag;
asm {
psq_l vxy, 0x0(v), 0, 0
ps_mul vxy, vxy, vxy
lfs vzz, 0x8(v)
ps_madd sqmag, vzz, vzz, vxy
ps_sum0 sqmag, sqmag, vxy, vxy
}
return sqmag;
}
f32 C_VECMag(const Vec* v) {
return sqrtf(C_VECSquareMag(v));
}
f32 PSVECMag(const __REGISTER Vec* v) {
__REGISTER f32 vxy, vzz;
__REGISTER f32 sqmag, rmag;
__REGISTER f32 nwork0, nwork1;
__REGISTER f32 c_three, c_half, c_zero;
c_half = 0.5f;
asm {
psq_l vxy, 0x0(v), 0, 0
ps_mul vxy, vxy, vxy
lfs vzz, 0x8(v)
fsubs c_zero, c_half, c_half
ps_madd sqmag, vzz, vzz, vxy
ps_sum0 sqmag, sqmag, vxy, vxy
fcmpu cr0, sqmag, c_zero
beq L_000005F0
frsqrte rmag, sqmag
}
c_three = 3.0f;
asm {
fmuls nwork0, rmag, rmag
fmuls nwork1, rmag, c_half
fnmsubs nwork0, nwork0, sqmag, c_three
fmuls rmag, nwork0, nwork1
fmuls sqmag, sqmag, rmag
L_000005F0:
}
return sqmag;
}
f32 C_VECDotProduct(const Vec* a, const Vec* b) {
f32 dot;
ASSERTMSGLINE(546, a, "VECDotProduct(): NULL VecPtr 'a' ");
ASSERTMSGLINE(547, b, "VECDotProduct(): NULL VecPtr 'b' ");
dot = (a->z * b->z) + ((a->x * b->x) + (a->y * b->y));
return dot;
}
asm f32 PSVECDotProduct(const __REGISTER Vec* a, const __REGISTER Vec* b) {
psq_l f2, Vec.y(a), 0, 0
psq_l f3, Vec.y(b), 0, 0
ps_mul f2, f2, f3
psq_l f5, Vec.x(a), 0, 0
psq_l f4, Vec.x(b), 0, 0
ps_madd f3, f5, f4, f2
ps_sum0 f1, f3, f2, f2
}
void C_VECCrossProduct(const Vec* a, const Vec* b, Vec* axb) {
Vec vTmp;
ASSERTMSGLINE(608, a, "VECCrossProduct(): NULL VecPtr 'a' ");
ASSERTMSGLINE(609, b, "VECCrossProduct(): NULL VecPtr 'b' ");
ASSERTMSGLINE(610, axb, "VECCrossProduct(): NULL VecPtr 'axb' ");
vTmp.x = (a->y * b->z) - (a->z * b->y);
vTmp.y = (a->z * b->x) - (a->x * b->z);
vTmp.z = (a->x * b->y) - (a->y * b->x);
axb->x = vTmp.x;
axb->y = vTmp.y;
axb->z = vTmp.z;
}
asm void PSVECCrossProduct(const __REGISTER Vec* a, const __REGISTER Vec* b, __REGISTER Vec* axb) {
psq_l f1, Vec.x(b), 0, 0
lfs f2, Vec.z(a)
psq_l f0, Vec.x(a), 0, 0
ps_merge10 f6, f1, f1
lfs f3, Vec.z(b)
ps_mul f4, f1, f2
ps_muls0 f7, f1, f0
ps_msub f5, f0, f3, f4
ps_msub f8, f0, f6, f7
ps_merge11 f9, f5, f5
ps_merge01 f10, f5, f8
psq_st f9, Vec.x(axb), 1, 0
ps_neg f10, f10
psq_st f10, Vec.y(axb), 0, 0
}
void C_VECHalfAngle(const Vec* a, const Vec* b, Vec* half) {
Vec aTmp;
Vec bTmp;
Vec hTmp;
ASSERTMSGLINE(713, a, "VECHalfAngle(): NULL VecPtr 'a' ");
ASSERTMSGLINE(714, b, "VECHalfAngle(): NULL VecPtr 'b' ");
ASSERTMSGLINE(715, half, "VECHalfAngle(): NULL VecPtr 'half' ");
aTmp.x = -a->x;
aTmp.y = -a->y;
aTmp.z = -a->z;
bTmp.x = -b->x;
bTmp.y = -b->y;
bTmp.z = -b->z;
VECNormalize(&aTmp, &aTmp);
VECNormalize(&bTmp, &bTmp);
VECAdd(&aTmp, &bTmp, &hTmp);
if (VECDotProduct(&hTmp, &hTmp) > 0.0f) {
VECNormalize(&hTmp, half);
return;
}
*half = hTmp;
}
void C_VECReflect(const Vec* src, const Vec* normal, Vec* dst) {
f32 cosA;
Vec uI;
Vec uN;
ASSERTMSGLINE(769, src, "VECReflect(): NULL VecPtr 'src' ");
ASSERTMSGLINE(770, normal, "VECReflect(): NULL VecPtr 'normal' ");
ASSERTMSGLINE(771, dst, "VECReflect(): NULL VecPtr 'dst' ");
uI.x = -src->x;
uI.y = -src->y;
uI.z = -src->z;
VECNormalize(&uI, &uI);
VECNormalize(normal, &uN);
cosA = VECDotProduct(&uI, &uN);
dst->x = (2.0f * uN.x * cosA) - uI.x;
dst->y = (2.0f * uN.y * cosA) - uI.y;
dst->z = (2.0f * uN.z * cosA) - uI.z;
VECNormalize(dst, dst);
}
f32 C_VECSquareDistance(const Vec* a, const Vec* b) {
Vec diff;
diff.x = a->x - b->x;
diff.y = a->y - b->y;
diff.z = a->z - b->z;
return (diff.z * diff.z) + ((diff.x * diff.x) + (diff.y * diff.y));
}
f32 PSVECSquareDistance(const __REGISTER Vec* a, const __REGISTER Vec* b) {
__REGISTER f32 v0yz, v1yz, v0xy, v1xy, dyz, dxy;
__REGISTER f32 sqdist;
asm {
psq_l v0yz, 0x4(a), 0, 0
psq_l v1yz, 0x4(b), 0, 0
ps_sub dyz, v0yz, v1yz
psq_l v0xy, 0x0(a), 0, 0
psq_l v1xy, 0x0(b), 0, 0
ps_mul dyz, dyz, dyz
ps_sub dxy, v0xy, v1xy
ps_madd sqdist, dxy, dxy, dyz
ps_sum0 sqdist, sqdist, dyz, dyz
}
return sqdist;
}
f32 C_VECDistance(const Vec* a, const Vec* b) {
return sqrtf(C_VECSquareDistance(a, b));
}
f32 PSVECDistance(const __REGISTER Vec* a, const __REGISTER Vec* b) {
__REGISTER f32 v0yz, v1yz, v0xy, v1xy, dyz, dxy;
__REGISTER f32 sqdist, rdist;
__REGISTER f32 nwork0, nwork1;
__REGISTER f32 c_half, c_three, c_zero;
asm {
psq_l v0yz, 0x4(a), 0, 0
psq_l v1yz, 0x4(b), 0, 0
ps_sub dyz, v0yz, v1yz
psq_l v0xy, 0x0(a), 0, 0
psq_l v1xy, 0x0(b), 0, 0
ps_mul dyz, dyz, dyz
ps_sub dxy, v0xy, v1xy
}
c_half = 0.5f;
asm {
ps_madd sqdist, dxy, dxy, dyz
fsubs c_zero, c_half, c_half
ps_sum0 sqdist, sqdist, dyz, dyz
fcmpu cr0, c_zero, sqdist
beq L_00000CBC
}
c_three = 3.0f;
asm {
frsqrte rdist, sqdist
fmuls nwork0, rdist, rdist
fmuls nwork1, rdist, c_half
fnmsubs nwork0, nwork0, sqdist, c_three
fmuls rdist, nwork0, nwork1
fmuls sqdist, sqdist, rdist
L_00000CBC:
}
return sqdist;
}

123
src/revolution/sc/scapi.c Normal file
View File

@ -0,0 +1,123 @@
#include <revolution/sc.h>
u8 SCGetAspectRatio(void) {
u8 aspect;
if (!SCFindU8Item(&aspect, SC_ITEM_ID_IPL_ASPECT_RATIO)) {
aspect = 0;
} else {
if (aspect != 1) {
aspect = 0;
}
}
return aspect;
}
s8 SCGetDisplayOffsetH(void) {
s8 offset;
if (!SCFindS8Item(&offset, SC_ITEM_ID_IPL_DISPLAY_OFFSET_H)) {
offset = 0;
} else {
if (offset < -32) {
offset = -32;
} else if (offset > 32) {
offset = 32;
}
}
offset &= ~1;
return offset;
}
u8 SCGetEuRgb60Mode(void) {
u8 mode;
if (!SCFindU8Item(&mode, SC_ITEM_ID_IPL_EURGB60_MODE)) {
mode = 0;
} else {
if (mode != 1) {
mode = 0;
}
}
return mode;
}
BOOL SCGetIdleMode(SCIdleModeInfo* info) {
return SCFindByteArrayItem(info, sizeof(*info), SC_ITEM_ID_IPL_IDLE_MODE);
}
u8 SCGetLanguage(void) {
u8 lang;
s8 area;
if (!SCFindU8Item(&lang, SC_ITEM_ID_IPL_LANGUAGE)) {
area = SCGetProductArea();
if (area == 0) {
lang = SC_LANG_JAPANESE;
} else {
lang = SC_LANG_ENGLISH;
}
} else {
if (lang > SC_LANG_KOREAN) {
lang = SC_LANG_ENGLISH;
}
}
return lang;
}
u8 SCGetProgressiveMode(void) {
u8 mode;
if (!SCFindU8Item(&mode, SC_ITEM_ID_IPL_PROGRESSIVE_MODE)) {
mode = 0;
} else {
if (mode != 1) {
mode = 0;
}
}
return mode;
}
u8 SCGetScreenSaverMode(void) {
u8 mode;
if (!SCFindU8Item(&mode, SC_ITEM_ID_IPL_SCREEN_SAVER_MODE)) {
mode = 1;
} else {
if (mode != 1) {
mode = 0;
}
}
return mode;
}
u8 SCGetSoundMode(void) {
u8 mode;
if (!SCFindU8Item(&mode, SC_ITEM_ID_IPL_SOUND_MODE)) {
mode = 1;
} else {
if (mode != 0 && mode != 1 && mode != 2) {
mode = 1;
}
}
return mode;
}
u32 SCGetCounterBias(void) {
u32 bias;
if (!SCFindU32Item(&bias, SC_ITEM_ID_IPL_COUNTER_BIAS)) {
bias = 189388800;
}
return bias;
}

View File

@ -0,0 +1,136 @@
#include <revolution/sc.h>
#include <revolution/os.h>
#include <string.h>
typedef struct {
s8 area;
char string[4];
} SCProductAreaAndString;
static SCProductAreaAndString ProductAreaAndStringTbl[] = {
0, "JPN",
1, "USA",
2, "EUR",
3, "AUS",
4, "BRA",
5, "TWN",
5, "ROC",
6, "KOR",
7, "HKG",
8, "ASI",
9, "LTN",
10, "SAF",
11, "CHN",
-1
};
BOOL __SCF1(const char* keyword, char* buf, u32 bufSize) {
BOOL result = FALSE;
u8* p = (u8*)OSPhysicalToCached(0x3800);
u32 size = 0x100, i, seed = 0x73b5dbfa, kwOffset = 0;
u8 data;
u32 bufOffset = 0;
for (i = 0; i < size; i++) {
data = p[i];
if (data != 0) {
data ^= seed;
if (keyword[kwOffset] == '\0') {
if (data == '=') {
result = TRUE;
break;
}
}
if (((keyword[kwOffset] ^ data) & 0xDF) == 0) {
kwOffset++;
}
else {
kwOffset = 0;
}
}
seed = (u32)((seed >> 31) | (seed << 1));
}
if (result) {
i++;
while (i < size && bufOffset < bufSize) {
seed = (u32)((seed >> 31) | (seed << 1));
data = p[i];
if (data != 0) {
data ^= seed;
if (data == '\x0d' || data == '\x0a') {
data = 0;
}
}
buf[bufOffset] = (char)data;
bufOffset++;
if (data == 0) {
return TRUE;
}
i++;
}
}
return FALSE;
}
BOOL SCGetProductAreaString(char* buf, u32 bufSize) {
return __SCF1("AREA", buf, bufSize);
}
s8 SCGetProductArea(void) {
char buf[4];
SCProductAreaAndString* p = ProductAreaAndStringTbl;
if (SCGetProductAreaString(buf, sizeof(buf))) {
while (p->area != -1) {
if (strcmp(p->string, buf) == 0) {
return p->area;
}
p++;
}
}
return -1;
}
typedef struct {
s8 game;
char string[3];
} SCProductGameRegionAndString;
static SCProductGameRegionAndString ProductGameRegionAndStringTbl[] = {
0, "JP",
1, "US",
2, "EU",
4, "KR",
5, "CN",
-1
};
s8 SCGetProductGameRegion(void) {
char buf[3];
SCProductGameRegionAndString* p = ProductGameRegionAndStringTbl;
if (__SCF1("GAME", buf, sizeof(buf))) {
while (p->game != -1) {
if (strcmp(p->string, buf) == 0) {
return p->game;
}
p++;
}
}
return -1;
}

View File

@ -0,0 +1,996 @@
#include <revolution/types.h>
#include <revolution/sc.h>
#include <string.h>
// #include <mem.h>
#ifdef SDK_AUG2010
#define BUILD_DATE "Aug 23 2010"
#if DEBUG
#define BUILD_TIME "17:28:26"
#else
#define BUILD_TIME "17:33:06"
#endif
#elif SDK_SEP2006
#define BUILD_DATE "Sep 21 2006"
#define BUILD_TIME "14:32:13"
#endif
#ifdef SDK_AUG2010
#if DEBUG
const char* __SCVersion = "<< RVL_SDK - SC \tdebug build: " BUILD_DATE " " BUILD_TIME " (0x4302_145) >>";
#else
const char* __SCVersion = "<< RVL_SDK - SC \trelease build: " BUILD_DATE " " BUILD_TIME " (0x4302_145) >>";
#endif
#elif SDK_SEP2006
const char* __SCVersion = "<< RVL_SDK - SC \trelease build: " BUILD_DATE " " BUILD_TIME " (0x4200_60422) >>";
#endif
typedef struct {
char* name;
SCItemID id;
} NameAndID;
static NameAndID NameAndIDTbl[38] = {
"IPL.CB", SC_ITEM_ID_IPL_COUNTER_BIAS,
"IPL.AR", SC_ITEM_ID_IPL_ASPECT_RATIO,
"IPL.ARN", SC_ITEM_ID_IPL_AUTORUN_MODE,
"IPL.CD", SC_ITEM_ID_IPL_CONFIG_DONE,
"IPL.CD2", SC_ITEM_ID_IPL_CONFIG_DONE2,
"IPL.DH", SC_ITEM_ID_IPL_DISPLAY_OFFSET_H,
"IPL.E60", SC_ITEM_ID_IPL_EURGB60_MODE,
"IPL.EULA", SC_ITEM_ID_IPL_EULA,
"IPL.FRC", SC_ITEM_ID_IPL_FREE_CHANNEL_APP_COUNT,
"IPL.IDL", SC_ITEM_ID_IPL_IDLE_MODE,
"IPL.INC", SC_ITEM_ID_IPL_INSTALLED_CHANNEL_APP_COUNT,
"IPL.LNG", SC_ITEM_ID_IPL_LANGUAGE,
"IPL.NIK", SC_ITEM_ID_IPL_OWNER_NICKNAME,
"IPL.PC", SC_ITEM_ID_IPL_PARENTAL_CONTROL,
"IPL.PGS", SC_ITEM_ID_IPL_PROGRESSIVE_MODE,
"IPL.SSV", SC_ITEM_ID_IPL_SCREEN_SAVER_MODE,
"IPL.SADR", SC_ITEM_ID_IPL_SIMPLE_ADDRESS,
"IPL.SND", SC_ITEM_ID_IPL_SOUND_MODE,
"IPL.UPT", SC_ITEM_ID_IPL_UPDATE_TYPE,
"NET.CNF", SC_ITEM_ID_NET_CONFIG,
"NET.CTPC", SC_ITEM_ID_NET_CONTENT_RESTRICTIONS,
"NET.PROF", SC_ITEM_ID_NET_PROFILE,
"NET.WCPC", SC_ITEM_ID_NET_WC_RESTRICTION,
"NET.WCFG", SC_ITEM_ID_NET_WC_FLAGS,
"DEV.BTM", SC_ITEM_ID_DEV_BOOT_MODE,
"DEV.VIM", SC_ITEM_ID_DEV_VIDEO_MODE,
"DEV.CTC", SC_ITEM_ID_DEV_COUNTRY_CODE,
"DEV.DSM", SC_ITEM_ID_DEV_DRIVESAVING_MODE,
"BT.DINF", SC_ITEM_ID_BT_DEVICE_INFO,
"BT.CDIF", SC_ITEM_ID_BT_CMPDEV_INFO,
"BT.SENS", SC_ITEM_ID_BT_DPD_SENSIBILITY,
"BT.SPKV", SC_ITEM_ID_BT_SPEAKER_VOLUME,
"BT.MOT", SC_ITEM_ID_BT_MOTOR_MODE,
"BT.BAR", SC_ITEM_ID_BT_SENSOR_BAR_POSITION,
"DVD.CNF", SC_ITEM_ID_DVD_CONFIG,
"WWW.RST", SC_ITEM_ID_WWW_RESTRICTION,
"MPLS.MOVIE", SC_ITEM_ID_MOTION_PLUS_MOVIE,
"IPL.TID", SC_ITEM_ID_TEMPORARY_TITLE_ID,
};
static const char ConfDirName[] = "/shared2/sys";
static const char ConfFileName[] = "/shared2/sys/SYSCONF";
static const char ProductInfoFileName[] = "/title/00000001/00000002/data/setting.txt";
static u8 ConfBuf[0x4000] ATTRIBUTE_ALIGN(32);
static u8 ConfBufForFlush[0x4000] ATTRIBUTE_ALIGN(32);
static u8 Initialized;
static u8 DirtyFlag;
static u8 IsDevKit;
static vu8 BgJobStatus = 0;
static u32 ItemIDOffsetTblOffset;
static u32 ItemIDMaxPlus1;
static u32 ItemNumTotal;
static u32 ItemRestSize;
static SCControl Control;
static void SetBgJobStatus(u32 status);
static u32 ParseConfBuf(u8* bufp, u32 bufSize);
static void ClearConfBuf(u8* bufp);
static BOOL ParseGetBEValue(const u8* bufp, const u8* bufEndp, u32* varp, u32 varSize);
static void OpenCallbackFromReload(s32, NANDCommandBlock*);
static void ReadCallbackFromReload(s32 result, NANDCommandBlock* block);
static void CloseCallbackFromReloadError(s32 result, NANDCommandBlock* block);
static void CloseCallbackFromReload(s32 result, NANDCommandBlock* block);
static void ErrorFromReload(s32 result);
static void FinishFromReload(void);
static BOOL UnpackItem(const u8*, SCItem*);
static void MyNandCallback(s32, NANDCommandBlock* block);
static void FinishFromFlush(void);
static void ErrorFromFlush(void);
static BOOL __SCIsDirty(void);
static void __SCSetDirtyFlag(void);
static void __SCClearDirtyFlag(void);
static u8* __SCGetConfBuf(void);
static u32 __SCGetConfBufSize(void);
void SCInit(void) {
BOOL enabled = OSDisableInterrupts();
if (Initialized) {
OSRestoreInterrupts(enabled);
return;
}
Initialized = TRUE;
SetBgJobStatus(1);
OSRestoreInterrupts(enabled);
OSRegisterVersion(__SCVersion);
OSInitThreadQueue(&Control.threadQueue);
if (OSGetConsoleType() & 0x10000000) {
IsDevKit = TRUE;
}
if (NANDInit() != 0 || SCReloadConfFileAsync(__SCGetConfBuf(), __SCGetConfBufSize(), NULL) != 0) {
SetBgJobStatus(2);
}
}
static void SetBgJobStatus(u32 status) {
BgJobStatus = (u8)status;
}
u32 SCCheckStatus(void) {
BOOL enabled;
u32 ret;
enabled = OSDisableInterrupts();
ret = BgJobStatus;
if (ret == 3) {
SetBgJobStatus(1);
OSRestoreInterrupts(enabled);
if (ParseConfBuf(Control.reloadBufp[0], Control.reloadedSize[0]) == 0) {
enabled = OSDisableInterrupts();
if (__SCGetConfBuf() != Control.reloadBufp[0]) {
memcpy(__SCGetConfBuf(), Control.reloadBufp[0], __SCGetConfBufSize());
}
__SCClearDirtyFlag();
OSRestoreInterrupts(enabled);
} else {
enabled = OSDisableInterrupts();
ClearConfBuf(Control.reloadBufp[0]);
__SCClearDirtyFlag();
OSRestoreInterrupts(enabled);
}
ret = 0;
SetBgJobStatus(ret);
} else {
OSRestoreInterrupts(enabled);
}
return ret;
}
s32 SCReloadConfFileAsync(u8* bufp, u32 bufSize, SCReloadConfFileCallback callback) {
u32 i;
ASSERTLINE(392, bufp != NULL);
ASSERTLINE(393, ((u32)bufp & 0x1f) == 0);
if (bufSize < __SCGetConfBufSize()) {
return -128;
}
SetBgJobStatus(1);
Control.reloadCallback = callback;
Control.reloadResult = 0;
Control.reloadFileCount = 0;
for (i = 0; i < 2; i++) {
Control.reloadedSize[i] = 0;
}
Control.reloadFileName[0] = ConfFileName;
Control.reloadFileName[1] = ProductInfoFileName;
Control.reloadBufp[0] = bufp;
Control.reloadBufp[1] = (u8*)OSPhysicalToCached(0x3800);
Control.reloadSizeExpected[0] = __SCGetConfBufSize();
Control.reloadSizeExpected[1] = 0x100;
ClearConfBuf(bufp);
ItemIDOffsetTblOffset = 0;
ItemNumTotal = 0;
ItemRestSize = 0;
Control.nandNeedClose = FALSE;
return NANDPrivateOpenAsync(Control.reloadFileName[Control.reloadFileCount],
&Control.nandFileInfo, 1, OpenCallbackFromReload,
&Control.nandCommandBlock);
}
static void OpenCallbackFromReload(s32 result, NANDCommandBlock* block) {
if (result == 0) {
Control.nandNeedClose = TRUE;
if (NANDReadAsync(&Control.nandFileInfo, Control.reloadBufp[Control.reloadFileCount],
Control.reloadSizeExpected[Control.reloadFileCount],
ReadCallbackFromReload, &Control.nandCommandBlock) == 0)
{
return;
}
}
ErrorFromReload(result);
}
static void ReadCallbackFromReload(s32 result, NANDCommandBlock* block) {
if (result == Control.reloadSizeExpected[Control.reloadFileCount]) {
Control.reloadedSize[Control.reloadFileCount] = (u32)result;
Control.nandNeedClose = FALSE;
if (NANDCloseAsync(&Control.nandFileInfo, CloseCallbackFromReload,
&Control.nandCommandBlock) == 0)
{
return;
}
}
ErrorFromReload((s32)((result == 0) ? -128 : result));
}
static void CloseCallbackFromReload(s32 result, NANDCommandBlock* block) {
if (result == 0) {
FinishFromReload();
return;
}
ErrorFromReload(result);
}
void FinishFromReload(void) {
u32 status;
nextFile:
Control.reloadFileCount++;
if (Control.reloadFileCount < 2) {
Control.nandNeedClose = FALSE;
if (NANDPrivateOpenAsync(Control.reloadFileName[Control.reloadFileCount],
&Control.nandFileInfo, 1, OpenCallbackFromReload,
&Control.nandCommandBlock) == 0)
{
return;
}
goto nextFile;
}
switch (Control.reloadResult) {
case 0:
status = 3;
break;
default:
case -12:
ClearConfBuf(Control.reloadBufp[0]);
Control.reloadedSize[0] = Control.reloadSizeExpected[0];
status = 3;
break;
}
*(u8*)((u8*)OSPhysicalToCached(0x3800) + 0x100 - 1) = '\0';
if (Control.reloadCallback) {
Control.reloadCallback(Control.reloadResult);
Control.reloadCallback = NULL;
}
SetBgJobStatus(status);
}
static void ErrorFromReload(s32 result) {
if (Control.reloadFileCount == 0) {
Control.reloadResult = result;
}
Control.reloadedSize[Control.reloadFileCount] = 0;
if (Control.nandNeedClose) {
if (NANDCloseAsync(&Control.nandFileInfo, CloseCallbackFromReloadError,
&Control.nandCommandBlock) == 0)
{
return;
}
}
FinishFromReload();
}
static void CloseCallbackFromReloadError(s32 result, NANDCommandBlock* block) {
FinishFromReload();
}
static void ClearConfBuf(u8* bufp) {
u32 size = __SCGetConfBufSize();
memset(bufp, 0, size);
if (size > 12) {
memcpy(bufp, "SCv0", 4);
memcpy(bufp + (size - 4), "SCed", 4);
*((u16*)bufp + 3) = 8;
}
}
u32 ParseConfBuf(u8* bufp, u32 bufSize) {
u8 *bufTop, *bufEndp;
u32 numItems, loopItem;
SCItem item;
u32 itemOffset;
u16* itemOfsp;
u16* runtimeRefp;
u32 restSize;
NameAndID* tblp = NameAndIDTbl;
NameAndID* tblEndp;
char* name;
ASSERTLINE(576, bufp != NULL);
ASSERTLINE(577, ((u32)bufp & 0x1f) == 0);
if ((bufSize < 12) || (bufSize > __SCGetConfBufSize())) {
goto error;
}
bufTop = bufp;
bufEndp = bufp + bufSize - 4;
ItemIDMaxPlus1 = SC_ITEM_ID_MAX_PLUS1;
if (memcmp(bufp, "SCv0", 4) || memcmp(bufEndp, "SCed", 4)) {
goto error;
}
bufp += 4;
if (bufSize < __SCGetConfBufSize()) {
u32 expandSize = __SCGetConfBufSize() - bufSize;
memset(bufEndp, 0, expandSize);
bufEndp += expandSize;
memcpy(bufEndp, "SCed", 4);
}
if (ParseGetBEValue(bufp, bufEndp, &numItems, 2) == FALSE) {
goto error;
}
bufp += 2;
itemOfsp = (u16*)bufp;
itemOffset = ((u8*)(itemOfsp + numItems + 1) - bufTop);
for (loopItem = 0; loopItem < numItems; loopItem++) {
if (itemOffset > bufSize || ((u8*)&itemOfsp[loopItem] - bufTop) > bufSize) {
goto error;
}
if (itemOffset != itemOfsp[loopItem] || UnpackItem(bufTop + itemOffset, &item) == FALSE) {
goto error;
}
itemOffset += item.packedSize;
}
if (itemOffset > bufSize) {
goto error;
}
if (itemOffset != itemOfsp[loopItem]) {
goto error;
}
runtimeRefp = (u16*)(bufEndp - 2 * (SC_ITEM_ID_MAX_PLUS1));
if ((u8*)(bufTop + itemOffset) > (u8*)runtimeRefp) {
goto error;
}
restSize = (u32)((u8*)runtimeRefp - (u8*)(bufTop + itemOffset));
memset(runtimeRefp, 0, (u32)(bufEndp - (u8*)runtimeRefp));
runtimeRefp = (u16*)(bufEndp - 2);
tblEndp = tblp + ItemIDMaxPlus1;
while (tblp < tblEndp && (name = tblp->name) != NULL) {
u32 nameLen;
u8* p;
nameLen = strlen(name);
for (loopItem = 0; loopItem < numItems; loopItem++) {
p = bufTop + itemOfsp[loopItem];
if (nameLen == (u32)(((*p) & 0x1F) + 1) &&
memcmp(name, p + sizeof(SCType), nameLen) == 0)
{
runtimeRefp[-tblp->id] = (u16)((u8*)(&itemOfsp[loopItem]) - bufTop);
break;
}
}
tblp++;
}
ItemIDOffsetTblOffset = (u32)((u8*)runtimeRefp - bufTop);
ItemNumTotal = numItems;
ItemRestSize = restSize;
return 0;
error:
return 2;
}
static BOOL ParseGetBEValue(const u8* bufp, const u8* bufEndp, u32* varp, u32 varSize) {
u32 value = 0;
if ((bufp + varSize) > bufEndp) {
return FALSE;
}
while (varSize) {
value = (value << 8) | *bufp;
bufp++;
varSize--;
}
*varp = value;
return TRUE;
}
static BOOL UnpackItem(const u8* bufp, SCItem* itemp) {
SCType type;
ASSERTLINE(698, bufp != NULL);
ASSERTLINE(699, itemp != NULL);
memset(itemp, 0, sizeof(SCItem));
type = (u8)(*bufp & 0xE0);
itemp->name = (char*)(bufp + sizeof(SCType));
itemp->nameLen = (u32)((*bufp & 0x1F) + 1);
itemp->data = (u8*)(bufp + sizeof(SCType) + itemp->nameLen);
switch (type) {
case 0x60:
case 0xE0:
itemp->dataSize = sizeof(u8);
break;
case 0x80:
itemp->dataSize = sizeof(u16);
break;
case 0xA0:
itemp->dataSize = sizeof(u32);
break;
case 0xC0:
itemp->dataSize = sizeof(u64);
break;
case 0x40:
itemp->dataSize = (u32)(*(itemp->data) + 1);
itemp->data++;
itemp->packedSize++;
break;
case 0x20:
itemp->dataSize = (u32)((((*(itemp->data)) << 8) | (*(itemp->data + 1))) + 1);
itemp->data += 2;
itemp->packedSize += 2;
break;
default:
goto err;
}
if (type == 0x40 || type == 0x20) {
itemp->typeByteArray = 0x40;
} else {
itemp->typeInteger = type;
memcpy(&itemp->integer, itemp->data, itemp->dataSize);
}
itemp->packedSize += sizeof(SCType) + itemp->nameLen + itemp->dataSize;
{
const char* typeString;
switch (type) {
case 0x60:
typeString = "U8/S8";
break;
case 0xE0:
typeString = "BOOL";
break;
case 0x80:
typeString = "U16/S16";
break;
case 0xA0:
typeString = "U32/S32";
break;
case 0xC0:
typeString = "U64/S64";
break;
case 0x40:
case 0x20:
typeString = "ARRAY";
break;
default:
typeString = "UNKNOWN";
}
}
err:
return (itemp->dataSize != 0);
}
static BOOL FindItemByID(SCItemID id, SCItem* itemp) {
u8* conf = __SCGetConfBuf();
u16* refp;
if (id < ItemIDMaxPlus1 && ItemIDOffsetTblOffset != 0) {
refp = (u16*)(conf + ItemIDOffsetTblOffset);
if (refp[-id] != 0) {
return UnpackItem(conf + *(u16*)(conf + refp[-id]), itemp);
}
}
return FALSE;
}
void DeleteItemByID(SCItemID id) {
u8* conf = __SCGetConfBuf();
u32 targetRef, initialTopOfFreeSpace, moveSize, shrinkSize, i;
u16 *refp, *itemOfsTop, *itemOfsTargetp, *itemOfsEndp, *itemOfsp;
if (id < ItemIDMaxPlus1 && ItemIDOffsetTblOffset != 0) {
refp = (u16*)(conf + ItemIDOffsetTblOffset);
targetRef = refp[-id];
if (targetRef != 0 && ItemNumTotal != 0) {
itemOfsTop = (u16*)(conf + 4);
itemOfsTargetp = (u16*)(conf + targetRef);
itemOfsEndp = itemOfsTop + ItemNumTotal;
initialTopOfFreeSpace = *itemOfsEndp;
shrinkSize = 2 + (itemOfsTargetp[1] - itemOfsTargetp[0]);
moveSize = *itemOfsTargetp - (targetRef + 4);
memmove(conf + targetRef, conf + targetRef + 4, moveSize);
for (itemOfsp = itemOfsEndp - 1; itemOfsp >= itemOfsTop; itemOfsp--) {
if (itemOfsp < itemOfsTargetp) {
*itemOfsp -= 2;
} else {
*itemOfsp -= shrinkSize;
}
}
memmove(conf + itemOfsTargetp[0], conf + (itemOfsTargetp[0] + shrinkSize),
initialTopOfFreeSpace - (itemOfsTargetp[0] + shrinkSize));
memset(conf + (initialTopOfFreeSpace - shrinkSize), 0, shrinkSize);
for (i = 0; i < ItemIDMaxPlus1; i++) {
if (refp[-i] < targetRef) {
// empty branch?
} else if (refp[-i] > targetRef) {
refp[-i] -= 2;
} else {
refp[-i] = 0;
}
}
ItemRestSize += shrinkSize;
ItemNumTotal--;
*(u16*)(conf + 4) = (u16)ItemNumTotal;
__SCSetDirtyFlag();
}
}
}
BOOL CreateItemByID(SCItemID id, SCType type, const u8* data, u32 size) {
u8* conf = __SCGetConfBuf();
u8* p;
u32 nameLen;
u32 packedSize = sizeof(SCType);
NameAndID* tblp = NameAndIDTbl;
char* name;
u32 topOfFreeSpace;
u16* refp;
u16* itemOfsTop;
u16* itemOfsEndp;
u16* itemOfsp;
if (id < ItemIDMaxPlus1 && data != NULL && ItemNumTotal < 0xFFFF && ItemIDOffsetTblOffset != 0) {
switch (type) {
case 0xE0:
case 0x60:
size = 1;
break;
case 0x80:
size = 2;
break;
case 0xA0:
size = 4;
break;
case 0xC0:
size = 8;
break;
case 0x40:
if (size == 0 || size > 65536) {
goto error;
}
if (size > 256) {
packedSize += 2;
type = 0x20;
} else {
packedSize += 1;
}
break;
default:
goto error;
}
packedSize += size;
while ((name = tblp->name) != NULL) {
if (tblp->id == id) {
break;
}
tblp++;
}
if (name == NULL) {
goto error;
}
nameLen = strlen(name);
if (nameLen > 32) {
goto error;
}
packedSize += nameLen;
if (ItemRestSize < (2 + packedSize)) {
goto error;
}
itemOfsTop = (u16*)(conf + 6);
itemOfsEndp = itemOfsTop + ItemNumTotal;
topOfFreeSpace = *itemOfsEndp;
memmove(conf + (itemOfsTop[0] + 2), conf + itemOfsTop[0], topOfFreeSpace - itemOfsTop[0]);
itemOfsp = itemOfsTop;
do {
*itemOfsp += 2;
itemOfsp++;
} while (itemOfsp <= itemOfsEndp);
topOfFreeSpace = *itemOfsEndp;
p = (u8*)(conf + topOfFreeSpace);
*p = (SCType)(type | (nameLen - 1));
memcpy(p + sizeof(SCType), name, nameLen);
p += sizeof(SCType) + nameLen;
if (type == 0x40) {
*p++ = (u8)(size - 1);
} else if (type == 0x20) {
*p++ = (u8)((size - 1) >> 8);
*p++ = (u8)(size - 1);
}
memcpy(p, data, size);
p += size;
refp = (u16*)(conf + ItemIDOffsetTblOffset);
refp[-id] = (u16)((u8*)itemOfsEndp - conf);
itemOfsEndp[1] = (u16)(itemOfsEndp[0] + packedSize);
ItemRestSize -= 2 + packedSize;
ItemNumTotal++;
*(u16*)(conf + 4) = (u16)ItemNumTotal;
__SCSetDirtyFlag();
return TRUE;
}
error:
return FALSE;
}
BOOL SCFindByteArrayItem(void* data, u32 size, SCItemID id) {
SCItem item;
BOOL result = FALSE;
BOOL enabled = OSDisableInterrupts();
if (data != NULL && FindItemByID(id, &item) && item.typeByteArray != 0 && item.dataSize == size) {
memcpy(data, item.data, size);
result = TRUE;
}
OSRestoreInterrupts(enabled);
return result;
}
BOOL SCReplaceByteArrayItem(const void* data, u32 size, SCItemID id) {
SCItem item;
BOOL result = FALSE;
BOOL enabled = OSDisableInterrupts();
if (data != NULL) {
if (FindItemByID(id, &item)) {
if (item.typeByteArray != 0 && item.dataSize == size) {
if (memcmp(item.data, data, size) != 0) {
memcpy(item.data, data, size);
__SCSetDirtyFlag();
}
result = TRUE;
goto finish;
} else {
DeleteItemByID(id);
}
}
result = CreateItemByID(id, 0x40, data, size);
}
finish:
OSRestoreInterrupts(enabled);
return result;
}
BOOL SCFindIntegerItem(void* data, SCItemID id, SCType type) {
SCItem item;
BOOL result = FALSE;
BOOL enabled = OSDisableInterrupts();
ASSERTLINE(1126, data != NULL);
ASSERTLINE(1127, type != 0);
if (FindItemByID(id, &item) && item.typeInteger == type) {
memcpy(data, item.data, item.dataSize);
result = TRUE;
}
OSRestoreInterrupts(enabled);
return result;
}
BOOL SCReplaceIntegerItem(const void* data, SCItemID id, SCType type) {
SCItem item;
BOOL result = FALSE;
BOOL enabled = OSDisableInterrupts();
if (FindItemByID(id, &item)) {
if (item.typeInteger == type) {
if (memcmp(item.data, data, item.dataSize) != 0) {
memcpy(item.data, data, item.dataSize);
__SCSetDirtyFlag();
}
result = TRUE;
goto finish;
} else {
DeleteItemByID(id);
}
}
result = CreateItemByID(id, type, data, 0);
finish:
OSRestoreInterrupts(enabled);
return result;
}
BOOL SCFindU8Item(u8* data, SCItemID id) {
return SCFindIntegerItem(data, id, 0x60);
}
BOOL SCFindS8Item(s8* data, SCItemID id) {
return SCFindIntegerItem(data, id, 0x60);
}
BOOL SCFindU32Item(u32* data, SCItemID id) {
return SCFindIntegerItem(data, id, 0xA0);
}
BOOL SCReplaceU8Item(u8 data, SCItemID id) {
return SCReplaceIntegerItem(&data, id, 0x60);
}
static void __SCFlushSyncCallback(u32 status) {
OSWakeupThread(&Control.threadQueue);
}
void SCFlushAsync(SCFlushCallback callback) {
SCControl* ctrl;
BOOL enabled;
u8 status;
ctrl = &Control;
enabled = OSDisableInterrupts();
status = BgJobStatus;
if (status == 0) {
SetBgJobStatus(1);
if (callback == NULL) {
callback = __SCFlushSyncCallback;
}
ctrl->flushCallback = callback;
ctrl->flushResult = 0;
ctrl->nandNeedClose = FALSE;
ctrl->flushSize = __SCGetConfBufSize();
if (!__SCIsDirty()) {
OSRestoreInterrupts(enabled);
FinishFromFlush();
} else {
__SCClearDirtyFlag();
memcpy(ConfBufForFlush, __SCGetConfBuf(), __SCGetConfBufSize());
OSRestoreInterrupts(enabled);
ctrl->nandStep = 0;
if (NANDPrivateGetTypeAsync(ConfFileName, &ctrl->u.nandType, MyNandCallback, &ctrl->nandCommandBlock) != NAND_RESULT_OK) {
ErrorFromFlush();
}
}
} else {
if (callback != NULL) {
callback(status == 1 ? status : 2);
}
OSRestoreInterrupts(enabled);
}
}
void MyNandCallback(s32 result, NANDCommandBlock* block) {
SCControl* ctrl = &Control;
switch (ctrl->nandStep) {
case 0:
if (result == NAND_RESULT_OK && ctrl->u.nandType == 1) {
ctrl->nandStep = 1;
if (NANDPrivateGetStatusAsync(ConfFileName, &ctrl->u.nandStatus, MyNandCallback, &ctrl->nandCommandBlock) != NAND_RESULT_OK) {
break;
}
} else {
goto _case_1_lbl;
}
return;
case 1:
if (result == NAND_RESULT_OK && ctrl->u.nandStatus.permission == NAND_PERM_RWALL) {
goto _case_5_lbl;
}
_case_1_lbl:
ctrl->nandStep = 2;
if (NANDPrivateDeleteAsync(ConfFileName, MyNandCallback, &ctrl->nandCommandBlock) != NAND_RESULT_OK) {
break;
}
return;
case 2:
ctrl->nandStep = 3;
if (NANDPrivateGetTypeAsync(ConfDirName, &ctrl->u.nandType, MyNandCallback, &ctrl->nandCommandBlock) != NAND_RESULT_OK) {
break;
}
return;
case 3:
if (result == NAND_RESULT_OK && ctrl->u.nandType == 2) {
goto _case_4_lbl;
}
ctrl->nandStep = 4;
if (NANDPrivateCreateDirAsync(ConfDirName, NAND_PERM_RWALL, 0, MyNandCallback, &ctrl->nandCommandBlock) != NAND_RESULT_OK) {
break;
}
return;
case 4:
_case_4_lbl:
ctrl->nandStep = 5;
if (NANDPrivateCreateAsync(ConfFileName, NAND_PERM_RWALL, 0, MyNandCallback, &ctrl->nandCommandBlock) != NAND_RESULT_OK) {
break;
}
return;
case 5:
_case_5_lbl:
ctrl->nandStep = 6;
if (NANDPrivateOpenAsync(ConfFileName, &ctrl->nandFileInfo, NAND_ACCESS_WRITE, MyNandCallback, &ctrl->nandCommandBlock) != NAND_RESULT_OK) {
break;
}
return;
case 6:
if (result != NAND_RESULT_OK) {
break;
}
ctrl->nandNeedClose = TRUE;
ctrl->nandStep = 7;
if (NANDWriteAsync(&ctrl->nandFileInfo, ConfBufForFlush, ctrl->flushSize, MyNandCallback, &ctrl->nandCommandBlock) != NAND_RESULT_OK) {
break;
}
return;
case 7:
if (result != ctrl->flushSize) {
break;
}
ctrl->nandNeedClose = FALSE;
ctrl->nandStep = 8;
if (NANDCloseAsync(&ctrl->nandFileInfo, MyNandCallback, &ctrl->nandCommandBlock) != NAND_RESULT_OK) {
break;
}
return;
case 8:
if (result != NAND_RESULT_OK) {
break;
}
case 9:
FinishFromFlush();
default:
return;
}
ErrorFromFlush();
}
static void FinishFromFlush(void) {
SCControl* ctrl;
SCFlushCallback callback;
ctrl = &Control;
if (ctrl->flushResult != 0) {
__SCSetDirtyFlag();
}
callback = ctrl->flushCallback;
if (callback) {
ctrl->flushCallback = NULL;
callback(ctrl->flushResult);
if (ctrl->threadQueue.head != NULL) {
OSWakeupThread(&ctrl->threadQueue);
}
}
SetBgJobStatus(ctrl->flushResult);
}
static void ErrorFromFlush(void) {
SCControl* ctrl;
ctrl = &Control;
ctrl->flushResult = 2;
if (ctrl->nandNeedClose) {
ctrl->nandStep = 9;
if (NANDCloseAsync(&ctrl->nandFileInfo, MyNandCallback, &ctrl->nandCommandBlock) == NAND_RESULT_OK) {
return;
}
}
FinishFromFlush();
}
static BOOL __SCIsDirty(void) {
return DirtyFlag ? TRUE : FALSE;
}
static void __SCSetDirtyFlag(void) {
DirtyFlag = TRUE;
}
static void __SCClearDirtyFlag(void) {
DirtyFlag = FALSE;
}
static u8* __SCGetConfBuf(void) {
return ConfBuf;
}
static u32 __SCGetConfBufSize(void) {
return sizeof(ConfBuf);
}

821
src/revolution/si/SIBios.c Normal file
View File

@ -0,0 +1,821 @@
#include <revolution/si.h>
#include <revolution/vi.h>
#include "__os.h"
#define ROUND(n, a) (((u32)(n) + (a)-1) & ~((a)-1))
#ifdef SDK_AUG2010
#define BUILD_DATE "Aug 23 2010"
#if DEBUG
#define BUILD_TIME "17:27:56"
#else
#define BUILD_TIME "17:33:06"
#endif
#elif SDK_SEP2006
#define BUILD_DATE "Sep 21 2006"
#define BUILD_TIME "14:32:13"
#endif
#ifdef SDK_AUG2010
#if DEBUG
const char* __SIVersion = "<< RVL_SDK - SI \tdebug build: "BUILD_DATE" "BUILD_TIME" (0x4302_145) >>";
#else
const char* __SIVersion = "<< RVL_SDK - SI \trelease build: "BUILD_DATE" "BUILD_TIME" (0x4302_145) >>";
#endif
#elif SDK_SEP2006
const char* __SIVersion = "<< RVL_SDK - SI \trelease build: "BUILD_DATE" "BUILD_TIME" (0x4200_60422) >>";
#endif
static SIControl Si = {
/* chan */ -1,
/* poll */ 0,
/* inputBytes */ 0,
/* input */ NULL,
/* callback */ NULL
};
static SIPacket Packet[4];
static OSAlarm Alarm[4];
static u32 Type[4] = { SI_ERROR_NO_RESPONSE, SI_ERROR_NO_RESPONSE, SI_ERROR_NO_RESPONSE, SI_ERROR_NO_RESPONSE };
static OSTime TypeTime[4];
static OSTime XferTime[4];
static SITypeCallback TypeCallback[4][4];
static __OSInterruptHandler RDSTHandler[4];
static BOOL InputBufferValid[4];
static u32 InputBuffer[4][2];
static volatile u32 InputBufferVcount[4];
u32 __PADFixBits;
// prototypes
static u32 CompleteTransfer();
static void SITransferNext(s32 chan);
static void SIInterruptHandler(__OSInterrupt interrupt, OSContext* context);
static int __SITransfer(s32 chan, void* output, u32 outputBytes, void* input, u32 inputBytes, SICallback callback);
static void AlarmHandler(OSAlarm* alarm, OSContext* context);
static void GetTypeCallback(s32 chan, u32 error, OSContext* context);
static int SIGetResponseRaw(s32 chan);
BOOL SIBusy(void) {
return (Si.chan != -1) ? TRUE : FALSE;
}
BOOL SIIsChanBusy(s32 chan) {
return Packet[chan].chan != -1 || Si.chan == chan;
}
static void SIClearTCInterrupt(void) {
u32 reg;
reg = __SIRegs[SI_COMCSR_IDX];
reg |= SI_COMCSR_TCINT_MASK;
reg &= ~SI_COMCSR_TSTART_MASK;
__SIRegs[SI_COMCSR_IDX] = reg;
}
static u32 CompleteTransfer(void) {
u32 sr;
u32 i;
u32 rLen;
u8* input;
sr = __SIRegs[SI_STATUS_IDX];
SIClearTCInterrupt();
if (Si.chan != -1) {
XferTime[Si.chan] = __OSGetSystemTime();
input = Si.input;
rLen = Si.inputBytes / sizeof(u32);
for (i = 0; i < rLen; i++) {
*(u32*)input = __SIRegs[0x20 + i];
input += 4;
}
rLen = Si.inputBytes & 3;
if (rLen != 0) {
u32 temp = __SIRegs[i + 32];
for (i = 0; i < rLen; i++) {
*(input++) = temp >> ((3 - i) * 8);
}
}
if (__SIRegs[SI_COMCSR_IDX] & SI_COMCSR_COMERR_MASK) {
sr >>= (3 - Si.chan) * 8;
sr &= 0xF;
if ((sr & 8) != 0 && (Type[Si.chan] & 0x80) == 0) {
Type[Si.chan] = 8;
}
if (sr == 0) {
sr = 4;
}
} else {
TypeTime[Si.chan] = __OSGetSystemTime();
sr = 0;
}
Si.chan = -1;
}
return sr;
}
static void SITransferNext(s32 chan) {
int i;
SIPacket* packet;
for (i = 0; i < 4; i++) {
chan++;
chan %= 4;
packet = &Packet[chan];
if (packet->chan != -1) {
if (packet->fire <= __OSGetSystemTime()) {
if (__SITransfer(packet->chan, packet->output, packet->outputBytes, packet->input, packet->inputBytes, packet->callback) != 0) {
OSCancelAlarm(&Alarm[chan]);
packet->chan = -1;
}
break;
}
}
}
}
#define CHAN_NONE -1
static void SIInterruptHandler(__OSInterrupt interrupt, OSContext* context) {
u32 reg;
s32 chan;
u32 sr;
SICallback callback;
int i;
u32 vcount;
u32 x;
reg = __SIRegs[SI_COMCSR_IDX];
if ((reg & (SI_COMCSR_TCINT_MASK | SI_COMCSR_TCINTMSK_MASK)) == (SI_COMCSR_TCINT_MASK | SI_COMCSR_TCINTMSK_MASK)) {
ASSERTLINE(384, Si.chan != CHAN_NONE);
chan = Si.chan;
sr = CompleteTransfer();
callback = Si.callback;
Si.callback = NULL;
SITransferNext(chan);
if (callback) {
callback(chan, sr, context);
}
sr = __SIRegs[SI_STATUS_IDX];
sr &= 0x0F000000 >> (chan << 3);
__SIRegs[SI_STATUS_IDX] = sr;
if (Type[chan] == SI_ERROR_BUSY && !SIIsChanBusy(chan)) {
static u32 cmdTypeAndStatus;
SITransfer(chan, &cmdTypeAndStatus, 1, &Type[chan], 3, &GetTypeCallback, OSMicrosecondsToTicks(65));
}
}
if ((reg & (SI_COMCSR_RDSTINT_MASK | SI_COMCSR_RDSTINTMSK_MASK)) == (SI_COMCSR_RDSTINT_MASK | SI_COMCSR_RDSTINTMSK_MASK)) {
vcount = 1 + VIGetCurrentLine();
x = (Si.poll & (0x3FF << 16)) >> 16;
for (i = 0; i < 4; i++) {
if (SIGetResponseRaw(i)) {
InputBufferVcount[i] = vcount;
}
}
for (i = 0; i < 4; i++) {
if ((Si.poll & (0x80000000 >> (24 + i))) != 0) {
if (InputBufferVcount[i] == 0 || ((x >> 1) + InputBufferVcount[i]) < vcount) {
return;
}
}
}
for (i = 0; i < 4; i++) {
InputBufferVcount[i] = 0;
}
for (i = 0; i < 4; i++) {
if (RDSTHandler[i] != 0) {
(*RDSTHandler[i])(interrupt, context);
}
}
}
}
static BOOL SIEnablePollingInterrupt(BOOL enable) {
BOOL enabled;
BOOL rc;
u32 reg;
int i;
enabled = OSDisableInterrupts();
reg = __SIRegs[SI_COMCSR_IDX];
rc = ((reg & SI_COMCSR_RDSTINTMSK_MASK) != 0) ? TRUE : FALSE;
if (enable) {
reg |= SI_COMCSR_RDSTINTMSK_MASK;
for (i = 0; i < 4; i++) {
InputBufferVcount[i] = 0;
}
} else {
reg &= ~SI_COMCSR_RDSTINTMSK_MASK;
}
reg &= ~(SI_COMCSR_TCINT_MASK | SI_COMCSR_TSTART_MASK);
__SIRegs[SI_COMCSR_IDX] = reg;
OSRestoreInterrupts(enabled);
return rc;
}
BOOL SIRegisterPollingHandler(__OSInterruptHandler handler) {
BOOL enabled;
int i;
enabled = OSDisableInterrupts();
for (i = 0; i < 4; i++) {
if (RDSTHandler[i] == handler) {
OSRestoreInterrupts(enabled);
return TRUE;
}
}
for (i = 0; i < 4; i++) {
if (RDSTHandler[i] == 0) {
RDSTHandler[i] = handler;
SIEnablePollingInterrupt(TRUE);
OSRestoreInterrupts(enabled);
return TRUE;
}
}
OSRestoreInterrupts(enabled);
return FALSE;
}
BOOL SIUnregisterPollingHandler(__OSInterruptHandler handler) {
BOOL enabled;
int i;
enabled = OSDisableInterrupts();
for (i = 0; i < 4; i++) {
if (RDSTHandler[i] == handler) {
RDSTHandler[i] = 0;
for (i = 0; i < 4; i++) {
if (RDSTHandler[i] != 0) {
break;
}
}
if (i == 4) {
SIEnablePollingInterrupt(FALSE);
}
OSRestoreInterrupts(enabled);
return TRUE;
}
}
OSRestoreInterrupts(enabled);
return FALSE;
}
void SIInit(void) {
static BOOL Initialized = FALSE;
if (Initialized) {
return;
}
OSRegisterVersion(__SIVersion);
Packet[0].chan = Packet[1].chan = Packet[2].chan = Packet[3].chan = -1;
Si.poll = 0;
SISetSamplingRate(0);
do {} while(__SIRegs[SI_COMCSR_IDX] & SI_COMCSR_TSTART_MASK);
__SIRegs[SI_COMCSR_IDX] = SI_COMCSR_TCINT_MASK;
__OSSetInterruptHandler(0x14, SIInterruptHandler);
__OSUnmaskInterrupts(0x800);
SIGetType(0);
SIGetType(1);
SIGetType(2);
SIGetType(3);
Initialized = TRUE;
}
static int __SITransfer(s32 chan, void* output, u32 outputBytes, void* input, u32 inputBytes, SICallback callback) {
BOOL enabled;
u32 rLen;
u32 i;
u32 sr;
union {
u32 val;
struct {
u32 tcint : 1;
u32 tcintmsk : 1;
u32 comerr : 1;
u32 rdstint : 1;
u32 rdstintmsk : 1;
u32 pad2 : 4;
u32 outlngth : 7;
u32 pad1 : 1;
u32 inlngth : 7;
u32 pad0 : 5;
u32 channel : 2;
u32 tstart : 1;
} f;
} comcsr;
ASSERTMSGLINE(645, (chan >= 0) && (chan < 4), "SITransfer(): invalid channel.");
ASSERTMSGLINE(647, (outputBytes != 0) && (outputBytes <= 128), "SITransfer(): output size is out of range (must be 1 to 128).");
ASSERTMSGLINE(649, (inputBytes != 0) && (inputBytes <= 128), "SITransfer(): input size is out of range (must be 1 to 128).");
enabled = OSDisableInterrupts();
if (Si.chan != -1) {
OSRestoreInterrupts(enabled);
return 0;
}
ASSERTLINE(659, (__SIRegs[SI_COMCSR_IDX] & (SI_COMCSR_TSTART_MASK | SI_COMCSR_TCINT_MASK)) == 0);
sr = __SIRegs[SI_STATUS_IDX];
sr &= (0x0F000000 >> (chan* 8));
__SIRegs[SI_STATUS_IDX] = sr;
Si.chan = chan;
Si.callback = callback;
Si.inputBytes = inputBytes;
Si.input = input;
rLen = ROUND(outputBytes, 4) / 4;
for (i = 0; i < rLen; i++) {
__SIRegs[i + 0x20] = ((u32*)output)[i];
}
comcsr.val = __SIRegs[SI_COMCSR_IDX];
comcsr.f.tcint = 1;
comcsr.f.tcintmsk = callback ? 1 : 0;
comcsr.f.outlngth = outputBytes == 0x80 ? 0 : outputBytes;
comcsr.f.inlngth = inputBytes == 0x80 ? 0 : inputBytes;
comcsr.f.channel = chan;
comcsr.f.tstart = 1;
__SIRegs[SI_COMCSR_IDX] = comcsr.val;
OSRestoreInterrupts(enabled);
return 1;
}
u32 SISync(void) {
BOOL enabled;
u32 sr;
do {} while(__SIRegs[SI_COMCSR_IDX] & SI_COMCSR_TSTART_MASK);
enabled = OSDisableInterrupts();
sr = CompleteTransfer();
SITransferNext(4);
OSRestoreInterrupts(enabled);
return sr;
}
u32 SIGetStatus(s32 chan) {
BOOL enabled;
u32 sr;
int chanShift;
enabled = OSDisableInterrupts();
sr = __SIRegs[SI_STATUS_IDX];
chanShift = (3 - chan) * 8;
sr >>= chanShift;
if ((sr & 8) != 0) {
if ((Type[chan] & SI_ERROR_BUSY) == 0) {
Type[chan] = 8;
}
}
OSRestoreInterrupts(enabled);
return sr;
}
void SISetCommand(s32 chan, u32 command) {
ASSERTMSGLINE(770, (chan >= 0) && (chan < 4), "SISetCommand(): invalid channel.");
__SIRegs[chan* 3] = command;
}
u32 SIGetCommand(s32 chan) {
ASSERTMSGLINE(770, (chan >= 0) && (chan < 4), "SIGetCommand(): invalid channel.");
return __SIRegs[chan* 3];
}
void SITransferCommands(void) {
__SIRegs[SI_STATUS_IDX] = SI_COMCSR_TCINT_MASK;
}
u32 SISetXY(u32 x, u32 y) {
u32 poll;
BOOL enabled;
ASSERTMSGLINE(821, x >= 8, "SISetXY(): x is out of range (8 <= x <= 1023).");
ASSERTMSGLINE(822, x <= 1023, "SISetXY(): x is out of range (8 <= x <= 1023).");
ASSERTMSGLINE(823, y <= 255, "SISetXY(): y is out of range (0 <= y <= 255).");
poll = x << 0x10;
poll |= y << 8;
enabled = OSDisableInterrupts();
Si.poll &= 0xFC0000FF;
Si.poll |= poll;
poll = Si.poll;
__SIRegs[0x30 / 4] = poll;
OSRestoreInterrupts(enabled);
return poll;
}
u32 SIEnablePolling(u32 poll) {
BOOL enabled;
u32 en;
ASSERTMSGLINE(852, (poll & 0x0FFFFFFF) == 0, "SIEnablePolling(): invalid chan bit(s).");
if (poll == 0) {
return Si.poll;
}
enabled = OSDisableInterrupts();
poll = poll >> 24;
en = poll & 0xF0;
ASSERTLINE(883, en);
poll &= ((en >> 4) | 0x03FFFFF0);
poll &= 0xFC0000FF;
Si.poll &= ~(en >> 4);
Si.poll |= poll;
poll = Si.poll;
SITransferCommands();
__SIRegs[0x30 / 4] = poll;
OSRestoreInterrupts(enabled);
return poll;
}
u32 SIDisablePolling(u32 poll) {
BOOL enabled;
ASSERTMSGLINE(926, (poll & 0x0FFFFFFF) == 0, "SIDisablePolling(): invalid chan bit(s).");
if (poll == 0) {
return Si.poll;
}
enabled = OSDisableInterrupts();
poll = poll >> 24;
poll &= 0xF0;
ASSERTLINE(939, poll);
poll = Si.poll & ~poll;
__SIRegs[0x30 / 4] = poll;
Si.poll = poll;
OSRestoreInterrupts(enabled);
return poll;
}
static BOOL SIGetResponseRaw(s32 chan) {
u32 sr;
sr = SIGetStatus(chan);
if (sr & 0x20) {
InputBuffer[chan][0] = __SIRegs[1 + chan * 3];
InputBuffer[chan][1] = __SIRegs[2 + chan * 3];
InputBufferValid[chan] = TRUE;
return TRUE;
}
return FALSE;
}
BOOL SIGetResponse(s32 chan, void* data) {
BOOL rc;
BOOL enabled;
ASSERTMSGLINE(989, ((chan >= 0) && (chan < 4)), "SIGetResponse(): invalid channel.");
enabled = OSDisableInterrupts();
SIGetResponseRaw(chan);
rc = InputBufferValid[chan];
InputBufferValid[chan] = FALSE;
if (rc) {
((u32*)data)[0] = InputBuffer[chan][0];
((u32*)data)[1] = InputBuffer[chan][1];
}
OSRestoreInterrupts(enabled);
return rc;
}
static void AlarmHandler(OSAlarm* alarm, OSContext* context) {
s32 chan;
SIPacket* packet;
chan = (s32)(alarm - Alarm);
ASSERTLINE(1020, 0 <= chan && chan < SI_MAX_CHAN);
packet = &Packet[chan];
if (packet->chan != -1) {
ASSERTLINE(1024, packet->fire <= __OSGetSystemTime());
if (__SITransfer(packet->chan, packet->output, packet->outputBytes, packet->input, packet->inputBytes, packet->callback)) {
packet->chan = -1;
}
}
}
BOOL SITransfer(s32 chan, void* output, u32 outputBytes, void* input, u32 inputBytes,
SICallback callback, OSTime delay) {
BOOL enabled;
SIPacket* packet;
OSTime now;
OSTime fire;
packet = &Packet[chan];
enabled = OSDisableInterrupts();
if (packet->chan != -1 || Si.chan == chan) {
OSRestoreInterrupts(enabled);
return FALSE;
}
now = __OSGetSystemTime();
if (delay == 0) {
fire = now;
} else {
fire = delay + XferTime[chan];
}
if (now < fire) {
delay = fire - now;
OSSetAlarm(&Alarm[chan], delay, AlarmHandler);
} else if (__SITransfer(chan, output, outputBytes, input, inputBytes, callback)) {
OSRestoreInterrupts(enabled);
return TRUE;
}
packet->chan = chan;
packet->output = output;
packet->outputBytes = outputBytes;
packet->input = input;
packet->inputBytes = inputBytes;
packet->callback = callback;
packet->fire = fire;
OSRestoreInterrupts(enabled);
return TRUE;
}
static void CallTypeAndStatusCallback(s32 chan, u32 type) {
SITypeCallback callback;
int i;
for (i = 0; i < 4; i++) {
callback = TypeCallback[chan][i];
if (callback != 0) {
TypeCallback[chan][i] = 0;
(*callback)(chan, type);
}
}
}
static void GetTypeCallback(s32 chan, u32 error, OSContext* context) {
static u32 cmdFixDevice[4];
u32 type;
u32 chanBit;
int fix;
u32 id;
ASSERTLINE(1155, 0 <= chan && chan < SI_MAX_CHAN);
ASSERTLINE(1157, (Type[chan] & 0xff) == SI_ERROR_BUSY);
Type[chan] &= ~SI_ERROR_BUSY;
Type[chan] |= error;
TypeTime[chan] = __OSGetSystemTime();
type = Type[chan];
chanBit = 0x80000000 >> chan;
fix = __PADFixBits & chanBit;
__PADFixBits &= ~chanBit;
if ((error & 0xF) != 0 || (type & 0x18000000) != 0x08000000 || (type & 0x80000000) == 0 || (type & 0x04000000) != 0) {
OSSetWirelessID(chan, 0);
CallTypeAndStatusCallback(chan, Type[chan]);
} else {
id = OSGetWirelessID(chan) << 8;
if (fix != 0 && (id & 0x100000) != 0) {
cmdFixDevice[chan] = 0x4E000000 | (id & 0xCFFF00) | 0x100000;
Type[chan] = SI_ERROR_BUSY;
SITransfer(chan, &cmdFixDevice[chan], 3, &Type[chan], 3, &GetTypeCallback, 0);
return;
}
if ((type & 0x00100000) != 0) {
if ((id & 0xCFFF00) != (type & 0xCFFF00)) {
if ((id & 0x100000) == 0) {
id = type & 0xCFFF00;
id |= 0x100000;
OSSetWirelessID(chan, (id >> 8) & 0xFFFF);
}
cmdFixDevice[chan] = 0x4E000000 | id;
Type[chan] = SI_ERROR_BUSY;
SITransfer(chan, &cmdFixDevice[chan], 3, &Type[chan], 3, &GetTypeCallback, 0);
return;
}
} else {
if ((type & 0x40000000) != 0) {
id = type & 0xCFFF00;
id |= 0x100000;
OSSetWirelessID(chan, (id >> 8) & 0xFFFF);
cmdFixDevice[chan] = 0x4E000000 | id;
Type[chan] = SI_ERROR_BUSY;
SITransfer(chan, &cmdFixDevice[chan], 3, &Type[chan], 3, &GetTypeCallback, 0);
return;
}
OSSetWirelessID(chan, 0);
}
CallTypeAndStatusCallback(chan, Type[chan]);
}
}
u32 SIGetType(s32 chan) {
static u32 cmdTypeAndStatus;
BOOL enabled;
u32 type;
OSTime diff;
enabled = OSDisableInterrupts();
ASSERTLINE(1261, 0 <= chan && chan < SI_MAX_CHAN);
type = Type[chan];
diff = __OSGetSystemTime() - TypeTime[chan];
if ((Si.poll & (0x80 >> chan)) != 0) {
if (type != 8) {
TypeTime[chan] = __OSGetSystemTime();
OSRestoreInterrupts(enabled);
return type;
}
type = Type[chan] = SI_ERROR_BUSY;
} else {
if (diff <= OSMillisecondsToTicks(50) && type != 8) {
OSRestoreInterrupts(enabled);
return type;
}
if (diff <= OSMillisecondsToTicks(75)) {
Type[chan] = SI_ERROR_BUSY;
} else {
type = Type[chan] = SI_ERROR_BUSY;
}
}
TypeTime[chan] = __OSGetSystemTime();
SITransfer(chan, &cmdTypeAndStatus, 1, &Type[chan], 3, &GetTypeCallback, OSMicrosecondsToTicks(65));
OSRestoreInterrupts(enabled);
return type;
}
u32 SIGetTypeAsync(s32 chan, SITypeCallback callback) {
BOOL enabled;
u32 type;
enabled = OSDisableInterrupts();
type = SIGetType(chan);
if ((Type[chan] & SI_ERROR_BUSY) != 0) {
int i;
for (i = 0; i < SI_MAX_TYPE; i++) {
if (TypeCallback[chan][i] == callback) {
break;
}
if (TypeCallback[chan][i] == 0) {
TypeCallback[chan][i] = callback;
break;
}
}
ASSERTLINE(1342, i < SI_MAX_TYPE);
} else {
(*callback)(chan, type);
}
OSRestoreInterrupts(enabled);
return type;
}
u32 SIDecodeType(u32 type) {
u32 error;
error = type & 0xFF;
type &= ~0xFF;
if (error & SI_ERROR_NO_RESPONSE) {
return SI_ERROR_NO_RESPONSE;
}
if (error & (SI_ERROR_UNKNOWN | SI_ERROR_COLLISION | SI_ERROR_OVER_RUN | SI_ERROR_UNDER_RUN)) {
return SI_ERROR_UNKNOWN;
}
if (error != 0) {
ASSERTLINE(1371, error == SI_ERROR_BUSY);
return SI_ERROR_BUSY;
}
if ((type & SI_TYPE_MASK) == SI_TYPE_N64) {
switch (type & 0xFFFF0000) {
case SI_N64_MIC:
case SI_N64_KEYBOARD:
case SI_GBA:
case SI_N64_MOUSE:
case SI_N64_CONTROLLER:
return type & 0xFFFF0000;
default:
return SI_ERROR_UNKNOWN;
}
}
if ((type & SI_TYPE_MASK) != SI_TYPE_DOLPHIN) {
return SI_ERROR_UNKNOWN;
}
switch (type & 0xFFFF0000) {
case SI_GC_STEERING:
case SI_GC_CONTROLLER:
return type & 0xFFFF0000;
}
if ((type & 0xFFE00000) == SI_GC_KEYBOARD) {
return SI_GC_KEYBOARD;
}
if ((type & SI_GC_WIRELESS) != 0 && (type & SI_WIRELESS_IR) == 0) {
if ((type & SI_GC_WAVEBIRD) == SI_GC_WAVEBIRD) {
return SI_GC_WAVEBIRD;
}
if ((type & SI_WIRELESS_STATE) == 0) {
return SI_GC_RECEIVER;
}
}
if ((type & SI_GC_CONTROLLER) == SI_GC_CONTROLLER) {
return SI_GC_CONTROLLER;
}
return SI_ERROR_UNKNOWN;
}
u32 SIProbe(s32 chan) {
return SIDecodeType(SIGetType(chan));
}
char* SIGetTypeString(u32 type) {
switch (SIDecodeType(type)) {
case SI_ERROR_NO_RESPONSE:
return "No response";
case SI_ERROR_BUSY:
return "Busy";
case SI_N64_CONTROLLER:
return "N64 controller";
case SI_N64_MIC:
return "N64 microphone";
case SI_N64_KEYBOARD:
return "N64 keyboard";
case SI_N64_MOUSE:
return "N64 mouse";
case SI_GBA:
return "GameBoy Advance";
case SI_GC_CONTROLLER:
return "Standard controller";
case SI_GC_RECEIVER:
return "Wireless receiver";
case SI_GC_WAVEBIRD:
return "WaveBird controller";
case SI_GC_KEYBOARD:
return "Keyboard";
case SI_GC_STEERING:
return "Steering";
case SI_ERROR_UNKNOWN:
default:
return "Unknown";
}
}

View File

@ -0,0 +1,125 @@
#include <revolution.h>
#include <revolution/si.h>
#include "__os.h"
#define LATENCY 8
static u32 SamplingRate = 0;
typedef struct XY {
u16 line;
u8 count;
} XY;
static XY XYNTSC[12] = {
{0x00F6, 0x02},
{0x000E, 0x13},
{0x001E, 0x09},
{0x002C, 0x06},
{0x0034, 0x05},
{0x0041, 0x04},
{0x0057, 0x03},
{0x0057, 0x03},
{0x0057, 0x03},
{0x0083, 0x02},
{0x0083, 0x02},
{0x0083, 0x02},
};
static XY XYPAL[12] = {
{0x0128, 0x02},
{0x000F, 0x15},
{0x001D, 0x0B},
{0x002D, 0x07},
{0x0034, 0x06},
{0x003F, 0x05},
{0x004E, 0x04},
{0x0068, 0x03},
{0x0068, 0x03},
{0x0068, 0x03},
{0x0068, 0x03},
{0x009C, 0x02},
};
void SISetSamplingRate(u32 msec) {
XY* xy;
BOOL progressive;
BOOL enabled;
ASSERTMSGLINE(387, msec <= 11, "SISetSamplingRate(): out of rage (0 <= msec <= 11)");
if (msec > 11) {
msec = 11;
}
enabled = OSDisableInterrupts();
SamplingRate = msec;
switch (VIGetTvFormat()) {
case VI_NTSC:
case VI_MPAL:
case VI_EURGB60:
xy = XYNTSC;
break;
case VI_PAL:
xy = XYPAL;
break;
default:
OSReport("SISetSamplingRate: unknown TV format. Use default.");
msec = 0;
xy = XYNTSC;
break;
}
progressive = __VIRegs[VI_CLOCK_SEL] & 1;
SISetXY((progressive ? 2 : 1) * xy[msec].line, xy[msec].count);
OSRestoreInterrupts(enabled);
}
void SIRefreshSamplingRate(void) {
SISetSamplingRate(SamplingRate);
}
#if DEBUG
void __SITestSamplingRate(u32 tvmode) {
u32 msec;
u32 line;
u32 count;
XY* xy;
switch (tvmode) {
case VI_NTSC:
case VI_MPAL:
xy = XYNTSC;
for (msec = 0; msec <= 11; msec++) {
line = xy[msec].line;
count = xy[msec].count;
OSReport("%2d[msec]: count %3d, line %3d, last %3d, diff0 %2d.%03d, diff1 %2d.%03d\n",
msec, count, line, line * (count - 1) + LATENCY, (line * 636) / 10000, (line * 636) % 10000,
((263 - line * (count - 1)) * 636) / 10000, ((263 - line * (count - 1)) * 636) % 10000);
ASSERTLINE(446, line * (count - 1) + LATENCY < 263);
if (msec != 0) {
ASSERTLINE(449, 636 * line < msec * 10000);
ASSERTLINE(450, 636 * (263 - line * (count - 1)) < msec * 10000);
}
}
break;
case VI_PAL:
xy = XYPAL;
for (msec = 0; msec <= 11; msec++) {
line = xy[msec].line;
count = xy[msec].count;
OSReport("%2d[msec]: count %3d, line %3d, last %3d, diff0 %2d.%03d, diff1 %2d.%03d\n",
msec, count, line, line * (count - 1) + LATENCY, (line * 640) / 10000, (line * 640) % 10000,
((313 - line * (count - 1)) * 640) / 10000, ((313 - line * (count - 1)) * 640) % 10000);
ASSERTLINE(470, line * (count - 1) + LATENCY < 313);
if (msec != 0) {
ASSERTLINE(473, 640 * line < msec * 10000);
ASSERTLINE(474, 640 * (313 - line * (count - 1)) < msec * 10000);
}
}
break;
}
}
#endif

40
src/revolution/vi/__vi.h Normal file
View File

@ -0,0 +1,40 @@
#ifndef _REVOLUTION_VI_INTERNAL_H_
#define _REVOLUTION_VI_INTERNAL_H_
#include <revolution/vi.h>
#ifdef __cplusplus
extern "C" {
#endif
/* i2c.c */
int __VISendI2CData(u8 slaveAddr, u8* pData, int nBytes);
/* vi.c */
void __VIInit(VITVMode mode);
void __VISetAdjustingValues(s16 x, s16 y);
void __VIGetAdjustingValues(s16* x, s16* y);
void __VIGetCurrentPosition(s16* x, s16* y);
BOOL __VIResetDev0Idle();
/* vi3in1.c */
void __VISetFilter4EURGB60(VIBool enable);
void __VISetGamma1_0(void);
void __VISetYUVSEL(VIBool outsel);
void __VISetCGMS(void);
void __VISetWSS(void);
void __VISetClosedCaption(void);
void __VISetMacrovision(void);
void __VISetGamma(void);
void __VISetTrapFilter(void);
void __VISetRGBOverDrive(void);
void __VISetRGBModeImm(void);
void __VISetRevolutionModeSimple(void);
#ifdef __cplusplus
}
#endif
#endif

230
src/revolution/vi/i2c.c Normal file
View File

@ -0,0 +1,230 @@
#include <revolution/vi.h>
#include <revolution/os.h>
#include "__vi.h"
static volatile u32 __i2c_ident_flag = 1;
static volatile u32 __i2c_ident_first = 0;
#define busRd32(addr) (*(volatile u32 *)(addr))
#define busWrt32(addr, val) (*(volatile u32 *)(addr)) = (val)
void WaitMicroTime(s32 usec) {
OSTime t = __OSGetSystemTime();
while (((__OSGetSystemTime() - t) * 8) / 486 < usec);
}
static void VICheckI2C(void) {
__i2c_ident_flag = 1;
}
static BOOL __VISetSCL(u32 value) {
u32 reg;
value &= 1;
reg = busRd32(0xCD8000C0);
reg &= ~(1 << 14);
reg = (u32)(reg | (value << 14));
busWrt32(0xCD8000C0, reg);
return TRUE;
}
static BOOL __VISetSDA(u32 value) {
u32 reg;
value &= 1;
reg = busRd32(0xCD8000C0);
reg &= ~(1 << 15);
reg = (u32)(reg | (value << 15));
busWrt32(0xCD8000C0, reg);
return TRUE;
}
static u32 __VIGetSDA(void) {
u32 reg = busRd32(0xCD8000C8);
return (u32)((reg >> 15) & 1);
}
static void __VIOpenI2C(u32 dir) {
u32 reg = busRd32(0xCD8000C4);
reg = (u32)(reg & ~(1 << 15));
reg = (u32)(reg | (1 << 14) | (dir << 15));
busWrt32(0xCD8000C4, reg);
}
static int wait4ClkHigh(void) {
WaitMicroTime(2);
return 1;
}
static int sendSlaveAddr(u8 slaveAddr) {
int i;
if (0 == __i2c_ident_flag) {
__VISetSDA(1);
} else {
__VISetSDA(0);
}
WaitMicroTime(2);
__VISetSCL(0);
for (i = 0; i < 8; i++) {
if (slaveAddr & 0x80) {
if (0 == __i2c_ident_flag) {
__VISetSDA(0);
} else {
__VISetSDA(1);
}
} else {
if (0 == __i2c_ident_flag) {
__VISetSDA(1);
} else {
__VISetSDA(0);
}
}
WaitMicroTime(2);
__VISetSCL(1);
if (wait4ClkHigh() == 0) {
return 0;
}
__VISetSCL(0);
slaveAddr <<= 1;
}
__VIOpenI2C(0);
WaitMicroTime(2);
__VISetSCL(1);
if (wait4ClkHigh() == 0) {
return 0;
}
if (1 == __i2c_ident_flag) {
if (__VIGetSDA() != 0) {
return 0;
}
}
if (0 == __i2c_ident_flag) {
__VISetSDA(1);
} else {
__VISetSDA(0);
}
__VIOpenI2C(1);
__VISetSCL(0);
return 1;
}
int __VISendI2CData(u8 slaveAddr, u8* pData, int nBytes) {
s32 i;
u8 data;
BOOL enabled;
if (__i2c_ident_first == 0) {
VICheckI2C();
__i2c_ident_first = 1;
}
enabled = OSDisableInterrupts();
__VIOpenI2C(1);
__VISetSCL(1);
if (0 == __i2c_ident_flag) {
__VISetSDA(0);
} else {
__VISetSDA(1);
}
WaitMicroTime(2);
WaitMicroTime(2);
if (sendSlaveAddr(slaveAddr) == 0) {
OSRestoreInterrupts(enabled);
return 0;
}
__VIOpenI2C(1);
while (nBytes != 0) {
data = *pData++;
for (i = 0; i < 8; i++) {
if (data & 0x80) {
if (0 == __i2c_ident_flag) {
__VISetSDA(0);
} else {
__VISetSDA(1);
}
} else {
if (0 == __i2c_ident_flag) {
__VISetSDA(1);
} else {
__VISetSDA(0);
}
}
WaitMicroTime(2);
__VISetSCL(1);
if (wait4ClkHigh() == 0) {
OSRestoreInterrupts(enabled);
return 0;
}
__VISetSCL(0);
data <<= 1;
}
__VIOpenI2C(0);
WaitMicroTime(2);
__VISetSCL(1);
if (wait4ClkHigh() == 0) {
OSRestoreInterrupts(enabled);
return 0;
}
if (1 == __i2c_ident_flag) {
if (__VIGetSDA() != 0) {
OSRestoreInterrupts(enabled);
return 0;
}
}
if (0 == __i2c_ident_flag) {
__VISetSDA(1);
} else {
__VISetSDA(0);
}
__VIOpenI2C(1);
__VISetSCL(0);
nBytes--;
}
__VIOpenI2C(1);
if (0 == __i2c_ident_flag) {
__VISetSDA(1);
} else {
__VISetSDA(0);
}
WaitMicroTime(2);
__VISetSCL(1);
WaitMicroTime(2);
if (0 == __i2c_ident_flag) {
__VISetSDA(0);
} else {
__VISetSDA(1);
}
OSRestoreInterrupts(enabled);
return 1;
}

1703
src/revolution/vi/vi.c Normal file

File diff suppressed because it is too large Load Diff

501
src/revolution/vi/vi3in1.c Normal file
View File

@ -0,0 +1,501 @@
#include <revolution/os.h>
#include <revolution/vi.h>
static VIVideo Vdac_Flag_Region;
volatile u32 Vdac_Flag_Changed = 0;
static u32 __current_3in1_video_mode = 0;
static VIACPType __type;
static u32 __tvType = 0xFF;
static VIGammaObj gammaSet[] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0030,
0x0397, 0x3B49, 0x0010, 0x001D, 0x0036, 0x0058, 0x0082, 0x00B3, 0x00EB, 0x1000, 0x1000, 0x1000,
0x1000, 0x1080, 0x1B80, 0xEB00, 0x0000, 0x0028, 0x005A, 0x02DB, 0x0D8D, 0x3049, 0x0010, 0x001D,
0x0036, 0x0058, 0x0082, 0x00B3, 0x00EB, 0x1000, 0x1000, 0x1040, 0x1100, 0x1880, 0x4200, 0xEB00,
0x0000, 0x007A, 0x023C, 0x076D, 0x129C, 0x2724, 0x0010, 0x001D, 0x0036, 0x0058, 0x0082, 0x00B3,
0x00EB, 0x1000, 0x1000, 0x10C0, 0x1580, 0x2900, 0x6200, 0xEB00, 0x004E, 0x0199, 0x052D, 0x0B24,
0x1429, 0x20A4, 0x0010, 0x001D, 0x0036, 0x0058, 0x0082, 0x00B3, 0x00EB, 0x1000, 0x1040, 0x12C0,
0x1DC0, 0x3B00, 0x78C0, 0xEB00, 0x00EC, 0x03D7, 0x0800, 0x0D9E, 0x143E, 0x1BDB, 0x0010, 0x001D,
0x0036, 0x0058, 0x0082, 0x00B3, 0x00EB, 0x1000, 0x10C0, 0x16C0, 0x27C0, 0x4B80, 0x8980, 0xEB00,
0x0276, 0x0666, 0x0A96, 0x0EF3, 0x13AC, 0x1849, 0x0010, 0x001D, 0x0036, 0x0058, 0x0082, 0x00B3,
0x00EB, 0x1000, 0x1200, 0x1C00, 0x3280, 0x59C0, 0x9600, 0xEB00, 0x04EC, 0x08F5, 0x0C96, 0x0FCF,
0x12C6, 0x1580, 0x0010, 0x001D, 0x0036, 0x0058, 0x0082, 0x00B3, 0x00EB, 0x1000, 0x1400, 0x2200,
0x3CC0, 0x6640, 0x9FC0, 0xEB00, 0x0800, 0x0BAE, 0x0E00, 0x1030, 0x11CB, 0x1349, 0x0010, 0x001D,
0x0036, 0x0058, 0x0082, 0x00B3, 0x00EB, 0x1000, 0x1680, 0x28C0, 0x4680, 0x7100, 0xA780, 0xEB00,
0x0BB1, 0x0E14, 0x0F2D, 0x1018, 0x10E5, 0x1180, 0x0010, 0x001D, 0x0036, 0x0058, 0x0082, 0x00B3,
0x00EB, 0x1000, 0x1980, 0x2F80, 0x4FC0, 0x7A00, 0xADC0, 0xEB00, 0x1000, 0x1000, 0x1000, 0x1000,
0x1000, 0x1000, 0x10, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xEB, 0x1000, 0x2000, 0x4000,
0x6000, 0x8000, 0xA000, 0xEB00, 0x14EC, 0x11C2, 0x1078, 0x0FB6, 0x0F2F, 0x0EB6, 0x0010, 0x001D,
0x0036, 0x0058, 0x0082, 0x00B3, 0x00EB, 0x1000, 0x2100, 0x3CC0, 0x5FC0, 0x8900, 0xB780, 0xEB00,
0x19D8, 0x1333, 0x10D2, 0x0F6D, 0x0E5E, 0x0DA4, 0x0010, 0x001D, 0x0036, 0x0058, 0x0082, 0x00B3,
0x00EB, 0x1000, 0x2500, 0x4300, 0x66C0, 0x8F40, 0xBB40, 0xEB00, 0x1EC4, 0x147A, 0x110F, 0x0F0C,
0x0DA1, 0x0CB6, 0x0010, 0x001D, 0x0036, 0x0058, 0x0082, 0x00B3, 0x00EB, 0x1000, 0x2900, 0x4900,
0x6D40, 0x94C0, 0xBE80, 0xEB00, 0x2400, 0x1570, 0x110F, 0x0EAA, 0x0D0F, 0x0BDB, 0x0010, 0x001D,
0x0036, 0x0058, 0x0082, 0x00B3, 0x00EB, 0x1000, 0x2D40, 0x4EC0, 0x7300, 0x9980, 0xC180, 0xEB00,
0x293B, 0x163D, 0x110F, 0x0E30, 0x0C7D, 0x0B24, 0x0010, 0x001D, 0x0036, 0x0058, 0x0082, 0x00B3,
0x00EB, 0x1000, 0x3180, 0x5440, 0x7880, 0x9DC0, 0xC400, 0xEB00, 0x2E27, 0x170A, 0x10D2, 0x0DE7,
0x0BEB, 0x0A80, 0x0010, 0x001D, 0x0036, 0x0058, 0x0082, 0x00B3, 0x00EB, 0x1000, 0x3580, 0x5980,
0x7D40, 0xA1C0, 0xC640, 0xEB00, 0x3362, 0x175C, 0x10D2, 0x0D6D, 0x0B6D, 0x09ED, 0x0010, 0x001D,
0x0036, 0x0058, 0x0082, 0x00B3, 0x00EB, 0x1000, 0x39C0, 0x5E40, 0x8200, 0xA540, 0xC840, 0xEB00,
0x384E, 0x17AE, 0x10B4, 0x0D0C, 0x0AF0, 0x096D, 0x0010, 0x001D, 0x0036, 0x0058, 0x0082, 0x00B3,
0x00EB, 0x1000, 0x3DC0, 0x62C0, 0x8640, 0xA880, 0xCA00, 0xEB00, 0x3D3B, 0x1800, 0x105A, 0x0CC3,
0x0A72, 0x0900, 0x0010, 0x001D, 0x0036, 0x0058, 0x0082, 0x00B3, 0x00EB, 0x1000, 0x41C0, 0x6740,
0x8A00, 0xAB80, 0xCB80, 0xEB00, 0x41D8, 0x1828, 0x103C, 0x0C49, 0x0A1F, 0x0892, 0x0010, 0x001D,
0x0036, 0x0058, 0x0082, 0x00B3, 0x00EB, 0x1000, 0x4580, 0x6B40, 0x8DC0, 0xAE00, 0xCD00, 0xEB00,
0x4676, 0x1851, 0x0FE1, 0x0C00, 0x09B6, 0x0836, 0x0010, 0x001D, 0x0036, 0x0058, 0x0082, 0x00B3,
0x00EB, 0x1000, 0x4940, 0x6F40, 0x9100, 0xB080, 0xCE40, 0xEB00, 0x4AC4, 0x187A, 0x0FA5, 0x0B9E,
0x0963, 0x07DB, 0x0010, 0x001D, 0x0036, 0x0058, 0x0082, 0x00B3, 0x00EB, 0x1000, 0x4CC0, 0x7300,
0x9440, 0xB2C0, 0xCF80, 0xEB00, 0x4F13, 0x1851, 0x0F69, 0x0B6D, 0x090F, 0x0780, 0x0010, 0x001D,
0x0036, 0x0058, 0x0082, 0x00B3, 0x00EB, 0x1000, 0x5040, 0x7640, 0x9700, 0xB500, 0xD0C0, 0xEB00,
0x5313, 0x187A, 0x0F0F, 0x0B24, 0x08BC, 0x0736, 0x0010, 0x001D, 0x0036, 0x0058, 0x0082, 0x00B3,
0x00EB, 0x1000, 0x5380, 0x79C0, 0x99C0, 0xB700, 0xD1C0, 0xEB00, 0x5713, 0x1851, 0x0EF0, 0x0AC3,
0x087D, 0x06ED, 0x0010, 0x001D, 0x0036, 0x0058, 0x0082, 0x00B3, 0x00EB, 0x1000, 0x56C0, 0x7CC0,
0x9C80, 0xB8C0, 0xD2C0, 0xEB00, 0x5B13, 0x1828, 0x0E96, 0x0A92, 0x0829, 0x06B6, 0x0010, 0x001D,
0x0036, 0x0058, 0x0082, 0x00B3, 0x00EB, 0x1000, 0x5A00, 0x7FC0, 0x9EC0, 0xBA80, 0xD380, 0xEB00,
0x5EC4, 0x1800, 0x0E78, 0x0A30, 0x0800, 0x066D, 0x0010, 0x001D, 0x0036, 0x0058, 0x0082, 0x00B3,
0x00EB, 0x1000, 0x5D00, 0x8280, 0xA140, 0xBC00, 0xD480, 0xEB00, 0x6276, 0x17D7, 0x0E1E, 0x0A00,
0x07C1, 0x0636, 0x0010, 0x001D, 0x0036, 0x0058, 0x0082, 0x00B3, 0x00EB, 0x1000, 0x6000, 0x8540,
0xA340, 0xBD80, 0xD540, 0xEB00, 0x65D8, 0x17AE, 0x0DE1, 0x09CF, 0x0782, 0x0600, 0x0010, 0x001D,
0x0036, 0x0058, 0x0082, 0x00B3, 0x00EB, 0x1000, 0x62C0, 0x87C0, 0xA540, 0xBF00, 0xD600, 0xEB00,
0x693B, 0x1785, 0x0DA5, 0x0986, 0x0743, 0x05DB, 0x0010, 0x001D, 0x0036, 0x0058, 0x0082, 0x00B3,
0x00EB, 0x1000, 0x6580, 0x8A40, 0xA740, 0xC040, 0xD680, 0xEB00};
VIMacroVisionObj VINtscACPType1 = {0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B,
0x1B, 0x24, 0x07, 0xF8, 0x00, 0x00, 0x0F, 0x0F, 0x60,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
VIMacroVisionObj VINtscACPType2 = {0x3E, 0x1D, 0x11, 0x25, 0x11, 0x01, 0x07, 0x00, 0x1B,
0x1B, 0x24, 0x07, 0xF8, 0x00, 0x00, 0x0F, 0x0F, 0x60,
0x01, 0x0A, 0x00, 0x05, 0x04, 0x03, 0xFF, 0x00};
VIMacroVisionObj VINtscACPType3 = {0x3E, 0x17, 0x15, 0x21, 0x15, 0x05, 0x05, 0x02, 0x1B,
0x1B, 0x24, 0x07, 0xF8, 0x00, 0x00, 0x0F, 0x0F, 0x60,
0x01, 0x0A, 0x00, 0x05, 0x04, 0x03, 0xFF, 0x00};
VIMacroVisionObj VIPalACPType1 = {0x36, 0x1A, 0x22, 0x2A, 0x22, 0x05, 0x02, 0x00, 0x1C,
0x3D, 0x14, 0x03, 0xFE, 0x01, 0x54, 0xFE, 0x7E, 0x60,
0x00, 0x08, 0x00, 0x04, 0x07, 0x01, 0x55, 0x01};
VIMacroVisionObj VIPalACPType2 = {0x36, 0x1A, 0x22, 0x2A, 0x22, 0x05, 0x02, 0x00, 0x1C,
0x3D, 0x14, 0x03, 0xFE, 0x01, 0x54, 0xFE, 0x7E, 0x60,
0x00, 0x08, 0x00, 0x04, 0x07, 0x01, 0x55, 0x01};
VIMacroVisionObj VIPalACPType3 = {0x36, 0x1A, 0x22, 0x2A, 0x22, 0x05, 0x02, 0x00, 0x1C,
0x3D, 0x14, 0x03, 0xFE, 0x01, 0x54, 0xFE, 0x7E, 0x60,
0x00, 0x08, 0x00, 0x04, 0x07, 0x01, 0x55, 0x01};
VIMacroVisionObj VIEurgb60ACPType1 = {0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B,
0x1B, 0x24, 0x07, 0xF8, 0x00, 0x00, 0x1E, 0x1E, 0x60,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
VIMacroVisionObj VIEurgb60ACPType2 = {0x36, 0x1D, 0x11, 0x25, 0x11, 0x01, 0x07, 0x00, 0x1B,
0x1B, 0x24, 0x07, 0xF8, 0x00, 0x00, 0x1E, 0x1E, 0x60,
0x01, 0x0A, 0x00, 0x05, 0x04, 0x03, 0xFF, 0x01};
VIMacroVisionObj VIEurgb60ACPType3 = {0x36, 0x17, 0x15, 0x21, 0x15, 0x05, 0x05, 0x02, 0x1B,
0x1B, 0x24, 0x07, 0xF8, 0x00, 0x00, 0x1E, 0x1E, 0x60,
0x01, 0x0A, 0x00, 0x05, 0x04, 0x03, 0xFF, 0x01};
VIMacroVisionObj VIMpalACPType1 = {0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B,
0x1B, 0x24, 0x07, 0xF8, 0x00, 0x00, 0x0F, 0x0F, 0x60,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
VIMacroVisionObj VIMpalACPType2 = {0x36, 0x1D, 0x11, 0x25, 0x11, 0x01, 0x07, 0x00, 0x1B,
0x1B, 0x24, 0x07, 0xF8, 0x00, 0x00, 0x0F, 0x0F, 0x60,
0x01, 0x0A, 0x00, 0x05, 0x04, 0x03, 0xFF, 0x00};
VIMacroVisionObj VIMpalACPType3 = {0x36, 0x17, 0x15, 0x21, 0x15, 0x05, 0x05, 0x02, 0x1B,
0x1B, 0x24, 0x07, 0xF8, 0x00, 0x00, 0x0F, 0x0F, 0x60,
0x01, 0x0A, 0x00, 0x05, 0x04, 0x03, 0xFF, 0x00};
VIMacroVisionObj VIProgressiveACPType = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
VIMacroVisionObj VIZeroACPType = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
extern s32 __VISendI2CData(u8, u8*, s32);
extern void WaitMicroTime(s32);
static void __VISetVideoMode(VIVideo vmode, VIBool outsel) {
u8 buffer[2];
Vdac_Flag_Region = vmode;
buffer[0] = 1;
buffer[1] = (u8)((outsel << 5) | Vdac_Flag_Region);
__VISendI2CData(0xE0, buffer, 2);
WaitMicroTime(2);
}
static void __VISetCCSEL(VIBool ccsel) {
u8 buffer[2];
buffer[0] = 0x6A;
buffer[1] = VI_ENABLE;
__VISendI2CData((u8)0xE0, buffer, 2);
WaitMicroTime(2);
}
static void __VISetOverSampling(VIBool os) {
u8 buffer[2];
buffer[0] = 0x65;
buffer[1] = VI_ENABLE;
__VISendI2CData((u8)0xE0, buffer, 2);
WaitMicroTime(2);
}
void __VISetVolume(u8 volumeL, u8 volumeR) {
u8 buffer[3];
buffer[0] = 0x71;
buffer[1] = volumeL;
buffer[2] = volumeR;
__VISendI2CData((u8)0xE0, buffer, 3);
WaitMicroTime(2);
}
void __VISetYUVSEL(VIBool outsel) {
u8 buffer[2];
u32 tv;
tv = *(u32*)OSPhysicalToCached(0xCC);
switch (tv) {
case VI_PAL:
case VI_EURGB60:
Vdac_Flag_Region = VI_VMODE_PAL;
break;
case VI_MPAL:
Vdac_Flag_Region = VI_VMODE_MPAL;
break;
case VI_NTSC:
Vdac_Flag_Region = VI_VMODE_NTSC;
break;
default:
ASSERTMSGLINE(919, FALSE, "Unkwon TV mode!! TV mode is set to NTSC mode.\n");
Vdac_Flag_Region = VI_VMODE_NTSC;
break;
}
buffer[0] = 0x1;
buffer[1] = (u8)((outsel << 5) | Vdac_Flag_Region);
__VISendI2CData((u8)0xE0, buffer, 2);
WaitMicroTime(2);
}
void __VISetTiming(VITiming timing) {
u8 buffer[2];
buffer[0] = 0x0;
buffer[1] = timing;
__VISendI2CData((u8)0xE0, buffer, 2);
WaitMicroTime(2);
}
void __VISetFilter4EURGB60(VIBool enable) {
u8 buffer[2];
buffer[0] = 0x6E;
buffer[1] = (u8)enable;
__VISendI2CData((u8)0xE0, buffer, 2);
WaitMicroTime(2);
}
void __VISetVBICtrl(VIBool cgms, VIBool wss, VIBool cc) {
u8 buffer[2];
buffer[0] = 0x2;
buffer[1] = (u8)(((~wss & 0x1) << 2) | ((~cgms & 0x1) << 1) | (~cc & 0x1));
__VISendI2CData((u8)0xE0, buffer, 2);
WaitMicroTime(2);
}
static u8 __wd0 = 0xFF;
static u8 __wd1 = 0xFF;
static u8 __wd2 = 0xFF;
void __VISetCGMS(void) {
u8 buffer[3];
buffer[0] = 5;
buffer[1] = (u8)(((__wd1 & 0xF) << 2) | (__wd0 & 3));
buffer[2] = __wd2;
__VISendI2CData((u8)0xE0, buffer, 3);
WaitMicroTime(2);
}
void __VISetCGMSClear(void) {
__wd0 = 0;
__wd1 = 0;
__wd2 = 0;
__VISetCGMS();
}
// NOTE: function doesn't exist in TP debug, needed for string data
void VISetCGMS(void) {
OSReport("VISetCGMS(): Tried to set APS Trigger bit(WORD2[3:2]) \nwhen the scan is progressive in DTV mode, which is forbidden\n");
}
static u8 __gp1 = 0xFF;
static u8 __gp2 = 0xFF;
static u8 __gp3 = 0xFF;
static u8 __gp4 = 0xFF;
void __VISetWSS(void) {
u8 buffer[3];
buffer[0] = 0x8;
buffer[1] = (u8)(((__gp2 & 0xf) << 4) | (__gp1 & 0xf));
buffer[2] = (u8)(((__gp4 & 0x7) << 3) | (__gp3 & 0x7));
__VISendI2CData((u8)0xE0, buffer, 3);
WaitMicroTime(2);
}
void VISetWSS(u8 gp1, u8 gp2, u8 gp3, u8 gp4) {
if ((__gp1 == gp1) && (__gp2 == gp2) && (__gp3 == gp3) && (__gp4 == gp4)) {
return;
}
__gp1 = gp1;
__gp2 = gp2;
__gp3 = gp3;
__gp4 = gp4;
Vdac_Flag_Changed |= 2;
}
static u8 __cc1 = 0xFF;
static u8 __cc2 = 0xFF;
static u8 __cc3 = 0xFF;
static u8 __cc4 = 0xFF;
void __VISetClosedCaption(void) {
u8 buffer[5];
buffer[0] = 0x7A;
buffer[1] = (u8)(__cc1 & 0x7F);
buffer[2] = (u8)(__cc2 & 0x7F);
buffer[3] = (u8)(__cc3 & 0x7F);
buffer[4] = (u8)(__cc4 & 0x7F);
__VISendI2CData((u8)0xE0, buffer, 5);
WaitMicroTime(2);
}
void VISetClosedCaption(u8 cc1, u8 cc2, u8 cc3, u8 cc4) {
if ((__cc1 == cc1) && (__cc2 == cc2) && (__cc3 == cc3) && (__cc4 == cc4)) {
return;
}
__cc1 = cc1;
__cc2 = cc2;
__cc3 = cc3;
__cc4 = cc4;
Vdac_Flag_Changed |= 4;
}
void __VISetMacrovisionImm(VIMacroVisionObj* mparam) {
u8 i;
u8 buffer[27];
buffer[0] = 0x40;
for (i = 1; i < 27; i++) {
buffer[i] = mparam->m[i - 1];
}
__VISendI2CData((u8)0xE0, buffer, 27);
WaitMicroTime(2);
}
void __VISetMacrovision(void) {
switch (__type) {
case 2:
switch (__tvType) {
case VI_NTSC:
__VISetMacrovisionImm(&VINtscACPType1);
break;
case VI_PAL:
__VISetMacrovisionImm(&VIPalACPType1);
break;
case VI_MPAL:
__VISetMacrovisionImm(&VIMpalACPType1);
break;
case VI_EURGB60:
__VISetMacrovisionImm(&VIEurgb60ACPType1);
break;
}
break;
case 3:
switch (__tvType) {
case VI_NTSC:
__VISetMacrovisionImm(&VINtscACPType2);
break;
case VI_PAL:
__VISetMacrovisionImm(&VIPalACPType2);
break;
case VI_MPAL:
__VISetMacrovisionImm(&VIMpalACPType2);
break;
case VI_EURGB60:
__VISetMacrovisionImm(&VIEurgb60ACPType2);
break;
}
break;
case 4:
switch (__tvType) {
case VI_NTSC:
__VISetMacrovisionImm(&VINtscACPType3);
break;
case VI_PAL:
__VISetMacrovisionImm(&VIPalACPType3);
break;
case VI_MPAL:
__VISetMacrovisionImm(&VIMpalACPType3);
break;
case VI_EURGB60:
__VISetMacrovisionImm(&VIEurgb60ACPType3);
break;
}
break;
case 1:
__VISetMacrovisionImm(&VIZeroACPType);
break;
}
}
void __VISetGammaImm(VIGammaObj* gamma) {
u8 i, j;
u8 buffer[34];
buffer[0] = 0x10;
i = 1;
for (j = 0; j < 6; j++) {
buffer[i] = (u8)((gamma->a[j] >> 8) & 0xFF);
buffer[i + 1] = (u8)(gamma->a[j] & 0xFF);
i += 2;
}
for (j = 0; j < 7; j++) {
buffer[i] = gamma->yin[j];
i++;
}
for (j = 0; j < 7; j++) {
buffer[i] = (u8)((gamma->yout[j] >> 8) & 0xFF);
buffer[i + 1] = (u8)(gamma->yout[j] & 0xC0);
i += 2;
}
__VISendI2CData((u8)0xE0, buffer, 34);
WaitMicroTime(2);
}
void __VISetGamma1_0(void) {
__VISetGammaImm(&gammaSet[10]);
}
static VIGamma __gamma;
void __VISetGamma(void) {
__VISetGammaImm(&gammaSet[__gamma]);
}
void VISetGamma(VIGamma gamma) {
if (__gamma != gamma) {
__gamma = gamma;
Vdac_Flag_Changed |= 0x10;
}
}
static VIBool __filter = 0xFF;
void __VISetTrapFilterImm(VIBool filter) {
u8 buffer[2];
buffer[0] = 0x3;
if (filter == VI_TRUE) {
buffer[1] = VI_FALSE;
} else {
buffer[1] = VI_TRUE;
}
__VISendI2CData((u8)0xE0, buffer, 2);
WaitMicroTime(2);
}
void __VISetTrapFilter(void) {
u8 buffer[2];
buffer[0] = 0x3;
if (__filter == VI_TRUE) {
buffer[1] = VI_FALSE;
} else {
buffer[1] = VI_TRUE;
}
__VISendI2CData((u8)0xE0, buffer, 2);
WaitMicroTime(2);
}
void VISetTrapFilter(VIBool filter) {
if (__filter == filter) {
return;
}
__filter = filter;
Vdac_Flag_Changed |= 0x20;
}
static VIOverDrive __level;
void __VISetRGBOverDrive(void) {
u8 buffer[2];
if (Vdac_Flag_Region == VI_VMODE_RGB) {
buffer[0] = 0xA;
buffer[1] = (u8)((__level << 1) | VI_ENABLE);
__VISendI2CData((u8)0xE0, buffer, 2);
WaitMicroTime(2);
} else {
buffer[0] = 0xA;
buffer[1] = VI_DISABLE;
__VISendI2CData((u8)0xE0, buffer, 2);
WaitMicroTime(2);
}
}
void VISetRGBOverDrive(VIOverDrive level) {
if (__level == level) {
return;
}
__level = level;
Vdac_Flag_Changed |= 0x40;
}
void VISetRGBModeImm(void) {
Vdac_Flag_Changed |= 0x80;
}
void __VISetRGBModeImm(void) {
__VISetVideoMode(VI_VMODE_RGB, VI_DISABLE);
}
void __VISetRevolutionModeSimple(void) {
u32 dtv;
__VISetCCSEL(VI_TRUE);
__VISetOverSampling(VI_TRUE);
dtv = VIGetDTVStatus();
__VISetYUVSEL((VIBool)dtv);
__VISetTiming(VI_TMG_GAME);
__VISetVolume(0x8E, 0x8E);
__VISetVBICtrl(VI_DISABLE, VI_DISABLE, VI_DISABLE);
__VISetCGMSClear();
VISetWSS(0, 0, 0, 0);
__VISetWSS();
VISetClosedCaption(0, 0, 0, 0);
__VISetClosedCaption();
__VISetMacrovisionImm(&VIZeroACPType);
VISetRGBOverDrive(VI_ODV_L1);
__VISetRGBOverDrive();
__VISetTrapFilterImm(VI_DISABLE);
__VISetGammaImm(&gammaSet[VI_GM_1_0]);
__current_3in1_video_mode = 0;
}

117
src/revolution/wenc/wenc.c Normal file
View File

@ -0,0 +1,117 @@
#include <revolution/wenc.h>
#include <string.h>
s32 WENCGetEncodeData(WENCInfo* info, u32 flag, const s16* pcmData, s32 samples, u8* adpcmData) {
const f64 table[] = {0.89843750, 0.89843750, 0.89843750, 0.89843750,
1.19921875, 1.59765625, 2.00000000, 2.39843750};
u8* dst;
const s16* src;
s32 i;
s32 da;
s32 l3, l2, l1, l0;
s32 dlx;
s32 xnc;
s32 offset;
s32 index;
s32 encodeSize;
s32 xn;
s32 dl;
s32 qn;
s32 dn;
s32 dlh;
s32 dlq;
u8 by;
encodeSize = (samples + 1) / 2;
memset(adpcmData, 0, encodeSize);
src = pcmData;
dst = adpcmData;
if ((flag & WENC_FLAG_USER_INFO) == 0) {
xn = 0;
dl = 127;
qn = 0;
dn = 0;
dlh = 0;
dlq = 0;
} else {
xn = info->xn;
dl = info->dl;
qn = info->qn;
dn = info->dn;
dlh = info->dlh;
dlq = info->dlq;
}
for (i = 0; i < samples; i++) {
l3 = l2 = l1 = l0 = 0;
da = *src++;
if (da < xn) {
l3 = 1;
}
dn = __abs(da - xn);
if (dn >= dl) {
l2 = 1;
dn -= dl;
}
dlh = dl / 2;
if (dn >= dlh) {
l1 = 1;
dn -= dlh;
}
dlq = dlh / 2;
if (dn >= dlq) {
l0 = 1;
dn -= dlq;
}
dlx = dlq / 2;
qn = (1 - l3 * 2) * (dl * l2 + dlh * l1 + dlq * l0 + dlx);
if (qn > 0xFFFF) {
qn = 0xFFFF;
}
if (qn < -0x10000) {
qn = -0x10000;
}
xnc = xn + qn;
if (xnc > 0x7FFF) {
xnc = 0x7FFF;
}
if (xnc < -0x8000) {
xnc = -0x8000;
}
xn = xnc;
offset = (i & 1) == 0 ? 4 : 0;
by = l3 * 8 + l2 * 4 + l1 * 2 + l0;
dst[i / 2] |= by << offset;
index = l2 * 4 + l1 * 2 + l0;
dl *= table[index];
if (dl <= 127) {
dl = 127;
}
if (dl >= 0x6000) {
dl = 0x6000;
}
}
info->xn = xn;
info->dl = dl;
info->qn = qn;
info->dn = dn;
info->dlh = dlh;
info->dlq = dlq;
return samples;
}

434
src/revolution/wpad/WPAD.c Normal file
View File

@ -0,0 +1,434 @@
#include <revolution/os.h>
#include <revolution/wpad.h>
#include <revolution/wpad/wud.h>
#include <string.h>
#include "__wpad.h"
wpad_cb_st* __rvl_p_wpadcb[WPAD_MAX_CONTROLLERS];
static u8 _wpadSpeakerVol;
static s8 __wpadGetQueueSize(struct WPADCmdQueue* cmdQueue);
static u16 __wpadGetBTEBufferStatus(s32 chan);
static u16 __wpadGetBTMBufferStatus(s32 chan);
static BOOL __wpadPushCommand(struct WPADCmdQueue* cmdQueue, struct WPADCmd cmdBlk);
void dummyString(void* p_buf) {
ASSERTLINE(0, p_buf != NULL);
}
static u32 __wpadFmt2Size(u32 fmt) {
u32 fmtSize;
switch (fmt) {
case WPAD_FMT_FS_BTN:
case WPAD_FMT_FS_BTN_ACC:
case WPAD_FMT_FS_BTN_ACC_DPD:
fmtSize = sizeof(WPADFSStatus);
break;
case WPAD_FMT_CLASSIC_BTN:
case WPAD_FMT_CLASSIC_BTN_ACC:
case WPAD_FMT_CLASSIC_BTN_ACC_DPD:
case WPAD_FMT_GUITAR:
case WPAD_FMT_DRUM:
case WPAD_FMT_TAIKO:
case WPAD_FMT_TURNTABLE:
fmtSize = sizeof(WPADCLStatus);
break;
case WPAD_FMT_BULK:
fmtSize = sizeof(WPADBKStatus);
break;
case WPAD_FMT_TRAIN:
fmtSize = sizeof(WPADTRStatus);
break;
case 20:
fmtSize = 0x32;
break;
case WPAD_FMT_BALANCE_CHECKER:
fmtSize = sizeof(WPADBLStatus);
break;
case WPAD_FMT_VSM:
fmtSize = sizeof(WPADVSStatus);
break;
case WPAD_FMT_BTN_ACC_DPD_EXTENDED:
fmtSize = sizeof(WPADStatusEx);
break;
case WPAD_FMT_MOTION_PLUS:
fmtSize = sizeof(WPADMPStatus);
break;
default:
fmtSize = sizeof(WPADStatus);
break;
}
return fmtSize;
}
u8 WPADGetRadioSensitivity(s32 chan) {
wpad_cb_st* p_wpd = __rvl_p_wpadcb[chan];
BOOL intrStatus = OSDisableInterrupts();
u8 radioSensitivity = p_wpd->radioSensitivity;
OSRestoreInterrupts(intrStatus);
return radioSensitivity;
}
void WPADRead(s32 chan, WPADStatus* status) {
wpad_cb_st* p_wpd = __rvl_p_wpadcb[chan];
BOOL intrStatus;
u8 rxBufIndex;
WPADStatus* rxStatus;
u32 fmtSize;
ASSERTLINE(4013, (0 <= chan) && (chan < WPAD_MAX_CONTROLLERS));
ASSERTLINE(4014, status != NULL);
intrStatus = OSDisableInterrupts();
rxBufIndex = p_wpd->rxBufIndex != 0 ? 0 : 1;
rxStatus = (WPADStatus*)p_wpd->rxBufs[rxBufIndex];
fmtSize = __wpadFmt2Size(p_wpd->dataFormat);
if (rxStatus->err != WPAD_ESUCCESS)
fmtSize = sizeof(WPADStatus);
memcpy(status, rxStatus, fmtSize);
OSRestoreInterrupts(intrStatus);
}
BOOL WPADIsSpeakerEnabled(s32 chan) {
BOOL enabled;
wpad_cb_st* p_wpd = __rvl_p_wpadcb[chan];
BOOL intrStatus = OSDisableInterrupts();
enabled = p_wpd->info.speaker;
OSRestoreInterrupts(intrStatus);
return enabled;
}
s32 WPADControlSpeaker(s32 chan, u32 command, WPADCallback* cb) {
u8 data[7] = {0x00, 0x00, 0xd0, 0x07, 0x40, 0x0c, 0x0e};
wpad_cb_st* p_wpd = __rvl_p_wpadcb[chan];
BOOL intrStatus = OSDisableInterrupts();
BOOL speakerEnabled = p_wpd->info.speaker;
BOOL handshakeFinished;
s32 status = p_wpd->status;
handshakeFinished = p_wpd->handshakeFinished;
OSRestoreInterrupts(intrStatus);
if (status == WPAD_ENODEV)
goto end;
if (!handshakeFinished) {
status = WPAD_EBUSY;
goto end;
}
if (command == WPAD_SPEAKER_DISABLE) {
if (!speakerEnabled) {
status = WPAD_ESUCCESS;
goto end;
}
intrStatus = OSDisableInterrupts();
if (WPADiIsAvailableCmdQueue(&p_wpd->stdCmdQueue, 5)) {
WPADiSendMuteSpeaker(&p_wpd->stdCmdQueue, TRUE, NULL);
WPADiSendWriteDataCmd(&p_wpd->stdCmdQueue, 0x01, WM_REG_SPEAKER_01, NULL);
WPADiSendWriteDataCmd(&p_wpd->stdCmdQueue, 0x00, WM_REG_SPEAKER_09, NULL);
WPADiSendEnableSpeaker(&p_wpd->stdCmdQueue, FALSE, NULL);
WPADiSendGetContStat(&p_wpd->stdCmdQueue, NULL, cb);
OSRestoreInterrupts(intrStatus);
return WPAD_ESUCCESS;
}
status = WPAD_EBUSY;
OSRestoreInterrupts(intrStatus);
} else {
switch (command) {
case WPAD_SPEAKER_ENABLE:
case WPAD_SPEAKER_CMD_05:
intrStatus = OSDisableInterrupts();
if (WPADiIsAvailableCmdQueue(&p_wpd->stdCmdQueue, 7)) {
WPADiSendEnableSpeaker(&p_wpd->stdCmdQueue, TRUE, NULL);
WPADiSendMuteSpeaker(&p_wpd->stdCmdQueue, TRUE, NULL);
WPADiSendWriteDataCmd(&p_wpd->stdCmdQueue, 0x01, WM_REG_SPEAKER_09, NULL);
// sends 0x80 instead of 0x08?
WPADiSendWriteDataCmd(&p_wpd->stdCmdQueue, 0x80, WM_REG_SPEAKER_01, NULL);
data[4] = _wpadSpeakerVol;
WPADiSendWriteData(&p_wpd->stdCmdQueue, &data, sizeof data, WM_REG_SPEAKER_01,
NULL);
WPADiSendMuteSpeaker(&p_wpd->stdCmdQueue, FALSE, NULL);
WPADiSendGetContStat(&p_wpd->stdCmdQueue, NULL, cb);
OSRestoreInterrupts(intrStatus);
return WPAD_ESUCCESS;
}
status = WPAD_EBUSY;
OSRestoreInterrupts(intrStatus);
break;
case WPAD_SPEAKER_MUTE:
if (!WPADiSendMuteSpeaker(&p_wpd->stdCmdQueue, TRUE, cb)) {
status = WPAD_EBUSY;
goto end;
}
return WPAD_ESUCCESS;
case WPAD_SPEAKER_UNMUTE:
if (!WPADiSendMuteSpeaker(&p_wpd->stdCmdQueue, FALSE, cb)) {
status = WPAD_EBUSY;
goto end;
}
return WPAD_ESUCCESS;
case WPAD_SPEAKER_PLAY:
if (!WPADiSendWriteDataCmd(&p_wpd->stdCmdQueue, 0x01, WM_REG_SPEAKER_08, cb)) {
status = WPAD_EBUSY;
goto end;
}
return WPAD_ESUCCESS;
}
}
end:
if (cb)
(*cb)(chan, status);
return status;
}
BOOL __wpadIsBusyStream(s32 chan) {
BOOL intrStatus;
wpad_cb_st* p_wpd = __rvl_p_wpadcb[chan];
u8 radioQuality;
u32 devType;
u8 bufferStatus;
u16 bteBufferStatus;
u16 btmBufferStatus;
u8 audioFrames;
s8 queueSize;
u8 linkNumber;
intrStatus = OSDisableInterrupts();
radioQuality = p_wpd->radioQuality;
devType = p_wpd->devType;
bufferStatus = WUDGetBufferStatus();
queueSize = __wpadGetQueueSize(&p_wpd->stdCmdQueue);
bteBufferStatus = __wpadGetBTEBufferStatus(chan);
btmBufferStatus = __wpadGetBTMBufferStatus(chan);
audioFrames = p_wpd->audioFrames;
linkNumber = _WUDGetLinkNumber();
OSRestoreInterrupts(intrStatus);
if (radioQuality != WPAD_RADIO_QUALITY_GOOD || btmBufferStatus > 3 || bufferStatus == 10 ||
bufferStatus >= linkNumber * 2 + 2 || devType == WPAD_DEV_INITIALIZING || queueSize >= 21 ||
audioFrames >= 1)
{
return TRUE;
} else {
return FALSE;
}
}
s32 WPADSendStreamData(s32 chan, void* p_buf, u16 len) {
wpad_cb_st* p_wpd = __rvl_p_wpadcb[chan];
BOOL intrStatus;
BOOL handshakeFinished;
s32 status;
ASSERTLINE(4528, p_buf != NULL);
ASSERTLINE(4529, len >= 0 && len <= 20);
intrStatus = OSDisableInterrupts();
status = p_wpd->status;
handshakeFinished = p_wpd->handshakeFinished;
OSRestoreInterrupts(intrStatus);
if (status == WPAD_ENODEV)
return WPAD_ENODEV;
if (!handshakeFinished)
return WPAD_EBUSY;
if (__wpadIsBusyStream(chan))
return WPAD_EBUSY;
if (!WPADiSendStreamData(&p_wpd->stdCmdQueue, p_buf, len))
return WPAD_EBUSY;
intrStatus = OSDisableInterrupts();
++p_wpd->audioFrames;
OSRestoreInterrupts(intrStatus);
return WPAD_ESUCCESS;
}
BOOL WPADiSendEnableSpeaker(struct WPADCmdQueue* cmdQueue, BOOL enabled, WPADCallback* cb) {
BOOL success;
struct WPADCmd cmdBlk;
cmdBlk.reportID = RPTID_ENABLE_SPEAKER;
cmdBlk.dataLength = RPT14_SIZE;
cmdBlk.dataBuf[RPT14_SPEAKER_ENABLE] = enabled ? 4 : 0;
cmdBlk.cmdCB = cb;
success = __wpadPushCommand(cmdQueue, cmdBlk);
return success;
}
BOOL WPADiSendGetContStat(struct WPADCmdQueue* cmdQueue, WPADInfo* infoOut, WPADCallback* cb) {
BOOL success;
struct WPADCmd cmdBlk;
cmdBlk.reportID = RPTID_REQUEST_STATUS;
cmdBlk.dataLength = RPT15_SIZE;
cmdBlk.dataBuf[0] = 0;
cmdBlk.cmdCB = cb;
cmdBlk.statusReportOut = infoOut;
success = __wpadPushCommand(cmdQueue, cmdBlk);
return success;
}
BOOL WPADiSendWriteDataCmd(struct WPADCmdQueue* cmdQueue, u8 cmd, u32 address, WPADCallback* cb) {
return WPADiSendWriteData(cmdQueue, &cmd, sizeof(cmd), address, cb);
}
BOOL WPADiSendWriteData(struct WPADCmdQueue* cmdQueue, void const* p_buf, u16 len, u32 address,
WPADCallback* cb) {
BOOL success;
u8 packedLen = len & 0x1f;
struct WPADCmd cmdBlk;
ASSERTLINE(5830, len > 0 && len <= 16);
ASSERTLINE(5831, p_buf != NULL);
cmdBlk.reportID = RPTID_WRITE_DATA;
cmdBlk.dataLength = RPT16_SIZE;
cmdBlk.cmdCB = cb;
memcpy(&cmdBlk.dataBuf[RPT16_DATA_DST_ADDRESS], &address, sizeof address);
memcpy(&cmdBlk.dataBuf[RPT16_DATA_LENGTH], &packedLen, sizeof packedLen);
memcpy(&cmdBlk.dataBuf[RPT16_DATA], p_buf, len);
success = __wpadPushCommand(cmdQueue, cmdBlk);
return success;
}
BOOL WPADiSendStreamData(struct WPADCmdQueue* cmdQueue, void const* p_buf, u16 len) {
BOOL success;
u8 packedLen = len << 3;
struct WPADCmd cmdBlk;
ASSERTLINE(5873, len > 0 && len <= 20);
cmdBlk.reportID = RPTID_SEND_SPEAKER_DATA;
cmdBlk.dataLength = sizeof cmdBlk.dataBuf;
cmdBlk.dataBuf[RPT18_DATA_LENGTH] = packedLen;
cmdBlk.cmdCB = NULL;
memcpy(&cmdBlk.dataBuf[RPT18_DATA], p_buf, len);
success = __wpadPushCommand(cmdQueue, cmdBlk);
return success;
}
BOOL WPADiSendMuteSpeaker(struct WPADCmdQueue* cmdQueue, BOOL muted, WPADCallback* cb) {
BOOL success;
struct WPADCmd cmdBlk;
cmdBlk.reportID = RPTID_MUTE_SPEAKER;
cmdBlk.dataLength = RPT19_SIZE;
cmdBlk.dataBuf[RPT19_SPEAKER_MUTE] = muted ? 4 : 0;
cmdBlk.cmdCB = cb;
success = __wpadPushCommand(cmdQueue, cmdBlk);
return success;
}
BOOL WPADiIsAvailableCmdQueue(struct WPADCmdQueue* cmdQueue, s8 num) {
s8 queueSize = __wpadGetQueueSize(cmdQueue);
if ((u32)(queueSize + num) <= cmdQueue->length - 1)
return TRUE;
else
return FALSE;
}
static s8 __wpadGetQueueSize(struct WPADCmdQueue* cmdQueue) {
BOOL intrStatus = OSDisableInterrupts();
s8 queueRemaining = cmdQueue->indexIn - cmdQueue->indexOut;
if (queueRemaining < 0)
queueRemaining += cmdQueue->length;
OSRestoreInterrupts(intrStatus);
return queueRemaining;
}
static BOOL __wpadPushCommand(struct WPADCmdQueue* cmdQueue, struct WPADCmd cmdBlk) {
BOOL intrStatus = OSDisableInterrupts();
if (cmdQueue->length - 1 == (u32)__wpadGetQueueSize(cmdQueue)) {
OSRestoreInterrupts(intrStatus);
return FALSE;
}
memset(&cmdQueue->queue[cmdQueue->indexIn], 0, sizeof cmdQueue->queue[cmdQueue->indexIn]);
memcpy(&cmdQueue->queue[cmdQueue->indexIn], &cmdBlk, sizeof cmdQueue->queue[cmdQueue->indexIn]);
cmdQueue->indexIn = (u32)cmdQueue->indexIn == ((cmdQueue->length) - 1) ? 0 : cmdQueue->indexIn + 1;
OSRestoreInterrupts(intrStatus);
return TRUE;
}
static u16 __wpadGetBTEBufferStatus(s32 chan) {
wpad_cb_st* p_wpd = __rvl_p_wpadcb[chan];
BOOL intrStatus = OSDisableInterrupts();
s32 status = p_wpd->status;
s8 dev_handle = p_wpd->devHandle;
OSRestoreInterrupts(intrStatus);
if (status == WPAD_ENODEV)
return 0;
return _WUDGetQueuedSize(dev_handle);
}
static u16 __wpadGetBTMBufferStatus(s32 chan) {
wpad_cb_st* p_wpd = __rvl_p_wpadcb[chan];
BOOL intrStatus = OSDisableInterrupts();
s32 status = p_wpd->status;
s8 dev_handle = p_wpd->devHandle;
OSRestoreInterrupts(intrStatus);
if (status == WPAD_ENODEV)
return 0;
return _WUDGetNotAckedSize(dev_handle);
}

Some files were not shown because too many files have changed in this diff Show More