cd: switch to CD controller code from genplus
[picodrive.git] / pico / cd / cd_sys.c
index 1c19057..f7cd7b5 100644 (file)
 #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
@@ -139,15 +143,32 @@ PICO_INTERNAL void Check_CD_Command(void)
                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
@@ -755,3 +776,158 @@ PICO_INTERNAL int CDD_Def(void)
 }\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