#define FAST_REV 0x10300 // FAST REVERSE track CDD status\r
#define PLAYING 0x0100 // PLAYING audio track CDD status\r
\r
+//#undef cdprintf\r
+//#define cdprintf(x, ...) elprintf(EL_STATUS, x, ##__VA_ARGS__)\r
+\r
+#define CDC_Update_Header()\r
\r
static int CD_Present = 0;\r
\r
cdprintf("Got a read command");\r
\r
// DATA ?\r
- if (Pico_mcd->scd.Cur_Track == 1)\r
+ if (Pico_mcd->scd.Cur_Track == 1) {\r
Pico_mcd->s68k_regs[0x36] |= 0x01;\r
- else Pico_mcd->s68k_regs[0x36] &= ~0x01; // AUDIO\r
\r
- if (Pico_mcd->scd.File_Add_Delay == 0)\r
- {\r
- FILE_Read_One_LBA_CDC();\r
+ if (Pico_mcd->scd.File_Add_Delay == 0)\r
+ {\r
+ unsigned char header[4];\r
+ _msf MSF;\r
+\r
+ LBA_to_MSF(Pico_mcd->scd.Cur_LBA, &MSF);\r
+\r
+ header[0] = INT_TO_BCDB(MSF.M);\r
+ header[1] = INT_TO_BCDB(MSF.S);\r
+ header[2] = INT_TO_BCDB(MSF.F);\r
+ header[3] = 0x01;\r
+\r
+ //FILE_Read_One_LBA_CDC();\r
+ Pico_mcd->scd.Cur_LBA +=\r
+ cdc_decoder_update(header);\r
+ }\r
+ else Pico_mcd->scd.File_Add_Delay--;\r
+ }\r
+ else {\r
+ Pico_mcd->s68k_regs[0x36] &= ~0x01; // AUDIO\r
+ unsigned char header[4] = { 0, };\r
+ cdc_decoder_update(header);\r
}\r
- else Pico_mcd->scd.File_Add_Delay--;\r
}\r
\r
// Check CDD\r
Pico_mcd->scd.Cur_Track = 0;\r
Pico_mcd->scd.Cur_LBA = -150;\r
Pico_mcd->scd.Status_CDC &= ~1;\r
- Pico_mcd->scd.Status_CDD = CD_Present ? READY : NOCD;\r
+ if (Pico_mcd->scd.Status_CDD != TRAY_OPEN)\r
+ Pico_mcd->scd.Status_CDD = CD_Present ? READY : NOCD;\r
Pico_mcd->scd.CDD_Complete = 0;\r
Pico_mcd->scd.File_Add_Delay = 0;\r
}\r
int ret = 1;\r
\r
CD_Present = 0;\r
- Pico_mcd->scd.Status_CDD = NOCD;\r
\r
if (cdimg_name != NULL && type != CIT_NOT_CD)\r
{\r
ret = Load_CD_Image(cdimg_name, type);\r
if (ret == 0) {\r
CD_Present = 1;\r
- /* for open tray close command will handle Status_CDD */\r
- if (Pico_mcd->scd.Status_CDD != TRAY_OPEN)\r
+\r
+ if (Pico_mcd->scd.Status_CDD == TRAY_OPEN)\r
+ {\r
+ if (Pico_mcd->bios[0x122 ^ 1] == '2')\r
+ Close_Tray_CDD_cC();\r
+ // else bios will issue it\r
+ }\r
+ else\r
+ {\r
Pico_mcd->scd.Status_CDD = READY;\r
+ }\r
}\r
}\r
\r
+ if (Pico_mcd->scd.Status_CDD != TRAY_OPEN && !CD_Present)\r
+ Pico_mcd->scd.Status_CDD = NOCD;\r
+\r
return ret;\r
}\r
\r
\r
-void Stop_CD(void)\r
+int Stop_CD(void)\r
{\r
+ int ret = CD_Present;\r
+\r
Unload_ISO();\r
CD_Present = 0;\r
+\r
+ return ret;\r
}\r
\r
\r
if (delay < 0) delay = -delay;\r
delay >>= 12;\r
\r
+ if (Pico_mcd->scd.Cur_LBA > 0 && delay < 13)\r
+ // based on genplus GX\r
+ delay = 13;\r
+\r
Pico_mcd->scd.Cur_LBA = new_lba;\r
CDC_Update_Header();\r
\r
}\r
\r
\r
+static int bswapwrite(int a, unsigned short d)\r
+{\r
+ *(unsigned short *)(Pico_mcd->s68k_regs + a) = (d>>8)|(d<<8);\r
+ return d + (d >> 8);\r
+}\r
+\r
+PICO_INTERNAL void CDD_Export_Status(void)\r
+{\r
+ unsigned int csum;\r
+\r
+ csum = bswapwrite( 0x38+0, Pico_mcd->cdd.Status);\r
+ csum += bswapwrite( 0x38+2, Pico_mcd->cdd.Minute);\r
+ csum += bswapwrite( 0x38+4, Pico_mcd->cdd.Seconde);\r
+ csum += bswapwrite( 0x38+6, Pico_mcd->cdd.Frame);\r
+ Pico_mcd->s68k_regs[0x38+8] = Pico_mcd->cdd.Ext;\r
+ csum += Pico_mcd->cdd.Ext;\r
+ Pico_mcd->s68k_regs[0x38+9] = ~csum & 0xf;\r
+\r
+ Pico_mcd->s68k_regs[0x37] &= 3; // CDD.Control\r
+\r
+ if (Pico_mcd->s68k_regs[0x33] & PCDS_IEN4)\r
+ {\r
+ elprintf(EL_INTS, "cdd export irq 4");\r
+ SekInterruptS68k(4);\r
+ }\r
+\r
+// cdprintf("CDD exported status\n");\r
+ cdprintf("out: Status=%.4X, Minute=%.4X, Second=%.4X, Frame=%.4X Checksum=%.4X",\r
+ (Pico_mcd->s68k_regs[0x38+0] << 8) | Pico_mcd->s68k_regs[0x38+1],\r
+ (Pico_mcd->s68k_regs[0x38+2] << 8) | Pico_mcd->s68k_regs[0x38+3],\r
+ (Pico_mcd->s68k_regs[0x38+4] << 8) | Pico_mcd->s68k_regs[0x38+5],\r
+ (Pico_mcd->s68k_regs[0x38+6] << 8) | Pico_mcd->s68k_regs[0x38+7],\r
+ (Pico_mcd->s68k_regs[0x38+8] << 8) | Pico_mcd->s68k_regs[0x38+9]);\r
+}\r
+\r
+\r
+PICO_INTERNAL void CDD_Import_Command(void)\r
+{\r
+// cdprintf("CDD importing command\n");\r
+ cdprintf("in: Command=%.4X, Minute=%.4X, Second=%.4X, Frame=%.4X Checksum=%.4X",\r
+ (Pico_mcd->s68k_regs[0x38+10+0] << 8) | Pico_mcd->s68k_regs[0x38+10+1],\r
+ (Pico_mcd->s68k_regs[0x38+10+2] << 8) | Pico_mcd->s68k_regs[0x38+10+3],\r
+ (Pico_mcd->s68k_regs[0x38+10+4] << 8) | Pico_mcd->s68k_regs[0x38+10+5],\r
+ (Pico_mcd->s68k_regs[0x38+10+6] << 8) | Pico_mcd->s68k_regs[0x38+10+7],\r
+ (Pico_mcd->s68k_regs[0x38+10+8] << 8) | Pico_mcd->s68k_regs[0x38+10+9]);\r
+\r
+ switch (Pico_mcd->s68k_regs[0x38+10+0])\r
+ {\r
+ case 0x0: // STATUS (?)\r
+ Get_Status_CDD_c0();\r
+ break;\r
+\r
+ case 0x1: // STOP ALL (?)\r
+ Stop_CDD_c1();\r
+ break;\r
+\r
+ case 0x2: // GET TOC INFORMATIONS\r
+ switch(Pico_mcd->s68k_regs[0x38+10+3])\r
+ {\r
+ case 0x0: // get current position (MSF format)\r
+ Pico_mcd->cdd.Status = (Pico_mcd->cdd.Status & 0xFF00);\r
+ Get_Pos_CDD_c20();\r
+ break;\r
+\r
+ case 0x1: // get elapsed time of current track played/scanned (relative MSF format)\r
+ Pico_mcd->cdd.Status = (Pico_mcd->cdd.Status & 0xFF00) | 1;\r
+ Get_Track_Pos_CDD_c21();\r
+ break;\r
+\r
+ case 0x2: // get current track in RS2-RS3\r
+ Pico_mcd->cdd.Status = (Pico_mcd->cdd.Status & 0xFF00) | 2;\r
+ Get_Current_Track_CDD_c22();\r
+ break;\r
+\r
+ case 0x3: // get total length (MSF format)\r
+ Pico_mcd->cdd.Status = (Pico_mcd->cdd.Status & 0xFF00) | 3;\r
+ Get_Total_Lenght_CDD_c23();\r
+ break;\r
+\r
+ case 0x4: // first & last track number\r
+ Pico_mcd->cdd.Status = (Pico_mcd->cdd.Status & 0xFF00) | 4;\r
+ Get_First_Last_Track_CDD_c24();\r
+ break;\r
+\r
+ case 0x5: // get track addresse (MSF format)\r
+ Pico_mcd->cdd.Status = (Pico_mcd->cdd.Status & 0xFF00) | 5;\r
+ Get_Track_Adr_CDD_c25();\r
+ break;\r
+\r
+ default : // invalid, then we return status\r
+ Pico_mcd->cdd.Status = (Pico_mcd->cdd.Status & 0xFF00) | 0xF;\r
+ Get_Status_CDD_c0();\r
+ break;\r
+ }\r
+ break;\r
+\r
+ case 0x3: // READ\r
+ Play_CDD_c3();\r
+ break;\r
+\r
+ case 0x4: // SEEK\r
+ Seek_CDD_c4();\r
+ break;\r
+\r
+ case 0x6: // PAUSE/STOP\r
+ Pause_CDD_c6();\r
+ break;\r
+\r
+ case 0x7: // RESUME\r
+ Resume_CDD_c7();\r
+ break;\r
+\r
+ case 0x8: // FAST FOWARD\r
+ Fast_Foward_CDD_c8();\r
+ break;\r
+\r
+ case 0x9: // FAST REWIND\r
+ Fast_Rewind_CDD_c9();\r
+ break;\r
+\r
+ case 0xA: // RECOVER INITIAL STATE (?)\r
+ CDD_cA();\r
+ break;\r
+\r
+ case 0xC: // CLOSE TRAY\r
+ Close_Tray_CDD_cC();\r
+ break;\r
+\r
+ case 0xD: // OPEN TRAY\r
+ Open_Tray_CDD_cD();\r
+ break;\r
+\r
+ default: // UNKNOWN\r
+ CDD_Def();\r
+ break;\r
+ }\r
+}\r
+\r
+void CDD_Reset(void)\r
+{\r
+ // Reseting CDD\r
+\r
+ memset(Pico_mcd->s68k_regs+0x34, 0, 2*2); // CDD.Fader, CDD.Control\r
+ Pico_mcd->cdd.Status = 0;\r
+ Pico_mcd->cdd.Minute = 0;\r
+ Pico_mcd->cdd.Seconde = 0;\r
+ Pico_mcd->cdd.Frame = 0;\r
+ Pico_mcd->cdd.Ext = 0;\r
+\r
+ // clear receive status and transfer command\r
+ memset(Pico_mcd->s68k_regs+0x38, 0, 20);\r
+ Pico_mcd->s68k_regs[0x38+9] = 0xF; // Default checksum\r
+}\r
+\r
+\r