1 // Private oscillators used by Gb_Apu
2 
3 // Gb_Snd_Emu $vers
4 #ifndef GB_OSCS_H
5 #define GB_OSCS_H
6 
7 #include "blargg_common.h"
8 #include "Blip_Buffer.h"
9 
10 #ifndef GB_APU_OVERCLOCK
11 	#define GB_APU_OVERCLOCK 1
12 #endif
13 
14 #if GB_APU_OVERCLOCK & (GB_APU_OVERCLOCK - 1)
15 	#error "GB_APU_OVERCLOCK must be a power of 2"
16 #endif
17 
18 class Gb_Osc {
19 protected:
20 
21 	// 11-bit frequency in NRx3 and NRx4
frequency()22 	int frequency() const { return (regs [4] & 7) * 0x100 + regs [3]; }
23 
24 	void update_amp( blip_time_t, int new_amp );
25 	int write_trig( int frame_phase, int max_len, int old_data );
26 public:
27 
28 	enum { clk_mul  = GB_APU_OVERCLOCK };
29 	enum { dac_bias = 7 };
30 
31 	Blip_Buffer*    outputs [4];// NULL, right, left, center
32 	Blip_Buffer*    output;     // where to output sound
33 	BOOST::uint8_t* regs;       // osc's 5 registers
34 	int             mode;       // mode_dmg, mode_cgb, mode_agb
35 	int             dac_off_amp;// amplitude when DAC is off
36 	int             last_amp;   // current amplitude in Blip_Buffer
37 	Blip_Synth_Norm const* norm_synth;
38 	Blip_Synth_Fast const* fast_synth;
39 
40 	int         delay;      // clocks until frequency timer expires
41 	int         length_ctr; // length counter
42 	unsigned    phase;      // waveform phase (or equivalent)
43 	bool        enabled;    // internal enabled flag
44 
45 	void clock_length();
46 	void reset();
47 };
48 
49 class Gb_Env : public Gb_Osc {
50 public:
51 	int  env_delay;
52 	int  volume;
53 	bool env_enabled;
54 
55 	void clock_envelope();
56 	bool write_register( int frame_phase, int reg, int old_data, int data );
57 
reset()58 	void reset()
59 	{
60 		env_delay = 0;
61 		volume    = 0;
62 		Gb_Osc::reset();
63 	}
64 protected:
65 	// Non-zero if DAC is enabled
dac_enabled()66 	int dac_enabled() const { return regs [2] & 0xF8; }
67 private:
68 	void zombie_volume( int old, int data );
69 	int reload_env_timer();
70 };
71 
72 class Gb_Square : public Gb_Env {
73 public:
74 	bool write_register( int frame_phase, int reg, int old_data, int data );
75 	void run( blip_time_t, blip_time_t );
76 
reset()77 	void reset()
78 	{
79 		Gb_Env::reset();
80 		delay = 0x40000000; // TODO: something less hacky (never clocked until first trigger)
81 	}
82 private:
83 	// Frequency timer period
period()84 	int period() const { return (2048 - frequency()) * (4 * clk_mul); }
85 };
86 
87 class Gb_Sweep_Square : public Gb_Square {
88 public:
89 	int  sweep_freq;
90 	int  sweep_delay;
91 	bool sweep_enabled;
92 	bool sweep_neg;
93 
94 	void clock_sweep();
95 	void write_register( int frame_phase, int reg, int old_data, int data );
96 
reset()97 	void reset()
98 	{
99 		sweep_freq    = 0;
100 		sweep_delay   = 0;
101 		sweep_enabled = false;
102 		sweep_neg     = false;
103 		Gb_Square::reset();
104 	}
105 private:
106 	enum { period_mask = 0x70 };
107 	enum { shift_mask  = 0x07 };
108 
109 	void calc_sweep( bool update );
110 	void reload_sweep_timer();
111 };
112 
113 class Gb_Noise : public Gb_Env {
114 public:
115 	int divider; // noise has more complex frequency divider setup
116 
117 	void run( blip_time_t, blip_time_t );
118 	void write_register( int frame_phase, int reg, int old_data, int data );
119 
reset()120 	void reset()
121 	{
122 		divider = 0;
123 		Gb_Env::reset();
124 		delay = 4 * clk_mul; // TODO: remove?
125 	}
126 
127 private:
128 	enum { period2_mask = 0x1FFFF };
129 
period2_index()130 	int period2_index() const { return regs [3] >> 4; }
131 	int period2( int base = 8 ) const { return base << period2_index(); }
lfsr_mask()132 	unsigned lfsr_mask() const { return (regs [3] & 0x08) ? ~0x4040 : ~0x4000; }
133 };
134 
135 class Gb_Wave : public Gb_Osc {
136 public:
137 	int sample_buf; // last wave RAM byte read (hardware has this as well)
138 
139 	void write_register( int frame_phase, int reg, int old_data, int data );
140 	void run( blip_time_t, blip_time_t );
141 
142 	// Reads/writes wave RAM
143 	int read( int addr ) const;
144 	void write( int addr, int data );
145 
reset()146 	void reset()
147 	{
148 		sample_buf = 0;
149 		Gb_Osc::reset();
150 	}
151 
152 private:
153 	enum { bank40_mask = 0x40 };
154 	enum { bank_size   = 32 };
155 
156 	int agb_mask;               // 0xFF if AGB features enabled, 0 otherwise
157 	BOOST::uint8_t* wave_ram;   // 32 bytes (64 nybbles), stored in APU
158 
159 	friend class Gb_Apu;
160 
161 	// Frequency timer period
period()162 	int period() const { return (2048 - frequency()) * (2 * clk_mul); }
163 
164 	// Non-zero if DAC is enabled
dac_enabled()165 	int dac_enabled() const { return regs [0] & 0x80; }
166 
167 	void corrupt_wave();
168 
wave_bank()169 	BOOST::uint8_t* wave_bank() const { return &wave_ram [(~regs [0] & bank40_mask) >> 2 & agb_mask]; }
170 
171 	// Wave index that would be accessed, or -1 if no access would occur
172 	int access( int addr ) const;
173 };
174 
read(int addr)175 inline int Gb_Wave::read( int addr ) const
176 {
177 	int index = access( addr );
178 	return (index < 0 ? 0xFF : wave_bank() [index]);
179 }
180 
write(int addr,int data)181 inline void Gb_Wave::write( int addr, int data )
182 {
183 	int index = access( addr );
184 	if ( index >= 0 )
185 		wave_bank() [index] = data;;
186 }
187 
188 #endif
189