Browse code

* Fixes for gcc and clang (while they can compile the code, the DLLs made aren't functional, but oh well).

* [2SF] Used more up-to-date asmjit, despite the ugly looking code.

Naram Qashat authored on 2014/09/17 19:51:45
Showing 1 changed files
... ...
@@ -533,7 +533,7 @@ void Gb_Noise::run(blip_time_t time, blip_time_t end_time)
533 533
 		else if (!vol)
534 534
 		{
535 535
 			// Maintain phase when not playing
536
-			int32_t count = (end_time - time + per - 1) / per;
536
+			count = (end_time - time + per - 1) / per;
537 537
 			time += static_cast<blip_time_t>(count) * per;
538 538
 			bits = run_lfsr(bits, ~mask, count);
539 539
 		}
Browse code

[GSF] Copied a few things from kode54's viogsf.

Naram Qashat authored on 2014/09/15 14:27:18
Showing 1 changed files
... ...
@@ -373,7 +373,7 @@ void Gb_Square::run(blip_time_t time, blip_time_t end_time)
373 373
 		if (!vol)
374 374
 		{
375 375
 			// Maintain phase when not playing
376
-			int count = (end_time - time + per - 1) / per;
376
+			int32_t count = (end_time - time + per - 1) / per;
377 377
 			ph += count; // will be masked below
378 378
 			time += static_cast<blip_time_t>(count) * per;
379 379
 		}
... ...
@@ -402,7 +402,7 @@ void Gb_Square::run(blip_time_t time, blip_time_t end_time)
402 402
 
403 403
 // Quickly runs LFSR for a large number of clocks. For use when noise is generating
404 404
 // no sound.
405
-static unsigned run_lfsr(unsigned s, unsigned mask, int count)
405
+static unsigned run_lfsr(unsigned s, unsigned mask, int32_t count)
406 406
 {
407 407
 	static const bool optimized = true; // set to false to use only unoptimized loop in middle
408 408
 
... ...
@@ -513,11 +513,11 @@ void Gb_Noise::run(blip_time_t time, blip_time_t end_time)
513 513
 	// Run timer and calculate time of next LFSR clock
514 514
 	static const uint8_t period1s[] = { 1, 2, 4, 6, 8, 10, 12, 14 };
515 515
 	int period1 = period1s[this->regs[3] & 7] * clk_mul;
516
-	int extra = (end_time - time) - this->delay;
516
+	int32_t extra = (end_time - time) - this->delay;
517 517
 	int per2 = this->period2();
518 518
 	time += this->delay + ((this->divider ^ (per2 >> 1)) & (per2 - 1)) * period1;
519 519
 
520
-	int count = extra < 0 ? 0 : (extra + period1 - 1) / period1;
520
+	int32_t count = extra < 0 ? 0 : (extra + period1 - 1) / period1;
521 521
 	this->divider = (this->divider - count) & period2_mask;
522 522
 	this->delay = count * period1 - extra;
523 523
 
... ...
@@ -533,7 +533,7 @@ void Gb_Noise::run(blip_time_t time, blip_time_t end_time)
533 533
 		else if (!vol)
534 534
 		{
535 535
 			// Maintain phase when not playing
536
-			int count = (end_time - time + per - 1) / per;
536
+			int32_t count = (end_time - time + per - 1) / per;
537 537
 			time += static_cast<blip_time_t>(count) * per;
538 538
 			bits = run_lfsr(bits, ~mask, count);
539 539
 		}
... ...
@@ -618,7 +618,7 @@ void Gb_Wave::run(blip_time_t time, blip_time_t end_time)
618 618
 		if (!playing)
619 619
 		{
620 620
 			// Maintain phase when not playing
621
-			int count = (end_time - time + per - 1) / per;
621
+			int32_t count = (end_time - time + per - 1) / per;
622 622
 			ph += count; // will be masked below
623 623
 			time += static_cast<blip_time_t>(count) * per;
624 624
 		}
Browse code

Updating the VBA-M code to revision 1231.

Naram Qashat authored on 2014/09/08 12:20:28
Showing 1 changed files
... ...
@@ -22,8 +22,7 @@ static const int length_enabled = 0x40;
22 22
 void Gb_Osc::reset()
23 23
 {
24 24
 	this->output = nullptr;
25
-	this->last_amp = 0;
26
-	this->delay = 0;
25
+	this->last_amp = this->delay = 0;
27 26
 	this->phase = 0;
28 27
 	this->enabled = false;
29 28
 }
... ...
@@ -90,7 +89,7 @@ void Gb_Sweep_Square::calc_sweep(bool update)
90 89
 		this->sweep_freq = freq;
91 90
 
92 91
 		this->regs[3] = freq & 0xFF;
93
-		this->regs[4] = (this->regs[4] & ~0x07) | ((freq >> 8) & 0x07);
92
+		this->regs[4] = (this->regs[4] & ~0x07) | (freq >> 8 & 0x07);
94 93
 	}
95 94
 }
96 95
 
... ...
@@ -441,7 +440,7 @@ static unsigned run_lfsr(unsigned s, unsigned mask, int count)
441 440
 	{
442 441
 		// won't fully replace upper 8 bits, so have to do the unoptimized way
443 442
 		while (--count >= 0)
444
-			s = ((s >> 1) | mask) ^ (mask & (0 - ((s - 1) & 2)));
443
+			s = (s >> 1 | mask) ^ (mask & (0 - ((s - 1) & 2)));
445 444
 	}
446 445
 	else
447 446
 	{
... ...
@@ -453,7 +452,7 @@ static unsigned run_lfsr(unsigned s, unsigned mask, int count)
453 452
 		}
454 453
 
455 454
 		// Need to keep one extra bit of history
456
-		s = (s << 1) & 0xFF;
455
+		s = s << 1 & 0xFF;
457 456
 
458 457
 		// Convert from Fibonacci to Galois configuration,
459 458
 		// shifted left 2 bits
... ...
@@ -471,7 +470,7 @@ static unsigned run_lfsr(unsigned s, unsigned mask, int count)
471 470
 
472 471
 		// Convert back to Fibonacci configuration and
473 472
 		// repeat last 8 bits above significant 7
474
-		s = ((s << 7) & 0x7F80) | ((s >> 1) & 0x7F);
473
+		s = (s << 7 & 0x7F80) | (s >> 1 & 0x7F);
475 474
 	}
476 475
 
477 476
 	return s;
... ...
@@ -514,15 +513,13 @@ void Gb_Noise::run(blip_time_t time, blip_time_t end_time)
514 513
 	// Run timer and calculate time of next LFSR clock
515 514
 	static const uint8_t period1s[] = { 1, 2, 4, 6, 8, 10, 12, 14 };
516 515
 	int period1 = period1s[this->regs[3] & 7] * clk_mul;
517
-	{
518
-		int extra = (end_time - time) - this->delay;
519
-		int per2 = this->period2();
520
-		time += this->delay + ((this->divider ^ (per2 >> 1)) & (per2 - 1)) * period1;
516
+	int extra = (end_time - time) - this->delay;
517
+	int per2 = this->period2();
518
+	time += this->delay + ((this->divider ^ (per2 >> 1)) & (per2 - 1)) * period1;
521 519
 
522
-		int count = extra < 0 ? 0 : (extra + period1 - 1) / period1;
523
-		this->divider = (this->divider - count) & period2_mask;
524
-		this->delay = count * period1 - extra;
525
-	}
520
+	int count = extra < 0 ? 0 : (extra + period1 - 1) / period1;
521
+	this->divider = (this->divider - count) & period2_mask;
522
+	this->delay = count * period1 - extra;
526 523
 
527 524
 	// Generate wave
528 525
 	if (time < end_time)
... ...
@@ -547,7 +544,7 @@ void Gb_Noise::run(blip_time_t time, blip_time_t end_time)
547 544
 			do
548 545
 			{
549 546
 				unsigned changed = bits + 1;
550
-				bits = (bits >> 1) & mask;
547
+				bits = bits >> 1 & mask;
551 548
 				if (changed & 2)
552 549
 				{
553 550
 					bits |= ~mask;
... ...
@@ -569,11 +566,11 @@ void Gb_Wave::run(blip_time_t time, blip_time_t end_time)
569 566
 	// Calc volume
570 567
 	static const uint8_t volumes[] = { 0, 4, 2, 1, 3, 3, 3, 3 };
571 568
 	static const int volume_shift = 2;
572
-	int volume_idx = (this->regs[2] >> 5) & (this->agb_mask | 3); // 2 bits on DMG/CGB, 3 on AGB
569
+	int volume_idx = this->regs[2] >> 5 & (this->agb_mask | 3); // 2 bits on DMG/CGB, 3 on AGB
573 570
 	int volume_mul = volumes[volume_idx];
574 571
 
575 572
 	// Determine what will be generated
576
-	int playing = false;
573
+	int playing = 0;
577 574
 	auto out = this->output;
578 575
 	if (out)
579 576
 	{
... ...
@@ -587,9 +584,9 @@ void Gb_Wave::run(blip_time_t time, blip_time_t end_time)
587 584
 			if (this->frequency() <= 0x7FB || this->delay > 15 * clk_mul)
588 585
 			{
589 586
 				if (volume_mul)
590
-					playing = this->enabled;
587
+					playing = static_cast<int>(this->enabled);
591 588
 
592
-				amp = (this->sample_buf << ((this->phase << 2) & 4) & 0xF0) * playing;
589
+				amp = (this->sample_buf << (this->phase << 2 & 4) & 0xF0) * playing;
593 590
 			}
594 591
 
595 592
 			amp = ((amp * volume_mul) >> (volume_shift + 4)) - dac_bias;
... ...
@@ -632,7 +629,7 @@ void Gb_Wave::run(blip_time_t time, blip_time_t end_time)
632 629
 			do
633 630
 			{
634 631
 				// Extract nybble
635
-				int nybble = (wave[ph >> 1] << ((ph << 2) & 4)) & 0xF0;
632
+				int nybble = wave[ph >> 1] << (ph << 2 & 4) & 0xF0;
636 633
 				ph = (ph + 1) & wave_mask;
637 634
 
638 635
 				// Scale by volume
Browse code

[GSF] Some more code cleanup, also removed a few files that were unneeded.

Naram Qashat authored on 2013/05/16 01:25:34
Showing 1 changed files
... ...
@@ -13,8 +13,6 @@ details. You should have received a copy of the GNU Lesser General Public
13 13
 License along with this module; if not, write to the Free Software Foundation,
14 14
 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
15 15
 
16
-#include "blargg_source.h"
17
-
18 16
 static const bool cgb_02 = false; // enables bug in early CGB units that causes problems in some games
19 17
 static const bool cgb_05 = false; // enables CGB-05 zombie behavior
20 18
 
... ...
@@ -45,14 +43,14 @@ void Gb_Osc::update_amp(blip_time_t time, int new_amp)
45 43
 
46 44
 void Gb_Osc::clock_length()
47 45
 {
48
-	if ((this->regs [4] & length_enabled) && this->length_ctr)
46
+	if ((this->regs[4] & length_enabled) && this->length_ctr)
49 47
 	{
50 48
 		if (--this->length_ctr <= 0)
51 49
 			this->enabled = false;
52 50
 	}
53 51
 }
54 52
 
55
-inline int Gb_Env::reload_env_timer()
53
+int Gb_Env::reload_env_timer()
56 54
 {
57 55
 	int raw = this->regs[2] & 7;
58 56
 	this->env_delay = raw ? raw : 8;
... ...
@@ -154,7 +152,7 @@ int Gb_Osc::write_trig(int frame_phase, int max_len, int old_data)
154 152
 	return data & trigger_mask;
155 153
 }
156 154
 
157
-inline void Gb_Env::zombie_volume(int old, int data)
155
+void Gb_Env::zombie_volume(int old, int data)
158 156
 {
159 157
 	int v = this->volume;
160 158
 	if (this->mode == Gb_Apu::mode_agb || cgb_05)
... ...
@@ -188,7 +186,7 @@ inline void Gb_Env::zombie_volume(int old, int data)
188 186
 	this->volume = v & 0x0F;
189 187
 }
190 188
 
191
-bool Gb_Env::write_register( int frame_phase, int reg, int old, int data )
189
+bool Gb_Env::write_register(int frame_phase, int reg, int old, int data)
192 190
 {
193 191
 	static const int max_len = 64;
194 192
 
... ...
@@ -235,7 +233,7 @@ bool Gb_Square::write_register(int frame_phase, int reg, int old_data, int data)
235 233
 	return result;
236 234
 }
237 235
 
238
-inline void Gb_Noise::write_register( int frame_phase, int reg, int old_data, int data )
236
+void Gb_Noise::write_register(int frame_phase, int reg, int old_data, int data)
239 237
 {
240 238
 	if (Gb_Env::write_register(frame_phase, reg, old_data, data))
241 239
 	{
... ...
@@ -244,7 +242,7 @@ inline void Gb_Noise::write_register( int frame_phase, int reg, int old_data, in
244 242
 	}
245 243
 }
246 244
 
247
-inline void Gb_Sweep_Square::write_register(int frame_phase, int reg, int old_data, int data)
245
+void Gb_Sweep_Square::write_register(int frame_phase, int reg, int old_data, int data)
248 246
 {
249 247
 	if (!reg && this->sweep_enabled && this->sweep_neg && !(data & 0x08))
250 248
 		this->enabled = false; // sweep negate disabled after used
... ...
@@ -270,7 +268,7 @@ void Gb_Wave::corrupt_wave()
270 268
 			this->wave_ram[i] = this->wave_ram[(pos & ~3) + i];
271 269
 }
272 270
 
273
-inline void Gb_Wave::write_register(int frame_phase, int reg, int old_data, int data)
271
+void Gb_Wave::write_register(int frame_phase, int reg, int old_data, int data)
274 272
 {
275 273
 	static const int max_len = 256;
276 274
 
... ...
@@ -455,7 +453,7 @@ static unsigned run_lfsr(unsigned s, unsigned mask, int count)
455 453
 		}
456 454
 
457 455
 		// Need to keep one extra bit of history
458
-		s = s << 1 & 0xFF;
456
+		s = (s << 1) & 0xFF;
459 457
 
460 458
 		// Convert from Fibonacci to Galois configuration,
461 459
 		// shifted left 2 bits
... ...
@@ -521,7 +519,7 @@ void Gb_Noise::run(blip_time_t time, blip_time_t end_time)
521 519
 		int per2 = this->period2();
522 520
 		time += this->delay + ((this->divider ^ (per2 >> 1)) & (per2 - 1)) * period1;
523 521
 
524
-		int count = (extra < 0 ? 0 : (extra + period1 - 1) / period1);
522
+		int count = extra < 0 ? 0 : (extra + period1 - 1) / period1;
525 523
 		this->divider = (this->divider - count) & period2_mask;
526 524
 		this->delay = count * period1 - extra;
527 525
 	}
... ...
@@ -579,7 +577,7 @@ void Gb_Wave::run(blip_time_t time, blip_time_t end_time)
579 577
 	auto out = this->output;
580 578
 	if (out)
581 579
 	{
582
-		int amp = dac_off_amp;
580
+		int amp = this->dac_off_amp;
583 581
 		if (this->dac_enabled())
584 582
 		{
585 583
 			// Play inaudible frequencies as constant amplitude
... ...
@@ -589,7 +587,7 @@ void Gb_Wave::run(blip_time_t time, blip_time_t end_time)
589 587
 			if (this->frequency() <= 0x7FB || this->delay > 15 * clk_mul)
590 588
 			{
591 589
 				if (volume_mul)
592
-					playing = enabled;
590
+					playing = this->enabled;
593 591
 
594 592
 				amp = (this->sample_buf << ((this->phase << 2) & 4) & 0xF0) * playing;
595 593
 			}
... ...
@@ -634,7 +632,7 @@ void Gb_Wave::run(blip_time_t time, blip_time_t end_time)
634 632
 			do
635 633
 			{
636 634
 				// Extract nybble
637
-				int nybble = wave[ph >> 1] << ((ph << 2) & 4) & 0xF0;
635
+				int nybble = (wave[ph >> 1] << ((ph << 2) & 4)) & 0xF0;
638 636
 				ph = (ph + 1) & wave_mask;
639 637
 
640 638
 				// Scale by volume
Browse code

[GSF] Massive code cleanup.

(As an aside, blargg's code style makes me go blarg myself.)

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

Import actual code.

Naram Qashat authored on 2013/03/26 02:41:19
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,665 @@
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
6
+can redistribute it and/or modify it under the terms of the GNU Lesser
7
+General Public License as published by the Free Software Foundation; either
8
+version 2.1 of the License, or (at your option) any later version. This
9
+module is distributed in the hope that it will be useful, but WITHOUT ANY
10
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12
+details. You should have received a copy of the GNU Lesser General Public
13
+License along with this module; if not, write to the Free Software Foundation,
14
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
15
+
16
+#include "blargg_source.h"
17
+
18
+bool const cgb_02 = false; // enables bug in early CGB units that causes problems in some games
19
+bool const cgb_05 = false; // enables CGB-05 zombie behavior
20
+
21
+int const trigger_mask   = 0x80;
22
+int const length_enabled = 0x40;
23
+
24
+void Gb_Osc::reset()
25
+{
26
+	output   = 0;
27
+	last_amp = 0;
28
+	delay    = 0;
29
+	phase    = 0;
30
+	enabled  = false;
31
+}
32
+
33
+inline 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
+
46
+void 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
+
55
+inline int Gb_Env::reload_env_timer()
56
+{
57
+	int raw = regs [2] & 7;
58
+	env_delay = (raw ? raw : 8);
59
+	return raw;
60
+}
61
+
62
+void 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
+
74
+inline 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
+
81
+void 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
+
101
+void 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
+
114
+int 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
+
132
+int 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
+
159
+inline 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
+
195
+bool 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
+
234
+bool 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
+
242
+inline 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
+
251
+inline 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
+
267
+void 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
+
277
+inline 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
+
308
+void 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
+
322
+void 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.
407
+static 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
+
481
+void 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
+
571
+void 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
+}