1 // Nintendo NES/Famicom NSF music file emulator
2 
3 // Game_Music_Emu 0.6.0
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