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 ); } } } }
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() ); }