487 lines
24 KiB
C++
487 lines
24 KiB
C++
|
<EFBFBD><EFBFBD>//////////////////////////////////////////////////////////////////////////
|
|||
|
// //
|
|||
|
// NES ROM Cartridge class //
|
|||
|
// Norix //
|
|||
|
// written 2001/02/20 //
|
|||
|
// last modify ----/--/-- //
|
|||
|
//////////////////////////////////////////////////////////////////////////
|
|||
|
#define WIN32_LEAN_AND_MEAN
|
|||
|
#include <windows.h>
|
|||
|
#include <stdio.h>
|
|||
|
#include <stdlib.h>
|
|||
|
#include <mbstring.h>
|
|||
|
|
|||
|
#include "typedef.h"
|
|||
|
#include "macro.h"
|
|||
|
|
|||
|
#include "VirtuaNESres.h"
|
|||
|
|
|||
|
#include "DebugOut.h"
|
|||
|
#include "App.h"
|
|||
|
#include "Plugin.h"
|
|||
|
#include "Pathlib.h"
|
|||
|
#include "Crclib.h"
|
|||
|
#include "Config.h"
|
|||
|
|
|||
|
#include "Archive.h"
|
|||
|
|
|||
|
#include "rom.h"
|
|||
|
#include "romdb.h"
|
|||
|
#include "mmu.h"
|
|||
|
|
|||
|
#include "ips.h"
|
|||
|
|
|||
|
//
|
|||
|
// <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0
|
|||
|
//
|
|||
|
ROM::ROM( const char* fname )
|
|||
|
{
|
|||
|
FILE *fp = NULL;
|
|||
|
LPBYTE temp = NULL;
|
|||
|
LPBYTE bios = NULL;
|
|||
|
LONG FileSize;
|
|||
|
|
|||
|
ZEROMEMORY( &header, sizeof(header) );
|
|||
|
ZEROMEMORY( path, sizeof(path) );
|
|||
|
ZEROMEMORY( name, sizeof(name) );
|
|||
|
|
|||
|
bPAL = FALSE;
|
|||
|
bNSF = FALSE;
|
|||
|
NSF_PAGE_SIZE = 0;
|
|||
|
|
|||
|
lpPRG = lpCHR = lpTrainer = lpDiskBios = lpDisk = NULL;
|
|||
|
|
|||
|
crc = crcall = 0;
|
|||
|
mapper = 0;
|
|||
|
diskno = 0;
|
|||
|
|
|||
|
try {
|
|||
|
if( !(fp = ::fopen( fname, "rb" )) ) {
|
|||
|
// xxx <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD><EFBFBD>Q0~0[0<EFBFBD>0
|
|||
|
LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN );
|
|||
|
::wsprintf( szErrorString, szErrStr, fname );
|
|||
|
throw szErrorString;
|
|||
|
}
|
|||
|
|
|||
|
// <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>S<EFBFBD>_
|
|||
|
::fseek( fp, 0, SEEK_END );
|
|||
|
FileSize = ::ftell( fp );
|
|||
|
::fseek( fp, 0, SEEK_SET );
|
|||
|
// <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0(NES<EFBFBD>0<EFBFBD>0<EFBFBD>0+1<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>N
|
|||
|
NK0<EFBFBD>)
|
|||
|
if( FileSize < 17 ) {
|
|||
|
// <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0L0\U0Y0N0~0Y0
|
|||
|
throw CApp::GetErrorString( IDS_ERROR_SMALLFILE );
|
|||
|
}
|
|||
|
|
|||
|
// <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>x<EFBFBD>O
|
|||
|
if( !(temp = (LPBYTE)::malloc( FileSize )) ) {
|
|||
|
// <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>x<EFBFBD>O<EFBFBD>Qeg~0[0<EFBFBD>0
|
|||
|
throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY );
|
|||
|
}
|
|||
|
|
|||
|
// <EFBFBD>0<EFBFBD>0<EFBFBD>0R<EFBFBD><EFBFBD>0<EFBFBD><EFBFBD>0
|
|||
|
if( ::fread( temp, FileSize, 1, fp ) != 1 ) {
|
|||
|
// <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0n0<EFBFBD><EFBFBD>0<EFBFBD><EFBFBD>0k01YWeW0~0W0_0
|
|||
|
throw CApp::GetErrorString( IDS_ERROR_READ );
|
|||
|
}
|
|||
|
|
|||
|
FCLOSE( fp );
|
|||
|
|
|||
|
// <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0
|
|||
|
::memcpy( &header, temp, sizeof(NESHEADER) );
|
|||
|
|
|||
|
if( header.ID[0] == 'N' && header.ID[1] == 'E'
|
|||
|
&& header.ID[2] == 'S' && header.ID[3] == 0x1A ) {
|
|||
|
// <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0
|
|||
|
memcpy( &header, temp, sizeof(NESHEADER) );
|
|||
|
} else if( header.ID[0] == 'F' && header.ID[1] == 'D'
|
|||
|
&& header.ID[2] == 'S' && header.ID[3] == 0x1A ) {
|
|||
|
// <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0
|
|||
|
memcpy( &header, temp, sizeof(NESHEADER) );
|
|||
|
} else if( header.ID[0] == 'N' && header.ID[1] == 'E'
|
|||
|
&& header.ID[2] == 'S' && header.ID[3] == 'M') {
|
|||
|
// <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0
|
|||
|
memcpy( &header, temp, sizeof(NESHEADER) );
|
|||
|
} else {
|
|||
|
FREE( temp );
|
|||
|
|
|||
|
if( !UnCompress( fname, &temp, (LPDWORD)&FileSize ) ) {
|
|||
|
// *g<EFBFBD>[<EFBFBD>_b__g0Y0
|
|||
|
throw CApp::GetErrorString( IDS_ERROR_UNSUPPORTFORMAT );
|
|||
|
}
|
|||
|
// <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0
|
|||
|
::memcpy( &header, temp, sizeof(NESHEADER) );
|
|||
|
}
|
|||
|
|
|||
|
// Since the zip/fds/nes is defrosted and raw, now apply the patch
|
|||
|
if( Config.emulator.bAutoIPS ) {
|
|||
|
LPBYTE ipstemp = NULL;
|
|||
|
if( !(ipstemp = (LPBYTE)::malloc( FileSize )) ) {
|
|||
|
// <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>x<EFBFBD>O<EFBFBD>Qeg~0[0<EFBFBD>0
|
|||
|
throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY );
|
|||
|
}
|
|||
|
::memcpy( ipstemp, temp, FileSize );
|
|||
|
if( ApplyIPS( fname, ipstemp, FileSize ) ) {
|
|||
|
::memcpy( &header, ipstemp, sizeof(NESHEADER) );
|
|||
|
::memcpy( temp, ipstemp, FileSize );
|
|||
|
}
|
|||
|
|
|||
|
FREE( ipstemp );
|
|||
|
}
|
|||
|
|
|||
|
DWORD PRGoffset, CHRoffset;
|
|||
|
LONG PRGsize, CHRsize;
|
|||
|
|
|||
|
if( header.ID[0] == 'N' && header.ID[1] == 'E'
|
|||
|
&& header.ID[2] == 'S' && header.ID[3] == 0x1A ) {
|
|||
|
// nf<EFBFBD>n0NES<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0
|
|||
|
PRGsize = (LONG)header.PRG_PAGE_SIZE*0x4000;
|
|||
|
CHRsize = (LONG)header.CHR_PAGE_SIZE*0x2000;
|
|||
|
PRGoffset = sizeof(NESHEADER);
|
|||
|
CHRoffset = PRGoffset + PRGsize;
|
|||
|
|
|||
|
if( IsTRAINER() ) {
|
|||
|
PRGoffset += 512;
|
|||
|
CHRoffset += 512;
|
|||
|
}
|
|||
|
|
|||
|
if( PRGsize <= 0 || (PRGsize+CHRsize) > FileSize ) {
|
|||
|
// NES<EFBFBD>0<EFBFBD>0<EFBFBD>0L0pu8^g0Y0
|
|||
|
throw CApp::GetErrorString( IDS_ERROR_INVALIDNESHEADER );
|
|||
|
}
|
|||
|
|
|||
|
// PRG BANK
|
|||
|
if( !(lpPRG = (LPBYTE)malloc( PRGsize )) ) {
|
|||
|
// <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>x<EFBFBD>O<EFBFBD>Qeg~0[0<EFBFBD>0
|
|||
|
throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY );
|
|||
|
}
|
|||
|
|
|||
|
::memcpy( lpPRG, temp+PRGoffset, PRGsize );
|
|||
|
|
|||
|
// CHR BANK
|
|||
|
if( CHRsize > 0 ) {
|
|||
|
if( !(lpCHR = (LPBYTE)malloc( CHRsize )) ) {
|
|||
|
// <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>x<EFBFBD>O<EFBFBD>Qeg~0[0<EFBFBD>0
|
|||
|
throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY );
|
|||
|
}
|
|||
|
|
|||
|
if( FileSize >= CHRoffset+CHRsize ) {
|
|||
|
memcpy( lpCHR, temp+CHRoffset, CHRsize );
|
|||
|
} else {
|
|||
|
// CHR<EFBFBD>0<EFBFBD>0<EFBFBD>0\j0D0&
|
|||
|
CHRsize -= (CHRoffset+CHRsize - FileSize);
|
|||
|
memcpy( lpCHR, temp+CHRoffset, CHRsize );
|
|||
|
}
|
|||
|
} else {
|
|||
|
lpCHR = NULL;
|
|||
|
}
|
|||
|
|
|||
|
// Trainer
|
|||
|
if( IsTRAINER() ) {
|
|||
|
if( !(lpTrainer = (LPBYTE)malloc( 512 )) ) {
|
|||
|
// <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>x<EFBFBD>O<EFBFBD>Qeg~0[0<EFBFBD>0
|
|||
|
throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY );
|
|||
|
}
|
|||
|
|
|||
|
memcpy( lpTrainer, temp+sizeof(NESHEADER), 512 );
|
|||
|
} else {
|
|||
|
lpTrainer = NULL;
|
|||
|
}
|
|||
|
} else if( header.ID[0] == 'F' && header.ID[1] == 'D'
|
|||
|
&& header.ID[2] == 'S' && header.ID[3] == 0x1A ) {
|
|||
|
// FDS(Nintendo Disk System)
|
|||
|
// <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0
|
|||
|
diskno = header.PRG_PAGE_SIZE;
|
|||
|
|
|||
|
if( FileSize < (16+65500*diskno) ) {
|
|||
|
// <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0L0pu8^g0Y0
|
|||
|
throw CApp::GetErrorString( IDS_ERROR_ILLEGALDISKSIZE );
|
|||
|
}
|
|||
|
if( diskno > 8 ) {
|
|||
|
// 8b<EFBFBD><EFBFBD>0<EFBFBD>0YD0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0o0<EFBFBD>[<EFBFBD>_W0f0D0~0[0<EFBFBD>0
|
|||
|
throw CApp::GetErrorString( IDS_ERROR_UNSUPPORTDISK );
|
|||
|
}
|
|||
|
|
|||
|
ZEROMEMORY( &header, sizeof(NESHEADER) );
|
|||
|
|
|||
|
// <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0\O<EFBFBD>0
|
|||
|
header.ID[0] = 'N';
|
|||
|
header.ID[1] = 'E';
|
|||
|
header.ID[2] = 'S';
|
|||
|
header.ID[3] = 0x1A;
|
|||
|
header.PRG_PAGE_SIZE = (BYTE)diskno*4;
|
|||
|
header.CHR_PAGE_SIZE = 0;
|
|||
|
header.control1 = 0x40;
|
|||
|
header.control2 = 0x10;
|
|||
|
|
|||
|
PRGsize = sizeof(NESHEADER)+65500*(LONG)diskno;
|
|||
|
// PRG BANK
|
|||
|
if( !(lpPRG = (LPBYTE)malloc( PRGsize )) ) {
|
|||
|
// <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>x<EFBFBD>O<EFBFBD>Qeg~0[0<EFBFBD>0
|
|||
|
throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY );
|
|||
|
}
|
|||
|
// <EFBFBD>0<EFBFBD>0<EFBFBD>0n0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0(u
|
|||
|
if( !(lpDisk = (LPBYTE)malloc( PRGsize )) ) {
|
|||
|
// <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>x<EFBFBD>O<EFBFBD>Qeg~0[0<EFBFBD>0
|
|||
|
throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY );
|
|||
|
}
|
|||
|
// CHR BANK
|
|||
|
lpCHR = NULL;
|
|||
|
|
|||
|
::memcpy( lpPRG, &header, sizeof(NESHEADER) );
|
|||
|
::memcpy( lpPRG+sizeof(NESHEADER), temp+sizeof(NESHEADER), 65500*(LONG)diskno );
|
|||
|
// <EFBFBD>0<EFBFBD>0<EFBFBD>0n0<EFBFBD>fM0<EFBFBD>cH04X@byr<EFBFBD>[(u
|
|||
|
ZEROMEMORY( lpDisk, PRGsize );
|
|||
|
// memcpy( lpDisk, &header, sizeof(NESHEADER) );
|
|||
|
// memcpy( lpDisk+sizeof(NESHEADER), temp+sizeof(NESHEADER), PRGsize-sizeof(NESHEADER) );
|
|||
|
|
|||
|
lpPRG[0] = 'F';
|
|||
|
lpPRG[1] = 'D';
|
|||
|
lpPRG[2] = 'S';
|
|||
|
lpPRG[3] = 0x1A;
|
|||
|
lpPRG[4] = (BYTE)diskno;
|
|||
|
|
|||
|
// DISKSYSTEM BIOSn0<EFBFBD>0<EFBFBD>0<EFBFBD>0
|
|||
|
string Path = CPathlib::MakePathExt( CApp::GetModulePath(), "DISKSYS", "ROM" );
|
|||
|
|
|||
|
if( !(fp = fopen( Path.c_str(), "rb" )) ) {
|
|||
|
// DISKSYS.ROML0B0<EFBFBD>0~0[0<EFBFBD>0
|
|||
|
throw CApp::GetErrorString( IDS_ERROR_NODISKBIOS );
|
|||
|
}
|
|||
|
|
|||
|
::fseek( fp, 0, SEEK_END );
|
|||
|
FileSize = ::ftell( fp );
|
|||
|
::fseek( fp, 0, SEEK_SET );
|
|||
|
if( FileSize < 17 ) {
|
|||
|
// <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0L0\U0Y0N0~0Y0
|
|||
|
throw CApp::GetErrorString( IDS_ERROR_SMALLFILE );
|
|||
|
}
|
|||
|
if( !(bios = (LPBYTE)malloc( FileSize )) ) {
|
|||
|
// <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>x<EFBFBD>O<EFBFBD>Qeg~0[0<EFBFBD>0
|
|||
|
throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY );
|
|||
|
}
|
|||
|
if( fread( bios, FileSize, 1, fp ) != 1 ) {
|
|||
|
// <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0n0<EFBFBD><EFBFBD>0<EFBFBD><EFBFBD>0k01YWeW0~0W0_0
|
|||
|
throw CApp::GetErrorString( IDS_ERROR_READ );
|
|||
|
}
|
|||
|
FCLOSE( fp );
|
|||
|
|
|||
|
if( !(lpDiskBios = (LPBYTE)malloc( 8*1024 )) ) {
|
|||
|
// <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>x<EFBFBD>O<EFBFBD>Qeg~0[0<EFBFBD>0
|
|||
|
throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY );
|
|||
|
}
|
|||
|
|
|||
|
if( bios[0] == 'N' && bios[1] == 'E' && bios[2] == 'S' && bios[3] == 0x1A ) {
|
|||
|
// NESb__BIOS
|
|||
|
::memcpy( lpDiskBios, bios+0x6010, 8*1024 );
|
|||
|
} else {
|
|||
|
// uBIOS
|
|||
|
::memcpy( lpDiskBios, bios, 8*1024 );
|
|||
|
}
|
|||
|
FREE( bios );
|
|||
|
} else if( header.ID[0] == 'N' && header.ID[1] == 'E'
|
|||
|
&& header.ID[2] == 'S' && header.ID[3] == 'M') {
|
|||
|
// NSF
|
|||
|
bNSF = TRUE;
|
|||
|
ZEROMEMORY( &header, sizeof(NESHEADER) );
|
|||
|
|
|||
|
// <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0
|
|||
|
memcpy( &nsfheader, temp, sizeof(NSFHEADER) );
|
|||
|
|
|||
|
PRGsize = FileSize-sizeof(NSFHEADER);
|
|||
|
DEBUGOUT( "PRGSIZE:%d\n", PRGsize );
|
|||
|
PRGsize = (PRGsize+0x0FFF)&~0x0FFF;
|
|||
|
DEBUGOUT( "PRGSIZE:%d\n", PRGsize );
|
|||
|
if( !(lpPRG = (LPBYTE)malloc( PRGsize )) ) {
|
|||
|
// <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>x<EFBFBD>O<EFBFBD>Qeg~0[0<EFBFBD>0
|
|||
|
throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY );
|
|||
|
throw szErrorString;
|
|||
|
}
|
|||
|
ZEROMEMORY( lpPRG, PRGsize );
|
|||
|
memcpy( lpPRG, temp+sizeof(NSFHEADER), FileSize-sizeof(NSFHEADER) );
|
|||
|
|
|||
|
NSF_PAGE_SIZE = PRGsize>>12;
|
|||
|
DEBUGOUT( "PAGESIZE:%d\n", NSF_PAGE_SIZE );
|
|||
|
} else {
|
|||
|
// *g<EFBFBD>[<EFBFBD>_b__g0Y0
|
|||
|
throw CApp::GetErrorString( IDS_ERROR_UNSUPPORTFORMAT );
|
|||
|
}
|
|||
|
|
|||
|
// <EFBFBD>0<EFBFBD>0/<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0
T<EFBFBD>S<EFBFBD>_
|
|||
|
{
|
|||
|
string tempstr;
|
|||
|
tempstr = CPathlib::SplitPath( fname );
|
|||
|
::strcpy( path, tempstr.c_str() );
|
|||
|
tempstr = CPathlib::SplitFname( fname );
|
|||
|
::strcpy( name, tempstr.c_str() );
|
|||
|
// <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0
T(<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0)
|
|||
|
::strcpy( fullpath, fname );
|
|||
|
}
|
|||
|
|
|||
|
// <EFBFBD>0<EFBFBD>0<EFBFBD>0-<EFBFBD><EFBFBD>[
|
|||
|
if( !bNSF ) {
|
|||
|
mapper = (header.control1>>4)|(header.control2&0xF0);
|
|||
|
crc = crcall = crcvrom = 0;
|
|||
|
|
|||
|
if( mapper != 20 ) {
|
|||
|
// PRG crcn0<EFBFBD><EFBFBD>{(NesToyn0PRG CRCh0TX0)
|
|||
|
if( IsTRAINER() ) {
|
|||
|
crcall = CRC::CrcRev( 512+PRGsize+CHRsize, temp+sizeof(NESHEADER) );
|
|||
|
crc = CRC::CrcRev( 512+PRGsize, temp+sizeof(NESHEADER) );
|
|||
|
if( CHRsize )
|
|||
|
crcvrom = CRC::CrcRev( CHRsize, temp+PRGsize+512+sizeof(NESHEADER) );
|
|||
|
} else {
|
|||
|
crcall = CRC::CrcRev( PRGsize+CHRsize, temp+sizeof(NESHEADER) );
|
|||
|
crc = CRC::CrcRev( PRGsize, temp+sizeof(NESHEADER) );
|
|||
|
if( CHRsize )
|
|||
|
crcvrom = CRC::CrcRev( CHRsize, temp+PRGsize+sizeof(NESHEADER) );
|
|||
|
}
|
|||
|
|
|||
|
FilenameCheck( name );
|
|||
|
|
|||
|
romdatabase.HeaderCorrect( header, crcall, crc );
|
|||
|
|
|||
|
#include "ROM_Patch.cpp"
|
|||
|
fdsmakerID = fdsgameID = 0;
|
|||
|
} else {
|
|||
|
crc = crcall = crcvrom = 0;
|
|||
|
|
|||
|
fdsmakerID = lpPRG[0x1F];
|
|||
|
fdsgameID = (lpPRG[0x20]<<24)|(lpPRG[0x21]<<16)|(lpPRG[0x22]<<8)|(lpPRG[0x23]<<0);
|
|||
|
}
|
|||
|
} else {
|
|||
|
// NSF
|
|||
|
mapper = 0x0100; // Private mapper
|
|||
|
crc = crcall = crcvrom = 0;
|
|||
|
fdsmakerID = fdsgameID = 0;
|
|||
|
}
|
|||
|
|
|||
|
FREE( temp );
|
|||
|
} catch( CHAR* str ) {
|
|||
|
// <EFBFBD>S<EFBFBD>VL0<EFBFBD>0K0c0f0D0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>Qt
|
|||
|
FCLOSE( fp );
|
|||
|
FREE( temp );
|
|||
|
FREE( bios );
|
|||
|
|
|||
|
FREE( lpPRG );
|
|||
|
FREE( lpCHR );
|
|||
|
FREE( lpTrainer );
|
|||
|
FREE( lpDiskBios );
|
|||
|
FREE( lpDisk );
|
|||
|
|
|||
|
throw str;
|
|||
|
#ifndef _DEBUG
|
|||
|
} catch(...) {
|
|||
|
// N,<EFBFBD><EFBFBD>Ow<EFBFBD><EFBFBD>0<EFBFBD>0<EFBFBD>0h0K0<EFBFBD>QW0_0O0!qD0n0g0...(^^;
|
|||
|
FCLOSE( fp );
|
|||
|
FREE( temp );
|
|||
|
FREE( bios );
|
|||
|
|
|||
|
FREE( lpPRG );
|
|||
|
FREE( lpCHR );
|
|||
|
FREE( lpTrainer );
|
|||
|
FREE( lpDiskBios );
|
|||
|
FREE( lpDisk );
|
|||
|
|
|||
|
#ifdef _DATATRACE
|
|||
|
// For dis...
|
|||
|
FREE( PROM_ACCESS );
|
|||
|
#endif
|
|||
|
|
|||
|
//
Nfj0<EFBFBD>0<EFBFBD>0<EFBFBD>0L0zvuW0~0W0_0
|
|||
|
throw CApp::GetErrorString( IDS_ERROR_UNKNOWN );
|
|||
|
#endif // !_DEBUG
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0
|
|||
|
//
|
|||
|
ROM::~ROM()
|
|||
|
{
|
|||
|
FREE( lpPRG );
|
|||
|
FREE( lpCHR );
|
|||
|
FREE( lpTrainer );
|
|||
|
FREE( lpDiskBios );
|
|||
|
FREE( lpDisk );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// ROM<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0
|
|||
|
//
|
|||
|
INT ROM::IsRomFile( const char* fname )
|
|||
|
{
|
|||
|
FILE* fp = NULL;
|
|||
|
NESHEADER header;
|
|||
|
|
|||
|
if( !(fp = fopen( fname, "rb" )) )
|
|||
|
return IDS_ERROR_OPEN;
|
|||
|
|
|||
|
// <EFBFBD>0<EFBFBD>0<EFBFBD>0R<EFBFBD><EFBFBD>0<EFBFBD><EFBFBD>0
|
|||
|
if( fread( &header, sizeof(header), 1, fp ) != 1 ) {
|
|||
|
FCLOSE( fp );
|
|||
|
return IDS_ERROR_READ;
|
|||
|
}
|
|||
|
FCLOSE( fp );
|
|||
|
|
|||
|
if( header.ID[0] == 'N' && header.ID[1] == 'E'
|
|||
|
&& header.ID[2] == 'S' && header.ID[3] == 0x1A ) {
|
|||
|
for( INT i = 0; i < 8; i++ ) {
|
|||
|
if( header.reserved[i] )
|
|||
|
return IDS_ERROR_ILLEGALHEADER;
|
|||
|
}
|
|||
|
return 0;
|
|||
|
} else if( header.ID[0] == 'F' && header.ID[1] == 'D'
|
|||
|
&& header.ID[2] == 'S' && header.ID[3] == 0x1A ) {
|
|||
|
return 0;
|
|||
|
} else if( header.ID[0] == 'N' && header.ID[1] == 'E'
|
|||
|
&& header.ID[2] == 'S' && header.ID[3] == 'M') {
|
|||
|
return 0;
|
|||
|
} else {
|
|||
|
LPBYTE temp = NULL;
|
|||
|
LONG size;
|
|||
|
if( !UnCompress( fname, &temp, (LPDWORD)&size ) )
|
|||
|
return IDS_ERROR_UNSUPPORTFORMAT;
|
|||
|
|
|||
|
memcpy( &header, temp, sizeof(NESHEADER) );
|
|||
|
FREE( temp );
|
|||
|
if( header.ID[0] == 'N' && header.ID[1] == 'E'
|
|||
|
&& header.ID[2] == 'S' && header.ID[3] == 0x1A ) {
|
|||
|
for( INT i = 0; i < 8; i++ ) {
|
|||
|
if( header.reserved[i] )
|
|||
|
return IDS_ERROR_ILLEGALHEADER;
|
|||
|
}
|
|||
|
return 0;
|
|||
|
} else if( header.ID[0] == 'F' && header.ID[1] == 'D'
|
|||
|
&& header.ID[2] == 'S' && header.ID[3] == 0x1A ) {
|
|||
|
return 0;
|
|||
|
} else if( header.ID[0] == 'N' && header.ID[1] == 'E'
|
|||
|
&& header.ID[2] == 'S' && header.ID[3] == 'M') {
|
|||
|
return 0;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return IDS_ERROR_UNSUPPORTFORMAT;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// ROM<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0
Tn0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0(PAL<EFBFBD>0<EFBFBD><EFBFBD><EFBFBD>R$R%R)
|
|||
|
//
|
|||
|
void ROM::FilenameCheck( const char* fname )
|
|||
|
{
|
|||
|
unsigned char* p = (unsigned char*)fname;
|
|||
|
|
|||
|
while( *p != (unsigned char)'\0' ) {
|
|||
|
if( *p == (unsigned char)'(' ) {
|
|||
|
if( _mbsnbicmp( p, (unsigned char*)"(E)", 3 ) == 0 ) {
|
|||
|
bPAL = TRUE;
|
|||
|
return;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
p = _mbsinc(p);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|