DimkaM

NEMO and ATM HDD driver

Aug 5th, 2021
614
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. DSTATUS disks_stat[4]={STA_NOINIT, STA_NOINIT, STA_NOINIT, STA_NOINIT};
  2.  
  3.  
  4. extern unsigned char fbufer[512];
  5. #define tmpbuf fbufer
  6.  
  7. #define IDE_MASTER 0xe0
  8. #define IDE_SLAVE 0xf0
  9.  
  10. #define NEMO_DATA   0x10
  11. #define NEMO_COUNT  0x50
  12. #define NEMO_LBA0   0x70
  13. #define NEMO_LBA1   0x90
  14. #define NEMO_LBA2   0xB0
  15. #define NEMO_LBA3   0xD0
  16. #define NEMO_MS     0xD0
  17. #define NEMO_CMD    0xF0
  18. #define NEMO_STAT   0xF0
  19.  
  20. #define ATM_DATA_LOW    0x000f
  21. #define ATM_DATA_HI     0x010f
  22. #define ATM_COUNT   0x004f
  23. #define ATM_LBA0    0x006f
  24. #define ATM_LBA1    0x008f
  25. #define ATM_LBA2    0x00af
  26. #define ATM_LBA3    0x00cf
  27. #define ATM_MS      0x00cf
  28. #define ATM_CMD     0x00ef
  29. #define ATM_STAT    0x00ef
  30.  
  31. #define ATA_STAT_ERR    0x01
  32. #define ATA_STAT_IDX    0x02
  33. #define ATA_STAT_CORR   0x04
  34. #define ATA_STAT_DRQ    0x08
  35. #define ATA_STAT_DSC    0x10
  36. #define ATA_STAT_DWF    0x20
  37. #define ATA_STAT_DRDY   0x40
  38. #define ATA_STAT_BSY    0x80
  39.  
  40. #define ATA_CMD_READ_SECTORS 0x20
  41. #define ATA_CMD_WRITE_SECTORS 0x30
  42. #define ATA_CMD_INIT_DRIVE_PARAM 0x91
  43. #define ATA_CMD_IDENTIFY_DRIVE 0xec
  44. /*-----------------------------------------------------------------------*/
  45. /* Get Drive Status                                                      */
  46. /*-----------------------------------------------------------------------*/
  47.  
  48. DSTATUS disk_status (
  49.     BYTE pdrv       /* Physical drive nmuber to identify the drive */
  50. )
  51. {
  52.     return disks_stat[pdrv];
  53. }
  54.  
  55.  
  56.  
  57. /*-----------------------------------------------------------------------*/
  58. /* Inidialize a Drive                                                    */
  59. /*-----------------------------------------------------------------------*/
  60.  
  61. DSTATUS disk_initialize (
  62.     BYTE pdrv               /* Physical drive nmuber to identify the drive */
  63. )
  64. {
  65.     unsigned int i = 26;
  66.     unsigned char d;
  67.    
  68.     if(disks_stat[pdrv] == RES_OK) return RES_OK;
  69.    
  70.     if(DEV_NEMO_M == (pdrv & 0xfe)){
  71.         output8(NEMO_MS, (pdrv & 0x01) ? IDE_SLAVE : IDE_MASTER);
  72.         while(--i){
  73.             halt();
  74.             d=input8(NEMO_STAT);
  75.             if((d & ATA_STAT_BSY) == 0x00) break;
  76.         }
  77.         if(i == 0x00) return STA_NODISK;
  78.         if(d == 0x00) return STA_NODISK;
  79.         //if(d == 0xff) return STA_NODISK;
  80.         output8(NEMO_LBA2, 0x00);
  81.         output8(NEMO_LBA1, 0x00);
  82.         output8(NEMO_CMD, ATA_CMD_IDENTIFY_DRIVE);
  83.         while(1){
  84.             d = input8(NEMO_STAT);
  85.             if(d == 0x00 || d == 0xff) return STA_NODISK;
  86.             if(d & ATA_STAT_ERR) break;
  87.             if((d  & (ATA_STAT_BSY | ATA_STAT_DRQ)) == ATA_STAT_DRQ) break;
  88.         }
  89.         if(input8(NEMO_LBA2) | input8(NEMO_LBA1)) return STA_NODISK; //is CD-ROM
  90.         input_block_inc(NEMO_DATA, tmpbuf, 256);
  91.         input_block_inc(NEMO_DATA, tmpbuf+256, 256);
  92.         if((tmpbuf[49*2+1] & 0x02) == 0x00) return STA_NODISK; //no LBA
  93.         //                  \/Number of sectors per track
  94.         output8(NEMO_COUNT,tmpbuf[12]);
  95.         d = (tmpbuf[6] - 1) | IDE_MASTER;
  96.         if(pdrv & 0x01) d |= DEV_MS_BIT;
  97.         output8(NEMO_MS,tmpbuf[6]);
  98.         output8(NEMO_CMD, ATA_CMD_INIT_DRIVE_PARAM);
  99.         i = 1000;
  100.         while(--i){
  101.             if(input8(NEMO_STAT) & ATA_STAT_BSY) continue;
  102.             disks_stat[pdrv] = RES_OK;
  103.             break;
  104.         }  
  105.     }else if(DEV_ATM_M == (pdrv & 0xfe)){
  106.         output(ATM_MS, (pdrv & 0x01) ? IDE_SLAVE : IDE_MASTER);
  107.         while(--i){
  108.             halt();
  109.             d=input(ATM_STAT);
  110.             if((d & ATA_STAT_BSY) == 0x00) break;
  111.         }
  112.         if(i == 0x00) return STA_NODISK;
  113.         if(d == 0x00) return STA_NODISK;
  114.         //if(d == 0xff) return STA_NODISK;
  115.         output(ATM_LBA2, 0x00);
  116.         output(ATM_LBA1, 0x00);
  117.         output(ATM_CMD, ATA_CMD_IDENTIFY_DRIVE);
  118.         while(1){
  119.             d = input(ATM_STAT);
  120.             if(d == 0x00 || d == 0xff) return STA_NODISK;
  121.             if(d & ATA_STAT_ERR) break;
  122.             if((d  & (ATA_STAT_BSY | ATA_STAT_DRQ)) == ATA_STAT_DRQ) break;
  123.         }
  124.         if(input(ATM_LBA2) | input(ATM_LBA1)) return STA_NODISK; //is CD-ROM
  125.         input_block_inc(ATM_DATA_LOW, tmpbuf, 256);
  126.         input_block_inc(ATM_DATA_LOW, tmpbuf+256, 256);
  127.         if((tmpbuf[49*2+1] & 0x02) == 0x00) return STA_NODISK; //no LBA
  128.         //                  \/Number of sectors per track
  129.         output(ATM_COUNT,tmpbuf[12]);
  130.         d = (tmpbuf[6] - 1) | IDE_MASTER;
  131.         if(pdrv & 0x01) d |= DEV_MS_BIT;
  132.         output(ATM_MS,tmpbuf[6]);
  133.         output(ATM_CMD, ATA_CMD_INIT_DRIVE_PARAM);
  134.         i = 1000;
  135.         while(--i){
  136.             if(input(ATM_STAT) & ATA_STAT_BSY) continue;
  137.             disks_stat[pdrv] = RES_OK;
  138.             break;
  139.         }  
  140.     }
  141.     return disks_stat[pdrv];
  142. }
  143.  
  144.  
  145.  
  146. /*-----------------------------------------------------------------------*/
  147. /* Read Sector(s)                                                        */
  148. /*-----------------------------------------------------------------------*/
  149.  
  150. DRESULT disk_read (
  151.     BYTE pdrv,      /* Physical drive nmuber to identify the drive */
  152.     BYTE *buff,     /* Data buffer to store read data */
  153.     DWORD sector,   /* Start sector in LBA */
  154.     UINT count      /* Number of sectors to read */
  155. )
  156. {
  157.     unsigned char c = count;
  158.     if(DEV_NEMO_M == (pdrv & 0xfe)){
  159.         if(pdrv & 0x01)
  160.             output8(NEMO_LBA3,((unsigned char*)&sector)[3] | IDE_SLAVE);
  161.         else
  162.             output8(NEMO_LBA3,((unsigned char*)&sector)[3] | IDE_MASTER);
  163.         while((input8(NEMO_STAT) & ATA_STAT_BSY) != 0);
  164.         output8(NEMO_LBA2,((unsigned char*)&sector)[2]);
  165.         output8(NEMO_LBA1,((unsigned char*)&sector)[1]);
  166.         output8(NEMO_LBA0,((unsigned char*)&sector)[0]);
  167.         output8(NEMO_COUNT,c);
  168.         output8(NEMO_CMD, ATA_CMD_READ_SECTORS);
  169.         while((input8(NEMO_STAT) & (ATA_STAT_BSY | ATA_STAT_DRQ)) != 8);
  170.         while(c--){
  171.             //unsigned int i = 512;
  172.             input_block_inc(NEMO_DATA, buff, 256);
  173.             buff += 256;
  174.             input_block_inc(NEMO_DATA, buff, 256);
  175.             buff += 256;
  176.             //while(i--){
  177.             //  *buff = input8(NEMO_DATA);
  178.             //  buff++;
  179.             //}
  180.             while((input8(NEMO_STAT) & ATA_STAT_BSY) != 0);
  181.         }
  182.         return RES_OK;
  183.     }else if(DEV_ATM_M == (pdrv & 0xfe)){
  184.         if(pdrv & 0x01)
  185.             output(ATM_LBA3,((unsigned char*)&sector)[3] | IDE_SLAVE);
  186.         else
  187.             output(ATM_LBA3,((unsigned char*)&sector)[3] | IDE_MASTER);
  188.         while((input(ATM_STAT) & ATA_STAT_BSY) != 0);
  189.         output(ATM_LBA2,((unsigned char*)&sector)[2]);
  190.         output(ATM_LBA1,((unsigned char*)&sector)[1]);
  191.         output(ATM_LBA0,((unsigned char*)&sector)[0]);
  192.         output(ATM_COUNT,c);
  193.         output(ATM_CMD, ATA_CMD_READ_SECTORS);
  194.         while((input(ATM_STAT) & (ATA_STAT_BSY | ATA_STAT_DRQ)) != 8);
  195.         while(c--){
  196.             //unsigned int i = 512;
  197.             input_block_inc(ATM_DATA_LOW, buff, 256);
  198.             buff += 256;
  199.             input_block_inc(ATM_DATA_LOW, buff, 256);
  200.             buff += 256;
  201.             //while(i--){
  202.             //  *buff = input8(NEMO_DATA);
  203.             //  buff++;
  204.             //}
  205.             while((input(ATM_STAT) & ATA_STAT_BSY) != 0);
  206.         }
  207.         return RES_OK;
  208.     }
  209.  
  210.     return RES_PARERR;
  211. }
  212.  
  213.  
  214.  
  215. /*-----------------------------------------------------------------------*/
  216. /* Write Sector(s)                                                       */
  217. /*-----------------------------------------------------------------------*/
  218.  
  219. #if _FS_READONLY == 0
  220.  
  221. DRESULT disk_write (
  222.     BYTE pdrv,          /* Physical drive nmuber to identify the drive */
  223.     const BYTE *buff,   /* Data to be written */
  224.     DWORD sector,       /* Start sector in LBA */
  225.     UINT count          /* Number of sectors to write */
  226. )
  227. {
  228.     unsigned char c = count;
  229.     if(DEV_NEMO_M == (pdrv & 0xfe)){
  230.         if(pdrv & 0x01)
  231.             output8(NEMO_LBA3,((unsigned char*)&sector)[3] | IDE_SLAVE);
  232.         else
  233.             output8(NEMO_LBA3,((unsigned char*)&sector)[3] | IDE_MASTER);
  234.         while((input8(NEMO_STAT) & ATA_STAT_BSY) != 0);
  235.         output8(NEMO_LBA2,((unsigned char*)&sector)[2]);
  236.         output8(NEMO_LBA1,((unsigned char*)&sector)[1]);
  237.         output8(NEMO_LBA0,((unsigned char*)&sector)[0]);
  238.         output8(NEMO_COUNT,c);
  239.         output8(NEMO_CMD, ATA_CMD_WRITE_SECTORS);
  240.         while((input8(NEMO_STAT) & (ATA_STAT_BSY | ATA_STAT_DRQ)) != 8);
  241.         while(c--){
  242.             output_block_inc(NEMO_DATA, (void*)buff, 256);
  243.             buff += 256;
  244.             output_block_inc(NEMO_DATA, (void*)buff, 256);
  245.             buff += 256;
  246.             /*
  247.             unsigned int i = 512;
  248.             while(i--){
  249.                 output8(NEMO_DATA,*buff);
  250.                 buff++;
  251.             }
  252.             */
  253.             while((input8(NEMO_STAT) & ATA_STAT_BSY) != 0);
  254.         }
  255.         return RES_OK;
  256.     }else if(DEV_ATM_M == (pdrv & 0xfe)){
  257.         if(pdrv & 0x01)
  258.             output(ATM_LBA3,((unsigned char*)&sector)[3] | IDE_SLAVE);
  259.         else
  260.             output(ATM_LBA3,((unsigned char*)&sector)[3] | IDE_MASTER);
  261.         while((input(ATM_STAT) & ATA_STAT_BSY) != 0);
  262.         output(ATM_LBA2,((unsigned char*)&sector)[2]);
  263.         output(ATM_LBA1,((unsigned char*)&sector)[1]);
  264.         output(ATM_LBA0,((unsigned char*)&sector)[0]);
  265.         output(ATM_COUNT,c);
  266.         output(ATM_CMD, ATA_CMD_WRITE_SECTORS);
  267.         while((input(ATM_STAT) & (ATA_STAT_BSY | ATA_STAT_DRQ)) != 8);
  268.         while(c--){
  269.             BYTE * i = (BYTE *)buff + 512;
  270.             while(buff != i){
  271.                 output(ATM_DATA_HI, buff[1]);
  272.                 output(ATM_DATA_LOW, buff[0]);
  273.                 buff += 2;
  274.             }
  275.             while((input(ATM_STAT) & ATA_STAT_BSY) != 0);
  276.         }
  277.         return RES_OK;
  278.     }
  279.  
  280.     return RES_PARERR;
  281. }
  282.  
  283. #endif
  284.  
  285.  
  286. /*-----------------------------------------------------------------------*/
  287. /* Miscellaneous Functions                                               */
  288. /*-----------------------------------------------------------------------*/
  289.  
  290. DRESULT disk_ioctl (
  291.     BYTE pdrv,      /* Physical drive nmuber (0..) */
  292.     BYTE cmd,       /* Control code */
  293.     void *buff      /* Buffer to send/receive control data */
  294. )
  295. {
  296.     if((pdrv == DEV_NEMO_M) && (cmd == GET_SECTOR_COUNT)){
  297.         if(pdrv == DEV_NEMO_M){
  298.             output8(NEMO_LBA3,0xe0);
  299.             output8(NEMO_CMD, ATA_CMD_IDENTIFY_DRIVE);
  300.             while((input8(NEMO_STAT) & (ATA_STAT_BSY | ATA_STAT_DRQ)) != 8);
  301.            
  302.             input_block_inc(NEMO_DATA, tmpbuf, 256);
  303.             input_block_inc(NEMO_DATA, tmpbuf+256, 256);
  304.             while((input8(NEMO_STAT) & ATA_STAT_BSY) != 0);
  305.             *((unsigned long*)buff)=*((unsigned long*)(tmpbuf+120));
  306.             return RES_OK;
  307.         }else if(pdrv == DEV_ATM_M){
  308.             BYTE * i = (BYTE *)tmpbuf;
  309.             output(ATM_LBA3,0xe0);
  310.             output(ATM_CMD, ATA_CMD_IDENTIFY_DRIVE);
  311.             while((input(ATM_STAT) & (ATA_STAT_BSY | ATA_STAT_DRQ)) != 8);
  312.             {
  313.                 while((tmpbuf+512) != i){
  314.                     output(ATM_DATA_HI, i[1]);
  315.                     output(ATM_DATA_LOW, i[0]);
  316.                     i += 2;
  317.                 }
  318.             }
  319.             while((input(ATM_STAT) & ATA_STAT_BSY) != 0);
  320.             *((unsigned long*)buff)=*((unsigned long*)(i+120));
  321.             return RES_OK;
  322.         }
  323.         return RES_PARERR;
  324.     }else if(CTRL_SYNC == cmd){
  325.         return RES_OK;
  326.     }
  327.  
  328.     return RES_PARERR;
  329. }
  330.  
  331.  
RAW Paste Data