1 // Nintendo Game Boy GBS music file emulator
2 
3 // Game_Music_Emu 0.6.0
4 #ifndef GBS_EMU_H
5 #define GBS_EMU_H
6 
7 #include "Classic_Emu.h"
8 #include "Gb_Apu.h"
9 #include "Gb_Cpu.h"
10 
11 class Gbs_Emu : private Gb_Cpu, public Classic_Emu {
12 	typedef Gb_Cpu cpu;
13 public:
14 	// Equalizer profiles for Game Boy Color speaker and headphones
15 	static equalizer_t const handheld_eq;
16 	static equalizer_t const headphones_eq;
17 
18 	// GBS file header
19 	enum { header_size = 112 };
20 	struct header_t
21 	{
22 		char tag [3];
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 		byte stack_ptr [2];
30 		byte timer_modulo;
31 		byte timer_mode;
32 		char game [32];
33 		char author [32];
34 		char copyright [32];
35 	};
36 
37 	// Header for currently loaded file
header()38 	header_t const& header() const { return header_; }
39 
static_type()40 	static gme_type_t static_type() { return gme_gbs_type; }
41 
42 public:
43 	// deprecated
44 	using Music_Emu::load;
load(header_t const & h,Data_Reader & in)45 	blargg_err_t load( header_t const& h, Data_Reader& in ) // use Remaining_Reader
46 			{ return load_remaining_( &h, sizeof h, in ); }
47 
48 public:
49 	Gbs_Emu();
50 	~Gbs_Emu();
51 protected:
52 	blargg_err_t track_info_( track_info_t*, int track ) const;
53 	blargg_err_t load_( Data_Reader& );
54 	blargg_err_t start_track_( int );
55 	blargg_err_t run_clocks( blip_time_t&, int );
56 	void set_tempo_( double );
57 	void set_voice( int, Blip_Buffer*, Blip_Buffer*, Blip_Buffer* );
58 	void update_eq( blip_eq_t const& );
59 	void unload();
60 private:
61 	// rom
62 	enum { bank_size = 0x4000 };
63 	Rom_Data<bank_size> rom;
64 	void set_bank( int );
65 
66 	// timer
67 	blip_time_t cpu_time;
68 	blip_time_t play_period;
69 	blip_time_t next_play;
70 	void update_timer();
71 
72 	header_t header_;
73 	void cpu_jsr( gb_addr_t );
74 
75 public: private: friend class Gb_Cpu;
clock()76 	blip_time_t clock() const { return cpu_time - cpu::remain(); }
77 
78 	enum { joypad_addr = 0xFF00 };
79 	enum { ram_addr = 0xA000 };
80 	enum { hi_page = 0xFF00 - ram_addr };
81 	byte ram [0x4000 + 0x2000 + Gb_Cpu::cpu_padding];
82 	Gb_Apu apu;
83 
84 	int cpu_read( gb_addr_t );
85 	void cpu_write( gb_addr_t, int );
86 };
87 
88 #endif
89