filename | src/aica/aica.c |
changeset | 82:81a4acf75f10 |
prev | 76:e9a0bd313036 |
next | 86:f151e63f9754 |
author | nkeynes |
date | Sun Jan 22 22:38:51 2006 +0000 (18 years ago) |
permissions | -rw-r--r-- |
last change | Fix colour mode definitions Add PVR2 palette region Fix ta end-of-command when it's not in the same buffer |
view | annotate | diff | log | raw |
1 /**
2 * $Id: aica.c,v 1.15 2006-01-17 12:54:02 nkeynes Exp $
3 *
4 * This is the core sound system (ie the bit which does the actual work)
5 *
6 * Copyright (c) 2005 Nathan Keynes.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
19 #define MODULE aica_module
21 #include "dream.h"
22 #include "dreamcast.h"
23 #include "mem.h"
24 #include "aica.h"
25 #include "armcore.h"
26 #include "audio.h"
27 #define MMIO_IMPL
28 #include "aica.h"
30 MMIO_REGION_READ_DEFFN( AICA0 )
31 MMIO_REGION_READ_DEFFN( AICA1 )
32 MMIO_REGION_READ_DEFFN( AICA2 )
34 void aica_init( void );
35 void aica_reset( void );
36 void aica_start( void );
37 void aica_stop( void );
38 void aica_save_state( FILE *f );
39 int aica_load_state( FILE *f );
40 uint32_t aica_run_slice( uint32_t );
42 struct dreamcast_module aica_module = { "AICA", aica_init, aica_reset,
43 aica_start, aica_run_slice, aica_stop,
44 aica_save_state, aica_load_state };
46 /**
47 * Initialize the AICA subsystem. Note requires that
48 */
49 void aica_init( void )
50 {
51 register_io_regions( mmio_list_spu );
52 MMIO_NOTRACE(AICA0);
53 MMIO_NOTRACE(AICA1);
54 arm_mem_init();
55 aica_reset();
56 audio_set_output( &esd_audio_driver, 44100, AUDIO_FMT_16BIT|AUDIO_FMT_STEREO );
57 }
59 void aica_reset( void )
60 {
61 arm_reset();
62 aica_event(2); /* Pre-deliver a timer interrupt */
63 }
65 void aica_start( void )
66 {
68 }
70 /**
71 * Keep track of what we've done so far this second, to try to keep the
72 * precision of samples/second.
73 */
74 int samples_done = 0;
75 uint32_t nanosecs_done = 0;
77 uint32_t aica_run_slice( uint32_t nanosecs )
78 {
79 /* Run arm instructions */
80 int reset = MMIO_READ( AICA2, AICA_RESET );
81 if( (reset & 1) == 0 ) { /* Running */
82 int num_samples = (int)((uint64_t)AICA_SAMPLE_RATE * (nanosecs_done + nanosecs) / 1000000000) - samples_done;
83 num_samples = arm_run_slice( num_samples );
84 audio_mix_samples( num_samples );
86 samples_done += num_samples;
87 nanosecs_done += nanosecs;
88 }
89 if( nanosecs_done > 1000000000 ) {
90 samples_done -= AICA_SAMPLE_RATE;
91 nanosecs_done -= 1000000000;
92 }
93 return nanosecs;
94 }
96 void aica_stop( void )
97 {
99 }
101 void aica_save_state( FILE *f )
102 {
103 arm_save_state( f );
104 }
106 int aica_load_state( FILE *f )
107 {
108 return arm_load_state( f );
109 }
111 int aica_event_pending = 0;
112 int aica_clear_count = 0;
114 /* Note: This is probably not necessarily technically correct but it should
115 * work in the meantime.
116 */
118 void aica_event( int event )
119 {
120 if( aica_event_pending == 0 )
121 armr.int_pending |= CPSR_F;
122 aica_event_pending |= (1<<event);
124 int pending = MMIO_READ( AICA2, AICA_IRQ );
125 if( pending == 0 || event < pending )
126 MMIO_WRITE( AICA2, AICA_IRQ, event );
127 }
129 void aica_clear_event( )
130 {
131 aica_clear_count++;
132 if( aica_clear_count == 4 ) {
133 int i;
134 aica_clear_count = 0;
136 for( i=0; i<8; i++ ) {
137 if( aica_event_pending & (1<<i) ) {
138 aica_event_pending &= ~(1<<i);
139 break;
140 }
141 }
142 for( ;i<8; i++ ) {
143 if( aica_event_pending & (1<<i) ) {
144 MMIO_WRITE( AICA2, AICA_IRQ, i );
145 break;
146 }
147 }
148 if( aica_event_pending == 0 )
149 armr.int_pending &= ~CPSR_F;
150 }
151 }
153 /** Channel register structure:
154 * 00 4 Channel config
155 * 04 4 Waveform address lo (16 bits)
156 * 08 4 Loop start address
157 * 0C 4 Loop end address
158 * 10 4 Volume envelope
159 * 14 4 Init to 0x1F
160 * 18 4 Frequency (floating point)
161 * 1C 4 ??
162 * 20 4 ??
163 * 24 1 Pan
164 * 25 1 ??
165 * 26
166 * 27
167 * 28 1 ??
168 * 29 1 Volume
169 * 2C
170 * 30
171 *
173 /* Write to channels 0-31 */
174 void mmio_region_AICA0_write( uint32_t reg, uint32_t val )
175 {
176 MMIO_WRITE( AICA0, reg, val );
177 aica_write_channel( reg >> 7, reg % 128, val );
178 // DEBUG( "AICA0 Write %08X => %08X", val, reg );
179 }
181 /* Write to channels 32-64 */
182 void mmio_region_AICA1_write( uint32_t reg, uint32_t val )
183 {
184 MMIO_WRITE( AICA1, reg, val );
185 aica_write_channel( (reg >> 7) + 32, reg % 128, val );
186 // DEBUG( "AICA1 Write %08X => %08X", val, reg );
187 }
189 /**
190 * AICA control registers
191 */
192 void mmio_region_AICA2_write( uint32_t reg, uint32_t val )
193 {
194 uint32_t tmp;
195 switch( reg ) {
196 case AICA_RESET:
197 tmp = MMIO_READ( AICA2, AICA_RESET );
198 if( (tmp & 1) == 1 && (val & 1) == 0 ) {
199 /* ARM enabled - execute a core reset */
200 DEBUG( "ARM enabled" );
201 arm_reset();
202 samples_done = 0;
203 nanosecs_done = 0;
204 } else if( (tmp&1) == 0 && (val&1) == 1 ) {
205 DEBUG( "ARM disabled" );
206 }
207 MMIO_WRITE( AICA2, AICA_RESET, val );
208 break;
209 case AICA_IRQCLEAR:
210 aica_clear_event();
211 break;
212 default:
213 MMIO_WRITE( AICA2, reg, val );
214 break;
215 }
216 }
218 /**
219 * Translate the channel frequency to a sample rate. The frequency is a
220 * 14-bit floating point number, where bits 0..9 is the mantissa,
221 * 11..14 is the signed exponent (-8 to +7). Bit 10 appears to
222 * be unused.
223 *
224 * @return sample rate in samples per second.
225 */
226 uint32_t aica_frequency_to_sample_rate( uint32_t freq )
227 {
228 uint32_t exponent = (freq & 0x3800) >> 11;
229 uint32_t mantissa = freq & 0x03FF;
230 uint32_t rate;
231 if( freq & 0x4000 ) {
232 /* neg exponent - rate < 44100 */
233 exponent = 8 - exponent;
234 rate = (44100 >> exponent) +
235 ((44100 * mantissa) >> (10+exponent));
236 } else {
237 /* pos exponent - rate > 44100 */
238 rate = (44100 << exponent) +
239 ((44100 * mantissa) >> (10-exponent));
240 }
241 return rate;
242 }
244 /**
245 * Derived directly from Dan Potter's log table
246 */
247 uint8_t aica_volume_table[256] = {
248 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
249 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4,
250 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 9,
251 9, 9, 10, 10, 11, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16,
252 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 22, 22, 23, 23, 24, 25,
253 25, 26, 27, 27, 28, 29, 29, 30, 31, 31, 32, 33, 34, 34, 35, 36,
254 37, 37, 38, 39, 40, 40, 41, 42, 43, 44, 45, 45, 46, 47, 48, 49,
255 50, 51, 52, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
256 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 76, 77, 78, 79, 80, 81,
257 82, 83, 85, 86, 87, 88, 89, 90, 92, 93, 94, 95, 97, 98, 99, 100,
258 102, 103, 104, 105, 107, 108, 109, 111, 112, 113, 115, 116, 117, 119, 120, 121,
259 123, 124, 126, 127, 128, 130, 131, 133, 134, 136, 137, 139, 140, 142, 143, 145,
260 146, 148, 149, 151, 152, 154, 155, 157, 159, 160, 162, 163, 165, 167, 168, 170,
261 171, 173, 175, 176, 178, 180, 181, 183, 185, 187, 188, 190, 192, 194, 195, 197,
262 199, 201, 202, 204, 206, 208, 210, 211, 213, 215, 217, 219, 221, 223, 224, 226,
263 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 253, 254, 255 };
266 void aica_write_channel( int channelNo, uint32_t reg, uint32_t val )
267 {
268 val &= 0x0000FFFF;
269 audio_channel_t channel = audio_get_channel(channelNo);
270 switch( reg ) {
271 case 0x00: /* Config + high address bits*/
272 channel->start = (channel->start & 0xFFFF) | ((val&0x1F) << 16);
273 if( val & 0x200 )
274 channel->loop = TRUE;
275 else
276 channel->loop = FALSE;
277 switch( (val >> 7) & 0x03 ) {
278 case 0:
279 channel->sample_format = AUDIO_FMT_16BIT;
280 break;
281 case 1:
282 channel->sample_format = AUDIO_FMT_8BIT;
283 break;
284 case 2:
285 case 3:
286 channel->sample_format = AUDIO_FMT_ADPCM;
287 break;
288 }
289 switch( (val >> 14) & 0x03 ) {
290 case 2:
291 audio_stop_channel( channelNo );
292 break;
293 case 3:
294 audio_start_channel( channelNo );
295 break;
296 default:
297 break;
298 /* Hrmm... */
299 }
300 break;
301 case 0x04: /* Low 16 address bits */
302 channel->start = (channel->start & 0x001F0000) | val;
303 break;
304 case 0x08: /* Loop start */
305 channel->loop_start = val;
306 break;
307 case 0x0C: /* End */
308 channel->end = val;
309 break;
310 case 0x10: /* Envelope register 1 */
311 break;
312 case 0x14: /* Envelope register 2 */
313 break;
314 case 0x18: /* Frequency */
315 channel->sample_rate = aica_frequency_to_sample_rate ( val );
316 break;
317 case 0x1C: /* ??? */
318 case 0x20: /* ??? */
319 case 0x24: /* Volume? /pan */
320 val = val & 0x1F;
321 if( val <= 0x0F )
322 val = 0x0F - val; /* Convert to smooth pan over 0..31 */
323 channel->pan = val;
324 break;
325 case 0x28: /* Volume */
326 channel->vol = aica_volume_table[val & 0xFF];
327 break;
328 default: /* ??? */
329 break;
330 }
332 }
.