Core (v0.9.10):

- Backport changes from r4946 to the 0.9.10 branch.
This commit is contained in:
rogerman 2013-12-18 08:15:33 +00:00
parent 71231d8c24
commit 50d040a3a1
5 changed files with 111 additions and 80 deletions

View File

@ -179,61 +179,10 @@ void NDS_DeInit(void)
NDS_header * NDS_getROMHeader(void) NDS_header * NDS_getROMHeader(void)
{ {
NDS_header * header = new NDS_header; NDS_header *newHeader = new NDS_header;
memcpy(newHeader, &gameInfo.header, sizeof(NDS_header));
memcpy(header, &gameInfo.header, sizeof(gameInfo.header));
return newHeader;
//endian swap necessary fields. It would be better if we made accessors for these. I wonder if you could make a macro for a field accessor that would take the bitsize and do the swap on the fly
struct FieldSwap {
size_t offset;
int bytes;
};
static const FieldSwap fieldSwaps[] = {
{ offsetof(NDS_header,makerCode), 2},
{ offsetof(NDS_header,ARM9src), 4},
{ offsetof(NDS_header,ARM9exe), 4},
{ offsetof(NDS_header,ARM9cpy), 4},
{ offsetof(NDS_header,ARM7src), 4},
{ offsetof(NDS_header,ARM7exe), 4},
{ offsetof(NDS_header,ARM7cpy), 4},
{ offsetof(NDS_header,ARM7binSize), 4},
{ offsetof(NDS_header,FNameTblOff), 4},
{ offsetof(NDS_header,FNameTblSize), 4},
{ offsetof(NDS_header,FATOff), 4},
{ offsetof(NDS_header,FATSize), 4},
{ offsetof(NDS_header,ARM9OverlayOff), 4},
{ offsetof(NDS_header,ARM9OverlaySize), 4},
{ offsetof(NDS_header,ARM7OverlayOff), 4},
{ offsetof(NDS_header,ARM7OverlaySize), 4},
{ offsetof(NDS_header,normalCmd), 4},
{ offsetof(NDS_header,Key1Cmd), 4},
{ offsetof(NDS_header,IconOff), 4},
{ offsetof(NDS_header,CRC16), 2},
{ offsetof(NDS_header,ROMtimeout), 2},
{ offsetof(NDS_header,ARM9autoload), 4},
{ offsetof(NDS_header,ARM7autoload), 4},
{ offsetof(NDS_header,endROMoffset), 4},
{ offsetof(NDS_header,HeaderSize), 4},
{ offsetof(NDS_header, ARM9module), 4},
{ offsetof(NDS_header, ARM7module), 4},
{ offsetof(NDS_header,logoCRC16), 2},
{ offsetof(NDS_header,headerCRC16), 2},
};
for(int i=0;i<ARRAY_SIZE(fieldSwaps);i++)
switch(fieldSwaps[i].bytes)
{
case 2: HostWriteWord((u8*)header,fieldSwaps[i].offset,T1ReadWord(header,fieldSwaps[i].offset));
case 4: HostWriteLong((u8*)header,fieldSwaps[i].offset,T1ReadLong((u8*)header,fieldSwaps[i].offset));
}
return header;
} }
@ -332,11 +281,7 @@ void GameInfo::populate()
"AUS", // U "AUS", // U
}; };
NDS_header * _header = NDS_getROMHeader();
header = *_header;
delete _header;
memset(ROMserial, 0, sizeof(ROMserial)); memset(ROMserial, 0, sizeof(ROMserial));
memset(ROMname, 0, sizeof(ROMname)); memset(ROMname, 0, sizeof(ROMname));
@ -376,8 +321,6 @@ void GameInfo::populate()
trim(ROMfullName[i]); trim(ROMfullName[i]);
} }
}*/ }*/
} }
bool GameInfo::loadROM(std::string fname, u32 type) bool GameInfo::loadROM(std::string fname, u32 type)
@ -398,6 +341,67 @@ bool GameInfo::loadROM(std::string fname, u32 type)
if (res) if (res)
{ {
#ifndef LOCAL_LE
//endian swap necessary fields. It would be better if we made accessors for these. I wonder if you could make a macro for a field accessor that would take the bitsize and do the swap on the fly
struct FieldSwap {
const size_t offset;
const size_t bytes;
};
static const FieldSwap fieldSwaps[] = {
{ offsetof(NDS_header,makerCode), 2},
{ offsetof(NDS_header,ARM9src), 4},
{ offsetof(NDS_header,ARM9exe), 4},
{ offsetof(NDS_header,ARM9cpy), 4},
{ offsetof(NDS_header,ARM9binSize), 4},
{ offsetof(NDS_header,ARM7src), 4},
{ offsetof(NDS_header,ARM7exe), 4},
{ offsetof(NDS_header,ARM7cpy), 4},
{ offsetof(NDS_header,ARM7binSize), 4},
{ offsetof(NDS_header,FNameTblOff), 4},
{ offsetof(NDS_header,FNameTblSize), 4},
{ offsetof(NDS_header,FATOff), 4},
{ offsetof(NDS_header,FATSize), 4},
{ offsetof(NDS_header,ARM9OverlayOff), 4},
{ offsetof(NDS_header,ARM9OverlaySize), 4},
{ offsetof(NDS_header,ARM7OverlayOff), 4},
{ offsetof(NDS_header,ARM7OverlaySize), 4},
{ offsetof(NDS_header,normalCmd), 4},
{ offsetof(NDS_header,Key1Cmd), 4},
{ offsetof(NDS_header,IconOff), 4},
{ offsetof(NDS_header,CRC16), 2},
{ offsetof(NDS_header,ROMtimeout), 2},
{ offsetof(NDS_header,ARM9autoload), 4},
{ offsetof(NDS_header,ARM7autoload), 4},
{ offsetof(NDS_header,endROMoffset), 4},
{ offsetof(NDS_header,HeaderSize), 4},
{ offsetof(NDS_header, ARM9module), 4},
{ offsetof(NDS_header, ARM7module), 4},
{ offsetof(NDS_header,logoCRC16), 2},
{ offsetof(NDS_header,headerCRC16), 2},
};
for(size_t i = 0; i < ARRAY_SIZE(fieldSwaps); i++)
{
const u8 *fieldAddr = (u8 *)&header + fieldSwaps[i].offset;
switch(fieldSwaps[i].bytes)
{
case 2:
*(u16 *)fieldAddr = LE_TO_LOCAL_16(*(u16 *)fieldAddr);
break;
case 4:
*(u32 *)fieldAddr = LE_TO_LOCAL_32(*(u32 *)fieldAddr);
break;
}
}
#endif
cardSize = (128 * 1024) << header.cardSize; cardSize = (128 * 1024) << header.cardSize;
mask = (cardSize - 1); mask = (cardSize - 1);
mask |= (mask >>1); mask |= (mask >>1);
@ -421,14 +425,24 @@ bool GameInfo::loadROM(std::string fname, u32 type)
{ {
delete [] romdata; romdata = NULL; delete [] romdata; romdata = NULL;
romsize = 0; romsize = 0;
return false; return false;
} }
if(hasRomBanner()) if(hasRomBanner())
{
memcpy(&banner, romdata + header.IconOff, sizeof(RomBanner)); memcpy(&banner, romdata + header.IconOff, sizeof(RomBanner));
_isDSiEnhanced = ((*(u32*)(romdata + 0x180) == 0x8D898581U) && (*(u32*)(romdata + 0x184) == 0x8C888480U)); banner.version = LE_TO_LOCAL_16(banner.version);
banner.crc16 = LE_TO_LOCAL_16(banner.crc16);
for(size_t i = 0; i < ARRAY_SIZE(banner.palette); i++)
{
banner.palette[i] = LE_TO_LOCAL_16(banner.palette[i]);
}
}
_isDSiEnhanced = (LE_TO_LOCAL_32(*(u32*)(romdata + 0x180) == 0x8D898581U) && LE_TO_LOCAL_32(*(u32*)(romdata + 0x184) == 0x8C888480U));
fclose(fROM); fROM = NULL; fclose(fROM); fROM = NULL;
return true; return true;
} }
@ -437,6 +451,14 @@ bool GameInfo::loadROM(std::string fname, u32 type)
{ {
fseek(fROM, header.IconOff + headerOffset, SEEK_SET); fseek(fROM, header.IconOff + headerOffset, SEEK_SET);
fread(&banner, 1, sizeof(RomBanner), fROM); fread(&banner, 1, sizeof(RomBanner), fROM);
banner.version = LE_TO_LOCAL_16(banner.version);
banner.crc16 = LE_TO_LOCAL_16(banner.crc16);
for(size_t i = 0; i < ARRAY_SIZE(banner.palette); i++)
{
banner.palette[i] = LE_TO_LOCAL_16(banner.palette[i]);
}
} }
fseek(fROM, headerOffset, SEEK_SET); fseek(fROM, headerOffset, SEEK_SET);
lastReadPos = 0; lastReadPos = 0;
@ -471,10 +493,10 @@ u32 GameInfo::readROM(u32 pos)
fseek(fROM, pos + headerOffset, SEEK_SET); fseek(fROM, pos + headerOffset, SEEK_SET);
u32 num = fread(&data, 1, 4, fROM); u32 num = fread(&data, 1, 4, fROM);
lastReadPos = (pos + num); lastReadPos = (pos + num);
return data; return LE_TO_LOCAL_32(data);
} }
else else
return *(u32*)(romdata + pos); return LE_TO_LOCAL_32(*(u32*)(romdata + pos));
} }
static int rom_init_path(const char *filename, const char *physicalName, const char *logicalFilename) static int rom_init_path(const char *filename, const char *physicalName, const char *logicalFilename)
@ -2175,7 +2197,7 @@ bool NDS_FakeBoot()
u32 dst = header->ARM9cpy; u32 dst = header->ARM9cpy;
for(u32 i = 0; i < header->ARM9binSize; i+=4) for(u32 i = 0; i < header->ARM9binSize; i+=4)
{ {
u32 tmp = (hasSecureArea && ((src >= 0x4000) && (src < 0x8000)))?*(u32*)(gameInfo.secureArea + (src - 0x4000)):gameInfo.readROM(src); u32 tmp = (hasSecureArea && ((src >= 0x4000) && (src < 0x8000)))?LE_TO_LOCAL_32(*(u32*)(gameInfo.secureArea + (src - 0x4000))):gameInfo.readROM(src);
_MMU_write32<ARMCPU_ARM9>(dst, tmp); _MMU_write32<ARMCPU_ARM9>(dst, tmp);
@ -2215,12 +2237,12 @@ bool NDS_FakeBoot()
{ {
//dsi needs this copied later in memory. there are probably a number of things that get copied to a later location in memory.. thats where the NDS consoles tend to stash stuff. //dsi needs this copied later in memory. there are probably a number of things that get copied to a later location in memory.. thats where the NDS consoles tend to stash stuff.
for (int i = 0; i < (0x170); i+=4) for (int i = 0; i < (0x170); i+=4)
_MMU_write32<ARMCPU_ARM9>(0x027FFE00 + i, LE_TO_LOCAL_32(gameInfo.readROM(i))); _MMU_write32<ARMCPU_ARM9>(0x027FFE00 + i, gameInfo.readROM(i));
} }
else else
{ {
for (int i = 0; i < (0x170); i+=4) for (int i = 0; i < (0x170); i+=4)
_MMU_write32<ARMCPU_ARM9>(0x027FFE00 + i, LE_TO_LOCAL_32(gameInfo.readROM(i))); _MMU_write32<ARMCPU_ARM9>(0x027FFE00 + i, gameInfo.readROM(i));
} }
//the firmware will be booting to these entrypoint addresses via BX (well, the arm9 at least; is unverified for the arm7) //the firmware will be booting to these entrypoint addresses via BX (well, the arm9 at least; is unverified for the arm7)

View File

@ -95,7 +95,11 @@ void Slot1Comp_Protocol::write_command_KEY1(GC_Command command)
//TODO - more endian-safe way of doing this (theres examples in R4) //TODO - more endian-safe way of doing this (theres examples in R4)
{ {
#ifdef LOCAL_LE
u64 cmd64 = bswap64(*(u64*)command.bytes); u64 cmd64 = bswap64(*(u64*)command.bytes);
#else
u64 cmd64 = *(u64*)command.bytes;
#endif
//todo - parse into blocknumber //todo - parse into blocknumber
address = (u32)((cmd64 >> 32) & 0xF000); address = (u32)((cmd64 >> 32) & 0xF000);
} }
@ -129,7 +133,12 @@ void Slot1Comp_Protocol::write_command_NORMAL(GC_Command command)
operation = eSlot1Operation_B7_Read; operation = eSlot1Operation_B7_Read;
//TODO - more endian-safe way of doing this (theres examples in R4) //TODO - more endian-safe way of doing this (theres examples in R4)
#ifdef LOCAL_LE
u64 cmd64 = bswap64(*(u64*)command.bytes); u64 cmd64 = bswap64(*(u64*)command.bytes);
#else
u64 cmd64 = *(u64*)command.bytes;
#endif
address = (u32)((cmd64 >> 24)); address = (u32)((cmd64 >> 24));
length = 0x200; length = 0x200;

View File

@ -42,7 +42,7 @@ u32 Slot1Comp_Rom::read()
{ {
//see B7 for details //see B7 for details
address &= gameInfo.mask; //sanity check address &= gameInfo.mask; //sanity check
u32 ret = *(u32*)(gameInfo.secureArea + (address - 0x4000)); u32 ret = LE_TO_LOCAL_32(*(u32*)(gameInfo.secureArea + (address - 0x4000)));
address = (address&~0xFFF) + ((address+4)&0xFFF); address = (address&~0xFFF) + ((address+4)&0xFFF);
return ret; return ret;
} }

View File

@ -256,10 +256,10 @@ typedef int desmume_BOOL;
#ifdef LOCAL_BE /* local arch is big endian */ #ifdef LOCAL_BE /* local arch is big endian */
# define LE_TO_LOCAL_16(x) ((((x)&0xff)<<8)|(((x)>>8)&0xff)) # define LE_TO_LOCAL_16(x) ((((x)&0xff)<<8)|(((x)>>8)&0xff))
# define LE_TO_LOCAL_32(x) ((((x)&0xff)<<24)|(((x)&0xff00)<<8)|(((x)>>8)&0xff00)|(((x)>>24)&0xff)) # define LE_TO_LOCAL_32(x) ((((x)&0xff)<<24)|(((x)&0xff00)<<8)|(((x)>>8)&0xff00)|(((x)>>24)&0xff))
# define LE_TO_LOCAL_64(x) ((((x)&0xff)<<56)|(((x)&0xff00)<<40)|(((x)&0xff0000)<<24)|(((x)&0xff000000)<<8)|(((x)>>8)&0xff000000)|(((x)>>24)&0xff00)|(((x)>>40)&0xff00)|(((x)>>56)&0xff)) # define LE_TO_LOCAL_64(x) ((((x)&0xff)<<56)|(((x)&0xff00)<<40)|(((x)&0xff0000)<<24)|(((x)&0xff000000)<<8)|(((x)>>8)&0xff000000)|(((x)>>24)&0xff0000)|(((x)>>40)&0xff00)|(((x)>>56)&0xff))
# define LOCAL_TO_LE_16(x) ((((x)&0xff)<<8)|(((x)>>8)&0xff)) # define LOCAL_TO_LE_16(x) ((((x)&0xff)<<8)|(((x)>>8)&0xff))
# define LOCAL_TO_LE_32(x) ((((x)&0xff)<<24)|(((x)&0xff00)<<8)|(((x)>>8)&0xff00)|(((x)>>24)&0xff)) # define LOCAL_TO_LE_32(x) ((((x)&0xff)<<24)|(((x)&0xff00)<<8)|(((x)>>8)&0xff00)|(((x)>>24)&0xff))
# define LOCAL_TO_LE_64(x) ((((x)&0xff)<<56)|(((x)&0xff00)<<40)|(((x)&0xff0000)<<24)|(((x)&0xff000000)<<8)|(((x)>>8)&0xff000000)|(((x)>>24)&0xff00)|(((x)>>40)&0xff00)|(((x)>>56)&0xff)) # define LOCAL_TO_LE_64(x) ((((x)&0xff)<<56)|(((x)&0xff00)<<40)|(((x)&0xff0000)<<24)|(((x)&0xff000000)<<8)|(((x)>>8)&0xff000000)|(((x)>>24)&0xff0000)|(((x)>>40)&0xff00)|(((x)>>56)&0xff))
#else /* local arch is little endian */ #else /* local arch is little endian */
# define LE_TO_LOCAL_16(x) (x) # define LE_TO_LOCAL_16(x) (x)
# define LE_TO_LOCAL_32(x) (x) # define LE_TO_LOCAL_32(x) (x)

View File

@ -68,14 +68,14 @@
*/ */
int DetectRomType(const Header& header, char* secure) int DetectRomType(const Header& header, char* secure)
{ {
unsigned int * data = (unsigned int*)(secure); const u64 data = LE_TO_LOCAL_64(*(u64 *)secure);
//this is attempting to check for an utterly invalid nds header //this is attempting to check for an utterly invalid nds header
if(header.unitcode < 0 && header.unitcode > 3) return ROMTYPE_INVALID; if(header.unitcode > 3) return ROMTYPE_INVALID;
if (header.arm9_rom_offset < 0x4000) return ROMTYPE_HOMEBREW; if (header.arm9_rom_offset < 0x4000) return ROMTYPE_HOMEBREW;
if (data[0] == 0x00000000 && data[1] == 0x00000000) return ROMTYPE_MULTIBOOT; else if (data == 0x0000000000000000ULL) return ROMTYPE_MULTIBOOT;
if (data[0] == 0xE7FFDEFF && data[1] == 0xE7FFDEFF) return ROMTYPE_NDSDUMPED; else if (data == 0xE7FFDEFFE7FFDEFFULL) return ROMTYPE_NDSDUMPED;
//TODO //TODO
//for (int i=0x200; i<0x4000; i++) //for (int i=0x200; i<0x4000; i++)
// if (romdata[i]) return ROMTYPE_MASKROM; // found something odd ;) // if (romdata[i]) return ROMTYPE_MASKROM; // found something odd ;)