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

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_mips_fix.c 339 2005-11-15 11:22:45Z 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(MIPS) 
  27. typedef struct stack
  28. {
  29. int EndOfRect;
  30. int DstNext;
  31. int SrcNext; // SrcPitch for scale
  32. int UVNext;
  33. int EndOfLineInc;
  34. int Y,U,V;
  35. int StackFrame[7];
  36. void* This;   //R4
  37. char* Dst;    //R5
  38. char* Src;    //R6
  39. int DstPitch; //R7
  40. int SrcPitch;
  41. int Width; 
  42. int Height;
  43. int Src2SrcLast;
  44. } stack;
  45. // R10 buffer_u
  46. // R11 buffer_v
  47. // R12 buffer_y1
  48. // R14 buffer_y2
  49. // R20 buffer_u2 (scale)
  50. // R21 buffer_v2 (scale)
  51. // R22 pos (scale)
  52. // R17 radd / pal:accy
  53. // R18 gadd / pal:accu
  54. // R19 badd / pal:accv
  55. // R13 negsat / LookUp_Y / pal:lookup
  56. // R15 possat / LookUp_U / pal:U
  57. // R4  r
  58. // R5  g
  59. // R6  b
  60. // R8  y1/rgb out
  61. // R9  y2/(rgb2 out)
  62. // R16 tmp / LookUp_V / pal:V
  63. // R2  tmp
  64. // R3  tmp
  65. // R7  endofline
  66. // R24 dest
  67. // R25 pitch
  68. // R1  tmp dest
  69. static NOINLINE int ConstAdjust(int v)
  70. {
  71. if (v>0)
  72. return (v + 0x1000) >> (16-3);
  73. return -((-v + 0x1000) >> (16-3));
  74. }
  75. static NOINLINE void Fix_RGB_UV_LoadUV(blit_soft* p,int OfsUV,int OfsUV2)
  76. {
  77. if (p->DstPalette)
  78. {
  79. if (!p->Scale)
  80. {
  81. I2C(LBU,R15,R10,0); //u
  82. I2C(ADDIU,R10,R10,1);
  83. I2C(LBU,R16,R11,0); //v
  84. I2C(ADDIU,R11,R11,1);
  85. }
  86. else
  87. {
  88. reg U = R10;
  89. reg V = R11;
  90. reg U2 = R10;
  91. reg V2 = R11;
  92. if (p->SwapXY)
  93. {
  94. if (p->DirX<0)
  95. {
  96. U = R20;
  97. V = R21;
  98. }
  99. else
  100. {
  101. U2 = R20;
  102. V2 = R21;
  103. }
  104. }
  105. I2C(LBU,R2,U2,OfsUV2); //u2
  106. I2C(LBU,R3,V2,OfsUV2); //v2
  107. I2C(LBU,R15,U,OfsUV); //u
  108. I2C(LBU,R16,V,OfsUV); //v
  109. }
  110. }
  111. else
  112. if (p->ColorLookup)
  113. {
  114. //set R4 =           RVMul*v + RAdd
  115. //set R5 = GUMul*u + GVMul*v + GAdd
  116. //set R6 = BUMul*u +           BAdd
  117. I2C(LBU,R2,R10,0); //u
  118. I2C(LBU,R3,R11,0); //v
  119. I2C(SLL,R2,R2,3);
  120. I2C(SLL,R3,R3,3);
  121. I3(ADDU,R2,R2,R15); //LookUp_U + u
  122. I3(ADDU,R3,R3,R16); //LookUp_V + v
  123. I2C(LW,R8,R2,4);
  124. I2C(ADDIU,R10,R10,1);
  125. I2C(LW,R9,R3,4);
  126. I2C(ADDIU,R11,R11,1);
  127. I2C(LW,R6,R2,0);
  128. I3(ADDU,R5,R8,R9);
  129. I2C(LW,R4,R3,0);
  130. }
  131. else
  132. {
  133. reg v;
  134. bool_t Neg;
  135. if (!p->Scale)
  136. {
  137. I2C(LBU,R4,R10,0); //u
  138. I2C(LBU,R5,R11,0); //v
  139. I2C(ADDIU,R10,R10,1);
  140. I2C(ADDIU,R11,R11,1);
  141. I2C(SLL,R2,R4,16);
  142. I2C(SLL,R3,R5,16);
  143. }
  144. else
  145. {
  146. reg U = R10;
  147. reg V = R11;
  148. reg U2 = R10;
  149. reg V2 = R11;
  150. if (p->SwapXY)
  151. {
  152. if (p->DirX<0)
  153. {
  154. U = R20;
  155. V = R21;
  156. }
  157. else
  158. {
  159. U2 = R20;
  160. V2 = R21;
  161. }
  162. }
  163. I2C(LBU,R2,U2,OfsUV2); //u2
  164. I2C(LBU,R3,V2,OfsUV2); //v2
  165. I2C(LBU,R4,U,OfsUV); //u
  166. I2C(SLL,R2,R2,16);
  167. I2C(LBU,R5,V,OfsUV); //v
  168. I2C(SLL,R3,R3,16);
  169. }
  170. I3(OR,R2,R4,R2); // u | u
  171. I3(OR,R3,R5,R3); // v | v
  172. v = IMul(R2,ConstAdjust(p->_GUMul),R16,R4,R6,&Neg);
  173. I3(Neg?SUBU:ADDU,R5,R18,v);
  174. v = IMul(R3,ConstAdjust(p->_GVMul),R16,R4,R6,&Neg);
  175. I3(Neg?SUBU:ADDU,R5,R5,v);
  176. v = IMul(R3,ConstAdjust(p->_RVMul),R16,R4,R6,&Neg);
  177. I3(Neg?SUBU:ADDU,R4,R17,v);
  178. v = IMul(R2,ConstAdjust(p->_BUMul),R16,R3,R6,&Neg);
  179. I3(Neg?SUBU:ADDU,R6,R19,v);
  180. }
  181. }
  182. static NOINLINE void Fix_RGB_UV_Pixel(blit_soft* p, int Row, int Col)
  183. {
  184. int Shift;
  185. reg v;
  186. reg Y1,Y2;
  187. bool_t Neg;
  188. int OfsY;
  189. int OfsUV;
  190. int OfsY2;
  191. int OfsUV2;
  192. if (p->Scale)
  193. {
  194. OfsY = (Col * p->RScaleX) >> 4;
  195. OfsUV = (Col * p->RScaleX) >> (4+p->SrcUVX2);
  196. if (!p->SwapXY)
  197. {
  198. OfsY2 = ((Col+1) * p->RScaleX) >> 4;
  199. OfsUV2 = ((Col+1) * p->RScaleX) >> (4+p->SrcUVX2);
  200. }
  201. else
  202. {
  203. OfsY2 = OfsY;
  204. OfsUV2 = OfsUV;
  205. }
  206. Fix_RGB_UV_LoadUV(p,OfsUV,OfsUV2);
  207. }
  208. else
  209. {
  210. if (p->SwapXY)
  211. {
  212. OfsY = Row;
  213. OfsY2 = Row;
  214. }
  215. else
  216. {
  217. OfsY = 0;
  218. OfsY2 = 1;
  219. }
  220. }
  221. if (p->SwapXY)
  222. {
  223. Y1 = R12;
  224. Y2 = R14;
  225. }
  226. else
  227. Y1 = Y2 = (reg)(Row==0?R12:R14);
  228. //load Y
  229. if (p->DirX>0)
  230. {
  231. I2C(LBU,R9,Y2,OfsY2); //y2
  232. I2C(LBU,R8,Y1,OfsY);  //y1
  233. }
  234. else
  235. {
  236. I2C(LBU,R9,Y1,OfsY);  //y2
  237. I2C(LBU,R8,Y2,OfsY2); //y1
  238. }
  239. if (p->DstPalette)
  240. {
  241. I3(ADDU,R17,R17,R8);
  242. I3(ADDU,R18,R18,R15);
  243. I3(ADDU,R19,R19,R16);
  244. I2C(ANDI,R4,R17,0x1E0); 
  245. I2C(ANDI,R5,R18,0x1E0); 
  246. I2C(ANDI,R6,R19,0x1E0); 
  247. I2C(SLL,R4,R4,5); 
  248. I2C(SLL,R5,R5,1);
  249. I2C(SRL,R6,R6,3);
  250. I3(ADDU,R4,R4,R13);
  251. I3(ADDU,R4,R4,R5);
  252. I3(ADDU,R4,R4,R6);
  253. I2C(LBU,R8,R4,0);
  254. I2C(LBU,R6,R4,1);
  255. I2C(LBU,R5,R4,2);
  256. I2C(LBU,R4,R4,3);
  257. I3(SUBU,R17,R17,R6);
  258. I3(SUBU,R18,R18,R5);
  259. I3(SUBU,R19,R19,R4);
  260. I3(ADDU,R17,R17,R9);
  261. I3(ADDU,R18,R18,(reg)(p->Scale ? R2:R15));
  262. I3(ADDU,R19,R19,(reg)(p->Scale ? R3:R16));
  263. I2C(ANDI,R4,R17,0x1E0); 
  264. I2C(ANDI,R5,R18,0x1E0); 
  265. I2C(ANDI,R6,R19,0x1E0); 
  266. I2C(SLL,R4,R4,5); 
  267. I2C(SLL,R5,R5,1);
  268. I2C(SRL,R6,R6,3);
  269. I3(ADDU,R4,R4,R13);
  270. I3(ADDU,R4,R4,R5);
  271. I3(ADDU,R4,R4,R6);
  272. I2C(LBU,R9,R4,0);
  273. I2C(LBU,R6,R4,1);
  274. I2C(LBU,R5,R4,2);
  275. I2C(LBU,R4,R4,3);
  276. I3(SUBU,R17,R17,R6);
  277. I3(SUBU,R18,R18,R5);
  278. I3(SUBU,R19,R19,R4);
  279. }
  280. else
  281. if (p->ColorLookup)
  282. {
  283. I3(ADDU,R8,R8,R13); //LookUp_Y + y1
  284. I2C(LBU,R8,R8,0);
  285. I3(ADDU,R9,R9,R13); //LookUp_Y + y2
  286. I2C(LBU,R9,R9,0);
  287. I3(ADDU,R2,R4,R8);
  288. I2C(LBU,R2,R2,0);
  289. I3(ADDU,R3,R5,R8);
  290. I2C(LBU,R3,R3,0);
  291. I3(ADDU,R8,R6,R8);
  292. I2C(LBU,R8,R8,0);
  293. I2C(SLL,R2,R2,p->DstPos[0]);
  294. I2C(SLL,R3,R3,p->DstPos[1]);
  295. if (p->DstPos[2]) I2C(SLL,R8,R8,p->DstPos[2]);
  296. I3(OR,R8,R8,R2);
  297. I3(OR,R8,R8,R3);
  298. I3(ADDU,R2,R4,R9);
  299. I2C(LBU,R2,R2,0);
  300. I3(ADDU,R3,R5,R9);
  301. I2C(LBU,R3,R3,0);
  302. I3(ADDU,R9,R6,R9);
  303. I2C(LBU,R9,R9,0);
  304. if (p->DstDoubleX || p->DstBPP > 16)
  305. {
  306. I2C(SLL,R2,R2,p->DstPos[0]);
  307. I2C(SLL,R3,R3,p->DstPos[1]);
  308. if (p->DstPos[2]) I2C(SLL,R9,R9,p->DstPos[2]);
  309. I3(OR,R9,R9,R2);
  310. I3(OR,R9,R9,R3);
  311. }
  312. else
  313. {
  314. I2C(SLL,R2,R2,p->DstPos[0]+16);
  315. I2C(SLL,R3,R3,p->DstPos[1]+16);
  316. I2C(SLL,R9,R9,p->DstPos[2]+16);
  317. I3(OR,R8,R8,R2);
  318. I3(OR,R8,R8,R3);
  319. I3(OR,R8,R8,R9);
  320. }
  321. }
  322. else
  323. {
  324. I2C(SLL,R9,R9,16);
  325. I3(OR,R8,R8,R9); // y1 | y2
  326. v = IMul(R8,ConstAdjust(p->_YMul),R16,R3,R2,&Neg);
  327. I3(Neg?SUBU:ADDU,R8,R4,v);
  328. I3(Neg?SUBU:ADDU,R9,R5,v);
  329. I3(Neg?SUBU:ADDU,R16,R6,v);
  330. // negative sat and mask final rbg
  331. I3(NOR,R2,R8,R13);
  332. I2C(SRL,R3,R2,4+p->DstSize[0]);
  333. I3(SUBU,R2,R2,R3);
  334. I3(AND,R8,R8,R2);
  335. I3(NOR,R2,R9,R13);
  336. I2C(SRL,R3,R2,4+p->DstSize[1]);
  337. I3(SUBU,R2,R2,R3);
  338. I3(AND,R9,R9,R2);
  339. I3(NOR,R2,R16,R13);
  340. I2C(SRL,R3,R2,4+p->DstSize[2]);
  341. I3(SUBU,R2,R2,R3);
  342. I3(AND,R16,R16,R2);
  343. // positive sat
  344. I3(AND,R2,R8,R15);
  345. I2C(SRL,R3,R2,p->DstSize[0]);
  346. I3(SUBU,R2,R2,R3);
  347. I3(OR,R8,R8,R2);
  348. I3(AND,R2,R9,R15);
  349. I2C(SRL,R3,R2,p->DstSize[1]);
  350. I3(SUBU,R2,R2,R3);
  351. I3(OR,R9,R9,R2);
  352. I3(AND,R2,R16,R15);
  353. I2C(SRL,R3,R2,p->DstSize[2]);
  354. I3(SUBU,R2,R2,R3);
  355. I3(OR,R16,R16,R2);
  356. Shift = p->DstPos[0] + p->DstSize[0] - (8+3);
  357. if (Shift) I2C(SLL,R8,R8,Shift);
  358. Shift = p->DstPos[1] + p->DstSize[1] - (8+3);
  359. if (Shift) I2C(SLL,R9,R9,Shift);
  360. Shift = p->DstPos[2] + p->DstSize[2] - (8+3);
  361. if (Shift) I2C(SLL,R16,R16,Shift);
  362. I3(OR,R8,R8,R9);
  363. I3(OR,R8,R8,R16);
  364. }
  365. }
  366. // R3,R2 for temp
  367. static NOINLINE void Write(blit_soft* p,reg Dst,reg A,reg B,bool_t Prepare)
  368. {
  369. switch (p->DstBPP)
  370. {
  371. case 8:
  372. if (p->DstDoubleX)
  373. {
  374. if (Prepare)
  375. {
  376. I2C(SLL,R3,A,8);
  377. I3(OR,A,A,R3);
  378. I2C(SLL,R3,B,8);
  379. I3(OR,B,B,R3);
  380. I2C(SLL,R3,B,16);
  381. I3(OR,A,A,R3);
  382. }
  383. I2C(SW,A,Dst,0);
  384. }
  385. else
  386. {
  387. if (Prepare)
  388. {
  389. I2C(SLL,R3,B,8);
  390. I3(OR,A,A,R3);
  391. }
  392. I2C(SH,A,Dst,0);
  393. }
  394. break;
  395. case 16:
  396. if (p->Dst.Flags & PF_16BITACCESS)
  397. {
  398. if (p->DstDoubleX)
  399. {
  400. if (Prepare && !p->ColorLookup)
  401. I2C(SRL,B,A,16);
  402. I2C(SH,A,Dst,0);
  403. I2C(SH,A,Dst,2);
  404. I2C(SH,B,Dst,4);
  405. I2C(SH,B,Dst,6);
  406. }
  407. else
  408. {
  409. if (Prepare)
  410. I2C(SRL,B,A,16);
  411. I2C(SH,A,Dst,0);
  412. I2C(SH,B,Dst,2);
  413. }
  414. }
  415. else
  416. {
  417. if (p->DstDoubleX)
  418. {
  419. if (Prepare)
  420. {
  421. if (p->ColorLookup)
  422. {
  423. I2C(SLL,R3,A,16);
  424. I2C(SLL,R2,B,16);
  425. I3(OR,A,A,R3);
  426. I3(OR,B,B,R2);
  427. }
  428. else
  429. {
  430. I2C(SLL,R3,A,16);
  431. I2C(SRL,R2,A,16);
  432. I2C(SRL,A,R3,16);
  433. I2C(SLL,B,R2,16);
  434. I3(OR,A,A,R3);
  435. I3(OR,B,B,R2);
  436. }
  437. }
  438. I2C(SW,B,Dst,4);
  439. }
  440. I2C(SW,A,Dst,0);
  441. }
  442. break;
  443. case 24:
  444. if (p->DstDoubleX)
  445. {
  446. if (Prepare)
  447. {
  448. I2C(SLL,R3,A,24);
  449. I2C(SRL,R2,A,8);
  450. I3(OR,A,A,R3);
  451. I2C(SLL,R3,B,16);
  452. I3(OR,R3,R3,R2);
  453. I2C(SRL,R2,B,16);
  454. I2C(SLL,B,B,8);
  455. I3(OR,B,B,R2);
  456. }
  457. I2C(SW,A,Dst,0);
  458. I2C(SW,R3,Dst,4);
  459. I2C(SW,B,Dst,8);
  460. }
  461. else
  462. {
  463. if (Prepare)
  464. {
  465. I2C(SRL,R3,A,16);
  466. I2C(SLL,B,B,8);
  467. I3(OR,R3,R3,B);
  468. I2C(SRL,B,B,16);
  469. }
  470. I2C(SH,A,Dst,0);
  471. I2C(SH,R3,Dst,2);
  472. I2C(SH,B,Dst,4);
  473. }
  474. break;
  475. case 32:
  476. if (p->DstDoubleX)
  477. {
  478. I2C(SW,A,Dst,0);
  479. I2C(SW,A,Dst,4);
  480. I2C(SW,B,Dst,8);
  481. I2C(SW,B,Dst,12);
  482. }
  483. else
  484. {
  485. I2C(SW,A,Dst,0);
  486. I2C(SW,B,Dst,4);
  487. }
  488. break;
  489. }
  490. }
  491. void Fix_RGB_UV(blit_soft* p)
  492. {
  493. int Col,ColCount,i,RowStep;
  494. dyninst* LoopY;
  495. dyninst* LoopX;
  496. dyninst* EndOfLine;
  497. p->Scale = (boolmem_t)(!(p->RScaleX == 8 || p->RScaleX == 16) || 
  498. !(p->RScaleY == 8 || p->RScaleY == 16) ||
  499. p->SrcUVX2!=1 || p->SrcUVY2!=1);
  500. if (p->Scale)
  501. {
  502. p->DstDoubleX = p->DstDoubleY = 0;
  503. p->ColorLookup = 0;
  504. }
  505. if (p->RScaleX == 8 || p->RScaleY == 8)
  506. p->DstAlignSize = 4;
  507. p->DstStepX = p->DirX * ((p->DstBPP*2) >> 3) << p->DstDoubleX;
  508. CodeBegin(7,OFS(stack,StackFrame),0);
  509. if (p->DstPalette)
  510. {
  511. IConst(R17,0);
  512. IConst(R18,0);
  513. IConst(R19,0);
  514. I2C(LW,R13,R4,OFS(blit_soft,LookUp_Data));
  515. }
  516. else
  517. if (p->ColorLookup)
  518. {
  519. CalcLookUp(p,0);
  520. I2C(LW,R13,R4,OFS(blit_soft,LookUp_Data));
  521. I2C(ADDIU,R15,R13,p->LookUp_U);
  522. I2C(ADDIU,R16,R13,p->LookUp_V);
  523. }
  524. else
  525. {
  526. IConst(R17,(ConstAdjust(p->_RAdd) & 0xFFFF) * 0x10001);
  527. IConst(R18,(ConstAdjust(p->_GAdd) & 0xFFFF) * 0x10001);
  528. IConst(R19,(ConstAdjust(p->_BAdd) & 0xFFFF) * 0x10001);
  529. IConst(R15,0x01000100 << 3); //possat
  530. IConst(R13,0x7FFF7FFF); //negsat
  531. }
  532. I2C(LW,R24,R5,0); //Dst[0] RGB
  533. I2C(LW,R10,R6,4); //Src[1] U
  534. I2C(LW,R11,R6,8); //Src[2] V
  535. I2C(LW,R12,R6,0); //Src[0] Y
  536. I3(ADDU,R25,R7,ZERO); //DstPitch
  537. if (p->Scale)
  538. {
  539. I2C(SW,R10,SP,OFS(stack,U));
  540. I2C(SW,R11,SP,OFS(stack,V));
  541. I2C(SW,R12,SP,OFS(stack,Y));
  542. I2C(LW,R7,SP,OFS(stack,SrcPitch));
  543. }
  544. I2C(LW,R7,SP,OFS(stack,SrcPitch));
  545. I2C(LW,R5,SP,OFS(stack,Height));
  546. I2C(LW,R4,SP,OFS(stack,Width));
  547. if (!p->Scale)
  548. {
  549. //SrcNext = 2*Src->Pitch - (Width >> SrcDoubleX)
  550. I2C(SLL,R2,R7,1);
  551. if (p->SrcDoubleX)
  552. {
  553. I2C(SRL,R3,R4,p->SrcDoubleX);
  554. I3(SUBU,R2,R2,R3); 
  555. }
  556. else
  557. I3(SUBU,R2,R2,R4); 
  558. I2C(SW,R2,SP,OFS(stack,SrcNext));
  559. //UVNext = (Src->Pitch >> 1) - (Width >> SrcDoubleX >> 1);
  560. I2C(SRA,R2,R7,1);
  561. I2C(SRL,R3,R4,p->SrcDoubleX+1);
  562. I3(SUBU,R2,R2,R3); 
  563. I2C(SW,R2,SP,OFS(stack,UVNext));
  564. }
  565. else
  566. I2C(SW,R7,SP,OFS(stack,SrcNext));
  567. if (p->DirX<0) //adjust reversed destination for block size
  568. I2C(ADDIU,R24,R24,p->DstStepX+(p->DstBPP >> 3));
  569. if (p->SwapXY)
  570. {
  571. I2C(ADDIU,R3,ZERO,p->DstBPP * p->DirX);
  572. I2(MULT,R5,R3); // p->DstBPP * p->DirX * Height
  573. I1(MFLO,R3);
  574. I2C(SRA,R3,R3,3); // bits->byte
  575. I3(ADDU,R3,R3,R24);
  576. I2C(SW,R3,SP,OFS(stack,EndOfRect));
  577. //DstNext = DstStepX - Width * DstPitch;
  578. I2(MULT,R25,R4);
  579. I1(MFLO,R2);
  580. I2C(ADDIU,R3,ZERO,p->DstStepX);
  581. I3(SUBU,R3,R3,R2);
  582. I2C(SW,R3,SP,OFS(stack,DstNext));
  583. }
  584. else
  585. {
  586. I2(MULT,R5,R25); //Height * DstPitch
  587. I1(MFLO,R3);
  588. I3(ADDU,R3,R3,R24);
  589. I2C(SW,R3,SP,OFS(stack,EndOfRect));
  590. //DstNext = ((DstPitch*(Scale?1:2) << DstDoubleY) - DirX * Width << DstBPP2;
  591. I2C(SLL,R2,R25,p->DstDoubleY+(p->Scale?0:1));
  592. I2C(SLL,R3,R4,p->DstBPP2);
  593. I3(p->DirX>0?SUBU:ADDU,R2,R2,R3);
  594. I2C(SW,R2,SP,OFS(stack,DstNext));
  595. }
  596. if (p->SwapXY)
  597. {
  598. I2(MULT,R25,R4); // Width * DstPitch
  599. I1(MFLO,R4);
  600. }
  601. else
  602. {
  603. I2C(SLL,R4,R4,p->DstBPP2);
  604. if (p->DirX < 0)
  605. I3(SUBU,R4,ZERO,R4);
  606. }
  607. I2C(SW,R4,SP,OFS(stack,EndOfLineInc));
  608. if (p->Scale)
  609. I3(ADDU,R22,ZERO,ZERO); //pos=0
  610. else
  611. I3(ADDU,R14,R12,R7);
  612. ColCount = 32;
  613. for (i=1;i<16 && !(p->RScaleX & i);i<<=1)
  614. ColCount >>= 1;
  615. LoopY = Label(1);
  616. // R4 = EndOfLineInc
  617. I3(ADDU,R7,R24,R4);
  618. LoopX = Label(1);
  619. if (p->Scale)
  620. {
  621. EndOfLine = Label(0);
  622. if (p->SwapXY)
  623. {
  624. //we need next row in R14,R20,R21 (YUV)
  625. I2C(LW,R2,SP,OFS(stack,SrcNext)); //srcpitch
  626. //increment row of Y,U,V according to Pos -> Pos+RowStep*RScaleY
  627. I2C(ADDIU,R9,R22,p->RScaleY); //Pos += RScaleY
  628. I2C(SRL,R8,R22,4);
  629. I2C(SRL,R9,R9,4);
  630. // dY  = ((Pos+RowStep*RScaleY) >> 4) - (Pos >> 4);
  631. I3(SUBU,R4,R9,R8); 
  632. I2(MULT,R4,R2); // dY * SrcPitch
  633. I1(MFLO,R4);
  634. I3(ADDU,R14,R12,R4);
  635. // dUV = ((Pos+RowStep*RScaleY) >> (4+SrcUVY2)) - (Pos >> (4+SrcUVY2));
  636. if (p->SrcUVY2) I2C(SRL,R9,R9,p->SrcUVY2);
  637. if (p->SrcUVY2) I2C(SRL,R8,R8,p->SrcUVY2);
  638. I3(SUBU,R4,R9,R8); 
  639. I2(MULT,R4,R2); // dUV * (SrcPitch >> SrcUVX2)
  640. I1(MFLO,R4);
  641. if (p->SrcUVX2) I2C(SRA,R4,R4,p->SrcUVX2);
  642. I3(ADDU,R20,R10,R4);
  643. I3(ADDU,R21,R11,R4);
  644. }
  645. for (Col=0;Col<ColCount;)
  646. {
  647. Fix_RGB_UV_Pixel(p,0,Col);
  648. ++Col;
  649. if (!p->SwapXY)
  650. ++Col;
  651. Write(p,R24,R8,R9,1);
  652. if (p->SwapXY)
  653. I3(ADDU,R24,R24,R25);
  654. else
  655. I2C(ADDIU,R24,R24,p->DstStepX);
  656. if (Col == ColCount) 
  657. {
  658. //last item in block, increase source pointers
  659. I2C(ADDIU,R12,R12,(p->RScaleX * ColCount) >> 4);
  660. I2C(ADDIU,R10,R10,(p->RScaleX * ColCount) >> (4+p->SrcUVX2));
  661. I2C(ADDIU,R11,R11,(p->RScaleX * ColCount) >> (4+p->SrcUVX2));
  662. if (p->SwapXY)
  663. {
  664. I2C(ADDIU,R14,R14,(p->RScaleX * ColCount) >> 4);
  665. I2C(ADDIU,R20,R20,(p->RScaleX * ColCount) >> (4+p->SrcUVX2));
  666. I2C(ADDIU,R21,R21,(p->RScaleX * ColCount) >> (4+p->SrcUVX2));
  667. }
  668. DS(); I2P(BNE,R24,R7,LoopX);
  669. }
  670. else
  671. {
  672. I2P(BEQ,R24,R7,EndOfLine); // delay slot will be the next item
  673. }
  674. }
  675. InstPost(EndOfLine);
  676. I2C(LW,R2,SP,OFS(stack,SrcNext)); //srcpitch
  677. I2C(LW,R4,SP,OFS(stack,DstNext));
  678. I2C(LW,R5,SP,OFS(stack,EndOfRect));
  679. I2C(LW,R10,SP,OFS(stack,U));
  680. I2C(LW,R11,SP,OFS(stack,V));
  681. I2C(LW,R12,SP,OFS(stack,Y));
  682. //increment pointers
  683. I3(ADDU,R24,R24,R4);
  684. RowStep = (p->SwapXY) ? 2:1;
  685. //increment row of Y,U,V according to Pos -> Pos+RowStep*RScaleY
  686. I2C(SRL,R8,R22,4);
  687. I2C(ADDIU,R22,R22,RowStep*p->RScaleY); //Pos += RowStep*RScaleY
  688. I2C(SRL,R9,R22,4);
  689. // dY  = ((Pos+RowStep*RScaleY) >> 4) - (Pos >> 4);
  690. I3(SUBU,R4,R9,R8); 
  691. I2(MULT,R4,R2); // dY * SrcPitch
  692. I1(MFLO,R4);
  693. I3(ADDU,R12,R12,R4);
  694.     // dUV = ((Pos+RowStep*RScaleY) >> (4+SrcUVY2)) - (Pos >> (4+SrcUVY2));
  695. if (p->SrcUVY2) I2C(SRL,R9,R9,p->SrcUVY2);
  696. if (p->SrcUVY2) I2C(SRL,R8,R8,p->SrcUVY2);
  697. I3(SUBU,R4,R9,R8); 
  698. I2(MULT,R4,R2); // dUV * (SrcPitch >> SrcUVX2)
  699. I1(MFLO,R4);
  700. if (p->SrcUVX2) I2C(SRA,R4,R4,p->SrcUVX2);
  701. I3(ADDU,R10,R10,R4);
  702. I3(ADDU,R11,R11,R4);
  703. I2C(SW,R10,SP,OFS(stack,U));
  704. I2C(SW,R11,SP,OFS(stack,V));
  705. I2C(SW,R12,SP,OFS(stack,Y));
  706. }
  707. else
  708. {
  709. reg Dst;
  710. Fix_RGB_UV_LoadUV(p,0,0);
  711. Fix_RGB_UV_Pixel(p,0,0);
  712. Dst = R24;
  713. if (!p->SwapXY)
  714. Dst = R1;
  715. Write(p,R24,R8,R9,1);
  716. I3(ADDU,Dst,R24,R25);
  717. if (p->DstDoubleY)
  718. {
  719. Write(p,Dst,R8,R9,0);
  720. I3(ADDU,Dst,Dst,R25);
  721. }
  722. Fix_RGB_UV_Pixel(p,1,0);
  723. Write(p,Dst,R8,R9,1);
  724. if (p->DstDoubleY)
  725. {
  726. I3(ADDU,Dst,Dst,R25);
  727. Write(p,Dst,R8,R9,0);
  728. }
  729. if (p->SwapXY)
  730. I3(ADDU,Dst,Dst,R25);
  731. else
  732. I2C(ADDIU,R24,R24,p->DstStepX);
  733. I2C(ADDIU,R12,R12,2);
  734. I2C(ADDIU,R14,R14,2);
  735. DS(); I2P(BNE,R24,R7,LoopX);
  736. I2C(LW,R2,SP,OFS(stack,SrcNext));
  737. I2C(LW,R4,SP,OFS(stack,DstNext));
  738. I2C(LW,R6,SP,OFS(stack,UVNext));
  739. I2C(LW,R5,SP,OFS(stack,EndOfRect));
  740. //increment pointers
  741. I3(ADDU,R12,R12,R2);
  742. I3(ADDU,R14,R14,R2);
  743. I3(ADDU,R24,R24,R4);
  744. I3(ADDU,R10,R10,R6);
  745. I3(ADDU,R11,R11,R6);
  746. }
  747. //prepare registers for next row
  748. I2C(LW,R4,SP,OFS(stack,EndOfLineInc));
  749. DS(); I2P(BNE,R24,R5,LoopY);
  750. CodeEnd(7,OFS(stack,StackFrame),0);
  751. }
  752. #endif