//====================================================================== // IrisMacro.h // IRIS 標準マクロ関数 // // Copyright (C) 2002-2003 NINTENDO Co.,Ltd. //====================================================================== #ifndef _IRIS_MACRO_H #define _IRIS_MACRO_H #ifdef __cplusplus extern "C" { #endif #include #include #include #include #include #include #include //---------------------------------------------------------------------- // カラー //---------------------------------------------------------------------- #define RGB555(r, g, b) \ \ ((r) << RED5_SHIFT | (g) << GREEN5_SHIFT | (b) << BLUE5_SHIFT) #define RGBA5551(r, g, b, a) \ \ ((r) << RED5_SHIFT | (g) << GREEN5_SHIFT | (b) << BLUE5_SHIFT | (a) << ALPHA1_SHIFT) #define RGBF5551(r, g, b, flag) \ \ ((r) << RED5_SHIFT | (g) << GREEN5_SHIFT | (b) << BLUE5_SHIFT | (flag) << 15) #define RGB888(r, g, b) \ \ ((r) << RED8_SHIFT | (g) << GREEN8_SHIFT | (b) << BLUE8_SHIFT) #define RGBA8888(r, g, b, a) \ \ ((r) << RED8_SHIFT | (g) << GREEN8_SHIFT | (b) << BLUE8_SHIFT | (a) << ALPHA8_SHIFT) //---------------------------------------------------------------------- // 座標 //---------------------------------------------------------------------- #define XYZ101010(x, y, z) (((x) & X10_MASK) << X10_SHIFT \ | ((y) & X10_MASK) << Y10_SHIFT \ | ((z) & X10_MASK) << Z10_SHIFT) #define XY1616(x, y) (((x) & X16_MASK) | (y) << Y16_SHIFT) #define Z16(z) ((z) & X16_MASK) #define ZW1616(z, w) (((z) & X16_MASK) | (w) << Y16_SHIFT) #define HD1616(h, d) (((h) & X16_MASK) | (d) << Y16_SHIFT) #define ST1616(s, t) (((s) & TEX_S_MASK ) | (t) << TEX_T_SHIFT) //---------------------------------------------------------------------- // ライト //---------------------------------------------------------------------- #define LIGHT_VECTOR(no, x, y, z) ((no)<> TEX_IMAGE_BASE_SHIFT) & TEX_IMAGE_BASE_MASK) #define ADDR_TO_TEXPLTT_BASE(basep, mode) (((basep) >> mode##_SHIFT) & TEX_PLTT_BASE_MASK) // リアルタイム処理用 #define Addr2TexImageBase(basep) (((u32 )(basep) >> TEX_IMAGE_BASE_SHIFT) & TEX_IMAGE_BASE_MASK) #define Addr2TexPlttBase(basep, mode) ( (u32 )(basep) >> "\0\4\3\4\4\4\4"[mode]) //---------------------------------------------------------------------- // 除算器 //---------------------------------------------------------------------- // パラメータ設定(通常版) #define SetDiv(numer, denom, numBits, denBits) \ { \ *(vu32 *)REG_DIVCNT = DIV_##numBits##_##denBits##BIT_MODE; \ SetDivImm(numer, denom, numBits, denBits); \ } // パラメータ設定(モード設定省略版) #define SetDivImm(numer, denom, numBits, denBits) \ { \ *(vs##numBits *)REG_DIV_NUMER = (numer); \ *(vs##denBits *)REG_DIV_DENOM = (denom); \ } // 除算器終了待ち #define IsDivBusy() (((vu8 *)REG_DIVCNT)[1] & (DIV_BUSY>>8)) #define WaitDiv() \ { \ while (IsDivBusy()) ; \ } // 結果読み出し(除算器終了未確認版) #define DivResultImm(bits) (*(vs##bits *)REG_DIV_RESULT) #define DivRemResultImm(bits) (*(vs##bits *)REG_DIVREM_RESULT) // 結果読み出し(通常版) #define DivResult(bits) DivResult##bits##() #define DivRemResult(bits) DivRemResult##bits##() __inline static s64 DivResult64(void) { WaitDiv(); return DivResultImm(64); } __inline static s64 DivRemResult64(void) { WaitDiv(); return DivRemResultImm(64); } __inline static s32 DivResult32(void) { WaitDiv(); return DivResultImm(32); } __inline static s32 DivRemResult32(void) { WaitDiv(); return DivRemResultImm(32); } __inline static s16 DivResult16(void) { WaitDiv(); return DivResultImm(16); } __inline static s16 DivRemResult16(void) { WaitDiv(); return DivRemResultImm(16); } __inline static s8 DivResult8(void) { WaitDiv(); return DivResultImm(8); } __inline static s8 DivRemResult8(void) { WaitDiv(); return DivRemResultImm(8); } //---------------------------------------------------------------------- // 平方根演算器 //---------------------------------------------------------------------- // パラメータ設定(通常版) #define SetSqrt(param, bits) \ { \ *(vu32 *)REG_SQRTCNT = SQRT_##bits##BIT_MODE; \ SetSqrtImm(param, bits); \ } // パラメータ設定(モード設定省略版) #define SetSqrtImm(param, bits) \ { \ *(vu##bits *)REG_SQRT_PARAM = (param); \ } // 平方根演算器終了待ち #define IsSqrtBusy() (((vu8 *)REG_SQRTCNT)[1] & (SQRT_BUSY>>8)) #define WaitSqrt() \ { \ while (IsSqrtBusy()) ; \ } // 結果読み出し(除算器終了未確認版) #define SqrtResultImm(bits) (*(vu##bits *)REG_SQRT_RESULT) // 結果読み出し(通常版) #define SqrtResult(bits) SqrtResult##bits##() __inline static u32 SqrtResult32(void) { WaitSqrt(); return SqrtResultImm(32); } __inline static u16 SqrtResult16(void) { WaitSqrt(); return SqrtResultImm(16); } __inline static u8 SqrtResult8(void) { WaitSqrt(); return SqrtResultImm(8); } //---------------------------------------------------------------------- // データ読み込み //---------------------------------------------------------------------- #define ReadData(readp, bit) (*(vu##bit *)(readp)) //---------------------------------------------------------------------- // データ書き込み //---------------------------------------------------------------------- #define WriteData(writep, data, bit) \ \ (*(vu##bit *)(writep) = (data)) //---------------------------------------------------------------------- // データ コピー //---------------------------------------------------------------------- #define CopyData(readp, writep, bit) \ \ (*(vu##bit *)(writep) = *(vu##bit *)(readp)) //---------------------------------------------------------------------- // アドレス境界整列バッファの有効化 //---------------------------------------------------------------------- #ifdef __CC_ARM #define EnableAlignBuf(alignBuf) \ { \ vu16 alignBufTmp = *(vu16 *)alignBuf; \ } #else #define EnableAlignBuf(alignBuf) ((void) 0) #endif //---------------------------------------------------------------------- // 割り込みアドレス セット //---------------------------------------------------------------------- #define SetIntrAddr(intrp) \ \ (*(vu32 *)INTR_VECTOR_BUF = (vu32 )intrp) //・割り込み処理のアドレスをセットします。 //---------------------------------------------------------------------- // DMA セット //---------------------------------------------------------------------- //#define SIMULATOR #ifndef SIMULATOR #define DmaSet(dmaNo, srcp, destp, dmaCntData) \ { \ vu32 *dmaCntp = &((vu32 *)REG_DMA0)[dmaNo * 3]; \ dmaCntp[0] = (vu32 )(srcp); \ dmaCntp[1] = (vu32 )(destp); \ dmaCntp[2] = (vu32 )(dmaCntData); \ {u32 dummy = dmaCntp[2];} \ {u32 dummy = dmaCntp[2];} \ } #define DmaSetAsync(dmaNo, srcp, destp, dmaCntData) \ { \ vu32 *dmaCntp = &((vu32 *)REG_DMA0)[dmaNo * 3]; \ dmaCntp[0] = (vu32 )(srcp); \ dmaCntp[1] = (vu32 )(destp); \ dmaCntp[2] = (vu32 )(dmaCntData); \ } #else #define DmaSet(dmaNo, srcp, destp, dmaCntData) \ { \ int i; \ for (i=0; i<(dmaCntData & 0x1ffff); i++) \ if ((dmaCntData) & DMA_SRC_FIX) { \ if ((dmaCntData) & DMA_32BIT_BUS) \ ((vu32 *)(destp))[i] = ((vu32 *)(srcp))[0]; \ else ((vu16 *)(destp))[i] = ((vu16 *)(srcp))[0]; \ } else { \ if ((dmaCntData) & DMA_32BIT_BUS) \ ((vu32 *)(destp))[i] = ((vu32 *)(srcp))[i]; \ else ((vu16 *)(destp))[i] = ((vu16 *)(srcp))[i]; \ } \ } #define DmaSetAsync(dmaNo, srcp, destp, dmaCntData) \ DmaSet( dmaNo, srcp, destp, dmaCntData) #endif //・DMAコントローラにパラメータをセットします。 //・SIMULATERを定義するとCPUでシミュレートします。 // GDBでデバッグする場合などに有効です。 //・最後にDMA起動待ちのために"LDR"命令が挿入されます。 // //・引数: // dmaNo DMA番号 // srcp ソースアドレス // destp デスティネーションアドレス // dmaCntData パラメータデータ // //※CPU内部RAM上のプログラムにてDMAを起動すると // その次の命令が先に実行されます。 // よって、DMA直後に転送先をCPUにて変更しようとした場合、 // 読み込み/書き戻しの間にDMAが起動されてしまいますので、 // DMAの転送先のデータが意図していない値になる場合があります。 // その場合にはWaitDma()を直後に挿入して、DMAが終了したか // どうかをチェックすると続くコードへの影響を確実に回避できます。 //---------------------------------------------------------------------- // DMA クリア //---------------------------------------------------------------------- #define DmaClear(dmaNo, data, destp, size, bit) \ { \ vu32 *srcp = &((vu32 *)REG_DMA0_CLR_DATA)[dmaNo]; \ *srcp = (data); \ DmaSet(dmaNo, srcp, destp, ( \ DMA_ENABLE | DMA_TIMMING_IMM | \ DMA_SRC_FIX | DMA_DEST_INC | \ DMA_##bit##BIT_BUS | ((size)/(bit/8)))); \ } #define DmaClearIf(dmaNo, data, destp, size, bit) \ { \ vu32 *srcp = &((vu32 *)REG_DMA0_CLR_DATA)[dmaNo]; \ *srcp = (data); \ DmaSet(dmaNo, srcp, destp, ( \ DMA_ENABLE | DMA_TIMMING_IMM | \ DMA_IF_ENABLE | \ DMA_SRC_FIX | DMA_DEST_INC | \ DMA_##bit##BIT_BUS | ((size)/(bit/8)))); \ } #define DmaClearArray( dmaNo, data, destp, bit) \ DmaClear( dmaNo, data, destp, sizeof(destp), bit) #define DmaClearArrayIf(dmaNo, data, destp, bit) \ DmaClearIf( dmaNo, data, destp, sizeof(destp), bit) //・DMAでRAMクリアします。 //・クリアデータはスタックに置かれ、それをデスティネーションへコピーします。 //・DmaClearIf/DmaClearArrayIfは終了時に割り込み要求を発生します。 //・DmaClearArray/DmaClearArrayIfはデスティネーション配列全体をクリアします。 // //・引数: // dmaNo DMA番号 // data クリアデータ // destp デスティネーションアドレス // size クリアバイト数 // bit 転送ビット幅(16|32) // // //※CPU内部RAM上のプログラムにてDMAを起動すると // その次の命令が先に実行されます。 // よって、DMA直後に転送先をCPUにて変更しようとした場合、 // 読み込み/書き戻しの間にDMAが起動されてしまいますので、 // DMAの転送先のデータが意図していない値になる場合があります。 // その場合にはWaitDma()を直後に挿入して、DMAが終了したか // どうかをチェックすると続くコードへの影響を確実に回避できます。 //---------------------------------------------------------------------- // DMA コピー //---------------------------------------------------------------------- #define DmaCopy(dmaNo, srcp, destp, size, bit) \ \ DmaSet(dmaNo, srcp, destp, ( \ DMA_ENABLE | DMA_TIMMING_IMM | \ DMA_SRC_INC | DMA_DEST_INC | \ DMA_##bit##BIT_BUS | ((size)/((bit)/8)))) #define DmaCopyIf(dmaNo, srcp, destp, size, bit) \ \ DmaSet(dmaNo, srcp, destp, ( \ DMA_ENABLE | DMA_TIMMING_IMM | \ DMA_IF_ENABLE | \ DMA_SRC_INC | DMA_DEST_INC | \ DMA_##bit##BIT_BUS | ((size)/(bit/8)))) #define DmaCopyArray( dmaNo, srcp, destp, bit) \ DmaCopy( dmaNo, srcp, destp, sizeof(srcp), bit) #define DmaCopyArrayIf(dmaNo, srcp, destp, bit) \ DmaCopyIf( dmaNo, srcp, destp, sizeof(srcp), bit) //・DMAでコピーします。 //・DmaCopyIf/DmaCopyArrayIfは終了時に割り込み要求を発生します。 //・DmaCopyArray/DmaCopyArrayIfはソース配列全体をコピーします。 // //・引数: // dmaNo DMA番号 // srcp ソースアドレス // destp デスティネーションアドレス // size 転送バイト数 // bit 転送ビット幅(16|32) // // //※CPU内部RAM上のプログラムにてDMAを起動すると // その次の命令が先に実行されます。 // よって、DMA直後に転送先をCPUにて変更しようとした場合、 // 読み込み/書き戻しの間にDMAが起動されてしまいますので、 // DMAの転送先のデータが意図していない値になる場合があります。 // その場合にはWaitDma()を直後に挿入して、DMAが終了したか // どうかをチェックすると続くコードへの影響を確実に回避できます。 //---------------------------------------------------------------------- // HブランクDMA コピー //---------------------------------------------------------------------- #define H_DmaCopy(dmaNo, srcp, destp, size, bit) \ \ DmaSet(dmaNo, srcp, destp, ( \ DMA_ENABLE | DMA_TIMMING_H_BLANK | \ DMA_SRC_INC | DMA_DEST_RELOAD | \ DMA_CONTINUOUS_ON | \ DMA_##bit##BIT_BUS | ((size)/((bit)/8)))) #define H_DmaCopyIf(dmaNo, srcp, destp, size, bit) \ \ DmaSet(dmaNo, srcp, destp, ( \ DMA_ENABLE | DMA_TIMMING_H_BLANK | \ DMA_IF_ENABLE | \ DMA_SRC_INC | DMA_DEST_RELOAD | \ DMA_CONTINUOUS_ON | \ DMA_##bit##BIT_BUS | ((size)/(bit/8)))) #define H_DmaCopyArray( dmaNo, srcp, destp, bit) \ H_DmaCopy( dmaNo, srcp, destp, sizeof(srcp), bit) #define H_DmaCopyArrayIf(dmaNo, srcp, destp, bit) \ H_DmaCopyIf( dmaNo, srcp, destp, sizeof(srcp), bit) //・Hブランクに同期してDMAでコピーします。 //・H_DmaCopyIf/H_DmaCopyArrayIfは終了時に割り込み要求を発生します。 //・H_DmaCopyArray/H_DmaCopyArrayIfはソース配列全体をコピーします。 // //・引数: // dmaNo DMA番号 // srcp ソースアドレス // destp デスティネーションアドレス // size 転送バイト数 // bit 転送ビット幅(16|32) //---------------------------------------------------------------------- // VブランクDMA コピー //---------------------------------------------------------------------- #define V_DmaCopy(dmaNo, srcp, destp, size, bit) \ \ DmaSet(dmaNo, srcp, destp, ( \ DMA_ENABLE | DMA_TIMMING_V_BLANK | \ DMA_SRC_INC | DMA_DEST_INC | \ DMA_##bit##BIT_BUS | ((size)/(bit/8)))) #define V_DmaCopyIf(dmaNo, srcp, destp, size, bit) \ \ DmaSet(dmaNo, srcp, destp, ( \ DMA_ENABLE | DMA_TIMMING_V_BLANK | \ DMA_IF_ENABLE | \ DMA_SRC_INC | DMA_DEST_INC | \ DMA_##bit##BIT_BUS | ((size)/(bit/8)))) #define V_DmaCopyArray( dmaNo, srcp, destp, bit) \ V_DmaCopy( dmaNo, srcp, destp, sizeof(srcp), bit) #define V_DmaCopyArrayIf(dmaNo, srcp, destp, bit) \ V_DmaCopyIf( dmaNo, srcp, destp, sizeof(srcp), bit) //・Vブランクに同期してDMAでコピーします。 //・V_DmaCopyIf/V_DmaCopyArrayIfは終了時に割り込み要求を発生します。 //・V_DmaCopyArray/V_DmaCopyArrayIfはソース配列全体をコピーします。 // //・引数: // dmaNo DMA番号 // srcp ソースアドレス // destp デスティネーションアドレス // size 転送バイト数 // bit 転送ビット幅(16|32) //---------------------------------------------------------------------- // メインメモリ表示DMA //---------------------------------------------------------------------- #define DmaDispMainmem(dmaNo, srcp) \ \ DmaSet(dmaNo, srcp, REG_DISP_WRAM_FIFO, ( \ DMA_ENABLE | DMA_TIMMING_DISP_MMEM | \ DMA_SRC_INC | DMA_DEST_FIX | \ DMA_CONTINUOUS_ON | \ DMA_32BIT_BUS | (4))) //・メインメモリ上のイメージを表示するDMA転送を行います。 // //・引数: // dmaNo DMA番号 // srcp ソースアドレス //---------------------------------------------------------------------- // ジオメトリFIFO−DMA //---------------------------------------------------------------------- #define GX_Dma(dmaNo, srcp, length) \ \ DmaSetAsync(dmaNo, srcp, REG_GXFIFO, ( \ DMA_ENABLE | DMA_TIMMING_GXFIFO | \ DMA_SRC_INC | DMA_DEST_FIX | \ DMA_32BIT_BUS | (length))) #define GX_DmaIf(dmaNo, srcp, length) \ \ DmaSetAsync(dmaNo, srcp, REG_GXFIFO, ( \ DMA_ENABLE | DMA_TIMMING_GXFIFO | \ DMA_IF_ENABLE | \ DMA_SRC_INC | DMA_DEST_FIX | \ DMA_32BIT_BUS | (length))) #define GX_DmaFast(dmaNo, srcp, length) \ \ DmaSet(dmaNo, srcp, REG_GXFIFO, ( \ DMA_ENABLE | DMA_TIMMING_IMM | \ DMA_SRC_INC | DMA_DEST_FIX | \ DMA_32BIT_BUS | (length))) #define GX_DmaFastIf(dmaNo, srcp, length) \ \ DmaSet(dmaNo, srcp, REG_GXFIFO, ( \ DMA_ENABLE | DMA_TIMMING_IMM | \ DMA_IF_ENABLE | \ DMA_SRC_INC | DMA_DEST_FIX | \ DMA_32BIT_BUS | (length))) #define GX_DmaArray( dmaNo, srcp, destp, bit) \ GX_Dma( dmaNo, srcp, destp, sizeof(srcp), bit) #define GX_DmaArrayIf(dmaNo, srcp, destp, bit) \ GX_DmaIf(dmaNo, srcp, destp, sizeof(srcp), bit) #define GX_DmaArrayFast( dmaNo, srcp, destp, bit) \ GX_DmaFast( dmaNo, srcp, destp, sizeof(srcp), bit) #define GX_DmaArrayFastIf(dmaNo, srcp, destp, bit) \ GX_DmaFastIf(dmaNo, srcp, destp, sizeof(srcp), bit) //・ジオメトリFIFOからの要求によってDMAでコピーします。 //・GX_DmaIf/GX_DmaArrayIf/GX_DmaFastIf/GX_DmaArrayFastIf // は終了時に割り込み要求を発生します。 //・GX_DmaArray/GX_DmaArrayIf/GX_DmaArrayFast/GX_DmaArrayFastIf // はソース配列全体をコピーします。 // //・引数: // dmaNo DMA番号 // srcp ソースアドレス // size 転送バイト数 //---------------------------------------------------------------------- // DMA 終了待ち //---------------------------------------------------------------------- #define WaitDma(dmaNo) \ { \ vu32 *(dmaCntp) = &((vu32 *)REG_DMA0)[dmaNo * 3]; \ while (dmaCntp[2] & DMA_ENABLE) ; \ } //・DMAの終了を待ちます。 // //・引数: // dmaNo DMA番号 //---------------------------------------------------------------------- // DMA ストップ //---------------------------------------------------------------------- #define StopDma(dmaNo) \ { \ vu16 *(dmaCntp) = &((vu16 *)REG_DMA0)[dmaNo * 6]; \ dmaCntp[5] &= ~((DMA_TIMMING_MASK | DMA_CONTINUOUS_ON) \ >> 16); \ dmaCntp[5] &= ~( DMA_ENABLE >> 16); \ {u32 dummy = dmaCntp[5];} \ {u32 dummy = dmaCntp[5];} \ } //・DMAを停止します。 //・但し、処理中にDMAの自動起動が掛かった場合は一度だけDMAが実行されます。 // //・引数: // dmaNo DMA番号 //---------------------------------------------------------------------- // CPU クリア //---------------------------------------------------------------------- #define CpuClear(data, destp, size, bit) UTL_CpuClear##bit(data, (void *)(destp), size) #define CpuClearArray(data, destp, bit) \ CpuClear( data, destp, sizeof(destp), bit) //・CPUでRAMクリアするシステムコールを呼び出します。 //・クリアデータはスタックに置かれ、それをデスティネーションへコピーします。 //・CpuClearArrayはデスティネーション配列全体をクリアします。 // //・引数: // data クリアデータ // destp デスティネーションアドレス // size クリアバイト数 // bit 転送ビット幅(16|32) //---------------------------------------------------------------------- // CPU コピー //---------------------------------------------------------------------- #define CpuCopy(srcp, destp, size, bit) UTL_CpuCopy##bit((void *)(srcp), (void *)(destp), size) #define CpuCopyArray(srcp, destp, bit) \ CpuCopy( srcp, destp, sizeof(srcp), bit) //・CPUでコピーするシステムコールを呼び出します。 //・CpuCopyArrayはソース配列全体をコピーします。 // //・引数: // srcp ソースアドレス // destp デスティネーションアドレス // size 転送バイト数 // bit 転送ビット幅(16|32) //---------------------------------------------------------------------- // CPU 高速クリア //---------------------------------------------------------------------- #define CpuClearFast(data, destp, size) UTL_CpuClearFast(data, (void *)(destp), size) #define CpuClearArrayFast(data, destp) \ CpuClearFast( data, destp, sizeof(destp)) //・CPUで高速にRAMクリアするシステムコールを呼び出します。 //・クリアデータはスタックに置かれ、それをデスティネーションへコピーします。 //・CpuClearArrayFastはデスティネーション配列全体をクリアします。 // //・引数: // data クリアデータ // destp デスティネーションアドレス // size クリアバイト数 //---------------------------------------------------------------------- // CPU 高速コピー //---------------------------------------------------------------------- #define CpuCopyFast(srcp, destp, size) UTL_CpuCopyFast((void *)(srcp), (void *)(destp), size) #define CpuCopyArrayFast(srcp, destp) \ CpuCopyFast( srcp, destp, sizeof(srcp)) //・CPUで高速にコピーするシステムコールを呼び出します。 //・CpuCopyArrayFastはソース配列全体をコピーします。 // //・引数: // srcp ソースアドレス // destp デスティネーションアドレス // size 転送バイト数 #ifdef __cplusplus } // extern "C" #endif #endif // _IRIS_MACRO_H