Mercurial > audlegacy
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 |
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 |