mirror of
https://github.com/melonDS-emu/melonDS.git
synced 2025-07-26 15:50:00 -06:00
BAHAHAHAHAHAHAHH
This commit is contained in:
@ -20,6 +20,7 @@ add_library(core STATIC
|
|||||||
DSi_Camera.cpp
|
DSi_Camera.cpp
|
||||||
DSi_DSP.cpp
|
DSi_DSP.cpp
|
||||||
DSi_I2C.cpp
|
DSi_I2C.cpp
|
||||||
|
DSi_NAND.cpp
|
||||||
DSi_NDMA.cpp
|
DSi_NDMA.cpp
|
||||||
DSi_NWifi.cpp
|
DSi_NWifi.cpp
|
||||||
DSi_SD.cpp
|
DSi_SD.cpp
|
||||||
|
68
src/DSi.cpp
68
src/DSi.cpp
@ -36,10 +36,10 @@
|
|||||||
#include "DSi_I2C.h"
|
#include "DSi_I2C.h"
|
||||||
#include "DSi_SD.h"
|
#include "DSi_SD.h"
|
||||||
#include "DSi_AES.h"
|
#include "DSi_AES.h"
|
||||||
|
#include "DSi_NAND.h"
|
||||||
#include "DSi_DSP.h"
|
#include "DSi_DSP.h"
|
||||||
#include "DSi_Camera.h"
|
#include "DSi_Camera.h"
|
||||||
|
|
||||||
#include "sha1/sha1.hpp"
|
|
||||||
#include "tiny-AES-c/aes.hpp"
|
#include "tiny-AES-c/aes.hpp"
|
||||||
|
|
||||||
|
|
||||||
@ -530,70 +530,8 @@ bool LoadNAND()
|
|||||||
memcpy(&ARM7Init[0x0254], &ARM7iBIOS[0xC6D0], 0x1048);
|
memcpy(&ARM7Init[0x0254], &ARM7iBIOS[0xC6D0], 0x1048);
|
||||||
memcpy(&ARM7Init[0x129C], &ARM7iBIOS[0xD718], 0x1048);
|
memcpy(&ARM7Init[0x129C], &ARM7iBIOS[0xD718], 0x1048);
|
||||||
|
|
||||||
// TEST ZONE
|
DSi_NAND::Init();
|
||||||
{
|
DSi_NAND::PatchTSC();
|
||||||
SHA1_CTX sha;
|
|
||||||
u8 cidhash[20];
|
|
||||||
u8 iv[16];
|
|
||||||
|
|
||||||
SHA1Init(&sha);
|
|
||||||
SHA1Update(&sha, eMMC_CID, 16);
|
|
||||||
SHA1Final(cidhash, &sha);
|
|
||||||
|
|
||||||
printf("ASS HASH: ");
|
|
||||||
for (int i = 0; i < 20; i++) printf("%02X", cidhash[i]);
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
DSi_AES::Swap16(iv, cidhash);
|
|
||||||
|
|
||||||
printf("ASS IV: ");
|
|
||||||
for (int i = 0; i < 16; i++) printf("%02X", iv[i]);
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
u8 keyX[16];
|
|
||||||
*(u32*)&keyX[0] = (u32)ConsoleID;
|
|
||||||
*(u32*)&keyX[4] = (u32)ConsoleID ^ 0x24EE6906;
|
|
||||||
*(u32*)&keyX[8] = (u32)(ConsoleID >> 32) ^ 0xE65B601D;
|
|
||||||
*(u32*)&keyX[12] = (u32)(ConsoleID >> 32);
|
|
||||||
|
|
||||||
u8 keyY[16];
|
|
||||||
*(u32*)&keyY[0] = 0x0AB9DC76;
|
|
||||||
*(u32*)&keyY[4] = 0xBD4DC4D3;
|
|
||||||
*(u32*)&keyY[8] = 0x202DDD1D;
|
|
||||||
*(u32*)&keyY[12] = 0xE1A00005;
|
|
||||||
|
|
||||||
u8 shittykey[16];
|
|
||||||
DSi_AES::DeriveNormalKey(keyX, keyY, shittykey);
|
|
||||||
|
|
||||||
u8 normalkey[16];
|
|
||||||
DSi_AES::Swap16(normalkey, shittykey);
|
|
||||||
|
|
||||||
u8 dorp[0x200];
|
|
||||||
fseek(SDMMCFile, 0, SEEK_SET);
|
|
||||||
fread(&dorp, 0x200, 1, SDMMCFile);
|
|
||||||
|
|
||||||
AES_ctx ctx;
|
|
||||||
AES_init_ctx_iv(&ctx, normalkey, iv);
|
|
||||||
|
|
||||||
//AES_CTR_xcrypt_buffer(&ctx, dorp, 0x200);
|
|
||||||
for (int i = 0; i < 0x200; i+=16)
|
|
||||||
{
|
|
||||||
u8 tmp[16];
|
|
||||||
DSi_AES::Swap16(tmp, &dorp[i]);
|
|
||||||
AES_CTR_xcrypt_buffer(&ctx, tmp, 16);
|
|
||||||
DSi_AES::Swap16(&dorp[i], tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
//printf("%08X %08X %08X %08X\n", *(u32*)&dorp[0], *(u32*)&dorp[4], *(u32*)&dorp[8], *(u32*)&dorp[12]);
|
|
||||||
for (int i = 0; i < 0x200; i+=16)
|
|
||||||
{
|
|
||||||
for (int j = 0; j < 16; j++)
|
|
||||||
{
|
|
||||||
printf("%02X ", dorp[i+j]);
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
173
src/DSi_NAND.cpp
Normal file
173
src/DSi_NAND.cpp
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2016-2021 Arisotura
|
||||||
|
|
||||||
|
This file is part of melonDS.
|
||||||
|
|
||||||
|
melonDS is free software: you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation, either version 3 of the License, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
melonDS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with melonDS. If not, see http://www.gnu.org/licenses/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "DSi.h"
|
||||||
|
#include "DSi_AES.h"
|
||||||
|
#include "DSi_NAND.h"
|
||||||
|
|
||||||
|
#include "sha1/sha1.hpp"
|
||||||
|
#include "tiny-AES-c/aes.hpp"
|
||||||
|
|
||||||
|
#include "fatfs/ff.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace DSi_NAND
|
||||||
|
{
|
||||||
|
|
||||||
|
u8 FATIV[16];
|
||||||
|
u8 FATKey[16];
|
||||||
|
|
||||||
|
|
||||||
|
void Init()
|
||||||
|
{
|
||||||
|
// init NAND crypto
|
||||||
|
|
||||||
|
SHA1_CTX sha;
|
||||||
|
u8 tmp[20];
|
||||||
|
|
||||||
|
SHA1Init(&sha);
|
||||||
|
SHA1Update(&sha, DSi::eMMC_CID, 16);
|
||||||
|
SHA1Final(tmp, &sha);
|
||||||
|
|
||||||
|
DSi_AES::Swap16(FATIV, tmp);
|
||||||
|
|
||||||
|
u8 keyX[16];
|
||||||
|
*(u32*)&keyX[0] = (u32)DSi::ConsoleID;
|
||||||
|
*(u32*)&keyX[4] = (u32)DSi::ConsoleID ^ 0x24EE6906;
|
||||||
|
*(u32*)&keyX[8] = (u32)(DSi::ConsoleID >> 32) ^ 0xE65B601D;
|
||||||
|
*(u32*)&keyX[12] = (u32)(DSi::ConsoleID >> 32);
|
||||||
|
|
||||||
|
u8 keyY[16];
|
||||||
|
*(u32*)&keyY[0] = 0x0AB9DC76;
|
||||||
|
*(u32*)&keyY[4] = 0xBD4DC4D3;
|
||||||
|
*(u32*)&keyY[8] = 0x202DDD1D;
|
||||||
|
*(u32*)&keyY[12] = 0xE1A00005;
|
||||||
|
|
||||||
|
DSi_AES::DeriveNormalKey(keyX, keyY, tmp);
|
||||||
|
DSi_AES::Swap16(FATKey, tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetupFATCrypto(AES_ctx* ctx, u32 ctr)
|
||||||
|
{
|
||||||
|
u8 iv[16];
|
||||||
|
memcpy(iv, FATIV, 16);
|
||||||
|
|
||||||
|
u32 res;
|
||||||
|
res = iv[15] + (ctr & 0xFF);
|
||||||
|
iv[15] = (res & 0xFF);
|
||||||
|
res = iv[14] + ((ctr >> 8) & 0xFF) + (res >> 8);
|
||||||
|
iv[14] = (res & 0xFF);
|
||||||
|
res = iv[13] + ((ctr >> 16) & 0xFF) + (res >> 8);
|
||||||
|
iv[13] = (res & 0xFF);
|
||||||
|
res = iv[12] + (ctr >> 24) + (res >> 8);
|
||||||
|
iv[12] = (res & 0xFF);
|
||||||
|
iv[11] += (res >> 8);
|
||||||
|
|
||||||
|
AES_init_ctx_iv(ctx, FATKey, iv);
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 ReadFATBlock(u64 addr, u32 len, u8* buf)
|
||||||
|
{
|
||||||
|
u32 ctr = (u32)(addr >> 4);
|
||||||
|
|
||||||
|
AES_ctx ctx;
|
||||||
|
SetupFATCrypto(&ctx, ctr);
|
||||||
|
|
||||||
|
fseek(DSi::SDMMCFile, addr, SEEK_SET);
|
||||||
|
u32 res = fread(buf, len, 1, DSi::SDMMCFile);
|
||||||
|
if (!res) return 0;
|
||||||
|
|
||||||
|
for (u32 i = 0; i < len; i += 16)
|
||||||
|
{
|
||||||
|
//printf("BLOCK %d: IV=", i);
|
||||||
|
//for (int k = 0; k < 16; k++) printf("%02X:", ctx.Iv[k]);
|
||||||
|
//printf("\n");
|
||||||
|
|
||||||
|
u8 tmp[16];
|
||||||
|
DSi_AES::Swap16(tmp, &buf[i]);
|
||||||
|
AES_CTR_xcrypt_buffer(&ctx, tmp, 16);
|
||||||
|
DSi_AES::Swap16(&buf[i], tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
UINT FF_ReadNAND(BYTE* buf, LBA_t sector, UINT num)
|
||||||
|
{
|
||||||
|
printf("READ %08X %08X\n", sector, num);
|
||||||
|
|
||||||
|
// TODO: allow selecting other partitions?
|
||||||
|
u64 baseaddr = 0x10EE00;
|
||||||
|
|
||||||
|
u64 blockaddr = baseaddr + (sector * 0x200ULL);
|
||||||
|
|
||||||
|
u32 res = ReadFATBlock(blockaddr, num*0x200, buf);
|
||||||
|
return res >> 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT FF_WriteNAND(BYTE* buf, LBA_t sector, UINT num)
|
||||||
|
{
|
||||||
|
// TODO!
|
||||||
|
printf("!! WRITE %08X %08X\n", sector, num);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PatchTSC()
|
||||||
|
{
|
||||||
|
// TEST ZONE
|
||||||
|
|
||||||
|
u8 dorp[0x200];
|
||||||
|
ReadFATBlock(0, 0x200, dorp);
|
||||||
|
|
||||||
|
for (int i = 0; i < 0x200; i+=16)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < 16; j++)
|
||||||
|
{
|
||||||
|
printf("%02X ", dorp[i+j]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
ReadFATBlock(0x0010EE00, 0x200, dorp);
|
||||||
|
printf("FUKA\n");
|
||||||
|
for (int i = 0; i < 0x200; i+=16)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < 16; j++)
|
||||||
|
{
|
||||||
|
printf("%02X ", dorp[i+j]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
ff_disk_open(FF_ReadNAND, FF_WriteNAND);
|
||||||
|
|
||||||
|
FRESULT res;
|
||||||
|
FATFS fs;
|
||||||
|
res = f_mount(&fs, "0:", 0);
|
||||||
|
printf("mount=%d\n", res);
|
||||||
|
|
||||||
|
FIL file;
|
||||||
|
res = f_open(&file, "0:/shared1/TWLCFG0.dat", FA_READ);
|
||||||
|
printf("blarg=%d\n", res);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
33
src/DSi_NAND.h
Normal file
33
src/DSi_NAND.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2016-2021 Arisotura
|
||||||
|
|
||||||
|
This file is part of melonDS.
|
||||||
|
|
||||||
|
melonDS is free software: you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation, either version 3 of the License, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
melonDS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with melonDS. If not, see http://www.gnu.org/licenses/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DSI_NAND_H
|
||||||
|
#define DSI_NAND_H
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
namespace DSi_NAND
|
||||||
|
{
|
||||||
|
|
||||||
|
void Init();
|
||||||
|
|
||||||
|
void PatchTSC();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // DSI_NAND_H
|
@ -167,7 +167,6 @@ void Reset()
|
|||||||
|
|
||||||
UserSettings = userdata;
|
UserSettings = userdata;
|
||||||
|
|
||||||
// TODO evetually: do this in DSi mode
|
|
||||||
if (NDS::ConsoleType == 0)
|
if (NDS::ConsoleType == 0)
|
||||||
{
|
{
|
||||||
// fix touchscreen coords
|
// fix touchscreen coords
|
||||||
|
@ -10,10 +10,32 @@
|
|||||||
#include "ff.h" /* Obtains integer types */
|
#include "ff.h" /* Obtains integer types */
|
||||||
#include "diskio.h" /* Declarations of disk functions */
|
#include "diskio.h" /* Declarations of disk functions */
|
||||||
|
|
||||||
/* Definitions of physical drive number for each drive */
|
|
||||||
#define DEV_RAM 0 /* Example: Map Ramdisk to physical drive 0 */
|
static ff_disk_read_cb ReadCb;
|
||||||
#define DEV_MMC 1 /* Example: Map MMC/SD card to physical drive 1 */
|
static ff_disk_write_cb WriteCb;
|
||||||
#define DEV_USB 2 /* Example: Map USB MSD to physical drive 2 */
|
static DSTATUS Status = STA_NOINIT | STA_NODISK;
|
||||||
|
|
||||||
|
|
||||||
|
void ff_disk_open(ff_disk_read_cb readcb, ff_disk_write_cb writecb)
|
||||||
|
{
|
||||||
|
if (!readcb) return;
|
||||||
|
|
||||||
|
ReadCb = readcb;
|
||||||
|
WriteCb = writecb;
|
||||||
|
|
||||||
|
Status &= ~STA_NODISK;
|
||||||
|
if (!writecb) Status |= STA_PROTECT;
|
||||||
|
else Status &= ~STA_PROTECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ff_disk_close()
|
||||||
|
{
|
||||||
|
ReadCb = NULL;
|
||||||
|
WriteCb = NULL;
|
||||||
|
|
||||||
|
Status &= ~STA_PROTECT;
|
||||||
|
Status |= STA_NODISK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
@ -24,32 +46,7 @@ DSTATUS disk_status (
|
|||||||
BYTE pdrv /* Physical drive nmuber to identify the drive */
|
BYTE pdrv /* Physical drive nmuber to identify the drive */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
DSTATUS stat;
|
return Status;
|
||||||
int result;
|
|
||||||
|
|
||||||
switch (pdrv) {
|
|
||||||
case DEV_RAM :
|
|
||||||
result = RAM_disk_status();
|
|
||||||
|
|
||||||
// translate the reslut code here
|
|
||||||
|
|
||||||
return stat;
|
|
||||||
|
|
||||||
case DEV_MMC :
|
|
||||||
result = MMC_disk_status();
|
|
||||||
|
|
||||||
// translate the reslut code here
|
|
||||||
|
|
||||||
return stat;
|
|
||||||
|
|
||||||
case DEV_USB :
|
|
||||||
result = USB_disk_status();
|
|
||||||
|
|
||||||
// translate the reslut code here
|
|
||||||
|
|
||||||
return stat;
|
|
||||||
}
|
|
||||||
return STA_NOINIT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -62,32 +59,8 @@ DSTATUS disk_initialize (
|
|||||||
BYTE pdrv /* Physical drive nmuber to identify the drive */
|
BYTE pdrv /* Physical drive nmuber to identify the drive */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
DSTATUS stat;
|
Status &= ~STA_NOINIT;
|
||||||
int result;
|
return Status;
|
||||||
|
|
||||||
switch (pdrv) {
|
|
||||||
case DEV_RAM :
|
|
||||||
result = RAM_disk_initialize();
|
|
||||||
|
|
||||||
// translate the reslut code here
|
|
||||||
|
|
||||||
return stat;
|
|
||||||
|
|
||||||
case DEV_MMC :
|
|
||||||
result = MMC_disk_initialize();
|
|
||||||
|
|
||||||
// translate the reslut code here
|
|
||||||
|
|
||||||
return stat;
|
|
||||||
|
|
||||||
case DEV_USB :
|
|
||||||
result = USB_disk_initialize();
|
|
||||||
|
|
||||||
// translate the reslut code here
|
|
||||||
|
|
||||||
return stat;
|
|
||||||
}
|
|
||||||
return STA_NOINIT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -103,39 +76,12 @@ DRESULT disk_read (
|
|||||||
UINT count /* Number of sectors to read */
|
UINT count /* Number of sectors to read */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
DRESULT res;
|
if (Status & (STA_NOINIT | STA_NODISK)) return RES_NOTRDY;
|
||||||
int result;
|
if (!ReadCb) return RES_ERROR;
|
||||||
|
|
||||||
switch (pdrv) {
|
UINT res = ReadCb(buff, sector, count);
|
||||||
case DEV_RAM :
|
if (res != count) return RES_ERROR;
|
||||||
// translate the arguments here
|
return RES_OK;
|
||||||
|
|
||||||
result = RAM_disk_read(buff, sector, count);
|
|
||||||
|
|
||||||
// translate the reslut code here
|
|
||||||
|
|
||||||
return res;
|
|
||||||
|
|
||||||
case DEV_MMC :
|
|
||||||
// translate the arguments here
|
|
||||||
|
|
||||||
result = MMC_disk_read(buff, sector, count);
|
|
||||||
|
|
||||||
// translate the reslut code here
|
|
||||||
|
|
||||||
return res;
|
|
||||||
|
|
||||||
case DEV_USB :
|
|
||||||
// translate the arguments here
|
|
||||||
|
|
||||||
result = USB_disk_read(buff, sector, count);
|
|
||||||
|
|
||||||
// translate the reslut code here
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
return RES_PARERR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -153,39 +99,13 @@ DRESULT disk_write (
|
|||||||
UINT count /* Number of sectors to write */
|
UINT count /* Number of sectors to write */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
DRESULT res;
|
if (Status & (STA_NOINIT | STA_NODISK)) return RES_NOTRDY;
|
||||||
int result;
|
if (Status & STA_PROTECT) return RES_WRPRT;
|
||||||
|
if (!WriteCb) return RES_ERROR;
|
||||||
|
|
||||||
switch (pdrv) {
|
UINT res = WriteCb(buff, sector, count);
|
||||||
case DEV_RAM :
|
if (res != count) return RES_ERROR;
|
||||||
// translate the arguments here
|
return RES_OK;
|
||||||
|
|
||||||
result = RAM_disk_write(buff, sector, count);
|
|
||||||
|
|
||||||
// translate the reslut code here
|
|
||||||
|
|
||||||
return res;
|
|
||||||
|
|
||||||
case DEV_MMC :
|
|
||||||
// translate the arguments here
|
|
||||||
|
|
||||||
result = MMC_disk_write(buff, sector, count);
|
|
||||||
|
|
||||||
// translate the reslut code here
|
|
||||||
|
|
||||||
return res;
|
|
||||||
|
|
||||||
case DEV_USB :
|
|
||||||
// translate the arguments here
|
|
||||||
|
|
||||||
result = USB_disk_write(buff, sector, count);
|
|
||||||
|
|
||||||
// translate the reslut code here
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
return RES_PARERR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -201,29 +121,7 @@ DRESULT disk_ioctl (
|
|||||||
void *buff /* Buffer to send/receive control data */
|
void *buff /* Buffer to send/receive control data */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
DRESULT res;
|
printf("disk_ioctl(%02X, %02X, %p)\n", pdrv, cmd, buff);
|
||||||
int result;
|
|
||||||
|
|
||||||
switch (pdrv) {
|
|
||||||
case DEV_RAM :
|
|
||||||
|
|
||||||
// Process of the command for the RAM drive
|
|
||||||
|
|
||||||
return res;
|
|
||||||
|
|
||||||
case DEV_MMC :
|
|
||||||
|
|
||||||
// Process of the command for the MMC/SD card
|
|
||||||
|
|
||||||
return res;
|
|
||||||
|
|
||||||
case DEV_USB :
|
|
||||||
|
|
||||||
// Process of the command the USB drive
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
return RES_PARERR;
|
return RES_PARERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -415,6 +415,15 @@ int ff_del_syncobj (FF_SYNC_t sobj); /* Delete a sync object */
|
|||||||
#define AM_ARC 0x20 /* Archive */
|
#define AM_ARC 0x20 /* Archive */
|
||||||
|
|
||||||
|
|
||||||
|
// extra additions for interfacing with melonDS
|
||||||
|
|
||||||
|
typedef UINT (*ff_disk_read_cb)(BYTE* buff, LBA_t sector, UINT count);
|
||||||
|
typedef UINT (*ff_disk_write_cb)(BYTE* buff, LBA_t sector, UINT count);
|
||||||
|
|
||||||
|
void ff_disk_open(ff_disk_read_cb readcb, ff_disk_write_cb writecb);
|
||||||
|
void ff_disk_close();
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -171,7 +171,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#define FF_STR_VOLUME_ID 0
|
#define FF_STR_VOLUME_ID 0
|
||||||
#define FF_VOLUME_STRS "RAM","NAND","CF","SD","SD2","USB","USB2","USB3"
|
#define FF_VOLUME_STRS "fat"
|
||||||
/* FF_STR_VOLUME_ID switches support for volume ID in arbitrary strings.
|
/* FF_STR_VOLUME_ID switches support for volume ID in arbitrary strings.
|
||||||
/ When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive
|
/ When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive
|
||||||
/ number in the path name. FF_VOLUME_STRS defines the volume ID strings for each
|
/ number in the path name. FF_VOLUME_STRS defines the volume ID strings for each
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
/* (C)ChaN, 2018 */
|
/* (C)ChaN, 2018 */
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define _POSIX_THREAD_SAFE_FUNCTIONS
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
#include "ff.h"
|
#include "ff.h"
|
||||||
|
|
||||||
@ -54,27 +56,6 @@ int ff_cre_syncobj ( /* 1:Function succeeded, 0:Could not create the sync object
|
|||||||
FF_SYNC_t* sobj /* Pointer to return the created sync object */
|
FF_SYNC_t* sobj /* Pointer to return the created sync object */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
/* Win32 */
|
|
||||||
*sobj = CreateMutex(NULL, FALSE, NULL);
|
|
||||||
return (int)(*sobj != INVALID_HANDLE_VALUE);
|
|
||||||
|
|
||||||
/* uITRON */
|
|
||||||
// T_CSEM csem = {TA_TPRI,1,1};
|
|
||||||
// *sobj = acre_sem(&csem);
|
|
||||||
// return (int)(*sobj > 0);
|
|
||||||
|
|
||||||
/* uC/OS-II */
|
|
||||||
// OS_ERR err;
|
|
||||||
// *sobj = OSMutexCreate(0, &err);
|
|
||||||
// return (int)(err == OS_NO_ERR);
|
|
||||||
|
|
||||||
/* FreeRTOS */
|
|
||||||
// *sobj = xSemaphoreCreateMutex();
|
|
||||||
// return (int)(*sobj != NULL);
|
|
||||||
|
|
||||||
/* CMSIS-RTOS */
|
|
||||||
// *sobj = osMutexCreate(&Mutex[vol]);
|
|
||||||
// return (int)(*sobj != NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -90,23 +71,6 @@ int ff_del_syncobj ( /* 1:Function succeeded, 0:Could not delete due to an error
|
|||||||
FF_SYNC_t sobj /* Sync object tied to the logical drive to be deleted */
|
FF_SYNC_t sobj /* Sync object tied to the logical drive to be deleted */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
/* Win32 */
|
|
||||||
return (int)CloseHandle(sobj);
|
|
||||||
|
|
||||||
/* uITRON */
|
|
||||||
// return (int)(del_sem(sobj) == E_OK);
|
|
||||||
|
|
||||||
/* uC/OS-II */
|
|
||||||
// OS_ERR err;
|
|
||||||
// OSMutexDel(sobj, OS_DEL_ALWAYS, &err);
|
|
||||||
// return (int)(err == OS_NO_ERR);
|
|
||||||
|
|
||||||
/* FreeRTOS */
|
|
||||||
// vSemaphoreDelete(sobj);
|
|
||||||
// return 1;
|
|
||||||
|
|
||||||
/* CMSIS-RTOS */
|
|
||||||
// return (int)(osMutexDelete(sobj) == osOK);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -121,22 +85,6 @@ int ff_req_grant ( /* 1:Got a grant to access the volume, 0:Could not get a gran
|
|||||||
FF_SYNC_t sobj /* Sync object to wait */
|
FF_SYNC_t sobj /* Sync object to wait */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
/* Win32 */
|
|
||||||
return (int)(WaitForSingleObject(sobj, FF_FS_TIMEOUT) == WAIT_OBJECT_0);
|
|
||||||
|
|
||||||
/* uITRON */
|
|
||||||
// return (int)(wai_sem(sobj) == E_OK);
|
|
||||||
|
|
||||||
/* uC/OS-II */
|
|
||||||
// OS_ERR err;
|
|
||||||
// OSMutexPend(sobj, FF_FS_TIMEOUT, &err));
|
|
||||||
// return (int)(err == OS_NO_ERR);
|
|
||||||
|
|
||||||
/* FreeRTOS */
|
|
||||||
// return (int)(xSemaphoreTake(sobj, FF_FS_TIMEOUT) == pdTRUE);
|
|
||||||
|
|
||||||
/* CMSIS-RTOS */
|
|
||||||
// return (int)(osMutexWait(sobj, FF_FS_TIMEOUT) == osOK);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -150,21 +98,27 @@ void ff_rel_grant (
|
|||||||
FF_SYNC_t sobj /* Sync object to be signaled */
|
FF_SYNC_t sobj /* Sync object to be signaled */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
/* Win32 */
|
|
||||||
ReleaseMutex(sobj);
|
|
||||||
|
|
||||||
/* uITRON */
|
|
||||||
// sig_sem(sobj);
|
|
||||||
|
|
||||||
/* uC/OS-II */
|
|
||||||
// OSMutexPost(sobj);
|
|
||||||
|
|
||||||
/* FreeRTOS */
|
|
||||||
// xSemaphoreGive(sobj);
|
|
||||||
|
|
||||||
/* CMSIS-RTOS */
|
|
||||||
// osMutexRelease(sobj);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
DWORD get_fattime()
|
||||||
|
{
|
||||||
|
// TODO: return melonDS time instead of RTC??
|
||||||
|
|
||||||
|
time_t timestamp = time(NULL);
|
||||||
|
struct tm timedata;
|
||||||
|
localtime_r(×tamp, &timedata);
|
||||||
|
|
||||||
|
DWORD ret;
|
||||||
|
ret = (timedata.tm_sec >> 1);
|
||||||
|
ret |= (timedata.tm_min << 5);
|
||||||
|
ret |= (timedata.tm_hour << 11);
|
||||||
|
ret |= (timedata.tm_mday << 16);
|
||||||
|
ret |= ((timedata.tm_mon + 1) << 21);
|
||||||
|
ret |= ((timedata.tm_year - 80) << 25);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user