Initial support for CARD2 read

Can I get card2 writing to work?

Am I _that_ good?

Will I break by copy of X?

I won't know until I try!
This commit is contained in:
Balint Kovacs 2021-02-04 00:16:08 +00:00 committed by d0k3
parent dfb2dff352
commit f2e52bd1c7
3 changed files with 27 additions and 11 deletions

View File

@ -217,7 +217,7 @@ u32 InitCartRead(CartData* cdata) {
return 0; return 0;
} }
u32 ReadCartSectors(void* buffer, u32 sector, u32 count, CartData* cdata) { u32 ReadCartSectors(void* buffer, u32 sector, u32 count, CartData* cdata, bool card2_blanking) {
u8* buffer8 = (u8*) buffer; u8* buffer8 = (u8*) buffer;
if (!CART_INSERTED) return 1; if (!CART_INSERTED) return 1;
// header // header
@ -244,7 +244,8 @@ u32 ReadCartSectors(void* buffer, u32 sector, u32 count, CartData* cdata) {
// overwrite the card2 savegame with 0xFF // overwrite the card2 savegame with 0xFF
u32 card2_offset = getle32(cdata->header + 0x200); u32 card2_offset = getle32(cdata->header + 0x200);
if ((card2_offset != 0xFFFFFFFF) && if (card2_blanking &&
(card2_offset != 0xFFFFFFFF) &&
((card2_offset * 0x200) >= cdata->data_size) && ((card2_offset * 0x200) >= cdata->data_size) &&
(sector + count > card2_offset)) { (sector + count > card2_offset)) {
if (sector > card2_offset) if (sector > card2_offset)
@ -292,16 +293,16 @@ u32 ReadCartSectors(void* buffer, u32 sector, u32 count, CartData* cdata) {
return 0; return 0;
} }
u32 ReadCartBytes(void* buffer, u64 offset, u64 count, CartData* cdata) { u32 ReadCartBytes(void* buffer, u64 offset, u64 count, CartData* cdata, bool card2_blanking) {
if (!(offset % 0x200) && !(count % 0x200)) { // aligned data -> simple case if (!(offset % 0x200) && !(count % 0x200)) { // aligned data -> simple case
// simple wrapper function for ReadCartSectors(...) // simple wrapper function for ReadCartSectors(...)
return ReadCartSectors(buffer, offset / 0x200, count / 0x200, cdata); return ReadCartSectors(buffer, offset / 0x200, count / 0x200, cdata, card2_blanking);
} else { // misaligned data -> -___- } else { // misaligned data -> -___-
u8* buffer8 = (u8*) buffer; u8* buffer8 = (u8*) buffer;
u8 l_buffer[0x200]; u8 l_buffer[0x200];
if (offset % 0x200) { // handle misaligned offset if (offset % 0x200) { // handle misaligned offset
u32 offset_fix = 0x200 - (offset % 0x200); u32 offset_fix = 0x200 - (offset % 0x200);
if (ReadCartSectors(l_buffer, offset / 0x200, 1, cdata) != 0) return 1; if (ReadCartSectors(l_buffer, offset / 0x200, 1, cdata, card2_blanking) != 0) return 1;
memcpy(buffer8, l_buffer + 0x200 - offset_fix, min(offset_fix, count)); memcpy(buffer8, l_buffer + 0x200 - offset_fix, min(offset_fix, count));
if (count <= offset_fix) return 0; if (count <= offset_fix) return 0;
offset += offset_fix; offset += offset_fix;
@ -309,11 +310,11 @@ u32 ReadCartBytes(void* buffer, u64 offset, u64 count, CartData* cdata) {
count -= offset_fix; count -= offset_fix;
} // offset is now aligned and part of the data is read } // offset is now aligned and part of the data is read
if (count >= 0x200) { // otherwise this is misaligned and will be handled below if (count >= 0x200) { // otherwise this is misaligned and will be handled below
if (ReadCartSectors(buffer8, offset / 0x200, count / 0x200, cdata) != 0) return 1; if (ReadCartSectors(buffer8, offset / 0x200, count / 0x200, cdata, card2_blanking) != 0) return 1;
} }
if (count % 0x200) { // handle misaligned count if (count % 0x200) { // handle misaligned count
u32 count_fix = count % 0x200; u32 count_fix = count % 0x200;
if (ReadCartSectors(l_buffer, (offset + count) / 0x200, 1, cdata) != 0) return 1; if (ReadCartSectors(l_buffer, (offset + count) / 0x200, 1, cdata, card2_blanking) != 0) return 1;
memcpy(buffer8 + count - count_fix, l_buffer, count_fix); memcpy(buffer8 + count - count_fix, l_buffer, count_fix);
} }
return 0; return 0;
@ -347,7 +348,19 @@ u32 ReadCartInfo(u8* 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) {
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 (CardSPIReadSaveData(cdata->spi_save_type, offset, buffer, count) == 0) ? 0 : 1; switch (cdata->save_type) {
case CARD_SAVE_SPI:
return (CardSPIReadSaveData(cdata->spi_save_type, offset, buffer, count) == 0) ? 0 : 1;
break;
case CARD_SAVE_CARD2:
return ReadCartBytes(buffer, cdata->cart_size - cdata->save_size + offset, count, cdata, false);
break;
default:
return 1;
break;
}
} }
u32 WriteCartSave(const u8* buffer, u64 offset, u64 count, CartData* cdata) { u32 WriteCartSave(const u8* buffer, u64 offset, u64 count, CartData* cdata) {

View File

@ -36,8 +36,8 @@ u32 GetCartName(char* name, CartData* cdata);
u32 GetCartInfoString(char* info, CartData* cdata); u32 GetCartInfoString(char* info, CartData* cdata);
u32 SetSecureAreaEncryption(bool encrypted); u32 SetSecureAreaEncryption(bool encrypted);
u32 InitCartRead(CartData* cdata); u32 InitCartRead(CartData* cdata);
u32 ReadCartSectors(void* buffer, u32 sector, u32 count, CartData* cdata); u32 ReadCartSectors(void* buffer, u32 sector, u32 count, CartData* cdata, bool card2_blanking);
u32 ReadCartBytes(void* buffer, u64 offset, u64 count, CartData* cdata); u32 ReadCartBytes(void* buffer, u64 offset, u64 count, CartData* cdata, bool card2_blanking);
u32 ReadCartPrivateHeader(void* buffer, u64 offset, u64 count, CartData* cdata); u32 ReadCartPrivateHeader(void* buffer, u64 offset, u64 count, CartData* cdata);
u32 ReadCartInfo(u8* buffer, u64 offset, u64 count, CartData* cdata); u32 ReadCartInfo(u8* 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);

View File

@ -69,6 +69,9 @@ bool ReadVCartDir(VirtualFile* vfile, VirtualDir* vdir) {
snprintf(vfile->name, 32, "%s.sav", name); snprintf(vfile->name, 32, "%s.sav", name);
vfile->size = cdata->save_size; vfile->size = cdata->save_size;
vfile->flags = VFLAG_SAVEGAME; vfile->flags = VFLAG_SAVEGAME;
if (cdata->save_type == CARD_SAVE_CARD2) {
vfile->flags |= VFLAG_READONLY;
}
return true; return true;
} else if (vdir->index == 8) { // gamecart info } else if (vdir->index == 8) { // gamecart info
char info[256]; char info[256];
@ -95,7 +98,7 @@ int ReadVCartFile(const VirtualFile* vfile, void* buffer, u64 offset, u64 count)
return ReadCartInfo(buffer, foffset, count, cdata); return ReadCartInfo(buffer, foffset, count, cdata);
SetSecureAreaEncryption(vfile->flags & VFLAG_SECURE_AREA_ENC); SetSecureAreaEncryption(vfile->flags & VFLAG_SECURE_AREA_ENC);
return ReadCartBytes(buffer, foffset, count, cdata); return ReadCartBytes(buffer, foffset, count, cdata, true);
} }
int WriteVCartFile(const VirtualFile* vfile, const void* buffer, u64 offset, u64 count) { int WriteVCartFile(const VirtualFile* vfile, const void* buffer, u64 offset, u64 count) {