annotate Plugins/Input/console/Gb_Apu.cpp @ 877:82a978e884af trunk

[svn] - we should not compile arts_helper.h here.
author nenolod
date Fri, 24 Mar 2006 17:31:08 -0800
parents c04dff121e1d
children f12d7e208b43
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
493
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
1
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
2 // Gb_Snd_Emu 0.1.4. http://www.slack.net/~ant/
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
3
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
4 #include "Gb_Apu.h"
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
5
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
6 #include <string.h>
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
7
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
8 /* Copyright (C) 2003-2006 Shay Green. This module is free software; you
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
9 can redistribute it and/or modify it under the terms of the GNU Lesser
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
10 General Public License as published by the Free Software Foundation; either
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
11 version 2.1 of the License, or (at your option) any later version. This
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
12 module is distributed in the hope that it will be useful, but WITHOUT ANY
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
14 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
15 more details. You should have received a copy of the GNU Lesser General
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
16 Public License along with this module; if not, write to the Free Software
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
18
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
19 #include BLARGG_SOURCE_BEGIN
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
20
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
21 int const vol_reg = 0xFF24;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
22 int const status_reg = 0xFF26;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
23
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
24 Gb_Apu::Gb_Apu()
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
25 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
26 square1.synth = &square_synth;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
27 square2.synth = &square_synth;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
28 wave.synth = &other_synth;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
29 noise.synth = &other_synth;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
30
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
31 oscs [0] = &square1;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
32 oscs [1] = &square2;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
33 oscs [2] = &wave;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
34 oscs [3] = &noise;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
35
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
36 for ( int i = 0; i < osc_count; i++ )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
37 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
38 Gb_Osc& osc = *oscs [i];
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
39 osc.regs = &regs [i * 5];
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
40 osc.output = NULL;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
41 osc.outputs [0] = NULL;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
42 osc.outputs [1] = NULL;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
43 osc.outputs [2] = NULL;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
44 osc.outputs [3] = NULL;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
45 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
46
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
47 volume( 1.0 );
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
48 reset();
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
49 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
50
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
51 Gb_Apu::~Gb_Apu()
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
52 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
53 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
54
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
55 void Gb_Apu::treble_eq( const blip_eq_t& eq )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
56 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
57 square_synth.treble_eq( eq );
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
58 other_synth.treble_eq( eq );
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
59 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
60
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
61 void Gb_Apu::osc_output( int index, Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
62 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
63 require( (unsigned) index < osc_count );
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
64 require( (center && left && right) || (!center && !left && !right) );
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
65 Gb_Osc& osc = *oscs [index];
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
66 osc.outputs [1] = right;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
67 osc.outputs [2] = left;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
68 osc.outputs [3] = center;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
69 osc.output = osc.outputs [osc.output_select];
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
70 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
71
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
72 void Gb_Apu::output( Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
73 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
74 for ( int i = 0; i < osc_count; i++ )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
75 osc_output( i, center, left, right );
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
76 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
77
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
78 void Gb_Apu::update_volume()
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
79 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
80 // to do: doesn't handle differing left/right global volume
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
81 int data = regs [vol_reg - start_addr];
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
82 double vol = (max( data & 7, data >> 4 & 7 ) + 1) * volume_unit;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
83 square_synth.volume( vol );
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
84 other_synth.volume( vol );
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
85 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
86
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
87 static unsigned char const powerup_regs [0x30] = {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
88 0x80,0x3F,0x00,0xFF,0xBF, // square 1
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
89 0xFF,0x3F,0x00,0xFF,0xBF, // square 2
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
90 0x7F,0xFF,0x9F,0xFF,0xBF, // wave
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
91 0xFF,0xFF,0x00,0x00,0xBF, // noise
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
92 0x00, // left/right enables
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
93 0x77, // master volume
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
94 0x80, // power
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
95 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
96 0x84,0x40,0x43,0xAA,0x2D,0x78,0x92,0x3C, // wave table
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
97 0x60,0x59,0x59,0xB0,0x34,0xB8,0x2E,0xDA
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
98 };
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
99
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
100 void Gb_Apu::reset()
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
101 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
102 next_frame_time = 0;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
103 last_time = 0;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
104 frame_count = 0;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
105 stereo_found = false;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
106
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
107 square1.reset();
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
108 square2.reset();
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
109 wave.reset();
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
110 noise.reset();
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
111 noise.bits = 1;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
112 wave.wave_pos = 0;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
113
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
114 // avoid click at beginning
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
115 regs [vol_reg - start_addr] = 0x77;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
116 update_volume();
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
117
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
118 regs [status_reg - start_addr] = 0x01; // force power
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
119 write_register( 0, status_reg, 0x00 );
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
120 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
121
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
122 // to do: remove
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
123 static unsigned long abs_time;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
124
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
125 void Gb_Apu::run_until( gb_time_t end_time )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
126 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
127 require( end_time >= last_time ); // end_time must not be before previous time
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
128 if ( end_time == last_time )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
129 return;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
130
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
131 while ( true )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
132 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
133 gb_time_t time = next_frame_time;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
134 if ( time > end_time )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
135 time = end_time;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
136
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
137 // run oscillators
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
138 for ( int i = 0; i < osc_count; ++i )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
139 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
140 Gb_Osc& osc = *oscs [i];
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
141 if ( osc.output )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
142 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
143 int playing = false;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
144 if ( osc.enabled && osc.volume &&
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
145 (!(osc.regs [4] & osc.len_enabled_mask) || osc.length) )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
146 playing = -1;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
147 if ( osc.output != osc.outputs [3] )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
148 stereo_found = true;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
149 switch ( i )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
150 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
151 case 0: square1.run( last_time, time, playing ); break;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
152 case 1: square2.run( last_time, time, playing ); break;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
153 case 2: wave .run( last_time, time, playing ); break;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
154 case 3: noise .run( last_time, time, playing ); break;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
155 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
156 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
157 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
158 last_time = time;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
159
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
160 if ( time == end_time )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
161 break;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
162
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
163 next_frame_time += 4194304 / 256; // 256 Hz
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
164
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
165 // 256 Hz actions
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
166 square1.clock_length();
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
167 square2.clock_length();
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
168 wave.clock_length();
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
169 noise.clock_length();
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
170
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
171 frame_count = (frame_count + 1) & 3;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
172 if ( frame_count == 0 )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
173 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
174 // 64 Hz actions
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
175 square1.clock_envelope();
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
176 square2.clock_envelope();
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
177 noise.clock_envelope();
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
178 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
179
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
180 if ( frame_count & 1 )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
181 square1.clock_sweep(); // 128 Hz action
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
182 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
183 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
184
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
185 bool Gb_Apu::end_frame( gb_time_t end_time )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
186 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
187 if ( end_time > last_time )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
188 run_until( end_time );
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
189
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
190 abs_time += end_time;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
191
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
192 assert( next_frame_time >= end_time );
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
193 next_frame_time -= end_time;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
194
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
195 assert( last_time >= end_time );
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
196 last_time -= end_time;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
197
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
198 bool result = stereo_found;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
199 stereo_found = false;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
200 return result;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
201 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
202
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
203 void Gb_Apu::write_register( gb_time_t time, gb_addr_t addr, int data )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
204 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
205 require( (unsigned) data < 0x100 );
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
206
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
207 int reg = addr - start_addr;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
208 if ( (unsigned) reg >= register_count )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
209 return;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
210
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
211 run_until( time );
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
212
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
213 int old_reg = regs [reg];
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
214 regs [reg] = data;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
215
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
216 if ( addr < vol_reg )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
217 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
218 write_osc( reg / 5, reg, data );
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
219 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
220 else if ( addr == vol_reg && data != old_reg ) // global volume
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
221 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
222 // return all oscs to 0
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
223 for ( int i = 0; i < osc_count; i++ )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
224 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
225 Gb_Osc& osc = *oscs [i];
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
226 int amp = osc.last_amp;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
227 osc.last_amp = 0;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
228 if ( amp && osc.enabled && osc.output )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
229 other_synth.offset( time, -amp, osc.output );
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
230 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
231
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
232 if ( wave.outputs [3] )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
233 other_synth.offset( time, 30, wave.outputs [3] );
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
234
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
235 update_volume();
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
236
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
237 if ( wave.outputs [3] )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
238 other_synth.offset( time, -30, wave.outputs [3] );
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
239
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
240 // oscs will update with new amplitude when next run
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
241 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
242 else if ( addr == 0xFF25 || addr == status_reg )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
243 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
244 int mask = (regs [status_reg - start_addr] & 0x80) ? ~0 : 0;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
245 int flags = regs [0xFF25 - start_addr] & mask;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
246
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
247 // left/right assignments
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
248 for ( int i = 0; i < osc_count; i++ )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
249 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
250 Gb_Osc& osc = *oscs [i];
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
251 osc.enabled &= mask;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
252 int bits = flags >> i;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
253 Blip_Buffer* old_output = osc.output;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
254 osc.output_select = (bits >> 3 & 2) | (bits & 1);
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
255 osc.output = osc.outputs [osc.output_select];
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
256 if ( osc.output != old_output )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
257 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
258 int amp = osc.last_amp;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
259 osc.last_amp = 0;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
260 if ( amp && old_output )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
261 other_synth.offset( time, -amp, old_output );
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
262 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
263 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
264
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
265 if ( addr == status_reg && data != old_reg )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
266 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
267 if ( !(data & 0x80) )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
268 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
269 for ( int i = 0; i < (int) sizeof powerup_regs; i++ )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
270 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
271 if ( i != status_reg - start_addr )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
272 write_register( time, i + start_addr, powerup_regs [i] );
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
273 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
274 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
275 else
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
276 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
277 //dprintf( "APU powered on\n" );
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
278 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
279 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
280 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
281 else if ( addr >= 0xFF30 )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
282 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
283
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
284 int index = (addr & 0x0F) * 2;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
285 wave.wave [index] = data >> 4;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
286 wave.wave [index + 1] = data & 0x0F;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
287 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
288 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
289
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
290 int Gb_Apu::read_register( gb_time_t time, gb_addr_t addr )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
291 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
292 run_until( time );
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
293
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
294 int index = addr - start_addr;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
295 require( (unsigned) index < register_count );
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
296 int data = regs [index];
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
297
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
298 if ( addr == status_reg )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
299 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
300 data = (data & 0x80) | 0x70;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
301 for ( int i = 0; i < osc_count; i++ )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
302 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
303 const Gb_Osc& osc = *oscs [i];
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
304 if ( osc.enabled && (osc.length || !(osc.regs [4] & osc.len_enabled_mask)) )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
305 data |= 1 << i;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
306 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
307 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
308
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
309 return data;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
310 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
311