/[pcsx2_0.9.7]/trunk/pcsx2/IPU/IPU.cpp
ViewVC logotype

Diff of /trunk/pcsx2/IPU/IPU.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 191 by william, Mon Sep 20 05:35:51 2010 UTC revision 273 by william, Fri Nov 12 01:10:22 2010 UTC
# Line 26  Line 26 
26  #include "Vif_Dma.h"  #include "Vif_Dma.h"
27  #include <limits.h>  #include <limits.h>
28    
 static __fi void IPU_INT0_FROM()  
 {  
         if (ipu0dma.qwc > 0 && ipu0dma.chcr.STR) ipu0Interrupt();  
 }  
   
 tIPU_cmd ipu_cmd;  
   
 void ReorderBitstream();  
   
29  // the BP doesn't advance and returns -1 if there is no data to be read  // the BP doesn't advance and returns -1 if there is no data to be read
30    __aligned16 tIPU_cmd ipu_cmd;
31  __aligned16 tIPU_BP g_BP;  __aligned16 tIPU_BP g_BP;
32    __aligned16 decoder_t decoder;
33    
34  void IPUWorker();  void IPUWorker();
35    
# Line 53  int coded_block_pattern = 0; Line 46  int coded_block_pattern = 0;
46    
47    
48  u8 indx4[16*16/2];  u8 indx4[16*16/2];
49  __aligned16 decoder_t decoder;  
50    
51    void tIPU_cmd::clear()
52    {
53            memzero_sse_a(*this);
54            current = 0xffffffff;
55    }
56    
57  __fi void IPUProcessInterrupt()  __fi void IPUProcessInterrupt()
58  {  {
59          if (ipuRegs.ctrl.BUSY && g_BP.IFC) IPUWorker();          if (ipuRegs.ctrl.BUSY) // && (g_BP.FP || g_BP.IFC || (ipu1dma.chcr.STR && ipu1dma.qwc > 0)))
60                    IPUWorker();
61  }  }
62    
63  /////////////////////////////////////////////////////////  /////////////////////////////////////////////////////////
# Line 194  __fi u32 ipuRead32(u32 mem) Line 194  __fi u32 ipuRead32(u32 mem)
194          pxAssert((mem & ~0xff) == 0x10002000);          pxAssert((mem & ~0xff) == 0x10002000);
195          mem &= 0xff;    // ipu repeats every 0x100          mem &= 0xff;    // ipu repeats every 0x100
196    
197          //IPUProcessInterrupt();          IPUProcessInterrupt();
198    
199          switch (mem)          switch (mem)
200          {          {
# Line 207  __fi u32 ipuRead32(u32 mem) Line 207  __fi u32 ipuRead32(u32 mem)
207                                  IPU_LOG("read32: IPU_CTRL=0x%08X", ipuRegs.ctrl._u32);                                  IPU_LOG("read32: IPU_CTRL=0x%08X", ipuRegs.ctrl._u32);
208    
209                          return ipuRegs.ctrl._u32;                          return ipuRegs.ctrl._u32;
210                  }                                }
211    
212                  ipucase(IPU_BP): // IPU_BP                  ipucase(IPU_BP): // IPU_BP
213                  {                  {
# Line 236  __fi u64 ipuRead64(u32 mem) Line 236  __fi u64 ipuRead64(u32 mem)
236          pxAssert((mem & ~0xff) == 0x10002000);          pxAssert((mem & ~0xff) == 0x10002000);
237          mem &= 0xff;    // ipu repeats every 0x100          mem &= 0xff;    // ipu repeats every 0x100
238    
239          //IPUProcessInterrupt();          IPUProcessInterrupt();
240    
241          switch (mem)          switch (mem)
242          {          {
# Line 286  __fi bool ipuWrite32(u32 mem, u32 value) Line 286  __fi bool ipuWrite32(u32 mem, u32 value)
286          pxAssert((mem & ~0xfff) == 0x10002000);          pxAssert((mem & ~0xfff) == 0x10002000);
287          mem &= 0xfff;          mem &= 0xfff;
288    
         IPUProcessInterrupt();  
   
289          switch (mem)          switch (mem)
290          {          {
291                  ipucase(IPU_CMD): // IPU_CMD                  ipucase(IPU_CMD): // IPU_CMD
292                          IPU_LOG("write32: IPU_CMD=0x%08X", value);                          IPU_LOG("write32: IPU_CMD=0x%08X", value);
293                          IPUCMD_WRITE(value);                          IPUCMD_WRITE(value);
294                            IPUProcessInterrupt();
295                  return false;                  return false;
296    
297                  ipucase(IPU_CTRL): // IPU_CTRL                  ipucase(IPU_CTRL): // IPU_CTRL
# Line 323  __fi bool ipuWrite64(u32 mem, u64 value) Line 322  __fi bool ipuWrite64(u32 mem, u64 value)
322          pxAssert((mem & ~0xfff) == 0x10002000);          pxAssert((mem & ~0xfff) == 0x10002000);
323          mem &= 0xfff;          mem &= 0xfff;
324    
         IPUProcessInterrupt();  
   
325          switch (mem)          switch (mem)
326          {          {
327                  ipucase(IPU_CMD):                  ipucase(IPU_CMD):
328                          IPU_LOG("write64: IPU_CMD=0x%08X", value);                          IPU_LOG("write64: IPU_CMD=0x%08X", value);
329                          IPUCMD_WRITE((u32)value);                          IPUCMD_WRITE((u32)value);
330                            IPUProcessInterrupt();
331                  return false;                  return false;
332          }          }
333    
# Line 352  static void ipuBCLR(u32 val) Line 350  static void ipuBCLR(u32 val)
350          IPU_LOG("Clear IPU input FIFO. Set Bit offset=0x%X", g_BP.BP);          IPU_LOG("Clear IPU input FIFO. Set Bit offset=0x%X", g_BP.BP);
351  }  }
352    
353  static bool ipuIDEC(u32 val, bool resume)  static __ri void ipuIDEC(tIPU_CMD_IDEC idec)
354  {  {
355          tIPU_CMD_IDEC idec(val);          idec.log();
   
         if (!resume)  
         {  
                 idec.log();  
                 g_BP.Advance(idec.FB);  
356    
357          //from IPU_CTRL          //from IPU_CTRL
358                  ipuRegs.ctrl.PCT = I_TYPE; //Intra DECoding;)          ipuRegs.ctrl.PCT = I_TYPE; //Intra DECoding;)
359    
360                  decoder.coding_type                     = ipuRegs.ctrl.PCT;          decoder.coding_type                     = ipuRegs.ctrl.PCT;
361                  decoder.mpeg1                           = ipuRegs.ctrl.MP1;          decoder.mpeg1                           = ipuRegs.ctrl.MP1;
362                  decoder.q_scale_type            = ipuRegs.ctrl.QST;          decoder.q_scale_type            = ipuRegs.ctrl.QST;
363                  decoder.intra_vlc_format        = ipuRegs.ctrl.IVF;          decoder.intra_vlc_format        = ipuRegs.ctrl.IVF;
364                  decoder.scantype                        = ipuRegs.ctrl.AS;          decoder.scantype                        = ipuRegs.ctrl.AS;
365                  decoder.intra_dc_precision      = ipuRegs.ctrl.IDP;          decoder.intra_dc_precision      = ipuRegs.ctrl.IDP;
366    
367          //from IDEC value  //from IDEC value
368                  decoder.quantizer_scale         = idec.QSC;          decoder.quantizer_scale         = idec.QSC;
369                  decoder.frame_pred_frame_dct= !idec.DTD;          decoder.frame_pred_frame_dct= !idec.DTD;
370                  decoder.sgn = idec.SGN;          decoder.sgn = idec.SGN;
371                  decoder.dte = idec.DTE;          decoder.dte = idec.DTE;
372                  decoder.ofm = idec.OFM;          decoder.ofm = idec.OFM;
373    
374          //other stuff          //other stuff
375                  decoder.dcr = 1; // resets DC prediction value          decoder.dcr = 1; // resets DC prediction value
         }  
   
         return mpeg2sliceIDEC();  
376  }  }
377    
378  static int s_bdec = 0;  static int s_bdec = 0;
379    
380  static __fi bool ipuBDEC(u32 val, bool resume)  static __ri void ipuBDEC(tIPU_CMD_BDEC bdec)
381  {  {
382          tIPU_CMD_BDEC bdec(val);          bdec.log(s_bdec);
383            if (IsDebugBuild) s_bdec++;
384    
385          if (!resume)          decoder.coding_type                     = I_TYPE;
386          {          decoder.mpeg1                           = ipuRegs.ctrl.MP1;
387                  bdec.log(s_bdec);          decoder.q_scale_type            = ipuRegs.ctrl.QST;
388                  if (IsDebugBuild) s_bdec++;          decoder.intra_vlc_format        = ipuRegs.ctrl.IVF;
389            decoder.scantype                        = ipuRegs.ctrl.AS;
390                  g_BP.Advance(bdec.FB);          decoder.intra_dc_precision      = ipuRegs.ctrl.IDP;
                 decoder.coding_type                     = I_TYPE;  
                 decoder.mpeg1                           = ipuRegs.ctrl.MP1;  
                 decoder.q_scale_type            = ipuRegs.ctrl.QST;  
                 decoder.intra_vlc_format        = ipuRegs.ctrl.IVF;  
                 decoder.scantype                        = ipuRegs.ctrl.AS;  
                 decoder.intra_dc_precision      = ipuRegs.ctrl.IDP;  
391    
392          //from BDEC value          //from BDEC value
393                  decoder.quantizer_scale         = decoder.q_scale_type ? non_linear_quantizer_scale [bdec.QSC] : bdec.QSC << 1;          decoder.quantizer_scale         = decoder.q_scale_type ? non_linear_quantizer_scale [bdec.QSC] : bdec.QSC << 1;
394                  decoder.macroblock_modes        = bdec.DT ? DCT_TYPE_INTERLACED : 0;          decoder.macroblock_modes        = bdec.DT ? DCT_TYPE_INTERLACED : 0;
395                  decoder.dcr                                     = bdec.DCR;          decoder.dcr                                     = bdec.DCR;
396                  decoder.macroblock_modes        |= bdec.MBI ? MACROBLOCK_INTRA : MACROBLOCK_PATTERN;          decoder.macroblock_modes        |= bdec.MBI ? MACROBLOCK_INTRA : MACROBLOCK_PATTERN;
   
                 memzero_sse_a(decoder.mb8);  
                 memzero_sse_a(decoder.mb16);  
         }  
397    
398          return mpeg2_slice();          memzero_sse_a(decoder.mb8);
399            memzero_sse_a(decoder.mb16);
400  }  }
401    
402  static bool __fastcall ipuVDEC(u32 val)  static __fi bool ipuVDEC(u32 val)
403  {  {
404          switch (ipu_cmd.pos[0])          switch (ipu_cmd.pos[0])
405          {          {
# Line 448  static bool __fastcall ipuVDEC(u32 val) Line 430  static bool __fastcall ipuVDEC(u32 val)
430                                  jNO_DEFAULT                                  jNO_DEFAULT
431                          }                          }
432    
433                            // HACK ATTACK!  This code OR's the MPEG decoder's bitstream position into the upper
434                            // 16 bits of DATA; which really doesn't make sense since (a) we already rewound the bits
435                            // back into the IPU internal buffer above, and (b) the IPU doesn't have an MPEG internal
436                            // 32-bit decoder buffer of its own anyway.  Furthermore, setting the upper 16 bits to
437                            // any value other than zero appears to work fine.  When set to zero, however, FMVs run
438                            // very choppy (basically only decoding/updating every 30th frame or so). So yeah,
439                            // someone with knowledge on the subject please feel free to explain this one. :) --air
440    
441                          ipuRegs.cmd.DATA &= 0xFFFF;                          ipuRegs.cmd.DATA &= 0xFFFF;
442                          ipuRegs.cmd.DATA |= 0x10000;                          ipuRegs.cmd.DATA |= 0x10000;
443    
# Line 466  static bool __fastcall ipuVDEC(u32 val) Line 456  static bool __fastcall ipuVDEC(u32 val)
456                          IPU_LOG("VDEC command data 0x%x(0x%x). Skip 0x%X bits/Table=%d (%s), pct %d",                          IPU_LOG("VDEC command data 0x%x(0x%x). Skip 0x%X bits/Table=%d (%s), pct %d",
457                                  ipuRegs.cmd.DATA, ipuRegs.cmd.DATA >> 16, val & 0x3f, (val >> 26) & 3, (val >> 26) & 1 ?                                  ipuRegs.cmd.DATA, ipuRegs.cmd.DATA >> 16, val & 0x3f, (val >> 26) & 3, (val >> 26) & 1 ?
458                                  ((val >> 26) & 2 ? "DMV" : "MBT") : (((val >> 26) & 2 ? "MC" : "MBAI")), ipuRegs.ctrl.PCT);                                  ((val >> 26) & 2 ? "DMV" : "MBT") : (((val >> 26) & 2 ? "MC" : "MBAI")), ipuRegs.ctrl.PCT);
459    
460                          return true;                          return true;
461    
462                  jNO_DEFAULT                  jNO_DEFAULT
# Line 474  static bool __fastcall ipuVDEC(u32 val) Line 465  static bool __fastcall ipuVDEC(u32 val)
465          return false;          return false;
466  }  }
467    
468  static __fi bool ipuFDEC(u32 val)  static __ri bool ipuFDEC(u32 val)
469  {  {
470          if (!getBits32((u8*)&ipuRegs.cmd.DATA, 0)) return false;          if (!getBits32((u8*)&ipuRegs.cmd.DATA, 0)) return false;
471    
# Line 488  static __fi bool ipuFDEC(u32 val) Line 479  static __fi bool ipuFDEC(u32 val)
479    
480  static bool ipuSETIQ(u32 val)  static bool ipuSETIQ(u32 val)
481  {  {
         int i;  
   
482          if ((val >> 27) & 1)          if ((val >> 27) & 1)
483          {          {
484                  u8 (&niq)[64] = decoder.niq;                  u8 (&niq)[64] = decoder.niq;
# Line 500  static bool ipuSETIQ(u32 val) Line 489  static bool ipuSETIQ(u32 val)
489                  }                  }
490    
491                  IPU_LOG("Read non-intra quantization matrix from FIFO.");                  IPU_LOG("Read non-intra quantization matrix from FIFO.");
492                  for (i = 0; i < 8; i++)                  for (uint i = 0; i < 8; i++)
493                  {                  {
494                          IPU_LOG("%02X %02X %02X %02X %02X %02X %02X %02X",                          IPU_LOG("%02X %02X %02X %02X %02X %02X %02X %02X",
495                                  niq[i * 8 + 0], niq[i * 8 + 1], niq[i * 8 + 2], niq[i * 8 + 3],                                  niq[i * 8 + 0], niq[i * 8 + 1], niq[i * 8 + 2], niq[i * 8 + 3],
# Line 517  static bool ipuSETIQ(u32 val) Line 506  static bool ipuSETIQ(u32 val)
506                  }                  }
507    
508                  IPU_LOG("Read intra quantization matrix from FIFO.");                  IPU_LOG("Read intra quantization matrix from FIFO.");
509                  for (i = 0; i < 8; i++)                  for (uint i = 0; i < 8; i++)
510                  {                  {
511                          IPU_LOG("%02X %02X %02X %02X %02X %02X %02X %02X",                          IPU_LOG("%02X %02X %02X %02X %02X %02X %02X %02X",
512                                  iq[i * 8 + 0], iq[i * 8 + 1], iq[i * 8 + 2], iq[i *8 + 3],                                  iq[i * 8 + 0], iq[i * 8 + 1], iq[i * 8 + 2], iq[i *8 + 3],
# Line 539  static bool ipuSETVQ(u32 val) Line 528  static bool ipuSETVQ(u32 val)
528              "%02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d\n"              "%02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d\n"
529              "%02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d\n"              "%02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d\n"
530              "%02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d\n"              "%02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d\n"
531              "%02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d",                  "%02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d",
532              vqclut[0] >> 10, (vqclut[0] >> 5) & 0x1F, vqclut[0] & 0x1F,              vqclut[0] >> 10, (vqclut[0] >> 5) & 0x1F, vqclut[0] & 0x1F,
533              vqclut[1] >> 10, (vqclut[1] >> 5) & 0x1F, vqclut[1] & 0x1F,              vqclut[1] >> 10, (vqclut[1] >> 5) & 0x1F, vqclut[1] & 0x1F,
534              vqclut[2] >> 10, (vqclut[2] >> 5) & 0x1F, vqclut[2] & 0x1F,              vqclut[2] >> 10, (vqclut[2] >> 5) & 0x1F, vqclut[2] & 0x1F,
# Line 561  static bool ipuSETVQ(u32 val) Line 550  static bool ipuSETVQ(u32 val)
550  }  }
551    
552  // IPU Transfers are split into 8Qwords so we need to send ALL the data  // IPU Transfers are split into 8Qwords so we need to send ALL the data
553  static bool __fastcall ipuCSC(u32 val)  static __ri bool ipuCSC(tIPU_CMD_CSC csc)
554  {  {
         tIPU_CMD_CSC csc(val);  
555          csc.log_from_YCbCr();          csc.log_from_YCbCr();
556    
557          for (;ipu_cmd.index < (int)csc.MBC; ipu_cmd.index++)          for (;ipu_cmd.index < (int)csc.MBC; ipu_cmd.index++)
# Line 578  static bool __fastcall ipuCSC(u32 val) Line 566  static bool __fastcall ipuCSC(u32 val)
566                                    
567                  if (csc.OFM)                  if (csc.OFM)
568                  {                  {
569                          while (ipu_cmd.pos[1] < 32)                          ipu_cmd.pos[1] += ipu_fifo.out.write(((u32*) & decoder.rgb16) + 4 * ipu_cmd.pos[1], 32 - ipu_cmd.pos[1]);
570                          {                          if (ipu_cmd.pos[1] < 32) return false;
                                 ipu_cmd.pos[1] += ipu_fifo.out.write(((u32*) & decoder.rgb16) + 4 * ipu_cmd.pos[1], 32 - ipu_cmd.pos[1]);  
   
                                 if (ipu_cmd.pos[1] <= 0) return false;  
                         }  
571                  }                  }
572                  else                  else
573                  {                  {
574                          while (ipu_cmd.pos[1] < 64)                          ipu_cmd.pos[1] += ipu_fifo.out.write(((u32*) & decoder.rgb32) + 4 * ipu_cmd.pos[1], 64 - ipu_cmd.pos[1]);
575                          {                          if (ipu_cmd.pos[1] < 64) return false;
                                 ipu_cmd.pos[1] += ipu_fifo.out.write(((u32*) & decoder.rgb32) + 4 * ipu_cmd.pos[1], 64 - ipu_cmd.pos[1]);  
   
                                 if (ipu_cmd.pos[1] <= 0) return false;  
                         }  
576                  }                  }
577    
578                  ipu_cmd.pos[0] = 0;                  ipu_cmd.pos[0] = 0;
# Line 602  static bool __fastcall ipuCSC(u32 val) Line 582  static bool __fastcall ipuCSC(u32 val)
582          return true;          return true;
583  }  }
584    
585  // Todo - Need to add the same stop and start code as CSC  static __ri bool ipuPACK(tIPU_CMD_CSC csc)
 static bool ipuPACK(u32 val)  
586  {  {
         tIPU_CMD_CSC  csc(val);  
587          csc.log_from_RGB32();          csc.log_from_RGB32();
588    
589          for (;ipu_cmd.index < (int)csc.MBC; ipu_cmd.index++)          for (;ipu_cmd.index < (int)csc.MBC; ipu_cmd.index++)
# Line 623  static bool ipuPACK(u32 val) Line 601  static bool ipuPACK(u32 val)
601                  if (csc.OFM)                  if (csc.OFM)
602                  {                  {
603                          ipu_cmd.pos[1] += ipu_fifo.out.write(((u32*) & decoder.rgb16) + 4 * ipu_cmd.pos[1], 32 - ipu_cmd.pos[1]);                          ipu_cmd.pos[1] += ipu_fifo.out.write(((u32*) & decoder.rgb16) + 4 * ipu_cmd.pos[1], 32 - ipu_cmd.pos[1]);
   
604                          if (ipu_cmd.pos[1] < 32) return false;                          if (ipu_cmd.pos[1] < 32) return false;
605                  }                  }
606                  else                  else
607                  {                  {
608                          ipu_cmd.pos[1] += ipu_fifo.out.write(((u32*)indx4) + 4 * ipu_cmd.pos[1], 8 - ipu_cmd.pos[1]);                          ipu_cmd.pos[1] += ipu_fifo.out.write(((u32*)indx4) + 4 * ipu_cmd.pos[1], 8 - ipu_cmd.pos[1]);
   
609                          if (ipu_cmd.pos[1] < 8) return false;                          if (ipu_cmd.pos[1] < 8) return false;
610                  }                  }
611    
# Line 832  u8 getBits8(u8 *address, bool advance) Line 808  u8 getBits8(u8 *address, bool advance)
808  // --------------------------------------------------------------------------------------  // --------------------------------------------------------------------------------------
809  //  IPU Worker / Dispatcher  //  IPU Worker / Dispatcher
810  // --------------------------------------------------------------------------------------  // --------------------------------------------------------------------------------------
811  void IPUCMD_WRITE(u32 val)  
812    // When a command is written, we set some various busy flags and clear some other junk.
813    // The actual decoding will be handled by IPUworker.
814    __fi void IPUCMD_WRITE(u32 val)
815  {  {
816          // don't process anything if currently busy          // don't process anything if currently busy
817          if (ipuRegs.ctrl.BUSY) Console.WriteLn("IPU BUSY!"); // wait for thread          //if (ipuRegs.ctrl.BUSY) Console.WriteLn("IPU BUSY!"); // wait for thread
818    
819          ipuRegs.ctrl.ECD = 0;          ipuRegs.ctrl.ECD = 0;
820          ipuRegs.ctrl.SCD = 0; //clear ECD/SCD          ipuRegs.ctrl.SCD = 0;
821          ipu_cmd.clear();          ipu_cmd.clear();
822          ipu_cmd.current = val;          ipu_cmd.current = val;
823    
824          switch (val >> 28)          switch (ipu_cmd.CMD)
825          {          {
826                    // BCLR and SETTH  require no data so they always execute inline:
827    
828                  case SCE_IPU_BCLR:                  case SCE_IPU_BCLR:
829                          ipuBCLR(val);                          ipuBCLR(val);
830                          hwIntcIrq(INTC_IPU); //DMAC_TO_IPU                          hwIntcIrq(INTC_IPU); //DMAC_TO_IPU
831                            ipuRegs.ctrl.BUSY = 0;
832                            return;
833    
834                    case SCE_IPU_SETTH:
835                            ipuSETTH(val);
836                            hwIntcIrq(INTC_IPU);
837                            ipuRegs.ctrl.BUSY = 0;
838                          return;                          return;
839    
                 case SCE_IPU_VDEC:  
840    
841    
842                    case SCE_IPU_IDEC:
843                          g_BP.Advance(val & 0x3F);                          g_BP.Advance(val & 0x3F);
844                            ipuIDEC(val);
845                            ipuRegs.SetTopBusy();
846                            break;
847    
848                          // check if enough data in queue                  case SCE_IPU_BDEC:
849                          if (ipuVDEC(val)) return;                          g_BP.Advance(val & 0x3F);
850                            ipuBDEC(val);
851                            ipuRegs.SetTopBusy();
852                            break;
853    
854                          ipuRegs.cmd.BUSY = 0x80000000;                  case SCE_IPU_VDEC:
855                          ipuRegs.topbusy = 0x80000000;                          g_BP.Advance(val & 0x3F);
856                            ipuRegs.SetDataBusy();
857                          break;                          break;
858    
859                  case SCE_IPU_FDEC:                  case SCE_IPU_FDEC:
860                          IPU_LOG("FDEC command. Skip 0x%X bits, FIFO 0x%X qwords, BP 0x%X, CHCR 0x%x",                          IPU_LOG("FDEC command. Skip 0x%X bits, FIFO 0x%X qwords, BP 0x%X, CHCR 0x%x",
861                                  val & 0x3f, g_BP.IFC, (int)g_BP.BP, ipu1dma.chcr._u32);                                  val & 0x3f, g_BP.IFC, g_BP.BP, ipu1dma.chcr._u32);
862    
863                          g_BP.Advance(val & 0x3F);                          g_BP.Advance(val & 0x3F);
864                            ipuRegs.SetDataBusy();
                         if (ipuFDEC(val)) return;  
                         ipuRegs.cmd.BUSY = 0x80000000;  
                         ipuRegs.topbusy = 0x80000000;  
865                          break;                          break;
866    
                 case SCE_IPU_SETTH:  
                         ipuSETTH(val);  
                         hwIntcIrq(INTC_IPU);  
                         return;  
   
867                  case SCE_IPU_SETIQ:                  case SCE_IPU_SETIQ:
868                          IPU_LOG("SETIQ command.");                          IPU_LOG("SETIQ command.");
                         if (val & 0x3f) IPU_LOG("Skip %d bits.", val & 0x3f);  
869                          g_BP.Advance(val & 0x3F);                          g_BP.Advance(val & 0x3F);
                         if (ipuSETIQ(val)) return;  
870                          break;                          break;
871    
872                  case SCE_IPU_SETVQ:                  case SCE_IPU_SETVQ:
                         if (ipuSETVQ(val)) return;  
873                          break;                          break;
874    
875                  case SCE_IPU_CSC:                  case SCE_IPU_CSC:
                         ipu_cmd.pos[1] = 0;  
                         ipu_cmd.index = 0;  
   
                         if (ipuCSC(val))  
                         {  
                                 IPU_INT0_FROM();  
                                 return;  
                         }  
876                          break;                          break;
877    
878                  case SCE_IPU_PACK:                  case SCE_IPU_PACK:
                         ipu_cmd.pos[1] = 0;  
                         ipu_cmd.index = 0;  
                         if (ipuPACK(val)) return;  
879                          break;                          break;
880    
881                  case SCE_IPU_IDEC:                  jNO_DEFAULT;
                         if (ipuIDEC(val, false))  
                         {  
                                 // idec done, ipu0 done too  
                                 IPU_INT0_FROM();  
                                 return;  
882                          }                          }
883    
                         ipuRegs.topbusy = 0x80000000;  
                         break;  
   
                 case SCE_IPU_BDEC:  
                         if (ipuBDEC(val, false))  
                         {  
                                 IPU_INT0_FROM();  
                                 if (ipuRegs.ctrl.SCD || ipuRegs.ctrl.ECD) hwIntcIrq(INTC_IPU);  
                                 return;  
                         }  
                         else  
                         {  
                                 ipuRegs.topbusy = 0x80000000;  
                         }  
                         break;  
         }  
   
         // have to resort to the thread  
884          ipuRegs.ctrl.BUSY = 1;          ipuRegs.ctrl.BUSY = 1;
885          if(ipu1dma.chcr.STR == false) hwIntcIrq(INTC_IPU);  
886            //if(!ipu1dma.chcr.STR) hwIntcIrq(INTC_IPU);
887  }  }
888    
889  void IPUWorker()  __noinline void IPUWorker()
890  {  {
891          pxAssert(ipuRegs.ctrl.BUSY);          pxAssert(ipuRegs.ctrl.BUSY);
892    
893          switch (ipu_cmd.CMD)          switch (ipu_cmd.CMD)
894          {          {
895                  case SCE_IPU_VDEC:                  // These are unreachable (BUSY will always be 0 for them)
896                          if (!ipuVDEC(ipu_cmd.current))                  //case SCE_IPU_BCLR:
897                          {                  //case SCE_IPU_SETTH:
898                                  if(ipu1dma.chcr.STR == false) hwIntcIrq(INTC_IPU);                          //break;
899                                  return;  
900                          }                  case SCE_IPU_IDEC:
901                            if (!mpeg2sliceIDEC()) return;
902    
903                            //ipuRegs.ctrl.OFC = 0;
904                            ipuRegs.topbusy = 0;
905                          ipuRegs.cmd.BUSY = 0;                          ipuRegs.cmd.BUSY = 0;
906    
907                            // CHECK!: IPU0dma remains when IDEC is done, so we need to clear it
908                            // Check Mana Khemia 1 "off campus" to trigger a GUST IDEC messup.
909                            // This hackfixes it :/
910                            if (ipu0dma.qwc > 0 && ipu0dma.chcr.STR) ipu0Interrupt();
911                            break;
912    
913                    case SCE_IPU_BDEC:
914                            if (!mpeg2_slice()) return;
915    
916                          ipuRegs.topbusy = 0;                          ipuRegs.topbusy = 0;
917                            ipuRegs.cmd.BUSY = 0;
918    
919                            //if (ipuRegs.ctrl.SCD || ipuRegs.ctrl.ECD) hwIntcIrq(INTC_IPU);
920                          break;                          break;
921    
922                  case SCE_IPU_FDEC:                  case SCE_IPU_VDEC:
923                          if (!ipuFDEC(ipu_cmd.current))                          if (!ipuVDEC(ipu_cmd.current)) return;
924                          {  
925                                  if(ipu1dma.chcr.STR == false) hwIntcIrq(INTC_IPU);                          ipuRegs.topbusy = 0;
                                 return;  
                         }  
926                          ipuRegs.cmd.BUSY = 0;                          ipuRegs.cmd.BUSY = 0;
927                            break;
928    
929                    case SCE_IPU_FDEC:
930                            if (!ipuFDEC(ipu_cmd.current)) return;
931    
932                          ipuRegs.topbusy = 0;                          ipuRegs.topbusy = 0;
933                            ipuRegs.cmd.BUSY = 0;
934                          break;                          break;
935    
936                  case SCE_IPU_SETIQ:                  case SCE_IPU_SETIQ:
937                          if (!ipuSETIQ(ipu_cmd.current))                          if (!ipuSETIQ(ipu_cmd.current)) return;
                         {  
                                 if(ipu1dma.chcr.STR == false) hwIntcIrq(INTC_IPU);  
                                 return;  
                         }  
938                          break;                          break;
939    
940                  case SCE_IPU_SETVQ:                  case SCE_IPU_SETVQ:
941                          if (!ipuSETVQ(ipu_cmd.current))                          if (!ipuSETVQ(ipu_cmd.current)) return;
                         {  
                                 if(ipu1dma.chcr.STR == false) hwIntcIrq(INTC_IPU);  
                                 return;  
                         }  
942                          break;                          break;
943    
944                  case SCE_IPU_CSC:                  case SCE_IPU_CSC:
945                          if (!ipuCSC(ipu_cmd.current))                          if (!ipuCSC(ipu_cmd.current)) return;
                         {  
                                 if(ipu1dma.chcr.STR == false) hwIntcIrq(INTC_IPU);  
                                 return;  
                         }  
                         IPU_INT0_FROM();  
946                          break;                          break;
947    
948                  case SCE_IPU_PACK:                  case SCE_IPU_PACK:
949                          if (!ipuPACK(ipu_cmd.current))                          if (!ipuPACK(ipu_cmd.current)) return;
                         {  
                                 if(ipu1dma.chcr.STR == false) hwIntcIrq(INTC_IPU);  
                                 return;  
                         }  
                         break;  
   
                 case SCE_IPU_IDEC:  
                         if (!ipuIDEC(ipu_cmd.current, true))  
                         {  
                                 if(ipu1dma.chcr.STR == false) hwIntcIrq(INTC_IPU);  
                                 return;  
                         }  
   
                         ipuRegs.ctrl.OFC = 0;  
                         ipuRegs.ctrl.BUSY = 0;  
                         ipuRegs.topbusy = 0;  
                         ipuRegs.cmd.BUSY = 0;  
                         ipu_cmd.current = 0xffffffff;  
   
                         // CHECK!: IPU0dma remains when IDEC is done, so we need to clear it  
                         IPU_INT0_FROM();  
950                          break;                          break;
951    
952                  case SCE_IPU_BDEC:                  jNO_DEFAULT
                         if (!ipuBDEC(ipu_cmd.current, true))  
                         {  
                                 if(ipu1dma.chcr.STR == false) hwIntcIrq(INTC_IPU);  
                                 return;  
953                          }                          }
954    
                         ipuRegs.ctrl.BUSY = 0;  
                         ipuRegs.topbusy = 0;  
                         ipuRegs.cmd.BUSY = 0;  
                         ipu_cmd.current = 0xffffffff;  
   
                         IPU_INT0_FROM();  
                         if (ipuRegs.ctrl.SCD || ipuRegs.ctrl.ECD) hwIntcIrq(INTC_IPU);  
                         return;  
   
                 default:  
                         Console.WriteLn("Unknown IPU command: %08x", ipu_cmd.current);  
                         break;  
         }  
   
955          // success          // success
956          ipuRegs.ctrl.BUSY = 0;          ipuRegs.ctrl.BUSY = 0;
957          ipu_cmd.current = 0xffffffff;          ipu_cmd.current = 0xffffffff;
958            hwIntcIrq(INTC_IPU);
959  }  }

Legend:
Removed from v.191  
changed lines
  Added in v.273

  ViewVC Help
Powered by ViewVC 1.1.22