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

Diff of /trunk/pcsx2/Sif0.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 sif0; Line 24  _sif sif0;
24    
25  static bool done = false;  static bool done = false;
26    
27  static __forceinline void Sif0Init()  static __fi void Sif0Init()
28  {  {
29          SIF_LOG("SIF0 DMA start...");          SIF_LOG("SIF0 DMA start...");
30          done = false;          done = false;
# Line 33  static __forceinline void Sif0Init() Line 33  static __forceinline void Sif0Init()
33  }  }
34    
35  // Write from Fifo to EE.  // Write from Fifo to EE.
36  static __forceinline bool WriteFifoToEE()  static __fi bool WriteFifoToEE()
37  {  {
38          const int readSize = min((s32)sif0dma->qwc, sif0.fifo.size >> 2);          const int readSize = min((s32)sif0dma.qwc, sif0.fifo.size >> 2);
39    
40          tDMA_TAG *ptag;          tDMA_TAG *ptag;
41    
42          //SIF_LOG(" EE SIF doing transfer %04Xqw to %08X", readSize, sif0dma->madr);          //SIF_LOG(" EE SIF doing transfer %04Xqw to %08X", readSize, sif0dma.madr);
43          SIF_LOG("Write Fifo to EE: ----------- %lX of %lX", readSize << 2, sif0dma->qwc << 2);          SIF_LOG("Write Fifo to EE: ----------- %lX of %lX", readSize << 2, sif0dma.qwc << 2);
44    
45          ptag = sif0dma->getAddr(sif0dma->madr, DMAC_SIF0, true);          ptag = sif0dma.getAddr(sif0dma.madr, DMAC_SIF0, true);
46          if (ptag == NULL)          if (ptag == NULL)
47          {          {
48                  DevCon.Warning("Write Fifo to EE: ptag == NULL");                  DevCon.Warning("Write Fifo to EE: ptag == NULL");
# Line 52  static __forceinline bool WriteFifoToEE( Line 52  static __forceinline bool WriteFifoToEE(
52          sif0.fifo.read((u32*)ptag, readSize << 2);          sif0.fifo.read((u32*)ptag, readSize << 2);
53    
54          // Clearing handled by vtlb memory protection and manual blocks.          // Clearing handled by vtlb memory protection and manual blocks.
55          //Cpu->Clear(sif0dma->madr, readSize*4);          //Cpu->Clear(sif0dma.madr, readSize*4);
56    
57          sif0dma->madr += readSize << 4;          sif0dma.madr += readSize << 4;
58          sif0.ee.cycles += readSize;     // fixme : BIAS is factored in above          sif0.ee.cycles += readSize;     // fixme : BIAS is factored in above
59          sif0dma->qwc -= readSize;          sif0dma.qwc -= readSize;
60    
61          return true;          return true;
62  }  }
63    
64  // Write IOP to Fifo.  // Write IOP to Fifo.
65  static __forceinline bool WriteIOPtoFifo()  static __fi bool WriteIOPtoFifo()
66  {  {
67          // There's some data ready to transfer into the fifo..          // There's some data ready to transfer into the fifo..
68          const int writeSize = min(sif0.iop.counter, sif0.fifo.free());          const int writeSize = min(sif0.iop.counter, sif0.fifo.free());
# Line 73  static __forceinline bool WriteIOPtoFifo Line 73  static __forceinline bool WriteIOPtoFifo
73          hw_dma(9).madr += writeSize << 2;          hw_dma(9).madr += writeSize << 2;
74    
75          // 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).
76          sif0.iop.cycles += (writeSize >> 2) * BIAS;             // fixme : should be >> 4          sif0.iop.cycles += (writeSize >> 2)/* * BIAS*/;         // fixme : should be >> 4
77          sif0.iop.counter -= writeSize;          sif0.iop.counter -= writeSize;
78    
79          return true;          return true;
80  }  }
81    
82  // Read Fifo into an ee tag, transfer it to sif0dma, and process it.  // Read Fifo into an ee tag, transfer it to sif0dma, and process it.
83  static __forceinline bool ProcessEETag()  static __fi bool ProcessEETag()
84  {  {
85          static __aligned16 u32 tag[4];          static __aligned16 u32 tag[4];
86    
87          sif0.fifo.read((u32*)&tag[0], 4); // Tag          sif0.fifo.read((u32*)&tag[0], 4); // Tag
88          SIF_LOG("SIF0 EE read tag: %x %x %x %x", tag[0], tag[1], tag[2], tag[3]);          SIF_LOG("SIF0 EE read tag: %x %x %x %x", tag[0], tag[1], tag[2], tag[3]);
89    
90          sif0dma->unsafeTransfer(((tDMA_TAG*)(tag)));          sif0dma.unsafeTransfer(((tDMA_TAG*)(tag)));
91          sif0dma->madr = tag[1];          sif0dma.madr = tag[1];
92          tDMA_TAG ptag(tag[0]);          tDMA_TAG ptag(tag[0]);
93    
94          SIF_LOG("SIF0 EE dest chain tag madr:%08X qwc:%04X id:%X irq:%d(%08X_%08X)",          SIF_LOG("SIF0 EE dest chain tag madr:%08X qwc:%04X id:%X irq:%d(%08X_%08X)",
95                  sif0dma->madr, sif0dma->qwc, ptag.ID, ptag.IRQ, tag[1], tag[0]);                  sif0dma.madr, sif0dma.qwc, ptag.ID, ptag.IRQ, tag[1], tag[0]);
96    
97          if (sif0dma->chcr.TIE && ptag.IRQ)          if (sif0dma.chcr.TIE && ptag.IRQ)
98          {          {
99                  //Console.WriteLn("SIF0 TIE");                  //Console.WriteLn("SIF0 TIE");
100                  sif0.ee.end = true;                  sif0.ee.end = true;
# Line 104  static __forceinline bool ProcessEETag() Line 104  static __forceinline bool ProcessEETag()
104          {          {
105                  case TAG_REFE:                  case TAG_REFE:
106                          sif0.ee.end = true;                          sif0.ee.end = true;
107                          if (dmacRegs->ctrl.STS != NO_STS)                          if (dmacRegs.ctrl.STS != NO_STS)
108                                  dmacRegs->stadr.ADDR = sif0dma->madr + (sif0dma->qwc * 16);                                  dmacRegs.stadr.ADDR = sif0dma.madr + (sif0dma.qwc * 16);
109                                  break;                                  break;
110    
111                  case TAG_REFS:                  case TAG_REFS:
112                          if (dmacRegs->ctrl.STS != NO_STS)                          if (dmacRegs.ctrl.STS != NO_STS)
113                                  dmacRegs->stadr.ADDR = sif0dma->madr + (sif0dma->qwc * 16);                                  dmacRegs.stadr.ADDR = sif0dma.madr + (sif0dma.qwc * 16);
114                                  break;                                  break;
115    
116                  case TAG_END:                  case TAG_END:
# Line 121  static __forceinline bool ProcessEETag() Line 121  static __forceinline bool ProcessEETag()
121  }  }
122    
123  // Read Fifo into an iop tag, and transfer it to hw_dma(9). And presumably process it.  // Read Fifo into an iop tag, and transfer it to hw_dma(9). And presumably process it.
124  static __forceinline bool ProcessIOPTag()  static __fi bool ProcessIOPTag()
125  {  {
126          // Process DMA tag at hw_dma(9).tadr          // Process DMA tag at hw_dma(9).tadr
127          sif0.iop.data = *(sifData *)iopPhysMem(hw_dma(9).tadr);          sif0.iop.data = *(sifData *)iopPhysMem(hw_dma(9).tadr);
# Line 141  static __forceinline bool ProcessIOPTag( Line 141  static __forceinline bool ProcessIOPTag(
141  }  }
142    
143  // Stop transferring ee, and signal an interrupt.  // Stop transferring ee, and signal an interrupt.
144  static __forceinline void EndEE()  static __fi void EndEE()
145  {  {
146          SIF_LOG("Sif0: End EE");          SIF_LOG("Sif0: End EE");
147          sif0.ee.end = false;          sif0.ee.end = false;
# Line 156  static __forceinline void EndEE() Line 156  static __forceinline void EndEE()
156  }  }
157    
158  // Stop transferring iop, and signal an interrupt.  // Stop transferring iop, and signal an interrupt.
159  static __forceinline void EndIOP()  static __fi void EndIOP()
160  {  {
161          SIF_LOG("Sif0: End IOP");          SIF_LOG("Sif0: End IOP");
162          sif0data = 0;          sif0data = 0;
# Line 175  static __forceinline void EndIOP() Line 175  static __forceinline void EndIOP()
175  }  }
176    
177  // Handle the EE transfer.  // Handle the EE transfer.
178  static __forceinline void HandleEETransfer()  static __fi void HandleEETransfer()
179  {  {
180          if(sif0dma->chcr.STR == false)          if(sif0dma.chcr.STR == false)
181          {          {
182                  DevCon.Warning("Replacement for irq prevention hack EE SIF0");                  DevCon.Warning("Replacement for irq prevention hack EE SIF0");
183                  sif0.ee.end = false;                  sif0.ee.end = false;
# Line 185  static __forceinline void HandleEETransf Line 185  static __forceinline void HandleEETransf
185                  return;                  return;
186          }          }
187    
188          if (dmacRegs->ctrl.STS == STS_SIF0)          if (dmacRegs.ctrl.STS == STS_SIF0)
189          {          {
190                  DevCon.Warning("SIF0 stall control");                  DevCon.Warning("SIF0 stall control");
191          }          }
192    
193          /*if (sif0dma->qwc == 0)          /*if (sif0dma.qwc == 0)
194                  if (sif0dma->chcr.MOD == NORMAL_MODE)                  if (sif0dma.chcr.MOD == NORMAL_MODE)
195                          if (!sif0.ee.end){                          if (!sif0.ee.end){
196                                  DevCon.Warning("sif0 irq prevented");                                  DevCon.Warning("sif0 irq prevented");
197                                  done = true;                                  done = true;
198                                  return;                                  return;
199                          }*/                          }*/
200    
201          if (sif0dma->qwc <= 0)          if (sif0dma.qwc <= 0)
202          {          {
203                  if ((sif0dma->chcr.MOD == NORMAL_MODE) || sif0.ee.end)                  if ((sif0dma.chcr.MOD == NORMAL_MODE) || sif0.ee.end)
204                  {                  {
205                          // Stop transferring ee, and signal an interrupt.                          // Stop transferring ee, and signal an interrupt.
206                          done = true;                          done = true;
# Line 214  static __forceinline void HandleEETransf Line 214  static __forceinline void HandleEETransf
214                  }                  }
215          }          }
216    
217          if (sif0dma->qwc > 0) // If we're writing something, continue to do so.          if (sif0dma.qwc > 0) // If we're writing something, continue to do so.
218          {          {
219                  // Write from Fifo to EE.                  // Write from Fifo to EE.
220                  if (sif0.fifo.size > 0)                  if (sif0.fifo.size > 0)
# Line 253  static __forceinline void HandleEETransf Line 253  static __forceinline void HandleEETransf
253  // SIF - 8 = 0 (pos=12)  // SIF - 8 = 0 (pos=12)
254  // SIF0 DMA end...  // SIF0 DMA end...
255    
256  static __forceinline void HandleIOPTransfer()  static __fi void HandleIOPTransfer()
257  {  {
258          if (sif0.iop.counter <= 0) // If there's no more to transfer          if (sif0.iop.counter <= 0) // If there's no more to transfer
259          {          {
# Line 280  static __forceinline void HandleIOPTrans Line 280  static __forceinline void HandleIOPTrans
280          }          }
281  }  }
282    
283  static __forceinline void Sif0End()  static __fi void Sif0End()
284  {  {
285          SIF_LOG("SIF0 DMA end...");          SIF_LOG("SIF0 DMA end...");
286  }  }
287    
288  // Transfer IOP to EE, putting data in the fifo as an intermediate step.  // Transfer IOP to EE, putting data in the fifo as an intermediate step.
289  __forceinline void SIF0Dma()  __fi void SIF0Dma()
290  {  {
291          int BusyCheck = 0;          int BusyCheck = 0;
292          Sif0Init();          Sif0Init();
# Line 298  __forceinline void SIF0Dma() Line 298  __forceinline void SIF0Dma()
298    
299                  if (sif0.iop.busy)                  if (sif0.iop.busy)
300                  {                  {
301                          if(sif0.fifo.free() > 0) BusyCheck++;                          if(sif0.fifo.free() > 0 || (sif0.iop.end == true && sif0.iop.counter == 0))
302                          HandleIOPTransfer();                          {
303                                    BusyCheck++;
304                                    HandleIOPTransfer();
305                            }
306                  }                  }
307                  if (sif0.ee.busy)                  if (sif0.ee.busy)
308                  {                  {
309                          if(sif0.fifo.size >= 4) BusyCheck++;                          if(sif0.fifo.size >= 4 || (sif0.ee.end == true && sif0dma.qwc == 0))
310                          HandleEETransfer();                          {
311                                    BusyCheck++;
312                                    HandleEETransfer();
313                            }
314                  }                  }
315          } while (!done && BusyCheck > 0); // Substituting (sif0.ee.busy || sif0.iop.busy) breaks things.          } while (/*!done && */BusyCheck > 0); // Substituting (sif0.ee.busy || sif0.iop.busy) breaks things.
316    
317          Sif0End();          Sif0End();
318  }  }
319    
320  __forceinline void  sif0Interrupt()  __fi void  sif0Interrupt()
321  {  {
322          HW_DMA9_CHCR &= ~0x01000000;          HW_DMA9_CHCR &= ~0x01000000;
323          psxDmaInterrupt2(2);          psxDmaInterrupt2(2);
324  }  }
325    
326  __forceinline void  EEsif0Interrupt()  __fi void  EEsif0Interrupt()
327  {  {
328          hwDmacIrq(DMAC_SIF0);          hwDmacIrq(DMAC_SIF0);
329          sif0dma->chcr.STR = false;          sif0dma.chcr.STR = false;
330  }  }
331    
332  __forceinline void dmaSIF0()  __fi void dmaSIF0()
333  {  {
334          SIF_LOG(wxString(L"dmaSIF0" + sif0dma->cmqt_to_str()).To8BitData());          SIF_LOG(wxString(L"dmaSIF0" + sif0dma.cmqt_to_str()).To8BitData());
335    
336          if (sif0.fifo.readPos != sif0.fifo.writePos)          if (sif0.fifo.readPos != sif0.fifo.writePos)
337          {          {
338                  SIF_LOG("warning, sif0.fifoReadPos != sif0.fifoWritePos");                  SIF_LOG("warning, sif0.fifoReadPos != sif0.fifoWritePos");
339          }          }
340    
341          if(sif0dma->chcr.MOD == CHAIN_MODE && sif0dma->qwc > 0) DevCon.Warning(L"SIF0 QWC on Chain CHCR " + sif0dma->chcr.desc());          //if(sif0dma.chcr.MOD == CHAIN_MODE && sif0dma.qwc > 0) DevCon.Warning(L"SIF0 QWC on Chain CHCR " + sif0dma.chcr.desc());
342          psHu32(SBUS_F240) |= 0x2000;          psHu32(SBUS_F240) |= 0x2000;
343          sif0.ee.busy = true;          sif0.ee.busy = true;
344    
345            // Okay, this here is needed currently (r3644).
346            // FFX battles in the thunder plains map die otherwise, Phantasy Star 4 as well
347            // These 2 games could be made playable again by increasing the time the EE or the IOP run,
348            // showing that this is very timing sensible.
349            // Doing this DMA unfortunately brings back an old warning in Legend of Legaia though, but it still works.
350          if (sif0.iop.busy)          if (sif0.iop.busy)
351          {          {
352          XMMRegisters::Freeze();          //hwIntcIrq(INTC_SBUS); // not sure, so let's not
                 hwIntcIrq(INTC_SBUS);  
353                  SIF0Dma();                  SIF0Dma();
354                  psHu32(SBUS_F240) &= ~0x20;                  // Do we really want to mess with the SIF flags like that? Nah.
355                  psHu32(SBUS_F240) &= ~0x2000;                  //psHu32(SBUS_F240) &= ~0x20;
356          XMMRegisters::Thaw();                  //psHu32(SBUS_F240) &= ~0x2000;
357          }          }
358  }  }

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

  ViewVC Help
Powered by ViewVC 1.1.22