示例#1
0
static INLINE void ChRW(int32 timestamp, uint32 *V)
{
 switch(ch)
 {
  default:
	abort();

  case CH_MDEC_IN:
	  MDEC_DMAWrite(*V);
	  break;

  case CH_MDEC_OUT:
	  *V = MDEC_DMARead();
	  break;

  case CH_GPU:
	  if(write_mode)
	   GPU->WriteDMA(*V);
	  else
	   *V = GPU->Read(timestamp, 0);
	  break;

  case CH_CDC:
	  // 0x1f801018 affects CDC DMA timing.
#if 0
	  if(DMACH[ch].ChanControl & 0x100)		// For CDC DMA(at least): When this bit is set, DMA controller doesn't appear to hog the (RAM?) bus.
	  {
	   if(DMACH[ch].ChanControl & 0x00400000)	// For CDC DMA(at least): When this bit is set, DMA controller appears to get even less bus time(or has a lower priority??)
	   {
	    DMACH[ch].ClockCounter -= 44 * 20 / 12;
	   }
	   else
	   {
	    DMACH[ch].ClockCounter -= 29 * 20 / 12;
	   }
	  }
	  else
	  {
	   DMACH[ch].ClockCounter -= 23 * 20 / 12; // (23 + 1) = 24.  (Though closer to 24.5 or 24.4 on average per tests on a PS1)
	  }
#endif
	  *V = CDC->DMARead();
	  break;

  case CH_SPU:
	  // 0x1f801014 affects SPU DMA timing.
	  // Wild conjecture about 0x1f801014:
	  //
	  //  & 0x0000000F
	  //  & 0x000001E0  --- Used if (& 0x20000000) == 0?
	  //  & 0x00001000  --- Double total bus cycle time if value == 0?
	  //  & 0x0f000000  --- (value << 1) 33MHz cycles, bus cycle extension(added to 4?)?
	  //  & 0x20000000  --- 
	  //
	  //
	  // TODO?: SPU DMA will "complete" much faster if there's a mismatch between the CHCR read/write mode bit and the SPU control register DMA mode.
	  //
	  //
	  // Investigate: SPU DMA doesn't seem to work right if the value written to 0x1F801DAA doesn't have the upper bit set to 1(0x8000) on a PS1.

	  DMACH[ch].ClockCounter -= 47; // Should be closer to 69, average, but actual timing is...complicated.
	  if(write_mode)
	   SPU->WriteDMA(*V);
	  else
	   *V = SPU->ReadDMA();
	  break;

  case CH_OT:
	  if(DMACH[ch].WordCounter == 1)
	   *V = 0xFFFFFF;
	  else
	   *V = (DMACH[ch].CurAddr - 4) & 0x1FFFFF;
	  break;
 }
}
示例#2
0
static INLINE void ChRW(const unsigned ch, const uint32_t CRModeCache, uint32_t *V)
{
   unsigned extra_cyc_overhead = 0;

   switch(ch)
   {
      default:
         abort();
         break;

      case CH_MDEC_IN:
         if(CRModeCache & 0x1)
            MDEC_DMAWrite(*V);
         else
            *V = 0;
         break;

      case CH_MDEC_OUT:
         if(CRModeCache & 0x1)
         {
         }
         else
            *V = MDEC_DMARead();
         break;

      case CH_GPU:
         if(CRModeCache & 0x1)
            GPU->WriteDMA(*V);
         else
            *V = GPU->ReadDMA();
         break;

      case CH_CDC:
         // 0x1f801018 affects CDC DMA timing.
#if 0
         if(CRModeCache & 0x100)		// For CDC DMA(at least): When this bit is set, DMA controller doesn't appear to hog the (RAM?) bus.
         {
            if(CRModeCache & 0x00400000)	// For CDC DMA(at least): When this bit is set, DMA controller appears to get even less bus time(or has a lower priority??)
            {
               DMACH[ch].ClockCounter -= 44 * 20 / 12;
            }
            else
            {
               DMACH[ch].ClockCounter -= 29 * 20 / 12;
            }
         }
         else
         {
            DMACH[ch].ClockCounter -= 23 * 20 / 12; // (23 + 1) = 24.  (Though closer to 24.5 or 24.4 on average per tests on a PS1)
         }
#endif
         if(CRModeCache & 0x1)
         {
         }
         else
         {
            extra_cyc_overhead = 8;	// FIXME: Test.
            *V = CDC->DMARead();		// Note: Legend of Mana's opening movie is sensitive to DMA timing, including CDC.
         }
         break;

      case CH_SPU:
         // 0x1f801014 affects SPU DMA timing.
         // Wild conjecture about 0x1f801014:
         //
         //  & 0x0000000F
         //  & 0x000001E0  --- Used if (& 0x20000000) == 0?
         //  & 0x00001000  --- Double total bus cycle time if value == 0?
         //  & 0x0f000000  --- (value << 1) 33MHz cycles, bus cycle extension(added to 4?)?
         //  & 0x20000000  --- 
         //
         //
         // TODO?: SPU DMA will "complete" much faster if there's a mismatch between the CHCR read/write mode bit and the SPU control register DMA mode.
         //
         //
         // Investigate: SPU DMA doesn't seem to work right if the value written to 0x1F801DAA doesn't have the upper bit set to 1(0x8000) on a PS1.

         extra_cyc_overhead = 47;	// Should be closer to 69, average, but actual timing is...complicated.

         if(CRModeCache & 0x1)
            SPU->WriteDMA(*V);
         else
            *V = SPU->ReadDMA();
         break;

      case CH_FIVE:
         if(CRModeCache & 0x1)
         {
         }
         else
         {
            *V = 0;
         }
         break;

      case CH_OT:
         if(DMACH[ch].WordCounter == 1)
            *V = 0xFFFFFF;
         else
            *V = (DMACH[ch].CurAddr - 4) & 0x1FFFFF;
         break;
   }

   // GROSS APPROXIMATION, shoehorning multiple effects together, TODO separate(especially SPU and CDC)
   DMACH[ch].ClockCounter -= std::max<int>(extra_cyc_overhead, (CRModeCache & 0x100) ? 7 : 0);
}