blit_sh3_gray.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:7k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*****************************************************************************
  2.  *
  3.  * This program is free software ; you can redistribute it and/or modify
  4.  * it under the terms of the GNU General Public License as published by
  5.  * the Free Software Foundation; either version 2 of the License, or
  6.  * (at your option) any later version.
  7.  *
  8.  * This program is distributed in the hope that it will be useful,
  9.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11.  * GNU General Public License for more details.
  12.  *
  13.  * You should have received a copy of the GNU General Public License
  14.  * along with this program; if not, write to the Free Software
  15.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  16.  *
  17.  * $Id: blit_sh3_gray.c 271 2005-08-09 08:31:35Z picard $
  18.  *
  19.  * The Core Pocket Media Player
  20.  * Copyright (c) 2004-2005 Gabor Kovacs
  21.  *
  22.  ****************************************************************************/
  23. #include "../common.h"
  24. #include "../dyncode/dyncode.h"
  25. #include "blit_soft.h"
  26. #if defined(SH3)
  27. typedef struct stack
  28. {
  29. int EndOfRect;
  30. int DstNext;
  31. int SrcNext;
  32. int AdjWidth;
  33. int StackFrame[7];
  34. void* This;   //R4
  35. char* Dst;    //R5
  36. char* Src;    //R6
  37. int DstPitch; //R7
  38. int SrcPitch;
  39. int Width; 
  40. int Height;
  41. int Src2SrcLast;
  42. } stack;
  43. void Fix_Gray_UV(blit_soft* p)
  44. {
  45. int SrcBlock2;
  46. bool_t Invert = (p->Dst.Flags & PF_INVERTED) != 0;
  47. int DitherMask = (1 << (8 - p->DstBPP))-1;
  48. int ValueMask = 255 - DitherMask;
  49. int Count = 8 / p->DstBPP;
  50. int DstRows = (p->DstDoubleY && !(p->SwapXY)) ? 2:1;
  51. int SrcRows = (p->SwapXY) ? (Count >> p->DstDoubleX) : 1; 
  52. int n;
  53. dyninst* LoopY;
  54. dyninst* LoopX;
  55. p->DstAlignPos = 4;
  56. p->DstAlignSize = 4;
  57. p->Caps = VC_BRIGHTNESS|VC_DITHER;
  58. CodeBegin(7,OFS(stack,StackFrame));
  59. I2(MOVL_LD,R5,R2); //Dst[0]
  60. I2(MOVL_LD,R6,R4); //Src[0]
  61. I2(MOV,R7,R8);
  62. I1C(MOVI,R0,OFS(stack,This));
  63. I2(ADD,SP,R0);
  64. I2C(MOVL_LDOFS,R0,R14,OFS(stack,SrcPitch)-OFS(stack,This)); //SrcPitch
  65. I2C(MOVL_LDOFS,R0,R7,OFS(stack,Height)-OFS(stack,This));
  66. I2C(MOVL_LDOFS,R0,R1,OFS(stack,Width)-OFS(stack,This));
  67. if (p->SwapXY)
  68. {
  69. SrcBlock2 = -p->DstBPP2 - p->DstDoubleX;
  70. //EndOfRect = Dst + (Height * DstBPP * DirX) >> 3;
  71. I1C(MOVI,R9,p->DstBPP * p->DirX);
  72. I2(MULL,R7,R9);
  73. I1C(MOVI,R9,-3);
  74. I1(STS_MACL,R7);
  75. I2(SHAD,R9,R7);
  76. I2(ADD,R2,R7);
  77. I2C(MOVL_STOFS,R7,SP,OFS(stack,EndOfRect));
  78. //DstNext = DirX - Width * DstPitch;
  79. I2(MULL,R1,R8);
  80. I1C(MOVI,R9,p->DirX);
  81. I1(STS_MACL,R7);
  82. I2(SUB,R7,R9);
  83. I2C(MOVL_STOFS,R9,SP,OFS(stack,DstNext));
  84. }
  85. else
  86. {
  87. SrcBlock2 = 0;
  88. //EndOfRect = Dst + DstPitch * Height
  89. I2(MULL,R7,R8);
  90. I1(STS_MACL,R7);
  91. I2(ADD,R2,R7);
  92. I2C(MOVL_STOFS,R7,SP,OFS(stack,EndOfRect));
  93. //DstNext = (DstPitch << DstDoubleY) - DirX * (Width >> -DstBPP2);
  94. I1C(MOVI,R7,p->DstBPP2);
  95. I2(MOV,R1,R9);
  96. I2(SHAD,R7,R9);
  97. I2(MOV,R8,R7);
  98. if (p->DstDoubleY) I1(SHLL,R7);
  99. I2(p->DirX>0 ? SUB:ADD,R9,R7);
  100. I2C(MOVL_STOFS,R7,SP,OFS(stack,DstNext));
  101. }
  102. //SrcNext = (SrcPitch << SrcBlock2) - (Width >> SrcDoubleX);
  103. I2(MOV,R14,R7);
  104. if (SrcBlock2) 
  105. {
  106. I1C(MOVI,R9,SrcBlock2);
  107. I2(SHLD,R9,R7);
  108. }
  109. I2(MOV,R1,R9);
  110. if (p->SrcDoubleX) I1(SHLR,R9);
  111. I2(SUB,R9,R7); 
  112. I2C(MOVL_STOFS,R7,SP,OFS(stack,SrcNext));
  113. if (p->FX.Flags & BLITFX_DITHER)
  114. I1C(MOVI,R13,DitherMask >> 1); //Y0
  115. for (n=1;n<SrcRows;++n)
  116. {
  117. I2(MOV,(reg)(R4+n-1),(reg)(R4+n));
  118. I2(ADD,R14,(reg)(R4+n));
  119. }
  120. for (n=1;n<DstRows;++n)
  121. {
  122. I2(MOV,(reg)(R2+n-1),(reg)(R2+n));
  123. I2(ADD,R8,(reg)(R2+n));
  124. }
  125. if (p->SwapXY)
  126. {
  127. I2(MULL,R1,R8); //width*dstpitch
  128. I1(STS_MACL,R1);
  129. }
  130. else
  131. {
  132. if (p->DirX < 0)
  133. I2(NEG,R1,R1);
  134. I1C(MOVI,R7,p->DstBPP2);
  135. I2(SHAD,R7,R1);
  136. }
  137. I2C(MOVL_STOFS,R1,SP,OFS(stack,AdjWidth));
  138. I1C(MOVI,R0,(int8_t)ValueMask);
  139. I2(EXTUB,R0,R9);
  140. if (p->FX.Flags & BLITFX_DITHER)
  141. I1C(MOVI,R10,DitherMask);
  142. LoopY = Label(1);
  143. I2C(MOVL_LDOFS,SP,R1,OFS(stack,AdjWidth));
  144. I2(ADD,R2,R1); //end of line
  145. //R0 temp
  146. //R12 temp
  147. //R13 dither
  148. //R14 out
  149. //R11 out2 (doubley)
  150. //R1 Endofline
  151. //R2 Dst
  152. //R3 Dst2 (doubley)
  153. //R4 Src
  154. //R5 Src2 (Swap)
  155. //R6 Src3 (Swap)
  156. //R7 Src4 (Swap)
  157. //R8 DstPitch
  158. //R9 ValueMask
  159. //R10 DitherMask
  160. LoopX = Label(1);
  161. {
  162. for (n=0;n<Count;++n)
  163. {
  164. int Pos;
  165. reg Y;
  166. bool_t Reverse;
  167. reg Tmp;
  168. if (p->SwapXY)
  169. {
  170. switch ((Count-1-n) >> p->DstDoubleX)
  171. {
  172. case 0: I2(MOVB_LD,R4,R0); break;
  173. case 1: I2(MOVB_LD,R5,R0); break;
  174. case 2: I2(MOVB_LD,R6,R0); break;
  175. case 3: I2(MOVB_LD,R7,R0); break;
  176. }
  177. else
  178. I1C(MOVB_LDOFS,R4,n >> p->DstDoubleX);
  179. I2(EXTUB,R0,R0);
  180. Y=R0;
  181. if (p->FX.Flags & BLITFX_DITHER)
  182. {
  183. I2(ADD,R0,R13);
  184. Y = R13;
  185. }
  186. I1C(ADDI,Y,p->FX.Brightness-16);
  187. I2(MOV,Y,R12);
  188. I1(SHLR16,R12);
  189. I2(SHLD,R12,Y);
  190. I2(MOV,Y,R12);
  191. I1(SHLR8,R12);
  192. I2(NEG,R12,R12);
  193. I2(OR,R12,Y);
  194. Reverse = (p->DirX>0) ^ ((p->SwapXY)!=0);
  195. Pos = Reverse ? n*p->DstBPP : (8-(n+1)*p->DstBPP);
  196. Tmp = R12;
  197. if (!Invert && n==0 && Pos==0) 
  198. Tmp = R14;
  199. I2(MOV,Y,Tmp);
  200. I2(AND,R9,Tmp);
  201. if (Pos)
  202. {
  203. I1C(MOVI,R0,-Pos);
  204. I2(SHLD,R0,Tmp);
  205. }
  206. if (n==0)
  207. {
  208. if (Invert || Pos)
  209. I2(Invert ? NOT:MOV,Tmp,R14);
  210. }
  211. else
  212. I2(XOR,Tmp,R14);
  213. if (p->DstDoubleY)
  214. {
  215. int Pos2 = Reverse ? (n^p->DstDoubleX)*p->DstBPP : (8-((n^p->DstDoubleX)+1)*p->DstBPP);
  216. if (Tmp != R12)
  217. I2(MOV,Tmp,R12);
  218. I1C(MOVI,R0,Pos-Pos2);
  219. I2(SHLD,R0,R12);
  220. if (n==0)
  221. I2(Invert ? NOT:MOV,R12,R11);
  222. else
  223. I2(XOR,R12,R11);
  224. }
  225. if (p->FX.Flags & BLITFX_DITHER)
  226. I2(AND,R10,R13);
  227. }
  228. if (p->DstDoubleY)
  229. {
  230. MB(); 
  231. if (p->SwapXY)
  232. {
  233. I2(MOVB_ST,R11,R2);
  234. I2(ADD,R8,R2);
  235. }
  236. else
  237. {
  238. I2(MOVB_ST,R11,R3);
  239. I1C(ADDI,R3,p->DirX>0 ? 1:-1);
  240. }
  241. }
  242. MB(); I2(MOVB_ST,R14,R2);
  243. if (p->SwapXY)
  244. {
  245. I2(ADD,R8,R2);
  246. for (n=0;n<SrcRows;++n)
  247. I1C(ADDI,(reg)(R4+n),1);
  248. }
  249. else
  250. {
  251. I1C(ADDI,R2,p->DirX>0 ? 1:-1);
  252. I1C(ADDI,R4,Count >> p->DstDoubleX);
  253. }
  254. MB(); I2(CMPEQ,R2,R1); // has to go back at least one instruction (because of delay slot)
  255. DS(); I0P(BFS,LoopX);
  256. }
  257. //increment pointers
  258. I2C(MOVL_LDOFS,SP,R0,OFS(stack,DstNext));
  259. I2C(MOVL_LDOFS,SP,R1,OFS(stack,SrcNext));
  260. I2C(MOVL_LDOFS,SP,R12,OFS(stack,EndOfRect));
  261. for (n=0;n<DstRows;++n)
  262. I2(ADD,R0,(reg)(R2+n));
  263. for (n=0;n<SrcRows;++n)
  264. I2(ADD,R1,(reg)(R4+n));
  265. MB(); I2(CMPEQ,R2,R12); // has to go back at least one instruction (because of delay slot)
  266. DS(); I0P(BFS,LoopY);
  267. CodeEnd(7,OFS(stack,StackFrame));
  268. }
  269. #endif