bios CD player runs
[picodrive.git] / Pico / cd / cd_sys.c
CommitLineData
cc68a136 1#include <stdio.h>\r
2#include "cd_sys.h"\r
3//#include "cd_file.h"\r
4\r
5#include "../PicoInt.h"\r
6\r
7#define cdprintf printf\r
8//#define cdprintf(x...)\r
9\r
10#define TRAY_OPEN 0x0500 // TRAY OPEN CDD status\r
11#define NOCD 0x0000 // CD removed CDD status\r
12#define STOPPED 0x0900 // STOPPED CDD status (happen after stop or close tray command)\r
13#define READY 0x0400 // READY CDD status (also used for seeking)\r
14#define FAST_FOW 0x0300 // FAST FORWARD track CDD status\r
15#define FAST_REV 0x10300 // FAST REVERSE track CDD status\r
16#define PLAYING 0x0100 // PLAYING audio track CDD status\r
17\r
18/*\r
19#include "gens.h"\r
20#include "G_dsound.h"\r
21#include "cdda_mp3.h"\r
22#include "lc89510.h"\r
23#include "Star_68k.h"\r
24#include "Mem_M68K.h"\r
25#include "Mem_S68K.h"\r
26#include "save.h"\r
27#include "misc.h"\r
28*/\r
29\r
30\r
31/*\r
32int CDDA_Enable;\r
33\r
34int CD_Audio_Buffer_L[8192];\r
35int CD_Audio_Buffer_R[8192];\r
36int CD_Audio_Buffer_Read_Pos = 0;\r
37int CD_Audio_Buffer_Write_Pos = 2000;\r
38int CD_Audio_Starting;\r
39*/\r
40\r
41static int CD_Present = 0;\r
42int CD_Timer_Counter = 0; // TODO: check refs\r
43\r
44static int CDD_Complete;\r
45\r
46static int File_Add_Delay = 0;\r
47\r
48//_scd SCD;\r
49\r
50\r
51\r
52#define CHECK_TRAY_OPEN \\r
53if (Pico_mcd->scd.Status_CDD == TRAY_OPEN) \\r
54{ \\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
62 CDD_Complete = 1; \\r
63 \\r
64 return 2; \\r
65}\r
66\r
67\r
68#define CHECK_CD_PRESENT \\r
69if (!CD_Present) \\r
70{ \\r
71 Pico_mcd->scd.Status_CDD = NOCD; \\r
72 Pico_mcd->cdd.Status = Pico_mcd->scd.Status_CDD; \\r
73 \\r
74 Pico_mcd->cdd.Minute = 0; \\r
75 Pico_mcd->cdd.Seconde = 0; \\r
76 Pico_mcd->cdd.Frame = 0; \\r
77 Pico_mcd->cdd.Ext = 0; \\r
78 \\r
79 CDD_Complete = 1; \\r
80 \\r
81 return 3; \\r
82}\r
83\r
84\r
85#if 0\r
86static void MSB2DWORD(unsigned int *d, unsigned char *b)\r
87{\r
88 unsigned int retVal;\r
89\r
90 retVal = (unsigned int )b[0];\r
91 retVal = (retVal<<8) + (unsigned int )b[1];\r
92 retVal = (retVal<<8) + (unsigned int )b[2];\r
93 retVal = (retVal<<8) + (unsigned int )b[3];\r
94\r
95 *d = retVal;\r
96}\r
97#endif\r
98\r
99static int MSF_to_LBA(_msf *MSF)\r
100{\r
101 return (MSF->M * 60 * 75) + (MSF->S * 75) + MSF->F - 150;\r
102}\r
103\r
104\r
105void LBA_to_MSF(int lba, _msf *MSF)\r
106{\r
107 if (lba < -150) lba = 0;\r
108 else lba += 150;\r
109 MSF->M = lba / (60 * 75);\r
110 MSF->S = (lba / 75) % 60;\r
111 MSF->F = lba % 75;\r
112}\r
113\r
114\r
115static unsigned int MSF_to_Track(_msf *MSF)\r
116{\r
117 int i, Start, Cur;\r
118\r
119 Start = (MSF->M << 16) + (MSF->S << 8) + MSF->F;\r
120\r
121 for(i = Pico_mcd->scd.TOC.First_Track; i <= (Pico_mcd->scd.TOC.Last_Track + 1); i++)\r
122 {\r
123 Cur = Pico_mcd->scd.TOC.Tracks[i - Pico_mcd->scd.TOC.First_Track].MSF.M << 16;\r
124 Cur += Pico_mcd->scd.TOC.Tracks[i - Pico_mcd->scd.TOC.First_Track].MSF.S << 8;\r
125 Cur += Pico_mcd->scd.TOC.Tracks[i - Pico_mcd->scd.TOC.First_Track].MSF.F;\r
126\r
127 if (Cur > Start) break;\r
128 }\r
129\r
130 --i;\r
131\r
132 if (i > Pico_mcd->scd.TOC.Last_Track) return 100;\r
133 if (i < Pico_mcd->scd.TOC.First_Track) i = Pico_mcd->scd.TOC.First_Track;\r
134\r
135 return (unsigned) i;\r
136}\r
137\r
138\r
139static unsigned int LBA_to_Track(int lba)\r
140{\r
141 _msf MSF;\r
142\r
143 LBA_to_MSF(lba, &MSF);\r
144 return MSF_to_Track(&MSF);\r
145}\r
146\r
147\r
148static void Track_to_MSF(int track, _msf *MSF)\r
149{\r
150 if (track < Pico_mcd->scd.TOC.First_Track) track = Pico_mcd->scd.TOC.First_Track;\r
151 else if (track > Pico_mcd->scd.TOC.Last_Track) track = Pico_mcd->scd.TOC.Last_Track;\r
152\r
153 MSF->M = Pico_mcd->scd.TOC.Tracks[track - Pico_mcd->scd.TOC.First_Track].MSF.M;\r
154 MSF->S = Pico_mcd->scd.TOC.Tracks[track - Pico_mcd->scd.TOC.First_Track].MSF.S;\r
155 MSF->F = Pico_mcd->scd.TOC.Tracks[track - Pico_mcd->scd.TOC.First_Track].MSF.F;\r
156}\r
157\r
158\r
159int Track_to_LBA(int track)\r
160{\r
161 _msf MSF;\r
162\r
163 Track_to_MSF(track, &MSF);\r
164 return MSF_to_LBA(&MSF);\r
165}\r
166\r
167\r
168void Check_CD_Command(void)\r
169{\r
170 cdprintf("CHECK CD COMMAND\n");\r
171\r
172 // Check CDD\r
173\r
174 if (CDD_Complete)\r
175 {\r
176 CDD_Complete = 0;\r
177\r
178 CDD_Export_Status();\r
179 }\r
180\r
181 // Check CDC\r
182\r
183 if (Pico_mcd->scd.Status_CDC & 1) // CDC is reading data ...\r
184 {\r
185 cdprintf("Sending a read command\n");\r
186\r
187 // DATA ?\r
188 if (Pico_mcd->scd.TOC.Tracks[Pico_mcd->scd.Cur_Track - Pico_mcd->scd.TOC.First_Track].Type)\r
189 Pico_mcd->s68k_regs[0x36] |= 0x01;\r
190 else Pico_mcd->s68k_regs[0x36] &= ~0x01; // AUDIO\r
191\r
192 if (File_Add_Delay == 0)\r
193 {\r
194#if 0 // TODO\r
195 FILE_Read_One_LBA_CDC();\r
196#endif\r
197 }\r
198 else File_Add_Delay--;\r
199 }\r
200\r
201 if (Pico_mcd->scd.Status_CDD == FAST_FOW)\r
202 {\r
203 Pico_mcd->scd.Cur_LBA += 10;\r
204 CDC_Update_Header();\r
205\r
206 }\r
207 else if (Pico_mcd->scd.Status_CDD == FAST_REV)\r
208 {\r
209 Pico_mcd->scd.Cur_LBA -= 10;\r
210 if (Pico_mcd->scd.Cur_LBA < -150) Pico_mcd->scd.Cur_LBA = -150;\r
211 CDC_Update_Header();\r
212 }\r
213}\r
214\r
215\r
216int Init_CD_Driver(void)\r
217{\r
218#if 0 // TODO\r
219 FILE_Init();\r
220#endif\r
221\r
222 return 0;\r
223}\r
224\r
225\r
226void End_CD_Driver(void)\r
227{\r
228#if 0 // TODO\r
229 FILE_End();\r
230#endif\r
231}\r
232\r
233\r
234void Reset_CD(void)\r
235{\r
236 Pico_mcd->scd.Cur_Track = 0;\r
237 Pico_mcd->scd.Cur_LBA = -150;\r
238 Pico_mcd->scd.Status_CDD = READY;\r
239 CDD_Complete = 0;\r
240}\r
241\r
242\r
243int Insert_CD(char *buf, char *iso_name)\r
244{\r
245// memset(CD_Audio_Buffer_L, 0, 4096 * 4);\r
246// memset(CD_Audio_Buffer_R, 0, 4096 * 4);\r
247\r
248 if (iso_name == NULL)\r
249 {\r
250 CD_Present = 0;\r
251 }\r
252 else\r
253 {\r
254#if 0 // TODO\r
255 Load_ISO(buf, iso_name);\r
256 CD_Present = 1;\r
257#endif\r
258 return 0;\r
259 }\r
260\r
261 return 0;\r
262}\r
263\r
264\r
265void Stop_CD(void)\r
266{\r
267#if 0 // TODO\r
268 Unload_ISO();\r
269#endif\r
270 CD_Present = 0;\r
271}\r
272\r
273\r
274void Change_CD(void)\r
275{\r
276 if (Pico_mcd->scd.Status_CDD == TRAY_OPEN) Close_Tray_CDD_cC();\r
277 else Open_Tray_CDD_cD();\r
278}\r
279\r
280\r
281int Get_Status_CDD_c0(void)\r
282{\r
283 cdprintf("Status command : Cur LBA = %d\n", Pico_mcd->scd.Cur_LBA);\r
284\r
285 // Clear immediat status\r
286 if ((Pico_mcd->cdd.Status & 0x0F00) == 0x0200)\r
287 Pico_mcd->cdd.Status = (Pico_mcd->scd.Status_CDD & 0xFF00) | (Pico_mcd->cdd.Status & 0x00FF);\r
288 else if ((Pico_mcd->cdd.Status & 0x0F00) == 0x0700)\r
289 Pico_mcd->cdd.Status = (Pico_mcd->scd.Status_CDD & 0xFF00) | (Pico_mcd->cdd.Status & 0x00FF);\r
290 else if ((Pico_mcd->cdd.Status & 0x0F00) == 0x0E00)\r
291 Pico_mcd->cdd.Status = (Pico_mcd->scd.Status_CDD & 0xFF00) | (Pico_mcd->cdd.Status & 0x00FF);\r
292\r
293 CDD_Complete = 1;\r
294\r
295 return 0;\r
296}\r
297\r
298\r
299int Stop_CDD_c1(void)\r
300{\r
301 CHECK_TRAY_OPEN\r
302\r
303 Pico_mcd->scd.Status_CDC &= ~1; // Stop CDC read\r
304\r
305 if (CD_Present) Pico_mcd->scd.Status_CDD = STOPPED;\r
306 else Pico_mcd->scd.Status_CDD = NOCD;\r
307 Pico_mcd->cdd.Status = 0x0000;\r
308\r
309 Pico_mcd->s68k_regs[0x36] |= 0x01; // Data bit set because stopped\r
310\r
311 Pico_mcd->cdd.Minute = 0;\r
312 Pico_mcd->cdd.Seconde = 0;\r
313 Pico_mcd->cdd.Frame = 0;\r
314 Pico_mcd->cdd.Ext = 0;\r
315\r
316 CDD_Complete = 1;\r
317\r
318 return 0;\r
319}\r
320\r
321\r
322int Get_Pos_CDD_c20(void)\r
323{\r
324 _msf MSF;\r
325\r
326 cdprintf("command 200 : Cur LBA = %d\n", Pico_mcd->scd.Cur_LBA);\r
327\r
328 CHECK_TRAY_OPEN\r
329\r
330 Pico_mcd->cdd.Status &= 0xFF;\r
331 if (!CD_Present)\r
332 {\r
333 Pico_mcd->scd.Status_CDD = NOCD;\r
334 Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
335 }\r
336// else if (!(CDC.CTRL.B.B0 & 0x80)) Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
337 Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
338\r
339 cdprintf("Status CDD = %.4X Status = %.4X\n", Pico_mcd->scd.Status_CDD, Pico_mcd->cdd.Status);\r
340\r
341 LBA_to_MSF(Pico_mcd->scd.Cur_LBA, &MSF);\r
342\r
343 Pico_mcd->cdd.Minute = INT_TO_BCDW(MSF.M);\r
344 Pico_mcd->cdd.Seconde = INT_TO_BCDW(MSF.S);\r
345 Pico_mcd->cdd.Frame = INT_TO_BCDW(MSF.F);\r
346 Pico_mcd->cdd.Ext = 0;\r
347\r
348 CDD_Complete = 1;\r
349\r
350 return 0;\r
351}\r
352\r
353\r
354int Get_Track_Pos_CDD_c21(void)\r
355{\r
356 int elapsed_time;\r
357 _msf MSF;\r
358\r
359 cdprintf("command 201 : Cur LBA = %d", Pico_mcd->scd.Cur_LBA);\r
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 elapsed_time = Pico_mcd->scd.Cur_LBA - Track_to_LBA(LBA_to_Track(Pico_mcd->scd.Cur_LBA));\r
373 LBA_to_MSF(elapsed_time - 150, &MSF);\r
374\r
375 cdprintf(" elapsed = %d\n", elapsed_time);\r
376\r
377 Pico_mcd->cdd.Minute = INT_TO_BCDW(MSF.M);\r
378 Pico_mcd->cdd.Seconde = INT_TO_BCDW(MSF.S);\r
379 Pico_mcd->cdd.Frame = INT_TO_BCDW(MSF.F);\r
380 Pico_mcd->cdd.Ext = 0;\r
381\r
382 CDD_Complete = 1;\r
383\r
384 return 0;\r
385}\r
386\r
387\r
388int Get_Current_Track_CDD_c22(void)\r
389{\r
390 cdprintf("Status CDD = %.4X Status = %.4X\n", Pico_mcd->scd.Status_CDD, Pico_mcd->cdd.Status);\r
391\r
392 CHECK_TRAY_OPEN\r
393\r
394 Pico_mcd->cdd.Status &= 0xFF;\r
395 if (!CD_Present)\r
396 {\r
397 Pico_mcd->scd.Status_CDD = NOCD;\r
398 Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
399 }\r
400// else if (!(CDC.CTRL.B.B0 & 0x80)) Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
401 Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
402\r
403 Pico_mcd->scd.Cur_Track = LBA_to_Track(Pico_mcd->scd.Cur_LBA);\r
404\r
405 if (Pico_mcd->scd.Cur_Track == 100) Pico_mcd->cdd.Minute = 0x0A02;\r
406 else Pico_mcd->cdd.Minute = INT_TO_BCDW(Pico_mcd->scd.Cur_Track);\r
407 Pico_mcd->cdd.Seconde = 0;\r
408 Pico_mcd->cdd.Frame = 0;\r
409 Pico_mcd->cdd.Ext = 0;\r
410\r
411 CDD_Complete = 1;\r
412\r
413 return 0;\r
414}\r
415\r
416\r
417int Get_Total_Lenght_CDD_c23(void)\r
418{\r
419 CHECK_TRAY_OPEN\r
420\r
421 Pico_mcd->cdd.Status &= 0xFF;\r
422 if (!CD_Present)\r
423 {\r
424 Pico_mcd->scd.Status_CDD = NOCD;\r
425 Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
426 }\r
427// else if (!(CDC.CTRL.B.B0 & 0x80)) Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
428 Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
429\r
430 Pico_mcd->cdd.Minute = INT_TO_BCDW(Pico_mcd->scd.TOC.Tracks[Pico_mcd->scd.TOC.Last_Track -\r
431 Pico_mcd->scd.TOC.First_Track + 1].MSF.M);\r
432 Pico_mcd->cdd.Seconde = INT_TO_BCDW(Pico_mcd->scd.TOC.Tracks[Pico_mcd->scd.TOC.Last_Track -\r
433 Pico_mcd->scd.TOC.First_Track + 1].MSF.S);\r
434 Pico_mcd->cdd.Frame = INT_TO_BCDW(Pico_mcd->scd.TOC.Tracks[Pico_mcd->scd.TOC.Last_Track -\r
435 Pico_mcd->scd.TOC.First_Track + 1].MSF.F);\r
436 Pico_mcd->cdd.Ext = 0;\r
437\r
438// FIXME: remove\r
439Pico_mcd->cdd.Seconde = 2;\r
440\r
441 CDD_Complete = 1;\r
442\r
443 return 0;\r
444}\r
445\r
446\r
447int Get_First_Last_Track_CDD_c24(void)\r
448{\r
449 CHECK_TRAY_OPEN\r
450\r
451 Pico_mcd->cdd.Status &= 0xFF;\r
452 if (!CD_Present)\r
453 {\r
454 Pico_mcd->scd.Status_CDD = NOCD;\r
455 }\r
456// else if (!(CDC.CTRL.B.B0 & 0x80)) Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
457 Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
458\r
459 Pico_mcd->cdd.Minute = INT_TO_BCDW(Pico_mcd->scd.TOC.First_Track);\r
460 Pico_mcd->cdd.Seconde = INT_TO_BCDW(Pico_mcd->scd.TOC.Last_Track);\r
461 Pico_mcd->cdd.Frame = 0;\r
462 Pico_mcd->cdd.Ext = 0;\r
463\r
464// FIXME: remove\r
465Pico_mcd->cdd.Minute = Pico_mcd->cdd.Seconde = 1;\r
466\r
467 CDD_Complete = 1;\r
468\r
469 return 0;\r
470}\r
471\r
472\r
473int Get_Track_Adr_CDD_c25(void)\r
474{\r
475 int track_number;\r
476\r
477 CHECK_TRAY_OPEN\r
478\r
479 // track number in TC4 & TC5\r
480\r
481 track_number = (Pico_mcd->s68k_regs[0x38+10+4] & 0xF) * 10 + (Pico_mcd->s68k_regs[0x38+10+5] & 0xF);\r
482\r
483 Pico_mcd->cdd.Status &= 0xFF;\r
484 if (!CD_Present)\r
485 {\r
486 Pico_mcd->scd.Status_CDD = NOCD;\r
487 Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
488 }\r
489// else if (!(CDC.CTRL.B.B0 & 0x80)) Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
490 Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r
491\r
492 if (track_number > Pico_mcd->scd.TOC.Last_Track) track_number = Pico_mcd->scd.TOC.Last_Track;\r
493 else if (track_number < Pico_mcd->scd.TOC.First_Track) track_number = Pico_mcd->scd.TOC.First_Track;\r
494\r
495 Pico_mcd->cdd.Minute = INT_TO_BCDW(Pico_mcd->scd.TOC.Tracks[track_number - Pico_mcd->scd.TOC.First_Track].MSF.M);\r
496 Pico_mcd->cdd.Seconde = INT_TO_BCDW(Pico_mcd->scd.TOC.Tracks[track_number - Pico_mcd->scd.TOC.First_Track].MSF.S);\r
497 Pico_mcd->cdd.Frame = INT_TO_BCDW(Pico_mcd->scd.TOC.Tracks[track_number - Pico_mcd->scd.TOC.First_Track].MSF.F);\r
498 Pico_mcd->cdd.Ext = track_number % 10;\r
499\r
500 if (Pico_mcd->scd.TOC.Tracks[track_number - Pico_mcd->scd.TOC.First_Track].Type) Pico_mcd->cdd.Frame |= 0x0800;\r
501\r
502 CDD_Complete = 1;\r
503 return 0;\r
504}\r
505\r
506\r
507int Play_CDD_c3(void)\r
508{\r
509 _msf MSF;\r
510 int delay, new_lba;\r
511\r
512 CHECK_TRAY_OPEN\r
513 CHECK_CD_PRESENT\r
514\r
515 // MSF of the track to play in TC buffer\r
516\r
517 MSF.M = (Pico_mcd->s68k_regs[0x38+10+2] & 0xF) * 10 + (Pico_mcd->s68k_regs[0x38+10+3] & 0xF);\r
518 MSF.S = (Pico_mcd->s68k_regs[0x38+10+4] & 0xF) * 10 + (Pico_mcd->s68k_regs[0x38+10+5] & 0xF);\r
519 MSF.F = (Pico_mcd->s68k_regs[0x38+10+6] & 0xF) * 10 + (Pico_mcd->s68k_regs[0x38+10+7] & 0xF);\r
520\r
521 Pico_mcd->scd.Cur_Track = MSF_to_Track(&MSF);\r
522\r
523 new_lba = MSF_to_LBA(&MSF);\r
524 delay = new_lba - Pico_mcd->scd.Cur_LBA;\r
525 if (delay < 0) delay = -delay;\r
526 delay >>= 12;\r
527\r
528 Pico_mcd->scd.Cur_LBA = new_lba;\r
529 CDC_Update_Header();\r
530\r
531 cdprintf("Read : Cur LBA = %d, M=%d, S=%d, F=%d\n", Pico_mcd->scd.Cur_LBA, MSF.M, MSF.S, MSF.F);\r
532\r
533 if (Pico_mcd->scd.Status_CDD != PLAYING) delay += 20;\r
534\r
535 Pico_mcd->scd.Status_CDD = PLAYING;\r
536 Pico_mcd->cdd.Status = 0x0102;\r
537// Pico_mcd->cdd.Status = COMM_OK;\r
538\r
539 if (File_Add_Delay == 0) File_Add_Delay = delay;\r
540\r
541 if (Pico_mcd->scd.TOC.Tracks[Pico_mcd->scd.Cur_Track - Pico_mcd->scd.TOC.First_Track].Type)\r
542 {\r
543 Pico_mcd->s68k_regs[0x36] |= 0x01; // DATA\r
544 }\r
545 else\r
546 {\r
547 Pico_mcd->s68k_regs[0x36] &= ~0x01; // AUDIO\r
548 //CD_Audio_Starting = 1;\r
549#if 0 // TODO\r
550 FILE_Play_CD_LBA();\r
551#endif\r
552 }\r
553\r
554 if (Pico_mcd->scd.Cur_Track == 100) Pico_mcd->cdd.Minute = 0x0A02;\r
555 else Pico_mcd->cdd.Minute = INT_TO_BCDW(Pico_mcd->scd.Cur_Track);\r
556 Pico_mcd->cdd.Seconde = 0;\r
557 Pico_mcd->cdd.Frame = 0;\r
558 Pico_mcd->cdd.Ext = 0;\r
559\r
560 Pico_mcd->scd.Status_CDC |= 1; // Read data with CDC\r
561\r
562 CDD_Complete = 1;\r
563 return 0;\r
564}\r
565\r
566\r
567int Seek_CDD_c4(void)\r
568{\r
569 _msf MSF;\r
570\r
571 CHECK_TRAY_OPEN\r
572 CHECK_CD_PRESENT\r
573\r
574 // MSF to seek in TC buffer\r
575\r
576 MSF.M = (Pico_mcd->s68k_regs[0x38+10+2] & 0xF) * 10 + (Pico_mcd->s68k_regs[0x38+10+3] & 0xF);\r
577 MSF.S = (Pico_mcd->s68k_regs[0x38+10+4] & 0xF) * 10 + (Pico_mcd->s68k_regs[0x38+10+5] & 0xF);\r
578 MSF.F = (Pico_mcd->s68k_regs[0x38+10+6] & 0xF) * 10 + (Pico_mcd->s68k_regs[0x38+10+7] & 0xF);\r
579\r
580 Pico_mcd->scd.Cur_Track = MSF_to_Track(&MSF);\r
581 Pico_mcd->scd.Cur_LBA = MSF_to_LBA(&MSF);\r
582 CDC_Update_Header();\r
583\r
584 Pico_mcd->scd.Status_CDC &= ~1; // Stop CDC read\r
585\r
586 Pico_mcd->scd.Status_CDD = READY;\r
587 Pico_mcd->cdd.Status = 0x0200;\r
588\r
589 // DATA ?\r
590 if (Pico_mcd->scd.TOC.Tracks[Pico_mcd->scd.Cur_Track - Pico_mcd->scd.TOC.First_Track].Type)\r
591 Pico_mcd->s68k_regs[0x36] |= 0x01;\r
592 else Pico_mcd->s68k_regs[0x36] &= ~0x01; // AUDIO\r
593\r
594 Pico_mcd->cdd.Minute = 0;\r
595 Pico_mcd->cdd.Seconde = 0;\r
596 Pico_mcd->cdd.Frame = 0;\r
597 Pico_mcd->cdd.Ext = 0;\r
598\r
599 CDD_Complete = 1;\r
600\r
601 return 0;\r
602}\r
603\r
604\r
605int Pause_CDD_c6(void)\r
606{\r
607 CHECK_TRAY_OPEN\r
608 CHECK_CD_PRESENT\r
609\r
610 Pico_mcd->scd.Status_CDC &= ~1; // Stop CDC read to start a new one if raw data\r
611\r
612 Pico_mcd->scd.Status_CDD = READY;\r
613 Pico_mcd->cdd.Status = Pico_mcd->scd.Status_CDD;\r
614\r
615 Pico_mcd->s68k_regs[0x36] |= 0x01; // Data bit set because stopped\r
616\r
617 Pico_mcd->cdd.Minute = 0;\r
618 Pico_mcd->cdd.Seconde = 0;\r
619 Pico_mcd->cdd.Frame = 0;\r
620 Pico_mcd->cdd.Ext = 0;\r
621\r
622 CDD_Complete = 1;\r
623\r
624 return 0;\r
625}\r
626\r
627\r
628int Resume_CDD_c7(void)\r
629{\r
630 CHECK_TRAY_OPEN\r
631 CHECK_CD_PRESENT\r
632\r
633 Pico_mcd->scd.Cur_Track = LBA_to_Track(Pico_mcd->scd.Cur_LBA);\r
634\r
635#ifdef DEBUG_CD\r
636 {\r
637 _msf MSF;\r
638 LBA_to_MSF(Pico_mcd->scd.Cur_LBA, &MSF);\r
639 cdprintf("Resume read : Cur LBA = %d, M=%d, S=%d, F=%d\n", Pico_mcd->scd.Cur_LBA, MSF.M, MSF.S, MSF.F);\r
640 }\r
641#endif\r
642\r
643 Pico_mcd->scd.Status_CDD = PLAYING;\r
644 Pico_mcd->cdd.Status = 0x0102;\r
645\r
646 if (Pico_mcd->scd.TOC.Tracks[Pico_mcd->scd.Cur_Track - Pico_mcd->scd.TOC.First_Track].Type)\r
647 {\r
648 Pico_mcd->s68k_regs[0x36] |= 0x01; // DATA\r
649 }\r
650 else\r
651 {\r
652 Pico_mcd->s68k_regs[0x36] &= ~0x01; // AUDIO\r
653 //CD_Audio_Starting = 1;\r
654#if 0 // TODO\r
655 FILE_Play_CD_LBA();\r
656#endif\r
657 }\r
658\r
659 if (Pico_mcd->scd.Cur_Track == 100) Pico_mcd->cdd.Minute = 0x0A02;\r
660 else Pico_mcd->cdd.Minute = INT_TO_BCDW(Pico_mcd->scd.Cur_Track);\r
661 Pico_mcd->cdd.Seconde = 0;\r
662 Pico_mcd->cdd.Frame = 0;\r
663 Pico_mcd->cdd.Ext = 0;\r
664\r
665 Pico_mcd->scd.Status_CDC |= 1; // Read data with CDC\r
666\r
667 CDD_Complete = 1;\r
668 return 0;\r
669}\r
670\r
671\r
672int Fast_Foward_CDD_c8(void)\r
673{\r
674 CHECK_TRAY_OPEN\r
675 CHECK_CD_PRESENT\r
676\r
677 Pico_mcd->scd.Status_CDC &= ~1; // Stop CDC read\r
678\r
679 Pico_mcd->scd.Status_CDD = FAST_FOW;\r
680 Pico_mcd->cdd.Status = Pico_mcd->scd.Status_CDD | 2;\r
681\r
682 Pico_mcd->cdd.Minute = INT_TO_BCDW(Pico_mcd->scd.Cur_Track);\r
683 Pico_mcd->cdd.Seconde = 0;\r
684 Pico_mcd->cdd.Frame = 0;\r
685 Pico_mcd->cdd.Ext = 0;\r
686\r
687 CDD_Complete = 1;\r
688\r
689 return 0;\r
690}\r
691\r
692\r
693int Fast_Rewind_CDD_c9(void)\r
694{\r
695 CHECK_TRAY_OPEN\r
696 CHECK_CD_PRESENT\r
697\r
698 Pico_mcd->scd.Status_CDC &= ~1; // Stop CDC read\r
699\r
700 Pico_mcd->scd.Status_CDD = FAST_REV;\r
701 Pico_mcd->cdd.Status = Pico_mcd->scd.Status_CDD | 2;\r
702\r
703 Pico_mcd->cdd.Minute = INT_TO_BCDW(Pico_mcd->scd.Cur_Track);\r
704 Pico_mcd->cdd.Seconde = 0;\r
705 Pico_mcd->cdd.Frame = 0;\r
706 Pico_mcd->cdd.Ext = 0;\r
707\r
708 CDD_Complete = 1;\r
709\r
710 return 0;\r
711}\r
712\r
713\r
714int Close_Tray_CDD_cC(void)\r
715{\r
716 //Clear_Sound_Buffer();\r
717\r
718 Pico_mcd->scd.Status_CDC &= ~1; // Stop CDC read\r
719\r
720 {\r
721#if 0 // TODO\r
722 char new_iso[1024];\r
723\r
724 memset(new_iso, 0, 1024);\r
725\r
726 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
727 Reload_SegaCD(new_iso);\r
728\r
729 CD_Present = 1;\r
730#else\r
731 CD_Present = 0;\r
732#endif\r
733 Pico_mcd->scd.Status_CDD = STOPPED;\r
734 Pico_mcd->cdd.Status = 0x0000;\r
735\r
736 Pico_mcd->cdd.Minute = 0;\r
737 Pico_mcd->cdd.Seconde = 0;\r
738 Pico_mcd->cdd.Frame = 0;\r
739 Pico_mcd->cdd.Ext = 0;\r
740 }\r
741\r
742 CDD_Complete = 1;\r
743\r
744 return 0;\r
745}\r
746\r
747\r
748int Open_Tray_CDD_cD(void)\r
749{\r
750 CHECK_TRAY_OPEN\r
751\r
752 Pico_mcd->scd.Status_CDC &= ~1; // Stop CDC read\r
753\r
754#if 0 // TODO\r
755 Unload_ISO();\r
756#endif\r
757 CD_Present = 0;\r
758\r
759 Pico_mcd->scd.Status_CDD = TRAY_OPEN;\r
760 Pico_mcd->cdd.Status = 0x0E00;\r
761\r
762 Pico_mcd->cdd.Minute = 0;\r
763 Pico_mcd->cdd.Seconde = 0;\r
764 Pico_mcd->cdd.Frame = 0;\r
765 Pico_mcd->cdd.Ext = 0;\r
766\r
767 CDD_Complete = 1;\r
768\r
769 return 0;\r
770}\r
771\r
772\r
773int CDD_cA(void)\r
774{\r
775 CHECK_TRAY_OPEN\r
776 CHECK_CD_PRESENT\r
777\r
778 Pico_mcd->scd.Status_CDC &= ~1;\r
779\r
780 Pico_mcd->scd.Status_CDD = READY;\r
781 Pico_mcd->cdd.Status = Pico_mcd->scd.Status_CDD;\r
782\r
783 Pico_mcd->cdd.Minute = 0;\r
784 Pico_mcd->cdd.Seconde = INT_TO_BCDW(1);\r
785 Pico_mcd->cdd.Frame = INT_TO_BCDW(1);\r
786 Pico_mcd->cdd.Ext = 0;\r
787\r
788 CDD_Complete = 1;\r
789\r
790 return 0;\r
791}\r
792\r
793\r
794int CDD_Def(void)\r
795{\r
796 Pico_mcd->cdd.Status = Pico_mcd->scd.Status_CDD;\r
797\r
798 Pico_mcd->cdd.Minute = 0;\r
799 Pico_mcd->cdd.Seconde = 0;\r
800 Pico_mcd->cdd.Frame = 0;\r
801 Pico_mcd->cdd.Ext = 0;\r
802\r
803 return 0;\r
804}\r
805\r
806\r
807\r
808\r
809/***************************\r
810 * Others CD functions *\r
811 **************************/\r
812\r
813\r
814// do we need them?\r
815#if 0\r
816void Write_CD_Audio(short *Buf, int rate, int channel, int lenght)\r
817{\r
818 unsigned int lenght_src, lenght_dst;\r
819 unsigned int pos_src, pas_src;\r
820\r
821 if (rate == 0) return;\r
822 if (Sound_Rate == 0) return;\r
823\r
824 if (CD_Audio_Starting)\r
825 {\r
826 CD_Audio_Starting = 0;\r
827 memset(CD_Audio_Buffer_L, 0, 4096 * 4);\r
828 memset(CD_Audio_Buffer_R, 0, 4096 * 4);\r
829 CD_Audio_Buffer_Write_Pos = (CD_Audio_Buffer_Read_Pos + 2000) & 0xFFF;\r
830 }\r
831\r
832 lenght_src = rate / 75; // 75th of a second\r
833 lenght_dst = Sound_Rate / 75; // 75th of a second\r
834\r
835 pas_src = (lenght_src << 16) / lenght_dst;\r
836 pos_src = 0;\r
837\r
838#ifdef DEBUG_CD\r
839 fprintf(debug_SCD_file, "\n********* Write Pos = %d ", CD_Audio_Buffer_Write_Pos);\r
840#endif\r
841\r
842 if (channel == 2)\r
843 {\r
844 __asm\r
845 {\r
846 mov edi, CD_Audio_Buffer_Write_Pos\r
847 mov ebx, Buf\r
848 xor esi, esi\r
849 mov ecx, lenght_dst\r
850 xor eax, eax\r
851 mov edx, pas_src\r
852 dec ecx\r
853 jmp short loop_stereo\r
854\r
855align 16\r
856\r
857loop_stereo:\r
858 movsx eax, word ptr [ebx + esi * 4]\r
859 mov CD_Audio_Buffer_L[edi * 4], eax\r
860 movsx eax, word ptr [ebx + esi * 4 + 2]\r
861 mov CD_Audio_Buffer_R[edi * 4], eax\r
862 mov esi, dword ptr pos_src\r
863 inc edi\r
864 add esi, edx\r
865 and edi, 0xFFF\r
866 mov dword ptr pos_src, esi\r
867 shr esi, 16\r
868 dec ecx\r
869 jns short loop_stereo\r
870\r
871 mov CD_Audio_Buffer_Write_Pos, edi\r
872 }\r
873 }\r
874 else\r
875 {\r
876 __asm\r
877 {\r
878 mov edi, CD_Audio_Buffer_Write_Pos\r
879 mov ebx, Buf\r
880 xor esi, esi\r
881 mov ecx, lenght_dst\r
882 xor eax, eax\r
883 mov edx, pas_src\r
884 dec ecx\r
885 jmp short loop_mono\r
886\r
887align 16\r
888\r
889loop_mono:\r
890 movsx eax, word ptr [ebx + esi * 2]\r
891 mov CD_Audio_Buffer_L[edi * 4], eax\r
892 mov CD_Audio_Buffer_R[edi * 4], eax\r
893 mov esi, dword ptr pos_src\r
894 inc edi\r
895 add esi, edx\r
896 and edi, 0xFFF\r
897 mov dword ptr pos_src, esi\r
898 shr esi, 16\r
899 dec ecx\r
900 jns short loop_mono\r
901\r
902 mov CD_Audio_Buffer_Write_Pos, edi\r
903 }\r
904 }\r
905\r
906#ifdef DEBUG_CD\r
907 fprintf(debug_SCD_file, "Write Pos 2 = %d\n\n", CD_Audio_Buffer_Write_Pos);\r
908#endif\r
909}\r
910\r
911\r
912void Update_CD_Audio(int **buf, int lenght)\r
913{\r
914 int *Buf_L, *Buf_R;\r
915 int diff;\r
916\r
917 Buf_L = buf[0];\r
918 Buf_R = buf[1];\r
919\r
920 if (Pico_mcd->s68k_regs[0x36] & 0x01) return;\r
921 if (!(Pico_mcd->scd.Status_CDC & 1)) return;\r
922 if (CD_Audio_Starting) return;\r
923\r
924#ifdef DEBUG_CD\r
925 fprintf(debug_SCD_file, "\n********* Read Pos Normal = %d ", CD_Audio_Buffer_Read_Pos);\r
926#endif\r
927\r
928 if (CD_Audio_Buffer_Write_Pos < CD_Audio_Buffer_Read_Pos)\r
929 {\r
930 diff = CD_Audio_Buffer_Write_Pos + (4096) - CD_Audio_Buffer_Read_Pos;\r
931 }\r
932 else\r
933 {\r
934 diff = CD_Audio_Buffer_Write_Pos - CD_Audio_Buffer_Read_Pos;\r
935 }\r
936\r
937 if (diff < 500) CD_Audio_Buffer_Read_Pos -= 2000;\r
938 else if (diff > 3500) CD_Audio_Buffer_Read_Pos += 2000;\r
939\r
940#ifdef DEBUG_CD\r
941 else fprintf(debug_SCD_file, " pas de modifs ");\r
942#endif\r
943\r
944 CD_Audio_Buffer_Read_Pos &= 0xFFF;\r
945\r
946#ifdef DEBUG_CD\r
947 fprintf(debug_SCD_file, "Read Pos = %d ", CD_Audio_Buffer_Read_Pos);\r
948#endif\r
949\r
950 if (CDDA_Enable)\r
951 {\r
952 __asm\r
953 {\r
954 mov ecx, lenght\r
955 mov esi, CD_Audio_Buffer_Read_Pos\r
956 mov edi, Buf_L\r
957 dec ecx\r
958\r
959loop_L:\r
960 mov eax, CD_Audio_Buffer_L[esi * 4]\r
961 add [edi], eax\r
962 inc esi\r
963 add edi, 4\r
964 and esi, 0xFFF\r
965 dec ecx\r
966 jns short loop_L\r
967\r
968 mov ecx, lenght\r
969 mov esi, CD_Audio_Buffer_Read_Pos\r
970 mov edi, Buf_R\r
971 dec ecx\r
972\r
973loop_R:\r
974 mov eax, CD_Audio_Buffer_R[esi * 4]\r
975 add [edi], eax\r
976 inc esi\r
977 add edi, 4\r
978 and esi, 0xFFF\r
979 dec ecx\r
980 jns short loop_R\r
981\r
982 mov CD_Audio_Buffer_Read_Pos, esi\r
983 }\r
984 }\r
985 else\r
986 {\r
987 CD_Audio_Buffer_Read_Pos += lenght;\r
988 CD_Audio_Buffer_Read_Pos &= 0xFFF;\r
989 }\r
990\r
991#ifdef DEBUG_CD\r
992 fprintf(debug_SCD_file, "Read Pos 2 = %d\n\n", CD_Audio_Buffer_Read_Pos);\r
993#endif\r
994}\r
995#endif\r
996\r