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 * header = new NDS_header;
memcpy(header, &gameInfo.header, sizeof(gameInfo.header));
//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;
NDS_header *newHeader = new NDS_header;
memcpy(newHeader, &gameInfo.header, sizeof(NDS_header));
return newHeader;
}
@ -332,11 +281,7 @@ void GameInfo::populate()
"AUS", // U
};
NDS_header * _header = NDS_getROMHeader();
header = *_header;
delete _header;
memset(ROMserial, 0, sizeof(ROMserial));
memset(ROMname, 0, sizeof(ROMname));
@ -376,8 +321,6 @@ void GameInfo::populate()
trim(ROMfullName[i]);
}
}*/
}
bool GameInfo::loadROM(std::string fname, u32 type)
@ -398,6 +341,67 @@ bool GameInfo::loadROM(std::string fname, u32 type)
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;
mask = (cardSize - 1);
mask |= (mask >>1);
@ -421,14 +425,24 @@ bool GameInfo::loadROM(std::string fname, u32 type)
{
delete [] romdata; romdata = NULL;
romsize = 0;
return false;
}
if(hasRomBanner())
{
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;
return true;
}
@ -437,6 +451,14 @@ bool GameInfo::loadROM(std::string fname, u32 type)
{
fseek(fROM, header.IconOff + headerOffset, SEEK_SET);
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);
lastReadPos = 0;
@ -471,10 +493,10 @@ u32 GameInfo::readROM(u32 pos)
fseek(fROM, pos + headerOffset, SEEK_SET);
u32 num = fread(&data, 1, 4, fROM);
lastReadPos = (pos + num);
return data;
return LE_TO_LOCAL_32(data);
}
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)
@ -2175,7 +2197,7 @@ bool NDS_FakeBoot()
u32 dst = header->ARM9cpy;
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);
@ -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.
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
{
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)

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

View File

@ -42,7 +42,7 @@ u32 Slot1Comp_Rom::read()
{
//see B7 for details
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);
return ret;
}

View File

@ -256,10 +256,10 @@ typedef int desmume_BOOL;
#ifdef LOCAL_BE /* local arch is big endian */
# 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_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_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 */
# define LE_TO_LOCAL_16(x) (x)
# define LE_TO_LOCAL_32(x) (x)

View File

@ -68,14 +68,14 @@
*/
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
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 (data[0] == 0x00000000 && data[1] == 0x00000000) return ROMTYPE_MULTIBOOT;
if (data[0] == 0xE7FFDEFF && data[1] == 0xE7FFDEFF) return ROMTYPE_NDSDUMPED;
else if (data == 0x0000000000000000ULL) return ROMTYPE_MULTIBOOT;
else if (data == 0xE7FFDEFFE7FFDEFFULL) return ROMTYPE_NDSDUMPED;
//TODO
//for (int i=0x200; i<0x4000; i++)
// if (romdata[i]) return ROMTYPE_MASKROM; // found something odd ;)