- fix ROM mask (use card size from header instead file size);
- fix read range from DS card (real DS can't read data from ROM for DSi console);
- temporary fix "write enable/disable" mc command;
This commit is contained in:
mtabachenko 2013-10-28 00:42:41 +00:00
parent c9507d2e8e
commit b782e366e2
6 changed files with 68 additions and 37 deletions

View File

@ -240,9 +240,9 @@ NDS_header * NDS_getROMHeader(void)
{ offsetof(NDS_header,CRC16), 2},
{ offsetof(NDS_header,ROMtimeout), 2},
{ offsetof(NDS_header,ARM9unk), 4},
{ offsetof(NDS_header,ARM7unk), 4},
{ offsetof(NDS_header,ROMSize), 4},
{ offsetof(NDS_header,ARM9autoload), 4},
{ offsetof(NDS_header,ARM7autoload), 4},
{ offsetof(NDS_header,endROMoffset), 4},
{ offsetof(NDS_header,HeaderSize), 4},
{ offsetof(NDS_header,logoCRC16), 2},
@ -452,7 +452,8 @@ static void loadrom(std::string fname) {
gameInfo.resize(size);
fread(gameInfo.romdata,1,size,inf);
gameInfo.loadRom(inf);
gameInfo.fillGap();
fclose(inf);
@ -616,6 +617,21 @@ int NDS_LoadROM(const char *filename, const char *physicalName, const char *logi
//crazymax: how would it have got whacked? dont think we need this
//gameInfo.storeSecureArea();
#if 1
u32 mask = gameInfo.header.endROMoffset - 1;
mask |= (mask >> 1);
mask |= (mask >> 2);
mask |= (mask >> 4);
mask |= (mask >> 8);
mask |= (mask >> 16);
printf("======================================================================\n");
printf("card size %10u (%08Xh) mask %08Xh\n", gameInfo.cardSize, gameInfo.cardSize, gameInfo.mask);
printf("file size %10u (%08Xh) mask %08Xh\n", gameInfo.romsize, gameInfo.romsize, gameInfo.filemask);
printf("endROMoffset %10u (%08Xh) mask %08Xh\n", gameInfo.header.endROMoffset, gameInfo.header.endROMoffset, mask);
printf("======================================================================\n");
#endif
memset(buf, 0, MAX_PATH);
strcpy(buf, path.pathToModule);

View File

@ -97,8 +97,8 @@ struct NDS_header
u8 unitCode; // 012 - Unitcode (00h=Nintendo DS)
u8 deviceCode; // 013 - Encryption Seed Select (00..07h, usually 00h)
u8 cardSize; // 014 - Devicecapacity (Chipsize = 128KB SHL nn) (eg. 7 = 16MB)
u8 cardInfo[8]; // 015 - ??? --> reversed (padded 00h)
u8 flags; // 01D - ??? |
u8 reserved1[8]; // 015 - Must be set to 0x00
u8 region; // 01D - Specific region: 0x80 - China, 0x40 - Korea, 0x00 - Other
u8 romversion; // 01E - ROM Version (usually 00h)
u8 autostart; // 01F - Autostart (Bit2: Skip "Press Button" after Health and Safety)
// (Also skips bootmenu, even in Manual mode & even Start pressed)
@ -127,19 +127,21 @@ struct NDS_header
u32 Key1Cmd; // 064 - Port 40001A4h setting for KEY1 commands (usually 001808F8h)
u32 IconOff; // 068 - Icon_title_offset (0=None) (8000h and up)
u16 CRC16; // 06C - Secure Area Checksum, CRC-16 of [ [20h]..7FFFh]
u16 CRC16; // 06C - Secure Area Checksum, CRC-16 of [ [20h]..7FFFh] - Calculations with this algorithm use 0xffff as the initial value
u16 ROMtimeout; // 06E - Secure Area Loading Timeout (usually 051Eh)
u32 ARM9unk; // 070 -
u32 ARM7unk; // 074 -
u32 ARM9autoload; // 070 - ARM9 Auto Load List RAM Address
u32 ARM7autoload; // 074 - ARM7 Auto Load List RAM Address
u8 secAreaDisable[8]; // 078 - Secure Area Disable (by encrypted "NmMdOnly") (usually zero)
u32 ROMSize; // 080 - Total Used ROM size (remaining/unused bytes usually FFh-padded)
u8 infoResevedRegion[8]; // 078 - ROM Information Reserved Region (must be set to 0x00)
u32 endROMoffset; // 080 - Total Used ROM size (remaining/unused bytes usually FFh-padded)
u32 HeaderSize; // 084 - ROM Header Size (4000h)
u8 unknown5[56]; // 088 - Reserved (zero filled) - "PASS" is contained within here?
u32 ARM9module; // 088 - ARM9 Module Parameter Address (auto-load parameters)
u32 ARM7module; // 08C - ARM7 Module Parameter Address (auto-load parameters)
u8 reserved2[58]; // 090 - Must be set to 0x00 - "PASS" is contained within here?
u8 logo[156]; // 0C0 - Nintendo Logo (compressed bitmap, same as in GBA Headers)
u16 logoCRC16; // 15C - Nintendo Logo Checksum, CRC-16 of [0C0h-15Bh], fixed CF56h
u16 headerCRC16; // 15E - Header Checksum, CRC-16 of [000h-15Dh]
u8 reserved[160]; //
u8 reserved[160]; // Must be set to 0x00
};
#include "PACKED_END.h"
@ -324,8 +326,10 @@ struct GameInfo
crc(0),
chipID(0x00000FC2),
romsize(0),
cardSize(0),
allocatedSize(0),
mask(0)
mask(0),
filemask(0)
{
memset(&header, 0, sizeof(header));
memset(&ROMserial[0], 0, sizeof(ROMserial));
@ -362,21 +366,38 @@ struct GameInfo
if(romdata != NULL) delete[] romdata;
//calculate the necessary mask for the requested size
mask = size-1;
mask |= (mask >>1);
mask |= (mask >>2);
mask |= (mask >>4);
mask |= (mask >>8);
mask |= (mask >>16);
filemask = (size - 1);
filemask |= (filemask >>1);
filemask |= (filemask >>2);
filemask |= (filemask >>4);
filemask |= (filemask >>8);
filemask |= (filemask >>16);
//now, we actually need to over-allocate, because bytes from anywhere protected by that mask
//could be read from the rom
allocatedSize = mask+4;
allocatedSize = (filemask + 4);
romdata = new char[allocatedSize];
romsize = size;
}
bool loadRom(FILE *fp)
{
bool res = (fread(romdata, 1, romsize, fp) == romsize);
if (res)
{
cardSize = (128 * 1024) << romdata[0x14];
mask = (cardSize - 1);
mask |= (mask >>1);
mask |= (mask >>2);
mask |= (mask >>4);
mask |= (mask >>8);
mask |= (mask >>16);
return true;
}
return false;
}
bool isDSiEnhanced();
u32 crc;
u32 chipID;
@ -387,8 +408,10 @@ struct GameInfo
void populate();
char* romdata;
u32 romsize;
u32 cardSize;
u32 allocatedSize;
u32 mask;
u32 filemask;
const RomBanner& getRomBanner();
bool hasRomBanner();
bool isHomebrew;

View File

@ -46,7 +46,6 @@ private:
u32 mode;
u32 handle_save;
u32 save_adr;
u32 rom_mask;
public:
virtual Slot1Info const* info()
@ -63,9 +62,7 @@ public:
handle_save = 0;
subAdr = T1ReadWord(gameInfo.header.unknown5, 0xE) << 17;
rom_mask = (0x020000 << gameInfo.header.cardSize) - 1;
subAdr = T1ReadWord(gameInfo.header.reserved2, 0x6) << 17;
mode = 0;
}
@ -126,9 +123,7 @@ public:
case 0xB2: //Set save position
mode = cmd;
save_adr = protocol.address & rom_mask;
// to Normmatt: Made in Ore (UORJ, crc 2E7111B8) crash when save_addr < subAdr
save_adr -= subAdr;
save_adr = (protocol.address & gameInfo.mask) - subAdr;
handle_save = 1;
break;
}

View File

@ -49,11 +49,6 @@ u32 Slot1Comp_Rom::read()
case eSlot1Operation_B7_Read:
{
//is this legitimate? need some way to verify.
//if(length == 0)
// return 0xFFFFFFFF;
//length -= 4;
//TODO - check about non-4-byte aligned addresses
//OBSOLETED?
@ -61,15 +56,16 @@ u32 Slot1Comp_Rom::read()
////but, a thought: does the internal rom address counter register wrap around? we may be making a mistake by keeping the extra precision
////but there is no test case yet
//at any rate, this is good for safety's sake.
address &= gameInfo.mask;
//"Can be used only for addresses 8000h and up, smaller addresses will be silently redirected to address `8000h+(addr AND 1FFh)`"
if(address < 0x8000)
address = (0x8000 + (address&0x1FF));
address = (0x8000 + (address & 0x1FF));
//as a sanity measure for funny-sized roms (homebrew and perhaps truncated retail roms)
//we need to protect ourselves by returning 0xFF for things still out of range
if(address+4 >= gameInfo.romsize)
if (address > gameInfo.header.endROMoffset)
{
DEBUG_Notify.ReadBeyondEndOfCart(address,gameInfo.romsize);
return 0xFFFFFFFF;
@ -81,7 +77,6 @@ u32 Slot1Comp_Rom::read()
//"However, the datastream wraps to the begin of the current 4K block when address+length crosses a 4K boundary (1000h bytes)"
address = (address&~0xFFF) + ((address+4)&0xFFF);
return ret;
}
break;

View File

@ -22,7 +22,7 @@
#include "armcpu.h"
extern u32 (* ARM_swi_tab[2][32])();
extern char* ARM_swi_names[2][32];
extern const char* ARM_swi_names[2][32];
#endif

View File

@ -457,6 +457,7 @@ u8 BackupDevice::data_command(u8 val, u8 PROCNUM)
}
#endif
write_enable = FALSE;
com = 0;
break;
case BM_CMD_READSTATUS:
@ -467,6 +468,7 @@ u8 BackupDevice::data_command(u8 val, u8 PROCNUM)
case BM_CMD_WRITEENABLE:
//printf("MC%c: write enable\n", PROCNUM?'7':'9');
write_enable = TRUE;
com = 0;
break;
case BM_CMD_WRITELOW: