Gb_Apu.cpp (8855B)
1// Gb_Snd_Emu 0.2.0. http://www.slack.net/~ant/ 2 3#include "Gb_Apu.h" 4 5/* Copyright (C) 2003-2007 Shay Green. This module is free software; you 6can redistribute it and/or modify it under the terms of the GNU Lesser 7General Public License as published by the Free Software Foundation; either 8version 2.1 of the License, or (at your option) any later version. This 9module is distributed in the hope that it will be useful, but WITHOUT ANY 10WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 12details. You should have received a copy of the GNU Lesser General Public 13License along with this module; if not, write to the Free Software Foundation, 14Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ 15 16#include "blargg_source.h" 17 18unsigned const vol_reg = 0xFF24; 19unsigned const stereo_reg = 0xFF25; 20unsigned const status_reg = 0xFF26; 21unsigned const wave_ram = 0xFF30; 22 23int const power_mask = 0x80; 24 25void Gb_Apu::treble_eq( blip_eq_t const& eq ) 26{ 27 good_synth.treble_eq( eq ); 28 med_synth .treble_eq( eq ); 29} 30 31inline int Gb_Apu::calc_output( int osc ) const 32{ 33 int bits = regs [stereo_reg - start_addr] >> osc; 34 return (bits >> 3 & 2) | (bits & 1); 35} 36 37void Gb_Apu::set_output( Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right, int osc ) 38{ 39 // Must be silent (all NULL), mono (left and right NULL), or stereo (none NULL) 40 require( !center || (center && !left && !right) || (center && left && right) ); 41 require( (unsigned) osc <= osc_count ); // fails if you pass invalid osc index 42 43 if ( !center || !left || !right ) 44 { 45 left = center; 46 right = center; 47 } 48 49 int i = (unsigned) osc % osc_count; 50 do 51 { 52 Gb_Osc& o = *oscs [i]; 53 o.outputs [1] = right; 54 o.outputs [2] = left; 55 o.outputs [3] = center; 56 o.output = o.outputs [calc_output( i )]; 57 } 58 while ( ++i < osc ); 59} 60 61void Gb_Apu::synth_volume( int iv ) 62{ 63 double v = volume_ * 0.60 / osc_count / 15 /*steps*/ / 8 /*master vol range*/ * iv; 64 good_synth.volume( v ); 65 med_synth .volume( v ); 66} 67 68void Gb_Apu::apply_volume() 69{ 70 // TODO: Doesn't handle differing left and right volumes (panning). 71 // Not worth the complexity. 72 int data = regs [vol_reg - start_addr]; 73 int left = data >> 4 & 7; 74 int right = data & 7; 75 //if ( data & 0x88 ) dprintf( "Vin: %02X\n", data & 0x88 ); 76 //if ( left != right ) dprintf( "l: %d r: %d\n", left, right ); 77 synth_volume( max( left, right ) + 1 ); 78} 79 80void Gb_Apu::volume( double v ) 81{ 82 if ( volume_ != v ) 83 { 84 volume_ = v; 85 apply_volume(); 86 } 87} 88 89void Gb_Apu::reset_regs() 90{ 91 for ( int i = 0; i < 0x20; i++ ) 92 regs [i] = 0; 93 94 square1.reset(); 95 square2.reset(); 96 wave .reset(); 97 noise .reset(); 98 99 apply_volume(); 100} 101 102void Gb_Apu::reset_lengths() 103{ 104 square1.length_ctr = 64; 105 square2.length_ctr = 64; 106 wave .length_ctr = 256; 107 noise .length_ctr = 64; 108} 109 110void Gb_Apu::reduce_clicks( bool reduce ) 111{ 112 reduce_clicks_ = reduce; 113 114 // Click reduction makes DAC off generate same output as volume 0 115 int dac_off_amp = 0; 116 if ( reduce && wave.mode != mode_agb ) // AGB already eliminates clicks 117 dac_off_amp = -Gb_Osc::dac_bias; 118 119 for ( int i = 0; i < osc_count; i++ ) 120 oscs [i]->dac_off_amp = dac_off_amp; 121 122 // AGB always eliminates clicks on wave channel using same method 123 if ( wave.mode == mode_agb ) 124 wave.dac_off_amp = -Gb_Osc::dac_bias; 125} 126 127void Gb_Apu::reset( mode_t mode, bool agb_wave ) 128{ 129 // Hardware mode 130 if ( agb_wave ) 131 mode = mode_agb; // using AGB wave features implies AGB hardware 132 wave.agb_mask = agb_wave ? 0xFF : 0; 133 for ( int i = 0; i < osc_count; i++ ) 134 oscs [i]->mode = mode; 135 reduce_clicks( reduce_clicks_ ); 136 137 // Reset state 138 frame_time = 0; 139 last_time = 0; 140 frame_phase = 0; 141 142 reset_regs(); 143 reset_lengths(); 144 145 // Load initial wave RAM 146 static byte const initial_wave [2] [16] = { 147 {0x84,0x40,0x43,0xAA,0x2D,0x78,0x92,0x3C,0x60,0x59,0x59,0xB0,0x34,0xB8,0x2E,0xDA}, 148 {0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF}, 149 }; 150 for ( int b = 2; --b >= 0; ) 151 { 152 // Init both banks (does nothing if not in AGB mode) 153 // TODO: verify that this works 154 write_register( 0, 0xFF1A, b * 0x40 ); 155 for ( unsigned i = 0; i < sizeof initial_wave [0]; i++ ) 156 write_register( 0, i + wave_ram, initial_wave [(mode != mode_dmg)] [i] ); 157 } 158} 159 160void Gb_Apu::set_tempo( double t ) 161{ 162 frame_period = 4194304 / 512; // 512 Hz 163 if ( t != 1.0 ) 164 frame_period = blip_time_t (frame_period / t); 165} 166 167Gb_Apu::Gb_Apu() 168{ 169 wave.wave_ram = ®s [wave_ram - start_addr]; 170 171 oscs [0] = &square1; 172 oscs [1] = &square2; 173 oscs [2] = &wave; 174 oscs [3] = &noise; 175 176 for ( int i = osc_count; --i >= 0; ) 177 { 178 Gb_Osc& o = *oscs [i]; 179 o.regs = ®s [i * 5]; 180 o.output = 0; 181 o.outputs [0] = 0; 182 o.outputs [1] = 0; 183 o.outputs [2] = 0; 184 o.outputs [3] = 0; 185 o.good_synth = &good_synth; 186 o.med_synth = &med_synth; 187 } 188 189 reduce_clicks_ = false; 190 set_tempo( 1.0 ); 191 volume_ = 1.0; 192 reset(); 193} 194 195void Gb_Apu::run_until_( blip_time_t end_time ) 196{ 197 while ( true ) 198 { 199 // run oscillators 200 blip_time_t time = end_time; 201 if ( time > frame_time ) 202 time = frame_time; 203 204 square1.run( last_time, time ); 205 square2.run( last_time, time ); 206 wave .run( last_time, time ); 207 noise .run( last_time, time ); 208 last_time = time; 209 210 if ( time == end_time ) 211 break; 212 213 // run frame sequencer 214 frame_time += frame_period * Gb_Osc::clk_mul; 215 switch ( frame_phase++ ) 216 { 217 case 2: 218 case 6: 219 // 128 Hz 220 square1.clock_sweep(); 221 /* fall through */ 222 case 0: 223 case 4: 224 // 256 Hz 225 square1.clock_length(); 226 square2.clock_length(); 227 wave .clock_length(); 228 noise .clock_length(); 229 break; 230 231 case 7: 232 // 64 Hz 233 frame_phase = 0; 234 square1.clock_envelope(); 235 square2.clock_envelope(); 236 noise .clock_envelope(); 237 } 238 } 239} 240 241inline void Gb_Apu::run_until( blip_time_t time ) 242{ 243 //require( time >= last_time ); // end_time must not be before previous time 244 if ( time > last_time ) 245 run_until_( time ); 246} 247 248void Gb_Apu::end_frame( blip_time_t end_time ) 249{ 250 if ( end_time > last_time ) 251 run_until( end_time ); 252 253 frame_time -= end_time; 254 assert( frame_time >= 0 ); 255 256 last_time -= end_time; 257 assert( last_time >= 0 ); 258} 259 260void Gb_Apu::silence_osc( Gb_Osc& o ) 261{ 262 int delta = -o.last_amp; 263 if ( delta ) 264 { 265 o.last_amp = 0; 266 if ( o.output ) 267 { 268 o.output->set_modified(); 269 med_synth.offset( last_time, delta, o.output ); 270 } 271 } 272} 273 274void Gb_Apu::apply_stereo() 275{ 276 for ( int i = osc_count; --i >= 0; ) 277 { 278 Gb_Osc& o = *oscs [i]; 279 Blip_Buffer* out = o.outputs [calc_output( i )]; 280 if ( o.output != out ) 281 { 282 silence_osc( o ); 283 o.output = out; 284 } 285 } 286} 287 288void Gb_Apu::write_register( blip_time_t time, unsigned addr, int data ) 289{ 290 require( (unsigned) data < 0x100 ); 291 292 int reg = addr - start_addr; 293 if ( (unsigned) reg >= register_count ) 294 { 295 require( false ); 296 return; 297 } 298 299 if ( addr < status_reg && !(regs [status_reg - start_addr] & power_mask) ) 300 { 301 // Power is off 302 303 // length counters can only be written in DMG mode 304 if ( wave.mode != mode_dmg || (reg != 1 && reg != 5+1 && reg != 10+1 && reg != 15+1) ) 305 return; 306 307 if ( reg < 10 ) 308 data &= 0x3F; // clear square duty 309 } 310 311 run_until( time ); 312 313 if ( addr >= wave_ram ) 314 { 315 wave.write( addr, data ); 316 } 317 else 318 { 319 int old_data = regs [reg]; 320 regs [reg] = data; 321 322 if ( addr < vol_reg ) 323 { 324 // Oscillator 325 write_osc( reg / 5, reg, old_data, data ); 326 } 327 else if ( addr == vol_reg && data != old_data ) 328 { 329 // Master volume 330 for ( int i = osc_count; --i >= 0; ) 331 silence_osc( *oscs [i] ); 332 333 apply_volume(); 334 } 335 else if ( addr == stereo_reg ) 336 { 337 // Stereo panning 338 apply_stereo(); 339 } 340 else if ( addr == status_reg && (data ^ old_data) & power_mask ) 341 { 342 // Power control 343 frame_phase = 0; 344 for ( int i = osc_count; --i >= 0; ) 345 silence_osc( *oscs [i] ); 346 347 reset_regs(); 348 if ( wave.mode != mode_dmg ) 349 reset_lengths(); 350 351 regs [status_reg - start_addr] = data; 352 } 353 } 354} 355 356int Gb_Apu::read_register( blip_time_t time, unsigned addr ) 357{ 358 run_until( time ); 359 360 int reg = addr - start_addr; 361 if ( (unsigned) reg >= register_count ) 362 { 363 require( false ); 364 return 0; 365 } 366 367 if ( addr >= wave_ram ) 368 return wave.read( addr ); 369 370 // Value read back has some bits always set 371 static byte const masks [] = { 372 0x80,0x3F,0x00,0xFF,0xBF, 373 0xFF,0x3F,0x00,0xFF,0xBF, 374 0x7F,0xFF,0x9F,0xFF,0xBF, 375 0xFF,0xFF,0x00,0x00,0xBF, 376 0x00,0x00,0x70, 377 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF 378 }; 379 int mask = masks [reg]; 380 if ( wave.agb_mask && (reg == 10 || reg == 12) ) 381 mask = 0x1F; // extra implemented bits in wave regs on AGB 382 int data = regs [reg] | mask; 383 384 // Status register 385 if ( addr == status_reg ) 386 { 387 data &= 0xF0; 388 data |= (int) square1.enabled << 0; 389 data |= (int) square2.enabled << 1; 390 data |= (int) wave .enabled << 2; 391 data |= (int) noise .enabled << 3; 392 } 393 394 return data; 395}