annotate Plugins/Input/console/Nes_Apu.cpp @ 108:cde5ca21ddc3 trunk

[svn] Improved latency on the decode loop.
author nenolod
date Wed, 02 Nov 2005 21:45:23 -0800
parents 252843aac42f
children 7c5e886205ef
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
90
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
1
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
2 // Nes_Snd_Emu 0.1.6. http://www.slack.net/~ant/libs/
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
3
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
4 #include "Nes_Apu.h"
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
5
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
6 /* Copyright (C) 2003-2005 Shay Green. This module is free software; you
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
7 can redistribute it and/or modify it under the terms of the GNU Lesser
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
8 General Public License as published by the Free Software Foundation; either
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
9 version 2.1 of the License, or (at your option) any later version. This
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
10 module is distributed in the hope that it will be useful, but WITHOUT ANY
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
11 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
12 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
13 more details. You should have received a copy of the GNU Lesser General
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
14 Public License along with this module; if not, write to the Free Software
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
15 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
16
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
17 #include BLARGG_SOURCE_BEGIN
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
18
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
19 Nes_Apu::Nes_Apu()
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
20 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
21 dmc.apu = this;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
22 dmc.rom_reader = NULL;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
23 square1.synth = &square_synth;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
24 square2.synth = &square_synth;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
25 irq_notifier_ = NULL;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
26
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
27 oscs [0] = &square1;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
28 oscs [1] = &square2;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
29 oscs [2] = ▵
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
30 oscs [3] = &noise;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
31 oscs [4] = &dmc;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
32
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
33 output( NULL );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
34 volume( 1.0 );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
35 reset( false );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
36 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
37
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
38 Nes_Apu::~Nes_Apu()
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
39 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
40 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
41
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
42 void Nes_Apu::treble_eq( const blip_eq_t& eq )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
43 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
44 square_synth.treble_eq( eq );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
45 triangle.synth.treble_eq( eq );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
46 noise.synth.treble_eq( eq );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
47 dmc.synth.treble_eq( eq );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
48 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
49
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
50 void Nes_Apu::volume( double v, bool nonlinear )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
51 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
52 dmc.nonlinear = nonlinear;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
53 if ( nonlinear )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
54 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
55 square_synth.volume( 0.25751258 * 0.25 * v );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
56
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
57 const double tnd = 1.0 / 202 * 0.48;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
58 triangle.synth.volume_unit( 3 * tnd );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
59 noise.synth.volume_unit( 2 * tnd );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
60 dmc.synth.volume_unit( tnd );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
61 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
62 else
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
63 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
64 square_synth.volume( 0.1128 * v );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
65 triangle.synth.volume( 0.12765 * v );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
66 noise.synth.volume( 0.0741 * v );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
67 dmc.synth.volume( 0.42545 * v );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
68 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
69 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
70
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
71 void Nes_Apu::output( Blip_Buffer* buffer )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
72 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
73 for ( int i = 0; i < osc_count; i++ )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
74 osc_output( i, buffer );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
75 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
76
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
77 void Nes_Apu::reset( bool pal_mode, int initial_dmc_dac )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
78 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
79 // to do: time pal frame periods exactly
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
80 frame_period = pal_mode ? 8314 : 7458;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
81 dmc.pal_mode = pal_mode;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
82
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
83 square1.reset();
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
84 square2.reset();
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
85 triangle.reset();
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
86 noise.reset();
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
87 dmc.reset();
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
88
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
89 last_time = 0;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
90 osc_enables = 0;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
91 irq_flag = false;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
92 earliest_irq_ = no_irq;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
93 frame_delay = 1;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
94 write_register( 0, 0x4017, 0x00 );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
95 write_register( 0, 0x4015, 0x00 );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
96
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
97 for ( nes_addr_t addr = start_addr; addr <= 0x4013; addr++ )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
98 write_register( 0, addr, (addr & 3) ? 0x00 : 0x10 );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
99
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
100 dmc.dac = initial_dmc_dac;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
101 if ( !dmc.nonlinear )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
102 dmc.last_amp = initial_dmc_dac; // prevent output transition
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
103 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
104
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
105 void Nes_Apu::irq_changed()
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
106 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
107 nes_time_t new_irq = dmc.next_irq;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
108 if ( dmc.irq_flag | irq_flag ) {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
109 new_irq = 0;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
110 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
111 else if ( new_irq > next_irq ) {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
112 new_irq = next_irq;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
113 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
114
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
115 if ( new_irq != earliest_irq_ ) {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
116 earliest_irq_ = new_irq;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
117 if ( irq_notifier_ )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
118 irq_notifier_( irq_data );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
119 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
120 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
121
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
122 // frames
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
123
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
124 void Nes_Apu::run_until( nes_time_t end_time )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
125 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
126 require( end_time >= last_time );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
127
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
128 if ( end_time == last_time )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
129 return;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
130
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
131 while ( true )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
132 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
133 // earlier of next frame time or end time
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
134 nes_time_t time = last_time + frame_delay;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
135 if ( time > end_time )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
136 time = end_time;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
137 frame_delay -= time - last_time;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
138
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
139 // run oscs to present
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
140 square1.run( last_time, time );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
141 square2.run( last_time, time );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
142 triangle.run( last_time, time );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
143 noise.run( last_time, time );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
144 dmc.run( last_time, time );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
145 last_time = time;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
146
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
147 if ( time == end_time )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
148 break; // no more frames to run
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
149
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
150 // take frame-specific actions
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
151 frame_delay = frame_period;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
152 switch ( frame++ )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
153 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
154 case 0:
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
155 // set interrupt in mode 0
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
156 if ( !(frame_mode & 0xc0) ) {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
157 irq_flag = true;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
158 next_irq = time + frame_period * 4 + 1;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
159 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
160 // fall through
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
161 case 2:
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
162 // clock length and sweep on frames 0 and 2
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
163 square1.clock_length( 0x20 );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
164 square2.clock_length( 0x20 );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
165 noise.clock_length( 0x20 );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
166 triangle.clock_length( 0x80 ); // different bit for halt flag on triangle
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
167
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
168 square1.clock_sweep( -1 );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
169 square2.clock_sweep( 0 );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
170 break;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
171
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
172 case 1:
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
173 // frame 1 is slightly shorter
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
174 frame_delay -= 2;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
175 break;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
176
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
177 case 3:
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
178 frame = 0;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
179
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
180 // frame 3 is almost twice as long in mode 1
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
181 if ( frame_mode & 0x80 )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
182 frame_delay += frame_period - 6;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
183 break;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
184 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
185
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
186 // clock envelopes and linear counter every frame
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
187 triangle.clock_linear_counter();
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
188 square1.clock_envelope();
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
189 square2.clock_envelope();
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
190 noise.clock_envelope();
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
191 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
192 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
193
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
194 void Nes_Apu::end_frame( nes_time_t end_time )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
195 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
196 run_until( end_time );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
197
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
198 // make times relative to new frame
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
199 last_time = 0;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
200 if ( next_irq != no_irq ) {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
201 next_irq -= end_time;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
202 assert( next_irq >= 0 );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
203 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
204 if ( dmc.next_irq != no_irq ) {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
205 dmc.next_irq -= end_time;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
206 assert( dmc.next_irq >= 0 );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
207 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
208 if ( earliest_irq_ != no_irq ) {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
209 earliest_irq_ -= end_time;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
210 if ( earliest_irq_ < 0 )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
211 earliest_irq_ = 0;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
212 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
213 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
214
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
215 // registers
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
216
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
217 static const unsigned char length_table [0x20] = {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
218 0x0A, 0xFE, 0x14, 0x02, 0x28, 0x04, 0x50, 0x06,
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
219 0xA0, 0x08, 0x3C, 0x0A, 0x0E, 0x0C, 0x1A, 0x0E,
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
220 0x0C, 0x10, 0x18, 0x12, 0x30, 0x14, 0x60, 0x16,
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
221 0xC0, 0x18, 0x48, 0x1A, 0x10, 0x1C, 0x20, 0x1E
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
222 };
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
223
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
224 void Nes_Apu::write_register( nes_time_t time, nes_addr_t addr, int data )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
225 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
226 require( addr > 0x20 ); // addr must be actual address (i.e. 0x40xx)
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
227 require( (unsigned) data <= 0xff );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
228
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
229 // Ignore addresses outside range
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
230 if ( addr < start_addr || end_addr < addr )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
231 return;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
232
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
233 run_until( time );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
234
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
235 if ( addr < 0x4014 )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
236 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
237 // Write to channel
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
238 int osc_index = (addr - start_addr) >> 2;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
239 Nes_Osc* osc = oscs [osc_index];
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
240
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
241 int reg = addr & 3;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
242 osc->regs [reg] = data;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
243 osc->reg_written [reg] = true;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
244
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
245 if ( osc_index == 4 )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
246 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
247 // handle DMC specially
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
248 dmc.write_register( reg, data );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
249 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
250 else if ( reg == 3 )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
251 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
252 // load length counter
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
253 if ( (osc_enables >> osc_index) & 1 )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
254 osc->length_counter = length_table [(data >> 3) & 0x1f];
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
255
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
256 // reset square phase
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
257 if ( osc_index < 2 )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
258 ((Nes_Square*) osc)->phase = Nes_Square::phase_range - 1;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
259 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
260 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
261 else if ( addr == 0x4015 )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
262 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
263 // Channel enables
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
264 for ( int i = osc_count; i--; )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
265 if ( !((data >> i) & 1) )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
266 oscs [i]->length_counter = 0;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
267
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
268 bool recalc_irq = dmc.irq_flag;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
269 dmc.irq_flag = false;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
270
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
271 int old_enables = osc_enables;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
272 osc_enables = data;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
273 if ( !(data & 0x10) ) {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
274 dmc.next_irq = no_irq;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
275 recalc_irq = true;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
276 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
277 else if ( !(old_enables & 0x10) ) {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
278 dmc.start(); // dmc just enabled
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
279 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
280
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
281 if ( recalc_irq )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
282 irq_changed();
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
283 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
284 else if ( addr == 0x4017 )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
285 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
286 // Frame mode
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
287 frame_mode = data;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
288
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
289 bool irq_enabled = !(data & 0x40);
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
290 irq_flag &= irq_enabled;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
291 next_irq = no_irq;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
292
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
293 // mode 1
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
294 frame_delay = (frame_delay & 1);
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
295 frame = 0;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
296
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
297 if ( !(data & 0x80) )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
298 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
299 // mode 0
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
300 frame = 1;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
301 frame_delay += frame_period;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
302 if ( irq_enabled )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
303 next_irq = time + frame_delay + frame_period * 3;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
304 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
305
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
306 irq_changed();
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
307 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
308 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
309
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
310 int Nes_Apu::read_status( nes_time_t time )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
311 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
312 run_until( time - 1 );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
313
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
314 int result = (dmc.irq_flag << 7) | (irq_flag << 6);
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
315
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
316 for ( int i = 0; i < osc_count; i++ )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
317 if ( oscs [i]->length_counter )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
318 result |= 1 << i;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
319
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
320 run_until( time );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
321
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
322 if ( irq_flag ) {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
323 irq_flag = false;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
324 irq_changed();
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
325 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
326
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
327 return result;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
328 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
329