Subversion Repositories pentevo

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

  1. #include "std.h"
  2.  
  3. #include <io.h>
  4.  
  5. #include "emul.h"
  6. #include "vars.h"
  7. #include "sdcard.h"
  8.  
  9. #include "util.h"
  10.  
  11. void TSdCard::Reset()
  12. {
  13. //    printf(__FUNCTION__"\n");
  14.  
  15.     CurrState = ST_IDLE;
  16.     ArgCnt = 0;
  17.     Cmd = CMD_INVALID;
  18.     DataBlockLen = 512;
  19.     DataCnt = 0;
  20.  
  21.     CsdCnt = 0;
  22.     //memset(Csd, 0, sizeof(Csd));      //шч NEDOREPO
  23.     Csd[0] = (1 << 6); // CSD structure (SDHC)
  24.     Csd[1] = 0xE;  // TACC
  25.     Csd[2] = 0x00; // NSAC
  26.     Csd[3] = 0x32; // TRAN_SPEED
  27.     Csd[4] = 0x5B; // CCC x1x11011
  28.     Csd[5] = 0x59; // CCC 0101 | READ_BL_LEN 9
  29.     Csd[6] = 0x00; // READ_BL_PARTIAL | WRITE_BLK_MISALIGN | READ_BLK_MISALIGN | DSR_IMP
  30.  
  31.     UpdateCsdImageSize();
  32.  
  33.     Csd[10] = (1 << 6) | (0x3F << 1); // ERASE_BLK_EN | SECTOR_SIZE
  34.     Csd[11] = (1 << 7); // SECTOR_SIZE | WP_GRP_SIZE
  35.     Csd[12] = (2 << 2) | 2; // R2W_FACTOR | WRITE_BL_LEN 9
  36.     Csd[13] = (1 << 6); // WRITE_BL_LEN 9 | WRITE_BL_PARTIAL
  37.     Csd[14] = 0x00; // FILE_FORMAT_GRP | COPY | PERM_WRITE_PROTECT | TMP_WRITE_PROTECT | FILE_FORMAT
  38.     Csd[15] = 1; // CRC | 1
  39.  
  40.     CidCnt = 0;
  41.     memset(Cid, 0, sizeof(Cid));
  42.  
  43.     // OEM/Application ID (OID)
  44.     Cid[1] = 'U';
  45.     Cid[2] = 'S';
  46.  
  47.     // Product Name (PNM)
  48.     Cid[3] = 'U';
  49.     Cid[4] = 'S';
  50.     Cid[5] = '0' + (VER_HL / 10) % 10;
  51.     Cid[6] = '0' + VER_HL % 10;
  52.     Cid[7] = '0' + VER_A % 10;
  53.  
  54.     Cid[8] = 0x10; // Product Revision (PRV) (BCD)
  55.     Cid[14] = 0x04; // Manufacture Date Code (MDT)
  56.     Cid[15] = 1; // CRC7 | 1
  57.  
  58. //  Ocr = 0x80200000;   //эхЄ т NEDOREPO
  59.     OcrCnt = 0;
  60.     R7_Cnt = 0;
  61.    
  62.     AppCmd = false;
  63. }
  64.  
  65. void TSdCard::UpdateCsdImageSize()
  66. {
  67.     Csd[7] = (ImageSize >> 16) & 0x3F; // C_SIZE
  68.     Csd[8] = (ImageSize >> 8) & 0xFF; // C_SIZE
  69.     Csd[9] = ImageSize & 0xFF; // C_SIZE
  70. }
  71.  
  72. void TSdCard::Wr(u8 Val)
  73. {
  74.     static u32 WrPos = -1U;
  75.     TState NextState = ST_IDLE;
  76. //    printf(__FUNCTION__" Val = %X\n", Val);
  77.  
  78.     if(!Image)
  79.         return;
  80.  
  81.     switch(CurrState)
  82.     {
  83.         case ST_IDLE:
  84.        // case ST_WR_DATA_SIG:  //╟└╩╬╠┼═╫┼═╬ ┬ NEDOREPO
  85.         {
  86.             if((Val & 0xC0) != 0x40) // start=0, transm=1
  87.                break;
  88.  
  89.             Cmd = TCmd(Val & 0x3F);
  90.             if(!AppCmd)
  91.             {
  92.                 switch(Cmd) // Check commands
  93.                 {
  94.                
  95. //0.39.0       
  96. //     
  97. //                case CMD_GO_IDLE_STATE:
  98. ////                    printf(__FUNCTION__" CMD_GO_IDLE_STATE, Val = %X\n", Val);
  99. //                    NextState = ST_RD_ARG;
  100. //                    ArgCnt = 0;
  101. //                break;
  102. //
  103. //                case CMD_SEND_OP_COND:
  104. ////                    printf(__FUNCTION__" CMD_SEND_OP_COND, Val = %X\n", Val);
  105. //                    NextState = ST_RD_ARG;
  106. //                    ArgCnt = 0;
  107. //                break;
  108. //
  109. //                case CMD_SET_BLOCKLEN:
  110. ////                    printf(__FUNCTION__" CMD_SET_BLOCKLEN, Val = %X\n", Val);
  111. //                    NextState = ST_RD_ARG;
  112. //                    ArgCnt = 0;
  113. //                break;
  114. //
  115. //                case CMD_READ_SINGLE_BLOCK:
  116. ////                    printf(__FUNCTION__" CMD_READ_SINGLE_BLOCK, Val = %X\n", Val);
  117. //                    NextState = ST_RD_ARG;
  118. //                    ArgCnt = 0;
  119. //                break;
  120. //
  121. //                case CMD_READ_MULTIPLE_BLOCK:
  122. ////                    printf(__FUNCTION__" CMD_READ_MULTIPLE_BLOCK, Val = %X\n", Val);
  123. //                    NextState = ST_RD_ARG;
  124. //                    ArgCnt = 0;
  125. //                break;
  126. //
  127. //                case CMD_WRITE_BLOCK:
  128. ////                    printf(__FUNCTION__" CMD_WRITE_BLOCK, Val = %X\n", Val);
  129. //                    NextState = ST_RD_ARG;
  130. //                    ArgCnt = 0;
  131. //                break;
  132. //
  133. //                case CMD_WRITE_MULTIPLE_BLOCK:
  134. ////                    printf(__FUNCTION__" CMD_WRITE_MULTIPLE_BLOCK, Val = %X\n", Val);
  135. //                    NextState = ST_RD_ARG;
  136. //                    ArgCnt = 0;
  137. //                break;
  138. //
  139. //                case CMD_STOP_TRANSMISSION:
  140. ////                    printf(__FUNCTION__" CMD_STOP_TRANSMISSION, Val = %X\n", Val);
  141. //                    NextState = ST_RD_ARG;
  142. //                    ArgCnt = 0;
  143. //                break;
  144. //
  145. //                case CMD_SEND_IF_COND:
  146. ////                    printf(__FUNCTION__" CMD_SEND_IF_COND, Val = %X\n", Val);
  147. //                    NextState = ST_RD_ARG;
  148. //                    ArgCnt = 0;
  149. //                break;
  150. //
  151. //                case CMD_SEND_CSD:
  152. ////                    printf(__FUNCTION__" CMD_SEND_CSD, Val = %X\n", Val);
  153. //                    NextState = ST_RD_ARG;
  154. //                    ArgCnt = 0;
  155. //                    CsdCnt = 0;
  156. //                break;
  157. //
  158. //                case CMD_SEND_CID:
  159. ////                    printf(__FUNCTION__" CMD_SEND_CID, Val = %X\n", Val);
  160. //                    NextState = ST_RD_ARG;
  161. //                    ArgCnt = 0;
  162. //                    CidCnt = 0;
  163. //                break;
  164. //
  165. //                case CMD_CRC_ON_OFF:
  166. ////                    printf(__FUNCTION__" CMD_CRC_ON_OFF, Val = %X\n", Val);
  167. //                    NextState = ST_RD_ARG;
  168. //                    ArgCnt = 0;
  169. //                break;
  170. //
  171. //                case CMD_READ_OCR:
  172. ////                    printf(__FUNCTION__" CMD_READ_OCR, Val = %X\n", Val);
  173. ////                    __debugbreak();
  174. //                    NextState = ST_RD_ARG;
  175. //                    ArgCnt = 0;
  176. //                    OcrCnt = 0;
  177. //                break;
  178. //
  179. //                case CMD_APP_CMD:
  180. ////                    printf(__FUNCTION__" CMD_APP_CMD, Val = %X\n", Val);
  181. //                    NextState = ST_RD_ARG;
  182. //                    ArgCnt = 0;
  183. //                break;
  184. //
  185. //                default:
  186. //                    printf("%s Unknown CMD = 0x%X, Val = %X\n", __FUNCTION__, Cmd, Val);
  187. //                    NextState = ST_RD_ARG;
  188. //                    ArgCnt = 0;
  189. //                }
  190. //            }
  191. //            else // AppCmd
  192. //            {
  193. //                switch(Cmd)
  194. //                {
  195. //                case CMD_SET_WR_BLK_ERASE_COUNT:
  196. //                case CMD_SD_SEND_OP_COND:
  197. ////                    printf(__FUNCTION__" CMD_SD_SEND_OP_COND, Val = %X\n", Val);
  198. //                    NextState = ST_RD_ARG;
  199. //                    ArgCnt = 0;
  200. //                break;
  201. //
  202. //                default:
  203. //                    printf("%s Unknown ACMD = 0x%X, Val = %X\n", __FUNCTION__, Cmd, Val);
  204. //                    AppCmd = false;
  205. //                }
  206. //            }
  207. //         
  208.  
  209.  
  210. //NEDOREPO
  211.                 case CMD_SEND_CSD:
  212.                     CsdCnt = 0;
  213.                 break;
  214.  
  215.                 case CMD_SEND_CID:
  216.                     CidCnt = 0;
  217.                 break;
  218.  
  219.                 case CMD_READ_OCR:
  220.                     OcrCnt = 0;
  221.                 break;
  222.  
  223.                 case CMD_SEND_IF_COND:
  224.                     R7_Cnt = 0;
  225.                 //break;
  226.  
  227.                 //case CMD_APP_CMD:
  228.                 //    AppCmd = true;
  229.                 }
  230.             }
  231.             NextState = ST_RD_ARG;
  232.             ArgCnt = 0;
  233.            
  234.  
  235.         }
  236.         break;
  237.  
  238.         case ST_RD_ARG:
  239.             NextState = ST_RD_ARG;
  240.             ArgArr[3 - ArgCnt++] = Val;
  241.  
  242. //            printf(__FUNCTION__" ST_RD_ARG val=0x%X\n", Val);
  243.             if(ArgCnt == 4)
  244.             {
  245.                 if(!AppCmd)
  246.                 {
  247.                     switch(Cmd)
  248.                     {
  249.                     case CMD_SET_BLOCKLEN:                      //
  250.                         if (Arg<=4096)  DataBlockLen = Arg;     //NEDOREPO
  251.                     break;                                      //
  252.                    
  253.                     case CMD_READ_SINGLE_BLOCK:
  254. //                      printf(__FUNCTION__" CMD_READ_SINGLE_BLOCK, Addr = 0x%X\n", Arg);
  255.                         fseek(Image, long(Arg), SEEK_SET);
  256.                 //      fread(Buf, 512, 1, Image);              //0.39.0
  257.                         fread(Buf, DataBlockLen, 1, Image);     //NEDOREPO
  258.                     break;
  259.  
  260.                     case CMD_READ_MULTIPLE_BLOCK:
  261. //                      printf(__FUNCTION__" CMD_READ_MULTIPLE_BLOCK, Addr = 0x%X\n", Arg);
  262.                         fseek(Image, long(Arg), SEEK_SET);
  263.                 //      fread(Buf, 512, 1, Image);              //0.39.0
  264.                         fread(Buf, DataBlockLen, 1, Image);     //NEDOREPO
  265.                     break;
  266.  
  267.                     case CMD_WRITE_BLOCK:
  268. //                        printf(__FUNCTION__" CMD_WRITE_BLOCK, Addr = 0x%X\n", Arg);
  269.                     break;
  270.  
  271.                     case CMD_WRITE_MULTIPLE_BLOCK:
  272.                         WrPos = Arg;
  273. //                        printf(__FUNCTION__" CMD_WRITE_MULTIPLE_BLOCK, Addr = 0x%X\n", Arg);
  274.                     break;
  275.                     }
  276.                 }
  277.  
  278.                 NextState = ST_RD_CRC;
  279.                 ArgCnt = 0;
  280.             }
  281.         break;
  282.  
  283.         case ST_RD_CRC:
  284. //            printf(__FUNCTION__" ST_RD_CRC val=0x%X\n", Val);
  285.             NextState = GetRespondType();
  286.         break;
  287.  
  288.         case ST_RD_DATA_SIG:
  289. //             NextState = ST_RD_DATA;  //0.39.0
  290. // //
  291. // //          if(Val != 0xFE) // ╧ЁютхЁър ёшуэрЄєЁ√ фрээ√ї
  292. // //              __debugbreak();
  293. // //
  294. //             DataCnt = 0;
  295.  
  296.             if (Val==0xFE) // ╧ЁютхЁър ёшуэрЄєЁ√ фрээ√ї
  297.             {
  298.                 DataCnt = 0;
  299.                 NextState = ST_RD_DATA;
  300.             }
  301.             else
  302.                 NextState = ST_RD_DATA_SIG;
  303.                
  304.         break;
  305.  
  306.         case ST_RD_DATA_SIG_MUL:
  307.             switch(Val)
  308.             {
  309.             case 0xFC: // ╧ЁютхЁър ёшуэрЄєЁ√ фрээ√ї
  310. //                printf(__FUNCTION__" ST_RD_DATA_SIG_MUL, Start\n");
  311.                 DataCnt = 0;
  312.                 NextState = ST_RD_DATA_MUL;
  313.             break;
  314.             case 0xFD: // ╬ъюэўрэшх яхЁхфрўш
  315. //                printf(__FUNCTION__" ST_RD_DATA_SIG_MUL, Stop\n");
  316.  
  317.                 DataCnt = 0;            //NEDOREPO
  318.  
  319.                 NextState = ST_IDLE;
  320.             break;
  321.             default:
  322.                 NextState = ST_RD_DATA_SIG_MUL;
  323.             }
  324.         break;
  325.  
  326.         case ST_RD_DATA: // ╧Ёшхь фрээ√ї т сєЇхЁ
  327.         {
  328. //            printf(__FUNCTION__" ST_RD_DATA, Addr = 0x%X, Idx=%d\n", Arg, DataCnt);
  329.             Buf[DataCnt++] = Val;
  330.             NextState = ST_RD_DATA;
  331.             if(DataCnt == DataBlockLen) // ╟ряшё№ фрээ√ї т SD ърЁЄє
  332.             {
  333.                 DataCnt = 0;
  334. //                printf(__FUNCTION__" ST_RD_DATA, Addr = 0x%X, write to disk\n", Arg);
  335.                 fseek(Image, long(Arg), SEEK_SET);
  336.         //      fwrite(Buf, 512, 1, Image);     //0.39.0
  337.                 fwrite(Buf, DataBlockLen, 1, Image);    //NEDOREPO
  338.                 NextState = ST_RD_CRC16_1;
  339.             }
  340.         }
  341.         break;
  342.  
  343.         case ST_RD_DATA_MUL: // ╧Ёшхь фрээ√ї т сєЇхЁ
  344.         {
  345. //            printf(__FUNCTION__" ST_RD_DATA_MUL, Addr = 0x%X, Idx=%d\n", WrPos, DataCnt);
  346.             Buf[DataCnt++] = Val;
  347.             NextState = ST_RD_DATA_MUL;
  348.             if(DataCnt == DataBlockLen) // ╟ряшё№ фрээ√ї т SD ърЁЄє
  349.             {
  350.                 DataCnt = 0;
  351. //                printf(__FUNCTION__" ST_RD_DATA_MUL, Addr = 0x%X, write to disk\n", WrPos);
  352.                 fseek(Image, long(WrPos), SEEK_SET);
  353.         //      fwrite(Buf, 512, 1, Image);             //0.39.0
  354.         //      WrPos += 512;
  355.                 fwrite(Buf, DataBlockLen, 1, Image);    //NEDOREPO
  356.                 WrPos += DataBlockLen;
  357.                 NextState = ST_RD_CRC16_1;
  358.             }
  359.         }
  360.         break;
  361.  
  362.         case ST_RD_CRC16_1: // ╫Єхэшх ёЄрЁ°хую срщЄр CRC16
  363.         //printf("%s CRC16_1=0x%X\n", __FUNCTION__, Val);       //═┼╥ ┬ NEDOREPO
  364.             NextState = ST_RD_CRC16_2;
  365.         break;
  366.  
  367.         case ST_RD_CRC16_2: // ╫Єхэшх ьырф°хую срщЄр CRC16
  368.         //printf("%s CRC16_2=0x%X\n", __FUNCTION__, Val);       //═┼╥ ┬ NEDOREPO
  369.             NextState = ST_WR_DATA_RESP;
  370.         break;
  371.  
  372.         default:
  373. //0.39.0
  374. //          printf("%s Unknown St = 0x%X, Val = 0x%X\n", __FUNCTION__, CurrState, Val);
  375. //NEDOREPO
  376. //          printf(__FUNCTION__" St=0x%X,  val=0x%X\n", CurrState, Val);       
  377.             return;
  378.     }
  379.  
  380.     CurrState = NextState;
  381. }
  382.  
  383. u8 TSdCard::Rd()
  384. {
  385. //    printf(__FUNCTION__" cmd=0x%X, St=0x%X\n", Cmd, CurrState);
  386.     if(!Image)
  387.         return 0xFF;
  388.  
  389.     switch(Cmd)
  390.     {
  391.     case CMD_GO_IDLE_STATE:
  392.         if(CurrState == ST_R1)
  393.         {
  394. //            Cmd = CMD_INVALID;
  395.             CurrState = ST_IDLE;
  396.             return 1;
  397.         }
  398.     break;
  399.     case CMD_SEND_OP_COND:
  400.         if(CurrState == ST_R1)
  401.         {
  402. //            Cmd = CMD_INVALID;
  403.             CurrState = ST_IDLE;
  404.             return 0;
  405.         }
  406.     break;
  407.     case CMD_SET_BLOCKLEN:
  408.         if(CurrState == ST_R1)
  409.         {
  410. //            Cmd = CMD_INVALID;
  411.             CurrState = ST_IDLE;
  412.             return 0;
  413.         }
  414.     break;
  415.     case CMD_SEND_IF_COND:
  416.         if(CurrState == ST_R7)
  417.         {
  418.        
  419. //0.39.0
  420. //            CurrState = ST_IDLE;
  421. //            return 5; // invalid command | idle state
  422.        
  423. //NEDOREPO     
  424.             switch (R7_Cnt++)
  425.             {
  426.              case 0: return 0x01; // R1
  427.              case 1: return 0x00;
  428.              case 2: return 0x00;
  429.              case 3: return 0x01;
  430.              default:
  431.                 CurrState = ST_IDLE;
  432.                 R7_Cnt = 0;
  433.                 return ArgArr[0]; // echo-back
  434.             }
  435.         }
  436.     break;
  437.  
  438.     case CMD_READ_OCR:
  439. //      if(CurrState == ST_R1)  //0.39.0
  440.         if (CurrState == ST_R3) //NEDOREPO
  441.         {
  442. //0.39.0
  443. //            CurrState = ST_R3;
  444. //            return 0;
  445.             switch (OcrCnt++)
  446.             {
  447.              case 0: return 0x00; // R1
  448.              case 1: return 0x80;
  449.              case 2: return 0xFF;
  450.              case 3: return 0x80;
  451.              default:
  452.                 CurrState = ST_IDLE;
  453.                 OcrCnt = 0;
  454.                 return 0x00;
  455.             }
  456.         }
  457.     break;
  458.  
  459.     case CMD_APP_CMD:
  460.         if(CurrState == ST_R1)
  461.         {
  462.             CurrState = ST_IDLE;
  463.             return 0;
  464.         }
  465.     break;
  466.  
  467. //    case CMD_SET_WR_BLK_ERASE_COUNT:  //═┼╥ ┬ NEDOREPO
  468. //        if(CurrState == ST_R1)        //0.39.0
  469. //        {
  470. //            CurrState = ST_IDLE;
  471. //            return 0;
  472. //        }
  473. //    break;
  474.  
  475.     case CMD_SD_SEND_OP_COND:
  476.         if (CurrState == ST_R1)
  477.         {
  478.             CurrState = ST_IDLE;
  479.             return 0;
  480.         }
  481.     break;
  482.  
  483.     case CMD_CRC_ON_OFF:
  484.         if (CurrState == ST_R1)
  485.         {
  486.             CurrState = ST_IDLE;
  487.             return 0;
  488.         }
  489.     break;
  490.  
  491.     case CMD_STOP_TRANSMISSION:
  492.         switch(CurrState)
  493.         {
  494.         case ST_R1:
  495.             //CurrState = ST_R1b;       //0.39.0
  496.             DataCnt = 0;                //NEDOREPO
  497.             CurrState = ST_IDLE;
  498.             return 0;
  499.         case ST_R1b:
  500.             //CurrState = ST_IDLE;      //0.39.0
  501.             //return 0xFF;
  502.             DataCnt = 0;
  503.             CurrState = ST_R1;
  504.             return 0x7F;
  505.                 case ST_RD_ARG:
  506.                 case ST_RD_CRC:
  507.             return 0;
  508.         }
  509.     break;
  510.  
  511.     case CMD_READ_SINGLE_BLOCK:
  512.         switch(CurrState)
  513.         {
  514. //0.39.0
  515. //        case ST_R1: // ╬ЄтхЄ эр ъюьрэфє (ърЁЄр->їюёЄ)
  516. //            CurrState = ST_WR_DATA_SIG;
  517. //            return 0;
  518. //        case ST_WR_DATA_SIG: // ╥юъхэ фрээ√ї (ърЁЄр->їюёЄ)
  519. //            DataCnt = 0;
  520. //            CurrState = ST_WR_DATA;
  521. //            return 0xFE;
  522. //        case ST_WR_DATA: // ╧хЁхфрўр фрээ√ї (ърЁЄр->їюёЄ)
  523. //        {
  524. //            u8 Val = Buf[DataCnt++];
  525. //            if(DataCnt == DataBlockLen)
  526. //            {
  527. //                DataCnt = 0;
  528. //                CurrState = ST_WR_CRC16_1;
  529. //            }
  530. //            return Val;
  531. //        }
  532. //        case ST_WR_CRC16_1: // ╧хЁхфрўр crc16 (ърЁЄр->їюёЄ)
  533. //            CurrState = ST_WR_CRC16_2;
  534. //            return 0xFF;
  535. //        case ST_WR_CRC16_2: // ╧хЁхфрўр crc16 (ърЁЄр->їюёЄ)
  536. //            CurrState = ST_IDLE;
  537. //            Cmd = CMD_INVALID;
  538. //            return 0xFF;
  539.            
  540.  
  541.           unsigned int cpu_dt;
  542.  
  543.           case ST_R1:
  544.               CurrState = ST_DELAY_S;
  545.               InitialCPUt = cpu.t;
  546.               return 0;
  547.  
  548.           case ST_DELAY_S:
  549.               cpu_dt = cpu.t - InitialCPUt;
  550.               if (cpu_dt < 0)
  551.                 cpu_dt += conf.frame;
  552.               if (cpu_dt >= conf.sd_delay)
  553.                 CurrState = ST_STARTBLOCK;
  554.               return 0xFF;
  555.  
  556.           case ST_STARTBLOCK:
  557.               CurrState = ST_WR_DATA;
  558.               DataCnt = 0;
  559.               return 0xFE;
  560.  
  561.           case ST_WR_DATA:
  562.           {
  563.               u8 Val = Buf[DataCnt++];
  564.               if (DataCnt == DataBlockLen)
  565.               {
  566.                 DataCnt = 0;
  567.                 CurrState = ST_WR_CRC16_1;
  568.               }
  569.               return Val;
  570.           }
  571.  
  572.           case ST_WR_CRC16_1:
  573.               CurrState = ST_WR_CRC16_2;
  574.               return 0xFF; // crc
  575.           case ST_WR_CRC16_2:
  576.               CurrState = ST_IDLE;
  577.               Cmd = CMD_INVALID;
  578.               return 0xFF; // crc
  579.         }
  580. //        Cmd = CMD_INVALID;
  581.     break;
  582.  
  583.     case CMD_READ_MULTIPLE_BLOCK:
  584.         switch(CurrState)
  585.         {
  586.  
  587. //0.39.0
  588. //        case ST_R1: // ╬ЄтхЄ эр ъюьрэфє (ърЁЄр->їюёЄ)
  589. //            CurrState = ST_WR_DATA_SIG;
  590. //            return 0;
  591. //        case ST_WR_DATA_SIG: // ╥юъхэ фрээ√ї (ърЁЄр->їюёЄ)
  592. //            DataCnt = 0;
  593. //            CurrState = ST_IDLE;
  594. //            return 0xFE;
  595. //        case ST_IDLE: // ╧хЁхфрўр фрээ√ї (ърЁЄр->їюёЄ), яЁхЁ√трхЄё  ъюьрэфющ CMD_STOP_TRANSMISSION
  596. //        {
  597. //            u8 Val = Buf[DataCnt++];
  598. //            if(DataCnt == DataBlockLen)
  599. //            {
  600. //                DataCnt = 0;
  601. //                fread(Buf, 512, 1, Image);
  602. //                CurrState = ST_WR_CRC16_1;
  603. //            }
  604. //            return Val;
  605. //        }
  606. //        case ST_WR_CRC16_1: // ╧хЁхфрўр crc16 (ърЁЄр->їюёЄ)
  607. //            CurrState = ST_WR_CRC16_2;
  608. //            return 0xFF;
  609. //        case ST_WR_CRC16_2: // ╧хЁхфрўр crc16 (ърЁЄр->їюёЄ)
  610. //            CurrState = ST_WR_DATA_SIG;
  611. //            return 0xFF;
  612.  
  613. //NEDOREPO
  614.           unsigned int cpu_dt;
  615.  
  616.           case ST_R1:
  617.               CurrState = ST_DELAY_S;
  618.               InitialCPUt = cpu.t;
  619.               return 0;
  620.  
  621.           case ST_DELAY_S:
  622.               cpu_dt = cpu.t - InitialCPUt;
  623.               if (cpu_dt < 0)
  624.                 cpu_dt += conf.frame;
  625.               if (cpu_dt >= conf.sd_delay)
  626.                 CurrState = ST_STARTBLOCK;
  627.               return 0xFF;
  628.  
  629.           case ST_STARTBLOCK:
  630.               CurrState = ST_IDLE;
  631.               DataCnt = 0;
  632.               return 0xFE;
  633.  
  634.           case ST_IDLE:
  635.           {
  636.               if (DataCnt<DataBlockLen)
  637.               {
  638.                 u8 Val = Buf[DataCnt++];
  639.                 if (DataCnt == DataBlockLen)
  640.                     fread(Buf, DataBlockLen, 1, Image);
  641.                 return Val;
  642.               }
  643.               else if (DataCnt>(DataBlockLen+8))
  644.               {
  645.                 DataCnt=0;
  646.                 return 0xFE; // next startblock
  647.               }
  648.               else
  649.               {
  650.                 DataCnt++;
  651.                 return 0xFF; // crc & pause
  652.               }
  653.           }
  654.  
  655.  
  656. /*
  657.         case ST_R1:
  658.             CurrState = ST_WR_DATA_SIG;
  659.             return 0;
  660.         case ST_WR_DATA_SIG:
  661.             CurrState = ST_IDLE;
  662.             DataCnt = 0;
  663.             return 0xFE;
  664.         case ST_IDLE:
  665.         {
  666.             u8 Val = Buf[DataCnt++];
  667.             if (DataCnt == DataBlockLen)
  668.             {
  669.                 DataCnt = 0;
  670.                 fread(Buf, DataBlockLen, 1, Image);
  671.                 CurrState = ST_WR_CRC16_1;
  672.             }
  673.             return Val;
  674.         }
  675.         case ST_WR_CRC16_1:
  676.             CurrState = ST_WR_CRC16_2;
  677.             return 0xFF;
  678.         case ST_WR_CRC16_2:
  679.             CurrState = ST_WR_DATA_SIG;
  680.             return 0xFF;
  681. */
  682.            
  683.         }
  684.     break;
  685.  
  686.     case CMD_SEND_CSD:
  687.         switch(CurrState)
  688.         {
  689.         case ST_R1:
  690.         //    CurrState = ST_WR_DATA_SIG;       //0.39.0
  691.             CurrState = ST_DELAY_S;             //NEDOREPO
  692.             return 0;
  693.  
  694. //        case ST_WR_DATA_SIG:          //═┼╥ ┬ NEDOREPO
  695. //            CurrState = ST_WR_DATA;
  696. //            return 0xFE;
  697.  
  698.         case ST_DELAY_S:                //NEDOREPO
  699.             CurrState = ST_STARTBLOCK;
  700.             return 0xFF;
  701.         case ST_STARTBLOCK:             //NEDOREPO
  702.             CurrState = ST_WR_DATA;
  703.             return 0xFE;
  704.            
  705.         case ST_WR_DATA:
  706.         {
  707.             u8 Val = Csd[CsdCnt++];
  708.             if (CsdCnt == 16)
  709.             {
  710.                 CsdCnt = 0;
  711.                 CurrState = ST_IDLE;
  712.                 Cmd = CMD_INVALID;
  713.             }
  714.             return Val;
  715.         }
  716.         }
  717. //        Cmd = CMD_INVALID;
  718.     break;
  719.  
  720.     case CMD_SEND_CID:
  721.         switch(CurrState)
  722.         {
  723.         case ST_R1:
  724.             //CurrState = ST_WR_DATA_SIG;       //0.39.0
  725.             //return 0x00;
  726.             CurrState = ST_DELAY_S;             //NEDOREPO
  727.             return 0;
  728. //       case ST_WR_DATA_SIG:                   //═┼╥ ┬ NEDOREPO
  729. //           CurrState = ST_WR_DATA;
  730. //           return 0xFE;
  731.  
  732.         case ST_DELAY_S:
  733.             CurrState = ST_STARTBLOCK;  //NEDOREPO
  734.             return 0xFF;
  735.         case ST_STARTBLOCK:
  736.             CurrState = ST_WR_DATA;     //NEDOREPO
  737.             return 0xFE;
  738.            
  739.         case ST_WR_DATA:
  740.         {
  741.             u8 Val = Cid[CidCnt++];
  742.             if (CidCnt == 16)
  743.             {
  744.                 CidCnt = 0;
  745.                 CurrState = ST_IDLE;
  746.                 Cmd = CMD_INVALID;
  747.             }
  748.             return Val;
  749.         }
  750.         }
  751. //        Cmd = CMD_INVALID;
  752.     break;
  753.  
  754.     case CMD_WRITE_BLOCK:
  755. //        printf(__FUNCTION__" cmd=0x%X, St=0x%X\n", Cmd, CurrState);
  756.         switch(CurrState)
  757.         {
  758.         case ST_R1:
  759.             CurrState = ST_RD_DATA_SIG;
  760.             return 0x00;        //NEDOREPO
  761.             //return 0;         0.39.0
  762.  
  763.         case ST_WR_DATA_RESP:
  764.         {
  765.             CurrState = ST_IDLE;
  766.             u8 Resp = ((STAT_DATA_ACCEPTED) << 1) | 1;
  767.             return Resp;
  768.         }
  769.         }
  770.     break;
  771.  
  772.     case CMD_WRITE_MULTIPLE_BLOCK:
  773.         switch(CurrState)
  774.         {
  775.         case ST_R1:
  776.             CurrState = ST_RD_DATA_SIG_MUL;
  777.             return 0x00;    // !!! check this !!!
  778.             //return 0;         0.39.0
  779.         case ST_WR_DATA_RESP:
  780.         {
  781.             CurrState = ST_RD_DATA_SIG_MUL;
  782.             u8 Resp = ((STAT_DATA_ACCEPTED) << 1) | 1;
  783.             return Resp;
  784.         }
  785.         }
  786.     break;
  787.  
  788. //0.39.0
  789. //    default:
  790. //        if(!((CurrState == ST_IDLE) && (Cmd == CMD_INVALID)))
  791. //        {
  792. //            printf("%s Unknown CMD = 0x%X\n", __FUNCTION__, Cmd);
  793. //        }
  794. //
  795. //        if(Cmd != CMD_INVALID)
  796. //        {
  797. //            return 4; // illegal command
  798. //        }
  799. //    }
  800. //
  801. //    if(CurrState == ST_R3)
  802. //    {
  803. //        u8 Val = OcrArr[3 - OcrCnt++];
  804. //
  805. //        if(OcrCnt == 4)
  806. //        {
  807. //            CurrState = ST_IDLE;
  808. //            OcrCnt = 0;
  809. //        }
  810. //        return Val;
  811. //    }
  812.         }
  813.  
  814.     if (CurrState == ST_R1) // CMD_INVALID
  815.     {
  816.         CurrState = ST_IDLE;
  817.         return 0x05;
  818.     }
  819.    
  820.     return 0xFF;
  821. }
  822.  
  823. TSdCard::TState TSdCard::GetRespondType()
  824. {
  825.     if(!AppCmd)
  826.     {
  827.         switch(Cmd)
  828.         {
  829.         case CMD_APP_CMD:
  830.             AppCmd = true;
  831.                 return ST_R1;   //NEDOREPO
  832.         case CMD_GO_IDLE_STATE:
  833.         case CMD_SEND_OP_COND:
  834.         case CMD_SET_BLOCKLEN:
  835.         case CMD_READ_SINGLE_BLOCK:
  836.         case CMD_READ_MULTIPLE_BLOCK:
  837.         case CMD_CRC_ON_OFF:
  838.       //  case CMD_STOP_TRANSMISSION:   //NEDOREPO
  839.         case CMD_SEND_CSD:
  840.         case CMD_SEND_CID:
  841.     //    case CMD_WRITE_BLOCK:
  842.     //    case CMD_WRITE_MULTIPLE_BLOCK:
  843.             return ST_R1;
  844.         case CMD_READ_OCR:
  845.                 return ST_R3;           //NEDOREPO
  846.                 //  return ST_R1; // R3 //0.39.0
  847.         case CMD_SEND_IF_COND:
  848.             return ST_R7;
  849.            
  850.         case CMD_STOP_TRANSMISSION:
  851.             return ST_R1b;
  852.  
  853.         case CMD_WRITE_BLOCK:
  854.         case CMD_WRITE_MULTIPLE_BLOCK:
  855.             return ST_R1;
  856.            
  857. //        default:
  858. //            printf("%s Unknown CMD = 0x%X\n", __FUNCTION__, Cmd);
  859. //            return ST_R1;
  860.         }
  861.     }
  862.     else
  863.     {
  864.         AppCmd = false;
  865.         switch(Cmd)
  866.         {
  867. //            case CMD_SET_WR_BLK_ERASE_COUNT:  NEDOREPO
  868.             case CMD_SD_SEND_OP_COND:
  869. //                AppCmd = false;               NEDOREPO
  870.                 return ST_R1;
  871. //            default:
  872. //                printf("%s Unknown ACMD = 0x%X\n", __FUNCTION__, Cmd);
  873.         }
  874.     }
  875.  
  876.     Cmd = CMD_INVALID;  //NEDOREPO
  877.     return ST_R1;
  878.     //return ST_IDLE;   //╟└╩╬╠┼═╫┼═╬ ┬ NEDOREPO
  879. }
  880.  
  881. void TSdCard::Open(const char *Name)
  882. {
  883. //    printf(__FUNCTION__"\n");
  884.     assert(!Image);
  885.     Image = fopen(Name, "r+b");
  886.     if(!Image)
  887.     {
  888.         if(Name[0])
  889.         {
  890.             errmsg("can't find SD card image `%s'", Name);
  891.         }
  892.         return;
  893.     }
  894.     ImageSize = u32(_filelengthi64(fileno(Image)) / (512 * 1024)) - 1;
  895.     UpdateCsdImageSize();
  896. }
  897.  
  898. void TSdCard::Close()
  899. {
  900.     if(Image)
  901.     {
  902.         fclose(Image);
  903.         Image = 0;              //NEDOREPO
  904.         //Image = nullptr;      0.39.0
  905.     }
  906. }
  907.  
  908. TSdCard SdCard;
  909.