diskio_emul.c
Go to the documentation of this file.00001
00038
00039
00040
00041
00042 #include <fs/fatfs/diskio.h>
00043 #include <stdio.h>
00044 #include <errno.h>
00045 #include <time.h>
00046
00047 #define SECTOR_SIZE 512
00048
00049 static volatile DSTATUS Stat = STA_NOINIT;
00050
00057
00058
00059
00060 static FILE *fake_disk = 0;
00061
00062 DSTATUS disk_initialize (
00063 BYTE drv
00064 )
00065 {
00066 if (drv)
00067 return STA_NOINIT;
00068
00069
00070
00071
00072 if (fake_disk)
00073 return Stat;
00074
00075 const char *path = "emuldisk.dsk";
00076 fake_disk = fopen(path, "w+");
00077 int err = errno;
00078 if (!fake_disk)
00079 {
00080 switch (err)
00081 {
00082 case EINVAL:
00083 fprintf(stderr, "invalid mode\n");
00084 default:
00085 return STA_NOINIT;
00086 }
00087 }
00088 Stat &= ~STA_NOINIT;
00089 return Stat;
00090 }
00091
00092
00093
00094
00095
00096
00097 DSTATUS disk_status (
00098 BYTE drv
00099 )
00100 {
00101 if (drv)
00102 return STA_NOINIT;
00103 return Stat;
00104 }
00105
00106
00107
00108
00109
00110
00111 DRESULT disk_read (
00112 BYTE drv,
00113 BYTE *buff,
00114 DWORD sector,
00115 BYTE count
00116 )
00117 {
00118 if (drv || !count) return RES_PARERR;
00119 if (Stat & STA_NOINIT) return RES_NOTRDY;
00120
00121 fseek(fake_disk, sector * SECTOR_SIZE, SEEK_SET);
00122 size_t read_items = fread(buff, SECTOR_SIZE, count, fake_disk);
00123 if (read_items == count)
00124 return RES_OK;
00125 else
00126 {
00127 if (feof(fake_disk))
00128 fprintf(stderr, "end-of-file\n");
00129 if (ferror(fake_disk))
00130 fprintf(stderr, "error\n");
00131 return RES_ERROR;
00132 }
00133 }
00134
00135
00136
00137
00138
00139 #if _READONLY == 0
00140 DRESULT disk_write (
00141 BYTE drv,
00142 const BYTE *buff,
00143 DWORD sector,
00144 BYTE count
00145 )
00146 {
00147 if (drv || !count) return RES_PARERR;
00148 if (Stat & STA_NOINIT) return RES_NOTRDY;
00149 if (Stat & STA_PROTECT) return RES_WRPRT;
00150
00151 fseek(fake_disk, sector * SECTOR_SIZE, SEEK_SET);
00152 size_t write_items = fwrite(buff, SECTOR_SIZE, count, fake_disk);
00153 if (write_items == count)
00154 return RES_OK;
00155 else
00156 {
00157 if (feof(fake_disk))
00158 fprintf(stderr, "end-of-file\n");
00159 if (ferror(fake_disk))
00160 fprintf(stderr, "error\n");
00161 return RES_ERROR;
00162 }
00163 }
00164 #endif
00165
00166
00167
00168
00169
00170
00171 DRESULT disk_ioctl (
00172 BYTE drv,
00173 BYTE ctrl,
00174 void *buff
00175 )
00176 {
00177 if (drv) return RES_PARERR;
00178 if (Stat & STA_NOINIT) return RES_NOTRDY;
00179
00180 switch (ctrl)
00181 {
00182 case GET_SECTOR_SIZE:
00183 *(WORD*)buff = SECTOR_SIZE;
00184 break;
00185 case GET_SECTOR_COUNT:
00186 *(DWORD*)buff = 65536;
00187 break;
00188 case GET_BLOCK_SIZE:
00189 *(DWORD*)buff = 1;
00190 break;
00191 case CTRL_SYNC:
00192 fflush(fake_disk);
00193 break;
00194 default:
00195 return RES_PARERR;
00196 }
00197 return RES_OK;
00198 }
00199
00200 DWORD get_fattime(void)
00201 {
00202 time_t tmp = time(0);
00203 struct tm *t = localtime(&tmp);
00204 DWORD tim = 0;
00205
00206 tim |= (t->tm_sec / 2);
00207
00208 tim |= (t->tm_min << 5);
00209
00210 tim |= (t->tm_hour << 11);
00211
00212 tim |= (t->tm_mday << 16);
00213
00214 tim |= ((t->tm_mon + 1) << 21);
00215
00216 tim |= ((t->tm_year - 80) << 25);
00217 return tim;
00218 }
00219