diskio.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. #include "integer.h"
  2. #include "diskio.h"
  3. static volatile
  4. DSTATUS Stat = STA_NOINIT; /* Disk status */
  5. /* Interface
  6. ** Scratch Buffer
  7. addr 3 byte
  8. size 1 byte
  9. ** Call Interface
  10. cmd 1 byte
  11. sector 4 bytes
  12. count 1 byte
  13. return 1 byte
  14. ** Commands
  15. * disk_init
  16. * disk_read
  17. * disk_write
  18. */
  19. /*-----------------------------------------------------------------------*/
  20. /* Initialize Disk Drive */
  21. /*-----------------------------------------------------------------------*/
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <sys/types.h>
  25. #include <sys/stat.h>
  26. #include <unistd.h>
  27. #include <fcntl.h>
  28. #include <sys/mman.h>
  29. #include <string.h>
  30. #define IMAGE_NAME "disk00.vfat"
  31. BYTE *image_addr;
  32. DSTATUS disk_initialize (BYTE drv) {
  33. if (drv) return STA_NOINIT; /* Supports only single drive */
  34. Stat |= STA_NOINIT;
  35. int fd = open(IMAGE_NAME, O_RDWR);
  36. if (fd == -1) {
  37. perror("DISKIO::disk_initialize: Error opening file for writing");
  38. exit(EXIT_FAILURE);
  39. }
  40. int size = lseek(fd,0,SEEK_END);
  41. lseek(fd,0,SEEK_SET);
  42. image_addr = (BYTE*)mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
  43. printf("DISKIO::disk_initialize: Open Image (size %i) %p\n",size,image_addr);
  44. if (image_addr == MAP_FAILED) {
  45. close(fd);
  46. perror("DISKIO::disk_initialize: Error mmapping the file");
  47. exit(EXIT_FAILURE);
  48. }
  49. Stat &= ~STA_NOINIT; /* When device goes ready, clear STA_NOINIT */
  50. return Stat;
  51. }
  52. /*-----------------------------------------------------------------------*/
  53. /* Return Disk Status */
  54. /*-----------------------------------------------------------------------*/
  55. DSTATUS disk_status (BYTE drv){
  56. if (drv) return STA_NOINIT; /* Supports only single drive */
  57. return Stat;
  58. }
  59. /*-----------------------------------------------------------------------*/
  60. /* Read Sector(s) */
  61. /*-----------------------------------------------------------------------*/
  62. DRESULT disk_read (
  63. BYTE drv, /* Physical drive nmuber (0) */
  64. BYTE *buff, /* Data buffer to store read data */
  65. DWORD sector, /* Sector number (LBA) */
  66. BYTE count /* Sector count (1..255) */
  67. )
  68. {
  69. BYTE c, iord_l, iord_h;
  70. if (drv || !count) return RES_PARERR;
  71. if (Stat & STA_NOINIT) return RES_NOTRDY;
  72. DWORD offset = sector * 512;
  73. int size = count * 512;
  74. printf("DISKIO::disk_read: sector=%li count=%i addr=%p off=%li size=%i\n",sector,count,image_addr + offset,offset,size);
  75. memcpy(buff,image_addr + offset,size);
  76. printf("DISKIO::disk_read: done\n");
  77. return RES_OK;
  78. }
  79. /*-----------------------------------------------------------------------*/
  80. /* Write Sector(s) */
  81. /*-----------------------------------------------------------------------*/
  82. #if _READONLY == 0
  83. DRESULT disk_write (
  84. BYTE drv, /* Physical drive nmuber (0) */
  85. const BYTE *buff, /* Data to be written */
  86. DWORD sector, /* Sector number (LBA) */
  87. BYTE count /* Sector count (1..255) */
  88. )
  89. {
  90. if (drv || !count) return RES_PARERR;
  91. if (Stat & STA_NOINIT) return RES_NOTRDY;
  92. DWORD offset = sector * 512;
  93. int size = count * 512;
  94. printf("disk_write: sector=%li count=%i addr=%p off=%li size=%i\n",sector,count,image_addr + offset,offset,size);
  95. memcpy(image_addr + offset,buff,size);
  96. return RES_OK;
  97. }
  98. #endif /* _READONLY */
  99. /*-----------------------------------------------------------------------*/
  100. /* Miscellaneous Functions */
  101. /*-----------------------------------------------------------------------*/
  102. #if _USE_IOCTL != 0
  103. DRESULT disk_ioctl (
  104. BYTE drv, /* Physical drive nmuber (0) */
  105. BYTE ctrl, /* Control code */
  106. void *buff /* Buffer to send/receive data block */
  107. )
  108. {
  109. BYTE n, w, ofs, dl, dh, *ptr = (BYTE*)buff;
  110. if (drv) return RES_PARERR;
  111. if (Stat & STA_NOINIT) return RES_NOTRDY;
  112. switch (ctrl) {
  113. case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */
  114. printf("disk_ioctl: GET_SECTOR_COUNT\n");
  115. ofs = 60; w = 2; n = 0;
  116. break;
  117. case GET_SECTOR_SIZE : /* Get sectors on the disk (WORD) */
  118. printf("disk_ioctl: GET_SECTOR_SIZE\n");
  119. *(WORD*)buff = 512;
  120. return RES_OK;
  121. case GET_BLOCK_SIZE : /* Get erase block size in sectors (DWORD) */
  122. printf("disk_ioctl: GET_BLOCK_SIZE\n");
  123. *(DWORD*)buff = 32;
  124. return RES_OK;
  125. default:
  126. return RES_PARERR;
  127. }
  128. return RES_OK;
  129. }
  130. #endif /* _USE_IOCTL != 0 */