From 647d5722aa682602c95a08e85938f1a21ae16841 Mon Sep 17 00:00:00 2001 From: d0k3 Date: Wed, 23 Dec 2020 16:20:10 +0100 Subject: [PATCH] gamecart: Replaced ID file with info file --- arm9/source/gamecart/gamecart.c | 50 +++++++++++++++++++++++++-------- arm9/source/gamecart/gamecart.h | 4 +-- arm9/source/virtual/vcart.c | 16 ++++++----- 3 files changed, 50 insertions(+), 20 deletions(-) diff --git a/arm9/source/gamecart/gamecart.c b/arm9/source/gamecart/gamecart.c index e4e5529..ee56662 100644 --- a/arm9/source/gamecart/gamecart.c +++ b/arm9/source/gamecart/gamecart.c @@ -6,6 +6,7 @@ #include "nds.h" #include "ncch.h" #include "ncsd.h" +#include "rtc.h" #define CART_INSERTED (!(REG_CARDSTATUS & 0x1)) @@ -44,6 +45,8 @@ typedef struct { u32 arm9i_rom_offset; } PACKED_ALIGN(16) CartDataNtrTwl; +DsTime init_time; + u32 GetCartName(char* name, CartData* cdata) { if (cdata->cart_type & CART_CTR) { CartDataCtr* cdata_i = (CartDataCtr*)cdata; @@ -59,7 +62,32 @@ u32 GetCartName(char* name, CartData* cdata) { return 0; } +u32 GetCartInfoString(char* info, CartData* cdata) { + if (cdata->cart_type & CART_CTR) { + CartDataCtr* cdata_i = (CartDataCtr*)cdata; + NcsdHeader* ncsd = &(cdata_i->ncsd); + NcchHeader* ncch = &(cdata_i->ncch); + snprintf(info, 256, "Title ID : %016llX\nProduct Code : %.10s\nRevision : %lu\nCart ID : %08lX\nPlatform : %s\nTimestamp : 20%02X-%02X-%02X %02X:%02X:%02X\nGM9 Version : %s\n", + ncsd->mediaId, ncch->productcode, cdata_i->rom_version, cdata_i->cart_id, + (ncch->flags[4] == 0x2) ? "N3DS" : "O3DS", + init_time.bcd_Y, init_time.bcd_M, init_time.bcd_D, + init_time.bcd_h, init_time.bcd_m, init_time.bcd_s, + VERSION); + } else if (cdata->cart_type & CART_NTR) { + CartDataNtrTwl* cdata_i = (CartDataNtrTwl*)cdata; + TwlHeader* nds = &(cdata_i->ntr_header); + snprintf(info, 256, "Title String : %.12s\nProduct Code : %.6s\nRevision : %u\nCart ID : %08lX\nPlatform : %s\nTimestamp : 20%02X-%02X-%02X %02X:%02X:%02X\nGM9 Version : %s\n", + nds->game_title, nds->game_code, nds->rom_version, cdata_i->cart_id, + (nds->unit_code == 0x2) ? "DSi Enhanced" : (nds->unit_code == 0x3) ? "DSi Exclusive" : "DS", + init_time.bcd_Y, init_time.bcd_M, init_time.bcd_D, + init_time.bcd_h, init_time.bcd_m, init_time.bcd_s, + VERSION); + } else return 1; + return 0; +} + u32 InitCartRead(CartData* cdata) { + get_dstime(&init_time); memset(cdata, 0x00, sizeof(CartData)); cdata->cart_type = CART_NONE; if (!CART_INSERTED) return 1; @@ -264,17 +292,17 @@ u32 ReadCartPrivateHeader(void* buffer, u64 offset, u64 count, CartData* cdata) return 0; } -u32 ReadCartId(u8* buffer, u64 offset, u64 count, CartData* cdata) { - u8 ownBuf[GAMECART_ID_SIZE] = { 0 }; - u32 id; - u8 sReg; - if (offset >= GAMECART_ID_SIZE) return 1; - if (offset + count > GAMECART_ID_SIZE) count = GAMECART_ID_SIZE - offset; - ownBuf[0] = (cdata->cart_id >> 24) & 0xff; - ownBuf[1] = (cdata->cart_id >> 16) & 0xff; - ownBuf[2] = (cdata->cart_id >> 8) & 0xff; - ownBuf[3] = cdata->cart_id & 0xff; - memcpy(buffer, ownBuf + offset, count); +u32 ReadCartInfo(u8* buffer, u64 offset, u64 count, CartData* cdata) { + char info[256]; + u32 len; + + GetCartInfoString(info, cdata); + len = strnlen(info, 255); + + if (offset >= len) return 0; + if (offset + count > len) count = len - offset; + memcpy(buffer, info + offset, count); + return 0; } diff --git a/arm9/source/gamecart/gamecart.h b/arm9/source/gamecart/gamecart.h index 33c2a3e..9da0a53 100644 --- a/arm9/source/gamecart/gamecart.h +++ b/arm9/source/gamecart/gamecart.h @@ -11,7 +11,6 @@ #define MODC_AREA_SIZE 0x4000 #define PRIV_HDR_SIZE 0x50 #define JEDECID_AND_SREG_SIZE 0x4 -#define GAMECART_ID_SIZE 0x4 typedef struct { u8 header[0x8000]; // NTR header + secure area / CTR header + private header @@ -26,11 +25,12 @@ typedef struct { } PACKED_ALIGN(16) CartData; u32 GetCartName(char* name, CartData* cdata); +u32 GetCartInfoString(char* info, CartData* cdata); u32 InitCartRead(CartData* cdata); u32 ReadCartSectors(void* buffer, u32 sector, u32 count, CartData* cdata); u32 ReadCartBytes(void* buffer, u64 offset, u64 count, CartData* cdata); u32 ReadCartPrivateHeader(void* buffer, u64 offset, u64 count, CartData* cdata); -u32 ReadCartId(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 WriteCartSave(const u8* buffer, u64 offset, u64 count, CartData* cdata); u32 ReadCartSaveJedecId(u8* buffer, u64 offset, u64 count, CartData* cdata); diff --git a/arm9/source/virtual/vcart.c b/arm9/source/virtual/vcart.c index 2d4a083..48098ae 100644 --- a/arm9/source/virtual/vcart.c +++ b/arm9/source/virtual/vcart.c @@ -2,7 +2,7 @@ #include "gamecart.h" #define FAT_LIMIT 0x100000000 -#define VFLAG_GAMECART_ID (1UL<<28) +#define VFLAG_GAMECART_NFO (1UL<<28) #define VFLAG_JEDECID_AND_SRFG (1UL<<29) #define VFLAG_SAVEGAME (1UL<<30) #define VFLAG_PRIV_HDR (1UL<<31) @@ -63,10 +63,12 @@ bool ReadVCartDir(VirtualFile* vfile, VirtualDir* vdir) { vfile->size = cdata->save_size; vfile->flags = VFLAG_SAVEGAME; return true; - } else if (vdir->index == 7) { // gamecart ID - strcpy(vfile->name, "gamecart_id.bin"); - vfile->size = GAMECART_ID_SIZE; - vfile->flags |= VFLAG_GAMECART_ID; + } else if (vdir->index == 7) { // gamecart info + char info[256]; + GetCartInfoString(info, cdata); + snprintf(vfile->name, 32, "%s.txt", name); + vfile->size = strnlen(info, 255); + vfile->flags |= VFLAG_GAMECART_NFO; return true; } else if ((vdir->index == 8) && cdata->save_type.chip) { // JEDEC id and status register strcpy(vfile->name, "jedecid_and_sreg.bin"); @@ -86,8 +88,8 @@ int ReadVCartFile(const VirtualFile* vfile, void* buffer, u64 offset, u64 count) return ReadCartPrivateHeader(buffer, foffset, count, cdata); else if (vfile->flags & VFLAG_SAVEGAME) return ReadCartSave(buffer, foffset, count, cdata); - else if (vfile->flags & VFLAG_GAMECART_ID) - return ReadCartId(buffer, foffset, count, cdata); + else if (vfile->flags & VFLAG_GAMECART_NFO) + return ReadCartInfo(buffer, foffset, count, cdata); else if (vfile->flags & VFLAG_JEDECID_AND_SRFG) return ReadCartSaveJedecId(buffer, foffset, count, cdata); else return ReadCartBytes(buffer, foffset, count, cdata);