コード例 #1
0
ファイル: dma.cpp プロジェクト: CatalystG/mednafen-libretro
void DMA_Power(void)
{
 lastts = 0;

 memset(DMACH, 0, sizeof(DMACH));

 DMACycleCounter = 128;

 DMAControl = 0;
 DMAIntControl = 0;
 DMAIntStatus = 0;
 RecalcIRQOut();
}
コード例 #2
0
ファイル: dma.cpp プロジェクト: CatalystG/mednafen-libretro
static INLINE void RunChannelT(pscpu_timestamp_t timestamp, int32 clocks)
{
 //const uint32 dc = (DMAControl >> (ch * 4)) & 0xF;

 DMACH[ch].ClockCounter += clocks;

 while(DMACH[ch].ClockCounter > 0)
 {
  if(!DMACH[ch].WordCounter)
  {
   if(!(DMACH[ch].ChanControl & (1 << 24)))
   {
    break;
   }

   if(DMACH[ch].NextAddr & 0x800000)
   {
    //if(ch == 2)
    // PSX_WARNING("[DMA] LL Channel 2 ended normally: %d\n", GPU->GetScanlineNum());
    DMACH[ch].ChanControl &= ~(0x11 << 24);
    if(DMAIntControl & (1 << (16 + ch)))
    {
     DMAIntStatus |= 1 << ch;
     RecalcIRQOut();
    }
    break;
   }

   if(!ChCan<ch, write_mode>())
    break;

   if((DMACH[ch].ChanControl & (1 << 10)) && write_mode)
   {
    uint32 header;

    DMACH[ch].CurAddr = DMACH[ch].NextAddr & 0x1FFFFC;
    header = MainRAM.ReadU32(DMACH[ch].CurAddr);
    DMACH[ch].CurAddr = (DMACH[ch].CurAddr + 4) & 0x1FFFFF;

    DMACH[ch].WordCounter = header >> 24;
    DMACH[ch].NextAddr = header & 0xFFFFFF;

    /*
    if(DMACH[ch].WordCounter > 0x10) 
     printf("What the lala?  0x%02x @ 0x%08x\n", DMACH[ch].WordCounter, DMACH[ch].CurAddr - 4);
     */

    if(DMACH[ch].WordCounter)
     DMACH[ch].ClockCounter -= 15;
    else
     DMACH[ch].ClockCounter -= 10;

    continue;
   }
   else
   {
    DMACH[ch].CurAddr = DMACH[ch].NextAddr & 0x1FFFFC;
    DMACH[ch].WordCounter = DMACH[ch].BlockControl & 0xFFFF;
    DMACH[ch].BlockCounter--;

    if(!DMACH[ch].BlockCounter || ch == 6 || ch == 3)
     DMACH[ch].NextAddr = 0xFFFFFF;
    else
     DMACH[ch].NextAddr = (DMACH[ch].CurAddr + ((DMACH[ch].BlockControl & 0xFFFF) << 2)) & 0x1FFFFF;
   }
  }
コード例 #3
0
ファイル: dma.cpp プロジェクト: zeromus/octafen-psx
//
// Remember to handle an end condition on the same iteration of the while(DMACH[ch].ClockCounter > 0) loop that caused it,
// otherwise RecalcHalt() might take the CPU out of a halted state before the end-of-DMA is signaled(especially a problem considering our largeish
// DMA update timing granularity).
//
static INLINE void RunChannelI(const unsigned ch, const uint32_t CRModeCache, int32_t clocks)
{
   //const uint32_t dc = (DMAControl >> (ch * 4)) & 0xF;

   DMACH[ch].ClockCounter += clocks;

   while(MDFN_LIKELY(DMACH[ch].ClockCounter > 0))
   {
      if(DMACH[ch].WordCounter == 0)	// Begin WordCounter reload.
      {
         if(!(DMACH[ch].ChanControl & (1 << 24)))	// Needed for the forced-DMA-stop kludge(see DMA_Write()).
            break;

         if(!ChCan(ch, CRModeCache))
            break;

         DMACH[ch].CurAddr = DMACH[ch].BaseAddr;

         if(CRModeCache & (1U << 10))
         {
            uint32_t header;

            if(MDFN_UNLIKELY(DMACH[ch].CurAddr & 0x800000))
            {
               DMACH[ch].ChanControl &= ~(0x11 << 24);
               DMAIntControl |= 0x8000;
               RecalcIRQOut();
               break;
            }

            header = MainRAM.ReadU32(DMACH[ch].CurAddr & 0x1FFFFC);
            DMACH[ch].CurAddr = (DMACH[ch].CurAddr + 4) & 0xFFFFFF;

            DMACH[ch].WordCounter = header >> 24;
            DMACH[ch].BaseAddr = header & 0xFFFFFF;

            // printf to debug Soul Reaver ;)
            //if(DMACH[ch].WordCounter > 0x10) 
            // printf("What the lala?  0x%02x @ 0x%08x\n", DMACH[ch].WordCounter, DMACH[ch].CurAddr - 4);

            if(DMACH[ch].WordCounter)
               DMACH[ch].ClockCounter -= 15;
            else
               DMACH[ch].ClockCounter -= 10;

            goto SkipPayloadStuff;	// 3 cheers for gluten-free spaghetticode(necessary because the newly-loaded WordCounter might be 0, and we actually
            // want 0 to mean 0 and not 65536 in this context)!
         }
         else
         {
            DMACH[ch].WordCounter = DMACH[ch].BlockControl & 0xFFFF;

            if(CRModeCache & (1U << 9))
            {
               if(ch == 2)	// Technically should apply to all channels, but since we don't implement CPU read penalties for channels other than 2 yet, it's like this to avoid making DMA longer than what games can handle.
                  DMACH[ch].ClockCounter -= 7;

               DMACH[ch].BlockControl = (DMACH[ch].BlockControl & 0xFFFF) | ((DMACH[ch].BlockControl - (1U << 16)) & 0xFFFF0000);
            }
         }
      }	// End WordCounter reload.