Gb_Oscs.h (4650B)
1// Private oscillators used by Gb_Apu 2 3// Gb_Snd_Emu 0.2.0 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 18class Gb_Osc { 19protected: 20 21 // 11-bit frequency in NRx3 and NRx4 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 ); 26public: 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 typedef Blip_Synth<blip_good_quality,1> Good_Synth; 38 typedef Blip_Synth<blip_med_quality ,1> Med_Synth; 39 Good_Synth const* good_synth; 40 Med_Synth const* med_synth; 41 42 int delay; // clocks until frequency timer expires 43 int length_ctr; // length counter 44 unsigned phase; // waveform phase (or equivalent) 45 bool enabled; // internal enabled flag 46 47 void clock_length(); 48 void reset(); 49}; 50 51class Gb_Env : public Gb_Osc { 52public: 53 Gb_Env() : env_delay(0), env_enabled(false) {} 54 int env_delay; 55 int volume; 56 bool env_enabled; 57 58 void clock_envelope(); 59 bool write_register( int frame_phase, int reg, int old_data, int data ); 60 61 void reset() 62 { 63 env_delay = 0; 64 volume = 0; 65 Gb_Osc::reset(); 66 } 67protected: 68 // Non-zero if DAC is enabled 69 int dac_enabled() const { return regs [2] & 0xF8; } 70private: 71 void zombie_volume( int old, int data ); 72 int reload_env_timer(); 73}; 74 75class Gb_Square : public Gb_Env { 76public: 77 bool write_register( int frame_phase, int reg, int old_data, int data ); 78 void run( blip_time_t, blip_time_t ); 79 80 void reset() 81 { 82 Gb_Env::reset(); 83 delay = 0x40000000; // TODO: something less hacky (never clocked until first trigger) 84 } 85private: 86 // Frequency timer period 87 int period() const { return (2048 - frequency()) * (4 * clk_mul); } 88}; 89 90class Gb_Sweep_Square : public Gb_Square { 91public: 92 int sweep_freq; 93 int sweep_delay; 94 bool sweep_enabled; 95 bool sweep_neg; 96 97 void clock_sweep(); 98 void write_register( int frame_phase, int reg, int old_data, int data ); 99 100 void reset() 101 { 102 sweep_freq = 0; 103 sweep_delay = 0; 104 sweep_enabled = false; 105 sweep_neg = false; 106 Gb_Square::reset(); 107 } 108private: 109 enum { period_mask = 0x70 }; 110 enum { shift_mask = 0x07 }; 111 112 void calc_sweep( bool update ); 113 void reload_sweep_timer(); 114}; 115 116class Gb_Noise : public Gb_Env { 117public: 118 119 int divider; // noise has more complex frequency divider setup 120 121 void run( blip_time_t, blip_time_t ); 122 void write_register( int frame_phase, int reg, int old_data, int data ); 123 124 void reset() 125 { 126 divider = 0; 127 Gb_Env::reset(); 128 delay = 4 * clk_mul; // TODO: remove? 129 } 130private: 131 enum { period2_mask = 0x1FFFF }; 132 133 int period2_index() const { return regs [3] >> 4; } 134 int period2( int base = 8 ) const { return base << period2_index(); } 135 unsigned lfsr_mask() const { return (regs [3] & 0x08) ? ~0x4040 : ~0x4000; } 136}; 137 138class Gb_Wave : public Gb_Osc { 139public: 140 int sample_buf; // last wave RAM byte read (hardware has this as well) 141 142 void write_register( int frame_phase, int reg, int old_data, int data ); 143 void run( blip_time_t, blip_time_t ); 144 145 // Reads/writes wave RAM 146 int read( unsigned addr ) const; 147 void write( unsigned addr, int data ); 148 149 void reset() 150 { 151 sample_buf = 0; 152 Gb_Osc::reset(); 153 } 154 155private: 156 enum { bank40_mask = 0x40 }; 157 enum { bank_size = 32 }; 158 159 int agb_mask; // 0xFF if AGB features enabled, 0 otherwise 160 BOOST::uint8_t* wave_ram; // 32 bytes (64 nybbles), stored in APU 161 162 friend class Gb_Apu; 163 164 // Frequency timer period 165 int period() const { return (2048 - frequency()) * (2 * clk_mul); } 166 167 // Non-zero if DAC is enabled 168 int dac_enabled() const { return regs [0] & 0x80; } 169 170 void corrupt_wave(); 171 172 BOOST::uint8_t* wave_bank() const { return &wave_ram [(~regs [0] & bank40_mask) >> 2 & agb_mask]; } 173 174 // Wave index that would be accessed, or -1 if no access would occur 175 int access( unsigned addr ) const; 176}; 177 178inline int Gb_Wave::read( unsigned addr ) const 179{ 180 int index = access( addr ); 181 return (index < 0 ? 0xFF : wave_bank() [index]); 182} 183 184inline void Gb_Wave::write( unsigned addr, int data ) 185{ 186 int index = access( addr ); 187 if ( index >= 0 ) 188 wave_bank() [index] = data;; 189} 190 191#endif