コード例 #1
0
ファイル: Nsf_Impl.cpp プロジェクト: kode54/Cog
void Nsf_Impl::write_bank( int bank, int data )
{
	// Find bank in ROM
	int offset = rom.mask_addr( data * bank_size );
	if ( offset >= rom.size() )
		special_event( "invalid bank" );
	void const* rom_data = rom.at_addr( offset );
	
	#if !NSF_EMU_APU_ONLY
		if ( bank < bank_count - fds_banks && fds_enabled() )
		{
			// TODO: FDS bank switching is kind of hacky, might need to
			// treat ROM as RAM so changes won't get lost when switching.
			byte* out = sram();
			if ( bank >= fds_banks )
			{
				out = fdsram();
				bank -= fds_banks;
			}
			memcpy( &out [bank * bank_size], rom_data, bank_size );
			return;
		}
	#endif
	
	if ( bank >= fds_banks )
		cpu.map_code( (bank + 6) * bank_size, bank_size, rom_data );
}
コード例 #2
0
ファイル: Nsf_Impl.cpp プロジェクト: kode54/Cog
void Nsf_Impl::map_memory()
{
	// Map standard things
	cpu.reset( unmapped_code() );
	cpu.map_code( 0, 0x2000, low_ram, low_ram_size ); // mirrored four times
	cpu.map_code( sram_addr, sram_size, sram() );
	
	// Determine initial banks
	byte banks [bank_count];
	static byte const zero_banks [sizeof header_.banks] = { 0 };
	if ( memcmp( header_.banks, zero_banks, sizeof zero_banks ) )
	{
		banks [0] = header_.banks [6];
		banks [1] = header_.banks [7];
		memcpy( banks + fds_banks, header_.banks, sizeof header_.banks );
	}
	else
	{
		// No initial banks, so assign them based on load_addr
		int first_bank = (get_addr( header_.load_addr ) - sram_addr) / bank_size;
		unsigned total_banks = rom.size() / bank_size;
		for ( int i = bank_count; --i >= 0; )
		{
			int bank = i - first_bank;
			if ( (unsigned) bank >= total_banks )
				bank = 0;
			banks [i] = bank;
		}
	}
	
	// Map banks
	for ( int i = (fds_enabled() ? 0 : fds_banks); i < bank_count; ++i )
		write_bank( i, banks [i] );
	
	// Map FDS RAM
	if ( fds_enabled() )
		cpu.map_code( rom_addr, fdsram_size, fdsram() );
}
コード例 #3
0
ファイル: Nsf_Impl.cpp プロジェクト: kode54/Cog
blargg_err_t Nsf_Impl::load_( Data_Reader& in )
{
	// pad ROM data with 0
	RETURN_ERR( rom.load( in, header_.size, &header_, 0 ) );
	
	if ( !header_.valid_tag() )
		return blargg_err_file_type;
	
	RETURN_ERR( high_ram.resize( (fds_enabled() ? fdsram_offset + fdsram_size : fdsram_offset) ) );

	addr_t load_addr = get_addr( header_.load_addr );
	if ( load_addr < (fds_enabled() ? sram_addr : rom_addr) )
		set_warning( "Load address is too low" );
	
	rom.set_addr( load_addr % bank_size );
	
	if ( header_.vers != 1 )
		set_warning( "Unknown file version" );
	
	set_play_period( header_.play_period() );
	
	return blargg_ok;
}
コード例 #4
0
ファイル: Nsf_Cpu.cpp プロジェクト: Gardenya/deadbeef
void Nsf_Impl::write_mem( addr_t addr, int data )
{
    (void) LOG_MEM( addr, "<", data );

    int offset = addr - sram_addr;
    if ( (unsigned) offset < sram_size )
    {
        sram() [offset] = data;
    }
    else
    {
        // after sram because CPU handles most low_ram accesses internally already
        int temp = addr & (low_ram_size-1); // also handles wrap-around
        if ( !(addr & 0xE000) )
        {
            low_ram [temp] = data;
        }
        else
        {
            int bank = addr - banks_addr;
            if ( (unsigned) bank < bank_count )
            {
                write_bank( bank, data );
            }
            else if ( (unsigned) (addr - apu.io_addr) < apu.io_size )
            {
                apu.write_register( time(), addr, data );
            }
            else
            {
#if !NSF_EMU_APU_ONLY
                // 0x8000-0xDFFF is writable
                int i = addr - 0x8000;
                if ( (unsigned) i < fdsram_size && fds_enabled() )
                    fdsram() [i] = data;
                else
#endif
                    cpu_write( addr, data );
            }
        }
    }
}