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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (show annotations) (download)
Tue Sep 7 03:24:11 2010 UTC (10 years, 7 months ago) by william
File size: 19570 byte(s)
committing r3113 initial commit again...
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
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 static __forceinline void StartReading(u32 type) {
98 cdr.Reading = type;
99 cdr.FirstSector = 1;
100 cdr.Readed = 0xff;
101 AddIrqQueue(READ_ACK, 0x800);
102 }
103
104 static __forceinline void StopReading() {
105 if (cdr.Reading) {
106 cdr.Reading = 0;
107 psxRegs.interrupt &= ~(1<<IopEvt_CdromRead);
108 }
109 }
110
111 static __forceinline void StopCdda() {
112 if (cdr.Play) {
113 cdr.StatP&=~0x80;
114 cdr.Play = 0;
115 }
116 }
117
118 static __forceinline void SetResultSize(u8 size) {
119 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