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