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

Annotation of /trunk/pcsx2/IopSio2.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (hide annotations) (download)
Tue Sep 7 03:24:11 2010 UTC (10 years, 2 months ago) by william
File size: 9097 byte(s)
committing r3113 initial commit again...
1 william 31 /* 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    
17     #include "PrecompiledHeader.h"
18     #include "IopCommon.h"
19    
20     #include "Sio.h"
21     #include "sio_internal.h"
22    
23     sio2Struct sio2;
24    
25     /*
26     w [8268]=0x3bc sio2_start/sio2man
27     r [8270] padman_start/padman
28     padman->7480[00]=bit4;
29     padman->7480[13]=bit5;
30     packetExchange(&703F8);
31     w [8268]|=0x0C;
32     ........
33     w [8268]|=0x01;
34    
35     only recv2 & dataout influences padman
36     */
37    
38     // 0xBF808200,0xBF808204,0xBF808208,0xBF80820C,
39     // 0xBF808210,0xBF808214,0xBF808218,0xBF80821C, packet->sendArray3
40     // 0xBF808220,0xBF808224,0xBF808228,0xBF80822C, call12/13_s/getparams
41     // 0xBF808230,0xBF808234,0xBF808238,0xBF80823C,
42    
43     // 0xBF808240,0xBF808248,0xBF808250,0xBF808258, packet->sendArray1/call_7/8
44     // 0xBF808244,0xBF80824C,0xBF808254,0xBF80825C, packet->sendArray2/call_9/10
45    
46     // 0xBF808260, serial data/fifo in/out s/get8260_datain/out packet->sendbuf(nomem!)
47     // 0xBF808268, ctrl s/get8268_ctrl
48    
49     // 0xBF80826C, packet->recv1/2/3 get826C_recv1, get8270_recv2, get8274_recv3
50     // 0xBF808270,0xBF808274,
51    
52     // 0xBF808278,0xBF80827C, s/get8278, s/get827C
53     // 0xBF808280 interrupt related s/get8280_intr
54    
55    
56     void sio2Reset() {
57     DevCon.WriteLn( "Sio2 Reset" );
58     memzero(sio2);
59     sio2.packet.recvVal1 = 0x1D100; // Nothing is connected at start
60     }
61    
62     u32 sio2_getRecv1() {
63     PAD_LOG("Reading Recv1 = %x",sio2.packet.recvVal1);
64    
65     return sio2.packet.recvVal1;
66     }
67    
68     u32 sio2_getRecv2() {
69     PAD_LOG("Reading Recv2 = %x",0xF);
70    
71     return 0xf;
72     }//0, 0x10, 0x20, 0x10 | 0x20; bits 4 & 5
73    
74     u32 sio2_getRecv3() {
75     if(sio2.packet.recvVal3 == 0x8C || sio2.packet.recvVal3 == 0x8b ||
76     sio2.packet.recvVal3 == 0x83)
77     {
78     PAD_LOG("Reading Recv3 = %x",sio2.packet.recvVal3);
79    
80     sio.packetsize = sio2.packet.recvVal3;
81     sio2.packet.recvVal3 = 0; // Reset
82     return sio.packetsize;
83     }
84     else
85     {
86     PAD_LOG("Reading Recv3 = %x",sio.packetsize << 16);
87    
88     return sio.packetsize << 16;
89     }
90     }
91    
92     void sio2_setSend1(u32 index, u32 value){sio2.packet.sendArray1[index]=value;} //0->3
93     u32 sio2_getSend1(u32 index){return sio2.packet.sendArray1[index];} //0->3
94     void sio2_setSend2(u32 index, u32 value){sio2.packet.sendArray2[index]=value;} //0->3
95     u32 sio2_getSend2(u32 index){return sio2.packet.sendArray2[index];} //0->3
96    
97     void sio2_setSend3(u32 index, u32 value)
98     {
99     // int i;
100     sio2.packet.sendArray3[index]=value;
101     // if (index==15){
102     // for (i=0; i<4; i++){PAD_LOG("0x%08X ", sio2.packet.sendArray1[i]);}PAD_LOG("\n");
103     // for (i=0; i<4; i++){PAD_LOG("0x%08X ", sio2.packet.sendArray2[i]);}PAD_LOG("\n");
104     // for (i=0; i<8; i++){PAD_LOG("0x%08X ", sio2.packet.sendArray3[i]);}PAD_LOG("\n");
105     // for ( ; i<16; i++){PAD_LOG("0x%08X ", sio2.packet.sendArray3[i]);}PAD_LOG("\n");
106     PAD_LOG("[%d] : 0x%08X", index,sio2.packet.sendArray3[index]);
107     // }
108     } //0->15
109    
110     u32 sio2_getSend3(u32 index) {return sio2.packet.sendArray3[index];} //0->15
111    
112     void sio2_setCtrl(u32 value){
113     sio2.ctrl=value;
114     if (sio2.ctrl & 1){ //recv packet
115     //handle data that had been sent
116    
117     iopIntcIrq( 17 );
118     //SBUS
119     sio2.recvIndex=0;
120     sio2.ctrl &= ~1;
121     } else { // send packet
122     //clean up
123     sio2.packet.sendSize=0; //reset size
124     sio2.cmdport=0;
125     sio2.cmdlength=0;
126     sioWriteCtrl16(SIO_RESET);
127     }
128     }
129     u32 sio2_getCtrl(){return sio2.ctrl;}
130    
131     void sio2_setIntr(u32 value){sio2.intr=value;}
132     u32 sio2_getIntr(){
133     return sio2.intr;
134     }
135    
136     void sio2_set8278(u32 value){sio2._8278=value;}
137     u32 sio2_get8278(){return sio2._8278;}
138     void sio2_set827C(u32 value){sio2._827C=value;}
139     u32 sio2_get827C(){return sio2._827C;}
140    
141     void sio2_serialIn(u8 value){
142     u16 ctrl=0x0002;
143     if (sio2.packet.sendArray3[sio2.cmdport] && (sio2.cmdlength==0))
144     {
145    
146     sio2.cmdlength=(sio2.packet.sendArray3[sio2.cmdport] >> 8) & 0x1FF;
147     ctrl &= ~0x2000;
148     ctrl |= (sio2.packet.sendArray3[sio2.cmdport] & 1) << 13;
149     //sioWriteCtrl16(SIO_RESET);
150     sioWriteCtrl16(ctrl);
151     PSXDMA_LOG("sio2_fifoIn: ctrl = %x, cmdlength = %x, cmdport = %d (%x)", ctrl, sio2.cmdlength, sio2.cmdport, sio2.packet.sendArray3[sio2.cmdport]);
152    
153     sio2.cmdport++;
154     }
155    
156     if (sio2.cmdlength) sio2.cmdlength--;
157     sioWrite8(value);
158    
159     if (sio2.packet.sendSize > BUFSIZE) {//asadr
160     Console.Warning("*PCSX2*: sendSize >= %d", BUFSIZE);
161     } else {
162     sio2.buf[sio2.packet.sendSize] = sioRead8();
163     sio2.packet.sendSize++;
164     }
165     }
166     extern void SIODMAWrite(u8 value);
167    
168     void sio2_fifoIn(u8 value){
169     u16 ctrl=0x0002;
170     if (sio2.packet.sendArray3[sio2.cmdport] && (sio2.cmdlength==0))
171     {
172    
173     sio2.cmdlength=(sio2.packet.sendArray3[sio2.cmdport] >> 8) & 0x1FF;
174     ctrl &= ~0x2000;
175     ctrl |= (sio2.packet.sendArray3[sio2.cmdport] & 1) << 13;
176     //sioWriteCtrl16(SIO_RESET);
177     sioWriteCtrl16(ctrl);
178     PSXDMA_LOG("sio2_fifoIn: ctrl = %x, cmdlength = %x, cmdport = %d (%x)", ctrl, sio2.cmdlength, sio2.cmdport, sio2.packet.sendArray3[sio2.cmdport]);
179    
180     sio2.cmdport++;
181     }
182    
183     if (sio2.cmdlength) sio2.cmdlength--;
184     SIODMAWrite(value);
185    
186     if (sio2.packet.sendSize > BUFSIZE) {//asadr
187     Console.WriteLn("*PCSX2*: sendSize >= %d", BUFSIZE);
188     } else {
189     sio2.buf[sio2.packet.sendSize] = sioRead8();
190     sio2.packet.sendSize++;
191     }
192     }
193    
194     u8 sio2_fifoOut(){
195     if (sio2.recvIndex <= sio2.packet.sendSize){
196     //PAD_LOG("READING %x\n",sio2.buf[sio2.recvIndex]);
197     return sio2.buf[sio2.recvIndex++];
198     } else {
199     Console.Error( "*PCSX2*: buffer overrun" );
200     }
201     return 0; // No Data
202     }
203    
204     void SaveStateBase::sio2Freeze()
205     {
206     FreezeTag( "sio2" );
207     Freeze(sio2);
208     }
209    
210     /////////////////////////////////////////////////
211     //////////////////////////////////////////// DMA
212     /////////////////////////////////////////////////
213     #ifdef ENABLE_NEW_IOPDMA
214    
215     static int dmaBlockSize = 0x24;
216     s32 CALLBACK sio2DmaStart(s32 channel, u32 madr, u32 bcr, u32 chcr)
217     {
218     dmaBlockSize = bcr & 0xFFFF;
219     return 0; // continue
220     }
221    
222     s32 CALLBACK sio2DmaRead(s32 channel, u32* tdata, u32 bytesLeft, u32* bytesProcessed)
223     {
224     #ifdef ENABLE_NEW_IOPDMA_SIO
225     u8* data = (u8*)tdata;
226    
227     if(channel!=12)
228     return -1;
229    
230     sio2.recvIndex = 0; // Set To start; saqib
231    
232     int read = 0;
233    
234     // limit the burst length to avoid problems
235     //if(bytesLeft>2048) bytesLeft = 2048;
236    
237     while (bytesLeft > 0)
238     {
239     (*(data++)) = sio2_fifoOut();
240     bytesLeft--;
241     read++;
242     if(sio2.recvIndex == sio2.packet.sendSize)
243     {
244     //read = bytesLeft;
245     break;
246     }
247     }
248    
249     *bytesProcessed = read;
250     #endif
251     return 0;
252     }
253    
254     s32 CALLBACK sio2DmaWrite(s32 channel, u32* tdata, u32 bytesLeft, u32* bytesProcessed)
255     {
256     #ifdef ENABLE_NEW_IOPDMA_SIO
257     u8* data = (u8*)tdata;
258    
259     if(channel!=11)
260     return -1;
261    
262     //int available = sio2_getFifoInFree();
263    
264     // limit the burst length to avoid problems
265     //if(bytesLeft>2048) bytesLeft = 2048;
266    
267     int written = 0;
268    
269     int bs = dmaBlockSize * 4;
270     int bc = bytesLeft / bs;
271    
272     //assert(ts == bytesLeft);
273    
274     for(int j=0;j<bc;j++)
275     {
276     sio.count = 1;
277     for(int i=0;i<bs;i++)
278     {
279     sio2_fifoIn(*(data++));
280     written++;
281     if((sio2.packet.sendSize == BUFSIZE))
282     {
283     //written = bytesLeft;
284     break;
285     }
286     }
287     }
288    
289     *bytesProcessed = written;
290     #endif
291     return 0;
292     }
293    
294     void CALLBACK sio2DmaInterrupt(s32 channel)
295     {
296     #ifdef ENABLE_NEW_IOPDMA_SIO
297     switch(channel) // Interrupts should always occur at the end
298     {
299     case 11: PSX_INT(IopEvt_Dma11,0); break;
300     case 12: PSX_INT(IopEvt_Dma12,0); break;
301     }
302     #endif
303     }
304    
305     //#else
306     #endif
307    
308     void psxDma11(u32 madr, u32 bcr, u32 chcr) {
309     unsigned int i, j;
310     int size = (bcr >> 16) * (bcr & 0xffff);
311     PSXDMA_LOG("*** DMA 11 - SIO2 in *** %lx addr = %lx size = %lx", chcr, madr, bcr);
312    
313     if (chcr != 0x01000201) return;
314    
315     for(i = 0; i < (bcr >> 16); i++)
316     {
317     sio.count = 1;
318     for(j = 0; j < ((bcr & 0xFFFF) * 4); j++)
319     {
320     sio2_fifoIn(iopMemRead8(madr));
321     madr++;
322     if(sio2.packet.sendSize == BUFSIZE)
323     goto finished;
324     }
325     }
326    
327     finished:
328     HW_DMA11_MADR = madr;
329     PSX_INT(IopEvt_Dma11,(size>>2)); // Interrupts should always occur at the end
330     }
331    
332     void psxDMA11Interrupt()
333     {
334     HW_DMA11_CHCR &= ~0x01000000;
335     psxDmaInterrupt2(4);
336     }
337    
338     void psxDma12(u32 madr, u32 bcr, u32 chcr) {
339     int size = ((bcr >> 16) * (bcr & 0xFFFF)) * 4;
340     PSXDMA_LOG("*** DMA 12 - SIO2 out *** %lx addr = %lx size = %lx", chcr, madr, size);
341    
342     if (chcr != 0x41000200) return;
343    
344     sio2.recvIndex = 0; // Set To start; saqib
345    
346     bcr = size;
347     while (bcr > 0) {
348     iopMemWrite8( madr, sio2_fifoOut() );
349     bcr--; madr++;
350     if(sio2.recvIndex == sio2.packet.sendSize) break;
351     }
352     HW_DMA12_MADR = madr;
353     PSX_INT(IopEvt_Dma12,(size>>2)); // Interrupts should always occur at the end
354     }
355    
356     void psxDMA12Interrupt()
357     {
358     HW_DMA12_CHCR &= ~0x01000000;
359     psxDmaInterrupt2(5);
360     }
361    
362     //#endif

  ViewVC Help
Powered by ViewVC 1.1.22