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

Diff of /trunk/pcsx2/Sif1.cpp

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

revision 31 by william, Tue Sep 7 03:24:11 2010 UTC revision 62 by william, Tue Sep 7 11:08:22 2010 UTC
# Line 24  _sif sif1; Line 24  _sif sif1;
24    
25  static bool done = false;  static bool done = false;
26    
27  static __forceinline void Sif1Init()  static __fi void Sif1Init()
28  {  {
29          SIF_LOG("SIF1 DMA start...");          SIF_LOG("SIF1 DMA start...");
30          done = false;          done = false;
# Line 33  static __forceinline void Sif1Init() Line 33  static __forceinline void Sif1Init()
33  }  }
34    
35  // Write from the EE to Fifo.  // Write from the EE to Fifo.
36  static __forceinline bool WriteEEtoFifo()  static __fi bool WriteEEtoFifo()
37  {  {
38          // There's some data ready to transfer into the fifo..          // There's some data ready to transfer into the fifo..
39    
40          SIF_LOG("Sif 1: Write EE to Fifo");          SIF_LOG("Sif 1: Write EE to Fifo");
41          const int writeSize = min((s32)sif1dma->qwc, sif1.fifo.free() >> 2);          const int writeSize = min((s32)sif1dma.qwc, sif1.fifo.free() >> 2);
42    
43          tDMA_TAG *ptag;          tDMA_TAG *ptag;
44    
45          ptag = sif1dma->getAddr(sif1dma->madr, DMAC_SIF1, false);          ptag = sif1dma.getAddr(sif1dma.madr, DMAC_SIF1, false);
46          if (ptag == NULL)          if (ptag == NULL)
47          {          {
48                  DevCon.Warning("Write EE to Fifo: ptag == NULL");                  DevCon.Warning("Write EE to Fifo: ptag == NULL");
# Line 51  static __forceinline bool WriteEEtoFifo( Line 51  static __forceinline bool WriteEEtoFifo(
51    
52          sif1.fifo.write((u32*)ptag, writeSize << 2);          sif1.fifo.write((u32*)ptag, writeSize << 2);
53    
54          sif1dma->madr += writeSize << 4;          sif1dma.madr += writeSize << 4;
55          sif1.ee.cycles += writeSize;            // fixme : BIAS is factored in above          sif1.ee.cycles += writeSize;            // fixme : BIAS is factored in above
56          sif1dma->qwc -= writeSize;          sif1dma.qwc -= writeSize;
57    
58          return true;          return true;
59  }  }
60    
61  // Read from the fifo and write to IOP  // Read from the fifo and write to IOP
62  static __forceinline bool WriteFifoToIOP()  static __fi bool WriteFifoToIOP()
63  {  {
64          // If we're reading something, continue to do so.          // If we're reading something, continue to do so.
65    
# Line 78  static __forceinline bool WriteFifoToIOP Line 78  static __forceinline bool WriteFifoToIOP
78  }  }
79    
80  // Get a tag and process it.  // Get a tag and process it.
81  static __forceinline bool ProcessEETag()  static __fi bool ProcessEETag()
82  {  {
83          // Chain mode          // Chain mode
84          tDMA_TAG *ptag;          tDMA_TAG *ptag;
85          SIF_LOG("Sif1: ProcessEETag");          SIF_LOG("Sif1: ProcessEETag");
86    
87          // Process DMA tag at sif1dma->tadr          // Process DMA tag at sif1dma.tadr
88          ptag = sif1dma->DMAtransfer(sif1dma->tadr, DMAC_SIF1);          ptag = sif1dma.DMAtransfer(sif1dma.tadr, DMAC_SIF1);
89          if (ptag == NULL)          if (ptag == NULL)
90          {          {
91                  Console.WriteLn("Sif1 ProcessEETag: ptag = NULL");                  Console.WriteLn("Sif1 ProcessEETag: ptag = NULL");
92                  return false;                  return false;
93          }          }
94    
95          if (sif1dma->chcr.TTE)          if (sif1dma.chcr.TTE)
96          {          {
97                  Console.WriteLn("SIF1 TTE");                  Console.WriteLn("SIF1 TTE");
98                  sif1.fifo.write((u32*)ptag + 2, 2);                  sif1.fifo.write((u32*)ptag + 2, 2);
99          }          }
100    
101          if (sif1dma->chcr.TIE && ptag->IRQ)          if (sif1dma.chcr.TIE && ptag->IRQ)
102          {          {
103                  Console.WriteLn("SIF1 TIE");                  Console.WriteLn("SIF1 TIE");
104                  sif1.ee.end = true;                  sif1.ee.end = true;
# Line 109  static __forceinline bool ProcessEETag() Line 109  static __forceinline bool ProcessEETag()
109          {          {
110                  case TAG_REFE:                  case TAG_REFE:
111                          sif1.ee.end = true;                          sif1.ee.end = true;
112                          sif1dma->madr = ptag[1]._u32;                          sif1dma.madr = ptag[1]._u32;
113                          sif1dma->tadr += 16;                          sif1dma.tadr += 16;
114                          break;                          break;
115    
116                  case TAG_CNT:                  case TAG_CNT:
117                          sif1dma->madr = sif1dma->tadr + 16;                          sif1dma.madr = sif1dma.tadr + 16;
118                          sif1dma->tadr = sif1dma->madr + (sif1dma->qwc << 4);                          sif1dma.tadr = sif1dma.madr + (sif1dma.qwc << 4);
119                          break;                          break;
120    
121                  case TAG_NEXT:                  case TAG_NEXT:
122                          sif1dma->madr = sif1dma->tadr + 16;                          sif1dma.madr = sif1dma.tadr + 16;
123                          sif1dma->tadr = ptag[1]._u32;                          sif1dma.tadr = ptag[1]._u32;
124                          break;                          break;
125    
126                  case TAG_REF:                  case TAG_REF:
127                  case TAG_REFS:                  case TAG_REFS:
128                          sif1dma->madr = ptag[1]._u32;                          sif1dma.madr = ptag[1]._u32;
129                          sif1dma->tadr += 16;                          sif1dma.tadr += 16;
130                          break;                          break;
131    
132                  case TAG_END:                  case TAG_END:
133                          sif1.ee.end = true;                          sif1.ee.end = true;
134                          sif1dma->madr = sif1dma->tadr + 16;                          sif1dma.madr = sif1dma.tadr + 16;
135                          sif1dma->tadr = sif1dma->madr + (sif1dma->qwc << 4);                          sif1dma.tadr = sif1dma.madr + (sif1dma.qwc << 4);
136                          break;                          break;
137    
138                  default:                  default:
# Line 142  static __forceinline bool ProcessEETag() Line 142  static __forceinline bool ProcessEETag()
142  }  }
143    
144  // Write fifo to data, and put it in IOP.  // Write fifo to data, and put it in IOP.
145  static __forceinline bool SIFIOPReadTag()  static __fi bool SIFIOPReadTag()
146  {  {
147          // Read a tag.          // Read a tag.
148          sif1.fifo.read((u32*)&sif1.iop.data, 4);          sif1.fifo.read((u32*)&sif1.iop.data, 4);
# Line 160  static __forceinline bool SIFIOPReadTag( Line 160  static __forceinline bool SIFIOPReadTag(
160  }  }
161    
162  // Stop processing EE, and signal an interrupt.  // Stop processing EE, and signal an interrupt.
163  static __forceinline void EndEE()  static __fi void EndEE()
164  {  {
165          sif1.ee.end = false;          sif1.ee.end = false;
166          sif1.ee.busy = false;          sif1.ee.busy = false;
# Line 176  static __forceinline void EndEE() Line 176  static __forceinline void EndEE()
176          }          }
177    
178    
179          CPU_INT(DMAC_SIF1, min((int)(sif1.ee.cycles*BIAS), 384));          CPU_INT(DMAC_SIF1, /*min((int)(*/sif1.ee.cycles*BIAS/*), 384)*/);
180  }  }
181    
182  // Stop processing IOP, and signal an interrupt.  // Stop processing IOP, and signal an interrupt.
183  static __forceinline void EndIOP()  static __fi void EndIOP()
184  {  {
185          sif1data = 0;          sif1data = 0;
186          sif1.iop.end = false;          sif1.iop.end = false;
# Line 197  static __forceinline void EndIOP() Line 197  static __forceinline void EndIOP()
197                  sif1.iop.cycles = 1;                  sif1.iop.cycles = 1;
198          }          }
199          // iop is 1/8th the clock rate of the EE and psxcycles is in words (not quadwords)          // iop is 1/8th the clock rate of the EE and psxcycles is in words (not quadwords)
200          PSX_INT(IopEvt_SIF1, min((sif1.iop.cycles * 26), 1024));          PSX_INT(IopEvt_SIF1, /*min((*/sif1.iop.cycles/* * 26*//*), 1024)*/);
201  }  }
202    
203  // Handle the EE transfer.  // Handle the EE transfer.
204  static __forceinline void HandleEETransfer()  static __fi void HandleEETransfer()
205  {  {
206          if(sif1dma->chcr.STR == false)          if(sif1dma.chcr.STR == false)
207          {          {
208                  DevCon.Warning("Replacement for irq prevention hack EE SIF1");                  DevCon.Warning("Replacement for irq prevention hack EE SIF1");
209                  sif1.ee.end = false;                  sif1.ee.end = false;
210                  sif1.ee.busy = false;                  sif1.ee.busy = false;
211                  return;                  return;
212          }          }
213          if (dmacRegs->ctrl.STD == STD_SIF1)          if (dmacRegs.ctrl.STD == STD_SIF1)
214          {          {
215                  DevCon.Warning("SIF1 stall control"); // STD == fromSIF1                  DevCon.Warning("SIF1 stall control"); // STD == fromSIF1
216          }          }
217    
218          /*if (sif1dma->qwc == 0)          /*if (sif1dma.qwc == 0)
219                  if (sif1dma->chcr.MOD == NORMAL_MODE)                  if (sif1dma.chcr.MOD == NORMAL_MODE)
220                          if (!sif1.ee.end){                          if (!sif1.ee.end){
221                                  DevCon.Warning("sif1 irq prevented CHCR %x QWC %x", sif1dma->chcr, sif1dma->qwc);                                  DevCon.Warning("sif1 irq prevented CHCR %x QWC %x", sif1dma.chcr, sif1dma.qwc);
222                                  done = true;                                  done = true;
223                                  return;                                  return;
224                          }*/                          }*/
225    
226          // If there's no more to transfer.          // If there's no more to transfer.
227          if (sif1dma->qwc <= 0)          if (sif1dma.qwc <= 0)
228          {          {
229                  // If NORMAL mode or end of CHAIN then stop DMA.                  // If NORMAL mode or end of CHAIN then stop DMA.
230                  if ((sif1dma->chcr.MOD == NORMAL_MODE) || sif1.ee.end)                  if ((sif1dma.chcr.MOD == NORMAL_MODE) || sif1.ee.end)
231                  {                  {
232                          done = true;                          done = true;
233                          EndEE();                          EndEE();
# Line 248  static __forceinline void HandleEETransf Line 248  static __forceinline void HandleEETransf
248  }  }
249    
250  // Handle the IOP transfer.  // Handle the IOP transfer.
251  static __forceinline void HandleIOPTransfer()  static __fi void HandleIOPTransfer()
252  {  {
253          if (sif1.iop.counter > 0)          if (sif1.iop.counter > 0)
254          {          {
# Line 274  static __forceinline void HandleIOPTrans Line 274  static __forceinline void HandleIOPTrans
274          }          }
275  }  }
276    
277  static __forceinline void Sif1End()  static __fi void Sif1End()
278  {  {
279          SIF_LOG("SIF1 DMA end...");          SIF_LOG("SIF1 DMA end...");
280  }  }
281    
282  // Transfer EE to IOP, putting data in the fifo as an intermediate step.  // Transfer EE to IOP, putting data in the fifo as an intermediate step.
283  __forceinline void SIF1Dma()  __fi void SIF1Dma()
284  {  {
285          int BusyCheck = 0;          int BusyCheck = 0;
286          Sif1Init();          Sif1Init();
# Line 292  __forceinline void SIF1Dma() Line 292  __forceinline void SIF1Dma()
292    
293                  if (sif1.ee.busy)                  if (sif1.ee.busy)
294                  {                  {
295                          if(sif1.fifo.free() > 0) BusyCheck++;                          if(sif1.fifo.free() > 0 || (sif1.ee.end == true && sif1dma.qwc == 0))
296                          HandleEETransfer();                          {
297                                    BusyCheck++;
298                                    HandleEETransfer();
299                            }
300                  }                  }
301    
302                  if (sif1.iop.busy)                  if (sif1.iop.busy)
303                  {                  {
304                          if(sif1.fifo.size >= 4) BusyCheck++;                          if(sif1.fifo.size >= 4 || (sif1.iop.end == true && sif1.iop.counter == 0))
305                          HandleIOPTransfer();                          {
306                                    BusyCheck++;
307                                    HandleIOPTransfer();
308                            }
309                  }                  }
310    
311          } while (!done && BusyCheck > 0);          } while (/*!done &&*/ BusyCheck > 0);
312    
313          Sif1End();          Sif1End();
314  }  }
315    
316  __forceinline void  sif1Interrupt()  __fi void  sif1Interrupt()
317  {  {
318          HW_DMA10_CHCR &= ~0x01000000; //reset TR flag          HW_DMA10_CHCR &= ~0x01000000; //reset TR flag
319          psxDmaInterrupt2(3);          psxDmaInterrupt2(3);
320  }  }
321    
322  __forceinline void  EEsif1Interrupt()  __fi void  EEsif1Interrupt()
323  {  {
324          hwDmacIrq(DMAC_SIF1);          hwDmacIrq(DMAC_SIF1);
325          sif1dma->chcr.STR = false;          sif1dma.chcr.STR = false;
326  }  }
327    
328  // Do almost exactly the same thing as psxDma10 in IopDma.cpp.  // Do almost exactly the same thing as psxDma10 in IopDma.cpp.
329  // Main difference is this checks for iop, where psxDma10 checks for ee.  // Main difference is this checks for iop, where psxDma10 checks for ee.
330  __forceinline void dmaSIF1()  __fi void dmaSIF1()
331  {  {
332          SIF_LOG(wxString(L"dmaSIF1" + sif1dma->cmqt_to_str()).To8BitData());          SIF_LOG(wxString(L"dmaSIF1" + sif1dma.cmqt_to_str()).To8BitData());
333    
334          if (sif1.fifo.readPos != sif1.fifo.writePos)          if (sif1.fifo.readPos != sif1.fifo.writePos)
335          {          {
336                  SIF_LOG("warning, sif1.fifoReadPos != sif1.fifoWritePos");                  SIF_LOG("warning, sif1.fifoReadPos != sif1.fifoWritePos");
337          }          }
338    
339          if(sif1dma->chcr.MOD == CHAIN_MODE && sif1dma->qwc > 0) DevCon.Warning(L"SIF1 QWC on Chain CHCR " + sif1dma->chcr.desc());          //if(sif1dma.chcr.MOD == CHAIN_MODE && sif1dma.qwc > 0) DevCon.Warning(L"SIF1 QWC on Chain CHCR " + sif1dma.chcr.desc());
340    
341          psHu32(SBUS_F240) |= 0x4000;          psHu32(SBUS_F240) |= 0x4000;
342          sif1.ee.busy = true;          sif1.ee.busy = true;
343    
344            // Okay, this here is needed currently (r3644).
345            // FFX battles in the thunder plains map die otherwise, Phantasy Star 4 as well
346            // These 2 games could be made playable again by increasing the time the EE or the IOP run,
347            // showing that this is very timing sensible.
348            // Doing this DMA unfortunately brings back an old warning in Legend of Legaia though, but it still works.
349          if (sif1.iop.busy)          if (sif1.iop.busy)
350          {          {
         XMMRegisters::Freeze();  
351                  SIF1Dma();                  SIF1Dma();
352                  psHu32(SBUS_F240) &= ~0x40;                  // Do we really want to mess with the SIF flags like that? Nah.
353                  psHu32(SBUS_F240) &= ~0x100;                  //psHu32(SBUS_F240) &= ~0x40;
354                  psHu32(SBUS_F240) &= ~0x4000;                  //psHu32(SBUS_F240) &= ~0x100;
355          XMMRegisters::Thaw();                  //psHu32(SBUS_F240) &= ~0x4000;
356          }          }
357  }  }

Legend:
Removed from v.31  
changed lines
  Added in v.62

  ViewVC Help
Powered by ViewVC 1.1.22