+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