@@ -33,30 +33,21 @@ enum : u32
3333};
3434
3535static std::mutex s_fatfs_mutex;
36- static File::IOFile* s_image;
37- static bool s_deterministic;
36+ static Common::FatFsCallbacks* s_callbacks;
3837
39- extern " C" DSTATUS disk_status (BYTE pdrv)
40- {
41- return 0 ;
42- }
43-
44- extern " C" DSTATUS disk_initialize (BYTE pdrv)
38+ namespace
4539{
46- return 0 ;
47- }
48-
49- extern " C" DRESULT disk_read (BYTE pdrv, BYTE * buff, LBA_t sector, UINT count)
40+ int SDCardDiskRead (File::IOFile* image, u8 pdrv, u8 * buff, u32 sector, unsigned int count)
5041{
5142 const u64 offset = static_cast <u64 >(sector) * SECTOR_SIZE ;
52- if (!s_image ->Seek (offset, File::SeekOrigin::Begin))
43+ if (!image ->Seek (offset, File::SeekOrigin::Begin))
5344 {
5445 ERROR_LOG_FMT (COMMON , " SD image seek failed (offset={})" , offset);
5546 return RES_ERROR ;
5647 }
5748
5849 const size_t size = static_cast <size_t >(count) * SECTOR_SIZE ;
59- if (!s_image ->ReadBytes (buff, size))
50+ if (!image ->ReadBytes (buff, size))
6051 {
6152 ERROR_LOG_FMT (COMMON , " SD image read failed (offset={}, size={})" , offset, size);
6253 return RES_ERROR ;
@@ -65,17 +56,17 @@ extern "C" DRESULT disk_read(BYTE pdrv, BYTE* buff, LBA_t sector, UINT count)
6556 return RES_OK ;
6657}
6758
68- extern " C " DRESULT disk_write ( BYTE pdrv, const BYTE * buff, LBA_t sector, UINT count)
59+ int SDCardDiskWrite (File::IOFile* image, u8 pdrv, const u8 * buff, u32 sector, unsigned int count)
6960{
7061 const u64 offset = static_cast <u64 >(sector) * SECTOR_SIZE ;
71- if (!s_image ->Seek (offset, File::SeekOrigin::Begin))
62+ if (!image ->Seek (offset, File::SeekOrigin::Begin))
7263 {
7364 ERROR_LOG_FMT (COMMON , " SD image seek failed (offset={})" , offset);
7465 return RES_ERROR ;
7566 }
7667
7768 const size_t size = static_cast <size_t >(count) * SECTOR_SIZE ;
78- if (!s_image ->WriteBytes (buff, size))
69+ if (!image ->WriteBytes (buff, size))
7970 {
8071 ERROR_LOG_FMT (COMMON , " SD image write failed (offset={}, size={})" , offset, size);
8172 return RES_ERROR ;
@@ -84,26 +75,23 @@ extern "C" DRESULT disk_write(BYTE pdrv, const BYTE* buff, LBA_t sector, UINT co
8475 return RES_OK ;
8576}
8677
87- extern " C " DRESULT disk_ioctl ( BYTE pdrv, BYTE cmd, void * buff)
78+ int SDCardDiskIOCtl (File::IOFile* image, u8 pdrv, u8 cmd, void * buff)
8879{
8980 switch (cmd)
9081 {
9182 case CTRL_SYNC :
9283 return RES_OK ;
9384 case GET_SECTOR_COUNT :
94- *reinterpret_cast <LBA_t*>(buff) = s_image ->GetSize () / SECTOR_SIZE ;
85+ *reinterpret_cast <LBA_t*>(buff) = image ->GetSize () / SECTOR_SIZE ;
9586 return RES_OK ;
9687 default :
9788 WARN_LOG_FMT (COMMON , " Unexpected SD image ioctl {}" , cmd);
9889 return RES_OK ;
9990 }
10091}
10192
102- extern " C " DWORD get_fattime ( void )
93+ u32 GetSystemTimeFAT ( )
10394{
104- if (s_deterministic)
105- return 0 ;
106-
10795 const std::time_t time = std::time (nullptr );
10896 std::tm tm;
10997#ifdef _WIN32
@@ -121,6 +109,91 @@ extern "C" DWORD get_fattime(void)
121109 fattime |= std::min (tm.tm_sec , 59 ) >> 1 ;
122110 return fattime;
123111}
112+ } // namespace
113+
114+ namespace Common
115+ {
116+ FatFsCallbacks::FatFsCallbacks () = default ;
117+ FatFsCallbacks::~FatFsCallbacks () = default ;
118+
119+ u8 FatFsCallbacks::DiskInitialize (u8 pdrv)
120+ {
121+ return 0 ;
122+ }
123+
124+ u8 FatFsCallbacks::DiskStatus (u8 pdrv)
125+ {
126+ return 0 ;
127+ }
128+
129+ u32 FatFsCallbacks::GetCurrentTimeFAT ()
130+ {
131+ return GetSystemTimeFAT ();
132+ }
133+ } // namespace Common
134+
135+ namespace
136+ {
137+ class SDCardFatFsCallbacks : public Common ::FatFsCallbacks
138+ {
139+ public:
140+ int DiskRead (u8 pdrv, u8 * buff, u32 sector, unsigned int count) override
141+ {
142+ return SDCardDiskRead (m_image, pdrv, buff, sector, count);
143+ }
144+
145+ int DiskWrite (u8 pdrv, const u8 * buff, u32 sector, unsigned int count) override
146+ {
147+ return SDCardDiskWrite (m_image, pdrv, buff, sector, count);
148+ }
149+
150+ int DiskIOCtl (u8 pdrv, u8 cmd, void * buff) override
151+ {
152+ return SDCardDiskIOCtl (m_image, pdrv, cmd, buff);
153+ }
154+
155+ u32 GetCurrentTimeFAT () override
156+ {
157+ if (m_deterministic)
158+ return 0 ;
159+
160+ return GetSystemTimeFAT ();
161+ }
162+
163+ File::IOFile* m_image;
164+ bool m_deterministic;
165+ };
166+ } // namespace
167+
168+ extern " C" DSTATUS disk_status (BYTE pdrv)
169+ {
170+ return static_cast <DSTATUS >(s_callbacks->DiskStatus (pdrv));
171+ }
172+
173+ extern " C" DSTATUS disk_initialize (BYTE pdrv)
174+ {
175+ return static_cast <DSTATUS >(s_callbacks->DiskInitialize (pdrv));
176+ }
177+
178+ extern " C" DRESULT disk_read (BYTE pdrv, BYTE * buff, LBA_t sector, UINT count)
179+ {
180+ return static_cast <DRESULT >(s_callbacks->DiskRead (pdrv, buff, sector, count));
181+ }
182+
183+ extern " C" DRESULT disk_write (BYTE pdrv, const BYTE * buff, LBA_t sector, UINT count)
184+ {
185+ return static_cast <DRESULT >(s_callbacks->DiskWrite (pdrv, buff, sector, count));
186+ }
187+
188+ extern " C" DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void * buff)
189+ {
190+ return static_cast <DRESULT >(s_callbacks->DiskIOCtl (pdrv, cmd, buff));
191+ }
192+
193+ extern " C" DWORD get_fattime (void )
194+ {
195+ return static_cast <DWORD >(s_callbacks->GetCurrentTimeFAT ());
196+ }
124197
125198extern " C" void * ff_memalloc (UINT msize)
126199{
@@ -435,11 +508,13 @@ bool SyncSDFolderToSDImage(bool deterministic)
435508 size = AlignUp (size, MAX_CLUSTER_SIZE );
436509
437510 std::lock_guard lk (s_fatfs_mutex);
511+ SDCardFatFsCallbacks callbacks;
512+ s_callbacks = &callbacks;
513+ Common::ScopeGuard callbacks_guard{[] { s_callbacks = nullptr ; }};
438514
439515 File::IOFile image;
440- s_image = ℑ
441- Common::ScopeGuard image_guard{[] { s_image = nullptr ; }};
442- s_deterministic = deterministic;
516+ callbacks.m_image = ℑ
517+ callbacks.m_deterministic = deterministic;
443518
444519 const std::string temp_image_path = File::GetTempFilenameForAtomicWrite (image_path);
445520 if (!image.Open (temp_image_path, " w+b" ))
@@ -672,17 +747,19 @@ bool SyncSDImageToSDFolder()
672747 return false ;
673748
674749 std::lock_guard lk (s_fatfs_mutex);
750+ SDCardFatFsCallbacks callbacks;
751+ s_callbacks = &callbacks;
752+ Common::ScopeGuard callbacks_guard{[] { s_callbacks = nullptr ; }};
675753
676754 INFO_LOG_FMT (COMMON , " Starting SD card conversion from file {} to folder {}" , image_path,
677755 target_dir);
678756
679757 File::IOFile image;
680- s_image = ℑ
681- Common::ScopeGuard image_guard{[] { s_image = nullptr ; }};
758+ callbacks.m_image = ℑ
682759
683760 // this shouldn't matter since we're not modifying the SD image here, but initialize it to
684761 // something consistent just in case
685- s_deterministic = true ;
762+ callbacks. m_deterministic = true ;
686763
687764 if (!image.Open (image_path, " r+b" ))
688765 {
@@ -740,4 +817,12 @@ bool SyncSDImageToSDFolder()
740817 INFO_LOG_FMT (COMMON , " Successfully unpacked SD image {} to {}" , image_path, target_dir);
741818 return true ;
742819}
820+
821+ void RunInFatFsContext (FatFsCallbacks& callbacks, const std::function<void ()>& function)
822+ {
823+ std::lock_guard lk (s_fatfs_mutex);
824+ s_callbacks = &callbacks;
825+ Common::ScopeGuard callbacks_guard{[] { s_callbacks = nullptr ; }};
826+ function ();
827+ }
743828} // namespace Common
0 commit comments