1 // Game_Music_Emu 0.6-pre. http://www.slack.net/~ant/
5 #include "blargg_endian.h"
7 /* Copyright (C) 2006-2009 Shay Green. This module is free software; you
8 can redistribute it and/or modify it under the terms of the GNU Lesser
9 General Public License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version. This
11 module is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
14 details. You should have received a copy of the GNU Lesser General Public
15 License along with this module; if not, write to the Free Software Foundation,
16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
18 #include "blargg_source.h"
20 const char* const gme_wrong_file_type
= "Wrong file type for this emulator";
22 // TODO: probably don't need detailed errors as to why file is corrupt
24 int const spectrum_clock
= 3546900; // 128K Spectrum
25 int const spectrum_period
= 70908;
27 //int const spectrum_clock = 3500000; // 48K Spectrum
28 //int const spectrum_period = 69888;
30 int const cpc_clock
= 2000000;
32 static void clear_track_vars( struct Ay_Emu
*this )
34 this->current_track
= -1;
35 track_stop( &this->track_filter
);
38 void Ay_init( struct Ay_Emu
*this )
40 this->sample_rate
= 0;
42 this->tempo
= (int)FP_ONE_TEMPO
;
43 this->gain
= (int)FP_ONE_GAIN
;
44 this->track_count
= 0;
47 this->tfilter
= *track_get_setup( &this->track_filter
);
48 this->tfilter
.max_initial
= 2;
49 this->tfilter
.lookahead
= 6;
50 this->track_filter
.silence_ignored_
= false;
52 this->beeper_output
= NULL
;
53 disable_beeper( this );
55 Ay_apu_init( &this->apu
);
56 Z80_init( &this->cpu
);
59 this->voice_count
= 0;
60 this->voice_types
= 0;
61 clear_track_vars( this );
66 // Given pointer to 2-byte offset of data, returns pointer to data, or NULL if
67 // offset is 0 or there is less than min_size bytes of data available.
68 static byte
const* get_data( struct file_t
const* file
, byte
const ptr
[], int min_size
)
70 int offset
= (int16_t) get_be16( ptr
);
71 int pos
= ptr
- (byte
const*) file
->header
;
72 int size
= file
->end
- (byte
const*) file
->header
;
73 assert( (unsigned) pos
<= (unsigned) size
- 2 );
74 int limit
= size
- min_size
;
75 if ( limit
< 0 || !offset
|| (unsigned) (pos
+ offset
) > (unsigned) limit
)
80 static blargg_err_t
parse_header( byte
const in
[], int size
, struct file_t
* out
)
82 if ( size
< header_size
)
83 return gme_wrong_file_type
;
85 out
->header
= (struct header_t
const*) in
;
87 struct header_t
const* h
= (struct header_t
const*) in
;
88 if ( memcmp( h
->tag
, "ZXAYEMUL", 8 ) )
89 return gme_wrong_file_type
;
91 out
->tracks
= get_data( out
, h
->track_info
, (h
->max_track
+ 1) * 4 );
93 return "missing track data";
100 static void change_clock_rate( struct Ay_Emu
*this, int rate
)
102 this->clock_rate_
= rate
;
103 Buffer_clock_rate( &this->stereo_buf
, rate
);
106 blargg_err_t
Ay_load_mem( struct Ay_Emu
*this, byte
const in
[], long size
)
109 this->voice_count
= 0;
110 this->track_count
= 0;
112 clear_track_vars( this );
114 assert( offsetof (struct header_t
,track_info
[2]) == header_size
);
116 RETURN_ERR( parse_header( in
, size
, &this->file
) );
118 /* if ( file.header->vers > 2 )
119 warning( "Unknown file version" ); */
121 this->voice_count
= ay_osc_count
+ 1; // +1 for beeper
122 static int const types
[ay_osc_count
+ 1] = {
123 wave_type
+0, wave_type
+1, wave_type
+2, mixed_type
+1
125 this->voice_types
= types
;
127 Ay_apu_volume( &this->apu
, this->gain
);
130 change_clock_rate( this, spectrum_clock
);
131 RETURN_ERR( Buffer_set_channel_count( &this->stereo_buf
, this->voice_count
, this->voice_types
) );
132 this->buf_changed_count
= Buffer_channels_changed_count( &this->stereo_buf
);
134 Sound_set_tempo( this, this->tempo
);
135 Sound_mute_voices( this, this->mute_mask_
);
137 this->track_count
= this->file
.header
->max_track
+ 1;
141 static void set_beeper_output( struct Ay_Emu
*this, struct Blip_Buffer
* b
)
143 this->beeper_output
= b
;
144 if ( b
&& !this->cpc_mode
)
145 this->beeper_mask
= 0x10;
147 disable_beeper( this );
150 static void set_voice( struct Ay_Emu
*this, int i
, struct Blip_Buffer
* center
)
152 if ( i
>= ay_osc_count
)
153 set_beeper_output( this, center
);
155 Ay_apu_set_output( &this->apu
, i
, center
);
158 static blargg_err_t
run_clocks( struct Ay_Emu
*this, blip_time_t
* duration
, int msec
)
164 cpu_time_t
*end
= duration
;
165 struct Z80_Cpu
* cpu
= &this->cpu
;
166 Z80_set_time( cpu
, 0 );
168 // Since detection of CPC mode will halve clock rate during the frame
169 // and thus generate up to twice as much sound, we must generate half
170 // as much until mode is known.
171 if ( !(this->spectrum_mode
| this->cpc_mode
) )
174 while ( Z80_time( cpu
) < *end
)
176 run_cpu( this, min( *end
, this->next_play
) );
178 if ( Z80_time( cpu
) >= this->next_play
)
181 this->next_play
+= this->play_period
;
187 if ( this->mem
.ram
[cpu
->r
.pc
] == 0x76 )
188 cpu
->r
.pc
++; // advance past HALT instruction
193 this->mem
.ram
[--cpu
->r
.sp
] = (byte
) (cpu
->r
.pc
>> 8);
194 this->mem
.ram
[--cpu
->r
.sp
] = (byte
) (cpu
->r
.pc
);
198 Z80_adjust_time( cpu
, 12 );
200 if ( cpu
->r
.im
== 2 )
202 // vectored interrupt
203 addr_t addr
= cpu
->r
.i
* 0x100 + 0xFF;
204 cpu
->r
.pc
= this->mem
.ram
[(addr
+ 1) & 0xFFFF] * 0x100 + this->mem
.ram
[addr
];
205 Z80_adjust_time( cpu
, 6 );
212 *end
= Z80_time( cpu
);
213 this->next_play
-= *end
;
214 check( this->next_play
>= 0 );
215 Z80_adjust_time( cpu
, -*end
);
216 Ay_apu_end_frame( &this->apu
, *end
);
222 void cpu_out_( struct Ay_Emu
*this, cpu_time_t time
, addr_t addr
, int data
)
225 if ( !this->cpc_mode
)
227 switch ( addr
& 0xFEFF )
230 this->spectrum_mode
= true;
231 Ay_apu_write_addr( &this->apu
, data
);
235 this->spectrum_mode
= true;
236 Ay_apu_write_data( &this->apu
, time
, data
);
242 if ( !this->spectrum_mode
)
247 switch ( data
& 0xC0 )
250 Ay_apu_write_addr( &this->apu
, this->cpc_latch
);
254 Ay_apu_write_data( &this->apu
, time
, this->cpc_latch
);
260 this->cpc_latch
= data
;
265 /* dprintf( "Unmapped OUT: $%04X <- $%02X\n", addr, data ); */
269 if ( !this->cpc_mode
)
271 this->cpc_mode
= true;
272 disable_beeper( this );
274 change_clock_rate( this, cpc_clock
);
275 Sound_set_tempo( this, this->tempo
);
279 blargg_err_t
Ay_set_sample_rate( struct Ay_Emu
*this, int rate
)
281 require( !this->sample_rate
); // sample rate can't be changed once set
282 Buffer_init( &this->stereo_buf
);
283 RETURN_ERR( Buffer_set_sample_rate( &this->stereo_buf
, rate
, 1000 / 20 ) );
286 Buffer_bass_freq( &this->stereo_buf
, 160 );
288 this->sample_rate
= rate
;
289 RETURN_ERR( track_init( &this->track_filter
, this ) );
290 this->tfilter
.max_silence
= 6 * stereo
* this->sample_rate
;
294 void Sound_mute_voice( struct Ay_Emu
*this, int index
, bool mute
)
296 require( (unsigned) index
< (unsigned) this->voice_count
);
297 int bit
= 1 << index
;
298 int mask
= this->mute_mask_
| bit
;
301 Sound_mute_voices( this, mask
);
304 void Sound_mute_voices( struct Ay_Emu
*this, int mask
)
306 require( this->sample_rate
); // sample rate must be set first
307 this->mute_mask_
= mask
;
310 for ( i
= this->voice_count
; i
--; )
312 if ( mask
& (1 << i
) )
314 set_voice( this, i
, 0 );
318 struct channel_t ch
= Buffer_channel( &this->stereo_buf
, i
);
319 assert( (ch
.center
&& ch
.left
&& ch
.right
) ||
320 (!ch
.center
&& !ch
.left
&& !ch
.right
) ); // all or nothing
321 set_voice( this, i
, ch
.center
);
326 void Sound_set_tempo( struct Ay_Emu
*this, int t
)
328 require( this->sample_rate
); // sample rate must be set first
329 int const min
= (int)(FP_ONE_TEMPO
*0.02);
330 int const max
= (int)(FP_ONE_TEMPO
*4.00);
331 if ( t
< min
) t
= min
;
332 if ( t
> max
) t
= max
;
335 int p
= spectrum_period
;
336 if ( this->clock_rate_
!= spectrum_clock
)
337 p
= this->clock_rate_
/ 50;
339 this->play_period
= (blip_time_t
) ((p
* FP_ONE_TEMPO
) / t
);
342 blargg_err_t
Ay_start_track( struct Ay_Emu
*this, int track
)
344 clear_track_vars( this );
346 // Remap track if playlist available
347 if ( this->m3u
.size
> 0 ) {
348 struct entry_t
* e
= &this->m3u
.entries
[track
];
352 this->current_track
= track
;
353 Buffer_clear( &this->stereo_buf
);
355 byte
* const mem
= this->mem
.ram
;
357 memset( mem
+ 0x0000, 0xC9, 0x100 ); // fill RST vectors with RET
358 memset( mem
+ 0x0100, 0xFF, 0x4000 - 0x100 );
359 memset( mem
+ ram_addr
, 0x00, mem_size
- ram_addr
);
361 // locate data blocks
362 byte
const* const data
= get_data( &this->file
, this->file
.tracks
+ track
* 4 + 2, 14 );
364 return "file data missing";
366 byte
const* const more_data
= get_data( &this->file
, data
+ 10, 6 );
368 return "file data missing";
370 byte
const* blocks
= get_data( &this->file
, data
+ 12, 8 );
372 return "file data missing";
375 unsigned addr
= get_be16( blocks
);
377 return "file data missing";
379 unsigned init
= get_be16( more_data
+ 2 );
383 // copy blocks into memory
387 unsigned len
= get_be16( blocks
); blocks
+= 2;
388 if ( addr
+ len
> mem_size
)
390 /* warning( "Bad data block size" ); */
391 len
= mem_size
- addr
;
394 byte
const* in
= get_data( &this->file
, blocks
, 0 ); blocks
+= 2;
395 if ( len
> (unsigned) (this->file
.end
- in
) )
397 /* warning( "File data missing" ); */
398 len
= this->file
.end
- in
;
401 memcpy( mem
+ addr
, in
, len
);
403 if ( this->file
.end
- blocks
< 8 )
405 /* warning( "File data missing" ); */
409 while ( (addr
= get_be16( blocks
)) != 0 );
411 // copy and configure driver
412 static byte
const passive
[] = {
414 0xCD, 0, 0, // CALL init
415 0xED, 0x5E, // LOOP: IM 2
418 0x18, 0xFA // JR LOOP
420 static byte
const active
[] = {
422 0xCD, 0, 0, // CALL init
423 0xED, 0x56, // LOOP: IM 1
426 0xCD, 0, 0, // CALL play
427 0x18, 0xF7 // JR LOOP
429 memcpy( mem
, passive
, sizeof passive
);
430 int const play_addr
= get_be16( more_data
+ 4 );
433 memcpy( mem
, active
, sizeof active
);
434 mem
[ 9] = play_addr
;
435 mem
[10] = play_addr
>> 8;
440 mem
[0x38] = 0xFB; // Put EI at interrupt vector (followed by RET)
442 // start at spectrum speed
443 change_clock_rate( this, spectrum_clock
);
444 Sound_set_tempo( this, this->tempo
);
446 struct registers_t r
;
447 memset( &r
, 0, sizeof(struct registers_t
) );
449 r
.sp
= get_be16( more_data
);
450 r
.b
.a
= r
.b
.b
= r
.b
.d
= r
.b
.h
= data
[8];
451 r
.b
.flags
= r
.b
.c
= r
.b
.e
= r
.b
.l
= data
[9];
453 r
.ix
= r
.iy
= r
.w
.hl
;
455 memset( this->mem
.padding1
, 0xFF, sizeof this->mem
.padding1
);
457 int const mirrored
= 0x80; // this much is mirrored after end of memory
458 memset( this->mem
.ram
+ mem_size
+ mirrored
, 0xFF, sizeof this->mem
.ram
- mem_size
- mirrored
);
459 memcpy( this->mem
.ram
+ mem_size
, this->mem
.ram
, mirrored
); // some code wraps around (ugh)
461 Z80_reset( &this->cpu
, this->mem
.padding1
, this->mem
.padding1
);
462 Z80_map_mem( &this->cpu
, 0, mem_size
, this->mem
.ram
, this->mem
.ram
);
465 this->beeper_delta
= (int) ((ay_amp_range
*4)/5);
466 this->last_beeper
= 0;
467 this->next_play
= this->play_period
;
468 this->spectrum_mode
= false;
469 this->cpc_mode
= false;
471 set_beeper_output( this, this->beeper_output
);
472 Ay_apu_reset( &this->apu
);
474 // a few tunes rely on channels having tone enabled at the beginning
475 Ay_apu_write_addr( &this->apu
, 7 );
476 Ay_apu_write_data( &this->apu
, 0, 0x38 );
478 // convert filter times to samples
479 struct setup_t s
= this->tfilter
;
480 s
.max_initial
*= this->sample_rate
* stereo
;
481 #ifdef GME_DISABLE_SILENCE_LOOKAHEAD
484 track_setup( &this->track_filter
, &s
);
486 return track_start( &this->track_filter
);
491 static int msec_to_samples( int msec
, int sample_rate
)
493 int sec
= msec
/ 1000;
495 return (sec
* sample_rate
+ msec
* sample_rate
/ 1000) * stereo
;
498 int Track_tell( struct Ay_Emu
*this )
500 int rate
= this->sample_rate
* stereo
;
501 int sec
= track_sample_count( &this->track_filter
) / rate
;
502 return sec
* 1000 + (track_sample_count( &this->track_filter
) - sec
* rate
) * 1000 / rate
;
505 blargg_err_t
Track_seek( struct Ay_Emu
*this, int msec
)
507 int time
= msec_to_samples( msec
, this->sample_rate
);
508 if ( time
< track_sample_count( &this->track_filter
) )
509 RETURN_ERR( Ay_start_track( this, this->current_track
) );
510 return Track_skip( this, time
- track_sample_count( &this->track_filter
) );
513 blargg_err_t
skip_( void *emu
, int count
)
515 struct Ay_Emu
* this = (struct Ay_Emu
*) emu
;
517 // for long skip, mute sound
518 const int threshold
= 32768;
519 if ( count
> threshold
)
521 int saved_mute
= this->mute_mask_
;
522 Sound_mute_voices( this, ~0 );
524 int n
= count
- threshold
/2;
525 n
&= ~(2048-1); // round to multiple of 2048
527 RETURN_ERR( skippy_( &this->track_filter
, n
) );
529 Sound_mute_voices( this, saved_mute
);
532 return skippy_( &this->track_filter
, count
);
535 blargg_err_t
Track_skip( struct Ay_Emu
*this, int count
)
537 require( this->current_track
>= 0 ); // start_track() must have been called already
538 return track_skip( &this->track_filter
, count
);
541 int Track_get_length( struct Ay_Emu
* this, int n
)
545 byte
const* track_info
= get_data( &this->file
, this->file
.tracks
+ n
* 4 + 2, 6 );
547 length
= get_be16( track_info
+ 4 ) * (1000 / 50); // frames to msec
549 if ( (this->m3u
.size
> 0) && (n
< this->m3u
.size
) ) {
550 struct entry_t
* entry
= &this->m3u
.entries
[n
];
551 length
= entry
->length
;
555 length
= 120 * 1000; /* 2 minutes */
560 void Track_set_fade( struct Ay_Emu
*this, int start_msec
, int length_msec
)
562 track_set_fade( &this->track_filter
, msec_to_samples( start_msec
, this->sample_rate
),
563 length_msec
* this->sample_rate
/ (1000 / stereo
) );
566 blargg_err_t
Ay_play( struct Ay_Emu
*this, int out_count
, sample_t
* out
)
568 require( this->current_track
>= 0 );
569 require( out_count
% stereo
== 0 );
570 return track_play( &this->track_filter
, out_count
, out
);
573 blargg_err_t
play_( void *emu
, int count
, sample_t
* out
)
575 struct Ay_Emu
* this = (struct Ay_Emu
*) emu
;
580 Buffer_disable_immediate_removal( &this->stereo_buf
);
581 remain
-= Buffer_read_samples( &this->stereo_buf
, &out
[count
- remain
], remain
);
584 if ( this->buf_changed_count
!= Buffer_channels_changed_count( &this->stereo_buf
) )
586 this->buf_changed_count
= Buffer_channels_changed_count( &this->stereo_buf
);
589 Sound_mute_voices( this, this->mute_mask_
);
591 int msec
= Buffer_length( &this->stereo_buf
);
592 blip_time_t clocks_emulated
= msec
* this->clock_rate_
/ 1000 - 100;
593 RETURN_ERR( run_clocks( this, &clocks_emulated
, msec
) );
594 assert( clocks_emulated
);
595 Buffer_end_frame( &this->stereo_buf
, clocks_emulated
);