/[pcsx2_0.9.7]/trunk/pcsx2/Dmac.h
ViewVC logotype

Annotation of /trunk/pcsx2/Dmac.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 280 - (hide annotations) (download)
Thu Dec 23 12:02:12 2010 UTC (9 years, 6 months ago) by william
File MIME type: text/plain
File size: 13274 byte(s)
re-commit (had local access denied errors when committing)
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 william 62 #pragma once
17 william 31
18     // Useful enums for some of the fields.
19     enum pce_values
20     {
21     PCE_NOTHING = 0,
22     PCE_RESERVED,
23     PCE_DISABLED,
24     PCE_ENABLED
25     };
26    
27    
28     enum tag_id
29     {
30     TAG_CNTS = 0,
31     TAG_REFE = 0, // Transfer Packet According to ADDR field, clear STR, and end
32     TAG_CNT, // Transfer QWC following the tag.
33     TAG_NEXT, // Transfer QWC following tag. TADR = ADDR
34     TAG_REF, // Transfer QWC from ADDR field
35     TAG_REFS, // Transfer QWC from ADDR field (Stall Control)
36     TAG_CALL, // Transfer QWC following the tag, save succeeding tag
37     TAG_RET, // Transfer QWC following the tag, load next tag
38     TAG_END // Transfer QWC following the tag
39     };
40    
41     enum mfd_type
42     {
43     NO_MFD = 0,
44     MFD_RESERVED,
45     MFD_VIF1,
46     MFD_GIF
47     };
48    
49     enum sts_type
50     {
51     NO_STS = 0,
52     STS_SIF0,
53     STS_fromSPR,
54     STS_fromIPU
55     };
56    
57     enum std_type
58     {
59     NO_STD = 0,
60     STD_VIF1,
61     STD_GIF,
62     STD_SIF1
63     };
64    
65 william 62 enum LogicalTransferMode
66 william 31 {
67     NORMAL_MODE = 0,
68     CHAIN_MODE,
69     INTERLEAVE_MODE,
70     UNDEFINED_MODE
71     };
72    
73     //
74     // --- DMA ---
75     //
76    
77     // Doing double duty as both the top 32 bits *and* the lower 32 bits of a chain tag.
78     // Theoretically should probably both be in a u64 together, but with the way the
79     // code is layed out, this is easier for the moment.
80    
81     union tDMA_TAG {
82     struct {
83     u32 QWC : 16;
84 william 62 u32 _reserved2 : 10;
85 william 31 u32 PCE : 2;
86     u32 ID : 3;
87     u32 IRQ : 1;
88     };
89     struct {
90     u32 ADDR : 31;
91     u32 SPR : 1;
92     };
93     u32 _u32;
94    
95 william 273 tDMA_TAG() {}
96    
97 william 31 tDMA_TAG(u32 val) { _u32 = val; }
98     u16 upper() const { return (_u32 >> 16); }
99     u16 lower() const { return (u16)_u32; }
100     wxString tag_to_str() const
101     {
102     switch(ID)
103     {
104     case TAG_REFE: return wxsFormat(L"REFE %08X", _u32); break;
105     case TAG_CNT: return L"CNT"; break;
106     case TAG_NEXT: return wxsFormat(L"NEXT %08X", _u32); break;
107     case TAG_REF: return wxsFormat(L"REF %08X", _u32); break;
108     case TAG_REFS: return wxsFormat(L"REFS %08X", _u32); break;
109     case TAG_CALL: return L"CALL"; break;
110     case TAG_RET: return L"RET"; break;
111     case TAG_END: return L"END"; break;
112     default: return L"????"; break;
113     }
114     }
115     void reset() { _u32 = 0; }
116     };
117     #define DMA_TAG(value) ((tDMA_TAG)(value))
118    
119     union tDMA_CHCR {
120     struct {
121     u32 DIR : 1; // Direction: 0 - to memory, 1 - from memory. VIF1 & SIF2 only.
122 william 62 u32 _reserved1 : 1;
123     u32 MOD : 2; // Logical transfer mode. Normal, Chain, or Interleave (see LogicalTransferMode enum)
124 william 31 u32 ASP : 2; // ASP1 & ASP2; Address stack pointer. 0, 1, or 2 addresses.
125     u32 TTE : 1; // Tag Transfer Enable. 0 - Disable / 1 - Enable.
126     u32 TIE : 1; // Tag Interrupt Enable. 0 - Disable / 1 - Enable.
127     u32 STR : 1; // Start. 0 while stopping DMA, 1 while it's running.
128 william 62 u32 _reserved2 : 7;
129     u32 TAG : 16; // Maintains upper 16 bits of the most recently read DMAtag.
130 william 31 };
131     u32 _u32;
132    
133     tDMA_CHCR( u32 val) { _u32 = val; }
134    
135     bool test(u32 flags) const { return !!(_u32 & flags); }
136     void set(u32 value) { _u32 = value; }
137     void set_flags(u32 flags) { _u32 |= flags; }
138     void clear_flags(u32 flags) { _u32 &= ~flags; }
139     void reset() { _u32 = 0; }
140     u16 upper() const { return (_u32 >> 16); }
141     u16 lower() const { return (u16)_u32; }
142     wxString desc() const { return wxsFormat(L"Chcr: 0x%x", _u32); }
143 william 62 tDMA_TAG tag() { return (tDMA_TAG)_u32; }
144 william 31 };
145    
146     #define CHCR(value) ((tDMA_CHCR)(value))
147    
148     union tDMA_SADR {
149     struct {
150     u32 ADDR : 14;
151     u32 reserved2 : 18;
152     };
153     u32 _u32;
154    
155     tDMA_SADR(u32 val) { _u32 = val; }
156    
157     void reset() { _u32 = 0; }
158     wxString desc() const { return wxsFormat(L"Sadr: 0x%x", _u32); }
159 william 62 tDMA_TAG tag() const { return (tDMA_TAG)_u32; }
160 william 31 };
161    
162     union tDMA_QWC {
163     struct {
164 william 62 u16 QWC;
165     u16 _unused;
166 william 31 };
167     u32 _u32;
168    
169     tDMA_QWC(u32 val) { _u32 = val; }
170    
171     void reset() { _u32 = 0; }
172 william 62 wxString desc() const { return wxsFormat(L"QWC: 0x%04x", QWC); }
173     tDMA_TAG tag() const { return (tDMA_TAG)_u32; }
174 william 31 };
175    
176     struct DMACh {
177     tDMA_CHCR chcr;
178 william 62 u32 _null0[3];
179 william 31 u32 madr;
180 william 62 u32 _null1[3];
181 william 31 u16 qwc; u16 pad;
182 william 62 u32 _null2[3];
183 william 31 u32 tadr;
184 william 62 u32 _null3[3];
185 william 31 u32 asr0;
186 william 62 u32 _null4[3];
187 william 31 u32 asr1;
188 william 62 u32 _null5[11];
189 william 31 u32 sadr;
190    
191     void chcrTransfer(tDMA_TAG* ptag)
192     {
193     chcr.TAG = ptag[0].upper();
194     }
195    
196     void qwcTransfer(tDMA_TAG* ptag)
197     {
198     qwc = ptag[0].QWC;
199     }
200    
201 william 62 bool transfer(const char *s, tDMA_TAG* ptag);
202     void unsafeTransfer(tDMA_TAG* ptag);
203     tDMA_TAG *getAddr(u32 addr, u32 num, bool write);
204     tDMA_TAG *DMAtransfer(u32 addr, u32 num);
205     tDMA_TAG dma_tag();
206 william 31
207 william 62 wxString cmq_to_str() const;
208     wxString cmqt_to_str() const;
209 william 31 };
210    
211     enum INTCIrqs
212     {
213     INTC_GS = 0,
214     INTC_SBUS,
215     INTC_VBLANK_S,
216     INTC_VBLANK_E,
217     INTC_VIF0,
218     INTC_VIF1,
219     INTC_VU0,
220     INTC_VU1,
221     INTC_IPU,
222     INTC_TIM0,
223     INTC_TIM1,
224     INTC_TIM2,
225     INTC_TIM3,
226     INTC_SFIFO,
227     INTVU0_WD
228     };
229    
230     enum dmac_conditions
231     {
232     DMAC_STAT_SIS = (1<<13), // stall condition
233     DMAC_STAT_MEIS = (1<<14), // mfifo empty
234     DMAC_STAT_BEIS = (1<<15), // bus error
235     DMAC_STAT_SIM = (1<<29), // stall mask
236     DMAC_STAT_MEIM = (1<<30) // mfifo mask
237     };
238    
239     //DMA interrupts & masks
240     enum DMAInter
241     {
242     BEISintr = 0x00008000,
243     VIF0intr = 0x00010001,
244     VIF1intr = 0x00020002,
245     GIFintr = 0x00040004,
246     IPU0intr = 0x00080008,
247     IPU1intr = 0x00100010,
248     SIF0intr = 0x00200020,
249     SIF1intr = 0x00400040,
250     SIF2intr = 0x00800080,
251     SPR0intr = 0x01000100,
252     SPR1intr = 0x02000200,
253     SISintr = 0x20002000,
254     MEISintr = 0x40004000
255     };
256    
257     union tDMAC_QUEUE
258     {
259     struct
260     {
261     u16 VIF0 : 1;
262     u16 VIF1 : 1;
263     u16 GIF : 1;
264     u16 IPU0 : 1;
265     u16 IPU1 : 1;
266     u16 SIF0 : 1;
267     u16 SIF1 : 1;
268     u16 SIF2 : 1;
269     u16 SPR0 : 1;
270     u16 SPR1 : 1;
271     u16 SIS : 1;
272     u16 MEIS : 1;
273     u16 BEIS : 1;
274     };
275     u16 _u16;
276    
277     tDMAC_QUEUE(u16 val) { _u16 = val; }
278     void reset() { _u16 = 0; }
279     bool empty() const { return (_u16 == 0); }
280     };
281    
282 william 62 static __fi const wxChar* ChcrName(u32 addr)
283 william 31 {
284     switch (addr)
285     {
286     case D0_CHCR: return L"Vif 0";
287     case D1_CHCR: return L"Vif 1";
288     case D2_CHCR: return L"GIF";
289     case D3_CHCR: return L"Ipu 0";
290     case D4_CHCR: return L"Ipu 1";
291     case D5_CHCR: return L"Sif 0";
292     case D6_CHCR: return L"Sif 1";
293     case D7_CHCR: return L"Sif 2";
294     case D8_CHCR: return L"SPR 0";
295     case D9_CHCR: return L"SPR 1";
296     default: return L"???";
297     }
298     }
299    
300     // Believe it or not, making this const can generate compiler warnings in gcc.
301 william 62 static __fi int ChannelNumber(u32 addr)
302 william 31 {
303     switch (addr)
304     {
305     case D0_CHCR: return 0;
306     case D1_CHCR: return 1;
307     case D2_CHCR: return 2;
308     case D3_CHCR: return 3;
309     case D4_CHCR: return 4;
310     case D5_CHCR: return 5;
311     case D6_CHCR: return 6;
312     case D7_CHCR: return 7;
313     case D8_CHCR: return 8;
314     case D9_CHCR: return 9;
315     default:
316     {
317 william 62 pxFailDev("Invalid DMA channel number");
318 william 31 return 51; // some value
319     }
320     }
321     }
322    
323     union tDMAC_CTRL {
324     struct {
325     u32 DMAE : 1; // 0/1 - disables/enables all DMAs
326     u32 RELE : 1; // 0/1 - cycle stealing off/on
327     u32 MFD : 2; // Memory FIFO drain channel (mfd_type)
328     u32 STS : 2; // Stall Control source channel (sts type)
329     u32 STD : 2; // Stall Control drain channel (std_type)
330     u32 RCYC : 3; // Release cycle (8/16/32/64/128/256)
331 william 62 u32 _reserved1 : 21;
332 william 31 };
333     u32 _u32;
334    
335     tDMAC_CTRL(u32 val) { _u32 = val; }
336    
337     bool test(u32 flags) const { return !!(_u32 & flags); }
338     void set_flags(u32 flags) { _u32 |= flags; }
339     void clear_flags(u32 flags) { _u32 &= ~flags; }
340     void reset() { _u32 = 0; }
341     wxString desc() const { return wxsFormat(L"Ctrl: 0x%x", _u32); }
342     };
343    
344     union tDMAC_STAT {
345     struct {
346     u32 CIS : 10;
347 william 62 u32 _reserved1 : 3;
348 william 31 u32 SIS : 1;
349     u32 MEIS : 1;
350     u32 BEIS : 1;
351     u32 CIM : 10;
352 william 62 u32 _reserved2 : 3;
353 william 31 u32 SIM : 1;
354     u32 MEIM : 1;
355 william 62 u32 _reserved3 : 1;
356 william 31 };
357     u32 _u32;
358 william 62 u16 _u16[2];
359 william 31
360     tDMAC_STAT(u32 val) { _u32 = val; }
361    
362     bool test(u32 flags) const { return !!(_u32 & flags); }
363     void set_flags(u32 flags) { _u32 |= flags; }
364     void clear_flags(u32 flags) { _u32 &= ~flags; }
365     void reset() { _u32 = 0; }
366     wxString desc() const { return wxsFormat(L"Stat: 0x%x", _u32); }
367 william 62
368     bool TestForInterrupt() const
369     {
370     return ((_u16[0] & _u16[1]) != 0) || BEIS;
371     }
372 william 31 };
373    
374     union tDMAC_PCR {
375     struct {
376     u32 CPC : 10;
377 william 62 u32 _reserved1 : 6;
378 william 31 u32 CDE : 10;
379 william 62 u32 _reserved2 : 5;
380 william 31 u32 PCE : 1;
381     };
382     u32 _u32;
383    
384     tDMAC_PCR(u32 val) { _u32 = val; }
385    
386     bool test(u32 flags) const { return !!(_u32 & flags); }
387     void set_flags(u32 flags) { _u32 |= flags; }
388     void clear_flags(u32 flags) { _u32 &= ~flags; }
389     void reset() { _u32 = 0; }
390     wxString desc() const { return wxsFormat(L"Pcr: 0x%x", _u32); }
391     };
392    
393     union tDMAC_SQWC {
394     struct {
395     u32 SQWC : 8;
396 william 62 u32 _reserved1 : 8;
397 william 31 u32 TQWC : 8;
398 william 62 u32 _reserved2 : 8;
399 william 31 };
400     u32 _u32;
401    
402     tDMAC_SQWC(u32 val) { _u32 = val; }
403    
404     bool test(u32 flags) const { return !!(_u32 & flags); }
405     void set_flags(u32 flags) { _u32 |= flags; }
406     void clear_flags(u32 flags) { _u32 &= ~flags; }
407     void reset() { _u32 = 0; }
408     wxString desc() const { return wxsFormat(L"Sqwc: 0x%x", _u32); }
409     };
410    
411     union tDMAC_RBSR {
412     struct {
413     u32 RMSK : 31;
414 william 62 u32 _reserved1 : 1;
415 william 31 };
416     u32 _u32;
417    
418     tDMAC_RBSR(u32 val) { _u32 = val; }
419    
420     void reset() { _u32 = 0; }
421     wxString desc() const { return wxsFormat(L"Rbsr: 0x%x", _u32); }
422     };
423    
424     union tDMAC_RBOR {
425     struct {
426     u32 ADDR : 31;
427 william 62 u32 _reserved1 : 1;
428 william 31 };
429     u32 _u32;
430    
431     tDMAC_RBOR(u32 val) { _u32 = val; }
432    
433     void reset() { _u32 = 0; }
434     wxString desc() const { return wxsFormat(L"Rbor: 0x%x", _u32); }
435     };
436    
437 william 62 // --------------------------------------------------------------------------------------
438     // tDMAC_ADDR
439     // --------------------------------------------------------------------------------------
440     // This struct is used for several DMA address types, including some that do not have
441     // effective SPR bit (the bit is ignored for all addresses that are not "allowed" to access
442     // the scratchpad, including STADR, toSPR.MADR, fromSPR.MADR, etc.).
443     //
444     union tDMAC_ADDR
445     {
446 william 31 struct {
447 william 62 u32 ADDR : 31; // Transfer memory address
448     u32 SPR : 1; // Memory/SPR Address (only effective for MADR and TADR of non-SPR DMAs)
449 william 31 };
450     u32 _u32;
451    
452 william 62 tDMAC_ADDR() {}
453     tDMAC_ADDR(u32 val) { _u32 = val; }
454 william 31
455 william 62 void clear() { _u32 = 0; }
456    
457     void AssignADDR(uint addr)
458     {
459     ADDR = addr;
460     if (SPR) ADDR &= (Ps2MemSize::Scratch-1);
461     }
462    
463     void IncrementQWC(uint incval = 1)
464     {
465     ADDR += incval;
466     if (SPR) ADDR &= (Ps2MemSize::Scratch-1);
467     }
468    
469     wxString ToString(bool sprIsValid=true) const
470     {
471     return pxsFmt((sprIsValid && SPR) ? L"0x%04X(SPR)" : L"0x%08X", ADDR);
472     }
473    
474     wxCharBuffer ToUTF8(bool sprIsValid=true) const
475     {
476     return FastFormatAscii().Write((sprIsValid && SPR) ? "0x%04X(SPR)" : "0x%08X", ADDR).c_str();
477     }
478 william 31 };
479    
480     struct DMACregisters
481     {
482     tDMAC_CTRL ctrl;
483 william 62 u32 _padding[3];
484 william 31 tDMAC_STAT stat;
485 william 62 u32 _padding1[3];
486 william 31 tDMAC_PCR pcr;
487 william 62 u32 _padding2[3];
488 william 31
489     tDMAC_SQWC sqwc;
490 william 62 u32 _padding3[3];
491 william 31 tDMAC_RBSR rbsr;
492 william 62 u32 _padding4[3];
493 william 31 tDMAC_RBOR rbor;
494 william 62 u32 _padding5[3];
495     tDMAC_ADDR stadr;
496     u32 _padding6[3];
497 william 31 };
498    
499     // Currently guesswork.
500     union tINTC_STAT {
501     struct {
502     u32 interrupts : 10;
503 william 62 u32 _placeholder : 22;
504 william 31 };
505     u32 _u32;
506    
507     tINTC_STAT(u32 val) { _u32 = val; }
508    
509     bool test(u32 flags) const { return !!(_u32 & flags); }
510     void set_flags(u32 flags) { _u32 |= flags; }
511     void clear_flags(u32 flags) { _u32 &= ~flags; }
512     void reset() { _u32 = 0; }
513     wxString desc() const { return wxsFormat(L"Stat: 0x%x", _u32); }
514     };
515    
516     union tINTC_MASK {
517     struct {
518     u32 int_mask : 10;
519 william 62 u32 _placeholder:22;
520 william 31 };
521     u32 _u32;
522    
523     tINTC_MASK(u32 val) { _u32 = val; }
524    
525     bool test(u32 flags) const { return !!(_u32 & flags); }
526     void set_flags(u32 flags) { _u32 |= flags; }
527     void clear_flags(u32 flags) { _u32 &= ~flags; }
528     void reset() { _u32 = 0; }
529     wxString desc() const { return wxsFormat(L"Mask: 0x%x", _u32); }
530     };
531    
532     struct INTCregisters
533     {
534     tINTC_STAT stat;
535 william 62 u32 _padding1[3];
536 william 31 tINTC_MASK mask;
537 william 62 u32 _padding2[3];
538 william 31 };
539    
540 william 62 #define intcRegs ((INTCregisters*)(eeHw+0xF000))
541 william 31
542 william 62 static DMACregisters& dmacRegs = (DMACregisters&)eeHw[0xE000];
543 william 31
544 william 62 // Various useful locations
545     static DMACh& vif0ch = (DMACh&)eeHw[0x8000];
546     static DMACh& vif1ch = (DMACh&)eeHw[0x9000];
547     static DMACh& gifch = (DMACh&)eeHw[0xA000];
548     static DMACh& spr0ch = (DMACh&)eeHw[0xD000];
549     static DMACh& spr1ch = (DMACh&)eeHw[0xD400];
550 william 31
551 william 62 extern void throwBusError(const char *s);
552     extern void setDmacStat(u32 num);
553     extern tDMA_TAG *SPRdmaGetAddr(u32 addr, bool write);
554     extern tDMA_TAG *dmaGetAddr(u32 addr, bool write);
555 william 31
556 william 62 extern void hwIntcIrq(int n);
557     extern void hwDmacIrq(int n);
558 william 31
559 william 280 extern void FireMFIFOEmpty();
560 william 62 extern bool hwMFIFOWrite(u32 addr, const u128* data, uint size_qwc);
561 william 280 extern void hwDmacSrcTadrInc(DMACh& dma);
562 william 62 extern bool hwDmacSrcChainWithStack(DMACh& dma, int id);
563     extern bool hwDmacSrcChain(DMACh& dma, int id);
564 william 31
565 william 62 template< uint page > u32 dmacRead32( u32 mem );
566     template< uint page > extern bool dmacWrite32( u32 mem, mem32_t& value );

  ViewVC Help
Powered by ViewVC 1.1.22