◎飽和加算ルーチン ピクセルフォーマットは15bpp(R5G5B5)とします。 スプライトパターンとフレームバッファのRGB値をそれぞれ加算します。 加算結果が31を越えた場合、値は31にします。 /* C言語風表記(2ピクセル処理) */ /* vram = フレームバッファへのポインタ */ /* sprite = スプライトパターンへのポインタ */ const unsigned maskA = 0x3def3def; const unsigned maskB = 0x42104210; /* 丸め(ラップラウンド)加算 */ tmp1 = ((col1 & maskA) + (col2 & maskA)) ^ ((col1 ^ col2) & maskB); /* RGBの桁あふれ算出 */ tmp2 = col1 + col2 - tmp1; output = tmp1 | (tmp2 - (tmp2>>5)); ; NASM(4ピクセル処理) ;UV大文字表記は他のパイプに移動できない命令です ;edi = フレームバッファのアドレス ;edx = スプライトパターンのアドレス ;ecx = スプライトの横幅(4ピクセル単位) ;mm6 = 04210421042104210h ;mm7 = 03def3def3def3defh movq mm0,[edx] ;n movq mm1,[edi] ;n LP: movq mm2,mm0 ;u1 movq mm3,mm1 ;v1 movq mm4,mm1 ;u2 pand mm2,mm7 ;v2 pxor mm0,mm1 ;u3 pand mm3,mm7 ;v3 pand mm0,mm6 ;u4 paddw mm2,mm3 ;v4 pxor mm2,mm0 ;u5 padd mm4,mm1 ;v5 psubw mm4,mm2 ;u6 lea edi,[edi+8] ;v6 movq mm3,mm4 ;u7 psrlw mm4,5 ;v7 movq mm0,[edx+8] ;U8 psubw mm3,mm4 ;v8 movq mm1,[edi] ;U9 por mm2,mm3 ;v9 lea edx,[edx+8] ;u10 dec ecx ;v10 movq [edi-8],mm2 ;U11 jnz LP ;v11 とりあえずキャッシュが全てヒットした場合を考えます。 MMX Pentium(P55C)では、 4ピクセル当たり11クロックで処理します。 パターンをQWORDにアラインするのは当然にしても、 転送先のアドレスは表示位置によって変わってしまうので、 4ピクセル当たり17クロック程度と考えるのが妥当です。