AxibugEmuOnline/References/VirtuaNESex_src_191105/NES/ROM.cpp

720 lines
18 KiB
C++
Raw Normal View History

2024-08-05 17:58:53 +08:00
//////////////////////////////////////////////////////////////////////////
// //
// 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 "Archive.h"
#include "rom.h"
#include "romdb.h"
#include "mmu.h"
#include "mapper.h"
const char* img_fname; //for bbk
BOOL g_bSan2;
unsigned char pFont[256*1024];
INT g_UnfTVMode = -1;
#define MKID(a) ((unsigned long) \
(((a) >> 24) & 0x000000FF) | \
(((a) >> 8) & 0x0000FF00) | \
(((a) << 8) & 0x00FF0000) | \
(((a) << 24) & 0xFF000000))
//
// <20>R<EFBFBD><52><EFBFBD>X<EFBFBD>g<EFBFBD><67><EFBFBD>N<EFBFBD>^
//
ROM::ROM( const char* fname )
{
FILE *fp = NULL;
LPBYTE temp = NULL;
LPBYTE bios = NULL;
LONG FileSize;
g_bSan2 = FALSE;
ZEROMEMORY( &header, sizeof(header) );
ZEROMEMORY( path, sizeof(path) );
ZEROMEMORY( name, sizeof(name) );
bPAL = FALSE;
bNSF = FALSE;
NSF_PAGE_SIZE = 0;
board = 0;
bUnif = FALSE;
g_UnfTVMode = -1;
lpPRG = lpCHR = lpTrainer = lpDiskBios = lpDisk = NULL;
crc = crcall = 0;
mapper = 0;
diskno = 0;
try {
//for bbk-------------------------------------------------------------------------
if( !(fp = ::fopen( fname, "rb" )) ) {
LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN );
::wsprintf( szErrorString, szErrStr, fname );
throw szErrorString;
}
::fseek( fp, 0, SEEK_END );
FileSize = ::ftell( fp );
::fseek( fp, 0, SEEK_SET );
if( !(temp = (LPBYTE)::malloc( FileSize )) ) {
throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY );
}
if( ::fread( temp, FileSize, 1, fp ) != 1 ) {
throw CApp::GetErrorString( IDS_ERROR_READ );
}
FCLOSE( fp );
::memcpy( &header, temp, sizeof(NESHEADER) );
if( header.ID[0] == 0xEB && header.ID[1] == 0x3C
&& header.ID[2] == 0x90 && header.ID[3] == 0x53 ) {
img_fname = fname;
// DEBUGOUT( "img_fname: %s\n", img_fname );
fname = "bbk_bios10.rom";
} else {
FREE( temp );
}
//--------------------------------------------------------------------------------
if( !(fp = ::fopen( fname, "rb" )) ) {
// xxx <20>t<EFBFBD>@<40>C<EFBFBD><43><EFBFBD><EFBFBD><EFBFBD>J<EFBFBD><4A><EFBFBD>܂<EFBFBD><DC82><EFBFBD>
LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN );
::wsprintf( szErrorString, szErrStr, fname );
throw szErrorString;
}
// <20>t<EFBFBD>@<40>C<EFBFBD><43><EFBFBD>T<EFBFBD>C<EFBFBD>Y<EFBFBD>
::fseek( fp, 0, SEEK_END );
FileSize = ::ftell( fp );
::fseek( fp, 0, SEEK_SET );
// <20>t<EFBFBD>@<40>C<EFBFBD><43><EFBFBD>T<EFBFBD>C<EFBFBD>Y<EFBFBD>`<60>F<EFBFBD>b<EFBFBD>N(NES<45>w<EFBFBD>b<EFBFBD>_+1<>o<EFBFBD>C<EFBFBD>g<EFBFBD>ȏォ<C88F>H)
if( FileSize < 17 ) {
// <20>t<EFBFBD>@<40>C<EFBFBD><43><EFBFBD>T<EFBFBD>C<EFBFBD>Y<EFBFBD><59><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>܂<EFBFBD>
throw CApp::GetErrorString( IDS_ERROR_SMALLFILE );
}
// <20>e<EFBFBD><65><EFBFBD>|<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>m<EFBFBD><6D>
if( !(temp = (LPBYTE)::malloc( FileSize )) ) {
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>m<EFBFBD>ۏo<DB8F><6F><EFBFBD>܂<EFBFBD><DC82><EFBFBD>
throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY );
}
// <20>T<EFBFBD>C<EFBFBD>Y<EFBFBD><59><EFBFBD>ǂݍ<C782><DD8D><EFBFBD>
if( ::fread( temp, FileSize, 1, fp ) != 1 ) {
// <20>t<EFBFBD>@<40>C<EFBFBD><43><EFBFBD>̓ǂݍ<C782><DD8D>݂Ɏ<DD82><C98E>s<EFBFBD><73><EFBFBD>܂<EFBFBD><DC82><EFBFBD>
throw CApp::GetErrorString( IDS_ERROR_READ );
}
FCLOSE( fp );
// <20>w<EFBFBD>b<EFBFBD>_<EFBFBD>R<EFBFBD>s<EFBFBD>[
::memcpy( &header, temp, sizeof(NESHEADER) );
header.CHR_PAGE_SIZE = header.CHR_PAGE_SIZE_old;
header.PRG_PAGE_SIZE = header.PRG_PAGE_SIZE_old;
if( header.ID[0] == 'N' && header.ID[1] == 'E'
&& header.ID[2] == 'S' && header.ID[3] == 0x1A ) {
// <20>w<EFBFBD>b<EFBFBD>_<EFBFBD>R<EFBFBD>s<EFBFBD>[
memcpy( &header, temp, sizeof(NESHEADER) );
header.CHR_PAGE_SIZE = header.CHR_PAGE_SIZE_old;
header.PRG_PAGE_SIZE = header.PRG_PAGE_SIZE_old;
} else if( header.ID[0] == 'F' && header.ID[1] == 'D'
&& header.ID[2] == 'S' && header.ID[3] == 0x1A ) {
// <20>w<EFBFBD>b<EFBFBD>_<EFBFBD>R<EFBFBD>s<EFBFBD>[
memcpy( &header, temp, sizeof(NESHEADER) );
header.CHR_PAGE_SIZE = header.CHR_PAGE_SIZE_old;
header.PRG_PAGE_SIZE = header.PRG_PAGE_SIZE_old;
} else if( header.ID[0] == 'N' && header.ID[1] == 'E'
&& header.ID[2] == 'S' && header.ID[3] == 'M') {
// <20>w<EFBFBD>b<EFBFBD>_<EFBFBD>R<EFBFBD>s<EFBFBD>[
memcpy( &header, temp, sizeof(NESHEADER) );
header.CHR_PAGE_SIZE = header.CHR_PAGE_SIZE_old;
header.PRG_PAGE_SIZE = header.PRG_PAGE_SIZE_old;
} else if( header.ID[0] == 'U' && header.ID[1] == 'N'
&& header.ID[2] == 'I' && header.ID[3] == 'F') {
//<2F><><EFBFBD><EFBFBD>Unif ROM
} else {
FREE( temp );
if( !UnCompress( fname, &temp, (LPDWORD)&FileSize ) ) {
// <20><><EFBFBD>Ή<EFBFBD><CE89>`<60><><EFBFBD>ł<EFBFBD>
throw CApp::GetErrorString( IDS_ERROR_UNSUPPORTFORMAT );
}
// <20>w<EFBFBD>b<EFBFBD>_<EFBFBD>R<EFBFBD>s<EFBFBD>[
::memcpy( &header, temp, sizeof(NESHEADER) );
header.CHR_PAGE_SIZE = header.CHR_PAGE_SIZE_old;
header.PRG_PAGE_SIZE = header.PRG_PAGE_SIZE_old;
}
DWORD PRGoffset, CHRoffset;
LONG PRGsize, CHRsize;
BYTE *pUnif = temp;
DWORD filesize = FileSize;
if( header.ID[0] == 'N' && header.ID[1] == 'E'
&& header.ID[2] == 'S' && header.ID[3] == 0x1A ) {
// <20><><EFBFBD>ʂ<EFBFBD>NES<45>t<EFBFBD>@<40>C<EFBFBD><43>
PRGsize = (LONG)header.PRG_PAGE_SIZE*0x4000;
CHRsize = (LONG)header.CHR_PAGE_SIZE*0x2000;
PRGoffset = sizeof(NESHEADER);
CHRoffset = PRGoffset + PRGsize;
//for Game Star - Smart Genius (Unl)
if(header.PRG_PAGE_SIZE==0xff)
PRGsize = (LONG)(header.PRG_PAGE_SIZE+1)*0x4000;
if( IsTRAINER() ) {
PRGoffset += 512;
CHRoffset += 512;
}
if( PRGsize <= 0 || (PRGsize+CHRsize) > FileSize ) {
// NES<45>w<EFBFBD>b<EFBFBD>_<EFBFBD><5F><EFBFBD>ُ<EFBFBD><D98F>ł<EFBFBD>
throw CApp::GetErrorString( IDS_ERROR_INVALIDNESHEADER );
}
// PRG BANK
if( !(lpPRG = (LPBYTE)malloc( PRGsize )) ) {
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>m<EFBFBD>ۏo<DB8F><6F><EFBFBD>܂<EFBFBD><DC82><EFBFBD>
throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY );
}
::memcpy( lpPRG, temp+PRGoffset, PRGsize );
// CHR BANK
if( CHRsize > 0 ) {
if( !(lpCHR = (LPBYTE)malloc( CHRsize )) ) {
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>m<EFBFBD>ۏo<DB8F><6F><EFBFBD>܂<EFBFBD><DC82><EFBFBD>
throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY );
}
if( FileSize >= CHRoffset+CHRsize ) {
memcpy( lpCHR, temp+CHRoffset, CHRsize );
} else {
// CHR<48>o<EFBFBD><6F><EFBFBD>N<EFBFBD><4E><EFBFBD>Ȃ<EFBFBD><C882>c
CHRsize -= (CHRoffset+CHRsize - FileSize);
memcpy( lpCHR, temp+CHRoffset, CHRsize );
}
} else {
lpCHR = NULL;
}
// Trainer
if( IsTRAINER() ) {
if( !(lpTrainer = (LPBYTE)malloc( 512 )) ) {
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>m<EFBFBD>ۏo<DB8F><6F><EFBFBD>܂<EFBFBD><DC82><EFBFBD>
throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY );
}
memcpy( lpTrainer, temp+sizeof(NESHEADER), 512 );
} else {
lpTrainer = NULL;
}
} else if( header.ID[0] == 'U' && header.ID[1] == 'N'
&& header.ID[2] == 'I' && header.ID[3] == 'F' ) {
DWORD Signature, BlockLen;
DWORD ipos =0x20;//<2F><><EFBFBD><EFBFBD>UNIFͷ
BYTE id,i;
BYTE *tPRG[0x10], *tCHR[0x10];
DWORD sizePRG[0x10],sizeCHR[0x10];
//char info[100];
//char name[100];
PRGsize = 0x00;
CHRsize = 0x00;
header.ID[0] = 'N';
header.ID[1] = 'E';
header.ID[2] = 'S';
header.ID[3] = 0x1A;
board = 0;
bUnif = TRUE;
// header.PRG_PAGE_SIZE = (BYTE)diskno*4;
// header.CHR_PAGE_SIZE = 0;
// header.control1 = 0x40;
// header.control2 = 0x10;
header.control1 = 0;
header.control2 = 0;
for (i = 0; i < 0x10; i++)
{
tPRG[i] = tCHR[i] = 0;
}
//filesize
while(ipos<filesize)
{
id = 0;
memcpy(&Signature,&pUnif[ipos],4);ipos+=4;
memcpy(&BlockLen,&pUnif[ipos],4);ipos+=4;
switch(Signature)
{
case MKID('MAPR')://board<72><64><EFBFBD><EFBFBD>
memcpy( pboardname, &pUnif[ipos], BlockLen);
pboardname[BlockLen]=0;
//memcpy( info, &pUnif[ipos], BlockLen);
//fl.info = info;
ipos+=BlockLen; break;
case MKID('NAME'):
//memcpy( pboardname, &pUnif[ipos], BlockLen);
//fl.title = name;
ipos+=BlockLen; break;
case MKID('TVCI')://<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ
g_UnfTVMode = pUnif[ipos];
ipos+=BlockLen; break;
case MKID('BATR')://ʹ<>õ<EFBFBD><C3B5>ؼ<EFBFBD><D8BC><EFBFBD>
header.control1 |=2;
ipos+=BlockLen; break;
case MKID('FONT')://<2F>ֿ<EFBFBD>
// memcpy( pFont, &pUnif[ipos], BlockLen>65536?65536:BlockLen );
memcpy( pFont, &pUnif[ipos], BlockLen );
ipos+=BlockLen; break;
case MKID('MIRR'):
if (pUnif[ipos]==0)
header.control1 &=14;
else if (pUnif[ipos]==1)
header.control1 |=1;
ipos+=BlockLen;
break;
case MKID('PRGF'): id++;
case MKID('PRGE'): id++;
case MKID('PRGD'): id++;
case MKID('PRGC'): id++;
case MKID('PRGB'): id++;
case MKID('PRGA'): id++;
case MKID('PRG9'): id++;
case MKID('PRG8'): id++;
case MKID('PRG7'): id++;
case MKID('PRG6'): id++;
case MKID('PRG5'): id++;
case MKID('PRG4'): id++;
case MKID('PRG3'): id++;
case MKID('PRG2'): id++;
case MKID('PRG1'): id++;
case MKID('PRG0'):
sizePRG[id] = BlockLen;
tPRG[id] = (BYTE*)malloc(BlockLen);
memcpy( tPRG[id], &pUnif[ipos], BlockLen );
ipos+=BlockLen;
PRGsize += BlockLen;
break;
case MKID('CHRF'): id++;
case MKID('CHRE'): id++;
case MKID('CHRD'): id++;
case MKID('CHRC'): id++;
case MKID('CHRB'): id++;
case MKID('CHRA'): id++;
case MKID('CHR9'): id++;
case MKID('CHR8'): id++;
case MKID('CHR7'): id++;
case MKID('CHR6'): id++;
case MKID('CHR5'): id++;
case MKID('CHR4'): id++;
case MKID('CHR3'): id++;
case MKID('CHR2'): id++;
case MKID('CHR1'): id++;
case MKID('CHR0'):
sizeCHR[id] = BlockLen;
tCHR[id] = (BYTE*)malloc(BlockLen);
memcpy( tCHR[id], &pUnif[ipos], BlockLen );
ipos+=BlockLen;
CHRsize += BlockLen;
break;
default:
ipos+=BlockLen; break;
}
}
//fl.mapper = 0;
//fl.prg_size = 0;
//fl.chr_size = 0;
board = NES_ROM_get_unifBoardID(pboardname);
header.PRG_PAGE_SIZE = PRGsize/(16*1024);
header.CHR_PAGE_SIZE = CHRsize/(8*1024);
DWORD LenPRG=0,LenCHR=0;
if(PRGsize)
lpPRG = (LPBYTE)malloc( PRGsize );
if(CHRsize)
lpCHR = (LPBYTE)malloc( CHRsize );
for (i = 0; i < 16; i++)
{
if (tPRG[i])
{
memcpy(&lpPRG[LenPRG], tPRG[i], sizePRG[i]);
LenPRG += sizePRG[i];
//fl.prg_size += sizePRG[i]>>14;
//PRGsize = PRGsize+LenPRG;
free(tPRG[i]);
}
if (tCHR[i])
{
memcpy(&lpCHR[LenCHR], tCHR[i], sizeCHR[i]);
LenCHR += sizeCHR[i];
//fl.chr_size = (fl.chr_size)+(sizeCHR[i]>>13);
//CHRsize = CHRsize+LenCHR;
free(tCHR[i]);
}
}
} else if( header.ID[0] == 'F' && header.ID[1] == 'D'
&& header.ID[2] == 'S' && header.ID[3] == 0x1A ) {
// FDS(Nintendo Disk System)
// <20>f<EFBFBD>B<EFBFBD>X<EFBFBD>N<EFBFBD>T<EFBFBD>C<EFBFBD>Y
diskno = header.PRG_PAGE_SIZE;
if( FileSize < (16+65500*diskno) ) {
// <20>f<EFBFBD>B<EFBFBD>X<EFBFBD>N<EFBFBD>T<EFBFBD>C<EFBFBD>Y<EFBFBD><59><EFBFBD>ُ<EFBFBD><D98F>ł<EFBFBD>
throw CApp::GetErrorString( IDS_ERROR_ILLEGALDISKSIZE );
}
if( diskno > 4 ) {
// 4<>ʂ<EFBFBD><CA82><EFBFBD><E891BD><EFBFBD>f<EFBFBD>B<EFBFBD>X<EFBFBD>N<EFBFBD>͑Ή<CD91><CE89><EFBFBD><EFBFBD>Ă<EFBFBD><C482>܂<EFBFBD><DC82><EFBFBD>
throw CApp::GetErrorString( IDS_ERROR_UNSUPPORTDISK );
}
ZEROMEMORY( &header, sizeof(NESHEADER) );
// <20>_<EFBFBD>~<7E>[<5B>w<EFBFBD>b<EFBFBD>_<EFBFBD><5F><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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 )) ) {
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>m<EFBFBD>ۏo<DB8F><6F><EFBFBD>܂<EFBFBD><DC82><EFBFBD>
throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY );
}
// <20>f<EFBFBD>[<5B>^<5E>̃o<CC83>b<EFBFBD>N<EFBFBD>A<EFBFBD>b<EFBFBD>v<EFBFBD>p
if( !(lpDisk = (LPBYTE)malloc( PRGsize )) ) {
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>m<EFBFBD>ۏo<DB8F><6F><EFBFBD>܂<EFBFBD><DC82><EFBFBD>
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 );
// <20>f<EFBFBD>[<5B>^<5E>̏<EFBFBD><CC8F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EA8F8A><EFBFBD><EFBFBD><EFBFBD>p
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 BIOS<4F>̃<EFBFBD><CC83>[<5B>h
string Path = CPathlib::MakePathExt( CApp::GetModulePath(), "DISKSYS", "ROM" );
if( !(fp = fopen( Path.c_str(), "rb" )) ) {
// DISKSYS.ROM<4F><4D><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>܂<EFBFBD><DC82><EFBFBD>
throw CApp::GetErrorString( IDS_ERROR_NODISKBIOS );
}
::fseek( fp, 0, SEEK_END );
FileSize = ::ftell( fp );
::fseek( fp, 0, SEEK_SET );
if( FileSize < 17 ) {
// <20>t<EFBFBD>@<40>C<EFBFBD><43><EFBFBD>T<EFBFBD>C<EFBFBD>Y<EFBFBD><59><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>܂<EFBFBD>
throw CApp::GetErrorString( IDS_ERROR_SMALLFILE );
}
if( !(bios = (LPBYTE)malloc( FileSize )) ) {
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>m<EFBFBD>ۏo<DB8F><6F><EFBFBD>܂<EFBFBD><DC82><EFBFBD>
throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY );
}
if( fread( bios, FileSize, 1, fp ) != 1 ) {
// <20>t<EFBFBD>@<40>C<EFBFBD><43><EFBFBD>̓ǂݍ<C782><DD8D>݂Ɏ<DD82><C98E>s<EFBFBD><73><EFBFBD>܂<EFBFBD><DC82><EFBFBD>
throw CApp::GetErrorString( IDS_ERROR_READ );
}
FCLOSE( fp );
if( !(lpDiskBios = (LPBYTE)malloc( 8*1024 )) ) {
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>m<EFBFBD>ۏo<DB8F><6F><EFBFBD>܂<EFBFBD><DC82><EFBFBD>
throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY );
}
if( bios[0] == 'N' && bios[1] == 'E' && bios[2] == 'S' && bios[3] == 0x1A ) {
// NES<45>`<60><>BIOS
::memcpy( lpDiskBios, bios+0x6010, 8*1024 );
} else {
// <20><>BIOS
::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) );
// <20>w<EFBFBD>b<EFBFBD>_<EFBFBD>R<EFBFBD>s<EFBFBD>[
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 )) ) {
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>m<EFBFBD>ۏo<DB8F><6F><EFBFBD>܂<EFBFBD><DC82><EFBFBD>
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 {
// <20><><EFBFBD>Ή<EFBFBD><CE89>`<60><><EFBFBD>ł<EFBFBD>
throw CApp::GetErrorString( IDS_ERROR_UNSUPPORTFORMAT );
}
// <20>p<EFBFBD>X/<2F>t<EFBFBD>@<40>C<EFBFBD><43><EFBFBD><EFBFBD><EFBFBD>
{
string tempstr;
tempstr = CPathlib::SplitPath( fname );
::strcpy( path, tempstr.c_str() );
tempstr = CPathlib::SplitFname( fname );
::strcpy( name, tempstr.c_str() );
// <20>I<EFBFBD><49><EFBFBD>W<EFBFBD>i<EFBFBD><69><EFBFBD>t<EFBFBD>@<40>C<EFBFBD><43><EFBFBD><EFBFBD>(<28>t<EFBFBD><74><EFBFBD>p<EFBFBD>X)
::strcpy( fullpath, fname );
}
// <20>}<7D>b<EFBFBD>p<EFBFBD>ݒ<EFBFBD>
if( !bNSF ) {
mapper = (header.control1>>4)|(header.control2&0xF0);
crc = crcall = crcvrom = 0;
if( mapper != 20 ) {
// PRG crc<72>̌v<CC8C>Z(NesToy<6F><79>PRG CRC<52>Ɠ<EFBFBD><C693><EFBFBD>)
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);
}
if(bUnif){
mapper = board;
crc = CRC::CrcRev( PRGsize, lpPRG );
if( CHRsize )
crcvrom = CRC::CrcRev( CHRsize, lpCHR );
}
} else {
// NSF
mapper = 0x0100; // Private mapper
crc = crcall = crcvrom = 0;
fdsmakerID = fdsgameID = 0;
}
FREE( temp );
} catch( CHAR* str ) {
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><ED82A9><EFBFBD>Ă<EFBFBD><C482><EFBFBD><EFBFBD>G<EFBFBD><47><EFBFBD>[<5B><><EFBFBD><EFBFBD>
FCLOSE( fp );
FREE( temp );
FREE( bios );
FREE( lpPRG );
FREE( lpCHR );
FREE( lpTrainer );
FREE( lpDiskBios );
FREE( lpDisk );
throw str;
#ifndef _DEBUG
} catch(...) {
// <20><><EFBFBD>ʕی<CA95><DB8C>G<EFBFBD><47><EFBFBD>[<5B>Ƃ<EFBFBD><C682>o<EFBFBD><6F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̂<EFBFBD>...(^^;
FCLOSE( fp );
FREE( temp );
FREE( bios );
FREE( lpPRG );
FREE( lpCHR );
FREE( lpTrainer );
FREE( lpDiskBios );
FREE( lpDisk );
#ifdef _DATATRACE
// For dis...
FREE( PROM_ACCESS );
#endif
// <20>s<EFBFBD><73><EFBFBD>ȃG<C883><47><EFBFBD>[<5B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>܂<EFBFBD><DC82><EFBFBD>
throw CApp::GetErrorString( IDS_ERROR_UNKNOWN );
#endif // !_DEBUG
}
}
//
// <20>f<EFBFBD>X<EFBFBD>g<EFBFBD><67><EFBFBD>N<EFBFBD>^
//
ROM::~ROM()
{
FREE( lpPRG );
FREE( lpCHR );
FREE( lpTrainer );
FREE( lpDiskBios );
FREE( lpDisk );
}
//
// ROM<4F>t<EFBFBD>@<40>C<EFBFBD><43><EFBFBD>`<60>F<EFBFBD>b<EFBFBD>N
//
INT ROM::IsRomFile( const char* fname )
{
FILE* fp = NULL;
NESHEADER header;
if( !(fp = fopen( fname, "rb" )) )
return IDS_ERROR_OPEN;
// <20>T<EFBFBD>C<EFBFBD>Y<EFBFBD><59><EFBFBD>ǂݍ<C782><DD8D><EFBFBD>
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 < 4; 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] == 'U' && header.ID[1] == 'N'
&& header.ID[2] == 'I' && header.ID[3] == 'F' ) {
return 0;
} else if( header.ID[0] == 'N' && header.ID[1] == 'E'
&& header.ID[2] == 'S' && header.ID[3] == 'M' ) {
return 0;
} else if( header.ID[0] == 0xEB && header.ID[1] == 0x3C //BBK
&& header.ID[2] == 0x90 && header.ID[3] == 0x53 ) {
return 0;
} else {
LPBYTE temp = NULL;
LONG size;
if( !UnCompress( fname, &temp, (LPDWORD)&size ) )
return IDS_ERROR_UNSUPPORTFORMAT;
memcpy( &header, temp, sizeof(NESHEADER) );
header.CHR_PAGE_SIZE = header.CHR_PAGE_SIZE_old;
header.PRG_PAGE_SIZE = header.PRG_PAGE_SIZE_old;
FREE( temp );
if( header.ID[0] == 'N' && header.ID[1] == 'E'
&& header.ID[2] == 'S' && header.ID[3] == 0x1A ) {
for( INT i = 0; i < 4; i++ ) {
if( header.reserved[i] )
return IDS_ERROR_ILLEGALHEADER;
}
return 0;
} else if( header.ID[0] == 'U' && header.ID[1] == 'N'
&& header.ID[2] == 'I' && header.ID[3] == 'F' ) {
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 if( header.ID[0] == 0xEB && header.ID[1] == 0x3C //BBK
&& header.ID[2] == 0x90 && header.ID[3] == 0x53 ) {
return 0;
}
}
return IDS_ERROR_UNSUPPORTFORMAT;
}
//
// ROM<4F>t<EFBFBD>@<40>C<EFBFBD><43><EFBFBD><EFBFBD><EFBFBD>̃`<60>F<EFBFBD>b<EFBFBD>N(PAL<41><4C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
//
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);
}
}