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

Contents of /trunk/pcsx2/Hw.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 10 - (show annotations) (download)
Mon Sep 6 11:40:06 2010 UTC (9 years, 5 months ago) by william
File size: 8446 byte(s)
exported r3113 from ./upstream/trunk
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
19 #include "Hardware.h"
20 #include "newVif.h"
21
22 using namespace R5900;
23
24 u8 *psH; // hw mem
25
26 const int rdram_devices = 2; // put 8 for TOOL and 2 for PS2 and PSX
27 int rdram_sdevid = 0;
28
29 static bool hwInitialized = false;
30
31 void hwInit()
32 {
33 if( hwInitialized ) return;
34
35 VifUnpackSSE_Init();
36 vif0Init();
37 vif1Init();
38
39 gsInit();
40 sifInit();
41 sprInit();
42 ipuInit();
43
44 hwInitialized = true;
45 }
46
47 /*void hwShutdown()
48 {
49 ipuShutdown();
50 }*/
51
52 void hwReset()
53 {
54 hwInit();
55
56 memzero_ptr<Ps2MemSize::Hardware>( PS2MEM_HW );
57 //memset(PS2MEM_HW+0x2000, 0, 0x0000e000);
58
59 psHu32(SBUS_F260) = 0x1D000060;
60 // i guess this is kinda a version, it's used by some bioses
61 psHu32(DMAC_ENABLEW) = 0x1201;
62 psHu32(DMAC_ENABLER) = 0x1201;
63
64 sifInit();
65 sprInit();
66
67 gsReset();
68 ipuReset();
69 vif0Reset();
70 vif1Reset();
71 }
72
73 __forceinline void intcInterrupt()
74 {
75 if ((cpuRegs.CP0.n.Status.val & 0x400) != 0x400) return;
76
77 if ((psHu32(INTC_STAT)) == 0) {
78 DevCon.Warning("*PCSX2*: intcInterrupt already cleared");
79 return;
80 }
81 if ((psHu32(INTC_STAT) & psHu32(INTC_MASK)) == 0) return;
82
83 HW_LOG("intcInterrupt %x", psHu32(INTC_STAT) & psHu32(INTC_MASK));
84 if(psHu32(INTC_STAT) & 0x2){
85 counters[0].hold = rcntRcount(0);
86 counters[1].hold = rcntRcount(1);
87 }
88
89 cpuException(0x400, cpuRegs.branch);
90 }
91
92 __forceinline void dmacInterrupt()
93 {
94 if ((cpuRegs.CP0.n.Status.val & 0x10807) != 0x10801) return;
95
96 if( ((psHu16(DMAC_STAT + 2) & psHu16(DMAC_STAT)) == 0 ) &&
97 ( psHu16(DMAC_STAT) & 0x8000) == 0 ) return;
98
99 if (!(dmacRegs->ctrl.DMAE)) return;
100
101 HW_LOG("dmacInterrupt %x", (psHu16(DMAC_STAT + 2) & psHu16(DMAC_STAT) |
102 psHu16(DMAC_STAT) & 0x8000));
103
104 cpuException(0x800, cpuRegs.branch);
105 }
106
107 void hwIntcIrq(int n)
108 {
109 psHu32(INTC_STAT) |= 1<<n;
110 cpuTestINTCInts();
111 }
112
113 void hwDmacIrq(int n)
114 {
115 psHu32(DMAC_STAT) |= 1<<n;
116 cpuTestDMACInts();
117 }
118
119 // Write 'size' bytes to memory address 'addr' from 'data'.
120 bool hwMFIFOWrite(u32 addr, u8 *data, u32 size)
121 {
122 u32 msize = dmacRegs->rbor.ADDR + dmacRegs->rbsr.RMSK + 16;
123 u8 *dst;
124
125 addr = dmacRegs->rbor.ADDR + (addr & dmacRegs->rbsr.RMSK);
126
127 // Check if the transfer should wrap around the ring buffer
128 if ((addr+size) >= msize) {
129 int s1 = msize - addr;
130 int s2 = size - s1;
131
132 // it does, so first copy 's1' bytes from 'data' to 'addr'
133 dst = (u8*)PSM(addr);
134 if (dst == NULL) return false;
135 memcpy_fast(dst, data, s1);
136
137 // and second copy 's2' bytes from '&data[s1]' to 'maddr'
138 dst = (u8*)PSM(dmacRegs->rbor.ADDR);
139 if (dst == NULL) return false;
140 memcpy_fast(dst, &data[s1], s2);
141 }
142 else {
143 // it doesn't, so just copy 'size' bytes from 'data' to 'addr'
144 dst = (u8*)PSM(addr);
145 if (dst == NULL) return false;
146 memcpy_fast(dst, data, size);
147 }
148
149 return true;
150 }
151
152 bool hwDmacSrcChainWithStack(DMACh *dma, int id) {
153 switch (id) {
154 case TAG_REFE: // Refe - Transfer Packet According to ADDR field
155 //End Transfer
156 return true;
157
158 case TAG_CNT: // CNT - Transfer QWC following the tag.
159 // Set MADR to QW afer tag, and set TADR to QW following the data.
160 dma->madr = dma->tadr + 16;
161 dma->tadr = dma->madr + (dma->qwc << 4);
162 return false;
163
164 case TAG_NEXT: // Next - Transfer QWC following tag. TADR = ADDR
165 {
166 // Set MADR to QW following the tag, and set TADR to the address formerly in MADR.
167 u32 temp = dma->madr;
168 dma->madr = dma->tadr + 16;
169 dma->tadr = temp;
170 return false;
171 }
172 case TAG_REF: // Ref - Transfer QWC from ADDR field
173 case TAG_REFS: // Refs - Transfer QWC from ADDR field (Stall Control)
174 //Set TADR to next tag
175 dma->tadr += 16;
176 return false;
177
178 case TAG_CALL: // Call - Transfer QWC following the tag, save succeeding tag
179 {
180 // Store the address in MADR in temp, and set MADR to the data following the tag.
181 u32 temp = dma->madr;
182 dma->madr = dma->tadr + 16;
183
184 // Stash an address on the address stack pointer.
185 switch(dma->chcr.ASP)
186 {
187 case 0: //Check if ASR0 is empty
188 // Store the succeeding tag in asr0, and mark chcr as having 1 address.
189 dma->asr0 = dma->madr + (dma->qwc << 4);
190 dma->chcr.ASP++;
191 break;
192
193 case 1:
194 // Store the succeeding tag in asr1, and mark chcr as having 2 addresses.
195 dma->asr1 = dma->madr + (dma->qwc << 4);
196 dma->chcr.ASP++;
197 break;
198
199 default:
200 Console.Warning("Call Stack Overflow (report if it fixes/breaks anything)");
201 return true;
202 }
203
204 // Set TADR to the address from MADR we stored in temp.
205 dma->tadr = temp;
206
207 return false;
208 }
209
210 case TAG_RET: // Ret - Transfer QWC following the tag, load next tag
211 //Set MADR to data following the tag.
212 dma->madr = dma->tadr + 16;
213
214 // Snag an address from the address stack pointer.
215 switch(dma->chcr.ASP)
216 {
217 case 2:
218 // Pull asr1 from the stack, give it to TADR, and decrease the # of addresses.
219 dma->tadr = dma->asr1;
220 dma->asr1 = 0;
221 dma->chcr.ASP--;
222 break;
223
224 case 1:
225 // Pull asr0 from the stack, give it to TADR, and decrease the # of addresses.
226 dma->tadr = dma->asr0;
227 dma->asr0 = 0;
228 dma->chcr.ASP--;
229 break;
230
231 case 0:
232 // There aren't any addresses to pull, so end the transfer.
233 //dma->tadr += 16; //Clear tag address - Kills Klonoa 2
234 return true;
235
236 default:
237 // If ASR1 and ASR0 are messed up, end the transfer.
238 //Console.Error("TAG_RET: ASR 1 & 0 == 1. This shouldn't happen!");
239 //dma->tadr += 16; //Clear tag address - Kills Klonoa 2
240 return true;
241 }
242 return false;
243
244 case TAG_END: // End - Transfer QWC following the tag
245 //Set MADR to data following the tag, and end the transfer.
246 dma->madr = dma->tadr + 16;
247 //Don't Increment tadr; breaks Soul Calibur II and III
248 return true;
249 }
250
251 return false;
252 }
253
254 bool hwDmacSrcChain(DMACh *dma, int id)
255 {
256 u32 temp;
257
258 switch (id)
259 {
260 case TAG_REFE: // Refe - Transfer Packet According to ADDR field
261 // End the transfer.
262 return true;
263
264 case TAG_CNT: // CNT - Transfer QWC following the tag.
265 // Set MADR to QW after the tag, and TADR to QW following the data.
266 dma->madr = dma->tadr + 16;
267 dma->tadr = dma->madr + (dma->qwc << 4);
268 return false;
269
270 case TAG_NEXT: // Next - Transfer QWC following tag. TADR = ADDR
271 // Set MADR to QW following the tag, and set TADR to the address formerly in MADR.
272 temp = dma->madr;
273 dma->madr = dma->tadr + 16;
274 dma->tadr = temp;
275 return false;
276
277 case TAG_REF: // Ref - Transfer QWC from ADDR field
278 case TAG_REFS: // Refs - Transfer QWC from ADDR field (Stall Control)
279 //Set TADR to next tag
280 dma->tadr += 16;
281 return false;
282
283 case TAG_END: // End - Transfer QWC following the tag
284 //Set MADR to data following the tag, and end the transfer.
285 dma->madr = dma->tadr + 16;
286 //Don't Increment tadr; breaks Soul Calibur II and III
287 return true;
288 }
289
290 return false;
291 }

  ViewVC Help
Powered by ViewVC 1.1.22