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

  ViewVC Help
Powered by ViewVC 1.1.22