Gb_Oscs.cpp (14767B)
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 18bool const cgb_02 = false; // enables bug in early CGB units that causes problems in some games 19bool const cgb_05 = false; // enables CGB-05 zombie behavior 20 21int const trigger_mask = 0x80; 22int const length_enabled = 0x40; 23 24void Gb_Osc::reset() 25{ 26 output = 0; 27 last_amp = 0; 28 delay = 0; 29 phase = 0; 30 enabled = false; 31} 32 33inline void Gb_Osc::update_amp( blip_time_t time, int new_amp ) 34{ 35 output->set_modified(); 36 int delta = new_amp - last_amp; 37 if ( delta ) 38 { 39 last_amp = new_amp; 40 med_synth->offset( time, delta, output ); 41 } 42} 43 44// Units 45 46void Gb_Osc::clock_length() 47{ 48 if ( (regs [4] & length_enabled) && length_ctr ) 49 { 50 if ( --length_ctr <= 0 ) 51 enabled = false; 52 } 53} 54 55inline int Gb_Env::reload_env_timer() 56{ 57 int raw = regs [2] & 7; 58 env_delay = (raw ? raw : 8); 59 return raw; 60} 61 62void Gb_Env::clock_envelope() 63{ 64 if ( env_enabled && --env_delay <= 0 && reload_env_timer() ) 65 { 66 int v = volume + (regs [2] & 0x08 ? +1 : -1); 67 if ( 0 <= v && v <= 15 ) 68 volume = v; 69 else 70 env_enabled = false; 71 } 72} 73 74inline void Gb_Sweep_Square::reload_sweep_timer() 75{ 76 sweep_delay = (regs [0] & period_mask) >> 4; 77 if ( !sweep_delay ) 78 sweep_delay = 8; 79} 80 81void Gb_Sweep_Square::calc_sweep( bool update ) 82{ 83 int const shift = regs [0] & shift_mask; 84 int const delta = sweep_freq >> shift; 85 sweep_neg = (regs [0] & 0x08) != 0; 86 int const freq = sweep_freq + (sweep_neg ? -delta : delta); 87 88 if ( freq > 0x7FF ) 89 { 90 enabled = false; 91 } 92 else if ( shift && update ) 93 { 94 sweep_freq = freq; 95 96 regs [3] = freq & 0xFF; 97 regs [4] = (regs [4] & ~0x07) | (freq >> 8 & 0x07); 98 } 99} 100 101void Gb_Sweep_Square::clock_sweep() 102{ 103 if ( --sweep_delay <= 0 ) 104 { 105 reload_sweep_timer(); 106 if ( sweep_enabled && (regs [0] & period_mask) ) 107 { 108 calc_sweep( true ); 109 calc_sweep( false ); 110 } 111 } 112} 113 114int Gb_Wave::access( unsigned addr ) const 115{ 116 if ( enabled && mode != Gb_Apu::mode_agb ) 117 { 118 addr = phase & (bank_size - 1); 119 if ( mode == Gb_Apu::mode_dmg ) 120 { 121 addr++; 122 if ( delay > clk_mul ) 123 return -1; // can only access within narrow time window while playing 124 } 125 addr >>= 1; 126 } 127 return addr & 0x0F; 128} 129 130// write_register 131 132int Gb_Osc::write_trig( int frame_phase, int max_len, int old_data ) 133{ 134 int data = regs [4]; 135 136 if ( (frame_phase & 1) && !(old_data & length_enabled) && length_ctr ) 137 { 138 if ( (data & length_enabled) || cgb_02 ) 139 length_ctr--; 140 } 141 142 if ( data & trigger_mask ) 143 { 144 enabled = true; 145 if ( !length_ctr ) 146 { 147 length_ctr = max_len; 148 if ( (frame_phase & 1) && (data & length_enabled) ) 149 length_ctr--; 150 } 151 } 152 153 if ( !length_ctr ) 154 enabled = false; 155 156 return data & trigger_mask; 157} 158 159inline void Gb_Env::zombie_volume( int old, int data ) 160{ 161 int v = volume; 162 if ( mode == Gb_Apu::mode_agb || cgb_05 ) 163 { 164 // CGB-05 behavior, very close to AGB behavior as well 165 if ( (old ^ data) & 8 ) 166 { 167 if ( !(old & 8) ) 168 { 169 v++; 170 if ( old & 7 ) 171 v++; 172 } 173 174 v = 16 - v; 175 } 176 else if ( (old & 0x0F) == 8 ) 177 { 178 v++; 179 } 180 } 181 else 182 { 183 // CGB-04&02 behavior, very close to MGB behavior as well 184 if ( !(old & 7) && env_enabled ) 185 v++; 186 else if ( !(old & 8) ) 187 v += 2; 188 189 if ( (old ^ data) & 8 ) 190 v = 16 - v; 191 } 192 volume = v & 0x0F; 193} 194 195bool Gb_Env::write_register( int frame_phase, int reg, int old, int data ) 196{ 197 int const max_len = 64; 198 199 switch ( reg ) 200 { 201 case 1: 202 length_ctr = max_len - (data & (max_len - 1)); 203 break; 204 205 case 2: 206 if ( !dac_enabled() ) 207 enabled = false; 208 209 zombie_volume( old, data ); 210 211 if ( (data & 7) && env_delay == 8 ) 212 { 213 env_delay = 1; 214 clock_envelope(); // TODO: really happens at next length clock 215 } 216 break; 217 218 case 4: 219 if ( write_trig( frame_phase, max_len, old ) ) 220 { 221 volume = regs [2] >> 4; 222 reload_env_timer(); 223 env_enabled = true; 224 if ( frame_phase == 7 ) 225 env_delay++; 226 if ( !dac_enabled() ) 227 enabled = false; 228 return true; 229 } 230 } 231 return false; 232} 233 234bool Gb_Square::write_register( int frame_phase, int reg, int old_data, int data ) 235{ 236 bool result = Gb_Env::write_register( frame_phase, reg, old_data, data ); 237 if ( result ) 238 delay = (delay & (4 * clk_mul - 1)) + period(); 239 return result; 240} 241 242inline void Gb_Noise::write_register( int frame_phase, int reg, int old_data, int data ) 243{ 244 if ( Gb_Env::write_register( frame_phase, reg, old_data, data ) ) 245 { 246 phase = 0x7FFF; 247 delay += 8 * clk_mul; 248 } 249} 250 251inline void Gb_Sweep_Square::write_register( int frame_phase, int reg, int old_data, int data ) 252{ 253 if ( reg == 0 && sweep_enabled && sweep_neg && !(data & 0x08) ) 254 enabled = false; // sweep negate disabled after used 255 256 if ( Gb_Square::write_register( frame_phase, reg, old_data, data ) ) 257 { 258 sweep_freq = frequency(); 259 sweep_neg = false; 260 reload_sweep_timer(); 261 sweep_enabled = (regs [0] & (period_mask | shift_mask)) != 0; 262 if ( regs [0] & shift_mask ) 263 calc_sweep( false ); 264 } 265} 266 267void Gb_Wave::corrupt_wave() 268{ 269 int pos = ((phase + 1) & (bank_size - 1)) >> 1; 270 if ( pos < 4 ) 271 wave_ram [0] = wave_ram [pos]; 272 else 273 for ( int i = 4; --i >= 0; ) 274 wave_ram [i] = wave_ram [(pos & ~3) + i]; 275} 276 277inline void Gb_Wave::write_register( int frame_phase, int reg, int old_data, int data ) 278{ 279 int const max_len = 256; 280 281 switch ( reg ) 282 { 283 case 0: 284 if ( !dac_enabled() ) 285 enabled = false; 286 break; 287 288 case 1: 289 length_ctr = max_len - data; 290 break; 291 292 case 4: 293 bool was_enabled = enabled; 294 if ( write_trig( frame_phase, max_len, old_data ) ) 295 { 296 if ( !dac_enabled() ) 297 enabled = false; 298 else if ( mode == Gb_Apu::mode_dmg && was_enabled && 299 (unsigned) (delay - 2 * clk_mul) < 2 * clk_mul ) 300 corrupt_wave(); 301 302 phase = 0; 303 delay = period() + 6 * clk_mul; 304 } 305 } 306} 307 308void Gb_Apu::write_osc( int index, int reg, int old_data, int data ) 309{ 310 reg -= index * 5; 311 switch ( index ) 312 { 313 case 0: square1.write_register( frame_phase, reg, old_data, data ); break; 314 case 1: square2.write_register( frame_phase, reg, old_data, data ); break; 315 case 2: wave .write_register( frame_phase, reg, old_data, data ); break; 316 case 3: noise .write_register( frame_phase, reg, old_data, data ); break; 317 } 318} 319 320// Synthesis 321 322void Gb_Square::run( blip_time_t time, blip_time_t end_time ) 323{ 324 // Calc duty and phase 325 static byte const duty_offsets [4] = { 1, 1, 3, 7 }; 326 static byte const duties [4] = { 1, 2, 4, 6 }; 327 int const duty_code = regs [1] >> 6; 328 int duty_offset = duty_offsets [duty_code]; 329 int duty = duties [duty_code]; 330 if ( mode == Gb_Apu::mode_agb ) 331 { 332 // AGB uses inverted duty 333 duty_offset -= duty; 334 duty = 8 - duty; 335 } 336 int ph = (this->phase + duty_offset) & 7; 337 338 // Determine what will be generated 339 int vol = 0; 340 Blip_Buffer* const out = this->output; 341 if ( out ) 342 { 343 int amp = dac_off_amp; 344 if ( dac_enabled() ) 345 { 346 if ( enabled ) 347 vol = this->volume; 348 349 amp = -dac_bias; 350 if ( mode == Gb_Apu::mode_agb ) 351 amp = -(vol >> 1); 352 353 // Play inaudible frequencies as constant amplitude 354 if ( frequency() >= 0x7FA && delay < 32 * clk_mul ) 355 { 356 amp += (vol * duty) >> 3; 357 vol = 0; 358 } 359 360 if ( ph < duty ) 361 { 362 amp += vol; 363 vol = -vol; 364 } 365 } 366 update_amp( time, amp ); 367 } 368 369 // Generate wave 370 time += delay; 371 if ( time < end_time ) 372 { 373 int const per = this->period(); 374 if ( !vol ) 375 { 376 // Maintain phase when not playing 377 int count = (end_time - time + per - 1) / per; 378 ph += count; // will be masked below 379 time += (blip_time_t) count * per; 380 } 381 else 382 { 383 // Output amplitude transitions 384 int delta = vol; 385 do 386 { 387 ph = (ph + 1) & 7; 388 if ( ph == 0 || ph == duty ) 389 { 390 good_synth->offset_inline( time, delta, out ); 391 delta = -delta; 392 } 393 time += per; 394 } 395 while ( time < end_time ); 396 397 if ( delta != vol ) 398 last_amp -= delta; 399 } 400 this->phase = (ph - duty_offset) & 7; 401 } 402 delay = time - end_time; 403} 404 405// Quickly runs LFSR for a large number of clocks. For use when noise is generating 406// no sound. 407static unsigned run_lfsr( unsigned s, unsigned mask, int count ) 408{ 409 bool const optimized = true; // set to false to use only unoptimized loop in middle 410 411 // optimization used in several places: 412 // ((s & (1 << b)) << n) ^ ((s & (1 << b)) << (n + 1)) = (s & (1 << b)) * (3 << n) 413 414 if ( mask == 0x4000 && optimized ) 415 { 416 if ( count >= 32767 ) 417 count %= 32767; 418 419 // Convert from Fibonacci to Galois configuration, 420 // shifted left 1 bit 421 s ^= (s & 1) * 0x8000; 422 423 // Each iteration is equivalent to clocking LFSR 255 times 424 while ( (count -= 255) > 0 ) 425 s ^= ((s & 0xE) << 12) ^ ((s & 0xE) << 11) ^ (s >> 3); 426 count += 255; 427 428 // Each iteration is equivalent to clocking LFSR 15 times 429 // (interesting similarity to single clocking below) 430 while ( (count -= 15) > 0 ) 431 s ^= ((s & 2) * (3 << 13)) ^ (s >> 1); 432 count += 15; 433 434 // Remaining singles 435 while ( --count >= 0 ) 436 s = ((s & 2) * (3 << 13)) ^ (s >> 1); 437 438 // Convert back to Fibonacci configuration 439 s &= 0x7FFF; 440 } 441 else if ( count < 8 || !optimized ) 442 { 443 // won't fully replace upper 8 bits, so have to do the unoptimized way 444 while ( --count >= 0 ) 445 s = (s >> 1 | mask) ^ (mask & (0 - ((s - 1) & 2))); 446 } 447 else 448 { 449 if ( count > 127 ) 450 { 451 count %= 127; 452 if ( !count ) 453 count = 127; // must run at least once 454 } 455 456 // Need to keep one extra bit of history 457 s = s << 1 & 0xFF; 458 459 // Convert from Fibonacci to Galois configuration, 460 // shifted left 2 bits 461 s ^= (s & 2) * 0x80; 462 463 // Each iteration is equivalent to clocking LFSR 7 times 464 // (interesting similarity to single clocking below) 465 while ( (count -= 7) > 0 ) 466 s ^= ((s & 4) * (3 << 5)) ^ (s >> 1); 467 count += 7; 468 469 // Remaining singles 470 while ( --count >= 0 ) 471 s = ((s & 4) * (3 << 5)) ^ (s >> 1); 472 473 // Convert back to Fibonacci configuration and 474 // repeat last 8 bits above significant 7 475 s = (s << 7 & 0x7F80) | (s >> 1 & 0x7F); 476 } 477 478 return s; 479} 480 481void Gb_Noise::run( blip_time_t time, blip_time_t end_time ) 482{ 483 // Determine what will be generated 484 int vol = 0; 485 Blip_Buffer* const out = this->output; 486 if ( out ) 487 { 488 int amp = dac_off_amp; 489 if ( dac_enabled() ) 490 { 491 if ( enabled ) 492 vol = this->volume; 493 494 amp = -dac_bias; 495 if ( mode == Gb_Apu::mode_agb ) 496 amp = -(vol >> 1); 497 498 if ( !(phase & 1) ) 499 { 500 amp += vol; 501 vol = -vol; 502 } 503 } 504 505 // AGB negates final output 506 if ( mode == Gb_Apu::mode_agb ) 507 { 508 vol = -vol; 509 amp = -amp; 510 } 511 512 update_amp( time, amp ); 513 } 514 515 // Run timer and calculate time of next LFSR clock 516 static byte const period1s [8] = { 1, 2, 4, 6, 8, 10, 12, 14 }; 517 int const period1 = period1s [regs [3] & 7] * clk_mul; 518 { 519 int extra = (end_time - time) - delay; 520 int const per2 = this->period2(); 521 time += delay + ((divider ^ (per2 >> 1)) & (per2 - 1)) * period1; 522 523 int count = (extra < 0 ? 0 : (extra + period1 - 1) / period1); 524 divider = (divider - count) & period2_mask; 525 delay = count * period1 - extra; 526 } 527 528 // Generate wave 529 if ( time < end_time ) 530 { 531 unsigned const mask = this->lfsr_mask(); 532 unsigned bits = this->phase; 533 534 int per = period2( period1 * 8 ); 535 if ( period2_index() >= 0xE ) 536 { 537 time = end_time; 538 } 539 else if ( !vol ) 540 { 541 // Maintain phase when not playing 542 int count = (end_time - time + per - 1) / per; 543 time += (blip_time_t) count * per; 544 bits = run_lfsr( bits, ~mask, count ); 545 } 546 else 547 { 548 // Output amplitude transitions 549 int delta = -vol; 550 do 551 { 552 unsigned changed = bits + 1; 553 bits = bits >> 1 & mask; 554 if ( changed & 2 ) 555 { 556 bits |= ~mask; 557 delta = -delta; 558 med_synth->offset_inline( time, delta, out ); 559 } 560 time += per; 561 } 562 while ( time < end_time ); 563 564 if ( delta == vol ) 565 last_amp += delta; 566 } 567 this->phase = bits; 568 } 569} 570 571void Gb_Wave::run( blip_time_t time, blip_time_t end_time ) 572{ 573 // Calc volume 574 static byte const volumes [8] = { 0, 4, 2, 1, 3, 3, 3, 3 }; 575 int const volume_shift = 2; 576 int const volume_idx = regs [2] >> 5 & (agb_mask | 3); // 2 bits on DMG/CGB, 3 on AGB 577 int const volume_mul = volumes [volume_idx]; 578 579 // Determine what will be generated 580 int playing = false; 581 Blip_Buffer* const out = this->output; 582 if ( out ) 583 { 584 int amp = dac_off_amp; 585 if ( dac_enabled() ) 586 { 587 // Play inaudible frequencies as constant amplitude 588 amp = 8 << 4; // really depends on average of all samples in wave 589 590 // if delay is larger, constant amplitude won't start yet 591 if ( frequency() <= 0x7FB || delay > 15 * clk_mul ) 592 { 593 if ( volume_mul ) 594 playing = (int) enabled; 595 596 amp = (sample_buf << (phase << 2 & 4) & 0xF0) * playing; 597 } 598 599 amp = ((amp * volume_mul) >> (volume_shift + 4)) - dac_bias; 600 } 601 update_amp( time, amp ); 602 } 603 604 // Generate wave 605 time += delay; 606 if ( time < end_time ) 607 { 608 byte const* wave = this->wave_ram; 609 610 // wave size and bank 611 int const size20_mask = 0x20; 612 int const flags = regs [0] & agb_mask; 613 int const wave_mask = (flags & size20_mask) | 0x1F; 614 int swap_banks = 0; 615 if ( flags & bank40_mask ) 616 { 617 swap_banks = flags & size20_mask; 618 wave += bank_size/2 - (swap_banks >> 1); 619 } 620 621 int ph = this->phase ^ swap_banks; 622 ph = (ph + 1) & wave_mask; // pre-advance 623 624 int const per = this->period(); 625 if ( !playing ) 626 { 627 // Maintain phase when not playing 628 int count = (end_time - time + per - 1) / per; 629 ph += count; // will be masked below 630 time += (blip_time_t) count * per; 631 } 632 else 633 { 634 // Output amplitude transitions 635 int lamp = this->last_amp + dac_bias; 636 do 637 { 638 // Extract nybble 639 int nybble = wave [ph >> 1] << (ph << 2 & 4) & 0xF0; 640 ph = (ph + 1) & wave_mask; 641 642 // Scale by volume 643 int amp = (nybble * volume_mul) >> (volume_shift + 4); 644 645 int delta = amp - lamp; 646 if ( delta ) 647 { 648 lamp = amp; 649 med_synth->offset_inline( time, delta, out ); 650 } 651 time += per; 652 } 653 while ( time < end_time ); 654 this->last_amp = lamp - dac_bias; 655 } 656 ph = (ph - 1) & wave_mask; // undo pre-advance and mask position 657 658 // Keep track of last byte read 659 if ( enabled ) 660 sample_buf = wave [ph >> 1]; 661 662 this->phase = ph ^ swap_banks; // undo swapped banks 663 } 664 delay = time - end_time; 665}