diff options
Diffstat (limited to 'src/DMA.cpp')
| -rw-r--r-- | src/DMA.cpp | 72 | 
1 files changed, 47 insertions, 25 deletions
diff --git a/src/DMA.cpp b/src/DMA.cpp index 9edbf4b..2f6674d 100644 --- a/src/DMA.cpp +++ b/src/DMA.cpp @@ -100,7 +100,7 @@ void DMA::DoSavestate(Savestate* file)      file->Var32(&SrcAddrInc);      file->Var32(&DstAddrInc); -    file->Var32((u32*)&Running); +    file->Var32(&Running);      file->Var32((u32*)&InProgress);      file->Var32((u32*)&IsGXFIFODMA);  } @@ -170,36 +170,45 @@ void DMA::Start()      if ((Cnt & 0x00600000) == 0x00600000)          CurDstAddr = DstAddr; - -    //printf("ARM%d DMA%d %08X %02X %08X->%08X %d bytes %dbit\n", CPU?7:9, Num, Cnt, StartMode, CurSrcAddr, CurDstAddr, RemCount*((Cnt&0x04000000)?4:2), (Cnt&0x04000000)?32:16); +if(CPU==0&&StartMode!=7&&false) +    printf("ARM%d DMA%d %08X %02X %08X->%08X %d bytes %dbit\n", CPU?7:9, Num, Cnt, StartMode, CurSrcAddr, CurDstAddr, RemCount*((Cnt&0x04000000)?4:2), (Cnt&0x04000000)?32:16);      IsGXFIFODMA = (CPU == 0 && (CurSrcAddr>>24) == 0x02 && CurDstAddr == 0x04000400 && DstAddrInc == 0);      // TODO eventually: not stop if we're running code in ITCM -    Running = true; +    if (NDS::DMAsRunning(CPU)) +        Running = 1; +    else +        Running = 2; +      InProgress = true;      NDS::StopCPU(CPU, 1<<Num);  } - +extern u64 arm9total, arm7total;  s32 DMA::Run(s32 cycles)  {      if (!Running)          return cycles; - +s32 startc = cycles;      Executing = true;      // add NS penalty for first accesses in burst -    bool burststart; -    if (StartMode == 0x07 && RemCount > 112) -        burststart = (IterCount == 112); -    else -        burststart = (IterCount == RemCount); +    // note: this seems to only apply when starting DMA 'in the void' +    // for example, the aging cart DMA PRIORITY test: +    // starts a big DMA immediately, and a small DMA upon HBlank +    // each pulling from a timer incrementing once per cycle +    // it expects that the values be increasing linearly (2c/unit) +    // even as the small DMA starts and ends +    bool burststart = (Running == 2); +    Running = 1; + +    s32 unitcycles; +    s32 lastcycles = cycles;      if (!(Cnt & 0x04000000))      { -        int unitcycles; -        if (Num == 0) +        if (CPU == 0)          {              if ((CurSrcAddr >> 24) == 0x02 && (CurDstAddr >> 24) == 0x02)              { @@ -213,6 +222,7 @@ s32 DMA::Run(s32 cycles)                  if (burststart)                  { +                    cycles -= 2;                      cycles -= (NDS::ARM9MemTimings[CurSrcAddr >> 14][0] + NDS::ARM9MemTimings[CurDstAddr >> 14][0]);                      cycles += unitcycles;                  } @@ -232,6 +242,7 @@ s32 DMA::Run(s32 cycles)                  if (burststart)                  { +                    cycles -= 2;                      cycles -= (NDS::ARM7MemTimings[CurSrcAddr >> 15][0] + NDS::ARM7MemTimings[CurDstAddr >> 15][0]);                      cycles += unitcycles;                  } @@ -243,21 +254,25 @@ s32 DMA::Run(s32 cycles)          while (IterCount > 0 && !Stall)          { +            cycles -= unitcycles; + +            NDS::RunTightTimers(CPU, lastcycles-cycles); +//if(CPU){arm7timer+=(lastcycles-cycles);}else{arm9timer+=(lastcycles-cycles);} +            lastcycles = cycles; +              writefn(CurDstAddr, readfn(CurSrcAddr)); -            cycles -= unitcycles;              CurSrcAddr += SrcAddrInc<<1;              CurDstAddr += DstAddrInc<<1;              IterCount--;              RemCount--; -            if (cycles < 0) break; +            if (cycles <= 0) break;          }      }      else      { -        int unitcycles; -        if (Num == 0) +        if (CPU == 0)          {              if ((CurSrcAddr >> 24) == 0x02 && (CurDstAddr >> 24) == 0x02)              { @@ -273,6 +288,7 @@ s32 DMA::Run(s32 cycles)                  if (burststart)                  { +                    cycles -= 2;                      cycles -= (NDS::ARM9MemTimings[CurSrcAddr >> 14][2] + NDS::ARM9MemTimings[CurDstAddr >> 14][2]);                      cycles += unitcycles;                  } @@ -294,6 +310,7 @@ s32 DMA::Run(s32 cycles)                  if (burststart)                  { +                    cycles -= 2;                      cycles -= (NDS::ARM7MemTimings[CurSrcAddr >> 15][2] + NDS::ARM7MemTimings[CurDstAddr >> 15][2]);                      cycles += unitcycles;                  } @@ -305,32 +322,37 @@ s32 DMA::Run(s32 cycles)          while (IterCount > 0 && !Stall)          { +            cycles -= unitcycles; + +            NDS::RunTightTimers(CPU, lastcycles-cycles); +//if(CPU){arm7timer+=(lastcycles-cycles);}else{arm9timer+=(lastcycles-cycles);} +            lastcycles = cycles; +              writefn(CurDstAddr, readfn(CurSrcAddr)); -            cycles -= unitcycles;              CurSrcAddr += SrcAddrInc<<2;              CurDstAddr += DstAddrInc<<2;              IterCount--;              RemCount--; -            if (cycles < 0) break; +            if (cycles <= 0) break;          }      }      Executing = false;      Stall = false; - +//if (CPU) printf("ran DMA for %d cycles (asked %d)\n", startc-cycles, startc);      if (RemCount)      {          if (IterCount == 0)          { -            Running = false; +            Running = 0;              NDS::ResumeCPU(CPU, 1<<Num);              if (StartMode == 0x07)                  GPU3D::CheckFIFODMA();          } - +if(CPU){arm7total+=(startc-cycles);}else{arm9total+=(startc-cycles);}          return cycles;      } @@ -340,9 +362,9 @@ s32 DMA::Run(s32 cycles)      if (Cnt & 0x40000000)          NDS::SetIRQ(CPU, NDS::IRQ_DMA0 + Num); -    Running = false; +    Running = 0;      InProgress = false;      NDS::ResumeCPU(CPU, 1<<Num); - -    return cycles - 2; +if(CPU){arm7total+=(startc-(cycles));}else{arm9total+=(startc-(cycles));} +    return cycles;  }  |