diff --git a/config/ShieldD/splits.txt b/config/ShieldD/splits.txt index 2139785b55..8c2109d6d1 100644 --- a/config/ShieldD/splits.txt +++ b/config/ShieldD/splits.txt @@ -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 diff --git a/configure.py b/configure.py index cc0545e0cf..133c4cfd04 100755 --- a/configure.py +++ b/configure.py @@ -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), diff --git a/include/global.h b/include/global.h index 63e3defa45..24d22c7522 100644 --- a/include/global.h +++ b/include/global.h @@ -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__ diff --git a/include/revolution/ai.h b/include/revolution/ai.h index 340da848b2..dd103eb0af 100644 --- a/include/revolution/ai.h +++ b/include/revolution/ai.h @@ -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); diff --git a/include/revolution/aralt.h b/include/revolution/aralt.h new file mode 100644 index 0000000000..8a699bb857 --- /dev/null +++ b/include/revolution/aralt.h @@ -0,0 +1,56 @@ +#ifndef _REVOLUTION_ARALT_H_ +#define _REVOLUTION_ARALT_H_ + +#include + +#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 diff --git a/include/revolution/esp.h b/include/revolution/esp.h index 802a028630..43fe6d8787 100644 --- a/include/revolution/esp.h +++ b/include/revolution/esp.h @@ -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_ diff --git a/include/revolution/euart.h b/include/revolution/euart.h new file mode 100644 index 0000000000..a560debc2d --- /dev/null +++ b/include/revolution/euart.h @@ -0,0 +1,61 @@ +#ifndef _REVOLUTION_EUART_H_ +#define _REVOLUTION_EUART_H_ + +#include + +#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 diff --git a/include/revolution/exi.h b/include/revolution/exi.h index 9672a30aa6..b13745dab2 100644 --- a/include/revolution/exi.h +++ b/include/revolution/exi.h @@ -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 diff --git a/include/revolution/hio2.h b/include/revolution/hio2.h new file mode 100644 index 0000000000..3758415931 --- /dev/null +++ b/include/revolution/hio2.h @@ -0,0 +1,44 @@ +#ifndef _REVOLUTION_HIO2_H_ +#define _REVOLUTION_HIO2_H_ + +#include + +#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 diff --git a/include/revolution/hw_regs.h b/include/revolution/hw_regs.h index 1bf8658f9f..b1f8a2c4e5 100644 --- a/include/revolution/hw_regs.h +++ b/include/revolution/hw_regs.h @@ -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) diff --git a/include/revolution/private/GXFDLShortcut.h b/include/revolution/private/GXFDLShortcut.h new file mode 100644 index 0000000000..a717d18fb6 --- /dev/null +++ b/include/revolution/private/GXFDLShortcut.h @@ -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<> 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 diff --git a/include/revolution/private/GXRegs.h b/include/revolution/private/GXRegs.h new file mode 100644 index 0000000000..ab6ca00c4d --- /dev/null +++ b/include/revolution/private/GXRegs.h @@ -0,0 +1,186 @@ +#ifndef GXREGS_H +#define GXREGS_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 diff --git a/include/revolution/private/bp_reg.h b/include/revolution/private/bp_reg.h new file mode 100644 index 0000000000..1ac478453d --- /dev/null +++ b/include/revolution/private/bp_reg.h @@ -0,0 +1,229 @@ +#ifndef BP_REG_H +#define BP_REG_H + +#include + +#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 diff --git a/include/revolution/private/cp_reg.h b/include/revolution/private/cp_reg.h new file mode 100644 index 0000000000..2cfda75e75 --- /dev/null +++ b/include/revolution/private/cp_reg.h @@ -0,0 +1,2043 @@ +#ifndef __FDL_CP_REG_H__ +#define __FDL_CP_REG_H__ + +#include + +#define FDL_ASSERT(c) + +#define CP_CMD_NOP 0x00 +#define CP_CMD_QUADS 0x10 +#define CP_CMD_QUAD_STRIP 0x11 +#define CP_CMD_TRIANGLES 0x12 +#define CP_CMD_TRIANGLE_STRIP 0x13 +#define CP_CMD_TRIANGLE_FAN 0x14 +#define CP_CMD_LINES 0x15 +#define CP_CMD_LINE_STRIP 0x16 +#define CP_CMD_POINTS 0x17 +#define CP_CMD_LOADREGS 0x01 +#define CP_CMD_XF_LOADREGS 0x02 +#define CP_CMD_XF_IDXLDREG_A 0x04 +#define CP_CMD_XF_IDXLDREG_B 0x05 +#define CP_CMD_XF_IDXLDREG_C 0x06 +#define CP_CMD_XF_IDXLDREG_D 0x07 +#define CP_CMD_CALL_OBJECT 0x08 +#define CP_CMD_VCACHE_INVALIDATE 0x09 +#define CP_CMD_SU_BYPCMD0 0x0c +#define CP_CMD_SU_BYPCMD1 0x0d + +#define CP_COUNTER0L 0x20 +#define CP_COUNTER0H 0x21 +#define CP_COUNTER1L 0x22 +#define CP_COUNTER1H 0x23 +#define CP_COUNTER2L 0x24 +#define CP_COUNTER2H 0x25 +#define CP_COUNTER3L 0x26 +#define CP_COUNTER3H 0x27 +#define CP_VC_CHKCNTL 0x28 +#define CP_VC_CHKCNTH 0x29 + +#define CP_OPCODE_INDEX_SIZE 3 +#define CP_OPCODE_INDEX_SHIFT 0 +#define CP_OPCODE_INDEX_MASK 0x00000007 +#define CP_OPCODE_GET_INDEX(cp_opcode) \ + ((((unsigned long)(cp_opcode)) & CP_OPCODE_INDEX_MASK) >> CP_OPCODE_INDEX_SHIFT) +#define CP_OPCODE_SET_INDEX(cp_opcode, index) { \ + FDL_ASSERT(!((index) & ~((1 << CP_OPCODE_INDEX_SIZE)-1))); \ + cp_opcode = (((unsigned long)(cp_opcode)) & ~CP_OPCODE_INDEX_MASK) | (((unsigned long)(index)) << CP_OPCODE_INDEX_SHIFT);\ +} +#define CP_OPCODE_CMD_SIZE 5 +#define CP_OPCODE_CMD_SHIFT 3 +#define CP_OPCODE_CMD_MASK 0x000000f8 +#define CP_OPCODE_GET_CMD(cp_opcode) \ + ((((unsigned long)(cp_opcode)) & CP_OPCODE_CMD_MASK) >> CP_OPCODE_CMD_SHIFT) +#define CP_OPCODE_SET_CMD(cp_opcode, cmd) { \ + FDL_ASSERT(!((cmd) & ~((1 << CP_OPCODE_CMD_SIZE)-1))); \ + cp_opcode = (((unsigned long)(cp_opcode)) & ~CP_OPCODE_CMD_MASK) | (((unsigned long)(cmd)) << CP_OPCODE_CMD_SHIFT);\ +} +#define CP_OPCODE_TOTAL_SIZE 8 +#define CP_OPCODE(index, cmd) \ + ((((unsigned long)(index)) << CP_OPCODE_INDEX_SHIFT) | \ + (((unsigned long)(cmd)) << CP_OPCODE_CMD_SHIFT)) + +#define CP_VC_STAT_RESET 0x00 +#define CP_STAT_ENABLE 0x01 +#define CP_STAT_SEL 0x02 +#define CP_MATINDEX_A 0x03 +#define CP_MATINDEX_B 0x04 +#define CP_VCD_LO 0x05 +#define CP_VCD_HI 0x06 +#define CP_VAT_A 0x07 +#define CP_VAT_B 0x08 +#define CP_VAT_C 0x09 +#define CP_ARRAY_BASE 0x0a +#define CP_ARRAY_STRIDE 0x0b + +#define CP_STREAM_REG_INDEX_SIZE 4 +#define CP_STREAM_REG_INDEX_SHIFT 0 +#define CP_STREAM_REG_INDEX_MASK 0x0000000f +#define CP_STREAM_REG_GET_INDEX(cp_stream_reg) \ + ((((unsigned long)(cp_stream_reg)) & CP_STREAM_REG_INDEX_MASK) >> CP_STREAM_REG_INDEX_SHIFT) +#define CP_STREAM_REG_SET_INDEX(cp_stream_reg, index) { \ + FDL_ASSERT(!((index) & ~((1 << CP_STREAM_REG_INDEX_SIZE)-1))); \ + cp_stream_reg = (((unsigned long)(cp_stream_reg)) & ~CP_STREAM_REG_INDEX_MASK) | (((unsigned long)(index)) << CP_STREAM_REG_INDEX_SHIFT);\ +} +#define CP_STREAM_REG_ADDR_SIZE 4 +#define CP_STREAM_REG_ADDR_SHIFT 4 +#define CP_STREAM_REG_ADDR_MASK 0x000000f0 +#define CP_STREAM_REG_GET_ADDR(cp_stream_reg) \ + ((((unsigned long)(cp_stream_reg)) & CP_STREAM_REG_ADDR_MASK) >> CP_STREAM_REG_ADDR_SHIFT) +#define CP_STREAM_REG_SET_ADDR(cp_stream_reg, addr) { \ + FDL_ASSERT(!((addr) & ~((1 << CP_STREAM_REG_ADDR_SIZE)-1))); \ + cp_stream_reg = (((unsigned long)(cp_stream_reg)) & ~CP_STREAM_REG_ADDR_MASK) | (((unsigned long)(addr)) << CP_STREAM_REG_ADDR_SHIFT);\ +} +#define CP_STREAM_REG_TOTAL_SIZE 8 +#define CP_STREAM_REG(index, addr) \ + ((((unsigned long)(index)) << CP_STREAM_REG_INDEX_SHIFT) | \ + (((unsigned long)(addr)) << CP_STREAM_REG_ADDR_SHIFT)) + +#define CP_STATUS 0x00 +#define CP_ENABLE 0x01 +#define CP_CLR 0x02 +#define CP_MEMPERF_SEL 0x03 +#define CP_STM_LOW 0x05 +#define CP_FIFO_BASEL 0x10 +#define CP_FIFO_BASEH 0x11 +#define CP_FIFO_TOPL 0x12 +#define CP_FIFO_TOPH 0x13 +#define CP_FIFO_HICNTL 0x14 +#define CP_FIFO_HICNTH 0x15 +#define CP_FIFO_LOCNTL 0x16 +#define CP_FIFO_LOCNTH 0x17 +#define CP_FIFO_COUNTL 0x18 +#define CP_FIFO_COUNTH 0x19 +#define CP_FIFO_WPTRL 0x1a +#define CP_FIFO_WPTRH 0x1b +#define CP_FIFO_RPTRL 0x1c +#define CP_FIFO_RPTRH 0x1d +#define CP_FIFO_BRKL 0x1e +#define CP_FIFO_BRKH 0x1f +#define CP_COUNTER0L 0x20 +#define CP_COUNTER0H 0x21 +#define CP_COUNTER1L 0x22 +#define CP_COUNTER1H 0x23 +#define CP_COUNTER2L 0x24 +#define CP_COUNTER2H 0x25 +#define CP_COUNTER3L 0x26 +#define CP_COUNTER3H 0x27 +#define CP_VC_CHKCNTL 0x28 +#define CP_VC_CHKCNTH 0x29 +#define CP_VC_MISSL 0x2a +#define CP_VC_MISSH 0x2b +#define CP_VC_STALLL 0x2c +#define CP_VC_STALLH 0x2d +#define CP_FRCLK_CNTL 0x2e +#define CP_FRCLK_CNTH 0x2f +#define CP_XF_ADDR 0x30 +#define CP_XF_DATAL 0x31 +#define CP_XF_DATAH 0x32 +#define CP_NUM_REGS 0x33 + +/* +* cp_reg_status struct +*/ +#define CP_REG_STATUS_OVFL_SIZE 1 +#define CP_REG_STATUS_OVFL_SHIFT 0 +#define CP_REG_STATUS_OVFL_MASK 0x00000001 +#define CP_REG_STATUS_GET_OVFL(cp_reg_status) \ + ((((unsigned long)(cp_reg_status)) & CP_REG_STATUS_OVFL_MASK) >> CP_REG_STATUS_OVFL_SHIFT) +#define CP_REG_STATUS_SET_OVFL(cp_reg_status, ovfl) { \ + FDL_ASSERT(!((ovfl) & ~((1 << CP_REG_STATUS_OVFL_SIZE)-1))); \ + cp_reg_status = (((unsigned long)(cp_reg_status)) & ~CP_REG_STATUS_OVFL_MASK) | (((unsigned long)(ovfl)) << CP_REG_STATUS_OVFL_SHIFT);\ +} +#define CP_REG_STATUS_UNFL_SIZE 1 +#define CP_REG_STATUS_UNFL_SHIFT 1 +#define CP_REG_STATUS_UNFL_MASK 0x00000002 +#define CP_REG_STATUS_GET_UNFL(cp_reg_status) \ + ((((unsigned long)(cp_reg_status)) & CP_REG_STATUS_UNFL_MASK) >> CP_REG_STATUS_UNFL_SHIFT) +#define CP_REG_STATUS_SET_UNFL(cp_reg_status, unfl) { \ + FDL_ASSERT(!((unfl) & ~((1 << CP_REG_STATUS_UNFL_SIZE)-1))); \ + cp_reg_status = (((unsigned long)(cp_reg_status)) & ~CP_REG_STATUS_UNFL_MASK) | (((unsigned long)(unfl)) << CP_REG_STATUS_UNFL_SHIFT);\ +} +#define CP_REG_STATUS_FIFO_RDIDLE_SIZE 1 +#define CP_REG_STATUS_FIFO_RDIDLE_SHIFT 2 +#define CP_REG_STATUS_FIFO_RDIDLE_MASK 0x00000004 +#define CP_REG_STATUS_GET_FIFO_RDIDLE(cp_reg_status) \ + ((((unsigned long)(cp_reg_status)) & CP_REG_STATUS_FIFO_RDIDLE_MASK) >> CP_REG_STATUS_FIFO_RDIDLE_SHIFT) +#define CP_REG_STATUS_SET_FIFO_RDIDLE(cp_reg_status, fifo_rdidle) { \ + FDL_ASSERT(!((fifo_rdidle) & ~((1 << CP_REG_STATUS_FIFO_RDIDLE_SIZE)-1))); \ + cp_reg_status = (((unsigned long)(cp_reg_status)) & ~CP_REG_STATUS_FIFO_RDIDLE_MASK) | (((unsigned long)(fifo_rdidle)) << CP_REG_STATUS_FIFO_RDIDLE_SHIFT);\ +} +#define CP_REG_STATUS_CPIDLE_SIZE 1 +#define CP_REG_STATUS_CPIDLE_SHIFT 3 +#define CP_REG_STATUS_CPIDLE_MASK 0x00000008 +#define CP_REG_STATUS_GET_CPIDLE(cp_reg_status) \ + ((((unsigned long)(cp_reg_status)) & CP_REG_STATUS_CPIDLE_MASK) >> CP_REG_STATUS_CPIDLE_SHIFT) +#define CP_REG_STATUS_SET_CPIDLE(cp_reg_status, cpidle) { \ + FDL_ASSERT(!((cpidle) & ~((1 << CP_REG_STATUS_CPIDLE_SIZE)-1))); \ + cp_reg_status = (((unsigned long)(cp_reg_status)) & ~CP_REG_STATUS_CPIDLE_MASK) | (((unsigned long)(cpidle)) << CP_REG_STATUS_CPIDLE_SHIFT);\ +} +#define CP_REG_STATUS_FIFOBRK_SIZE 1 +#define CP_REG_STATUS_FIFOBRK_SHIFT 4 +#define CP_REG_STATUS_FIFOBRK_MASK 0x00000010 +#define CP_REG_STATUS_GET_FIFOBRK(cp_reg_status) \ + ((((unsigned long)(cp_reg_status)) & CP_REG_STATUS_FIFOBRK_MASK) >> CP_REG_STATUS_FIFOBRK_SHIFT) +#define CP_REG_STATUS_SET_FIFOBRK(cp_reg_status, fifobrk) { \ + FDL_ASSERT(!((fifobrk) & ~((1 << CP_REG_STATUS_FIFOBRK_SIZE)-1))); \ + cp_reg_status = (((unsigned long)(cp_reg_status)) & ~CP_REG_STATUS_FIFOBRK_MASK) | (((unsigned long)(fifobrk)) << CP_REG_STATUS_FIFOBRK_SHIFT);\ +} +#define CP_REG_STATUS_TOTAL_SIZE 5 +#define CP_REG_STATUS(ovfl, unfl, fifo_rdidle, cpidle, fifobrk) \ + ((((unsigned long)(ovfl)) << CP_REG_STATUS_OVFL_SHIFT) | \ + (((unsigned long)(unfl)) << CP_REG_STATUS_UNFL_SHIFT) | \ + (((unsigned long)(fifo_rdidle)) << CP_REG_STATUS_FIFO_RDIDLE_SHIFT) | \ + (((unsigned long)(cpidle)) << CP_REG_STATUS_CPIDLE_SHIFT) | \ + (((unsigned long)(fifobrk)) << CP_REG_STATUS_FIFOBRK_SHIFT)) + +/* +* cp_reg_enable struct +*/ +#define CP_REG_ENABLE_FIFORD_SIZE 1 +#define CP_REG_ENABLE_FIFORD_SHIFT 0 +#define CP_REG_ENABLE_FIFORD_MASK 0x00000001 +#define CP_REG_ENABLE_GET_FIFORD(cp_reg_enable) \ + ((((unsigned long)(cp_reg_enable)) & CP_REG_ENABLE_FIFORD_MASK) >> CP_REG_ENABLE_FIFORD_SHIFT) +#define CP_REG_ENABLE_SET_FIFORD(cp_reg_enable, fiford) { \ + FDL_ASSERT(!((fiford) & ~((1 << CP_REG_ENABLE_FIFORD_SIZE)-1))); \ + cp_reg_enable = (((unsigned long)(cp_reg_enable)) & ~CP_REG_ENABLE_FIFORD_MASK) | (((unsigned long)(fiford)) << CP_REG_ENABLE_FIFORD_SHIFT);\ +} +#define CP_REG_ENABLE_FIFOBRK_SIZE 1 +#define CP_REG_ENABLE_FIFOBRK_SHIFT 1 +#define CP_REG_ENABLE_FIFOBRK_MASK 0x00000002 +#define CP_REG_ENABLE_GET_FIFOBRK(cp_reg_enable) \ + ((((unsigned long)(cp_reg_enable)) & CP_REG_ENABLE_FIFOBRK_MASK) >> CP_REG_ENABLE_FIFOBRK_SHIFT) +#define CP_REG_ENABLE_SET_FIFOBRK(cp_reg_enable, fifobrk) { \ + FDL_ASSERT(!((fifobrk) & ~((1 << CP_REG_ENABLE_FIFOBRK_SIZE)-1))); \ + cp_reg_enable = (((unsigned long)(cp_reg_enable)) & ~CP_REG_ENABLE_FIFOBRK_MASK) | (((unsigned long)(fifobrk)) << CP_REG_ENABLE_FIFOBRK_SHIFT);\ +} +#define CP_REG_ENABLE_OVFLINT_SIZE 1 +#define CP_REG_ENABLE_OVFLINT_SHIFT 2 +#define CP_REG_ENABLE_OVFLINT_MASK 0x00000004 +#define CP_REG_ENABLE_GET_OVFLINT(cp_reg_enable) \ + ((((unsigned long)(cp_reg_enable)) & CP_REG_ENABLE_OVFLINT_MASK) >> CP_REG_ENABLE_OVFLINT_SHIFT) +#define CP_REG_ENABLE_SET_OVFLINT(cp_reg_enable, ovflint) { \ + FDL_ASSERT(!((ovflint) & ~((1 << CP_REG_ENABLE_OVFLINT_SIZE)-1))); \ + cp_reg_enable = (((unsigned long)(cp_reg_enable)) & ~CP_REG_ENABLE_OVFLINT_MASK) | (((unsigned long)(ovflint)) << CP_REG_ENABLE_OVFLINT_SHIFT);\ +} +#define CP_REG_ENABLE_UNFLINT_SIZE 1 +#define CP_REG_ENABLE_UNFLINT_SHIFT 3 +#define CP_REG_ENABLE_UNFLINT_MASK 0x00000008 +#define CP_REG_ENABLE_GET_UNFLINT(cp_reg_enable) \ + ((((unsigned long)(cp_reg_enable)) & CP_REG_ENABLE_UNFLINT_MASK) >> CP_REG_ENABLE_UNFLINT_SHIFT) +#define CP_REG_ENABLE_SET_UNFLINT(cp_reg_enable, unflint) { \ + FDL_ASSERT(!((unflint) & ~((1 << CP_REG_ENABLE_UNFLINT_SIZE)-1))); \ + cp_reg_enable = (((unsigned long)(cp_reg_enable)) & ~CP_REG_ENABLE_UNFLINT_MASK) | (((unsigned long)(unflint)) << CP_REG_ENABLE_UNFLINT_SHIFT);\ +} +#define CP_REG_ENABLE_WRPTRINC_SIZE 1 +#define CP_REG_ENABLE_WRPTRINC_SHIFT 4 +#define CP_REG_ENABLE_WRPTRINC_MASK 0x00000010 +#define CP_REG_ENABLE_GET_WRPTRINC(cp_reg_enable) \ + ((((unsigned long)(cp_reg_enable)) & CP_REG_ENABLE_WRPTRINC_MASK) >> CP_REG_ENABLE_WRPTRINC_SHIFT) +#define CP_REG_ENABLE_SET_WRPTRINC(cp_reg_enable, wrptrinc) { \ + FDL_ASSERT(!((wrptrinc) & ~((1 << CP_REG_ENABLE_WRPTRINC_SIZE)-1))); \ + cp_reg_enable = (((unsigned long)(cp_reg_enable)) & ~CP_REG_ENABLE_WRPTRINC_MASK) | (((unsigned long)(wrptrinc)) << CP_REG_ENABLE_WRPTRINC_SHIFT);\ +} +#define CP_REG_ENABLE_FIFOBRKINT_SIZE 1 +#define CP_REG_ENABLE_FIFOBRKINT_SHIFT 5 +#define CP_REG_ENABLE_FIFOBRKINT_MASK 0x00000020 +#define CP_REG_ENABLE_GET_FIFOBRKINT(cp_reg_enable) \ + ((((unsigned long)(cp_reg_enable)) & CP_REG_ENABLE_FIFOBRKINT_MASK) >> CP_REG_ENABLE_FIFOBRKINT_SHIFT) +#define CP_REG_ENABLE_SET_FIFOBRKINT(cp_reg_enable, fifobrkint) { \ + FDL_ASSERT(!((fifobrkint) & ~((1 << CP_REG_ENABLE_FIFOBRKINT_SIZE)-1))); \ + cp_reg_enable = (((unsigned long)(cp_reg_enable)) & ~CP_REG_ENABLE_FIFOBRKINT_MASK) | (((unsigned long)(fifobrkint)) << CP_REG_ENABLE_FIFOBRKINT_SHIFT);\ +} +#define CP_REG_ENABLE_TOTAL_SIZE 6 +#define CP_REG_ENABLE(fiford, fifobrk, ovflint, unflint, wrptrinc, fifobrkint) \ + ((((unsigned long)(fiford)) << CP_REG_ENABLE_FIFORD_SHIFT) | \ + (((unsigned long)(fifobrk)) << CP_REG_ENABLE_FIFOBRK_SHIFT) | \ + (((unsigned long)(ovflint)) << CP_REG_ENABLE_OVFLINT_SHIFT) | \ + (((unsigned long)(unflint)) << CP_REG_ENABLE_UNFLINT_SHIFT) | \ + (((unsigned long)(wrptrinc)) << CP_REG_ENABLE_WRPTRINC_SHIFT) | \ + (((unsigned long)(fifobrkint)) << CP_REG_ENABLE_FIFOBRKINT_SHIFT)) + +/* +* cp_reg_clr struct +*/ +#define CP_REG_CLR_OVFLINT_SIZE 1 +#define CP_REG_CLR_OVFLINT_SHIFT 0 +#define CP_REG_CLR_OVFLINT_MASK 0x00000001 +#define CP_REG_CLR_GET_OVFLINT(cp_reg_clr) \ + ((((unsigned long)(cp_reg_clr)) & CP_REG_CLR_OVFLINT_MASK) >> CP_REG_CLR_OVFLINT_SHIFT) +#define CP_REG_CLR_SET_OVFLINT(cp_reg_clr, ovflint) { \ + FDL_ASSERT(!((ovflint) & ~((1 << CP_REG_CLR_OVFLINT_SIZE)-1))); \ + cp_reg_clr = (((unsigned long)(cp_reg_clr)) & ~CP_REG_CLR_OVFLINT_MASK) | (((unsigned long)(ovflint)) << CP_REG_CLR_OVFLINT_SHIFT);\ +} +#define CP_REG_CLR_UNFLINT_SIZE 1 +#define CP_REG_CLR_UNFLINT_SHIFT 1 +#define CP_REG_CLR_UNFLINT_MASK 0x00000002 +#define CP_REG_CLR_GET_UNFLINT(cp_reg_clr) \ + ((((unsigned long)(cp_reg_clr)) & CP_REG_CLR_UNFLINT_MASK) >> CP_REG_CLR_UNFLINT_SHIFT) +#define CP_REG_CLR_SET_UNFLINT(cp_reg_clr, unflint) { \ + FDL_ASSERT(!((unflint) & ~((1 << CP_REG_CLR_UNFLINT_SIZE)-1))); \ + cp_reg_clr = (((unsigned long)(cp_reg_clr)) & ~CP_REG_CLR_UNFLINT_MASK) | (((unsigned long)(unflint)) << CP_REG_CLR_UNFLINT_SHIFT);\ +} +#define CP_REG_CLR_PERFCNT_SIZE 1 +#define CP_REG_CLR_PERFCNT_SHIFT 2 +#define CP_REG_CLR_PERFCNT_MASK 0x00000004 +#define CP_REG_CLR_GET_PERFCNT(cp_reg_clr) \ + ((((unsigned long)(cp_reg_clr)) & CP_REG_CLR_PERFCNT_MASK) >> CP_REG_CLR_PERFCNT_SHIFT) +#define CP_REG_CLR_SET_PERFCNT(cp_reg_clr, perfcnt) { \ + FDL_ASSERT(!((perfcnt) & ~((1 << CP_REG_CLR_PERFCNT_SIZE)-1))); \ + cp_reg_clr = (((unsigned long)(cp_reg_clr)) & ~CP_REG_CLR_PERFCNT_MASK) | (((unsigned long)(perfcnt)) << CP_REG_CLR_PERFCNT_SHIFT);\ +} +#define CP_REG_CLR_TOTAL_SIZE 3 +#define CP_REG_CLR(ovflint, unflint, perfcnt) \ + ((((unsigned long)(ovflint)) << CP_REG_CLR_OVFLINT_SHIFT) | \ + (((unsigned long)(unflint)) << CP_REG_CLR_UNFLINT_SHIFT) | \ + (((unsigned long)(perfcnt)) << CP_REG_CLR_PERFCNT_SHIFT)) + +/* +* cp_reg_memperfsel struct +*/ +#define CP_REG_MEMPERFSEL_PERFSEL_SIZE 3 +#define CP_REG_MEMPERFSEL_PERFSEL_SHIFT 0 +#define CP_REG_MEMPERFSEL_PERFSEL_MASK 0x00000007 +#define CP_REG_MEMPERFSEL_GET_PERFSEL(cp_reg_memperfsel) \ + ((((unsigned long)(cp_reg_memperfsel)) & CP_REG_MEMPERFSEL_PERFSEL_MASK) >> CP_REG_MEMPERFSEL_PERFSEL_SHIFT) +#define CP_REG_MEMPERFSEL_SET_PERFSEL(cp_reg_memperfsel, perfsel) { \ + FDL_ASSERT(!((perfsel) & ~((1 << CP_REG_MEMPERFSEL_PERFSEL_SIZE)-1))); \ + cp_reg_memperfsel = (((unsigned long)(cp_reg_memperfsel)) & ~CP_REG_MEMPERFSEL_PERFSEL_MASK) | (((unsigned long)(perfsel)) << CP_REG_MEMPERFSEL_PERFSEL_SHIFT);\ +} +#define CP_REG_MEMPERFSEL_TOTAL_SIZE 3 +#define CP_REG_MEMPERFSEL(perfsel) \ + ((((unsigned long)(perfsel)) << CP_REG_MEMPERFSEL_PERFSEL_SHIFT)) + +/* +* cp_reg_fifo_basel struct +*/ +#define CP_REG_FIFO_BASEL_PAD0_SIZE 5 +#define CP_REG_FIFO_BASEL_PAD0_SHIFT 0 +#define CP_REG_FIFO_BASEL_PAD0_MASK 0x0000001f +#define CP_REG_FIFO_BASEL_GET_PAD0(cp_reg_fifo_basel) \ + ((((unsigned long)(cp_reg_fifo_basel)) & CP_REG_FIFO_BASEL_PAD0_MASK) >> CP_REG_FIFO_BASEL_PAD0_SHIFT) +#define CP_REG_FIFO_BASEL_SET_PAD0(cp_reg_fifo_basel, pad0) { \ + FDL_ASSERT(!((pad0) & ~((1 << CP_REG_FIFO_BASEL_PAD0_SIZE)-1))); \ + cp_reg_fifo_basel = (((unsigned long)(cp_reg_fifo_basel)) & ~CP_REG_FIFO_BASEL_PAD0_MASK) | (((unsigned long)(pad0)) << CP_REG_FIFO_BASEL_PAD0_SHIFT);\ +} +#define CP_REG_FIFO_BASEL_ADDR_SIZE 11 +#define CP_REG_FIFO_BASEL_ADDR_SHIFT 5 +#define CP_REG_FIFO_BASEL_ADDR_MASK 0x0000ffe0 +#define CP_REG_FIFO_BASEL_GET_ADDR(cp_reg_fifo_basel) \ + ((((unsigned long)(cp_reg_fifo_basel)) & CP_REG_FIFO_BASEL_ADDR_MASK) >> CP_REG_FIFO_BASEL_ADDR_SHIFT) +#define CP_REG_FIFO_BASEL_SET_ADDR(cp_reg_fifo_basel, addr) { \ + FDL_ASSERT(!((addr) & ~((1 << CP_REG_FIFO_BASEL_ADDR_SIZE)-1))); \ + cp_reg_fifo_basel = (((unsigned long)(cp_reg_fifo_basel)) & ~CP_REG_FIFO_BASEL_ADDR_MASK) | (((unsigned long)(addr)) << CP_REG_FIFO_BASEL_ADDR_SHIFT);\ +} +#define CP_REG_FIFO_BASEL_TOTAL_SIZE 16 +#define CP_REG_FIFO_BASEL(addr) \ + ((((unsigned long)(addr)) << CP_REG_FIFO_BASEL_ADDR_SHIFT)) + +/* +* cp_reg_fifo_baseh struct +*/ +#define CP_REG_FIFO_BASEH_ADDR_SIZE 13 +#define CP_REG_FIFO_BASEH_ADDR_SHIFT 0 +#define CP_REG_FIFO_BASEH_ADDR_MASK 0x00001fff +#define CP_REG_FIFO_BASEH_GET_ADDR(cp_reg_fifo_baseh) \ + ((((unsigned long)(cp_reg_fifo_baseh)) & CP_REG_FIFO_BASEH_ADDR_MASK) >> CP_REG_FIFO_BASEH_ADDR_SHIFT) +#define CP_REG_FIFO_BASEH_SET_ADDR(cp_reg_fifo_baseh, addr) { \ + FDL_ASSERT(!((addr) & ~((1 << CP_REG_FIFO_BASEH_ADDR_SIZE)-1))); \ + cp_reg_fifo_baseh = (((unsigned long)(cp_reg_fifo_baseh)) & ~CP_REG_FIFO_BASEH_ADDR_MASK) | (((unsigned long)(addr)) << CP_REG_FIFO_BASEH_ADDR_SHIFT);\ +} +#define CP_REG_FIFO_BASEH_TOTAL_SIZE 13 +#define CP_REG_FIFO_BASEH(addr) \ + ((((unsigned long)(addr)) << CP_REG_FIFO_BASEH_ADDR_SHIFT)) + +/* +* cp_reg_fifo_topl struct +*/ +#define CP_REG_FIFO_TOPL_PAD0_SIZE 5 +#define CP_REG_FIFO_TOPL_PAD0_SHIFT 0 +#define CP_REG_FIFO_TOPL_PAD0_MASK 0x0000001f +#define CP_REG_FIFO_TOPL_GET_PAD0(cp_reg_fifo_topl) \ + ((((unsigned long)(cp_reg_fifo_topl)) & CP_REG_FIFO_TOPL_PAD0_MASK) >> CP_REG_FIFO_TOPL_PAD0_SHIFT) +#define CP_REG_FIFO_TOPL_SET_PAD0(cp_reg_fifo_topl, pad0) { \ + FDL_ASSERT(!((pad0) & ~((1 << CP_REG_FIFO_TOPL_PAD0_SIZE)-1))); \ + cp_reg_fifo_topl = (((unsigned long)(cp_reg_fifo_topl)) & ~CP_REG_FIFO_TOPL_PAD0_MASK) | (((unsigned long)(pad0)) << CP_REG_FIFO_TOPL_PAD0_SHIFT);\ +} +#define CP_REG_FIFO_TOPL_ADDR_SIZE 11 +#define CP_REG_FIFO_TOPL_ADDR_SHIFT 5 +#define CP_REG_FIFO_TOPL_ADDR_MASK 0x0000ffe0 +#define CP_REG_FIFO_TOPL_GET_ADDR(cp_reg_fifo_topl) \ + ((((unsigned long)(cp_reg_fifo_topl)) & CP_REG_FIFO_TOPL_ADDR_MASK) >> CP_REG_FIFO_TOPL_ADDR_SHIFT) +#define CP_REG_FIFO_TOPL_SET_ADDR(cp_reg_fifo_topl, addr) { \ + FDL_ASSERT(!((addr) & ~((1 << CP_REG_FIFO_TOPL_ADDR_SIZE)-1))); \ + cp_reg_fifo_topl = (((unsigned long)(cp_reg_fifo_topl)) & ~CP_REG_FIFO_TOPL_ADDR_MASK) | (((unsigned long)(addr)) << CP_REG_FIFO_TOPL_ADDR_SHIFT);\ +} +#define CP_REG_FIFO_TOPL_TOTAL_SIZE 16 +#define CP_REG_FIFO_TOPL(addr) \ + ((((unsigned long)(addr)) << CP_REG_FIFO_TOPL_ADDR_SHIFT)) + +/* +* cp_reg_fifo_toph struct +*/ +#define CP_REG_FIFO_TOPH_ADDR_SIZE 13 +#define CP_REG_FIFO_TOPH_ADDR_SHIFT 0 +#define CP_REG_FIFO_TOPH_ADDR_MASK 0x00001fff +#define CP_REG_FIFO_TOPH_GET_ADDR(cp_reg_fifo_toph) \ + ((((unsigned long)(cp_reg_fifo_toph)) & CP_REG_FIFO_TOPH_ADDR_MASK) >> CP_REG_FIFO_TOPH_ADDR_SHIFT) +#define CP_REG_FIFO_TOPH_SET_ADDR(cp_reg_fifo_toph, addr) { \ + FDL_ASSERT(!((addr) & ~((1 << CP_REG_FIFO_TOPH_ADDR_SIZE)-1))); \ + cp_reg_fifo_toph = (((unsigned long)(cp_reg_fifo_toph)) & ~CP_REG_FIFO_TOPH_ADDR_MASK) | (((unsigned long)(addr)) << CP_REG_FIFO_TOPH_ADDR_SHIFT);\ +} +#define CP_REG_FIFO_TOPH_TOTAL_SIZE 13 +#define CP_REG_FIFO_TOPH(addr) \ + ((((unsigned long)(addr)) << CP_REG_FIFO_TOPH_ADDR_SHIFT)) + +/* +* cp_reg_fifo_hicntl struct +*/ +#define CP_REG_FIFO_HICNTL_PAD0_SIZE 5 +#define CP_REG_FIFO_HICNTL_PAD0_SHIFT 0 +#define CP_REG_FIFO_HICNTL_PAD0_MASK 0x0000001f +#define CP_REG_FIFO_HICNTL_GET_PAD0(cp_reg_fifo_hicntl) \ + ((((unsigned long)(cp_reg_fifo_hicntl)) & CP_REG_FIFO_HICNTL_PAD0_MASK) >> CP_REG_FIFO_HICNTL_PAD0_SHIFT) +#define CP_REG_FIFO_HICNTL_SET_PAD0(cp_reg_fifo_hicntl, pad0) { \ + FDL_ASSERT(!((pad0) & ~((1 << CP_REG_FIFO_HICNTL_PAD0_SIZE)-1))); \ + cp_reg_fifo_hicntl = (((unsigned long)(cp_reg_fifo_hicntl)) & ~CP_REG_FIFO_HICNTL_PAD0_MASK) | (((unsigned long)(pad0)) << CP_REG_FIFO_HICNTL_PAD0_SHIFT);\ +} +#define CP_REG_FIFO_HICNTL_ADDR_SIZE 11 +#define CP_REG_FIFO_HICNTL_ADDR_SHIFT 5 +#define CP_REG_FIFO_HICNTL_ADDR_MASK 0x0000ffe0 +#define CP_REG_FIFO_HICNTL_GET_ADDR(cp_reg_fifo_hicntl) \ + ((((unsigned long)(cp_reg_fifo_hicntl)) & CP_REG_FIFO_HICNTL_ADDR_MASK) >> CP_REG_FIFO_HICNTL_ADDR_SHIFT) +#define CP_REG_FIFO_HICNTL_SET_ADDR(cp_reg_fifo_hicntl, addr) { \ + FDL_ASSERT(!((addr) & ~((1 << CP_REG_FIFO_HICNTL_ADDR_SIZE)-1))); \ + cp_reg_fifo_hicntl = (((unsigned long)(cp_reg_fifo_hicntl)) & ~CP_REG_FIFO_HICNTL_ADDR_MASK) | (((unsigned long)(addr)) << CP_REG_FIFO_HICNTL_ADDR_SHIFT);\ +} +#define CP_REG_FIFO_HICNTL_TOTAL_SIZE 16 +#define CP_REG_FIFO_HICNTL(addr) \ + ((((unsigned long)(addr)) << CP_REG_FIFO_HICNTL_ADDR_SHIFT)) + +/* +* cp_reg_fifo_hicnth struct +*/ +#define CP_REG_FIFO_HICNTH_ADDR_SIZE 13 +#define CP_REG_FIFO_HICNTH_ADDR_SHIFT 0 +#define CP_REG_FIFO_HICNTH_ADDR_MASK 0x00001fff +#define CP_REG_FIFO_HICNTH_GET_ADDR(cp_reg_fifo_hicnth) \ + ((((unsigned long)(cp_reg_fifo_hicnth)) & CP_REG_FIFO_HICNTH_ADDR_MASK) >> CP_REG_FIFO_HICNTH_ADDR_SHIFT) +#define CP_REG_FIFO_HICNTH_SET_ADDR(cp_reg_fifo_hicnth, addr) { \ + FDL_ASSERT(!((addr) & ~((1 << CP_REG_FIFO_HICNTH_ADDR_SIZE)-1))); \ + cp_reg_fifo_hicnth = (((unsigned long)(cp_reg_fifo_hicnth)) & ~CP_REG_FIFO_HICNTH_ADDR_MASK) | (((unsigned long)(addr)) << CP_REG_FIFO_HICNTH_ADDR_SHIFT);\ +} +#define CP_REG_FIFO_HICNTH_TOTAL_SIZE 13 +#define CP_REG_FIFO_HICNTH(addr) \ + ((((unsigned long)(addr)) << CP_REG_FIFO_HICNTH_ADDR_SHIFT)) + +#define CP_REG_FIFO_LOCNTL_PAD0_SIZE 5 +#define CP_REG_FIFO_LOCNTL_PAD0_SHIFT 0 +#define CP_REG_FIFO_LOCNTL_PAD0_MASK 0x0000001f +#define CP_REG_FIFO_LOCNTL_GET_PAD0(cp_reg_fifo_locntl) \ + ((((unsigned long)(cp_reg_fifo_locntl)) & CP_REG_FIFO_LOCNTL_PAD0_MASK) >> CP_REG_FIFO_LOCNTL_PAD0_SHIFT) +#define CP_REG_FIFO_LOCNTL_SET_PAD0(cp_reg_fifo_locntl, pad0) { \ + FDL_ASSERT(!((pad0) & ~((1 << CP_REG_FIFO_LOCNTL_PAD0_SIZE)-1))); \ + cp_reg_fifo_locntl = (((unsigned long)(cp_reg_fifo_locntl)) & ~CP_REG_FIFO_LOCNTL_PAD0_MASK) | (((unsigned long)(pad0)) << CP_REG_FIFO_LOCNTL_PAD0_SHIFT);\ +} +#define CP_REG_FIFO_LOCNTL_ADDR_SIZE 11 +#define CP_REG_FIFO_LOCNTL_ADDR_SHIFT 5 +#define CP_REG_FIFO_LOCNTL_ADDR_MASK 0x0000ffe0 +#define CP_REG_FIFO_LOCNTL_GET_ADDR(cp_reg_fifo_locntl) \ + ((((unsigned long)(cp_reg_fifo_locntl)) & CP_REG_FIFO_LOCNTL_ADDR_MASK) >> CP_REG_FIFO_LOCNTL_ADDR_SHIFT) +#define CP_REG_FIFO_LOCNTL_SET_ADDR(cp_reg_fifo_locntl, addr) { \ + FDL_ASSERT(!((addr) & ~((1 << CP_REG_FIFO_LOCNTL_ADDR_SIZE)-1))); \ + cp_reg_fifo_locntl = (((unsigned long)(cp_reg_fifo_locntl)) & ~CP_REG_FIFO_LOCNTL_ADDR_MASK) | (((unsigned long)(addr)) << CP_REG_FIFO_LOCNTL_ADDR_SHIFT);\ +} +#define CP_REG_FIFO_LOCNTL_TOTAL_SIZE 16 +#define CP_REG_FIFO_LOCNTL(addr) \ + ((((unsigned long)(addr)) << CP_REG_FIFO_LOCNTL_ADDR_SHIFT)) + +#define CP_REG_FIFO_LOCNTH_ADDR_SIZE 13 +#define CP_REG_FIFO_LOCNTH_ADDR_SHIFT 0 +#define CP_REG_FIFO_LOCNTH_ADDR_MASK 0x00001fff +#define CP_REG_FIFO_LOCNTH_GET_ADDR(cp_reg_fifo_locnth) \ + ((((unsigned long)(cp_reg_fifo_locnth)) & CP_REG_FIFO_LOCNTH_ADDR_MASK) >> CP_REG_FIFO_LOCNTH_ADDR_SHIFT) +#define CP_REG_FIFO_LOCNTH_SET_ADDR(cp_reg_fifo_locnth, addr) { \ + FDL_ASSERT(!((addr) & ~((1 << CP_REG_FIFO_LOCNTH_ADDR_SIZE)-1))); \ + cp_reg_fifo_locnth = (((unsigned long)(cp_reg_fifo_locnth)) & ~CP_REG_FIFO_LOCNTH_ADDR_MASK) | (((unsigned long)(addr)) << CP_REG_FIFO_LOCNTH_ADDR_SHIFT);\ +} +#define CP_REG_FIFO_LOCNTH_TOTAL_SIZE 13 +#define CP_REG_FIFO_LOCNTH(addr) \ + ((((unsigned long)(addr)) << CP_REG_FIFO_LOCNTH_ADDR_SHIFT)) + +#define CP_REG_FIFO_COUNTL_PAD0_SIZE 5 +#define CP_REG_FIFO_COUNTL_PAD0_SHIFT 0 +#define CP_REG_FIFO_COUNTL_PAD0_MASK 0x0000001f +#define CP_REG_FIFO_COUNTL_GET_PAD0(cp_reg_fifo_countl) \ + ((((unsigned long)(cp_reg_fifo_countl)) & CP_REG_FIFO_COUNTL_PAD0_MASK) >> CP_REG_FIFO_COUNTL_PAD0_SHIFT) +#define CP_REG_FIFO_COUNTL_SET_PAD0(cp_reg_fifo_countl, pad0) { \ + FDL_ASSERT(!((pad0) & ~((1 << CP_REG_FIFO_COUNTL_PAD0_SIZE)-1))); \ + cp_reg_fifo_countl = (((unsigned long)(cp_reg_fifo_countl)) & ~CP_REG_FIFO_COUNTL_PAD0_MASK) | (((unsigned long)(pad0)) << CP_REG_FIFO_COUNTL_PAD0_SHIFT);\ +} +#define CP_REG_FIFO_COUNTL_ADDR_SIZE 11 +#define CP_REG_FIFO_COUNTL_ADDR_SHIFT 5 +#define CP_REG_FIFO_COUNTL_ADDR_MASK 0x0000ffe0 +#define CP_REG_FIFO_COUNTL_GET_ADDR(cp_reg_fifo_countl) \ + ((((unsigned long)(cp_reg_fifo_countl)) & CP_REG_FIFO_COUNTL_ADDR_MASK) >> CP_REG_FIFO_COUNTL_ADDR_SHIFT) +#define CP_REG_FIFO_COUNTL_SET_ADDR(cp_reg_fifo_countl, addr) { \ + FDL_ASSERT(!((addr) & ~((1 << CP_REG_FIFO_COUNTL_ADDR_SIZE)-1))); \ + cp_reg_fifo_countl = (((unsigned long)(cp_reg_fifo_countl)) & ~CP_REG_FIFO_COUNTL_ADDR_MASK) | (((unsigned long)(addr)) << CP_REG_FIFO_COUNTL_ADDR_SHIFT);\ +} +#define CP_REG_FIFO_COUNTL_TOTAL_SIZE 16 +#define CP_REG_FIFO_COUNTL(addr) \ + ((((unsigned long)(addr)) << CP_REG_FIFO_COUNTL_ADDR_SHIFT)) + +#define CP_REG_FIFO_COUNTH_ADDR_SIZE 13 +#define CP_REG_FIFO_COUNTH_ADDR_SHIFT 0 +#define CP_REG_FIFO_COUNTH_ADDR_MASK 0x00001fff +#define CP_REG_FIFO_COUNTH_GET_ADDR(cp_reg_fifo_counth) \ + ((((unsigned long)(cp_reg_fifo_counth)) & CP_REG_FIFO_COUNTH_ADDR_MASK) >> CP_REG_FIFO_COUNTH_ADDR_SHIFT) +#define CP_REG_FIFO_COUNTH_SET_ADDR(cp_reg_fifo_counth, addr) { \ + FDL_ASSERT(!((addr) & ~((1 << CP_REG_FIFO_COUNTH_ADDR_SIZE)-1))); \ + cp_reg_fifo_counth = (((unsigned long)(cp_reg_fifo_counth)) & ~CP_REG_FIFO_COUNTH_ADDR_MASK) | (((unsigned long)(addr)) << CP_REG_FIFO_COUNTH_ADDR_SHIFT);\ +} +#define CP_REG_FIFO_COUNTH_TOTAL_SIZE 13 +#define CP_REG_FIFO_COUNTH(addr) \ + ((((unsigned long)(addr)) << CP_REG_FIFO_COUNTH_ADDR_SHIFT)) + +#define CP_REG_FIFO_WPTRL_PAD0_SIZE 5 +#define CP_REG_FIFO_WPTRL_PAD0_SHIFT 0 +#define CP_REG_FIFO_WPTRL_PAD0_MASK 0x0000001f +#define CP_REG_FIFO_WPTRL_GET_PAD0(cp_reg_fifo_wptrl) \ + ((((unsigned long)(cp_reg_fifo_wptrl)) & CP_REG_FIFO_WPTRL_PAD0_MASK) >> CP_REG_FIFO_WPTRL_PAD0_SHIFT) +#define CP_REG_FIFO_WPTRL_SET_PAD0(cp_reg_fifo_wptrl, pad0) { \ + FDL_ASSERT(!((pad0) & ~((1 << CP_REG_FIFO_WPTRL_PAD0_SIZE)-1))); \ + cp_reg_fifo_wptrl = (((unsigned long)(cp_reg_fifo_wptrl)) & ~CP_REG_FIFO_WPTRL_PAD0_MASK) | (((unsigned long)(pad0)) << CP_REG_FIFO_WPTRL_PAD0_SHIFT);\ +} +#define CP_REG_FIFO_WPTRL_ADDR_SIZE 11 +#define CP_REG_FIFO_WPTRL_ADDR_SHIFT 5 +#define CP_REG_FIFO_WPTRL_ADDR_MASK 0x0000ffe0 +#define CP_REG_FIFO_WPTRL_GET_ADDR(cp_reg_fifo_wptrl) \ + ((((unsigned long)(cp_reg_fifo_wptrl)) & CP_REG_FIFO_WPTRL_ADDR_MASK) >> CP_REG_FIFO_WPTRL_ADDR_SHIFT) +#define CP_REG_FIFO_WPTRL_SET_ADDR(cp_reg_fifo_wptrl, addr) { \ + FDL_ASSERT(!((addr) & ~((1 << CP_REG_FIFO_WPTRL_ADDR_SIZE)-1))); \ + cp_reg_fifo_wptrl = (((unsigned long)(cp_reg_fifo_wptrl)) & ~CP_REG_FIFO_WPTRL_ADDR_MASK) | (((unsigned long)(addr)) << CP_REG_FIFO_WPTRL_ADDR_SHIFT);\ +} +#define CP_REG_FIFO_WPTRL_TOTAL_SIZE 16 +#define CP_REG_FIFO_WPTRL(addr) \ + ((((unsigned long)(addr)) << CP_REG_FIFO_WPTRL_ADDR_SHIFT)) + +#define CP_REG_FIFO_WPTRH_ADDR_SIZE 13 +#define CP_REG_FIFO_WPTRH_ADDR_SHIFT 0 +#define CP_REG_FIFO_WPTRH_ADDR_MASK 0x00001fff +#define CP_REG_FIFO_WPTRH_GET_ADDR(cp_reg_fifo_wptrh) \ + ((((unsigned long)(cp_reg_fifo_wptrh)) & CP_REG_FIFO_WPTRH_ADDR_MASK) >> CP_REG_FIFO_WPTRH_ADDR_SHIFT) +#define CP_REG_FIFO_WPTRH_SET_ADDR(cp_reg_fifo_wptrh, addr) { \ + FDL_ASSERT(!((addr) & ~((1 << CP_REG_FIFO_WPTRH_ADDR_SIZE)-1))); \ + cp_reg_fifo_wptrh = (((unsigned long)(cp_reg_fifo_wptrh)) & ~CP_REG_FIFO_WPTRH_ADDR_MASK) | (((unsigned long)(addr)) << CP_REG_FIFO_WPTRH_ADDR_SHIFT);\ +} +#define CP_REG_FIFO_WPTRH_TOTAL_SIZE 13 +#define CP_REG_FIFO_WPTRH(addr) \ + ((((unsigned long)(addr)) << CP_REG_FIFO_WPTRH_ADDR_SHIFT)) + +#define CP_REG_FIFO_RPTRL_PAD0_SIZE 5 +#define CP_REG_FIFO_RPTRL_PAD0_SHIFT 0 +#define CP_REG_FIFO_RPTRL_PAD0_MASK 0x0000001f +#define CP_REG_FIFO_RPTRL_GET_PAD0(cp_reg_fifo_rptrl) \ + ((((unsigned long)(cp_reg_fifo_rptrl)) & CP_REG_FIFO_RPTRL_PAD0_MASK) >> CP_REG_FIFO_RPTRL_PAD0_SHIFT) +#define CP_REG_FIFO_RPTRL_SET_PAD0(cp_reg_fifo_rptrl, pad0) { \ + FDL_ASSERT(!((pad0) & ~((1 << CP_REG_FIFO_RPTRL_PAD0_SIZE)-1))); \ + cp_reg_fifo_rptrl = (((unsigned long)(cp_reg_fifo_rptrl)) & ~CP_REG_FIFO_RPTRL_PAD0_MASK) | (((unsigned long)(pad0)) << CP_REG_FIFO_RPTRL_PAD0_SHIFT);\ +} +#define CP_REG_FIFO_RPTRL_ADDR_SIZE 11 +#define CP_REG_FIFO_RPTRL_ADDR_SHIFT 5 +#define CP_REG_FIFO_RPTRL_ADDR_MASK 0x0000ffe0 +#define CP_REG_FIFO_RPTRL_GET_ADDR(cp_reg_fifo_rptrl) \ + ((((unsigned long)(cp_reg_fifo_rptrl)) & CP_REG_FIFO_RPTRL_ADDR_MASK) >> CP_REG_FIFO_RPTRL_ADDR_SHIFT) +#define CP_REG_FIFO_RPTRL_SET_ADDR(cp_reg_fifo_rptrl, addr) { \ + FDL_ASSERT(!((addr) & ~((1 << CP_REG_FIFO_RPTRL_ADDR_SIZE)-1))); \ + cp_reg_fifo_rptrl = (((unsigned long)(cp_reg_fifo_rptrl)) & ~CP_REG_FIFO_RPTRL_ADDR_MASK) | (((unsigned long)(addr)) << CP_REG_FIFO_RPTRL_ADDR_SHIFT);\ +} +#define CP_REG_FIFO_RPTRL_TOTAL_SIZE 16 +#define CP_REG_FIFO_RPTRL(addr) \ + ((((unsigned long)(addr)) << CP_REG_FIFO_RPTRL_ADDR_SHIFT)) + +#define CP_REG_FIFO_RPTRH_ADDR_SIZE 13 +#define CP_REG_FIFO_RPTRH_ADDR_SHIFT 0 +#define CP_REG_FIFO_RPTRH_ADDR_MASK 0x00001fff +#define CP_REG_FIFO_RPTRH_GET_ADDR(cp_reg_fifo_rptrh) \ + ((((unsigned long)(cp_reg_fifo_rptrh)) & CP_REG_FIFO_RPTRH_ADDR_MASK) >> CP_REG_FIFO_RPTRH_ADDR_SHIFT) +#define CP_REG_FIFO_RPTRH_SET_ADDR(cp_reg_fifo_rptrh, addr) { \ + FDL_ASSERT(!((addr) & ~((1 << CP_REG_FIFO_RPTRH_ADDR_SIZE)-1))); \ + cp_reg_fifo_rptrh = (((unsigned long)(cp_reg_fifo_rptrh)) & ~CP_REG_FIFO_RPTRH_ADDR_MASK) | (((unsigned long)(addr)) << CP_REG_FIFO_RPTRH_ADDR_SHIFT);\ +} +#define CP_REG_FIFO_RPTRH_TOTAL_SIZE 13 +#define CP_REG_FIFO_RPTRH(addr) \ + ((((unsigned long)(addr)) << CP_REG_FIFO_RPTRH_ADDR_SHIFT)) + +#define CP_REG_FIFO_BRKL_PAD0_SIZE 5 +#define CP_REG_FIFO_BRKL_PAD0_SHIFT 0 +#define CP_REG_FIFO_BRKL_PAD0_MASK 0x0000001f +#define CP_REG_FIFO_BRKL_GET_PAD0(cp_reg_fifo_brkl) \ + ((((unsigned long)(cp_reg_fifo_brkl)) & CP_REG_FIFO_BRKL_PAD0_MASK) >> CP_REG_FIFO_BRKL_PAD0_SHIFT) +#define CP_REG_FIFO_BRKL_SET_PAD0(cp_reg_fifo_brkl, pad0) { \ + FDL_ASSERT(!((pad0) & ~((1 << CP_REG_FIFO_BRKL_PAD0_SIZE)-1))); \ + cp_reg_fifo_brkl = (((unsigned long)(cp_reg_fifo_brkl)) & ~CP_REG_FIFO_BRKL_PAD0_MASK) | (((unsigned long)(pad0)) << CP_REG_FIFO_BRKL_PAD0_SHIFT);\ +} +#define CP_REG_FIFO_BRKL_ADDR_SIZE 11 +#define CP_REG_FIFO_BRKL_ADDR_SHIFT 5 +#define CP_REG_FIFO_BRKL_ADDR_MASK 0x0000ffe0 +#define CP_REG_FIFO_BRKL_GET_ADDR(cp_reg_fifo_brkl) \ + ((((unsigned long)(cp_reg_fifo_brkl)) & CP_REG_FIFO_BRKL_ADDR_MASK) >> CP_REG_FIFO_BRKL_ADDR_SHIFT) +#define CP_REG_FIFO_BRKL_SET_ADDR(cp_reg_fifo_brkl, addr) { \ + FDL_ASSERT(!((addr) & ~((1 << CP_REG_FIFO_BRKL_ADDR_SIZE)-1))); \ + cp_reg_fifo_brkl = (((unsigned long)(cp_reg_fifo_brkl)) & ~CP_REG_FIFO_BRKL_ADDR_MASK) | (((unsigned long)(addr)) << CP_REG_FIFO_BRKL_ADDR_SHIFT);\ +} +#define CP_REG_FIFO_BRKL_TOTAL_SIZE 16 +#define CP_REG_FIFO_BRKL(addr) \ + ((((unsigned long)(addr)) << CP_REG_FIFO_BRKL_ADDR_SHIFT)) + +/* +* cp_reg_fifo_brkh struct +*/ +#define CP_REG_FIFO_BRKH_ADDR_SIZE 13 +#define CP_REG_FIFO_BRKH_ADDR_SHIFT 0 +#define CP_REG_FIFO_BRKH_ADDR_MASK 0x00001fff +#define CP_REG_FIFO_BRKH_GET_ADDR(cp_reg_fifo_brkh) \ + ((((unsigned long)(cp_reg_fifo_brkh)) & CP_REG_FIFO_BRKH_ADDR_MASK) >> CP_REG_FIFO_BRKH_ADDR_SHIFT) +#define CP_REG_FIFO_BRKH_SET_ADDR(cp_reg_fifo_brkh, addr) { \ + FDL_ASSERT(!((addr) & ~((1 << CP_REG_FIFO_BRKH_ADDR_SIZE)-1))); \ + cp_reg_fifo_brkh = (((unsigned long)(cp_reg_fifo_brkh)) & ~CP_REG_FIFO_BRKH_ADDR_MASK) | (((unsigned long)(addr)) << CP_REG_FIFO_BRKH_ADDR_SHIFT);\ +} +#define CP_REG_FIFO_BRKH_TOTAL_SIZE 13 +#define CP_REG_FIFO_BRKH(addr) \ + ((((unsigned long)(addr)) << CP_REG_FIFO_BRKH_ADDR_SHIFT)) + +/* +* memperf_sel enum +*/ +#define MEMPERF_ZERO 0x00000000 +#define MEMPERF_ONE 0x00000001 +#define DFIFO_REQ_CNT 0x00000002 +#define OBJCALL_REQ_CNT 0x00000003 +#define VCMISS_REQ_CNT 0x00000004 +#define ALL_MEMREQ_CNT 0x00000005 +#define MEMPERF_SEL_UNUSED_6 0x00000006 +#define MEMPERF_SEL_UNUSED_7 0x00000007 + +/* +* vtx_attr_name value +*/ +#define VTX_ATTR_POSMATIDX 0x00 +#define VTX_ATTR_TEX0MATIDX 0x01 +#define VTX_ATTR_TEX1MATIDX 0x02 +#define VTX_ATTR_TEX2MATIDX 0x03 +#define VTX_ATTR_TEX3MATIDX 0x04 +#define VTX_ATTR_TEX4MATIDX 0x05 +#define VTX_ATTR_TEX5MATIDX 0x06 +#define VTX_ATTR_TEX6MATIDX 0x07 +#define VTX_ATTR_TEX7MATIDX 0x08 +#define VTX_ATTR_POS 0x09 +#define VTX_ATTR_NRM 0x0a +#define VTX_ATTR_COL0 0x0b +#define VTX_ATTR_COL1 0x0c +#define VTX_ATTR_TEX0 0x0d +#define VTX_ATTR_TEX1 0x0e +#define VTX_ATTR_TEX2 0x0f +#define VTX_ATTR_TEX3 0x10 +#define VTX_ATTR_TEX4 0x11 +#define VTX_ATTR_TEX5 0x12 +#define VTX_ATTR_TEX6 0x13 +#define VTX_ATTR_TEX7 0x14 +#define VTX_ATTR_POSARRAY 0x15 +#define VTX_ATTR_NRMARRAY 0x16 +#define VTX_ATTR_TEXARRAY 0x17 +#define VTX_ATTR_LIGHTARRAY 0x18 +#define VTX_NUM_ATTR 0x19 + +/* +* vtx_attr_type value +*/ +#define ATTR_NONE 0x0 +#define ATTR_DIRECT 0x1 +#define ATTR_INDEX8 0x2 +#define ATTR_INDEX16 0x3 + +/* +* attr_comp_fmt value +*/ +#define ATTR_COMP_UBYTE 0x0 +#define ATTR_COMP_BYTE 0x1 +#define ATTR_COMP_USHORT 0x2 +#define ATTR_COMP_SHORT 0x3 +#define ATTR_COMP_FLOAT 0x4 + +/* +* attr_clr_fmt value +*/ +#define ATTR_CLR_565 0x0 +#define ATTR_CLR_888 0x1 +#define ATTR_CLR_888X 0x2 +#define ATTR_CLR_4444 0x3 +#define ATTR_CLR_6666 0x4 +#define ATTR_CLR_8888 0x5 + +/* +* cp_vcd_reg_lo struct +*/ +#define CP_VCD_REG_LO_PMIDX_SIZE 1 +#define CP_VCD_REG_LO_PMIDX_SHIFT 0 +#define CP_VCD_REG_LO_PMIDX_MASK 0x00000001 +#define CP_VCD_REG_LO_GET_PMIDX(cp_vcd_reg_lo) \ + ((((unsigned long)(cp_vcd_reg_lo)) & CP_VCD_REG_LO_PMIDX_MASK) >> CP_VCD_REG_LO_PMIDX_SHIFT) +#define CP_VCD_REG_LO_SET_PMIDX(cp_vcd_reg_lo, pmidx) { \ + FDL_ASSERT(!((pmidx) & ~((1 << CP_VCD_REG_LO_PMIDX_SIZE)-1))); \ + cp_vcd_reg_lo = (((unsigned long)(cp_vcd_reg_lo)) & ~CP_VCD_REG_LO_PMIDX_MASK) | (((unsigned long)(pmidx)) << CP_VCD_REG_LO_PMIDX_SHIFT);\ +} +#define CP_VCD_REG_LO_T0MIDX_SIZE 1 +#define CP_VCD_REG_LO_T0MIDX_SHIFT 1 +#define CP_VCD_REG_LO_T0MIDX_MASK 0x00000002 +#define CP_VCD_REG_LO_GET_T0MIDX(cp_vcd_reg_lo) \ + ((((unsigned long)(cp_vcd_reg_lo)) & CP_VCD_REG_LO_T0MIDX_MASK) >> CP_VCD_REG_LO_T0MIDX_SHIFT) +#define CP_VCD_REG_LO_SET_T0MIDX(cp_vcd_reg_lo, t0midx) { \ + FDL_ASSERT(!((t0midx) & ~((1 << CP_VCD_REG_LO_T0MIDX_SIZE)-1))); \ + cp_vcd_reg_lo = (((unsigned long)(cp_vcd_reg_lo)) & ~CP_VCD_REG_LO_T0MIDX_MASK) | (((unsigned long)(t0midx)) << CP_VCD_REG_LO_T0MIDX_SHIFT);\ +} +#define CP_VCD_REG_LO_T1MIDX_SIZE 1 +#define CP_VCD_REG_LO_T1MIDX_SHIFT 2 +#define CP_VCD_REG_LO_T1MIDX_MASK 0x00000004 +#define CP_VCD_REG_LO_GET_T1MIDX(cp_vcd_reg_lo) \ + ((((unsigned long)(cp_vcd_reg_lo)) & CP_VCD_REG_LO_T1MIDX_MASK) >> CP_VCD_REG_LO_T1MIDX_SHIFT) +#define CP_VCD_REG_LO_SET_T1MIDX(cp_vcd_reg_lo, t1midx) { \ + FDL_ASSERT(!((t1midx) & ~((1 << CP_VCD_REG_LO_T1MIDX_SIZE)-1))); \ + cp_vcd_reg_lo = (((unsigned long)(cp_vcd_reg_lo)) & ~CP_VCD_REG_LO_T1MIDX_MASK) | (((unsigned long)(t1midx)) << CP_VCD_REG_LO_T1MIDX_SHIFT);\ +} +#define CP_VCD_REG_LO_T2MIDX_SIZE 1 +#define CP_VCD_REG_LO_T2MIDX_SHIFT 3 +#define CP_VCD_REG_LO_T2MIDX_MASK 0x00000008 +#define CP_VCD_REG_LO_GET_T2MIDX(cp_vcd_reg_lo) \ + ((((unsigned long)(cp_vcd_reg_lo)) & CP_VCD_REG_LO_T2MIDX_MASK) >> CP_VCD_REG_LO_T2MIDX_SHIFT) +#define CP_VCD_REG_LO_SET_T2MIDX(cp_vcd_reg_lo, t2midx) { \ + FDL_ASSERT(!((t2midx) & ~((1 << CP_VCD_REG_LO_T2MIDX_SIZE)-1))); \ + cp_vcd_reg_lo = (((unsigned long)(cp_vcd_reg_lo)) & ~CP_VCD_REG_LO_T2MIDX_MASK) | (((unsigned long)(t2midx)) << CP_VCD_REG_LO_T2MIDX_SHIFT);\ +} +#define CP_VCD_REG_LO_T3MIDX_SIZE 1 +#define CP_VCD_REG_LO_T3MIDX_SHIFT 4 +#define CP_VCD_REG_LO_T3MIDX_MASK 0x00000010 +#define CP_VCD_REG_LO_GET_T3MIDX(cp_vcd_reg_lo) \ + ((((unsigned long)(cp_vcd_reg_lo)) & CP_VCD_REG_LO_T3MIDX_MASK) >> CP_VCD_REG_LO_T3MIDX_SHIFT) +#define CP_VCD_REG_LO_SET_T3MIDX(cp_vcd_reg_lo, t3midx) { \ + FDL_ASSERT(!((t3midx) & ~((1 << CP_VCD_REG_LO_T3MIDX_SIZE)-1))); \ + cp_vcd_reg_lo = (((unsigned long)(cp_vcd_reg_lo)) & ~CP_VCD_REG_LO_T3MIDX_MASK) | (((unsigned long)(t3midx)) << CP_VCD_REG_LO_T3MIDX_SHIFT);\ +} +#define CP_VCD_REG_LO_T4MIDX_SIZE 1 +#define CP_VCD_REG_LO_T4MIDX_SHIFT 5 +#define CP_VCD_REG_LO_T4MIDX_MASK 0x00000020 +#define CP_VCD_REG_LO_GET_T4MIDX(cp_vcd_reg_lo) \ + ((((unsigned long)(cp_vcd_reg_lo)) & CP_VCD_REG_LO_T4MIDX_MASK) >> CP_VCD_REG_LO_T4MIDX_SHIFT) +#define CP_VCD_REG_LO_SET_T4MIDX(cp_vcd_reg_lo, t4midx) { \ + FDL_ASSERT(!((t4midx) & ~((1 << CP_VCD_REG_LO_T4MIDX_SIZE)-1))); \ + cp_vcd_reg_lo = (((unsigned long)(cp_vcd_reg_lo)) & ~CP_VCD_REG_LO_T4MIDX_MASK) | (((unsigned long)(t4midx)) << CP_VCD_REG_LO_T4MIDX_SHIFT);\ +} +#define CP_VCD_REG_LO_T5MIDX_SIZE 1 +#define CP_VCD_REG_LO_T5MIDX_SHIFT 6 +#define CP_VCD_REG_LO_T5MIDX_MASK 0x00000040 +#define CP_VCD_REG_LO_GET_T5MIDX(cp_vcd_reg_lo) \ + ((((unsigned long)(cp_vcd_reg_lo)) & CP_VCD_REG_LO_T5MIDX_MASK) >> CP_VCD_REG_LO_T5MIDX_SHIFT) +#define CP_VCD_REG_LO_SET_T5MIDX(cp_vcd_reg_lo, t5midx) { \ + FDL_ASSERT(!((t5midx) & ~((1 << CP_VCD_REG_LO_T5MIDX_SIZE)-1))); \ + cp_vcd_reg_lo = (((unsigned long)(cp_vcd_reg_lo)) & ~CP_VCD_REG_LO_T5MIDX_MASK) | (((unsigned long)(t5midx)) << CP_VCD_REG_LO_T5MIDX_SHIFT);\ +} +#define CP_VCD_REG_LO_T6MIDX_SIZE 1 +#define CP_VCD_REG_LO_T6MIDX_SHIFT 7 +#define CP_VCD_REG_LO_T6MIDX_MASK 0x00000080 +#define CP_VCD_REG_LO_GET_T6MIDX(cp_vcd_reg_lo) \ + ((((unsigned long)(cp_vcd_reg_lo)) & CP_VCD_REG_LO_T6MIDX_MASK) >> CP_VCD_REG_LO_T6MIDX_SHIFT) +#define CP_VCD_REG_LO_SET_T6MIDX(cp_vcd_reg_lo, t6midx) { \ + FDL_ASSERT(!((t6midx) & ~((1 << CP_VCD_REG_LO_T6MIDX_SIZE)-1))); \ + cp_vcd_reg_lo = (((unsigned long)(cp_vcd_reg_lo)) & ~CP_VCD_REG_LO_T6MIDX_MASK) | (((unsigned long)(t6midx)) << CP_VCD_REG_LO_T6MIDX_SHIFT);\ +} +#define CP_VCD_REG_LO_T7MIDX_SIZE 1 +#define CP_VCD_REG_LO_T7MIDX_SHIFT 8 +#define CP_VCD_REG_LO_T7MIDX_MASK 0x00000100 +#define CP_VCD_REG_LO_GET_T7MIDX(cp_vcd_reg_lo) \ + ((((unsigned long)(cp_vcd_reg_lo)) & CP_VCD_REG_LO_T7MIDX_MASK) >> CP_VCD_REG_LO_T7MIDX_SHIFT) +#define CP_VCD_REG_LO_SET_T7MIDX(cp_vcd_reg_lo, t7midx) { \ + FDL_ASSERT(!((t7midx) & ~((1 << CP_VCD_REG_LO_T7MIDX_SIZE)-1))); \ + cp_vcd_reg_lo = (((unsigned long)(cp_vcd_reg_lo)) & ~CP_VCD_REG_LO_T7MIDX_MASK) | (((unsigned long)(t7midx)) << CP_VCD_REG_LO_T7MIDX_SHIFT);\ +} +#define CP_VCD_REG_LO_POS_SIZE 2 +#define CP_VCD_REG_LO_POS_SHIFT 9 +#define CP_VCD_REG_LO_POS_MASK 0x00000600 +#define CP_VCD_REG_LO_GET_POS(cp_vcd_reg_lo) \ + ((((unsigned long)(cp_vcd_reg_lo)) & CP_VCD_REG_LO_POS_MASK) >> CP_VCD_REG_LO_POS_SHIFT) +#define CP_VCD_REG_LO_SET_POS(cp_vcd_reg_lo, pos) { \ + FDL_ASSERT(!((pos) & ~((1 << CP_VCD_REG_LO_POS_SIZE)-1))); \ + cp_vcd_reg_lo = (((unsigned long)(cp_vcd_reg_lo)) & ~CP_VCD_REG_LO_POS_MASK) | (((unsigned long)(pos)) << CP_VCD_REG_LO_POS_SHIFT);\ +} +#define CP_VCD_REG_LO_NRM_SIZE 2 +#define CP_VCD_REG_LO_NRM_SHIFT 11 +#define CP_VCD_REG_LO_NRM_MASK 0x00001800 +#define CP_VCD_REG_LO_GET_NRM(cp_vcd_reg_lo) \ + ((((unsigned long)(cp_vcd_reg_lo)) & CP_VCD_REG_LO_NRM_MASK) >> CP_VCD_REG_LO_NRM_SHIFT) +#define CP_VCD_REG_LO_SET_NRM(cp_vcd_reg_lo, nrm) { \ + FDL_ASSERT(!((nrm) & ~((1 << CP_VCD_REG_LO_NRM_SIZE)-1))); \ + cp_vcd_reg_lo = (((unsigned long)(cp_vcd_reg_lo)) & ~CP_VCD_REG_LO_NRM_MASK) | (((unsigned long)(nrm)) << CP_VCD_REG_LO_NRM_SHIFT);\ +} +#define CP_VCD_REG_LO_COL0_SIZE 2 +#define CP_VCD_REG_LO_COL0_SHIFT 13 +#define CP_VCD_REG_LO_COL0_MASK 0x00006000 +#define CP_VCD_REG_LO_GET_COL0(cp_vcd_reg_lo) \ + ((((unsigned long)(cp_vcd_reg_lo)) & CP_VCD_REG_LO_COL0_MASK) >> CP_VCD_REG_LO_COL0_SHIFT) +#define CP_VCD_REG_LO_SET_COL0(cp_vcd_reg_lo, col0) { \ + FDL_ASSERT(!((col0) & ~((1 << CP_VCD_REG_LO_COL0_SIZE)-1))); \ + cp_vcd_reg_lo = (((unsigned long)(cp_vcd_reg_lo)) & ~CP_VCD_REG_LO_COL0_MASK) | (((unsigned long)(col0)) << CP_VCD_REG_LO_COL0_SHIFT);\ +} +#define CP_VCD_REG_LO_COL1_SIZE 2 +#define CP_VCD_REG_LO_COL1_SHIFT 15 +#define CP_VCD_REG_LO_COL1_MASK 0x00018000 +#define CP_VCD_REG_LO_GET_COL1(cp_vcd_reg_lo) \ + ((((unsigned long)(cp_vcd_reg_lo)) & CP_VCD_REG_LO_COL1_MASK) >> CP_VCD_REG_LO_COL1_SHIFT) +#define CP_VCD_REG_LO_SET_COL1(cp_vcd_reg_lo, col1) { \ + FDL_ASSERT(!((col1) & ~((1 << CP_VCD_REG_LO_COL1_SIZE)-1))); \ + cp_vcd_reg_lo = (((unsigned long)(cp_vcd_reg_lo)) & ~CP_VCD_REG_LO_COL1_MASK) | (((unsigned long)(col1)) << CP_VCD_REG_LO_COL1_SHIFT);\ +} +#define CP_VCD_REG_LO_TOTAL_SIZE 17 +#define CP_VCD_REG_LO(pmidx, t0midx, t1midx, t2midx, t3midx, t4midx, t5midx, t6midx, t7midx, pos, nrm, col0, col1) \ + ((((unsigned long)(pmidx)) << CP_VCD_REG_LO_PMIDX_SHIFT) | \ + (((unsigned long)(t0midx)) << CP_VCD_REG_LO_T0MIDX_SHIFT) | \ + (((unsigned long)(t1midx)) << CP_VCD_REG_LO_T1MIDX_SHIFT) | \ + (((unsigned long)(t2midx)) << CP_VCD_REG_LO_T2MIDX_SHIFT) | \ + (((unsigned long)(t3midx)) << CP_VCD_REG_LO_T3MIDX_SHIFT) | \ + (((unsigned long)(t4midx)) << CP_VCD_REG_LO_T4MIDX_SHIFT) | \ + (((unsigned long)(t5midx)) << CP_VCD_REG_LO_T5MIDX_SHIFT) | \ + (((unsigned long)(t6midx)) << CP_VCD_REG_LO_T6MIDX_SHIFT) | \ + (((unsigned long)(t7midx)) << CP_VCD_REG_LO_T7MIDX_SHIFT) | \ + (((unsigned long)(pos)) << CP_VCD_REG_LO_POS_SHIFT) | \ + (((unsigned long)(nrm)) << CP_VCD_REG_LO_NRM_SHIFT) | \ + (((unsigned long)(col0)) << CP_VCD_REG_LO_COL0_SHIFT) | \ + (((unsigned long)(col1)) << CP_VCD_REG_LO_COL1_SHIFT)) + +/* +* cp_vcd_reg_hi struct +*/ +#define CP_VCD_REG_HI_TEX0_SIZE 2 +#define CP_VCD_REG_HI_TEX0_SHIFT 0 +#define CP_VCD_REG_HI_TEX0_MASK 0x00000003 +#define CP_VCD_REG_HI_GET_TEX0(cp_vcd_reg_hi) \ + ((((unsigned long)(cp_vcd_reg_hi)) & CP_VCD_REG_HI_TEX0_MASK) >> CP_VCD_REG_HI_TEX0_SHIFT) +#define CP_VCD_REG_HI_SET_TEX0(cp_vcd_reg_hi, tex0) { \ + FDL_ASSERT(!((tex0) & ~((1 << CP_VCD_REG_HI_TEX0_SIZE)-1))); \ + cp_vcd_reg_hi = (((unsigned long)(cp_vcd_reg_hi)) & ~CP_VCD_REG_HI_TEX0_MASK) | (((unsigned long)(tex0)) << CP_VCD_REG_HI_TEX0_SHIFT);\ +} +#define CP_VCD_REG_HI_TEX1_SIZE 2 +#define CP_VCD_REG_HI_TEX1_SHIFT 2 +#define CP_VCD_REG_HI_TEX1_MASK 0x0000000c +#define CP_VCD_REG_HI_GET_TEX1(cp_vcd_reg_hi) \ + ((((unsigned long)(cp_vcd_reg_hi)) & CP_VCD_REG_HI_TEX1_MASK) >> CP_VCD_REG_HI_TEX1_SHIFT) +#define CP_VCD_REG_HI_SET_TEX1(cp_vcd_reg_hi, tex1) { \ + FDL_ASSERT(!((tex1) & ~((1 << CP_VCD_REG_HI_TEX1_SIZE)-1))); \ + cp_vcd_reg_hi = (((unsigned long)(cp_vcd_reg_hi)) & ~CP_VCD_REG_HI_TEX1_MASK) | (((unsigned long)(tex1)) << CP_VCD_REG_HI_TEX1_SHIFT);\ +} +#define CP_VCD_REG_HI_TEX2_SIZE 2 +#define CP_VCD_REG_HI_TEX2_SHIFT 4 +#define CP_VCD_REG_HI_TEX2_MASK 0x00000030 +#define CP_VCD_REG_HI_GET_TEX2(cp_vcd_reg_hi) \ + ((((unsigned long)(cp_vcd_reg_hi)) & CP_VCD_REG_HI_TEX2_MASK) >> CP_VCD_REG_HI_TEX2_SHIFT) +#define CP_VCD_REG_HI_SET_TEX2(cp_vcd_reg_hi, tex2) { \ + FDL_ASSERT(!((tex2) & ~((1 << CP_VCD_REG_HI_TEX2_SIZE)-1))); \ + cp_vcd_reg_hi = (((unsigned long)(cp_vcd_reg_hi)) & ~CP_VCD_REG_HI_TEX2_MASK) | (((unsigned long)(tex2)) << CP_VCD_REG_HI_TEX2_SHIFT);\ +} +#define CP_VCD_REG_HI_TEX3_SIZE 2 +#define CP_VCD_REG_HI_TEX3_SHIFT 6 +#define CP_VCD_REG_HI_TEX3_MASK 0x000000c0 +#define CP_VCD_REG_HI_GET_TEX3(cp_vcd_reg_hi) \ + ((((unsigned long)(cp_vcd_reg_hi)) & CP_VCD_REG_HI_TEX3_MASK) >> CP_VCD_REG_HI_TEX3_SHIFT) +#define CP_VCD_REG_HI_SET_TEX3(cp_vcd_reg_hi, tex3) { \ + FDL_ASSERT(!((tex3) & ~((1 << CP_VCD_REG_HI_TEX3_SIZE)-1))); \ + cp_vcd_reg_hi = (((unsigned long)(cp_vcd_reg_hi)) & ~CP_VCD_REG_HI_TEX3_MASK) | (((unsigned long)(tex3)) << CP_VCD_REG_HI_TEX3_SHIFT);\ +} +#define CP_VCD_REG_HI_TEX4_SIZE 2 +#define CP_VCD_REG_HI_TEX4_SHIFT 8 +#define CP_VCD_REG_HI_TEX4_MASK 0x00000300 +#define CP_VCD_REG_HI_GET_TEX4(cp_vcd_reg_hi) \ + ((((unsigned long)(cp_vcd_reg_hi)) & CP_VCD_REG_HI_TEX4_MASK) >> CP_VCD_REG_HI_TEX4_SHIFT) +#define CP_VCD_REG_HI_SET_TEX4(cp_vcd_reg_hi, tex4) { \ + FDL_ASSERT(!((tex4) & ~((1 << CP_VCD_REG_HI_TEX4_SIZE)-1))); \ + cp_vcd_reg_hi = (((unsigned long)(cp_vcd_reg_hi)) & ~CP_VCD_REG_HI_TEX4_MASK) | (((unsigned long)(tex4)) << CP_VCD_REG_HI_TEX4_SHIFT);\ +} +#define CP_VCD_REG_HI_TEX5_SIZE 2 +#define CP_VCD_REG_HI_TEX5_SHIFT 10 +#define CP_VCD_REG_HI_TEX5_MASK 0x00000c00 +#define CP_VCD_REG_HI_GET_TEX5(cp_vcd_reg_hi) \ + ((((unsigned long)(cp_vcd_reg_hi)) & CP_VCD_REG_HI_TEX5_MASK) >> CP_VCD_REG_HI_TEX5_SHIFT) +#define CP_VCD_REG_HI_SET_TEX5(cp_vcd_reg_hi, tex5) { \ + FDL_ASSERT(!((tex5) & ~((1 << CP_VCD_REG_HI_TEX5_SIZE)-1))); \ + cp_vcd_reg_hi = (((unsigned long)(cp_vcd_reg_hi)) & ~CP_VCD_REG_HI_TEX5_MASK) | (((unsigned long)(tex5)) << CP_VCD_REG_HI_TEX5_SHIFT);\ +} +#define CP_VCD_REG_HI_TEX6_SIZE 2 +#define CP_VCD_REG_HI_TEX6_SHIFT 12 +#define CP_VCD_REG_HI_TEX6_MASK 0x00003000 +#define CP_VCD_REG_HI_GET_TEX6(cp_vcd_reg_hi) \ + ((((unsigned long)(cp_vcd_reg_hi)) & CP_VCD_REG_HI_TEX6_MASK) >> CP_VCD_REG_HI_TEX6_SHIFT) +#define CP_VCD_REG_HI_SET_TEX6(cp_vcd_reg_hi, tex6) { \ + FDL_ASSERT(!((tex6) & ~((1 << CP_VCD_REG_HI_TEX6_SIZE)-1))); \ + cp_vcd_reg_hi = (((unsigned long)(cp_vcd_reg_hi)) & ~CP_VCD_REG_HI_TEX6_MASK) | (((unsigned long)(tex6)) << CP_VCD_REG_HI_TEX6_SHIFT);\ +} +#define CP_VCD_REG_HI_TEX7_SIZE 2 +#define CP_VCD_REG_HI_TEX7_SHIFT 14 +#define CP_VCD_REG_HI_TEX7_MASK 0x0000c000 +#define CP_VCD_REG_HI_GET_TEX7(cp_vcd_reg_hi) \ + ((((unsigned long)(cp_vcd_reg_hi)) & CP_VCD_REG_HI_TEX7_MASK) >> CP_VCD_REG_HI_TEX7_SHIFT) +#define CP_VCD_REG_HI_SET_TEX7(cp_vcd_reg_hi, tex7) { \ + FDL_ASSERT(!((tex7) & ~((1 << CP_VCD_REG_HI_TEX7_SIZE)-1))); \ + cp_vcd_reg_hi = (((unsigned long)(cp_vcd_reg_hi)) & ~CP_VCD_REG_HI_TEX7_MASK) | (((unsigned long)(tex7)) << CP_VCD_REG_HI_TEX7_SHIFT);\ +} +#define CP_VCD_REG_HI_TOTAL_SIZE 16 +#define CP_VCD_REG_HI(tex0, tex1, tex2, tex3, tex4, tex5, tex6, tex7) \ + ((((unsigned long)(tex0)) << CP_VCD_REG_HI_TEX0_SHIFT) | \ + (((unsigned long)(tex1)) << CP_VCD_REG_HI_TEX1_SHIFT) | \ + (((unsigned long)(tex2)) << CP_VCD_REG_HI_TEX2_SHIFT) | \ + (((unsigned long)(tex3)) << CP_VCD_REG_HI_TEX3_SHIFT) | \ + (((unsigned long)(tex4)) << CP_VCD_REG_HI_TEX4_SHIFT) | \ + (((unsigned long)(tex5)) << CP_VCD_REG_HI_TEX5_SHIFT) | \ + (((unsigned long)(tex6)) << CP_VCD_REG_HI_TEX6_SHIFT) | \ + (((unsigned long)(tex7)) << CP_VCD_REG_HI_TEX7_SHIFT)) + +/* +* cp_vat_table value +*/ +#define CP_NUM_VATS 0x08 + +/* +* cp_vat_reg_a struct +*/ +#define CP_VAT_REG_A_POSCNT_SIZE 1 +#define CP_VAT_REG_A_POSCNT_SHIFT 0 +#define CP_VAT_REG_A_POSCNT_MASK 0x00000001 +#define CP_VAT_REG_A_GET_POSCNT(cp_vat_reg_a) \ + ((((unsigned long)(cp_vat_reg_a)) & CP_VAT_REG_A_POSCNT_MASK) >> CP_VAT_REG_A_POSCNT_SHIFT) +#define CP_VAT_REG_A_SET_POSCNT(cp_vat_reg_a, posCnt) { \ + FDL_ASSERT(!((posCnt) & ~((1 << CP_VAT_REG_A_POSCNT_SIZE)-1))); \ + cp_vat_reg_a = (((unsigned long)(cp_vat_reg_a)) & ~CP_VAT_REG_A_POSCNT_MASK) | (((unsigned long)(posCnt)) << CP_VAT_REG_A_POSCNT_SHIFT);\ +} +#define CP_VAT_REG_A_POSFMT_SIZE 3 +#define CP_VAT_REG_A_POSFMT_SHIFT 1 +#define CP_VAT_REG_A_POSFMT_MASK 0x0000000e +#define CP_VAT_REG_A_GET_POSFMT(cp_vat_reg_a) \ + ((((unsigned long)(cp_vat_reg_a)) & CP_VAT_REG_A_POSFMT_MASK) >> CP_VAT_REG_A_POSFMT_SHIFT) +#define CP_VAT_REG_A_SET_POSFMT(cp_vat_reg_a, posFmt) { \ + FDL_ASSERT(!((posFmt) & ~((1 << CP_VAT_REG_A_POSFMT_SIZE)-1))); \ + cp_vat_reg_a = (((unsigned long)(cp_vat_reg_a)) & ~CP_VAT_REG_A_POSFMT_MASK) | (((unsigned long)(posFmt)) << CP_VAT_REG_A_POSFMT_SHIFT);\ +} +#define CP_VAT_REG_A_POSSHFT_SIZE 5 +#define CP_VAT_REG_A_POSSHFT_SHIFT 4 +#define CP_VAT_REG_A_POSSHFT_MASK 0x000001f0 +#define CP_VAT_REG_A_GET_POSSHFT(cp_vat_reg_a) \ + ((((unsigned long)(cp_vat_reg_a)) & CP_VAT_REG_A_POSSHFT_MASK) >> CP_VAT_REG_A_POSSHFT_SHIFT) +#define CP_VAT_REG_A_SET_POSSHFT(cp_vat_reg_a, posShft) { \ + FDL_ASSERT(!((posShft) & ~((1 << CP_VAT_REG_A_POSSHFT_SIZE)-1))); \ + cp_vat_reg_a = (((unsigned long)(cp_vat_reg_a)) & ~CP_VAT_REG_A_POSSHFT_MASK) | (((unsigned long)(posShft)) << CP_VAT_REG_A_POSSHFT_SHIFT);\ +} +#define CP_VAT_REG_A_NRMCNT_SIZE 1 +#define CP_VAT_REG_A_NRMCNT_SHIFT 9 +#define CP_VAT_REG_A_NRMCNT_MASK 0x00000200 +#define CP_VAT_REG_A_GET_NRMCNT(cp_vat_reg_a) \ + ((((unsigned long)(cp_vat_reg_a)) & CP_VAT_REG_A_NRMCNT_MASK) >> CP_VAT_REG_A_NRMCNT_SHIFT) +#define CP_VAT_REG_A_SET_NRMCNT(cp_vat_reg_a, nrmCnt) { \ + FDL_ASSERT(!((nrmCnt) & ~((1 << CP_VAT_REG_A_NRMCNT_SIZE)-1))); \ + cp_vat_reg_a = (((unsigned long)(cp_vat_reg_a)) & ~CP_VAT_REG_A_NRMCNT_MASK) | (((unsigned long)(nrmCnt)) << CP_VAT_REG_A_NRMCNT_SHIFT);\ +} +#define CP_VAT_REG_A_NRMFMT_SIZE 3 +#define CP_VAT_REG_A_NRMFMT_SHIFT 10 +#define CP_VAT_REG_A_NRMFMT_MASK 0x00001c00 +#define CP_VAT_REG_A_GET_NRMFMT(cp_vat_reg_a) \ + ((((unsigned long)(cp_vat_reg_a)) & CP_VAT_REG_A_NRMFMT_MASK) >> CP_VAT_REG_A_NRMFMT_SHIFT) +#define CP_VAT_REG_A_SET_NRMFMT(cp_vat_reg_a, nrmFmt) { \ + FDL_ASSERT(!((nrmFmt) & ~((1 << CP_VAT_REG_A_NRMFMT_SIZE)-1))); \ + cp_vat_reg_a = (((unsigned long)(cp_vat_reg_a)) & ~CP_VAT_REG_A_NRMFMT_MASK) | (((unsigned long)(nrmFmt)) << CP_VAT_REG_A_NRMFMT_SHIFT);\ +} +#define CP_VAT_REG_A_COL0CNT_SIZE 1 +#define CP_VAT_REG_A_COL0CNT_SHIFT 13 +#define CP_VAT_REG_A_COL0CNT_MASK 0x00002000 +#define CP_VAT_REG_A_GET_COL0CNT(cp_vat_reg_a) \ + ((((unsigned long)(cp_vat_reg_a)) & CP_VAT_REG_A_COL0CNT_MASK) >> CP_VAT_REG_A_COL0CNT_SHIFT) +#define CP_VAT_REG_A_SET_COL0CNT(cp_vat_reg_a, Col0Cnt) { \ + FDL_ASSERT(!((Col0Cnt) & ~((1 << CP_VAT_REG_A_COL0CNT_SIZE)-1))); \ + cp_vat_reg_a = (((unsigned long)(cp_vat_reg_a)) & ~CP_VAT_REG_A_COL0CNT_MASK) | (((unsigned long)(Col0Cnt)) << CP_VAT_REG_A_COL0CNT_SHIFT);\ +} +#define CP_VAT_REG_A_COL0FMT_SIZE 3 +#define CP_VAT_REG_A_COL0FMT_SHIFT 14 +#define CP_VAT_REG_A_COL0FMT_MASK 0x0001c000 +#define CP_VAT_REG_A_GET_COL0FMT(cp_vat_reg_a) \ + ((((unsigned long)(cp_vat_reg_a)) & CP_VAT_REG_A_COL0FMT_MASK) >> CP_VAT_REG_A_COL0FMT_SHIFT) +#define CP_VAT_REG_A_SET_COL0FMT(cp_vat_reg_a, Col0Fmt) { \ + FDL_ASSERT(!((Col0Fmt) & ~((1 << CP_VAT_REG_A_COL0FMT_SIZE)-1))); \ + cp_vat_reg_a = (((unsigned long)(cp_vat_reg_a)) & ~CP_VAT_REG_A_COL0FMT_MASK) | (((unsigned long)(Col0Fmt)) << CP_VAT_REG_A_COL0FMT_SHIFT);\ +} +#define CP_VAT_REG_A_COL1CNT_SIZE 1 +#define CP_VAT_REG_A_COL1CNT_SHIFT 17 +#define CP_VAT_REG_A_COL1CNT_MASK 0x00020000 +#define CP_VAT_REG_A_GET_COL1CNT(cp_vat_reg_a) \ + ((((unsigned long)(cp_vat_reg_a)) & CP_VAT_REG_A_COL1CNT_MASK) >> CP_VAT_REG_A_COL1CNT_SHIFT) +#define CP_VAT_REG_A_SET_COL1CNT(cp_vat_reg_a, Col1Cnt) { \ + FDL_ASSERT(!((Col1Cnt) & ~((1 << CP_VAT_REG_A_COL1CNT_SIZE)-1))); \ + cp_vat_reg_a = (((unsigned long)(cp_vat_reg_a)) & ~CP_VAT_REG_A_COL1CNT_MASK) | (((unsigned long)(Col1Cnt)) << CP_VAT_REG_A_COL1CNT_SHIFT);\ +} +#define CP_VAT_REG_A_COL1FMT_SIZE 3 +#define CP_VAT_REG_A_COL1FMT_SHIFT 18 +#define CP_VAT_REG_A_COL1FMT_MASK 0x001c0000 +#define CP_VAT_REG_A_GET_COL1FMT(cp_vat_reg_a) \ + ((((unsigned long)(cp_vat_reg_a)) & CP_VAT_REG_A_COL1FMT_MASK) >> CP_VAT_REG_A_COL1FMT_SHIFT) +#define CP_VAT_REG_A_SET_COL1FMT(cp_vat_reg_a, Col1Fmt) { \ + FDL_ASSERT(!((Col1Fmt) & ~((1 << CP_VAT_REG_A_COL1FMT_SIZE)-1))); \ + cp_vat_reg_a = (((unsigned long)(cp_vat_reg_a)) & ~CP_VAT_REG_A_COL1FMT_MASK) | (((unsigned long)(Col1Fmt)) << CP_VAT_REG_A_COL1FMT_SHIFT);\ +} +#define CP_VAT_REG_A_TEX0CNT_SIZE 1 +#define CP_VAT_REG_A_TEX0CNT_SHIFT 21 +#define CP_VAT_REG_A_TEX0CNT_MASK 0x00200000 +#define CP_VAT_REG_A_GET_TEX0CNT(cp_vat_reg_a) \ + ((((unsigned long)(cp_vat_reg_a)) & CP_VAT_REG_A_TEX0CNT_MASK) >> CP_VAT_REG_A_TEX0CNT_SHIFT) +#define CP_VAT_REG_A_SET_TEX0CNT(cp_vat_reg_a, tex0Cnt) { \ + FDL_ASSERT(!((tex0Cnt) & ~((1 << CP_VAT_REG_A_TEX0CNT_SIZE)-1))); \ + cp_vat_reg_a = (((unsigned long)(cp_vat_reg_a)) & ~CP_VAT_REG_A_TEX0CNT_MASK) | (((unsigned long)(tex0Cnt)) << CP_VAT_REG_A_TEX0CNT_SHIFT);\ +} +#define CP_VAT_REG_A_TEX0FMT_SIZE 3 +#define CP_VAT_REG_A_TEX0FMT_SHIFT 22 +#define CP_VAT_REG_A_TEX0FMT_MASK 0x01c00000 +#define CP_VAT_REG_A_GET_TEX0FMT(cp_vat_reg_a) \ + ((((unsigned long)(cp_vat_reg_a)) & CP_VAT_REG_A_TEX0FMT_MASK) >> CP_VAT_REG_A_TEX0FMT_SHIFT) +#define CP_VAT_REG_A_SET_TEX0FMT(cp_vat_reg_a, tex0Fmt) { \ + FDL_ASSERT(!((tex0Fmt) & ~((1 << CP_VAT_REG_A_TEX0FMT_SIZE)-1))); \ + cp_vat_reg_a = (((unsigned long)(cp_vat_reg_a)) & ~CP_VAT_REG_A_TEX0FMT_MASK) | (((unsigned long)(tex0Fmt)) << CP_VAT_REG_A_TEX0FMT_SHIFT);\ +} +#define CP_VAT_REG_A_TEX0SHFT_SIZE 5 +#define CP_VAT_REG_A_TEX0SHFT_SHIFT 25 +#define CP_VAT_REG_A_TEX0SHFT_MASK 0x3e000000 +#define CP_VAT_REG_A_GET_TEX0SHFT(cp_vat_reg_a) \ + ((((unsigned long)(cp_vat_reg_a)) & CP_VAT_REG_A_TEX0SHFT_MASK) >> CP_VAT_REG_A_TEX0SHFT_SHIFT) +#define CP_VAT_REG_A_SET_TEX0SHFT(cp_vat_reg_a, tex0Shft) { \ + FDL_ASSERT(!((tex0Shft) & ~((1 << CP_VAT_REG_A_TEX0SHFT_SIZE)-1))); \ + cp_vat_reg_a = (((unsigned long)(cp_vat_reg_a)) & ~CP_VAT_REG_A_TEX0SHFT_MASK) | (((unsigned long)(tex0Shft)) << CP_VAT_REG_A_TEX0SHFT_SHIFT);\ +} +#define CP_VAT_REG_A_BYTEDEQUANT_SIZE 1 +#define CP_VAT_REG_A_BYTEDEQUANT_SHIFT 30 +#define CP_VAT_REG_A_BYTEDEQUANT_MASK 0x40000000 +#define CP_VAT_REG_A_GET_BYTEDEQUANT(cp_vat_reg_a) \ + ((((unsigned long)(cp_vat_reg_a)) & CP_VAT_REG_A_BYTEDEQUANT_MASK) >> CP_VAT_REG_A_BYTEDEQUANT_SHIFT) +#define CP_VAT_REG_A_SET_BYTEDEQUANT(cp_vat_reg_a, byteDequant) { \ + FDL_ASSERT(!((byteDequant) & ~((1 << CP_VAT_REG_A_BYTEDEQUANT_SIZE)-1))); \ + cp_vat_reg_a = (((unsigned long)(cp_vat_reg_a)) & ~CP_VAT_REG_A_BYTEDEQUANT_MASK) | (((unsigned long)(byteDequant)) << CP_VAT_REG_A_BYTEDEQUANT_SHIFT);\ +} +#define CP_VAT_REG_A_NORMALINDEX3_SIZE 1 +#define CP_VAT_REG_A_NORMALINDEX3_SHIFT 31 +#define CP_VAT_REG_A_NORMALINDEX3_MASK 0x80000000 +#define CP_VAT_REG_A_GET_NORMALINDEX3(cp_vat_reg_a) \ + ((((unsigned long)(cp_vat_reg_a)) & CP_VAT_REG_A_NORMALINDEX3_MASK) >> CP_VAT_REG_A_NORMALINDEX3_SHIFT) +#define CP_VAT_REG_A_SET_NORMALINDEX3(cp_vat_reg_a, normalIndex3) { \ + FDL_ASSERT(!((normalIndex3) & ~((1 << CP_VAT_REG_A_NORMALINDEX3_SIZE)-1))); \ + cp_vat_reg_a = (((unsigned long)(cp_vat_reg_a)) & ~CP_VAT_REG_A_NORMALINDEX3_MASK) | (((unsigned long)(normalIndex3)) << CP_VAT_REG_A_NORMALINDEX3_SHIFT);\ +} +#define CP_VAT_REG_A_TOTAL_SIZE 32 +#define CP_VAT_REG_A(posCnt, posFmt, posShft, nrmCnt, nrmFmt, Col0Cnt, Col0Fmt, Col1Cnt, Col1Fmt, tex0Cnt, tex0Fmt, tex0Shft, byteDequant, normalIndex3) \ + ((((unsigned long)(posCnt)) << CP_VAT_REG_A_POSCNT_SHIFT) | \ + (((unsigned long)(posFmt)) << CP_VAT_REG_A_POSFMT_SHIFT) | \ + (((unsigned long)(posShft)) << CP_VAT_REG_A_POSSHFT_SHIFT) | \ + (((unsigned long)(nrmCnt)) << CP_VAT_REG_A_NRMCNT_SHIFT) | \ + (((unsigned long)(nrmFmt)) << CP_VAT_REG_A_NRMFMT_SHIFT) | \ + (((unsigned long)(Col0Cnt)) << CP_VAT_REG_A_COL0CNT_SHIFT) | \ + (((unsigned long)(Col0Fmt)) << CP_VAT_REG_A_COL0FMT_SHIFT) | \ + (((unsigned long)(Col1Cnt)) << CP_VAT_REG_A_COL1CNT_SHIFT) | \ + (((unsigned long)(Col1Fmt)) << CP_VAT_REG_A_COL1FMT_SHIFT) | \ + (((unsigned long)(tex0Cnt)) << CP_VAT_REG_A_TEX0CNT_SHIFT) | \ + (((unsigned long)(tex0Fmt)) << CP_VAT_REG_A_TEX0FMT_SHIFT) | \ + (((unsigned long)(tex0Shft)) << CP_VAT_REG_A_TEX0SHFT_SHIFT) | \ + (((unsigned long)(byteDequant)) << CP_VAT_REG_A_BYTEDEQUANT_SHIFT) | \ + (((unsigned long)(normalIndex3)) << CP_VAT_REG_A_NORMALINDEX3_SHIFT)) + +/* +* cp_vat_reg_b struct +*/ +#define CP_VAT_REG_B_TEX1CNT_SIZE 1 +#define CP_VAT_REG_B_TEX1CNT_SHIFT 0 +#define CP_VAT_REG_B_TEX1CNT_MASK 0x00000001 +#define CP_VAT_REG_B_GET_TEX1CNT(cp_vat_reg_b) \ + ((((unsigned long)(cp_vat_reg_b)) & CP_VAT_REG_B_TEX1CNT_MASK) >> CP_VAT_REG_B_TEX1CNT_SHIFT) +#define CP_VAT_REG_B_SET_TEX1CNT(cp_vat_reg_b, tex1Cnt) { \ + FDL_ASSERT(!((tex1Cnt) & ~((1 << CP_VAT_REG_B_TEX1CNT_SIZE)-1))); \ + cp_vat_reg_b = (((unsigned long)(cp_vat_reg_b)) & ~CP_VAT_REG_B_TEX1CNT_MASK) | (((unsigned long)(tex1Cnt)) << CP_VAT_REG_B_TEX1CNT_SHIFT);\ +} +#define CP_VAT_REG_B_TEX1FMT_SIZE 3 +#define CP_VAT_REG_B_TEX1FMT_SHIFT 1 +#define CP_VAT_REG_B_TEX1FMT_MASK 0x0000000e +#define CP_VAT_REG_B_GET_TEX1FMT(cp_vat_reg_b) \ + ((((unsigned long)(cp_vat_reg_b)) & CP_VAT_REG_B_TEX1FMT_MASK) >> CP_VAT_REG_B_TEX1FMT_SHIFT) +#define CP_VAT_REG_B_SET_TEX1FMT(cp_vat_reg_b, tex1Fmt) { \ + FDL_ASSERT(!((tex1Fmt) & ~((1 << CP_VAT_REG_B_TEX1FMT_SIZE)-1))); \ + cp_vat_reg_b = (((unsigned long)(cp_vat_reg_b)) & ~CP_VAT_REG_B_TEX1FMT_MASK) | (((unsigned long)(tex1Fmt)) << CP_VAT_REG_B_TEX1FMT_SHIFT);\ +} +#define CP_VAT_REG_B_TEX1SHFT_SIZE 5 +#define CP_VAT_REG_B_TEX1SHFT_SHIFT 4 +#define CP_VAT_REG_B_TEX1SHFT_MASK 0x000001f0 +#define CP_VAT_REG_B_GET_TEX1SHFT(cp_vat_reg_b) \ + ((((unsigned long)(cp_vat_reg_b)) & CP_VAT_REG_B_TEX1SHFT_MASK) >> CP_VAT_REG_B_TEX1SHFT_SHIFT) +#define CP_VAT_REG_B_SET_TEX1SHFT(cp_vat_reg_b, tex1Shft) { \ + FDL_ASSERT(!((tex1Shft) & ~((1 << CP_VAT_REG_B_TEX1SHFT_SIZE)-1))); \ + cp_vat_reg_b = (((unsigned long)(cp_vat_reg_b)) & ~CP_VAT_REG_B_TEX1SHFT_MASK) | (((unsigned long)(tex1Shft)) << CP_VAT_REG_B_TEX1SHFT_SHIFT);\ +} +#define CP_VAT_REG_B_TEX2CNT_SIZE 1 +#define CP_VAT_REG_B_TEX2CNT_SHIFT 9 +#define CP_VAT_REG_B_TEX2CNT_MASK 0x00000200 +#define CP_VAT_REG_B_GET_TEX2CNT(cp_vat_reg_b) \ + ((((unsigned long)(cp_vat_reg_b)) & CP_VAT_REG_B_TEX2CNT_MASK) >> CP_VAT_REG_B_TEX2CNT_SHIFT) +#define CP_VAT_REG_B_SET_TEX2CNT(cp_vat_reg_b, tex2Cnt) { \ + FDL_ASSERT(!((tex2Cnt) & ~((1 << CP_VAT_REG_B_TEX2CNT_SIZE)-1))); \ + cp_vat_reg_b = (((unsigned long)(cp_vat_reg_b)) & ~CP_VAT_REG_B_TEX2CNT_MASK) | (((unsigned long)(tex2Cnt)) << CP_VAT_REG_B_TEX2CNT_SHIFT);\ +} +#define CP_VAT_REG_B_TEX2FMT_SIZE 3 +#define CP_VAT_REG_B_TEX2FMT_SHIFT 10 +#define CP_VAT_REG_B_TEX2FMT_MASK 0x00001c00 +#define CP_VAT_REG_B_GET_TEX2FMT(cp_vat_reg_b) \ + ((((unsigned long)(cp_vat_reg_b)) & CP_VAT_REG_B_TEX2FMT_MASK) >> CP_VAT_REG_B_TEX2FMT_SHIFT) +#define CP_VAT_REG_B_SET_TEX2FMT(cp_vat_reg_b, tex2Fmt) { \ + FDL_ASSERT(!((tex2Fmt) & ~((1 << CP_VAT_REG_B_TEX2FMT_SIZE)-1))); \ + cp_vat_reg_b = (((unsigned long)(cp_vat_reg_b)) & ~CP_VAT_REG_B_TEX2FMT_MASK) | (((unsigned long)(tex2Fmt)) << CP_VAT_REG_B_TEX2FMT_SHIFT);\ +} +#define CP_VAT_REG_B_TEX2SHFT_SIZE 5 +#define CP_VAT_REG_B_TEX2SHFT_SHIFT 13 +#define CP_VAT_REG_B_TEX2SHFT_MASK 0x0003e000 +#define CP_VAT_REG_B_GET_TEX2SHFT(cp_vat_reg_b) \ + ((((unsigned long)(cp_vat_reg_b)) & CP_VAT_REG_B_TEX2SHFT_MASK) >> CP_VAT_REG_B_TEX2SHFT_SHIFT) +#define CP_VAT_REG_B_SET_TEX2SHFT(cp_vat_reg_b, tex2Shft) { \ + FDL_ASSERT(!((tex2Shft) & ~((1 << CP_VAT_REG_B_TEX2SHFT_SIZE)-1))); \ + cp_vat_reg_b = (((unsigned long)(cp_vat_reg_b)) & ~CP_VAT_REG_B_TEX2SHFT_MASK) | (((unsigned long)(tex2Shft)) << CP_VAT_REG_B_TEX2SHFT_SHIFT);\ +} +#define CP_VAT_REG_B_TEX3CNT_SIZE 1 +#define CP_VAT_REG_B_TEX3CNT_SHIFT 18 +#define CP_VAT_REG_B_TEX3CNT_MASK 0x00040000 +#define CP_VAT_REG_B_GET_TEX3CNT(cp_vat_reg_b) \ + ((((unsigned long)(cp_vat_reg_b)) & CP_VAT_REG_B_TEX3CNT_MASK) >> CP_VAT_REG_B_TEX3CNT_SHIFT) +#define CP_VAT_REG_B_SET_TEX3CNT(cp_vat_reg_b, tex3Cnt) { \ + FDL_ASSERT(!((tex3Cnt) & ~((1 << CP_VAT_REG_B_TEX3CNT_SIZE)-1))); \ + cp_vat_reg_b = (((unsigned long)(cp_vat_reg_b)) & ~CP_VAT_REG_B_TEX3CNT_MASK) | (((unsigned long)(tex3Cnt)) << CP_VAT_REG_B_TEX3CNT_SHIFT);\ +} +#define CP_VAT_REG_B_TEX3FMT_SIZE 3 +#define CP_VAT_REG_B_TEX3FMT_SHIFT 19 +#define CP_VAT_REG_B_TEX3FMT_MASK 0x00380000 +#define CP_VAT_REG_B_GET_TEX3FMT(cp_vat_reg_b) \ + ((((unsigned long)(cp_vat_reg_b)) & CP_VAT_REG_B_TEX3FMT_MASK) >> CP_VAT_REG_B_TEX3FMT_SHIFT) +#define CP_VAT_REG_B_SET_TEX3FMT(cp_vat_reg_b, tex3Fmt) { \ + FDL_ASSERT(!((tex3Fmt) & ~((1 << CP_VAT_REG_B_TEX3FMT_SIZE)-1))); \ + cp_vat_reg_b = (((unsigned long)(cp_vat_reg_b)) & ~CP_VAT_REG_B_TEX3FMT_MASK) | (((unsigned long)(tex3Fmt)) << CP_VAT_REG_B_TEX3FMT_SHIFT);\ +} +#define CP_VAT_REG_B_TEX3SHFT_SIZE 5 +#define CP_VAT_REG_B_TEX3SHFT_SHIFT 22 +#define CP_VAT_REG_B_TEX3SHFT_MASK 0x07c00000 +#define CP_VAT_REG_B_GET_TEX3SHFT(cp_vat_reg_b) \ + ((((unsigned long)(cp_vat_reg_b)) & CP_VAT_REG_B_TEX3SHFT_MASK) >> CP_VAT_REG_B_TEX3SHFT_SHIFT) +#define CP_VAT_REG_B_SET_TEX3SHFT(cp_vat_reg_b, tex3Shft) { \ + FDL_ASSERT(!((tex3Shft) & ~((1 << CP_VAT_REG_B_TEX3SHFT_SIZE)-1))); \ + cp_vat_reg_b = (((unsigned long)(cp_vat_reg_b)) & ~CP_VAT_REG_B_TEX3SHFT_MASK) | (((unsigned long)(tex3Shft)) << CP_VAT_REG_B_TEX3SHFT_SHIFT);\ +} +#define CP_VAT_REG_B_TEX4CNT_SIZE 1 +#define CP_VAT_REG_B_TEX4CNT_SHIFT 27 +#define CP_VAT_REG_B_TEX4CNT_MASK 0x08000000 +#define CP_VAT_REG_B_GET_TEX4CNT(cp_vat_reg_b) \ + ((((unsigned long)(cp_vat_reg_b)) & CP_VAT_REG_B_TEX4CNT_MASK) >> CP_VAT_REG_B_TEX4CNT_SHIFT) +#define CP_VAT_REG_B_SET_TEX4CNT(cp_vat_reg_b, tex4Cnt) { \ + FDL_ASSERT(!((tex4Cnt) & ~((1 << CP_VAT_REG_B_TEX4CNT_SIZE)-1))); \ + cp_vat_reg_b = (((unsigned long)(cp_vat_reg_b)) & ~CP_VAT_REG_B_TEX4CNT_MASK) | (((unsigned long)(tex4Cnt)) << CP_VAT_REG_B_TEX4CNT_SHIFT);\ +} +#define CP_VAT_REG_B_TEX4FMT_SIZE 3 +#define CP_VAT_REG_B_TEX4FMT_SHIFT 28 +#define CP_VAT_REG_B_TEX4FMT_MASK 0x70000000 +#define CP_VAT_REG_B_GET_TEX4FMT(cp_vat_reg_b) \ + ((((unsigned long)(cp_vat_reg_b)) & CP_VAT_REG_B_TEX4FMT_MASK) >> CP_VAT_REG_B_TEX4FMT_SHIFT) +#define CP_VAT_REG_B_SET_TEX4FMT(cp_vat_reg_b, tex4Fmt) { \ + FDL_ASSERT(!((tex4Fmt) & ~((1 << CP_VAT_REG_B_TEX4FMT_SIZE)-1))); \ + cp_vat_reg_b = (((unsigned long)(cp_vat_reg_b)) & ~CP_VAT_REG_B_TEX4FMT_MASK) | (((unsigned long)(tex4Fmt)) << CP_VAT_REG_B_TEX4FMT_SHIFT);\ +} +#define CP_VAT_REG_B_VCACHE_ENHANCE_SIZE 1 +#define CP_VAT_REG_B_VCACHE_ENHANCE_SHIFT 31 +#define CP_VAT_REG_B_VCACHE_ENHANCE_MASK 0x80000000 +#define CP_VAT_REG_B_GET_VCACHE_ENHANCE(cp_vat_reg_b) \ + ((((unsigned long)(cp_vat_reg_b)) & CP_VAT_REG_B_VCACHE_ENHANCE_MASK) >> CP_VAT_REG_B_VCACHE_ENHANCE_SHIFT) +#define CP_VAT_REG_B_SET_VCACHE_ENHANCE(cp_vat_reg_b, vcache_enhance) { \ + FDL_ASSERT(!((vcache_enhance) & ~((1 << CP_VAT_REG_B_VCACHE_ENHANCE_SIZE)-1))); \ + cp_vat_reg_b = (((unsigned long)(cp_vat_reg_b)) & ~CP_VAT_REG_B_VCACHE_ENHANCE_MASK) | (((unsigned long)(vcache_enhance)) << CP_VAT_REG_B_VCACHE_ENHANCE_SHIFT);\ +} +#define CP_VAT_REG_B_TOTAL_SIZE 32 +#define CP_VAT_REG_B(tex1Cnt, tex1Fmt, tex1Shft, tex2Cnt, tex2Fmt, tex2Shft, tex3Cnt, tex3Fmt, tex3Shft, tex4Cnt, tex4Fmt, vcache_enhance) \ + ((((unsigned long)(tex1Cnt)) << CP_VAT_REG_B_TEX1CNT_SHIFT) | \ + (((unsigned long)(tex1Fmt)) << CP_VAT_REG_B_TEX1FMT_SHIFT) | \ + (((unsigned long)(tex1Shft)) << CP_VAT_REG_B_TEX1SHFT_SHIFT) | \ + (((unsigned long)(tex2Cnt)) << CP_VAT_REG_B_TEX2CNT_SHIFT) | \ + (((unsigned long)(tex2Fmt)) << CP_VAT_REG_B_TEX2FMT_SHIFT) | \ + (((unsigned long)(tex2Shft)) << CP_VAT_REG_B_TEX2SHFT_SHIFT) | \ + (((unsigned long)(tex3Cnt)) << CP_VAT_REG_B_TEX3CNT_SHIFT) | \ + (((unsigned long)(tex3Fmt)) << CP_VAT_REG_B_TEX3FMT_SHIFT) | \ + (((unsigned long)(tex3Shft)) << CP_VAT_REG_B_TEX3SHFT_SHIFT) | \ + (((unsigned long)(tex4Cnt)) << CP_VAT_REG_B_TEX4CNT_SHIFT) | \ + (((unsigned long)(tex4Fmt)) << CP_VAT_REG_B_TEX4FMT_SHIFT) | \ + (((unsigned long)(vcache_enhance)) << CP_VAT_REG_B_VCACHE_ENHANCE_SHIFT)) + +/* +* cp_vat_reg_c struct +*/ +#define CP_VAT_REG_C_TEX4SHFT_SIZE 5 +#define CP_VAT_REG_C_TEX4SHFT_SHIFT 0 +#define CP_VAT_REG_C_TEX4SHFT_MASK 0x0000001f +#define CP_VAT_REG_C_GET_TEX4SHFT(cp_vat_reg_c) \ + ((((unsigned long)(cp_vat_reg_c)) & CP_VAT_REG_C_TEX4SHFT_MASK) >> CP_VAT_REG_C_TEX4SHFT_SHIFT) +#define CP_VAT_REG_C_SET_TEX4SHFT(cp_vat_reg_c, tex4Shft) { \ + FDL_ASSERT(!((tex4Shft) & ~((1 << CP_VAT_REG_C_TEX4SHFT_SIZE)-1))); \ + cp_vat_reg_c = (((unsigned long)(cp_vat_reg_c)) & ~CP_VAT_REG_C_TEX4SHFT_MASK) | (((unsigned long)(tex4Shft)) << CP_VAT_REG_C_TEX4SHFT_SHIFT);\ +} +#define CP_VAT_REG_C_TEX5CNT_SIZE 1 +#define CP_VAT_REG_C_TEX5CNT_SHIFT 5 +#define CP_VAT_REG_C_TEX5CNT_MASK 0x00000020 +#define CP_VAT_REG_C_GET_TEX5CNT(cp_vat_reg_c) \ + ((((unsigned long)(cp_vat_reg_c)) & CP_VAT_REG_C_TEX5CNT_MASK) >> CP_VAT_REG_C_TEX5CNT_SHIFT) +#define CP_VAT_REG_C_SET_TEX5CNT(cp_vat_reg_c, tex5Cnt) { \ + FDL_ASSERT(!((tex5Cnt) & ~((1 << CP_VAT_REG_C_TEX5CNT_SIZE)-1))); \ + cp_vat_reg_c = (((unsigned long)(cp_vat_reg_c)) & ~CP_VAT_REG_C_TEX5CNT_MASK) | (((unsigned long)(tex5Cnt)) << CP_VAT_REG_C_TEX5CNT_SHIFT);\ +} +#define CP_VAT_REG_C_TEX5FMT_SIZE 3 +#define CP_VAT_REG_C_TEX5FMT_SHIFT 6 +#define CP_VAT_REG_C_TEX5FMT_MASK 0x000001c0 +#define CP_VAT_REG_C_GET_TEX5FMT(cp_vat_reg_c) \ + ((((unsigned long)(cp_vat_reg_c)) & CP_VAT_REG_C_TEX5FMT_MASK) >> CP_VAT_REG_C_TEX5FMT_SHIFT) +#define CP_VAT_REG_C_SET_TEX5FMT(cp_vat_reg_c, tex5Fmt) { \ + FDL_ASSERT(!((tex5Fmt) & ~((1 << CP_VAT_REG_C_TEX5FMT_SIZE)-1))); \ + cp_vat_reg_c = (((unsigned long)(cp_vat_reg_c)) & ~CP_VAT_REG_C_TEX5FMT_MASK) | (((unsigned long)(tex5Fmt)) << CP_VAT_REG_C_TEX5FMT_SHIFT);\ +} +#define CP_VAT_REG_C_TEX5SHFT_SIZE 5 +#define CP_VAT_REG_C_TEX5SHFT_SHIFT 9 +#define CP_VAT_REG_C_TEX5SHFT_MASK 0x00003e00 +#define CP_VAT_REG_C_GET_TEX5SHFT(cp_vat_reg_c) \ + ((((unsigned long)(cp_vat_reg_c)) & CP_VAT_REG_C_TEX5SHFT_MASK) >> CP_VAT_REG_C_TEX5SHFT_SHIFT) +#define CP_VAT_REG_C_SET_TEX5SHFT(cp_vat_reg_c, tex5Shft) { \ + FDL_ASSERT(!((tex5Shft) & ~((1 << CP_VAT_REG_C_TEX5SHFT_SIZE)-1))); \ + cp_vat_reg_c = (((unsigned long)(cp_vat_reg_c)) & ~CP_VAT_REG_C_TEX5SHFT_MASK) | (((unsigned long)(tex5Shft)) << CP_VAT_REG_C_TEX5SHFT_SHIFT);\ +} +#define CP_VAT_REG_C_TEX6CNT_SIZE 1 +#define CP_VAT_REG_C_TEX6CNT_SHIFT 14 +#define CP_VAT_REG_C_TEX6CNT_MASK 0x00004000 +#define CP_VAT_REG_C_GET_TEX6CNT(cp_vat_reg_c) \ + ((((unsigned long)(cp_vat_reg_c)) & CP_VAT_REG_C_TEX6CNT_MASK) >> CP_VAT_REG_C_TEX6CNT_SHIFT) +#define CP_VAT_REG_C_SET_TEX6CNT(cp_vat_reg_c, tex6Cnt) { \ + FDL_ASSERT(!((tex6Cnt) & ~((1 << CP_VAT_REG_C_TEX6CNT_SIZE)-1))); \ + cp_vat_reg_c = (((unsigned long)(cp_vat_reg_c)) & ~CP_VAT_REG_C_TEX6CNT_MASK) | (((unsigned long)(tex6Cnt)) << CP_VAT_REG_C_TEX6CNT_SHIFT);\ +} +#define CP_VAT_REG_C_TEX6FMT_SIZE 3 +#define CP_VAT_REG_C_TEX6FMT_SHIFT 15 +#define CP_VAT_REG_C_TEX6FMT_MASK 0x00038000 +#define CP_VAT_REG_C_GET_TEX6FMT(cp_vat_reg_c) \ + ((((unsigned long)(cp_vat_reg_c)) & CP_VAT_REG_C_TEX6FMT_MASK) >> CP_VAT_REG_C_TEX6FMT_SHIFT) +#define CP_VAT_REG_C_SET_TEX6FMT(cp_vat_reg_c, tex6Fmt) { \ + FDL_ASSERT(!((tex6Fmt) & ~((1 << CP_VAT_REG_C_TEX6FMT_SIZE)-1))); \ + cp_vat_reg_c = (((unsigned long)(cp_vat_reg_c)) & ~CP_VAT_REG_C_TEX6FMT_MASK) | (((unsigned long)(tex6Fmt)) << CP_VAT_REG_C_TEX6FMT_SHIFT);\ +} +#define CP_VAT_REG_C_TEX6SHFT_SIZE 5 +#define CP_VAT_REG_C_TEX6SHFT_SHIFT 18 +#define CP_VAT_REG_C_TEX6SHFT_MASK 0x007c0000 +#define CP_VAT_REG_C_GET_TEX6SHFT(cp_vat_reg_c) \ + ((((unsigned long)(cp_vat_reg_c)) & CP_VAT_REG_C_TEX6SHFT_MASK) >> CP_VAT_REG_C_TEX6SHFT_SHIFT) +#define CP_VAT_REG_C_SET_TEX6SHFT(cp_vat_reg_c, tex6Shft) { \ + FDL_ASSERT(!((tex6Shft) & ~((1 << CP_VAT_REG_C_TEX6SHFT_SIZE)-1))); \ + cp_vat_reg_c = (((unsigned long)(cp_vat_reg_c)) & ~CP_VAT_REG_C_TEX6SHFT_MASK) | (((unsigned long)(tex6Shft)) << CP_VAT_REG_C_TEX6SHFT_SHIFT);\ +} +#define CP_VAT_REG_C_TEX7CNT_SIZE 1 +#define CP_VAT_REG_C_TEX7CNT_SHIFT 23 +#define CP_VAT_REG_C_TEX7CNT_MASK 0x00800000 +#define CP_VAT_REG_C_GET_TEX7CNT(cp_vat_reg_c) \ + ((((unsigned long)(cp_vat_reg_c)) & CP_VAT_REG_C_TEX7CNT_MASK) >> CP_VAT_REG_C_TEX7CNT_SHIFT) +#define CP_VAT_REG_C_SET_TEX7CNT(cp_vat_reg_c, tex7Cnt) { \ + FDL_ASSERT(!((tex7Cnt) & ~((1 << CP_VAT_REG_C_TEX7CNT_SIZE)-1))); \ + cp_vat_reg_c = (((unsigned long)(cp_vat_reg_c)) & ~CP_VAT_REG_C_TEX7CNT_MASK) | (((unsigned long)(tex7Cnt)) << CP_VAT_REG_C_TEX7CNT_SHIFT);\ +} +#define CP_VAT_REG_C_TEX7FMT_SIZE 3 +#define CP_VAT_REG_C_TEX7FMT_SHIFT 24 +#define CP_VAT_REG_C_TEX7FMT_MASK 0x07000000 +#define CP_VAT_REG_C_GET_TEX7FMT(cp_vat_reg_c) \ + ((((unsigned long)(cp_vat_reg_c)) & CP_VAT_REG_C_TEX7FMT_MASK) >> CP_VAT_REG_C_TEX7FMT_SHIFT) +#define CP_VAT_REG_C_SET_TEX7FMT(cp_vat_reg_c, tex7Fmt) { \ + FDL_ASSERT(!((tex7Fmt) & ~((1 << CP_VAT_REG_C_TEX7FMT_SIZE)-1))); \ + cp_vat_reg_c = (((unsigned long)(cp_vat_reg_c)) & ~CP_VAT_REG_C_TEX7FMT_MASK) | (((unsigned long)(tex7Fmt)) << CP_VAT_REG_C_TEX7FMT_SHIFT);\ +} +#define CP_VAT_REG_C_TEX7SHFT_SIZE 5 +#define CP_VAT_REG_C_TEX7SHFT_SHIFT 27 +#define CP_VAT_REG_C_TEX7SHFT_MASK 0xf8000000 +#define CP_VAT_REG_C_GET_TEX7SHFT(cp_vat_reg_c) \ + ((((unsigned long)(cp_vat_reg_c)) & CP_VAT_REG_C_TEX7SHFT_MASK) >> CP_VAT_REG_C_TEX7SHFT_SHIFT) +#define CP_VAT_REG_C_SET_TEX7SHFT(cp_vat_reg_c, tex7Shft) { \ + FDL_ASSERT(!((tex7Shft) & ~((1 << CP_VAT_REG_C_TEX7SHFT_SIZE)-1))); \ + cp_vat_reg_c = (((unsigned long)(cp_vat_reg_c)) & ~CP_VAT_REG_C_TEX7SHFT_MASK) | (((unsigned long)(tex7Shft)) << CP_VAT_REG_C_TEX7SHFT_SHIFT);\ +} +#define CP_VAT_REG_C_TOTAL_SIZE 32 +#define CP_VAT_REG_C(tex4Shft, tex5Cnt, tex5Fmt, tex5Shft, tex6Cnt, tex6Fmt, tex6Shft, tex7Cnt, tex7Fmt, tex7Shft) \ + ((((unsigned long)(tex4Shft)) << CP_VAT_REG_C_TEX4SHFT_SHIFT) | \ + (((unsigned long)(tex5Cnt)) << CP_VAT_REG_C_TEX5CNT_SHIFT) | \ + (((unsigned long)(tex5Fmt)) << CP_VAT_REG_C_TEX5FMT_SHIFT) | \ + (((unsigned long)(tex5Shft)) << CP_VAT_REG_C_TEX5SHFT_SHIFT) | \ + (((unsigned long)(tex6Cnt)) << CP_VAT_REG_C_TEX6CNT_SHIFT) | \ + (((unsigned long)(tex6Fmt)) << CP_VAT_REG_C_TEX6FMT_SHIFT) | \ + (((unsigned long)(tex6Shft)) << CP_VAT_REG_C_TEX6SHFT_SHIFT) | \ + (((unsigned long)(tex7Cnt)) << CP_VAT_REG_C_TEX7CNT_SHIFT) | \ + (((unsigned long)(tex7Fmt)) << CP_VAT_REG_C_TEX7FMT_SHIFT) | \ + (((unsigned long)(tex7Shft)) << CP_VAT_REG_C_TEX7SHFT_SHIFT)) + +/* +* cp_matidx_reg_a struct +*/ +#define CP_MATIDX_REG_A_POSIDX_SIZE 6 +#define CP_MATIDX_REG_A_POSIDX_SHIFT 0 +#define CP_MATIDX_REG_A_POSIDX_MASK 0x0000003f +#define CP_MATIDX_REG_A_GET_POSIDX(cp_matidx_reg_a) \ + ((((unsigned long)(cp_matidx_reg_a)) & CP_MATIDX_REG_A_POSIDX_MASK) >> CP_MATIDX_REG_A_POSIDX_SHIFT) +#define CP_MATIDX_REG_A_SET_POSIDX(cp_matidx_reg_a, posIdx) { \ + FDL_ASSERT(!((posIdx) & ~((1 << CP_MATIDX_REG_A_POSIDX_SIZE)-1))); \ + cp_matidx_reg_a = (((unsigned long)(cp_matidx_reg_a)) & ~CP_MATIDX_REG_A_POSIDX_MASK) | (((unsigned long)(posIdx)) << CP_MATIDX_REG_A_POSIDX_SHIFT);\ +} +#define CP_MATIDX_REG_A_TEX0IDX_SIZE 6 +#define CP_MATIDX_REG_A_TEX0IDX_SHIFT 6 +#define CP_MATIDX_REG_A_TEX0IDX_MASK 0x00000fc0 +#define CP_MATIDX_REG_A_GET_TEX0IDX(cp_matidx_reg_a) \ + ((((unsigned long)(cp_matidx_reg_a)) & CP_MATIDX_REG_A_TEX0IDX_MASK) >> CP_MATIDX_REG_A_TEX0IDX_SHIFT) +#define CP_MATIDX_REG_A_SET_TEX0IDX(cp_matidx_reg_a, tex0Idx) { \ + FDL_ASSERT(!((tex0Idx) & ~((1 << CP_MATIDX_REG_A_TEX0IDX_SIZE)-1))); \ + cp_matidx_reg_a = (((unsigned long)(cp_matidx_reg_a)) & ~CP_MATIDX_REG_A_TEX0IDX_MASK) | (((unsigned long)(tex0Idx)) << CP_MATIDX_REG_A_TEX0IDX_SHIFT);\ +} +#define CP_MATIDX_REG_A_TEX1IDX_SIZE 6 +#define CP_MATIDX_REG_A_TEX1IDX_SHIFT 12 +#define CP_MATIDX_REG_A_TEX1IDX_MASK 0x0003f000 +#define CP_MATIDX_REG_A_GET_TEX1IDX(cp_matidx_reg_a) \ + ((((unsigned long)(cp_matidx_reg_a)) & CP_MATIDX_REG_A_TEX1IDX_MASK) >> CP_MATIDX_REG_A_TEX1IDX_SHIFT) +#define CP_MATIDX_REG_A_SET_TEX1IDX(cp_matidx_reg_a, tex1Idx) { \ + FDL_ASSERT(!((tex1Idx) & ~((1 << CP_MATIDX_REG_A_TEX1IDX_SIZE)-1))); \ + cp_matidx_reg_a = (((unsigned long)(cp_matidx_reg_a)) & ~CP_MATIDX_REG_A_TEX1IDX_MASK) | (((unsigned long)(tex1Idx)) << CP_MATIDX_REG_A_TEX1IDX_SHIFT);\ +} +#define CP_MATIDX_REG_A_TEX2IDX_SIZE 6 +#define CP_MATIDX_REG_A_TEX2IDX_SHIFT 18 +#define CP_MATIDX_REG_A_TEX2IDX_MASK 0x00fc0000 +#define CP_MATIDX_REG_A_GET_TEX2IDX(cp_matidx_reg_a) \ + ((((unsigned long)(cp_matidx_reg_a)) & CP_MATIDX_REG_A_TEX2IDX_MASK) >> CP_MATIDX_REG_A_TEX2IDX_SHIFT) +#define CP_MATIDX_REG_A_SET_TEX2IDX(cp_matidx_reg_a, tex2Idx) { \ + FDL_ASSERT(!((tex2Idx) & ~((1 << CP_MATIDX_REG_A_TEX2IDX_SIZE)-1))); \ + cp_matidx_reg_a = (((unsigned long)(cp_matidx_reg_a)) & ~CP_MATIDX_REG_A_TEX2IDX_MASK) | (((unsigned long)(tex2Idx)) << CP_MATIDX_REG_A_TEX2IDX_SHIFT);\ +} +#define CP_MATIDX_REG_A_TEX3IDX_SIZE 6 +#define CP_MATIDX_REG_A_TEX3IDX_SHIFT 24 +#define CP_MATIDX_REG_A_TEX3IDX_MASK 0x3f000000 +#define CP_MATIDX_REG_A_GET_TEX3IDX(cp_matidx_reg_a) \ + ((((unsigned long)(cp_matidx_reg_a)) & CP_MATIDX_REG_A_TEX3IDX_MASK) >> CP_MATIDX_REG_A_TEX3IDX_SHIFT) +#define CP_MATIDX_REG_A_SET_TEX3IDX(cp_matidx_reg_a, tex3Idx) { \ + FDL_ASSERT(!((tex3Idx) & ~((1 << CP_MATIDX_REG_A_TEX3IDX_SIZE)-1))); \ + cp_matidx_reg_a = (((unsigned long)(cp_matidx_reg_a)) & ~CP_MATIDX_REG_A_TEX3IDX_MASK) | (((unsigned long)(tex3Idx)) << CP_MATIDX_REG_A_TEX3IDX_SHIFT);\ +} +#define CP_MATIDX_REG_A_TOTAL_SIZE 30 +#define CP_MATIDX_REG_A(posIdx, tex0Idx, tex1Idx, tex2Idx, tex3Idx) \ + ((((unsigned long)(posIdx)) << CP_MATIDX_REG_A_POSIDX_SHIFT) | \ + (((unsigned long)(tex0Idx)) << CP_MATIDX_REG_A_TEX0IDX_SHIFT) | \ + (((unsigned long)(tex1Idx)) << CP_MATIDX_REG_A_TEX1IDX_SHIFT) | \ + (((unsigned long)(tex2Idx)) << CP_MATIDX_REG_A_TEX2IDX_SHIFT) | \ + (((unsigned long)(tex3Idx)) << CP_MATIDX_REG_A_TEX3IDX_SHIFT)) + +/* +* cp_matidx_reg_b struct +*/ +#define CP_MATIDX_REG_B_TEX4IDX_SIZE 6 +#define CP_MATIDX_REG_B_TEX4IDX_SHIFT 0 +#define CP_MATIDX_REG_B_TEX4IDX_MASK 0x0000003f +#define CP_MATIDX_REG_B_GET_TEX4IDX(cp_matidx_reg_b) \ + ((((unsigned long)(cp_matidx_reg_b)) & CP_MATIDX_REG_B_TEX4IDX_MASK) >> CP_MATIDX_REG_B_TEX4IDX_SHIFT) +#define CP_MATIDX_REG_B_SET_TEX4IDX(cp_matidx_reg_b, tex4Idx) { \ + FDL_ASSERT(!((tex4Idx) & ~((1 << CP_MATIDX_REG_B_TEX4IDX_SIZE)-1))); \ + cp_matidx_reg_b = (((unsigned long)(cp_matidx_reg_b)) & ~CP_MATIDX_REG_B_TEX4IDX_MASK) | (((unsigned long)(tex4Idx)) << CP_MATIDX_REG_B_TEX4IDX_SHIFT);\ +} +#define CP_MATIDX_REG_B_TEX5IDX_SIZE 6 +#define CP_MATIDX_REG_B_TEX5IDX_SHIFT 6 +#define CP_MATIDX_REG_B_TEX5IDX_MASK 0x00000fc0 +#define CP_MATIDX_REG_B_GET_TEX5IDX(cp_matidx_reg_b) \ + ((((unsigned long)(cp_matidx_reg_b)) & CP_MATIDX_REG_B_TEX5IDX_MASK) >> CP_MATIDX_REG_B_TEX5IDX_SHIFT) +#define CP_MATIDX_REG_B_SET_TEX5IDX(cp_matidx_reg_b, tex5Idx) { \ + FDL_ASSERT(!((tex5Idx) & ~((1 << CP_MATIDX_REG_B_TEX5IDX_SIZE)-1))); \ + cp_matidx_reg_b = (((unsigned long)(cp_matidx_reg_b)) & ~CP_MATIDX_REG_B_TEX5IDX_MASK) | (((unsigned long)(tex5Idx)) << CP_MATIDX_REG_B_TEX5IDX_SHIFT);\ +} +#define CP_MATIDX_REG_B_TEX6IDX_SIZE 6 +#define CP_MATIDX_REG_B_TEX6IDX_SHIFT 12 +#define CP_MATIDX_REG_B_TEX6IDX_MASK 0x0003f000 +#define CP_MATIDX_REG_B_GET_TEX6IDX(cp_matidx_reg_b) \ + ((((unsigned long)(cp_matidx_reg_b)) & CP_MATIDX_REG_B_TEX6IDX_MASK) >> CP_MATIDX_REG_B_TEX6IDX_SHIFT) +#define CP_MATIDX_REG_B_SET_TEX6IDX(cp_matidx_reg_b, tex6Idx) { \ + FDL_ASSERT(!((tex6Idx) & ~((1 << CP_MATIDX_REG_B_TEX6IDX_SIZE)-1))); \ + cp_matidx_reg_b = (((unsigned long)(cp_matidx_reg_b)) & ~CP_MATIDX_REG_B_TEX6IDX_MASK) | (((unsigned long)(tex6Idx)) << CP_MATIDX_REG_B_TEX6IDX_SHIFT);\ +} +#define CP_MATIDX_REG_B_TEX7IDX_SIZE 6 +#define CP_MATIDX_REG_B_TEX7IDX_SHIFT 18 +#define CP_MATIDX_REG_B_TEX7IDX_MASK 0x00fc0000 +#define CP_MATIDX_REG_B_GET_TEX7IDX(cp_matidx_reg_b) \ + ((((unsigned long)(cp_matidx_reg_b)) & CP_MATIDX_REG_B_TEX7IDX_MASK) >> CP_MATIDX_REG_B_TEX7IDX_SHIFT) +#define CP_MATIDX_REG_B_SET_TEX7IDX(cp_matidx_reg_b, tex7Idx) { \ + FDL_ASSERT(!((tex7Idx) & ~((1 << CP_MATIDX_REG_B_TEX7IDX_SIZE)-1))); \ + cp_matidx_reg_b = (((unsigned long)(cp_matidx_reg_b)) & ~CP_MATIDX_REG_B_TEX7IDX_MASK) | (((unsigned long)(tex7Idx)) << CP_MATIDX_REG_B_TEX7IDX_SHIFT);\ +} +#define CP_MATIDX_REG_B_TOTAL_SIZE 24 +#define CP_MATIDX_REG_B(tex4Idx, tex5Idx, tex6Idx, tex7Idx) \ + ((((unsigned long)(tex4Idx)) << CP_MATIDX_REG_B_TEX4IDX_SHIFT) | \ + (((unsigned long)(tex5Idx)) << CP_MATIDX_REG_B_TEX5IDX_SHIFT) | \ + (((unsigned long)(tex6Idx)) << CP_MATIDX_REG_B_TEX6IDX_SHIFT) | \ + (((unsigned long)(tex7Idx)) << CP_MATIDX_REG_B_TEX7IDX_SHIFT)) + +/* +* cp_array_base_reg struct +*/ +#define CP_ARRAY_BASE_REG_BASE_SIZE 29 +#define CP_ARRAY_BASE_REG_BASE_SHIFT 0 +#define CP_ARRAY_BASE_REG_BASE_MASK 0x1fffffff +#define CP_ARRAY_BASE_REG_GET_BASE(cp_array_base_reg) \ + ((((unsigned long)(cp_array_base_reg)) & CP_ARRAY_BASE_REG_BASE_MASK) >> CP_ARRAY_BASE_REG_BASE_SHIFT) +#define CP_ARRAY_BASE_REG_SET_BASE(cp_array_base_reg, base) { \ + FDL_ASSERT(!((base) & ~((1 << CP_ARRAY_BASE_REG_BASE_SIZE)-1))); \ + cp_array_base_reg = (((unsigned long)(cp_array_base_reg)) & ~CP_ARRAY_BASE_REG_BASE_MASK) | (((unsigned long)(base)) << CP_ARRAY_BASE_REG_BASE_SHIFT);\ +} +#define CP_ARRAY_BASE_REG_PAD0_SIZE 3 +#define CP_ARRAY_BASE_REG_PAD0_SHIFT 29 +#define CP_ARRAY_BASE_REG_PAD0_MASK 0xe0000000 +#define CP_ARRAY_BASE_REG_GET_PAD0(cp_array_base_reg) \ + ((((unsigned long)(cp_array_base_reg)) & CP_ARRAY_BASE_REG_PAD0_MASK) >> CP_ARRAY_BASE_REG_PAD0_SHIFT) +#define CP_ARRAY_BASE_REG_SET_PAD0(cp_array_base_reg, pad0) { \ + FDL_ASSERT(!((pad0) & ~((1 << CP_ARRAY_BASE_REG_PAD0_SIZE)-1))); \ + cp_array_base_reg = (((unsigned long)(cp_array_base_reg)) & ~CP_ARRAY_BASE_REG_PAD0_MASK) | (((unsigned long)(pad0)) << CP_ARRAY_BASE_REG_PAD0_SHIFT);\ +} +#define CP_ARRAY_BASE_REG_TOTAL_SIZE 32 +#define CP_ARRAY_BASE_REG(base) \ + ((((unsigned long)(base)) << CP_ARRAY_BASE_REG_BASE_SHIFT)) + +/* +* cp_array_stride_reg struct +*/ +#define CP_ARRAY_STRIDE_REG_STRIDE_SIZE 8 +#define CP_ARRAY_STRIDE_REG_STRIDE_SHIFT 0 +#define CP_ARRAY_STRIDE_REG_STRIDE_MASK 0x000000ff +#define CP_ARRAY_STRIDE_REG_GET_STRIDE(cp_array_stride_reg) \ + ((((unsigned long)(cp_array_stride_reg)) & CP_ARRAY_STRIDE_REG_STRIDE_MASK) >> CP_ARRAY_STRIDE_REG_STRIDE_SHIFT) +#define CP_ARRAY_STRIDE_REG_SET_STRIDE(cp_array_stride_reg, stride) { \ + FDL_ASSERT(!((stride) & ~((1 << CP_ARRAY_STRIDE_REG_STRIDE_SIZE)-1))); \ + cp_array_stride_reg = (((unsigned long)(cp_array_stride_reg)) & ~CP_ARRAY_STRIDE_REG_STRIDE_MASK) | (((unsigned long)(stride)) << CP_ARRAY_STRIDE_REG_STRIDE_SHIFT);\ +} +#define CP_ARRAY_STRIDE_REG_PAD0_SIZE 24 +#define CP_ARRAY_STRIDE_REG_PAD0_SHIFT 8 +#define CP_ARRAY_STRIDE_REG_PAD0_MASK 0xffffff00 +#define CP_ARRAY_STRIDE_REG_GET_PAD0(cp_array_stride_reg) \ + ((((unsigned long)(cp_array_stride_reg)) & CP_ARRAY_STRIDE_REG_PAD0_MASK) >> CP_ARRAY_STRIDE_REG_PAD0_SHIFT) +#define CP_ARRAY_STRIDE_REG_SET_PAD0(cp_array_stride_reg, pad0) { \ + FDL_ASSERT(!((pad0) & ~((1 << CP_ARRAY_STRIDE_REG_PAD0_SIZE)-1))); \ + cp_array_stride_reg = (((unsigned long)(cp_array_stride_reg)) & ~CP_ARRAY_STRIDE_REG_PAD0_MASK) | (((unsigned long)(pad0)) << CP_ARRAY_STRIDE_REG_PAD0_SHIFT);\ +} +#define CP_ARRAY_STRIDE_REG_TOTAL_SIZE 32 +#define CP_ARRAY_STRIDE_REG(stride) \ + ((((unsigned long)(stride)) << CP_ARRAY_STRIDE_REG_STRIDE_SHIFT)) + +/* +* cp_stat_enable_reg struct +*/ +#define CP_STAT_ENABLE_REG_VC_STAT_SIZE 1 +#define CP_STAT_ENABLE_REG_VC_STAT_SHIFT 0 +#define CP_STAT_ENABLE_REG_VC_STAT_MASK 0x00000001 +#define CP_STAT_ENABLE_REG_GET_VC_STAT(cp_stat_enable_reg) \ + ((((unsigned long)(cp_stat_enable_reg)) & CP_STAT_ENABLE_REG_VC_STAT_MASK) >> CP_STAT_ENABLE_REG_VC_STAT_SHIFT) +#define CP_STAT_ENABLE_REG_SET_VC_STAT(cp_stat_enable_reg, vc_stat) { \ + FDL_ASSERT(!((vc_stat) & ~((1 << CP_STAT_ENABLE_REG_VC_STAT_SIZE)-1))); \ + cp_stat_enable_reg = (((unsigned long)(cp_stat_enable_reg)) & ~CP_STAT_ENABLE_REG_VC_STAT_MASK) | (((unsigned long)(vc_stat)) << CP_STAT_ENABLE_REG_VC_STAT_SHIFT);\ +} +#define CP_STAT_ENABLE_REG_PAD0_SIZE 1 +#define CP_STAT_ENABLE_REG_PAD0_SHIFT 1 +#define CP_STAT_ENABLE_REG_PAD0_MASK 0x00000002 +#define CP_STAT_ENABLE_REG_GET_PAD0(cp_stat_enable_reg) \ + ((((unsigned long)(cp_stat_enable_reg)) & CP_STAT_ENABLE_REG_PAD0_MASK) >> CP_STAT_ENABLE_REG_PAD0_SHIFT) +#define CP_STAT_ENABLE_REG_SET_PAD0(cp_stat_enable_reg, pad0) { \ + FDL_ASSERT(!((pad0) & ~((1 << CP_STAT_ENABLE_REG_PAD0_SIZE)-1))); \ + cp_stat_enable_reg = (((unsigned long)(cp_stat_enable_reg)) & ~CP_STAT_ENABLE_REG_PAD0_MASK) | (((unsigned long)(pad0)) << CP_STAT_ENABLE_REG_PAD0_SHIFT);\ +} +#define CP_STAT_ENABLE_REG_FRCLK_SIZE 1 +#define CP_STAT_ENABLE_REG_FRCLK_SHIFT 2 +#define CP_STAT_ENABLE_REG_FRCLK_MASK 0x00000004 +#define CP_STAT_ENABLE_REG_GET_FRCLK(cp_stat_enable_reg) \ + ((((unsigned long)(cp_stat_enable_reg)) & CP_STAT_ENABLE_REG_FRCLK_MASK) >> CP_STAT_ENABLE_REG_FRCLK_SHIFT) +#define CP_STAT_ENABLE_REG_SET_FRCLK(cp_stat_enable_reg, frclk) { \ + FDL_ASSERT(!((frclk) & ~((1 << CP_STAT_ENABLE_REG_FRCLK_SIZE)-1))); \ + cp_stat_enable_reg = (((unsigned long)(cp_stat_enable_reg)) & ~CP_STAT_ENABLE_REG_FRCLK_MASK) | (((unsigned long)(frclk)) << CP_STAT_ENABLE_REG_FRCLK_SHIFT);\ +} +#define CP_STAT_ENABLE_REG_TOTAL_SIZE 3 +#define CP_STAT_ENABLE_REG(vc_stat, frclk) \ + ((((unsigned long)(vc_stat)) << CP_STAT_ENABLE_REG_VC_STAT_SHIFT) | \ + (((unsigned long)(frclk)) << CP_STAT_ENABLE_REG_FRCLK_SHIFT)) + +/* +* cp_stat_sel_reg struct +*/ +#define CP_STAT_SEL_REG_ATTR_SEL_SIZE 4 +#define CP_STAT_SEL_REG_ATTR_SEL_SHIFT 0 +#define CP_STAT_SEL_REG_ATTR_SEL_MASK 0x0000000f +#define CP_STAT_SEL_REG_GET_ATTR_SEL(cp_stat_sel_reg) \ + ((((unsigned long)(cp_stat_sel_reg)) & CP_STAT_SEL_REG_ATTR_SEL_MASK) >> CP_STAT_SEL_REG_ATTR_SEL_SHIFT) +#define CP_STAT_SEL_REG_SET_ATTR_SEL(cp_stat_sel_reg, attr_sel) { \ + FDL_ASSERT(!((attr_sel) & ~((1 << CP_STAT_SEL_REG_ATTR_SEL_SIZE)-1))); \ + cp_stat_sel_reg = (((unsigned long)(cp_stat_sel_reg)) & ~CP_STAT_SEL_REG_ATTR_SEL_MASK) | (((unsigned long)(attr_sel)) << CP_STAT_SEL_REG_ATTR_SEL_SHIFT);\ +} +#define CP_STAT_SEL_REG_STALLPERF_SEL_SIZE 4 +#define CP_STAT_SEL_REG_STALLPERF_SEL_SHIFT 4 +#define CP_STAT_SEL_REG_STALLPERF_SEL_MASK 0x000000f0 +#define CP_STAT_SEL_REG_GET_STALLPERF_SEL(cp_stat_sel_reg) \ + ((((unsigned long)(cp_stat_sel_reg)) & CP_STAT_SEL_REG_STALLPERF_SEL_MASK) >> CP_STAT_SEL_REG_STALLPERF_SEL_SHIFT) +#define CP_STAT_SEL_REG_SET_STALLPERF_SEL(cp_stat_sel_reg, stallperf_sel) { \ + FDL_ASSERT(!((stallperf_sel) & ~((1 << CP_STAT_SEL_REG_STALLPERF_SEL_SIZE)-1))); \ + cp_stat_sel_reg = (((unsigned long)(cp_stat_sel_reg)) & ~CP_STAT_SEL_REG_STALLPERF_SEL_MASK) | (((unsigned long)(stallperf_sel)) << CP_STAT_SEL_REG_STALLPERF_SEL_SHIFT);\ +} +#define CP_STAT_SEL_REG_TOTAL_SIZE 8 +#define CP_STAT_SEL_REG(attr_sel, stallperf_sel) \ + ((((unsigned long)(attr_sel)) << CP_STAT_SEL_REG_ATTR_SEL_SHIFT) | \ + (((unsigned long)(stallperf_sel)) << CP_STAT_SEL_REG_STALLPERF_SEL_SHIFT)) + +/* +* cp_stallperf_sel enum +*/ +#define STALLPERF_ZERO 0x00000000 +#define STALLPERF_ONE 0x00000001 +#define ELEMQ_FULL 0x00000002 +#define MISSQ_FULL 0x00000003 +#define MEMREQ_FULL 0x00000004 +#define VC_STATCNT7 0x00000005 +#define VC_MISS_REP_FULL 0x00000006 +#define VC_STALL_STMBUFLOW 0x00000007 +#define VTX_CNT 0x00000008 +#define ALL_STALL 0x00000009 +#define CP_STALLPERF_SEL_UNUSED_10 0x0000000a +#define CP_STALLPERF_SEL_UNUSED_11 0x0000000b +#define CP_STALLPERF_SEL_UNUSED_12 0x0000000c +#define CP_STALLPERF_SEL_UNUSED_13 0x0000000d +#define CP_STALLPERF_SEL_UNUSED_14 0x0000000e +#define CP_STALLPERF_SEL_UNUSED_15 0x0000000f + +/* +* cp_array_addr value +*/ +#define ATTR_ARRAY_POS 0x0 +#define ATTR_ARRAY_NRM 0x1 +#define ATTR_ARRAY_COL0 0x2 +#define ATTR_ARRAY_COL1 0x3 +#define ATTR_ARRAY_TEX0 0x4 +#define ATTR_ARRAY_TEX1 0x5 +#define ATTR_ARRAY_TEX2 0x6 +#define ATTR_ARRAY_TEX3 0x7 +#define ATTR_ARRAY_TEX4 0x8 +#define ATTR_ARRAY_TEX5 0x9 +#define ATTR_ARRAY_TEX6 0xa +#define ATTR_ARRAY_TEX7 0xb +#define ATTR_ARRAY_XFINDREGA 0xc +#define ATTR_ARRAY_XFINDREGB 0xd +#define ATTR_ARRAY_XFINDREGC 0xe +#define ATTR_ARRAY_XFINDREGD 0xf + +/* +* cp_xf_loadregs struct +*/ +#define CP_XF_LOADREGS_ADDR_SIZE 16 +#define CP_XF_LOADREGS_ADDR_SHIFT 0 +#define CP_XF_LOADREGS_ADDR_MASK 0x0000ffff +#define CP_XF_LOADREGS_GET_ADDR(cp_xf_loadregs) \ + ((((unsigned long)(cp_xf_loadregs)) & CP_XF_LOADREGS_ADDR_MASK) >> CP_XF_LOADREGS_ADDR_SHIFT) +#define CP_XF_LOADREGS_SET_ADDR(cp_xf_loadregs, addr) { \ + FDL_ASSERT(!((addr) & ~((1 << CP_XF_LOADREGS_ADDR_SIZE)-1))); \ + cp_xf_loadregs = (((unsigned long)(cp_xf_loadregs)) & ~CP_XF_LOADREGS_ADDR_MASK) | (((unsigned long)(addr)) << CP_XF_LOADREGS_ADDR_SHIFT);\ +} +#define CP_XF_LOADREGS_CNT_SIZE 4 +#define CP_XF_LOADREGS_CNT_SHIFT 16 +#define CP_XF_LOADREGS_CNT_MASK 0x000f0000 +#define CP_XF_LOADREGS_GET_CNT(cp_xf_loadregs) \ + ((((unsigned long)(cp_xf_loadregs)) & CP_XF_LOADREGS_CNT_MASK) >> CP_XF_LOADREGS_CNT_SHIFT) +#define CP_XF_LOADREGS_SET_CNT(cp_xf_loadregs, cnt) { \ + FDL_ASSERT(!((cnt) & ~((1 << CP_XF_LOADREGS_CNT_SIZE)-1))); \ + cp_xf_loadregs = (((unsigned long)(cp_xf_loadregs)) & ~CP_XF_LOADREGS_CNT_MASK) | (((unsigned long)(cnt)) << CP_XF_LOADREGS_CNT_SHIFT);\ +} +#define CP_XF_LOADREGS_TOTAL_SIZE 20 +#define CP_XF_LOADREGS_UNUSED_SIZE 12 + +#define CP_XF_LOADREGS(addr, cnt) \ + ((((unsigned long)(addr)) << CP_XF_LOADREGS_ADDR_SHIFT) | \ + (((unsigned long)(cnt)) << CP_XF_LOADREGS_CNT_SHIFT)) + +/* +* cp_xf_loadindex struct +*/ +#define CP_XF_LOADINDEX_ADDR_SIZE 12 +#define CP_XF_LOADINDEX_ADDR_SHIFT 0 +#define CP_XF_LOADINDEX_ADDR_MASK 0x00000fff +#define CP_XF_LOADINDEX_GET_ADDR(cp_xf_loadindex) \ + ((((unsigned long)(cp_xf_loadindex)) & CP_XF_LOADINDEX_ADDR_MASK) >> CP_XF_LOADINDEX_ADDR_SHIFT) +#define CP_XF_LOADINDEX_SET_ADDR(cp_xf_loadindex, addr) { \ + FDL_ASSERT(!((addr) & ~((1 << CP_XF_LOADINDEX_ADDR_SIZE)-1))); \ + cp_xf_loadindex = (((unsigned long)(cp_xf_loadindex)) & ~CP_XF_LOADINDEX_ADDR_MASK) | (((unsigned long)(addr)) << CP_XF_LOADINDEX_ADDR_SHIFT);\ +} +#define CP_XF_LOADINDEX_CNT_SIZE 4 +#define CP_XF_LOADINDEX_CNT_SHIFT 12 +#define CP_XF_LOADINDEX_CNT_MASK 0x0000f000 +#define CP_XF_LOADINDEX_GET_CNT(cp_xf_loadindex) \ + ((((unsigned long)(cp_xf_loadindex)) & CP_XF_LOADINDEX_CNT_MASK) >> CP_XF_LOADINDEX_CNT_SHIFT) +#define CP_XF_LOADINDEX_SET_CNT(cp_xf_loadindex, cnt) { \ + FDL_ASSERT(!((cnt) & ~((1 << CP_XF_LOADINDEX_CNT_SIZE)-1))); \ + cp_xf_loadindex = (((unsigned long)(cp_xf_loadindex)) & ~CP_XF_LOADINDEX_CNT_MASK) | (((unsigned long)(cnt)) << CP_XF_LOADINDEX_CNT_SHIFT);\ +} +#define CP_XF_LOADINDEX_IDX_SIZE 16 +#define CP_XF_LOADINDEX_IDX_SHIFT 16 +#define CP_XF_LOADINDEX_IDX_MASK 0xffff0000 +#define CP_XF_LOADINDEX_GET_IDX(cp_xf_loadindex) \ + ((((unsigned long)(cp_xf_loadindex)) & CP_XF_LOADINDEX_IDX_MASK) >> CP_XF_LOADINDEX_IDX_SHIFT) +#define CP_XF_LOADINDEX_SET_IDX(cp_xf_loadindex, idx) { \ + FDL_ASSERT(!((idx) & ~((1 << CP_XF_LOADINDEX_IDX_SIZE)-1))); \ + cp_xf_loadindex = (((unsigned long)(cp_xf_loadindex)) & ~CP_XF_LOADINDEX_IDX_MASK) | (((unsigned long)(idx)) << CP_XF_LOADINDEX_IDX_SHIFT);\ +} +#define CP_XF_LOADINDEX_TOTAL_SIZE 32 +#define CP_XF_LOADINDEX(addr, cnt, idx) \ + ((((unsigned long)(addr)) << CP_XF_LOADINDEX_ADDR_SHIFT) | \ + (((unsigned long)(cnt)) << CP_XF_LOADINDEX_CNT_SHIFT) | \ + (((unsigned long)(idx)) << CP_XF_LOADINDEX_IDX_SHIFT)) + +/* +* cp_callobj_d1 struct +*/ +#define CP_CALLOBJ_D1_PAD0_SIZE 5 +#define CP_CALLOBJ_D1_PAD0_SHIFT 0 +#define CP_CALLOBJ_D1_PAD0_MASK 0x0000001f +#define CP_CALLOBJ_D1_GET_PAD0(cp_callobj_d1) \ + ((((unsigned long)(cp_callobj_d1)) & CP_CALLOBJ_D1_PAD0_MASK) >> CP_CALLOBJ_D1_PAD0_SHIFT) +#define CP_CALLOBJ_D1_SET_PAD0(cp_callobj_d1, pad0) { \ + FDL_ASSERT(!((pad0) & ~((1 << CP_CALLOBJ_D1_PAD0_SIZE)-1))); \ + cp_callobj_d1 = (((unsigned long)(cp_callobj_d1)) & ~CP_CALLOBJ_D1_PAD0_MASK) | (((unsigned long)(pad0)) << CP_CALLOBJ_D1_PAD0_SHIFT);\ +} +#define CP_CALLOBJ_D1_ADDR_SIZE 24 +#define CP_CALLOBJ_D1_ADDR_SHIFT 5 +#define CP_CALLOBJ_D1_ADDR_MASK 0x1fffffe0 +#define CP_CALLOBJ_D1_GET_ADDR(cp_callobj_d1) \ + ((((unsigned long)(cp_callobj_d1)) & CP_CALLOBJ_D1_ADDR_MASK) >> CP_CALLOBJ_D1_ADDR_SHIFT) +#define CP_CALLOBJ_D1_SET_ADDR(cp_callobj_d1, addr) { \ + FDL_ASSERT(!((addr) & ~((1 << CP_CALLOBJ_D1_ADDR_SIZE)-1))); \ + cp_callobj_d1 = (((unsigned long)(cp_callobj_d1)) & ~CP_CALLOBJ_D1_ADDR_MASK) | (((unsigned long)(addr)) << CP_CALLOBJ_D1_ADDR_SHIFT);\ +} +#define CP_CALLOBJ_D1_TOTAL_SIZE 29 +#define CP_CALLOBJ_D1_UNUSED_SIZE 3 + +#define CP_CALLOBJ_D1(addr) \ + ((((unsigned long)(addr)) << CP_CALLOBJ_D1_ADDR_SHIFT)) + +/* +* cp_callobj_d2 struct +*/ +#define CP_CALLOBJ_D2_PAD0_SIZE 5 +#define CP_CALLOBJ_D2_PAD0_SHIFT 0 +#define CP_CALLOBJ_D2_PAD0_MASK 0x0000001f +#define CP_CALLOBJ_D2_GET_PAD0(cp_callobj_d2) \ + ((((unsigned long)(cp_callobj_d2)) & CP_CALLOBJ_D2_PAD0_MASK) >> CP_CALLOBJ_D2_PAD0_SHIFT) +#define CP_CALLOBJ_D2_SET_PAD0(cp_callobj_d2, pad0) { \ + FDL_ASSERT(!((pad0) & ~((1 << CP_CALLOBJ_D2_PAD0_SIZE)-1))); \ + cp_callobj_d2 = (((unsigned long)(cp_callobj_d2)) & ~CP_CALLOBJ_D2_PAD0_MASK) | (((unsigned long)(pad0)) << CP_CALLOBJ_D2_PAD0_SHIFT);\ +} +#define CP_CALLOBJ_D2_CNT_SIZE 24 +#define CP_CALLOBJ_D2_CNT_SHIFT 5 +#define CP_CALLOBJ_D2_CNT_MASK 0x1fffffe0 +#define CP_CALLOBJ_D2_GET_CNT(cp_callobj_d2) \ + ((((unsigned long)(cp_callobj_d2)) & CP_CALLOBJ_D2_CNT_MASK) >> CP_CALLOBJ_D2_CNT_SHIFT) +#define CP_CALLOBJ_D2_SET_CNT(cp_callobj_d2, cnt) { \ + FDL_ASSERT(!((cnt) & ~((1 << CP_CALLOBJ_D2_CNT_SIZE)-1))); \ + cp_callobj_d2 = (((unsigned long)(cp_callobj_d2)) & ~CP_CALLOBJ_D2_CNT_MASK) | (((unsigned long)(cnt)) << CP_CALLOBJ_D2_CNT_SHIFT);\ +} +#define CP_CALLOBJ_D2_TOTAL_SIZE 29 +#define CP_CALLOBJ_D2_UNUSED_SIZE 3 + +#define CP_CALLOBJ_D2(cnt) \ + ((((unsigned long)(cnt)) << CP_CALLOBJ_D2_CNT_SHIFT)) + + + +#define SC_CP_OPCODE_SET_INDEX(line, cp_opcode,index) \ + FAST_GPFLAGSET(line, cp_opcode,index,CP_OPCODE_INDEX) + +#define SC_CP_OPCODE_SET_CMD(line, cp_opcode,cmd) \ + FAST_GPFLAGSET(line, cp_opcode,cmd,CP_OPCODE_CMD) + +#define SC_CP_STREAM_REG_SET_INDEX(line, cp_stream_reg,index) \ + FAST_GPFLAGSET(line, cp_stream_reg,index,CP_STREAM_REG_INDEX) + +#define SC_CP_STREAM_REG_SET_ADDR(line, cp_stream_reg,addr) \ + FAST_GPFLAGSET(line, cp_stream_reg,addr,CP_STREAM_REG_ADDR) + +#define SC_CP_REG_STATUS_SET_OVFL(line, cp_reg_status,ovfl) \ + FAST_GPFLAGSET(line, cp_reg_status,ovfl,CP_REG_STATUS_OVFL) + +#define SC_CP_REG_STATUS_SET_UNFL(line, cp_reg_status,unfl) \ + FAST_GPFLAGSET(line, cp_reg_status,unfl,CP_REG_STATUS_UNFL) + +#define SC_CP_REG_STATUS_SET_FIFO_RDIDLE(line, cp_reg_status,fifo_rdidle) \ + FAST_GPFLAGSET(line, cp_reg_status,fifo_rdidle,CP_REG_STATUS_FIFO_RDIDLE) + +#define SC_CP_REG_STATUS_SET_CPIDLE(line, cp_reg_status,cpidle) \ + FAST_GPFLAGSET(line, cp_reg_status,cpidle,CP_REG_STATUS_CPIDLE) + +#define SC_CP_REG_STATUS_SET_FIFOBRK(line, cp_reg_status,fifobrk) \ + FAST_GPFLAGSET(line, cp_reg_status,fifobrk,CP_REG_STATUS_FIFOBRK) + +#define SC_CP_REG_ENABLE_SET_FIFORD(line, cp_reg_enable,fiford) \ + FAST_GPFLAGSET(line, cp_reg_enable,fiford,CP_REG_ENABLE_FIFORD) + +#define SC_CP_REG_ENABLE_SET_FIFOBRK(line, cp_reg_enable,fifobrk) \ + FAST_GPFLAGSET(line, cp_reg_enable,fifobrk,CP_REG_ENABLE_FIFOBRK) + +#define SC_CP_REG_ENABLE_SET_OVFLINT(line, cp_reg_enable,ovflint) \ + FAST_GPFLAGSET(line, cp_reg_enable,ovflint,CP_REG_ENABLE_OVFLINT) + +#define SC_CP_REG_ENABLE_SET_UNFLINT(line, cp_reg_enable,unflint) \ + FAST_GPFLAGSET(line, cp_reg_enable,unflint,CP_REG_ENABLE_UNFLINT) + +#define SC_CP_REG_ENABLE_SET_WRPTRINC(line, cp_reg_enable,wrptrinc) \ + FAST_GPFLAGSET(line, cp_reg_enable,wrptrinc,CP_REG_ENABLE_WRPTRINC) + +#define SC_CP_REG_ENABLE_SET_FIFOBRKINT(line, cp_reg_enable,fifobrkint) \ + FAST_GPFLAGSET(line, cp_reg_enable,fifobrkint,CP_REG_ENABLE_FIFOBRKINT) + +#define SC_CP_REG_CLR_SET_OVFLINT(line, cp_reg_clr,ovflint) \ + FAST_GPFLAGSET(line, cp_reg_clr,ovflint,CP_REG_CLR_OVFLINT) + +#define SC_CP_REG_CLR_SET_UNFLINT(line, cp_reg_clr,unflint) \ + FAST_GPFLAGSET(line, cp_reg_clr,unflint,CP_REG_CLR_UNFLINT) + +#define SC_CP_REG_CLR_SET_PERFCNT(line, cp_reg_clr,perfcnt) \ + FAST_GPFLAGSET(line, cp_reg_clr,perfcnt,CP_REG_CLR_PERFCNT) + +#define SC_CP_REG_MEMPERFSEL_SET_PERFSEL(line, cp_reg_memperfsel,perfsel) \ + FAST_GPFLAGSET(line, cp_reg_memperfsel,perfsel,CP_REG_MEMPERFSEL_PERFSEL) + +#define SC_CP_REG_FIFO_BASEL_SET_PAD0(line, cp_reg_fifo_basel,pad0) \ + FAST_GPFLAGSET(line, cp_reg_fifo_basel,pad0,CP_REG_FIFO_BASEL_PAD0) + +#define SC_CP_REG_FIFO_BASEL_SET_ADDR(line, cp_reg_fifo_basel,addr) \ + FAST_GPFLAGSET(line, cp_reg_fifo_basel,addr,CP_REG_FIFO_BASEL_ADDR) + +#define SC_CP_REG_FIFO_BASEH_SET_ADDR(line, cp_reg_fifo_baseh,addr) \ + FAST_GPFLAGSET(line, cp_reg_fifo_baseh,addr,CP_REG_FIFO_BASEH_ADDR) + +#define SC_CP_REG_FIFO_TOPL_SET_PAD0(line, cp_reg_fifo_topl,pad0) \ + FAST_GPFLAGSET(line, cp_reg_fifo_topl,pad0,CP_REG_FIFO_TOPL_PAD0) + +#define SC_CP_REG_FIFO_TOPL_SET_ADDR(line, cp_reg_fifo_topl,addr) \ + FAST_GPFLAGSET(line, cp_reg_fifo_topl,addr,CP_REG_FIFO_TOPL_ADDR) + +#define SC_CP_REG_FIFO_TOPH_SET_ADDR(line, cp_reg_fifo_toph,addr) \ + FAST_GPFLAGSET(line, cp_reg_fifo_toph,addr,CP_REG_FIFO_TOPH_ADDR) + +#define SC_CP_REG_FIFO_HICNTL_SET_PAD0(line, cp_reg_fifo_hicntl,pad0) \ + FAST_GPFLAGSET(line, cp_reg_fifo_hicntl,pad0,CP_REG_FIFO_HICNTL_PAD0) + +#define SC_CP_REG_FIFO_HICNTL_SET_ADDR(line, cp_reg_fifo_hicntl,addr) \ + FAST_GPFLAGSET(line, cp_reg_fifo_hicntl,addr,CP_REG_FIFO_HICNTL_ADDR) + +#define SC_CP_REG_FIFO_HICNTH_SET_ADDR(line, cp_reg_fifo_hicnth,addr) \ + FAST_GPFLAGSET(line, cp_reg_fifo_hicnth,addr,CP_REG_FIFO_HICNTH_ADDR) + +#define SC_CP_REG_FIFO_LOCNTL_SET_PAD0(line, cp_reg_fifo_locntl,pad0) \ + FAST_GPFLAGSET(line, cp_reg_fifo_locntl,pad0,CP_REG_FIFO_LOCNTL_PAD0) + +#define SC_CP_REG_FIFO_LOCNTL_SET_ADDR(line, cp_reg_fifo_locntl,addr) \ + FAST_GPFLAGSET(line, cp_reg_fifo_locntl,addr,CP_REG_FIFO_LOCNTL_ADDR) + +#define SC_CP_REG_FIFO_LOCNTH_SET_ADDR(line, cp_reg_fifo_locnth,addr) \ + FAST_GPFLAGSET(line, cp_reg_fifo_locnth,addr,CP_REG_FIFO_LOCNTH_ADDR) + +#define SC_CP_REG_FIFO_COUNTL_SET_PAD0(line, cp_reg_fifo_countl,pad0) \ + FAST_GPFLAGSET(line, cp_reg_fifo_countl,pad0,CP_REG_FIFO_COUNTL_PAD0) + +#define SC_CP_REG_FIFO_COUNTL_SET_ADDR(line, cp_reg_fifo_countl,addr) \ + FAST_GPFLAGSET(line, cp_reg_fifo_countl,addr,CP_REG_FIFO_COUNTL_ADDR) + +#define SC_CP_REG_FIFO_COUNTH_SET_ADDR(line, cp_reg_fifo_counth,addr) \ + FAST_GPFLAGSET(line, cp_reg_fifo_counth,addr,CP_REG_FIFO_COUNTH_ADDR) + +#define SC_CP_REG_FIFO_WPTRL_SET_PAD0(line, cp_reg_fifo_wptrl,pad0) \ + FAST_GPFLAGSET(line, cp_reg_fifo_wptrl,pad0,CP_REG_FIFO_WPTRL_PAD0) + +#define SC_CP_REG_FIFO_WPTRL_SET_ADDR(line, cp_reg_fifo_wptrl,addr) \ + FAST_GPFLAGSET(line, cp_reg_fifo_wptrl,addr,CP_REG_FIFO_WPTRL_ADDR) + +#define SC_CP_REG_FIFO_WPTRH_SET_ADDR(line, cp_reg_fifo_wptrh,addr) \ + FAST_GPFLAGSET(line, cp_reg_fifo_wptrh,addr,CP_REG_FIFO_WPTRH_ADDR) + +#define SC_CP_REG_FIFO_RPTRL_SET_PAD0(line, cp_reg_fifo_rptrl,pad0) \ + FAST_GPFLAGSET(line, cp_reg_fifo_rptrl,pad0,CP_REG_FIFO_RPTRL_PAD0) + +#define SC_CP_REG_FIFO_RPTRL_SET_ADDR(line, cp_reg_fifo_rptrl,addr) \ + FAST_GPFLAGSET(line, cp_reg_fifo_rptrl,addr,CP_REG_FIFO_RPTRL_ADDR) + +#define SC_CP_REG_FIFO_RPTRH_SET_ADDR(line, cp_reg_fifo_rptrh,addr) \ + FAST_GPFLAGSET(line, cp_reg_fifo_rptrh,addr,CP_REG_FIFO_RPTRH_ADDR) + +#define SC_CP_REG_FIFO_BRKL_SET_PAD0(line, cp_reg_fifo_brkl,pad0) \ + FAST_GPFLAGSET(line, cp_reg_fifo_brkl,pad0,CP_REG_FIFO_BRKL_PAD0) + +#define SC_CP_REG_FIFO_BRKL_SET_ADDR(line, cp_reg_fifo_brkl,addr) \ + FAST_GPFLAGSET(line, cp_reg_fifo_brkl,addr,CP_REG_FIFO_BRKL_ADDR) + +#define SC_CP_REG_FIFO_BRKH_SET_ADDR(line, cp_reg_fifo_brkh,addr) \ + FAST_GPFLAGSET(line, cp_reg_fifo_brkh,addr,CP_REG_FIFO_BRKH_ADDR) + +#define SC_CP_VCD_REG_LO_SET_PMIDX(line, cp_vcd_reg_lo,pmidx) \ + FAST_GPFLAGSET(line, cp_vcd_reg_lo,pmidx,CP_VCD_REG_LO_PMIDX) + +#define SC_CP_VCD_REG_LO_SET_T0MIDX(line, cp_vcd_reg_lo,t0midx) \ + FAST_GPFLAGSET(line, cp_vcd_reg_lo,t0midx,CP_VCD_REG_LO_T0MIDX) + +#define SC_CP_VCD_REG_LO_SET_T1MIDX(line, cp_vcd_reg_lo,t1midx) \ + FAST_GPFLAGSET(line, cp_vcd_reg_lo,t1midx,CP_VCD_REG_LO_T1MIDX) + +#define SC_CP_VCD_REG_LO_SET_T2MIDX(line, cp_vcd_reg_lo,t2midx) \ + FAST_GPFLAGSET(line, cp_vcd_reg_lo,t2midx,CP_VCD_REG_LO_T2MIDX) + +#define SC_CP_VCD_REG_LO_SET_T3MIDX(line, cp_vcd_reg_lo,t3midx) \ + FAST_GPFLAGSET(line, cp_vcd_reg_lo,t3midx,CP_VCD_REG_LO_T3MIDX) + +#define SC_CP_VCD_REG_LO_SET_T4MIDX(line, cp_vcd_reg_lo,t4midx) \ + FAST_GPFLAGSET(line, cp_vcd_reg_lo,t4midx,CP_VCD_REG_LO_T4MIDX) + +#define SC_CP_VCD_REG_LO_SET_T5MIDX(line, cp_vcd_reg_lo,t5midx) \ + FAST_GPFLAGSET(line, cp_vcd_reg_lo,t5midx,CP_VCD_REG_LO_T5MIDX) + +#define SC_CP_VCD_REG_LO_SET_T6MIDX(line, cp_vcd_reg_lo,t6midx) \ + FAST_GPFLAGSET(line, cp_vcd_reg_lo,t6midx,CP_VCD_REG_LO_T6MIDX) + +#define SC_CP_VCD_REG_LO_SET_T7MIDX(line, cp_vcd_reg_lo,t7midx) \ + FAST_GPFLAGSET(line, cp_vcd_reg_lo,t7midx,CP_VCD_REG_LO_T7MIDX) + +#define SC_CP_VCD_REG_LO_SET_POS(line, cp_vcd_reg_lo,pos) \ + FAST_GPFLAGSET(line, cp_vcd_reg_lo,pos,CP_VCD_REG_LO_POS) + +#define SC_CP_VCD_REG_LO_SET_NRM(line, cp_vcd_reg_lo,nrm) \ + FAST_GPFLAGSET(line, cp_vcd_reg_lo,nrm,CP_VCD_REG_LO_NRM) + +#define SC_CP_VCD_REG_LO_SET_COL0(line, cp_vcd_reg_lo,col0) \ + FAST_GPFLAGSET(line, cp_vcd_reg_lo,col0,CP_VCD_REG_LO_COL0) + +#define SC_CP_VCD_REG_LO_SET_COL1(line, cp_vcd_reg_lo,col1) \ + FAST_GPFLAGSET(line, cp_vcd_reg_lo,col1,CP_VCD_REG_LO_COL1) + +#define SC_CP_VCD_REG_HI_SET_TEX0(line, cp_vcd_reg_hi,tex0) \ + FAST_GPFLAGSET(line, cp_vcd_reg_hi,tex0,CP_VCD_REG_HI_TEX0) + +#define SC_CP_VCD_REG_HI_SET_TEX1(line, cp_vcd_reg_hi,tex1) \ + FAST_GPFLAGSET(line, cp_vcd_reg_hi,tex1,CP_VCD_REG_HI_TEX1) + +#define SC_CP_VCD_REG_HI_SET_TEX2(line, cp_vcd_reg_hi,tex2) \ + FAST_GPFLAGSET(line, cp_vcd_reg_hi,tex2,CP_VCD_REG_HI_TEX2) + +#define SC_CP_VCD_REG_HI_SET_TEX3(line, cp_vcd_reg_hi,tex3) \ + FAST_GPFLAGSET(line, cp_vcd_reg_hi,tex3,CP_VCD_REG_HI_TEX3) + +#define SC_CP_VCD_REG_HI_SET_TEX4(line, cp_vcd_reg_hi,tex4) \ + FAST_GPFLAGSET(line, cp_vcd_reg_hi,tex4,CP_VCD_REG_HI_TEX4) + +#define SC_CP_VCD_REG_HI_SET_TEX5(line, cp_vcd_reg_hi,tex5) \ + FAST_GPFLAGSET(line, cp_vcd_reg_hi,tex5,CP_VCD_REG_HI_TEX5) + +#define SC_CP_VCD_REG_HI_SET_TEX6(line, cp_vcd_reg_hi,tex6) \ + FAST_GPFLAGSET(line, cp_vcd_reg_hi,tex6,CP_VCD_REG_HI_TEX6) + +#define SC_CP_VCD_REG_HI_SET_TEX7(line, cp_vcd_reg_hi,tex7) \ + FAST_GPFLAGSET(line, cp_vcd_reg_hi,tex7,CP_VCD_REG_HI_TEX7) + +#define SC_CP_VAT_REG_A_SET_POSCNT(line, cp_vat_reg_a,posCnt) \ + FAST_GPFLAGSET(line, cp_vat_reg_a,posCnt,CP_VAT_REG_A_POSCNT) + +#define SC_CP_VAT_REG_A_SET_POSFMT(line, cp_vat_reg_a,posFmt) \ + FAST_GPFLAGSET(line, cp_vat_reg_a,posFmt,CP_VAT_REG_A_POSFMT) + +#define SC_CP_VAT_REG_A_SET_POSSHFT(line, cp_vat_reg_a,posShft) \ + FAST_GPFLAGSET(line, cp_vat_reg_a,posShft,CP_VAT_REG_A_POSSHFT) + +#define SC_CP_VAT_REG_A_SET_NRMCNT(line, cp_vat_reg_a,nrmCnt) \ + FAST_GPFLAGSET(line, cp_vat_reg_a,nrmCnt,CP_VAT_REG_A_NRMCNT) + +#define SC_CP_VAT_REG_A_SET_NRMFMT(line, cp_vat_reg_a,nrmFmt) \ + FAST_GPFLAGSET(line, cp_vat_reg_a,nrmFmt,CP_VAT_REG_A_NRMFMT) + +#define SC_CP_VAT_REG_A_SET_COL0CNT(line, cp_vat_reg_a,Col0Cnt) \ + FAST_GPFLAGSET(line, cp_vat_reg_a,Col0Cnt,CP_VAT_REG_A_COL0CNT) + +#define SC_CP_VAT_REG_A_SET_COL0FMT(line, cp_vat_reg_a,Col0Fmt) \ + FAST_GPFLAGSET(line, cp_vat_reg_a,Col0Fmt,CP_VAT_REG_A_COL0FMT) + +#define SC_CP_VAT_REG_A_SET_COL1CNT(line, cp_vat_reg_a,Col1Cnt) \ + FAST_GPFLAGSET(line, cp_vat_reg_a,Col1Cnt,CP_VAT_REG_A_COL1CNT) + +#define SC_CP_VAT_REG_A_SET_COL1FMT(line, cp_vat_reg_a,Col1Fmt) \ + FAST_GPFLAGSET(line, cp_vat_reg_a,Col1Fmt,CP_VAT_REG_A_COL1FMT) + +#define SC_CP_VAT_REG_A_SET_TEX0CNT(line, cp_vat_reg_a,tex0Cnt) \ + FAST_GPFLAGSET(line, cp_vat_reg_a,tex0Cnt,CP_VAT_REG_A_TEX0CNT) + +#define SC_CP_VAT_REG_A_SET_TEX0FMT(line, cp_vat_reg_a,tex0Fmt) \ + FAST_GPFLAGSET(line, cp_vat_reg_a,tex0Fmt,CP_VAT_REG_A_TEX0FMT) + +#define SC_CP_VAT_REG_A_SET_TEX0SHFT(line, cp_vat_reg_a,tex0Shft) \ + FAST_GPFLAGSET(line, cp_vat_reg_a,tex0Shft,CP_VAT_REG_A_TEX0SHFT) + +#define SC_CP_VAT_REG_A_SET_BYTEDEQUANT(line, cp_vat_reg_a,byteDequant) \ + FAST_GPFLAGSET(line, cp_vat_reg_a,byteDequant,CP_VAT_REG_A_BYTEDEQUANT) + +#define SC_CP_VAT_REG_A_SET_NORMALINDEX3(line, cp_vat_reg_a,normalIndex3) \ + FAST_GPFLAGSET(line, cp_vat_reg_a,normalIndex3,CP_VAT_REG_A_NORMALINDEX3) + +#define SC_CP_VAT_REG_B_SET_TEX1CNT(line, cp_vat_reg_b,tex1Cnt) \ + FAST_GPFLAGSET(line, cp_vat_reg_b,tex1Cnt,CP_VAT_REG_B_TEX1CNT) + +#define SC_CP_VAT_REG_B_SET_TEX1FMT(line, cp_vat_reg_b,tex1Fmt) \ + FAST_GPFLAGSET(line, cp_vat_reg_b,tex1Fmt,CP_VAT_REG_B_TEX1FMT) + +#define SC_CP_VAT_REG_B_SET_TEX1SHFT(line, cp_vat_reg_b,tex1Shft) \ + FAST_GPFLAGSET(line, cp_vat_reg_b,tex1Shft,CP_VAT_REG_B_TEX1SHFT) + +#define SC_CP_VAT_REG_B_SET_TEX2CNT(line, cp_vat_reg_b,tex2Cnt) \ + FAST_GPFLAGSET(line, cp_vat_reg_b,tex2Cnt,CP_VAT_REG_B_TEX2CNT) + +#define SC_CP_VAT_REG_B_SET_TEX2FMT(line, cp_vat_reg_b,tex2Fmt) \ + FAST_GPFLAGSET(line, cp_vat_reg_b,tex2Fmt,CP_VAT_REG_B_TEX2FMT) + +#define SC_CP_VAT_REG_B_SET_TEX2SHFT(line, cp_vat_reg_b,tex2Shft) \ + FAST_GPFLAGSET(line, cp_vat_reg_b,tex2Shft,CP_VAT_REG_B_TEX2SHFT) + +#define SC_CP_VAT_REG_B_SET_TEX3CNT(line, cp_vat_reg_b,tex3Cnt) \ + FAST_GPFLAGSET(line, cp_vat_reg_b,tex3Cnt,CP_VAT_REG_B_TEX3CNT) + +#define SC_CP_VAT_REG_B_SET_TEX3FMT(line, cp_vat_reg_b,tex3Fmt) \ + FAST_GPFLAGSET(line, cp_vat_reg_b,tex3Fmt,CP_VAT_REG_B_TEX3FMT) + +#define SC_CP_VAT_REG_B_SET_TEX3SHFT(line, cp_vat_reg_b,tex3Shft) \ + FAST_GPFLAGSET(line, cp_vat_reg_b,tex3Shft,CP_VAT_REG_B_TEX3SHFT) + +#define SC_CP_VAT_REG_B_SET_TEX4CNT(line, cp_vat_reg_b,tex4Cnt) \ + FAST_GPFLAGSET(line, cp_vat_reg_b,tex4Cnt,CP_VAT_REG_B_TEX4CNT) + +#define SC_CP_VAT_REG_B_SET_TEX4FMT(line, cp_vat_reg_b,tex4Fmt) \ + FAST_GPFLAGSET(line, cp_vat_reg_b,tex4Fmt,CP_VAT_REG_B_TEX4FMT) + +#define SC_CP_VAT_REG_B_SET_VCACHE_ENHANCE(line, cp_vat_reg_b,vcache_enhance) \ + FAST_GPFLAGSET(line, cp_vat_reg_b,vcache_enhance,CP_VAT_REG_B_VCACHE_ENHANCE) + +#define SC_CP_VAT_REG_C_SET_TEX4SHFT(line, cp_vat_reg_c,tex4Shft) \ + FAST_GPFLAGSET(line, cp_vat_reg_c,tex4Shft,CP_VAT_REG_C_TEX4SHFT) + +#define SC_CP_VAT_REG_C_SET_TEX5CNT(line, cp_vat_reg_c,tex5Cnt) \ + FAST_GPFLAGSET(line, cp_vat_reg_c,tex5Cnt,CP_VAT_REG_C_TEX5CNT) + +#define SC_CP_VAT_REG_C_SET_TEX5FMT(line, cp_vat_reg_c,tex5Fmt) \ + FAST_GPFLAGSET(line, cp_vat_reg_c,tex5Fmt,CP_VAT_REG_C_TEX5FMT) + +#define SC_CP_VAT_REG_C_SET_TEX5SHFT(line, cp_vat_reg_c,tex5Shft) \ + FAST_GPFLAGSET(line, cp_vat_reg_c,tex5Shft,CP_VAT_REG_C_TEX5SHFT) + +#define SC_CP_VAT_REG_C_SET_TEX6CNT(line, cp_vat_reg_c,tex6Cnt) \ + FAST_GPFLAGSET(line, cp_vat_reg_c,tex6Cnt,CP_VAT_REG_C_TEX6CNT) + +#define SC_CP_VAT_REG_C_SET_TEX6FMT(line, cp_vat_reg_c,tex6Fmt) \ + FAST_GPFLAGSET(line, cp_vat_reg_c,tex6Fmt,CP_VAT_REG_C_TEX6FMT) + +#define SC_CP_VAT_REG_C_SET_TEX6SHFT(line, cp_vat_reg_c,tex6Shft) \ + FAST_GPFLAGSET(line, cp_vat_reg_c,tex6Shft,CP_VAT_REG_C_TEX6SHFT) + +#define SC_CP_VAT_REG_C_SET_TEX7CNT(line, cp_vat_reg_c,tex7Cnt) \ + FAST_GPFLAGSET(line, cp_vat_reg_c,tex7Cnt,CP_VAT_REG_C_TEX7CNT) + +#define SC_CP_VAT_REG_C_SET_TEX7FMT(line, cp_vat_reg_c,tex7Fmt) \ + FAST_GPFLAGSET(line, cp_vat_reg_c,tex7Fmt,CP_VAT_REG_C_TEX7FMT) + +#define SC_CP_VAT_REG_C_SET_TEX7SHFT(line, cp_vat_reg_c,tex7Shft) \ + FAST_GPFLAGSET(line, cp_vat_reg_c,tex7Shft,CP_VAT_REG_C_TEX7SHFT) + +#define SC_CP_MATIDX_REG_A_SET_POSIDX(line, cp_matidx_reg_a,posIdx) \ + FAST_GPFLAGSET(line, cp_matidx_reg_a,posIdx,CP_MATIDX_REG_A_POSIDX) + +#define SC_CP_MATIDX_REG_A_SET_TEX0IDX(line, cp_matidx_reg_a,tex0Idx) \ + FAST_GPFLAGSET(line, cp_matidx_reg_a,tex0Idx,CP_MATIDX_REG_A_TEX0IDX) + +#define SC_CP_MATIDX_REG_A_SET_TEX1IDX(line, cp_matidx_reg_a,tex1Idx) \ + FAST_GPFLAGSET(line, cp_matidx_reg_a,tex1Idx,CP_MATIDX_REG_A_TEX1IDX) + +#define SC_CP_MATIDX_REG_A_SET_TEX2IDX(line, cp_matidx_reg_a,tex2Idx) \ + FAST_GPFLAGSET(line, cp_matidx_reg_a,tex2Idx,CP_MATIDX_REG_A_TEX2IDX) + +#define SC_CP_MATIDX_REG_A_SET_TEX3IDX(line, cp_matidx_reg_a,tex3Idx) \ + FAST_GPFLAGSET(line, cp_matidx_reg_a,tex3Idx,CP_MATIDX_REG_A_TEX3IDX) + +#define SC_CP_MATIDX_REG_B_SET_TEX4IDX(line, cp_matidx_reg_b,tex4Idx) \ + FAST_GPFLAGSET(line, cp_matidx_reg_b,tex4Idx,CP_MATIDX_REG_B_TEX4IDX) + +#define SC_CP_MATIDX_REG_B_SET_TEX5IDX(line, cp_matidx_reg_b,tex5Idx) \ + FAST_GPFLAGSET(line, cp_matidx_reg_b,tex5Idx,CP_MATIDX_REG_B_TEX5IDX) + +#define SC_CP_MATIDX_REG_B_SET_TEX6IDX(line, cp_matidx_reg_b,tex6Idx) \ + FAST_GPFLAGSET(line, cp_matidx_reg_b,tex6Idx,CP_MATIDX_REG_B_TEX6IDX) + +#define SC_CP_MATIDX_REG_B_SET_TEX7IDX(line, cp_matidx_reg_b,tex7Idx) \ + FAST_GPFLAGSET(line, cp_matidx_reg_b,tex7Idx,CP_MATIDX_REG_B_TEX7IDX) + +#define SC_CP_ARRAY_BASE_REG_SET_BASE(line, cp_array_base_reg,base) \ + FAST_GPFLAGSET(line, cp_array_base_reg,base,CP_ARRAY_BASE_REG_BASE) + +#define SC_CP_ARRAY_BASE_REG_SET_PAD0(line, cp_array_base_reg,pad0) \ + FAST_GPFLAGSET(line, cp_array_base_reg,pad0,CP_ARRAY_BASE_REG_PAD0) + +#define SC_CP_ARRAY_STRIDE_REG_SET_STRIDE(line, cp_array_stride_reg,stride) \ + FAST_GPFLAGSET(line, cp_array_stride_reg,stride,CP_ARRAY_STRIDE_REG_STRIDE) + +#define SC_CP_ARRAY_STRIDE_REG_SET_PAD0(line, cp_array_stride_reg,pad0) \ + FAST_GPFLAGSET(line, cp_array_stride_reg,pad0,CP_ARRAY_STRIDE_REG_PAD0) + +#define SC_CP_STAT_ENABLE_REG_SET_VC_STAT(line, cp_stat_enable_reg,vc_stat) \ + FAST_GPFLAGSET(line, cp_stat_enable_reg,vc_stat,CP_STAT_ENABLE_REG_VC_STAT) + +#define SC_CP_STAT_ENABLE_REG_SET_PAD0(line, cp_stat_enable_reg,pad0) \ + FAST_GPFLAGSET(line, cp_stat_enable_reg,pad0,CP_STAT_ENABLE_REG_PAD0) + +#define SC_CP_STAT_ENABLE_REG_SET_FRCLK(line, cp_stat_enable_reg,frclk) \ + FAST_GPFLAGSET(line, cp_stat_enable_reg,frclk,CP_STAT_ENABLE_REG_FRCLK) + +#define SC_CP_STAT_SEL_REG_SET_ATTR_SEL(line, cp_stat_sel_reg,attr_sel) \ + FAST_GPFLAGSET(line, cp_stat_sel_reg,attr_sel,CP_STAT_SEL_REG_ATTR_SEL) + +#define SC_CP_STAT_SEL_REG_SET_STALLPERF_SEL(line, cp_stat_sel_reg,stallperf_sel) \ + FAST_GPFLAGSET(line, cp_stat_sel_reg,stallperf_sel,CP_STAT_SEL_REG_STALLPERF_SEL) + +#define SC_CP_XF_LOADREGS_SET_ADDR(line, cp_xf_loadregs,addr) \ + FAST_GPFLAGSET(line, cp_xf_loadregs,addr,CP_XF_LOADREGS_ADDR) + +#define SC_CP_XF_LOADREGS_SET_CNT(line, cp_xf_loadregs,cnt) \ + FAST_GPFLAGSET(line, cp_xf_loadregs,cnt,CP_XF_LOADREGS_CNT) + +#define SC_CP_XF_LOADINDEX_SET_ADDR(line, cp_xf_loadindex,addr) \ + FAST_GPFLAGSET(line, cp_xf_loadindex,addr,CP_XF_LOADINDEX_ADDR) + +#define SC_CP_XF_LOADINDEX_SET_CNT(line, cp_xf_loadindex,cnt) \ + FAST_GPFLAGSET(line, cp_xf_loadindex,cnt,CP_XF_LOADINDEX_CNT) + +#define SC_CP_XF_LOADINDEX_SET_IDX(line, cp_xf_loadindex,idx) \ + FAST_GPFLAGSET(line, cp_xf_loadindex,idx,CP_XF_LOADINDEX_IDX) + +#define SC_CP_CALLOBJ_D1_SET_PAD0(line, cp_callobj_d1,pad0) \ + FAST_GPFLAGSET(line, cp_callobj_d1,pad0,CP_CALLOBJ_D1_PAD0) + +#define SC_CP_CALLOBJ_D1_SET_ADDR(line, cp_callobj_d1,addr) \ + FAST_GPFLAGSET(line, cp_callobj_d1,addr,CP_CALLOBJ_D1_ADDR) + +#define SC_CP_CALLOBJ_D2_SET_PAD0(line, cp_callobj_d2,pad0) \ + FAST_GPFLAGSET(line, cp_callobj_d2,pad0,CP_CALLOBJ_D2_PAD0) + +#define SC_CP_CALLOBJ_D2_SET_CNT(line, cp_callobj_d2,cnt) \ + FAST_GPFLAGSET(line, cp_callobj_d2,cnt,CP_CALLOBJ_D2_CNT) + +#endif /* __FDL_CP_REG_H__ */ diff --git a/include/revolution/private/gen_reg.h b/include/revolution/private/gen_reg.h new file mode 100644 index 0000000000..09aca016c0 --- /dev/null +++ b/include/revolution/private/gen_reg.h @@ -0,0 +1,163 @@ +#ifndef GEN_REG_H +#define GEN_REG_H + +#include + +#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 diff --git a/include/revolution/private/pe_reg.h b/include/revolution/private/pe_reg.h new file mode 100644 index 0000000000..837948a38c --- /dev/null +++ b/include/revolution/private/pe_reg.h @@ -0,0 +1,1160 @@ +#ifndef PE_REG_H +#define PE_REG_H + +#include + +#define PE_REFRESH_RID_SIZE 8 +#define PE_REFRESH_RID_SHIFT 24 +#define PE_REFRESH_RID_MASK 0xff000000 +#define PE_REFRESH_GET_RID(pe_refresh) \ + ((((unsigned long)(pe_refresh)) & PE_REFRESH_RID_MASK) >> PE_REFRESH_RID_SHIFT) + +#define PE_REFRESH_ENABLE_SIZE 1 +#define PE_REFRESH_ENABLE_SHIFT 9 +#define PE_REFRESH_ENABLE_MASK 0x00000200 +#define PE_REFRESH_GET_ENABLE(pe_refresh) \ + ((((unsigned long)(pe_refresh)) & PE_REFRESH_ENABLE_MASK) >> PE_REFRESH_ENABLE_SHIFT) + +#define PE_REFRESH_INTERVAL_SIZE 9 +#define PE_REFRESH_INTERVAL_SHIFT 0 +#define PE_REFRESH_INTERVAL_MASK 0x000001ff +#define PE_REFRESH_GET_INTERVAL(pe_refresh) \ + ((((unsigned long)(pe_refresh)) & PE_REFRESH_INTERVAL_MASK) >> PE_REFRESH_INTERVAL_SHIFT) + +#define PE_REFRESH_TOTAL_SIZE 32 +#define PE_REFRESH(interval, enable, rid) \ + ((((unsigned long)(interval)) << PE_REFRESH_INTERVAL_SHIFT) | \ + (((unsigned long)(enable)) << PE_REFRESH_ENABLE_SHIFT) | \ + (((unsigned long)(rid)) << PE_REFRESH_RID_SHIFT)) + +#define PE_CHICKEN_PIWR_SIZE 1 +#define PE_CHICKEN_PIWR_SHIFT 0 +#define PE_CHICKEN_PIWR_MASK 0x00000001 +#define PE_CHICKEN_GET_PIWR(pe_chicken) \ + ((((unsigned long)(pe_chicken)) & PE_CHICKEN_PIWR_MASK) >> PE_CHICKEN_PIWR_SHIFT) + +#define PE_CHICKEN_TXCPY_FMT_SIZE 1 +#define PE_CHICKEN_TXCPY_FMT_SHIFT 1 +#define PE_CHICKEN_TXCPY_FMT_MASK 0x00000002 +#define PE_CHICKEN_GET_TXCPY_FMT(pe_chicken) \ + ((((unsigned long)(pe_chicken)) & PE_CHICKEN_TXCPY_FMT_MASK) >> PE_CHICKEN_TXCPY_FMT_SHIFT) + +#define PE_CHICKEN_TXCPY_CCV_SIZE 1 +#define PE_CHICKEN_TXCPY_CCV_SHIFT 2 +#define PE_CHICKEN_TXCPY_CCV_MASK 0x00000004 +#define PE_CHICKEN_GET_TXCPY_CCV(pe_chicken) \ + ((((unsigned long)(pe_chicken)) & PE_CHICKEN_TXCPY_CCV_MASK) >> PE_CHICKEN_TXCPY_CCV_SHIFT) + +#define PE_CHICKEN_BLENDOP_SIZE 1 +#define PE_CHICKEN_BLENDOP_SHIFT 3 +#define PE_CHICKEN_BLENDOP_MASK 0x00000008 +#define PE_CHICKEN_GET_BLENDOP(pe_chicken) \ + ((((unsigned long)(pe_chicken)) & PE_CHICKEN_BLENDOP_MASK) >> PE_CHICKEN_BLENDOP_SHIFT) + +#define PE_CHICKEN_RID_SIZE 8 +#define PE_CHICKEN_RID_SHIFT 24 +#define PE_CHICKEN_RID_MASK 0xff000000 +#define PE_CHICKEN_GET_RID(pe_chicken) \ + ((((unsigned long)(pe_chicken)) & PE_CHICKEN_RID_MASK) >> PE_CHICKEN_RID_SHIFT) + +#define PE_CMODE0_RID_SIZE 8 +#define PE_CMODE0_RID_SHIFT 24 +#define PE_CMODE0_RID_MASK 0xff000000 +#define PE_CMODE0_GET_RID(pe_cmode0) \ + ((((unsigned long)(pe_cmode0)) & PE_CMODE0_RID_MASK) >> PE_CMODE0_RID_SHIFT) + +#define PE_CMODE1_RID_SIZE 8 +#define PE_CMODE1_RID_SHIFT 24 +#define PE_CMODE1_RID_MASK 0xff000000 +#define PE_CMODE1_GET_RID(pe_cmode1) \ + ((((unsigned long)(pe_cmode1)) & PE_CMODE1_RID_MASK) >> PE_CMODE1_RID_SHIFT) + +#define PE_ZMODE_RID_SIZE 8 +#define PE_ZMODE_RID_SHIFT 24 +#define PE_ZMODE_RID_MASK 0xff000000 +#define PE_ZMODE_GET_RID(pe_zmode) \ + ((((unsigned long)(pe_zmode)) & PE_ZMODE_RID_MASK) >> PE_ZMODE_RID_SHIFT) + +#define PE_CONTROL_RID_SIZE 8 +#define PE_CONTROL_RID_SHIFT 24 +#define PE_CONTROL_RID_MASK 0xff000000 +#define PE_CONTROL_GET_RID(pe_control) \ + ((((unsigned long)(pe_control)) & PE_CONTROL_RID_MASK) >> PE_CONTROL_RID_SHIFT) + +#define PE_COPY_CMD_GAMMA_SIZE 2 +#define PE_COPY_CMD_GAMMA_SHIFT 7 +#define PE_COPY_CMD_GAMMA_MASK 0x00000180 +#define PE_COPY_CMD_GET_GAMMA(pe_copy_cmd) \ + ((((unsigned long)(pe_copy_cmd)) & PE_COPY_CMD_GAMMA_MASK) >> PE_COPY_CMD_GAMMA_SHIFT) + +#define PE_TOKEN_TOKEN_SIZE 16 +#define PE_TOKEN_TOKEN_SHIFT 0 +#define PE_TOKEN_TOKEN_MASK 0x0000ffff +#define PE_TOKEN_GET_TOKEN(pe_token) \ + ((((unsigned long)(pe_token)) & PE_TOKEN_TOKEN_MASK) >> PE_TOKEN_TOKEN_SHIFT) +#define PE_TOKEN_SET_TOKEN(pe_token, token) { \ + FDL_ASSERT(!((token) & ~((1 << PE_TOKEN_TOKEN_SIZE)-1))); \ + pe_token = (((unsigned long)(pe_token)) & ~PE_TOKEN_TOKEN_MASK) | (((unsigned long)(token)) << PE_TOKEN_TOKEN_SHIFT);\ +} + +#define PE_TOKEN_RID_SIZE 8 +#define PE_TOKEN_RID_SHIFT 24 +#define PE_TOKEN_RID_MASK 0xff000000 +#define PE_TOKEN_GET_RID(pe_token) \ + ((((unsigned long)(pe_token)) & PE_TOKEN_RID_MASK) >> PE_TOKEN_RID_SHIFT) +#define PE_TOKEN_SET_RID(pe_token, rid) { \ + FDL_ASSERT(!((rid) & ~((1 << PE_TOKEN_RID_SIZE)-1))); \ + pe_token = (((unsigned long)(pe_token)) & ~PE_TOKEN_RID_MASK) | (((unsigned long)(rid)) << PE_TOKEN_RID_SHIFT);\ +} + +#define PE_TOKEN_INT_TOKEN_SIZE 16 +#define PE_TOKEN_INT_TOKEN_SHIFT 0 +#define PE_TOKEN_INT_TOKEN_MASK 0x0000ffff +#define PE_TOKEN_INT_GET_TOKEN(pe_token_int) \ + ((((unsigned long)(pe_token_int)) & PE_TOKEN_INT_TOKEN_MASK) >> PE_TOKEN_INT_TOKEN_SHIFT) +#define PE_TOKEN_INT_SET_TOKEN(pe_token_int, token) { \ + FDL_ASSERT(!((token) & ~((1 << PE_TOKEN_INT_TOKEN_SIZE)-1))); \ + pe_token_int = (((unsigned long)(pe_token_int)) & ~PE_TOKEN_INT_TOKEN_MASK) | (((unsigned long)(token)) << PE_TOKEN_INT_TOKEN_SHIFT);\ +} + +#define PE_TOKEN_INT_RID_SIZE 8 +#define PE_TOKEN_INT_RID_SHIFT 24 +#define PE_TOKEN_INT_RID_MASK 0xff000000 +#define PE_TOKEN_INT_GET_RID(pe_token_int) \ + ((((unsigned long)(pe_token_int)) & PE_TOKEN_INT_RID_MASK) >> PE_TOKEN_INT_RID_SHIFT) +#define PE_TOKEN_INT_SET_RID(pe_token_int, rid) { \ + FDL_ASSERT(!((rid) & ~((1 << PE_TOKEN_INT_RID_SIZE)-1))); \ + pe_token_int = (((unsigned long)(pe_token_int)) & ~PE_TOKEN_INT_RID_MASK) | (((unsigned long)(rid)) << PE_TOKEN_INT_RID_SHIFT);\ +} +#define PE_TOKEN_INT_TOTAL_SIZE 32 +#define PE_TOKEN_INT(token, rid) \ + ((((unsigned long)(token)) << PE_TOKEN_INT_TOKEN_SHIFT) | \ + (((unsigned long)(rid)) << PE_TOKEN_INT_RID_SHIFT)) + +#define PE_FINISH_DST_SIZE 2 +#define PE_FINISH_DST_SHIFT 0 +#define PE_FINISH_DST_MASK 0x00000003 +#define PE_FINISH_GET_DST(pe_finish) \ + ((((unsigned long)(pe_finish)) & PE_FINISH_DST_MASK) >> PE_FINISH_DST_SHIFT) +#define PE_FINISH_SET_DST(pe_finish, dst) { \ + FDL_ASSERT(!((dst) & ~((1 << PE_FINISH_DST_SIZE)-1))); \ + pe_finish = (((unsigned long)(pe_finish)) & ~PE_FINISH_DST_MASK) | (((unsigned long)(dst)) << PE_FINISH_DST_SHIFT);\ +} +#define PE_FINISH_PAD0_SIZE 22 +#define PE_FINISH_PAD0_SHIFT 2 +#define PE_FINISH_PAD0_MASK 0x00fffffc +#define PE_FINISH_GET_PAD0(pe_finish) \ + ((((unsigned long)(pe_finish)) & PE_FINISH_PAD0_MASK) >> PE_FINISH_PAD0_SHIFT) +#define PE_FINISH_SET_PAD0(pe_finish, pad0) { \ + FDL_ASSERT(!((pad0) & ~((1 << PE_FINISH_PAD0_SIZE)-1))); \ + pe_finish = (((unsigned long)(pe_finish)) & ~PE_FINISH_PAD0_MASK) | (((unsigned long)(pad0)) << PE_FINISH_PAD0_SHIFT);\ +} +#define PE_FINISH_RID_SIZE 8 +#define PE_FINISH_RID_SHIFT 24 +#define PE_FINISH_RID_MASK 0xff000000 +#define PE_FINISH_GET_RID(pe_finish) \ + ((((unsigned long)(pe_finish)) & PE_FINISH_RID_MASK) >> PE_FINISH_RID_SHIFT) +#define PE_FINISH_SET_RID(pe_finish, rid) { \ + FDL_ASSERT(!((rid) & ~((1 << PE_FINISH_RID_SIZE)-1))); \ + pe_finish = (((unsigned long)(pe_finish)) & ~PE_FINISH_RID_MASK) | (((unsigned long)(rid)) << PE_FINISH_RID_SHIFT);\ +} +#define PE_FINISH_TOTAL_SIZE 32 +#define PE_FINISH(dst, rid) \ + ((((unsigned long)(dst)) << PE_FINISH_DST_SHIFT) | \ + (((unsigned long)(rid)) << PE_FINISH_RID_SHIFT)) + +#define PE_PI_CTL_AFMT_SIZE 2 +#define PE_PI_CTL_AFMT_SHIFT 0 +#define PE_PI_CTL_AFMT_MASK 0x00000003 +#define PE_PI_CTL_GET_AFMT(pe_pi_ctl) \ + ((((unsigned long)(pe_pi_ctl)) & PE_PI_CTL_AFMT_MASK) >> PE_PI_CTL_AFMT_SHIFT) +#define PE_PI_CTL_SET_AFMT(pe_pi_ctl, afmt) { \ + FDL_ASSERT(!((afmt) & ~((1 << PE_PI_CTL_AFMT_SIZE)-1))); \ + pe_pi_ctl = (((unsigned long)(pe_pi_ctl)) & ~PE_PI_CTL_AFMT_MASK) | (((unsigned long)(afmt)) << PE_PI_CTL_AFMT_SHIFT);\ +} +#define PE_PI_CTL_ZFMT_SIZE 1 +#define PE_PI_CTL_ZFMT_SHIFT 2 +#define PE_PI_CTL_ZFMT_MASK 0x00000004 +#define PE_PI_CTL_GET_ZFMT(pe_pi_ctl) \ + ((((unsigned long)(pe_pi_ctl)) & PE_PI_CTL_ZFMT_MASK) >> PE_PI_CTL_ZFMT_SHIFT) +#define PE_PI_CTL_SET_ZFMT(pe_pi_ctl, zfmt) { \ + FDL_ASSERT(!((zfmt) & ~((1 << PE_PI_CTL_ZFMT_SIZE)-1))); \ + pe_pi_ctl = (((unsigned long)(pe_pi_ctl)) & ~PE_PI_CTL_ZFMT_MASK) | (((unsigned long)(zfmt)) << PE_PI_CTL_ZFMT_SHIFT);\ +} +#define PE_PI_CTL_PAD0_SIZE 21 +#define PE_PI_CTL_PAD0_SHIFT 3 +#define PE_PI_CTL_PAD0_MASK 0x00fffff8 +#define PE_PI_CTL_GET_PAD0(pe_pi_ctl) \ + ((((unsigned long)(pe_pi_ctl)) & PE_PI_CTL_PAD0_MASK) >> PE_PI_CTL_PAD0_SHIFT) +#define PE_PI_CTL_SET_PAD0(pe_pi_ctl, pad0) { \ + FDL_ASSERT(!((pad0) & ~((1 << PE_PI_CTL_PAD0_SIZE)-1))); \ + pe_pi_ctl = (((unsigned long)(pe_pi_ctl)) & ~PE_PI_CTL_PAD0_MASK) | (((unsigned long)(pad0)) << PE_PI_CTL_PAD0_SHIFT);\ +} +#define PE_PI_CTL_RID_SIZE 8 +#define PE_PI_CTL_RID_SHIFT 24 +#define PE_PI_CTL_RID_MASK 0xff000000 +#define PE_PI_CTL_GET_RID(pe_pi_ctl) \ + ((((unsigned long)(pe_pi_ctl)) & PE_PI_CTL_RID_MASK) >> PE_PI_CTL_RID_SHIFT) +#define PE_PI_CTL_SET_RID(pe_pi_ctl, rid) { \ + FDL_ASSERT(!((rid) & ~((1 << PE_PI_CTL_RID_SIZE)-1))); \ + pe_pi_ctl = (((unsigned long)(pe_pi_ctl)) & ~PE_PI_CTL_RID_MASK) | (((unsigned long)(rid)) << PE_PI_CTL_RID_SHIFT);\ +} +#define PE_PI_CTL_TOTAL_SIZE 32 +#define PE_PI_CTL(afmt, zfmt, rid) \ + ((((unsigned long)(afmt)) << PE_PI_CTL_AFMT_SHIFT) | \ + (((unsigned long)(zfmt)) << PE_PI_CTL_ZFMT_SHIFT) | \ + (((unsigned long)(rid)) << PE_PI_CTL_RID_SHIFT)) + +#define PE_CMODE0_BLEND_ENABLE_SIZE 1 +#define PE_CMODE0_BLEND_ENABLE_SHIFT 0 +#define PE_CMODE0_BLEND_ENABLE_MASK 0x00000001 +#define PE_CMODE0_GET_BLEND_ENABLE(pe_cmode0) \ + ((((unsigned long)(pe_cmode0)) & PE_CMODE0_BLEND_ENABLE_MASK) >> PE_CMODE0_BLEND_ENABLE_SHIFT) +#define PE_CMODE0_SET_BLEND_ENABLE(pe_cmode0, blend_enable) { \ + FDL_ASSERT(!((blend_enable) & ~((1 << PE_CMODE0_BLEND_ENABLE_SIZE)-1))); \ + pe_cmode0 = (((unsigned long)(pe_cmode0)) & ~PE_CMODE0_BLEND_ENABLE_MASK) | (((unsigned long)(blend_enable)) << PE_CMODE0_BLEND_ENABLE_SHIFT);\ +} +#define PE_CMODE0_LOGICOP_ENABLE_SIZE 1 +#define PE_CMODE0_LOGICOP_ENABLE_SHIFT 1 +#define PE_CMODE0_LOGICOP_ENABLE_MASK 0x00000002 +#define PE_CMODE0_GET_LOGICOP_ENABLE(pe_cmode0) \ + ((((unsigned long)(pe_cmode0)) & PE_CMODE0_LOGICOP_ENABLE_MASK) >> PE_CMODE0_LOGICOP_ENABLE_SHIFT) +#define PE_CMODE0_SET_LOGICOP_ENABLE(pe_cmode0, logicop_enable) { \ + FDL_ASSERT(!((logicop_enable) & ~((1 << PE_CMODE0_LOGICOP_ENABLE_SIZE)-1))); \ + pe_cmode0 = (((unsigned long)(pe_cmode0)) & ~PE_CMODE0_LOGICOP_ENABLE_MASK) | (((unsigned long)(logicop_enable)) << PE_CMODE0_LOGICOP_ENABLE_SHIFT);\ +} +#define PE_CMODE0_DITHER_ENABLE_SIZE 1 +#define PE_CMODE0_DITHER_ENABLE_SHIFT 2 +#define PE_CMODE0_DITHER_ENABLE_MASK 0x00000004 +#define PE_CMODE0_GET_DITHER_ENABLE(pe_cmode0) \ + ((((unsigned long)(pe_cmode0)) & PE_CMODE0_DITHER_ENABLE_MASK) >> PE_CMODE0_DITHER_ENABLE_SHIFT) +#define PE_CMODE0_SET_DITHER_ENABLE(pe_cmode0, dither_enable) { \ + FDL_ASSERT(!((dither_enable) & ~((1 << PE_CMODE0_DITHER_ENABLE_SIZE)-1))); \ + pe_cmode0 = (((unsigned long)(pe_cmode0)) & ~PE_CMODE0_DITHER_ENABLE_MASK) | (((unsigned long)(dither_enable)) << PE_CMODE0_DITHER_ENABLE_SHIFT);\ +} +#define PE_CMODE0_COLOR_MASK_SIZE 1 +#define PE_CMODE0_COLOR_MASK_SHIFT 3 +#define PE_CMODE0_COLOR_MASK_MASK 0x00000008 +#define PE_CMODE0_GET_COLOR_MASK(pe_cmode0) \ + ((((unsigned long)(pe_cmode0)) & PE_CMODE0_COLOR_MASK_MASK) >> PE_CMODE0_COLOR_MASK_SHIFT) +#define PE_CMODE0_SET_COLOR_MASK(pe_cmode0, color_mask) { \ + FDL_ASSERT(!((color_mask) & ~((1 << PE_CMODE0_COLOR_MASK_SIZE)-1))); \ + pe_cmode0 = (((unsigned long)(pe_cmode0)) & ~PE_CMODE0_COLOR_MASK_MASK) | (((unsigned long)(color_mask)) << PE_CMODE0_COLOR_MASK_SHIFT);\ +} +#define PE_CMODE0_ALPHA_MASK_SIZE 1 +#define PE_CMODE0_ALPHA_MASK_SHIFT 4 +#define PE_CMODE0_ALPHA_MASK_MASK 0x00000010 +#define PE_CMODE0_GET_ALPHA_MASK(pe_cmode0) \ + ((((unsigned long)(pe_cmode0)) & PE_CMODE0_ALPHA_MASK_MASK) >> PE_CMODE0_ALPHA_MASK_SHIFT) +#define PE_CMODE0_SET_ALPHA_MASK(pe_cmode0, alpha_mask) { \ + FDL_ASSERT(!((alpha_mask) & ~((1 << PE_CMODE0_ALPHA_MASK_SIZE)-1))); \ + pe_cmode0 = (((unsigned long)(pe_cmode0)) & ~PE_CMODE0_ALPHA_MASK_MASK) | (((unsigned long)(alpha_mask)) << PE_CMODE0_ALPHA_MASK_SHIFT);\ +} +#define PE_CMODE0_DFACTOR_SIZE 3 +#define PE_CMODE0_DFACTOR_SHIFT 5 +#define PE_CMODE0_DFACTOR_MASK 0x000000e0 +#define PE_CMODE0_GET_DFACTOR(pe_cmode0) \ + ((((unsigned long)(pe_cmode0)) & PE_CMODE0_DFACTOR_MASK) >> PE_CMODE0_DFACTOR_SHIFT) +#define PE_CMODE0_SET_DFACTOR(pe_cmode0, dfactor) { \ + FDL_ASSERT(!((dfactor) & ~((1 << PE_CMODE0_DFACTOR_SIZE)-1))); \ + pe_cmode0 = (((unsigned long)(pe_cmode0)) & ~PE_CMODE0_DFACTOR_MASK) | (((unsigned long)(dfactor)) << PE_CMODE0_DFACTOR_SHIFT);\ +} +#define PE_CMODE0_SFACTOR_SIZE 3 +#define PE_CMODE0_SFACTOR_SHIFT 8 +#define PE_CMODE0_SFACTOR_MASK 0x00000700 +#define PE_CMODE0_GET_SFACTOR(pe_cmode0) \ + ((((unsigned long)(pe_cmode0)) & PE_CMODE0_SFACTOR_MASK) >> PE_CMODE0_SFACTOR_SHIFT) +#define PE_CMODE0_SET_SFACTOR(pe_cmode0, sfactor) { \ + FDL_ASSERT(!((sfactor) & ~((1 << PE_CMODE0_SFACTOR_SIZE)-1))); \ + pe_cmode0 = (((unsigned long)(pe_cmode0)) & ~PE_CMODE0_SFACTOR_MASK) | (((unsigned long)(sfactor)) << PE_CMODE0_SFACTOR_SHIFT);\ +} +#define PE_CMODE0_BLENDOP_SIZE 1 +#define PE_CMODE0_BLENDOP_SHIFT 11 +#define PE_CMODE0_BLENDOP_MASK 0x00000800 +#define PE_CMODE0_GET_BLENDOP(pe_cmode0) \ + ((((unsigned long)(pe_cmode0)) & PE_CMODE0_BLENDOP_MASK) >> PE_CMODE0_BLENDOP_SHIFT) +#define PE_CMODE0_SET_BLENDOP(pe_cmode0, blendop) { \ + FDL_ASSERT(!((blendop) & ~((1 << PE_CMODE0_BLENDOP_SIZE)-1))); \ + pe_cmode0 = (((unsigned long)(pe_cmode0)) & ~PE_CMODE0_BLENDOP_MASK) | (((unsigned long)(blendop)) << PE_CMODE0_BLENDOP_SHIFT);\ +} +#define PE_CMODE0_LOGICOP_SIZE 4 +#define PE_CMODE0_LOGICOP_SHIFT 12 +#define PE_CMODE0_LOGICOP_MASK 0x0000f000 +#define PE_CMODE0_GET_LOGICOP(pe_cmode0) \ + ((((unsigned long)(pe_cmode0)) & PE_CMODE0_LOGICOP_MASK) >> PE_CMODE0_LOGICOP_SHIFT) +#define PE_CMODE0_SET_LOGICOP(pe_cmode0, logicop) { \ + FDL_ASSERT(!((logicop) & ~((1 << PE_CMODE0_LOGICOP_SIZE)-1))); \ + pe_cmode0 = (((unsigned long)(pe_cmode0)) & ~PE_CMODE0_LOGICOP_MASK) | (((unsigned long)(logicop)) << PE_CMODE0_LOGICOP_SHIFT);\ +} +#define PE_CMODE0_PAD0_SIZE 8 +#define PE_CMODE0_PAD0_SHIFT 16 +#define PE_CMODE0_PAD0_MASK 0x00ff0000 +#define PE_CMODE0_GET_PAD0(pe_cmode0) \ + ((((unsigned long)(pe_cmode0)) & PE_CMODE0_PAD0_MASK) >> PE_CMODE0_PAD0_SHIFT) +#define PE_CMODE0_SET_PAD0(pe_cmode0, pad0) { \ + FDL_ASSERT(!((pad0) & ~((1 << PE_CMODE0_PAD0_SIZE)-1))); \ + pe_cmode0 = (((unsigned long)(pe_cmode0)) & ~PE_CMODE0_PAD0_MASK) | (((unsigned long)(pad0)) << PE_CMODE0_PAD0_SHIFT);\ +} +#define PE_CMODE0_RID_SIZE 8 +#define PE_CMODE0_RID_SHIFT 24 +#define PE_CMODE0_RID_MASK 0xff000000 +#define PE_CMODE0_GET_RID(pe_cmode0) \ + ((((unsigned long)(pe_cmode0)) & PE_CMODE0_RID_MASK) >> PE_CMODE0_RID_SHIFT) +#define PE_CMODE0_SET_RID(pe_cmode0, rid) { \ + FDL_ASSERT(!((rid) & ~((1 << PE_CMODE0_RID_SIZE)-1))); \ + pe_cmode0 = (((unsigned long)(pe_cmode0)) & ~PE_CMODE0_RID_MASK) | (((unsigned long)(rid)) << PE_CMODE0_RID_SHIFT);\ +} +#define PE_CMODE0_TOTAL_SIZE 32 +#define PE_CMODE0(blend_enable, logicop_enable, dither_enable, color_mask, alpha_mask, dfactor, sfactor, blendop, logicop, rid) \ + ((((unsigned long)(blend_enable)) << PE_CMODE0_BLEND_ENABLE_SHIFT) | \ + (((unsigned long)(logicop_enable)) << PE_CMODE0_LOGICOP_ENABLE_SHIFT) | \ + (((unsigned long)(dither_enable)) << PE_CMODE0_DITHER_ENABLE_SHIFT) | \ + (((unsigned long)(color_mask)) << PE_CMODE0_COLOR_MASK_SHIFT) | \ + (((unsigned long)(alpha_mask)) << PE_CMODE0_ALPHA_MASK_SHIFT) | \ + (((unsigned long)(dfactor)) << PE_CMODE0_DFACTOR_SHIFT) | \ + (((unsigned long)(sfactor)) << PE_CMODE0_SFACTOR_SHIFT) | \ + (((unsigned long)(blendop)) << PE_CMODE0_BLENDOP_SHIFT) | \ + (((unsigned long)(logicop)) << PE_CMODE0_LOGICOP_SHIFT) | \ + (((unsigned long)(rid)) << PE_CMODE0_RID_SHIFT)) + +#define PE_CMODE1_CONSTANT_ALPHA_SIZE 8 +#define PE_CMODE1_CONSTANT_ALPHA_SHIFT 0 +#define PE_CMODE1_CONSTANT_ALPHA_MASK 0x000000ff +#define PE_CMODE1_GET_CONSTANT_ALPHA(pe_cmode1) \ + ((((unsigned long)(pe_cmode1)) & PE_CMODE1_CONSTANT_ALPHA_MASK) >> PE_CMODE1_CONSTANT_ALPHA_SHIFT) +#define PE_CMODE1_SET_CONSTANT_ALPHA(pe_cmode1, constant_alpha) { \ + FDL_ASSERT(!((constant_alpha) & ~((1 << PE_CMODE1_CONSTANT_ALPHA_SIZE)-1))); \ + pe_cmode1 = (((unsigned long)(pe_cmode1)) & ~PE_CMODE1_CONSTANT_ALPHA_MASK) | (((unsigned long)(constant_alpha)) << PE_CMODE1_CONSTANT_ALPHA_SHIFT);\ +} +#define PE_CMODE1_CONSTANT_ALPHA_ENABLE_SIZE 1 +#define PE_CMODE1_CONSTANT_ALPHA_ENABLE_SHIFT 8 +#define PE_CMODE1_CONSTANT_ALPHA_ENABLE_MASK 0x00000100 +#define PE_CMODE1_GET_CONSTANT_ALPHA_ENABLE(pe_cmode1) \ + ((((unsigned long)(pe_cmode1)) & PE_CMODE1_CONSTANT_ALPHA_ENABLE_MASK) >> PE_CMODE1_CONSTANT_ALPHA_ENABLE_SHIFT) +#define PE_CMODE1_SET_CONSTANT_ALPHA_ENABLE(pe_cmode1, constant_alpha_enable) { \ + FDL_ASSERT(!((constant_alpha_enable) & ~((1 << PE_CMODE1_CONSTANT_ALPHA_ENABLE_SIZE)-1))); \ + pe_cmode1 = (((unsigned long)(pe_cmode1)) & ~PE_CMODE1_CONSTANT_ALPHA_ENABLE_MASK) | (((unsigned long)(constant_alpha_enable)) << PE_CMODE1_CONSTANT_ALPHA_ENABLE_SHIFT);\ +} +#define PE_CMODE1_YUV_SIZE 2 +#define PE_CMODE1_YUV_SHIFT 9 +#define PE_CMODE1_YUV_MASK 0x00000600 +#define PE_CMODE1_GET_YUV(pe_cmode1) \ + ((((unsigned long)(pe_cmode1)) & PE_CMODE1_YUV_MASK) >> PE_CMODE1_YUV_SHIFT) +#define PE_CMODE1_SET_YUV(pe_cmode1, yuv) { \ + FDL_ASSERT(!((yuv) & ~((1 << PE_CMODE1_YUV_SIZE)-1))); \ + pe_cmode1 = (((unsigned long)(pe_cmode1)) & ~PE_CMODE1_YUV_MASK) | (((unsigned long)(yuv)) << PE_CMODE1_YUV_SHIFT);\ +} +#define PE_CMODE1_PAD0_SIZE 13 +#define PE_CMODE1_PAD0_SHIFT 11 +#define PE_CMODE1_PAD0_MASK 0x00fff800 +#define PE_CMODE1_GET_PAD0(pe_cmode1) \ + ((((unsigned long)(pe_cmode1)) & PE_CMODE1_PAD0_MASK) >> PE_CMODE1_PAD0_SHIFT) +#define PE_CMODE1_SET_PAD0(pe_cmode1, pad0) { \ + FDL_ASSERT(!((pad0) & ~((1 << PE_CMODE1_PAD0_SIZE)-1))); \ + pe_cmode1 = (((unsigned long)(pe_cmode1)) & ~PE_CMODE1_PAD0_MASK) | (((unsigned long)(pad0)) << PE_CMODE1_PAD0_SHIFT);\ +} +#define PE_CMODE1_RID_SIZE 8 +#define PE_CMODE1_RID_SHIFT 24 +#define PE_CMODE1_RID_MASK 0xff000000 +#define PE_CMODE1_GET_RID(pe_cmode1) \ + ((((unsigned long)(pe_cmode1)) & PE_CMODE1_RID_MASK) >> PE_CMODE1_RID_SHIFT) +#define PE_CMODE1_SET_RID(pe_cmode1, rid) { \ + FDL_ASSERT(!((rid) & ~((1 << PE_CMODE1_RID_SIZE)-1))); \ + pe_cmode1 = (((unsigned long)(pe_cmode1)) & ~PE_CMODE1_RID_MASK) | (((unsigned long)(rid)) << PE_CMODE1_RID_SHIFT);\ +} +#define PE_CMODE1_TOTAL_SIZE 32 +#define PE_CMODE1(constant_alpha, constant_alpha_enable, yuv, rid) \ + ((((unsigned long)(constant_alpha)) << PE_CMODE1_CONSTANT_ALPHA_SHIFT) | \ + (((unsigned long)(constant_alpha_enable)) << PE_CMODE1_CONSTANT_ALPHA_ENABLE_SHIFT) | \ + (((unsigned long)(yuv)) << PE_CMODE1_YUV_SHIFT) | \ + (((unsigned long)(rid)) << PE_CMODE1_RID_SHIFT)) + +#define PE_ZMODE_ENABLE_SIZE 1 +#define PE_ZMODE_ENABLE_SHIFT 0 +#define PE_ZMODE_ENABLE_MASK 0x00000001 +#define PE_ZMODE_GET_ENABLE(pe_zmode) \ + ((((unsigned long)(pe_zmode)) & PE_ZMODE_ENABLE_MASK) >> PE_ZMODE_ENABLE_SHIFT) +#define PE_ZMODE_SET_ENABLE(pe_zmode, enable) { \ + FDL_ASSERT(!((enable) & ~((1 << PE_ZMODE_ENABLE_SIZE)-1))); \ + pe_zmode = (((unsigned long)(pe_zmode)) & ~PE_ZMODE_ENABLE_MASK) | (((unsigned long)(enable)) << PE_ZMODE_ENABLE_SHIFT);\ +} +#define PE_ZMODE_FUNC_SIZE 3 +#define PE_ZMODE_FUNC_SHIFT 1 +#define PE_ZMODE_FUNC_MASK 0x0000000e +#define PE_ZMODE_GET_FUNC(pe_zmode) \ + ((((unsigned long)(pe_zmode)) & PE_ZMODE_FUNC_MASK) >> PE_ZMODE_FUNC_SHIFT) +#define PE_ZMODE_SET_FUNC(pe_zmode, func) { \ + FDL_ASSERT(!((func) & ~((1 << PE_ZMODE_FUNC_SIZE)-1))); \ + pe_zmode = (((unsigned long)(pe_zmode)) & ~PE_ZMODE_FUNC_MASK) | (((unsigned long)(func)) << PE_ZMODE_FUNC_SHIFT);\ +} +#define PE_ZMODE_MASK_SIZE 1 +#define PE_ZMODE_MASK_SHIFT 4 +#define PE_ZMODE_MASK_MASK 0x00000010 +#define PE_ZMODE_GET_MASK(pe_zmode) \ + ((((unsigned long)(pe_zmode)) & PE_ZMODE_MASK_MASK) >> PE_ZMODE_MASK_SHIFT) +#define PE_ZMODE_SET_MASK(pe_zmode, mask) { \ + FDL_ASSERT(!((mask) & ~((1 << PE_ZMODE_MASK_SIZE)-1))); \ + pe_zmode = (((unsigned long)(pe_zmode)) & ~PE_ZMODE_MASK_MASK) | (((unsigned long)(mask)) << PE_ZMODE_MASK_SHIFT);\ +} +#define PE_ZMODE_PAD0_SIZE 19 +#define PE_ZMODE_PAD0_SHIFT 5 +#define PE_ZMODE_PAD0_MASK 0x00ffffe0 +#define PE_ZMODE_GET_PAD0(pe_zmode) \ + ((((unsigned long)(pe_zmode)) & PE_ZMODE_PAD0_MASK) >> PE_ZMODE_PAD0_SHIFT) +#define PE_ZMODE_SET_PAD0(pe_zmode, pad0) { \ + FDL_ASSERT(!((pad0) & ~((1 << PE_ZMODE_PAD0_SIZE)-1))); \ + pe_zmode = (((unsigned long)(pe_zmode)) & ~PE_ZMODE_PAD0_MASK) | (((unsigned long)(pad0)) << PE_ZMODE_PAD0_SHIFT);\ +} +#define PE_ZMODE_RID_SIZE 8 +#define PE_ZMODE_RID_SHIFT 24 +#define PE_ZMODE_RID_MASK 0xff000000 +#define PE_ZMODE_GET_RID(pe_zmode) \ + ((((unsigned long)(pe_zmode)) & PE_ZMODE_RID_MASK) >> PE_ZMODE_RID_SHIFT) +#define PE_ZMODE_SET_RID(pe_zmode, rid) { \ + FDL_ASSERT(!((rid) & ~((1 << PE_ZMODE_RID_SIZE)-1))); \ + pe_zmode = (((unsigned long)(pe_zmode)) & ~PE_ZMODE_RID_MASK) | (((unsigned long)(rid)) << PE_ZMODE_RID_SHIFT);\ +} +#define PE_ZMODE_TOTAL_SIZE 32 +#define PE_ZMODE(enable, func, mask, rid) \ + ((((unsigned long)(enable)) << PE_ZMODE_ENABLE_SHIFT) | \ + (((unsigned long)(func)) << PE_ZMODE_FUNC_SHIFT) | \ + (((unsigned long)(mask)) << PE_ZMODE_MASK_SHIFT) | \ + (((unsigned long)(rid)) << PE_ZMODE_RID_SHIFT)) + +#define PE_PI_EFB_ADDR_PAD0_SIZE 2 +#define PE_PI_EFB_ADDR_PAD0_SHIFT 0 +#define PE_PI_EFB_ADDR_PAD0_MASK 0x00000003 +#define PE_PI_EFB_ADDR_GET_PAD0(pe_pi_efb_addr) \ + ((((unsigned long)(pe_pi_efb_addr)) & PE_PI_EFB_ADDR_PAD0_MASK) >> PE_PI_EFB_ADDR_PAD0_SHIFT) +#define PE_PI_EFB_ADDR_SET_PAD0(pe_pi_efb_addr, pad0) { \ + FDL_ASSERT(!((pad0) & ~((1 << PE_PI_EFB_ADDR_PAD0_SIZE)-1))); \ + pe_pi_efb_addr = (((unsigned long)(pe_pi_efb_addr)) & ~PE_PI_EFB_ADDR_PAD0_MASK) | (((unsigned long)(pad0)) << PE_PI_EFB_ADDR_PAD0_SHIFT);\ +} +#define PE_PI_EFB_ADDR_X_SIZE 10 +#define PE_PI_EFB_ADDR_X_SHIFT 2 +#define PE_PI_EFB_ADDR_X_MASK 0x00000ffc +#define PE_PI_EFB_ADDR_GET_X(pe_pi_efb_addr) \ + ((((unsigned long)(pe_pi_efb_addr)) & PE_PI_EFB_ADDR_X_MASK) >> PE_PI_EFB_ADDR_X_SHIFT) +#define PE_PI_EFB_ADDR_SET_X(pe_pi_efb_addr, x) { \ + FDL_ASSERT(!((x) & ~((1 << PE_PI_EFB_ADDR_X_SIZE)-1))); \ + pe_pi_efb_addr = (((unsigned long)(pe_pi_efb_addr)) & ~PE_PI_EFB_ADDR_X_MASK) | (((unsigned long)(x)) << PE_PI_EFB_ADDR_X_SHIFT);\ +} +#define PE_PI_EFB_ADDR_Y_SIZE 10 +#define PE_PI_EFB_ADDR_Y_SHIFT 12 +#define PE_PI_EFB_ADDR_Y_MASK 0x003ff000 +#define PE_PI_EFB_ADDR_GET_Y(pe_pi_efb_addr) \ + ((((unsigned long)(pe_pi_efb_addr)) & PE_PI_EFB_ADDR_Y_MASK) >> PE_PI_EFB_ADDR_Y_SHIFT) +#define PE_PI_EFB_ADDR_SET_Y(pe_pi_efb_addr, y) { \ + FDL_ASSERT(!((y) & ~((1 << PE_PI_EFB_ADDR_Y_SIZE)-1))); \ + pe_pi_efb_addr = (((unsigned long)(pe_pi_efb_addr)) & ~PE_PI_EFB_ADDR_Y_MASK) | (((unsigned long)(y)) << PE_PI_EFB_ADDR_Y_SHIFT);\ +} +#define PE_PI_EFB_ADDR_TYPE_SIZE 2 +#define PE_PI_EFB_ADDR_TYPE_SHIFT 22 +#define PE_PI_EFB_ADDR_TYPE_MASK 0x00c00000 +#define PE_PI_EFB_ADDR_GET_TYPE(pe_pi_efb_addr) \ + ((((unsigned long)(pe_pi_efb_addr)) & PE_PI_EFB_ADDR_TYPE_MASK) >> PE_PI_EFB_ADDR_TYPE_SHIFT) +#define PE_PI_EFB_ADDR_SET_TYPE(pe_pi_efb_addr, type) { \ + FDL_ASSERT(!((type) & ~((1 << PE_PI_EFB_ADDR_TYPE_SIZE)-1))); \ + pe_pi_efb_addr = (((unsigned long)(pe_pi_efb_addr)) & ~PE_PI_EFB_ADDR_TYPE_MASK) | (((unsigned long)(type)) << PE_PI_EFB_ADDR_TYPE_SHIFT);\ +} +#define PE_PI_EFB_ADDR_TOTAL_SIZE 24 +#define PE_PI_EFB_ADDR(x, y, type) \ + ((((unsigned long)(x)) << PE_PI_EFB_ADDR_X_SHIFT) | \ + (((unsigned long)(y)) << PE_PI_EFB_ADDR_Y_SHIFT) | \ + (((unsigned long)(type)) << PE_PI_EFB_ADDR_TYPE_SHIFT)) + +#define PE_INTRCTL_INT0EN_SIZE 1 +#define PE_INTRCTL_INT0EN_SHIFT 0 +#define PE_INTRCTL_INT0EN_MASK 0x00000001 +#define PE_INTRCTL_GET_INT0EN(pe_intrctl) \ + ((((unsigned long)(pe_intrctl)) & PE_INTRCTL_INT0EN_MASK) >> PE_INTRCTL_INT0EN_SHIFT) +#define PE_INTRCTL_SET_INT0EN(pe_intrctl, int0en) { \ + FDL_ASSERT(!((int0en) & ~((1 << PE_INTRCTL_INT0EN_SIZE)-1))); \ + pe_intrctl = (((unsigned long)(pe_intrctl)) & ~PE_INTRCTL_INT0EN_MASK) | (((unsigned long)(int0en)) << PE_INTRCTL_INT0EN_SHIFT);\ +} +#define PE_INTRCTL_INT1EN_SIZE 1 +#define PE_INTRCTL_INT1EN_SHIFT 1 +#define PE_INTRCTL_INT1EN_MASK 0x00000002 +#define PE_INTRCTL_GET_INT1EN(pe_intrctl) \ + ((((unsigned long)(pe_intrctl)) & PE_INTRCTL_INT1EN_MASK) >> PE_INTRCTL_INT1EN_SHIFT) +#define PE_INTRCTL_SET_INT1EN(pe_intrctl, int1en) { \ + FDL_ASSERT(!((int1en) & ~((1 << PE_INTRCTL_INT1EN_SIZE)-1))); \ + pe_intrctl = (((unsigned long)(pe_intrctl)) & ~PE_INTRCTL_INT1EN_MASK) | (((unsigned long)(int1en)) << PE_INTRCTL_INT1EN_SHIFT);\ +} +#define PE_INTRCTL_INT0CLR_SIZE 1 +#define PE_INTRCTL_INT0CLR_SHIFT 2 +#define PE_INTRCTL_INT0CLR_MASK 0x00000004 +#define PE_INTRCTL_GET_INT0CLR(pe_intrctl) \ + ((((unsigned long)(pe_intrctl)) & PE_INTRCTL_INT0CLR_MASK) >> PE_INTRCTL_INT0CLR_SHIFT) +#define PE_INTRCTL_SET_INT0CLR(pe_intrctl, int0clr) { \ + FDL_ASSERT(!((int0clr) & ~((1 << PE_INTRCTL_INT0CLR_SIZE)-1))); \ + pe_intrctl = (((unsigned long)(pe_intrctl)) & ~PE_INTRCTL_INT0CLR_MASK) | (((unsigned long)(int0clr)) << PE_INTRCTL_INT0CLR_SHIFT);\ +} +#define PE_INTRCTL_INT1CLR_SIZE 1 +#define PE_INTRCTL_INT1CLR_SHIFT 3 +#define PE_INTRCTL_INT1CLR_MASK 0x00000008 +#define PE_INTRCTL_GET_INT1CLR(pe_intrctl) \ + ((((unsigned long)(pe_intrctl)) & PE_INTRCTL_INT1CLR_MASK) >> PE_INTRCTL_INT1CLR_SHIFT) +#define PE_INTRCTL_SET_INT1CLR(pe_intrctl, int1clr) { \ + FDL_ASSERT(!((int1clr) & ~((1 << PE_INTRCTL_INT1CLR_SIZE)-1))); \ + pe_intrctl = (((unsigned long)(pe_intrctl)) & ~PE_INTRCTL_INT1CLR_MASK) | (((unsigned long)(int1clr)) << PE_INTRCTL_INT1CLR_SHIFT);\ +} +#define PE_INTRCTL_TOTAL_SIZE 4 +#define PE_INTRCTL(int0en, int1en, int0clr, int1clr) \ + ((((unsigned long)(int0en)) << PE_INTRCTL_INT0EN_SHIFT) | \ + (((unsigned long)(int1en)) << PE_INTRCTL_INT1EN_SHIFT) | \ + (((unsigned long)(int0clr)) << PE_INTRCTL_INT0CLR_SHIFT) | \ + (((unsigned long)(int1clr)) << PE_INTRCTL_INT1CLR_SHIFT)) + +#define SC_PE_ZMODE_SET_ENABLE(line, pe_zmode,enable) \ + FAST_GPFLAGSET(line, pe_zmode,enable,PE_ZMODE_ENABLE) + +#define SC_PE_ZMODE_SET_FUNC(line, pe_zmode,func) \ + FAST_GPFLAGSET(line, pe_zmode,func,PE_ZMODE_FUNC) + +#define SC_PE_ZMODE_SET_MASK(line, pe_zmode,mask) \ + FAST_GPFLAGSET(line, pe_zmode,mask,PE_ZMODE_MASK) + +#define SC_PE_ZMODE_SET_PAD0(line, pe_zmode,pad0) \ + FAST_GPFLAGSET(line, pe_zmode,pad0,PE_ZMODE_PAD0) + +#define SC_PE_ZMODE_SET_RID(line, pe_zmode,rid) \ + FAST_GPFLAGSET(line, pe_zmode,rid,PE_ZMODE_RID) + +#define SC_PE_CMODE0_SET_BLEND_ENABLE(line, pe_cmode0,blend_enable) \ + FAST_GPFLAGSET(line, pe_cmode0,blend_enable,PE_CMODE0_BLEND_ENABLE) + +#define SC_PE_CMODE0_SET_LOGICOP_ENABLE(line, pe_cmode0,logicop_enable) \ + FAST_GPFLAGSET(line, pe_cmode0,logicop_enable,PE_CMODE0_LOGICOP_ENABLE) + +#define SC_PE_CMODE0_SET_DITHER_ENABLE(line, pe_cmode0,dither_enable) \ + FAST_GPFLAGSET(line, pe_cmode0,dither_enable,PE_CMODE0_DITHER_ENABLE) + +#define SC_PE_CMODE0_SET_COLOR_MASK(line, pe_cmode0,color_mask) \ + FAST_GPFLAGSET(line, pe_cmode0,color_mask,PE_CMODE0_COLOR_MASK) + +#define SC_PE_CMODE0_SET_ALPHA_MASK(line, pe_cmode0,alpha_mask) \ + FAST_GPFLAGSET(line, pe_cmode0,alpha_mask,PE_CMODE0_ALPHA_MASK) + +#define SC_PE_CMODE0_SET_DFACTOR(line, pe_cmode0,dfactor) \ + FAST_GPFLAGSET(line, pe_cmode0,dfactor,PE_CMODE0_DFACTOR) + +#define SC_PE_CMODE0_SET_SFACTOR(line, pe_cmode0,sfactor) \ + FAST_GPFLAGSET(line, pe_cmode0,sfactor,PE_CMODE0_SFACTOR) + +#define SC_PE_CMODE0_SET_BLENDOP(line, pe_cmode0,blendop) \ + FAST_GPFLAGSET(line, pe_cmode0,blendop,PE_CMODE0_BLENDOP) + +#define SC_PE_CMODE0_SET_LOGICOP(line, pe_cmode0,logicop) \ + FAST_GPFLAGSET(line, pe_cmode0,logicop,PE_CMODE0_LOGICOP) + +#define SC_PE_CMODE0_SET_PAD0(line, pe_cmode0,pad0) \ + FAST_GPFLAGSET(line, pe_cmode0,pad0,PE_CMODE0_PAD0) + +#define SC_PE_CMODE0_SET_RID(line, pe_cmode0,rid) \ + FAST_GPFLAGSET(line, pe_cmode0,rid,PE_CMODE0_RID) + +#define SC_PE_CMODE1_SET_CONSTANT_ALPHA(line, pe_cmode1,constant_alpha) \ + FAST_GPFLAGSET(line, pe_cmode1,constant_alpha,PE_CMODE1_CONSTANT_ALPHA) + +#define SC_PE_CMODE1_SET_CONSTANT_ALPHA_ENABLE(line, pe_cmode1,constant_alpha_enable) \ + FAST_GPFLAGSET(line, pe_cmode1,constant_alpha_enable,PE_CMODE1_CONSTANT_ALPHA_ENABLE) + +#define SC_PE_CMODE1_SET_YUV(line, pe_cmode1,yuv) \ + FAST_GPFLAGSET(line, pe_cmode1,yuv,PE_CMODE1_YUV) + +#define SC_PE_CMODE1_SET_PAD0(line, pe_cmode1,pad0) \ + FAST_GPFLAGSET(line, pe_cmode1,pad0,PE_CMODE1_PAD0) + +#define SC_PE_CMODE1_SET_RID(line, pe_cmode1,rid) \ + FAST_GPFLAGSET(line, pe_cmode1,rid,PE_CMODE1_RID) + +#define SC_PE_CONTROL_SET_PIXTYPE(line, pe_control,pixtype) \ + FAST_GPFLAGSET(line, pe_control,pixtype,PE_CONTROL_PIXTYPE) + +#define SC_PE_CONTROL_SET_ZCMODE(line, pe_control,zcmode) \ + FAST_GPFLAGSET(line, pe_control,zcmode,PE_CONTROL_ZCMODE) + +#define SC_PE_CONTROL_SET_ZTOP(line, pe_control,ztop) \ + FAST_GPFLAGSET(line, pe_control,ztop,PE_CONTROL_ZTOP) + +#define SC_PE_CONTROL_SET_PAD0(line, pe_control,pad0) \ + FAST_GPFLAGSET(line, pe_control,pad0,PE_CONTROL_PAD0) + +#define SC_PE_CONTROL_SET_RID(line, pe_control,rid) \ + FAST_GPFLAGSET(line, pe_control,rid,PE_CONTROL_RID) + +#define SC_PE_FIELD_MASK_SET_EVEN(line, pe_field_mask,even) \ + FAST_GPFLAGSET(line, pe_field_mask,even,PE_FIELD_MASK_EVEN) + +#define SC_PE_FIELD_MASK_SET_ODD(line, pe_field_mask,odd) \ + FAST_GPFLAGSET(line, pe_field_mask,odd,PE_FIELD_MASK_ODD) + +#define SC_PE_FIELD_MASK_SET_PAD0(line, pe_field_mask,pad0) \ + FAST_GPFLAGSET(line, pe_field_mask,pad0,PE_FIELD_MASK_PAD0) + +#define SC_PE_FIELD_MASK_SET_RID(line, pe_field_mask,rid) \ + FAST_GPFLAGSET(line, pe_field_mask,rid,PE_FIELD_MASK_RID) + +#define SC_PE_FINISH_SET_DST(line, pe_finish,dst) \ + FAST_GPFLAGSET(line, pe_finish,dst,PE_FINISH_DST) + +#define SC_PE_FINISH_SET_PAD0(line, pe_finish,pad0) \ + FAST_GPFLAGSET(line, pe_finish,pad0,PE_FINISH_PAD0) + +#define SC_PE_FINISH_SET_RID(line, pe_finish,rid) \ + FAST_GPFLAGSET(line, pe_finish,rid,PE_FINISH_RID) + +#define SC_PE_REFRESH_SET_INTERVAL(line, pe_refresh,interval) \ + FAST_GPFLAGSET(line, pe_refresh,interval,PE_REFRESH_INTERVAL) + +#define SC_PE_REFRESH_SET_ENABLE(line, pe_refresh,enable) \ + FAST_GPFLAGSET(line, pe_refresh,enable,PE_REFRESH_ENABLE) + +#define SC_PE_REFRESH_SET_PAD0(line, pe_refresh,pad0) \ + FAST_GPFLAGSET(line, pe_refresh,pad0,PE_REFRESH_PAD0) + +#define SC_PE_REFRESH_SET_RID(line, pe_refresh,rid) \ + FAST_GPFLAGSET(line, pe_refresh,rid,PE_REFRESH_RID) + +#define SC_PE_TOKEN_SET_TOKEN(line, pe_token,token) \ + FAST_GPFLAGSET(line, pe_token,token,PE_TOKEN_TOKEN) + +#define SC_PE_TOKEN_SET_PAD0(line, pe_token,pad0) \ + FAST_GPFLAGSET(line, pe_token,pad0,PE_TOKEN_PAD0) + +#define SC_PE_TOKEN_SET_RID(line, pe_token,rid) \ + FAST_GPFLAGSET(line, pe_token,rid,PE_TOKEN_RID) + +#define SC_PE_TOKEN_INT_SET_TOKEN(line, pe_token_int,token) \ + FAST_GPFLAGSET(line, pe_token_int,token,PE_TOKEN_INT_TOKEN) + +#define SC_PE_TOKEN_INT_SET_PAD0(line, pe_token_int,pad0) \ + FAST_GPFLAGSET(line, pe_token_int,pad0,PE_TOKEN_INT_PAD0) + +#define SC_PE_TOKEN_INT_SET_RID(line, pe_token_int,rid) \ + FAST_GPFLAGSET(line, pe_token_int,rid,PE_TOKEN_INT_RID) + +#define SC_PE_COPY_SRC_ADDR_SET_X(line, pe_copy_src_addr,x) \ + FAST_GPFLAGSET(line, pe_copy_src_addr,x,PE_COPY_SRC_ADDR_X) + +#define SC_PE_COPY_SRC_ADDR_SET_Y(line, pe_copy_src_addr,y) \ + FAST_GPFLAGSET(line, pe_copy_src_addr,y,PE_COPY_SRC_ADDR_Y) + +#define SC_PE_COPY_SRC_ADDR_SET_PAD0(line, pe_copy_src_addr,pad0) \ + FAST_GPFLAGSET(line, pe_copy_src_addr,pad0,PE_COPY_SRC_ADDR_PAD0) + +#define SC_PE_COPY_SRC_ADDR_SET_RID(line, pe_copy_src_addr,rid) \ + FAST_GPFLAGSET(line, pe_copy_src_addr,rid,PE_COPY_SRC_ADDR_RID) + +#define SC_PE_COPY_SRC_SIZE_SET_X(line, pe_copy_src_size,x) \ + FAST_GPFLAGSET(line, pe_copy_src_size,x,PE_COPY_SRC_SIZE_X) + +#define SC_PE_COPY_SRC_SIZE_SET_Y(line, pe_copy_src_size,y) \ + FAST_GPFLAGSET(line, pe_copy_src_size,y,PE_COPY_SRC_SIZE_Y) + +#define SC_PE_COPY_SRC_SIZE_SET_PAD0(line, pe_copy_src_size,pad0) \ + FAST_GPFLAGSET(line, pe_copy_src_size,pad0,PE_COPY_SRC_SIZE_PAD0) + +#define SC_PE_COPY_SRC_SIZE_SET_RID(line, pe_copy_src_size,rid) \ + FAST_GPFLAGSET(line, pe_copy_src_size,rid,PE_COPY_SRC_SIZE_RID) + +#define SC_PE_COPY_DST_BASE_SET_BASE(line, pe_copy_dst_base,base) \ + FAST_GPFLAGSET(line, pe_copy_dst_base,base,PE_COPY_DST_BASE_BASE) + +#define SC_PE_COPY_DST_BASE_SET_PAD0(line, pe_copy_dst_base,pad0) \ + FAST_GPFLAGSET(line, pe_copy_dst_base,pad0,PE_COPY_DST_BASE_PAD0) + +#define SC_PE_COPY_DST_BASE_SET_RID(line, pe_copy_dst_base,rid) \ + FAST_GPFLAGSET(line, pe_copy_dst_base,rid,PE_COPY_DST_BASE_RID) + +#define SC_PE_COPY_DST_STRIDE_SET_STRIDE(line, pe_copy_dst_stride,stride) \ + FAST_GPFLAGSET(line, pe_copy_dst_stride,stride,PE_COPY_DST_STRIDE_STRIDE) + +#define SC_PE_COPY_DST_STRIDE_SET_PAD0(line, pe_copy_dst_stride,pad0) \ + FAST_GPFLAGSET(line, pe_copy_dst_stride,pad0,PE_COPY_DST_STRIDE_PAD0) + +#define SC_PE_COPY_DST_STRIDE_SET_RID(line, pe_copy_dst_stride,rid) \ + FAST_GPFLAGSET(line, pe_copy_dst_stride,rid,PE_COPY_DST_STRIDE_RID) + +#define SC_PE_COPY_SCALE_SET_SCALE(line, pe_copy_scale,scale) \ + FAST_GPFLAGSET(line, pe_copy_scale,scale,PE_COPY_SCALE_SCALE) + +#define SC_PE_COPY_SCALE_SET_PAD0(line, pe_copy_scale,pad0) \ + FAST_GPFLAGSET(line, pe_copy_scale,pad0,PE_COPY_SCALE_PAD0) + +#define SC_PE_COPY_SCALE_SET_RID(line, pe_copy_scale,rid) \ + FAST_GPFLAGSET(line, pe_copy_scale,rid,PE_COPY_SCALE_RID) + +#define SC_PE_COPY_CLEAR_COLOR_AR_SET_RED(line, pe_copy_clear_color_ar,red) \ + FAST_GPFLAGSET(line, pe_copy_clear_color_ar,red,PE_COPY_CLEAR_COLOR_AR_RED) + +#define SC_PE_COPY_CLEAR_COLOR_AR_SET_ALPHA(line, pe_copy_clear_color_ar,alpha) \ + FAST_GPFLAGSET(line, pe_copy_clear_color_ar,alpha,PE_COPY_CLEAR_COLOR_AR_ALPHA) + +#define SC_PE_COPY_CLEAR_COLOR_AR_SET_PAD0(line, pe_copy_clear_color_ar,pad0) \ + FAST_GPFLAGSET(line, pe_copy_clear_color_ar,pad0,PE_COPY_CLEAR_COLOR_AR_PAD0) + +#define SC_PE_COPY_CLEAR_COLOR_AR_SET_RID(line, pe_copy_clear_color_ar,rid) \ + FAST_GPFLAGSET(line, pe_copy_clear_color_ar,rid,PE_COPY_CLEAR_COLOR_AR_RID) + +#define SC_PE_COPY_CLEAR_COLOR_GB_SET_BLUE(line, pe_copy_clear_color_gb,blue) \ + FAST_GPFLAGSET(line, pe_copy_clear_color_gb,blue,PE_COPY_CLEAR_COLOR_GB_BLUE) + +#define SC_PE_COPY_CLEAR_COLOR_GB_SET_GREEN(line, pe_copy_clear_color_gb,green) \ + FAST_GPFLAGSET(line, pe_copy_clear_color_gb,green,PE_COPY_CLEAR_COLOR_GB_GREEN) + +#define SC_PE_COPY_CLEAR_COLOR_GB_SET_PAD0(line, pe_copy_clear_color_gb,pad0) \ + FAST_GPFLAGSET(line, pe_copy_clear_color_gb,pad0,PE_COPY_CLEAR_COLOR_GB_PAD0) + +#define SC_PE_COPY_CLEAR_COLOR_GB_SET_RID(line, pe_copy_clear_color_gb,rid) \ + FAST_GPFLAGSET(line, pe_copy_clear_color_gb,rid,PE_COPY_CLEAR_COLOR_GB_RID) + +#define SC_PE_COPY_CLEAR_Z_SET_DATA(line, pe_copy_clear_z,data) \ + FAST_GPFLAGSET(line, pe_copy_clear_z,data,PE_COPY_CLEAR_Z_DATA) + +#define SC_PE_COPY_CLEAR_Z_SET_RID(line, pe_copy_clear_z,rid) \ + FAST_GPFLAGSET(line, pe_copy_clear_z,rid,PE_COPY_CLEAR_Z_RID) + +#define SC_PE_COPY_CMD_SET_CLAMP_TOP(line, pe_copy_cmd,clamp_top) \ + FAST_GPFLAGSET(line, pe_copy_cmd,clamp_top,PE_COPY_CMD_CLAMP_TOP) + +#define SC_PE_COPY_CMD_SET_CLAMP_BOTTOM(line, pe_copy_cmd,clamp_bottom) \ + FAST_GPFLAGSET(line, pe_copy_cmd,clamp_bottom,PE_COPY_CMD_CLAMP_BOTTOM) + +#define SC_PE_COPY_CMD_SET_PAD0(line, pe_copy_cmd,pad0) \ + FAST_GPFLAGSET(line, pe_copy_cmd,pad0,PE_COPY_CMD_PAD0) + +#define SC_PE_COPY_CMD_SET_TEX_FORMATH(line, pe_copy_cmd,tex_formatH) \ + FAST_GPFLAGSET(line, pe_copy_cmd,tex_formatH,PE_COPY_CMD_TEX_FORMATH) + +#define SC_PE_COPY_CMD_SET_TEX_FORMAT(line, pe_copy_cmd,tex_format) \ + FAST_GPFLAGSET(line, pe_copy_cmd,tex_format,PE_COPY_CMD_TEX_FORMAT) + +#define SC_PE_COPY_CMD_SET_GAMMA(line, pe_copy_cmd,gamma) \ + FAST_GPFLAGSET(line, pe_copy_cmd,gamma,PE_COPY_CMD_GAMMA) + +#define SC_PE_COPY_CMD_SET_MIP_MAP_FILTER(line, pe_copy_cmd,mip_map_filter) \ + FAST_GPFLAGSET(line, pe_copy_cmd,mip_map_filter,PE_COPY_CMD_MIP_MAP_FILTER) + +#define SC_PE_COPY_CMD_SET_VERTICAL_SCALE(line, pe_copy_cmd,vertical_scale) \ + FAST_GPFLAGSET(line, pe_copy_cmd,vertical_scale,PE_COPY_CMD_VERTICAL_SCALE) + +#define SC_PE_COPY_CMD_SET_CLEAR(line, pe_copy_cmd,clear) \ + FAST_GPFLAGSET(line, pe_copy_cmd,clear,PE_COPY_CMD_CLEAR) + +#define SC_PE_COPY_CMD_SET_INTERLACED(line, pe_copy_cmd,interlaced) \ + FAST_GPFLAGSET(line, pe_copy_cmd,interlaced,PE_COPY_CMD_INTERLACED) + +#define SC_PE_COPY_CMD_SET_OPCODE(line, pe_copy_cmd,opcode) \ + FAST_GPFLAGSET(line, pe_copy_cmd,opcode,PE_COPY_CMD_OPCODE) + +#define SC_PE_COPY_CMD_SET_CCV(line, pe_copy_cmd,ccv) \ + FAST_GPFLAGSET(line, pe_copy_cmd,ccv,PE_COPY_CMD_CCV) + +#define SC_PE_COPY_CMD_SET_PAD1(line, pe_copy_cmd,pad1) \ + FAST_GPFLAGSET(line, pe_copy_cmd,pad1,PE_COPY_CMD_PAD1) + +#define SC_PE_COPY_CMD_SET_RID(line, pe_copy_cmd,rid) \ + FAST_GPFLAGSET(line, pe_copy_cmd,rid,PE_COPY_CMD_RID) + +#define SC_PE_COPY_VFILTER0_SET_COEFF0(line, pe_copy_vfilter0,coeff0) \ + FAST_GPFLAGSET(line, pe_copy_vfilter0,coeff0,PE_COPY_VFILTER0_COEFF0) + +#define SC_PE_COPY_VFILTER0_SET_COEFF1(line, pe_copy_vfilter0,coeff1) \ + FAST_GPFLAGSET(line, pe_copy_vfilter0,coeff1,PE_COPY_VFILTER0_COEFF1) + +#define SC_PE_COPY_VFILTER0_SET_COEFF2(line, pe_copy_vfilter0,coeff2) \ + FAST_GPFLAGSET(line, pe_copy_vfilter0,coeff2,PE_COPY_VFILTER0_COEFF2) + +#define SC_PE_COPY_VFILTER0_SET_COEFF3(line, pe_copy_vfilter0,coeff3) \ + FAST_GPFLAGSET(line, pe_copy_vfilter0,coeff3,PE_COPY_VFILTER0_COEFF3) + +#define SC_PE_COPY_VFILTER0_SET_RID(line, pe_copy_vfilter0,rid) \ + FAST_GPFLAGSET(line, pe_copy_vfilter0,rid,PE_COPY_VFILTER0_RID) + +#define SC_PE_COPY_VFILTER1_SET_COEFF4(line, pe_copy_vfilter1,coeff4) \ + FAST_GPFLAGSET(line, pe_copy_vfilter1,coeff4,PE_COPY_VFILTER1_COEFF4) + +#define SC_PE_COPY_VFILTER1_SET_COEFF5(line, pe_copy_vfilter1,coeff5) \ + FAST_GPFLAGSET(line, pe_copy_vfilter1,coeff5,PE_COPY_VFILTER1_COEFF5) + +#define SC_PE_COPY_VFILTER1_SET_COEFF6(line, pe_copy_vfilter1,coeff6) \ + FAST_GPFLAGSET(line, pe_copy_vfilter1,coeff6,PE_COPY_VFILTER1_COEFF6) + +#define SC_PE_COPY_VFILTER1_SET_PAD0(line, pe_copy_vfilter1,pad0) \ + FAST_GPFLAGSET(line, pe_copy_vfilter1,pad0,PE_COPY_VFILTER1_PAD0) + +#define SC_PE_COPY_VFILTER1_SET_RID(line, pe_copy_vfilter1,rid) \ + FAST_GPFLAGSET(line, pe_copy_vfilter1,rid,PE_COPY_VFILTER1_RID) + +#define SC_PE_XBOUND_SET_LEFT(line, pe_xbound,left) \ + FAST_GPFLAGSET(line, pe_xbound,left,PE_XBOUND_LEFT) + +#define SC_PE_XBOUND_SET_RIGHT(line, pe_xbound,right) \ + FAST_GPFLAGSET(line, pe_xbound,right,PE_XBOUND_RIGHT) + +#define SC_PE_XBOUND_SET_PAD0(line, pe_xbound,pad0) \ + FAST_GPFLAGSET(line, pe_xbound,pad0,PE_XBOUND_PAD0) + +#define SC_PE_XBOUND_SET_RID(line, pe_xbound,rid) \ + FAST_GPFLAGSET(line, pe_xbound,rid,PE_XBOUND_RID) + +#define SC_PE_YBOUND_SET_TOP(line, pe_ybound,top) \ + FAST_GPFLAGSET(line, pe_ybound,top,PE_YBOUND_TOP) + +#define SC_PE_YBOUND_SET_BOTTOM(line, pe_ybound,bottom) \ + FAST_GPFLAGSET(line, pe_ybound,bottom,PE_YBOUND_BOTTOM) + +#define SC_PE_YBOUND_SET_PAD0(line, pe_ybound,pad0) \ + FAST_GPFLAGSET(line, pe_ybound,pad0,PE_YBOUND_PAD0) + +#define SC_PE_YBOUND_SET_RID(line, pe_ybound,rid) \ + FAST_GPFLAGSET(line, pe_ybound,rid,PE_YBOUND_RID) + +#define SC_PE_PERFMODE_SET_CNTR0(line, pe_perfmode,cntr0) \ + FAST_GPFLAGSET(line, pe_perfmode,cntr0,PE_PERFMODE_CNTR0) + +#define SC_PE_PERFMODE_SET_CNTR1(line, pe_perfmode,cntr1) \ + FAST_GPFLAGSET(line, pe_perfmode,cntr1,PE_PERFMODE_CNTR1) + +#define SC_PE_PERFMODE_SET_CNTR2(line, pe_perfmode,cntr2) \ + FAST_GPFLAGSET(line, pe_perfmode,cntr2,PE_PERFMODE_CNTR2) + +#define SC_PE_PERFMODE_SET_CNTR3(line, pe_perfmode,cntr3) \ + FAST_GPFLAGSET(line, pe_perfmode,cntr3,PE_PERFMODE_CNTR3) + +#define SC_PE_PERFMODE_SET_CNTR4(line, pe_perfmode,cntr4) \ + FAST_GPFLAGSET(line, pe_perfmode,cntr4,PE_PERFMODE_CNTR4) + +#define SC_PE_PERFMODE_SET_CNTR5(line, pe_perfmode,cntr5) \ + FAST_GPFLAGSET(line, pe_perfmode,cntr5,PE_PERFMODE_CNTR5) + +#define SC_PE_PERFMODE_SET_PAD0(line, pe_perfmode,pad0) \ + FAST_GPFLAGSET(line, pe_perfmode,pad0,PE_PERFMODE_PAD0) + +#define SC_PE_PERFMODE_SET_RID(line, pe_perfmode,rid) \ + FAST_GPFLAGSET(line, pe_perfmode,rid,PE_PERFMODE_RID) + +#define SC_PE_CHICKEN_SET_PIWR(line, pe_chicken,piwr) \ + FAST_GPFLAGSET(line, pe_chicken,piwr,PE_CHICKEN_PIWR) + +#define SC_PE_CHICKEN_SET_TXCPY_FMT(line, pe_chicken,txcpy_fmt) \ + FAST_GPFLAGSET(line, pe_chicken,txcpy_fmt,PE_CHICKEN_TXCPY_FMT) + +#define SC_PE_CHICKEN_SET_TXCPY_CCV(line, pe_chicken,txcpy_ccv) \ + FAST_GPFLAGSET(line, pe_chicken,txcpy_ccv,PE_CHICKEN_TXCPY_CCV) + +#define SC_PE_CHICKEN_SET_BLENDOP(line, pe_chicken,blendop) \ + FAST_GPFLAGSET(line, pe_chicken,blendop,PE_CHICKEN_BLENDOP) + +#define SC_PE_CHICKEN_SET_PAD0(line, pe_chicken,pad0) \ + FAST_GPFLAGSET(line, pe_chicken,pad0,PE_CHICKEN_PAD0) + +#define SC_PE_CHICKEN_SET_RID(line, pe_chicken,rid) \ + FAST_GPFLAGSET(line, pe_chicken,rid,PE_CHICKEN_RID) + +#define SC_PE_QUAD_OFFSET_SET_X(line, pe_quad_offset,x) \ + FAST_GPFLAGSET(line, pe_quad_offset,x,PE_QUAD_OFFSET_X) + +#define SC_PE_QUAD_OFFSET_SET_Y(line, pe_quad_offset,y) \ + FAST_GPFLAGSET(line, pe_quad_offset,y,PE_QUAD_OFFSET_Y) + +#define SC_PE_QUAD_OFFSET_SET_PAD0(line, pe_quad_offset,pad0) \ + FAST_GPFLAGSET(line, pe_quad_offset,pad0,PE_QUAD_OFFSET_PAD0) + +#define SC_PE_QUAD_OFFSET_SET_RID(line, pe_quad_offset,rid) \ + FAST_GPFLAGSET(line, pe_quad_offset,rid,PE_QUAD_OFFSET_RID) + +#define SC_PE_COLOR_RGB8_SET_BLUE(line, pe_color_rgb8,blue) \ + FAST_GPFLAGSET(line, pe_color_rgb8,blue,PE_COLOR_RGB8_BLUE) + +#define SC_PE_COLOR_RGB8_SET_GREEN(line, pe_color_rgb8,green) \ + FAST_GPFLAGSET(line, pe_color_rgb8,green,PE_COLOR_RGB8_GREEN) + +#define SC_PE_COLOR_RGB8_SET_RED(line, pe_color_rgb8,red) \ + FAST_GPFLAGSET(line, pe_color_rgb8,red,PE_COLOR_RGB8_RED) + +#define SC_PE_COLOR_RGB8_SET_PAD0(line, pe_color_rgb8,pad0) \ + FAST_GPFLAGSET(line, pe_color_rgb8,pad0,PE_COLOR_RGB8_PAD0) + +#define SC_PE_COLOR_RGBA6_SET_ALPHA(line, pe_color_rgba6,alpha) \ + FAST_GPFLAGSET(line, pe_color_rgba6,alpha,PE_COLOR_RGBA6_ALPHA) + +#define SC_PE_COLOR_RGBA6_SET_BLUE(line, pe_color_rgba6,blue) \ + FAST_GPFLAGSET(line, pe_color_rgba6,blue,PE_COLOR_RGBA6_BLUE) + +#define SC_PE_COLOR_RGBA6_SET_GREEN(line, pe_color_rgba6,green) \ + FAST_GPFLAGSET(line, pe_color_rgba6,green,PE_COLOR_RGBA6_GREEN) + +#define SC_PE_COLOR_RGBA6_SET_RED(line, pe_color_rgba6,red) \ + FAST_GPFLAGSET(line, pe_color_rgba6,red,PE_COLOR_RGBA6_RED) + +#define SC_PE_COLOR_RGBA6_SET_PAD0(line, pe_color_rgba6,pad0) \ + FAST_GPFLAGSET(line, pe_color_rgba6,pad0,PE_COLOR_RGBA6_PAD0) + +#define SC_PE_COLOR_RGBAA_SET_BLUE(line, pe_color_rgbaa,blue) \ + FAST_GPFLAGSET(line, pe_color_rgbaa,blue,PE_COLOR_RGBAA_BLUE) + +#define SC_PE_COLOR_RGBAA_SET_GREEN(line, pe_color_rgbaa,green) \ + FAST_GPFLAGSET(line, pe_color_rgbaa,green,PE_COLOR_RGBAA_GREEN) + +#define SC_PE_COLOR_RGBAA_SET_RED(line, pe_color_rgbaa,red) \ + FAST_GPFLAGSET(line, pe_color_rgbaa,red,PE_COLOR_RGBAA_RED) + +#define SC_PE_TEX_COPY_I4_SET_I1(line, pe_tex_copy_i4,i1) \ + FAST_GPFLAGSET(line, pe_tex_copy_i4,i1,PE_TEX_COPY_I4_I1) + +#define SC_PE_TEX_COPY_I4_SET_I0(line, pe_tex_copy_i4,i0) \ + FAST_GPFLAGSET(line, pe_tex_copy_i4,i0,PE_TEX_COPY_I4_I0) + +#define SC_PE_TEX_COPY_IA4_SET_I(line, pe_tex_copy_ia4,i) \ + FAST_GPFLAGSET(line, pe_tex_copy_ia4,i,PE_TEX_COPY_IA4_I) + +#define SC_PE_TEX_COPY_IA4_SET_ALPHA(line, pe_tex_copy_ia4,alpha) \ + FAST_GPFLAGSET(line, pe_tex_copy_ia4,alpha,PE_TEX_COPY_IA4_ALPHA) + +#define SC_PE_TEX_COPY_IA8_SET_I(line, pe_tex_copy_ia8,i) \ + FAST_GPFLAGSET(line, pe_tex_copy_ia8,i,PE_TEX_COPY_IA8_I) + +#define SC_PE_TEX_COPY_IA8_SET_ALPHA(line, pe_tex_copy_ia8,alpha) \ + FAST_GPFLAGSET(line, pe_tex_copy_ia8,alpha,PE_TEX_COPY_IA8_ALPHA) + +#define SC_PE_TEX_COPY_R5G6B5_SET_BLUE(line, pe_tex_copy_r5g6b5,blue) \ + FAST_GPFLAGSET(line, pe_tex_copy_r5g6b5,blue,PE_TEX_COPY_R5G6B5_BLUE) + +#define SC_PE_TEX_COPY_R5G6B5_SET_GREEN(line, pe_tex_copy_r5g6b5,green) \ + FAST_GPFLAGSET(line, pe_tex_copy_r5g6b5,green,PE_TEX_COPY_R5G6B5_GREEN) + +#define SC_PE_TEX_COPY_R5G6B5_SET_RED(line, pe_tex_copy_r5g6b5,red) \ + FAST_GPFLAGSET(line, pe_tex_copy_r5g6b5,red,PE_TEX_COPY_R5G6B5_RED) + +#define SC_PE_TEX_COPY_RGB5_SET_BLUE(line, pe_tex_copy_rgb5,blue) \ + FAST_GPFLAGSET(line, pe_tex_copy_rgb5,blue,PE_TEX_COPY_RGB5_BLUE) + +#define SC_PE_TEX_COPY_RGB5_SET_GREEN(line, pe_tex_copy_rgb5,green) \ + FAST_GPFLAGSET(line, pe_tex_copy_rgb5,green,PE_TEX_COPY_RGB5_GREEN) + +#define SC_PE_TEX_COPY_RGB5_SET_RED(line, pe_tex_copy_rgb5,red) \ + FAST_GPFLAGSET(line, pe_tex_copy_rgb5,red,PE_TEX_COPY_RGB5_RED) + +#define SC_PE_TEX_COPY_RGB5_SET_FORMAT(line, pe_tex_copy_rgb5,format) \ + FAST_GPFLAGSET(line, pe_tex_copy_rgb5,format,PE_TEX_COPY_RGB5_FORMAT) + +#define SC_PE_TEX_COPY_RGB4A3_SET_BLUE(line, pe_tex_copy_rgb4a3,blue) \ + FAST_GPFLAGSET(line, pe_tex_copy_rgb4a3,blue,PE_TEX_COPY_RGB4A3_BLUE) + +#define SC_PE_TEX_COPY_RGB4A3_SET_GREEN(line, pe_tex_copy_rgb4a3,green) \ + FAST_GPFLAGSET(line, pe_tex_copy_rgb4a3,green,PE_TEX_COPY_RGB4A3_GREEN) + +#define SC_PE_TEX_COPY_RGB4A3_SET_RED(line, pe_tex_copy_rgb4a3,red) \ + FAST_GPFLAGSET(line, pe_tex_copy_rgb4a3,red,PE_TEX_COPY_RGB4A3_RED) + +#define SC_PE_TEX_COPY_RGB4A3_SET_ALPHA(line, pe_tex_copy_rgb4a3,alpha) \ + FAST_GPFLAGSET(line, pe_tex_copy_rgb4a3,alpha,PE_TEX_COPY_RGB4A3_ALPHA) + +#define SC_PE_TEX_COPY_RGB4A3_SET_FORMAT(line, pe_tex_copy_rgb4a3,format) \ + FAST_GPFLAGSET(line, pe_tex_copy_rgb4a3,format,PE_TEX_COPY_RGB4A3_FORMAT) + +#define SC_PE_TEX_COPY_RGBA8_SET_RED(line, pe_tex_copy_rgba8,red) \ + FAST_GPFLAGSET(line, pe_tex_copy_rgba8,red,PE_TEX_COPY_RGBA8_RED) + +#define SC_PE_TEX_COPY_RGBA8_SET_ALPHA(line, pe_tex_copy_rgba8,alpha) \ + FAST_GPFLAGSET(line, pe_tex_copy_rgba8,alpha,PE_TEX_COPY_RGBA8_ALPHA) + +#define SC_PE_TEX_COPY_RGBA8_SET_BLUE(line, pe_tex_copy_rgba8,blue) \ + FAST_GPFLAGSET(line, pe_tex_copy_rgba8,blue,PE_TEX_COPY_RGBA8_BLUE) + +#define SC_PE_TEX_COPY_RGBA8_SET_GREEN(line, pe_tex_copy_rgba8,green) \ + FAST_GPFLAGSET(line, pe_tex_copy_rgba8,green,PE_TEX_COPY_RGBA8_GREEN) + +#define SC_PE_MASK_SET_M0(line, pe_mask,m0) \ + FAST_GPFLAGSET(line, pe_mask,m0,PE_MASK_M0) + +#define SC_PE_MASK_SET_M1(line, pe_mask,m1) \ + FAST_GPFLAGSET(line, pe_mask,m1,PE_MASK_M1) + +#define SC_PE_MASK_SET_M2(line, pe_mask,m2) \ + FAST_GPFLAGSET(line, pe_mask,m2,PE_MASK_M2) + +#define SC_PE_MASK_SET_M3(line, pe_mask,m3) \ + FAST_GPFLAGSET(line, pe_mask,m3,PE_MASK_M3) + +#define SC_PE_MISC_SET_V0(line, pe_misc,v0) \ + FAST_GPFLAGSET(line, pe_misc,v0,PE_MISC_V0) + +#define SC_PE_MISC_SET_V1(line, pe_misc,v1) \ + FAST_GPFLAGSET(line, pe_misc,v1,PE_MISC_V1) + +#define SC_PE_MISC_SET_V2(line, pe_misc,v2) \ + FAST_GPFLAGSET(line, pe_misc,v2,PE_MISC_V2) + +#define SC_PE_MISC_SET_V3(line, pe_misc,v3) \ + FAST_GPFLAGSET(line, pe_misc,v3,PE_MISC_V3) + +#define SC_PE_MISC_SET_ST(line, pe_misc,st) \ + FAST_GPFLAGSET(line, pe_misc,st,PE_MISC_ST) + +#define SC_PE_MISC_SET_SB(line, pe_misc,sb) \ + FAST_GPFLAGSET(line, pe_misc,sb,PE_MISC_SB) + +#define SC_PE_MISC_SET_SL(line, pe_misc,sl) \ + FAST_GPFLAGSET(line, pe_misc,sl,PE_MISC_SL) + +#define SC_PE_MISC_SET_SR(line, pe_misc,sr) \ + FAST_GPFLAGSET(line, pe_misc,sr,PE_MISC_SR) + +#define SC_PE_MISC_SET_TT(line, pe_misc,tt) \ + FAST_GPFLAGSET(line, pe_misc,tt,PE_MISC_TT) + +#define SC_PE_MISC_SET_TB(line, pe_misc,tb) \ + FAST_GPFLAGSET(line, pe_misc,tb,PE_MISC_TB) + +#define SC_PE_MISC_SET_TL(line, pe_misc,tl) \ + FAST_GPFLAGSET(line, pe_misc,tl,PE_MISC_TL) + +#define SC_PE_MISC_SET_TR(line, pe_misc,tr) \ + FAST_GPFLAGSET(line, pe_misc,tr,PE_MISC_TR) + +#define SC_PE_MISC_SET_TM(line, pe_misc,tm) \ + FAST_GPFLAGSET(line, pe_misc,tm,PE_MISC_TM) + +#define SC_PE_MISC_SET_TP(line, pe_misc,tp) \ + FAST_GPFLAGSET(line, pe_misc,tp,PE_MISC_TP) + +#define SC_PE_MISC_SET_SV(line, pe_misc,sv) \ + FAST_GPFLAGSET(line, pe_misc,sv,PE_MISC_SV) + +#define SC_PE_TAG_SET_CYCLE(line, pe_tag,cycle) \ + FAST_GPFLAGSET(line, pe_tag,cycle,PE_TAG_CYCLE) + +#define SC_PE_TAG_SET_YEC(line, pe_tag,yec) \ + FAST_GPFLAGSET(line, pe_tag,yec,PE_TAG_YEC) + +#define SC_PE_TAG_SET_YOC(line, pe_tag,yoc) \ + FAST_GPFLAGSET(line, pe_tag,yoc,PE_TAG_YOC) + +#define SC_PE_TAG_SET_XOC(line, pe_tag,xoc) \ + FAST_GPFLAGSET(line, pe_tag,xoc,PE_TAG_XOC) + +#define SC_PE_TAG_SET_CLR(line, pe_tag,clr) \ + FAST_GPFLAGSET(line, pe_tag,clr,PE_TAG_CLR) + +#define SC_PE_CMD_SET_VALID(line, pe_cmd,valid) \ + FAST_GPFLAGSET(line, pe_cmd,valid,PE_CMD_VALID) + +#define SC_PE_CMD_SET_OP(line, pe_cmd,op) \ + FAST_GPFLAGSET(line, pe_cmd,op,PE_CMD_OP) + +#define SC_PE_CMD_SET_BANKA(line, pe_cmd,bankA) \ + FAST_GPFLAGSET(line, pe_cmd,bankA,PE_CMD_BANKA) + +#define SC_PE_CMD_SET_BANKB(line, pe_cmd,bankB) \ + FAST_GPFLAGSET(line, pe_cmd,bankB,PE_CMD_BANKB) + +#define SC_PE_INTRCTL_SET_INT0EN(line, pe_intrctl,int0en) \ + FAST_GPFLAGSET(line, pe_intrctl,int0en,PE_INTRCTL_INT0EN) + +#define SC_PE_INTRCTL_SET_INT1EN(line, pe_intrctl,int1en) \ + FAST_GPFLAGSET(line, pe_intrctl,int1en,PE_INTRCTL_INT1EN) + +#define SC_PE_INTRCTL_SET_INT0CLR(line, pe_intrctl,int0clr) \ + FAST_GPFLAGSET(line, pe_intrctl,int0clr,PE_INTRCTL_INT0CLR) + +#define SC_PE_INTRCTL_SET_INT1CLR(line, pe_intrctl,int1clr) \ + FAST_GPFLAGSET(line, pe_intrctl,int1clr,PE_INTRCTL_INT1CLR) + +#define SC_PE_PI_EFB_ADDR_SET_PAD0(line, pe_pi_efb_addr,pad0) \ + FAST_GPFLAGSET(line, pe_pi_efb_addr,pad0,PE_PI_EFB_ADDR_PAD0) + +#define SC_PE_PI_EFB_ADDR_SET_X(line, pe_pi_efb_addr,x) \ + FAST_GPFLAGSET(line, pe_pi_efb_addr,x,PE_PI_EFB_ADDR_X) + +#define SC_PE_PI_EFB_ADDR_SET_Y(line, pe_pi_efb_addr,y) \ + FAST_GPFLAGSET(line, pe_pi_efb_addr,y,PE_PI_EFB_ADDR_Y) + +#define SC_PE_PI_EFB_ADDR_SET_TYPE(line, pe_pi_efb_addr,type) \ + FAST_GPFLAGSET(line, pe_pi_efb_addr,type,PE_PI_EFB_ADDR_TYPE) + +#define SC_PE_PI_ZMODE_SET_ZEN(line, pe_pi_zmode,zen) \ + FAST_GPFLAGSET(line, pe_pi_zmode,zen,PE_PI_ZMODE_ZEN) + +#define SC_PE_PI_ZMODE_SET_ZFUNC(line, pe_pi_zmode,zfunc) \ + FAST_GPFLAGSET(line, pe_pi_zmode,zfunc,PE_PI_ZMODE_ZFUNC) + +#define SC_PE_PI_ZMODE_SET_MASK(line, pe_pi_zmode,mask) \ + FAST_GPFLAGSET(line, pe_pi_zmode,mask,PE_PI_ZMODE_MASK) + +#define SC_PE_PI_ZMODE_SET_PAD0(line, pe_pi_zmode,pad0) \ + FAST_GPFLAGSET(line, pe_pi_zmode,pad0,PE_PI_ZMODE_PAD0) + +#define SC_PE_PI_ZMODE_SET_RID(line, pe_pi_zmode,rid) \ + FAST_GPFLAGSET(line, pe_pi_zmode,rid,PE_PI_ZMODE_RID) + +#define SC_PE_PI_CMODE0_SET_BEN(line, pe_pi_cmode0,ben) \ + FAST_GPFLAGSET(line, pe_pi_cmode0,ben,PE_PI_CMODE0_BEN) + +#define SC_PE_PI_CMODE0_SET_LEN(line, pe_pi_cmode0,len) \ + FAST_GPFLAGSET(line, pe_pi_cmode0,len,PE_PI_CMODE0_LEN) + +#define SC_PE_PI_CMODE0_SET_DEN(line, pe_pi_cmode0,den) \ + FAST_GPFLAGSET(line, pe_pi_cmode0,den,PE_PI_CMODE0_DEN) + +#define SC_PE_PI_CMODE0_SET_CMSK(line, pe_pi_cmode0,cmsk) \ + FAST_GPFLAGSET(line, pe_pi_cmode0,cmsk,PE_PI_CMODE0_CMSK) + +#define SC_PE_PI_CMODE0_SET_AMSK(line, pe_pi_cmode0,amsk) \ + FAST_GPFLAGSET(line, pe_pi_cmode0,amsk,PE_PI_CMODE0_AMSK) + +#define SC_PE_PI_CMODE0_SET_DFACTOR(line, pe_pi_cmode0,dfactor) \ + FAST_GPFLAGSET(line, pe_pi_cmode0,dfactor,PE_PI_CMODE0_DFACTOR) + +#define SC_PE_PI_CMODE0_SET_SFACTOR(line, pe_pi_cmode0,sfactor) \ + FAST_GPFLAGSET(line, pe_pi_cmode0,sfactor,PE_PI_CMODE0_SFACTOR) + +#define SC_PE_PI_CMODE0_SET_LOGICOP(line, pe_pi_cmode0,logicop) \ + FAST_GPFLAGSET(line, pe_pi_cmode0,logicop,PE_PI_CMODE0_LOGICOP) + +#define SC_PE_PI_CMODE0_SET_PAD0(line, pe_pi_cmode0,pad0) \ + FAST_GPFLAGSET(line, pe_pi_cmode0,pad0,PE_PI_CMODE0_PAD0) + +#define SC_PE_PI_CMODE0_SET_RID(line, pe_pi_cmode0,rid) \ + FAST_GPFLAGSET(line, pe_pi_cmode0,rid,PE_PI_CMODE0_RID) + +#define SC_PE_PI_CMODE1_SET_CONSTALPHA(line, pe_pi_cmode1,constAlpha) \ + FAST_GPFLAGSET(line, pe_pi_cmode1,constAlpha,PE_PI_CMODE1_CONSTALPHA) + +#define SC_PE_PI_CMODE1_SET_EN(line, pe_pi_cmode1,en) \ + FAST_GPFLAGSET(line, pe_pi_cmode1,en,PE_PI_CMODE1_EN) + +#define SC_PE_PI_CMODE1_SET_PAD0(line, pe_pi_cmode1,pad0) \ + FAST_GPFLAGSET(line, pe_pi_cmode1,pad0,PE_PI_CMODE1_PAD0) + +#define SC_PE_PI_CMODE1_SET_RID(line, pe_pi_cmode1,rid) \ + FAST_GPFLAGSET(line, pe_pi_cmode1,rid,PE_PI_CMODE1_RID) + +#define SC_PE_PI_ALPHA_THRESHOLD_SET_ALPHA_THRESHOLD(line, pe_pi_alpha_threshold,alpha_threshold) \ + FAST_GPFLAGSET(line, pe_pi_alpha_threshold,alpha_threshold,PE_PI_ALPHA_THRESHOLD_ALPHA_THRESHOLD) + +#define SC_PE_PI_ALPHA_THRESHOLD_SET_AFUNCTION(line, pe_pi_alpha_threshold,afunction) \ + FAST_GPFLAGSET(line, pe_pi_alpha_threshold,afunction,PE_PI_ALPHA_THRESHOLD_AFUNCTION) + +#define SC_PE_PI_ALPHA_THRESHOLD_SET_PAD0(line, pe_pi_alpha_threshold,pad0) \ + FAST_GPFLAGSET(line, pe_pi_alpha_threshold,pad0,PE_PI_ALPHA_THRESHOLD_PAD0) + +#define SC_PE_PI_ALPHA_THRESHOLD_SET_RID(line, pe_pi_alpha_threshold,rid) \ + FAST_GPFLAGSET(line, pe_pi_alpha_threshold,rid,PE_PI_ALPHA_THRESHOLD_RID) + +#define SC_PE_PI_CTL_SET_AFMT(line, pe_pi_ctl,afmt) \ + FAST_GPFLAGSET(line, pe_pi_ctl,afmt,PE_PI_CTL_AFMT) + +#define SC_PE_PI_CTL_SET_ZFMT(line, pe_pi_ctl,zfmt) \ + FAST_GPFLAGSET(line, pe_pi_ctl,zfmt,PE_PI_CTL_ZFMT) + +#define SC_PE_PI_CTL_SET_PAD0(line, pe_pi_ctl,pad0) \ + FAST_GPFLAGSET(line, pe_pi_ctl,pad0,PE_PI_CTL_PAD0) + +#define SC_PE_PI_CTL_SET_RID(line, pe_pi_ctl,rid) \ + FAST_GPFLAGSET(line, pe_pi_ctl,rid,PE_PI_CTL_RID) + +#endif // PE_REG_H diff --git a/include/revolution/private/pi_reg.h b/include/revolution/private/pi_reg.h new file mode 100644 index 0000000000..37fe2c401a --- /dev/null +++ b/include/revolution/private/pi_reg.h @@ -0,0 +1,73 @@ +#ifndef PI_REG_H +#define PI_REG_H + +#include + +#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 diff --git a/include/revolution/private/ras_reg.h b/include/revolution/private/ras_reg.h new file mode 100644 index 0000000000..58d56e86a8 --- /dev/null +++ b/include/revolution/private/ras_reg.h @@ -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 diff --git a/include/revolution/private/su_reg.h b/include/revolution/private/su_reg.h new file mode 100644 index 0000000000..afe7c7ca3b --- /dev/null +++ b/include/revolution/private/su_reg.h @@ -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 diff --git a/include/revolution/private/tev_reg.h b/include/revolution/private/tev_reg.h new file mode 100644 index 0000000000..22898e798b --- /dev/null +++ b/include/revolution/private/tev_reg.h @@ -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 diff --git a/include/revolution/private/tx_reg.h b/include/revolution/private/tx_reg.h new file mode 100644 index 0000000000..cf61cd1ac2 --- /dev/null +++ b/include/revolution/private/tx_reg.h @@ -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 diff --git a/include/revolution/private/xf_mem.h b/include/revolution/private/xf_mem.h new file mode 100644 index 0000000000..cf708e8646 --- /dev/null +++ b/include/revolution/private/xf_mem.h @@ -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 diff --git a/include/revolution/sc.h b/include/revolution/sc.h index 7a8da096d2..ef8bc2c636 100644 --- a/include/revolution/sc.h +++ b/include/revolution/sc.h @@ -77,35 +77,36 @@ 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; typedef struct { - OSThreadQueue threadQueue; - NANDFileInfo nandFileInfo; - NANDCommandBlock nandCommandBlock; + OSThreadQueue threadQueue; + NANDFileInfo nandFileInfo; + NANDCommandBlock nandCommandBlock; - union { - u8 nandType; - NANDStatus nandStatus; - } u; + union { + u8 nandType; + NANDStatus nandStatus; + } u; - u8 nandStep; - u8 nandNeedClose; - u8 reloadFileCount; - SCReloadConfFileCallback reloadCallback; - s32 reloadResult; - const char* reloadFileName[2]; - u8* reloadBufp[2]; - u32 reloadSizeExpected[2]; - u32 reloadedSize[2]; - SCFlushCallback flushCallback; - u32 flushResult; - u32 flushSize; + u8 nandStep; + u8 nandNeedClose; + u8 reloadFileCount; + SCReloadConfFileCallback reloadCallback; + s32 reloadResult; + const char* reloadFileName[2]; + u8* reloadBufp[2]; + u32 reloadSizeExpected[2]; + u32 reloadedSize[2]; + SCFlushCallback flushCallback; + u32 flushResult; + 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 diff --git a/include/revolution/vi/vifuncs.h b/include/revolution/vi/vifuncs.h index f2ed7ef6ca..b3cea5622d 100644 --- a/include/revolution/vi/vifuncs.h +++ b/include/revolution/vi/vifuncs.h @@ -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 } diff --git a/include/revolution/vi/vitypes.h b/include/revolution/vi/vitypes.h index d042cad2c3..728b5404cc 100644 --- a/include/revolution/vi/vitypes.h +++ b/include/revolution/vi/vitypes.h @@ -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 diff --git a/include/revolution/wenc.h b/include/revolution/wenc.h new file mode 100644 index 0000000000..39b9180977 --- /dev/null +++ b/include/revolution/wenc.h @@ -0,0 +1,30 @@ +#ifndef _REVOLUTION_WENC_H_ +#define _REVOLUTION_WENC_H_ + +#include + +#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 diff --git a/include/revolution/wpad.h b/include/revolution/wpad.h index 59b27ac5f7..2e7456e3e6 100644 --- a/include/revolution/wpad.h +++ b/include/revolution/wpad.h @@ -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 } diff --git a/include/revolution/wpad/bte.h b/include/revolution/wpad/bte.h new file mode 100644 index 0000000000..1751d8998b --- /dev/null +++ b/include/revolution/wpad/bte.h @@ -0,0 +1,1044 @@ +#ifndef CONTEXT_BTE_H +#define CONTEXT_BTE_H + +#include + +// taken from https://github.com/doldecomp/sdk_2009-12-11/blob/main/include/context_bte.h + +/* Contains the context of the BTE library that the WPAD library needs to + * compile. + * + * This is not the full context; the other half of the context is in + * . + * + * Most of this code is copyright (C) 2003-2012 Broadcom Corporation under the + * Apache 2.0 License . The original + * source can be found at + * ; + * specifically, I used the earliest commit available (late 2012, commit hash + * 5738f83aeb59361a0a2eda2460113f6dc9194271). + */ + +/* License redistribution conditions + * + * a. You may obtain a copy of the License at + * . + * b. Some of the code is modified. Comments will be marked with my name + * (muff1n) to show what I modified and where. + * c. See the following comment block, which is copied verbatim from bluedroid + * source. + * d. No NOTICE file is present in the commit that I used. + */ + +/****************************************************************************** + * + * Copyright (C) 2003-2012 Broadcom Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +// from bluedroid source + +typedef uint8_t UINT8; +typedef uint16_t UINT16; +typedef uint32_t UINT32; + +typedef int8_t INT8; + +typedef unsigned char BOOLEAN; + +/* muff1n: It seems like BTE_TRACE_LEVEL_VERBOSE did not exist at the time. Or + * maybe it was a different logging level. At the very least, one logging level + * is missing. + */ +#define MAX_TRACE_LEVEL 5 + +#define BD_ADDR_LEN 6 /* Device address length */ +typedef UINT8 BD_ADDR[BD_ADDR_LEN]; /* Device address */ +typedef UINT8 *BD_ADDR_PTR; /* Pointer to Device Address */ + +#define LINK_KEY_LEN 16 +typedef UINT8 LINK_KEY[LINK_KEY_LEN]; /* Link Key */ + +#define DEV_CLASS_LEN 3 +typedef UINT8 DEV_CLASS[DEV_CLASS_LEN]; /* Device class */ +typedef UINT8 *DEV_CLASS_PTR; /* Pointer to Device class */ + +/* muff1n: TODO: bta_dm_pin_cback looks mostly the same except that BD_NAME_LEN + * is 33 (or it was 32 and BD_NAME_LEN was not decreased by 1 in BCM_STRNCPY_S + * calls)? + * confirm this + * + * UPDATE: there is a case where it is 248 + */ +#define BD_NAME_LEN 248 +typedef UINT8 BD_NAME[BD_NAME_LEN]; /* Device name */ +typedef UINT8 *BD_NAME_PTR; /* Pointer to Device name */ + +#define BD_FEATURES_LEN 8 +typedef UINT8 BD_FEATURES[BD_FEATURES_LEN]; /* LMP features supported by device */ + +#define BT_DEVICE_TYPE_BREDR 0x01 +#define BT_DEVICE_TYPE_BLE 0x02 +#define BT_DEVICE_TYPE_DUMO 0x03 +typedef UINT8 tBT_DEVICE_TYPE; + +/* Maximum UUID size - 16 bytes, and structure to hold any type of UUID. */ +#define MAX_UUID_SIZE 16 +typedef struct +{ +#define LEN_UUID_16 2 +#define LEN_UUID_32 4 +#define LEN_UUID_128 16 + + UINT16 len; + + union + { + UINT16 uuid16; + UINT32 uuid32; + UINT8 uuid128[MAX_UUID_SIZE]; + } uu; + +} tBT_UUID; + +/* Status Return Value */ +#define BTA_SUCCESS 0 /* Successful operation. */ +#define BTA_FAILURE 1 /* Generic failure. */ +#define BTA_PENDING 2 /* API cannot be completed right now */ +#define BTA_BUSY 3 +#define BTA_NO_RESOURCES 4 +#define BTA_WRONG_MODE 5 + +typedef UINT8 tBTA_STATUS; + +/* + * Service ID + * + * NOTES: When you add a new Service ID for BTA AND require to change the value of BTA_MAX_SERVICE_ID, + * make sure that the correct security ID of the new service from Security service definitions (btm_api.h) + * should be added to bta_service_id_to_btm_srv_id_lkup_tbl table in bta_dm_act.c. + */ + +#define BTA_RES_SERVICE_ID 0 /* Reserved */ +#define BTA_SPP_SERVICE_ID 1 /* Serial port profile. */ +#define BTA_DUN_SERVICE_ID 2 /* Dial-up networking profile. */ +#define BTA_A2DP_SOURCE_SERVICE_ID 3 /* A2DP Source profile. */ +#define BTA_LAP_SERVICE_ID 4 /* LAN access profile. */ +#define BTA_HSP_SERVICE_ID 5 /* Headset profile. */ +#define BTA_HFP_SERVICE_ID 6 /* Hands-free profile. */ +#define BTA_OPP_SERVICE_ID 7 /* Object push */ +#define BTA_FTP_SERVICE_ID 8 /* File transfer */ +#define BTA_CTP_SERVICE_ID 9 /* Cordless Terminal */ +#define BTA_ICP_SERVICE_ID 10 /* Intercom Terminal */ +#define BTA_SYNC_SERVICE_ID 11 /* Synchronization */ +#define BTA_BPP_SERVICE_ID 12 /* Basic printing profile */ +#define BTA_BIP_SERVICE_ID 13 /* Basic Imaging profile */ +#define BTA_PANU_SERVICE_ID 14 /* PAN User */ +#define BTA_NAP_SERVICE_ID 15 /* PAN Network access point */ +#define BTA_GN_SERVICE_ID 16 /* PAN Group Ad-hoc networks */ +#define BTA_SAP_SERVICE_ID 17 /* SIM Access profile */ +#define BTA_A2DP_SERVICE_ID 18 /* A2DP Sink */ +#define BTA_AVRCP_SERVICE_ID 19 /* A/V remote control */ +#define BTA_HID_SERVICE_ID 20 /* HID */ +#define BTA_VDP_SERVICE_ID 21 /* Video distribution */ +#define BTA_PBAP_SERVICE_ID 22 /* PhoneBook Access Server*/ +#define BTA_HSP_HS_SERVICE_ID 23 /* HFP HS role */ +#define BTA_HFP_HS_SERVICE_ID 24 /* HSP HS role */ +#define BTA_MAP_SERVICE_ID 25 /* Message Access Profile */ +#define BTA_MN_SERVICE_ID 26 /* Message Notification Service */ +#define BTA_HDP_SERVICE_ID 27 /* Health Device Profile */ +#define BTA_PCE_SERVICE_ID 28 /* PhoneBook Access Client*/ + +#define BTA_USER_SERVICE_ID 29 /* User requested UUID */ +#define BTA_MAX_SERVICE_ID 30 + +/* service IDs (BTM_SEC_SERVICE_FIRST_EMPTY + 1) to (BTM_SEC_MAX_SERVICES - 1) + * are used by BTA JV */ +#define BTA_FIRST_JV_SERVICE_ID (BTM_SEC_SERVICE_FIRST_EMPTY + 1) +#define BTA_LAST_JV_SERVICE_ID (BTM_SEC_MAX_SERVICES - 1) + +typedef UINT8 tBTA_SERVICE_ID; + +/* Service ID Mask */ +#define BTA_RES_SERVICE_MASK 0x00000001 /* Reserved */ +#define BTA_SPP_SERVICE_MASK 0x00000002 /* Serial port profile. */ +#define BTA_DUN_SERVICE_MASK 0x00000004 /* Dial-up networking profile. */ +#define BTA_FAX_SERVICE_MASK 0x00000008 /* Fax profile. */ +#define BTA_LAP_SERVICE_MASK 0x00000010 /* LAN access profile. */ +#define BTA_HSP_SERVICE_MASK 0x00000020 /* HSP AG role. */ +#define BTA_HFP_SERVICE_MASK 0x00000040 /* HFP AG role */ +#define BTA_OPP_SERVICE_MASK 0x00000080 /* Object push */ +#define BTA_FTP_SERVICE_MASK 0x00000100 /* File transfer */ +#define BTA_CTP_SERVICE_MASK 0x00000200 /* Cordless Terminal */ +#define BTA_ICP_SERVICE_MASK 0x00000400 /* Intercom Terminal */ +#define BTA_SYNC_SERVICE_MASK 0x00000800 /* Synchronization */ +#define BTA_BPP_SERVICE_MASK 0x00001000 /* Print server */ +#define BTA_BIP_SERVICE_MASK 0x00002000 /* Basic Imaging */ +#define BTA_PANU_SERVICE_MASK 0x00004000 /* PAN User */ +#define BTA_NAP_SERVICE_MASK 0x00008000 /* PAN Network access point */ +#define BTA_GN_SERVICE_MASK 0x00010000 /* PAN Group Ad-hoc networks */ +#define BTA_SAP_SERVICE_MASK 0x00020000 /* PAN Group Ad-hoc networks */ +#define BTA_A2DP_SERVICE_MASK 0x00040000 /* Advanced audio distribution */ +#define BTA_AVRCP_SERVICE_MASK 0x00080000 /* A/V remote control */ +#define BTA_HID_SERVICE_MASK 0x00100000 /* HID */ +#define BTA_VDP_SERVICE_MASK 0x00200000 /* Video distribution */ +#define BTA_PBAP_SERVICE_MASK 0x00400000 /* Phone Book Server */ +#define BTA_HSP_HS_SERVICE_MASK 0x00800000 /* HFP HS role */ +#define BTA_HFP_HS_SERVICE_MASK 0x01000000 /* HSP HS role */ +#define BTA_MAS_SERVICE_MASK 0x02000000 /* Message Access Profile */ +#define BTA_MN_SERVICE_MASK 0x04000000 /* Message Notification Profile */ +#define BTA_HL_SERVICE_MASK 0x08000000 /* Health Device Profile */ +#define BTA_PCE_SERVICE_MASK 0x10000000 /* Phone Book Client */ + +// btla-specific ++ +#define BTA_USER_SERVICE_MASK 0x20000000 /* Message Notification Profile */ +// btla-specific -- + +#define BTA_ALL_SERVICE_MASK 0x1FFFFFFF /* All services supported by BTA. */ + +typedef UINT32 tBTA_SERVICE_MASK; + +/* SW sub-systems */ +#define BTA_ID_SYS 0 /* system manager */ +/* BLUETOOTH PART - from 0 to BTA_ID_BLUETOOTH_MAX */ +#define BTA_ID_DM 1 /* device manager */ +#define BTA_ID_DM_SEARCH 2 /* device manager search */ +#define BTA_ID_DM_SEC 3 /* device manager security */ +#define BTA_ID_DG 4 /* data gateway */ +#define BTA_ID_AG 5 /* audio gateway */ +#define BTA_ID_OPC 6 /* object push client */ +#define BTA_ID_OPS 7 /* object push server */ +#define BTA_ID_FTS 8 /* file transfer server */ +#define BTA_ID_CT 9 /* cordless telephony terminal */ +#define BTA_ID_FTC 10 /* file transfer client */ +#define BTA_ID_SS 11 /* synchronization server */ +#define BTA_ID_PR 12 /* Printer client */ +#define BTA_ID_BIC 13 /* Basic Imaging Client */ +#define BTA_ID_PAN 14 /* Personal Area Networking */ +#define BTA_ID_BIS 15 /* Basic Imaging Server */ +#define BTA_ID_ACC 16 /* Advanced Camera Client */ +#define BTA_ID_SC 17 /* SIM Card Access server */ +#define BTA_ID_AV 18 /* Advanced audio/video */ +#define BTA_ID_AVK 19 /* Audio/video sink */ +#define BTA_ID_HD 20 /* HID Device */ +#define BTA_ID_CG 21 /* Cordless Gateway */ +#define BTA_ID_BP 22 /* Basic Printing Client */ +#define BTA_ID_HH 23 /* Human Interface Device Host */ +#define BTA_ID_PBS 24 /* Phone Book Access Server */ +#define BTA_ID_PBC 25 /* Phone Book Access Client */ +#define BTA_ID_JV 26 /* Java */ +#define BTA_ID_HS 27 /* Headset */ +#define BTA_ID_MSE 28 /* Message Server Equipment */ +#define BTA_ID_MCE 29 /* Message Client Equipment */ +#define BTA_ID_HL 30 /* Health Device Profile*/ +#define BTA_ID_GATTC 31 /* GATT Client */ +#define BTA_ID_GATTS 32 /* GATT Client */ +#define BTA_ID_BLUETOOTH_MAX 33 /* last BT profile */ + +/* FM */ +#define BTA_ID_FM 34 /* FM */ +#define BTA_ID_FMTX 35 /* FM TX */ + +/* SENSOR */ +#define BTA_ID_SSR 36 /* Sensor */ + +/* GPS */ +#define BTA_ID_GPS 37 /* GPS */ + +/* GENERIC */ +#define BTA_ID_PRM 38 +#define BTA_ID_SYSTEM 39 /* platform-specific */ +#define BTA_ID_SWRAP 40 /* Insight script wrapper */ +#define BTA_ID_MIP 41 /* Multicase Individual Polling */ +#define BTA_ID_RT 42 /* Audio Routing module: This module is always on. */ + +/* JV */ +#define BTA_ID_JV1 43 /* JV1 */ +#define BTA_ID_JV2 44 /* JV2 */ + +#define BTA_ID_MAX (43 + BTA_DM_NUM_JV_ID) + +typedef UINT8 tBTA_SYS_ID; + +enum +{ + BTM_SUCCESS = 0, /* 0 Command succeeded */ + BTM_CMD_STARTED, /* 1 Command started OK. */ + BTM_BUSY, /* 2 Device busy with another command */ + BTM_NO_RESOURCES, /* 3 No resources to issue command */ + BTM_MODE_UNSUPPORTED, /* 4 Request for 1 or more unsupported modes */ + BTM_ILLEGAL_VALUE, /* 5 Illegal parameter value */ + BTM_WRONG_MODE, /* 6 Device in wrong mode for request */ + BTM_UNKNOWN_ADDR, /* 7 Unknown remote BD address */ + BTM_DEVICE_TIMEOUT, /* 8 Device timeout */ + BTM_BAD_VALUE_RET, /* 9 A bad value was received from HCI */ + BTM_ERR_PROCESSING, /* 10 Generic error */ + BTM_NOT_AUTHORIZED, /* 11 Authorization failed */ + BTM_DEV_RESET, /* 12 Device has been reset */ + BTM_CMD_STORED, /* 13 request is stored in control block */ + BTM_ILLEGAL_ACTION, /* 14 state machine gets illegal command */ + BTM_DELAY_CHECK, /* 15 delay the check on encryption */ + BTM_SCO_BAD_LENGTH, /* 16 Bad SCO over HCI data length */ + BTM_SUCCESS_NO_SECURITY, /* 17 security passed, no security set */ + BTM_FAILED_ON_SECURITY , /* 18 security failed */ + BTM_REPEATED_ATTEMPTS /* 19 repeated attempts for LE security requests */ +}; +typedef UINT8 tBTM_STATUS; + +typedef struct +{ + UINT16 event; + UINT16 len; + UINT16 offset; + UINT16 layer_specific; +} BT_HDR; + +#define BT_HDR_SIZE (sizeof (BT_HDR)) + +/* Security Service Levels [bit mask] (BTM_SetSecurityLevel) +** Encryption should not be used without authentication +*/ +#define BTM_SEC_NONE 0x0000 /* Nothing required */ +#define BTM_SEC_IN_AUTHORIZE 0x0001 /* Inbound call requires authorization */ +#define BTM_SEC_IN_AUTHENTICATE 0x0002 /* Inbound call requires authentication */ +#define BTM_SEC_IN_ENCRYPT 0x0004 /* Inbound call requires encryption */ +#define BTM_SEC_OUT_AUTHORIZE 0x0008 /* Outbound call requires authorization */ +#define BTM_SEC_OUT_AUTHENTICATE 0x0010 /* Outbound call requires authentication */ +#define BTM_SEC_OUT_ENCRYPT 0x0020 /* Outbound call requires encryption */ +#define BTM_SEC_BOND 0x0040 /* Bonding */ +#define BTM_SEC_BOND_CONN 0x0080 /* bond_created_connection */ +#define BTM_SEC_FORCE_MASTER 0x0100 /* Need to switch connection to be master */ +#define BTM_SEC_ATTEMPT_MASTER 0x0200 /* Try to switch connection to be master */ +#define BTM_SEC_FORCE_SLAVE 0x0400 /* Need to switch connection to be master */ +#define BTM_SEC_ATTEMPT_SLAVE 0x0800 /* Try to switch connection to be slave */ +#define BTM_SEC_IN_MITM 0x1000 /* inbound Do man in the middle protection */ +#define BTM_SEC_OUT_MITM 0x2000 /* outbound Do man in the middle protection */ + +/* Security Setting Mask */ +#define BTA_SEC_NONE BTM_SEC_NONE /* No security. */ +#define BTA_SEC_AUTHORIZE (BTM_SEC_IN_AUTHORIZE ) /* Authorization required (only needed for out going connection )*/ +#define BTA_SEC_AUTHENTICATE (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_OUT_AUTHENTICATE) /* Authentication required. */ +#define BTA_SEC_ENCRYPT (BTM_SEC_IN_ENCRYPT | BTM_SEC_OUT_ENCRYPT) /* Encryption required. */ + +typedef UINT8 tBTA_SEC; + +/* Pairable Modes */ +#define BTA_DM_PAIRABLE 1 +#define BTA_DM_NON_PAIRABLE 0 + +/* Connectable Paired Only Mode */ +#define BTA_DM_CONN_ALL 0 +#define BTA_DM_CONN_PAIRED 1 + +/* Inquiry modes + * Note: These modes are associated with the inquiry active values (BTM_*ACTIVE) */ +#define BTM_GENERAL_INQUIRY 0 +#define BTM_LIMITED_INQUIRY 1 +#define BTM_BR_INQUIRY_MASK 0x0f +/* high byte of inquiry mode for BLE inquiry mode */ +#define BTM_BLE_INQUIRY_NONE 0x00 +#define BTM_BLE_GENERAL_INQUIRY 0x10 +#define BTM_BLE_LIMITED_INQUIRY 0x20 +#define BTM_BLE_INQUIRY_MASK (BTM_BLE_GENERAL_INQUIRY|BTM_BLE_LIMITED_INQUIRY) + +#define BTA_BLE_INQUIRY_NONE BTM_BLE_INQUIRY_NONE +#define BTA_BLE_GENERAL_INQUIRY BTM_BLE_GENERAL_INQUIRY /* Perform LE general inquiry. */ +#define BTA_BLE_LIMITED_INQUIRY BTM_BLE_LIMITED_INQUIRY /* Perform LE limited inquiry. */ +typedef UINT8 tBTA_DM_INQ_MODE; + +/* Inquiry Filter Type */ +#define BTA_DM_INQ_CLR BTM_CLR_INQUIRY_FILTER /* Clear inquiry filter. */ +#define BTA_DM_INQ_DEV_CLASS BTM_FILTER_COND_DEVICE_CLASS /* Filter on device class. */ +#define BTA_DM_INQ_BD_ADDR BTM_FILTER_COND_BD_ADDR /* Filter on a specific BD address. */ + +typedef UINT8 tBTA_DM_INQ_FILT; + +/* Inquiry filter device class condition */ +typedef struct +{ + DEV_CLASS dev_class; /* device class of interest */ + DEV_CLASS dev_class_mask; /* mask to determine the bits of device class of interest */ +} tBTA_DM_COD_COND; + +/* Inquiry Filter Condition */ +typedef union +{ + BD_ADDR bd_addr; /* BD address of device to filter. */ + tBTA_DM_COD_COND dev_class_cond; /* Device class filter condition */ +} tBTA_DM_INQ_COND; + +/* Inquiry Parameters */ +typedef struct +{ + tBTA_DM_INQ_MODE mode; /* Inquiry mode, limited or general. */ + UINT8 duration; /* Inquiry duration in 1.28 sec units. */ + UINT8 max_resps; /* Maximum inquiry responses. Set to zero for unlimited responses. */ + BOOLEAN report_dup; /* report duplicated inquiry response with higher RSSI value */ + tBTA_DM_INQ_FILT filter_type; /* Filter condition type. */ + tBTA_DM_INQ_COND filter_cond; /* Filter condition data. */ +} tBTA_DM_INQ; + +/* Security Callback Events */ +#define BTA_DM_ENABLE_EVT 0 /* Enable Event */ +#define BTA_DM_DISABLE_EVT 1 /* Disable Event */ +#define BTA_DM_PIN_REQ_EVT 2 /* PIN request. */ +#define BTA_DM_AUTH_CMPL_EVT 3 /* Authentication complete indication. */ +#define BTA_DM_AUTHORIZE_EVT 4 /* Authorization request. */ +#define BTA_DM_LINK_UP_EVT 5 /* Connection UP event */ +#define BTA_DM_LINK_DOWN_EVT 6 /* Connection DOWN event */ +#define BTA_DM_SIG_STRENGTH_EVT 7 /* Signal strength for bluetooth connection */ +#define BTA_DM_BUSY_LEVEL_EVT 8 /* System busy level */ +#define BTA_DM_BOND_CANCEL_CMPL_EVT 9 /* Bond cancel complete indication */ +#define BTA_DM_SP_CFM_REQ_EVT 10 /* Simple Pairing User Confirmation request. */ +#define BTA_DM_SP_KEY_NOTIF_EVT 11 /* Simple Pairing Passkey Notification */ +#define BTA_DM_SP_RMT_OOB_EVT 12 /* Simple Pairing Remote OOB Data request. */ +#define BTA_DM_SP_KEYPRESS_EVT 13 /* Key press notification event. */ +#define BTA_DM_ROLE_CHG_EVT 14 /* Role Change event. */ +#define BTA_DM_BLE_KEY_EVT 15 /* BLE SMP key event for peer device keys */ +#define BTA_DM_BLE_SEC_REQ_EVT 16 /* BLE SMP security request */ +#define BTA_DM_BLE_PASSKEY_NOTIF_EVT 17 /* SMP passkey notification event */ +#define BTA_DM_BLE_PASSKEY_REQ_EVT 18 /* SMP passkey request event */ +#define BTA_DM_BLE_OOB_REQ_EVT 19 /* SMP OOB request event */ +#define BTA_DM_BLE_LOCAL_IR_EVT 20 /* BLE local IR event */ +#define BTA_DM_BLE_LOCAL_ER_EVT 21 /* BLE local ER event */ +// btla-specific ++ +#define BTA_DM_BLE_AUTH_CMPL_EVT 22 /* BLE Auth complete */ +// btla-specific -- +#define BTA_DM_DEV_UNPAIRED_EVT 23 +#define BTA_DM_HW_ERROR_EVT 24 /* BT Chip H/W error */ +typedef UINT8 tBTA_DM_SEC_EVT; + +/* Structure associated with BTA_DM_ENABLE_EVT */ +typedef struct +{ + BD_ADDR bd_addr; /* BD address of local device. */ + tBTA_STATUS status; +} tBTA_DM_ENABLE; + +/* Structure associated with BTA_DM_PIN_REQ_EVT */ +typedef struct +{ + BD_ADDR bd_addr; /* BD address peer device. */ + BD_NAME bd_name; /* Name of peer device. */ + DEV_CLASS dev_class; /* Class of Device */ +} tBTA_DM_PIN_REQ; + +/* Link Key Notification Event (Key Type) definitions */ +#define HCI_LKEY_TYPE_COMBINATION 0x00 +#define HCI_LKEY_TYPE_LOCAL_UNIT 0x01 +#define HCI_LKEY_TYPE_REMOTE_UNIT 0x02 +#define HCI_LKEY_TYPE_DEBUG_COMB 0x03 +#define HCI_LKEY_TYPE_UNAUTH_COMB 0x04 +#define HCI_LKEY_TYPE_AUTH_COMB 0x05 +#define HCI_LKEY_TYPE_CHANGED_COMB 0x06 + +/* Structure associated with BTA_DM_AUTH_CMPL_EVT */ +typedef struct +{ + BD_ADDR bd_addr; /* BD address peer device. */ + BD_NAME bd_name; /* Name of peer device. */ + BOOLEAN key_present; /* Valid link key value in key element */ + LINK_KEY key; /* Link key associated with peer device. */ + UINT8 key_type; /* The type of Link Key */ + BOOLEAN success; /* TRUE of authentication succeeded, FALSE if failed. */ + UINT8 fail_reason; /* The HCI reason/error code for when success=FALSE */ +} tBTA_DM_AUTH_CMPL; + +/* Structure associated with BTA_DM_AUTHORIZE_EVT */ +typedef struct +{ + BD_ADDR bd_addr; /* BD address peer device. */ + BD_NAME bd_name; /* Name of peer device. */ + tBTA_SERVICE_ID service; /* Service ID to authorize. */ +// btla-specific ++ + DEV_CLASS dev_class; +// btla-specific -- +} tBTA_DM_AUTHORIZE; + +/* Structure associated with BTA_DM_LINK_UP_EVT */ +typedef struct +{ + BD_ADDR bd_addr; /* BD address peer device. */ +} tBTA_DM_LINK_UP; + +/* +** Defentions for HCI Error Codes that are past in the events +*/ +#define HCI_SUCCESS 0x00 +#define HCI_PENDING 0x00 +#define HCI_ERR_ILLEGAL_COMMAND 0x01 +#define HCI_ERR_NO_CONNECTION 0x02 +#define HCI_ERR_HW_FAILURE 0x03 +#define HCI_ERR_PAGE_TIMEOUT 0x04 +#define HCI_ERR_AUTH_FAILURE 0x05 +#define HCI_ERR_KEY_MISSING 0x06 +#define HCI_ERR_MEMORY_FULL 0x07 +#define HCI_ERR_CONNECTION_TOUT 0x08 +#define HCI_ERR_MAX_NUM_OF_CONNECTIONS 0x09 +#define HCI_ERR_MAX_NUM_OF_SCOS 0x0A +#define HCI_ERR_CONNECTION_EXISTS 0x0B +#define HCI_ERR_COMMAND_DISALLOWED 0x0C +#define HCI_ERR_HOST_REJECT_RESOURCES 0x0D +#define HCI_ERR_HOST_REJECT_SECURITY 0x0E +#define HCI_ERR_HOST_REJECT_DEVICE 0x0F +#define HCI_ERR_HOST_TIMEOUT 0x10 +#define HCI_ERR_UNSUPPORTED_VALUE 0x11 +#define HCI_ERR_ILLEGAL_PARAMETER_FMT 0x12 +#define HCI_ERR_PEER_USER 0x13 +#define HCI_ERR_PEER_LOW_RESOURCES 0x14 +#define HCI_ERR_PEER_POWER_OFF 0x15 +#define HCI_ERR_CONN_CAUSE_LOCAL_HOST 0x16 +#define HCI_ERR_REPEATED_ATTEMPTS 0x17 +#define HCI_ERR_PAIRING_NOT_ALLOWED 0x18 +#define HCI_ERR_UNKNOWN_LMP_PDU 0x19 +#define HCI_ERR_UNSUPPORTED_REM_FEATURE 0x1A +#define HCI_ERR_SCO_OFFSET_REJECTED 0x1B +#define HCI_ERR_SCO_INTERVAL_REJECTED 0x1C +#define HCI_ERR_SCO_AIR_MODE 0x1D +#define HCI_ERR_INVALID_LMP_PARAM 0x1E +#define HCI_ERR_UNSPECIFIED 0x1F +#define HCI_ERR_UNSUPPORTED_LMP_FEATURE 0x20 +#define HCI_ERR_ROLE_CHANGE_NOT_ALLOWED 0x21 +#define HCI_ERR_LMP_RESPONSE_TIMEOUT 0x22 +#define HCI_ERR_LMP_ERR_TRANS_COLLISION 0x23 +#define HCI_ERR_LMP_PDU_NOT_ALLOWED 0x24 +#define HCI_ERR_ENCRY_MODE_NOT_ACCEPTABLE 0x25 +#define HCI_ERR_UNIT_KEY_USED 0x26 +#define HCI_ERR_QOS_NOT_SUPPORTED 0x27 +#define HCI_ERR_INSTANT_PASSED 0x28 +#define HCI_ERR_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED 0x29 +#define HCI_ERR_DIFF_TRANSACTION_COLLISION 0x2A +#define HCI_ERR_UNDEFINED_0x2B 0x2B +#define HCI_ERR_QOS_UNACCEPTABLE_PARAM 0x2C +#define HCI_ERR_QOS_REJECTED 0x2D +#define HCI_ERR_CHAN_CLASSIF_NOT_SUPPORTED 0x2E +#define HCI_ERR_INSUFFCIENT_SECURITY 0x2F +#define HCI_ERR_PARAM_OUT_OF_RANGE 0x30 +#define HCI_ERR_UNDEFINED_0x31 0x31 +#define HCI_ERR_ROLE_SWITCH_PENDING 0x32 +#define HCI_ERR_UNDEFINED_0x33 0x33 +#define HCI_ERR_RESERVED_SLOT_VIOLATION 0x34 +#define HCI_ERR_ROLE_SWITCH_FAILED 0x35 +#define HCI_ERR_INQ_RSP_DATA_TOO_LARGE 0x36 +#define HCI_ERR_SIMPLE_PAIRING_NOT_SUPPORTED 0x37 +#define HCI_ERR_HOST_BUSY_PAIRING 0x38 +#define HCI_ERR_REJ_NO_SUITABLE_CHANNEL 0x39 +#define HCI_ERR_CONTROLLER_BUSY 0x3A +#define HCI_ERR_UNACCEPT_CONN_INTERVAL 0x3B +#define HCI_ERR_DIRECTED_ADVERTISING_TIMEOUT 0x3C +#define HCI_ERR_CONN_TOUT_DUE_TO_MIC_FAILURE 0x3D +#define HCI_ERR_CONN_FAILED_ESTABLISHMENT 0x3E +#define HCI_ERR_MAC_CONNECTION_FAILED 0x3F + +#define HCI_ERR_MAX_ERR 0x40 + +#define HCI_HINT_TO_RECREATE_AMP_PHYS_LINK 0xFF + +/* Structure associated with BTA_DM_LINK_DOWN_EVT */ +typedef struct +{ + BD_ADDR bd_addr; /* BD address peer device. */ + UINT8 status; /* connection open/closed */ +} tBTA_DM_LINK_DOWN; + +typedef INT8 tBTA_DM_RSSI_VALUE; +typedef UINT8 tBTA_DM_LINK_QUALITY_VALUE; + +/* signal strength mask */ +#define BTA_SIG_STRENGTH_RSSI_MASK 1 +#define BTA_SIG_STRENGTH_LINK_QUALITY_MASK 2 + +typedef UINT8 tBTA_SIG_STRENGTH_MASK; + +/* Structure associated with BTA_DM_SIG_STRENGTH_EVT */ +typedef struct +{ + BD_ADDR bd_addr; /* BD address peer device. */ + tBTA_SIG_STRENGTH_MASK mask; /* mask for the values that are valid */ + tBTA_DM_RSSI_VALUE rssi_value; + tBTA_DM_LINK_QUALITY_VALUE link_quality_value; + +} tBTA_DM_SIG_STRENGTH; + +/* Structure associated with BTA_DM_BUSY_LEVEL_EVT */ +typedef struct +{ + UINT8 level; /* when paging or inquiring, level is 10. + Otherwise, the number of ACL links */ +} tBTA_DM_BUSY_LEVEL; + +// muff1n: only filled with used members +typedef union +{ + tBTA_DM_ENABLE enable; /* BTA enabled */ + tBTA_DM_PIN_REQ pin_req; /* PIN request */ + tBTA_DM_AUTH_CMPL auth_cmpl; /* Authentication complete indication */ + tBTA_DM_AUTHORIZE authorize; /* Authorization request */ + tBTA_DM_LINK_UP link_up; /* ACL connection up event */ + tBTA_DM_LINK_DOWN link_down; /* ACL connection down event */ + tBTA_DM_SIG_STRENGTH sig_strength; /* rssi and link quality value */ + tBTA_DM_BUSY_LEVEL busy_level; /* System busy level */ +} tBTA_DM_SEC; + +typedef void (tBTA_DM_SEC_CBACK)(tBTA_DM_SEC_EVT event, tBTA_DM_SEC *p_data); + +/* Search callback events */ +#define BTA_DM_INQ_RES_EVT 0 /* Inquiry result for a peer device. */ +#define BTA_DM_INQ_CMPL_EVT 1 /* Inquiry complete. */ +#define BTA_DM_DISC_RES_EVT 2 /* Discovery result for a peer device. */ +#define BTA_DM_DISC_BLE_RES_EVT 3 /* Discovery result for BLE GATT based service on a peer device. */ +#define BTA_DM_DISC_CMPL_EVT 4 /* Discovery complete. */ +#define BTA_DM_DI_DISC_CMPL_EVT 5 /* Discovery complete. */ +#define BTA_DM_SEARCH_CANCEL_CMPL_EVT 6 /* Search cancelled */ + +typedef UINT8 tBTA_DM_SEARCH_EVT; + +#define BTA_DM_INQ_RES_IGNORE_RSSI BTM_INQ_RES_IGNORE_RSSI /* 0x7f RSSI value not supplied (ignore it) */ + +// muff1n: commented some fields out +/* Structure associated with BTA_DM_INQ_RES_EVT */ +typedef struct +{ + BD_ADDR bd_addr; /* BD address peer device. */ + DEV_CLASS dev_class; /* Device class of peer device. */ + //BOOLEAN remt_name_not_required; /* Application sets this flag if it already knows the name of the device */ + /* If the device name is known to application BTA skips the remote name request */ + //BOOLEAN is_limited; /* TRUE, if the limited inquiry bit is set in the CoD */ + INT8 rssi; /* The rssi value */ + UINT8 *p_eir; /* received EIR */ +} tBTA_DM_INQ_RES; + +/* Structure associated with BTA_DM_INQ_CMPL_EVT */ +typedef struct +{ + UINT8 num_resps; /* Number of inquiry responses. */ +} tBTA_DM_INQ_CMPL; + +/* Structure associated with BTA_DM_DI_DISC_CMPL_EVT */ +typedef struct +{ + BD_ADDR bd_addr; /* BD address peer device. */ + UINT8 num_record; /* Number of DI record */ + tBTA_STATUS result; +} tBTA_DM_DI_DISC_CMPL; + +/* Structure associated with BTA_DM_DISC_RES_EVT */ +typedef struct +{ + BD_ADDR bd_addr; /* BD address peer device. */ + BD_NAME bd_name; /* Name of peer device. */ + tBTA_SERVICE_MASK services; /* Services found on peer device. */ +// btla-specific ++ + UINT8 * p_raw_data; /* Raw data for discovery DB */ + UINT32 raw_data_size; /* size of raw data */ + tBT_DEVICE_TYPE device_type; /* device type in case it is BLE device */ + UINT32 num_uuids; + UINT8 *p_uuid_list; +// btla-specific -- + tBTA_STATUS result; +} tBTA_DM_DISC_RES; + +/* Structure associated with tBTA_DM_DISC_BLE_RES */ +typedef struct +{ + BD_ADDR bd_addr; /* BD address peer device. */ + BD_NAME bd_name; /* Name of peer device. */ + tBT_UUID service; /* GATT based Services UUID found on peer device. */ +} tBTA_DM_DISC_BLE_RES; + +/* Union of all search callback structures */ +typedef union +{ + tBTA_DM_INQ_RES inq_res; /* Inquiry result for a peer device. */ + tBTA_DM_INQ_CMPL inq_cmpl; /* Inquiry complete. */ + tBTA_DM_DISC_RES disc_res; /* Discovery result for a peer device. */ + tBTA_DM_DISC_BLE_RES disc_ble_res; /* discovery result for GATT based service */ + tBTA_DM_DI_DISC_CMPL di_disc; /* DI discovery result for a peer device */ +} tBTA_DM_SEARCH; + +/* Search callback */ +typedef void (tBTA_DM_SEARCH_CBACK)(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data); + +/* type of protocol mode */ +#define BTA_HH_PROTO_RPT_MODE (0x00) +#define BTA_HH_PROTO_BOOT_MODE (0x01) +#define BTA_HH_PROTO_UNKNOWN (0xff) +typedef UINT8 tBTA_HH_PROTO_MODE; + +/* BTA HID Host callback events */ +#define BTA_HH_ENABLE_EVT 0 /* HH enabled */ +#define BTA_HH_DISABLE_EVT 1 /* HH disabled */ +#define BTA_HH_OPEN_EVT 2 /* connection opened */ +#define BTA_HH_CLOSE_EVT 3 /* connection closed */ +#define BTA_HH_GET_RPT_EVT 4 /* BTA_HhGetReport callback */ +#define BTA_HH_SET_RPT_EVT 5 /* BTA_HhSetReport callback */ +#define BTA_HH_GET_PROTO_EVT 6 /* BTA_GetProtoMode callback */ +#define BTA_HH_SET_PROTO_EVT 7 /* BTA_HhSetProtoMode callback */ +#define BTA_HH_GET_IDLE_EVT 8 /* BTA_HhGetIdle comes callback */ +#define BTA_HH_SET_IDLE_EVT 9 /* BTA_HhSetIdle finish callback */ +#define BTA_HH_GET_DSCP_EVT 10 /* Get report descripotor */ +#define BTA_HH_ADD_DEV_EVT 11 /* Add Device callback */ +#define BTA_HH_RMV_DEV_EVT 12 /* remove device finished */ +#define BTA_HH_VC_UNPLUG_EVT 13 /* virtually unplugged */ +#define BTA_HH_UPDATE_UCD_EVT 14 +#define BTA_HH_API_ERR_EVT 15 /* API error is caught */ + +typedef UINT16 tBTA_HH_EVT; + +enum +{ + BTA_HH_OK, + BTA_HH_HS_HID_NOT_READY, /* handshake error : device not ready */ + BTA_HH_HS_INVALID_RPT_ID, /* handshake error : invalid report ID */ + BTA_HH_HS_TRANS_NOT_SPT, /* handshake error : transaction not spt */ + BTA_HH_HS_INVALID_PARAM, /* handshake error : invalid paremter */ + BTA_HH_HS_ERROR, /* handshake error : unspecified HS error */ + BTA_HH_ERR, /* general BTA HH error */ + BTA_HH_ERR_SDP, /* SDP error */ + BTA_HH_ERR_PROTO, /* SET_Protocol error, + only used in BTA_HH_OPEN_EVT callback */ + BTA_HH_ERR_DB_FULL, /* device database full error, used in + BTA_HH_OPEN_EVT/BTA_HH_ADD_DEV_EVT */ + BTA_HH_ERR_TOD_UNSPT, /* type of device not supported */ + BTA_HH_ERR_NO_RES, /* out of system resources */ + BTA_HH_ERR_AUTH_FAILED, /* authentication fail */ + BTA_HH_ERR_HDL +}; +typedef UINT8 tBTA_HH_STATUS; + +/* callback event data for BTA_HH_OPEN_EVT */ +typedef struct +{ + BD_ADDR bda; /* HID device bd address */ + tBTA_HH_STATUS status; /* operation status */ + UINT8 handle; /* device handle */ +} tBTA_HH_CONN; + +typedef tBTA_HH_CONN tBTA_HH_DEV_INFO; + +/* callback event data */ +typedef struct +{ + tBTA_HH_STATUS status; /* operation status */ + UINT8 handle; /* device handle */ +} tBTA_HH_CBDATA; + +// muff1n: only filled with used members +typedef union +{ + tBTA_HH_DEV_INFO dev_info; /* BTA_HH_ADD_DEV_EVT, BTA_HH_RMV_DEV_EVT */ + tBTA_HH_CONN conn; /* BTA_HH_OPEN_EVT */ + tBTA_HH_CBDATA dev_status; /* BTA_HH_CLOSE_EVT, + BTA_HH_SET_PROTO_EVT + BTA_HH_SET_RPT_EVT + BTA_HH_SET_IDLE_EVT */ +} tBTA_HH; + +/* BTA HH callback function */ +typedef void (tBTA_HH_CBACK) (tBTA_HH_EVT event, tBTA_HH *p_data); + +/* General callback function for notifying an application that a synchronous +** BTM function is complete. The pointer contains the address of any returned data. +*/ +typedef void (tBTM_CMPL_CB) (void *p1); +/* Structure returned with local version information */ + +typedef struct +{ + UINT8 hci_version; + UINT16 hci_revision; + UINT8 lmp_version; + UINT16 manufacturer; + UINT16 lmp_subversion; +} tBTM_VERSION_INFO; + +/* Structure returned with Vendor Specific Command complete callback */ +typedef struct +{ + UINT16 opcode; + UINT16 param_len; + UINT8 *p_param_buf; +} tBTM_VSC_CMPL; + +#define BTM_VSC_CMPL_DATA_SIZE (BTM_MAX_VENDOR_SPECIFIC_LEN + sizeof(tBTM_VSC_CMPL)) +/* Callback function for when device status changes. Appl must poll for +** what the new state is (BTM_IsDeviceUp). The event occurs whenever the stack +** has detected that the controller status has changed. This asynchronous event +** is enabled/disabled by calling BTM_RegisterForDeviceStatusNotif(). +*/ +enum +{ + BTM_DEV_STATUS_UP, + BTM_DEV_STATUS_DOWN, + BTM_DEV_STATUS_CMD_TOUT +}; +typedef UINT8 tBTM_DEV_STATUS; + +typedef void (tBTM_DEV_STATUS_CB) (tBTM_DEV_STATUS status); + +/* Callback function for when a vendor specific event occurs. The length and +** array of returned parameter bytes are included. This asynchronous event +** is enabled/disabled by calling BTM_RegisterForVSEvents(). +*/ +typedef void (tBTM_VS_EVT_CB) (UINT8 len, UINT8 *p); + +/* VSC callback function for notifying an application that a synchronous +** BTM function is complete. The pointer contains the address of any returned data. +*/ +typedef void (tBTM_VSC_CMPL_CB) (tBTM_VSC_CMPL *p1); + +/* Attributes mask values to be used in HID_HostAddDev API */ +#define HID_VIRTUAL_CABLE 0x0001 +#define HID_NORMALLY_CONNECTABLE 0x0002 +#define HID_RECONN_INIT 0x0004 +#define HID_SDP_DISABLE 0x0008 +#define HID_BATTERY_POWER 0x0010 +#define HID_REMOTE_WAKE 0x0020 +#define HID_SUP_TOUT_AVLBL 0x0040 +#define HID_SSR_MAX_LATENCY 0x0080 +#define HID_SSR_MIN_TOUT 0x0100 + +#define HID_SEC_REQUIRED 0x8000 + +#define BTA_HH_VIRTUAL_CABLE HID_VIRTUAL_CABLE +#define BTA_HH_NORMALLY_CONNECTABLE HID_NORMALLY_CONNECTABLE +#define BTA_HH_RECONN_INIT HID_RECONN_INIT +#define BTA_HH_SDP_DISABLE HID_SDP_DISABLE +#define BTA_HH_BATTERY_POWER HID_BATTERY_POWER +#define BTA_HH_REMOTE_WAKE HID_REMOTE_WAKE +#define BTA_HH_SUP_TOUT_AVLBL HID_SUP_TOUT_AVLBL +#define BTA_HH_SEC_REQUIRED HID_SEC_REQUIRED +typedef UINT16 tBTA_HH_ATTR_MASK; + +typedef struct desc_info +{ + UINT16 dl_len; + UINT8 *dsc_list; +} tHID_DEV_DSCP_INFO; + +typedef tHID_DEV_DSCP_INFO tBTA_HH_DEV_DESCR; + +/* Policy settings status */ +#define HCI_DISABLE_ALL_LM_MODES 0x0000 +#define HCI_ENABLE_MASTER_SLAVE_SWITCH 0x0001 +#define HCI_ENABLE_HOLD_MODE 0x0002 +#define HCI_ENABLE_SNIFF_MODE 0x0004 +#define HCI_ENABLE_PARK_MODE 0x0008 + +/* HCI mode defenitions */ +#define HCI_MODE_ACTIVE 0x00 +#define HCI_MODE_HOLD 0x01 +#define HCI_MODE_SNIFF 0x02 +#define HCI_MODE_PARK 0x03 + +/* BTM Power manager status codes */ +enum +{ + BTM_PM_STS_ACTIVE = HCI_MODE_ACTIVE, + BTM_PM_STS_HOLD = HCI_MODE_HOLD, + BTM_PM_STS_SNIFF = HCI_MODE_SNIFF, + BTM_PM_STS_PARK = HCI_MODE_PARK, + BTM_PM_STS_SSR, /* report the SSR parameters in HCI_SNIFF_SUB_RATE_EVT */ + BTM_PM_STS_PENDING, /* when waiting for status from controller */ + BTM_PM_STS_ERROR /* when HCI command status returns error */ +}; +typedef UINT8 tBTM_PM_STATUS; + +/* BTM Power manager modes */ + +enum +{ + BTM_PM_MD_ACTIVE = BTM_PM_STS_ACTIVE, + BTM_PM_MD_HOLD = BTM_PM_STS_HOLD, + BTM_PM_MD_SNIFF = BTM_PM_STS_SNIFF, + BTM_PM_MD_PARK = BTM_PM_STS_PARK, + BTM_PM_MD_FORCE = 0x10 /* OR this to force ACL link to a certain mode */ +}; +typedef UINT8 tBTM_PM_MODE; + +#define BTM_PM_SET_ONLY_ID 0x80 + +/* Operation codes */ +#define BTM_PM_REG_SET 1 /* The module wants to set the desired power mode */ +#define BTM_PM_REG_NOTIF 2 /* The module wants to receive mode change event */ +#define BTM_PM_DEREG 4 /* The module does not want to involve with PM anymore */ + +typedef struct +{ + UINT16 max; + UINT16 min; + UINT16 attempt; + UINT16 timeout; + tBTM_PM_MODE mode; +} tBTM_PM_PWR_MD; + +/************************************* +** Power Manager Callback Functions +**************************************/ +typedef void (tBTM_PM_STATUS_CBACK) (BD_ADDR p_bda, tBTM_PM_STATUS status, + UINT16 value, UINT8 hci_status); + +/************************ +** Stored Linkkey Types +*************************/ +#define BTM_CB_EVT_RETURN_LINK_KEYS 1 +#define BTM_CB_EVT_READ_STORED_LINK_KEYS 2 +#define BTM_CB_EVT_WRITE_STORED_LINK_KEYS 3 +#define BTM_CB_EVT_DELETE_STORED_LINK_KEYS 4 + +typedef struct +{ + UINT8 event; + +} tBTM_STORED_LINK_KEYS_EVT; + + +typedef struct +{ + UINT8 event; + UINT8 num_keys; + +} tBTM_RETURN_LINK_KEYS_EVT; + + +typedef struct +{ + BD_ADDR bd_addr; + LINK_KEY link_key; + +} tBTM_BD_ADDR_LINK_KEY_PAIR; + + +typedef struct +{ + UINT8 event; + UINT8 status; + UINT16 max_keys; + UINT16 read_keys; + +} tBTM_READ_STORED_LINK_KEY_COMPLETE; + + +typedef struct +{ + UINT8 event; + UINT8 status; + UINT8 num_keys; + +} tBTM_WRITE_STORED_LINK_KEY_COMPLETE; + + +typedef struct +{ + UINT8 event; + UINT8 status; + UINT16 num_keys; + +} tBTM_DELETE_STORED_LINK_KEY_COMPLETE; + +// --- + +tBTA_STATUS BTA_EnableBluetooth(tBTA_DM_SEC_CBACK *p_cback); +tBTA_STATUS BTA_DisableBluetooth(void); + +// muff1n: most changed prototype so far +tBTA_STATUS BTA_DmAddDevice(BD_ADDR bd_addr, LINK_KEY link_key, + tBTA_SERVICE_MASK trusted_mask, BOOLEAN is_trusted); +tBTA_STATUS BTA_DmRemoveDevice(BD_ADDR bd_addr); +void BTA_DmSearch(tBTA_DM_INQ *p_dm_inq, tBTA_SERVICE_MASK services, tBTA_DM_SEARCH_CBACK *p_cback); +void BTA_DmSearchCancel(void); +void BTA_DmPinReply(BD_ADDR bd_addr, BOOLEAN accept, UINT8 pin_len, UINT8 *p_pin); +BOOLEAN BTA_DmIsDeviceUp(void); +void BTA_DmSetDeviceName(char *p_name); + +// muff1n: disc_mode and conn_mode might be the , based on usage +void BTA_DmSetVisibility(UINT8, UINT8); + +// muff1n: ucd_enabled might be the missing parameter +void BTA_HhEnable(tBTA_SEC sec_mask, tBTA_HH_CBACK *p_cback); +// muff1n: possibly takes just a tBTA_HH_DEV_DESCR in this version? i wrote it like that +void BTA_HhAddDev(BD_ADDR bda, tBTA_HH_ATTR_MASK attr_mask, UINT8 sub_class, + UINT8 app_id, tBTA_HH_DEV_DESCR descr); +void BTA_HhRemoveDev(UINT8 dev_handle); +void BTA_HhOpen(BD_ADDR dev_bda, tBTA_HH_PROTO_MODE mode, tBTA_SEC sec_mask); +void BTA_HhClose(UINT8 dev_handle); + +// muff1n: dev_bda is likely the missing parameter, as it is not used +void BTA_HhSendData(UINT8 dev_handle, BT_HDR *p_data); + +void bta_sys_set_trace_level(UINT8 level); + +void BTM_DeviceReset(tBTM_CMPL_CB *p_cb); + +tBTM_STATUS BTM_EnableTestMode(void); + +tBTM_STATUS BTM_ReadStoredLinkKey(BD_ADDR bd_addr, tBTM_CMPL_CB *p_cb); +tBTM_STATUS BTM_WriteStoredLinkKey(UINT8 num_keys, + BD_ADDR *bd_addr, + LINK_KEY *link_key, + tBTM_CMPL_CB *p_cb); +tBTM_STATUS BTM_DeleteStoredLinkKey(BD_ADDR bd_addr, tBTM_CMPL_CB *p_cb); + +tBTM_STATUS BTM_SetPowerMode(UINT8 pm_id, BD_ADDR remote_bda, tBTM_PM_PWR_MD *p_mode); +tBTM_STATUS BTM_SetAfhChannels(UINT8 first, UINT8 last); + +tBTM_STATUS BTM_VendorSpecificCommand(UINT16 opcode, UINT8 param_len, + UINT8 *p_param_buf, tBTM_VSC_CMPL_CB *p_cb); + +tBTM_STATUS BTM_ReadLocalVersion(tBTM_VERSION_INFO *p_vers); +tBTM_STATUS BTM_SetDeviceClass(DEV_CLASS dev_class); + +tBTM_STATUS btm_remove_acl(BD_ADDR bd_addr); + +// muff1n: is_register is probably the missing parameter here +tBTM_STATUS BTM_RegisterForVSEvents(tBTM_VS_EVT_CB *p_cb); +tBTM_DEV_STATUS_CB *BTM_RegisterForDeviceStatusNotif(tBTM_DEV_STATUS_CB *p_cb); + +tBTM_STATUS BTM_PmRegister(UINT8 mask, UINT8 *p_pm_id, tBTM_PM_STATUS_CBACK *p_cb); +tBTM_STATUS BTM_WritePageTimeout(UINT16 timeout); +void BTM_SetDefaultLinkPolicy(UINT16 settings); +void BTM_SetDefaultLinkSuperTout(UINT16 timeout); + +BOOLEAN BTM_SecAddDevice(BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name, + BD_FEATURES features, UINT32 trusted_mask[], + LINK_KEY link_key); + +void *GKI_getbuf(UINT16 size); + +UINT8 L2CA_SetTraceLevel(UINT8 trace_level); + +UINT8 SDP_SetTraceLevel(UINT8 new_level); + +/* muff1n: not in bluedroid source; might be older removed API functions */ +void BTA_DmSendHciReset(void); +void BTA_HhGetAclQueueInfo(void); +void BTA_Init(void); +void BTA_CleanUp(void (*p_cb)(tBTA_STATUS status)); // probably + +// --- +/* muff1n: I wrote this definition myself + * TODO: would this be part of BLE or WUD? + */ + +struct small_dev_info +{ + char devName[20]; // size 0x14? offset 0x00 // might be 0x13? + char at_0x14[1]; // size 0x??, offset 0x14? + char __pad0[0x20 - (0x14 + 0x01)]; + LINK_KEY linkKey; // size 0x10, offset 0x20 + char __pad1[0x10]; +}; // size 0x40 + +#endif // CONTEXT_BTE_H diff --git a/include/revolution/wpad/wud.h b/include/revolution/wpad/wud.h new file mode 100644 index 0000000000..da024b667b --- /dev/null +++ b/include/revolution/wpad/wud.h @@ -0,0 +1,53 @@ +#ifndef _REVOLUTION_WUD_H_ +#define _REVOLUTION_WUD_H_ + +#include +#include + +#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_ diff --git a/src/d/d_home_button.cpp b/src/d/d_home_button.cpp index 194f5a3f86..bd11f303eb 100644 --- a/src/d/d_home_button.cpp +++ b/src/d/d_home_button.cpp @@ -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]; diff --git a/src/m_Do/m_Do_graphic.cpp b/src/m_Do/m_Do_graphic.cpp index 7c6074323a..38f0b3dfb1 100644 --- a/src/m_Do/m_Do_graphic.cpp +++ b/src/m_Do/m_Do_graphic.cpp @@ -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) { diff --git a/src/revolution/ai/ai.c b/src/revolution/ai/ai.c new file mode 100644 index 0000000000..0587b05a66 --- /dev/null +++ b/src/revolution/ai/ai.c @@ -0,0 +1,273 @@ +#include +#include +#include +#include + +#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 +} diff --git a/src/revolution/aralt/__ar.h b/src/revolution/aralt/__ar.h new file mode 100644 index 0000000000..850f02aa20 --- /dev/null +++ b/src/revolution/aralt/__ar.h @@ -0,0 +1,18 @@ +#ifndef _REVOLUTION_AR_INTERNAL_H_ +#define _REVOLUTION_AR_INTERNAL_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void __ARQPopTaskQueueHi(void); +void __ARQServiceQueueLo(void); +void __ARQInterruptServiceRoutine(u32); + +#ifdef __cplusplus +} +#endif + +#endif // _REVOLUTION_AR_INTERNAL_H_ diff --git a/src/revolution/aralt/aralt.c b/src/revolution/aralt/aralt.c new file mode 100644 index 0000000000..8dfd3e2139 --- /dev/null +++ b/src/revolution/aralt/aralt.c @@ -0,0 +1,175 @@ +#include +#include +#include "fake_tgmath.h" + +#include + +#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; + } +} diff --git a/src/revolution/base/PPCArch.c b/src/revolution/base/PPCArch.c new file mode 100644 index 0000000000..a8119de74c --- /dev/null +++ b/src/revolution/base/PPCArch.c @@ -0,0 +1,306 @@ +#include +#include + +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 + } + } +} diff --git a/src/revolution/base/PPCPm.c b/src/revolution/base/PPCPm.c new file mode 100644 index 0000000000..1f27bc663f --- /dev/null +++ b/src/revolution/base/PPCPm.c @@ -0,0 +1,34 @@ +#include +#include + +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(); +} diff --git a/src/revolution/dsp/__dsp.h b/src/revolution/dsp/__dsp.h new file mode 100644 index 0000000000..08e654ff35 --- /dev/null +++ b/src/revolution/dsp/__dsp.h @@ -0,0 +1,27 @@ +#ifndef _REVOLUTION_DSP_INTERNAL_H_ +#define _REVOLUTION_DSP_INTERNAL_H_ + +#include + +#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 diff --git a/src/revolution/dsp/dsp.c b/src/revolution/dsp/dsp.c new file mode 100644 index 0000000000..a023089b59 --- /dev/null +++ b/src/revolution/dsp/dsp.c @@ -0,0 +1,194 @@ +#include +#include +#include + +#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; +} diff --git a/src/revolution/dsp/dsp_debug.c b/src/revolution/dsp/dsp_debug.c new file mode 100644 index 0000000000..4048cbe4e1 --- /dev/null +++ b/src/revolution/dsp/dsp_debug.c @@ -0,0 +1,9 @@ +#include + +#include "__dsp.h" + +void __DSP_debug_printf(const char* fmt, ...) {} + +DSPTaskInfo* __DSPGetCurrentTask(void) { + return __DSP_curr_task; +} diff --git a/src/revolution/dsp/dsp_task.c b/src/revolution/dsp/dsp_task.c new file mode 100644 index 0000000000..7ea99ba8e6 --- /dev/null +++ b/src/revolution/dsp/dsp_task.c @@ -0,0 +1,363 @@ +#include + +#include +#include + +#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; +} diff --git a/src/revolution/esp/esp.c b/src/revolution/esp/esp.c new file mode 100644 index 0000000000..68899e2598 --- /dev/null +++ b/src/revolution/esp/esp.c @@ -0,0 +1,320 @@ +#include +#include +#include + +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; +} diff --git a/src/revolution/euart/euart.c b/src/revolution/euart/euart.c new file mode 100644 index 0000000000..df69df2df8 --- /dev/null +++ b/src/revolution/euart/euart.c @@ -0,0 +1,148 @@ +#include +#include +#include + +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; +} diff --git a/src/revolution/exi/EXIBios.c b/src/revolution/exi/EXIBios.c new file mode 100644 index 0000000000..19290be936 --- /dev/null +++ b/src/revolution/exi/EXIBios.c @@ -0,0 +1,876 @@ +#include + +#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"; + } +} diff --git a/src/revolution/exi/EXICommon.c b/src/revolution/exi/EXICommon.c new file mode 100644 index 0000000000..e53525fbba --- /dev/null +++ b/src/revolution/exi/EXICommon.c @@ -0,0 +1,113 @@ +#include +#include +#include + +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, ®32, 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; +} diff --git a/src/revolution/exi/EXIUart.c b/src/revolution/exi/EXIUart.c new file mode 100644 index 0000000000..0a14c130b0 --- /dev/null +++ b/src/revolution/exi/EXIUart.c @@ -0,0 +1,190 @@ +#include +#include +#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; +} diff --git a/src/revolution/gd/GDBase.c b/src/revolution/gd/GDBase.c new file mode 100644 index 0000000000..2195dc602d --- /dev/null +++ b/src/revolution/gd/GDBase.c @@ -0,0 +1,45 @@ +#include +#include + +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; +} diff --git a/src/revolution/gd/GDFile.c b/src/revolution/gd/GDFile.c new file mode 100644 index 0000000000..0d890a8516 --- /dev/null +++ b/src/revolution/gd/GDFile.c @@ -0,0 +1,64 @@ +#include +#include + +#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; +} diff --git a/src/revolution/gd/GDGeometry.c b/src/revolution/gd/GDGeometry.c new file mode 100644 index 0000000000..79b098114e --- /dev/null +++ b/src/revolution/gd/GDGeometry.c @@ -0,0 +1,418 @@ +#include +#include + +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); +} diff --git a/src/revolution/gd/GDIndirect.c b/src/revolution/gd/GDIndirect.c new file mode 100644 index 0000000000..b2d221fd71 --- /dev/null +++ b/src/revolution/gd/GDIndirect.c @@ -0,0 +1,270 @@ +#include +#include + +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)); +} diff --git a/src/revolution/gd/GDLight.c b/src/revolution/gd/GDLight.c new file mode 100644 index 0000000000..15e6a64233 --- /dev/null +++ b/src/revolution/gd/GDLight.c @@ -0,0 +1,206 @@ +#include +#include + +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); + } +} diff --git a/src/revolution/gd/GDPixel.c b/src/revolution/gd/GDPixel.c new file mode 100644 index 0000000000..a14ddceee3 --- /dev/null +++ b/src/revolution/gd/GDPixel.c @@ -0,0 +1,118 @@ +#include +#include + +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)); +} diff --git a/src/revolution/gd/GDTev.c b/src/revolution/gd/GDTev.c new file mode 100644 index 0000000000..4aba7e8686 --- /dev/null +++ b/src/revolution/gd/GDTev.c @@ -0,0 +1,159 @@ +#include +#include + +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 + )); +} diff --git a/src/revolution/gd/GDTexture.c b/src/revolution/gd/GDTexture.c new file mode 100644 index 0000000000..748132e4d0 --- /dev/null +++ b/src/revolution/gd/GDTexture.c @@ -0,0 +1,104 @@ +#include +#include + +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); +} diff --git a/src/revolution/gd/GDTransform.c b/src/revolution/gd/GDTransform.c new file mode 100644 index 0000000000..c1c17ef0a1 --- /dev/null +++ b/src/revolution/gd/GDTransform.c @@ -0,0 +1,127 @@ +#include +#include + +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); +} diff --git a/src/revolution/gf/GFGeometry.cpp b/src/revolution/gf/GFGeometry.cpp new file mode 100644 index 0000000000..699ab207c8 --- /dev/null +++ b/src/revolution/gf/GFGeometry.cpp @@ -0,0 +1,10 @@ +#include +#include + +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); +} diff --git a/src/revolution/gf/GFLight.cpp b/src/revolution/gf/GFLight.cpp new file mode 100644 index 0000000000..8234f0eda9 --- /dev/null +++ b/src/revolution/gf/GFLight.cpp @@ -0,0 +1,6 @@ +#include +#include + +void GFSetChanAmbColor(GXChannelID chan, GXColor color) { + GFWriteXFCmd((chan & 1) + XF_REG_AMBIENT0_ID, color.r << 0x18 | color.g << 0x10 | color.b << 8 | color.a); +} diff --git a/src/revolution/gf/GFPixel.cpp b/src/revolution/gf/GFPixel.cpp new file mode 100644 index 0000000000..b3dbf0723d --- /dev/null +++ b/src/revolution/gf/GFPixel.cpp @@ -0,0 +1,74 @@ +#include +#include + +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)); +} diff --git a/src/revolution/gf/GFTev.cpp b/src/revolution/gf/GFTev.cpp new file mode 100644 index 0000000000..be98b5f0b6 --- /dev/null +++ b/src/revolution/gf/GFTev.cpp @@ -0,0 +1,15 @@ +#include +#include + +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); +} diff --git a/src/revolution/gx/GXAttr.c b/src/revolution/gx/GXAttr.c new file mode 100644 index 0000000000..b60f1063b9 --- /dev/null +++ b/src/revolution/gx/GXAttr.c @@ -0,0 +1,637 @@ +#include +#include + +#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; +} diff --git a/src/revolution/gx/GXBump.c b/src/revolution/gx/GXBump.c new file mode 100644 index 0000000000..0ce04a08b9 --- /dev/null +++ b/src/revolution/gx/GXBump.c @@ -0,0 +1,308 @@ +#include +#include + +#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; +} diff --git a/src/revolution/gx/GXDisplayList.c b/src/revolution/gx/GXDisplayList.c new file mode 100644 index 0000000000..747f9749bf --- /dev/null +++ b/src/revolution/gx/GXDisplayList.c @@ -0,0 +1,99 @@ +#include + +#include +#include + +#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); +} diff --git a/src/revolution/gx/GXDraw.c b/src/revolution/gx/GXDraw.c new file mode 100644 index 0000000000..30557b0dc6 --- /dev/null +++ b/src/revolution/gx/GXDraw.c @@ -0,0 +1,551 @@ +#include + +#include +#include + +#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; +} diff --git a/src/revolution/gx/GXFifo.c b/src/revolution/gx/GXFifo.c new file mode 100644 index 0000000000..b5e3784085 --- /dev/null +++ b/src/revolution/gx/GXFifo.c @@ -0,0 +1,614 @@ +#include +#include +#include + +#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); +} diff --git a/src/revolution/gx/GXFrameBuf.c b/src/revolution/gx/GXFrameBuf.c new file mode 100644 index 0000000000..e22bbb2b77 --- /dev/null +++ b/src/revolution/gx/GXFrameBuf.c @@ -0,0 +1,677 @@ +#include +#include + +#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); +} diff --git a/src/revolution/gx/GXGeometry.c b/src/revolution/gx/GXGeometry.c new file mode 100644 index 0000000000..f585938fa1 --- /dev/null +++ b/src/revolution/gx/GXGeometry.c @@ -0,0 +1,267 @@ +#include +#include +#include + +#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; +} diff --git a/src/revolution/gx/GXInit.c b/src/revolution/gx/GXInit.c new file mode 100644 index 0000000000..e7ecba2b8b --- /dev/null +++ b/src/revolution/gx/GXInit.c @@ -0,0 +1,567 @@ +#include + +#include +#include +#include +#include + +#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(); +} diff --git a/src/revolution/gx/GXLight.c b/src/revolution/gx/GXLight.c new file mode 100644 index 0000000000..b371eb1fae --- /dev/null +++ b/src/revolution/gx/GXLight.c @@ -0,0 +1,571 @@ +#include +#include +#include + +#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<chanCtrl[GX_ALPHA0] = reg; + __GXData->dirtyState |= (0x00001000|0x00004000); + } else if (chan == GX_COLOR1A1) { + __GXData->chanCtrl[GX_ALPHA1] = reg; + __GXData->dirtyState |= (0x00002000|0x00008000); + } +} diff --git a/src/revolution/gx/GXMisc.c b/src/revolution/gx/GXMisc.c new file mode 100644 index 0000000000..46980ceeb4 --- /dev/null +++ b/src/revolution/gx/GXMisc.c @@ -0,0 +1,482 @@ +#include +#include +#include +#include + +#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; +} diff --git a/src/revolution/gx/GXPerf.c b/src/revolution/gx/GXPerf.c new file mode 100644 index 0000000000..26d094e3fa --- /dev/null +++ b/src/revolution/gx/GXPerf.c @@ -0,0 +1,431 @@ +#include +#include + +#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; +} diff --git a/src/revolution/gx/GXPixel.c b/src/revolution/gx/GXPixel.c new file mode 100644 index 0000000000..a68a119305 --- /dev/null +++ b/src/revolution/gx/GXPixel.c @@ -0,0 +1,332 @@ +#include +#include +#include + +#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(); +} diff --git a/src/revolution/gx/GXSave.c b/src/revolution/gx/GXSave.c new file mode 100644 index 0000000000..5f3ff31413 --- /dev/null +++ b/src/revolution/gx/GXSave.c @@ -0,0 +1,528 @@ +#if DEBUG + +#include +#include + +#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(®8, 1) && __ReadMem(&d32, 4)) { + vatIdx = reg8 & 0xF; + cpAddr = (reg8& 0xF0) >> 4; + __SaveCPRegs(cpAddr, vatIdx, d32); + } + break; + case 2: + if (__ReadMem(®32, 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(®32, 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(®32, 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 diff --git a/src/revolution/gx/GXStubs.c b/src/revolution/gx/GXStubs.c new file mode 100644 index 0000000000..8716e2ea26 --- /dev/null +++ b/src/revolution/gx/GXStubs.c @@ -0,0 +1,5 @@ +#include + +#include "__gx.h" + +void __GXSetRange(f32 nearz, f32 fgSideX) {} diff --git a/src/revolution/gx/GXTev.c b/src/revolution/gx/GXTev.c new file mode 100644 index 0000000000..1565865615 --- /dev/null +++ b/src/revolution/gx/GXTev.c @@ -0,0 +1,465 @@ +#include +#include + +#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; +} diff --git a/src/revolution/gx/GXTexture.c b/src/revolution/gx/GXTexture.c new file mode 100644 index 0000000000..532294078b --- /dev/null +++ b/src/revolution/gx/GXTexture.c @@ -0,0 +1,1315 @@ +#include +#include +#include + +#include "__gx.h" + +// GXTexObj internal data +typedef struct __GXTexObjInt_struct { + u32 mode0; + u32 mode1; + u32 image0; + u32 image3; + void* userData; + GXTexFmt fmt; + u32 tlutName; + u16 loadCnt; + u8 loadFmt; + u8 flags; +} __GXTexObjInt; + +// GXTexRegion internal data +typedef struct __GXTexRegionInt_struct { + u32 image1; + u32 image2; + u16 sizeEven; + u16 sizeOdd; + u8 is32bMipmap; + u8 isCached; +} __GXTexRegionInt; + +// GXTlutObj internal data +typedef struct __GXTlutObjInt_struct { + u32 tlut; + u32 loadTlut0; + u16 numEntries; +} __GXTlutObjInt; + +// GXTlutRegion internal data +typedef struct __GXTlutRegionInt_struct { + u32 loadTlut1; + __GXTlutObjInt tlutObj; +} __GXTlutRegionInt; + +u8 GXTexMode0Ids[8] = { 0x80, 0x81, 0x82, 0x83, 0xA0, 0xA1, 0xA2, 0xA3 }; +u8 GXTexMode1Ids[8] = { 0x84, 0x85, 0x86, 0x87, 0xA4, 0xA5, 0xA6, 0xA7 }; +u8 GXTexImage0Ids[8] = { 0x88, 0x89, 0x8A, 0x8B, 0xA8, 0xA9, 0xAA, 0xAB }; +u8 GXTexImage1Ids[8] = { 0x8C, 0x8D, 0x8E, 0x8F, 0xAC, 0xAD, 0xAE, 0xAF }; +u8 GXTexImage2Ids[8] = { 0x90, 0x91, 0x92, 0x93, 0xB0, 0xB1, 0xB2, 0xB3 }; +u8 GXTexImage3Ids[8] = { 0x94, 0x95, 0x96, 0x97, 0xB4, 0xB5, 0xB6, 0xB7 }; +u8 GXTexTlutIds[8] = { 0x98, 0x99, 0x9A, 0x9B, 0xB8, 0xB9, 0xBA, 0xBB }; +static u8 GX2HWFiltConv[6] = { 0x00, 0x04, 0x01, 0x05, 0x02, 0x06 }; +static u8 HW2GXFiltConv[8] = { 0x00, 0x02, 0x04, 0x00, 0x01, 0x03, 0x05, 0x00 }; + +static void __GXGetTexTileShift(GXTexFmt fmt, u32* rowTileS, u32* colTileS) { + switch (fmt) { + case GX_TF_I4: + case 0x8: + case GX_TF_CMPR: + case GX_CTF_R4: + case GX_CTF_Z4: + *rowTileS = 3; + *colTileS = 3; + break; + case GX_TF_I8: + case GX_TF_IA4: + case 0x9: + case GX_TF_Z8: + case GX_CTF_RA4: + case GX_TF_A8: + case GX_CTF_R8: + case GX_CTF_G8: + case GX_CTF_B8: + case GX_CTF_Z8M: + case GX_CTF_Z8L: + *rowTileS = 3; + *colTileS = 2; + break; + case GX_TF_IA8: + case GX_TF_RGB565: + case GX_TF_RGB5A3: + case GX_TF_RGBA8: + case 0xA: + case GX_TF_Z16: + case GX_TF_Z24X8: + case GX_CTF_RA8: + case GX_CTF_RG8: + case GX_CTF_GB8: + case GX_CTF_Z16L: + *rowTileS = 2; + *colTileS = 2; + break; + default: + *rowTileS = *colTileS = 0; + ASSERTMSGLINEV(447, 0, "%s: invalid texture format", "GX"); + break; + } +} + +u32 GXGetTexBufferSize(u16 width, u16 height, u32 format, GXBool mipmap, u8 max_lod) { + u32 tileShiftX; + u32 tileShiftY; + u32 tileBytes; + u32 bufferSize; + u32 nx; + u32 ny; + u32 level; + + ASSERTMSGLINEV(463, width <= 1024, "%s: width too large", "GXGetTexBufferSize"); + ASSERTMSGLINEV(464, height <= 1024, "%s: height too large", "GXGetTexBufferSize"); + + __GXGetTexTileShift(format, &tileShiftX, &tileShiftY); + if (format == GX_TF_RGBA8 || format == GX_TF_Z24X8) { + tileBytes = 64; + } else { + tileBytes = 32; + } + + if (mipmap == GX_TRUE) { + nx = 1 << (31 - __cntlzw(width)); + ASSERTMSGLINEV(482, width == nx, "%s: width must be a power of 2", "GXGetTexBufferSize"); + ny = 1 << (31 - __cntlzw(height)); + ASSERTMSGLINEV(485, height == ny, "%s: height must be a power of 2", "GXGetTexBufferSize"); + + bufferSize = 0; + for (level = 0; level < max_lod; level++) { + nx = (width + (1 << tileShiftX) - 1) >> tileShiftX; + ny = (height + (1 << tileShiftY) - 1) >> tileShiftY; + bufferSize += tileBytes * (nx * ny); + if (width == 1 && height == 1) { + break; + } + width = (width > 1) ? width >> 1 : 1; + height = (height > 1) ? height >> 1 : 1; + } + } else { + nx = (width + (1 << tileShiftX) - 1) >> tileShiftX; + ny = (height + (1 << tileShiftY) - 1) >> tileShiftY; + bufferSize = nx * ny * tileBytes; + } + + return bufferSize; +} + +void __GetImageTileCount(GXTexFmt fmt, u16 wd, u16 ht, u32* rowTiles, u32* colTiles, u32* cmpTiles) { + u32 texRowShift; + u32 texColShift; + + __GXGetTexTileShift(fmt, &texRowShift, &texColShift); + if (wd == 0) { + wd = 1; + } + if (ht == 0) { + ht = 1; + } + *rowTiles = (wd + (1 << texRowShift) - 1) >> texRowShift; + *colTiles = (ht + (1 << texColShift) - 1) >> texColShift; + *cmpTiles = (fmt == GX_TF_RGBA8 || fmt == GX_TF_Z24X8) ? 2 : 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 GXInitTexObj(GXTexObj* obj, void* image_ptr, u16 width, u16 height, GXTexFmt format, GXTexWrapMode wrap_s, GXTexWrapMode wrap_t, GXBool mipmap) { + u32 imageBase; + u32 maxLOD; + u16 rowT; + u16 colT; + u32 rowC; + u32 colC; + __GXTexObjInt* t = (__GXTexObjInt*)obj; + + ASSERTMSGLINE(567, obj, "Texture Object Pointer is null"); + CHECK_GXBEGIN(569, "GXInitTexObj"); + ASSERTMSGLINEV(570, width <= 1024, "%s: width too large", "GXInitTexObj"); + ASSERTMSGLINEV(571, height <= 1024, "%s: height too large", "GXInitTexObj"); + ASSERTMSGLINEV(573, !(format & _GX_TF_CTF), "%s: invalid texture format", "GXInitTexObj"); + +#if DEBUG + if (wrap_s != GX_CLAMP || mipmap) { + u32 mask = 1 << (31 - __cntlzw(width)); + ASSERTMSGLINEV(583, width == mask, "%s: width must be a power of 2", "GXInitTexObj"); + } + if (wrap_t != GX_CLAMP || mipmap) { + u32 mask = 1 << (31 - __cntlzw(height)); + ASSERTMSGLINEV(588, height == mask, "%s: height must be a power of 2", "GXInitTexObj"); + } +#endif + + memset(t, 0, 0x20); + SET_REG_FIELD(602, t->mode0, 2, 0, wrap_s); + SET_REG_FIELD(603, t->mode0, 2, 2, wrap_t); + SET_REG_FIELD(604, t->mode0, 1, 4, 1); + + if (mipmap) { + u8 lmax; + t->flags |= 1; + + if (format == 8 || format == 9 || format == 10) { + SOME_SET_REG_MACRO(t->mode0, 3, 5, 5); + } else { + SOME_SET_REG_MACRO(t->mode0, 3, 5, 6); + } + + + if (width > height) { + maxLOD = 31 - __cntlzw(width); + } else { + maxLOD = 31 - __cntlzw(height); + } + + lmax = 16.0f * maxLOD; + SET_REG_FIELD(634, t->mode1, 8, 8, lmax); + } else { + SOME_SET_REG_MACRO(t->mode0, 3, 5, 4); + } + + t->fmt = format; + SET_REG_FIELD(648, t->image0, 10, 0, width - 1); + SET_REG_FIELD(649, t->image0, 10, 10, height - 1); + SET_REG_FIELD(650, t->image0, 4, 20, format & 0xF); + ASSERTMSGLINEV(656, ((u32)image_ptr & 0x1F) == 0, "%s: %s pointer not aligned to 32B", "GXInitTexObj", "image"); + imageBase = GX_PHY_ADDR(image_ptr) >> 5; + SET_REG_FIELD(658, t->image3, 24, 0, imageBase); + + switch (format & 0xF) { + case GX_TF_I4: + case 8: + t->loadFmt = 1; + rowT = 3; + colT = 3; + break; + case GX_TF_I8: + case GX_TF_IA4: + case 9: + t->loadFmt = 2; + rowT = 3; + colT = 2; + break; + case GX_TF_IA8: + case GX_TF_RGB565: + case GX_TF_RGB5A3: + case 10: + t->loadFmt = 2; + rowT = 2; + colT = 2; + break; + case GX_TF_RGBA8: + t->loadFmt = 3; + rowT = 2; + colT = 2; + break; + case GX_TF_CMPR: + t->loadFmt = 0; + rowT = 3; + colT = 3; + break; + default: + ASSERTMSGLINEV(701, 0, "%s: invalid texture format", "GXPreLoadEntireTexture"); + t->loadFmt = 2; + rowT = 2; + colT = 2; + break; + } + + rowC = (width + (1 << rowT) - 1) >> rowT; + colC = (height + (1 << colT) - 1) >> colT; + t->loadCnt = (rowC * colC) & 0x7FFF; + t->flags |= 2; +} + +void GXInitTexObjCI(GXTexObj* obj, void* image_ptr, u16 width, u16 height, GXCITexFmt format, GXTexWrapMode wrap_s, GXTexWrapMode wrap_t, GXBool mipmap, u32 tlut_name) { + __GXTexObjInt* t = (__GXTexObjInt*)obj; + + ASSERTMSGLINE(739, obj, "Texture Object Pointer is null"); + CHECK_GXBEGIN(741, "GXInitTexObjCI"); + GXInitTexObj(obj, image_ptr, width, height, format, wrap_s, wrap_t, mipmap); + t->flags &= 0xFFFFFFFD; + t->tlutName = tlut_name; +} + +void GXInitTexObjLOD(GXTexObj* obj, 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) { + u8 lbias; + u8 lmin; + u8 lmax; + __GXTexObjInt* t = (__GXTexObjInt*)obj; + + ASSERTMSGLINE(778, obj, "Texture Object Pointer is null"); + CHECK_GXBEGIN(780, "GXInitTexObjLOD"); + + if (lod_bias < -4.0f) { + lod_bias = -4.0f; + } else if (lod_bias >= 4.0f) { + lod_bias = 3.99f; + } + + lbias = (u8)(32.0f * lod_bias) & 0xFF; + SET_REG_FIELD(790, t->mode0, 8, 9, lbias); + ASSERTMSG1LINE(793, (u32)mag_filt <= 1, "%s: invalid mag_filt value", "GXInitTexObjLOD"); + SET_REG_FIELD(794, t->mode0, 1, 4, (mag_filt == GX_LINEAR) ? 1 : 0); + ASSERTMSG1LINE(797, (u32)min_filt <= 5, "%s: invalid min_filt value", "GXInitTexObjLOD"); + SET_REG_FIELD(798, t->mode0, 3, 5, GX2HWFiltConv[min_filt]); + SET_REG_FIELD(800, t->mode0, 1, 8, do_edge_lod ? 0 : 1); + SET_REG_FIELD(801, t->mode0, 1, 17, 0); + SET_REG_FIELD(801, t->mode0, 1, 18, 0); + SET_REG_FIELD(803, t->mode0, 2, 19, max_aniso); + SET_REG_FIELD(804, t->mode0, 1, 21, bias_clamp); + + if (min_lod < 0.0f) { + min_lod = 0.0f; + } else if (min_lod > 10.0f) { + min_lod = 10.0f; + } + lmin = 16.0f * min_lod; + if (max_lod < 0.0f) { + max_lod = 0.0f; + } else if (max_lod > 10.0f) { + max_lod = 10.0f; + } + lmax = 16.0f * max_lod; + SET_REG_FIELD(818, t->mode1, 8, 0, lmin); + SET_REG_FIELD(819, t->mode1, 8, 8, lmax); +} + +void GXInitTexObjData(GXTexObj* obj, void* image_ptr) { + u32 imageBase; + __GXTexObjInt* t = (__GXTexObjInt*)obj; + + ASSERTMSGLINE(835, obj, "Texture Object Pointer is null"); + CHECK_GXBEGIN(837, "GXInitTexObjData"); + ASSERTMSGLINEV(840, ((u32)image_ptr & 0x1F) == 0, "%s: %s pointer not aligned to 32B", "GXInitTexObjData", "image"); + imageBase = ((u32)image_ptr >> 5) & 0x01FFFFFF; + SET_REG_FIELD(843, t->image3, 21, 0, imageBase); +} + +void GXInitTexObjWrapMode(GXTexObj* obj, GXTexWrapMode sm, GXTexWrapMode tm) { + __GXTexObjInt* t = (__GXTexObjInt*)obj; + + ASSERTMSGLINE(860, obj, "Texture Object Pointer is null"); + CHECK_GXBEGIN(862, "GXInitTexObjWrapMode"); + SET_REG_FIELD(864, t->mode0, 2, 0, sm); + SET_REG_FIELD(865, t->mode0, 2, 2, tm); +} + +void GXInitTexObjTlut(GXTexObj* obj, u32 tlut_name) { + __GXTexObjInt* t = (__GXTexObjInt*)obj; + + ASSERTMSGLINE(881, obj, "Texture Object Pointer is null"); + CHECK_GXBEGIN(883, "GXInitTexObjTlut"); + t->tlutName = tlut_name; +} + +void GXInitTexObjFilter(GXTexObj* obj, GXTexFilter min_filt, GXTexFilter mag_filt) { + __GXTexObjInt* t = (__GXTexObjInt*)obj; + + ASSERTMSGLINE(902, obj, "Texture Object Pointer is null"); + CHECK_GXBEGIN(904, "GXInitTexObjFilter"); + + ASSERTMSG1LINE(907, (u32)mag_filt <= 1, "%s: invalid mag_filt value", "GXInitTexObjFilter"); + SET_REG_FIELD(908, t->mode0, 1, 4, mag_filt == 1 ? 1 : 0); + + ASSERTMSG1LINE(911, (u32)min_filt <= 5, "%s: invalid min_filt value", "GXInitTexObjFilter"); + SET_REG_FIELD(912, t->mode0, 3, 5, GX2HWFiltConv[min_filt]); +} + +void GXInitTexObjMaxLOD(GXTexObj* obj, f32 max_lod) { + u8 lmax; + __GXTexObjInt* t = (__GXTexObjInt*)obj; + + ASSERTMSGLINE(930, obj, "Texture Object Pointer is null"); + CHECK_GXBEGIN(932, "GXInitTexObjMaxLOD"); + + if (max_lod < 0.0f) { + max_lod = 0.0f; + } else if (max_lod > 10.0f) { + max_lod = 10.0f; + } + lmax = 16.0f * max_lod; + SET_REG_FIELD(938, t->mode1, 8, 8, lmax); +} + +void GXInitTexObjMinLOD(GXTexObj* obj, f32 min_lod) { + u8 lmin; + __GXTexObjInt* t = (__GXTexObjInt*)obj; + + ASSERTMSGLINE(956, obj, "Texture Object Pointer is null"); + CHECK_GXBEGIN(958, "GXInitTexObjMinLOD"); + + if (min_lod < 0.0f) { + min_lod = 0.0f; + } else if (min_lod > 10.0f) { + min_lod = 10.0f; + } + lmin = 16.0f * min_lod; + SET_REG_FIELD(964, t->mode1, 8, 0, lmin); +} + +void GXInitTexObjLODBias(GXTexObj* obj, f32 lod_bias) { + u8 lbias; + __GXTexObjInt* t = (__GXTexObjInt*)obj; + + ASSERTMSGLINE(982, obj, "Texture Object Pointer is null"); + CHECK_GXBEGIN(984, "GXInitTexObjLODBias"); + + if (lod_bias < -4.0f) { + lod_bias = -4.0f; + } else if (lod_bias >= 4.0f) { + lod_bias = 3.99f; + } + lbias = 32.0f * lod_bias; + SET_REG_FIELD(991, t->mode0, 8, 9, lbias); +} + +void GXInitTexObjBiasClamp(GXTexObj* obj, u8 bias_clamp) { + __GXTexObjInt* t = (__GXTexObjInt*)obj; + + ASSERTMSGLINE(1007, obj, "Texture Object Pointer is null"); + CHECK_GXBEGIN(1009, "GXInitTexObjBiasClamp"); + + SET_REG_FIELD(1011, t->mode0, 1, 21, bias_clamp); +} + +void GXInitTexObjEdgeLOD(GXTexObj* obj, u8 do_edge_lod) { + __GXTexObjInt* t = (__GXTexObjInt*)obj; + + ASSERTMSGLINE(1027, obj, "Texture Object Pointer is null"); + CHECK_GXBEGIN(1029, "GXInitTexObjEdgeLOD"); + + SET_REG_FIELD(1031, t->mode0, 1, 8, do_edge_lod ? 0 : 1); +} + +void GXInitTexObjMaxAniso(GXTexObj* obj, GXAnisotropy max_aniso) { + __GXTexObjInt* t = (__GXTexObjInt*)obj; + + ASSERTMSGLINE(1047, obj, "Texture Object Pointer is null"); + CHECK_GXBEGIN(1049, "GXInitTexObjMaxAniso"); + + SET_REG_FIELD(1051, t->mode0, 2, 19, max_aniso); +} + +void GXInitTexObjUserData(GXTexObj* obj, void* user_data) { + __GXTexObjInt* t = (__GXTexObjInt*)obj; + + ASSERTMSGLINE(1068, obj, "Texture Object Pointer is null"); + CHECK_GXBEGIN(1069, "GXInitTexObjUserData"); + t->userData = user_data; +} + +void* GXGetTexObjUserData(const GXTexObj* obj) { + const __GXTexObjInt* t = (const __GXTexObjInt *)obj; + + ASSERTMSGLINE(1075, obj, "Texture Object Pointer is null"); + return t->userData; +} + +void GXGetTexObjAll(const GXTexObj* obj, void** image_ptr, u16* width, u16* height, GXTexFmt* format, GXTexWrapMode* wrap_s, GXTexWrapMode* wrap_t, u8* mipmap) { + const __GXTexObjInt* t = (const __GXTexObjInt *)obj; + + ASSERTMSGLINE(1095, obj, "Texture Object Pointer is null"); + *image_ptr = (void *)(GET_REG_FIELD(t->image3, 21, 0) << 5); + *width = (u32)GET_REG_FIELD(t->image0, 10, 0) + 1; + *height = (u32)GET_REG_FIELD(t->image0, 10, 10) + 1; + *format = t->fmt; + *wrap_s = GET_REG_FIELD(t->mode0, 2, 0); + *wrap_t = GET_REG_FIELD(t->mode0, 2, 2); + *mipmap = (t->flags & 1) == 1; +} + +void* GXGetTexObjData(const GXTexObj* to) { + const __GXTexObjInt* t = (const __GXTexObjInt *)to; + + ASSERTMSGLINE(1108, to, "Texture Object Pointer is null"); + return (void*)(GET_REG_FIELD(t->image3, 21, 0) << 5); +} + +u16 GXGetTexObjWidth(const GXTexObj* to) { + const __GXTexObjInt* t = (const __GXTexObjInt *)to; + + ASSERTMSGLINE(1116, to, "Texture Object Pointer is null"); + return (u32)GET_REG_FIELD(t->image0, 10, 0) + 1; +} + +u16 GXGetTexObjHeight(const GXTexObj* to) { + const __GXTexObjInt* t = (const __GXTexObjInt *)to; + + ASSERTMSGLINE(1122, to, "Texture Object Pointer is null"); + return (u32)GET_REG_FIELD(t->image0, 10, 10) + 1; +} + +GXTexFmt GXGetTexObjFmt(const GXTexObj* to) { + const __GXTexObjInt* t = (const __GXTexObjInt *)to; + + ASSERTMSGLINE(1128, to, "Texture Object Pointer is null"); + return t->fmt; +} + +GXTexWrapMode GXGetTexObjWrapS(const GXTexObj* to) { + const __GXTexObjInt* t = (const __GXTexObjInt *)to; + + ASSERTMSGLINE(1134, to, "Texture Object Pointer is null"); + return GET_REG_FIELD(t->mode0, 2, 0); +} + +GXTexWrapMode GXGetTexObjWrapT(const GXTexObj* to) { + const __GXTexObjInt* t = (const __GXTexObjInt *)to; + + ASSERTMSGLINE(1140, to, "Texture Object Pointer is null"); + return GET_REG_FIELD(t->mode0, 2, 2); +} + +GXBool GXGetTexObjMipMap(const GXTexObj* to) { + const __GXTexObjInt* t = (const __GXTexObjInt *)to; + + ASSERTMSGLINE(1146, to, "Texture Object Pointer is null"); + return (t->flags & 1) == 1; +} + +void GXGetTexObjLODAll(const GXTexObj* tex_obj, 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) { + s16 tmp; + const __GXTexObjInt* t = (const __GXTexObjInt *)tex_obj; + + ASSERTMSGLINE(1166, tex_obj, "Texture Object Pointer is null"); + *min_filt = HW2GXFiltConv[GET_REG_FIELD(t->mode0, 3, 5)]; + *mag_filt = GET_REG_FIELD(t->mode0, 1, 4); + *min_lod = (u8)t->mode1 / 16.0f; + *max_lod = (u32)GET_REG_FIELD(t->mode1, 8, 8) / 16.0f; + tmp = (s32)GET_REG_FIELD(t->mode0, 8, 9); + *lod_bias = (s8)tmp / 32.0f; + *bias_clamp = (u32)GET_REG_FIELD(t->mode0, 1, 21); + *do_edge_lod = !GET_REG_FIELD(t->mode0, 1, 8); + *max_aniso = GET_REG_FIELD(t->mode0, 2, 19); +} + +GXTexFilter GXGetTexObjMinFilt(const GXTexObj* tex_obj) { + const __GXTexObjInt* t = (const __GXTexObjInt *)tex_obj; + + ASSERTMSGLINE(1182, tex_obj, "Texture Object Pointer is null"); + return HW2GXFiltConv[GET_REG_FIELD(t->mode0, 3, 5)]; +} + +GXTexFilter GXGetTexObjMagFilt(const GXTexObj* tex_obj) { + const __GXTexObjInt* t = (const __GXTexObjInt *)tex_obj; + + ASSERTMSGLINE(1189, tex_obj, "Texture Object Pointer is null"); + return GET_REG_FIELD(t->mode0, 1, 4); +} + +f32 GXGetTexObjMinLOD(const GXTexObj* tex_obj) { + const __GXTexObjInt* t = (const __GXTexObjInt *)tex_obj; + + ASSERTMSGLINE(1195, tex_obj, "Texture Object Pointer is null"); + return (u32)GET_REG_FIELD(t->mode1, 8, 0) / 16.0f; +} + +f32 GXGetTexObjMaxLOD(const GXTexObj* tex_obj) { + const __GXTexObjInt* t = (const __GXTexObjInt *)tex_obj; + + ASSERTMSGLINE(1201, tex_obj, "Texture Object Pointer is null"); + return (u32)GET_REG_FIELD(t->mode1, 8, 8) / 16.0f; +} + +f32 GXGetTexObjLODBias(const GXTexObj* tex_obj) { + s16 tmp; + const __GXTexObjInt* t = (const __GXTexObjInt *)tex_obj; + + ASSERTMSGLINE(1208, tex_obj, "Texture Object Pointer is null"); + tmp = (s32)GET_REG_FIELD(t->mode0, 8, 9); + return (s8)tmp / 32.0f; +} + +GXBool GXGetTexObjBiasClamp(const GXTexObj* tex_obj) { + const __GXTexObjInt* t = (const __GXTexObjInt *)tex_obj; + + ASSERTMSGLINE(1215, tex_obj, "Texture Object Pointer is null"); + return (u32)GET_REG_FIELD(t->mode0, 1, 21); +} + +GXBool GXGetTexObjEdgeLOD(const GXTexObj* tex_obj) { + const __GXTexObjInt* t = (const __GXTexObjInt *)tex_obj; + + ASSERTMSGLINE(1221, tex_obj, "Texture Object Pointer is null"); + return !GET_REG_FIELD(t->mode0, 1, 8); +} + +GXAnisotropy GXGetTexObjMaxAniso(const GXTexObj* tex_obj) { + const __GXTexObjInt* t = (const __GXTexObjInt *)tex_obj; + + ASSERTMSGLINE(1227, tex_obj, "Texture Object Pointer is null"); + return GET_REG_FIELD(t->mode0, 2, 19); +} + +u32 GXGetTexObjTlut(const GXTexObj* tex_obj) { + const __GXTexObjInt* t = (const __GXTexObjInt *)tex_obj; + + ASSERTMSGLINE(1235, tex_obj, "Texture Object Pointer is null"); + return t->tlutName; +} + +void GXLoadTexObjPreLoaded(GXTexObj* obj, GXTexRegion* region, GXTexMapID id) { + __GXTlutRegionInt* tlr; + u32 m0; + u32 m1; + u32 img0; + u32 img1; + u32 img2; + u32 img3; + __GXTexObjInt* t = (__GXTexObjInt*)obj; + __GXTexRegionInt* r = (__GXTexRegionInt *)region; + + ASSERTMSGLINE(1259, obj, "Texture Object Pointer is null"); + ASSERTMSGLINE(1259, region, "TexRegion Object Pointer is null"); + CHECK_GXBEGIN(1261, "GXLoadTexObjPreLoaded"); + ASSERTMSGLINEV(1262, id < GX_MAX_TEXMAP, "%s: invalid texture map ID", "GXLoadTexObj"); + + m0 = t->mode0; + m1 = t->mode1; + img0 = t->image0; + img1 = r->image1; + img2 = r->image2; + img3 = t->image3; + + SET_REG_FIELD(1273, t->mode0, 8, 24, GXTexMode0Ids[id]); + SET_REG_FIELD(1274, t->mode1, 8, 24, GXTexMode1Ids[id]); + SET_REG_FIELD(1275, t->image0, 8, 24, GXTexImage0Ids[id]); + SET_REG_FIELD(1276, r->image1, 8, 24, GXTexImage1Ids[id]); + SET_REG_FIELD(1277, r->image2, 8, 24, GXTexImage2Ids[id]); + SET_REG_FIELD(1278, t->image3, 8, 24, GXTexImage3Ids[id]); + + GX_WRITE_RAS_REG(t->mode0); + GX_WRITE_RAS_REG(t->mode1); + GX_WRITE_RAS_REG(t->image0); + GX_WRITE_RAS_REG(r->image1); + GX_WRITE_RAS_REG(r->image2); + GX_WRITE_RAS_REG(t->image3); + + if (!(t->flags & 2)) { + ASSERTMSGLINEV(1289, __GXData->tlutRegionCallback, "%s: Tex/Tlut Region Callback not set", "GXLoadTexObj/PreLoaded"); + tlr = (__GXTlutRegionInt*)__GXData->tlutRegionCallback(t->tlutName); + ASSERTMSGLINEV(1291, tlr, "%s: Tex/Tlut Region Callback returns NULL", "GXLoadTexObj/PreLoaded"); + + SET_REG_FIELD(1293, tlr->tlutObj.tlut, 8, 24, GXTexTlutIds[id]); + GX_WRITE_RAS_REG(tlr->tlutObj.tlut); + } + + __GXData->tImage0[id] = t->image0; + __GXData->tMode0[id] = t->mode0; + __GXData->dirtyState |= 1; + __GXData->bpSentNot = 0; +} + +void GXLoadTexObj(GXTexObj* obj, GXTexMapID id) { + GXTexRegion* r; + + CHECK_GXBEGIN(1320, "GXLoadTexObj"); + ASSERTMSGLINEV(1321, id < 8, "%s: invalid texture map ID", "GXLoadTexObj"); + ASSERTMSGLINEV(1326, __GXData->texRegionCallback, "%s: Tex/Tlut Region Callback not set", "GXLoadTexObj"); + r = __GXData->texRegionCallback(obj, id); + ASSERTMSGLINEV(1328, r, "%s: Tex/Tlut Region Callback returns NULL", "GXLoadTexObj"); + GXLoadTexObjPreLoaded(obj, r, id); +} + +void GXInitTlutObj(GXTlutObj* tlut_obj, void* lut, GXTlutFmt fmt, u16 n_entries) { + __GXTlutObjInt* t = (__GXTlutObjInt *)tlut_obj; + + ASSERTMSGLINE(1352, tlut_obj, "TLut Object Pointer is null"); + CHECK_GXBEGIN(1353, "GXInitTlutObj"); + ASSERTMSGLINEV(1356, n_entries <= 0x4000, "%s: number of entries exceeds maximum", "GXInitTlutObj"); + ASSERTMSGLINEV(1358, ((u32)lut & 0x1F) == 0, "%s: %s pointer not aligned to 32B", "GXInitTlutObj", "Tlut"); + t->tlut = 0; + SET_REG_FIELD(1361, t->tlut, 2, 10, fmt); + SET_REG_FIELD(1362, t->loadTlut0, 24, 0, GX_PHY_ADDR(lut) >> 5); + SET_REG_FIELD(1363, t->loadTlut0, 8, 24, 0x64); + t->numEntries = n_entries; +} + +void GXGetTlutObjAll(const GXTlutObj* tlut_obj, void **data, GXTlutFmt* format, u16* numEntries) { + const __GXTlutObjInt* t = (const __GXTlutObjInt *)tlut_obj; + + ASSERTMSGLINE(1382, tlut_obj, "TLut Object Pointer is null"); + *data = (void *)(GET_REG_FIELD(t->loadTlut0, 21, 0) << 5); + *format = GET_REG_FIELD(t->tlut, 2, 10); + *numEntries = t->numEntries; +} + +void* GXGetTlutObjData(const GXTlutObj* tlut_obj) { + const __GXTlutObjInt* t = (const __GXTlutObjInt *)tlut_obj; + + ASSERTMSGLINE(1391, tlut_obj, "TLut Object Pointer is null"); + return (void *)(GET_REG_FIELD(t->loadTlut0, 21, 0) << 5); +} + +GXTlutFmt GXGetTlutObjFmt(const GXTlutObj* tlut_obj) { + const __GXTlutObjInt* t = (const __GXTlutObjInt *)tlut_obj; + + ASSERTMSGLINE(1398, tlut_obj, "TLut Object Pointer is null"); + return GET_REG_FIELD(t->tlut, 2, 10); +} + +u16 GXGetTlutObjNumEntries(const GXTlutObj* tlut_obj) { + const __GXTlutObjInt* t = (const __GXTlutObjInt *)tlut_obj; + + ASSERTMSGLINE(1405, tlut_obj, "TLut Object Pointer is null"); + return t->numEntries; +} + +void GXLoadTlut(GXTlutObj* tlut_obj, u32 tlut_name) { + __GXTlutRegionInt* r; + u32 tlut_offset; + __GXTlutObjInt* t = (__GXTlutObjInt *)tlut_obj; + + ASSERTMSGLINE(1434, tlut_obj, "TLut Object Pointer is null"); + CHECK_GXBEGIN(1436, "GXLoadTlut"); + ASSERTMSGLINEV(1437, __GXData->tlutRegionCallback, "%s: Tex/Tlut Region Callback not set", "GXLoadTlut"); + r = (__GXTlutRegionInt *)__GXData->tlutRegionCallback(tlut_name); + ASSERTMSGLINEV(1439, r, "%s: Tex/Tlut Region Callback returns NULL", "GXLoadTlut"); + + __GXFlushTextureState(); + GX_WRITE_RAS_REG(t->loadTlut0); + GX_WRITE_RAS_REG(r->loadTlut1); + __GXFlushTextureState(); + tlut_offset = r->loadTlut1 & 0x3FF; + SET_REG_FIELD(1455, t->tlut, 10, 0, tlut_offset); + r->tlutObj = *t; +} + +void GXInitTexCacheRegion(GXTexRegion* region, u8 is_32b_mipmap, u32 tmem_even, GXTexCacheSize size_even, u32 tmem_odd, GXTexCacheSize size_odd) { + u32 WidthExp2; + __GXTexRegionInt* t = (__GXTexRegionInt*)region; + + ASSERTMSGLINE(1486, region, "TexRegion Object Pointer is null"); + CHECK_GXBEGIN(1488, "GXInitTexCacheRegion"); + ASSERTMSGLINEV(1490, (tmem_even & 0x1F) == 0, "%s: %s pointer not aligned to 32B", "GXInitTexCacheRegion", "tmem even"); + ASSERTMSGLINEV(1492, (tmem_odd & 0x1F) == 0, "%s: %s pointer not aligned to 32B", "GXInitTexCacheRegion", "tmem odd"); + + switch (size_even) { + case GX_TEXCACHE_32K: + WidthExp2 = 3; + break; + case GX_TEXCACHE_128K: + WidthExp2 = 4; + break; + case GX_TEXCACHE_512K: + WidthExp2 = 5; + break; + default: + ASSERTMSGLINEV(1500, 0, "%s: Invalid %s size", "GXInitTexCacheRegion", "tmem even"); + break; + } + + t->image1 = 0; + SET_REG_FIELD(1505, t->image1, 15, 0, tmem_even >> 5); + SET_REG_FIELD(1506, t->image1, 3, 15, WidthExp2); + SET_REG_FIELD(1507, t->image1, 3, 18, WidthExp2); + SET_REG_FIELD(1508, t->image1, 1, 21, 0); + + switch (size_odd) { + case GX_TEXCACHE_32K: + WidthExp2 = 3; + break; + case GX_TEXCACHE_128K: + WidthExp2 = 4; + break; + case GX_TEXCACHE_512K: + WidthExp2 = 5; + break; + case GX_TEXCACHE_NONE: + WidthExp2 = 0; + break; + default: + ASSERTMSGLINEV(1516, 0, "%s: Invalid %s size", "GXInitTexCacheRegion", "tmem odd"); + break; + } + + t->image2 = 0; + SET_REG_FIELD(1521, t->image2, 15, 0, tmem_odd >> 5); + SET_REG_FIELD(1522, t->image2, 3, 15, WidthExp2); + SET_REG_FIELD(1523, t->image2, 3, 18, WidthExp2); + t->is32bMipmap = (u8)is_32b_mipmap; + t->isCached = 1; +} + +void GXInitTexPreLoadRegion(GXTexRegion* region, u32 tmem_even, u32 size_even, u32 tmem_odd, u32 size_odd) { + __GXTexRegionInt* t = (__GXTexRegionInt *)region; + + ASSERTMSGLINE(1550, region, "TexRegion Object Pointer is null"); + CHECK_GXBEGIN(1552, "GXInitTexPreLoadRegion"); + ASSERTMSGLINEV(1554, (tmem_even & 0x1F) == 0, "%s: %s pointer not aligned to 32B", "GXInitTexPreLoadRegion", "tmem even"); + ASSERTMSGLINEV(1556, (tmem_odd & 0x1F) == 0, "%s: %s pointer not aligned to 32B", "GXInitTexPreLoadRegion", "tmem odd"); + ASSERTMSGLINEV(1558, (size_even & 0x1F) == 0, "%s: %s pointer not aligned to 32B", "GXInitTexPreLoadRegion", "size even"); + ASSERTMSGLINEV(1560, (size_odd & 0x1F) == 0, "%s: %s pointer not aligned to 32B", "GXInitTexPreLoadRegion", "size odd"); + + t->image1 = 0; + SET_REG_FIELD(1564, t->image1, 15, 0, tmem_even >> 5); + SET_REG_FIELD(1565, t->image1, 3, 15, 0); + SET_REG_FIELD(1566, t->image1, 3, 18, 0); + SET_REG_FIELD(1567, t->image1, 1, 21, 1); + + t->image2 = 0; + SET_REG_FIELD(1570, t->image2, 15, 0, tmem_odd >> 5); + SET_REG_FIELD(1571, t->image2, 3, 15, 0); + SET_REG_FIELD(1572, t->image2, 3, 18, 0); + t->is32bMipmap = 0; + t->isCached = 0; + t->sizeEven = (u16)(size_even >> 5); + t->sizeOdd = (u16)(size_odd >> 5); +} + +void GXGetTexRegionAll(const GXTexRegion* region, u8* is_cached, u8* is_32b_mipmap, u32* tmem_even, u32* size_even, u32* tmem_odd, u32* size_odd) { + const __GXTexRegionInt* t = (const __GXTexRegionInt *)region; + + ASSERTMSGLINE(1601, region, "TexRegion Object Pointer is null"); + *tmem_even = GET_REG_FIELD(t->image1, 15, 0) << 5; + *tmem_odd = GET_REG_FIELD(t->image2, 15, 0) << 5; + if (t->isCached) { + switch (GET_REG_FIELD(t->image1, 3, 15)) { + case 3: + *size_even = 0x8000; + break; + case 4: + *size_even = 0x20000; + break; + case 5: + *size_even = 0x80000; + break; + default: + *size_even = 0; + break; + } + + switch (GET_REG_FIELD(t->image2, 3, 15)) { + case 3: + *size_odd = 0x8000; + break; + case 4: + *size_odd = 0x20000; + break; + case 5: + *size_odd = 0x80000; + break; + default: + *size_odd = 0; + break; + } + } else { + *size_even = t->sizeEven << 5; + *size_odd = t->sizeOdd << 5; + } + + *is_32b_mipmap = t->is32bMipmap; + *is_cached = t->isCached; +} + +void GXInitTlutRegion(GXTlutRegion* region, u32 tmem_addr, GXTlutSize tlut_size) { + __GXTlutRegionInt* t = (__GXTlutRegionInt *)region; + + ASSERTMSGLINE(1654, region, "TLutRegion Object Pointer is null"); + CHECK_GXBEGIN(1656, "GXInitTlutRegion"); + ASSERTMSGLINEV(1657, (tmem_addr & 0x1FF) == 0, "%s: tmem pointer is not aligned to 512B", "GXInitTlutRegion"); + ASSERTMSGLINEV(1658, tlut_size <= 0x400, "%s: tlut size exceeds 16K", "GXInitTlutRegion"); + t->loadTlut1 = 0; + tmem_addr -= 0x80000; + SET_REG_FIELD(1662, t->loadTlut1, 10, 0, tmem_addr >> 9); + SET_REG_FIELD(1663, t->loadTlut1, 11, 10, tlut_size); + SET_REG_FIELD(1664, t->loadTlut1, 8, 24, 0x65); +} + +void GXGetTlutRegionAll(const GXTlutRegion* region, u32* tmem_addr, GXTlutSize* tlut_size) { + const __GXTlutRegionInt* t = (const __GXTlutRegionInt *)region; + + ASSERTMSGLINE(1682, region, "TLutRegion Object Pointer is null"); + *tmem_addr = (GET_REG_FIELD(t->loadTlut1, 10, 0) << 9) + 0x80000; + *tlut_size = GET_REG_FIELD(t->loadTlut1, 11, 10); +} + +void GXInvalidateTexRegion(GXTexRegion* region) { + s32 wle; + s32 hle; + s32 wlo; + s32 hlo; + s32 count; + u32 reg0; + u32 reg1; + __GXTexRegionInt* r = (__GXTexRegionInt*)region; + + ASSERTMSGLINE(1705, region, "TexRegion Object Pointer is null"); + CHECK_GXBEGIN(1707, "GXInvalidateTexRegion"); + + wle = GET_REG_FIELD(r->image1, 3, 15) - 1; + hle = GET_REG_FIELD(r->image1, 3, 18) - 1; + wlo = GET_REG_FIELD(r->image2, 3, 15) - 1; + hlo = GET_REG_FIELD(r->image2, 3, 18) - 1; + if (wle < 0) { + wle = 0; + } + if (hle < 0) { + hle = 0; + } + if (wlo < 0) { + wlo = 0; + } + if (hlo < 0) { + hlo = 0; + } + count = wle + hle; + if (r->is32bMipmap) { + count = wlo + hlo - 2 + count; + } + + reg0 = 0; + SET_REG_FIELD(1724, reg0, 9, 0, GET_REG_FIELD(r->image1, 9, 6)); + SET_REG_FIELD(1725, reg0, 4, 9, count); + SET_REG_FIELD(1724, reg0, 8, 24, 0x66); + + if (wlo != 0) { + count = wlo + hlo; + if (r->is32bMipmap) { + count = wle + hle - 2 + count; + } + reg1 = 0; + SET_REG_FIELD(1736, reg1, 9, 0, GET_REG_FIELD(r->image2, 9, 6)); + SET_REG_FIELD(1737, reg1, 4, 9, count); + SET_REG_FIELD(1738, reg1, 8, 24, 0x66); + } + + __GXFlushTextureState(); + GX_WRITE_RAS_REG(reg0); + if (wlo != 0) { + GX_WRITE_RAS_REG(reg1); + } + __GXFlushTextureState(); + + reg0; reg1; r; // needed to match +} + +void GXInvalidateTexAll(void) { + u32 reg0; + u32 reg1; + + CHECK_GXBEGIN(1757, "GXInvalidateTexAll"); + reg0 = 0x66001000; + reg1 = 0x66001100; + __GXFlushTextureState(); + GX_WRITE_RAS_REG(reg0); + GX_WRITE_RAS_REG(reg1); + __GXFlushTextureState(); +} + +GXTexRegionCallback GXSetTexRegionCallback(GXTexRegionCallback f) { + GXTexRegionCallback oldcb = __GXData->texRegionCallback; + + __GXData->texRegionCallback = f; + return oldcb; +} + +GXTlutRegionCallback GXSetTlutRegionCallback(GXTlutRegionCallback f) { + GXTlutRegionCallback oldcb = __GXData->tlutRegionCallback; + + __GXData->tlutRegionCallback = f; + return oldcb; +} + +void GXPreLoadEntireTexture(GXTexObj* tex_obj, GXTexRegion* region) { + GXBool isMipMap; + GXBool is32bit; + u32 wd; + u32 ht; + u32 maxLevelIndex; + u32 loadImage0; + u32 loadImage1; + u32 loadImage2; + u32 loadImage3; + u32 base; + u32 tmem1; + u32 tmem2; + u32 tmemAR; + u32 tmemGB; + u32 nTiles; +#if DEBUG + u32 totalOdd; + u32 totalEven; + u32 count; +#endif + u32 rowTiles; + u32 colTiles; + u32 cmpTiles; + u32 i; + __GXTexObjInt* t = (__GXTexObjInt*)tex_obj; + __GXTexRegionInt* r = (__GXTexRegionInt*)region; + + ASSERTMSGLINE(1820, tex_obj, "Texture Object Pointer is null"); + ASSERTMSGLINE(1820, region, "TexRegion Object Pointer is null"); + CHECK_GXBEGIN(1822, "GXPreLoadEntireTexture"); + isMipMap = (t->flags & 1) == 1; + is32bit = GET_REG_FIELD(t->image0, 4, 20) == 6; + + loadImage0 = 0; + SET_REG_FIELD(0, loadImage0, 8, 24, 0x60); + base = t->image3 & 0x1FFFFF; + SET_REG_FIELD(1831, loadImage0, 21, 0, base); + + loadImage1 = 0; + SET_REG_FIELD(0, loadImage1, 8, 24, 0x61); + tmem1 = r->image1 & 0x7FFF; + SET_REG_FIELD(1837, loadImage1, 15, 0, tmem1); + + loadImage2 = 0; + SET_REG_FIELD(0, loadImage2, 8, 24, 0x62); + tmem2 = r->image2 & 0x7FFF; + SET_REG_FIELD(1843, loadImage2, 15, 0, tmem2); + + loadImage3 = 0; + SET_REG_FIELD(0, loadImage3, 8, 24, 0x63); + SET_REG_FIELD(1848, loadImage3, 15, 0, t->loadCnt); + SET_REG_FIELD(1849, loadImage3, 2, 15, t->loadFmt); + maxLevelIndex = 0; + nTiles = t->loadCnt; + + if (isMipMap) { + wd = GET_REG_FIELD(t->image0, 10, 0) + 1; + ht = GET_REG_FIELD(t->image0, 10, 10) + 1; + if (wd > ht) { + maxLevelIndex = (u16)(31 - __cntlzw(wd)); + } else { + maxLevelIndex = (u16)(31 - __cntlzw(ht)); + } + +#if DEBUG + count = nTiles; + totalOdd = totalEven = 0; + + for (i = 0; i < maxLevelIndex; i++) { + if (i & 1) { + if (count == 0) { + count = 1; + } + totalOdd += count; + } else { + if (count == 0) { + count = 1; + } + totalEven += count; + } + __GetImageTileCount(t->fmt, wd >> (i + 1), ht >> (i + 1), &rowTiles, &colTiles, &cmpTiles); + count = rowTiles * colTiles; + } +#endif + } else { +#if DEBUG + totalEven = (nTiles == 0) ? 1 : nTiles; + totalOdd = totalEven; +#endif + } + +#if DEBUG + if (is32bit) { + totalOdd = isMipMap ? totalOdd : 0; + totalEven = totalEven + totalOdd; + ASSERTMSGLINE(1890, totalEven <= r->sizeEven, "GXPreLoadEntireTexture: Even tmem size does not match the texture size"); + ASSERTMSGLINE(1891, totalEven <= r->sizeOdd, "GXPreLoadEntireTexture: Odd tmem size does not match the texture size"); + } else if (isMipMap != 0) { + if (r->sizeEven > r->sizeOdd) { + ASSERTMSGLINE(1896, totalEven <= r->sizeEven, "GXPreLoadEntireTexture: Even tmem size does not match the texture size"); + ASSERTMSGLINE(1897, totalOdd <= r->sizeOdd, "GXPreLoadEntireTexture: Odd tmem size does not match the texture size"); + } else { + ASSERTMSGLINE(1900, totalEven <= r->sizeOdd, "GXPreLoadEntireTexture: Odd tmem size does not match the texture size"); + ASSERTMSGLINE(1901, totalOdd <= r->sizeEven, "GXPreLoadEntireTexture: Even tmem size does not match the texture size"); + } + } else if (r->sizeEven > r->sizeOdd) { + ASSERTMSGLINE(1906, totalEven <= r->sizeEven, "GXPreLoadEntireTexture: Even tmem size does not match the texture size"); + } else { + ASSERTMSGLINE(1908, totalOdd <= r->sizeOdd, "GXPreLoadEntireTexture: Odd tmem size does not match the texture size"); + } +#endif + + __GXFlushTextureState(); + GX_WRITE_RAS_REG(loadImage0); + GX_WRITE_RAS_REG(loadImage1); + GX_WRITE_RAS_REG(loadImage2); + GX_WRITE_RAS_REG(loadImage3); + + if (maxLevelIndex != 0) { + tmemAR = tmem1; + tmemGB = tmem2; + for (i = 0; i < maxLevelIndex; i++) { + if (is32bit) { + base += nTiles * 2; + tmemAR += nTiles; + tmemGB += nTiles; + } else { + base += nTiles; + if (i & 1) { + tmemGB += nTiles; + } else { + tmemAR += nTiles; + } + } + tmem1 = (i & 1) ? tmemAR : tmemGB; + tmem2 = (i & 1) ? tmemGB : tmemAR; + __GetImageTileCount(t->fmt, (u16) (wd >> (i + 1)), (u16) (ht >> (i + 1)), &rowTiles, &colTiles, &cmpTiles); + nTiles = rowTiles * colTiles; + SET_REG_FIELD(1957, loadImage0, 21, 0, base); + SET_REG_FIELD(1958, loadImage1, 15, 0, tmem1); + SET_REG_FIELD(1959, loadImage2, 15, 0, tmem2); + SET_REG_FIELD(1960, loadImage3, 15, 0, nTiles); + GX_WRITE_RAS_REG(loadImage0); + GX_WRITE_RAS_REG(loadImage1); + GX_WRITE_RAS_REG(loadImage2); + GX_WRITE_RAS_REG(loadImage3); + } + } + __GXFlushTextureState(); + + // needed to match debug + maxLevelIndex; maxLevelIndex; base; base; base; tmem1; tmem1; tmem2; tmem2; +} + +void GXSetTexCoordScaleManually(GXTexCoordID coord, GXBool enable, u16 ss, u16 ts) { + CHECK_GXBEGIN(1991, "GXSetTexCoordScaleManually"); + ASSERTMSGLINEV(1993, coord < GX_MAX_TEXCOORD, "%s: bad texcoord specified", "GXSetTexCoordScaleManually"); + __GXData->tcsManEnab = (__GXData->tcsManEnab & ~(1 << coord)) | (enable << coord); + + if (enable) { + SET_REG_FIELD(1999, __GXData->suTs0[coord], 16, 0, (u16)(ss - 1)); + SET_REG_FIELD(2000, __GXData->suTs1[coord], 16, 0, (u16)(ts - 1)); + GX_WRITE_RAS_REG(__GXData->suTs0[coord]); + GX_WRITE_RAS_REG(__GXData->suTs1[coord]); + __GXData->bpSentNot = 0; + } +} + +void GXSetTexCoordCylWrap(GXTexCoordID coord, u8 s_enable, u8 t_enable) { + CHECK_GXBEGIN(2023, "GXSetTexCoordCylWrap"); + ASSERTMSGLINEV(2025, coord < GX_MAX_TEXCOORD, "%s: bad texcoord specified", "GXSetTexCoordCylWrap"); + SET_REG_FIELD(2027, __GXData->suTs0[coord], 1, 17, s_enable); + SET_REG_FIELD(2028, __GXData->suTs1[coord], 1, 17, t_enable); + + if (__GXData->tcsManEnab & (1 << coord)) { + GX_WRITE_RAS_REG(__GXData->suTs0[coord]); + GX_WRITE_RAS_REG(__GXData->suTs1[coord]); + __GXData->bpSentNot = 0; + } +} + +void GXSetTexCoordBias(GXTexCoordID coord, u8 s_enable, u8 t_enable) { + CHECK_GXBEGIN(2054, "GXSetTexCoordBias"); + ASSERTMSGLINEV(2056, coord < GX_MAX_TEXCOORD, "%s: bad texcoord specified", "GXSetTexCoordBias"); + SET_REG_FIELD(2058, __GXData->suTs0[coord], 1, 16, s_enable); + SET_REG_FIELD(2059, __GXData->suTs1[coord], 1, 16, t_enable); + + if (__GXData->tcsManEnab & (1 << coord)) { + GX_WRITE_RAS_REG(__GXData->suTs0[coord]); + GX_WRITE_RAS_REG(__GXData->suTs1[coord]); + __GXData->bpSentNot = 0; + } +} + +static void __SetSURegs(u32 tmap, u32 tcoord) { + u32 w; + u32 h; + u8 s_bias; + u8 t_bias; + + w = GET_REG_FIELD(__GXData->tImage0[tmap], 10, 0); + h = GET_REG_FIELD(__GXData->tImage0[tmap], 10, 10); + SET_REG_FIELD(2091, __GXData->suTs0[tcoord], 16, 0, w); + SET_REG_FIELD(2092, __GXData->suTs1[tcoord], 16, 0, h); + s_bias = GET_REG_FIELD(__GXData->tMode0[tmap], 2, 0) == 1; + t_bias = GET_REG_FIELD(__GXData->tMode0[tmap], 2, 2) == 1; + SET_REG_FIELD(2098, __GXData->suTs0[tcoord], 1, 16, s_bias); + SET_REG_FIELD(2099, __GXData->suTs1[tcoord], 1, 16, t_bias); + GX_WRITE_RAS_REG(__GXData->suTs0[tcoord]); + GX_WRITE_RAS_REG(__GXData->suTs1[tcoord]); + __GXData->bpSentNot = 0; +} + +void __GXSetSUTexRegs(void) { + u32 nStages; + u32 nIndStages; + u32 i; + u32 map; + u32 tmap; + u32 coord; + u32* ptref; + + if (__GXData->tcsManEnab != 0xFF) { + nStages = GET_REG_FIELD(__GXData->genMode, 4, 10) + 1; + nIndStages = GET_REG_FIELD(__GXData->genMode, 3, 16); + for (i = 0; i < nIndStages; i++) { + switch (i) { + case 0: + tmap = GET_REG_FIELD(__GXData->iref, 3, 0); + coord = GET_REG_FIELD(__GXData->iref, 3, 3); + break; + case 1: + tmap = GET_REG_FIELD(__GXData->iref, 3, 6); + coord = GET_REG_FIELD(__GXData->iref, 3, 9); + break; + case 2: + tmap = GET_REG_FIELD(__GXData->iref, 3, 12); + coord = GET_REG_FIELD(__GXData->iref, 3, 15); + break; + case 3: + tmap = GET_REG_FIELD(__GXData->iref, 3, 18); + coord = GET_REG_FIELD(__GXData->iref, 3, 21); + break; + } + if (!(__GXData->tcsManEnab & (1 << coord))) { + __SetSURegs(tmap, coord); + } + } + + for (i = 0; i < nStages; i++) { + ptref = &__GXData->tref[i / 2]; + map = __GXData->texmapId[i]; + tmap = map & 0xFFFFFEFF; + if (i & 1) { + coord = GET_REG_FIELD(*ptref, 3, 15); + } else { + coord = GET_REG_FIELD(*ptref, 3, 3); + } + if ((tmap != 0xFF) && !(__GXData->tcsManEnab & (1 << coord)) && (__GXData->tevTcEnab & (1 << i))) { + __SetSURegs(tmap, coord); + } + } + } +} + +void __GXGetSUTexSize(GXTexCoordID coord, u16* width, u16* height) { + *width = (u16)__GXData->suTs0[coord] + 1; + *height = (u16)__GXData->suTs1[coord] + 1; +} + +void __GXSetTmemConfig(u32 config) { + switch (config) { + case 2: + GX_WRITE_RAS_REG(0x8c0d8000); + GX_WRITE_RAS_REG(0x900dc000); + + GX_WRITE_RAS_REG(0x8d0d8800); + GX_WRITE_RAS_REG(0x910dc800); + + GX_WRITE_RAS_REG(0x8e0d9000); + GX_WRITE_RAS_REG(0x920dd000); + + GX_WRITE_RAS_REG(0x8f0d9800); + GX_WRITE_RAS_REG(0x930dd800); + + GX_WRITE_RAS_REG(0xac0da000); + GX_WRITE_RAS_REG(0xb00dc400); + + GX_WRITE_RAS_REG(0xad0da800); + GX_WRITE_RAS_REG(0xb10dcc00); + + GX_WRITE_RAS_REG(0xae0db000); + GX_WRITE_RAS_REG(0xb20dd400); + + GX_WRITE_RAS_REG(0xaf0db800); + GX_WRITE_RAS_REG(0xb30ddc00); + break; + case 1: + GX_WRITE_RAS_REG(0x8c0d8000); + GX_WRITE_RAS_REG(0x900dc000); + + GX_WRITE_RAS_REG(0x8d0d8800); + GX_WRITE_RAS_REG(0x910dc800); + + GX_WRITE_RAS_REG(0x8e0d9000); + GX_WRITE_RAS_REG(0x920dd000); + + GX_WRITE_RAS_REG(0x8f0d9800); + GX_WRITE_RAS_REG(0x930dd800); + + GX_WRITE_RAS_REG(0xac0da000); + GX_WRITE_RAS_REG(0xb00de000); + + GX_WRITE_RAS_REG(0xad0da800); + GX_WRITE_RAS_REG(0xb10de800); + + GX_WRITE_RAS_REG(0xae0db000); + GX_WRITE_RAS_REG(0xb20df000); + + GX_WRITE_RAS_REG(0xaf0db800); + GX_WRITE_RAS_REG(0xb30df800); + + break; + case 0: + default: + GX_WRITE_RAS_REG(0x8c0d8000); + GX_WRITE_RAS_REG(0x900dc000); + + GX_WRITE_RAS_REG(0x8d0d8400); + GX_WRITE_RAS_REG(0x910dc400); + + GX_WRITE_RAS_REG(0x8e0d8800); + GX_WRITE_RAS_REG(0x920dc800); + + GX_WRITE_RAS_REG(0x8f0d8c00); + GX_WRITE_RAS_REG(0x930dcc00); + + GX_WRITE_RAS_REG(0xac0d9000); + GX_WRITE_RAS_REG(0xb00dd000); + + GX_WRITE_RAS_REG(0xad0d9400); + GX_WRITE_RAS_REG(0xb10dd400); + + GX_WRITE_RAS_REG(0xae0d9800); + GX_WRITE_RAS_REG(0xb20dd800); + + GX_WRITE_RAS_REG(0xaf0d9c00); + GX_WRITE_RAS_REG(0xb30ddc00); + + break; + } +} diff --git a/src/revolution/gx/GXTransform.c b/src/revolution/gx/GXTransform.c new file mode 100644 index 0000000000..0fb885b459 --- /dev/null +++ b/src/revolution/gx/GXTransform.c @@ -0,0 +1,607 @@ +#include +#include +#include + +#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; +} diff --git a/src/revolution/gx/GXVerifRAS.c b/src/revolution/gx/GXVerifRAS.c new file mode 100644 index 0000000000..cdb935069b --- /dev/null +++ b/src/revolution/gx/GXVerifRAS.c @@ -0,0 +1,628 @@ +#if DEBUG + +#include + +#include + +#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 diff --git a/src/revolution/gx/GXVerifXF.c b/src/revolution/gx/GXVerifXF.c new file mode 100644 index 0000000000..8784888afd --- /dev/null +++ b/src/revolution/gx/GXVerifXF.c @@ -0,0 +1,946 @@ +#if DEBUG + +#include + +#include + +#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 diff --git a/src/revolution/gx/GXVerify.c b/src/revolution/gx/GXVerify.c new file mode 100644 index 0000000000..9650ccb340 --- /dev/null +++ b/src/revolution/gx/GXVerify.c @@ -0,0 +1,372 @@ +#if DEBUG + +#include + +#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 diff --git a/src/revolution/gx/GXVert.c b/src/revolution/gx/GXVert.c new file mode 100644 index 0000000000..d1db47c48a --- /dev/null +++ b/src/revolution/gx/GXVert.c @@ -0,0 +1,86 @@ +#if DEBUG +#include + +#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 diff --git a/src/revolution/gx/__gx.h b/src/revolution/gx/__gx.h new file mode 100644 index 0000000000..eb8561b05e --- /dev/null +++ b/src/revolution/gx/__gx.h @@ -0,0 +1,573 @@ +#ifndef _REVOLUTION_GX_INTERNAL_H_ +#define _REVOLUTION_GX_INTERNAL_H_ + +#include +#include + +#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 diff --git a/src/revolution/hio2/hio2.c b/src/revolution/hio2/hio2.c new file mode 100644 index 0000000000..d317923650 --- /dev/null +++ b/src/revolution/hio2/hio2.c @@ -0,0 +1,273 @@ +#include +#include +#include +#include +#include + +#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, ®, 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; +} diff --git a/src/revolution/mtx/mtx.c b/src/revolution/mtx/mtx.c new file mode 100644 index 0000000000..5388c29669 --- /dev/null +++ b/src/revolution/mtx/mtx.c @@ -0,0 +1,1197 @@ +#include +#include +#include + +static f32 Unit01[2] = { + 0.0f, + 1.0f +}; + +void C_MTXIdentity(Mtx m) { + ASSERTMSGLINE(203, m, "MtxIdentity(): NULL Mtx 'm' "); + m[0][0] = 1; + m[0][1] = 0; + m[0][2] = 0; + m[0][3] = 0; + m[1][0] = 0; + m[1][1] = 1; + m[1][2] = 0; + m[1][3] = 0; + m[2][0] = 0; + m[2][1] = 0; + m[2][2] = 1; + m[2][3] = 0; +} + +void PSMTXIdentity(__REGISTER Mtx m) { + __REGISTER f32 c_zero = 0.0f; + __REGISTER f32 c_one = 1.0f; + __REGISTER f32 c_01; + __REGISTER f32 c_10; + + asm { + psq_st c_zero, 8(m), 0, 0 + ps_merge01 c_01, c_zero, c_one + psq_st c_zero, 24(m), 0, 0 + ps_merge10 c_10, c_one, c_zero + psq_st c_zero, 32(m), 0, 0 + psq_st c_01, 16(m), 0, 0 + psq_st c_10, 0(m), 0, 0 + psq_st c_10, 40(m), 0, 0 + } +} + +void C_MTXCopy(const Mtx src, Mtx dst) { + ASSERTMSGLINE(264, src, "MTXCopy(): NULL MtxPtr 'src' "); + ASSERTMSGLINE(265, dst, "MTXCopy(): NULL MtxPtr '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]; + } +} + +asm void PSMTXCopy(const __REGISTER Mtx src, __REGISTER Mtx dst) { + psq_l f0, 0(src), 0, 0 + psq_st f0, 0(dst), 0, 0 + psq_l f1, 8(src), 0, 0 + psq_st f1, 8(dst), 0, 0 + psq_l f2, 16(src), 0, 0 + psq_st f2, 16(dst), 0, 0 + psq_l f3, 24(src), 0, 0 + psq_st f3, 24(dst), 0, 0 + psq_l f4, 32(src), 0, 0 + psq_st f4, 32(dst), 0, 0 + psq_l f5, 40(src), 0, 0 + psq_st f5, 40(dst), 0, 0 +} + +void C_MTXConcat(const Mtx a, const Mtx b, Mtx ab) { + Mtx mTmp; + MtxPtr m; + + ASSERTMSGLINE(338, a, "MTXConcat(): NULL MtxPtr 'a' "); + ASSERTMSGLINE(339, b, "MTXConcat(): NULL MtxPtr 'b' "); + ASSERTMSGLINE(340, ab, "MTXConcat(): NULL MtxPtr 'ab' "); + + if (ab == a || ab == b) { + m = mTmp; + } else { + m = ab; + } + + m[0][0] = 0 + a[0][2] * b[2][0] + ((a[0][0] * b[0][0]) + (a[0][1] * b[1][0])); + m[0][1] = 0 + a[0][2] * b[2][1] + ((a[0][0] * b[0][1]) + (a[0][1] * b[1][1])); + m[0][2] = 0 + a[0][2] * b[2][2] + ((a[0][0] * b[0][2]) + (a[0][1] * b[1][2])); + m[0][3] = a[0][3] + (a[0][2] * b[2][3] + (a[0][0] * b[0][3] + (a[0][1] * b[1][3]))); + + m[1][0] = 0 + a[1][2] * b[2][0] + ((a[1][0] * b[0][0]) + (a[1][1] * b[1][0])); + m[1][1] = 0 + a[1][2] * b[2][1] + ((a[1][0] * b[0][1]) + (a[1][1] * b[1][1])); + m[1][2] = 0 + a[1][2] * b[2][2] + ((a[1][0] * b[0][2]) + (a[1][1] * b[1][2])); + m[1][3] = a[1][3] + (a[1][2] * b[2][3] + (a[1][0] * b[0][3] + (a[1][1] * b[1][3]))); + + m[2][0] = 0 + a[2][2] * b[2][0] + ((a[2][0] * b[0][0]) + (a[2][1] * b[1][0])); + m[2][1] = 0 + a[2][2] * b[2][1] + ((a[2][0] * b[0][1]) + (a[2][1] * b[1][1])); + m[2][2] = 0 + a[2][2] * b[2][2] + ((a[2][0] * b[0][2]) + (a[2][1] * b[1][2])); + m[2][3] = a[2][3] + (a[2][2] * b[2][3] + (a[2][0] * b[0][3] + (a[2][1] * b[1][3]))); + + if (m == mTmp) { + C_MTXCopy(mTmp, ab); + } +} + +asm void PSMTXConcat(const __REGISTER Mtx a, const __REGISTER Mtx b, __REGISTER Mtx ab) { + nofralloc + stwu r1, -64(r1) + psq_l f0, 0(a), 0, 0 + stfd f14, 8(r1) + psq_l f6, 0(b), 0, 0 + lis r6, Unit01@ha + psq_l f7, 8(b), 0, 0 + stfd f15, 16(r1) + addi r6, r6, Unit01@l + stfd f31, 40(r1) + psq_l f8, 16(b), 0, 0 + ps_muls0 f12, f6, f0 + psq_l f2, 16(a), 0, 0 + ps_muls0 f13, f7, f0 + psq_l f31, 0(r6), 0, 0 + ps_muls0 f14, f6, f2 + psq_l f9, 24(b), 0, 0 + ps_muls0 f15, f7, f2 + psq_l f1, 8(a), 0, 0 + ps_madds1 f12, f8, f0, f12 + psq_l f3, 24(a), 0, 0 + ps_madds1 f14, f8, f2, f14 + psq_l f10, 32(b), 0, 0 + ps_madds1 f13, f9, f0, f13 + psq_l f11, 40(b), 0, 0 + ps_madds1 f15, f9, f2, f15 + psq_l f4, 32(a), 0, 0 + psq_l f5, 40(a), 0, 0 + ps_madds0 f12, f10, f1, f12 + ps_madds0 f13, f11, f1, f13 + ps_madds0 f14, f10, f3, f14 + ps_madds0 f15, f11, f3, f15 + psq_st f12, 0(ab), 0, 0 + ps_muls0 f2, f6, f4 + ps_madds1 f13, f31, f1, f13 + ps_muls0 f0, f7, f4 + psq_st f14, 16(ab), 0, 0 + ps_madds1 f15, f31, f3, f15 + psq_st f13, 8(ab), 0, 0 + ps_madds1 f2, f8, f4, f2 + ps_madds1 f0, f9, f4, f0 + ps_madds0 f2, f10, f5, f2 + lfd f14, 8(r1) + psq_st f15, 24(ab), 0, 0 + ps_madds0 f0, f11, f5, f0 + psq_st f2, 32(ab), 0, 0 + ps_madds1 f0, f31, f5, f0 + lfd f15, 16(r1) + psq_st f0, 40(ab), 0, 0 + lfd f31, 40(r1) + addi r1, r1, 64 + blr +} + +void C_MTXConcatArray(const Mtx a, const Mtx* srcBase, Mtx* dstBase, u32 count) { + u32 i; + + ASSERTMSGLINE(580, a != 0, "MTXConcatArray(): NULL MtxPtr 'a' "); + ASSERTMSGLINE(581, srcBase != 0, "MTXConcatArray(): NULL MtxPtr 'srcBase' "); + ASSERTMSGLINE(582, dstBase != 0, "MTXConcatArray(): NULL MtxPtr 'dstBase' "); + ASSERTMSGLINE(583, count > 1, "MTXConcatArray(): count must be greater than 1."); + + for (i = 0; i < count; i++) { + C_MTXConcat(a, *srcBase, *dstBase); + srcBase++; + dstBase++; + } +} + +#if DEBUG +#pragma push +#pragma optimization_level 1 +// This function will not compile at optimization level 0 +#endif +void PSMTXConcatArray(const __REGISTER Mtx a, const __REGISTER Mtx* srcBase, __REGISTER Mtx* dstBase, __REGISTER u32 count) { + __REGISTER f32 va0, va1, va2, va3, va4, va5; + __REGISTER f32 vb0, vb1, vb2, vb3, vb4, vb5; + __REGISTER f32 vd0, vd1, vd2, vd3, vd4, vd5; + __REGISTER f32 u01; + __REGISTER f32* u01Ptr = Unit01; + + asm { + psq_l va0, 0(a), 0, 0; + psq_l va1, 8(a), 0, 0; + psq_l va2, 16(a), 0, 0; + psq_l va3, 24(a), 0, 0; + subi count, count, 1; + psq_l va4, 32(a), 0, 0; + psq_l va5, 40(a), 0, 0; + mtctr count; + psq_l u01, 0(u01Ptr), 0, 0; + psq_l vb0, 0(srcBase), 0, 0; + psq_l vb2, 16(srcBase), 0, 0; + ps_muls0 vd0, vb0, va0; + ps_muls0 vd2, vb0, va2; + ps_muls0 vd4, vb0, va4; + psq_l vb4, 32(srcBase), 0, 0; + ps_madds1 vd0, vb2, va0, vd0; + ps_madds1 vd2, vb2, va2, vd2; + ps_madds1 vd4, vb2, va4, vd4; + psq_l vb1, 8(srcBase), 0, 0; + ps_madds0 vd0, vb4, va1, vd0; + ps_madds0 vd2, vb4, va3, vd2; + ps_madds0 vd4, vb4, va5, vd4; + psq_l vb3, 24(srcBase), 0, 0; + psq_st vd0, 0(dstBase), 0, 0; + ps_muls0 vd1, vb1, va0; + ps_muls0 vd3, vb1, va2; + ps_muls0 vd5, vb1, va4; + psq_l vb5, 40(srcBase), 0, 0; + psq_st vd2, 16(dstBase), 0, 0; + ps_madds1 vd1, vb3, va0, vd1; + ps_madds1 vd3, vb3, va2, vd3; + ps_madds1 vd5, vb3, va4, vd5; + _loop: + addi srcBase, srcBase, sizeof(Mtx); + ps_madds0 vd1, vb5, va1, vd1; + ps_madds0 vd3, vb5, va3, vd3; + ps_madds0 vd5, vb5, va5, vd5; + psq_l vb0, 0(srcBase), 0, 0; + psq_st vd4, 32(dstBase), 0, 0; + ps_madd vd1, u01, va1, vd1; + ps_madd vd3, u01, va3, vd3; + ps_madd vd5, u01, va5, vd5; + psq_l vb2, 16(srcBase), 0, 0; + psq_st vd1, 8(dstBase), 0, 0; + ps_muls0 vd0, vb0, va0; + ps_muls0 vd2, vb0, va2; + ps_muls0 vd4, vb0, va4; + psq_l vb4, 32(srcBase), 0, 0; + psq_st vd3, 24(dstBase), 0, 0; + ps_madds1 vd0, vb2, va0, vd0; + ps_madds1 vd2, vb2, va2, vd2; + ps_madds1 vd4, vb2, va4, vd4; + psq_l vb1, 8(srcBase), 0, 0; + psq_st vd5, 40(dstBase), 0, 0; + addi dstBase, dstBase, sizeof(Mtx); + ps_madds0 vd0, vb4, va1, vd0; + ps_madds0 vd2, vb4, va3, vd2; + ps_madds0 vd4, vb4, va5, vd4; + psq_l vb3, 24(srcBase), 0, 0; + psq_st vd0, 0(dstBase), 0, 0; + ps_muls0 vd1, vb1, va0; + ps_muls0 vd3, vb1, va2; + ps_muls0 vd5, vb1, va4; + psq_l vb5, 40(srcBase), 0, 0; + psq_st vd2, 16(dstBase), 0, 0; + ps_madds1 vd1, vb3, va0, vd1; + ps_madds1 vd3, vb3, va2, vd3; + ps_madds1 vd5, vb3, va4, vd5; + bdnz _loop; + psq_st vd4, 32(dstBase), 0, 0; + ps_madds0 vd1, vb5, va1, vd1; + ps_madds0 vd3, vb5, va3, vd3; + ps_madds0 vd5, vb5, va5, vd5; + ps_madd vd1, u01, va1, vd1; + ps_madd vd3, u01, va3, vd3; + ps_madd vd5, u01, va5, vd5; + psq_st vd1, 8(dstBase), 0, 0; + psq_st vd3, 24(dstBase), 0, 0; + psq_st vd5, 40(dstBase), 0, 0; + } +} +#if DEBUG +#pragma pop +#endif + +void C_MTXTranspose(const Mtx src, Mtx xPose) { + Mtx mTmp; + MtxPtr m; + + ASSERTMSGLINE(851, src, "MTXTranspose(): NULL MtxPtr 'src' "); + ASSERTMSGLINE(852, xPose, "MTXTranspose(): NULL MtxPtr '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] = 0; + m[1][0] = src[0][1]; + m[1][1] = src[1][1]; + m[1][2] = src[2][1]; + m[1][3] = 0; + m[2][0] = src[0][2]; + m[2][1] = src[1][2]; + m[2][2] = src[2][2]; + m[2][3] = 0; + if (m == mTmp) { + C_MTXCopy(mTmp, xPose); + } +} + +void PSMTXTranspose(const __REGISTER Mtx src, __REGISTER Mtx xPose) { + __REGISTER f32 c_zero = 0; + __REGISTER f32 row0a; + __REGISTER f32 row1a; + __REGISTER f32 row0b; + __REGISTER f32 row1b; + __REGISTER f32 trns0; + __REGISTER f32 trns1; + __REGISTER f32 trns2; + + asm { + psq_l row0a, 0(src), 0, 0 + } + xPose[2][3] = c_zero; + asm { + psq_l row1a, 16(src), 0, 0 + ps_merge00 trns0, row0a, row1a + psq_l row0b, 8(src), 1, 0 + ps_merge11 trns1, row0a, row1a + psq_l row1b, 24(src), 1, 0 + psq_st trns0, 0(xPose), 0, 0 + psq_l row0a, 32(src), 0, 0 + ps_merge00 trns2, row0b, row1b + psq_st trns1, 16(xPose), 0, 0 + ps_merge00 trns0, row0a, c_zero + psq_st trns2, 32(xPose), 0, 0 + ps_merge10 trns1, row0a, c_zero + psq_st trns0, 8(xPose), 0, 0 + } + row0b = src[2][2]; + asm { + psq_st trns1, 24(xPose), 0, 0 + } + xPose[2][2] = row0b; +} + +u32 C_MTXInverse(const Mtx src, Mtx inv) { + Mtx mTmp; + MtxPtr m; + f32 det; + + ASSERTMSGLINE(964, src, "MTXInverse(): NULL MtxPtr 'src' "); + ASSERTMSGLINE(965, inv, "MTXInverse(): NULL MtxPtr 'inv' "); + + if (src == inv) { + m = mTmp; + } else { + m = inv; + } + det = ((((src[2][1] * (src[0][2] * src[1][0])) + + ((src[2][2] * (src[0][0] * src[1][1])) + + (src[2][0] * (src[0][1] * src[1][2])))) + - (src[0][2] * (src[2][0] * src[1][1]))) + - (src[2][2] * (src[1][0] * src[0][1]))) + - (src[1][2] * (src[0][0] * src[2][1])); + if (0 == det) { + return 0; + } + det = 1 / det; + m[0][0] = (det * +((src[1][1] * src[2][2]) - (src[2][1] * src[1][2]))); + m[0][1] = (det * -((src[0][1] * src[2][2]) - (src[2][1] * src[0][2]))); + m[0][2] = (det * +((src[0][1] * src[1][2]) - (src[1][1] * src[0][2]))); + + m[1][0] = (det * -((src[1][0] * src[2][2]) - (src[2][0] * src[1][2]))); + m[1][1] = (det * +((src[0][0] * src[2][2]) - (src[2][0] * src[0][2]))); + m[1][2] = (det * -((src[0][0] * src[1][2]) - (src[1][0] * src[0][2]))); + + m[2][0] = (det * +((src[1][0] * src[2][1]) - (src[2][0] * src[1][1]))); + m[2][1] = (det * -((src[0][0] * src[2][1]) - (src[2][0] * src[0][1]))); + m[2][2] = (det * +((src[0][0] * src[1][1]) - (src[1][0] * src[0][1]))); + + m[0][3] = ((-m[0][0] * src[0][3]) - (m[0][1] * src[1][3])) - (m[0][2] * src[2][3]); + m[1][3] = ((-m[1][0] * src[0][3]) - (m[1][1] * src[1][3])) - (m[1][2] * src[2][3]); + m[2][3] = ((-m[2][0] * src[0][3]) - (m[2][1] * src[1][3])) - (m[2][2] * src[2][3]); + + if (m == mTmp) { + C_MTXCopy(mTmp, inv); + } + return 1; +} + +asm u32 PSMTXInverse(const __REGISTER Mtx src, __REGISTER Mtx inv) { + psq_l f0, 0(src), 1, 0 + psq_l f1, 4(src), 0, 0 + psq_l f2, 16(src), 1, 0 + ps_merge10 f6, f1, f0 + psq_l f3, 20(src), 0, 0 + psq_l f4, 32(src), 1, 0 + ps_merge10 f7, f3, f2 + psq_l f5, 36(src), 0, 0 + ps_mul f11, f3, f6 + ps_merge10 f8, f5, f4 + ps_mul f13, f5, f7 + ps_msub f11, f1, f7, f11 + ps_mul f12, f1, f8 + ps_msub f13, f3, f8, f13 + ps_mul f10, f3, f4 + ps_msub f12, f5, f6, f12 + ps_mul f7, f0, f13 + ps_mul f9, f0, f5 + ps_mul f8, f1, f2 + ps_madd f7, f2, f12, f7 + ps_sub f6, f6, f6 + ps_msub f10, f2, f5, f10 + ps_madd f7, f4, f11, f7 + ps_msub f9, f1, f4, f9 + ps_msub f8, f0, f3, f8 + ps_cmpo0 cr0, f7, f6 + bne skip_return + li r3, 0 + blr +skip_return: + fres f0, f7 + ps_add f6, f0, f0 + ps_mul f5, f7, f0 + ps_nmsub f0, f0, f5, f6 + lfs f1, 12(src) + ps_muls0 f13, f13, f0 + lfs f2, 28(src) + ps_muls0 f12, f12, f0 + lfs f3, 44(src) + ps_muls0 f11, f11, f0 + ps_merge00 f5, f13, f12 + ps_merge11 f4, f13, f12 + ps_mul f6, f13, f1 + psq_st f5, 0(inv), 0, 0 + psq_st f4, 16(inv), 0, 0 + ps_muls0 f10, f10, f0 + ps_muls0 f9, f9, f0 + ps_madd f6, f12, f2, f6 + psq_st f10, 32(inv), 1, 0 + ps_muls0 f8, f8, f0 + ps_nmadd f6, f11, f3, f6 + psq_st f9, 36(inv), 1, 0 + ps_mul f7, f10, f1 + ps_merge00 f5, f11, f6 + psq_st f8, 40(inv), 1, 0 + ps_madd f7, f9, f2, f7 + ps_merge11 f4, f11, f6 + psq_st f5, 8(inv), 0, 0 + ps_nmadd f7, f8, f3, f7 + psq_st f4, 24(inv), 0, 0 + psq_st f7, 44(inv), 1, 0 + li r3, 1 +} + +u32 C_MTXInvXpose(const Mtx src, Mtx invX) { + Mtx mTmp; + MtxPtr m; + f32 det; + + ASSERTMSGLINE(1185, src, "MTXInvXpose(): NULL MtxPtr 'src' "); + ASSERTMSGLINE(1186, invX, "MTXInvXpose(): NULL MtxPtr 'invX' "); + + if (src == invX) { + m = mTmp; + } else { + m = invX; + } + det = ((((src[2][1] * (src[0][2] * src[1][0])) + + ((src[2][2] * (src[0][0] * src[1][1])) + + (src[2][0] * (src[0][1] * src[1][2])))) + - (src[0][2] * (src[2][0] * src[1][1]))) + - (src[2][2] * (src[1][0] * src[0][1]))) + - (src[1][2] * (src[0][0] * src[2][1])); + if (0 == det) { + return 0; + } + det = 1 / det; + m[0][0] = (det * +((src[1][1] * src[2][2]) - (src[2][1] * src[1][2]))); + m[0][1] = (det * -((src[1][0] * src[2][2]) - (src[2][0] * src[1][2]))); + m[0][2] = (det * +((src[1][0] * src[2][1]) - (src[2][0] * src[1][1]))); + + m[1][0] = (det * -((src[0][1] * src[2][2]) - (src[2][1] * src[0][2]))); + m[1][1] = (det * +((src[0][0] * src[2][2]) - (src[2][0] * src[0][2]))); + m[1][2] = (det * -((src[0][0] * src[2][1]) - (src[2][0] * src[0][1]))); + + m[2][0] = (det * +((src[0][1] * src[1][2]) - (src[1][1] * src[0][2]))); + m[2][1] = (det * -((src[0][0] * src[1][2]) - (src[1][0] * src[0][2]))); + m[2][2] = (det * +((src[0][0] * src[1][1]) - (src[1][0] * src[0][1]))); + + m[0][3] = 0; + m[1][3] = 0; + m[2][3] = 0; + + if (m == mTmp) { + C_MTXCopy(mTmp, invX); + } + return 1; +} + +asm u32 PSMTXInvXpose(const __REGISTER Mtx src, __REGISTER Mtx invX) { + psq_l f0, 0(src), 1, 0 + psq_l f1, 4(src), 0, 0 + psq_l f2, 16(src), 1, 0 + ps_merge10 f6, f1, f0 + psq_l f3, 20(src), 0, 0 + psq_l f4, 32(src), 1, 0 + ps_merge10 f7, f3, f2 + psq_l f5, 36(src), 0, 0 + ps_mul f11, f3, f6 + ps_merge10 f8, f5, f4 + ps_mul f13, f5, f7 + ps_msub f11, f1, f7, f11 + ps_mul f12, f1, f8 + ps_msub f13, f3, f8, f13 + ps_msub f12, f5, f6, f12 + ps_mul f10, f3, f4 + ps_mul f9, f0, f5 + ps_mul f8, f1, f2 + ps_msub f10, f2, f5, f10 + ps_msub f9, f1, f4, f9 + ps_msub f8, f0, f3, f8 + ps_mul f7, f0, f13 + ps_sub f1, f1, f1 + ps_madd f7, f2, f12, f7 + ps_madd f7, f4, f11, f7 + ps_cmpo0 cr0, f7, f1 + bne skip_return + li r3, 0 + blr +skip_return: + fres f0, f7 + psq_st f1, 12(invX), 1, 0 + ps_add f6, f0, f0 + ps_mul f5, f0, f0 + psq_st f1, 28(invX), 1, 0 + ps_nmsub f0, f7, f5, f6 + psq_st f1, 44(invX), 1, 0 + ps_muls0 f13, f13, f0 + ps_muls0 f12, f12, f0 + ps_muls0 f11, f11, f0 + psq_st f13, 0(invX), 0, 0 + psq_st f12, 16(invX), 0, 0 + ps_muls0 f10, f10, f0 + ps_muls0 f9, f9, f0 + psq_st f11, 32(invX), 0, 0 + psq_st f10, 8(invX), 1, 0 + ps_muls0 f8, f8, f0 + li r3, 1 + psq_st f9, 24(invX), 1, 0 + psq_st f8, 40(invX), 1, 0 +} + +void C_MTXRotRad(Mtx m, char axis, f32 rad) { + f32 sinA; + f32 cosA; + + ASSERTMSGLINE(1446, m, "MTXRotRad(): NULL MtxPtr 'm' "); + sinA = sinf(rad); + cosA = cosf(rad); + C_MTXRotTrig(m, axis, sinA, cosA); +} + +void PSMTXRotRad(Mtx m, char axis, f32 rad) { + f32 sinA, cosA; + sinA = sinf(rad); + cosA = cosf(rad); + PSMTXRotTrig(m, axis, sinA, cosA); +} + +void C_MTXRotTrig(Mtx m, char axis, f32 sinA, f32 cosA) { + ASSERTMSGLINE(1501, m, "MTXRotTrig(): NULL MtxPtr 'm' "); + switch(axis) { + case 'x': + case 'X': + m[0][0] = 1; + m[0][1] = 0; + m[0][2] = 0; + m[0][3] = 0; + m[1][0] = 0; + m[1][1] = cosA; + m[1][2] = -sinA; + m[1][3] = 0; + m[2][0] = 0; + m[2][1] = sinA; + m[2][2] = cosA; + m[2][3] = 0; + break; + case 'y': + case 'Y': + m[0][0] = cosA; + m[0][1] = 0; + m[0][2] = sinA; + m[0][3] = 0; + m[1][0] = 0; + m[1][1] = 1; + m[1][2] = 0; + m[1][3] = 0; + m[2][0] = -sinA; + m[2][1] = 0; + m[2][2] = cosA; + m[2][3] = 0; + break; + case 'z': + case 'Z': + m[0][0] = cosA; + m[0][1] = -sinA; + m[0][2] = 0; + m[0][3] = 0; + m[1][0] = sinA; + m[1][1] = cosA; + m[1][2] = 0; + m[1][3] = 0; + m[2][0] = 0; + m[2][1] = 0; + m[2][2] = 1; + m[2][3] = 0; + break; + default: + ASSERTMSGLINE(1528, FALSE, "MTXRotTrig(): invalid 'axis' value "); + break; + } +} + +void PSMTXRotTrig(__REGISTER Mtx m, __REGISTER char axis, __REGISTER f32 sinA, __REGISTER f32 cosA) { + __REGISTER f32 fc0, fc1, nsinA; + __REGISTER f32 fw0, fw1, fw2, fw3; + + asm { + frsp sinA, sinA + frsp cosA, cosA + } + + fc0 = 0.0f; + fc1 = 1.0f; + + asm { + ori axis, axis, 0x20 + ps_neg nsinA, sinA + cmplwi axis, 'x' + beq _case_x + cmplwi axis, 'y' + beq _case_y + cmplwi axis, 'z' + beq _case_z + b _end + + _case_x: + psq_st fc1, 0(m), 1, 0 + psq_st fc0, 4(m), 0, 0 + ps_merge00 fw0, sinA, cosA + psq_st fc0, 12(m), 0, 0 + ps_merge00 fw1, cosA, nsinA + psq_st fc0, 28(m), 0, 0 + psq_st fc0, 44(m), 1, 0 + psq_st fw0, 36(m), 0, 0 + psq_st fw1, 20(m), 0, 0 + b _end; + + _case_y: + ps_merge00 fw0, cosA, fc0 + ps_merge00 fw1, fc0, fc1 + psq_st fc0, 24(m), 0, 0 + psq_st fw0, 0(m), 0, 0 + ps_merge00 fw2, nsinA, fc0 + ps_merge00 fw3, sinA, fc0 + psq_st fw0, 40(m), 0, 0; + psq_st fw1, 16(m), 0, 0; + psq_st fw3, 8(m), 0, 0; + psq_st fw2, 32(m), 0, 0; + b _end; + + _case_z: + psq_st fc0, 8(m), 0, 0 + ps_merge00 fw0, sinA, cosA + ps_merge00 fw2, cosA, nsinA + psq_st fc0, 24(m), 0, 0 + psq_st fc0, 32(m), 0, 0 + ps_merge00 fw1, fc1, fc0 + psq_st fw0, 16(m), 0, 0 + psq_st fw2, 0(m), 0, 0 + psq_st fw1, 40(m), 0, 0 + + _end: + } +} + +static void __PSMTXRotAxisRadInternal(__REGISTER Mtx m, const __REGISTER Vec* axis, __REGISTER f32 sT, __REGISTER f32 cT) { + __REGISTER f32 tT, fc0; + __REGISTER f32 tmp0, tmp1, tmp2, tmp3, tmp4; + __REGISTER f32 tmp5, tmp6, tmp7, tmp8, tmp9; + tmp9 = 0.5f; + tmp8 = 3.0f; + + asm { + frsp cT, cT; + psq_l tmp0, 0(axis), 0, 0; + frsp sT, sT; + lfs tmp1, 8(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; + fmuls tmp2, tmp5, tmp5; + fmuls tmp3, tmp5, tmp9; + fnmsubs tmp2, tmp2, tmp4, tmp8; + fmuls tmp5, tmp2, tmp3; + 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, 8(m), 0, 0; + ps_sum0 tmp0, tmp4, tmp4, tmp0; + psq_st tmp2, 0(m), 0, 0; + ps_muls0 tmp5, tmp5, tmp1; + psq_st tmp3, 16(m), 0, 0; + ps_sum1 tmp4, tmp9, tmp0, tmp4; + psq_st tmp6, 24(m), 0, 0; + ps_sum0 tmp5, tmp5, fc0, cT; + psq_st tmp4, 32(m), 0, 0; + psq_st tmp5, 40(m), 0, 0; + } +} + +void PSMTXRotAxisRad(Mtx m, const Vec* axis, f32 rad) { + f32 sinT, cosT; + + sinT = sinf(rad); + cosT = cosf(rad); + + __PSMTXRotAxisRadInternal(m, axis, sinT, cosT); +} + +void C_MTXRotAxisRad(Mtx 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(1676, m, "MTXRotAxisRad(): NULL MtxPtr 'm' "); + ASSERTMSGLINE(1677, axis, "MTXRotAxisRad(): 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; + 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; + 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; +} + +void C_MTXTrans(Mtx m, f32 xT, f32 yT, f32 zT) { + ASSERTMSGLINE(1865, m, "MTXTrans(): NULL MtxPtr 'm' "); + m[0][0] = 1; + m[0][1] = 0; + m[0][2] = 0; + m[0][3] = xT; + m[1][0] = 0; + m[1][1] = 1; + m[1][2] = 0; + m[1][3] = yT; + m[2][0] = 0; + m[2][1] = 0; + m[2][2] = 1; + m[2][3] = zT; +} + +void PSMTXTrans(__REGISTER Mtx m, __REGISTER f32 xT, __REGISTER f32 yT, __REGISTER f32 zT) { + __REGISTER f32 c0 = 0.0f; + __REGISTER f32 c1 = 1.0f; + + asm { + stfs xT, 12(m) + stfs yT, 28(m) + psq_st c0, 4(m), 0, 0 + psq_st c0, 32(m), 0, 0 + stfs c0, 16(m) + stfs c1, 20(m) + stfs c0, 24(m) + stfs c1, 40(m) + stfs zT, 44(m) + stfs c1, 0(m) + } +} + +void C_MTXTransApply(const Mtx src, Mtx dst, f32 xT, f32 yT, f32 zT) { + ASSERTMSGLINE(1932, src, "MTXTransApply(): NULL MtxPtr 'src' "); + ASSERTMSGLINE(1933, dst, "MTXTransApply(): NULL MtxPtr '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[0][3] = (src[0][3] + xT); + dst[1][3] = (src[1][3] + yT); + dst[2][3] = (src[2][3] + zT); +} + +asm void PSMTXTransApply(const __REGISTER Mtx src, __REGISTER Mtx dst, __REGISTER f32 xT, __REGISTER f32 yT, __REGISTER f32 zT) { + nofralloc + psq_l fp4, 0(src), 0, 0 + frsp xT, xT + psq_l fp5, 8(src), 0, 0 + frsp yT, yT + psq_l fp7, 24(src), 0, 0 + frsp zT, zT + psq_l fp8, 40(src), 0, 0 + psq_st fp4, 0(dst), 0, 0 + ps_sum1 fp5, xT, fp5, fp5 + psq_l fp6, 16(src), 0, 0 + psq_st fp5, 8(dst), 0, 0 + ps_sum1 fp7, yT, fp7, fp7 + psq_l fp9, 32(src), 0, 0 + psq_st fp6, 16(dst), 0, 0 + ps_sum1 fp8, zT, fp8, fp8 + psq_st fp7, 24(dst), 0, 0 + psq_st fp9, 32(dst), 0, 0 + psq_st fp8, 40(dst), 0, 0 + blr +} + +void C_MTXScale(Mtx m, f32 xS, f32 yS, f32 zS) { + ASSERTMSGLINE(2007, m, "MTXScale(): NULL MtxPtr 'm' "); + m[0][0] = xS; + m[0][1] = 0; + m[0][2] = 0; + m[0][3] = 0; + m[1][0] = 0; + m[1][1] = yS; + m[1][2] = 0; + m[1][3] = 0; + m[2][0] = 0; + m[2][1] = 0; + m[2][2] = zS; + m[2][3] = 0; +} + +void PSMTXScale(__REGISTER Mtx m, __REGISTER f32 xS, __REGISTER f32 yS, __REGISTER f32 zS) { + __REGISTER f32 c0 = 0.0f; + + asm { + stfs xS, 0(m) + psq_st c0, 4(m), 0, 0 + psq_st c0, 12(m), 0, 0 + stfs yS, 20(m) + psq_st c0, 24(m), 0, 0 + psq_st c0, 32(m), 0, 0 + stfs zS, 40(m) + stfs c0, 44(m) + } +} + +void C_MTXScaleApply(const Mtx src, Mtx dst, f32 xS, f32 yS, f32 zS) { + ASSERTMSGLINE(2069, src, "MTXScaleApply(): NULL MtxPtr 'src' "); + ASSERTMSGLINE(2070, dst, "MTXScaleApply(): NULL MtxPtr '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); +} + +asm void PSMTXScaleApply(const __REGISTER Mtx src, __REGISTER Mtx dst, __REGISTER f32 xS, __REGISTER f32 yS, __REGISTER f32 zS) { + nofralloc + frsp xS, xS + psq_l fp4, 0(src), 0, 0 + frsp yS, yS + psq_l fp5, 8(src), 0, 0 + frsp zS, zS + ps_muls0 fp4, fp4, xS + psq_l fp6, 16(src), 0, 0 + ps_muls0 fp5, fp5, xS + psq_l fp7, 24(src), 0, 0 + ps_muls0 fp6, fp6, yS + psq_l fp8, 32(src), 0, 0 + psq_st fp4, 0(dst), 0, 0 + ps_muls0 fp7, fp7, yS + psq_l fp2, 40(src), 0, 0 + psq_st fp5, 8(dst), 0, 0 + ps_muls0 fp8, fp8, zS + psq_st fp6, 16(dst), 0, 0 + ps_muls0 fp2, fp2, zS + psq_st fp7, 24(dst), 0, 0 + psq_st fp8, 32(dst), 0, 0 + psq_st fp2, 40(dst), 0, 0 + blr +} + +void C_MTXQuat(Mtx m, const Quaternion* q) { + f32 s; + f32 xs; + f32 ys; + f32 zs; + f32 wx; + f32 wy; + f32 wz; + f32 xx; + f32 xy; + f32 xz; + f32 yy; + f32 yz; + f32 zz; + + ASSERTMSGLINE(2144, m, "MTXQuat(): NULL MtxPtr 'm' "); + ASSERTMSGLINE(2145, q, "MTXQuat(): NULL QuaternionPtr 'q' "); + ASSERTMSGLINE(2146, q->x || q->y || q->z || q->w, "MTXQuat(): zero-value quaternion "); + s = 2 / ((q->w * q->w) + ((q->z * q->z) + ((q->x * q->x) + (q->y * q->y)))); + xs = q->x * s; + ys = q->y * s; + zs = q->z * s; + wx = q->w * xs; + wy = q->w * ys; + wz = q->w * zs; + xx = q->x * xs; + xy = q->x * ys; + xz = q->x * zs; + yy = q->y * ys; + yz = q->y * zs; + zz = q->z * zs; + m[0][0] = (1 - (yy + zz)); + m[0][1] = (xy - wz); + m[0][2] = (xz + wy); + m[0][3] = 0; + m[1][0] = (xy + wz); + m[1][1] = (1 - (xx + zz)); + m[1][2] = (yz - wx); + m[1][3] = 0; + m[2][0] = (xz - wy); + m[2][1] = (yz + wx); + m[2][2] = (1 - (xx + yy)); + m[2][3] = 0; +} + +void PSMTXQuat(__REGISTER Mtx m, const __REGISTER Quaternion* q) { + __REGISTER f32 c_zero, c_one, c_two, scale; + __REGISTER f32 tmp0, tmp1, tmp2, tmp3, tmp4; + __REGISTER f32 tmp5, tmp6, tmp7, tmp8, tmp9; + c_one = 1.0f; + + asm { + psq_l tmp0, 0(q), 0, 0 + psq_l tmp1, 8(q), 0, 0 + fsubs c_zero, c_one, c_one + fadds c_two, c_one, c_one + ps_mul tmp2, tmp0, tmp0 + ps_merge10 tmp5, tmp0, tmp0 + ps_madd tmp4, tmp1, tmp1, tmp2 + ps_mul tmp3, tmp1, tmp1 + ps_sum0 scale, tmp4, tmp4, tmp4 + ps_muls1 tmp7, tmp5, tmp1 + fres tmp9, scale + ps_sum1 tmp4, tmp3, tmp4, tmp2 + ps_nmsub scale, scale, tmp9, c_two + ps_muls1 tmp6, tmp1, tmp1 + ps_mul scale, tmp9, scale + ps_sum0 tmp2, tmp2, tmp2, tmp2 + fmuls scale, scale, c_two + ps_madd tmp8, tmp0, tmp5, tmp6 + ps_msub tmp6, tmp0, tmp5, tmp6 + psq_st c_zero, 12(m), 1, 0 + ps_nmsub tmp2, tmp2, scale, c_one + ps_nmsub tmp4, tmp4, scale, c_one + psq_st c_zero, 44(m), 1, 0 + ps_mul tmp8, tmp8, scale + ps_mul tmp6, tmp6, scale + psq_st tmp2, 40(m), 1, 0 + ps_madds0 tmp5, tmp0, tmp1, tmp7 + ps_merge00 tmp1, tmp8, tmp4 + ps_nmsub tmp7, tmp7, c_two, tmp5 + ps_merge10 tmp0, tmp4, tmp6 + psq_st tmp1, 16(m), 0, 0 + ps_mul tmp5, tmp5, scale + ps_mul tmp7, tmp7, scale + psq_st tmp0, 0(m), 0, 0 + psq_st tmp5, 8(m), 1, 0 + ps_merge10 tmp3, tmp7, c_zero + ps_merge01 tmp9, tmp7, tmp5 + psq_st tmp3, 24(m), 0, 0 + psq_st tmp9, 32(m), 0, 0 + } +} + +void C_MTXReflect(Mtx m, const Vec* p, const Vec* n) { + f32 vxy; + f32 vxz; + f32 vyz; + f32 pdotn; + + vxy = -2 * n->x * n->y; + vxz = -2 * n->x * n->z; + vyz = -2 * n->y * n->z; + pdotn = 2 * C_VECDotProduct(p, n); + m[0][0] = (1 - (2 * n->x * n->x)); + m[0][1] = vxy; + m[0][2] = vxz; + m[0][3] = (pdotn * n->x); + m[1][0] = vxy; + m[1][1] = (1 - (2 * n->y * n->y)); + m[1][2] = vyz; + m[1][3] = (pdotn * n->y); + m[2][0] = vxz; + m[2][1] = vyz; + m[2][2] = (1 - (2 * n->z * n->z)); + m[2][3] = (pdotn * n->z); +} + +void PSMTXReflect(__REGISTER Mtx m, const __REGISTER Vec* p, const __REGISTER Vec* n) { + __REGISTER f32 c_one; + __REGISTER f32 vn_xy, vn_z1; + __REGISTER f32 n2vn_xy, n2vn_z1; + __REGISTER f32 pdotn; + __REGISTER f32 tmp0, tmp1, tmp2, tmp3; + __REGISTER f32 tmp4, tmp5, tmp6, tmp7; + + c_one = 1.0f; + + asm { + psq_l vn_z1, 0x8(n), 1, 0 + psq_l vn_xy, 0x0(n), 0, 0 + psq_l tmp0, 0x0(p), 0, 0 + ps_nmadd n2vn_z1, vn_z1, c_one, vn_z1 + psq_l tmp1, 0x8(p), 1, 0 + ps_nmadd n2vn_xy, vn_xy, c_one, vn_xy + ps_muls0 tmp4, vn_xy, n2vn_z1 + ps_mul pdotn, n2vn_xy, tmp0 + ps_muls0 tmp2, vn_xy, n2vn_xy + ps_sum0 pdotn, pdotn, pdotn, pdotn + ps_muls1 tmp3, vn_xy, n2vn_xy + psq_st tmp4, 0x20(m), 0, 0 + ps_sum0 tmp2, tmp2, tmp2, c_one + ps_nmadd pdotn, n2vn_z1, tmp1, pdotn + ps_sum1 tmp3, c_one, tmp3, tmp3 + psq_st tmp2, 0x0(m), 0, 0 + ps_muls0 tmp5, vn_xy, pdotn + ps_merge00 tmp6, n2vn_z1, pdotn + psq_st tmp3, 0x10(m), 0, 0 + ps_merge00 tmp7, tmp4, tmp5 + ps_muls0 tmp6, tmp6, vn_z1 + ps_merge11 tmp5, tmp4, tmp5 + psq_st tmp7, 0x8(m), 0, 0 + ps_sum0 tmp6, tmp6, tmp6, c_one + psq_st tmp5, 0x18(m), 0, 0 + psq_st tmp6, 0x28(m), 0, 0 + } +} + +void C_MTXLookAt(Mtx m, const Point3d* camPos, const Vec* camUp, const Point3d* target) { + Vec vLook; + Vec vRight; + Vec vUp; + + ASSERTMSGLINE(2437, m, "MTXLookAt(): NULL MtxPtr 'm' "); + ASSERTMSGLINE(2438, camPos, "MTXLookAt(): NULL VecPtr 'camPos' "); + ASSERTMSGLINE(2439, camUp, "MTXLookAt(): NULL VecPtr 'camUp' "); + ASSERTMSGLINE(2440, target, "MTXLookAt(): NULL Point3dPtr 'target' "); + + vLook.x = camPos->x - target->x; + vLook.y = camPos->y - target->y; + vLook.z = camPos->z - target->z; + VECNormalize(&vLook, &vLook); + VECCrossProduct(camUp, &vLook, &vRight); + VECNormalize(&vRight, &vRight); + VECCrossProduct(&vLook, &vRight, &vUp); + m[0][0] = vRight.x; + m[0][1] = vRight.y; + m[0][2] = vRight.z; + m[0][3] = -((camPos->z * vRight.z) + ((camPos->x * vRight.x) + (camPos->y * vRight.y))); + m[1][0] = vUp.x; + m[1][1] = vUp.y; + m[1][2] = vUp.z; + m[1][3] = -((camPos->z * vUp.z) + ((camPos->x * vUp.x) + (camPos->y * vUp.y))); + m[2][0] = vLook.x; + m[2][1] = vLook.y; + m[2][2] = vLook.z; + m[2][3] = -((camPos->z * vLook.z) + ((camPos->x * vLook.x) + (camPos->y * vLook.y))); +} + +void C_MTXLightFrustum(Mtx m, f32 t, f32 b, f32 l, f32 r, f32 n, f32 scaleS, f32 scaleT, f32 transS, f32 transT) { + f32 tmp; + + ASSERTMSGLINE(2541, m, "MTXLightFrustum(): NULL MtxPtr 'm' "); + ASSERTMSGLINE(2542, (t != b), "MTXLightFrustum(): 't' and 'b' clipping planes are equal "); + ASSERTMSGLINE(2543, (l != r), "MTXLightFrustum(): 'l' and 'r' clipping planes are equal "); + + tmp = 1 / (r - l); + m[0][0] = (scaleS * (2 * n * tmp)); + m[0][1] = 0; + m[0][2] = (scaleS * (tmp * (r + l))) - transS; + m[0][3] = 0; + tmp = 1 / (t - b); + m[1][0] = 0; + m[1][1] = (scaleT * (2 * n * tmp)); + m[1][2] = (scaleT * (tmp * (t + b))) - transT; + m[1][3] = 0; + m[2][0] = 0; + m[2][1] = 0; + m[2][2] = -1; + m[2][3] = 0; +} + +void C_MTXLightPerspective(Mtx m, f32 fovY, f32 aspect, f32 scaleS, f32 scaleT, f32 transS, f32 transT) { + f32 angle; + f32 cot; + + ASSERTMSGLINE(2604, m, "MTXLightPerspective(): NULL MtxPtr 'm' "); + ASSERTMSGLINE(2605, (fovY > 0.0) && (fovY < 180.0), "MTXLightPerspective(): 'fovY' out of range "); + ASSERTMSGLINE(2606, 0 != aspect, "MTXLightPerspective(): 'aspect' is 0 "); + + angle = (0.5f * fovY); + angle = MTXDegToRad(angle); + cot = 1 / tanf(angle); + m[0][0] = (scaleS * (cot / aspect)); + m[0][1] = 0; + m[0][2] = -transS; + m[0][3] = 0; + m[1][0] = 0; + m[1][1] = (cot * scaleT); + m[1][2] = -transT; + m[1][3] = 0; + m[2][0] = 0; + m[2][1] = 0; + m[2][2] = -1; + m[2][3] = 0; +} + +void C_MTXLightOrtho(Mtx m, f32 t, f32 b, f32 l, f32 r, f32 scaleS, f32 scaleT, f32 transS, f32 transT) { + f32 tmp; + + ASSERTMSGLINE(2672, m, "MTXLightOrtho(): NULL MtxPtr 'm' "); + ASSERTMSGLINE(2673, (t != b), "MTXLightOrtho(): 't' and 'b' clipping planes are equal "); + ASSERTMSGLINE(2674, (l != r), "MTXLightOrtho(): 'l' and 'r' clipping planes are equal "); + tmp = 1 / (r - l); + m[0][0] = (2 * tmp * scaleS); + m[0][1] = 0; + m[0][2] = 0; + m[0][3] = (transS + (scaleS * (tmp * -(r + l)))); + tmp = 1/ (t - b); + m[1][0] = 0; + m[1][1] = (2 * tmp * scaleT); + m[1][2] = 0; + m[1][3] = (transT + (scaleT * (tmp * -(t + b)))); + m[2][0] = 0; + m[2][1] = 0; + m[2][2] = 0; + m[2][3] = 1; +} diff --git a/src/revolution/mtx/mtx44.c b/src/revolution/mtx/mtx44.c new file mode 100644 index 0000000000..3cfedb61b3 --- /dev/null +++ b/src/revolution/mtx/mtx44.c @@ -0,0 +1,888 @@ +#include +#include +#include + +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); +} diff --git a/src/revolution/mtx/mtx44vec.c b/src/revolution/mtx/mtx44vec.c new file mode 100644 index 0000000000..da92c17ea7 --- /dev/null +++ b/src/revolution/mtx/mtx44vec.c @@ -0,0 +1,247 @@ +#include +#include +#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 +} diff --git a/src/revolution/mtx/mtxstack.c b/src/revolution/mtx/mtxstack.c new file mode 100644 index 0000000000..af7956f4f7 --- /dev/null +++ b/src/revolution/mtx/mtxstack.c @@ -0,0 +1,108 @@ +#include +#include +#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; +} diff --git a/src/revolution/mtx/mtxvec.c b/src/revolution/mtx/mtxvec.c new file mode 100644 index 0000000000..99c5a71a75 --- /dev/null +++ b/src/revolution/mtx/mtxvec.c @@ -0,0 +1,204 @@ +#include +#include +#include + +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 +} diff --git a/src/revolution/mtx/psmtx.c b/src/revolution/mtx/psmtx.c new file mode 100644 index 0000000000..ab9aac13db --- /dev/null +++ b/src/revolution/mtx/psmtx.c @@ -0,0 +1,336 @@ +#include +#include +#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 +} diff --git a/src/revolution/mtx/quat.c b/src/revolution/mtx/quat.c new file mode 100644 index 0000000000..14964d9bfb --- /dev/null +++ b/src/revolution/mtx/quat.c @@ -0,0 +1,486 @@ +#include +#include +#include + +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); +} diff --git a/src/revolution/mtx/vec.c b/src/revolution/mtx/vec.c new file mode 100644 index 0000000000..d2ef0675a1 --- /dev/null +++ b/src/revolution/mtx/vec.c @@ -0,0 +1,344 @@ +#include +#include +#include + +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; +} diff --git a/src/revolution/sc/scapi.c b/src/revolution/sc/scapi.c new file mode 100644 index 0000000000..9aa57e7ec1 --- /dev/null +++ b/src/revolution/sc/scapi.c @@ -0,0 +1,123 @@ +#include + +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; +} diff --git a/src/revolution/sc/scapi_prdinfo.c b/src/revolution/sc/scapi_prdinfo.c new file mode 100644 index 0000000000..820d24a4be --- /dev/null +++ b/src/revolution/sc/scapi_prdinfo.c @@ -0,0 +1,136 @@ +#include +#include +#include + +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; +} diff --git a/src/revolution/sc/scsystem.c b/src/revolution/sc/scsystem.c new file mode 100644 index 0000000000..9ddc1fb5c1 --- /dev/null +++ b/src/revolution/sc/scsystem.c @@ -0,0 +1,996 @@ +#include +#include +#include +// #include + +#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); +} diff --git a/src/revolution/si/SIBios.c b/src/revolution/si/SIBios.c new file mode 100644 index 0000000000..65f24d99eb --- /dev/null +++ b/src/revolution/si/SIBios.c @@ -0,0 +1,821 @@ +#include +#include + +#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"; + } +} diff --git a/src/revolution/si/SISamplingRate.c b/src/revolution/si/SISamplingRate.c new file mode 100644 index 0000000000..3006110e04 --- /dev/null +++ b/src/revolution/si/SISamplingRate.c @@ -0,0 +1,125 @@ +#include +#include + +#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 diff --git a/src/revolution/vi/__vi.h b/src/revolution/vi/__vi.h new file mode 100644 index 0000000000..e061de3369 --- /dev/null +++ b/src/revolution/vi/__vi.h @@ -0,0 +1,40 @@ +#ifndef _REVOLUTION_VI_INTERNAL_H_ +#define _REVOLUTION_VI_INTERNAL_H_ + +#include + +#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 diff --git a/src/revolution/vi/i2c.c b/src/revolution/vi/i2c.c new file mode 100644 index 0000000000..6996b1368d --- /dev/null +++ b/src/revolution/vi/i2c.c @@ -0,0 +1,230 @@ +#include +#include + +#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; +} diff --git a/src/revolution/vi/vi.c b/src/revolution/vi/vi.c new file mode 100644 index 0000000000..057ba805b4 --- /dev/null +++ b/src/revolution/vi/vi.c @@ -0,0 +1,1703 @@ +#include +#include +#include +#include +#include +#include + +#include "__gx.h" +#include "__os.h" +#include "__vi.h" + +// normal assert macros don't match in some places here +#if DEBUG +#define VI_ASSERTMSGLINE1(line, cond, msg, arg1) \ + if (!(cond)) \ + OSPanic(__FILE__, line, msg, arg1) + +#define VI_ASSERTMSGLINE2(line, cond, msg, arg1, arg2) \ + if (!(cond)) \ + OSPanic(__FILE__, line, msg, arg1, arg2) +#else +#define VI_ASSERTMSGLINE1(line, cond, msg, arg1) (void)0 +#define VI_ASSERTMSGLINE2(line, cond, msg, arg1, arg2) (void)0 +#endif + +// extern +extern DVDCommandBlock __DVDStopMotorCommandBlock; + +#ifdef SDK_AUG2010 +#define BUILD_DATE "Aug 23 2010" +#if DEBUG +#define BUILD_TIME "17:27:58" +#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* __VIVersion = "<< RVL_SDK - VI \tdebug build: "BUILD_DATE" "BUILD_TIME" (0x4302_145) >>"; +#else +const char* __VIVersion = "<< RVL_SDK - VI \trelease build: "BUILD_DATE" "BUILD_TIME" (0x4302_145) >>"; +#endif +#elif SDK_SEP2006 +const char* __VIVersion = "<< RVL_SDK - VI \trelease build: "BUILD_DATE" "BUILD_TIME" (0x4200_60422) >>"; +#endif + +typedef struct { + u8 equ; + u16 acv; + u16 prbOdd; + u16 prbEven; + u16 psbOdd; + u16 psbEven; + u8 bs1; + u8 bs2; + u8 bs3; + u8 bs4; + u16 be1; + u16 be2; + u16 be3; + u16 be4; + u16 nhlines; + u16 hlw; + u8 hsy; + u8 hcs; + u8 hce; + u8 hbe640; + u16 hbs640; + u8 hbeCCIR656; + u16 hbsCCIR656; +} timing_s; + +typedef struct { + u16 DispPosX; + u16 DispPosY; + u16 DispSizeX; + u16 DispSizeY; + u16 AdjustedDispPosX; + u16 AdjustedDispPosY; + u16 AdjustedDispSizeY; + u16 AdjustedPanPosY; + u16 AdjustedPanSizeY; + u16 FBSizeX; + u16 FBSizeY; + u16 PanPosX; + u16 PanPosY; + u16 PanSizeX; + u16 PanSizeY; + VIXFBMode FBMode; + u32 nonInter; + u32 tv; + u8 wordPerLine; + u8 std; + u8 wpl; + u32 bufAddr; + u32 tfbb; + u32 bfbb; + u8 xof; + BOOL black; + BOOL threeD; + u32 rbufAddr; + u32 rtfbb; + u32 rbfbb; + timing_s* timing; +} SomeVIStruct; + +static BOOL IsInitialized = FALSE; + +static volatile u32 retraceCount; +static volatile u32 flushFlag; +static volatile u32 flushFlag3in1; +static volatile u32 vsync_timing_err_cnt = 0; +static volatile u32 vsync_timing_test_flag = 0; + +static volatile BOOL __VIDimming_All_Clear = FALSE; +static volatile BOOL __VIDimmingFlag_Enable; +static volatile BOOL __VIDVDStopFlag_Enable; +static volatile VITimeToDIM g_current_time_to_dim; +static vu32 THD_TIME_TO_DIMMING = 0; +static vu32 NEW_TIME_TO_DIMMING = 0; +static vu32 THD_TIME_TO_DVD_STOP = 0; +static vu32 _gIdleCount_dimming = 0; +static vu32 _gIdleCount_dvd = 0; +static vu32 __VIDimmingFlag_RF_IDLE; +static vu32 __VIDimmingFlag_SI_IDLE; +static vu32 __VIDimmingFlag_DEV_IDLE[10]; +static volatile BOOL __VIDimmingState = FALSE; + +extern VIVideo Vdac_Flag_Region; +extern volatile u32 Vdac_Flag_Changed; + +static OSThreadQueue retraceQueue; + +static void (*PreCB)(u32); +static void (*PostCB)(u32); + +static u32 encoderType; +static u16 regs[59]; +static volatile u32 __VIDimmingFlag_DEV_IDLE[10]; +static timing_s* CurrTiming; +static u32 CurrTvMode; +static u32 NextBufAddr; +static u32 CurrBufAddr; +static u16 shdwRegs[59]; + +static void (*PositionCallback)(s16, s16) = NULL; +static s16 displayOffsetH = 0; +static s16 displayOffsetV = 0; +static volatile u32 changeMode = 0; +static volatile u64 changed = 0; +static volatile u32 shdwChangeMode = 0; +static volatile u64 shdwChanged = 0; +static u32 FBSet = 0; +static timing_s* timingExtra = NULL; + +#define MARK_CHANGED(index) (changed |= 1LL << (63 - (index))) + +static timing_s timing[11] = { + { 6, 240, 24, 25, 3, 2, 12, 13, 12, 13, 520, 519, 520, 519, 525, 429, 64, 71, 105, 162, 373, 122, 412 }, + { 6, 240, 24, 24, 4, 4, 12, 12, 12, 12, 520, 520, 520, 520, 526, 429, 64, 71, 105, 162, 373, 122, 412 }, + { 5, 287, 35, 36, 1, 0, 13, 12, 11, 10, 619, 618, 617, 620, 625, 432, 64, 75, 106, 172, 380, 133, 420 }, + { 5, 287, 33, 33, 2, 2, 13, 11, 13, 11, 619, 621, 619, 621, 624, 432, 64, 75, 106, 172, 380, 133, 420 }, + { 6, 240, 24, 25, 3, 2, 16, 15, 14, 13, 518, 517, 516, 519, 525, 429, 64, 78, 112, 162, 373, 122, 412 }, + { 6, 240, 24, 24, 4, 4, 16, 14, 16, 14, 518, 520, 518, 520, 526, 429, 64, 78, 112, 162, 373, 122, 412 }, + { 12, 480, 48, 48, 6, 6, 24, 24, 24, 24, 1038, 1038, 1038, 1038, 1050, 429, 64, 71, 105, 162, 373, 122, 412 }, + { 12, 480, 44, 44, 10, 10, 24, 24, 24, 24, 1038, 1038, 1038, 1038, 1050, 429, 64, 71, 105, 168, 379, 122, 412 }, + { 6, 241, 24, 25, 1, 0, 12, 13, 12, 13, 520, 519, 520, 519, 525, 429, 64, 71, 105, 159, 370, 122, 412 }, + { 12, 480, 48, 48, 6, 6, 24, 24, 24, 24, 1038, 1038, 1038, 1038, 1050, 429, 64, 71, 105, 180, 391, 122, 412 }, + { 10, 576, 62, 62, 6, 6, 20, 20, 20, 20, 1240, 1240, 1240, 1240, 1250, 432, 64, 75, 106, 172, 380, 122, 412 } +}; + +static u16 taps[25] = { + 0x01F0, 0x01DC, + 0x01AE, 0x0174, + 0x0129, 0x00DB, + 0x008E, 0x0046, + 0x000C, 0x00E2, + 0x00CB, 0x00C0, + 0x00C4, 0x00CF, + 0x00DE, 0x00EC, + 0x00FC, 0x0008, + 0x000F, 0x0013, + 0x0013, 0x000F, + 0x000C, 0x0008, + 0x0001 +}; + +GXRenderModeObj GXPal528Prog = { + 6, + 640, 528, 528, + 40, 23, + 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 GXPal528ProgSoft = { + 6, + 640, 528, 528, + 40, 23, + 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 }, + { 8, 8, 10, 12, 10, 8, 8 } +}; + +GXRenderModeObj GXPal524ProgAa = { + 6, + 640, 264, 524, + 40, 23, + 640, 524, + 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 } +}; + +static BOOL OnShutdown(BOOL final, u32 event); +static OSShutdownFunctionInfo ShutdownFunctionInfo = { + OnShutdown, + 127 +}; + +static SomeVIStruct HorVer; + + +// prototypes +static u32 getCurrentFieldEvenOdd(void); +timing_s* __VISetExtraTiming(timing_s* t); +void __VIEnableRawPositionInterrupt(s16 x, s16 y, void (*callback)(s16, s16)); +void (*__VIDisableRawPositionInterrupt())(s16, s16); +void __VIDisplayPositionToXY(u32 hct, u32 vct, s16* x, s16* y); +void __VISetLatchMode(u32 mode); +int __VIGetLatch0Position(s16* px, s16* py); +int __VIGetLatch1Position(s16* px, s16* py); +int __VIGetLatchPosition(u32 port, s16* px, s16* py); +static void GetCurrentDisplayPosition(u32* hct, u32* vct); + +static BOOL OnShutdown(BOOL final, u32 event) { + BOOL retval; + static BOOL first = TRUE; + static u32 count; + + if (final == FALSE) { + switch (event) { + case 3: + case 1: + case 2: + if (first) { + VISetRGBModeImm(); + VIFlush(); + count = retraceCount; + first = FALSE; + retval = FALSE; + } else { + if (count == retraceCount) { + retval = FALSE; + } else { + retval = TRUE; + } + } + break; + case 4: + case 0: + case 6: + case 5: + __VISetGamma1_0(); + retval = TRUE; + break; + } + } else { + retval = TRUE; + } + + return retval; +} + +static u32 getEncoderType(void) { + return 1; +} + +static s32 cntlzd(u64 bit) { + u32 hi; + u32 lo; + s32 value; + + hi = bit >> 32; + lo = bit & 0xFFFFFFFF; + value = __cntlzw(hi); + if (value < 32) { + return value; + } + return __cntlzw(lo) + 32; +} + +static int VISetRegs(void) { + s32 regIndex; + + if (shdwChangeMode != 1 || getCurrentFieldEvenOdd() != 0) { + while (shdwChanged != 0) { + regIndex = cntlzd(shdwChanged); + __VIRegs[regIndex] = shdwRegs[regIndex]; + shdwChanged &= ~((u64)1 << (63 - regIndex)); + } + + shdwChangeMode = 0; + CurrTiming = HorVer.timing; + CurrTvMode = HorVer.tv; + CurrBufAddr = NextBufAddr; + return 1; + } + + return 0; +} + +static void __VIRetraceHandler(__OSInterrupt unused, OSContext* context) { + OSContext exceptionContext; + u16 reg; + u32 inter = 0; + u32 regIndex; + static u32 old_dtvStatus = 999; + static u32 old_tvtype = 999; + u32 now_dtvStatus = 0; + u32 now_tvtype = 0; + static BOOL __VIDimmingFlag_Enable_old = TRUE; + static BOOL __VIDVDStopFlag_Enable_old = TRUE; + u32 i; + + #if DEBUG + static u32 dbgCount; + #endif + static u32 DimmingON_Pending = 0; + static u32 DimmingOFF_Pending = 0; + + + reg = __VIRegs[0x18]; + if (reg & 0x8000) { + __VIRegs[0x18] = reg & ~0x8000; + inter |= 1; + } + reg = __VIRegs[0x1A]; + if (reg & 0x8000) { + __VIRegs[0x1A] = reg & ~0x8000; + inter |= 2; + } + reg = __VIRegs[0x1C]; + if (reg & 0x8000) { + __VIRegs[0x1C] = reg & ~0x8000; + inter |= 4; + } + reg = __VIRegs[0x1E]; + if (reg & 0x8000) { + __VIRegs[0x1E] = reg & ~0x8000; + inter |= 8; + } + reg = __VIRegs[0x1E]; + + if ((inter & 4) || (inter & 8)) { + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + + if (PositionCallback != 0) { + s16 x, y; + __VIGetCurrentPosition(&x, &y); + (*PositionCallback)(x, y); + } + + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); + return; + } + + if (inter == 0) { + ASSERTLINE(1350, FALSE); + } + + retraceCount += 1; + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + + if (PreCB) { + PreCB(retraceCount); + } + + if (vsync_timing_test_flag) { + u32 hcount, vcount; + + GetCurrentDisplayPosition(&hcount, &vcount); + + if(!((vcount == 1) || (vcount == (CurrTiming->nhlines / 2 + 1)))) { + vsync_timing_err_cnt++; + } + } + + if (flushFlag != 0) { +#if DEBUG + dbgCount = 0; +#endif + if (VISetRegs() != 0) { + flushFlag = 0; + SIRefreshSamplingRate(); + } + } + + now_dtvStatus = VIGetDTVStatus(); + if(now_dtvStatus != old_dtvStatus) { + __VISetYUVSEL((VIBool)now_dtvStatus); + } + + old_dtvStatus = now_dtvStatus; + now_tvtype = VIGetTvFormat(); + + if (now_tvtype != old_tvtype) { + if (now_tvtype == VI_EURGB60) { + __VISetFilter4EURGB60(VI_ENABLE); + } + else { + __VISetFilter4EURGB60(VI_DISABLE); + } + + switch (now_tvtype) { + case VI_PAL: + switch(g_current_time_to_dim) { + case VI_DM_10M: + NEW_TIME_TO_DIMMING = 30000; + break; + case VI_DM_15M: + NEW_TIME_TO_DIMMING = 45000; + break; + default: + NEW_TIME_TO_DIMMING = 15000; + break; + } + THD_TIME_TO_DVD_STOP = 90000; + break; + default: + switch(g_current_time_to_dim) { + case VI_DM_10M: + NEW_TIME_TO_DIMMING = 36000; + break; + case VI_DM_15M: + NEW_TIME_TO_DIMMING = 54000; + break; + default: + NEW_TIME_TO_DIMMING = 18000; + break; + } + THD_TIME_TO_DVD_STOP = 108000; + break; + } + + _gIdleCount_dimming = 0; + _gIdleCount_dvd = 0; + } + + old_tvtype = now_tvtype; + + if (flushFlag3in1) { + while (Vdac_Flag_Changed) { + regIndex = (u32)__cntlzw(Vdac_Flag_Changed); + regIndex = (u32)(1 << (31 - regIndex)); + + switch(regIndex) { + case 1: + __VISetCGMS(); + break; + case 2: + __VISetWSS(); + break; + case 4: + __VISetClosedCaption(); + break; + case 8: + __VISetMacrovision(); + break; + case 0x10: + __VISetGamma(); + break; + case 0x20: + __VISetTrapFilter(); + break; + case 0x40: + __VISetRGBOverDrive(); + break; + case 0x80: + __VISetRGBModeImm(); + break; + } + + Vdac_Flag_Changed &= ~regIndex; + } + + flushFlag3in1 = 0; + } + #if DEBUG + else if (changed != 0) { + dbgCount++; + if (dbgCount > 60) { + OSReport("Warning: VIFlush() was not called for 60 frames although VI settings were changed\n"); + dbgCount = 0; + } + } + #endif + + if (PostCB) { + OSClearContext(&exceptionContext); + PostCB(retraceCount); + } + + OSWakeupThread(&retraceQueue); + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); + + if (__VIDimming_All_Clear == TRUE) { + if(__OSSetVIForceDimming(FALSE, 0, 0) == TRUE) { + __VIDimming_All_Clear = FALSE; + _gIdleCount_dimming = 0; + } + } + + for (i = 0; i < 10; i++) { + if(__VIDimmingFlag_DEV_IDLE[i] == 0) { + __VIDimmingFlag_DEV_IDLE[0] = 0; + break; + } + } + + if(__VIDimmingFlag_RF_IDLE && __VIDimmingFlag_SI_IDLE && __VIDimmingFlag_DEV_IDLE[0]) { + if ((__VIDimmingFlag_Enable == TRUE) && (_gIdleCount_dimming < 0xFFFFFFFF)) { + _gIdleCount_dimming++; + } + + if ((__VIDVDStopFlag_Enable == TRUE) && (_gIdleCount_dvd < 0xFFFFFFFF)) { + _gIdleCount_dvd++; + } + } + else { + if (_gIdleCount_dimming >= THD_TIME_TO_DIMMING) { + DimmingOFF_Pending = 1; + } + if (_gIdleCount_dvd >= THD_TIME_TO_DVD_STOP) { + __DVDRestartMotor(); + } + + _gIdleCount_dimming = 0; + _gIdleCount_dvd = 0; + THD_TIME_TO_DIMMING = NEW_TIME_TO_DIMMING; + } + + if (__VIDimmingFlag_Enable_old != __VIDimmingFlag_Enable) { + if (__VIDimmingFlag_Enable == FALSE) { + if (_gIdleCount_dimming >= THD_TIME_TO_DIMMING) { + DimmingOFF_Pending = 1; + } + } + + _gIdleCount_dimming = 0; + THD_TIME_TO_DIMMING = NEW_TIME_TO_DIMMING; + } + + if (_gIdleCount_dimming == THD_TIME_TO_DIMMING) { + DimmingON_Pending = 1; + } + + if (DimmingOFF_Pending) { + if (__OSSetVIForceDimming(FALSE, 2, 2) == TRUE) { + DimmingOFF_Pending = 0; + __VIDimmingState = FALSE; + } + } + + if (DimmingON_Pending) { + if (__OSSetVIForceDimming(TRUE, 2, 2) == TRUE) { + DimmingON_Pending = 0; + __VIDimmingState = TRUE; + } + } + + if (__VIDVDStopFlag_Enable_old != __VIDVDStopFlag_Enable) { + if (__VIDVDStopFlag_Enable == FALSE) { + if (_gIdleCount_dvd >= THD_TIME_TO_DVD_STOP) { + __DVDRestartMotor(); + } + } + _gIdleCount_dvd = 0; + } + + if(_gIdleCount_dvd == THD_TIME_TO_DVD_STOP) { + __DVDStopMotorAsync(&__DVDStopMotorCommandBlock, NULL); + } + + __VIDimmingFlag_RF_IDLE = 1; + __VIDimmingFlag_SI_IDLE = 1; + + for(i = 0; i < 10; i++) + { + __VIDimmingFlag_DEV_IDLE[i] = 1; + } + + __VIDimmingFlag_Enable_old = __VIDimmingFlag_Enable; + __VIDVDStopFlag_Enable_old = __VIDVDStopFlag_Enable; + + if ((NEW_TIME_TO_DIMMING > _gIdleCount_dimming) && (__VIDimmingState == FALSE)) { + THD_TIME_TO_DIMMING = NEW_TIME_TO_DIMMING; + } +} + +VIRetraceCallback VISetPreRetraceCallback(VIRetraceCallback cb) { + BOOL enabled; + VIRetraceCallback oldcb; + + oldcb = PreCB; + enabled = OSDisableInterrupts(); + PreCB = cb; + OSRestoreInterrupts(enabled); + return oldcb; +} + +VIRetraceCallback VISetPostRetraceCallback(VIRetraceCallback cb) { + BOOL enabled; + VIRetraceCallback oldcb; + + oldcb = PostCB; + enabled = OSDisableInterrupts(); + PostCB = cb; + OSRestoreInterrupts(enabled); + return oldcb; +} + +timing_s* __VISetExtraTiming(timing_s* t) { + timing_s* old = timingExtra; + + timingExtra = t; + return old; +} + +#pragma dont_inline on +static timing_s* getTiming(VITVMode mode) { + switch (mode) { + case VI_TVMODE_NTSC_INT: return &timing[0]; + case VI_TVMODE_NTSC_DS: return &timing[1]; + case VI_TVMODE_PAL_INT: return &timing[2]; + case VI_TVMODE_PAL_DS: return &timing[3]; + case VI_TVMODE_EURGB60_INT: return &timing[0]; + case VI_TVMODE_EURGB60_DS: return &timing[1]; + case VI_TVMODE_MPAL_INT: return &timing[4]; + case VI_TVMODE_MPAL_DS: return &timing[5]; + case VI_TVMODE_NTSC_PROG: + case VI_TVMODE_MPAL_PROG: + case VI_TVMODE_EURGB60_PROG: return &timing[6]; + case VI_TVMODE_NTSC_3D: return &timing[7]; + case VI_TVMODE_DEBUG_PAL_INT: return &timing[2]; + case VI_TVMODE_DEBUG_PAL_DS: return &timing[3]; + case VI_TVMODE_GCA_INT: return &timing[8]; + case VI_TVMODE_GCA_PROG: return &timing[9]; + case VI_TVMODE_PAL_PROG: return &timing[10]; + case VI_TVMODE_EXTRA_INT: + case VI_TVMODE_EXTRA_DS: + case VI_TVMODE_EXTRA_PROG: + case VI_TVMODE_HD720_PROG: return timingExtra; + default: + return NULL; + } +} +#pragma dont_inline reset + +void __VIInit(VITVMode mode) { + timing_s* tm; + u32 nonInter; + u32 tv; + u32 tvForReg; + volatile u32 a; + u16 hct; + u16 vct; + + nonInter = mode & 3; + tv = (u32)mode >> 2; + *(u32*)OSPhysicalToCached(0xCC) = tv; + + tm = getTiming(mode); + __VIRegs[1] = 2; + + // why? + for (a = 0; a < 1000; a++) {} + + __VIRegs[1] = 0; + __VIRegs[3] = (u32)tm->hlw; + __VIRegs[2] = tm->hce | (tm->hcs << 8); + __VIRegs[5] = tm->hsy | ((tm->hbe640 & 0x1FF) << 7); + __VIRegs[4] = (tm->hbe640 >> 9) | (tm->hbs640 << 1); + + if (encoderType == 0) { + __VIRegs[0x39] = tm->hbeCCIR656 | 0x8000; + __VIRegs[0x3A] = (u32)tm->hbsCCIR656; + } + + __VIRegs[0] = (u32)tm->equ; + __VIRegs[7] = (u32)(tm->prbOdd + (tm->acv * 2) - 2); + __VIRegs[6] = (u32)(tm->psbOdd + 2); + __VIRegs[9] = (u32)(tm->prbEven + (tm->acv * 2) - 2); + __VIRegs[8] = (u32)(tm->psbEven + 2); + __VIRegs[11] = tm->bs1 | (tm->be1 << 5); + __VIRegs[10] = tm->bs3 | (tm->be3 << 5); + __VIRegs[13] = tm->bs2 | (tm->be2 << 5); + __VIRegs[12] = tm->bs4 | (tm->be4 << 5); + __VIRegs[36] = 0x2828; + __VIRegs[27] = 1; + __VIRegs[26] = 0x1001; + hct = tm->hlw + 1; + vct = (tm->nhlines / 2) + 1; + __VIRegs[25] = (u16)(u32)hct; + __VIRegs[24] = vct | 0x1000; + + switch (tv) { + case VI_PAL: + case VI_MPAL: + case VI_DEBUG: + tvForReg = tv; + break; + default: + tvForReg = 0; + } + + if (nonInter == 0 || nonInter == 1) { + __VIRegs[1] = ((nonInter & 1) << 2) | 1 | (tvForReg << 8); + __VIRegs[54] = 0; + return; + } + + __VIRegs[1] = (tvForReg << 8) | 5; + __VIRegs[54] = 1; +} + +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define CLAMP(val, min, max) ((val) > (max) ? (max) : (val) < (min) ? (min) : (val)) + +static void AdjustPosition(u16 acv) { + s32 coeff; + s32 frac; + + HorVer.AdjustedDispPosX = CLAMP((s16)HorVer.DispPosX + displayOffsetH, 0, 0x2D0 - HorVer.DispSizeX); + coeff = (HorVer.FBMode == VI_XFBMODE_SF) ? 2 : 1; + frac = HorVer.DispPosY & 1; + HorVer.AdjustedDispPosY = MAX((s16)HorVer.DispPosY + displayOffsetV, frac); + HorVer.AdjustedDispSizeY = HorVer.DispSizeY + + MIN((s16)HorVer.DispPosY + displayOffsetV - frac, 0) + - MAX((s16)HorVer.DispPosY + (s16)HorVer.DispSizeY + displayOffsetV - (((s16)acv * 2) - frac), 0); + HorVer.AdjustedPanPosY = HorVer.PanPosY + - (MIN((s16)HorVer.DispPosY + displayOffsetV - frac, 0) / coeff); + HorVer.AdjustedPanSizeY = HorVer.PanSizeY + + (MIN((s16)HorVer.DispPosY + displayOffsetV - frac, 0) / coeff) + - (MAX((s16)HorVer.DispPosY + (s16)HorVer.DispSizeY + displayOffsetV - (((s16)acv * 2) - frac), 0) / coeff); +} + +static void ImportAdjustingValues(void) { + displayOffsetH = SCGetDisplayOffsetH(); + displayOffsetV = 0; +} + +void VIInit(void) { + u16 dspCfg; + u32 value; + u32 tv; + u32 tvInBootrom; + + if (IsInitialized) { + return; + } + + OSRegisterVersion(__VIVersion); + IsInitialized = TRUE; + + if (!(__VIRegs[1] & 1)) { + __VIInit(VI_TVMODE_NTSC_INT); + } + + retraceCount = 0; + changed = 0; + shdwChanged = 0; + changeMode = 0; + shdwChangeMode = 0; + flushFlag = 0; + flushFlag3in1 = 0; + + __VIRegs[39] = taps[0] | ((taps[1] & 0x3F) << 10); + __VIRegs[38] = (taps[1] >> 6) | (taps[2] << 4); + __VIRegs[41] = taps[3] | ((taps[4] & 0x3F) << 10); + __VIRegs[40] = (taps[4] >> 6) | (taps[5] << 4); + __VIRegs[43] = taps[6] | ((taps[7] & 0x3F) << 10); + __VIRegs[42] = (taps[7] >> 6) | (taps[8] << 4); + __VIRegs[45] = taps[9] | (taps[10] << 8); + __VIRegs[44] = taps[11] | (taps[12] << 8); + __VIRegs[47] = taps[13] | (taps[14] << 8); + __VIRegs[46] = taps[15] | (taps[16] << 8); + __VIRegs[49] = taps[17] | (taps[18] << 8); + __VIRegs[48] = taps[19] | (taps[20] << 8); + __VIRegs[51] = taps[21] | (taps[22] << 8); + __VIRegs[50] = taps[23] | (taps[24] << 8); + __VIRegs[56] = 0x280; + ImportAdjustingValues(); + + tvInBootrom = *(u32*)OSPhysicalToCached(0xCC); + dspCfg = __VIRegs[1]; + HorVer.nonInter = VIGetScanMode(); + HorVer.tv = ((u32)(dspCfg) & 0x300) >> 8; + + if (tvInBootrom == VI_EURGB60 || (tvInBootrom == VI_PAL && HorVer.tv == VI_NTSC)) { + HorVer.tv = VI_EURGB60; + } + + tv = (HorVer.tv == 3) ? 0 : HorVer.tv; + HorVer.timing = getTiming((tv << 2) + HorVer.nonInter); + regs[1] = dspCfg; + + CurrTiming = HorVer.timing; + CurrTvMode = HorVer.tv; + + HorVer.DispSizeX = 640; + HorVer.DispSizeY = CurrTiming->acv * 2; + HorVer.DispPosX = (720 - HorVer.DispSizeX) / 2; + HorVer.DispPosY = 0; + AdjustPosition(CurrTiming->acv); + HorVer.FBSizeX = 640; + HorVer.FBSizeY = CurrTiming->acv * 2; + HorVer.PanPosX = 0; + HorVer.PanPosY = 0; + HorVer.PanSizeX = 640; + HorVer.PanSizeY = CurrTiming->acv * 2; + HorVer.FBMode = 0; + + HorVer.wordPerLine = 40; + HorVer.std = 40; + HorVer.wpl = 40; + HorVer.xof = 0; + HorVer.black = 1; + HorVer.threeD = 0; + OSInitThreadQueue(&retraceQueue); + value = __VIRegs[24]; + value &= ~0x8000; +#if !DEBUG + value = (u16)value; +#endif + __VIRegs[24] = value; + value = __VIRegs[26]; + value = value & ~0x8000; +#if !DEBUG + value = (u16)value; +#endif + __VIRegs[26] = value; + PreCB = NULL; + PostCB = NULL; + __OSSetInterruptHandler(0x18, __VIRetraceHandler); + __OSUnmaskInterrupts(0x80); + OSRegisterShutdownFunction(&ShutdownFunctionInfo); + + switch(VIGetTvFormat()) { + case VI_PAL: + THD_TIME_TO_DIMMING = 15000; + NEW_TIME_TO_DIMMING = 15000; + THD_TIME_TO_DVD_STOP = 90000; + break; + default: + THD_TIME_TO_DIMMING = 18000; + NEW_TIME_TO_DIMMING = 18000; + THD_TIME_TO_DVD_STOP = 108000; + break; + } + + _gIdleCount_dimming = 0; + _gIdleCount_dvd = 0; + g_current_time_to_dim = VI_DM_DEFAULT; + __VIDimming_All_Clear = TRUE; + __VIDimmingState = FALSE; + VIEnableDimming(TRUE); + + VIEnableDVDStopMotor(FALSE); + __VISetRevolutionModeSimple(); +} + +void VIWaitForRetrace(void) { + BOOL enabled; + u32 count; + + enabled = OSDisableInterrupts(); + count = retraceCount; + do { + OSSleepThread(&retraceQueue); + } while (count == retraceCount); + OSRestoreInterrupts(enabled); +} + +static void setInterruptRegs(timing_s* tm) { +#if DEBUG + u16 vct, hct; +#else + u16 hct, vct; +#endif + u16 borrow; + + vct = tm->nhlines / 2; + borrow = tm->nhlines % 2; + hct = (u16)((borrow)? tm->hlw : (u16)0); + vct++; + hct++; + regs[25] = (u16)(u32)hct; + MARK_CHANGED(25); + regs[24] = vct | 0x1000; + MARK_CHANGED(24); + + vct; // fixes regalloc +} + +static void setPicConfig(u16 fbSizeX, VIXFBMode xfbMode, u16 panPosX, u16 panSizeX, u8* wordPerLine, u8* std, u8* wpl, u8* xof) { + *wordPerLine = (fbSizeX + 15) / 16; + *std = (xfbMode == VI_XFBMODE_SF) ? *wordPerLine : (u8)(*wordPerLine * 2); + *xof = panPosX % 16; + *wpl = (*xof + panSizeX + 15) / 16; + regs[0x24] = *std | (*wpl << 8); + changed |= 0x8000000; +} + +static void setBBIntervalRegs(timing_s* tm) { + u16 val; + + val = tm->bs1 | (tm->be1 << 5); + regs[11] = val; + changed |= 0x10000000000000; + + val = tm->bs3 | (tm->be3 << 5); + regs[10] = val; + changed |= 0x20000000000000; + + val = tm->bs2 | (tm->be2 << 5); + regs[13] = val; + changed |= 0x4000000000000; + + val = tm->bs4 | (tm->be4 << 5); + regs[12] = val; + changed |= (1LL << (63-12)); +} + +static void setScalingRegs(u16 panSizeX, u16 dispSizeX, BOOL threeD) { + u32 scale; + + panSizeX = threeD ? (panSizeX << 1) : panSizeX; + if (panSizeX < dispSizeX) { + scale = (u32)(dispSizeX + (panSizeX << 8) - 1) / dispSizeX; + regs[37] = scale | 0x1000; + changed |= 0x04000000; + regs[56] = (u32)panSizeX; + changed |= 0x80; + } else { + regs[37] = 0x100; + changed |= 0x04000000; + } +} + +static void calcFbbs(u32 bufAddr, u16 panPosX, u16 panPosY, u8 wordPerLine, VIXFBMode xfbMode, u16 dispPosY, u32* tfbb, u32* bfbb) { + u32 bytesPerLine; + u32 xoffInWords; + + xoffInWords = (u32)panPosX / 16; + bytesPerLine = (u32)wordPerLine * 32; + *tfbb = bufAddr + (xoffInWords << 5) + (bytesPerLine * panPosY); + *bfbb = (xfbMode == VI_XFBMODE_SF) ? *tfbb : *tfbb + bytesPerLine; + + if (dispPosY % 2 == 1) { + u32 tmp = *tfbb; + *tfbb = *bfbb; + *bfbb = tmp; + } + + *tfbb &= 0x3FFFFFFF; + *bfbb &= 0x3FFFFFFF; +} + +static void setFbbRegs(SomeVIStruct* HorVer, u32* tfbb, u32* bfbb, u32* rtfbb, u32* rbfbb) { + u32 shifted; + + calcFbbs(HorVer->bufAddr, HorVer->PanPosX, HorVer->AdjustedPanPosY, HorVer->wordPerLine, HorVer->FBMode, HorVer->AdjustedDispPosY, tfbb, bfbb); + if (HorVer->threeD) { + calcFbbs(HorVer->rbufAddr, HorVer->PanPosX, HorVer->AdjustedPanPosY, HorVer->wordPerLine, HorVer->FBMode, HorVer->AdjustedDispPosY, rtfbb, rbfbb); + } + + if (*tfbb < 0x01000000U && *bfbb < 0x01000000U && *rtfbb < 0x01000000U && *rbfbb < 0x01000000U) { + shifted = 0; + } else { + shifted = 1; + } + + if (shifted) { + *tfbb >>= 5; + *bfbb >>= 5; + *rtfbb >>= 5; + *rbfbb >>= 5; + } + + regs[15] = (u16)(*tfbb & 0xFFFF); + MARK_CHANGED(15); + regs[14] = (shifted << 12) | ((*tfbb >> 16) | (HorVer->xof << 8)); + MARK_CHANGED(14); + regs[19] = (u16)(*bfbb & 0xFFFF); + MARK_CHANGED(19); + regs[18] = (*bfbb >> 16); + MARK_CHANGED(18); + + if (HorVer->threeD) { + regs[17] = (u16)(*rtfbb & 0xFFFF); + MARK_CHANGED(17); + regs[16] = *rtfbb >> 16; + MARK_CHANGED(16); + regs[21] = (u16)(*rbfbb & 0xFFFF); + MARK_CHANGED(21); + regs[20] = *rbfbb >> 16; + MARK_CHANGED(20); + } +} + +static void setHorizontalRegs(timing_s* tm, u16 dispPosX, u16 dispSizeX) { + u32 hbe; + u32 hbs; + u32 hbeLo; + u32 hbeHi; + + regs[3] = (u16)(u32)tm->hlw; + MARK_CHANGED(3); + regs[2] = tm->hce | (tm->hcs << 8); + MARK_CHANGED(2); + + if (HorVer.tv == 8) { + hbe = (u32)(tm->hbe640 + 172); + hbs = tm->hbs640; + } else { + hbe = (u32)(tm->hbe640 - 40 + dispPosX); + hbs = (u32)(tm->hbs640 + 40 + dispPosX - (720 - dispSizeX)); + } + + hbeLo = hbe & 0x1FF; + hbeHi = hbe >> 9; + + regs[5] = tm->hsy | (hbeLo << 7); + MARK_CHANGED(5); + regs[4] = hbeHi | (hbs * 2); + MARK_CHANGED(4); +} + +static void setVerticalRegs(u16 dispPosY, u16 dispSizeY, u8 equ, u16 acv, u16 prbOdd, u16 prbEven, u16 psbOdd, u16 psbEven, BOOL black) { + u16 actualPrbOdd; + u16 actualPrbEven; + u16 actualPsbOdd; + u16 actualPsbEven; + u16 actualAcv; + u16 c; + u16 d; + + if (HorVer.nonInter == 2 || HorVer.nonInter == 3) { + c = 1; + d = 2; + } else { + c = 2; + d = 1; + } + + if ((dispPosY % 2) == 0) { + actualPrbOdd = prbOdd + (d * dispPosY); + actualPsbOdd = psbOdd + (d * (((c * acv) - dispSizeY) - dispPosY)); + actualPrbEven = prbEven + (d * dispPosY); + actualPsbEven = psbEven + (d * (((c * acv) - dispSizeY) - dispPosY)); + } else { + actualPrbOdd = prbEven + (d * dispPosY); + actualPsbOdd = psbEven + (d * (((c * acv) - dispSizeY) - dispPosY)); + actualPrbEven = prbOdd + (d * dispPosY); + actualPsbEven = psbOdd + (d * (((c * acv) - dispSizeY) - dispPosY)); + } + + actualAcv = dispSizeY / c; + + if (black) { + actualPrbOdd += 2 * actualAcv - 2; + actualPsbOdd += 2; + actualPrbEven += 2 * actualAcv - 2; + actualPsbEven += 2; + actualAcv = 0; + } + + regs[0] = equ | (actualAcv << 4); + MARK_CHANGED(0); + regs[7] = (u16)(u32)actualPrbOdd; + MARK_CHANGED(7); + regs[6] = (u16)(u32)actualPsbOdd; + MARK_CHANGED(6); + regs[9] = (u16)(u32)actualPrbEven; + MARK_CHANGED(9); + regs[8] = (u16)(u32)actualPsbEven; + MARK_CHANGED(8); +} + +static void PrintDebugPalCaution(void) { + static u32 message; + + if (message == 0) { + message = 1; + OSReport("***************************************\n"); + OSReport(" ! ! ! C A U T I O N ! ! ! \n"); + OSReport("This TV format \"DEBUG_PAL\" is only for \n"); + OSReport("temporary solution until PAL DAC board \n"); + OSReport("is available. Please do NOT use this \n"); + OSReport("mode in real games!!! \n"); + OSReport("***************************************\n"); + } +} + +void VIConfigure(const GXRenderModeObj* rm) { + timing_s* tm; + u32 regDspCfg; + u32 regClksel; + BOOL enabled; + u32 newNonInter; + u32 tvInBootrom; + u32 tvInGame; + + enabled = OSDisableInterrupts(); + newNonInter = rm->viTVmode & 3; + + if (HorVer.nonInter != newNonInter) { + changeMode = 1; + HorVer.nonInter = newNonInter; + } + + VI_ASSERTMSGLINE1(2617, (rm->viHeight & 1) == 0, + "VIConfigure(): Odd number(%d) is specified to viHeight\n", + rm->viHeight); + +#if DEBUG + if (rm->xFBmode == VI_XFBMODE_DF || newNonInter == VI_TVMODE_NTSC_PROG || newNonInter == 3) { + VI_ASSERTMSGLINE2(2624, rm->xfbHeight == rm->viHeight, + "VIConfigure(): xfbHeight(%d) is not equal to viHeight(%d) when DF XFB mode or progressive mode is specified\n", + rm->xfbHeight, rm->viHeight); + } + + if (rm->xFBmode == VI_XFBMODE_SF && newNonInter != VI_TVMODE_NTSC_PROG && newNonInter != 3) { + VI_ASSERTMSGLINE2(2632, rm->viHeight == rm->xfbHeight * 2, + "VIConfigure(): xfbHeight(%d) is not as twice as viHeight(%d) when SF XFB mode is specified\n", + rm->xfbHeight, rm->viHeight); + } +#endif + + tvInGame = (u32)rm->viTVmode >> 2; + tvInBootrom = *(u32*)OSPhysicalToCached(0xCC); + + if (tvInGame == VI_DEBUG_PAL) { + PrintDebugPalCaution(); + } + + if (((tvInBootrom != VI_PAL && tvInBootrom != VI_EURGB60) && (tvInGame == VI_PAL || tvInGame == VI_EURGB60)) || + ((tvInBootrom == VI_PAL || tvInBootrom == VI_EURGB60) && (tvInGame != VI_PAL && tvInGame != VI_EURGB60))) + { + OSPanic(__FILE__, 2651, "VIConfigure(): Tried to change mode from (%d) to (%d), which is forbidden\n", tvInBootrom, tvInGame); + } + + if ((tvInGame == VI_NTSC) || (tvInGame == VI_MPAL)) { + HorVer.tv = tvInBootrom; + } else { + HorVer.tv = tvInGame; + } + + HorVer.DispPosX = rm->viXOrigin; + HorVer.DispPosY = (HorVer.nonInter == 1) ? (u16)(rm->viYOrigin * 2) : rm->viYOrigin; + HorVer.DispSizeX = rm->viWidth; + HorVer.FBSizeX = rm->fbWidth; + HorVer.FBSizeY = rm->xfbHeight; + HorVer.FBMode = rm->xFBmode; + HorVer.PanSizeX = HorVer.FBSizeX; + HorVer.PanSizeY = HorVer.FBSizeY; + HorVer.PanPosX = 0; + HorVer.PanPosY = 0; + HorVer.DispSizeY = (HorVer.nonInter == 2) ? HorVer.PanSizeY : + (HorVer.nonInter == 3) ? HorVer.PanSizeY : + (HorVer.FBMode == VI_XFBMODE_SF) ? (u16)(HorVer.PanSizeY * 2) : + HorVer.PanSizeY; + HorVer.threeD = (HorVer.nonInter == 3) ? TRUE : FALSE; + + tm = getTiming((HorVer.tv << 2) + HorVer.nonInter); + HorVer.timing = tm; + + AdjustPosition(tm->acv); + VI_ASSERTMSGLINE2(2694, rm->viXOrigin <= tm->hlw + 40 - tm->hbe640, + "VIConfigure(): viXOrigin(%d) cannot be greater than %d in this TV mode\n", + rm->viXOrigin, tm->hlw + 40 - tm->hbe640); + VI_ASSERTMSGLINE2(2699, rm->viXOrigin + rm->viWidth >= 680 - tm->hbs640, + "VIConfigure(): viXOrigin + viWidth (%d) cannot be less than %d in this TV mode\n", + rm->viXOrigin + rm->viWidth, 680 - tm->hbs640); + + setInterruptRegs(tm); + + regDspCfg = regs[1]; + regClksel = regs[54]; + + if (HorVer.nonInter == VI_PROGRESSIVE || HorVer.nonInter == 3) { + regDspCfg = (((u32)(regDspCfg)) & ~0x00000004) | (((u32)(1)) << 2); + + if (HorVer.tv == VI_HD720) { + regClksel = (((u32)(regClksel)) & ~0x00000001) | 0; + } else { + regClksel = (((u32)(regClksel)) & ~0x00000001) | 1; + } + + } else { + OLD_SET_REG_FIELD(2722, regDspCfg, 1, 2, HorVer.nonInter & 1); + regClksel = (((u32)(regClksel)) & ~0x00000001); + } + + OLD_SET_REG_FIELD(2726, regDspCfg, 1, 3, HorVer.threeD); + + if ((HorVer.tv == VI_PAL) || (HorVer.tv == VI_MPAL) || (HorVer.tv == 3)) { + OLD_SET_REG_FIELD(2730, regDspCfg, 2, 8, HorVer.tv); + } else { + regDspCfg = (((u32)(regDspCfg)) & ~0x00000300); + } + + regs[1] = regDspCfg; + regs[54] = (u16)regClksel; + + MARK_CHANGED(1); + MARK_CHANGED(54); + + setScalingRegs(HorVer.PanSizeX, HorVer.DispSizeX, HorVer.threeD); + setHorizontalRegs(tm, HorVer.AdjustedDispPosX, HorVer.DispSizeX); + setBBIntervalRegs(tm); + setPicConfig(HorVer.FBSizeX, HorVer.FBMode, HorVer.PanPosX, HorVer.PanSizeX, &HorVer.wordPerLine, &HorVer.std, &HorVer.wpl, &HorVer.xof); + if (FBSet != 0) { + setFbbRegs(&HorVer, &HorVer.tfbb, &HorVer.bfbb, &HorVer.rtfbb, &HorVer.rbfbb); + } + setVerticalRegs(HorVer.AdjustedDispPosY, HorVer.AdjustedDispSizeY, tm->equ, tm->acv, tm->prbOdd, tm->prbEven, tm->psbOdd, tm->psbEven, HorVer.black); + OSRestoreInterrupts(enabled); +} + +void VIConfigurePan(u16 xOrg, u16 yOrg, u16 width, u16 height) { + BOOL enabled; + timing_s* tm; + +#if DEBUG + VI_ASSERTMSGLINE1(2788, (xOrg & 1) == 0, + "VIConfigurePan(): Odd number(%d) is specified to xOrg\n", + xOrg); + if (HorVer.FBMode == VI_XFBMODE_DF) { + VI_ASSERTMSGLINE1(2793, (height & 1) == 0, + "VIConfigurePan(): Odd number(%d) is specified to height when DF XFB mode\n", + height); + } +#endif + enabled = OSDisableInterrupts(); + HorVer.PanPosX = xOrg; + HorVer.PanPosY = yOrg; + HorVer.PanSizeX = width; + HorVer.PanSizeY = height; + HorVer.DispSizeY = (HorVer.nonInter == 2) ? HorVer.PanSizeY : + (HorVer.nonInter == 3) ? HorVer.PanSizeY : + (HorVer.FBMode == VI_XFBMODE_SF) ? (u16)(HorVer.PanSizeY * 2) : + HorVer.PanSizeY; + tm = HorVer.timing; + AdjustPosition(tm->acv); + setScalingRegs(HorVer.PanSizeX, HorVer.DispSizeX, HorVer.threeD); + setPicConfig(HorVer.FBSizeX, HorVer.FBMode, HorVer.PanPosX, HorVer.PanSizeX, &HorVer.wordPerLine, &HorVer.std, &HorVer.wpl, &HorVer.xof); + if (FBSet != 0) { + setFbbRegs(&HorVer, &HorVer.tfbb, &HorVer.bfbb, &HorVer.rtfbb, &HorVer.rbfbb); + } + setVerticalRegs(HorVer.AdjustedDispPosY, HorVer.DispSizeY, tm->equ, tm->acv, tm->prbOdd, tm->prbEven, tm->psbOdd, tm->psbEven, HorVer.black); + OSRestoreInterrupts(enabled); +} + +void VIFlush(void) { + BOOL enabled; + s32 regIndex; + + enabled = OSDisableInterrupts(); + shdwChangeMode |= changeMode; + changeMode = 0; + shdwChanged |= changed; + + while (changed != 0) { + regIndex = cntlzd(changed); + shdwRegs[regIndex] = regs[regIndex]; + changed &= ~((u64)1 << (63 - regIndex)); + } + + flushFlag = 1; + flushFlag3in1 = 1; + NextBufAddr = HorVer.bufAddr; + OSRestoreInterrupts(enabled); +} + +void VISetNextFrameBuffer(void* fb) { + BOOL enabled; + + VI_ASSERTMSGLINE1(2886, ((u32)fb & 0x1F) == 0, + "VISetNextFrameBuffer(): Frame buffer address(0x%08x) is not 32byte aligned\n", + fb); + enabled = OSDisableInterrupts(); + HorVer.bufAddr = (u32)fb; + FBSet = 1; + setFbbRegs(&HorVer, &HorVer.tfbb, &HorVer.bfbb, &HorVer.rtfbb, &HorVer.rbfbb); + OSRestoreInterrupts(enabled); +} + +void* VIGetNextFrameBuffer(void) { + return *(void**)(&NextBufAddr); +} + +void* VIGetCurrentFrameBuffer(void) { + return *(void**)(&CurrBufAddr); +} + +void VISetNextRightFrameBuffer(void* fb) { + BOOL enabled; + + ASSERTMSGLINEV(2284, ((u32)fb & 0x1F) == 0, + "VISetNextFrameBuffer(): Frame buffer address(0x%08x) is not 32byte aligned\n", + fb); + enabled = OSDisableInterrupts(); + HorVer.rbufAddr = (u32)fb; + FBSet = 1; + setFbbRegs(&HorVer, &HorVer.tfbb, &HorVer.bfbb, &HorVer.rtfbb, &HorVer.rbfbb); + OSRestoreInterrupts(enabled); +} + +void VISetBlack(BOOL black) { + BOOL enabled; + timing_s* tm; + + enabled = OSDisableInterrupts(); + HorVer.black = black; + tm = HorVer.timing; + setVerticalRegs(HorVer.AdjustedDispPosY, HorVer.DispSizeY, tm->equ, tm->acv, tm->prbOdd, tm->prbEven, tm->psbOdd, tm->psbEven, HorVer.black); + OSRestoreInterrupts(enabled); +} + +void VISet3D(BOOL threeD) { + BOOL enabled; + u32 reg; + + enabled = OSDisableInterrupts(); + HorVer.threeD = threeD; + reg = regs[1]; + OLD_SET_REG_FIELD(2355, reg, 1, 3, HorVer.threeD); + regs[1] = reg; + MARK_CHANGED(1); + setScalingRegs(HorVer.PanSizeX, HorVer.DispSizeX, HorVer.threeD); + OSRestoreInterrupts(enabled); +} + +u32 VIGetRetraceCount(void) { + return retraceCount; +} + +static void GetCurrentDisplayPosition(u32* hct, u32* vct) { + u32 hcount, vcount0, vcount; + vcount = __VIRegs[VI_VERT_COUNT] & 0x7FF; + + do { + vcount0 = vcount; + hcount = __VIRegs[VI_HORIZ_COUNT] & 0x7FF; + vcount = __VIRegs[VI_VERT_COUNT] & 0x7FF; + } while (vcount0 != vcount); + + *hct = hcount; + *vct = vcount; +} + +static u32 getCurrentHalfLine(void) { + u32 hcount, vcount; + GetCurrentDisplayPosition(&hcount, &vcount); + + return ((vcount - 1) << 1) + ((hcount - 1) / CurrTiming->hlw); +} + +static u32 getCurrentFieldEvenOdd(void) { + return (getCurrentHalfLine() < CurrTiming->nhlines) ? 1 : 0; +} + +u32 VIGetNextField(void) { + s32 nextField; + BOOL enabled; +#if !DEBUG + u8 unused[4]; +#endif + + enabled = OSDisableInterrupts(); + nextField = getCurrentFieldEvenOdd() ^ 1; + OSRestoreInterrupts(enabled); + return nextField ^ (HorVer.AdjustedDispPosY & 1); +} + +u32 VIGetCurrentLine(void) { + u32 halfLine; + timing_s* tm; + BOOL enabled; + + tm = CurrTiming; + enabled = OSDisableInterrupts(); + halfLine = getCurrentHalfLine(); + OSRestoreInterrupts(enabled); + if (halfLine >= tm->nhlines) { + halfLine -= tm->nhlines; + } + return halfLine >> 1U; +} + +u32 VIGetTvFormat(void) { + u32 format; + BOOL enabled; + + enabled = OSDisableInterrupts(); + + switch (CurrTvMode) { + case VI_NTSC: + case VI_DEBUG: + case 6: + case 7: + case 8: + format = VI_NTSC; + break; + case VI_PAL: + case VI_DEBUG_PAL: + format = VI_PAL; + break; + case VI_EURGB60: + case VI_MPAL: + format = CurrTvMode; + break; + default: + ASSERTLINE(3198, FALSE); + } + + OSRestoreInterrupts(enabled); + return format; +} + +u32 VIGetScanMode(void) { + u32 scanMode; + BOOL enabled = OSDisableInterrupts(); + + if ((u32)(__VIRegs[54] & 1) == 1) { + scanMode = 2; + } else if (((u32)(__VIRegs[1] & 4) >> 2) == 0) { + scanMode = 0; + } else { + scanMode = 1; + } + + OSRestoreInterrupts(enabled); + return scanMode; +} + +u32 VIGetDTVStatus(void) { + u32 dtvStatus; + BOOL enabled = OSDisableInterrupts(); + + dtvStatus = __VIRegs[55] & 3; + OSRestoreInterrupts(enabled); + return dtvStatus & 1; +} + +void __VISetAdjustingValues(s16 x, s16 y) { + BOOL enabled; + timing_s* tm; + + ASSERTMSGLINE(2611, (y & 1) == 0, "__VISetAdjustValues(): y offset should be an even number"); + enabled = OSDisableInterrupts(); + displayOffsetH = x; + displayOffsetV = y; + tm = HorVer.timing; + AdjustPosition(tm->acv); + setHorizontalRegs(tm, HorVer.AdjustedDispPosX, HorVer.DispSizeX); + if (FBSet != 0) { + setFbbRegs(&HorVer, &HorVer.tfbb, &HorVer.bfbb, &HorVer.rtfbb, &HorVer.rbfbb); + } + setVerticalRegs(HorVer.AdjustedDispPosY, HorVer.AdjustedDispSizeY, tm->equ, tm->acv, tm->prbOdd, tm->prbEven, tm->psbOdd, tm->psbEven, HorVer.black); + OSRestoreInterrupts(enabled); +} + +void __VIGetAdjustingValues(s16* x, s16* y) { + BOOL enabled; + + enabled = OSDisableInterrupts(); + *x = displayOffsetH; + *y = displayOffsetV; + OSRestoreInterrupts(enabled); +} + +// DEBUG NONMATCHING - wrong reg use, equivalent +void __VIEnableRawPositionInterrupt(s16 x, s16 y, void (*callback)(s16, s16)) { + BOOL enabled; + u32 halfLine; + u32 halfLineOff; + + enabled = OSDisableInterrupts(); + __VIRegs[29] = x + 1U; + __VIRegs[31] = x + 1U; + + if (HorVer.nonInter == 0) { + if (y & 1) { + halfLineOff = CurrTiming->prbEven + ((CurrTiming->equ * 3) + CurrTiming->nhlines); + __VIRegs[30] = (((halfLineOff / 2) + (y / 2)) + 1) | 0x1000; + } else { + halfLineOff = CurrTiming->prbOdd + (CurrTiming->equ * 3); + __VIRegs[28] = (((halfLineOff / 2) + (y / 2)) + 1) | 0x1000; + } + } else if (HorVer.nonInter == 1) { + ASSERTLINE(2702, (y & 1) == 0); + halfLine = CurrTiming->prbOdd + ((CurrTiming->equ * 3)) + y; + __VIRegs[28] = ((halfLine / 2) + 1) | 0x1000; + __VIRegs[30] = (((halfLine + CurrTiming->nhlines) / 2) + 1) | 0x1000; + } else if (HorVer.nonInter == 2) { + halfLine = CurrTiming->prbOdd + ((CurrTiming->equ * 3)) + y; + __VIRegs[28] = (halfLine + 1) | 0x1000; + __VIRegs[30] = 0; + } + + PositionCallback = callback; + OSRestoreInterrupts(enabled); +} + +void (*__VIDisableRawPositionInterrupt())(s16, s16) { + BOOL enabled; + void (*old)(s16, s16); + + enabled = OSDisableInterrupts(); + __VIRegs[28] = 0; + __VIRegs[30] = 0; + + old = PositionCallback; + PositionCallback = 0; + OSRestoreInterrupts(enabled); + return old; +} + +void __VIDisplayPositionToXY(u32 hct, u32 vct, s16* x, s16* y) { + u32 halfLine = ((vct - 1) << 1) + ((hct - 1) / CurrTiming->hlw); + + if (HorVer.nonInter == VI_INTERLACE) { + if (halfLine < CurrTiming->nhlines) { + if (halfLine < CurrTiming->equ * 3 + CurrTiming->prbOdd) { + *y = -1; + } else if (halfLine >= CurrTiming->nhlines - CurrTiming->psbOdd) { + *y = -1; + } else { + *y = (s16)((halfLine - CurrTiming->equ * 3 - CurrTiming->prbOdd) & ~1); + } + } else { + halfLine -= CurrTiming->nhlines; + + if (halfLine < CurrTiming->equ * 3 + CurrTiming->prbEven) { + *y = -1; + } else if (halfLine >= CurrTiming->nhlines - CurrTiming->psbEven) { + *y = -1; + } else { + *y = (s16)(((halfLine - CurrTiming->equ * 3 - CurrTiming->prbEven) & ~1) + 1); + } + } + } else if (HorVer.nonInter == VI_NON_INTERLACE) { + if (halfLine >= CurrTiming->nhlines) { + halfLine -= CurrTiming->nhlines; + } + + if (halfLine < CurrTiming->equ * 3 + CurrTiming->prbOdd) { + *y = -1; + } else if (halfLine >= CurrTiming->nhlines - CurrTiming->psbOdd) { + *y = -1; + } else { + *y = (s16)((halfLine - CurrTiming->equ * 3 - CurrTiming->prbOdd) & ~1); + } + } else if (HorVer.nonInter == VI_PROGRESSIVE) { + if (halfLine < CurrTiming->nhlines) { + if (halfLine < CurrTiming->equ * 3 + CurrTiming->prbOdd) { + *y = -1; + } else if (halfLine >= CurrTiming->nhlines - CurrTiming->psbOdd) { + *y = -1; + } else { + *y = (s16)(halfLine - CurrTiming->equ * 3 - CurrTiming->prbOdd); + } + } else { + halfLine -= CurrTiming->nhlines; + + if (halfLine < CurrTiming->equ * 3 + CurrTiming->prbEven) { + *y = -1; + } else if (halfLine >= CurrTiming->nhlines - CurrTiming->psbEven) { + *y = -1; + } else + *y = (s16)((halfLine - CurrTiming->equ * 3 - CurrTiming->prbEven) & ~1); + } + } + + *x = (s16)(hct - 1); +} + +void __VIGetCurrentPosition(s16* x, s16* y) { + u32 hcount, vcount; + GetCurrentDisplayPosition(&hcount, &vcount); + __VIDisplayPositionToXY(hcount, vcount, x, y); +} + +void __VISetLatchMode(u32 mode) { + u32 reg; + + reg = __VIRegs[1]; + OLD_SET_REG_FIELD(2834, reg, 2, 4, mode); + OLD_SET_REG_FIELD(2835, reg, 2, 6, mode); + __VIRegs[1] = reg; +} + +#pragma dont_inline on +int __VIGetLatch0Position(s16* px, s16* py) { + u32 hcount; + u32 vcount; + + if (((__VIRegs[32] & 0x8000) >> 15) != 0) { + vcount = __VIRegs[32] & 0x7FF; + hcount = __VIRegs[33] & 0x7FF; + __VIRegs[32] = 0; + __VIRegs[33] = 0; + __VIDisplayPositionToXY(hcount, vcount, px, py); + return 1; + } + + *px = *py = -1; + return 0; +} +#pragma dont_inline reset + +#pragma dont_inline on +int __VIGetLatch1Position(s16* px, s16* py) { + u32 hcount; + u32 vcount; + + if (((__VIRegs[34] & 0x8000) >> 15) != 0) { + vcount = __VIRegs[34] & 0x7FF; + hcount = __VIRegs[35] & 0x7FF; + __VIRegs[34] = 0; + __VIRegs[35] = 0; + __VIDisplayPositionToXY(hcount, vcount, px, py); + return 1; + } + + *px = *py = -1; + return 0; +} +#pragma dont_inline reset + +int __VIGetLatchPosition(u32 port, s16* px, s16* py) { + if (port == 0) { + return __VIGetLatch0Position(px, py); + } else { + return __VIGetLatch1Position(px, py); + } +} + +BOOL VIEnableDimming(BOOL enable) { + u8 value; + BOOL old = __VIDimmingFlag_Enable; + + if (enable == TRUE) { + value = SCGetScreenSaverMode(); + + if (value == 0) { + enable = FALSE; + } + } + + __VIDimmingFlag_Enable = enable; + return old; +} + +void VIResetDimmingCount() { + __VIResetDev0Idle(); +} + +BOOL VIEnableDVDStopMotor(BOOL enable) { + BOOL old = __VIDVDStopFlag_Enable; + __VIDVDStopFlag_Enable = enable; + return old; +} + +BOOL __VIResetSIIdle() { + __VIDimmingFlag_SI_IDLE = 0; + return TRUE; +} + +BOOL __VIResetDev0Idle() { + __VIDimmingFlag_DEV_IDLE[0] = 0; + return TRUE; +} diff --git a/src/revolution/vi/vi3in1.c b/src/revolution/vi/vi3in1.c new file mode 100644 index 0000000000..dbc4ef2209 --- /dev/null +++ b/src/revolution/vi/vi3in1.c @@ -0,0 +1,501 @@ +#include +#include + +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; +} diff --git a/src/revolution/wenc/wenc.c b/src/revolution/wenc/wenc.c new file mode 100644 index 0000000000..a738e08f1a --- /dev/null +++ b/src/revolution/wenc/wenc.c @@ -0,0 +1,117 @@ +#include +#include + +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; +} diff --git a/src/revolution/wpad/WPAD.c b/src/revolution/wpad/WPAD.c new file mode 100644 index 0000000000..ab34be44bb --- /dev/null +++ b/src/revolution/wpad/WPAD.c @@ -0,0 +1,434 @@ +#include +#include +#include + +#include + +#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); +} diff --git a/src/revolution/wpad/WUD.c b/src/revolution/wpad/WUD.c new file mode 100644 index 0000000000..54685342a8 --- /dev/null +++ b/src/revolution/wpad/WUD.c @@ -0,0 +1,63 @@ +#include +#include + +#include "__wud.h" + +wud_cb_st __rvl_wudcb; + +static u16 _dev_handle_queue_size[WUD_MAX_DEV_ENTRY]; +static u16 _dev_handle_notack_num[WUD_MAX_DEV_ENTRY]; + +u8 WUDGetBufferStatus(void) { + wud_cb_st* p_wcb = &__rvl_wudcb; + u8 ret; + BOOL intrStatus = OSDisableInterrupts(); + + ret = p_wcb->bufferStatus1 - p_wcb->bufferStatus0; + + OSRestoreInterrupts(intrStatus); + return ret; +} + +u16 _WUDGetQueuedSize(s8 dev_handle) { + u16 queuedSize; + BOOL intrStatus = OSDisableInterrupts(); + + if (dev_handle >= 0 && dev_handle < WUD_MAX_DEV_ENTRY) + queuedSize = WUDiGetQueueSizeForHandle(dev_handle); + else + queuedSize = 0; + + OSRestoreInterrupts(intrStatus); + return queuedSize; +} + +u16 _WUDGetNotAckedSize(s8 dev_handle) { + u16 notAckedSize; + BOOL intrStatus = OSDisableInterrupts(); + + if (dev_handle >= 0 && dev_handle < WUD_MAX_DEV_ENTRY) + notAckedSize = WUDiGetNotAckNumForHandle(dev_handle); + else + notAckedSize = 0; + + OSRestoreInterrupts(intrStatus); + return notAckedSize; +} + +u8 _WUDGetLinkNumber(void) { + wud_cb_st* p_wcb = &__rvl_wudcb; + BOOL intrStatus = OSDisableInterrupts(); + u8 linkedNum = p_wcb->linkedNum; + + OSRestoreInterrupts(intrStatus); + return linkedNum; +} + +u16 WUDiGetQueueSizeForHandle(u8 dev_handle) { + return _dev_handle_queue_size[dev_handle]; +} + +u16 WUDiGetNotAckNumForHandle(u8 dev_handle) { + return _dev_handle_notack_num[dev_handle]; +} diff --git a/src/revolution/wpad/__wpad.h b/src/revolution/wpad/__wpad.h new file mode 100644 index 0000000000..4a14700fab --- /dev/null +++ b/src/revolution/wpad/__wpad.h @@ -0,0 +1,538 @@ +#ifndef _REVOLUTION_WPAD_PRIVATE_H_ +#define _REVOLUTION_WPAD_PRIVATE_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define RPT_REPORT_ID 0 +#define RPT_MAX_SIZE 21 + +// Limits +#define RPTID_OUT_LO RPTID_SET_RUMBLE +#define RPTID_OUT_HI RPTID_SET_DPD_CSB + +#define RPTID_IN_LO RPTID_STATUS +#define RPTID_IN_HI RPTID_DATA_BTN_ACC_DPD18_2 + +// All outgoing reports +#define RPT_OUT_FLAGS 1 + +#define RPT_OUT_FLAG_ENABLE_FEATURE 2 +#define RPT_OUT_FLAG_REQUEST_ACK_RPT 1 +#define RPT_OUT_FLAG_RUMBLE 0 + +// All incoming reports with Button data (all except 0x3d) +#define RPT_BTN0 1 +#define RPT_BTN1 2 + +// All incoming reports with Accelerometer (Standard) data (0x31, 0x33, 0x35, 0x37) +#define RPT_ACC_OFFSET 1 +#define RPT_ACC_SIZE 3 + +/* + * Outgoing reports (from POV of the host) + */ + +// Report 0x10: Set rumble status +#define RPTID_SET_RUMBLE 0x10 +#define RPT10_SIZE 1 + +#define RPT10_RUMBLE 0 + +// Report 0x11: Set LED lights +#define RPTID_SET_PORT 0x11 // internally called SetPort +#define RPT11_SIZE 1 + +#define RPT11_LED 0 + +// Report 0x12: Set data reporting mode +#define RPTID_SET_DATA_REPORT_MODE 0x12 +#define RPT12_SIZE 2 + +#define RPT12_CONT_REPORT 0 +#define RPT12_DATA_REPORT_MODE 1 + +// Report 0x13: Enable IR camera +#define RPTID_ENABLE_DPD 0x13 // internally called the DPD +#define RPT13_SIZE 1 + +#define RPT13_DPD_ENABLE 0 + +// Report 0x14: Enable IR camera +#define RPTID_ENABLE_SPEAKER 0x14 +#define RPT14_SIZE 1 + +#define RPT14_SPEAKER_ENABLE 0 + +// Report 0x15: Request status report +#define RPTID_REQUEST_STATUS 0x15 +#define RPT15_SIZE 1 + +// Report 0x16: Write data +#define RPTID_WRITE_DATA 0x16 +#define RPT16_SIZE RPT_MAX_SIZE + +#define RPT16_DATA_DST_ADDRESS 0 +#define RPT16_DATA_LENGTH 4 +#define RPT16_DATA 5 + +// Report 0x17: Read data +#define RPTID_READ_DATA 0x17 +#define RPT17_SIZE 6 + +#define RPT17_DATA_SRC_ADDRESS 0 +#define RPT17_DATA_LENGTH 4 + +// Report 0x18: Send speaker data +#define RPTID_SEND_SPEAKER_DATA 0x18 +#define RPT18_SIZE RPT_MAX_SIZE + +#define RPT18_DATA_LENGTH 0 +#define RPT18_DATA 1 + +// Report 0x19: Mute speaker +#define RPTID_MUTE_SPEAKER 0x19 +#define RPT19_SIZE 1 + +#define RPT19_SPEAKER_MUTE 0 + +// Report 0x19: WPADiSendDPDCSB (?) +#define RPTID_SEND_DPD_CSB 0x1a +#define RPT1A_SIZE 1 + +#define RPT1A_DPD_CSB 0 + +/* + * Incoming reports (from POV of the host) + */ + +// Report 0x20: Status report +#define RPTID_STATUS 0x20 +#define RPT20_FLAGS 3 +#define RPT20_PROTO_FW 5 +#define RPT20_BATTERY 6 + +// Report 0x21: Read Wiimote data +#define RPTID_DATA_READ 0x21 +#define RPT21_SIZE_ERR 3 +#define RPT21_ADDR0 4 +#define RPT21_ADDR1 5 +#define RPT21_DATA 6 + +// Report 0x22: Acknowledgement and request result +#define RPTID_ACK 0x22 +#define RPT22_ACKED_RPT_ID 3 +#define RPT22_ERR_CODE 4 + +// Reports 0x23-0x2f: Unused + +// Report 0x30: Buttons +#define RPTID_DATA_BTN 0x30 + +// Report 0x31: Buttons, Accelerometer (Standard) +#define RPTID_DATA_BTN_ACC 0x31 + +// Report 0x32: Buttons, Extension (8 bytes) +#define RPTID_DATA_BTN_EXT8 0x32 +#define RPT32_EXT_OFFSET 3 +#define RPT32_EXT_LENGTH 8 + +/* Report 0x33: Buttons, Accelerometer (Standard), IR Camera (Standard, 12 + * bytes) + */ +#define RPTID_DATA_BTN_ACC_DPD12 0x33 +#define RPT33_DPD_OFFSET 6 +#define RPT33_DPD_LENGTH 12 + +// Report 0x34: Buttons, Extension (19 bytes) +#define RPTID_DATA_BTN_EXT19 0x34 +#define RPT34_EXT_OFFSET 3 +#define RPT34_EXT_LENGTH 19 + +// Report 0x35: Buttons, Accelerometer (Standard), Extension (16 bytes) +#define RPTID_DATA_BTN_ACC_EXT16 0x35 +#define RPT35_EXT_OFFSET 6 +#define RPT35_EXT_LENGTH 16 + +// Report 0x36: Buttons, IR Camera (Basic, 10 bytes), Extension (9 bytes) +#define RPTID_DATA_BTN_DPD10_EXT9 0x36 +#define RPT36_DPD_OFFSET 3 +#define RPT36_DPD_LENGTH 10 +#define RPT36_EXT_OFFSET 13 +#define RPT36_EXT_LENGTH 9 + +/* Report 0x37: Buttons, Accelerometer (Standard), IR Camera (Basic, 10 + * bytes), Extension (6 bytes) + */ +#define RPTID_DATA_BTN_ACC_DPD10_EXT9 0x37 +#define RPT37_DPD_OFFSET 6 +#define RPT37_DPD_LENGTH 10 +#define RPT37_EXT_OFFSET 16 +#define RPT37_EXT_LENGTH 6 + +// Report 0x38-0x3c: Unused + +// Report 0x3d: Extension (21 bytes) +#define RPTID_DATA_EXT21 0x3d +#define RPT3D_EXT_OFFSET 1 +#define RPT3D_EXT_LENGTH 21 + +/* Report 0x3e: Buttons, Accelerometer (Interleaved 1), IR Camera (Full 1, + * 18 bytes) + */ +#define RPTID_DATA_BTN_ACC_DPD18_1 0x3e +#define RPT3E_DPD0 0 +#define RPT3E_DPD0_OFFSET 4 +#define RPT3E_DPD1 1 +#define RPT3E_DPD1_OFFSET 13 + +/* Report 0x3e: Buttons, Accelerometer (Interleaved 2), IR Camera (Full 2, + * 18 bytes) + */ +#define RPTID_DATA_BTN_ACC_DPD18_2 0x3f +#define RPT3F_DPD2 2 +#define RPT3F_DPD2_OFFSET 4 +#define RPT3F_DPD3 3 +#define RPT3F_DPD3_OFFSET 13 + +#define WPAD_EXT_REG_SPEAKER 0xa2 +#define WPAD_EXT_REG_EXTENSION 0xa4 +#define WPAD_EXT_REG_MOTION_PLUS 0xa6 +#define WPAD_EXT_REG_DPD 0xb0 + +#define RX_BUFFER_SIZE OSRoundUp32B(sizeof(WPADStatusEx)) +#define LINT_NUM_MAX_LENGTH 64 +#define LINT_NUM_MAX_BUFSIZ (1 + LINT_NUM_MAX_LENGTH + 1) + +#define WM_MEM_ADDR(addr_) ((addr_) & 0xffff) +#define WM_EXT_REG_ADDR(type_, addr_) \ + (((addr_) & 0xffff) | ((WPAD_EXT_REG_##type_) << 16) | (1 << 26)) + +// https://wiibrew.org/wiki/Wiimote#EEPROM_Memory +#define WM_ADDR_MEM_DEV_CONFIG_0 WM_MEM_ADDR(0x0000) +#define WM_ADDR_MEM_GAME_INFO_0 WM_MEM_ADDR(0x002a) +#define WM_ADDR_MEM_GAME_INFO_1 WM_MEM_ADDR(0x0062) + +// out of range??? wiibrew says the wiimote only has 0x1600 bytes of memory +#define WM_ADDR_MEM_176C WM_MEM_ADDR(0x176c) +#define WM_ADDR_MEM_1770 WM_MEM_ADDR(0x1770) + +/* + * Wiimote extension register addresses + */ + +// Speaker register addresses +#define WM_REG_SPEAKER_01 WM_EXT_REG_ADDR(SPEAKER, 0x01) +#define WM_REG_SPEAKER_08 WM_EXT_REG_ADDR(SPEAKER, 0x08) +#define WM_REG_SPEAKER_09 WM_EXT_REG_ADDR(SPEAKER, 0x09) + +// Extension register addresses +#define WM_REG_EXTENSION_CONFIG WM_EXT_REG_ADDR(EXTENSION, 0x20) +#define WM_REG_EXTENSION_40 WM_EXT_REG_ADDR(EXTENSION, 0x40) +#define WM_REG_EXTENSION_CERT_PARAM WM_EXT_REG_ADDR(EXTENSION, 0x50) +#define WM_REG_EXTENSION_F0 WM_EXT_REG_ADDR(EXTENSION, 0xf0) +#define WM_REG_EXTENSION_CERT_CHALLENGE WM_EXT_REG_ADDR(EXTENSION, 0xf1) +#define WM_REG_EXTENSION_F2 WM_EXT_REG_ADDR(EXTENSION, 0xf2) +#define WM_REG_EXTENSION_F3 WM_EXT_REG_ADDR(EXTENSION, 0xf3) +#define WM_REG_EXTENSION_EXT_TYPE_2 WM_EXT_REG_ADDR(EXTENSION, 0xf6) +#define WM_REG_EXTENSION_CERT_PROBE WM_EXT_REG_ADDR(EXTENSION, 0xf7) +#define WM_REG_EXTENSION_FA WM_EXT_REG_ADDR(EXTENSION, 0xfa) +#define WM_REG_EXTENSION_FB WM_EXT_REG_ADDR(EXTENSION, 0xfb) +#define WM_REG_EXTENSION_DEV_MODE WM_EXT_REG_ADDR(EXTENSION, 0xfe) +#define WM_REG_EXTENSION_ID_BYTE WM_EXT_REG_ADDR(EXTENSION, 0xff) + +#define WM_EXTENSION_CONFIG_SIZE 0x20 // 0xa40020 - 0xa4003f +#define WM_EXTENSION_CERT_PARAM_SIZE 0x40 // 0xa40050 - 0xa4008f + +// Wiimote Motion Plus register addresses +#define WM_REG_MPLS_F0 WM_EXT_REG_ADDR(MOTION_PLUS, 0xf0) +#define WM_REG_MPLS_DEV_MODE WM_EXT_REG_ADDR(MOTION_PLUS, 0xfe) +#define WM_REG_MPLS_ID_BYTE WM_EXT_REG_ADDR(MOTION_PLUS, 0xff) + +// IR camera register addresses +#define WM_REG_DPD_CONFIG_BLOCK_1 WM_EXT_REG_ADDR(DPD, 0x00) +#define WM_REG_DPD_CONFIG_BLOCK_2 WM_EXT_REG_ADDR(DPD, 0x1a) +#define WM_REG_DPD_30 WM_EXT_REG_ADDR(DPD, 0x30) +#define WM_REG_DPD_DATA_FORMAT WM_EXT_REG_ADDR(DPD, 0x33) + + +#define WPAD_NZFILTER_ACC 0 +#define WPAD_NZFILTER_DPD 1 +#define WPAD_NZFILTER_EXT 2 +#define WPAD_NZFILTER_MPLS 3 +#define WPAD_MAX_NZFILTERS 4 + + +#define WPAD_RADIO_QUALITY_GOOD 0 // 80+ +#define WPAD_RADIO_QUALITY_BAD 1 // 80- + + +#define WPAD_DEV_CORE 0 +#define WPAD_DEV_FS 1 +#define WPAD_DEV_CLASSIC 2 +#define WPAD_DEV_BALANCE_CHECKER 3 +#define WPAD_DEV_VSM 4 +#define WPAD_DEV_MOTION_PLUS 5 +#define WPAD_DEV_MPLS_PT_FS 6 +#define WPAD_DEV_MPLS_PT_CLASSIC 7 + +#define WPAD_DEV_TRAIN 16 +#define WPAD_DEV_GUITAR 17 +#define WPAD_DEV_DRUM 18 +#define WPAD_DEV_TAIKO 19 +#define WPAD_DEV_TURNTABLE 20 + +// seems to be like maybe general purpose non-specific device types +// maybe this was for testing or something? idk +#define WPAD_DEV_BULK_1 21 +#define WPAD_DEV_BULK_2 22 +#define WPAD_DEV_BULK_3 23 +#define WPAD_DEV_BULK_4 24 +#define WPAD_DEV_BULK_5 25 +#define WPAD_DEV_BULK_6 26 +#define WPAD_DEV_BULK_7 27 +#define WPAD_DEV_BULK_8 28 + +#define WPAD_DEV_MPLS_PT_UNKNOWN 250 +#define WPAD_DEV_251 251 +#define WPAD_DEV_252 252 // invalid device mode? +#define WPAD_DEV_NONE 253 // sort of like WPAD_ENODEV (see __wpadAbortInitExtension in WPADHIDParser.c) +#define WPAD_DEV_INITIALIZING 255 // see __a1_20_status_report + + +struct WPADCmd { + /* 0x00 */ u32 reportID; + /* 0x04 */ u8 dataBuf[RPT_MAX_SIZE]; + /* 0x1a */ u16 dataLength; + /* 0x1c */ void* dstBuf; + /* 0x20 */ u16 readLength; + /* 0x24 */ u32 readAddress; + /* 0x28 */ WPADInfo* statusReportOut; + /* 0x2c */ WPADCallback* cmdCB; +}; // size 0x30 + +struct WPADCmdQueue { + /* 0x00 */ s8 indexOut; + /* 0x01 */ s8 indexIn; + /* 0x04 */ struct WPADCmd* queue; + /* 0x08 */ u32 length; +}; // size 0x0c + +struct WPADDevConfig { + /* 0x00 */ DPDObject dpd[WPAD_MAX_DPD_OBJECTS]; + /* 0x20 */ s16 accX0g; + /* 0x22 */ s16 accY0g; + /* 0x24 */ s16 accZ0g; + /* 0x26 */ s16 accX1g; + /* 0x28 */ s16 accY1g; + /* 0x2a */ s16 accZ1g; + /* 0x2c */ u8 motor; + /* 0x2d */ u8 volume; + /* 0x30 */ u8 pad0_[2]; +}; + +typedef struct WPADMplsCalibration { + /* 0x00 */ f32 pitchZero; + /* 0x04 */ f32 pitchScale; + /* 0x08 */ f32 yawZero; + /* 0x0c */ f32 yawScale; + /* 0x10 */ f32 rollZero; + /* 0x14 */ f32 rollScale; + /* 0x18 */ s32 degrees; +} WPADMplsCalibration; + +struct WPADExtConfig { + union { + struct WPADFSConfig { + /* 0x00 */ s16 stickXCenter; + /* 0x02 */ s16 at_0x02; + /* 0x04 */ s16 at_0x04; + /* 0x06 */ s16 stickYCenter; + /* 0x08 */ s16 at_0x08; + /* 0x0a */ s16 at_0x0a; + /* 0x0c */ s16 accX0g; + /* 0x0e */ s16 accY0g; + /* 0x10 */ s16 accZ0g; + /* 0x12 */ s16 accX1g; + /* 0x14 */ s16 accY1g; + /* 0x16 */ s16 accZ1g; + } fs; // size 0x1a + + struct WPADCLConfig { + /* 0x00 */ s16 lStickXCenter; + /* 0x02 */ s16 at_0x02; + /* 0x04 */ s16 at_0x04; + /* 0x06 */ s16 lStickYCenter; + /* 0x08 */ s16 at_0x08; + /* 0x0a */ s16 at_0x0a; + /* 0x0c */ s16 rStickXCenter; + /* 0x0e */ s16 at_0x0e; + /* 0x10 */ s16 at_0x10; + /* 0x12 */ s16 rStickYCenter; + /* 0x14 */ s16 at_0x14; + /* 0x16 */ s16 at_0x16; + /* 0x18 */ u8 triggerLZero; + /* 0x19 */ u8 triggerRZero; + } cl; // size 0x1a + + u8 forceUnionSize_[0x1c]; // alignment? + }; // size 0x1c + + struct WPADMplsConfig { + /* 0x00 */ WPADMplsCalibration high; + /* 0x1c */ WPADMplsCalibration low; + /* 0x38 */ u32 calibCRC; + /* 0x3c */ u16 calibID; + } /* 0x1a */ mpls; +}; // size 0x5c + +typedef struct WPADGameInfo { + /* 0x00 */ OSTime timestamp; + /* 0x08 */ u16 gameTitle[16 + 1]; + /* 0x2a */ char gameCode[4]; + /* 0x2e */ u8 gameType; + /* 0x2f */ u8 checksum; + u8 _pad0[8]; +} WPADGameInfo; // size 0x38 + +struct WPADMemBlock { + /* 0x00 */ BOOL busy; + /* 0x04 */ u8 const* data; + /* 0x08 */ u16 len; + /* 0x0c */ u32 addr; + /* 0x10 */ WPADCallback* cb; +}; // size 0x14 + +typedef struct /* possibly untagged, like kpad */ { + /* 0x000 */ WPADGameInfo gameInfo; + /* 0x038 */ s32 at_0x038[2]; /* unknown */ // WPADResult[2]? see __wpadGetGameInfo + /* 0x040 */ u8 rxBufMain[RX_BUFFER_SIZE]; + /* 0x0a0 */ u8 rxBufs[2][RX_BUFFER_SIZE]; + /* 0x160 */ struct WPADCmdQueue stdCmdQueue; + /* 0x16c */ struct WPADCmd stdCmdQueueList[24]; + /* 0x5ec */ struct WPADCmdQueue extCmdQueue; + /* 0x16c */ struct WPADCmd extCmdQueueList[12]; + /* 0x838 */ WPADInfo info; + /* 0x850 */ WPADInfo* infoOut; + /* 0x854 */ struct WPADDevConfig devConfig; + /* 0x884 */ struct WPADExtConfig extConfig; + /* 0x8e0 */ WPADCallback* cmdBlkCB; + /* 0x8e4 */ WPADExtensionCallback* extensionCB; + /* 0x8e8 */ WPADConnectCallback* connectCB; + /* 0x8ec */ WPADSamplingCallback* samplingCB; + /* 0x8f0 */ void* samplingBuf; + /* 0x8f4 */ u32 samplingBufIndex; + /* 0x8f8 */ u32 samplingBufSize; + /* 0x8fc */ u32 dataFormat; + /* 0x900 */ s32 status; + /* 0x904 */ u8 statusReqBusy; + /* 0x905 */ u8 devType; + /* 0x906 */ u8 devMode; + /* 0x907 */ s8 devHandle; + /* 0x908 */ int at_0x908; /* unknown */ + /* 0x90c */ u8 rxBufIndex; + /* 0x90d */ s8 at_0x90d; /* unknown */ + /* 0x90e */ u8 defaultDpdSize; // maybe? + /* 0x90f */ u8 currentDpdCommand; + /* 0x910 */ u8 pendingDpdCommand; + /* 0x911 */ u8 radioQuality; + /* 0x912 */ u8 radioQualityOkMs; // see __wpadCalcRadioQuality + /* 0x913 */ u8 audioFrames; + /* 0x914 */ u32 motorBusy; + /* 0x918 */ BOOL motorRunning; + /* 0x91c */ BOOL used; + /* 0x920 */ BOOL handshakeFinished; + /* 0x924 */ int configIndex; + /* 0x928 */ OSThreadQueue threadQueue; /* purpose unknown */ + /* 0x930 */ WPADCallback* vsmCallback; + /* 0x934 */ u8 controlMplsBusy; + /* 0x935 */ u8 mplsCBReadBuf[2]; + /* 0x937 */ u8 mplsCBCounter; // idk??? + /* 0x938 */ u8 pendingMplsCommand; + /* 0x939 */ u8 noParseMplsCount; + /* 0x93a */ u8 isInitingMpls; // maybe? + /* 0x93b */ u8 hasReadExtType2; // maybe? + /* 0x93c */ u8 at_0x93c; /* unknown */ + /* 0x93d */ u8 parseMPState; + /* 0x93e */ u8 wmParamOffset; + /* 0x93f */ u8 certWorkCounter; // idk??? + /* 0x940 */ u16 certWorkMs; + /* 0x942 */ s16 certStateWorkMs; + /* 0x944 */ s8 certChallengeRandomBit; + /* 0x945 */ u8 certWorkBusy; + /* 0x946 */ s8 certValidityStatus; + /* 0x947 */ s8 certState; + /* 0x948 */ u32* certParamPtr; + /* 0x94c */ u32 certLintX[1 + 16 + 1]; + /* 0x994 */ u32 certLintY[1 + 16 + 1]; + /* 0x994 */ u32 certLintBig[LINT_NUM_MAX_BUFSIZ]; + /* 0xae4 */ int at_0xae4; /* unknown */ + /* 0xae8 */ OSTime lastControllerDataUpdate; + /* 0xaf0 */ u16 filterDiff[WPAD_MAX_NZFILTERS]; + /* 0xaf8 */ u16 filterSame[WPAD_MAX_NZFILTERS]; + /* 0xb00 */ OSTime lastReportSendTime; + /* 0xb08 */ u8 at_0xb08; /* unknown */ + /* 0xb09 */ u8 calibrated; + /* 0xb0a */ u16 recalibHoldMs; + /* 0xb0c */ u8 encryptionKey[16]; + /* 0xb1c */ u8 decryptAddTable[8]; + /* 0xb24 */ u8 decryptXorTable[8]; + /* 0xb2c */ u8 wmReadDataBuf[64]; + /* 0xb6c */ u8* wmReadDataPtr; + /* 0xb70 */ u32 wmReadAddress; + /* 0xb74 */ int wmReadHadError; + /* 0xb78 */ u16 wmReadLength; + /* 0xb7a */ s8 at_0xb7a; /* unknown */ + /* 0xb7b */ u8 radioSensitivity; + /* 0xb7c */ u16 copyOutCount; + /* 0xb7e */ u8 sleeping; + /* 0xb7f */ u8 lastReportID; + /* 0xb80 */ WPADCallback* getInfoCB; + /* 0xb84 */ u8 getInfoBusy; + /* 0xb85 */ u8 extState; + /* 0xb86 */ u8 savePower; + /* 0xb87 */ u8 blcBattery; + /* 0xb88 */ u8 savedDevType; // maybe? + /* 0xb89 */ u8 extWasDisconnected; + /* 0xb8a */ s16 reconnectExtMs; + /* 0xb8c */ struct WPADMemBlock memBlock; + /* 0xba0 */ WPADCallback* controlMplsCB; + /* 0xba4 */ u8 parseMPBuf; + /* 0xba5 */ u8 certProbeByte; + /* 0xba6 */ u8 dpdBusy; + /* 0xba7 */ u8 interleaveFlags; + /* 0xba8 */ u32 mplsCBReadAddress; + /* 0xbac */ u8 mplsCBState; + /* 0xbad */ u8 mplsUptimeMs; + /* 0xbae */ s8 certMayVerifyByCalibBlock; + u8 pad0_[2]; /* unknown (can't be alignment) */ + /* 0xbb1 */ u8 certProbeStartingValue; + /* 0xbb2 */ u16 lastMplsCalibID; + /* 0xbb4 */ u32 lastMplsCalibCRC; + /* 0xbb8 */ u8 noParseExtCount; + /* 0xbb9 */ s8 extErr; + /* 0xbba */ u8 extDataLength; + /* 0xbbb */ u8 extDevType; + /* 0xbbc */ u8 currPwmDuty; + /* 0xbbd */ u8 pendingPwmDuty; + u8 pad1_[2]; /* unknown (can't be alignment) */ + /* 0xbc0 */ u8 extDataBuf[32]; +} ATTRIBUTE_ALIGN(32) wpad_cb_st; // size 0xbe0 + +BOOL WPADiIsAvailableCmdQueue(struct WPADCmdQueue* cmdQueue, s8 num); +BOOL WPADiSendWriteDataCmd(struct WPADCmdQueue* cmdQueue, u8 cmd, u32 address, WPADCallback* cb); +BOOL WPADiSendWriteData(struct WPADCmdQueue* cmdQueue, void const* p_buf, u16 len, u32 address, WPADCallback* cb); +BOOL WPADiSendStreamData(struct WPADCmdQueue* cmdQueue, void const* p_buf, u16 len); +BOOL WPADiSendMuteSpeaker(struct WPADCmdQueue* cmdQueue, BOOL muted, WPADCallback* cb); +BOOL WPADiSendEnableSpeaker(struct WPADCmdQueue* cmdQueue, BOOL enabled, WPADCallback* cb); +BOOL WPADiSendGetContStat(struct WPADCmdQueue* cmdQueue, WPADInfo* infoOut, WPADCallback* cb); + +#ifdef __cplusplus +} +#endif + +#endif // _REVOLUTION_WPAD_PRIVATE_H_ diff --git a/src/revolution/wpad/__wud.h b/src/revolution/wpad/__wud.h new file mode 100644 index 0000000000..0f3c2499b0 --- /dev/null +++ b/src/revolution/wpad/__wud.h @@ -0,0 +1,79 @@ +#ifndef _REVOLUTION_WUD_PRIVATE_H_ +#define _REVOLUTION_WUD_PRIVATE_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define WUD_MAX_DEV_ENTRY_FOR_STD 10 +#define WUD_MAX_DEV_ENTRY_FOR_SMP 6 + +#define WUD_MAX_DEV_ENTRY 16 + +#define WUD_DEV_HANDLE_INVALID (-1) + +struct WUDDevInfoList { + /* 0x00 */ WUDDevInfo* devInfo; + /* 0x04 */ struct WUDDevInfoList* prev; + /* 0x08 */ struct WUDDevInfoList* next; +}; // size 0x0c + +typedef struct /* possibly untagged, like kpad */ { + /* 0x000 */ WUDSyncDeviceCallback* syncStdCB; + /* 0x004 */ WUDSyncDeviceCallback* syncSmpCB; + /* 0x008 */ WUDClearDeviceCallback* clearDevCB; + /* 0x00c */ u8 syncState; + /* 0x00d */ u8 deleteState; + /* 0x00e */ u8 linkKeyState; + /* 0x00f */ u8 stackState; + /* 0x010 */ u8 initState; + /* 0x011 */ u8 shutdownState; + /* 0x012 */ u8 devNums; + /* 0x013 */ u8 devSmpNums; + /* 0x014 */ struct WUDDevInfoList* smpListHead; + /* 0x018 */ struct WUDDevInfoList* smpListTail; + /* 0x01c */ struct WUDDevInfoList smpList[WUD_MAX_DEV_ENTRY_FOR_SMP]; + /* 0x064 */ struct WUDDevInfoList* stdListHead; + /* 0x068 */ struct WUDDevInfoList* stdListTail; + /* 0x06c */ struct WUDDevInfoList stdList[WUD_MAX_DEV_ENTRY_FOR_STD]; + /* 0x0e4 */ WUDDevInfo stdDevs[WUD_MAX_DEV_ENTRY_FOR_STD]; + /* 0x4a4 */ WUDDevInfo smpDevs[WUD_MAX_DEV_ENTRY_FOR_SMP]; + /* 0x6e4 */ u8 connectedNum; + /* 0x6e5 */ u8 linkedNum; + /* 0x6e6 */ u8 syncedNum; + /* 0x6e7 */ u8 syncSkipChecks; + /* 0x6e8 */ s8 syncLoopNum; + /* 0x6e9 */ u8 syncType; + /* 0x6ea */ u8 connectable; + /* 0x6eb */ u8 discoverable; + /* 0x6ec */ WUDHidReceiveCallback* hidRecvCB; + /* 0x6f0 */ WUDHidConnectCallback* hidConnCB; + /* 0x6f4 */ WUDAllocFunc* allocFunc; + /* 0x6f8 */ WUDFreeFunc* freeFunc; + /* 0x6fc */ BD_ADDR pairAddr; + /* 0x702 */ BD_ADDR hostAddr; + /* 0x708 */ s8 libStatus; + /* 0x709 */ u8 siPortStatus; + /* 0x70a */ u8 pmID; + /* 0x70b */ s8 syncRssi; + /* 0x710 */ OSAlarm alarm; + /* 0x740 */ u32 hhFlags; // some flags maybe? + /* 0x744 */ u16 bufferStatus0; + /* 0x746 */ u16 bufferStatus1; + /* 0x748 */ s8 initWaitDeviceUpFrames; + /* 0x749 */ s8 waitStartSearchFrames; + /* 0x74a */ s16 waitIncomingFrames; +} wud_cb_st; // size 0x750 + +u16 WUDiGetQueueSizeForHandle(u8 dev_handle); +u16 WUDiGetNotAckNumForHandle(u8 dev_handle); + +#ifdef __cplusplus +} +#endif + +#endif // _REVOLUTION_WUD_PRIVATE_H_