6cadc2da |
1 | /***********************************************************\r |
2 | * *\r |
8b99ab90 |
3 | * This source file was taken from the Gens project *\r |
6cadc2da |
4 | * Written by Stéphane Dallongeville *\r |
5 | * Copyright (c) 2002 by Stéphane Dallongeville *\r |
6 | * Modified/adapted for PicoDrive by notaz, 2007 *\r |
7 | * *\r |
8 | ***********************************************************/\r |
9 | \r |
cc68a136 |
10 | #include <stdio.h>\r |
cc68a136 |
11 | \r |
efcba75f |
12 | #include "../pico_int.h"\r |
eff55556 |
13 | #include "cd_sys.h"\r |
14 | #include "cd_file.h"\r |
cc68a136 |
15 | \r |
c459aefd |
16 | #define DEBUG_CD\r |
cc68a136 |
17 | \r |
18 | #define TRAY_OPEN 0x0500 // TRAY OPEN CDD status\r |
19 | #define NOCD 0x0000 // CD removed CDD status\r |
20 | #define STOPPED 0x0900 // STOPPED CDD status (happen after stop or close tray command)\r |
21 | #define READY 0x0400 // READY CDD status (also used for seeking)\r |
22 | #define FAST_FOW 0x0300 // FAST FORWARD track CDD status\r |
23 | #define FAST_REV 0x10300 // FAST REVERSE track CDD status\r |
24 | #define PLAYING 0x0100 // PLAYING audio track CDD status\r |
25 | \r |
3f23709e |
26 | //#undef cdprintf\r |
27 | //#define cdprintf(x, ...) elprintf(EL_STATUS, x, ##__VA_ARGS__)\r |
28 | \r |
29 | #define CDC_Update_Header()\r |
cc68a136 |
30 | \r |
cc68a136 |
31 | static int CD_Present = 0;\r |
cc68a136 |
32 | \r |
33 | \r |
34 | #define CHECK_TRAY_OPEN \\r |
35 | if (Pico_mcd->scd.Status_CDD == TRAY_OPEN) \\r |
36 | { \\r |
37 | Pico_mcd->cdd.Status = Pico_mcd->scd.Status_CDD; \\r |
38 | \\r |
39 | Pico_mcd->cdd.Minute = 0; \\r |
40 | Pico_mcd->cdd.Seconde = 0; \\r |
41 | Pico_mcd->cdd.Frame = 0; \\r |
42 | Pico_mcd->cdd.Ext = 0; \\r |
43 | \\r |
51a902ae |
44 | Pico_mcd->scd.CDD_Complete = 1; \\r |
cc68a136 |
45 | \\r |
46 | return 2; \\r |
47 | }\r |
48 | \r |
49 | \r |
50 | #define CHECK_CD_PRESENT \\r |
51 | if (!CD_Present) \\r |
52 | { \\r |
53 | Pico_mcd->scd.Status_CDD = NOCD; \\r |
54 | Pico_mcd->cdd.Status = Pico_mcd->scd.Status_CDD; \\r |
55 | \\r |
56 | Pico_mcd->cdd.Minute = 0; \\r |
57 | Pico_mcd->cdd.Seconde = 0; \\r |
58 | Pico_mcd->cdd.Frame = 0; \\r |
59 | Pico_mcd->cdd.Ext = 0; \\r |
60 | \\r |
51a902ae |
61 | Pico_mcd->scd.CDD_Complete = 1; \\r |
cc68a136 |
62 | \\r |
63 | return 3; \\r |
64 | }\r |
65 | \r |
66 | \r |
cc68a136 |
67 | static int MSF_to_LBA(_msf *MSF)\r |
68 | {\r |
69 | return (MSF->M * 60 * 75) + (MSF->S * 75) + MSF->F - 150;\r |
70 | }\r |
71 | \r |
72 | \r |
eff55556 |
73 | PICO_INTERNAL void LBA_to_MSF(int lba, _msf *MSF)\r |
cc68a136 |
74 | {\r |
75 | if (lba < -150) lba = 0;\r |
76 | else lba += 150;\r |
77 | MSF->M = lba / (60 * 75);\r |
78 | MSF->S = (lba / 75) % 60;\r |
79 | MSF->F = lba % 75;\r |
80 | }\r |
81 | \r |
82 | \r |
83 | static unsigned int MSF_to_Track(_msf *MSF)\r |
84 | {\r |
85 | int i, Start, Cur;\r |
86 | \r |
87 | Start = (MSF->M << 16) + (MSF->S << 8) + MSF->F;\r |
88 | \r |
75736070 |
89 | for(i = 1; i <= (Pico_mcd->TOC.Last_Track + 1); i++)\r |
cc68a136 |
90 | {\r |
75736070 |
91 | Cur = Pico_mcd->TOC.Tracks[i - 1].MSF.M << 16;\r |
92 | Cur += Pico_mcd->TOC.Tracks[i - 1].MSF.S << 8;\r |
93 | Cur += Pico_mcd->TOC.Tracks[i - 1].MSF.F;\r |
cc68a136 |
94 | \r |
95 | if (Cur > Start) break;\r |
96 | }\r |
97 | \r |
98 | --i;\r |
99 | \r |
75736070 |
100 | if (i > Pico_mcd->TOC.Last_Track) return 100;\r |
101 | else if (i < 1) i = 1;\r |
cc68a136 |
102 | \r |
103 | return (unsigned) i;\r |
104 | }\r |
105 | \r |
106 | \r |
107 | static unsigned int LBA_to_Track(int lba)\r |
108 | {\r |
109 | _msf MSF;\r |
110 | \r |
111 | LBA_to_MSF(lba, &MSF);\r |
112 | return MSF_to_Track(&MSF);\r |
113 | }\r |
114 | \r |
115 | \r |
116 | static void Track_to_MSF(int track, _msf *MSF)\r |
117 | {\r |
75736070 |
118 | if (track < 1) track = 1;\r |
119 | else if (track > Pico_mcd->TOC.Last_Track) track = Pico_mcd->TOC.Last_Track;\r |
cc68a136 |
120 | \r |
75736070 |
121 | MSF->M = Pico_mcd->TOC.Tracks[track - 1].MSF.M;\r |
122 | MSF->S = Pico_mcd->TOC.Tracks[track - 1].MSF.S;\r |
123 | MSF->F = Pico_mcd->TOC.Tracks[track - 1].MSF.F;\r |
cc68a136 |
124 | }\r |
125 | \r |
126 | \r |
eff55556 |
127 | PICO_INTERNAL int Track_to_LBA(int track)\r |
cc68a136 |
128 | {\r |
129 | _msf MSF;\r |
130 | \r |
131 | Track_to_MSF(track, &MSF);\r |
132 | return MSF_to_LBA(&MSF);\r |
133 | }\r |
134 | \r |
135 | \r |
eff55556 |
136 | PICO_INTERNAL void Check_CD_Command(void)\r |
cc68a136 |
137 | {\r |
c459aefd |
138 | cdprintf("CHECK CD COMMAND");\r |
cc68a136 |
139 | \r |
cc68a136 |
140 | // Check CDC\r |
cc68a136 |
141 | if (Pico_mcd->scd.Status_CDC & 1) // CDC is reading data ...\r |
142 | {\r |
c459aefd |
143 | cdprintf("Got a read command");\r |
cc68a136 |
144 | \r |
145 | // DATA ?\r |
3f23709e |
146 | if (Pico_mcd->scd.Cur_Track == 1) {\r |
cc68a136 |
147 | Pico_mcd->s68k_regs[0x36] |= 0x01;\r |
cc68a136 |
148 | \r |
3f23709e |
149 | if (Pico_mcd->scd.File_Add_Delay == 0)\r |
150 | {\r |
151 | unsigned char header[4];\r |
152 | _msf MSF;\r |
153 | \r |
154 | LBA_to_MSF(Pico_mcd->scd.Cur_LBA, &MSF);\r |
155 | \r |
156 | header[0] = INT_TO_BCDB(MSF.M);\r |
157 | header[1] = INT_TO_BCDB(MSF.S);\r |
158 | header[2] = INT_TO_BCDB(MSF.F);\r |
159 | header[3] = 0x01;\r |
160 | \r |
161 | //FILE_Read_One_LBA_CDC();\r |
162 | Pico_mcd->scd.Cur_LBA +=\r |
163 | cdc_decoder_update(header);\r |
164 | }\r |
165 | else Pico_mcd->scd.File_Add_Delay--;\r |
166 | }\r |
167 | else {\r |
168 | Pico_mcd->s68k_regs[0x36] &= ~0x01; // AUDIO\r |
169 | unsigned char header[4] = { 0, };\r |
170 | cdc_decoder_update(header);\r |
cc68a136 |
171 | }\r |
cc68a136 |
172 | }\r |
173 | \r |
1cd356a3 |
174 | // Check CDD\r |
175 | if (Pico_mcd->scd.CDD_Complete)\r |
176 | {\r |
177 | Pico_mcd->scd.CDD_Complete = 0;\r |
178 | \r |
179 | CDD_Export_Status();\r |
180 | }\r |
181 | \r |
cc68a136 |
182 | if (Pico_mcd->scd.Status_CDD == FAST_FOW)\r |
183 | {\r |
184 | Pico_mcd->scd.Cur_LBA += 10;\r |
185 | CDC_Update_Header();\r |
186 | \r |
187 | }\r |
188 | else if (Pico_mcd->scd.Status_CDD == FAST_REV)\r |
189 | {\r |
190 | Pico_mcd->scd.Cur_LBA -= 10;\r |
191 | if (Pico_mcd->scd.Cur_LBA < -150) Pico_mcd->scd.Cur_LBA = -150;\r |
192 | CDC_Update_Header();\r |
193 | }\r |
194 | }\r |
195 | \r |
196 | \r |
eff55556 |
197 | PICO_INTERNAL int Init_CD_Driver(void)\r |
cc68a136 |
198 | {\r |
cc68a136 |
199 | return 0;\r |
200 | }\r |
201 | \r |
202 | \r |
eff55556 |
203 | PICO_INTERNAL void End_CD_Driver(void)\r |
cc68a136 |
204 | {\r |
eff55556 |
205 | Unload_ISO();\r |
cc68a136 |
206 | }\r |
207 | \r |
208 | \r |
eff55556 |
209 | PICO_INTERNAL void Reset_CD(void)\r |
cc68a136 |
210 | {\r |
211 | Pico_mcd->scd.Cur_Track = 0;\r |
212 | Pico_mcd->scd.Cur_LBA = -150;\r |
5c69a605 |
213 | Pico_mcd->scd.Status_CDC &= ~1;\r |
d0132772 |
214 | if (Pico_mcd->scd.Status_CDD != TRAY_OPEN)\r |
215 | Pico_mcd->scd.Status_CDD = CD_Present ? READY : NOCD;\r |
51a902ae |
216 | Pico_mcd->scd.CDD_Complete = 0;\r |
5c69a605 |
217 | Pico_mcd->scd.File_Add_Delay = 0;\r |
cc68a136 |
218 | }\r |
219 | \r |
220 | \r |
35e3031a |
221 | int Insert_CD(const char *cdimg_name, int type)\r |
cc68a136 |
222 | {\r |
b923ecbe |
223 | int ret = 1;\r |
bf098bc5 |
224 | \r |
bf098bc5 |
225 | CD_Present = 0;\r |
226 | \r |
b923ecbe |
227 | if (cdimg_name != NULL && type != CIT_NOT_CD)\r |
cc68a136 |
228 | {\r |
b923ecbe |
229 | ret = Load_CD_Image(cdimg_name, type);\r |
721cd396 |
230 | if (ret == 0) {\r |
bf098bc5 |
231 | CD_Present = 1;\r |
d0132772 |
232 | \r |
233 | if (Pico_mcd->scd.Status_CDD == TRAY_OPEN)\r |
234 | {\r |
235 | if (Pico_mcd->bios[0x122 ^ 1] == '2')\r |
236 | Close_Tray_CDD_cC();\r |
237 | // else bios will issue it\r |
238 | }\r |
239 | else\r |
240 | {\r |
d687ef50 |
241 | Pico_mcd->scd.Status_CDD = READY;\r |
d0132772 |
242 | }\r |
721cd396 |
243 | }\r |
cc68a136 |
244 | }\r |
245 | \r |
d0132772 |
246 | if (Pico_mcd->scd.Status_CDD != TRAY_OPEN && !CD_Present)\r |
247 | Pico_mcd->scd.Status_CDD = NOCD;\r |
248 | \r |
bf098bc5 |
249 | return ret;\r |
cc68a136 |
250 | }\r |
251 | \r |
252 | \r |
d0132772 |
253 | int Stop_CD(void)\r |
cc68a136 |
254 | {\r |
d0132772 |
255 | int ret = CD_Present;\r |
256 | \r |
cc68a136 |
257 | Unload_ISO();\r |
cc68a136 |
258 | CD_Present = 0;\r |
d0132772 |
259 | \r |
260 | return ret;\r |
cc68a136 |
261 | }\r |
262 | \r |
263 | \r |
eff55556 |
264 | /*\r |
265 | PICO_INTERNAL void Change_CD(void)\r |
cc68a136 |
266 | {\r |
267 | if (Pico_mcd->scd.Status_CDD == TRAY_OPEN) Close_Tray_CDD_cC();\r |
268 | else Open_Tray_CDD_cD();\r |
269 | }\r |
eff55556 |
270 | */\r |
cc68a136 |
271 | \r |
eff55556 |
272 | PICO_INTERNAL int Get_Status_CDD_c0(void)\r |
cc68a136 |
273 | {\r |
c459aefd |
274 | cdprintf("Status command : Cur LBA = %d", Pico_mcd->scd.Cur_LBA);\r |
cc68a136 |
275 | \r |
276 | // Clear immediat status\r |
277 | if ((Pico_mcd->cdd.Status & 0x0F00) == 0x0200)\r |
278 | Pico_mcd->cdd.Status = (Pico_mcd->scd.Status_CDD & 0xFF00) | (Pico_mcd->cdd.Status & 0x00FF);\r |
279 | else if ((Pico_mcd->cdd.Status & 0x0F00) == 0x0700)\r |
280 | Pico_mcd->cdd.Status = (Pico_mcd->scd.Status_CDD & 0xFF00) | (Pico_mcd->cdd.Status & 0x00FF);\r |
281 | else if ((Pico_mcd->cdd.Status & 0x0F00) == 0x0E00)\r |
282 | Pico_mcd->cdd.Status = (Pico_mcd->scd.Status_CDD & 0xFF00) | (Pico_mcd->cdd.Status & 0x00FF);\r |
283 | \r |
51a902ae |
284 | Pico_mcd->scd.CDD_Complete = 1;\r |
cc68a136 |
285 | \r |
286 | return 0;\r |
287 | }\r |
288 | \r |
289 | \r |
eff55556 |
290 | PICO_INTERNAL int Stop_CDD_c1(void)\r |
cc68a136 |
291 | {\r |
292 | CHECK_TRAY_OPEN\r |
293 | \r |
294 | Pico_mcd->scd.Status_CDC &= ~1; // Stop CDC read\r |
295 | \r |
296 | if (CD_Present) Pico_mcd->scd.Status_CDD = STOPPED;\r |
297 | else Pico_mcd->scd.Status_CDD = NOCD;\r |
298 | Pico_mcd->cdd.Status = 0x0000;\r |
299 | \r |
300 | Pico_mcd->s68k_regs[0x36] |= 0x01; // Data bit set because stopped\r |
301 | \r |
302 | Pico_mcd->cdd.Minute = 0;\r |
303 | Pico_mcd->cdd.Seconde = 0;\r |
304 | Pico_mcd->cdd.Frame = 0;\r |
305 | Pico_mcd->cdd.Ext = 0;\r |
306 | \r |
51a902ae |
307 | Pico_mcd->scd.CDD_Complete = 1;\r |
cc68a136 |
308 | \r |
309 | return 0;\r |
310 | }\r |
311 | \r |
312 | \r |
eff55556 |
313 | PICO_INTERNAL int Get_Pos_CDD_c20(void)\r |
cc68a136 |
314 | {\r |
315 | _msf MSF;\r |
316 | \r |
c459aefd |
317 | cdprintf("command 200 : Cur LBA = %d", Pico_mcd->scd.Cur_LBA);\r |
cc68a136 |
318 | \r |
319 | CHECK_TRAY_OPEN\r |
320 | \r |
321 | Pico_mcd->cdd.Status &= 0xFF;\r |
322 | if (!CD_Present)\r |
323 | {\r |
324 | Pico_mcd->scd.Status_CDD = NOCD;\r |
325 | Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r |
326 | }\r |
327 | // else if (!(CDC.CTRL.B.B0 & 0x80)) Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r |
328 | Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r |
329 | \r |
c459aefd |
330 | cdprintf("Status CDD = %.4X Status = %.4X", Pico_mcd->scd.Status_CDD, Pico_mcd->cdd.Status);\r |
cc68a136 |
331 | \r |
332 | LBA_to_MSF(Pico_mcd->scd.Cur_LBA, &MSF);\r |
333 | \r |
334 | Pico_mcd->cdd.Minute = INT_TO_BCDW(MSF.M);\r |
335 | Pico_mcd->cdd.Seconde = INT_TO_BCDW(MSF.S);\r |
336 | Pico_mcd->cdd.Frame = INT_TO_BCDW(MSF.F);\r |
337 | Pico_mcd->cdd.Ext = 0;\r |
338 | \r |
51a902ae |
339 | Pico_mcd->scd.CDD_Complete = 1;\r |
cc68a136 |
340 | \r |
341 | return 0;\r |
342 | }\r |
343 | \r |
344 | \r |
eff55556 |
345 | PICO_INTERNAL int Get_Track_Pos_CDD_c21(void)\r |
cc68a136 |
346 | {\r |
347 | int elapsed_time;\r |
348 | _msf MSF;\r |
349 | \r |
350 | cdprintf("command 201 : Cur LBA = %d", Pico_mcd->scd.Cur_LBA);\r |
351 | \r |
352 | CHECK_TRAY_OPEN\r |
353 | \r |
354 | Pico_mcd->cdd.Status &= 0xFF;\r |
355 | if (!CD_Present)\r |
356 | {\r |
357 | Pico_mcd->scd.Status_CDD = NOCD;\r |
358 | Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r |
359 | }\r |
360 | // else if (!(CDC.CTRL.B.B0 & 0x80)) Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r |
361 | Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r |
362 | \r |
363 | elapsed_time = Pico_mcd->scd.Cur_LBA - Track_to_LBA(LBA_to_Track(Pico_mcd->scd.Cur_LBA));\r |
364 | LBA_to_MSF(elapsed_time - 150, &MSF);\r |
365 | \r |
c459aefd |
366 | cdprintf(" elapsed = %d", elapsed_time);\r |
cc68a136 |
367 | \r |
368 | Pico_mcd->cdd.Minute = INT_TO_BCDW(MSF.M);\r |
369 | Pico_mcd->cdd.Seconde = INT_TO_BCDW(MSF.S);\r |
370 | Pico_mcd->cdd.Frame = INT_TO_BCDW(MSF.F);\r |
371 | Pico_mcd->cdd.Ext = 0;\r |
372 | \r |
51a902ae |
373 | Pico_mcd->scd.CDD_Complete = 1;\r |
cc68a136 |
374 | \r |
375 | return 0;\r |
376 | }\r |
377 | \r |
378 | \r |
eff55556 |
379 | PICO_INTERNAL int Get_Current_Track_CDD_c22(void)\r |
cc68a136 |
380 | {\r |
c459aefd |
381 | cdprintf("Status CDD = %.4X Status = %.4X", Pico_mcd->scd.Status_CDD, Pico_mcd->cdd.Status);\r |
cc68a136 |
382 | \r |
383 | CHECK_TRAY_OPEN\r |
384 | \r |
385 | Pico_mcd->cdd.Status &= 0xFF;\r |
386 | if (!CD_Present)\r |
387 | {\r |
388 | Pico_mcd->scd.Status_CDD = NOCD;\r |
389 | Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r |
390 | }\r |
391 | // else if (!(CDC.CTRL.B.B0 & 0x80)) Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r |
392 | Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r |
393 | \r |
394 | Pico_mcd->scd.Cur_Track = LBA_to_Track(Pico_mcd->scd.Cur_LBA);\r |
395 | \r |
396 | if (Pico_mcd->scd.Cur_Track == 100) Pico_mcd->cdd.Minute = 0x0A02;\r |
397 | else Pico_mcd->cdd.Minute = INT_TO_BCDW(Pico_mcd->scd.Cur_Track);\r |
398 | Pico_mcd->cdd.Seconde = 0;\r |
399 | Pico_mcd->cdd.Frame = 0;\r |
400 | Pico_mcd->cdd.Ext = 0;\r |
401 | \r |
51a902ae |
402 | Pico_mcd->scd.CDD_Complete = 1;\r |
cc68a136 |
403 | \r |
404 | return 0;\r |
405 | }\r |
406 | \r |
407 | \r |
eff55556 |
408 | PICO_INTERNAL int Get_Total_Lenght_CDD_c23(void)\r |
cc68a136 |
409 | {\r |
410 | CHECK_TRAY_OPEN\r |
411 | \r |
412 | Pico_mcd->cdd.Status &= 0xFF;\r |
413 | if (!CD_Present)\r |
414 | {\r |
415 | Pico_mcd->scd.Status_CDD = NOCD;\r |
416 | Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r |
417 | }\r |
418 | // else if (!(CDC.CTRL.B.B0 & 0x80)) Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r |
419 | Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r |
420 | \r |
75736070 |
421 | Pico_mcd->cdd.Minute = INT_TO_BCDW(Pico_mcd->TOC.Tracks[Pico_mcd->TOC.Last_Track].MSF.M);\r |
422 | Pico_mcd->cdd.Seconde = INT_TO_BCDW(Pico_mcd->TOC.Tracks[Pico_mcd->TOC.Last_Track].MSF.S);\r |
423 | Pico_mcd->cdd.Frame = INT_TO_BCDW(Pico_mcd->TOC.Tracks[Pico_mcd->TOC.Last_Track].MSF.F);\r |
cc68a136 |
424 | Pico_mcd->cdd.Ext = 0;\r |
425 | \r |
51a902ae |
426 | Pico_mcd->scd.CDD_Complete = 1;\r |
cc68a136 |
427 | \r |
428 | return 0;\r |
429 | }\r |
430 | \r |
431 | \r |
eff55556 |
432 | PICO_INTERNAL int Get_First_Last_Track_CDD_c24(void)\r |
cc68a136 |
433 | {\r |
434 | CHECK_TRAY_OPEN\r |
435 | \r |
436 | Pico_mcd->cdd.Status &= 0xFF;\r |
437 | if (!CD_Present)\r |
438 | {\r |
439 | Pico_mcd->scd.Status_CDD = NOCD;\r |
440 | }\r |
441 | // else if (!(CDC.CTRL.B.B0 & 0x80)) Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r |
442 | Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r |
443 | \r |
75736070 |
444 | Pico_mcd->cdd.Minute = INT_TO_BCDW(1);\r |
445 | Pico_mcd->cdd.Seconde = INT_TO_BCDW(Pico_mcd->TOC.Last_Track);\r |
cc68a136 |
446 | Pico_mcd->cdd.Frame = 0;\r |
447 | Pico_mcd->cdd.Ext = 0;\r |
448 | \r |
51a902ae |
449 | Pico_mcd->scd.CDD_Complete = 1;\r |
cc68a136 |
450 | \r |
451 | return 0;\r |
452 | }\r |
453 | \r |
454 | \r |
eff55556 |
455 | PICO_INTERNAL int Get_Track_Adr_CDD_c25(void)\r |
cc68a136 |
456 | {\r |
457 | int track_number;\r |
458 | \r |
459 | CHECK_TRAY_OPEN\r |
460 | \r |
461 | // track number in TC4 & TC5\r |
462 | \r |
463 | track_number = (Pico_mcd->s68k_regs[0x38+10+4] & 0xF) * 10 + (Pico_mcd->s68k_regs[0x38+10+5] & 0xF);\r |
464 | \r |
465 | Pico_mcd->cdd.Status &= 0xFF;\r |
466 | if (!CD_Present)\r |
467 | {\r |
468 | Pico_mcd->scd.Status_CDD = NOCD;\r |
469 | Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r |
470 | }\r |
471 | // else if (!(CDC.CTRL.B.B0 & 0x80)) Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r |
472 | Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;\r |
473 | \r |
75736070 |
474 | if (track_number > Pico_mcd->TOC.Last_Track) track_number = Pico_mcd->TOC.Last_Track;\r |
475 | else if (track_number < 1) track_number = 1;\r |
cc68a136 |
476 | \r |
75736070 |
477 | Pico_mcd->cdd.Minute = INT_TO_BCDW(Pico_mcd->TOC.Tracks[track_number - 1].MSF.M);\r |
478 | Pico_mcd->cdd.Seconde = INT_TO_BCDW(Pico_mcd->TOC.Tracks[track_number - 1].MSF.S);\r |
479 | Pico_mcd->cdd.Frame = INT_TO_BCDW(Pico_mcd->TOC.Tracks[track_number - 1].MSF.F);\r |
cc68a136 |
480 | Pico_mcd->cdd.Ext = track_number % 10;\r |
481 | \r |
75736070 |
482 | if (track_number == 1) Pico_mcd->cdd.Frame |= 0x0800; // data track\r |
cc68a136 |
483 | \r |
51a902ae |
484 | Pico_mcd->scd.CDD_Complete = 1;\r |
cc68a136 |
485 | return 0;\r |
486 | }\r |
487 | \r |
488 | \r |
eff55556 |
489 | PICO_INTERNAL int Play_CDD_c3(void)\r |
cc68a136 |
490 | {\r |
491 | _msf MSF;\r |
492 | int delay, new_lba;\r |
493 | \r |
494 | CHECK_TRAY_OPEN\r |
495 | CHECK_CD_PRESENT\r |
496 | \r |
497 | // MSF of the track to play in TC buffer\r |
498 | \r |
499 | MSF.M = (Pico_mcd->s68k_regs[0x38+10+2] & 0xF) * 10 + (Pico_mcd->s68k_regs[0x38+10+3] & 0xF);\r |
500 | MSF.S = (Pico_mcd->s68k_regs[0x38+10+4] & 0xF) * 10 + (Pico_mcd->s68k_regs[0x38+10+5] & 0xF);\r |
501 | MSF.F = (Pico_mcd->s68k_regs[0x38+10+6] & 0xF) * 10 + (Pico_mcd->s68k_regs[0x38+10+7] & 0xF);\r |
502 | \r |
503 | Pico_mcd->scd.Cur_Track = MSF_to_Track(&MSF);\r |
504 | \r |
505 | new_lba = MSF_to_LBA(&MSF);\r |
506 | delay = new_lba - Pico_mcd->scd.Cur_LBA;\r |
507 | if (delay < 0) delay = -delay;\r |
508 | delay >>= 12;\r |
509 | \r |
d0132772 |
510 | if (Pico_mcd->scd.Cur_LBA > 0 && delay < 13)\r |
511 | // based on genplus GX\r |
59991f11 |
512 | delay = 13;\r |
513 | \r |
cc68a136 |
514 | Pico_mcd->scd.Cur_LBA = new_lba;\r |
515 | CDC_Update_Header();\r |
516 | \r |
c459aefd |
517 | cdprintf("Read : Cur LBA = %d, M=%d, S=%d, F=%d", Pico_mcd->scd.Cur_LBA, MSF.M, MSF.S, MSF.F);\r |
cc68a136 |
518 | \r |
519 | if (Pico_mcd->scd.Status_CDD != PLAYING) delay += 20;\r |
520 | \r |
521 | Pico_mcd->scd.Status_CDD = PLAYING;\r |
522 | Pico_mcd->cdd.Status = 0x0102;\r |
523 | // Pico_mcd->cdd.Status = COMM_OK;\r |
524 | \r |
51a902ae |
525 | if (Pico_mcd->scd.File_Add_Delay == 0) Pico_mcd->scd.File_Add_Delay = delay;\r |
cc68a136 |
526 | \r |
75736070 |
527 | if (Pico_mcd->scd.Cur_Track == 1)\r |
cc68a136 |
528 | {\r |
529 | Pico_mcd->s68k_regs[0x36] |= 0x01; // DATA\r |
530 | }\r |
531 | else\r |
532 | {\r |
533 | Pico_mcd->s68k_regs[0x36] &= ~0x01; // AUDIO\r |
c9e1affc |
534 | cdda_start_play();\r |
cc68a136 |
535 | }\r |
536 | \r |
537 | if (Pico_mcd->scd.Cur_Track == 100) Pico_mcd->cdd.Minute = 0x0A02;\r |
538 | else Pico_mcd->cdd.Minute = INT_TO_BCDW(Pico_mcd->scd.Cur_Track);\r |
539 | Pico_mcd->cdd.Seconde = 0;\r |
540 | Pico_mcd->cdd.Frame = 0;\r |
541 | Pico_mcd->cdd.Ext = 0;\r |
542 | \r |
543 | Pico_mcd->scd.Status_CDC |= 1; // Read data with CDC\r |
544 | \r |
51a902ae |
545 | Pico_mcd->scd.CDD_Complete = 1;\r |
cc68a136 |
546 | return 0;\r |
547 | }\r |
548 | \r |
549 | \r |
eff55556 |
550 | PICO_INTERNAL int Seek_CDD_c4(void)\r |
cc68a136 |
551 | {\r |
552 | _msf MSF;\r |
553 | \r |
554 | CHECK_TRAY_OPEN\r |
555 | CHECK_CD_PRESENT\r |
556 | \r |
557 | // MSF to seek in TC buffer\r |
558 | \r |
559 | MSF.M = (Pico_mcd->s68k_regs[0x38+10+2] & 0xF) * 10 + (Pico_mcd->s68k_regs[0x38+10+3] & 0xF);\r |
560 | MSF.S = (Pico_mcd->s68k_regs[0x38+10+4] & 0xF) * 10 + (Pico_mcd->s68k_regs[0x38+10+5] & 0xF);\r |
561 | MSF.F = (Pico_mcd->s68k_regs[0x38+10+6] & 0xF) * 10 + (Pico_mcd->s68k_regs[0x38+10+7] & 0xF);\r |
562 | \r |
563 | Pico_mcd->scd.Cur_Track = MSF_to_Track(&MSF);\r |
564 | Pico_mcd->scd.Cur_LBA = MSF_to_LBA(&MSF);\r |
565 | CDC_Update_Header();\r |
566 | \r |
567 | Pico_mcd->scd.Status_CDC &= ~1; // Stop CDC read\r |
568 | \r |
569 | Pico_mcd->scd.Status_CDD = READY;\r |
570 | Pico_mcd->cdd.Status = 0x0200;\r |
571 | \r |
572 | // DATA ?\r |
75736070 |
573 | if (Pico_mcd->scd.Cur_Track == 1)\r |
cc68a136 |
574 | Pico_mcd->s68k_regs[0x36] |= 0x01;\r |
575 | else Pico_mcd->s68k_regs[0x36] &= ~0x01; // AUDIO\r |
576 | \r |
577 | Pico_mcd->cdd.Minute = 0;\r |
578 | Pico_mcd->cdd.Seconde = 0;\r |
579 | Pico_mcd->cdd.Frame = 0;\r |
580 | Pico_mcd->cdd.Ext = 0;\r |
581 | \r |
51a902ae |
582 | Pico_mcd->scd.CDD_Complete = 1;\r |
cc68a136 |
583 | \r |
584 | return 0;\r |
585 | }\r |
586 | \r |
587 | \r |
eff55556 |
588 | PICO_INTERNAL int Pause_CDD_c6(void)\r |
cc68a136 |
589 | {\r |
590 | CHECK_TRAY_OPEN\r |
591 | CHECK_CD_PRESENT\r |
592 | \r |
593 | Pico_mcd->scd.Status_CDC &= ~1; // Stop CDC read to start a new one if raw data\r |
594 | \r |
595 | Pico_mcd->scd.Status_CDD = READY;\r |
596 | Pico_mcd->cdd.Status = Pico_mcd->scd.Status_CDD;\r |
597 | \r |
598 | Pico_mcd->s68k_regs[0x36] |= 0x01; // Data bit set because stopped\r |
599 | \r |
600 | Pico_mcd->cdd.Minute = 0;\r |
601 | Pico_mcd->cdd.Seconde = 0;\r |
602 | Pico_mcd->cdd.Frame = 0;\r |
603 | Pico_mcd->cdd.Ext = 0;\r |
604 | \r |
51a902ae |
605 | Pico_mcd->scd.CDD_Complete = 1;\r |
cc68a136 |
606 | \r |
607 | return 0;\r |
608 | }\r |
609 | \r |
610 | \r |
eff55556 |
611 | PICO_INTERNAL int Resume_CDD_c7(void)\r |
cc68a136 |
612 | {\r |
613 | CHECK_TRAY_OPEN\r |
614 | CHECK_CD_PRESENT\r |
615 | \r |
616 | Pico_mcd->scd.Cur_Track = LBA_to_Track(Pico_mcd->scd.Cur_LBA);\r |
617 | \r |
618 | #ifdef DEBUG_CD\r |
619 | {\r |
620 | _msf MSF;\r |
621 | LBA_to_MSF(Pico_mcd->scd.Cur_LBA, &MSF);\r |
c459aefd |
622 | 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 |
623 | }\r |
624 | #endif\r |
625 | \r |
626 | Pico_mcd->scd.Status_CDD = PLAYING;\r |
627 | Pico_mcd->cdd.Status = 0x0102;\r |
628 | \r |
75736070 |
629 | if (Pico_mcd->scd.Cur_Track == 1)\r |
cc68a136 |
630 | {\r |
631 | Pico_mcd->s68k_regs[0x36] |= 0x01; // DATA\r |
632 | }\r |
633 | else\r |
634 | {\r |
635 | Pico_mcd->s68k_regs[0x36] &= ~0x01; // AUDIO\r |
c9e1affc |
636 | cdda_start_play();\r |
cc68a136 |
637 | }\r |
638 | \r |
639 | if (Pico_mcd->scd.Cur_Track == 100) Pico_mcd->cdd.Minute = 0x0A02;\r |
640 | else Pico_mcd->cdd.Minute = INT_TO_BCDW(Pico_mcd->scd.Cur_Track);\r |
641 | Pico_mcd->cdd.Seconde = 0;\r |
642 | Pico_mcd->cdd.Frame = 0;\r |
643 | Pico_mcd->cdd.Ext = 0;\r |
644 | \r |
645 | Pico_mcd->scd.Status_CDC |= 1; // Read data with CDC\r |
646 | \r |
51a902ae |
647 | Pico_mcd->scd.CDD_Complete = 1;\r |
cc68a136 |
648 | return 0;\r |
649 | }\r |
650 | \r |
651 | \r |
eff55556 |
652 | PICO_INTERNAL int Fast_Foward_CDD_c8(void)\r |
cc68a136 |
653 | {\r |
654 | CHECK_TRAY_OPEN\r |
655 | CHECK_CD_PRESENT\r |
656 | \r |
657 | Pico_mcd->scd.Status_CDC &= ~1; // Stop CDC read\r |
658 | \r |
659 | Pico_mcd->scd.Status_CDD = FAST_FOW;\r |
660 | Pico_mcd->cdd.Status = Pico_mcd->scd.Status_CDD | 2;\r |
661 | \r |
662 | Pico_mcd->cdd.Minute = INT_TO_BCDW(Pico_mcd->scd.Cur_Track);\r |
663 | Pico_mcd->cdd.Seconde = 0;\r |
664 | Pico_mcd->cdd.Frame = 0;\r |
665 | Pico_mcd->cdd.Ext = 0;\r |
666 | \r |
51a902ae |
667 | Pico_mcd->scd.CDD_Complete = 1;\r |
cc68a136 |
668 | \r |
669 | return 0;\r |
670 | }\r |
671 | \r |
672 | \r |
eff55556 |
673 | PICO_INTERNAL int Fast_Rewind_CDD_c9(void)\r |
cc68a136 |
674 | {\r |
675 | CHECK_TRAY_OPEN\r |
676 | CHECK_CD_PRESENT\r |
677 | \r |
678 | Pico_mcd->scd.Status_CDC &= ~1; // Stop CDC read\r |
679 | \r |
680 | Pico_mcd->scd.Status_CDD = FAST_REV;\r |
681 | Pico_mcd->cdd.Status = Pico_mcd->scd.Status_CDD | 2;\r |
682 | \r |
683 | Pico_mcd->cdd.Minute = INT_TO_BCDW(Pico_mcd->scd.Cur_Track);\r |
684 | Pico_mcd->cdd.Seconde = 0;\r |
685 | Pico_mcd->cdd.Frame = 0;\r |
686 | Pico_mcd->cdd.Ext = 0;\r |
687 | \r |
51a902ae |
688 | Pico_mcd->scd.CDD_Complete = 1;\r |
cc68a136 |
689 | \r |
690 | return 0;\r |
691 | }\r |
692 | \r |
693 | \r |
eff55556 |
694 | PICO_INTERNAL int Close_Tray_CDD_cC(void)\r |
cc68a136 |
695 | {\r |
cc68a136 |
696 | Pico_mcd->scd.Status_CDC &= ~1; // Stop CDC read\r |
697 | \r |
c6196c0f |
698 | elprintf(EL_STATUS, "tray close\n");\r |
cc68a136 |
699 | \r |
721cd396 |
700 | if (PicoMCDcloseTray != NULL)\r |
d687ef50 |
701 | PicoMCDcloseTray();\r |
cc68a136 |
702 | \r |
721cd396 |
703 | Pico_mcd->scd.Status_CDD = CD_Present ? STOPPED : NOCD;\r |
704 | Pico_mcd->cdd.Status = 0x0000;\r |
cc68a136 |
705 | \r |
721cd396 |
706 | Pico_mcd->cdd.Minute = 0;\r |
707 | Pico_mcd->cdd.Seconde = 0;\r |
708 | Pico_mcd->cdd.Frame = 0;\r |
709 | Pico_mcd->cdd.Ext = 0;\r |
cc68a136 |
710 | \r |
51a902ae |
711 | Pico_mcd->scd.CDD_Complete = 1;\r |
cc68a136 |
712 | \r |
713 | return 0;\r |
714 | }\r |
715 | \r |
716 | \r |
eff55556 |
717 | PICO_INTERNAL int Open_Tray_CDD_cD(void)\r |
cc68a136 |
718 | {\r |
719 | CHECK_TRAY_OPEN\r |
720 | \r |
721 | Pico_mcd->scd.Status_CDC &= ~1; // Stop CDC read\r |
722 | \r |
c6196c0f |
723 | elprintf(EL_STATUS, "tray open\n");\r |
721cd396 |
724 | \r |
cc68a136 |
725 | Unload_ISO();\r |
cc68a136 |
726 | CD_Present = 0;\r |
727 | \r |
721cd396 |
728 | if (PicoMCDopenTray != NULL)\r |
729 | PicoMCDopenTray();\r |
730 | \r |
cc68a136 |
731 | Pico_mcd->scd.Status_CDD = TRAY_OPEN;\r |
732 | Pico_mcd->cdd.Status = 0x0E00;\r |
733 | \r |
734 | Pico_mcd->cdd.Minute = 0;\r |
735 | Pico_mcd->cdd.Seconde = 0;\r |
736 | Pico_mcd->cdd.Frame = 0;\r |
737 | Pico_mcd->cdd.Ext = 0;\r |
738 | \r |
51a902ae |
739 | Pico_mcd->scd.CDD_Complete = 1;\r |
cc68a136 |
740 | \r |
741 | return 0;\r |
742 | }\r |
743 | \r |
744 | \r |
eff55556 |
745 | PICO_INTERNAL int CDD_cA(void)\r |
cc68a136 |
746 | {\r |
747 | CHECK_TRAY_OPEN\r |
748 | CHECK_CD_PRESENT\r |
749 | \r |
750 | Pico_mcd->scd.Status_CDC &= ~1;\r |
751 | \r |
752 | Pico_mcd->scd.Status_CDD = READY;\r |
753 | Pico_mcd->cdd.Status = Pico_mcd->scd.Status_CDD;\r |
754 | \r |
755 | Pico_mcd->cdd.Minute = 0;\r |
756 | Pico_mcd->cdd.Seconde = INT_TO_BCDW(1);\r |
757 | Pico_mcd->cdd.Frame = INT_TO_BCDW(1);\r |
758 | Pico_mcd->cdd.Ext = 0;\r |
759 | \r |
51a902ae |
760 | Pico_mcd->scd.CDD_Complete = 1;\r |
cc68a136 |
761 | \r |
762 | return 0;\r |
763 | }\r |
764 | \r |
765 | \r |
eff55556 |
766 | PICO_INTERNAL int CDD_Def(void)\r |
cc68a136 |
767 | {\r |
768 | Pico_mcd->cdd.Status = Pico_mcd->scd.Status_CDD;\r |
769 | \r |
770 | Pico_mcd->cdd.Minute = 0;\r |
771 | Pico_mcd->cdd.Seconde = 0;\r |
772 | Pico_mcd->cdd.Frame = 0;\r |
773 | Pico_mcd->cdd.Ext = 0;\r |
774 | \r |
775 | return 0;\r |
776 | }\r |
777 | \r |
778 | \r |
3f23709e |
779 | static int bswapwrite(int a, unsigned short d)\r |
780 | {\r |
781 | *(unsigned short *)(Pico_mcd->s68k_regs + a) = (d>>8)|(d<<8);\r |
782 | return d + (d >> 8);\r |
783 | }\r |
784 | \r |
785 | PICO_INTERNAL void CDD_Export_Status(void)\r |
786 | {\r |
787 | unsigned int csum;\r |
788 | \r |
789 | csum = bswapwrite( 0x38+0, Pico_mcd->cdd.Status);\r |
790 | csum += bswapwrite( 0x38+2, Pico_mcd->cdd.Minute);\r |
791 | csum += bswapwrite( 0x38+4, Pico_mcd->cdd.Seconde);\r |
792 | csum += bswapwrite( 0x38+6, Pico_mcd->cdd.Frame);\r |
793 | Pico_mcd->s68k_regs[0x38+8] = Pico_mcd->cdd.Ext;\r |
794 | csum += Pico_mcd->cdd.Ext;\r |
795 | Pico_mcd->s68k_regs[0x38+9] = ~csum & 0xf;\r |
796 | \r |
797 | Pico_mcd->s68k_regs[0x37] &= 3; // CDD.Control\r |
798 | \r |
799 | if (Pico_mcd->s68k_regs[0x33] & PCDS_IEN4)\r |
800 | {\r |
801 | elprintf(EL_INTS, "cdd export irq 4");\r |
802 | SekInterruptS68k(4);\r |
803 | }\r |
804 | \r |
805 | // cdprintf("CDD exported status\n");\r |
806 | cdprintf("out: Status=%.4X, Minute=%.4X, Second=%.4X, Frame=%.4X Checksum=%.4X",\r |
807 | (Pico_mcd->s68k_regs[0x38+0] << 8) | Pico_mcd->s68k_regs[0x38+1],\r |
808 | (Pico_mcd->s68k_regs[0x38+2] << 8) | Pico_mcd->s68k_regs[0x38+3],\r |
809 | (Pico_mcd->s68k_regs[0x38+4] << 8) | Pico_mcd->s68k_regs[0x38+5],\r |
810 | (Pico_mcd->s68k_regs[0x38+6] << 8) | Pico_mcd->s68k_regs[0x38+7],\r |
811 | (Pico_mcd->s68k_regs[0x38+8] << 8) | Pico_mcd->s68k_regs[0x38+9]);\r |
812 | }\r |
813 | \r |
814 | \r |
815 | PICO_INTERNAL void CDD_Import_Command(void)\r |
816 | {\r |
817 | // cdprintf("CDD importing command\n");\r |
818 | cdprintf("in: Command=%.4X, Minute=%.4X, Second=%.4X, Frame=%.4X Checksum=%.4X",\r |
819 | (Pico_mcd->s68k_regs[0x38+10+0] << 8) | Pico_mcd->s68k_regs[0x38+10+1],\r |
820 | (Pico_mcd->s68k_regs[0x38+10+2] << 8) | Pico_mcd->s68k_regs[0x38+10+3],\r |
821 | (Pico_mcd->s68k_regs[0x38+10+4] << 8) | Pico_mcd->s68k_regs[0x38+10+5],\r |
822 | (Pico_mcd->s68k_regs[0x38+10+6] << 8) | Pico_mcd->s68k_regs[0x38+10+7],\r |
823 | (Pico_mcd->s68k_regs[0x38+10+8] << 8) | Pico_mcd->s68k_regs[0x38+10+9]);\r |
824 | \r |
825 | switch (Pico_mcd->s68k_regs[0x38+10+0])\r |
826 | {\r |
827 | case 0x0: // STATUS (?)\r |
828 | Get_Status_CDD_c0();\r |
829 | break;\r |
830 | \r |
831 | case 0x1: // STOP ALL (?)\r |
832 | Stop_CDD_c1();\r |
833 | break;\r |
834 | \r |
835 | case 0x2: // GET TOC INFORMATIONS\r |
836 | switch(Pico_mcd->s68k_regs[0x38+10+3])\r |
837 | {\r |
838 | case 0x0: // get current position (MSF format)\r |
839 | Pico_mcd->cdd.Status = (Pico_mcd->cdd.Status & 0xFF00);\r |
840 | Get_Pos_CDD_c20();\r |
841 | break;\r |
842 | \r |
843 | case 0x1: // get elapsed time of current track played/scanned (relative MSF format)\r |
844 | Pico_mcd->cdd.Status = (Pico_mcd->cdd.Status & 0xFF00) | 1;\r |
845 | Get_Track_Pos_CDD_c21();\r |
846 | break;\r |
847 | \r |
848 | case 0x2: // get current track in RS2-RS3\r |
849 | Pico_mcd->cdd.Status = (Pico_mcd->cdd.Status & 0xFF00) | 2;\r |
850 | Get_Current_Track_CDD_c22();\r |
851 | break;\r |
852 | \r |
853 | case 0x3: // get total length (MSF format)\r |
854 | Pico_mcd->cdd.Status = (Pico_mcd->cdd.Status & 0xFF00) | 3;\r |
855 | Get_Total_Lenght_CDD_c23();\r |
856 | break;\r |
857 | \r |
858 | case 0x4: // first & last track number\r |
859 | Pico_mcd->cdd.Status = (Pico_mcd->cdd.Status & 0xFF00) | 4;\r |
860 | Get_First_Last_Track_CDD_c24();\r |
861 | break;\r |
862 | \r |
863 | case 0x5: // get track addresse (MSF format)\r |
864 | Pico_mcd->cdd.Status = (Pico_mcd->cdd.Status & 0xFF00) | 5;\r |
865 | Get_Track_Adr_CDD_c25();\r |
866 | break;\r |
867 | \r |
868 | default : // invalid, then we return status\r |
869 | Pico_mcd->cdd.Status = (Pico_mcd->cdd.Status & 0xFF00) | 0xF;\r |
870 | Get_Status_CDD_c0();\r |
871 | break;\r |
872 | }\r |
873 | break;\r |
874 | \r |
875 | case 0x3: // READ\r |
876 | Play_CDD_c3();\r |
877 | break;\r |
878 | \r |
879 | case 0x4: // SEEK\r |
880 | Seek_CDD_c4();\r |
881 | break;\r |
882 | \r |
883 | case 0x6: // PAUSE/STOP\r |
884 | Pause_CDD_c6();\r |
885 | break;\r |
886 | \r |
887 | case 0x7: // RESUME\r |
888 | Resume_CDD_c7();\r |
889 | break;\r |
890 | \r |
891 | case 0x8: // FAST FOWARD\r |
892 | Fast_Foward_CDD_c8();\r |
893 | break;\r |
894 | \r |
895 | case 0x9: // FAST REWIND\r |
896 | Fast_Rewind_CDD_c9();\r |
897 | break;\r |
898 | \r |
899 | case 0xA: // RECOVER INITIAL STATE (?)\r |
900 | CDD_cA();\r |
901 | break;\r |
902 | \r |
903 | case 0xC: // CLOSE TRAY\r |
904 | Close_Tray_CDD_cC();\r |
905 | break;\r |
906 | \r |
907 | case 0xD: // OPEN TRAY\r |
908 | Open_Tray_CDD_cD();\r |
909 | break;\r |
910 | \r |
911 | default: // UNKNOWN\r |
912 | CDD_Def();\r |
913 | break;\r |
914 | }\r |
915 | }\r |
916 | \r |
917 | void CDD_Reset(void)\r |
918 | {\r |
919 | // Reseting CDD\r |
920 | \r |
921 | memset(Pico_mcd->s68k_regs+0x34, 0, 2*2); // CDD.Fader, CDD.Control\r |
922 | Pico_mcd->cdd.Status = 0;\r |
923 | Pico_mcd->cdd.Minute = 0;\r |
924 | Pico_mcd->cdd.Seconde = 0;\r |
925 | Pico_mcd->cdd.Frame = 0;\r |
926 | Pico_mcd->cdd.Ext = 0;\r |
927 | \r |
928 | // clear receive status and transfer command\r |
929 | memset(Pico_mcd->s68k_regs+0x38, 0, 20);\r |
930 | Pico_mcd->s68k_regs[0x38+9] = 0xF; // Default checksum\r |
931 | }\r |
932 | \r |
933 | \r |