filename | src/aica/aica.c |
changeset | 1067:d3c00ffccfcd |
prev | 1024:c67f2d61ab97 |
prev | 934:3acd3b3ee6d1 |
author | nkeynes |
date | Sun May 24 19:46:06 2015 +1000 (8 years ago) |
permissions | -rw-r--r-- |
last change | Remove static from gl_load_frame_buffer() - also needed by video_egl.c Fix error location in gl_frame_buffer_to_tex |
view | annotate | diff | log | raw |
1 /**
2 * $Id$
3 *
4 * This module implements the AICA's IO interfaces, as well
5 * as providing the core AICA module to the system.
6 *
7 * Copyright (c) 2005 Nathan Keynes.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 */
20 #define MODULE aica_module
22 #include <time.h>
23 #include "dream.h"
24 #include "dreamcast.h"
25 #include "mem.h"
26 #include "aica/aica.h"
27 #include "armcore.h"
28 #include "aica/audio.h"
29 #define MMIO_IMPL
30 #include "aica.h"
32 MMIO_REGION_READ_DEFFN( AICA0 )
33 MMIO_REGION_READ_DEFFN( AICA1 )
34 MMIO_REGION_READ_DEFSUBFNS(AICA0)
35 MMIO_REGION_READ_DEFSUBFNS(AICA1)
36 MMIO_REGION_READ_DEFSUBFNS(AICA2)
37 MMIO_REGION_READ_DEFSUBFNS(AICARTC)
39 void aica_init( void );
40 void aica_reset( void );
41 void aica_start( void );
42 void aica_stop( void );
43 void aica_save_state( FILE *f );
44 int aica_load_state( FILE *f );
45 uint32_t aica_run_slice( uint32_t );
47 struct dreamcast_module aica_module = { "AICA", aica_init, aica_reset,
48 aica_start, aica_run_slice, aica_stop,
49 aica_save_state, aica_load_state };
51 struct aica_state_struct {
52 uint32_t time_of_day;
53 /**
54 * Keep track of what we've done so far this second, to try to keep the
55 * precision of samples/second.
56 */
57 uint32_t samples_done;
58 uint32_t nanosecs_done;
59 /**
60 * Event (IRQ) state
61 */
62 int event_pending;
63 int clear_count;
64 };
66 static struct aica_state_struct aica_state;
69 /**
70 * Initialize the AICA subsystem. Note requires that
71 */
72 void aica_init( void )
73 {
74 register_io_regions( mmio_list_spu );
75 MMIO_NOTRACE(AICA0);
76 MMIO_NOTRACE(AICA1);
77 aica_reset();
78 }
80 void aica_reset( void )
81 {
82 arm_reset();
83 aica_state.time_of_day = 0x5bfc8900;
84 aica_state.samples_done = 0;
85 aica_state.nanosecs_done = 0;
86 aica_state.event_pending = 0;
87 aica_state.clear_count = 0;
88 // aica_event(2); /* Pre-deliver a timer interrupt */
89 }
91 void aica_start( void )
92 {
93 audio_start_driver();
94 }
96 uint32_t aica_run_slice( uint32_t nanosecs )
97 {
98 /* Run arm instructions */
99 int reset = MMIO_READ( AICA2, AICA_RESET );
100 if( (reset & 1) == 0 ) { /* Running */
101 int num_samples = (int)((uint64_t)AICA_SAMPLE_RATE * (aica_state.nanosecs_done + nanosecs) / 1000000000) - aica_state.samples_done;
102 num_samples = arm_run_slice( num_samples );
103 audio_mix_samples( num_samples );
105 aica_state.samples_done += num_samples;
106 aica_state.nanosecs_done += nanosecs;
107 }
108 if( aica_state.nanosecs_done > 1000000000 ) {
109 aica_state.samples_done -= AICA_SAMPLE_RATE;
110 aica_state.nanosecs_done -= 1000000000;
111 aica_state.time_of_day++;
112 }
113 return nanosecs;
114 }
116 void aica_stop( void )
117 {
118 audio_stop_driver();
119 }
121 void aica_save_state( FILE *f )
122 {
123 fwrite( &aica_state, sizeof(struct aica_state_struct), 1, f );
124 arm_save_state( f );
125 audio_save_state(f);
126 }
128 int aica_load_state( FILE *f )
129 {
130 fread( &aica_state, sizeof(struct aica_state_struct), 1, f );
131 arm_load_state( f );
132 return audio_load_state(f);
133 }
135 /* Note: This is probably not necessarily technically correct but it should
136 * work in the meantime.
137 */
139 void aica_event( int event )
140 {
141 if( aica_state.event_pending == 0 )
142 armr.int_pending |= CPSR_F;
143 aica_state.event_pending |= (1<<event);
145 int pending = MMIO_READ( AICA2, AICA_IRQ );
146 if( pending == 0 || event < pending )
147 MMIO_WRITE( AICA2, AICA_IRQ, event );
148 }
150 void aica_clear_event( )
151 {
152 aica_state.clear_count++;
153 if( aica_state.clear_count == 4 ) {
154 int i;
155 aica_state.clear_count = 0;
157 for( i=0; i<8; i++ ) {
158 if( aica_state.event_pending & (1<<i) ) {
159 aica_state.event_pending &= ~(1<<i);
160 break;
161 }
162 }
163 for( ;i<8; i++ ) {
164 if( aica_state.event_pending & (1<<i) ) {
165 MMIO_WRITE( AICA2, AICA_IRQ, i );
166 break;
167 }
168 }
169 if( aica_state.event_pending == 0 )
170 armr.int_pending &= ~CPSR_F;
171 }
172 }
174 void aica_enable( void )
175 {
176 mmio_region_AICA2_write( AICA_RESET, MMIO_READ(AICA2,AICA_RESET) & ~1 );
177 }
179 /** Channel register structure:
180 * 00 4 Channel config
181 * 04 4 Waveform address lo (16 bits)
182 * 08 4 Loop start address
183 * 0C 4 Loop end address
184 * 10 4 Volume envelope
185 * 14 4 Init to 0x1F
186 * 18 4 Frequency (floating point)
187 * 1C 4 ??
188 * 20 4 ??
189 * 24 1 Pan
190 * 25 1 ??
191 * 26
192 * 27
193 * 28 1 ??
194 * 29 1 Volume
195 * 2C
196 * 30
197 */
199 /* Write to channels 0-31 */
200 MMIO_REGION_WRITE_FN( AICA0, reg, val )
201 {
202 reg &= 0xFFF;
203 MMIO_WRITE( AICA0, reg, val );
204 aica_write_channel( reg >> 7, reg % 128, val );
205 // DEBUG( "AICA0 Write %08X => %08X", val, reg );
206 }
208 /* Write to channels 32-64 */
209 MMIO_REGION_WRITE_FN( AICA1, reg, val )
210 {
211 reg &= 0xFFF;
212 MMIO_WRITE( AICA1, reg, val );
213 aica_write_channel( (reg >> 7) + 32, reg % 128, val );
214 // DEBUG( "AICA1 Write %08X => %08X", val, reg );
215 }
217 /**
218 * AICA control registers
219 */
220 MMIO_REGION_WRITE_FN( AICA2, reg, val )
221 {
222 uint32_t tmp;
223 reg &= 0xFFF;
225 switch( reg ) {
226 case AICA_RESET:
227 tmp = MMIO_READ( AICA2, AICA_RESET );
228 if( (tmp & 1) == 1 && (val & 1) == 0 ) {
229 /* ARM enabled - execute a core reset */
230 DEBUG( "ARM enabled" );
231 arm_reset();
232 aica_state.samples_done = 0;
233 aica_state.nanosecs_done = 0;
234 } else if( (tmp&1) == 0 && (val&1) == 1 ) {
235 DEBUG( "ARM disabled" );
236 }
237 MMIO_WRITE( AICA2, AICA_RESET, val );
238 break;
239 case AICA_IRQCLEAR:
240 aica_clear_event();
241 break;
242 case AICA_FIFOIN: /* Read-only */
243 break;
244 default:
245 MMIO_WRITE( AICA2, reg, val );
246 break;
247 }
248 }
250 MMIO_REGION_READ_FN( AICA2, reg )
251 {
252 audio_channel_t channel;
253 uint32_t channo;
254 int32_t val;
255 reg &= 0xFFF;
256 switch( reg ) {
257 case AICA_CHANSTATE:
258 channo = (MMIO_READ( AICA2, AICA_CHANSEL ) >> 8) & 0x3F;
259 channel = audio_get_channel(channo);
260 if( channel->loop == LOOP_LOOPED ) {
261 val = 0x8000;
262 channel->loop = LOOP_ON;
263 } else {
264 val = 0;
265 }
266 return val;
267 case AICA_CHANPOSN:
268 channo = (MMIO_READ( AICA2, AICA_CHANSEL ) >> 8) & 0x3F;
269 channel = audio_get_channel(channo);
270 return channel->posn;
271 default:
272 return MMIO_READ( AICA2, reg );
273 }
274 }
276 MMIO_REGION_READ_FN( AICARTC, reg )
277 {
278 int32_t rv = 0;
279 reg &= 0xFFF;
280 switch( reg ) {
281 case AICA_RTCHI:
282 rv = (aica_state.time_of_day >> 16) & 0xFFFF;
283 break;
284 case AICA_RTCLO:
285 rv = aica_state.time_of_day & 0xFFFF;
286 break;
287 }
288 // DEBUG( "Read AICA RTC %d => %08X", reg, rv );
289 return rv;
290 }
292 MMIO_REGION_WRITE_FN( AICARTC, reg, val )
293 {
294 reg &= 0xFFF;
295 switch( reg ) {
296 case AICA_RTCEN:
297 MMIO_WRITE( AICARTC, reg, val&0x01 );
298 break;
299 case AICA_RTCLO:
300 if( MMIO_READ( AICARTC, AICA_RTCEN ) & 0x01 ) {
301 aica_state.time_of_day = (aica_state.time_of_day & 0xFFFF0000) | (val & 0xFFFF);
302 }
303 break;
304 case AICA_RTCHI:
305 if( MMIO_READ( AICARTC, AICA_RTCEN ) & 0x01 ) {
306 aica_state.time_of_day = (aica_state.time_of_day & 0xFFFF) | (val<<16);
307 MMIO_WRITE( AICARTC, AICA_RTCEN, 0 );
308 }
309 break;
310 }
311 }
313 /**
314 * Translate the channel frequency to a sample rate. The frequency is a
315 * 14-bit floating point number, where bits 0..9 is the mantissa,
316 * 11..14 is the signed exponent (-8 to +7). Bit 10 appears to
317 * be unused.
318 *
319 * @return sample rate in samples per second.
320 */
321 uint32_t aica_frequency_to_sample_rate( uint32_t freq )
322 {
323 uint32_t exponent = (freq & 0x3800) >> 11;
324 uint32_t mantissa = freq & 0x03FF;
325 uint32_t rate;
326 if( freq & 0x4000 ) {
327 /* neg exponent - rate < 44100 */
328 exponent = 8 - exponent;
329 rate = (44100 >> exponent) +
330 ((44100 * mantissa) >> (10+exponent));
331 } else {
332 /* pos exponent - rate > 44100 */
333 rate = (44100 << exponent) +
334 ((44100 * mantissa) >> (10-exponent));
335 }
336 return rate;
337 }
339 void aica_start_stop_channels()
340 {
341 int i;
342 for( i=0; i<32; i++ ) {
343 uint32_t val = MMIO_READ( AICA0, i<<7 );
344 audio_start_stop_channel(i, val&0x4000);
345 }
346 for( ; i<64; i++ ) {
347 uint32_t val = MMIO_READ( AICA1, (i-32)<<7 );
348 audio_start_stop_channel(i, val&0x4000);
349 }
350 }
352 /**
353 * Derived directly from Dan Potter's log table
354 */
355 uint8_t aica_volume_table[256] = {
356 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
357 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4,
358 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 9,
359 9, 9, 10, 10, 11, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16,
360 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 22, 22, 23, 23, 24, 25,
361 25, 26, 27, 27, 28, 29, 29, 30, 31, 31, 32, 33, 34, 34, 35, 36,
362 37, 37, 38, 39, 40, 40, 41, 42, 43, 44, 45, 45, 46, 47, 48, 49,
363 50, 51, 52, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
364 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 76, 77, 78, 79, 80, 81,
365 82, 83, 85, 86, 87, 88, 89, 90, 92, 93, 94, 95, 97, 98, 99, 100,
366 102, 103, 104, 105, 107, 108, 109, 111, 112, 113, 115, 116, 117, 119, 120, 121,
367 123, 124, 126, 127, 128, 130, 131, 133, 134, 136, 137, 139, 140, 142, 143, 145,
368 146, 148, 149, 151, 152, 154, 155, 157, 159, 160, 162, 163, 165, 167, 168, 170,
369 171, 173, 175, 176, 178, 180, 181, 183, 185, 187, 188, 190, 192, 194, 195, 197,
370 199, 201, 202, 204, 206, 208, 210, 211, 213, 215, 217, 219, 221, 223, 224, 226,
371 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 253, 254, 255 };
374 void aica_write_channel( int channelNo, uint32_t reg, uint32_t val )
375 {
376 val &= 0x0000FFFF;
377 audio_channel_t channel = audio_get_channel(channelNo);
378 switch( reg ) {
379 case 0x00: /* Config + high address bits*/
380 channel->start = (channel->start & 0xFFFF) | ((val&0x1F) << 16);
381 if( val & 0x200 )
382 channel->loop = LOOP_ON;
383 else
384 channel->loop = LOOP_OFF;
385 switch( (val >> 7) & 0x03 ) {
386 case 0:
387 channel->sample_format = AUDIO_FMT_16BIT;
388 break;
389 case 1:
390 channel->sample_format = AUDIO_FMT_8BIT;
391 break;
392 case 2:
393 case 3:
394 channel->sample_format = AUDIO_FMT_ADPCM;
395 break;
396 }
397 if( val & 0x8000 ) {
398 aica_start_stop_channels();
399 }
400 break;
401 case 0x04: /* Low 16 address bits */
402 channel->start = (channel->start & 0x001F0000) | val;
403 break;
404 case 0x08: /* Loop start */
405 channel->loop_start = val;
406 break;
407 case 0x0C: /* End */
408 channel->end = val;
409 break;
410 case 0x10: /* Envelope register 1 */
411 break;
412 case 0x14: /* Envelope register 2 */
413 break;
414 case 0x18: /* Frequency */
415 channel->sample_rate = aica_frequency_to_sample_rate ( val );
416 break;
417 case 0x1C: /* ??? */
418 case 0x20: /* ??? */
419 case 0x24: /* Volume? /pan */
420 val = val & 0x1F;
421 if( val <= 0x0F )
422 val = 0x0F - val; /* Convert to smooth pan over 0..31 */
423 channel->pan = val;
424 break;
425 case 0x28: /* Volume */
426 // This isn't remotely correct, but it will have to suffice until I have
427 // time to figure out what's actually going on here...
428 channel->vol = aica_volume_table[max((val & 0xFF),((val>>8)&0xFF))];
429 break;
430 default: /* ??? */
431 break;
432 }
434 }
.