1 // Nintendo NES/Famicom NSF music file emulator 2 3 // Game_Music_Emu 0.5.5 4 #ifndef NSF_EMU_H 5 #define NSF_EMU_H 6 7 #include "Classic_Emu.h" 8 #include "Nes_Apu.h" 9 #include "Nes_Cpu.h" 10 11 class Nsf_Emu : private Nes_Cpu, public Classic_Emu { 12 typedef Nes_Cpu cpu; 13 public: 14 // Equalizer profiles for US NES and Japanese Famicom 15 static equalizer_t const nes_eq; 16 static equalizer_t const famicom_eq; 17 18 // NSF file header 19 enum { header_size = 0x80 }; 20 struct header_t 21 { 22 char tag [5]; 23 byte vers; 24 byte track_count; 25 byte first_track; 26 byte load_addr [2]; 27 byte init_addr [2]; 28 byte play_addr [2]; 29 char game [32]; 30 char author [32]; 31 char copyright [32]; 32 byte ntsc_speed [2]; 33 byte banks [8]; 34 byte pal_speed [2]; 35 byte speed_flags; 36 byte chip_flags; 37 byte unused [4]; 38 }; 39 40 // Header for currently loaded file header()41 header_t const& header() const { return header_; } 42 static_type()43 static gme_type_t static_type() { return gme_nsf_type; } 44 45 public: 46 // deprecated 47 using Music_Emu::load; load(header_t const & h,Data_Reader & in)48 blargg_err_t load( header_t const& h, Data_Reader& in ) // use Remaining_Reader 49 { return load_remaining_( &h, sizeof h, in ); } 50 51 public: 52 Nsf_Emu(); 53 ~Nsf_Emu(); apu_()54 Nes_Apu* apu_() { return &apu; } 55 protected: 56 blargg_err_t track_info_( track_info_t*, int track ) const; 57 blargg_err_t load_( Data_Reader& ); 58 blargg_err_t start_track_( int ); 59 blargg_err_t run_clocks( blip_time_t&, int ); 60 void set_tempo_( double ); 61 void set_voice( int, Blip_Buffer*, Blip_Buffer*, Blip_Buffer* ); 62 void update_eq( blip_eq_t const& ); 63 void unload(); 64 protected: 65 enum { bank_count = 8 }; 66 byte initial_banks [bank_count]; 67 nes_addr_t init_addr; 68 nes_addr_t play_addr; 69 double clock_rate_; 70 bool pal_only; 71 72 // timing 73 Nes_Cpu::registers_t saved_state; 74 nes_time_t next_play; 75 nes_time_t play_period; 76 int play_extra; 77 int play_ready; 78 79 enum { rom_begin = 0x8000 }; 80 enum { bank_select_addr = 0x5FF8 }; 81 enum { bank_size = 0x1000 }; 82 Rom_Data<bank_size> rom; 83 84 public: private: friend class Nes_Cpu; 85 void cpu_jsr( nes_addr_t ); 86 int cpu_read( nes_addr_t ); 87 void cpu_write( nes_addr_t, int ); 88 void cpu_write_misc( nes_addr_t, int ); 89 enum { badop_addr = bank_select_addr }; 90 91 private: 92 class Nes_Namco_Apu* namco; 93 class Nes_Vrc6_Apu* vrc6; 94 class Nes_Fme7_Apu* fme7; 95 Nes_Apu apu; 96 static int pcm_read( void*, nes_addr_t ); 97 blargg_err_t init_sound(); 98 99 header_t header_; 100 101 enum { sram_addr = 0x6000 }; 102 byte sram [0x2000]; 103 byte unmapped_code [Nes_Cpu::page_size + 8]; 104 }; 105 106 #endif 107