1 // Nintendo Game Boy sound hardware emulator with save state support
2 
3 // Gb_Snd_Emu 0.2.0
4 #ifndef GB_APU_H
5 #define GB_APU_H
6 
7 #include "Gb_Oscs.h"
8 
9 struct gb_apu_state_t;
10 
11 class Gb_Apu {
12 public:
13 // Basics
14 
15 	// Clock rate that sound hardware runs at.
16 	enum { clock_rate = 4194304 * GB_APU_OVERCLOCK };
17 
18 	// Sets buffer(s) to generate sound into. If left and right are NULL, output is mono.
19 	// If all are NULL, no output is generated but other emulation still runs.
20 	// If chan is specified, only that channel's output is changed, otherwise all are.
21 	enum { osc_count = 4 }; // 0: Square 1, 1: Square 2, 2: Wave, 3: Noise
22 	void set_output( Blip_Buffer* center, Blip_Buffer* left = NULL, Blip_Buffer* right = NULL,
23 			int chan = osc_count );
24 
25 	// Resets hardware to initial power on state BEFORE boot ROM runs. Mode selects
26 	// sound hardware. Additional AGB wave features are enabled separately.
27 	enum mode_t {
28 		mode_dmg,   // Game Boy monochrome
29 		mode_cgb,   // Game Boy Color
30 		mode_agb    // Game Boy Advance
31 	};
32 	void reset( mode_t mode = mode_cgb, bool agb_wave = false );
33 
34 	// Reads and writes must be within the start_addr to end_addr range, inclusive.
35 	// Addresses outside this range are not mapped to the sound hardware.
36 	enum { start_addr = 0xFF10 };
37 	enum { end_addr   = 0xFF3F };
38 	enum { register_count = end_addr - start_addr + 1 };
39 
40 	// Times are specified as the number of clocks since the beginning of the
41 	// current time frame.
42 
43 	// Emulates CPU write of data to addr at specified time.
44 	void write_register( blip_time_t time, unsigned addr, int data );
45 
46 	// Emulates CPU read from addr at specified time.
47 	int read_register( blip_time_t time, unsigned addr );
48 
49 	// Emulates sound hardware up to specified time, ends current time frame, then
50 	// starts a new frame at time 0.
51 	void end_frame( blip_time_t frame_length );
52 
53 // Sound adjustments
54 
55 	// Sets overall volume, where 1.0 is normal.
56 	void volume( double );
57 
58 	// If true, reduces clicking by disabling DAC biasing. Note that this reduces
59 	// emulation accuracy, since the clicks are authentic.
60 	void reduce_clicks( bool reduce = true );
61 
62 	// Sets treble equalization.
63 	void treble_eq( blip_eq_t const& );
64 
65 	// Treble and bass values for various hardware.
66 	enum {
67 		speaker_treble =  -47, // speaker on system
68 		speaker_bass   = 2000,
69 		dmg_treble     =    0, // headphones on each system
70 		dmg_bass       =   30,
71 		cgb_treble     =    0,
72 		cgb_bass       =  300, // CGB has much less bass
73 		agb_treble     =    0,
74 		agb_bass       =   30
75 	};
76 
77 	// Sets frame sequencer rate, where 1.0 is normal. Meant for adjusting the
78 	// tempo in a game music player.
79 	void set_tempo( double );
80 
81 // Save states
82 
83 	// Saves full emulation state to state_out. Data format is portable and
84 	// includes some extra space to avoid expansion in case more state needs
85 	// to be stored in the future.
86 	void save_state( gb_apu_state_t* state_out );
87 
88 	// Loads state. You should call reset() BEFORE this.
89 	blargg_err_t load_state( gb_apu_state_t const& in );
90 
91 public:
92 	Gb_Apu();
93 
94 	// Use set_output() in place of these
output(Blip_Buffer * c)95 	BLARGG_DEPRECATED void output    (        Blip_Buffer* c                                 ) { set_output( c, c, c    ); }
output(Blip_Buffer * c,Blip_Buffer * l,Blip_Buffer * r)96 	BLARGG_DEPRECATED void output    (        Blip_Buffer* c, Blip_Buffer* l, Blip_Buffer* r ) { set_output( c, l, r    ); }
osc_output(int i,Blip_Buffer * c)97 	BLARGG_DEPRECATED void osc_output( int i, Blip_Buffer* c                                 ) { set_output( c, c, c, i ); }
osc_output(int i,Blip_Buffer * c,Blip_Buffer * l,Blip_Buffer * r)98 	BLARGG_DEPRECATED void osc_output( int i, Blip_Buffer* c, Blip_Buffer* l, Blip_Buffer* r ) { set_output( c, l, r, i ); }
99 
100 private:
101 	// noncopyable
102 	Gb_Apu( const Gb_Apu& );
103 	Gb_Apu& operator = ( const Gb_Apu& );
104 
105 	Gb_Osc*     oscs [osc_count];
106 	blip_time_t last_time;          // time sound emulator has been run to
107 	blip_time_t frame_period;       // clocks between each frame sequencer step
108 	double      volume_;
109 	bool        reduce_clicks_;
110 
111 	Gb_Sweep_Square square1;
112 	Gb_Square       square2;
113 	Gb_Wave         wave;
114 	Gb_Noise        noise;
115 	blip_time_t     frame_time;     // time of next frame sequencer action
116 	int             frame_phase;    // phase of next frame sequencer step
117 	enum { regs_size = register_count + 0x10 };
118 	BOOST::uint8_t  regs [regs_size];// last values written to registers
119 
120 	// large objects after everything else
121 	Gb_Osc::Good_Synth  good_synth;
122 	Gb_Osc::Med_Synth   med_synth;
123 
124 	void reset_lengths();
125 	void reset_regs();
126 	int calc_output( int osc ) const;
127 	void apply_stereo();
128 	void apply_volume();
129 	void synth_volume( int );
130 	void run_until_( blip_time_t );
131 	void run_until( blip_time_t );
132 	void silence_osc( Gb_Osc& );
133 	void write_osc( int index, int reg, int old_data, int data );
134 	const char* save_load( gb_apu_state_t*, bool save );
135 	void save_load2( gb_apu_state_t*, bool save );
136 	friend class Gb_Apu_Tester;
137 };
138 
139 // Format of save state. Should be stable across versions of the library,
140 // with earlier versions properly opening later save states. Includes some
141 // room for expansion so the state size shouldn't increase.
142 struct gb_apu_state_t
143 {
144 #if GB_APU_CUSTOM_STATE
145 	// Values stored as plain int so your code can read/write them easily.
146 	// Structure can NOT be written to disk, since format is not portable.
147 	typedef int val_t;
148 #else
149 	// Values written in portable little-endian format, allowing structure
150 	// to be written directly to disk.
151 	typedef unsigned char val_t [4];
152 #endif
153 
154 	enum { format0 = 0x50414247 };
155 
156 	val_t format;   // format of all following data
157 	val_t version;  // later versions just add fields to end
158 
159 	unsigned char regs [0x40];
160 	val_t frame_time;
161 	val_t frame_phase;
162 
163 	val_t sweep_freq;
164 	val_t sweep_delay;
165 	val_t sweep_enabled;
166 	val_t sweep_neg;
167 	val_t noise_divider;
168 	val_t wave_buf;
169 
170 	val_t delay      [4];
171 	val_t length_ctr [4];
172 	val_t phase      [4];
173 	val_t enabled    [4];
174 
175 	val_t env_delay   [3];
176 	val_t env_volume  [3];
177 	val_t env_enabled [3];
178 
179 	val_t unused  [13]; // for future expansion
180 };
181 
182 #endif
183