⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mappernsf.cpp

📁 著名的任天堂FC游戏机模拟器VirtuaNes 085版的源码!
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	SetPROM_Bank( 5, WRAM+0x4000, BANKTYPE_RAM );	// A000-BFFF
	SetPROM_Bank( 6, WRAM+0x6000, BANKTYPE_RAM );	// C000-DFFF
	SetPROM_Bank( 7, WRAM+0x8000, BANKTYPE_RAM );	// E000-FFFF

	nsfheader = *(nes->rom->GetNsfHeader());
	exchip = nsfheader.ExtraChipSelect;
	banksize = nes->rom->GetNSF_SIZE();

	if( (songno = nsfheader.StartSong-1) >= nsfheader.TotalSong ) {
		songno = 0;
	}

	bankswitch = 0;
	for( i = 0; i < 8; i++ ) {
		bankswitch |= nsfheader.BankSwitch[i];
	}

	if( bankswitch ) {
	// Bankswitch on
		BYTE	start_bank = nsfheader.LoadAddress>>12;
		for( i = 0; (start_bank+i) < 8; i++ ) {
			BankSwitch( start_bank+i, i );
		}
		for( i = 0; i < 8; i++ ) {
			BankSwitch( i+8, nsfheader.BankSwitch[i] );
		}
		if( exchip&0x04 ) {
			BankSwitch( 6, nsfheader.BankSwitch[6] );
			BankSwitch( 7, nsfheader.BankSwitch[7] );
		}
	} else {
	// Bankswitch off
		LPBYTE	pPtr = nes->rom->GetPROM();
		if( banksize < 8 ) {
			for( i = 0; i < 0x1000*banksize; i++ ) {
				if( nsfheader.LoadAddress-0x8000+i < 0x8000 ) {
					WRAM[0x2000+nsfheader.LoadAddress-0x8000+i] = pPtr[i];
				}
			}
		} else {
			for( i = 0; i < 0x8000; i++ ) {
				if( nsfheader.LoadAddress-0x8000+i < 0x8000 ) {
					WRAM[0x2000+nsfheader.LoadAddress-0x8000+i] = pPtr[i];
				}
			}
		}
	}

	// $4700偼懸婡柍尷儖乕僾
	WRAM[0xA700] = 0x4c;	//jmp
	WRAM[0xA701] = 0x00;
	WRAM[0xA702] = 0x47;

	// $4710偼Init儖乕僠儞傪屇傫偩屻柍尷儖乕僾傊
	WRAM[0xA710] = 0x20;	// jsr
	WRAM[0xA711] = (BYTE) nsfheader.InitAddress & 0xFF;
	WRAM[0xA712] = (BYTE)(nsfheader.InitAddress>>8);
	WRAM[0xA713] = 0x4c;	// jmp
	WRAM[0xA714] = 0x00;
	WRAM[0xA715] = 0x47;
	
	// $4720偼Play儖乕僠儞傪屇傫偩屻柍尷儖乕僾傊
#if	NSF_PROFILE
	WRAM[0xA720] = 0x8D;	// sta
	WRAM[0xA721] = 0x1E;	// $401E
	WRAM[0xA722] = 0x40;	// $401E

	WRAM[0xA723] = 0x20;	// jsr
	WRAM[0xA724] = (BYTE) nsfheader.PlayAddress;
	WRAM[0xA725] = (BYTE)(nsfheader.PlayAddress>>8);

	WRAM[0xA726] = 0x8D;	// sta
	WRAM[0xA727] = 0x1F;	// $401F
	WRAM[0xA728] = 0x40;	// $401F

	WRAM[0xA729] = 0x4c;	//jmp
	WRAM[0xA72A] = 0x00;
	WRAM[0xA72B] = 0x47;
#else
	WRAM[0xA720] = 0x20;	// jsr
	WRAM[0xA721] = (BYTE) nsfheader.PlayAddress;
	WRAM[0xA722] = (BYTE)(nsfheader.PlayAddress>>8);
	WRAM[0xA723] = 0x4c;	//jmp
	WRAM[0xA724] = 0x00;
	WRAM[0xA725] = 0x47;
#endif

	nes->apu->SelectExSound( exchip );
	nes->apu->Write( 0x4015, 0x1F );
	nes->apu->ExWrite( 0x4080, 0x80 );	// FDS Volume 0
	nes->apu->ExWrite( 0x408A, 0xE8 );	// FDS Envelope ON

	// For DQ1/2??
	nes->SetFrameIRQmode( FALSE );

	// NTSC/PAL tune
	nes->SetVideoMode( (nsfheader.NTSC_PALbits&0x01)?TRUE:FALSE );

	// 廃攇悢->Key僥乕僽儖偺嶌惉
	for( i = 0; i < 12*8+1; i++ ) {
		Freq2KeyTbl[i] = (INT)(440.0*256.0*pow(2.0,((double)(i-45)-0.5)/12.0));
	}

	// 偍傑偗
	StarInitial();

	//
#if	NSF_PROFILE
	avecount = 0;
	tave = 0.0f;
	pave = 0.0f;
	ptave = 0.0f;
	maxtotalclk = 0;
	maxprofclk = 0;
	maxproftotalclk = 0;
	maxproftotalcnt = 0;
#endif
}

BYTE	MapperNSF::ExRead( WORD addr )
{
BYTE	data = 0;

	if( addr >= 0x4040 && addr < 0x4100 ) {
		data = nes->apu->ExRead( addr );
	}
	return	data;
}

void	MapperNSF::ExWrite( WORD addr, BYTE data )
{
	if( addr >= 0x4040 && addr < 0x4100 ) {
		nes->apu->ExWrite( addr, data );
	}
}

BYTE	MapperNSF::ReadLow( WORD addr )
{
	if( addr == 0x4800 ) {
		BYTE	data = exram[exaddr&0x7F];
		if( exaddr&0x80 )
			exaddr = (exaddr+1)|0x80;
		nes->apu->ExRead( addr );
		return	data;
	} else if( addr == 0x5205 ) {	// MMC5
		return	(BYTE)multipul[0]*multipul[1];
	} else if( addr == 0x5206 ) {	// MMC5
		return	(BYTE)(((WORD)multipul[0]*(WORD)multipul[1])>>8);
	}
//	if( addr >= 0x47A0 && addr < 0x4800 ) {
//		return	WRAM[addr+0x6000];
//	}
	if( addr >= 0x5C00 && addr < 0x5FFF ) {	// MMC5
		return	DRAM[addr-0x5C00];
	}
	if( addr >= 0x6000 ) {
		return	WRAM[addr-0x6000];
	}

	return	(BYTE)(addr>>8);
}

void	MapperNSF::WriteLow( WORD addr, BYTE data )
{
	if( addr == 0x4800 || (addr >= 0x5000 && addr <= 0x5015) ) {
//DEBUGOUT( "$4800 WR=%02X\n", data );
		exram[exaddr&0x7F] = data;
		if( exaddr&0x80 )
			exaddr = (exaddr+1)|0x80;
		nes->apu->ExWrite( addr, data );
	} else if( addr == 0x5205 ) {	// MMC5
		multipul[0] = data;
	} else if( addr == 0x5206 ) {	// MMC5
		multipul[1] = data;
	} else if( addr >= 0x5C00 && addr < 0x5FF6 ) {	// MMC5
		DRAM[addr-0x5C00] = data;
	}
//	if( addr >= 0x47A0 && addr < 0x4800 ) {
//		WRAM[addr+0x6000] = data;
//	}
	if( addr >= 0x5FF6 && addr <= 0x5FFF ) {
	// Bank switch
		BankSwitch( addr&0x0F, data );
	}
	if( addr >= 0x6000 ) {
		WRAM[addr-0x6000] = data;

		nes->apu->ExWrite( addr, data );
	}
}

void	MapperNSF::Write( WORD addr, BYTE data )
{
	if( (exchip&0x04) ) {
		WRAM[addr-0x6000] = data;
	}
	nes->apu->ExWrite( addr, data );
	if( addr == 0xF800 ) {
		exaddr = data;
	}
}

void	MapperNSF::BankSwitch( INT no, BYTE bank )
{
INT	i;
INT	addr, offs;
LPBYTE	pPtr;

	offs = 0x1000*(INT)bank-(INT)(nsfheader.LoadAddress&0x0FFF);
	pPtr = nes->rom->GetPROM();

	if( no == 6 || no == 7 ) {
		for( i = 0; i < 0x1000; i++ ) {
			addr = offs+i;
			if( addr < 0 || addr > (4096*banksize)-1 ) {
				WRAM[0x1000*(no&1)+i] = 0;
			} else {
				WRAM[0x1000*(no&1)+i] = pPtr[addr];
			}
		}
	} else if( no >= 8 && no <= 15 ) {
		for( i = 0; i < 0x1000; i++ ) {
			addr = offs+i;
			if( addr < 0 || addr > (4096*banksize)-1 ) {
				WRAM[0x2000+0x1000*(no&7)+i] = 0;
			} else {
				WRAM[0x2000+0x1000*(no&7)+i] = pPtr[addr];
			}
		}
	}
}

void	MapperNSF::VSync()
{
	// 僨乕僞愝掕
	padold = pad;
	pad = nes->pad->GetNsfController();
	BYTE	padpush = ~padold & pad;

	if( padpush ) {
		repcnt = 20;
	} else if( pad ) {
		if( --repcnt == 0 ) {
			repcnt = 8;
			padpush |= pad & 0xFC;
		}
	}

	// -1
	if( padpush & (1<<2) ) {
		if( --songno < 0 ) {
			songno = nsfheader.TotalSong-1;
		}
	}
	// +1
	if( padpush & (1<<3) ) {
		if( ++songno >= nsfheader.TotalSong ) {
			songno = 0;
		}
	}
	// -16
	if( padpush & (1<<4) ) {
		if( (songno-=16) < 0 ) {
			while( songno < 0 ) {
				songno += nsfheader.TotalSong;
			}
			songno %= nsfheader.TotalSong;
		}
	}
	// +16
	if( padpush & (1<<5) ) {
		if( (songno+=16) >= nsfheader.TotalSong ) {
			songno -= nsfheader.TotalSong;
			songno %= nsfheader.TotalSong;
		}
	}

	// Play
	if( padpush & (1<<0) ) {
		nes->SetNsfPlay( songno, 0 );
	}

	// Stop
	if( padpush & (1<<1) ) {
		nes->SetNsfStop();
	}

	// 偍傑偗
	Star();

	// Drawing screen
//	DrawString( 10, 16, "TITLE :", 0x30 );
//	DrawString( 10, 31, "ARTIST:", 0x30 );
//	DrawString( 10, 46, "(C)   :", 0x30 );
//	DrawString( 10, 61, "NO    :", 0x30 );

	DrawString( 10, 16, "Title :", 0x30 );
	DrawString( 10, 31, "Artist:", 0x30 );
	DrawString( 10, 46, "(C)   :", 0x30 );
	DrawString( 10, 61, "No    :", 0x30 );

	DrawString( 28,  76, "Keyboard", 0x30 );
	DrawString( 32, 152, "Wave View", 0x30 );

	// 僞僀僩儖側偳
	CHAR	str[64];
	memcpy( str, nsfheader.SongName, 32 );
	str[32] = 0;
	DrawString(  53,  16, str, 0x30 );
	memcpy( str, nsfheader.ArtistName, 32 );
	str[32] = 0;
	DrawString(  53,  31, str, 0x30 );
	memcpy( str, nsfheader.CopyrightName, 32 );
	str[32] = 0;
	DrawString(  53,  46, str, 0x30 );
	// Song no
	sprintf( str, "%02X", songno );
	DrawString(  53,  61, str, 0x30 );

	// Extra sound
	DrawString( 76+6* 0,  61, "VRC6", (exchip&0x01)?0x2B:0x2D );
	DrawString( 76+6* 5,  61, "VRC7", (exchip&0x02)?0x2B:0x2D );
	DrawString( 76+6*10,  61, "FDS",  (exchip&0x04)?0x2B:0x2D );
	DrawString( 76+6*14,  61, "MMC5", (exchip&0x08)?0x2B:0x2D );
	DrawString( 76+6*19,  61, "N106", (exchip&0x10)?0x2B:0x2D );
	DrawString( 76+6*24,  61, "FME7", (exchip&0x20)?0x2B:0x2D );

	// 僞僀僩儖側偳偺儔僀儞
	DrawRect(  52, 24, 243-52,   0, 0x30 );
	DrawRect(  52, 39, 243-52,   0, 0x30 );
	DrawRect(  52, 54, 243-52,   0, 0x30 );
	DrawRect(  52, 69, 12,       0, 0x30 );
	DrawRect(  75, 69, 243-75,   0, 0x30 );

	// 僉乕儃乕僪榞
	DrawRect(  27,  84, 229-27, 148- 84, 0x30 );

	// WAVEVIEW榞
#if	!NSF_PROFILE
	DrawRect(  31, 160, 224-31, 224-160, 0x30 );
	DrawRect(  32, 192, 223-32, 0,       0x27 );

	// Wave
	DrawWave( 28+4, 192, 0x2A );
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -