cd_sys.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743
  1. /***********************************************************
  2. * *
  3. * This source was taken from the Gens project *
  4. * Written by Stéphane Dallongeville *
  5. * Copyright (c) 2002 by Stéphane Dallongeville *
  6. * Modified/adapted for PicoDrive by notaz, 2007 *
  7. * *
  8. ***********************************************************/
  9. #include <stdio.h>
  10. #include "../PicoInt.h"
  11. #include "cd_sys.h"
  12. #include "cd_file.h"
  13. #define cdprintf dprintf
  14. //#define cdprintf(x...)
  15. #define DEBUG_CD
  16. #define TRAY_OPEN 0x0500 // TRAY OPEN CDD status
  17. #define NOCD 0x0000 // CD removed CDD status
  18. #define STOPPED 0x0900 // STOPPED CDD status (happen after stop or close tray command)
  19. #define READY 0x0400 // READY CDD status (also used for seeking)
  20. #define FAST_FOW 0x0300 // FAST FORWARD track CDD status
  21. #define FAST_REV 0x10300 // FAST REVERSE track CDD status
  22. #define PLAYING 0x0100 // PLAYING audio track CDD status
  23. static int CD_Present = 0;
  24. #define CHECK_TRAY_OPEN \
  25. if (Pico_mcd->scd.Status_CDD == TRAY_OPEN) \
  26. { \
  27. Pico_mcd->cdd.Status = Pico_mcd->scd.Status_CDD; \
  28. \
  29. Pico_mcd->cdd.Minute = 0; \
  30. Pico_mcd->cdd.Seconde = 0; \
  31. Pico_mcd->cdd.Frame = 0; \
  32. Pico_mcd->cdd.Ext = 0; \
  33. \
  34. Pico_mcd->scd.CDD_Complete = 1; \
  35. \
  36. return 2; \
  37. }
  38. #define CHECK_CD_PRESENT \
  39. if (!CD_Present) \
  40. { \
  41. Pico_mcd->scd.Status_CDD = NOCD; \
  42. Pico_mcd->cdd.Status = Pico_mcd->scd.Status_CDD; \
  43. \
  44. Pico_mcd->cdd.Minute = 0; \
  45. Pico_mcd->cdd.Seconde = 0; \
  46. Pico_mcd->cdd.Frame = 0; \
  47. Pico_mcd->cdd.Ext = 0; \
  48. \
  49. Pico_mcd->scd.CDD_Complete = 1; \
  50. \
  51. return 3; \
  52. }
  53. static int MSF_to_LBA(_msf *MSF)
  54. {
  55. return (MSF->M * 60 * 75) + (MSF->S * 75) + MSF->F - 150;
  56. }
  57. PICO_INTERNAL void LBA_to_MSF(int lba, _msf *MSF)
  58. {
  59. if (lba < -150) lba = 0;
  60. else lba += 150;
  61. MSF->M = lba / (60 * 75);
  62. MSF->S = (lba / 75) % 60;
  63. MSF->F = lba % 75;
  64. }
  65. static unsigned int MSF_to_Track(_msf *MSF)
  66. {
  67. int i, Start, Cur;
  68. Start = (MSF->M << 16) + (MSF->S << 8) + MSF->F;
  69. for(i = 1; i <= (Pico_mcd->TOC.Last_Track + 1); i++)
  70. {
  71. Cur = Pico_mcd->TOC.Tracks[i - 1].MSF.M << 16;
  72. Cur += Pico_mcd->TOC.Tracks[i - 1].MSF.S << 8;
  73. Cur += Pico_mcd->TOC.Tracks[i - 1].MSF.F;
  74. if (Cur > Start) break;
  75. }
  76. --i;
  77. if (i > Pico_mcd->TOC.Last_Track) return 100;
  78. else if (i < 1) i = 1;
  79. return (unsigned) i;
  80. }
  81. static unsigned int LBA_to_Track(int lba)
  82. {
  83. _msf MSF;
  84. LBA_to_MSF(lba, &MSF);
  85. return MSF_to_Track(&MSF);
  86. }
  87. static void Track_to_MSF(int track, _msf *MSF)
  88. {
  89. if (track < 1) track = 1;
  90. else if (track > Pico_mcd->TOC.Last_Track) track = Pico_mcd->TOC.Last_Track;
  91. MSF->M = Pico_mcd->TOC.Tracks[track - 1].MSF.M;
  92. MSF->S = Pico_mcd->TOC.Tracks[track - 1].MSF.S;
  93. MSF->F = Pico_mcd->TOC.Tracks[track - 1].MSF.F;
  94. }
  95. PICO_INTERNAL int Track_to_LBA(int track)
  96. {
  97. _msf MSF;
  98. Track_to_MSF(track, &MSF);
  99. return MSF_to_LBA(&MSF);
  100. }
  101. PICO_INTERNAL void Check_CD_Command(void)
  102. {
  103. cdprintf("CHECK CD COMMAND");
  104. // Check CDC
  105. if (Pico_mcd->scd.Status_CDC & 1) // CDC is reading data ...
  106. {
  107. cdprintf("Got a read command");
  108. // DATA ?
  109. if (Pico_mcd->scd.Cur_Track == 1)
  110. Pico_mcd->s68k_regs[0x36] |= 0x01;
  111. else Pico_mcd->s68k_regs[0x36] &= ~0x01; // AUDIO
  112. if (Pico_mcd->scd.File_Add_Delay == 0)
  113. {
  114. FILE_Read_One_LBA_CDC();
  115. }
  116. else Pico_mcd->scd.File_Add_Delay--;
  117. }
  118. // Check CDD
  119. if (Pico_mcd->scd.CDD_Complete)
  120. {
  121. Pico_mcd->scd.CDD_Complete = 0;
  122. CDD_Export_Status();
  123. }
  124. if (Pico_mcd->scd.Status_CDD == FAST_FOW)
  125. {
  126. Pico_mcd->scd.Cur_LBA += 10;
  127. CDC_Update_Header();
  128. }
  129. else if (Pico_mcd->scd.Status_CDD == FAST_REV)
  130. {
  131. Pico_mcd->scd.Cur_LBA -= 10;
  132. if (Pico_mcd->scd.Cur_LBA < -150) Pico_mcd->scd.Cur_LBA = -150;
  133. CDC_Update_Header();
  134. }
  135. }
  136. PICO_INTERNAL int Init_CD_Driver(void)
  137. {
  138. return 0;
  139. }
  140. PICO_INTERNAL void End_CD_Driver(void)
  141. {
  142. Unload_ISO();
  143. }
  144. PICO_INTERNAL void Reset_CD(void)
  145. {
  146. Pico_mcd->scd.Cur_Track = 0;
  147. Pico_mcd->scd.Cur_LBA = -150;
  148. Pico_mcd->scd.Status_CDC &= ~1;
  149. Pico_mcd->scd.Status_CDD = CD_Present ? READY : NOCD;
  150. Pico_mcd->scd.CDD_Complete = 0;
  151. Pico_mcd->scd.File_Add_Delay = 0;
  152. }
  153. int Insert_CD(char *iso_name, int is_bin)
  154. {
  155. int ret = 0;
  156. CD_Present = 0;
  157. Pico_mcd->scd.Status_CDD = NOCD;
  158. if (iso_name != NULL)
  159. {
  160. ret = Load_ISO(iso_name, is_bin);
  161. if (ret == 0) {
  162. CD_Present = 1;
  163. Pico_mcd->scd.Status_CDD = READY;
  164. }
  165. }
  166. return ret;
  167. }
  168. void Stop_CD(void)
  169. {
  170. Unload_ISO();
  171. CD_Present = 0;
  172. }
  173. /*
  174. PICO_INTERNAL void Change_CD(void)
  175. {
  176. if (Pico_mcd->scd.Status_CDD == TRAY_OPEN) Close_Tray_CDD_cC();
  177. else Open_Tray_CDD_cD();
  178. }
  179. */
  180. PICO_INTERNAL int Get_Status_CDD_c0(void)
  181. {
  182. cdprintf("Status command : Cur LBA = %d", Pico_mcd->scd.Cur_LBA);
  183. // Clear immediat status
  184. if ((Pico_mcd->cdd.Status & 0x0F00) == 0x0200)
  185. Pico_mcd->cdd.Status = (Pico_mcd->scd.Status_CDD & 0xFF00) | (Pico_mcd->cdd.Status & 0x00FF);
  186. else if ((Pico_mcd->cdd.Status & 0x0F00) == 0x0700)
  187. Pico_mcd->cdd.Status = (Pico_mcd->scd.Status_CDD & 0xFF00) | (Pico_mcd->cdd.Status & 0x00FF);
  188. else if ((Pico_mcd->cdd.Status & 0x0F00) == 0x0E00)
  189. Pico_mcd->cdd.Status = (Pico_mcd->scd.Status_CDD & 0xFF00) | (Pico_mcd->cdd.Status & 0x00FF);
  190. Pico_mcd->scd.CDD_Complete = 1;
  191. return 0;
  192. }
  193. PICO_INTERNAL int Stop_CDD_c1(void)
  194. {
  195. CHECK_TRAY_OPEN
  196. Pico_mcd->scd.Status_CDC &= ~1; // Stop CDC read
  197. if (CD_Present) Pico_mcd->scd.Status_CDD = STOPPED;
  198. else Pico_mcd->scd.Status_CDD = NOCD;
  199. Pico_mcd->cdd.Status = 0x0000;
  200. Pico_mcd->s68k_regs[0x36] |= 0x01; // Data bit set because stopped
  201. Pico_mcd->cdd.Minute = 0;
  202. Pico_mcd->cdd.Seconde = 0;
  203. Pico_mcd->cdd.Frame = 0;
  204. Pico_mcd->cdd.Ext = 0;
  205. Pico_mcd->scd.CDD_Complete = 1;
  206. return 0;
  207. }
  208. PICO_INTERNAL int Get_Pos_CDD_c20(void)
  209. {
  210. _msf MSF;
  211. cdprintf("command 200 : Cur LBA = %d", Pico_mcd->scd.Cur_LBA);
  212. CHECK_TRAY_OPEN
  213. Pico_mcd->cdd.Status &= 0xFF;
  214. if (!CD_Present)
  215. {
  216. Pico_mcd->scd.Status_CDD = NOCD;
  217. Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;
  218. }
  219. // else if (!(CDC.CTRL.B.B0 & 0x80)) Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;
  220. Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;
  221. cdprintf("Status CDD = %.4X Status = %.4X", Pico_mcd->scd.Status_CDD, Pico_mcd->cdd.Status);
  222. LBA_to_MSF(Pico_mcd->scd.Cur_LBA, &MSF);
  223. Pico_mcd->cdd.Minute = INT_TO_BCDW(MSF.M);
  224. Pico_mcd->cdd.Seconde = INT_TO_BCDW(MSF.S);
  225. Pico_mcd->cdd.Frame = INT_TO_BCDW(MSF.F);
  226. Pico_mcd->cdd.Ext = 0;
  227. Pico_mcd->scd.CDD_Complete = 1;
  228. return 0;
  229. }
  230. PICO_INTERNAL int Get_Track_Pos_CDD_c21(void)
  231. {
  232. int elapsed_time;
  233. _msf MSF;
  234. cdprintf("command 201 : Cur LBA = %d", Pico_mcd->scd.Cur_LBA);
  235. CHECK_TRAY_OPEN
  236. Pico_mcd->cdd.Status &= 0xFF;
  237. if (!CD_Present)
  238. {
  239. Pico_mcd->scd.Status_CDD = NOCD;
  240. Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;
  241. }
  242. // else if (!(CDC.CTRL.B.B0 & 0x80)) Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;
  243. Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;
  244. elapsed_time = Pico_mcd->scd.Cur_LBA - Track_to_LBA(LBA_to_Track(Pico_mcd->scd.Cur_LBA));
  245. LBA_to_MSF(elapsed_time - 150, &MSF);
  246. cdprintf(" elapsed = %d", elapsed_time);
  247. Pico_mcd->cdd.Minute = INT_TO_BCDW(MSF.M);
  248. Pico_mcd->cdd.Seconde = INT_TO_BCDW(MSF.S);
  249. Pico_mcd->cdd.Frame = INT_TO_BCDW(MSF.F);
  250. Pico_mcd->cdd.Ext = 0;
  251. Pico_mcd->scd.CDD_Complete = 1;
  252. return 0;
  253. }
  254. PICO_INTERNAL int Get_Current_Track_CDD_c22(void)
  255. {
  256. cdprintf("Status CDD = %.4X Status = %.4X", Pico_mcd->scd.Status_CDD, Pico_mcd->cdd.Status);
  257. CHECK_TRAY_OPEN
  258. Pico_mcd->cdd.Status &= 0xFF;
  259. if (!CD_Present)
  260. {
  261. Pico_mcd->scd.Status_CDD = NOCD;
  262. Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;
  263. }
  264. // else if (!(CDC.CTRL.B.B0 & 0x80)) Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;
  265. Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;
  266. Pico_mcd->scd.Cur_Track = LBA_to_Track(Pico_mcd->scd.Cur_LBA);
  267. if (Pico_mcd->scd.Cur_Track == 100) Pico_mcd->cdd.Minute = 0x0A02;
  268. else Pico_mcd->cdd.Minute = INT_TO_BCDW(Pico_mcd->scd.Cur_Track);
  269. Pico_mcd->cdd.Seconde = 0;
  270. Pico_mcd->cdd.Frame = 0;
  271. Pico_mcd->cdd.Ext = 0;
  272. Pico_mcd->scd.CDD_Complete = 1;
  273. return 0;
  274. }
  275. PICO_INTERNAL int Get_Total_Lenght_CDD_c23(void)
  276. {
  277. CHECK_TRAY_OPEN
  278. Pico_mcd->cdd.Status &= 0xFF;
  279. if (!CD_Present)
  280. {
  281. Pico_mcd->scd.Status_CDD = NOCD;
  282. Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;
  283. }
  284. // else if (!(CDC.CTRL.B.B0 & 0x80)) Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;
  285. Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;
  286. Pico_mcd->cdd.Minute = INT_TO_BCDW(Pico_mcd->TOC.Tracks[Pico_mcd->TOC.Last_Track].MSF.M);
  287. Pico_mcd->cdd.Seconde = INT_TO_BCDW(Pico_mcd->TOC.Tracks[Pico_mcd->TOC.Last_Track].MSF.S);
  288. Pico_mcd->cdd.Frame = INT_TO_BCDW(Pico_mcd->TOC.Tracks[Pico_mcd->TOC.Last_Track].MSF.F);
  289. Pico_mcd->cdd.Ext = 0;
  290. Pico_mcd->scd.CDD_Complete = 1;
  291. return 0;
  292. }
  293. PICO_INTERNAL int Get_First_Last_Track_CDD_c24(void)
  294. {
  295. CHECK_TRAY_OPEN
  296. Pico_mcd->cdd.Status &= 0xFF;
  297. if (!CD_Present)
  298. {
  299. Pico_mcd->scd.Status_CDD = NOCD;
  300. }
  301. // else if (!(CDC.CTRL.B.B0 & 0x80)) Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;
  302. Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;
  303. Pico_mcd->cdd.Minute = INT_TO_BCDW(1);
  304. Pico_mcd->cdd.Seconde = INT_TO_BCDW(Pico_mcd->TOC.Last_Track);
  305. Pico_mcd->cdd.Frame = 0;
  306. Pico_mcd->cdd.Ext = 0;
  307. Pico_mcd->scd.CDD_Complete = 1;
  308. return 0;
  309. }
  310. PICO_INTERNAL int Get_Track_Adr_CDD_c25(void)
  311. {
  312. int track_number;
  313. CHECK_TRAY_OPEN
  314. // track number in TC4 & TC5
  315. track_number = (Pico_mcd->s68k_regs[0x38+10+4] & 0xF) * 10 + (Pico_mcd->s68k_regs[0x38+10+5] & 0xF);
  316. Pico_mcd->cdd.Status &= 0xFF;
  317. if (!CD_Present)
  318. {
  319. Pico_mcd->scd.Status_CDD = NOCD;
  320. Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;
  321. }
  322. // else if (!(CDC.CTRL.B.B0 & 0x80)) Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;
  323. Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;
  324. if (track_number > Pico_mcd->TOC.Last_Track) track_number = Pico_mcd->TOC.Last_Track;
  325. else if (track_number < 1) track_number = 1;
  326. Pico_mcd->cdd.Minute = INT_TO_BCDW(Pico_mcd->TOC.Tracks[track_number - 1].MSF.M);
  327. Pico_mcd->cdd.Seconde = INT_TO_BCDW(Pico_mcd->TOC.Tracks[track_number - 1].MSF.S);
  328. Pico_mcd->cdd.Frame = INT_TO_BCDW(Pico_mcd->TOC.Tracks[track_number - 1].MSF.F);
  329. Pico_mcd->cdd.Ext = track_number % 10;
  330. if (track_number == 1) Pico_mcd->cdd.Frame |= 0x0800; // data track
  331. Pico_mcd->scd.CDD_Complete = 1;
  332. return 0;
  333. }
  334. PICO_INTERNAL int Play_CDD_c3(void)
  335. {
  336. _msf MSF;
  337. int delay, new_lba;
  338. CHECK_TRAY_OPEN
  339. CHECK_CD_PRESENT
  340. // MSF of the track to play in TC buffer
  341. MSF.M = (Pico_mcd->s68k_regs[0x38+10+2] & 0xF) * 10 + (Pico_mcd->s68k_regs[0x38+10+3] & 0xF);
  342. MSF.S = (Pico_mcd->s68k_regs[0x38+10+4] & 0xF) * 10 + (Pico_mcd->s68k_regs[0x38+10+5] & 0xF);
  343. MSF.F = (Pico_mcd->s68k_regs[0x38+10+6] & 0xF) * 10 + (Pico_mcd->s68k_regs[0x38+10+7] & 0xF);
  344. Pico_mcd->scd.Cur_Track = MSF_to_Track(&MSF);
  345. new_lba = MSF_to_LBA(&MSF);
  346. delay = new_lba - Pico_mcd->scd.Cur_LBA;
  347. if (delay < 0) delay = -delay;
  348. delay >>= 12;
  349. Pico_mcd->scd.Cur_LBA = new_lba;
  350. CDC_Update_Header();
  351. cdprintf("Read : Cur LBA = %d, M=%d, S=%d, F=%d", Pico_mcd->scd.Cur_LBA, MSF.M, MSF.S, MSF.F);
  352. if (Pico_mcd->scd.Status_CDD != PLAYING) delay += 20;
  353. Pico_mcd->scd.Status_CDD = PLAYING;
  354. Pico_mcd->cdd.Status = 0x0102;
  355. // Pico_mcd->cdd.Status = COMM_OK;
  356. if (Pico_mcd->scd.File_Add_Delay == 0) Pico_mcd->scd.File_Add_Delay = delay;
  357. if (Pico_mcd->scd.Cur_Track == 1)
  358. {
  359. Pico_mcd->s68k_regs[0x36] |= 0x01; // DATA
  360. }
  361. else
  362. {
  363. Pico_mcd->s68k_regs[0x36] &= ~0x01; // AUDIO
  364. //CD_Audio_Starting = 1;
  365. FILE_Play_CD_LBA();
  366. }
  367. if (Pico_mcd->scd.Cur_Track == 100) Pico_mcd->cdd.Minute = 0x0A02;
  368. else Pico_mcd->cdd.Minute = INT_TO_BCDW(Pico_mcd->scd.Cur_Track);
  369. Pico_mcd->cdd.Seconde = 0;
  370. Pico_mcd->cdd.Frame = 0;
  371. Pico_mcd->cdd.Ext = 0;
  372. Pico_mcd->scd.Status_CDC |= 1; // Read data with CDC
  373. Pico_mcd->scd.CDD_Complete = 1;
  374. return 0;
  375. }
  376. PICO_INTERNAL int Seek_CDD_c4(void)
  377. {
  378. _msf MSF;
  379. CHECK_TRAY_OPEN
  380. CHECK_CD_PRESENT
  381. // MSF to seek in TC buffer
  382. MSF.M = (Pico_mcd->s68k_regs[0x38+10+2] & 0xF) * 10 + (Pico_mcd->s68k_regs[0x38+10+3] & 0xF);
  383. MSF.S = (Pico_mcd->s68k_regs[0x38+10+4] & 0xF) * 10 + (Pico_mcd->s68k_regs[0x38+10+5] & 0xF);
  384. MSF.F = (Pico_mcd->s68k_regs[0x38+10+6] & 0xF) * 10 + (Pico_mcd->s68k_regs[0x38+10+7] & 0xF);
  385. Pico_mcd->scd.Cur_Track = MSF_to_Track(&MSF);
  386. Pico_mcd->scd.Cur_LBA = MSF_to_LBA(&MSF);
  387. CDC_Update_Header();
  388. Pico_mcd->scd.Status_CDC &= ~1; // Stop CDC read
  389. Pico_mcd->scd.Status_CDD = READY;
  390. Pico_mcd->cdd.Status = 0x0200;
  391. // DATA ?
  392. if (Pico_mcd->scd.Cur_Track == 1)
  393. Pico_mcd->s68k_regs[0x36] |= 0x01;
  394. else Pico_mcd->s68k_regs[0x36] &= ~0x01; // AUDIO
  395. Pico_mcd->cdd.Minute = 0;
  396. Pico_mcd->cdd.Seconde = 0;
  397. Pico_mcd->cdd.Frame = 0;
  398. Pico_mcd->cdd.Ext = 0;
  399. Pico_mcd->scd.CDD_Complete = 1;
  400. return 0;
  401. }
  402. PICO_INTERNAL int Pause_CDD_c6(void)
  403. {
  404. CHECK_TRAY_OPEN
  405. CHECK_CD_PRESENT
  406. Pico_mcd->scd.Status_CDC &= ~1; // Stop CDC read to start a new one if raw data
  407. Pico_mcd->scd.Status_CDD = READY;
  408. Pico_mcd->cdd.Status = Pico_mcd->scd.Status_CDD;
  409. Pico_mcd->s68k_regs[0x36] |= 0x01; // Data bit set because stopped
  410. Pico_mcd->cdd.Minute = 0;
  411. Pico_mcd->cdd.Seconde = 0;
  412. Pico_mcd->cdd.Frame = 0;
  413. Pico_mcd->cdd.Ext = 0;
  414. Pico_mcd->scd.CDD_Complete = 1;
  415. return 0;
  416. }
  417. PICO_INTERNAL int Resume_CDD_c7(void)
  418. {
  419. CHECK_TRAY_OPEN
  420. CHECK_CD_PRESENT
  421. Pico_mcd->scd.Cur_Track = LBA_to_Track(Pico_mcd->scd.Cur_LBA);
  422. #ifdef DEBUG_CD
  423. {
  424. _msf MSF;
  425. LBA_to_MSF(Pico_mcd->scd.Cur_LBA, &MSF);
  426. cdprintf("Resume read : Cur LBA = %d, M=%d, S=%d, F=%d", Pico_mcd->scd.Cur_LBA, MSF.M, MSF.S, MSF.F);
  427. }
  428. #endif
  429. Pico_mcd->scd.Status_CDD = PLAYING;
  430. Pico_mcd->cdd.Status = 0x0102;
  431. if (Pico_mcd->scd.Cur_Track == 1)
  432. {
  433. Pico_mcd->s68k_regs[0x36] |= 0x01; // DATA
  434. }
  435. else
  436. {
  437. Pico_mcd->s68k_regs[0x36] &= ~0x01; // AUDIO
  438. //CD_Audio_Starting = 1;
  439. FILE_Play_CD_LBA();
  440. }
  441. if (Pico_mcd->scd.Cur_Track == 100) Pico_mcd->cdd.Minute = 0x0A02;
  442. else Pico_mcd->cdd.Minute = INT_TO_BCDW(Pico_mcd->scd.Cur_Track);
  443. Pico_mcd->cdd.Seconde = 0;
  444. Pico_mcd->cdd.Frame = 0;
  445. Pico_mcd->cdd.Ext = 0;
  446. Pico_mcd->scd.Status_CDC |= 1; // Read data with CDC
  447. Pico_mcd->scd.CDD_Complete = 1;
  448. return 0;
  449. }
  450. PICO_INTERNAL int Fast_Foward_CDD_c8(void)
  451. {
  452. CHECK_TRAY_OPEN
  453. CHECK_CD_PRESENT
  454. Pico_mcd->scd.Status_CDC &= ~1; // Stop CDC read
  455. Pico_mcd->scd.Status_CDD = FAST_FOW;
  456. Pico_mcd->cdd.Status = Pico_mcd->scd.Status_CDD | 2;
  457. Pico_mcd->cdd.Minute = INT_TO_BCDW(Pico_mcd->scd.Cur_Track);
  458. Pico_mcd->cdd.Seconde = 0;
  459. Pico_mcd->cdd.Frame = 0;
  460. Pico_mcd->cdd.Ext = 0;
  461. Pico_mcd->scd.CDD_Complete = 1;
  462. return 0;
  463. }
  464. PICO_INTERNAL int Fast_Rewind_CDD_c9(void)
  465. {
  466. CHECK_TRAY_OPEN
  467. CHECK_CD_PRESENT
  468. Pico_mcd->scd.Status_CDC &= ~1; // Stop CDC read
  469. Pico_mcd->scd.Status_CDD = FAST_REV;
  470. Pico_mcd->cdd.Status = Pico_mcd->scd.Status_CDD | 2;
  471. Pico_mcd->cdd.Minute = INT_TO_BCDW(Pico_mcd->scd.Cur_Track);
  472. Pico_mcd->cdd.Seconde = 0;
  473. Pico_mcd->cdd.Frame = 0;
  474. Pico_mcd->cdd.Ext = 0;
  475. Pico_mcd->scd.CDD_Complete = 1;
  476. return 0;
  477. }
  478. PICO_INTERNAL int Close_Tray_CDD_cC(void)
  479. {
  480. CD_Present = 0;
  481. //Clear_Sound_Buffer();
  482. Pico_mcd->scd.Status_CDC &= ~1; // Stop CDC read
  483. printf("tray close\n");
  484. if (PicoMCDcloseTray != NULL)
  485. CD_Present = PicoMCDcloseTray();
  486. Pico_mcd->scd.Status_CDD = CD_Present ? STOPPED : NOCD;
  487. Pico_mcd->cdd.Status = 0x0000;
  488. Pico_mcd->cdd.Minute = 0;
  489. Pico_mcd->cdd.Seconde = 0;
  490. Pico_mcd->cdd.Frame = 0;
  491. Pico_mcd->cdd.Ext = 0;
  492. Pico_mcd->scd.CDD_Complete = 1;
  493. return 0;
  494. }
  495. PICO_INTERNAL int Open_Tray_CDD_cD(void)
  496. {
  497. CHECK_TRAY_OPEN
  498. Pico_mcd->scd.Status_CDC &= ~1; // Stop CDC read
  499. printf("tray open\n");
  500. Unload_ISO();
  501. CD_Present = 0;
  502. if (PicoMCDopenTray != NULL)
  503. PicoMCDopenTray();
  504. Pico_mcd->scd.Status_CDD = TRAY_OPEN;
  505. Pico_mcd->cdd.Status = 0x0E00;
  506. Pico_mcd->cdd.Minute = 0;
  507. Pico_mcd->cdd.Seconde = 0;
  508. Pico_mcd->cdd.Frame = 0;
  509. Pico_mcd->cdd.Ext = 0;
  510. Pico_mcd->scd.CDD_Complete = 1;
  511. return 0;
  512. }
  513. PICO_INTERNAL int CDD_cA(void)
  514. {
  515. CHECK_TRAY_OPEN
  516. CHECK_CD_PRESENT
  517. Pico_mcd->scd.Status_CDC &= ~1;
  518. Pico_mcd->scd.Status_CDD = READY;
  519. Pico_mcd->cdd.Status = Pico_mcd->scd.Status_CDD;
  520. Pico_mcd->cdd.Minute = 0;
  521. Pico_mcd->cdd.Seconde = INT_TO_BCDW(1);
  522. Pico_mcd->cdd.Frame = INT_TO_BCDW(1);
  523. Pico_mcd->cdd.Ext = 0;
  524. Pico_mcd->scd.CDD_Complete = 1;
  525. return 0;
  526. }
  527. PICO_INTERNAL int CDD_Def(void)
  528. {
  529. Pico_mcd->cdd.Status = Pico_mcd->scd.Status_CDD;
  530. Pico_mcd->cdd.Minute = 0;
  531. Pico_mcd->cdd.Seconde = 0;
  532. Pico_mcd->cdd.Frame = 0;
  533. Pico_mcd->cdd.Ext = 0;
  534. return 0;
  535. }