mirror of
https://github.com/d0k3/GodMode9.git
synced 2025-06-26 21:52:48 +00:00
Write support for NTR saves
Why does this work? We are writing flash memories without erasing them, and writing pages without regard to alignment. Yet it works?
This commit is contained in:
parent
38d9a23427
commit
fa741b265b
@ -69,7 +69,7 @@ bool CheckWritePermissions(const char* path) {
|
|||||||
snprintf(area_name, 16, "game images");
|
snprintf(area_name, 16, "game images");
|
||||||
} else if (drvtype & DRV_CART) {
|
} else if (drvtype & DRV_CART) {
|
||||||
perm = PERM_CART;
|
perm = PERM_CART;
|
||||||
snprintf(area_name, 16, "gamecarts");
|
snprintf(area_name, 16, "gamecart saves");
|
||||||
} else if (drvtype & DRV_VRAM) {
|
} else if (drvtype & DRV_VRAM) {
|
||||||
perm = PERM_VRAM;
|
perm = PERM_VRAM;
|
||||||
snprintf(area_name, 16, "vram0");
|
snprintf(area_name, 16, "vram0");
|
||||||
@ -100,7 +100,7 @@ bool CheckWritePermissions(const char* path) {
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
// offer unlock if possible
|
// offer unlock if possible
|
||||||
if (!(perm & (PERM_VRAM|PERM_CART|PERM_GAME|PERM_XORPAD))) {
|
if (!(perm & (PERM_VRAM|PERM_GAME|PERM_XORPAD))) {
|
||||||
// ask the user
|
// ask the user
|
||||||
if (!ShowPrompt(true, "Writing to %s is locked!\nUnlock it now?", area_name))
|
if (!ShowPrompt(true, "Writing to %s is locked!\nUnlock it now?", area_name))
|
||||||
return false;
|
return false;
|
||||||
@ -169,6 +169,10 @@ bool SetWritePermissions(u32 perm, bool add_perm) {
|
|||||||
if (!ShowUnlockSequence(2, "You want to enable SD data\nwriting permissions.\n \nThis enables you to modify\ninstallations, user data &\nsavegames."))
|
if (!ShowUnlockSequence(2, "You want to enable SD data\nwriting permissions.\n \nThis enables you to modify\ninstallations, user data &\nsavegames."))
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
|
case PERM_CART:
|
||||||
|
if (!ShowUnlockSequence(2, "You want to enable gamecart\nsave writing permissions."))
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
#ifndef SAFEMODE
|
#ifndef SAFEMODE
|
||||||
case PERM_SYS_LVL2:
|
case PERM_SYS_LVL2:
|
||||||
if (!ShowUnlockSequence(3, "!Better be careful!\n \nYou want to enable SysNAND\nlvl2 writing permissions.\n \nThis enables you to modify\nirrecoverable system data!"))
|
if (!ShowUnlockSequence(3, "!Better be careful!\n \nYou want to enable SysNAND\nlvl2 writing permissions.\n \nThis enables you to modify\nirrecoverable system data!"))
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
#define PERM_MEMORY (1UL<<10)
|
#define PERM_MEMORY (1UL<<10)
|
||||||
#define PERM_GAME (1UL<<11) // can't be enabled, placeholder
|
#define PERM_GAME (1UL<<11) // can't be enabled, placeholder
|
||||||
#define PERM_XORPAD (1UL<<12) // can't be enabled, placeholder
|
#define PERM_XORPAD (1UL<<12) // can't be enabled, placeholder
|
||||||
#define PERM_CART (1UL<<13) // can't be enabled, placeholder
|
#define PERM_CART (1UL<<13)
|
||||||
#define PERM_VRAM (1UL<<14) // can't be enabled, placeholder
|
#define PERM_VRAM (1UL<<14) // can't be enabled, placeholder
|
||||||
#define PERM_BASE (PERM_SDCARD | PERM_IMAGE | PERM_RAMDRIVE | PERM_EMU_LVL0 | PERM_SYS_LVL0)
|
#define PERM_BASE (PERM_SDCARD | PERM_IMAGE | PERM_RAMDRIVE | PERM_EMU_LVL0 | PERM_SYS_LVL0)
|
||||||
|
|
||||||
@ -24,7 +24,7 @@
|
|||||||
#define PERM_BLUE (GetWritePermissions()&PERM_MEMORY)
|
#define PERM_BLUE (GetWritePermissions()&PERM_MEMORY)
|
||||||
#define PERM_RED (GetWritePermissions()&(PERM_SYS_LVL3&~PERM_SYS_LVL2))
|
#define PERM_RED (GetWritePermissions()&(PERM_SYS_LVL3&~PERM_SYS_LVL2))
|
||||||
#define PERM_ORANGE (GetWritePermissions()&(PERM_SYS_LVL2&~PERM_SYS_LVL1))
|
#define PERM_ORANGE (GetWritePermissions()&(PERM_SYS_LVL2&~PERM_SYS_LVL1))
|
||||||
#define PERM_YELLOW (GetWritePermissions()&((PERM_SYS_LVL1&~PERM_SYS_LVL0)|(PERM_EMU_LVL1&~PERM_EMU_LVL0)|(PERM_SDDATA&~PERM_SDCARD)))
|
#define PERM_YELLOW (GetWritePermissions()&((PERM_SYS_LVL1&~PERM_SYS_LVL0)|(PERM_EMU_LVL1&~PERM_EMU_LVL0)|(PERM_SDDATA&~PERM_SDCARD)|PERM_CART))
|
||||||
#define PERM_GREEN (GetWritePermissions()&(PERM_SDCARD|PERM_IMAGE|PERM_RAMDRIVE|PERM_EMU_LVL0|PERM_SYS_LVL0))
|
#define PERM_GREEN (GetWritePermissions()&(PERM_SDCARD|PERM_IMAGE|PERM_RAMDRIVE|PERM_EMU_LVL0|PERM_SYS_LVL0))
|
||||||
|
|
||||||
/** Check if writing to this path is allowed **/
|
/** Check if writing to this path is allowed **/
|
||||||
|
@ -247,7 +247,7 @@ u32 ReadCartSave(u8* buffer, u64 offset, u64 count, CartData* cdata) {
|
|||||||
return (SPIReadSaveData((CardType) cdata->save_type, offset, buffer, count) == 0) ? 0 : 1;
|
return (SPIReadSaveData((CardType) cdata->save_type, offset, buffer, count) == 0) ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 WriteCartSave(u8* buffer, u64 offset, u64 count, CartData* cdata) {
|
u32 WriteCartSave(const u8* buffer, u64 offset, u64 count, CartData* cdata) {
|
||||||
if (offset >= cdata->save_size) return 1;
|
if (offset >= cdata->save_size) return 1;
|
||||||
if (offset + count > cdata->save_size) count = cdata->save_size - offset;
|
if (offset + count > cdata->save_size) count = cdata->save_size - offset;
|
||||||
return (SPIWriteSaveData((CardType) cdata->save_type, offset, buffer, count) == 0) ? 0 : 1;
|
return (SPIWriteSaveData((CardType) cdata->save_type, offset, buffer, count) == 0) ? 0 : 1;
|
||||||
|
@ -30,5 +30,5 @@ u32 ReadCartSectors(void* buffer, u32 sector, u32 count, CartData* cdata);
|
|||||||
u32 ReadCartBytes(void* buffer, u64 offset, u64 count, CartData* cdata);
|
u32 ReadCartBytes(void* buffer, u64 offset, u64 count, CartData* cdata);
|
||||||
u32 ReadCartPrivateHeader(void* buffer, u64 offset, u64 count, CartData* cdata);
|
u32 ReadCartPrivateHeader(void* buffer, u64 offset, u64 count, CartData* cdata);
|
||||||
u32 ReadCartSave(u8* buffer, u64 offset, u64 count, CartData* cdata);
|
u32 ReadCartSave(u8* buffer, u64 offset, u64 count, CartData* cdata);
|
||||||
u32 WriteCartSave(u8* buffer, u64 offset, u64 count, CartData* cdata);
|
u32 WriteCartSave(const u8* buffer, u64 offset, u64 count, CartData* cdata);
|
||||||
u32 ReadCartSaveJedecId(u8* buffer, u64 offset, u64 count, CartData* cdata);
|
u32 ReadCartSaveJedecId(u8* buffer, u64 offset, u64 count, CartData* cdata);
|
||||||
|
@ -106,7 +106,7 @@ u32 SPIGetCapacity(CardType type) {
|
|||||||
else return 1 << sz[(int) type];
|
else return 1 << sz[(int) type];
|
||||||
}
|
}
|
||||||
|
|
||||||
int SPIWriteSaveData(CardType type, u32 offset, void* data, u32 size) {
|
int SPIWriteSaveData(CardType type, u32 offset, const void* data, u32 size) {
|
||||||
u8 cmd[4] = { 0 };
|
u8 cmd[4] = { 0 };
|
||||||
u32 cmdSize = 4;
|
u32 cmdSize = 4;
|
||||||
|
|
||||||
@ -167,7 +167,7 @@ int SPIWriteSaveData(CardType type, u32 offset, void* data, u32 size) {
|
|||||||
case FLASH_8MB:
|
case FLASH_8MB:
|
||||||
return 0xC8E13404; // writing is unsupported (so is reading? need to test)
|
return 0xC8E13404; // writing is unsupported (so is reading? need to test)
|
||||||
default:
|
default:
|
||||||
return 0; // never happens
|
return -1; // never happens
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 remaining = end - pos;
|
u32 remaining = end - pos;
|
||||||
|
@ -89,7 +89,7 @@ int SPIGetCardType(CardType* type, int infrared);
|
|||||||
u32 SPIGetPageSize(CardType type);
|
u32 SPIGetPageSize(CardType type);
|
||||||
u32 SPIGetCapacity(CardType type);
|
u32 SPIGetCapacity(CardType type);
|
||||||
|
|
||||||
int SPIWriteSaveData(CardType type, u32 offset, void* data, u32 size);
|
int SPIWriteSaveData(CardType type, u32 offset, const void* data, u32 size);
|
||||||
int SPIReadSaveData(CardType type, u32 offset, void* data, u32 size);
|
int SPIReadSaveData(CardType type, u32 offset, void* data, u32 size);
|
||||||
|
|
||||||
// int SPIEraseSector(CardType type, u32 offset);
|
// int SPIEraseSector(CardType type, u32 offset);
|
||||||
|
@ -65,7 +65,7 @@ bool ReadVCartDir(VirtualFile* vfile, VirtualDir* vdir) {
|
|||||||
} else if (vdir->index == 7) { // JEDEC id and status register
|
} else if (vdir->index == 7) { // JEDEC id and status register
|
||||||
strcpy(vfile->name, "jedecid_and_sreg.bin");
|
strcpy(vfile->name, "jedecid_and_sreg.bin");
|
||||||
vfile->size = JEDECID_AND_SREG_SIZE;
|
vfile->size = JEDECID_AND_SREG_SIZE;
|
||||||
vfile->flags = VFLAG_JEDECID_AND_SRFG;
|
vfile->flags |= VFLAG_JEDECID_AND_SRFG;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -85,6 +85,14 @@ int ReadVCartFile(const VirtualFile* vfile, void* buffer, u64 offset, u64 count)
|
|||||||
else return ReadCartBytes(buffer, foffset, count, cdata);
|
else return ReadCartBytes(buffer, foffset, count, cdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int WriteVCartFile(const VirtualFile* vfile, const void* buffer, u64 offset, u64 count) {
|
||||||
|
if (!cdata) return -1;
|
||||||
|
if (vfile->flags & VFLAG_SAVEGAME) {
|
||||||
|
return WriteCartSave(buffer, offset, count, cdata);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
u64 GetVCartDriveSize(void) {
|
u64 GetVCartDriveSize(void) {
|
||||||
return cart_init ? cdata->cart_size : 0;
|
return cart_init ? cdata->cart_size : 0;
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,6 @@
|
|||||||
u32 InitVCartDrive(void);
|
u32 InitVCartDrive(void);
|
||||||
bool ReadVCartDir(VirtualFile* vfile, VirtualDir* vdir);
|
bool ReadVCartDir(VirtualFile* vfile, VirtualDir* vdir);
|
||||||
int ReadVCartFile(const VirtualFile* vfile, void* buffer, u64 offset, u64 count);
|
int ReadVCartFile(const VirtualFile* vfile, void* buffer, u64 offset, u64 count);
|
||||||
// int WriteVCartFile(const VirtualFile* vfile, const void* buffer, u64 offset, u64 count); // no writes
|
int WriteVCartFile(const VirtualFile* vfile, const void* buffer, u64 offset, u64 count);
|
||||||
u64 GetVCartDriveSize(void);
|
u64 GetVCartDriveSize(void);
|
||||||
void GetVCartTypeString(char* typestr);
|
void GetVCartTypeString(char* typestr);
|
||||||
|
@ -204,7 +204,9 @@ int WriteVirtualFile(const VirtualFile* vfile, const void* buffer, u64 offset, u
|
|||||||
return WriteVMemFile(vfile, buffer, offset, count);
|
return WriteVMemFile(vfile, buffer, offset, count);
|
||||||
} else if (vfile->flags & VRT_DISADIFF) {
|
} else if (vfile->flags & VRT_DISADIFF) {
|
||||||
return WriteVDisaDiffFile(vfile, buffer, offset, count);
|
return WriteVDisaDiffFile(vfile, buffer, offset, count);
|
||||||
} // no write support for virtual game / tickdb / keydb / cart / vram files
|
} else if (vfile->flags & VRT_CART) {
|
||||||
|
return WriteVCartFile(vfile, buffer, offset, count);
|
||||||
|
} // no write support for virtual game / tickdb / keydb / vram files
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user