/[pcsx2_0.9.7]/trunk/pcsx2/CDVD/CdRom.cpp
ViewVC logotype

Annotation of /trunk/pcsx2/CDVD/CdRom.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 62 - (hide annotations) (download)
Tue Sep 7 11:08:22 2010 UTC (10 years, 7 months ago) by william
File size: 19534 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    
17     #include "PrecompiledHeader.h"
18     #include "IopCommon.h"
19    
20     #include "CdRom.h"
21     #include "CDVD.h"
22    
23     //THIS ALL IS FOR THE CDROM REGISTERS HANDLING
24    
25     enum cdrom_registers
26     {
27     CdlSync = 0,
28     CdlNop = 1,
29     CdlSetloc = 2,
30     CdlPlay = 3,
31     CdlForward = 4,
32     CdlBackward = 5,
33     CdlReadN = 6,
34     CdlStandby = 7,
35     CdlStop = 8,
36     CdlPause = 9,
37     CdlInit = 10,
38     CdlMute = 11,
39     CdlDemute = 12,
40     CdlSetfilter = 13,
41     CdlSetmode = 14,
42     CdlGetmode = 15,
43     CdlGetlocL = 16,
44     CdlGetlocP = 17,
45     Cdl18 = 18,
46     CdlGetTN = 19,
47     CdlGetTD = 20,
48     CdlSeekL = 21,
49     CdlSeekP = 22,
50     CdlTest = 25,
51     CdlID = 26,
52     CdlReadS = 27,
53     CdlReset = 28,
54     CdlReadToc = 30,
55    
56     AUTOPAUSE = 249,
57     READ_ACK = 250,
58     READ = 251,
59     REPPLAY_ACK = 252,
60     REPPLAY = 253,
61     ASYNC = 254
62     /* don't set 255, it's reserved */
63     };
64    
65     const char *CmdName[0x100]= {
66     "CdlSync", "CdlNop", "CdlSetloc", "CdlPlay",
67     "CdlForward", "CdlBackward", "CdlReadN", "CdlStandby",
68     "CdlStop", "CdlPause", "CdlInit", "CdlMute",
69     "CdlDemute", "CdlSetfilter", "CdlSetmode", "CdlGetmode",
70     "CdlGetlocL", "CdlGetlocP", "Cdl18", "CdlGetTN",
71     "CdlGetTD", "CdlSeekL", "CdlSeekP", NULL,
72     NULL, "CdlTest", "CdlID", "CdlReadS",
73     "CdlReset", NULL, "CDlReadToc", NULL
74     };
75    
76     cdrStruct cdr;
77     s32 LoadCdBios;
78    
79     u8 Test04[] = { 0 };
80     u8 Test05[] = { 0 };
81     u8 Test20[] = { 0x98, 0x06, 0x10, 0xC3 };
82     u8 Test22[] = { 0x66, 0x6F, 0x72, 0x20, 0x45, 0x75, 0x72, 0x6F };
83     u8 Test23[] = { 0x43, 0x58, 0x44, 0x32, 0x39 ,0x34, 0x30, 0x51 };
84    
85     // 1x = 75 sectors per second
86     // PSXCLK = 1 sec in the ps
87     // so (PSXCLK / 75) / BIAS = cdr read time (linuzappz)
88     //#define cdReadTime ((PSXCLK / 75) / BIAS)
89     u32 cdReadTime;// = ((PSXCLK / 75) / BIAS);
90    
91     #define CDR_INT(eCycle) PSX_INT(IopEvt_Cdrom, eCycle)
92     #define CDREAD_INT(eCycle) PSX_INT(IopEvt_CdromRead, eCycle)
93    
94    
95     static void AddIrqQueue(u8 irq, u32 ecycle);
96    
97 william 62 static __fi void StartReading(u32 type) {
98 william 31 cdr.Reading = type;
99     cdr.FirstSector = 1;
100     cdr.Readed = 0xff;
101     AddIrqQueue(READ_ACK, 0x800);
102     }
103    
104 william 62 static __fi void StopReading() {
105 william 31 if (cdr.Reading) {
106     cdr.Reading = 0;
107     psxRegs.interrupt &= ~(1<<IopEvt_CdromRead);
108     }
109     }
110    
111 william 62 static __fi void StopCdda() {
112 william 31 if (cdr.Play) {
113     cdr.StatP&=~0x80;
114     cdr.Play = 0;
115     }
116     }
117    
118 william 62 static __fi void SetResultSize(u8 size) {
119 william 31 cdr.ResultP = 0;
120     cdr.ResultC = size;
121     cdr.ResultReady = 1;
122     }
123    
124     static void ReadTrack() {
125     cdr.Prev[0] = itob(cdr.SetSector[0]);
126     cdr.Prev[1] = itob(cdr.SetSector[1]);
127     cdr.Prev[2] = itob(cdr.SetSector[2]);
128    
129     CDVD_LOG("KEY *** %x:%x:%x", cdr.Prev[0], cdr.Prev[1], cdr.Prev[2]);
130     cdr.RErr = DoCDVDreadTrack(msf_to_lsn(cdr.SetSector), CDVD_MODE_2340);
131     }
132    
133     // cdr.Stat:
134     enum cdr_stat_values
135     {
136     NoIntr = 0,
137     DataReady,
138     Complete,
139     Acknowledge,
140     DataEnd,
141     DiskError
142     };
143    
144     static void AddIrqQueue(u8 irq, u32 ecycle) {
145     cdr.Irq = irq;
146     if (cdr.Stat) {
147     cdr.eCycle = ecycle;
148     } else {
149     CDR_INT(ecycle);
150     }
151     }
152    
153     void cdrInterrupt() {
154     cdvdTD trackInfo;
155     int i;
156     u8 Irq = cdr.Irq;
157    
158     if (cdr.Stat) {
159     CDR_INT(0x800);
160     return;
161     }
162    
163     cdr.Irq = 0xff;
164     cdr.Ctrl&=~0x80;
165    
166     switch (Irq) {
167     case CdlSync:
168     SetResultSize(1);
169     cdr.StatP|= 0x2;
170     cdr.Result[0] = cdr.StatP;
171     cdr.Stat = Acknowledge;
172     break;
173    
174     case CdlNop:
175     SetResultSize(1);
176     cdr.Result[0] = cdr.StatP;
177     cdr.Stat = Acknowledge;
178     break;
179    
180     case CdlSetloc:
181     cdr.CmdProcess = 0;
182     SetResultSize(1);
183     cdr.StatP|= 0x2;
184     cdr.Result[0] = cdr.StatP;
185     cdr.Stat = Acknowledge;
186     break;
187    
188     case CdlPlay:
189     cdr.CmdProcess = 0;
190     SetResultSize(1);
191     cdr.Result[0] = cdr.StatP;
192     cdr.Stat = Acknowledge;
193     cdr.StatP|= 0x82;
194     break;
195    
196     case CdlForward:
197     cdr.CmdProcess = 0;
198     SetResultSize(1);
199     cdr.StatP|= 0x2;
200     cdr.Result[0] = cdr.StatP;
201     cdr.Stat = Complete;
202     break;
203    
204     case CdlBackward:
205     cdr.CmdProcess = 0;
206     SetResultSize(1);
207     cdr.StatP|= 0x2;
208     cdr.Result[0] = cdr.StatP;
209     cdr.Stat = Complete;
210     break;
211    
212     case CdlStandby:
213     cdr.CmdProcess = 0;
214     SetResultSize(1);
215     cdr.StatP|= 0x2;
216     cdr.Result[0] = cdr.StatP;
217     cdr.Stat = Complete;
218     break;
219    
220     case CdlStop:
221     cdr.CmdProcess = 0;
222     SetResultSize(1);
223     cdr.StatP&=~0x2;
224     cdr.Result[0] = cdr.StatP;
225     cdr.Stat = Complete;
226     // cdr.Stat = Acknowledge;
227     break;
228    
229     case CdlPause:
230     SetResultSize(1);
231     cdr.Result[0] = cdr.StatP;
232     cdr.Stat = Acknowledge;
233     AddIrqQueue(CdlPause + 0x20, 0x800);
234     break;
235    
236     case CdlPause + 0x20:
237     SetResultSize(1);
238     cdr.StatP&=~0x20;
239     cdr.StatP|= 0x2;
240     cdr.Result[0] = cdr.StatP;
241     cdr.Stat = Complete;
242     break;
243    
244     case CdlInit:
245     SetResultSize(1);
246     cdr.StatP = 0x2;
247     cdr.Result[0] = cdr.StatP;
248     cdr.Stat = Acknowledge;
249     AddIrqQueue(CdlInit + 0x20, 0x800);
250     break;
251    
252     case CdlInit + 0x20:
253     SetResultSize(1);
254     cdr.Result[0] = cdr.StatP;
255     cdr.Stat = Complete;
256     cdr.Init = 1;
257     break;
258    
259     case CdlMute:
260     SetResultSize(1);
261     cdr.StatP|= 0x2;
262     cdr.Result[0] = cdr.StatP;
263     cdr.Stat = Acknowledge;
264     break;
265    
266     case CdlDemute:
267     SetResultSize(1);
268     cdr.StatP|= 0x2;
269     cdr.Result[0] = cdr.StatP;
270     cdr.Stat = Acknowledge;
271     break;
272    
273     case CdlSetfilter:
274     SetResultSize(1);
275     cdr.StatP|= 0x2;
276     cdr.Result[0] = cdr.StatP;
277     cdr.Stat = Acknowledge;
278     break;
279    
280     case CdlSetmode:
281     SetResultSize(1);
282     cdr.StatP|= 0x2;
283     cdr.Result[0] = cdr.StatP;
284     cdr.Stat = Acknowledge;
285     break;
286    
287     case CdlGetmode:
288     SetResultSize(6);
289     cdr.StatP|= 0x2;
290     cdr.Result[0] = cdr.StatP;
291     cdr.Result[1] = cdr.Mode;
292     cdr.Result[2] = cdr.File;
293     cdr.Result[3] = cdr.Channel;
294     cdr.Result[4] = 0;
295     cdr.Result[5] = 0;
296     cdr.Stat = Acknowledge;
297     break;
298    
299     case CdlGetlocL:
300     SetResultSize(8);
301     for (i=0; i<8; i++)
302     cdr.Result[i] = cdr.Transfer[i];
303     cdr.Stat = Acknowledge;
304     break;
305    
306     case CdlGetlocP:
307     SetResultSize(8);
308     cdr.Result[0] = 1;
309     cdr.Result[1] = 1;
310     cdr.Result[2] = cdr.Prev[0];
311     cdr.Result[3] = itob((btoi(cdr.Prev[1])) - 2);
312     cdr.Result[4] = cdr.Prev[2];
313     cdr.Result[5] = cdr.Prev[0];
314     cdr.Result[6] = cdr.Prev[1];
315     cdr.Result[7] = cdr.Prev[2];
316     cdr.Stat = Acknowledge;
317     break;
318    
319     case CdlGetTN:
320     cdr.CmdProcess = 0;
321     SetResultSize(3);
322     cdr.StatP|= 0x2;
323     cdr.Result[0] = cdr.StatP;
324     if (CDVD->getTN(&cdr.ResultTN) == -1) {
325     cdr.Stat = DiskError;
326     cdr.Result[0]|= 0x01;
327     } else {
328     cdr.Stat = Acknowledge;
329     cdr.Result[1] = itob(cdr.ResultTN.strack);
330     cdr.Result[2] = itob(cdr.ResultTN.etrack);
331     }
332     break;
333    
334     case CdlGetTD:
335     cdr.CmdProcess = 0;
336     cdr.Track = btoi(cdr.Param[0]);
337     SetResultSize(4);
338     cdr.StatP|= 0x2;
339     if (CDVD->getTD(cdr.Track, &trackInfo) == -1) {
340     cdr.Stat = DiskError;
341     cdr.Result[0]|= 0x01;
342     } else {
343     lsn_to_msf(cdr.ResultTD, trackInfo.lsn);
344     cdr.Stat = Acknowledge;
345     cdr.Result[0] = cdr.StatP;
346     cdr.Result[1] = cdr.ResultTD[2];
347     cdr.Result[2] = cdr.ResultTD[1];
348     cdr.Result[3] = cdr.ResultTD[0];
349     }
350     break;
351    
352     case CdlSeekL:
353     SetResultSize(1);
354     cdr.StatP|= 0x2;
355     cdr.Result[0] = cdr.StatP;
356     cdr.Stat = Acknowledge;
357     AddIrqQueue(CdlSeekL + 0x20, 0x800);
358     break;
359    
360     case CdlSeekL + 0x20:
361     SetResultSize(1);
362     cdr.StatP|= 0x2;
363     cdr.Result[0] = cdr.StatP;
364     cdr.Stat = Complete;
365     break;
366    
367     case CdlSeekP:
368     SetResultSize(1);
369     cdr.StatP|= 0x2;
370     cdr.Result[0] = cdr.StatP;
371     cdr.Stat = Acknowledge;
372     AddIrqQueue(CdlSeekP + 0x20, 0x800);
373     break;
374    
375     case CdlSeekP + 0x20:
376     SetResultSize(1);
377     cdr.StatP|= 0x2;
378     cdr.Result[0] = cdr.StatP;
379     cdr.Stat = Complete;
380     break;
381    
382     case CdlTest:
383     cdr.Stat = Acknowledge;
384     switch (cdr.Param[0]) {
385     case 0x20: // System Controller ROM Version
386     SetResultSize(4);
387     *(int*)cdr.Result = *(int*)Test20;
388     break;
389    
390     case 0x22:
391     SetResultSize(8);
392     *(int*)cdr.Result = *(int*)Test22;
393     break;
394    
395     case 0x23:
396     case 0x24:
397     SetResultSize(8);
398     *(int*)cdr.Result = *(int*)Test23;
399     break;
400     }
401     break;
402    
403     case CdlID:
404     SetResultSize(1);
405     cdr.StatP|= 0x2;
406     cdr.Result[0] = cdr.StatP;
407     cdr.Stat = Acknowledge;
408     AddIrqQueue(CdlID + 0x20, 0x800);
409     break;
410    
411     case CdlID + 0x20:
412     SetResultSize(8);
413     cdr.Result[0] = 0x00; // 0x08 and cdr.Result[1]|0x10 : audio cd, enters cd player
414     cdr.Result[1] = 0x00; // 0x80 leads to the menu in the bios, else loads CD
415    
416     if (!LoadCdBios) cdr.Result[1] |= 0x80;
417     cdr.Result[2] = 0x00;
418     cdr.Result[3] = 0x00;
419     strncpy((char *)&cdr.Result[4], "PCSX", 4);
420     cdr.Stat = Complete;
421     break;
422    
423     case CdlReset:
424     SetResultSize(1);
425     cdr.StatP = 0x2;
426     cdr.Result[0] = cdr.StatP;
427     cdr.Stat = Acknowledge;
428     break;
429    
430     case CdlReadToc:
431     SetResultSize(1);
432     cdr.StatP|= 0x2;
433     cdr.Result[0] = cdr.StatP;
434     cdr.Stat = Acknowledge;
435     AddIrqQueue(CdlReadToc + 0x20, 0x800);
436     break;
437    
438     case CdlReadToc + 0x20:
439     SetResultSize(1);
440     cdr.StatP|= 0x2;
441     cdr.Result[0] = cdr.StatP;
442     cdr.Stat = Complete;
443     break;
444    
445     case AUTOPAUSE:
446     cdr.OCUP = 0;
447     AddIrqQueue(CdlPause, 0x400);
448     break;
449    
450     case READ_ACK:
451     if (!cdr.Reading) return;
452    
453     SetResultSize(1);
454     cdr.StatP|= 0x2;
455     cdr.Result[0] = cdr.StatP;
456     cdr.Stat = Acknowledge;
457    
458     ReadTrack();
459    
460     CDREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime);
461    
462     break;
463    
464     case REPPLAY_ACK:
465     cdr.Stat = Acknowledge;
466     cdr.Result[0] = cdr.StatP;
467     SetResultSize(1);
468     AddIrqQueue(REPPLAY, cdReadTime);
469     break;
470    
471     case REPPLAY:
472     //if ((cdr.Mode & 5) != 5) break;
473     break;
474    
475     case 0xff:
476     return;
477    
478     default:
479     cdr.Stat = Complete;
480     break;
481     }
482    
483     if (cdr.Stat != NoIntr && cdr.Reg2 != 0x18)
484     psxHu32(0x1070)|= 0x4;
485    
486     CDVD_LOG("Cdr Interrupt %x\n", Irq);
487     }
488    
489     void cdrReadInterrupt() {
490    
491     if (!cdr.Reading)
492     return;
493    
494     if (cdr.Stat) {
495     CDREAD_INT(0x800);
496     return;
497     }
498    
499     CDVD_LOG("KEY END");
500    
501     cdr.OCUP = 1;
502     SetResultSize(1);
503     cdr.StatP|= 0x22;
504     cdr.Result[0] = cdr.StatP;
505    
506     if( cdr.RErr == 0 )
507     {
508     while( (cdr.RErr = DoCDVDgetBuffer(cdr.Transfer)), cdr.RErr == -2 )
509     {
510     // not finished yet ... block on the read until it finishes.
511     Threading::Sleep( 0 );
512     Threading::SpinWait();
513     }
514     }
515    
516     if (cdr.RErr == -1)
517     {
518     CDVD_LOG(" err\n");
519     memzero(cdr.Transfer);
520     cdr.Stat = DiskError;
521     cdr.Result[0] |= 0x01;
522     ReadTrack();
523     CDREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime);
524     return;
525     }
526    
527     cdr.Stat = DataReady;
528    
529     CDVD_LOG(" %x:%x:%x", cdr.Transfer[0], cdr.Transfer[1], cdr.Transfer[2]);
530    
531     cdr.SetSector[2]++;
532    
533     if (cdr.SetSector[2] == 75) {
534     cdr.SetSector[2] = 0;
535     cdr.SetSector[1]++;
536     if (cdr.SetSector[1] == 60) {
537     cdr.SetSector[1] = 0;
538     cdr.SetSector[0]++;
539     }
540     }
541    
542     cdr.Readed = 0;
543    
544     if ((cdr.Transfer[4+2] & 0x80) && (cdr.Mode & 0x2)) { // EOF
545     CDVD_LOG("AutoPausing Read");
546     AddIrqQueue(CdlPause, 0x800);
547     }
548     else {
549     ReadTrack();
550     CDREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime);
551     }
552    
553     psxHu32(0x1070)|= 0x4;
554     return;
555     }
556    
557     /*
558     cdrRead0:
559     bit 0 - 0 REG1 command send / 1 REG1 data read
560     bit 1 - 0 data transfer finish / 1 data transfer ready/in progress
561     bit 2 - unknown
562     bit 3 - unknown
563     bit 4 - unknown
564     bit 5 - 1 result ready
565     bit 6 - 1 dma ready
566     bit 7 - 1 command being processed
567     */
568    
569     u8 cdrRead0(void) {
570     if (cdr.ResultReady)
571     cdr.Ctrl |= 0x20;
572     else
573     cdr.Ctrl &= ~0x20;
574    
575     if (cdr.OCUP)
576     cdr.Ctrl |= 0x40;
577     else
578     cdr.Ctrl &= ~0x40;
579    
580     // what means the 0x10 and the 0x08 bits? i only saw it used by the bios
581     cdr.Ctrl|=0x18;
582    
583     CDVD_LOG("CD0 Read: %x", cdr.Ctrl);
584     return psxHu8(0x1800) = cdr.Ctrl;
585     }
586    
587     /*
588     cdrWrite0:
589     0 - to send a command / 1 - to get the result
590     */
591    
592     void cdrWrite0(u8 rt) {
593     CDVD_LOG("CD0 write: %x", rt);
594    
595     cdr.Ctrl = rt | (cdr.Ctrl & ~0x3);
596    
597     if (rt == 0) {
598     cdr.ParamP = 0;
599     cdr.ParamC = 0;
600     cdr.ResultReady = 0;
601     }
602     }
603    
604     u8 cdrRead1(void) {
605     if (cdr.ResultReady && cdr.Ctrl & 0x1) {
606     psxHu8(0x1801) = cdr.Result[cdr.ResultP++];
607     if (cdr.ResultP == cdr.ResultC) cdr.ResultReady = 0;
608     }
609     else
610     psxHu8(0x1801) = 0;
611    
612     CDVD_LOG("CD1 Read: %x", psxHu8(0x1801));
613     return psxHu8(0x1801);
614     }
615    
616     void cdrWrite1(u8 rt) {
617     int i;
618    
619     CDVD_LOG("CD1 write: %x (%s)", rt, CmdName[rt]);
620     cdr.Cmd = rt;
621     cdr.OCUP = 0;
622    
623     #ifdef CDRCMD_DEBUG
624     SysPrintf("CD1 write: %x (%s)", rt, CmdName[rt]);
625     if (cdr.ParamC) {
626     SysPrintf(" Param[%d] = {", cdr.ParamC);
627     for (i=0;i<cdr.ParamC;i++) SysPrintf(" %x,", cdr.Param[i]);
628     SysPrintf("}\n");
629     } else SysPrintf("\n");
630     #endif
631    
632     if (cdr.Ctrl & 0x1) return;
633    
634     switch(cdr.Cmd) {
635     case CdlSync:
636     cdr.Ctrl|= 0x80;
637     cdr.Stat = NoIntr;
638     AddIrqQueue(cdr.Cmd, 0x800);
639     break;
640    
641     case CdlNop:
642     cdr.Ctrl|= 0x80;
643     cdr.Stat = NoIntr;
644     AddIrqQueue(cdr.Cmd, 0x800);
645     break;
646    
647     case CdlSetloc:
648     StopReading();
649     for (i=0; i<3; i++) cdr.SetSector[i] = btoi(cdr.Param[i]);
650     cdr.SetSector[3] = 0;
651     if ((cdr.SetSector[0] | cdr.SetSector[1] | cdr.SetSector[2]) == 0) {
652     *(u32 *)cdr.SetSector = *(u32 *)cdr.SetSectorSeek;
653     }
654     cdr.Ctrl|= 0x80;
655     cdr.Stat = NoIntr;
656     AddIrqQueue(cdr.Cmd, 0x800);
657     break;
658    
659     case CdlPlay:
660     cdr.Play = 1;
661     cdr.Ctrl|= 0x80;
662     cdr.Stat = NoIntr;
663     AddIrqQueue(cdr.Cmd, 0x800);
664     break;
665    
666     case CdlForward:
667     if (cdr.CurTrack < 0xaa) cdr.CurTrack++;
668     cdr.Ctrl|= 0x80;
669     cdr.Stat = NoIntr;
670     AddIrqQueue(cdr.Cmd, 0x800);
671     break;
672    
673     case CdlBackward:
674     if (cdr.CurTrack > 1) cdr.CurTrack--;
675     cdr.Ctrl|= 0x80;
676     cdr.Stat = NoIntr;
677     AddIrqQueue(cdr.Cmd, 0x800);
678     break;
679    
680     case CdlReadN:
681     cdr.Irq = 0;
682     StopReading();
683     cdr.Ctrl|= 0x80;
684     cdr.Stat = NoIntr;
685     StartReading(1);
686     break;
687    
688     case CdlStandby:
689     StopCdda();
690     StopReading();
691     cdr.Ctrl|= 0x80;
692     cdr.Stat = NoIntr;
693     AddIrqQueue(cdr.Cmd, 0x800);
694     break;
695    
696     case CdlStop:
697     StopCdda();
698     StopReading();
699     cdr.Ctrl|= 0x80;
700     cdr.Stat = NoIntr;
701     AddIrqQueue(cdr.Cmd, 0x800);
702     break;
703    
704     case CdlPause:
705     StopCdda();
706     StopReading();
707     cdr.Ctrl|= 0x80;
708     cdr.Stat = NoIntr;
709     AddIrqQueue(cdr.Cmd, 0x40000);
710     break;
711    
712     case CdlReset:
713     case CdlInit:
714     StopCdda();
715     StopReading();
716     cdr.Ctrl|= 0x80;
717     cdr.Stat = NoIntr;
718     AddIrqQueue(cdr.Cmd, 0x800);
719     break;
720    
721     case CdlMute:
722     cdr.Muted = 0;
723     cdr.Ctrl|= 0x80;
724     cdr.Stat = NoIntr;
725     AddIrqQueue(cdr.Cmd, 0x800);
726     break;
727    
728     case CdlDemute:
729     cdr.Muted = 1;
730     cdr.Ctrl|= 0x80;
731     cdr.Stat = NoIntr;
732     AddIrqQueue(cdr.Cmd, 0x800);
733     break;
734    
735     case CdlSetfilter:
736     cdr.File = cdr.Param[0];
737     cdr.Channel = cdr.Param[1];
738     cdr.Ctrl|= 0x80;
739     cdr.Stat = NoIntr;
740     AddIrqQueue(cdr.Cmd, 0x800);
741     break;
742    
743     case CdlSetmode:
744     CDVD_LOG("Setmode %x", cdr.Param[0]);
745    
746     cdr.Mode = cdr.Param[0];
747     cdr.Ctrl|= 0x80;
748     cdr.Stat = NoIntr;
749     AddIrqQueue(cdr.Cmd, 0x800);
750     break;
751    
752     case CdlGetmode:
753     cdr.Ctrl|= 0x80;
754     cdr.Stat = NoIntr;
755     AddIrqQueue(cdr.Cmd, 0x800);
756     break;
757    
758     case CdlGetlocL:
759     cdr.Ctrl|= 0x80;
760     cdr.Stat = NoIntr;
761     AddIrqQueue(cdr.Cmd, 0x800);
762     break;
763    
764     case CdlGetlocP:
765     cdr.Ctrl|= 0x80;
766     cdr.Stat = NoIntr;
767     AddIrqQueue(cdr.Cmd, 0x800);
768     break;
769    
770     case CdlGetTN:
771     cdr.Ctrl|= 0x80;
772     cdr.Stat = NoIntr;
773     AddIrqQueue(cdr.Cmd, 0x800);
774     break;
775    
776     case CdlGetTD:
777     cdr.Ctrl|= 0x80;
778     cdr.Stat = NoIntr;
779     AddIrqQueue(cdr.Cmd, 0x800);
780     break;
781    
782     case CdlSeekL:
783     ((u32 *)cdr.SetSectorSeek)[0] = ((u32 *)cdr.SetSector)[0];
784     cdr.Ctrl|= 0x80;
785     cdr.Stat = NoIntr;
786     AddIrqQueue(cdr.Cmd, 0x800);
787     break;
788    
789     case CdlSeekP:
790     ((u32 *)cdr.SetSectorSeek)[0] = ((u32 *)cdr.SetSector)[0];
791     cdr.Ctrl|= 0x80;
792     cdr.Stat = NoIntr;
793     AddIrqQueue(cdr.Cmd, 0x800);
794     break;
795    
796     case CdlTest:
797     cdr.Ctrl|= 0x80;
798     cdr.Stat = NoIntr;
799     AddIrqQueue(cdr.Cmd, 0x800);
800     break;
801    
802     case CdlID:
803     cdr.Ctrl|= 0x80;
804     cdr.Stat = NoIntr;
805     AddIrqQueue(cdr.Cmd, 0x800);
806     break;
807    
808     case CdlReadS:
809     cdr.Irq = 0;
810     StopReading();
811     cdr.Ctrl|= 0x80;
812     cdr.Stat = NoIntr;
813     StartReading(2);
814     break;
815    
816     case CdlReadToc:
817     cdr.Ctrl|= 0x80;
818     cdr.Stat = NoIntr;
819     AddIrqQueue(cdr.Cmd, 0x800);
820     break;
821    
822     default:
823     CDVD_LOG("Unknown Cmd: %x\n", cdr.Cmd);
824     return;
825     }
826     if (cdr.Stat != NoIntr)
827     iopIntcIrq( 2 );
828     }
829    
830     u8 cdrRead2(void) {
831     u8 ret;
832    
833     if (cdr.Readed == 0) {
834     ret = 0;
835     } else {
836     ret = *cdr.pTransfer++;
837     }
838    
839     CDVD_LOG("CD2 Read: %x", ret);
840     return ret;
841     }
842    
843     void cdrWrite2(u8 rt) {
844     CDVD_LOG("CD2 write: %x", rt);
845    
846     if (cdr.Ctrl & 0x1) {
847     switch (rt) {
848     case 0x07:
849     cdr.ParamP = 0;
850     cdr.ParamC = 0;
851     cdr.ResultReady = 0;
852     cdr.Ctrl = 0;
853     break;
854    
855     default:
856     cdr.Reg2 = rt;
857     break;
858     }
859     }
860     else
861     {
862     if (!(cdr.Ctrl & 0x1) && cdr.ParamP < 8) {
863     cdr.Param[cdr.ParamP++] = rt;
864     cdr.ParamC++;
865     }
866     }
867     }
868    
869     u8 cdrRead3(void) {
870     if (cdr.Stat) {
871     if (cdr.Ctrl & 0x1)
872     psxHu8(0x1803) = cdr.Stat | 0xE0;
873     else
874     psxHu8(0x1803) = 0xff;
875     } else psxHu8(0x1803) = 0;
876    
877     CDVD_LOG("CD3 Read: %x", psxHu8(0x1803));
878     return psxHu8(0x1803);
879     }
880    
881     void cdrWrite3(u8 rt) {
882     CDVD_LOG("CD3 write: %x", rt);
883    
884     if (rt == 0x07 && cdr.Ctrl & 0x1) {
885     cdr.Stat = 0;
886    
887     if (cdr.Irq == 0xff) { cdr.Irq = 0; return; }
888     if (cdr.Irq) {
889     CDR_INT(cdr.eCycle);
890     }
891     return;
892     }
893    
894     if (rt == 0x80 && !(cdr.Ctrl & 0x1) && cdr.Readed == 0) {
895     cdr.Readed = 1;
896     cdr.pTransfer = cdr.Transfer;
897    
898     switch (cdr.Mode&0x30) {
899     case 0x10:
900     case 0x00: cdr.pTransfer+=12; break;
901     default: break;
902     }
903     }
904     }
905    
906     void psxDma3(u32 madr, u32 bcr, u32 chcr) {
907     u32 cdsize;
908    
909     CDVD_LOG("*** DMA 3 *** %lx addr = %lx size = %lx", chcr, madr, bcr);
910    
911     switch (chcr) {
912     case 0x11000000:
913     case 0x11400100:
914     if (cdr.Readed == 0) {
915     CDVD_LOG("*** DMA 3 *** NOT READY");
916     return;
917     }
918    
919     cdsize = (bcr & 0xffff) * 4;
920     memcpy_fast(iopPhysMem(madr), cdr.pTransfer, cdsize);
921     psxCpu->Clear(madr, cdsize/4);
922     cdr.pTransfer+=cdsize;
923    
924     break;
925     case 0x41000200:
926     //SysPrintf("unhandled cdrom dma3: madr: %x, bcr: %x, chcr %x\n", madr, bcr, chcr);
927     return;
928    
929     default:
930     CDVD_LOG("Unknown cddma %lx", chcr);
931     break;
932     }
933     HW_DMA3_CHCR &= ~0x01000000;
934     psxDmaInterrupt(3);
935     }
936    
937     #ifdef ENABLE_NEW_IOPDMA
938     s32 CALLBACK cdvdDmaRead(s32 channel, u32* data, u32 bytesLeft, u32* bytesProcessed)
939     {
940     #ifdef ENABLE_NEW_IOPDMA_CDVD
941     // hacked up from the code above
942    
943     if (cdr.Readed == 0)
944     {
945     //CDVD_LOG("*** DMA 3 *** NOT READY");
946     wordsProcessed = 0;
947     return 10000;
948     }
949    
950     memcpy_fast(data, cdr.pTransfer, wordsLeft);
951     //psxCpu->Clear(madr, cdsize/4);
952     cdr.pTransfer+=wordsLeft;
953     *wordsProcessed = wordsLeft;
954    
955     Console.WriteLn(Color_Black,"New IOP DMA handled CDVD DMA: channel %d, data %p, remaining %08x, processed %08x.", channel,data,wordsLeft, *wordsProcessed);
956     #endif
957     return 0;
958     }
959    
960     void CALLBACK cdvdDmaInterrupt(s32 channel)
961     {
962     #ifdef ENABLE_NEW_IOPDMA_CDVD
963     cdrInterrupt();
964     #endif
965     }
966    
967     #endif
968    
969     void cdrReset() {
970     memzero(cdr);
971     cdr.CurTrack=1;
972     cdr.File=1; cdr.Channel=1;
973     cdReadTime = (PSXCLK / 1757) * BIAS;
974     }
975    
976     void SaveStateBase::cdrFreeze()
977     {
978     FreezeTag( "cdrom" );
979     Freeze(cdr);
980     }
981    

  ViewVC Help
Powered by ViewVC 1.1.22