bugfixes, CD swap, autorepeat
[picodrive.git] / Pico / cd / cd_sys.c
CommitLineData
cc68a136 1#include <stdio.h>\r
2#include "cd_sys.h"\r
bf098bc5 3#include "cd_file.h"\r
cc68a136 4\r
5#include "../PicoInt.h"\r
6\r
c459aefd 7#define cdprintf dprintf\r
cc68a136 8//#define cdprintf(x...)\r
c459aefd 9#define DEBUG_CD\r
cc68a136 10\r
11#define TRAY_OPEN 0x0500 // TRAY OPEN CDD status\r
12#define NOCD 0x0000 // CD removed CDD status\r
13#define STOPPED 0x0900 // STOPPED CDD status (happen after stop or close tray command)\r
14#define READY 0x0400 // READY CDD status (also used for seeking)\r
15#define FAST_FOW 0x0300 // FAST FORWARD track CDD status\r
16#define FAST_REV 0x10300 // FAST REVERSE track CDD status\r
17#define PLAYING 0x0100 // PLAYING audio track CDD status\r
18\r
cc68a136 19\r
20/*\r
21int CDDA_Enable;\r
22\r
23int CD_Audio_Buffer_L[8192];\r
24int CD_Audio_Buffer_R[8192];\r
25int CD_Audio_Buffer_Read_Pos = 0;\r
26int CD_Audio_Buffer_Write_Pos = 2000;\r
27int CD_Audio_Starting;\r
28*/\r
29\r
30static int CD_Present = 0;\r
51a902ae 31// int CD_Timer_Counter = 0; // TODO: check refs\r
cc68a136 32\r
cc68a136 33\r
34\r
35#define CHECK_TRAY_OPEN \\r
36if (Pico_mcd->scd.Status_CDD == TRAY_OPEN) \\r
37{ \\r
38 Pico_mcd->cdd.Status = Pico_mcd->scd.Status_CDD; \\r
39 \\r
40 Pico_mcd->cdd.Minute = 0; \\r
41 Pico_mcd->cdd.Seconde = 0; \\r
42 Pico_mcd->cdd.Frame = 0; \\r
43 Pico_mcd->cdd.Ext = 0; \\r
44 \\r
51a902ae 45 Pico_mcd->scd.CDD_Complete = 1; \\r
cc68a136 46 \\r
47 return 2; \\r
48}\r
49\r
50\r
51#define CHECK_CD_PRESENT \\r
52if (!CD_Present) \\r
53{ \\r
54 Pico_mcd->scd.Status_CDD = NOCD; \\r
55 Pico_mcd->cdd.Status = Pico_mcd->scd.Status_CDD; \\r
56 \\r
57 Pico_mcd->cdd.Minute = 0; \\r
58 Pico_mcd->cdd.Seconde = 0; \\r
59 Pico_mcd->cdd.Frame = 0; \\r
60 Pico_mcd->cdd.Ext = 0; \\r
61 \\r
51a902ae 62 Pico_mcd->scd.CDD_Complete = 1; \\r
cc68a136 63 \\r
64 return 3; \\r
65}\r
66\r
67\r
68#if 0\r
69static void MSB2DWORD(unsigned int *d, unsigned char *b)\r
70{\r
71 unsigned int retVal;\r
72\r
73 retVal = (unsigned int )b[0];\r
74 retVal = (retVal<<8) + (unsigned int )b[1];\r
75 retVal = (retVal<<8) + (unsigned int )b[2];\r
76 retVal = (retVal<<8) + (unsigned int )b[3];\r
77\r
78 *d = retVal;\r
79}\r
80#endif\r
81\r
82static int MSF_to_LBA(_msf *MSF)\r
83{\r
84 return (MSF->M * 60 * 75) + (MSF->S * 75) + MSF->F - 150;\r
85}\r
86\r
87\r
88void LBA_to_MSF(int lba, _msf *MSF)\r
89{\r
90 if (lba < -150) lba = 0;\r
91 else lba += 150;\r
92 MSF->M = lba / (60 * 75);\r
93 MSF->S = (lba / 75) % 60;\r
94 MSF->F = lba % 75;\r
95}\r
96\r
97\r
98static unsigned int MSF_to_Track(_msf *MSF)\r
99{\r
100 int i, Start, Cur;\r
101\r
102 Start = (MSF->M << 16) + (MSF->S << 8) + MSF->F;\r
103\r
75736070 104 for(i = 1; i <= (Pico_mcd->TOC.Last_Track + 1); i++)\r
cc68a136 105 {\r
75736070 106 Cur = Pico_mcd->TOC.Tracks[i - 1].MSF.M << 16;\r
107 Cur += Pico_mcd->TOC.Tracks[i - 1].MSF.S << 8;\r
108 Cur += Pico_mcd->TOC.Tracks[i - 1].MSF.F;\r
cc68a136 109\r
110 if (Cur > Start) break;\r
111 }\r
112\r
113 --i;\r
114\r
75736070 115 if (i > Pico_mcd->TOC.Last_Track) return 100;\r
116 else if (i < 1) i = 1;\r
cc68a136 117\r
118 return (unsigned) i;\r
119}\r
120\r
121\r
122static unsigned int LBA_to_Track(int lba)\r
123{\r
124 _msf MSF;\r
125\r
126 LBA_to_MSF(lba, &MSF);\r
127 return MSF_to_Track(&MSF);\r
128}\r
129\r
130\r
131static void Track_to_MSF(int track, _msf *MSF)\r
132{\r
75736070 133 if (track < 1) track = 1;\r
134 else if (track > Pico_mcd->TOC.Last_Track) track = Pico_mcd->TOC.Last_Track;\r
cc68a136 135\r
75736070 136 MSF->M = Pico_mcd->TOC.Tracks[track - 1].MSF.M;\r
137 MSF->S = Pico_mcd->TOC.Tracks[track - 1].MSF.S;\r
138 MSF->F = Pico_mcd->TOC.Tracks[track - 1].MSF.F;\r
cc68a136 139}\r
140\r
141\r
142int Track_to_LBA(int track)\r
143{\r
144 _msf MSF;\r
145\r
146 Track_to_MSF(track, &MSF);\r
147 return MSF_to_LBA(&MSF);\r
148}\r
149\r
150\r
151void Check_CD_Command(void)\r
152{\r
c459aefd 153 cdprintf("CHECK CD COMMAND");\r
cc68a136 154\r
cc68a136 155 // Check CDC\r
cc68a136 156 if (Pico_mcd->scd.Status_CDC & 1) // CDC is reading data ...\r
157 {\r
c459aefd 158 cdprintf("Got a read command");\r
cc68a136 159\r
160 // DATA ?\r
75736070 161 if (Pico_mcd->scd.Cur_Track == 1)\r
cc68a136 162 Pico_mcd->s68k_regs[0x36] |= 0x01;\r
163 else Pico_mcd->s68k_regs[0x36] &= ~0x01; // AUDIO\r
164\r
51a902ae 165 if (Pico_mcd->scd.File_Add_Delay == 0)\r
cc68a136 166 {\r
cc68a136 167 FILE_Read_One_LBA_CDC();\r
cc68a136 168 }\r
51a902ae 169 else Pico_mcd->scd.File_Add_Delay--;\r
cc68a136 170 }\r
171\r
1cd356a3 172 // Check CDD\r
173 if (Pico_mcd->scd.CDD_Complete)\r
174 {\r
175 Pico_mcd->scd.CDD_Complete = 0;\r
176\r
177 CDD_Export_Status();\r
178 }\r
179\r
cc68a136 180 if (Pico_mcd->scd.Status_CDD == FAST_FOW)\r
181 {\r
182 Pico_mcd->scd.Cur_LBA += 10;\r
183 CDC_Update_Header();\r
184\r
185 }\r
186 else if (Pico_mcd->scd.Status_CDD == FAST_REV)\r
187 {\r
188 Pico_mcd->scd.Cur_LBA -= 10;\r
189 if (Pico_mcd->scd.Cur_LBA < -150) Pico_mcd->scd.Cur_LBA = -150;\r
190 CDC_Update_Header();\r
191 }\r
192}\r
193\r
194\r
195int Init_CD_Driver(void)\r
196{\r
cc68a136 197 return 0;\r
198}\r
199\r
200\r
201void End_CD_Driver(void)\r
202{\r
cc68a136 203 FILE_End();\r
cc68a136 204}\r
205\r
206\r
207void Reset_CD(void)\r
208{\r
209 Pico_mcd->scd.Cur_Track = 0;\r
210 Pico_mcd->scd.Cur_LBA = -150;\r
5c69a605 211 Pico_mcd->scd.Status_CDC &= ~1;\r
721cd396 212 Pico_mcd->scd.Status_CDD = CD_Present ? READY : NOCD;\r
51a902ae 213 Pico_mcd->scd.CDD_Complete = 0;\r
5c69a605 214 Pico_mcd->scd.File_Add_Delay = 0;\r
cc68a136 215}\r
216\r
217\r
bf098bc5 218int Insert_CD(char *iso_name, int is_bin)\r
cc68a136 219{\r
bf098bc5 220 int ret = 0;\r
221\r
cc68a136 222// memset(CD_Audio_Buffer_L, 0, 4096 * 4);\r
223// memset(CD_Audio_Buffer_R, 0, 4096 * 4);\r
224\r
bf098bc5 225 CD_Present = 0;\r
721cd396 226 Pico_mcd->scd.Status_CDD = NOCD;\r
bf098bc5 227\r
228 if (iso_name != NULL)\r
cc68a136 229 {\r
bf098bc5 230 ret = Load_ISO(iso_name, is_bin);\r
721cd396 231 if (ret == 0) {\r
bf098bc5 232 CD_Present = 1;\r
721cd396 233 Pico_mcd->scd.Status_CDD = READY;\r
234 }\r
cc68a136 235 }\r
236\r
bf098bc5 237 return ret;\r
cc68a136 238}\r
239\r
240\r
241void Stop_CD(void)\r
242{\r
cc68a136 243 Unload_ISO();\r
cc68a136 244 CD_Present = 0;\r
245}\r
246\r
247\r
248void Change_CD(void)\r
249{\r
250 if (Pico_mcd->scd.Status_CDD == TRAY_OPEN) Close_Tray_CDD_cC();\r
251 else Open_Tray_CDD_cD();\r
252}\r
253\r
254\r
255int Get_Status_CDD_c0(void)\r
256{\r
c459aefd 257 cdprintf("Status command : Cur LBA = %d", Pico_mcd->scd.Cur_LBA);\r
cc68a136 258\r
259 // Clear immediat status\r
260 if ((Pico_mcd->cdd.Status & 0x0F00) == 0x0200)\r
261 Pico_mcd->cdd.Status = (Pico_mcd->scd.Status_CDD & 0xFF00) | (Pico_mcd->cdd.Status & 0x00FF);\r
262 else if ((Pico_mcd->cdd.Status & 0x0F00) == 0x0700)\r
263 Pico_mcd->cdd.Status = (Pico_mcd->scd.Status_CDD & 0xFF00) | (Pico_mcd->cdd.Status & 0x00FF);\r
264 else if ((Pico_mcd->cdd.Status & 0x0F00) == 0x0E00)\r
265 Pico_mcd->cdd.Status = (Pico_mcd->scd.Status_CDD & 0xFF00) | (Pico_mcd->cdd.Status & 0x00FF);\r
266\r
51a902ae 267 Pico_mcd->scd.CDD_Complete = 1;\r
cc68a136 268\r
269 return 0;\r
270}\r
271\r
272\r
273int Stop_CDD_c1(void)\r
274{\r
275 CHECK_TRAY_OPEN\r
276\r
277 Pico_mcd->scd.Status_CDC &= ~1; // Stop CDC read\r
278\r
279 if (CD_Present) Pico_mcd->scd.Status_CDD = STOPPED;\r
280 else Pico_mcd->scd.Status_CDD = NOCD;\r
281 Pico_mcd->cdd.Status = 0x0000;\r
282\r
283 Pico_mcd->s68k_regs[0x36] |= 0x01; // Data bit set because stopped\r
284\r
285 Pico_mcd->cdd.Minute = 0;\r
286 Pico_mcd->cdd.Seconde = 0;\r
287 Pico_mcd->cdd.Frame = 0;\r
288 Pico_mcd->cdd.Ext = 0;\r
289\r
51a902ae 290 Pico_mcd->scd.CDD_Complete = 1;\r
cc68a136 291\r
292 return 0;\r
293}\r
294\r
295\r
296int Get_Pos_CDD_c20(void)\r
297{\r
298 _msf MSF;\r
299\r
c459aefd 300 cdprintf("command 200 : Cur LBA = %d", Pico_mcd->scd.Cur_LBA);\r
cc68a136 301\r
302 CHECK_TRAY_OPEN\r
303\r
304 Pico_mcd->cdd.Status &= 0xFF;\r
305 if (!CD_Present)\r
306 {\r
307 Pico_mcd->scd.Status_CDD = NOCD;\r
308 Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
309 }\r
310// else if (!(CDC.CTRL.B.B0 & 0x80)) Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
311 Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
312\r
c459aefd 313 cdprintf("Status CDD = %.4X Status = %.4X", Pico_mcd->scd.Status_CDD, Pico_mcd->cdd.Status);\r
cc68a136 314\r
315 LBA_to_MSF(Pico_mcd->scd.Cur_LBA, &MSF);\r
316\r
317 Pico_mcd->cdd.Minute = INT_TO_BCDW(MSF.M);\r
318 Pico_mcd->cdd.Seconde = INT_TO_BCDW(MSF.S);\r
319 Pico_mcd->cdd.Frame = INT_TO_BCDW(MSF.F);\r
320 Pico_mcd->cdd.Ext = 0;\r
321\r
51a902ae 322 Pico_mcd->scd.CDD_Complete = 1;\r
cc68a136 323\r
324 return 0;\r
325}\r
326\r
327\r
328int Get_Track_Pos_CDD_c21(void)\r
329{\r
330 int elapsed_time;\r
331 _msf MSF;\r
332\r
333 cdprintf("command 201 : Cur LBA = %d", Pico_mcd->scd.Cur_LBA);\r
334\r
335 CHECK_TRAY_OPEN\r
336\r
337 Pico_mcd->cdd.Status &= 0xFF;\r
338 if (!CD_Present)\r
339 {\r
340 Pico_mcd->scd.Status_CDD = NOCD;\r
341 Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
342 }\r
343// else if (!(CDC.CTRL.B.B0 & 0x80)) Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
344 Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
345\r
346 elapsed_time = Pico_mcd->scd.Cur_LBA - Track_to_LBA(LBA_to_Track(Pico_mcd->scd.Cur_LBA));\r
347 LBA_to_MSF(elapsed_time - 150, &MSF);\r
348\r
c459aefd 349 cdprintf(" elapsed = %d", elapsed_time);\r
cc68a136 350\r
351 Pico_mcd->cdd.Minute = INT_TO_BCDW(MSF.M);\r
352 Pico_mcd->cdd.Seconde = INT_TO_BCDW(MSF.S);\r
353 Pico_mcd->cdd.Frame = INT_TO_BCDW(MSF.F);\r
354 Pico_mcd->cdd.Ext = 0;\r
355\r
51a902ae 356 Pico_mcd->scd.CDD_Complete = 1;\r
cc68a136 357\r
358 return 0;\r
359}\r
360\r
361\r
362int Get_Current_Track_CDD_c22(void)\r
363{\r
c459aefd 364 cdprintf("Status CDD = %.4X Status = %.4X", Pico_mcd->scd.Status_CDD, Pico_mcd->cdd.Status);\r
cc68a136 365\r
366 CHECK_TRAY_OPEN\r
367\r
368 Pico_mcd->cdd.Status &= 0xFF;\r
369 if (!CD_Present)\r
370 {\r
371 Pico_mcd->scd.Status_CDD = NOCD;\r
372 Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
373 }\r
374// else if (!(CDC.CTRL.B.B0 & 0x80)) Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
375 Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
376\r
377 Pico_mcd->scd.Cur_Track = LBA_to_Track(Pico_mcd->scd.Cur_LBA);\r
378\r
379 if (Pico_mcd->scd.Cur_Track == 100) Pico_mcd->cdd.Minute = 0x0A02;\r
380 else Pico_mcd->cdd.Minute = INT_TO_BCDW(Pico_mcd->scd.Cur_Track);\r
381 Pico_mcd->cdd.Seconde = 0;\r
382 Pico_mcd->cdd.Frame = 0;\r
383 Pico_mcd->cdd.Ext = 0;\r
384\r
51a902ae 385 Pico_mcd->scd.CDD_Complete = 1;\r
cc68a136 386\r
387 return 0;\r
388}\r
389\r
390\r
391int Get_Total_Lenght_CDD_c23(void)\r
392{\r
393 CHECK_TRAY_OPEN\r
394\r
395 Pico_mcd->cdd.Status &= 0xFF;\r
396 if (!CD_Present)\r
397 {\r
398 Pico_mcd->scd.Status_CDD = NOCD;\r
399 Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
400 }\r
401// else if (!(CDC.CTRL.B.B0 & 0x80)) Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
402 Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
403\r
75736070 404 Pico_mcd->cdd.Minute = INT_TO_BCDW(Pico_mcd->TOC.Tracks[Pico_mcd->TOC.Last_Track].MSF.M);\r
405 Pico_mcd->cdd.Seconde = INT_TO_BCDW(Pico_mcd->TOC.Tracks[Pico_mcd->TOC.Last_Track].MSF.S);\r
406 Pico_mcd->cdd.Frame = INT_TO_BCDW(Pico_mcd->TOC.Tracks[Pico_mcd->TOC.Last_Track].MSF.F);\r
cc68a136 407 Pico_mcd->cdd.Ext = 0;\r
408\r
51a902ae 409 Pico_mcd->scd.CDD_Complete = 1;\r
cc68a136 410\r
411 return 0;\r
412}\r
413\r
414\r
415int Get_First_Last_Track_CDD_c24(void)\r
416{\r
417 CHECK_TRAY_OPEN\r
418\r
419 Pico_mcd->cdd.Status &= 0xFF;\r
420 if (!CD_Present)\r
421 {\r
422 Pico_mcd->scd.Status_CDD = NOCD;\r
423 }\r
424// else if (!(CDC.CTRL.B.B0 & 0x80)) Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
425 Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
426\r
75736070 427 Pico_mcd->cdd.Minute = INT_TO_BCDW(1);\r
428 Pico_mcd->cdd.Seconde = INT_TO_BCDW(Pico_mcd->TOC.Last_Track);\r
cc68a136 429 Pico_mcd->cdd.Frame = 0;\r
430 Pico_mcd->cdd.Ext = 0;\r
431\r
51a902ae 432 Pico_mcd->scd.CDD_Complete = 1;\r
cc68a136 433\r
434 return 0;\r
435}\r
436\r
437\r
438int Get_Track_Adr_CDD_c25(void)\r
439{\r
440 int track_number;\r
441\r
442 CHECK_TRAY_OPEN\r
443\r
444 // track number in TC4 & TC5\r
445\r
446 track_number = (Pico_mcd->s68k_regs[0x38+10+4] & 0xF) * 10 + (Pico_mcd->s68k_regs[0x38+10+5] & 0xF);\r
447\r
448 Pico_mcd->cdd.Status &= 0xFF;\r
449 if (!CD_Present)\r
450 {\r
451 Pico_mcd->scd.Status_CDD = NOCD;\r
452 Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
453 }\r
454// else if (!(CDC.CTRL.B.B0 & 0x80)) Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
455 Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
456\r
75736070 457 if (track_number > Pico_mcd->TOC.Last_Track) track_number = Pico_mcd->TOC.Last_Track;\r
458 else if (track_number < 1) track_number = 1;\r
cc68a136 459\r
75736070 460 Pico_mcd->cdd.Minute = INT_TO_BCDW(Pico_mcd->TOC.Tracks[track_number - 1].MSF.M);\r
461 Pico_mcd->cdd.Seconde = INT_TO_BCDW(Pico_mcd->TOC.Tracks[track_number - 1].MSF.S);\r
462 Pico_mcd->cdd.Frame = INT_TO_BCDW(Pico_mcd->TOC.Tracks[track_number - 1].MSF.F);\r
cc68a136 463 Pico_mcd->cdd.Ext = track_number % 10;\r
464\r
75736070 465 if (track_number == 1) Pico_mcd->cdd.Frame |= 0x0800; // data track\r
cc68a136 466\r
51a902ae 467 Pico_mcd->scd.CDD_Complete = 1;\r
cc68a136 468 return 0;\r
469}\r
470\r
471\r
472int Play_CDD_c3(void)\r
473{\r
474 _msf MSF;\r
475 int delay, new_lba;\r
476\r
477 CHECK_TRAY_OPEN\r
478 CHECK_CD_PRESENT\r
479\r
480 // MSF of the track to play in TC buffer\r
481\r
482 MSF.M = (Pico_mcd->s68k_regs[0x38+10+2] & 0xF) * 10 + (Pico_mcd->s68k_regs[0x38+10+3] & 0xF);\r
483 MSF.S = (Pico_mcd->s68k_regs[0x38+10+4] & 0xF) * 10 + (Pico_mcd->s68k_regs[0x38+10+5] & 0xF);\r
484 MSF.F = (Pico_mcd->s68k_regs[0x38+10+6] & 0xF) * 10 + (Pico_mcd->s68k_regs[0x38+10+7] & 0xF);\r
485\r
486 Pico_mcd->scd.Cur_Track = MSF_to_Track(&MSF);\r
487\r
488 new_lba = MSF_to_LBA(&MSF);\r
489 delay = new_lba - Pico_mcd->scd.Cur_LBA;\r
490 if (delay < 0) delay = -delay;\r
491 delay >>= 12;\r
492\r
493 Pico_mcd->scd.Cur_LBA = new_lba;\r
494 CDC_Update_Header();\r
495\r
c459aefd 496 cdprintf("Read : Cur LBA = %d, M=%d, S=%d, F=%d", Pico_mcd->scd.Cur_LBA, MSF.M, MSF.S, MSF.F);\r
cc68a136 497\r
498 if (Pico_mcd->scd.Status_CDD != PLAYING) delay += 20;\r
499\r
500 Pico_mcd->scd.Status_CDD = PLAYING;\r
501 Pico_mcd->cdd.Status = 0x0102;\r
502// Pico_mcd->cdd.Status = COMM_OK;\r
503\r
51a902ae 504 if (Pico_mcd->scd.File_Add_Delay == 0) Pico_mcd->scd.File_Add_Delay = delay;\r
cc68a136 505\r
75736070 506 if (Pico_mcd->scd.Cur_Track == 1)\r
cc68a136 507 {\r
508 Pico_mcd->s68k_regs[0x36] |= 0x01; // DATA\r
509 }\r
510 else\r
511 {\r
512 Pico_mcd->s68k_regs[0x36] &= ~0x01; // AUDIO\r
513 //CD_Audio_Starting = 1;\r
cc68a136 514 FILE_Play_CD_LBA();\r
cc68a136 515 }\r
516\r
517 if (Pico_mcd->scd.Cur_Track == 100) Pico_mcd->cdd.Minute = 0x0A02;\r
518 else Pico_mcd->cdd.Minute = INT_TO_BCDW(Pico_mcd->scd.Cur_Track);\r
519 Pico_mcd->cdd.Seconde = 0;\r
520 Pico_mcd->cdd.Frame = 0;\r
521 Pico_mcd->cdd.Ext = 0;\r
522\r
523 Pico_mcd->scd.Status_CDC |= 1; // Read data with CDC\r
524\r
51a902ae 525 Pico_mcd->scd.CDD_Complete = 1;\r
cc68a136 526 return 0;\r
527}\r
528\r
529\r
530int Seek_CDD_c4(void)\r
531{\r
532 _msf MSF;\r
533\r
534 CHECK_TRAY_OPEN\r
535 CHECK_CD_PRESENT\r
536\r
537 // MSF to seek in TC buffer\r
538\r
539 MSF.M = (Pico_mcd->s68k_regs[0x38+10+2] & 0xF) * 10 + (Pico_mcd->s68k_regs[0x38+10+3] & 0xF);\r
540 MSF.S = (Pico_mcd->s68k_regs[0x38+10+4] & 0xF) * 10 + (Pico_mcd->s68k_regs[0x38+10+5] & 0xF);\r
541 MSF.F = (Pico_mcd->s68k_regs[0x38+10+6] & 0xF) * 10 + (Pico_mcd->s68k_regs[0x38+10+7] & 0xF);\r
542\r
543 Pico_mcd->scd.Cur_Track = MSF_to_Track(&MSF);\r
544 Pico_mcd->scd.Cur_LBA = MSF_to_LBA(&MSF);\r
545 CDC_Update_Header();\r
546\r
547 Pico_mcd->scd.Status_CDC &= ~1; // Stop CDC read\r
548\r
549 Pico_mcd->scd.Status_CDD = READY;\r
550 Pico_mcd->cdd.Status = 0x0200;\r
551\r
552 // DATA ?\r
75736070 553 if (Pico_mcd->scd.Cur_Track == 1)\r
cc68a136 554 Pico_mcd->s68k_regs[0x36] |= 0x01;\r
555 else Pico_mcd->s68k_regs[0x36] &= ~0x01; // AUDIO\r
556\r
557 Pico_mcd->cdd.Minute = 0;\r
558 Pico_mcd->cdd.Seconde = 0;\r
559 Pico_mcd->cdd.Frame = 0;\r
560 Pico_mcd->cdd.Ext = 0;\r
561\r
51a902ae 562 Pico_mcd->scd.CDD_Complete = 1;\r
cc68a136 563\r
564 return 0;\r
565}\r
566\r
567\r
568int Pause_CDD_c6(void)\r
569{\r
570 CHECK_TRAY_OPEN\r
571 CHECK_CD_PRESENT\r
572\r
573 Pico_mcd->scd.Status_CDC &= ~1; // Stop CDC read to start a new one if raw data\r
574\r
575 Pico_mcd->scd.Status_CDD = READY;\r
576 Pico_mcd->cdd.Status = Pico_mcd->scd.Status_CDD;\r
577\r
578 Pico_mcd->s68k_regs[0x36] |= 0x01; // Data bit set because stopped\r
579\r
580 Pico_mcd->cdd.Minute = 0;\r
581 Pico_mcd->cdd.Seconde = 0;\r
582 Pico_mcd->cdd.Frame = 0;\r
583 Pico_mcd->cdd.Ext = 0;\r
584\r
51a902ae 585 Pico_mcd->scd.CDD_Complete = 1;\r
cc68a136 586\r
587 return 0;\r
588}\r
589\r
590\r
591int Resume_CDD_c7(void)\r
592{\r
593 CHECK_TRAY_OPEN\r
594 CHECK_CD_PRESENT\r
595\r
596 Pico_mcd->scd.Cur_Track = LBA_to_Track(Pico_mcd->scd.Cur_LBA);\r
597\r
598#ifdef DEBUG_CD\r
599 {\r
600 _msf MSF;\r
601 LBA_to_MSF(Pico_mcd->scd.Cur_LBA, &MSF);\r
c459aefd 602 cdprintf("Resume read : Cur LBA = %d, M=%d, S=%d, F=%d", Pico_mcd->scd.Cur_LBA, MSF.M, MSF.S, MSF.F);\r
cc68a136 603 }\r
604#endif\r
605\r
606 Pico_mcd->scd.Status_CDD = PLAYING;\r
607 Pico_mcd->cdd.Status = 0x0102;\r
608\r
75736070 609 if (Pico_mcd->scd.Cur_Track == 1)\r
cc68a136 610 {\r
611 Pico_mcd->s68k_regs[0x36] |= 0x01; // DATA\r
612 }\r
613 else\r
614 {\r
615 Pico_mcd->s68k_regs[0x36] &= ~0x01; // AUDIO\r
616 //CD_Audio_Starting = 1;\r
cc68a136 617 FILE_Play_CD_LBA();\r
cc68a136 618 }\r
619\r
620 if (Pico_mcd->scd.Cur_Track == 100) Pico_mcd->cdd.Minute = 0x0A02;\r
621 else Pico_mcd->cdd.Minute = INT_TO_BCDW(Pico_mcd->scd.Cur_Track);\r
622 Pico_mcd->cdd.Seconde = 0;\r
623 Pico_mcd->cdd.Frame = 0;\r
624 Pico_mcd->cdd.Ext = 0;\r
625\r
626 Pico_mcd->scd.Status_CDC |= 1; // Read data with CDC\r
627\r
51a902ae 628 Pico_mcd->scd.CDD_Complete = 1;\r
cc68a136 629 return 0;\r
630}\r
631\r
632\r
bf098bc5 633int Fast_Foward_CDD_c8(void)\r
cc68a136 634{\r
635 CHECK_TRAY_OPEN\r
636 CHECK_CD_PRESENT\r
637\r
638 Pico_mcd->scd.Status_CDC &= ~1; // Stop CDC read\r
639\r
640 Pico_mcd->scd.Status_CDD = FAST_FOW;\r
641 Pico_mcd->cdd.Status = Pico_mcd->scd.Status_CDD | 2;\r
642\r
643 Pico_mcd->cdd.Minute = INT_TO_BCDW(Pico_mcd->scd.Cur_Track);\r
644 Pico_mcd->cdd.Seconde = 0;\r
645 Pico_mcd->cdd.Frame = 0;\r
646 Pico_mcd->cdd.Ext = 0;\r
647\r
51a902ae 648 Pico_mcd->scd.CDD_Complete = 1;\r
cc68a136 649\r
650 return 0;\r
651}\r
652\r
653\r
bf098bc5 654int Fast_Rewind_CDD_c9(void)\r
cc68a136 655{\r
656 CHECK_TRAY_OPEN\r
657 CHECK_CD_PRESENT\r
658\r
659 Pico_mcd->scd.Status_CDC &= ~1; // Stop CDC read\r
660\r
661 Pico_mcd->scd.Status_CDD = FAST_REV;\r
662 Pico_mcd->cdd.Status = Pico_mcd->scd.Status_CDD | 2;\r
663\r
664 Pico_mcd->cdd.Minute = INT_TO_BCDW(Pico_mcd->scd.Cur_Track);\r
665 Pico_mcd->cdd.Seconde = 0;\r
666 Pico_mcd->cdd.Frame = 0;\r
667 Pico_mcd->cdd.Ext = 0;\r
668\r
51a902ae 669 Pico_mcd->scd.CDD_Complete = 1;\r
cc68a136 670\r
671 return 0;\r
672}\r
673\r
674\r
675int Close_Tray_CDD_cC(void)\r
676{\r
721cd396 677 CD_Present = 0;\r
cc68a136 678 //Clear_Sound_Buffer();\r
679\r
680 Pico_mcd->scd.Status_CDC &= ~1; // Stop CDC read\r
681\r
721cd396 682 printf("tray close\n");\r
cc68a136 683\r
721cd396 684 if (PicoMCDcloseTray != NULL)\r
685 CD_Present = PicoMCDcloseTray();\r
cc68a136 686\r
721cd396 687 Pico_mcd->scd.Status_CDD = CD_Present ? STOPPED : NOCD;\r
688 Pico_mcd->cdd.Status = 0x0000;\r
cc68a136 689\r
721cd396 690 Pico_mcd->cdd.Minute = 0;\r
691 Pico_mcd->cdd.Seconde = 0;\r
692 Pico_mcd->cdd.Frame = 0;\r
693 Pico_mcd->cdd.Ext = 0;\r
cc68a136 694\r
51a902ae 695 Pico_mcd->scd.CDD_Complete = 1;\r
cc68a136 696\r
697 return 0;\r
698}\r
699\r
700\r
701int Open_Tray_CDD_cD(void)\r
702{\r
703 CHECK_TRAY_OPEN\r
704\r
705 Pico_mcd->scd.Status_CDC &= ~1; // Stop CDC read\r
706\r
721cd396 707 printf("tray open\n");\r
708\r
cc68a136 709 Unload_ISO();\r
cc68a136 710 CD_Present = 0;\r
711\r
721cd396 712 if (PicoMCDopenTray != NULL)\r
713 PicoMCDopenTray();\r
714\r
cc68a136 715 Pico_mcd->scd.Status_CDD = TRAY_OPEN;\r
716 Pico_mcd->cdd.Status = 0x0E00;\r
717\r
718 Pico_mcd->cdd.Minute = 0;\r
719 Pico_mcd->cdd.Seconde = 0;\r
720 Pico_mcd->cdd.Frame = 0;\r
721 Pico_mcd->cdd.Ext = 0;\r
722\r
51a902ae 723 Pico_mcd->scd.CDD_Complete = 1;\r
cc68a136 724\r
725 return 0;\r
726}\r
727\r
728\r
729int CDD_cA(void)\r
730{\r
731 CHECK_TRAY_OPEN\r
732 CHECK_CD_PRESENT\r
733\r
734 Pico_mcd->scd.Status_CDC &= ~1;\r
735\r
736 Pico_mcd->scd.Status_CDD = READY;\r
737 Pico_mcd->cdd.Status = Pico_mcd->scd.Status_CDD;\r
738\r
739 Pico_mcd->cdd.Minute = 0;\r
740 Pico_mcd->cdd.Seconde = INT_TO_BCDW(1);\r
741 Pico_mcd->cdd.Frame = INT_TO_BCDW(1);\r
742 Pico_mcd->cdd.Ext = 0;\r
743\r
51a902ae 744 Pico_mcd->scd.CDD_Complete = 1;\r
cc68a136 745\r
746 return 0;\r
747}\r
748\r
749\r
750int CDD_Def(void)\r
751{\r
752 Pico_mcd->cdd.Status = Pico_mcd->scd.Status_CDD;\r
753\r
754 Pico_mcd->cdd.Minute = 0;\r
755 Pico_mcd->cdd.Seconde = 0;\r
756 Pico_mcd->cdd.Frame = 0;\r
757 Pico_mcd->cdd.Ext = 0;\r
758\r
759 return 0;\r
760}\r
761\r
762\r