📄 nes.cpp
字号:
case 0x17:
CPUREG[addr & 0xFF] = data;
pad->Write( addr, data );
apu->Write( addr, data );
break;
// VirtuaNES屌桳億乕僩
case 0x18:
apu->Write( addr, data );
break;
#if 0
case 0x1C:
m_dwProfileTempCycle = cpu->GetTotalCycles();
break;
case 0x1D:
m_dwProfileCycle = cpu->GetTotalCycles()-m_dwProfileTempCycle-4;
m_dwProfileTotalCycle += m_dwProfileCycle;
m_dwProfileTotalCount++;
break;
case 0x1E:
m_dwProfileTotalCount = 0;
m_dwProfileTotalCycle = 0;
m_dwTotalTempCycle = cpu->GetTotalCycles();
break;
case 0x1F:
m_dwTotalCycle = cpu->GetTotalCycles()-m_dwTotalTempCycle-4;
break;
#endif
default:
mapper->ExWrite( addr, data );
break;
}
}
void NES::LoadSRAM()
{
if( rom->IsNSF() )
return;
ZEROMEMORY( WRAM, sizeof(WRAM) );
if( !rom->IsSAVERAM() )
return;
string pathstr, tempstr;
if( Config.path.bSavePath ) {
pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szSavePath );
} else {
pathstr = rom->GetRomPath();
}
tempstr = CPathlib::MakePathExt( pathstr.c_str(), rom->GetRomName(), "sav" );
DEBUGOUT( "Path: %s\n", tempstr.c_str() );
FILE* fp = NULL;
try
{
if( !(fp = ::fopen( tempstr.c_str(), "rb" )) ) {
// xxx 僼傽僀儖傪奐偗傑偣傫
LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN );
sprintf( szErrorString, szErrStr, tempstr.c_str() );
throw szErrorString;
}
DEBUGOUT( "Loading SAVERAM..." );
LONG size;
// 僼傽僀儖僒僀僘庢摼
::fseek( fp, 0, SEEK_END );
size = ftell( fp );
::fseek( fp, 0, SEEK_SET );
if( size <= 128*1024 ) {
if( ::fread( WRAM, size, 1, fp ) != 1 )
throw "File Read error.";
}
DEBUGOUT( "Ok.\n" );
FCLOSE( fp );
} catch( CHAR* str ) {
FCLOSE( fp );
DEBUGOUT( "Loading SAVERAM Error.\n" );
DEBUGOUT( "%s\n", str );
// throw str;
#ifndef _DEBUG
} catch(...) {
FCLOSE( fp );
DEBUGOUT( "Loading SAVERAM Error.\n" );
// 晄柧側僄儔乕偑敪惗偟傑偟偨
throw CApp::GetErrorString( IDS_ERROR_UNKNOWN );
#endif
}
}
void NES::SaveSRAM()
{
INT i;
if( rom->IsNSF() )
return;
if( !rom->IsSAVERAM() )
return;
for( i = 0; i < SAVERAM_SIZE; i++ ) {
if( WRAM[i] != 0x00 )
break;
}
if( i < SAVERAM_SIZE ) {
DEBUGOUT( "Saving SAVERAM...\n" );
string pathstr, tempstr;
if( Config.path.bSavePath ) {
pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szSavePath );
::CreateDirectory( pathstr.c_str(), NULL );
} else {
pathstr = rom->GetRomPath();
}
tempstr = CPathlib::MakePathExt( pathstr.c_str(), rom->GetRomName(), "sav" );
DEBUGOUT( "Path: %s\n", tempstr.c_str() );
FILE* fp = NULL;
try
{
if( !(fp = ::fopen( tempstr.c_str(), "wb" )) ) {
// xxx 僼傽僀儖傪奐偗傑偣傫
LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN );
sprintf( szErrorString, szErrStr, tempstr.c_str() );
throw szErrorString;
}
if( ::fwrite( WRAM, SAVERAM_SIZE, 1, fp ) != 1 ) {
// 僼傽僀儖偺彂偒崬傒偵幐攕偟傑偟偨
throw CApp::GetErrorString( IDS_ERROR_WRITE );
}
DEBUGOUT( "Ok.\n" );
FCLOSE( fp );
} catch( CHAR* str ) {
DEBUGOUT( "Writing SAVERAM Error.\n" );
FCLOSE( fp );
throw str;
#ifndef _DEBUG
} catch(...) {
DEBUGOUT( "Writing SAVERAM Error.\n" );
FCLOSE( fp );
// 晄柧側僄儔乕偑敪惗偟傑偟偨
throw CApp::GetErrorString( IDS_ERROR_UNKNOWN );
#endif
}
}
}
void NES::LoadDISK()
{
if( rom->GetMapperNo() != 20 )
return;
BOOL bExit = FALSE;
INT i, j, diskno;
FILE* fp = NULL;
DISKIMGFILEHDR ifh;
DISKIMGHDR hdr;
LPBYTE disk;
WORD Version;
string pathstr, tempstr;
if( Config.path.bSavePath ) {
pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szSavePath );
} else {
pathstr = rom->GetRomPath();
}
tempstr = CPathlib::MakePathExt( pathstr.c_str(), rom->GetRomName(), "dsv" );
DEBUGOUT( "Path: %s\n", tempstr.c_str() );
try
{
if( !(fp = ::fopen( tempstr.c_str(), "rb" )) ) {
// xxx 僼傽僀儖傪奐偗傑偣傫
LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN );
sprintf( szErrorString, szErrStr, tempstr.c_str() );
throw szErrorString;
}
if( ::fread( &ifh, sizeof(DISKIMGFILEHDR), 1, fp ) != 1 ) {
// 僼傽僀儖偺撉傒崬傒偵幐攕偟傑偟偨
throw CApp::GetErrorString( IDS_ERROR_READ );
}
if( ::memcmp( ifh.ID, "VirtuaNES DI", sizeof(ifh.ID) ) == 0 ) {
if( ifh.BlockVersion < 0x0100 && ifh.BlockVersion > 0x200 ) {
// 枹懳墳宍幃偱偡
throw CApp::GetErrorString( IDS_ERROR_UNSUPPORTFORMAT );
}
Version = ifh.BlockVersion;
} else {
// 枹懳墳宍幃偱偡
throw CApp::GetErrorString( IDS_ERROR_UNSUPPORTFORMAT );
}
if( Version == 0x0100 ) {
// Ver0.24埲慜
if( ifh.DiskNumber > 4 ) {
// 枹懳墳宍幃偱偡
throw CApp::GetErrorString( IDS_ERROR_UNSUPPORTFORMAT );
}
for( i = 0; i < (INT)ifh.DiskNumber; i++ ) {
if( ::fread( &hdr, sizeof(DISKIMGHDR), 1, fp ) != 1 ) {
if( i == 0 ) {
// 僼傽僀儖偺撉傒崬傒偵幐攕偟傑偟偨
throw CApp::GetErrorString( IDS_ERROR_READ );
} else {
break;
}
}
if( ::memcmp( hdr.ID, "SIDE0A", sizeof(hdr.ID) ) == 0 ) {
diskno = 0;
} else if( ::memcmp( hdr.ID, "SIDE0B", sizeof(hdr.ID) ) == 0 ) {
diskno = 1;
} else if( ::memcmp( hdr.ID, "SIDE1A", sizeof(hdr.ID) ) == 0 ) {
diskno = 2;
} else if( ::memcmp( hdr.ID, "SIDE1B", sizeof(hdr.ID) ) == 0 ) {
diskno = 3;
} else {
// 枹懳墳宍幃偱偡
throw CApp::GetErrorString( IDS_ERROR_UNSUPPORTFORMAT );
}
for( j = 0; j < 16; j++ ) {
if( hdr.DiskTouch[j] ) {
disk = rom->GetPROM()+16+65500*diskno+(4*1024)*j;
if( j < 15 ) {
if( ::fread( disk, 4*1024, 1, fp ) != 1 ) {
bExit = TRUE;
// 僼傽僀儖偺撉傒崬傒偵幐攕偟傑偟偨
throw CApp::GetErrorString( IDS_ERROR_READ );
}
} else {
if( ::fread( disk, 4*1024-36, 1, fp ) != 1 ) {
bExit = TRUE;
// 僼傽僀儖偺撉傒崬傒偵幐攕偟傑偟偨
throw CApp::GetErrorString( IDS_ERROR_READ );
}
}
}
}
}
} else
if( Version == 0x0200 || Version == 0x0210 ) {
// Ver0.30埲崀
DISKFILEHDR dfh;
LPBYTE lpDisk = rom->GetPROM();
LPBYTE lpWrite = rom->GetDISK();
LONG DiskSize = 16+65500*rom->GetDiskNo();
DWORD pos;
BYTE data;
// 彂偒姺偊FLAG徚嫀
::ZeroMemory( lpWrite, 16+65500*rom->GetDiskNo() );
// 僿僢僟撉傒捈偟
if( ::fseek( fp, 0, SEEK_SET ) ) {
// 僼傽僀儖偺撉傒崬傒偵幐攕偟傑偟偨
throw CApp::GetErrorString( IDS_ERROR_READ );
}
if( ::fread( &dfh, sizeof(DISKFILEHDR), 1, fp ) != 1 ) {
// 僼傽僀儖偺撉傒崬傒偵幐攕偟傑偟偨
throw CApp::GetErrorString( IDS_ERROR_READ );
}
if( Config.emulator.bCrcCheck ) {
// 尰嵼儘乕僪拞偺僞僀僩儖偲堘偆偐傪僠僃僢僋
if( dfh.ProgID != rom->GetGameID()
|| dfh.MakerID != (WORD)rom->GetMakerID()
|| dfh.DiskNo != (WORD)rom->GetDiskNo() ) {
// 僼傽僀儖偺撉傒崬傒偵幐攕偟傑偟偨
throw CApp::GetErrorString( IDS_ERROR_READ );
}
}
for( i = 0; i < dfh.DifferentSize; i++ ) {
if( ::fread( &pos, sizeof(DWORD), 1, fp ) != 1 ) {
// 僼傽僀儖偺撉傒崬傒偵幐攕偟傑偟偨
bExit = TRUE;
throw CApp::GetErrorString( IDS_ERROR_READ );
}
data = (BYTE)(pos>>24);
pos &= 0x00FFFFFF;
if( pos >= 16 && pos < DiskSize ) {
lpDisk[pos] = data;
lpWrite[pos] = 0xFF;
}
}
}
FCLOSE( fp );
} catch( CHAR* str ) {
FCLOSE( fp );
DEBUGOUT( "%s\n", str );
if( bExit )
throw str;
#ifndef _DEBUG
} catch(...) {
FCLOSE( fp );
DEBUGOUT( "Loading DISKIMAGE Error.\n" );
// 晄柧側僄儔乕偑敪惗偟傑偟偨
throw CApp::GetErrorString( IDS_ERROR_UNKNOWN );
#endif
}
}
void NES::SaveDISK()
{
if( rom->GetMapperNo() != 20 )
return;
INT i;
FILE* fp = NULL;
DISKFILEHDR ifh;
LPBYTE lpDisk = rom->GetPROM();
LPBYTE lpWrite = rom->GetDISK();
LONG DiskSize = 16+65500*rom->GetDiskNo();
DWORD data;
try
{
::ZeroMemory( &ifh, sizeof(ifh) );
::memcpy( ifh.ID, "VirtuaNES DI", sizeof(ifh.ID) );
ifh.BlockVersion = 0x0210;
ifh.ProgID = rom->GetGameID();
ifh.MakerID = (WORD)rom->GetMakerID();
ifh.DiskNo = (WORD)rom->GetDiskNo();
// 憡堘悢傪僇僂儞僩
for( i = 16; i < DiskSize; i++ ) {
if( lpWrite[i] )
ifh.DifferentSize++;
}
if( !ifh.DifferentSize )
return;
string pathstr, tempstr;
if( Config.path.bSavePath ) {
pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szSavePath );
::CreateDirectory( pathstr.c_str(), NULL );
} else {
pathstr = rom->GetRomPath();
}
tempstr = CPathlib::MakePathExt( pathstr.c_str(), rom->GetRomName(), "dsv" );
DEBUGOUT( "Path: %s\n", tempstr.c_str() );
if( !(fp = ::fopen( tempstr.c_str(), "wb" )) ) {
// xxx 僼傽僀儖傪奐偗傑偣傫
LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN );
::wsprintf( szErrorString, szErrStr, tempstr.c_str() );
throw szErrorString;
}
if( ::fwrite( &ifh, sizeof(DISKFILEHDR), 1, fp ) != 1 ) {
// 僼傽僀儖偺彂偒崬傒偵幐攕偟傑偟偨
throw CApp::GetErrorString( IDS_ERROR_WRITE );
}
for( i = 16; i < DiskSize; i++ ) {
if( lpWrite[i] ) {
data = i & 0x00FFFFFF;
data |= ((DWORD)lpDisk[i]&0xFF)<<24;
// Write File
if( ::fwrite( &data, sizeof(DWORD), 1, fp ) != 1 ) {
// 僼傽僀儖偺彂偒崬傒偵幐攕偟傑偟偨
throw CApp::GetErrorString( IDS_ERROR_WRITE );
}
}
}
FCLOSE( fp );
} catch( CHAR* str ) {
FCLOSE( fp );
DEBUGOUT( "%s\n", str );
#ifndef _DEBUG
} catch(...) {
FCLOSE( fp );
DEBUGOUT( "Saving DISKIMAGE Error.\n" );
// 晄柧側僄儔乕偑敪惗偟傑偟偨
throw CApp::GetErrorString( IDS_ERROR_UNKNOWN );
#endif
}
}
void NES::LoadTurboFile()
{
ZEROMEMORY( ERAM, sizeof(ERAM) );
if( pad->GetExController() != PAD::EXCONTROLLER_TURBOFILE )
return;
string pathstr, tempstr;
if( Config.path.bSavePath ) {
pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szSavePath );
} else {
pathstr = rom->GetRomPath();
}
tempstr = CPathlib::MakePathExt( pathstr.c_str(), "TurboFile", "vtf" );
DEBUGOUT( "Path: %s\n", tempstr.c_str() );
FILE* fp = NULL;
try
{
if( !(fp = ::fopen( tempstr.c_str(), "rb" )) ) {
// xxx 僼傽僀儖傪奐偗傑偣傫
LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN );
sprintf( szErrorString, szErrStr, tempstr.c_str() );
throw szErrorString;
}
DEBUGOUT( "Loading TURBOFILE..." );
LONG size;
// 僼傽僀儖僒僀僘庢摼
::fseek( fp, 0, SEEK_END );
size = ftell( fp );
::fseek( fp, 0, SEEK_SET );
if( size > 32*1024 ) {
size = 32*1024;
}
if( ::fread( ERAM, size, 1, fp ) != 1 )
throw "File Read error.";
DEBUGOUT( "Ok.\n" );
FCLOSE( fp );
} catch( CHAR* str ) {
FCLOSE( fp );
DEBUGOUT( "Loading TurboFile Error.\n" );
DEBUGOUT( "%s\n", str );
// throw str;
#ifndef _DEBUG
} catch(...) {
FCLOSE( fp );
DEBUGOUT( "Loading TurboFile Error.\n" );
// 晄柧側僄儔乕偑敪惗偟傑偟偨
throw CApp::GetErrorString( IDS_ERROR_UNKNOWN );
#endif
}
}
void NES::SaveTurboFile()
{
INT i;
if( pad->GetExController() != PAD::EXCONTROLLER_TURBOFILE )
return;
for( i = 0; i < sizeof(ERAM); i++ ) {
if( ERAM[i] != 0x00 )
break;
}
if( i < sizeof(ERAM) ) {
DEBUGOUT( "Saving TURBOFILE...\n" );
string pathstr, tempstr;
if( Config.path.bSavePath ) {
pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szSavePath );
::CreateDirectory( pathstr.c_str(), NULL );
} else {
pathstr = rom->GetRomPath();
}
tempstr = CPathlib::MakePathExt( pathstr.c_str(), "TurboFile", "vtf" );
DEBUGOUT( "Path: %s\n", tempstr.c_str() );
FILE* fp = NULL;
try
{
if( !(fp = ::fopen( tempstr.c_str(), "wb" )) ) {
// xxx 僼傽僀儖傪奐偗傑偣傫
LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN );
sprintf( szErrorString, szErrStr, tempstr.c_str() );
throw szErrorString;
}
if( ::fwrite( ERAM, sizeof(ERAM), 1, fp ) != 1 ) {
// 僼傽僀儖偺彂偒崬傒偵幐攕偟傑偟偨
throw CApp::GetErrorString( IDS_ERROR_WRITE );
}
DEBUGOUT( "Ok.\n" );
FCLOSE( fp );
} catch( CHAR* str ) {
DEBUGOUT( "Writing TurboFile Error.\n" );
FCLOSE( fp );
throw str;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -