/[pcsx2_0.9.7]/trunk/pcsx2/IPU/IPU_Fifo.cpp
ViewVC logotype

Contents of /trunk/pcsx2/IPU/IPU_Fifo.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 280 - (show annotations) (download)
Thu Dec 23 12:02:12 2010 UTC (9 years, 6 months ago) by william
File size: 3877 byte(s)
re-commit (had local access denied errors when committing)
1 /* PCSX2 - PS2 Emulator for PCs
2 * Copyright (C) 2002-2010 PCSX2 Dev Team
3 *
4 * PCSX2 is free software: you can redistribute it and/or modify it under the terms
5 * of the GNU Lesser General Public License as published by the Free Software Found-
6 * ation, either version 3 of the License, or (at your option) any later version.
7 *
8 * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 * PURPOSE. See the GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License along with PCSX2.
13 * If not, see <http://www.gnu.org/licenses/>.
14 */
15
16 #include "PrecompiledHeader.h"
17 #include "Common.h"
18 #include "IPU.h"
19 #include "IPU/IPUdma.h"
20 #include "mpeg2lib/Mpeg.h"
21
22 __aligned16 IPU_Fifo ipu_fifo;
23
24 void IPU_Fifo::init()
25 {
26 out.readpos = 0;
27 out.writepos = 0;
28 in.readpos = 0;
29 in.writepos = 0;
30 memzero(in.data);
31 memzero(out.data);
32 }
33
34 void IPU_Fifo_Input::clear()
35 {
36 memzero(data);
37 g_BP.IFC = 0;
38 ipuRegs.ctrl.IFC = 0;
39 readpos = 0;
40 writepos = 0;
41 }
42
43 void IPU_Fifo_Output::clear()
44 {
45 memzero(data);
46 ipuRegs.ctrl.OFC = 0;
47 readpos = 0;
48 writepos = 0;
49 }
50
51 void IPU_Fifo::clear()
52 {
53 in.clear();
54 out.clear();
55 }
56
57 wxString IPU_Fifo_Input::desc() const
58 {
59 return wxsFormat(L"IPU Fifo Input: readpos = 0x%x, writepos = 0x%x, data = 0x%x", readpos, writepos, data);
60 }
61
62 wxString IPU_Fifo_Output::desc() const
63 {
64 return wxsFormat(L"IPU Fifo Output: readpos = 0x%x, writepos = 0x%x, data = 0x%x", readpos, writepos, data);
65 }
66
67 int IPU_Fifo_Input::write(u32* pMem, int size)
68 {
69 int transsize;
70 int firsttrans = min(size, 8 - (int)g_BP.IFC);
71
72 g_BP.IFC += firsttrans;
73 transsize = firsttrans;
74
75 while (transsize-- > 0)
76 {
77 CopyQWC(&data[writepos], pMem);
78 writepos = (writepos + 4) & 31;
79 pMem += 4;
80 }
81
82 return firsttrans;
83 }
84
85 int IPU_Fifo_Input::read(void *value)
86 {
87 // wait until enough data to ensure proper streaming.
88 if (g_BP.IFC < 3)
89 {
90 // IPU FIFO is empty and DMA is waiting so lets tell the DMA we are ready to put data in the FIFO
91 if(cpuRegs.eCycle[4] == 0x9999)
92 {
93 CPU_INT( DMAC_TO_IPU, 32 );
94 }
95
96 if (g_BP.IFC == 0) return 0;
97 pxAssert(g_BP.IFC > 0);
98 }
99
100 CopyQWC(value, &data[readpos]);
101
102 readpos = (readpos + 4) & 31;
103 g_BP.IFC--;
104 return 1;
105 }
106
107 int IPU_Fifo_Output::write(const u32 *value, uint size)
108 {
109 pxAssumeMsg(size>0, "Invalid size==0 when calling IPU_Fifo_Output::write");
110
111 uint origsize = size;
112 /*do {*/
113 //IPU0dma();
114
115 uint transsize = min(size, 8 - (uint)ipuRegs.ctrl.OFC);
116 if(!transsize) return 0;
117
118 ipuRegs.ctrl.OFC = transsize;
119 size -= transsize;
120 while (transsize > 0)
121 {
122 CopyQWC(&data[writepos], value);
123 writepos = (writepos + 4) & 31;
124 value += 4;
125 --transsize;
126 }
127 /*} while(true);*/
128
129 return origsize - size;
130 }
131
132 void IPU_Fifo_Output::read(void *value, uint size)
133 {
134 pxAssume(ipuRegs.ctrl.OFC >= size);
135 ipuRegs.ctrl.OFC -= size;
136
137 // Zeroing the read data is not needed, since the ringbuffer design will never read back
138 // the zero'd data anyway. --air
139
140 //__m128 zeroreg = _mm_setzero_ps();
141 while (size > 0)
142 {
143 CopyQWC(value, &data[readpos]);
144 //_mm_store_ps((float*)&data[readpos], zeroreg);
145
146 readpos = (readpos + 4) & 31;
147 value = (u128*)value + 1;
148 --size;
149 }
150 }
151
152 void __fastcall ReadFIFO_IPUout(mem128_t* out)
153 {
154 if (!pxAssertDev( ipuRegs.ctrl.OFC > 0, "Attempted read from IPUout's FIFO, but the FIFO is empty!" )) return;
155 ipu_fifo.out.read(out, 1);
156
157 // Games should always check the fifo before reading from it -- so if the FIFO has no data
158 // its either some glitchy game or a bug in pcsx2.
159 }
160
161 void __fastcall WriteFIFO_IPUin(const mem128_t* value)
162 {
163 IPU_LOG( "WriteFIFO/IPUin <- %ls", value->ToString().c_str() );
164
165 //committing every 16 bytes
166 if( ipu_fifo.in.write((u32*)value, 1) == 0 )
167 {
168 IPUProcessInterrupt();
169 }
170 }

  ViewVC Help
Powered by ViewVC 1.1.22