bugfixes, cd/Memory.s
[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
211 Pico_mcd->scd.Status_CDD = READY;\r
51a902ae 212 Pico_mcd->scd.CDD_Complete = 0;\r
cc68a136 213}\r
214\r
215\r
bf098bc5 216int Insert_CD(char *iso_name, int is_bin)\r
cc68a136 217{\r
bf098bc5 218 int ret = 0;\r
219\r
cc68a136 220// memset(CD_Audio_Buffer_L, 0, 4096 * 4);\r
221// memset(CD_Audio_Buffer_R, 0, 4096 * 4);\r
222\r
bf098bc5 223 CD_Present = 0;\r
224\r
225 if (iso_name != NULL)\r
cc68a136 226 {\r
bf098bc5 227 ret = Load_ISO(iso_name, is_bin);\r
228 if (ret == 0)\r
229 CD_Present = 1;\r
cc68a136 230 }\r
231\r
bf098bc5 232 return ret;\r
cc68a136 233}\r
234\r
235\r
236void Stop_CD(void)\r
237{\r
cc68a136 238 Unload_ISO();\r
cc68a136 239 CD_Present = 0;\r
240}\r
241\r
242\r
243void Change_CD(void)\r
244{\r
245 if (Pico_mcd->scd.Status_CDD == TRAY_OPEN) Close_Tray_CDD_cC();\r
246 else Open_Tray_CDD_cD();\r
247}\r
248\r
249\r
250int Get_Status_CDD_c0(void)\r
251{\r
c459aefd 252 cdprintf("Status command : Cur LBA = %d", Pico_mcd->scd.Cur_LBA);\r
cc68a136 253\r
254 // Clear immediat status\r
255 if ((Pico_mcd->cdd.Status & 0x0F00) == 0x0200)\r
256 Pico_mcd->cdd.Status = (Pico_mcd->scd.Status_CDD & 0xFF00) | (Pico_mcd->cdd.Status & 0x00FF);\r
257 else if ((Pico_mcd->cdd.Status & 0x0F00) == 0x0700)\r
258 Pico_mcd->cdd.Status = (Pico_mcd->scd.Status_CDD & 0xFF00) | (Pico_mcd->cdd.Status & 0x00FF);\r
259 else if ((Pico_mcd->cdd.Status & 0x0F00) == 0x0E00)\r
260 Pico_mcd->cdd.Status = (Pico_mcd->scd.Status_CDD & 0xFF00) | (Pico_mcd->cdd.Status & 0x00FF);\r
261\r
51a902ae 262 Pico_mcd->scd.CDD_Complete = 1;\r
cc68a136 263\r
264 return 0;\r
265}\r
266\r
267\r
268int Stop_CDD_c1(void)\r
269{\r
270 CHECK_TRAY_OPEN\r
271\r
272 Pico_mcd->scd.Status_CDC &= ~1; // Stop CDC read\r
273\r
274 if (CD_Present) Pico_mcd->scd.Status_CDD = STOPPED;\r
275 else Pico_mcd->scd.Status_CDD = NOCD;\r
276 Pico_mcd->cdd.Status = 0x0000;\r
277\r
278 Pico_mcd->s68k_regs[0x36] |= 0x01; // Data bit set because stopped\r
279\r
280 Pico_mcd->cdd.Minute = 0;\r
281 Pico_mcd->cdd.Seconde = 0;\r
282 Pico_mcd->cdd.Frame = 0;\r
283 Pico_mcd->cdd.Ext = 0;\r
284\r
51a902ae 285 Pico_mcd->scd.CDD_Complete = 1;\r
cc68a136 286\r
287 return 0;\r
288}\r
289\r
290\r
291int Get_Pos_CDD_c20(void)\r
292{\r
293 _msf MSF;\r
294\r
c459aefd 295 cdprintf("command 200 : Cur LBA = %d", Pico_mcd->scd.Cur_LBA);\r
cc68a136 296\r
297 CHECK_TRAY_OPEN\r
298\r
299 Pico_mcd->cdd.Status &= 0xFF;\r
300 if (!CD_Present)\r
301 {\r
302 Pico_mcd->scd.Status_CDD = NOCD;\r
303 Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
304 }\r
305// else if (!(CDC.CTRL.B.B0 & 0x80)) Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
306 Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
307\r
c459aefd 308 cdprintf("Status CDD = %.4X Status = %.4X", Pico_mcd->scd.Status_CDD, Pico_mcd->cdd.Status);\r
cc68a136 309\r
310 LBA_to_MSF(Pico_mcd->scd.Cur_LBA, &MSF);\r
311\r
312 Pico_mcd->cdd.Minute = INT_TO_BCDW(MSF.M);\r
313 Pico_mcd->cdd.Seconde = INT_TO_BCDW(MSF.S);\r
314 Pico_mcd->cdd.Frame = INT_TO_BCDW(MSF.F);\r
315 Pico_mcd->cdd.Ext = 0;\r
316\r
51a902ae 317 Pico_mcd->scd.CDD_Complete = 1;\r
cc68a136 318\r
319 return 0;\r
320}\r
321\r
322\r
323int Get_Track_Pos_CDD_c21(void)\r
324{\r
325 int elapsed_time;\r
326 _msf MSF;\r
327\r
328 cdprintf("command 201 : Cur LBA = %d", Pico_mcd->scd.Cur_LBA);\r
329\r
330 CHECK_TRAY_OPEN\r
331\r
332 Pico_mcd->cdd.Status &= 0xFF;\r
333 if (!CD_Present)\r
334 {\r
335 Pico_mcd->scd.Status_CDD = NOCD;\r
336 Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
337 }\r
338// else if (!(CDC.CTRL.B.B0 & 0x80)) Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
339 Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
340\r
341 elapsed_time = Pico_mcd->scd.Cur_LBA - Track_to_LBA(LBA_to_Track(Pico_mcd->scd.Cur_LBA));\r
342 LBA_to_MSF(elapsed_time - 150, &MSF);\r
343\r
c459aefd 344 cdprintf(" elapsed = %d", elapsed_time);\r
cc68a136 345\r
346 Pico_mcd->cdd.Minute = INT_TO_BCDW(MSF.M);\r
347 Pico_mcd->cdd.Seconde = INT_TO_BCDW(MSF.S);\r
348 Pico_mcd->cdd.Frame = INT_TO_BCDW(MSF.F);\r
349 Pico_mcd->cdd.Ext = 0;\r
350\r
51a902ae 351 Pico_mcd->scd.CDD_Complete = 1;\r
cc68a136 352\r
353 return 0;\r
354}\r
355\r
356\r
357int Get_Current_Track_CDD_c22(void)\r
358{\r
c459aefd 359 cdprintf("Status CDD = %.4X Status = %.4X", Pico_mcd->scd.Status_CDD, Pico_mcd->cdd.Status);\r
cc68a136 360\r
361 CHECK_TRAY_OPEN\r
362\r
363 Pico_mcd->cdd.Status &= 0xFF;\r
364 if (!CD_Present)\r
365 {\r
366 Pico_mcd->scd.Status_CDD = NOCD;\r
367 Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
368 }\r
369// else if (!(CDC.CTRL.B.B0 & 0x80)) Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
370 Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
371\r
372 Pico_mcd->scd.Cur_Track = LBA_to_Track(Pico_mcd->scd.Cur_LBA);\r
373\r
374 if (Pico_mcd->scd.Cur_Track == 100) Pico_mcd->cdd.Minute = 0x0A02;\r
375 else Pico_mcd->cdd.Minute = INT_TO_BCDW(Pico_mcd->scd.Cur_Track);\r
376 Pico_mcd->cdd.Seconde = 0;\r
377 Pico_mcd->cdd.Frame = 0;\r
378 Pico_mcd->cdd.Ext = 0;\r
379\r
51a902ae 380 Pico_mcd->scd.CDD_Complete = 1;\r
cc68a136 381\r
382 return 0;\r
383}\r
384\r
385\r
386int Get_Total_Lenght_CDD_c23(void)\r
387{\r
388 CHECK_TRAY_OPEN\r
389\r
390 Pico_mcd->cdd.Status &= 0xFF;\r
391 if (!CD_Present)\r
392 {\r
393 Pico_mcd->scd.Status_CDD = NOCD;\r
394 Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
395 }\r
396// else if (!(CDC.CTRL.B.B0 & 0x80)) Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
397 Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
398\r
75736070 399 Pico_mcd->cdd.Minute = INT_TO_BCDW(Pico_mcd->TOC.Tracks[Pico_mcd->TOC.Last_Track].MSF.M);\r
400 Pico_mcd->cdd.Seconde = INT_TO_BCDW(Pico_mcd->TOC.Tracks[Pico_mcd->TOC.Last_Track].MSF.S);\r
401 Pico_mcd->cdd.Frame = INT_TO_BCDW(Pico_mcd->TOC.Tracks[Pico_mcd->TOC.Last_Track].MSF.F);\r
cc68a136 402 Pico_mcd->cdd.Ext = 0;\r
403\r
51a902ae 404 Pico_mcd->scd.CDD_Complete = 1;\r
cc68a136 405\r
406 return 0;\r
407}\r
408\r
409\r
410int Get_First_Last_Track_CDD_c24(void)\r
411{\r
412 CHECK_TRAY_OPEN\r
413\r
414 Pico_mcd->cdd.Status &= 0xFF;\r
415 if (!CD_Present)\r
416 {\r
417 Pico_mcd->scd.Status_CDD = NOCD;\r
418 }\r
419// else if (!(CDC.CTRL.B.B0 & 0x80)) Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
420 Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
421\r
75736070 422 Pico_mcd->cdd.Minute = INT_TO_BCDW(1);\r
423 Pico_mcd->cdd.Seconde = INT_TO_BCDW(Pico_mcd->TOC.Last_Track);\r
cc68a136 424 Pico_mcd->cdd.Frame = 0;\r
425 Pico_mcd->cdd.Ext = 0;\r
426\r
51a902ae 427 Pico_mcd->scd.CDD_Complete = 1;\r
cc68a136 428\r
429 return 0;\r
430}\r
431\r
432\r
433int Get_Track_Adr_CDD_c25(void)\r
434{\r
435 int track_number;\r
436\r
437 CHECK_TRAY_OPEN\r
438\r
439 // track number in TC4 & TC5\r
440\r
441 track_number = (Pico_mcd->s68k_regs[0x38+10+4] & 0xF) * 10 + (Pico_mcd->s68k_regs[0x38+10+5] & 0xF);\r
442\r
443 Pico_mcd->cdd.Status &= 0xFF;\r
444 if (!CD_Present)\r
445 {\r
446 Pico_mcd->scd.Status_CDD = NOCD;\r
447 Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
448 }\r
449// else if (!(CDC.CTRL.B.B0 & 0x80)) Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
450 Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
451\r
75736070 452 if (track_number > Pico_mcd->TOC.Last_Track) track_number = Pico_mcd->TOC.Last_Track;\r
453 else if (track_number < 1) track_number = 1;\r
cc68a136 454\r
75736070 455 Pico_mcd->cdd.Minute = INT_TO_BCDW(Pico_mcd->TOC.Tracks[track_number - 1].MSF.M);\r
456 Pico_mcd->cdd.Seconde = INT_TO_BCDW(Pico_mcd->TOC.Tracks[track_number - 1].MSF.S);\r
457 Pico_mcd->cdd.Frame = INT_TO_BCDW(Pico_mcd->TOC.Tracks[track_number - 1].MSF.F);\r
cc68a136 458 Pico_mcd->cdd.Ext = track_number % 10;\r
459\r
75736070 460 if (track_number == 1) Pico_mcd->cdd.Frame |= 0x0800; // data track\r
cc68a136 461\r
51a902ae 462 Pico_mcd->scd.CDD_Complete = 1;\r
cc68a136 463 return 0;\r
464}\r
465\r
466\r
467int Play_CDD_c3(void)\r
468{\r
469 _msf MSF;\r
470 int delay, new_lba;\r
471\r
472 CHECK_TRAY_OPEN\r
473 CHECK_CD_PRESENT\r
474\r
475 // MSF of the track to play in TC buffer\r
476\r
477 MSF.M = (Pico_mcd->s68k_regs[0x38+10+2] & 0xF) * 10 + (Pico_mcd->s68k_regs[0x38+10+3] & 0xF);\r
478 MSF.S = (Pico_mcd->s68k_regs[0x38+10+4] & 0xF) * 10 + (Pico_mcd->s68k_regs[0x38+10+5] & 0xF);\r
479 MSF.F = (Pico_mcd->s68k_regs[0x38+10+6] & 0xF) * 10 + (Pico_mcd->s68k_regs[0x38+10+7] & 0xF);\r
480\r
481 Pico_mcd->scd.Cur_Track = MSF_to_Track(&MSF);\r
482\r
483 new_lba = MSF_to_LBA(&MSF);\r
484 delay = new_lba - Pico_mcd->scd.Cur_LBA;\r
485 if (delay < 0) delay = -delay;\r
486 delay >>= 12;\r
487\r
488 Pico_mcd->scd.Cur_LBA = new_lba;\r
489 CDC_Update_Header();\r
490\r
c459aefd 491 cdprintf("Read : Cur LBA = %d, M=%d, S=%d, F=%d", Pico_mcd->scd.Cur_LBA, MSF.M, MSF.S, MSF.F);\r
cc68a136 492\r
493 if (Pico_mcd->scd.Status_CDD != PLAYING) delay += 20;\r
494\r
495 Pico_mcd->scd.Status_CDD = PLAYING;\r
496 Pico_mcd->cdd.Status = 0x0102;\r
497// Pico_mcd->cdd.Status = COMM_OK;\r
498\r
51a902ae 499 if (Pico_mcd->scd.File_Add_Delay == 0) Pico_mcd->scd.File_Add_Delay = delay;\r
cc68a136 500\r
75736070 501 if (Pico_mcd->scd.Cur_Track == 1)\r
cc68a136 502 {\r
503 Pico_mcd->s68k_regs[0x36] |= 0x01; // DATA\r
504 }\r
505 else\r
506 {\r
507 Pico_mcd->s68k_regs[0x36] &= ~0x01; // AUDIO\r
508 //CD_Audio_Starting = 1;\r
cc68a136 509 FILE_Play_CD_LBA();\r
cc68a136 510 }\r
511\r
512 if (Pico_mcd->scd.Cur_Track == 100) Pico_mcd->cdd.Minute = 0x0A02;\r
513 else Pico_mcd->cdd.Minute = INT_TO_BCDW(Pico_mcd->scd.Cur_Track);\r
514 Pico_mcd->cdd.Seconde = 0;\r
515 Pico_mcd->cdd.Frame = 0;\r
516 Pico_mcd->cdd.Ext = 0;\r
517\r
518 Pico_mcd->scd.Status_CDC |= 1; // Read data with CDC\r
519\r
51a902ae 520 Pico_mcd->scd.CDD_Complete = 1;\r
cc68a136 521 return 0;\r
522}\r
523\r
524\r
525int Seek_CDD_c4(void)\r
526{\r
527 _msf MSF;\r
528\r
529 CHECK_TRAY_OPEN\r
530 CHECK_CD_PRESENT\r
531\r
532 // MSF to seek in TC buffer\r
533\r
534 MSF.M = (Pico_mcd->s68k_regs[0x38+10+2] & 0xF) * 10 + (Pico_mcd->s68k_regs[0x38+10+3] & 0xF);\r
535 MSF.S = (Pico_mcd->s68k_regs[0x38+10+4] & 0xF) * 10 + (Pico_mcd->s68k_regs[0x38+10+5] & 0xF);\r
536 MSF.F = (Pico_mcd->s68k_regs[0x38+10+6] & 0xF) * 10 + (Pico_mcd->s68k_regs[0x38+10+7] & 0xF);\r
537\r
538 Pico_mcd->scd.Cur_Track = MSF_to_Track(&MSF);\r
539 Pico_mcd->scd.Cur_LBA = MSF_to_LBA(&MSF);\r
540 CDC_Update_Header();\r
541\r
542 Pico_mcd->scd.Status_CDC &= ~1; // Stop CDC read\r
543\r
544 Pico_mcd->scd.Status_CDD = READY;\r
545 Pico_mcd->cdd.Status = 0x0200;\r
546\r
547 // DATA ?\r
75736070 548 if (Pico_mcd->scd.Cur_Track == 1)\r
cc68a136 549 Pico_mcd->s68k_regs[0x36] |= 0x01;\r
550 else Pico_mcd->s68k_regs[0x36] &= ~0x01; // AUDIO\r
551\r
552 Pico_mcd->cdd.Minute = 0;\r
553 Pico_mcd->cdd.Seconde = 0;\r
554 Pico_mcd->cdd.Frame = 0;\r
555 Pico_mcd->cdd.Ext = 0;\r
556\r
51a902ae 557 Pico_mcd->scd.CDD_Complete = 1;\r
cc68a136 558\r
559 return 0;\r
560}\r
561\r
562\r
563int Pause_CDD_c6(void)\r
564{\r
565 CHECK_TRAY_OPEN\r
566 CHECK_CD_PRESENT\r
567\r
568 Pico_mcd->scd.Status_CDC &= ~1; // Stop CDC read to start a new one if raw data\r
569\r
570 Pico_mcd->scd.Status_CDD = READY;\r
571 Pico_mcd->cdd.Status = Pico_mcd->scd.Status_CDD;\r
572\r
573 Pico_mcd->s68k_regs[0x36] |= 0x01; // Data bit set because stopped\r
574\r
575 Pico_mcd->cdd.Minute = 0;\r
576 Pico_mcd->cdd.Seconde = 0;\r
577 Pico_mcd->cdd.Frame = 0;\r
578 Pico_mcd->cdd.Ext = 0;\r
579\r
51a902ae 580 Pico_mcd->scd.CDD_Complete = 1;\r
cc68a136 581\r
582 return 0;\r
583}\r
584\r
585\r
586int Resume_CDD_c7(void)\r
587{\r
588 CHECK_TRAY_OPEN\r
589 CHECK_CD_PRESENT\r
590\r
591 Pico_mcd->scd.Cur_Track = LBA_to_Track(Pico_mcd->scd.Cur_LBA);\r
592\r
593#ifdef DEBUG_CD\r
594 {\r
595 _msf MSF;\r
596 LBA_to_MSF(Pico_mcd->scd.Cur_LBA, &MSF);\r
c459aefd 597 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 598 }\r
599#endif\r
600\r
601 Pico_mcd->scd.Status_CDD = PLAYING;\r
602 Pico_mcd->cdd.Status = 0x0102;\r
603\r
75736070 604 if (Pico_mcd->scd.Cur_Track == 1)\r
cc68a136 605 {\r
606 Pico_mcd->s68k_regs[0x36] |= 0x01; // DATA\r
607 }\r
608 else\r
609 {\r
610 Pico_mcd->s68k_regs[0x36] &= ~0x01; // AUDIO\r
611 //CD_Audio_Starting = 1;\r
cc68a136 612 FILE_Play_CD_LBA();\r
cc68a136 613 }\r
614\r
615 if (Pico_mcd->scd.Cur_Track == 100) Pico_mcd->cdd.Minute = 0x0A02;\r
616 else Pico_mcd->cdd.Minute = INT_TO_BCDW(Pico_mcd->scd.Cur_Track);\r
617 Pico_mcd->cdd.Seconde = 0;\r
618 Pico_mcd->cdd.Frame = 0;\r
619 Pico_mcd->cdd.Ext = 0;\r
620\r
621 Pico_mcd->scd.Status_CDC |= 1; // Read data with CDC\r
622\r
51a902ae 623 Pico_mcd->scd.CDD_Complete = 1;\r
cc68a136 624 return 0;\r
625}\r
626\r
627\r
bf098bc5 628int Fast_Foward_CDD_c8(void)\r
cc68a136 629{\r
630 CHECK_TRAY_OPEN\r
631 CHECK_CD_PRESENT\r
632\r
633 Pico_mcd->scd.Status_CDC &= ~1; // Stop CDC read\r
634\r
635 Pico_mcd->scd.Status_CDD = FAST_FOW;\r
636 Pico_mcd->cdd.Status = Pico_mcd->scd.Status_CDD | 2;\r
637\r
638 Pico_mcd->cdd.Minute = INT_TO_BCDW(Pico_mcd->scd.Cur_Track);\r
639 Pico_mcd->cdd.Seconde = 0;\r
640 Pico_mcd->cdd.Frame = 0;\r
641 Pico_mcd->cdd.Ext = 0;\r
642\r
51a902ae 643 Pico_mcd->scd.CDD_Complete = 1;\r
cc68a136 644\r
645 return 0;\r
646}\r
647\r
648\r
bf098bc5 649int Fast_Rewind_CDD_c9(void)\r
cc68a136 650{\r
651 CHECK_TRAY_OPEN\r
652 CHECK_CD_PRESENT\r
653\r
654 Pico_mcd->scd.Status_CDC &= ~1; // Stop CDC read\r
655\r
656 Pico_mcd->scd.Status_CDD = FAST_REV;\r
657 Pico_mcd->cdd.Status = Pico_mcd->scd.Status_CDD | 2;\r
658\r
659 Pico_mcd->cdd.Minute = INT_TO_BCDW(Pico_mcd->scd.Cur_Track);\r
660 Pico_mcd->cdd.Seconde = 0;\r
661 Pico_mcd->cdd.Frame = 0;\r
662 Pico_mcd->cdd.Ext = 0;\r
663\r
51a902ae 664 Pico_mcd->scd.CDD_Complete = 1;\r
cc68a136 665\r
666 return 0;\r
667}\r
668\r
669\r
670int Close_Tray_CDD_cC(void)\r
671{\r
672 //Clear_Sound_Buffer();\r
673\r
674 Pico_mcd->scd.Status_CDC &= ~1; // Stop CDC read\r
675\r
676 {\r
677#if 0 // TODO\r
678 char new_iso[1024];\r
679\r
680 memset(new_iso, 0, 1024);\r
681\r
682 while (!Change_File_L(new_iso, Rom_Dir, "Load SegaCD image file", "SegaCD image file\0*.bin;*.iso;*.raw\0All files\0*.*\0\0", ""));\r
683 Reload_SegaCD(new_iso);\r
684\r
685 CD_Present = 1;\r
686#else\r
687 CD_Present = 0;\r
688#endif\r
689 Pico_mcd->scd.Status_CDD = STOPPED;\r
690 Pico_mcd->cdd.Status = 0x0000;\r
691\r
692 Pico_mcd->cdd.Minute = 0;\r
693 Pico_mcd->cdd.Seconde = 0;\r
694 Pico_mcd->cdd.Frame = 0;\r
695 Pico_mcd->cdd.Ext = 0;\r
696 }\r
697\r
51a902ae 698 Pico_mcd->scd.CDD_Complete = 1;\r
cc68a136 699\r
700 return 0;\r
701}\r
702\r
703\r
704int Open_Tray_CDD_cD(void)\r
705{\r
706 CHECK_TRAY_OPEN\r
707\r
708 Pico_mcd->scd.Status_CDC &= ~1; // Stop CDC read\r
709\r
cc68a136 710 Unload_ISO();\r
cc68a136 711 CD_Present = 0;\r
712\r
713 Pico_mcd->scd.Status_CDD = TRAY_OPEN;\r
714 Pico_mcd->cdd.Status = 0x0E00;\r
715\r
716 Pico_mcd->cdd.Minute = 0;\r
717 Pico_mcd->cdd.Seconde = 0;\r
718 Pico_mcd->cdd.Frame = 0;\r
719 Pico_mcd->cdd.Ext = 0;\r
720\r
51a902ae 721 Pico_mcd->scd.CDD_Complete = 1;\r
cc68a136 722\r
723 return 0;\r
724}\r
725\r
726\r
727int CDD_cA(void)\r
728{\r
729 CHECK_TRAY_OPEN\r
730 CHECK_CD_PRESENT\r
731\r
732 Pico_mcd->scd.Status_CDC &= ~1;\r
733\r
734 Pico_mcd->scd.Status_CDD = READY;\r
735 Pico_mcd->cdd.Status = Pico_mcd->scd.Status_CDD;\r
736\r
737 Pico_mcd->cdd.Minute = 0;\r
738 Pico_mcd->cdd.Seconde = INT_TO_BCDW(1);\r
739 Pico_mcd->cdd.Frame = INT_TO_BCDW(1);\r
740 Pico_mcd->cdd.Ext = 0;\r
741\r
51a902ae 742 Pico_mcd->scd.CDD_Complete = 1;\r
cc68a136 743\r
744 return 0;\r
745}\r
746\r
747\r
748int CDD_Def(void)\r
749{\r
750 Pico_mcd->cdd.Status = Pico_mcd->scd.Status_CDD;\r
751\r
752 Pico_mcd->cdd.Minute = 0;\r
753 Pico_mcd->cdd.Seconde = 0;\r
754 Pico_mcd->cdd.Frame = 0;\r
755 Pico_mcd->cdd.Ext = 0;\r
756\r
757 return 0;\r
758}\r
759\r
760\r
761\r
762\r
763/***************************\r
764 * Others CD functions *\r
765 **************************/\r
766\r
767\r
768// do we need them?\r
769#if 0\r
770void Write_CD_Audio(short *Buf, int rate, int channel, int lenght)\r
771{\r
772 unsigned int lenght_src, lenght_dst;\r
773 unsigned int pos_src, pas_src;\r
774\r
775 if (rate == 0) return;\r
776 if (Sound_Rate == 0) return;\r
777\r
778 if (CD_Audio_Starting)\r
779 {\r
780 CD_Audio_Starting = 0;\r
781 memset(CD_Audio_Buffer_L, 0, 4096 * 4);\r
782 memset(CD_Audio_Buffer_R, 0, 4096 * 4);\r
783 CD_Audio_Buffer_Write_Pos = (CD_Audio_Buffer_Read_Pos + 2000) & 0xFFF;\r
784 }\r
785\r
786 lenght_src = rate / 75; // 75th of a second\r
787 lenght_dst = Sound_Rate / 75; // 75th of a second\r
788\r
789 pas_src = (lenght_src << 16) / lenght_dst;\r
790 pos_src = 0;\r
791\r
792#ifdef DEBUG_CD\r
793 fprintf(debug_SCD_file, "\n********* Write Pos = %d ", CD_Audio_Buffer_Write_Pos);\r
794#endif\r
795\r
796 if (channel == 2)\r
797 {\r
798 __asm\r
799 {\r
800 mov edi, CD_Audio_Buffer_Write_Pos\r
801 mov ebx, Buf\r
802 xor esi, esi\r
803 mov ecx, lenght_dst\r
804 xor eax, eax\r
805 mov edx, pas_src\r
806 dec ecx\r
807 jmp short loop_stereo\r
808\r
809align 16\r
810\r
811loop_stereo:\r
812 movsx eax, word ptr [ebx + esi * 4]\r
813 mov CD_Audio_Buffer_L[edi * 4], eax\r
814 movsx eax, word ptr [ebx + esi * 4 + 2]\r
815 mov CD_Audio_Buffer_R[edi * 4], eax\r
816 mov esi, dword ptr pos_src\r
817 inc edi\r
818 add esi, edx\r
819 and edi, 0xFFF\r
820 mov dword ptr pos_src, esi\r
821 shr esi, 16\r
822 dec ecx\r
823 jns short loop_stereo\r
824\r
825 mov CD_Audio_Buffer_Write_Pos, edi\r
826 }\r
827 }\r
828 else\r
829 {\r
830 __asm\r
831 {\r
832 mov edi, CD_Audio_Buffer_Write_Pos\r
833 mov ebx, Buf\r
834 xor esi, esi\r
835 mov ecx, lenght_dst\r
836 xor eax, eax\r
837 mov edx, pas_src\r
838 dec ecx\r
839 jmp short loop_mono\r
840\r
841align 16\r
842\r
843loop_mono:\r
844 movsx eax, word ptr [ebx + esi * 2]\r
845 mov CD_Audio_Buffer_L[edi * 4], eax\r
846 mov CD_Audio_Buffer_R[edi * 4], eax\r
847 mov esi, dword ptr pos_src\r
848 inc edi\r
849 add esi, edx\r
850 and edi, 0xFFF\r
851 mov dword ptr pos_src, esi\r
852 shr esi, 16\r
853 dec ecx\r
854 jns short loop_mono\r
855\r
856 mov CD_Audio_Buffer_Write_Pos, edi\r
857 }\r
858 }\r
859\r
860#ifdef DEBUG_CD\r
861 fprintf(debug_SCD_file, "Write Pos 2 = %d\n\n", CD_Audio_Buffer_Write_Pos);\r
862#endif\r
863}\r
864\r
865\r
866void Update_CD_Audio(int **buf, int lenght)\r
867{\r
868 int *Buf_L, *Buf_R;\r
869 int diff;\r
870\r
871 Buf_L = buf[0];\r
872 Buf_R = buf[1];\r
873\r
874 if (Pico_mcd->s68k_regs[0x36] & 0x01) return;\r
875 if (!(Pico_mcd->scd.Status_CDC & 1)) return;\r
876 if (CD_Audio_Starting) return;\r
877\r
878#ifdef DEBUG_CD\r
879 fprintf(debug_SCD_file, "\n********* Read Pos Normal = %d ", CD_Audio_Buffer_Read_Pos);\r
880#endif\r
881\r
882 if (CD_Audio_Buffer_Write_Pos < CD_Audio_Buffer_Read_Pos)\r
883 {\r
884 diff = CD_Audio_Buffer_Write_Pos + (4096) - CD_Audio_Buffer_Read_Pos;\r
885 }\r
886 else\r
887 {\r
888 diff = CD_Audio_Buffer_Write_Pos - CD_Audio_Buffer_Read_Pos;\r
889 }\r
890\r
891 if (diff < 500) CD_Audio_Buffer_Read_Pos -= 2000;\r
892 else if (diff > 3500) CD_Audio_Buffer_Read_Pos += 2000;\r
893\r
894#ifdef DEBUG_CD\r
895 else fprintf(debug_SCD_file, " pas de modifs ");\r
896#endif\r
897\r
898 CD_Audio_Buffer_Read_Pos &= 0xFFF;\r
899\r
900#ifdef DEBUG_CD\r
901 fprintf(debug_SCD_file, "Read Pos = %d ", CD_Audio_Buffer_Read_Pos);\r
902#endif\r
903\r
904 if (CDDA_Enable)\r
905 {\r
906 __asm\r
907 {\r
908 mov ecx, lenght\r
909 mov esi, CD_Audio_Buffer_Read_Pos\r
910 mov edi, Buf_L\r
911 dec ecx\r
912\r
913loop_L:\r
914 mov eax, CD_Audio_Buffer_L[esi * 4]\r
915 add [edi], eax\r
916 inc esi\r
917 add edi, 4\r
918 and esi, 0xFFF\r
919 dec ecx\r
920 jns short loop_L\r
921\r
922 mov ecx, lenght\r
923 mov esi, CD_Audio_Buffer_Read_Pos\r
924 mov edi, Buf_R\r
925 dec ecx\r
926\r
927loop_R:\r
928 mov eax, CD_Audio_Buffer_R[esi * 4]\r
929 add [edi], eax\r
930 inc esi\r
931 add edi, 4\r
932 and esi, 0xFFF\r
933 dec ecx\r
934 jns short loop_R\r
935\r
936 mov CD_Audio_Buffer_Read_Pos, esi\r
937 }\r
938 }\r
939 else\r
940 {\r
941 CD_Audio_Buffer_Read_Pos += lenght;\r
942 CD_Audio_Buffer_Read_Pos &= 0xFFF;\r
943 }\r
944\r
945#ifdef DEBUG_CD\r
946 fprintf(debug_SCD_file, "Read Pos 2 = %d\n\n", CD_Audio_Buffer_Read_Pos);\r
947#endif\r
948}\r
949#endif\r
950\r