diff options
Diffstat (limited to 'apps/codecs')
30 files changed, 8870 insertions, 8870 deletions
diff --git a/apps/codecs/libgme/2413tone.h b/apps/codecs/libgme/2413tone.h index e4366ab245..c0922c1225 100644 --- a/apps/codecs/libgme/2413tone.h +++ b/apps/codecs/libgme/2413tone.h | |||
@@ -1,20 +1,20 @@ | |||
1 | /* YM2413 tone by okazaki@angel.ne.jp */ | 1 | /* YM2413 tone by okazaki@angel.ne.jp */ |
2 | 0x49,0x4c,0x4c,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 2 | 0x49,0x4c,0x4c,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
3 | 0x61,0x61,0x1e,0x17,0xf0,0x7f,0x00,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 3 | 0x61,0x61,0x1e,0x17,0xf0,0x7f,0x00,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
4 | 0x13,0x41,0x16,0x0e,0xfd,0xf4,0x23,0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 4 | 0x13,0x41,0x16,0x0e,0xfd,0xf4,0x23,0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
5 | 0x03,0x01,0x9a,0x04,0xf3,0xf3,0x13,0xf3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 5 | 0x03,0x01,0x9a,0x04,0xf3,0xf3,0x13,0xf3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
6 | 0x11,0x61,0x0e,0x07,0xfa,0x64,0x70,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 6 | 0x11,0x61,0x0e,0x07,0xfa,0x64,0x70,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
7 | 0x22,0x21,0x1e,0x06,0xf0,0x76,0x00,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 7 | 0x22,0x21,0x1e,0x06,0xf0,0x76,0x00,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
8 | 0x21,0x22,0x16,0x05,0xf0,0x71,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 8 | 0x21,0x22,0x16,0x05,0xf0,0x71,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
9 | 0x21,0x61,0x1d,0x07,0x82,0x80,0x17,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 9 | 0x21,0x61,0x1d,0x07,0x82,0x80,0x17,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
10 | 0x23,0x21,0x2d,0x16,0x90,0x90,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 10 | 0x23,0x21,0x2d,0x16,0x90,0x90,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
11 | 0x21,0x21,0x1b,0x06,0x64,0x65,0x10,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 11 | 0x21,0x21,0x1b,0x06,0x64,0x65,0x10,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
12 | 0x21,0x21,0x0b,0x1a,0x85,0xa0,0x70,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 12 | 0x21,0x21,0x0b,0x1a,0x85,0xa0,0x70,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
13 | 0x23,0x01,0x83,0x10,0xff,0xb4,0x10,0xf4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 13 | 0x23,0x01,0x83,0x10,0xff,0xb4,0x10,0xf4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
14 | 0x97,0xc1,0x20,0x07,0xff,0xf4,0x22,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 14 | 0x97,0xc1,0x20,0x07,0xff,0xf4,0x22,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
15 | 0x61,0x00,0x0c,0x05,0xc2,0xf6,0x40,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 15 | 0x61,0x00,0x0c,0x05,0xc2,0xf6,0x40,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
16 | 0x01,0x01,0x56,0x03,0x94,0xc2,0x03,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 16 | 0x01,0x01,0x56,0x03,0x94,0xc2,0x03,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
17 | 0x21,0x01,0x89,0x03,0xf1,0xe4,0xf0,0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 17 | 0x21,0x01,0x89,0x03,0xf1,0xe4,0xf0,0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
18 | 0x07,0x21,0x14,0x00,0xee,0xf8,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 18 | 0x07,0x21,0x14,0x00,0xee,0xf8,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
19 | 0x01,0x31,0x00,0x00,0xf8,0xf7,0xf8,0xf7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 19 | 0x01,0x31,0x00,0x00,0xf8,0xf7,0xf8,0xf7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
20 | 0x25,0x11,0x00,0x00,0xf8,0xfa,0xf8,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 | 20 | 0x25,0x11,0x00,0x00,0xf8,0xfa,0xf8,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
diff --git a/apps/codecs/libgme/281btone.h b/apps/codecs/libgme/281btone.h index 1300523fbe..83f63bff00 100644 --- a/apps/codecs/libgme/281btone.h +++ b/apps/codecs/libgme/281btone.h | |||
@@ -1,20 +1,20 @@ | |||
1 | /* YMF281B tone by Chabin */ | 1 | /* YMF281B tone by Chabin */ |
2 | 0x49,0x4c,0x4c,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 2 | 0x49,0x4c,0x4c,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
3 | 0x62,0x21,0x1a,0x07,0xf0,0x6f,0x00,0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 3 | 0x62,0x21,0x1a,0x07,0xf0,0x6f,0x00,0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
4 | 0x00,0x10,0x44,0x02,0xf6,0xf4,0x54,0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 4 | 0x00,0x10,0x44,0x02,0xf6,0xf4,0x54,0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
5 | 0x03,0x01,0x97,0x04,0xf3,0xf3,0x13,0xf3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 5 | 0x03,0x01,0x97,0x04,0xf3,0xf3,0x13,0xf3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
6 | 0x01,0x61,0x0a,0x0f,0xfa,0x64,0x70,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 6 | 0x01,0x61,0x0a,0x0f,0xfa,0x64,0x70,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
7 | 0x22,0x21,0x1e,0x06,0xf0,0x76,0x00,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 7 | 0x22,0x21,0x1e,0x06,0xf0,0x76,0x00,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
8 | 0x00,0x61,0x8a,0x0e,0xc0,0x61,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 8 | 0x00,0x61,0x8a,0x0e,0xc0,0x61,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
9 | 0x21,0x61,0x1b,0x07,0x84,0x80,0x17,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 9 | 0x21,0x61,0x1b,0x07,0x84,0x80,0x17,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
10 | 0x37,0x32,0xc9,0x01,0x66,0x64,0x40,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 10 | 0x37,0x32,0xc9,0x01,0x66,0x64,0x40,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
11 | 0x01,0x21,0x06,0x03,0xa5,0x71,0x51,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 11 | 0x01,0x21,0x06,0x03,0xa5,0x71,0x51,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
12 | 0x06,0x11,0x5e,0x07,0xf3,0xf2,0xf6,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 12 | 0x06,0x11,0x5e,0x07,0xf3,0xf2,0xf6,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
13 | 0x00,0x20,0x18,0x06,0xf5,0xf3,0x20,0x26,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 13 | 0x00,0x20,0x18,0x06,0xf5,0xf3,0x20,0x26,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
14 | 0x97,0x41,0x20,0x07,0xff,0xf4,0x22,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 14 | 0x97,0x41,0x20,0x07,0xff,0xf4,0x22,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
15 | 0x65,0x61,0x15,0x00,0xf7,0xf3,0x16,0xf4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 15 | 0x65,0x61,0x15,0x00,0xf7,0xf3,0x16,0xf4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
16 | 0x01,0x31,0x0e,0x07,0xfa,0xf3,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 16 | 0x01,0x31,0x0e,0x07,0xfa,0xf3,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
17 | 0x48,0x61,0x09,0x07,0xf1,0x94,0xf0,0xf5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 17 | 0x48,0x61,0x09,0x07,0xf1,0x94,0xf0,0xf5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
18 | 0x07,0x21,0x14,0x00,0xee,0xf8,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 18 | 0x07,0x21,0x14,0x00,0xee,0xf8,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
19 | 0x01,0x31,0x00,0x00,0xf8,0xf7,0xf8,0xf7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 19 | 0x01,0x31,0x00,0x00,0xf8,0xf7,0xf8,0xf7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
20 | 0x25,0x11,0x00,0x00,0xf8,0xfa,0xf8,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 | 20 | 0x25,0x11,0x00,0x00,0xf8,0xfa,0xf8,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
diff --git a/apps/codecs/libgme/ay_emu.c b/apps/codecs/libgme/ay_emu.c index 42e739f2df..92faba4929 100644 --- a/apps/codecs/libgme/ay_emu.c +++ b/apps/codecs/libgme/ay_emu.c | |||
@@ -1,599 +1,599 @@ | |||
1 | // Game_Music_Emu 0.6-pre. http://www.slack.net/~ant/ | 1 | // Game_Music_Emu 0.6-pre. http://www.slack.net/~ant/ |
2 | 2 | ||
3 | #include "ay_emu.h" | 3 | #include "ay_emu.h" |
4 | 4 | ||
5 | #include "blargg_endian.h" | 5 | #include "blargg_endian.h" |
6 | 6 | ||
7 | /* Copyright (C) 2006-2009 Shay Green. This module is free software; you | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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, | 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 */ | 16 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ |
17 | 17 | ||
18 | #include "blargg_source.h" | 18 | #include "blargg_source.h" |
19 | 19 | ||
20 | const char* const gme_wrong_file_type = "Wrong file type for this emulator"; | 20 | const char* const gme_wrong_file_type = "Wrong file type for this emulator"; |
21 | 21 | ||
22 | // TODO: probably don't need detailed errors as to why file is corrupt | 22 | // TODO: probably don't need detailed errors as to why file is corrupt |
23 | 23 | ||
24 | int const spectrum_clock = 3546900; // 128K Spectrum | 24 | int const spectrum_clock = 3546900; // 128K Spectrum |
25 | int const spectrum_period = 70908; | 25 | int const spectrum_period = 70908; |
26 | 26 | ||
27 | //int const spectrum_clock = 3500000; // 48K Spectrum | 27 | //int const spectrum_clock = 3500000; // 48K Spectrum |
28 | //int const spectrum_period = 69888; | 28 | //int const spectrum_period = 69888; |
29 | 29 | ||
30 | int const cpc_clock = 2000000; | 30 | int const cpc_clock = 2000000; |
31 | 31 | ||
32 | static void clear_track_vars( struct Ay_Emu *this ) | 32 | static void clear_track_vars( struct Ay_Emu *this ) |
33 | { | 33 | { |
34 | this->current_track = -1; | 34 | this->current_track = -1; |
35 | track_stop( &this->track_filter ); | 35 | track_stop( &this->track_filter ); |
36 | } | 36 | } |
37 | 37 | ||
38 | void Ay_init( struct Ay_Emu *this ) | 38 | void Ay_init( struct Ay_Emu *this ) |
39 | { | 39 | { |
40 | this->sample_rate = 0; | 40 | this->sample_rate = 0; |
41 | this->mute_mask_ = 0; | 41 | this->mute_mask_ = 0; |
42 | this->tempo = (int)FP_ONE_TEMPO; | 42 | this->tempo = (int)FP_ONE_TEMPO; |
43 | this->gain = (int)FP_ONE_GAIN; | 43 | this->gain = (int)FP_ONE_GAIN; |
44 | this->track_count = 0; | 44 | this->track_count = 0; |
45 | 45 | ||
46 | // defaults | 46 | // defaults |
47 | this->tfilter = *track_get_setup( &this->track_filter ); | 47 | this->tfilter = *track_get_setup( &this->track_filter ); |
48 | this->tfilter.max_initial = 2; | 48 | this->tfilter.max_initial = 2; |
49 | this->tfilter.lookahead = 6; | 49 | this->tfilter.lookahead = 6; |
50 | this->track_filter.silence_ignored_ = false; | 50 | this->track_filter.silence_ignored_ = false; |
51 | 51 | ||
52 | this->beeper_output = NULL; | 52 | this->beeper_output = NULL; |
53 | disable_beeper( this ); | 53 | disable_beeper( this ); |
54 | 54 | ||
55 | Ay_apu_init( &this->apu ); | 55 | Ay_apu_init( &this->apu ); |
56 | Z80_init( &this->cpu ); | 56 | Z80_init( &this->cpu ); |
57 | 57 | ||
58 | // clears fields | 58 | // clears fields |
59 | this->voice_count = 0; | 59 | this->voice_count = 0; |
60 | this->voice_types = 0; | 60 | this->voice_types = 0; |
61 | clear_track_vars( this ); | 61 | clear_track_vars( this ); |
62 | } | 62 | } |
63 | 63 | ||
64 | // Track info | 64 | // Track info |
65 | 65 | ||
66 | // Given pointer to 2-byte offset of data, returns pointer to data, or NULL if | 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. | 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 ) | 68 | static byte const* get_data( struct file_t const* file, byte const ptr [], int min_size ) |
69 | { | 69 | { |
70 | int offset = (int16_t) get_be16( ptr ); | 70 | int offset = (int16_t) get_be16( ptr ); |
71 | int pos = ptr - (byte const*) file->header; | 71 | int pos = ptr - (byte const*) file->header; |
72 | int size = file->end - (byte const*) file->header; | 72 | int size = file->end - (byte const*) file->header; |
73 | assert( (unsigned) pos <= (unsigned) size - 2 ); | 73 | assert( (unsigned) pos <= (unsigned) size - 2 ); |
74 | int limit = size - min_size; | 74 | int limit = size - min_size; |
75 | if ( limit < 0 || !offset || (unsigned) (pos + offset) > (unsigned) limit ) | 75 | if ( limit < 0 || !offset || (unsigned) (pos + offset) > (unsigned) limit ) |
76 | return NULL; | 76 | return NULL; |
77 | return ptr + offset; | 77 | return ptr + offset; |
78 | } | 78 | } |
79 | 79 | ||
80 | static blargg_err_t parse_header( byte const in [], int size, struct file_t* out ) | 80 | static blargg_err_t parse_header( byte const in [], int size, struct file_t* out ) |
81 | { | 81 | { |
82 | if ( size < header_size ) | 82 | if ( size < header_size ) |
83 | return gme_wrong_file_type; | 83 | return gme_wrong_file_type; |
84 | 84 | ||
85 | out->header = (struct header_t const*) in; | 85 | out->header = (struct header_t const*) in; |
86 | out->end = in + size; | 86 | out->end = in + size; |
87 | struct header_t const* h = (struct header_t const*) in; | 87 | struct header_t const* h = (struct header_t const*) in; |
88 | if ( memcmp( h->tag, "ZXAYEMUL", 8 ) ) | 88 | if ( memcmp( h->tag, "ZXAYEMUL", 8 ) ) |
89 | return gme_wrong_file_type; | 89 | return gme_wrong_file_type; |
90 | 90 | ||
91 | out->tracks = get_data( out, h->track_info, (h->max_track + 1) * 4 ); | 91 | out->tracks = get_data( out, h->track_info, (h->max_track + 1) * 4 ); |
92 | if ( !out->tracks ) | 92 | if ( !out->tracks ) |
93 | return "missing track data"; | 93 | return "missing track data"; |
94 | 94 | ||
95 | return 0; | 95 | return 0; |
96 | } | 96 | } |
97 | 97 | ||
98 | // Setup | 98 | // Setup |
99 | 99 | ||
100 | static void change_clock_rate( struct Ay_Emu *this, int rate ) | 100 | static void change_clock_rate( struct Ay_Emu *this, int rate ) |
101 | { | 101 | { |
102 | this->clock_rate_ = rate; | 102 | this->clock_rate_ = rate; |
103 | Buffer_clock_rate( &this->stereo_buf, rate ); | 103 | Buffer_clock_rate( &this->stereo_buf, rate ); |
104 | } | 104 | } |
105 | 105 | ||
106 | blargg_err_t Ay_load_mem( struct Ay_Emu *this, byte const in [], long size ) | 106 | blargg_err_t Ay_load_mem( struct Ay_Emu *this, byte const in [], long size ) |
107 | { | 107 | { |
108 | // Unload | 108 | // Unload |
109 | this->voice_count = 0; | 109 | this->voice_count = 0; |
110 | this->track_count = 0; | 110 | this->track_count = 0; |
111 | this->m3u.size = 0; | 111 | this->m3u.size = 0; |
112 | clear_track_vars( this ); | 112 | clear_track_vars( this ); |
113 | 113 | ||
114 | assert( offsetof (struct header_t,track_info [2]) == header_size ); | 114 | assert( offsetof (struct header_t,track_info [2]) == header_size ); |
115 | 115 | ||
116 | RETURN_ERR( parse_header( in, size, &this->file ) ); | 116 | RETURN_ERR( parse_header( in, size, &this->file ) ); |
117 | 117 | ||
118 | /* if ( file.header->vers > 2 ) | 118 | /* if ( file.header->vers > 2 ) |
119 | warning( "Unknown file version" ); */ | 119 | warning( "Unknown file version" ); */ |
120 | 120 | ||
121 | this->voice_count = ay_osc_count + 1; // +1 for beeper | 121 | this->voice_count = ay_osc_count + 1; // +1 for beeper |
122 | static int const types [ay_osc_count + 1] = { | 122 | static int const types [ay_osc_count + 1] = { |
123 | wave_type+0, wave_type+1, wave_type+2, mixed_type+1 | 123 | wave_type+0, wave_type+1, wave_type+2, mixed_type+1 |
124 | }; | 124 | }; |
125 | this->voice_types = types; | 125 | this->voice_types = types; |
126 | 126 | ||
127 | Ay_apu_volume( &this->apu, this->gain); | 127 | Ay_apu_volume( &this->apu, this->gain); |
128 | 128 | ||
129 | // Setup buffer | 129 | // Setup buffer |
130 | change_clock_rate( this, spectrum_clock ); | 130 | change_clock_rate( this, spectrum_clock ); |
131 | RETURN_ERR( Buffer_set_channel_count( &this->stereo_buf, this->voice_count, this->voice_types ) ); | 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 ); | 132 | this->buf_changed_count = Buffer_channels_changed_count( &this->stereo_buf ); |
133 | 133 | ||
134 | Sound_set_tempo( this, this->tempo ); | 134 | Sound_set_tempo( this, this->tempo ); |
135 | Sound_mute_voices( this, this->mute_mask_ ); | 135 | Sound_mute_voices( this, this->mute_mask_ ); |
136 | 136 | ||
137 | this->track_count = this->file.header->max_track + 1; | 137 | this->track_count = this->file.header->max_track + 1; |
138 | return 0; | 138 | return 0; |
139 | } | 139 | } |
140 | 140 | ||
141 | static void set_beeper_output( struct Ay_Emu *this, struct Blip_Buffer* b ) | 141 | static void set_beeper_output( struct Ay_Emu *this, struct Blip_Buffer* b ) |
142 | { | 142 | { |
143 | this->beeper_output = b; | 143 | this->beeper_output = b; |
144 | if ( b && !this->cpc_mode ) | 144 | if ( b && !this->cpc_mode ) |
145 | this->beeper_mask = 0x10; | 145 | this->beeper_mask = 0x10; |
146 | else | 146 | else |
147 | disable_beeper( this ); | 147 | disable_beeper( this ); |
148 | } | 148 | } |
149 | 149 | ||
150 | static void set_voice( struct Ay_Emu *this, int i, struct Blip_Buffer* center ) | 150 | static void set_voice( struct Ay_Emu *this, int i, struct Blip_Buffer* center ) |
151 | { | 151 | { |
152 | if ( i >= ay_osc_count ) | 152 | if ( i >= ay_osc_count ) |
153 | set_beeper_output( this, center ); | 153 | set_beeper_output( this, center ); |
154 | else | 154 | else |
155 | Ay_apu_set_output( &this->apu, i, center ); | 155 | Ay_apu_set_output( &this->apu, i, center ); |
156 | } | 156 | } |
157 | 157 | ||
158 | static blargg_err_t run_clocks( struct Ay_Emu *this, blip_time_t* duration, int msec ) | 158 | static blargg_err_t run_clocks( struct Ay_Emu *this, blip_time_t* duration, int msec ) |
159 | { | 159 | { |
160 | #if defined(ROCKBOX) | 160 | #if defined(ROCKBOX) |
161 | (void) msec; | 161 | (void) msec; |
162 | #endif | 162 | #endif |
163 | 163 | ||
164 | cpu_time_t *end = duration; | 164 | cpu_time_t *end = duration; |
165 | struct Z80_Cpu* cpu = &this->cpu; | 165 | struct Z80_Cpu* cpu = &this->cpu; |
166 | Z80_set_time( cpu, 0 ); | 166 | Z80_set_time( cpu, 0 ); |
167 | 167 | ||
168 | // Since detection of CPC mode will halve clock rate during the frame | 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 | 169 | // and thus generate up to twice as much sound, we must generate half |
170 | // as much until mode is known. | 170 | // as much until mode is known. |
171 | if ( !(this->spectrum_mode | this->cpc_mode) ) | 171 | if ( !(this->spectrum_mode | this->cpc_mode) ) |
172 | *end /= 2; | 172 | *end /= 2; |
173 | 173 | ||
174 | while ( Z80_time( cpu ) < *end ) | 174 | while ( Z80_time( cpu ) < *end ) |
175 | { | 175 | { |
176 | run_cpu( this, min( *end, this->next_play ) ); | 176 | run_cpu( this, min( *end, this->next_play ) ); |
177 | 177 | ||
178 | if ( Z80_time( cpu ) >= this->next_play ) | 178 | if ( Z80_time( cpu ) >= this->next_play ) |
179 | { | 179 | { |
180 | // next frame | 180 | // next frame |
181 | this->next_play += this->play_period; | 181 | this->next_play += this->play_period; |
182 | 182 | ||
183 | if ( cpu->r.iff1 ) | 183 | if ( cpu->r.iff1 ) |
184 | { | 184 | { |
185 | // interrupt enabled | 185 | // interrupt enabled |
186 | 186 | ||
187 | if ( this->mem.ram [cpu->r.pc] == 0x76 ) | 187 | if ( this->mem.ram [cpu->r.pc] == 0x76 ) |
188 | cpu->r.pc++; // advance past HALT instruction | 188 | cpu->r.pc++; // advance past HALT instruction |
189 | 189 | ||
190 | cpu->r.iff1 = 0; | 190 | cpu->r.iff1 = 0; |
191 | cpu->r.iff2 = 0; | 191 | cpu->r.iff2 = 0; |
192 | 192 | ||
193 | this->mem.ram [--cpu->r.sp] = (byte) (cpu->r.pc >> 8); | 193 | this->mem.ram [--cpu->r.sp] = (byte) (cpu->r.pc >> 8); |
194 | this->mem.ram [--cpu->r.sp] = (byte) (cpu->r.pc); | 194 | this->mem.ram [--cpu->r.sp] = (byte) (cpu->r.pc); |
195 | 195 | ||
196 | // fixed interrupt | 196 | // fixed interrupt |
197 | cpu->r.pc = 0x38; | 197 | cpu->r.pc = 0x38; |
198 | Z80_adjust_time( cpu, 12 ); | 198 | Z80_adjust_time( cpu, 12 ); |
199 | 199 | ||
200 | if ( cpu->r.im == 2 ) | 200 | if ( cpu->r.im == 2 ) |
201 | { | 201 | { |
202 | // vectored interrupt | 202 | // vectored interrupt |
203 | addr_t addr = cpu->r.i * 0x100 + 0xFF; | 203 | addr_t addr = cpu->r.i * 0x100 + 0xFF; |
204 | cpu->r.pc = this->mem.ram [(addr + 1) & 0xFFFF] * 0x100 + this->mem.ram [addr]; | 204 | cpu->r.pc = this->mem.ram [(addr + 1) & 0xFFFF] * 0x100 + this->mem.ram [addr]; |
205 | Z80_adjust_time( cpu, 6 ); | 205 | Z80_adjust_time( cpu, 6 ); |
206 | } | 206 | } |
207 | } | 207 | } |
208 | } | 208 | } |
209 | } | 209 | } |
210 | 210 | ||
211 | // End time frame | 211 | // End time frame |
212 | *end = Z80_time( cpu ); | 212 | *end = Z80_time( cpu ); |
213 | this->next_play -= *end; | 213 | this->next_play -= *end; |
214 | check( this->next_play >= 0 ); | 214 | check( this->next_play >= 0 ); |
215 | Z80_adjust_time( cpu, -*end ); | 215 | Z80_adjust_time( cpu, -*end ); |
216 | Ay_apu_end_frame( &this->apu, *end ); | 216 | Ay_apu_end_frame( &this->apu, *end ); |
217 | return 0; | 217 | return 0; |
218 | } | 218 | } |
219 | 219 | ||
220 | // Emulation | 220 | // Emulation |
221 | 221 | ||
222 | void cpu_out_( struct Ay_Emu *this, cpu_time_t time, addr_t addr, int data ) | 222 | void cpu_out_( struct Ay_Emu *this, cpu_time_t time, addr_t addr, int data ) |
223 | { | 223 | { |
224 | // Spectrum | 224 | // Spectrum |
225 | if ( !this->cpc_mode ) | 225 | if ( !this->cpc_mode ) |
226 | { | 226 | { |
227 | switch ( addr & 0xFEFF ) | 227 | switch ( addr & 0xFEFF ) |
228 | { | 228 | { |
229 | case 0xFEFD: | 229 | case 0xFEFD: |
230 | this->spectrum_mode = true; | 230 | this->spectrum_mode = true; |
231 | Ay_apu_write_addr( &this->apu, data ); | 231 | Ay_apu_write_addr( &this->apu, data ); |
232 | return; | 232 | return; |
233 | 233 | ||
234 | case 0xBEFD: | 234 | case 0xBEFD: |
235 | this->spectrum_mode = true; | 235 | this->spectrum_mode = true; |
236 | Ay_apu_write_data( &this->apu, time, data ); | 236 | Ay_apu_write_data( &this->apu, time, data ); |
237 | return; | 237 | return; |
238 | } | 238 | } |
239 | } | 239 | } |
240 | 240 | ||
241 | // CPC | 241 | // CPC |
242 | if ( !this->spectrum_mode ) | 242 | if ( !this->spectrum_mode ) |
243 | { | 243 | { |
244 | switch ( addr >> 8 ) | 244 | switch ( addr >> 8 ) |
245 | { | 245 | { |
246 | case 0xF6: | 246 | case 0xF6: |
247 | switch ( data & 0xC0 ) | 247 | switch ( data & 0xC0 ) |
248 | { | 248 | { |
249 | case 0xC0: | 249 | case 0xC0: |
250 | Ay_apu_write_addr( &this->apu, this->cpc_latch ); | 250 | Ay_apu_write_addr( &this->apu, this->cpc_latch ); |
251 | goto enable_cpc; | 251 | goto enable_cpc; |
252 | 252 | ||
253 | case 0x80: | 253 | case 0x80: |
254 | Ay_apu_write_data( &this->apu, time, this->cpc_latch ); | 254 | Ay_apu_write_data( &this->apu, time, this->cpc_latch ); |
255 | goto enable_cpc; | 255 | goto enable_cpc; |
256 | } | 256 | } |
257 | break; | 257 | break; |
258 | 258 | ||
259 | case 0xF4: | 259 | case 0xF4: |
260 | this->cpc_latch = data; | 260 | this->cpc_latch = data; |
261 | goto enable_cpc; | 261 | goto enable_cpc; |
262 | } | 262 | } |
263 | } | 263 | } |
264 | 264 | ||
265 | /* dprintf( "Unmapped OUT: $%04X <- $%02X\n", addr, data ); */ | 265 | /* dprintf( "Unmapped OUT: $%04X <- $%02X\n", addr, data ); */ |
266 | return; | 266 | return; |
267 | 267 | ||
268 | enable_cpc: | 268 | enable_cpc: |
269 | if ( !this->cpc_mode ) | 269 | if ( !this->cpc_mode ) |
270 | { | 270 | { |
271 | this->cpc_mode = true; | 271 | this->cpc_mode = true; |
272 | disable_beeper( this ); | 272 | disable_beeper( this ); |
273 | 273 | ||
274 | change_clock_rate( this, cpc_clock ); | 274 | change_clock_rate( this, cpc_clock ); |
275 | Sound_set_tempo( this, this->tempo ); | 275 | Sound_set_tempo( this, this->tempo ); |
276 | } | 276 | } |
277 | } | 277 | } |
278 | 278 | ||
279 | blargg_err_t Ay_set_sample_rate( struct Ay_Emu *this, int rate ) | 279 | blargg_err_t Ay_set_sample_rate( struct Ay_Emu *this, int rate ) |
280 | { | 280 | { |
281 | require( !this->sample_rate ); // sample rate can't be changed once set | 281 | require( !this->sample_rate ); // sample rate can't be changed once set |
282 | Buffer_init( &this->stereo_buf ); | 282 | Buffer_init( &this->stereo_buf ); |
283 | RETURN_ERR( Buffer_set_sample_rate( &this->stereo_buf, rate, 1000 / 20 ) ); | 283 | RETURN_ERR( Buffer_set_sample_rate( &this->stereo_buf, rate, 1000 / 20 ) ); |
284 | 284 | ||
285 | // Set buffer bass | 285 | // Set buffer bass |
286 | Buffer_bass_freq( &this->stereo_buf, 160 ); | 286 | Buffer_bass_freq( &this->stereo_buf, 160 ); |
287 | 287 | ||
288 | this->sample_rate = rate; | 288 | this->sample_rate = rate; |
289 | RETURN_ERR( track_init( &this->track_filter, this ) ); | 289 | RETURN_ERR( track_init( &this->track_filter, this ) ); |
290 | this->tfilter.max_silence = 6 * stereo * this->sample_rate; | 290 | this->tfilter.max_silence = 6 * stereo * this->sample_rate; |
291 | return 0; | 291 | return 0; |
292 | } | 292 | } |
293 | 293 | ||
294 | void Sound_mute_voice( struct Ay_Emu *this, int index, bool mute ) | 294 | void Sound_mute_voice( struct Ay_Emu *this, int index, bool mute ) |
295 | { | 295 | { |
296 | require( (unsigned) index < (unsigned) this->voice_count ); | 296 | require( (unsigned) index < (unsigned) this->voice_count ); |
297 | int bit = 1 << index; | 297 | int bit = 1 << index; |
298 | int mask = this->mute_mask_ | bit; | 298 | int mask = this->mute_mask_ | bit; |
299 | if ( !mute ) | 299 | if ( !mute ) |
300 | mask ^= bit; | 300 | mask ^= bit; |
301 | Sound_mute_voices( this, mask ); | 301 | Sound_mute_voices( this, mask ); |
302 | } | 302 | } |
303 | 303 | ||
304 | void Sound_mute_voices( struct Ay_Emu *this, int mask ) | 304 | void Sound_mute_voices( struct Ay_Emu *this, int mask ) |
305 | { | 305 | { |
306 | require( this->sample_rate ); // sample rate must be set first | 306 | require( this->sample_rate ); // sample rate must be set first |
307 | this->mute_mask_ = mask; | 307 | this->mute_mask_ = mask; |
308 | 308 | ||
309 | int i; | 309 | int i; |
310 | for ( i = this->voice_count; i--; ) | 310 | for ( i = this->voice_count; i--; ) |
311 | { | 311 | { |
312 | if ( mask & (1 << i) ) | 312 | if ( mask & (1 << i) ) |
313 | { | 313 | { |
314 | set_voice( this, i, 0 ); | 314 | set_voice( this, i, 0 ); |
315 | } | 315 | } |
316 | else | 316 | else |
317 | { | 317 | { |
318 | struct channel_t ch = Buffer_channel( &this->stereo_buf, i ); | 318 | struct channel_t ch = Buffer_channel( &this->stereo_buf, i ); |
319 | assert( (ch.center && ch.left && ch.right) || | 319 | assert( (ch.center && ch.left && ch.right) || |
320 | (!ch.center && !ch.left && !ch.right) ); // all or nothing | 320 | (!ch.center && !ch.left && !ch.right) ); // all or nothing |
321 | set_voice( this, i, ch.center ); | 321 | set_voice( this, i, ch.center ); |
322 | } | 322 | } |
323 | } | 323 | } |
324 | } | 324 | } |
325 | 325 | ||
326 | void Sound_set_tempo( struct Ay_Emu *this, int t ) | 326 | void Sound_set_tempo( struct Ay_Emu *this, int t ) |
327 | { | 327 | { |
328 | require( this->sample_rate ); // sample rate must be set first | 328 | require( this->sample_rate ); // sample rate must be set first |
329 | int const min = (int)(FP_ONE_TEMPO*0.02); | 329 | int const min = (int)(FP_ONE_TEMPO*0.02); |
330 | int const max = (int)(FP_ONE_TEMPO*4.00); | 330 | int const max = (int)(FP_ONE_TEMPO*4.00); |
331 | if ( t < min ) t = min; | 331 | if ( t < min ) t = min; |
332 | if ( t > max ) t = max; | 332 | if ( t > max ) t = max; |
333 | this->tempo = t; | 333 | this->tempo = t; |
334 | 334 | ||
335 | int p = spectrum_period; | 335 | int p = spectrum_period; |
336 | if ( this->clock_rate_ != spectrum_clock ) | 336 | if ( this->clock_rate_ != spectrum_clock ) |
337 | p = this->clock_rate_ / 50; | 337 | p = this->clock_rate_ / 50; |
338 | 338 | ||
339 | this->play_period = (blip_time_t) ((p * FP_ONE_TEMPO) / t); | 339 | this->play_period = (blip_time_t) ((p * FP_ONE_TEMPO) / t); |
340 | } | 340 | } |
341 | 341 | ||
342 | blargg_err_t Ay_start_track( struct Ay_Emu *this, int track ) | 342 | blargg_err_t Ay_start_track( struct Ay_Emu *this, int track ) |
343 | { | 343 | { |
344 | clear_track_vars( this ); | 344 | clear_track_vars( this ); |
345 | 345 | ||
346 | // Remap track if playlist available | 346 | // Remap track if playlist available |
347 | if ( this->m3u.size > 0 ) { | 347 | if ( this->m3u.size > 0 ) { |
348 | struct entry_t* e = &this->m3u.entries[track]; | 348 | struct entry_t* e = &this->m3u.entries[track]; |
349 | track = e->track; | 349 | track = e->track; |
350 | } | 350 | } |
351 | 351 | ||
352 | this->current_track = track; | 352 | this->current_track = track; |
353 | Buffer_clear( &this->stereo_buf ); | 353 | Buffer_clear( &this->stereo_buf ); |
354 | 354 | ||
355 | byte* const mem = this->mem.ram; | 355 | byte* const mem = this->mem.ram; |
356 | 356 | ||
357 | memset( mem + 0x0000, 0xC9, 0x100 ); // fill RST vectors with RET | 357 | memset( mem + 0x0000, 0xC9, 0x100 ); // fill RST vectors with RET |
358 | memset( mem + 0x0100, 0xFF, 0x4000 - 0x100 ); | 358 | memset( mem + 0x0100, 0xFF, 0x4000 - 0x100 ); |
359 | memset( mem + ram_addr, 0x00, mem_size - ram_addr ); | 359 | memset( mem + ram_addr, 0x00, mem_size - ram_addr ); |
360 | 360 | ||
361 | // locate data blocks | 361 | // locate data blocks |
362 | byte const* const data = get_data( &this->file, this->file.tracks + track * 4 + 2, 14 ); | 362 | byte const* const data = get_data( &this->file, this->file.tracks + track * 4 + 2, 14 ); |
363 | if ( !data ) | 363 | if ( !data ) |
364 | return "file data missing"; | 364 | return "file data missing"; |
365 | 365 | ||
366 | byte const* const more_data = get_data( &this->file, data + 10, 6 ); | 366 | byte const* const more_data = get_data( &this->file, data + 10, 6 ); |
367 | if ( !more_data ) | 367 | if ( !more_data ) |
368 | return "file data missing"; | 368 | return "file data missing"; |
369 | 369 | ||
370 | byte const* blocks = get_data( &this->file, data + 12, 8 ); | 370 | byte const* blocks = get_data( &this->file, data + 12, 8 ); |
371 | if ( !blocks ) | 371 | if ( !blocks ) |
372 | return "file data missing"; | 372 | return "file data missing"; |
373 | 373 | ||
374 | // initial addresses | 374 | // initial addresses |
375 | unsigned addr = get_be16( blocks ); | 375 | unsigned addr = get_be16( blocks ); |
376 | if ( !addr ) | 376 | if ( !addr ) |
377 | return "file data missing"; | 377 | return "file data missing"; |
378 | 378 | ||
379 | unsigned init = get_be16( more_data + 2 ); | 379 | unsigned init = get_be16( more_data + 2 ); |
380 | if ( !init ) | 380 | if ( !init ) |
381 | init = addr; | 381 | init = addr; |
382 | 382 | ||
383 | // copy blocks into memory | 383 | // copy blocks into memory |
384 | do | 384 | do |
385 | { | 385 | { |
386 | blocks += 2; | 386 | blocks += 2; |
387 | unsigned len = get_be16( blocks ); blocks += 2; | 387 | unsigned len = get_be16( blocks ); blocks += 2; |
388 | if ( addr + len > mem_size ) | 388 | if ( addr + len > mem_size ) |
389 | { | 389 | { |
390 | /* warning( "Bad data block size" ); */ | 390 | /* warning( "Bad data block size" ); */ |
391 | len = mem_size - addr; | 391 | len = mem_size - addr; |
392 | } | 392 | } |
393 | check( len ); | 393 | check( len ); |
394 | byte const* in = get_data( &this->file, blocks, 0 ); blocks += 2; | 394 | byte const* in = get_data( &this->file, blocks, 0 ); blocks += 2; |
395 | if ( len > (unsigned) (this->file.end - in) ) | 395 | if ( len > (unsigned) (this->file.end - in) ) |
396 | { | 396 | { |
397 | /* warning( "File data missing" ); */ | 397 | /* warning( "File data missing" ); */ |
398 | len = this->file.end - in; | 398 | len = this->file.end - in; |
399 | } | 399 | } |
400 | 400 | ||
401 | memcpy( mem + addr, in, len ); | 401 | memcpy( mem + addr, in, len ); |
402 | 402 | ||
403 | if ( this->file.end - blocks < 8 ) | 403 | if ( this->file.end - blocks < 8 ) |
404 | { | 404 | { |
405 | /* warning( "File data missing" ); */ | 405 | /* warning( "File data missing" ); */ |
406 | break; | 406 | break; |
407 | } | 407 | } |
408 | } | 408 | } |
409 | while ( (addr = get_be16( blocks )) != 0 ); | 409 | while ( (addr = get_be16( blocks )) != 0 ); |
410 | 410 | ||
411 | // copy and configure driver | 411 | // copy and configure driver |
412 | static byte const passive [] = { | 412 | static byte const passive [] = { |
413 | 0xF3, // DI | 413 | 0xF3, // DI |
414 | 0xCD, 0, 0, // CALL init | 414 | 0xCD, 0, 0, // CALL init |
415 | 0xED, 0x5E, // LOOP: IM 2 | 415 | 0xED, 0x5E, // LOOP: IM 2 |
416 | 0xFB, // EI | 416 | 0xFB, // EI |
417 | 0x76, // HALT | 417 | 0x76, // HALT |
418 | 0x18, 0xFA // JR LOOP | 418 | 0x18, 0xFA // JR LOOP |
419 | }; | 419 | }; |
420 | static byte const active [] = { | 420 | static byte const active [] = { |
421 | 0xF3, // DI | 421 | 0xF3, // DI |
422 | 0xCD, 0, 0, // CALL init | 422 | 0xCD, 0, 0, // CALL init |
423 | 0xED, 0x56, // LOOP: IM 1 | 423 | 0xED, 0x56, // LOOP: IM 1 |
424 | 0xFB, // EI | 424 | 0xFB, // EI |
425 | 0x76, // HALT | 425 | 0x76, // HALT |
426 | 0xCD, 0, 0, // CALL play | 426 | 0xCD, 0, 0, // CALL play |
427 | 0x18, 0xF7 // JR LOOP | 427 | 0x18, 0xF7 // JR LOOP |
428 | }; | 428 | }; |
429 | memcpy( mem, passive, sizeof passive ); | 429 | memcpy( mem, passive, sizeof passive ); |
430 | int const play_addr = get_be16( more_data + 4 ); | 430 | int const play_addr = get_be16( more_data + 4 ); |
431 | if ( play_addr ) | 431 | if ( play_addr ) |
432 | { | 432 | { |
433 | memcpy( mem, active, sizeof active ); | 433 | memcpy( mem, active, sizeof active ); |
434 | mem [ 9] = play_addr; | 434 | mem [ 9] = play_addr; |
435 | mem [10] = play_addr >> 8; | 435 | mem [10] = play_addr >> 8; |
436 | } | 436 | } |
437 | mem [2] = init; | 437 | mem [2] = init; |
438 | mem [3] = init >> 8; | 438 | mem [3] = init >> 8; |
439 | 439 | ||
440 | mem [0x38] = 0xFB; // Put EI at interrupt vector (followed by RET) | 440 | mem [0x38] = 0xFB; // Put EI at interrupt vector (followed by RET) |
441 | 441 | ||
442 | // start at spectrum speed | 442 | // start at spectrum speed |
443 | change_clock_rate( this, spectrum_clock ); | 443 | change_clock_rate( this, spectrum_clock ); |
444 | Sound_set_tempo( this, this->tempo ); | 444 | Sound_set_tempo( this, this->tempo ); |
445 | 445 | ||
446 | struct registers_t r; | 446 | struct registers_t r; |
447 | memset( &r, 0, sizeof(struct registers_t) ); | 447 | memset( &r, 0, sizeof(struct registers_t) ); |
448 | 448 | ||
449 | r.sp = get_be16( more_data ); | 449 | r.sp = get_be16( more_data ); |
450 | r.b.a = r.b.b = r.b.d = r.b.h = data [8]; | 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]; | 451 | r.b.flags = r.b.c = r.b.e = r.b.l = data [9]; |
452 | r.alt.w = r.w; | 452 | r.alt.w = r.w; |
453 | r.ix = r.iy = r.w.hl; | 453 | r.ix = r.iy = r.w.hl; |
454 | 454 | ||
455 | memset( this->mem.padding1, 0xFF, sizeof this->mem.padding1 ); | 455 | memset( this->mem.padding1, 0xFF, sizeof this->mem.padding1 ); |
456 | 456 | ||
457 | int const mirrored = 0x80; // this much is mirrored after end of memory | 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 ); | 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) | 459 | memcpy( this->mem.ram + mem_size, this->mem.ram, mirrored ); // some code wraps around (ugh) |
460 | 460 | ||
461 | Z80_reset( &this->cpu, this->mem.padding1, this->mem.padding1 ); | 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 ); | 462 | Z80_map_mem( &this->cpu, 0, mem_size, this->mem.ram, this->mem.ram ); |
463 | this->cpu.r = r; | 463 | this->cpu.r = r; |
464 | 464 | ||
465 | this->beeper_delta = (int) ((ay_amp_range*4)/5); | 465 | this->beeper_delta = (int) ((ay_amp_range*4)/5); |
466 | this->last_beeper = 0; | 466 | this->last_beeper = 0; |
467 | this->next_play = this->play_period; | 467 | this->next_play = this->play_period; |
468 | this->spectrum_mode = false; | 468 | this->spectrum_mode = false; |
469 | this->cpc_mode = false; | 469 | this->cpc_mode = false; |
470 | this->cpc_latch = 0; | 470 | this->cpc_latch = 0; |
471 | set_beeper_output( this, this->beeper_output ); | 471 | set_beeper_output( this, this->beeper_output ); |
472 | Ay_apu_reset( &this->apu ); | 472 | Ay_apu_reset( &this->apu ); |
473 | 473 | ||
474 | // a few tunes rely on channels having tone enabled at the beginning | 474 | // a few tunes rely on channels having tone enabled at the beginning |
475 | Ay_apu_write_addr( &this->apu, 7 ); | 475 | Ay_apu_write_addr( &this->apu, 7 ); |
476 | Ay_apu_write_data( &this->apu, 0, 0x38 ); | 476 | Ay_apu_write_data( &this->apu, 0, 0x38 ); |
477 | 477 | ||
478 | // convert filter times to samples | 478 | // convert filter times to samples |
479 | struct setup_t s = this->tfilter; | 479 | struct setup_t s = this->tfilter; |
480 | s.max_initial *= this->sample_rate * stereo; | 480 | s.max_initial *= this->sample_rate * stereo; |
481 | #ifdef GME_DISABLE_SILENCE_LOOKAHEAD | 481 | #ifdef GME_DISABLE_SILENCE_LOOKAHEAD |
482 | s.lookahead = 1; | 482 | s.lookahead = 1; |
483 | #endif | 483 | #endif |
484 | track_setup( &this->track_filter, &s ); | 484 | track_setup( &this->track_filter, &s ); |
485 | 485 | ||
486 | return track_start( &this->track_filter ); | 486 | return track_start( &this->track_filter ); |
487 | } | 487 | } |
488 | 488 | ||
489 | // Tell/Seek | 489 | // Tell/Seek |
490 | 490 | ||
491 | static int msec_to_samples( int msec, int sample_rate ) | 491 | static int msec_to_samples( int msec, int sample_rate ) |
492 | { | 492 | { |
493 | int sec = msec / 1000; | 493 | int sec = msec / 1000; |
494 | msec -= sec * 1000; | 494 | msec -= sec * 1000; |
495 | return (sec * sample_rate + msec * sample_rate / 1000) * stereo; | 495 | return (sec * sample_rate + msec * sample_rate / 1000) * stereo; |
496 | } | 496 | } |
497 | 497 | ||
498 | int Track_tell( struct Ay_Emu *this ) | 498 | int Track_tell( struct Ay_Emu *this ) |
499 | { | 499 | { |
500 | int rate = this->sample_rate * stereo; | 500 | int rate = this->sample_rate * stereo; |
501 | int sec = track_sample_count( &this->track_filter ) / rate; | 501 | int sec = track_sample_count( &this->track_filter ) / rate; |
502 | return sec * 1000 + (track_sample_count( &this->track_filter ) - sec * rate) * 1000 / rate; | 502 | return sec * 1000 + (track_sample_count( &this->track_filter ) - sec * rate) * 1000 / rate; |
503 | } | 503 | } |
504 | 504 | ||
505 | blargg_err_t Track_seek( struct Ay_Emu *this, int msec ) | 505 | blargg_err_t Track_seek( struct Ay_Emu *this, int msec ) |
506 | { | 506 | { |
507 | int time = msec_to_samples( msec, this->sample_rate ); | 507 | int time = msec_to_samples( msec, this->sample_rate ); |
508 | if ( time < track_sample_count( &this->track_filter ) ) | 508 | if ( time < track_sample_count( &this->track_filter ) ) |
509 | RETURN_ERR( Ay_start_track( this, this->current_track ) ); | 509 | RETURN_ERR( Ay_start_track( this, this->current_track ) ); |
510 | return Track_skip( this, time - track_sample_count( &this->track_filter ) ); | 510 | return Track_skip( this, time - track_sample_count( &this->track_filter ) ); |
511 | } | 511 | } |
512 | 512 | ||
513 | blargg_err_t skip_( void *emu, int count ) | 513 | blargg_err_t skip_( void *emu, int count ) |
514 | { | 514 | { |
515 | struct Ay_Emu* this = (struct Ay_Emu*) emu; | 515 | struct Ay_Emu* this = (struct Ay_Emu*) emu; |
516 | 516 | ||
517 | // for long skip, mute sound | 517 | // for long skip, mute sound |
518 | const int threshold = 32768; | 518 | const int threshold = 32768; |
519 | if ( count > threshold ) | 519 | if ( count > threshold ) |
520 | { | 520 | { |
521 | int saved_mute = this->mute_mask_; | 521 | int saved_mute = this->mute_mask_; |
522 | Sound_mute_voices( this, ~0 ); | 522 | Sound_mute_voices( this, ~0 ); |
523 | 523 | ||
524 | int n = count - threshold/2; | 524 | int n = count - threshold/2; |
525 | n &= ~(2048-1); // round to multiple of 2048 | 525 | n &= ~(2048-1); // round to multiple of 2048 |
526 | count -= n; | 526 | count -= n; |
527 | RETURN_ERR( skippy_( &this->track_filter, n ) ); | 527 | RETURN_ERR( skippy_( &this->track_filter, n ) ); |
528 | 528 | ||
529 | Sound_mute_voices( this, saved_mute ); | 529 | Sound_mute_voices( this, saved_mute ); |
530 | } | 530 | } |
531 | 531 | ||
532 | return skippy_( &this->track_filter, count ); | 532 | return skippy_( &this->track_filter, count ); |
533 | } | 533 | } |
534 | 534 | ||
535 | blargg_err_t Track_skip( struct Ay_Emu *this, int count ) | 535 | blargg_err_t Track_skip( struct Ay_Emu *this, int count ) |
536 | { | 536 | { |
537 | require( this->current_track >= 0 ); // start_track() must have been called already | 537 | require( this->current_track >= 0 ); // start_track() must have been called already |
538 | return track_skip( &this->track_filter, count ); | 538 | return track_skip( &this->track_filter, count ); |
539 | } | 539 | } |
540 | 540 | ||
541 | int Track_get_length( struct Ay_Emu* this, int n ) | 541 | int Track_get_length( struct Ay_Emu* this, int n ) |
542 | { | 542 | { |
543 | int length = 0; | 543 | int length = 0; |
544 | 544 | ||
545 | byte const* track_info = get_data( &this->file, this->file.tracks + n * 4 + 2, 6 ); | 545 | byte const* track_info = get_data( &this->file, this->file.tracks + n * 4 + 2, 6 ); |
546 | if ( track_info ) | 546 | if ( track_info ) |
547 | length = get_be16( track_info + 4 ) * (1000 / 50); // frames to msec | 547 | length = get_be16( track_info + 4 ) * (1000 / 50); // frames to msec |
548 | 548 | ||
549 | if ( (this->m3u.size > 0) && (n < this->m3u.size) ) { | 549 | if ( (this->m3u.size > 0) && (n < this->m3u.size) ) { |
550 | struct entry_t* entry = &this->m3u.entries [n]; | 550 | struct entry_t* entry = &this->m3u.entries [n]; |
551 | length = entry->length; | 551 | length = entry->length; |
552 | } | 552 | } |
553 | 553 | ||
554 | if ( length <= 0 ) | 554 | if ( length <= 0 ) |
555 | length = 120 * 1000; /* 2 minutes */ | 555 | length = 120 * 1000; /* 2 minutes */ |
556 | 556 | ||
557 | return length; | 557 | return length; |
558 | } | 558 | } |
559 | 559 | ||
560 | void Track_set_fade( struct Ay_Emu *this, int start_msec, int length_msec ) | 560 | void Track_set_fade( struct Ay_Emu *this, int start_msec, int length_msec ) |
561 | { | 561 | { |
562 | track_set_fade( &this->track_filter, msec_to_samples( start_msec, this->sample_rate ), | 562 | track_set_fade( &this->track_filter, msec_to_samples( start_msec, this->sample_rate ), |
563 | length_msec * this->sample_rate / (1000 / stereo) ); | 563 | length_msec * this->sample_rate / (1000 / stereo) ); |
564 | } | 564 | } |
565 | 565 | ||
566 | blargg_err_t Ay_play( struct Ay_Emu *this, int out_count, sample_t* out ) | 566 | blargg_err_t Ay_play( struct Ay_Emu *this, int out_count, sample_t* out ) |
567 | { | 567 | { |
568 | require( this->current_track >= 0 ); | 568 | require( this->current_track >= 0 ); |
569 | require( out_count % stereo == 0 ); | 569 | require( out_count % stereo == 0 ); |
570 | return track_play( &this->track_filter, out_count, out ); | 570 | return track_play( &this->track_filter, out_count, out ); |
571 | } | 571 | } |
572 | 572 | ||
573 | blargg_err_t play_( void *emu, int count, sample_t* out ) | 573 | blargg_err_t play_( void *emu, int count, sample_t* out ) |
574 | { | 574 | { |
575 | struct Ay_Emu* this = (struct Ay_Emu*) emu; | 575 | struct Ay_Emu* this = (struct Ay_Emu*) emu; |
576 | 576 | ||
577 | int remain = count; | 577 | int remain = count; |
578 | while ( remain ) | 578 | while ( remain ) |
579 | { | 579 | { |
580 | Buffer_disable_immediate_removal( &this->stereo_buf ); | 580 | Buffer_disable_immediate_removal( &this->stereo_buf ); |
581 | remain -= Buffer_read_samples( &this->stereo_buf, &out [count - remain], remain ); | 581 | remain -= Buffer_read_samples( &this->stereo_buf, &out [count - remain], remain ); |
582 | if ( remain ) | 582 | if ( remain ) |
583 | { | 583 | { |
584 | if ( this->buf_changed_count != Buffer_channels_changed_count( &this->stereo_buf ) ) | 584 | if ( this->buf_changed_count != Buffer_channels_changed_count( &this->stereo_buf ) ) |
585 | { | 585 | { |
586 | this->buf_changed_count = Buffer_channels_changed_count( &this->stereo_buf ); | 586 | this->buf_changed_count = Buffer_channels_changed_count( &this->stereo_buf ); |
587 | 587 | ||
588 | // Remute voices | 588 | // Remute voices |
589 | Sound_mute_voices( this, this->mute_mask_ ); | 589 | Sound_mute_voices( this, this->mute_mask_ ); |
590 | } | 590 | } |
591 | int msec = Buffer_length( &this->stereo_buf ); | 591 | int msec = Buffer_length( &this->stereo_buf ); |
592 | blip_time_t clocks_emulated = msec * this->clock_rate_ / 1000 - 100; | 592 | blip_time_t clocks_emulated = msec * this->clock_rate_ / 1000 - 100; |
593 | RETURN_ERR( run_clocks( this, &clocks_emulated, msec ) ); | 593 | RETURN_ERR( run_clocks( this, &clocks_emulated, msec ) ); |
594 | assert( clocks_emulated ); | 594 | assert( clocks_emulated ); |
595 | Buffer_end_frame( &this->stereo_buf, clocks_emulated ); | 595 | Buffer_end_frame( &this->stereo_buf, clocks_emulated ); |
596 | } | 596 | } |
597 | } | 597 | } |
598 | return 0; | 598 | return 0; |
599 | } | 599 | } |
diff --git a/apps/codecs/libgme/blargg_config.h b/apps/codecs/libgme/blargg_config.h index 6490c15cfb..398913d1fe 100644 --- a/apps/codecs/libgme/blargg_config.h +++ b/apps/codecs/libgme/blargg_config.h | |||
@@ -1,42 +1,42 @@ | |||
1 | // Library configuration. Modify this file as necessary. | 1 | // Library configuration. Modify this file as necessary. |
2 | 2 | ||
3 | #ifndef BLARGG_CONFIG_H | 3 | #ifndef BLARGG_CONFIG_H |
4 | #define BLARGG_CONFIG_H | 4 | #define BLARGG_CONFIG_H |
5 | 5 | ||
6 | // Uncomment to enable platform-specific optimizations | 6 | // Uncomment to enable platform-specific optimizations |
7 | //#define BLARGG_NONPORTABLE 1 | 7 | //#define BLARGG_NONPORTABLE 1 |
8 | 8 | ||
9 | // Uncomment if automatic byte-order determination doesn't work | 9 | // Uncomment if automatic byte-order determination doesn't work |
10 | #ifdef ROCKBOX_BIG_ENDIAN | 10 | #ifdef ROCKBOX_BIG_ENDIAN |
11 | #define BLARGG_BIG_ENDIAN 1 | 11 | #define BLARGG_BIG_ENDIAN 1 |
12 | #endif | 12 | #endif |
13 | 13 | ||
14 | // Uncomment if you get errors in the bool section of blargg_common.h | 14 | // Uncomment if you get errors in the bool section of blargg_common.h |
15 | #define BLARGG_COMPILER_HAS_BOOL 1 | 15 | #define BLARGG_COMPILER_HAS_BOOL 1 |
16 | 16 | ||
17 | // Uncomment to use fast gb apu implementation | 17 | // Uncomment to use fast gb apu implementation |
18 | // #define GB_APU_FAST 1 | 18 | // #define GB_APU_FAST 1 |
19 | 19 | ||
20 | // Uncomment to remove agb emulation support | 20 | // Uncomment to remove agb emulation support |
21 | // #define GB_APU_NO_AGB 1 | 21 | // #define GB_APU_NO_AGB 1 |
22 | 22 | ||
23 | // Uncomment to emulate only nes apu | 23 | // Uncomment to emulate only nes apu |
24 | // #define NSF_EMU_APU_ONLY 1 | 24 | // #define NSF_EMU_APU_ONLY 1 |
25 | 25 | ||
26 | // Uncomment to remove vrc7 apu support | 26 | // Uncomment to remove vrc7 apu support |
27 | // #define NSF_EMU_NO_VRC7 1 | 27 | // #define NSF_EMU_NO_VRC7 1 |
28 | 28 | ||
29 | // Uncomment to remove fmopl apu support | 29 | // Uncomment to remove fmopl apu support |
30 | // #define KSS_EMU_NO_FMOPL 1 | 30 | // #define KSS_EMU_NO_FMOPL 1 |
31 | 31 | ||
32 | // To handle undefined reference to assert | 32 | // To handle undefined reference to assert |
33 | #define NDEBUG 1 | 33 | #define NDEBUG 1 |
34 | 34 | ||
35 | // Use standard config.h if present | 35 | // Use standard config.h if present |
36 | #define HAVE_CONFIG_H 1 | 36 | #define HAVE_CONFIG_H 1 |
37 | 37 | ||
38 | #ifdef HAVE_CONFIG_H | 38 | #ifdef HAVE_CONFIG_H |
39 | #include "config.h" | 39 | #include "config.h" |
40 | #endif | 40 | #endif |
41 | 41 | ||
42 | #endif | 42 | #endif |
diff --git a/apps/codecs/libgme/emu2413.c b/apps/codecs/libgme/emu2413.c index a4637ce15b..01075821cb 100644 --- a/apps/codecs/libgme/emu2413.c +++ b/apps/codecs/libgme/emu2413.c | |||
@@ -1,1981 +1,1981 @@ | |||
1 | /*********************************************************************************** | 1 | /*********************************************************************************** |
2 | 2 | ||
3 | emu2413.c -- YM2413 emulator written by Mitsutaka Okazaki 2001 | 3 | emu2413.c -- YM2413 emulator written by Mitsutaka Okazaki 2001 |
4 | 4 | ||
5 | 2001 01-08 : Version 0.10 -- 1st version. | 5 | 2001 01-08 : Version 0.10 -- 1st version. |
6 | 2001 01-15 : Version 0.20 -- semi-public version. | 6 | 2001 01-15 : Version 0.20 -- semi-public version. |
7 | 2001 01-16 : Version 0.30 -- 1st public version. | 7 | 2001 01-16 : Version 0.30 -- 1st public version. |
8 | 2001 01-17 : Version 0.31 -- Fixed bassdrum problem. | 8 | 2001 01-17 : Version 0.31 -- Fixed bassdrum problem. |
9 | : Version 0.32 -- LPF implemented. | 9 | : Version 0.32 -- LPF implemented. |
10 | 2001 01-18 : Version 0.33 -- Fixed the drum problem, refine the mix-down method. | 10 | 2001 01-18 : Version 0.33 -- Fixed the drum problem, refine the mix-down method. |
11 | -- Fixed the LFO bug. | 11 | -- Fixed the LFO bug. |
12 | 2001 01-24 : Version 0.35 -- Fixed the drum problem, | 12 | 2001 01-24 : Version 0.35 -- Fixed the drum problem, |
13 | support undocumented EG behavior. | 13 | support undocumented EG behavior. |
14 | 2001 02-02 : Version 0.38 -- Improved the performance. | 14 | 2001 02-02 : Version 0.38 -- Improved the performance. |
15 | Fixed the hi-hat and cymbal model. | 15 | Fixed the hi-hat and cymbal model. |
16 | Fixed the default percussive datas. | 16 | Fixed the default percussive datas. |
17 | Noise reduction. | 17 | Noise reduction. |
18 | Fixed the feedback problem. | 18 | Fixed the feedback problem. |
19 | 2001 03-03 : Version 0.39 -- Fixed some drum bugs. | 19 | 2001 03-03 : Version 0.39 -- Fixed some drum bugs. |
20 | Improved the performance. | 20 | Improved the performance. |
21 | 2001 03-04 : Version 0.40 -- Improved the feedback. | 21 | 2001 03-04 : Version 0.40 -- Improved the feedback. |
22 | Change the default table size. | 22 | Change the default table size. |
23 | Clock and Rate can be changed during play. | 23 | Clock and Rate can be changed during play. |
24 | 2001 06-24 : Version 0.50 -- Improved the hi-hat and the cymbal tone. | 24 | 2001 06-24 : Version 0.50 -- Improved the hi-hat and the cymbal tone. |
25 | Added VRC7 patch (OPLL_reset_patch is changed). | 25 | Added VRC7 patch (OPLL_reset_patch is changed). |
26 | Fixed OPLL_reset() bug. | 26 | Fixed OPLL_reset() bug. |
27 | Added OPLL_setMask, OPLL_getMask and OPLL_toggleMask. | 27 | Added OPLL_setMask, OPLL_getMask and OPLL_toggleMask. |
28 | Added OPLL_writeIO. | 28 | Added OPLL_writeIO. |
29 | 2001 09-28 : Version 0.51 -- Removed the noise table. | 29 | 2001 09-28 : Version 0.51 -- Removed the noise table. |
30 | 2002 01-28 : Version 0.52 -- Added Stereo mode. | 30 | 2002 01-28 : Version 0.52 -- Added Stereo mode. |
31 | 2002 02-07 : Version 0.53 -- Fixed some drum bugs. | 31 | 2002 02-07 : Version 0.53 -- Fixed some drum bugs. |
32 | 2002 02-20 : Version 0.54 -- Added the best quality mode. | 32 | 2002 02-20 : Version 0.54 -- Added the best quality mode. |
33 | 2002 03-02 : Version 0.55 -- Removed OPLL_init & OPLL_close. | 33 | 2002 03-02 : Version 0.55 -- Removed OPLL_init & OPLL_close. |
34 | 2002 05-30 : Version 0.60 -- Fixed HH&CYM generator and all voice datas. | 34 | 2002 05-30 : Version 0.60 -- Fixed HH&CYM generator and all voice datas. |
35 | 2004 04-10 : Version 0.61 -- Added YMF281B tone (defined by Chabin). | 35 | 2004 04-10 : Version 0.61 -- Added YMF281B tone (defined by Chabin). |
36 | 36 | ||
37 | 2011 03-22 : --------------- Modified by gama to use precalculated tables. | 37 | 2011 03-22 : --------------- Modified by gama to use precalculated tables. |
38 | 38 | ||
39 | References: | 39 | References: |
40 | fmopl.c -- 1999,2000 written by Tatsuyuki Satoh (MAME development). | 40 | fmopl.c -- 1999,2000 written by Tatsuyuki Satoh (MAME development). |
41 | fmopl.c(fixed) -- (C) 2002 Jarek Burczynski. | 41 | fmopl.c(fixed) -- (C) 2002 Jarek Burczynski. |
42 | s_opl.c -- 2001 written by Mamiya (NEZplug development). | 42 | s_opl.c -- 2001 written by Mamiya (NEZplug development). |
43 | fmgen.cpp -- 1999,2000 written by cisc. | 43 | fmgen.cpp -- 1999,2000 written by cisc. |
44 | fmpac.ill -- 2000 created by NARUTO. | 44 | fmpac.ill -- 2000 created by NARUTO. |
45 | MSX-Datapack | 45 | MSX-Datapack |
46 | YMU757 data sheet | 46 | YMU757 data sheet |
47 | YM2143 data sheet | 47 | YM2143 data sheet |
48 | 48 | ||
49 | **************************************************************************************/ | 49 | **************************************************************************************/ |
50 | #include <stdio.h> | 50 | #include <stdio.h> |
51 | #include <stdlib.h> | 51 | #include <stdlib.h> |
52 | #include <string.h> | 52 | #include <string.h> |
53 | #include <math.h> | 53 | #include <math.h> |
54 | #include "emu2413.h" | 54 | #include "emu2413.h" |
55 | 55 | ||
56 | #include "emutables.h" | 56 | #include "emutables.h" |
57 | #if !defined(ROCKBOX) | 57 | #if !defined(ROCKBOX) |
58 | #define EMU2413_CALCUL_TABLES | 58 | #define EMU2413_CALCUL_TABLES |
59 | #else | 59 | #else |
60 | #define EMU2413_COMPACTION | 60 | #define EMU2413_COMPACTION |
61 | #include "emutables.h" | 61 | #include "emutables.h" |
62 | #endif | 62 | #endif |
63 | 63 | ||
64 | #if defined(EMU2413_COMPACTION) && !defined(ROCKBOX) | 64 | #if defined(EMU2413_COMPACTION) && !defined(ROCKBOX) |
65 | #define OPLL_TONE_NUM 1 | 65 | #define OPLL_TONE_NUM 1 |
66 | static unsigned char default_inst[OPLL_TONE_NUM][(16 + 3) * 16] = { | 66 | static unsigned char default_inst[OPLL_TONE_NUM][(16 + 3) * 16] = { |
67 | { | 67 | { |
68 | #include "2413tone.h" | 68 | #include "2413tone.h" |
69 | } | 69 | } |
70 | }; | 70 | }; |
71 | #else | 71 | #else |
72 | #define OPLL_TONE_NUM 3 | 72 | #define OPLL_TONE_NUM 3 |
73 | static unsigned char default_inst[OPLL_TONE_NUM][(16 + 3) * 16] = { | 73 | static unsigned char default_inst[OPLL_TONE_NUM][(16 + 3) * 16] = { |
74 | { | 74 | { |
75 | #include "2413tone.h" | 75 | #include "2413tone.h" |
76 | }, | 76 | }, |
77 | { | 77 | { |
78 | #include "vrc7tone.h" | 78 | #include "vrc7tone.h" |
79 | }, | 79 | }, |
80 | { | 80 | { |
81 | #include "281btone.h" | 81 | #include "281btone.h" |
82 | } | 82 | } |
83 | }; | 83 | }; |
84 | #endif | 84 | #endif |
85 | 85 | ||
86 | /* Size of Sintable ( 8 -- 18 can be used. 9 recommended.) */ | 86 | /* Size of Sintable ( 8 -- 18 can be used. 9 recommended.) */ |
87 | #define PG_BITS 9 | 87 | #define PG_BITS 9 |
88 | #define PG_WIDTH (1<<PG_BITS) | 88 | #define PG_WIDTH (1<<PG_BITS) |
89 | 89 | ||
90 | /* Phase increment counter */ | 90 | /* Phase increment counter */ |
91 | #define DP_BITS 18 | 91 | #define DP_BITS 18 |
92 | #define DP_WIDTH (1<<DP_BITS) | 92 | #define DP_WIDTH (1<<DP_BITS) |
93 | #define DP_BASE_BITS (DP_BITS - PG_BITS) | 93 | #define DP_BASE_BITS (DP_BITS - PG_BITS) |
94 | 94 | ||
95 | /* Dynamic range (Accuracy of sin table) */ | 95 | /* Dynamic range (Accuracy of sin table) */ |
96 | #define DB_PREC 48 | 96 | #define DB_PREC 48 |
97 | #define DB_BITS 8 | 97 | #define DB_BITS 8 |
98 | #define DB_STEP ((double)DB_PREC/(1<<DB_BITS)) | 98 | #define DB_STEP ((double)DB_PREC/(1<<DB_BITS)) |
99 | #define DB_MUTE (1<<DB_BITS) | 99 | #define DB_MUTE (1<<DB_BITS) |
100 | 100 | ||
101 | /* Dynamic range of envelope */ | 101 | /* Dynamic range of envelope */ |
102 | #define EG_STEP 0.375 | 102 | #define EG_STEP 0.375 |
103 | #define EG_BITS 7 | 103 | #define EG_BITS 7 |
104 | #define EG_MUTE (1<<EG_BITS) | 104 | #define EG_MUTE (1<<EG_BITS) |
105 | 105 | ||
106 | /* Dynamic range of total level */ | 106 | /* Dynamic range of total level */ |
107 | #define TL_STEP 0.75 | 107 | #define TL_STEP 0.75 |
108 | #define TL_BITS 6 | 108 | #define TL_BITS 6 |
109 | #define TL_MUTE (1<<TL_BITS) | 109 | #define TL_MUTE (1<<TL_BITS) |
110 | 110 | ||
111 | /* Dynamic range of sustine level */ | 111 | /* Dynamic range of sustine level */ |
112 | #define SL_STEP 3.0 | 112 | #define SL_STEP 3.0 |
113 | #define SL_BITS 4 | 113 | #define SL_BITS 4 |
114 | #define SL_MUTE (1<<SL_BITS) | 114 | #define SL_MUTE (1<<SL_BITS) |
115 | 115 | ||
116 | #define EG2DB(d) ((d)*(e_int32)(EG_STEP/DB_STEP)) | 116 | #define EG2DB(d) ((d)*(e_int32)(EG_STEP/DB_STEP)) |
117 | #define TL2EG(d) ((d)*(e_int32)(TL_STEP/EG_STEP)) | 117 | #define TL2EG(d) ((d)*(e_int32)(TL_STEP/EG_STEP)) |
118 | #define SL2EG(d) ((d)*(e_int32)(SL_STEP/EG_STEP)) | 118 | #define SL2EG(d) ((d)*(e_int32)(SL_STEP/EG_STEP)) |
119 | 119 | ||
120 | #define DB_POS(x) (x*DB_MUTE/DB_PREC) | 120 | #define DB_POS(x) (x*DB_MUTE/DB_PREC) |
121 | #define DB_NEG(x) (DB_MUTE+DB_MUTE+x*DB_MUTE/DB_PREC) | 121 | #define DB_NEG(x) (DB_MUTE+DB_MUTE+x*DB_MUTE/DB_PREC) |
122 | 122 | ||
123 | /* Bits for liner value */ | 123 | /* Bits for liner value */ |
124 | #define DB2LIN_AMP_BITS 8 | 124 | #define DB2LIN_AMP_BITS 8 |
125 | #define SLOT_AMP_BITS (DB2LIN_AMP_BITS) | 125 | #define SLOT_AMP_BITS (DB2LIN_AMP_BITS) |
126 | 126 | ||
127 | /* Bits for envelope phase incremental counter */ | 127 | /* Bits for envelope phase incremental counter */ |
128 | #define EG_DP_BITS 22 | 128 | #define EG_DP_BITS 22 |
129 | #define EG_DP_WIDTH (1<<EG_DP_BITS) | 129 | #define EG_DP_WIDTH (1<<EG_DP_BITS) |
130 | 130 | ||
131 | /* Bits for Pitch and Amp modulator */ | 131 | /* Bits for Pitch and Amp modulator */ |
132 | #define PM_PG_BITS 8 | 132 | #define PM_PG_BITS 8 |
133 | #define PM_PG_WIDTH (1<<PM_PG_BITS) | 133 | #define PM_PG_WIDTH (1<<PM_PG_BITS) |
134 | #define PM_DP_BITS 16 | 134 | #define PM_DP_BITS 16 |
135 | #define PM_DP_WIDTH (1<<PM_DP_BITS) | 135 | #define PM_DP_WIDTH (1<<PM_DP_BITS) |
136 | #define AM_PG_BITS 8 | 136 | #define AM_PG_BITS 8 |
137 | #define AM_PG_WIDTH (1<<AM_PG_BITS) | 137 | #define AM_PG_WIDTH (1<<AM_PG_BITS) |
138 | #define AM_DP_BITS 16 | 138 | #define AM_DP_BITS 16 |
139 | #define AM_DP_WIDTH (1<<AM_DP_BITS) | 139 | #define AM_DP_WIDTH (1<<AM_DP_BITS) |
140 | 140 | ||
141 | /* PM table is calcurated by PM_AMP * pow(2,PM_DEPTH*sin(x)/1200) */ | 141 | /* PM table is calcurated by PM_AMP * pow(2,PM_DEPTH*sin(x)/1200) */ |
142 | #define PM_AMP_BITS 8 | 142 | #define PM_AMP_BITS 8 |
143 | #define PM_AMP (1<<PM_AMP_BITS) | 143 | #define PM_AMP (1<<PM_AMP_BITS) |
144 | 144 | ||
145 | /* PM speed(Hz) and depth(cent) */ | 145 | /* PM speed(Hz) and depth(cent) */ |
146 | #define PM_SPEED 6.4 | 146 | #define PM_SPEED 6.4 |
147 | #define PM_DEPTH 13.75 | 147 | #define PM_DEPTH 13.75 |
148 | 148 | ||
149 | /* AM speed(Hz) and depth(dB) */ | 149 | /* AM speed(Hz) and depth(dB) */ |
150 | #define AM_SPEED 3.6413 | 150 | #define AM_SPEED 3.6413 |
151 | #define AM_DEPTH 4.875 | 151 | #define AM_DEPTH 4.875 |
152 | 152 | ||
153 | /* Cut the lower b bit(s) off. */ | 153 | /* Cut the lower b bit(s) off. */ |
154 | #define HIGHBITS(c,b) ((c)>>(b)) | 154 | #define HIGHBITS(c,b) ((c)>>(b)) |
155 | 155 | ||
156 | /* Leave the lower b bit(s). */ | 156 | /* Leave the lower b bit(s). */ |
157 | #define LOWBITS(c,b) ((c)&((1<<(b))-1)) | 157 | #define LOWBITS(c,b) ((c)&((1<<(b))-1)) |
158 | 158 | ||
159 | /* Expand x which is s bits to d bits. */ | 159 | /* Expand x which is s bits to d bits. */ |
160 | #define EXPAND_BITS(x,s,d) ((x)<<((d)-(s))) | 160 | #define EXPAND_BITS(x,s,d) ((x)<<((d)-(s))) |
161 | 161 | ||
162 | /* Expand x which is s bits to d bits and fill expanded bits '1' */ | 162 | /* Expand x which is s bits to d bits and fill expanded bits '1' */ |
163 | #define EXPAND_BITS_X(x,s,d) (((x)<<((d)-(s)))|((1<<((d)-(s)))-1)) | 163 | #define EXPAND_BITS_X(x,s,d) (((x)<<((d)-(s)))|((1<<((d)-(s)))-1)) |
164 | 164 | ||
165 | /* Adjust envelope speed which depends on sampling rate. */ | 165 | /* Adjust envelope speed which depends on sampling rate. */ |
166 | #define RATE_ADJUST(x) (rate==49716?(e_uint32)x:(e_uint32)(((long long)(x)*clk/rate+36)/72)) | 166 | #define RATE_ADJUST(x) (rate==49716?(e_uint32)x:(e_uint32)(((long long)(x)*clk/rate+36)/72)) |
167 | 167 | ||
168 | #define MOD(o,x) (&(o)->slot[(x)<<1]) | 168 | #define MOD(o,x) (&(o)->slot[(x)<<1]) |
169 | #define CAR(o,x) (&(o)->slot[((x)<<1)|1]) | 169 | #define CAR(o,x) (&(o)->slot[((x)<<1)|1]) |
170 | 170 | ||
171 | #define BIT(s,b) (((s)>>(b))&1) | 171 | #define BIT(s,b) (((s)>>(b))&1) |
172 | 172 | ||
173 | /* Input clock */ | 173 | /* Input clock */ |
174 | static e_uint32 clk = 844451141; | 174 | static e_uint32 clk = 844451141; |
175 | /* Sampling rate */ | 175 | /* Sampling rate */ |
176 | static e_uint32 rate = 3354932; | 176 | static e_uint32 rate = 3354932; |
177 | 177 | ||
178 | /* WaveTable for each envelope amp */ | 178 | /* WaveTable for each envelope amp */ |
179 | static e_uint16 fullsintable[PG_WIDTH]; | 179 | static e_uint16 fullsintable[PG_WIDTH]; |
180 | static e_uint16 halfsintable[PG_WIDTH]; | 180 | static e_uint16 halfsintable[PG_WIDTH]; |
181 | 181 | ||
182 | static e_uint16 *waveform[2] = { fullsintable, halfsintable }; | 182 | static e_uint16 *waveform[2] = { fullsintable, halfsintable }; |
183 | 183 | ||
184 | /* LFO Table */ | 184 | /* LFO Table */ |
185 | #ifdef EMU2413_CALCUL_TABLES | 185 | #ifdef EMU2413_CALCUL_TABLES |
186 | static e_int32 pmtable[PM_PG_WIDTH]; | 186 | static e_int32 pmtable[PM_PG_WIDTH]; |
187 | static e_int32 amtable[AM_PG_WIDTH]; | 187 | static e_int32 amtable[AM_PG_WIDTH]; |
188 | #define PMTABLE(x) pmtable[x] | 188 | #define PMTABLE(x) pmtable[x] |
189 | #define AMTABLE(x) amtable[x] | 189 | #define AMTABLE(x) amtable[x] |
190 | #else | 190 | #else |
191 | #define PMTABLE(x) (e_int32)pm_coeff[x] | 191 | #define PMTABLE(x) (e_int32)pm_coeff[x] |
192 | #if (PM_PG_WIDTH != 256) | 192 | #if (PM_PG_WIDTH != 256) |
193 | #error PM_PG_WIDTH must be set to 256 if EMU2413_CALCUL_TABLES is not defined | 193 | #error PM_PG_WIDTH must be set to 256 if EMU2413_CALCUL_TABLES is not defined |
194 | #endif | 194 | #endif |
195 | #define AMTABLE(x) (e_int32)am_coeff[x] | 195 | #define AMTABLE(x) (e_int32)am_coeff[x] |
196 | #if (AM_PG_WIDTH != 256) | 196 | #if (AM_PG_WIDTH != 256) |
197 | #error AM_PG_WIDTH must be set to 256 if EMU2413_CALCUL_TABLES is not defined | 197 | #error AM_PG_WIDTH must be set to 256 if EMU2413_CALCUL_TABLES is not defined |
198 | #endif | 198 | #endif |
199 | #endif | 199 | #endif |
200 | 200 | ||
201 | /* Phase delta for LFO */ | 201 | /* Phase delta for LFO */ |
202 | static e_uint32 pm_dphase; | 202 | static e_uint32 pm_dphase; |
203 | static e_uint32 am_dphase; | 203 | static e_uint32 am_dphase; |
204 | 204 | ||
205 | /* dB to Liner table */ | 205 | /* dB to Liner table */ |
206 | static e_int16 DB2LIN_TABLE[(DB_MUTE + DB_MUTE) * 2]; | 206 | static e_int16 DB2LIN_TABLE[(DB_MUTE + DB_MUTE) * 2]; |
207 | 207 | ||
208 | /* Liner to Log curve conversion table (for Attack rate). */ | 208 | /* Liner to Log curve conversion table (for Attack rate). */ |
209 | #ifdef EMU2413_CALCUL_TABLES | 209 | #ifdef EMU2413_CALCUL_TABLES |
210 | static e_uint16 ar_adjust_table[1 << EG_BITS]; | 210 | static e_uint16 ar_adjust_table[1 << EG_BITS]; |
211 | #define AR_ADJUST_TABLE(x) ar_adjust_table[x] | 211 | #define AR_ADJUST_TABLE(x) ar_adjust_table[x] |
212 | #else | 212 | #else |
213 | #define AR_ADJUST_TABLE(x) ar_adjust_coeff[x] | 213 | #define AR_ADJUST_TABLE(x) ar_adjust_coeff[x] |
214 | #if (EG_BITS != 7) | 214 | #if (EG_BITS != 7) |
215 | #error EG_BITS must be set to 7 if EMU2413_CALCUL_TABLES is not defined | 215 | #error EG_BITS must be set to 7 if EMU2413_CALCUL_TABLES is not defined |
216 | #endif | 216 | #endif |
217 | #endif | 217 | #endif |
218 | 218 | ||
219 | /* Empty voice data */ | 219 | /* Empty voice data */ |
220 | static OPLL_PATCH null_patch = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; | 220 | static OPLL_PATCH null_patch = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; |
221 | 221 | ||
222 | /* Basic voice Data */ | 222 | /* Basic voice Data */ |
223 | static OPLL_PATCH default_patch[OPLL_TONE_NUM][(16 + 3) * 2]; | 223 | static OPLL_PATCH default_patch[OPLL_TONE_NUM][(16 + 3) * 2]; |
224 | 224 | ||
225 | /* Definition of envelope mode */ | 225 | /* Definition of envelope mode */ |
226 | enum OPLL_EG_STATE | 226 | enum OPLL_EG_STATE |
227 | { READY, ATTACK, DECAY, SUSHOLD, SUSTINE, RELEASE, SETTLE, FINISH }; | 227 | { READY, ATTACK, DECAY, SUSHOLD, SUSTINE, RELEASE, SETTLE, FINISH }; |
228 | 228 | ||
229 | /* Phase incr table for Attack */ | 229 | /* Phase incr table for Attack */ |
230 | static e_uint32 dphaseARTable[16][16]; | 230 | static e_uint32 dphaseARTable[16][16]; |
231 | /* Phase incr table for Decay and Release */ | 231 | /* Phase incr table for Decay and Release */ |
232 | static e_uint32 dphaseDRTable[16][16]; | 232 | static e_uint32 dphaseDRTable[16][16]; |
233 | 233 | ||
234 | /* KSL + TL Table */ | 234 | /* KSL + TL Table */ |
235 | e_uint8 tllTable[16][8][1 << TL_BITS][4]; | 235 | e_uint8 tllTable[16][8][1 << TL_BITS][4]; |
236 | static e_int32 rksTable[2][8][2]; | 236 | static e_int32 rksTable[2][8][2]; |
237 | 237 | ||
238 | /* We may not have too much SRAM in rockbox */ | 238 | /* We may not have too much SRAM in rockbox */ |
239 | #if !defined(ROCKBOX) | 239 | #if !defined(ROCKBOX) |
240 | /* Phase incr table for PG */ | 240 | /* Phase incr table for PG */ |
241 | static e_uint32 dphaseTable[512][8][16]; | 241 | static e_uint32 dphaseTable[512][8][16]; |
242 | #endif | 242 | #endif |
243 | 243 | ||
244 | /*************************************************** | 244 | /*************************************************** |
245 | 245 | ||
246 | Create tables | 246 | Create tables |
247 | 247 | ||
248 | ****************************************************/ | 248 | ****************************************************/ |
249 | #ifdef EMU2413_CALCUL_TABLES | 249 | #ifdef EMU2413_CALCUL_TABLES |
250 | INLINE static e_int32 | 250 | INLINE static e_int32 |
251 | Min (e_int32 i, e_int32 j) | 251 | Min (e_int32 i, e_int32 j) |
252 | { | 252 | { |
253 | if (i < j) | 253 | if (i < j) |
254 | return i; | 254 | return i; |
255 | else | 255 | else |
256 | return j; | 256 | return j; |
257 | } | 257 | } |
258 | 258 | ||
259 | /* Table for AR to LogCurve. */ | 259 | /* Table for AR to LogCurve. */ |
260 | static void | 260 | static void |
261 | makeAdjustTable (void) | 261 | makeAdjustTable (void) |
262 | { | 262 | { |
263 | e_int32 i; | 263 | e_int32 i; |
264 | 264 | ||
265 | ar_adjust_table[0] = (1 << EG_BITS) - 1; | 265 | ar_adjust_table[0] = (1 << EG_BITS) - 1; |
266 | for (i = 1; i < (1<<EG_BITS); i++) | 266 | for (i = 1; i < (1<<EG_BITS); i++) |
267 | ar_adjust_table[i] = (e_uint16) ((double) (1<<EG_BITS)-1 - ((1<<EG_BITS)-1)*log(i)/log(127)); | 267 | ar_adjust_table[i] = (e_uint16) ((double) (1<<EG_BITS)-1 - ((1<<EG_BITS)-1)*log(i)/log(127)); |
268 | } | 268 | } |
269 | #endif | 269 | #endif |
270 | 270 | ||
271 | /* Table for dB(0 -- (1<<DB_BITS)-1) to Liner(0 -- DB2LIN_AMP_WIDTH) */ | 271 | /* Table for dB(0 -- (1<<DB_BITS)-1) to Liner(0 -- DB2LIN_AMP_WIDTH) */ |
272 | static void | 272 | static void |
273 | makeDB2LinTable (void) | 273 | makeDB2LinTable (void) |
274 | { | 274 | { |
275 | e_int32 i; | 275 | e_int32 i; |
276 | for (i = 0; i < DB_MUTE + DB_MUTE; i++) | 276 | for (i = 0; i < DB_MUTE + DB_MUTE; i++) |
277 | { | 277 | { |
278 | #ifdef EMU2413_CALCUL_TABLES | 278 | #ifdef EMU2413_CALCUL_TABLES |
279 | DB2LIN_TABLE[i] = (e_int16) ((double) ((1 << DB2LIN_AMP_BITS) - 1) * pow (10, -(double) i * DB_STEP / 20)); | 279 | DB2LIN_TABLE[i] = (e_int16) ((double) ((1 << DB2LIN_AMP_BITS) - 1) * pow (10, -(double) i * DB_STEP / 20)); |
280 | #else | 280 | #else |
281 | DB2LIN_TABLE[i] = db2lin_coeff[i]; | 281 | DB2LIN_TABLE[i] = db2lin_coeff[i]; |
282 | #endif | 282 | #endif |
283 | if (i >= DB_MUTE) DB2LIN_TABLE[i] = 0; | 283 | if (i >= DB_MUTE) DB2LIN_TABLE[i] = 0; |
284 | DB2LIN_TABLE[i + DB_MUTE + DB_MUTE] = (e_int16) (-DB2LIN_TABLE[i]); | 284 | DB2LIN_TABLE[i + DB_MUTE + DB_MUTE] = (e_int16) (-DB2LIN_TABLE[i]); |
285 | } | 285 | } |
286 | } | 286 | } |
287 | 287 | ||
288 | #ifdef EMU2413_CALCUL_TABLES | 288 | #ifdef EMU2413_CALCUL_TABLES |
289 | /* Liner(+0.0 - +1.0) to dB((1<<DB_BITS) - 1 -- 0) */ | 289 | /* Liner(+0.0 - +1.0) to dB((1<<DB_BITS) - 1 -- 0) */ |
290 | static e_int32 | 290 | static e_int32 |
291 | lin2db (double d) | 291 | lin2db (double d) |
292 | { | 292 | { |
293 | if (d == 0) | 293 | if (d == 0) |
294 | return (DB_MUTE - 1); | 294 | return (DB_MUTE - 1); |
295 | else | 295 | else |
296 | return Min (-(e_int32) (20.0 * log10 (d) / DB_STEP), DB_MUTE-1); /* 0 -- 127 */ | 296 | return Min (-(e_int32) (20.0 * log10 (d) / DB_STEP), DB_MUTE-1); /* 0 -- 127 */ |
297 | } | 297 | } |
298 | #endif | 298 | #endif |
299 | 299 | ||
300 | /* Sin Table */ | 300 | /* Sin Table */ |
301 | static void | 301 | static void |
302 | makeSinTable (void) | 302 | makeSinTable (void) |
303 | { | 303 | { |
304 | e_int32 i; | 304 | e_int32 i; |
305 | 305 | ||
306 | for (i = 0; i < PG_WIDTH / 4; i++) | 306 | for (i = 0; i < PG_WIDTH / 4; i++) |
307 | #ifdef EMU2413_CALCUL_TABLES | 307 | #ifdef EMU2413_CALCUL_TABLES |
308 | fullsintable[i] = (e_uint32) lin2db (sin (2.0 * PI * i / PG_WIDTH) ); | 308 | fullsintable[i] = (e_uint32) lin2db (sin (2.0 * PI * i / PG_WIDTH) ); |
309 | #else | 309 | #else |
310 | fullsintable[i] = sin_coeff[i]; | 310 | fullsintable[i] = sin_coeff[i]; |
311 | #endif | 311 | #endif |
312 | 312 | ||
313 | for (i = 0; i < PG_WIDTH / 4; i++) | 313 | for (i = 0; i < PG_WIDTH / 4; i++) |
314 | { | 314 | { |
315 | fullsintable[PG_WIDTH / 2 - 1 - i] = fullsintable[i]; | 315 | fullsintable[PG_WIDTH / 2 - 1 - i] = fullsintable[i]; |
316 | } | 316 | } |
317 | 317 | ||
318 | for (i = 0; i < PG_WIDTH / 2; i++) | 318 | for (i = 0; i < PG_WIDTH / 2; i++) |
319 | { | 319 | { |
320 | fullsintable[PG_WIDTH / 2 + i] = (e_uint32) (DB_MUTE + DB_MUTE + fullsintable[i]); | 320 | fullsintable[PG_WIDTH / 2 + i] = (e_uint32) (DB_MUTE + DB_MUTE + fullsintable[i]); |
321 | } | 321 | } |
322 | 322 | ||
323 | for (i = 0; i < PG_WIDTH / 2; i++) | 323 | for (i = 0; i < PG_WIDTH / 2; i++) |
324 | halfsintable[i] = fullsintable[i]; | 324 | halfsintable[i] = fullsintable[i]; |
325 | for (i = PG_WIDTH / 2; i < PG_WIDTH; i++) | 325 | for (i = PG_WIDTH / 2; i < PG_WIDTH; i++) |
326 | halfsintable[i] = fullsintable[0]; | 326 | halfsintable[i] = fullsintable[0]; |
327 | } | 327 | } |
328 | 328 | ||
329 | #ifdef EMU2413_CALCUL_TABLES | 329 | #ifdef EMU2413_CALCUL_TABLES |
330 | static double saw(double phase) | 330 | static double saw(double phase) |
331 | { | 331 | { |
332 | if(phase <= PI/2) | 332 | if(phase <= PI/2) |
333 | return phase * 2 / PI ; | 333 | return phase * 2 / PI ; |
334 | else if(phase <= PI*3/2) | 334 | else if(phase <= PI*3/2) |
335 | return 2.0 - ( phase * 2 / PI ); | 335 | return 2.0 - ( phase * 2 / PI ); |
336 | else | 336 | else |
337 | return -4.0 + phase * 2 / PI; | 337 | return -4.0 + phase * 2 / PI; |
338 | } | 338 | } |
339 | 339 | ||
340 | /* Table for Pitch Modulator */ | 340 | /* Table for Pitch Modulator */ |
341 | static void | 341 | static void |
342 | makePmTable (void) | 342 | makePmTable (void) |
343 | { | 343 | { |
344 | e_int32 i; | 344 | e_int32 i; |
345 | 345 | ||
346 | for (i = 0; i < PM_PG_WIDTH; i++) | 346 | for (i = 0; i < PM_PG_WIDTH; i++) |
347 | /* pmtable[i] = (e_int32) ((double) PM_AMP * pow (2, (double) PM_DEPTH * sin (2.0 * PI * i / PM_PG_WIDTH) / 1200)); */ | 347 | /* pmtable[i] = (e_int32) ((double) PM_AMP * pow (2, (double) PM_DEPTH * sin (2.0 * PI * i / PM_PG_WIDTH) / 1200)); */ |
348 | pmtable[i] = (e_int32) ((double) PM_AMP * pow (2, (double) PM_DEPTH * saw (2.0 * PI * i / PM_PG_WIDTH) / 1200)); | 348 | pmtable[i] = (e_int32) ((double) PM_AMP * pow (2, (double) PM_DEPTH * saw (2.0 * PI * i / PM_PG_WIDTH) / 1200)); |
349 | } | 349 | } |
350 | 350 | ||
351 | /* Table for Amp Modulator */ | 351 | /* Table for Amp Modulator */ |
352 | static void | 352 | static void |
353 | makeAmTable (void) | 353 | makeAmTable (void) |
354 | { | 354 | { |
355 | e_int32 i; | 355 | e_int32 i; |
356 | 356 | ||
357 | for (i = 0; i < AM_PG_WIDTH; i++) | 357 | for (i = 0; i < AM_PG_WIDTH; i++) |
358 | /* amtable[i] = (e_int32) ((double) AM_DEPTH / 2 / DB_STEP * (1.0 + sin (2.0 * PI * i / PM_PG_WIDTH))); */ | 358 | /* amtable[i] = (e_int32) ((double) AM_DEPTH / 2 / DB_STEP * (1.0 + sin (2.0 * PI * i / PM_PG_WIDTH))); */ |
359 | amtable[i] = (e_int32) ((double) AM_DEPTH / 2 / DB_STEP * (1.0 + saw (2.0 * PI * i / PM_PG_WIDTH))); | 359 | amtable[i] = (e_int32) ((double) AM_DEPTH / 2 / DB_STEP * (1.0 + saw (2.0 * PI * i / PM_PG_WIDTH))); |
360 | } | 360 | } |
361 | #endif | 361 | #endif |
362 | 362 | ||
363 | #if !defined(ROCKBOX) | 363 | #if !defined(ROCKBOX) |
364 | /* Phase increment counter table */ | 364 | /* Phase increment counter table */ |
365 | static void | 365 | static void |
366 | makeDphaseTable (void) | 366 | makeDphaseTable (void) |
367 | { | 367 | { |
368 | e_uint32 fnum, block, ML; | 368 | e_uint32 fnum, block, ML; |
369 | e_uint32 mltable[16] = | 369 | e_uint32 mltable[16] = |
370 | { 1, 1 * 2, 2 * 2, 3 * 2, 4 * 2, 5 * 2, 6 * 2, 7 * 2, 8 * 2, 9 * 2, 10 * 2, 10 * 2, 12 * 2, 12 * 2, 15 * 2, 15 * 2 }; | 370 | { 1, 1 * 2, 2 * 2, 3 * 2, 4 * 2, 5 * 2, 6 * 2, 7 * 2, 8 * 2, 9 * 2, 10 * 2, 10 * 2, 12 * 2, 12 * 2, 15 * 2, 15 * 2 }; |
371 | 371 | ||
372 | for (fnum = 0; fnum < 512; fnum++) | 372 | for (fnum = 0; fnum < 512; fnum++) |
373 | for (block = 0; block < 8; block++) | 373 | for (block = 0; block < 8; block++) |
374 | for (ML = 0; ML < 16; ML++) | 374 | for (ML = 0; ML < 16; ML++) |
375 | dphaseTable[fnum][block][ML] = RATE_ADJUST (((fnum * mltable[ML]) << block) >> (20 - DP_BITS)); | 375 | dphaseTable[fnum][block][ML] = RATE_ADJUST (((fnum * mltable[ML]) << block) >> (20 - DP_BITS)); |
376 | } | 376 | } |
377 | #endif | 377 | #endif |
378 | 378 | ||
379 | static void | 379 | static void |
380 | makeTllTable (void) | 380 | makeTllTable (void) |
381 | { | 381 | { |
382 | /* Multiplication owith 8 to have an integer result. This allows to remove floating point operation. */ | 382 | /* Multiplication owith 8 to have an integer result. This allows to remove floating point operation. */ |
383 | #define dB2(x) (int)((x)*2*8) | 383 | #define dB2(x) (int)((x)*2*8) |
384 | 384 | ||
385 | static int kltable[16] = { | 385 | static int kltable[16] = { |
386 | dB2 ( 0.000), dB2 ( 9.000), dB2 (12.000), dB2 (13.875), dB2 (15.000), dB2 (16.125), dB2 (16.875), dB2 (17.625), | 386 | dB2 ( 0.000), dB2 ( 9.000), dB2 (12.000), dB2 (13.875), dB2 (15.000), dB2 (16.125), dB2 (16.875), dB2 (17.625), |
387 | dB2 (18.000), dB2 (18.750), dB2 (19.125), dB2 (19.500), dB2 (19.875), dB2 (20.250), dB2 (20.625), dB2 (21.000) | 387 | dB2 (18.000), dB2 (18.750), dB2 (19.125), dB2 (19.500), dB2 (19.875), dB2 (20.250), dB2 (20.625), dB2 (21.000) |
388 | }; | 388 | }; |
389 | 389 | ||
390 | e_int32 tmp; | 390 | e_int32 tmp; |
391 | e_int32 fnum, block, TL, KL; | 391 | e_int32 fnum, block, TL, KL; |
392 | 392 | ||
393 | for (fnum = 0; fnum < 16; fnum++) | 393 | for (fnum = 0; fnum < 16; fnum++) |
394 | for (block = 0; block < 8; block++) | 394 | for (block = 0; block < 8; block++) |
395 | for (TL = 0; TL < 64; TL++) | 395 | for (TL = 0; TL < 64; TL++) |
396 | for (KL = 0; KL < 4; KL++) | 396 | for (KL = 0; KL < 4; KL++) |
397 | { | 397 | { |
398 | if (KL == 0) | 398 | if (KL == 0) |
399 | { | 399 | { |
400 | tllTable[fnum][block][TL][KL] = TL2EG (TL); | 400 | tllTable[fnum][block][TL][KL] = TL2EG (TL); |
401 | } | 401 | } |
402 | else | 402 | else |
403 | { | 403 | { |
404 | tmp = (e_int32) ((kltable[fnum] - dB2 (3.000) * (7 - block))/8); | 404 | tmp = (e_int32) ((kltable[fnum] - dB2 (3.000) * (7 - block))/8); |
405 | if (tmp <= 0) | 405 | if (tmp <= 0) |
406 | tllTable[fnum][block][TL][KL] = TL2EG (TL); | 406 | tllTable[fnum][block][TL][KL] = TL2EG (TL); |
407 | else | 407 | else |
408 | /* tllTable[fnum][block][TL][KL] = (e_uint32) ((tmp >> (3 - KL)) / EG_STEP) + TL2EG (TL); */ | 408 | /* tllTable[fnum][block][TL][KL] = (e_uint32) ((tmp >> (3 - KL)) / EG_STEP) + TL2EG (TL); */ |
409 | tllTable[fnum][block][TL][KL] = (e_uint32) ((tmp << KL) / (int)(EG_STEP*8)) + TL2EG (TL); | 409 | tllTable[fnum][block][TL][KL] = (e_uint32) ((tmp << KL) / (int)(EG_STEP*8)) + TL2EG (TL); |
410 | } | 410 | } |
411 | } | 411 | } |
412 | } | 412 | } |
413 | 413 | ||
414 | #ifdef USE_SPEC_ENV_SPEED | 414 | #ifdef USE_SPEC_ENV_SPEED |
415 | static double attacktime[16][4] = { | 415 | static double attacktime[16][4] = { |
416 | {0, 0, 0, 0}, | 416 | {0, 0, 0, 0}, |
417 | {1730.15, 1400.60, 1153.43, 988.66}, | 417 | {1730.15, 1400.60, 1153.43, 988.66}, |
418 | {865.08, 700.30, 576.72, 494.33}, | 418 | {865.08, 700.30, 576.72, 494.33}, |
419 | {432.54, 350.15, 288.36, 247.16}, | 419 | {432.54, 350.15, 288.36, 247.16}, |
420 | {216.27, 175.07, 144.18, 123.58}, | 420 | {216.27, 175.07, 144.18, 123.58}, |
421 | {108.13, 87.54, 72.09, 61.79}, | 421 | {108.13, 87.54, 72.09, 61.79}, |
422 | {54.07, 43.77, 36.04, 30.90}, | 422 | {54.07, 43.77, 36.04, 30.90}, |
423 | {27.03, 21.88, 18.02, 15.45}, | 423 | {27.03, 21.88, 18.02, 15.45}, |
424 | {13.52, 10.94, 9.01, 7.72}, | 424 | {13.52, 10.94, 9.01, 7.72}, |
425 | {6.76, 5.47, 4.51, 3.86}, | 425 | {6.76, 5.47, 4.51, 3.86}, |
426 | {3.38, 2.74, 2.25, 1.93}, | 426 | {3.38, 2.74, 2.25, 1.93}, |
427 | {1.69, 1.37, 1.13, 0.97}, | 427 | {1.69, 1.37, 1.13, 0.97}, |
428 | {0.84, 0.70, 0.60, 0.54}, | 428 | {0.84, 0.70, 0.60, 0.54}, |
429 | {0.50, 0.42, 0.34, 0.30}, | 429 | {0.50, 0.42, 0.34, 0.30}, |
430 | {0.28, 0.22, 0.18, 0.14}, | 430 | {0.28, 0.22, 0.18, 0.14}, |
431 | {0.00, 0.00, 0.00, 0.00} | 431 | {0.00, 0.00, 0.00, 0.00} |
432 | }; | 432 | }; |
433 | 433 | ||
434 | static double decaytime[16][4] = { | 434 | static double decaytime[16][4] = { |
435 | {0, 0, 0, 0}, | 435 | {0, 0, 0, 0}, |
436 | {20926.60, 16807.20, 14006.00, 12028.60}, | 436 | {20926.60, 16807.20, 14006.00, 12028.60}, |
437 | {10463.30, 8403.58, 7002.98, 6014.32}, | 437 | {10463.30, 8403.58, 7002.98, 6014.32}, |
438 | {5231.64, 4201.79, 3501.49, 3007.16}, | 438 | {5231.64, 4201.79, 3501.49, 3007.16}, |
439 | {2615.82, 2100.89, 1750.75, 1503.58}, | 439 | {2615.82, 2100.89, 1750.75, 1503.58}, |
440 | {1307.91, 1050.45, 875.37, 751.79}, | 440 | {1307.91, 1050.45, 875.37, 751.79}, |
441 | {653.95, 525.22, 437.69, 375.90}, | 441 | {653.95, 525.22, 437.69, 375.90}, |
442 | {326.98, 262.61, 218.84, 187.95}, | 442 | {326.98, 262.61, 218.84, 187.95}, |
443 | {163.49, 131.31, 109.42, 93.97}, | 443 | {163.49, 131.31, 109.42, 93.97}, |
444 | {81.74, 65.65, 54.71, 46.99}, | 444 | {81.74, 65.65, 54.71, 46.99}, |
445 | {40.87, 32.83, 27.36, 23.49}, | 445 | {40.87, 32.83, 27.36, 23.49}, |
446 | {20.44, 16.41, 13.68, 11.75}, | 446 | {20.44, 16.41, 13.68, 11.75}, |
447 | {10.22, 8.21, 6.84, 5.87}, | 447 | {10.22, 8.21, 6.84, 5.87}, |
448 | {5.11, 4.10, 3.42, 2.94}, | 448 | {5.11, 4.10, 3.42, 2.94}, |
449 | {2.55, 2.05, 1.71, 1.47}, | 449 | {2.55, 2.05, 1.71, 1.47}, |
450 | {1.27, 1.27, 1.27, 1.27} | 450 | {1.27, 1.27, 1.27, 1.27} |
451 | }; | 451 | }; |
452 | #endif | 452 | #endif |
453 | 453 | ||
454 | /* Rate Table for Attack */ | 454 | /* Rate Table for Attack */ |
455 | static void | 455 | static void |
456 | makeDphaseARTable (void) | 456 | makeDphaseARTable (void) |
457 | { | 457 | { |
458 | e_int32 AR, Rks, RM, RL; | 458 | e_int32 AR, Rks, RM, RL; |
459 | 459 | ||
460 | #ifdef USE_SPEC_ENV_SPEED | 460 | #ifdef USE_SPEC_ENV_SPEED |
461 | e_uint32 attacktable[16][4]; | 461 | e_uint32 attacktable[16][4]; |
462 | 462 | ||
463 | for (RM = 0; RM < 16; RM++) | 463 | for (RM = 0; RM < 16; RM++) |
464 | for (RL = 0; RL < 4; RL++) | 464 | for (RL = 0; RL < 4; RL++) |
465 | { | 465 | { |
466 | if (RM == 0) | 466 | if (RM == 0) |
467 | attacktable[RM][RL] = 0; | 467 | attacktable[RM][RL] = 0; |
468 | else if (RM == 15) | 468 | else if (RM == 15) |
469 | attacktable[RM][RL] = EG_DP_WIDTH; | 469 | attacktable[RM][RL] = EG_DP_WIDTH; |
470 | else | 470 | else |
471 | attacktable[RM][RL] = (e_uint32) ((double) (1 << EG_DP_BITS) / (attacktime[RM][RL] * 3579545 / 72000)); | 471 | attacktable[RM][RL] = (e_uint32) ((double) (1 << EG_DP_BITS) / (attacktime[RM][RL] * 3579545 / 72000)); |
472 | 472 | ||
473 | } | 473 | } |
474 | #endif | 474 | #endif |
475 | 475 | ||
476 | for (AR = 0; AR < 16; AR++) | 476 | for (AR = 0; AR < 16; AR++) |
477 | for (Rks = 0; Rks < 16; Rks++) | 477 | for (Rks = 0; Rks < 16; Rks++) |
478 | { | 478 | { |
479 | RM = AR + (Rks >> 2); | 479 | RM = AR + (Rks >> 2); |
480 | RL = Rks & 3; | 480 | RL = Rks & 3; |
481 | if (RM > 15) | 481 | if (RM > 15) |
482 | RM = 15; | 482 | RM = 15; |
483 | switch (AR) | 483 | switch (AR) |
484 | { | 484 | { |
485 | case 0: | 485 | case 0: |
486 | dphaseARTable[AR][Rks] = 0; | 486 | dphaseARTable[AR][Rks] = 0; |
487 | break; | 487 | break; |
488 | case 15: | 488 | case 15: |
489 | dphaseARTable[AR][Rks] = 0;/*EG_DP_WIDTH;*/ | 489 | dphaseARTable[AR][Rks] = 0;/*EG_DP_WIDTH;*/ |
490 | break; | 490 | break; |
491 | default: | 491 | default: |
492 | #ifdef USE_SPEC_ENV_SPEED | 492 | #ifdef USE_SPEC_ENV_SPEED |
493 | dphaseARTable[AR][Rks] = RATE_ADJUST (attacktable[RM][RL]); | 493 | dphaseARTable[AR][Rks] = RATE_ADJUST (attacktable[RM][RL]); |
494 | #else | 494 | #else |
495 | dphaseARTable[AR][Rks] = RATE_ADJUST ((3 * (RL + 4) << (RM + 1))); | 495 | dphaseARTable[AR][Rks] = RATE_ADJUST ((3 * (RL + 4) << (RM + 1))); |
496 | #endif | 496 | #endif |
497 | break; | 497 | break; |
498 | } | 498 | } |
499 | } | 499 | } |
500 | } | 500 | } |
501 | 501 | ||
502 | /* Rate Table for Decay and Release */ | 502 | /* Rate Table for Decay and Release */ |
503 | static void | 503 | static void |
504 | makeDphaseDRTable (void) | 504 | makeDphaseDRTable (void) |
505 | { | 505 | { |
506 | e_int32 DR, Rks, RM, RL; | 506 | e_int32 DR, Rks, RM, RL; |
507 | 507 | ||
508 | #ifdef USE_SPEC_ENV_SPEED | 508 | #ifdef USE_SPEC_ENV_SPEED |
509 | e_uint32 decaytable[16][4]; | 509 | e_uint32 decaytable[16][4]; |
510 | 510 | ||
511 | for (RM = 0; RM < 16; RM++) | 511 | for (RM = 0; RM < 16; RM++) |
512 | for (RL = 0; RL < 4; RL++) | 512 | for (RL = 0; RL < 4; RL++) |
513 | if (RM == 0) | 513 | if (RM == 0) |
514 | decaytable[RM][RL] = 0; | 514 | decaytable[RM][RL] = 0; |
515 | else | 515 | else |
516 | decaytable[RM][RL] = (e_uint32) ((double) (1 << EG_DP_BITS) / (decaytime[RM][RL] * 3579545 / 72000)); | 516 | decaytable[RM][RL] = (e_uint32) ((double) (1 << EG_DP_BITS) / (decaytime[RM][RL] * 3579545 / 72000)); |
517 | #endif | 517 | #endif |
518 | 518 | ||
519 | for (DR = 0; DR < 16; DR++) | 519 | for (DR = 0; DR < 16; DR++) |
520 | for (Rks = 0; Rks < 16; Rks++) | 520 | for (Rks = 0; Rks < 16; Rks++) |
521 | { | 521 | { |
522 | RM = DR + (Rks >> 2); | 522 | RM = DR + (Rks >> 2); |
523 | RL = Rks & 3; | 523 | RL = Rks & 3; |
524 | if (RM > 15) | 524 | if (RM > 15) |
525 | RM = 15; | 525 | RM = 15; |
526 | switch (DR) | 526 | switch (DR) |
527 | { | 527 | { |
528 | case 0: | 528 | case 0: |
529 | dphaseDRTable[DR][Rks] = 0; | 529 | dphaseDRTable[DR][Rks] = 0; |
530 | break; | 530 | break; |
531 | default: | 531 | default: |
532 | #ifdef USE_SPEC_ENV_SPEED | 532 | #ifdef USE_SPEC_ENV_SPEED |
533 | dphaseDRTable[DR][Rks] = RATE_ADJUST (decaytable[RM][RL]); | 533 | dphaseDRTable[DR][Rks] = RATE_ADJUST (decaytable[RM][RL]); |
534 | #else | 534 | #else |
535 | dphaseDRTable[DR][Rks] = RATE_ADJUST ((RL + 4) << (RM - 1)); | 535 | dphaseDRTable[DR][Rks] = RATE_ADJUST ((RL + 4) << (RM - 1)); |
536 | #endif | 536 | #endif |
537 | break; | 537 | break; |
538 | } | 538 | } |
539 | } | 539 | } |
540 | } | 540 | } |
541 | 541 | ||
542 | static void | 542 | static void |
543 | makeRksTable (void) | 543 | makeRksTable (void) |
544 | { | 544 | { |
545 | 545 | ||
546 | e_int32 fnum8, block, KR; | 546 | e_int32 fnum8, block, KR; |
547 | 547 | ||
548 | for (fnum8 = 0; fnum8 < 2; fnum8++) | 548 | for (fnum8 = 0; fnum8 < 2; fnum8++) |
549 | for (block = 0; block < 8; block++) | 549 | for (block = 0; block < 8; block++) |
550 | for (KR = 0; KR < 2; KR++) | 550 | for (KR = 0; KR < 2; KR++) |
551 | { | 551 | { |
552 | if (KR != 0) | 552 | if (KR != 0) |
553 | rksTable[fnum8][block][KR] = (block << 1) + fnum8; | 553 | rksTable[fnum8][block][KR] = (block << 1) + fnum8; |
554 | else | 554 | else |
555 | rksTable[fnum8][block][KR] = block >> 1; | 555 | rksTable[fnum8][block][KR] = block >> 1; |
556 | } | 556 | } |
557 | } | 557 | } |
558 | 558 | ||
559 | void | 559 | void |
560 | OPLL_dump2patch (const e_uint8 * dump, OPLL_PATCH * patch) | 560 | OPLL_dump2patch (const e_uint8 * dump, OPLL_PATCH * patch) |
561 | { | 561 | { |
562 | patch[0].AM = (dump[0] >> 7) & 1; | 562 | patch[0].AM = (dump[0] >> 7) & 1; |
563 | patch[1].AM = (dump[1] >> 7) & 1; | 563 | patch[1].AM = (dump[1] >> 7) & 1; |
564 | patch[0].PM = (dump[0] >> 6) & 1; | 564 | patch[0].PM = (dump[0] >> 6) & 1; |
565 | patch[1].PM = (dump[1] >> 6) & 1; | 565 | patch[1].PM = (dump[1] >> 6) & 1; |
566 | patch[0].EG = (dump[0] >> 5) & 1; | 566 | patch[0].EG = (dump[0] >> 5) & 1; |
567 | patch[1].EG = (dump[1] >> 5) & 1; | 567 | patch[1].EG = (dump[1] >> 5) & 1; |
568 | patch[0].KR = (dump[0] >> 4) & 1; | 568 | patch[0].KR = (dump[0] >> 4) & 1; |
569 | patch[1].KR = (dump[1] >> 4) & 1; | 569 | patch[1].KR = (dump[1] >> 4) & 1; |
570 | patch[0].ML = (dump[0]) & 15; | 570 | patch[0].ML = (dump[0]) & 15; |
571 | patch[1].ML = (dump[1]) & 15; | 571 | patch[1].ML = (dump[1]) & 15; |
572 | patch[0].KL = (dump[2] >> 6) & 3; | 572 | patch[0].KL = (dump[2] >> 6) & 3; |
573 | patch[1].KL = (dump[3] >> 6) & 3; | 573 | patch[1].KL = (dump[3] >> 6) & 3; |
574 | patch[0].TL = (dump[2]) & 63; | 574 | patch[0].TL = (dump[2]) & 63; |
575 | patch[0].FB = (dump[3]) & 7; | 575 | patch[0].FB = (dump[3]) & 7; |
576 | patch[0].WF = (dump[3] >> 3) & 1; | 576 | patch[0].WF = (dump[3] >> 3) & 1; |
577 | patch[1].WF = (dump[3] >> 4) & 1; | 577 | patch[1].WF = (dump[3] >> 4) & 1; |
578 | patch[0].AR = (dump[4] >> 4) & 15; | 578 | patch[0].AR = (dump[4] >> 4) & 15; |
579 | patch[1].AR = (dump[5] >> 4) & 15; | 579 | patch[1].AR = (dump[5] >> 4) & 15; |
580 | patch[0].DR = (dump[4]) & 15; | 580 | patch[0].DR = (dump[4]) & 15; |
581 | patch[1].DR = (dump[5]) & 15; | 581 | patch[1].DR = (dump[5]) & 15; |
582 | patch[0].SL = (dump[6] >> 4) & 15; | 582 | patch[0].SL = (dump[6] >> 4) & 15; |
583 | patch[1].SL = (dump[7] >> 4) & 15; | 583 | patch[1].SL = (dump[7] >> 4) & 15; |
584 | patch[0].RR = (dump[6]) & 15; | 584 | patch[0].RR = (dump[6]) & 15; |
585 | patch[1].RR = (dump[7]) & 15; | 585 | patch[1].RR = (dump[7]) & 15; |
586 | } | 586 | } |
587 | 587 | ||
588 | void | 588 | void |
589 | OPLL_getDefaultPatch (e_int32 type, e_int32 num, OPLL_PATCH * patch) | 589 | OPLL_getDefaultPatch (e_int32 type, e_int32 num, OPLL_PATCH * patch) |
590 | { | 590 | { |
591 | OPLL_dump2patch (default_inst[type] + num * 16, patch); | 591 | OPLL_dump2patch (default_inst[type] + num * 16, patch); |
592 | } | 592 | } |
593 | 593 | ||
594 | static void | 594 | static void |
595 | makeDefaultPatch ( void ) | 595 | makeDefaultPatch ( void ) |
596 | { | 596 | { |
597 | e_int32 i, j; | 597 | e_int32 i, j; |
598 | 598 | ||
599 | for (i = 0; i < OPLL_TONE_NUM; i++) | 599 | for (i = 0; i < OPLL_TONE_NUM; i++) |
600 | for (j = 0; j < 19; j++) | 600 | for (j = 0; j < 19; j++) |
601 | OPLL_getDefaultPatch (i, j, &default_patch[i][j * 2]); | 601 | OPLL_getDefaultPatch (i, j, &default_patch[i][j * 2]); |
602 | 602 | ||
603 | } | 603 | } |
604 | 604 | ||
605 | void | 605 | void |
606 | OPLL_setPatch (OPLL * opll, const e_uint8 * dump) | 606 | OPLL_setPatch (OPLL * opll, const e_uint8 * dump) |
607 | { | 607 | { |
608 | OPLL_PATCH patch[2]; | 608 | OPLL_PATCH patch[2]; |
609 | int i; | 609 | int i; |
610 | 610 | ||
611 | for (i = 0; i < 19; i++) | 611 | for (i = 0; i < 19; i++) |
612 | { | 612 | { |
613 | OPLL_dump2patch (dump + i * 16, patch); | 613 | OPLL_dump2patch (dump + i * 16, patch); |
614 | memcpy (&opll->patch[i*2+0], &patch[0], sizeof (OPLL_PATCH)); | 614 | memcpy (&opll->patch[i*2+0], &patch[0], sizeof (OPLL_PATCH)); |
615 | memcpy (&opll->patch[i*2+1], &patch[1], sizeof (OPLL_PATCH)); | 615 | memcpy (&opll->patch[i*2+1], &patch[1], sizeof (OPLL_PATCH)); |
616 | } | 616 | } |
617 | } | 617 | } |
618 | 618 | ||
619 | void | 619 | void |
620 | OPLL_patch2dump (const OPLL_PATCH * patch, e_uint8 * dump) | 620 | OPLL_patch2dump (const OPLL_PATCH * patch, e_uint8 * dump) |
621 | { | 621 | { |
622 | dump[0] = (e_uint8) ((patch[0].AM << 7) + (patch[0].PM << 6) + (patch[0].EG << 5) + (patch[0].KR << 4) + patch[0].ML); | 622 | dump[0] = (e_uint8) ((patch[0].AM << 7) + (patch[0].PM << 6) + (patch[0].EG << 5) + (patch[0].KR << 4) + patch[0].ML); |
623 | dump[1] = (e_uint8) ((patch[1].AM << 7) + (patch[1].PM << 6) + (patch[1].EG << 5) + (patch[1].KR << 4) + patch[1].ML); | 623 | dump[1] = (e_uint8) ((patch[1].AM << 7) + (patch[1].PM << 6) + (patch[1].EG << 5) + (patch[1].KR << 4) + patch[1].ML); |
624 | dump[2] = (e_uint8) ((patch[0].KL << 6) + patch[0].TL); | 624 | dump[2] = (e_uint8) ((patch[0].KL << 6) + patch[0].TL); |
625 | dump[3] = (e_uint8) ((patch[1].KL << 6) + (patch[1].WF << 4) + (patch[0].WF << 3) + patch[0].FB); | 625 | dump[3] = (e_uint8) ((patch[1].KL << 6) + (patch[1].WF << 4) + (patch[0].WF << 3) + patch[0].FB); |
626 | dump[4] = (e_uint8) ((patch[0].AR << 4) + patch[0].DR); | 626 | dump[4] = (e_uint8) ((patch[0].AR << 4) + patch[0].DR); |
627 | dump[5] = (e_uint8) ((patch[1].AR << 4) + patch[1].DR); | 627 | dump[5] = (e_uint8) ((patch[1].AR << 4) + patch[1].DR); |
628 | dump[6] = (e_uint8) ((patch[0].SL << 4) + patch[0].RR); | 628 | dump[6] = (e_uint8) ((patch[0].SL << 4) + patch[0].RR); |
629 | dump[7] = (e_uint8) ((patch[1].SL << 4) + patch[1].RR); | 629 | dump[7] = (e_uint8) ((patch[1].SL << 4) + patch[1].RR); |
630 | dump[8] = 0; | 630 | dump[8] = 0; |
631 | dump[9] = 0; | 631 | dump[9] = 0; |
632 | dump[10] = 0; | 632 | dump[10] = 0; |
633 | dump[11] = 0; | 633 | dump[11] = 0; |
634 | dump[12] = 0; | 634 | dump[12] = 0; |
635 | dump[13] = 0; | 635 | dump[13] = 0; |
636 | dump[14] = 0; | 636 | dump[14] = 0; |
637 | dump[15] = 0; | 637 | dump[15] = 0; |
638 | } | 638 | } |
639 | 639 | ||
640 | /************************************************************ | 640 | /************************************************************ |
641 | 641 | ||
642 | Calc Parameters | 642 | Calc Parameters |
643 | 643 | ||
644 | ************************************************************/ | 644 | ************************************************************/ |
645 | 645 | ||
646 | INLINE static e_uint32 | 646 | INLINE static e_uint32 |
647 | calc_eg_dphase (OPLL_SLOT * slot) | 647 | calc_eg_dphase (OPLL_SLOT * slot) |
648 | { | 648 | { |
649 | 649 | ||
650 | switch (slot->eg_mode) | 650 | switch (slot->eg_mode) |
651 | { | 651 | { |
652 | case ATTACK: | 652 | case ATTACK: |
653 | return dphaseARTable[slot->patch->AR][slot->rks]; | 653 | return dphaseARTable[slot->patch->AR][slot->rks]; |
654 | 654 | ||
655 | case DECAY: | 655 | case DECAY: |
656 | return dphaseDRTable[slot->patch->DR][slot->rks]; | 656 | return dphaseDRTable[slot->patch->DR][slot->rks]; |
657 | 657 | ||
658 | case SUSHOLD: | 658 | case SUSHOLD: |
659 | return 0; | 659 | return 0; |
660 | 660 | ||
661 | case SUSTINE: | 661 | case SUSTINE: |
662 | return dphaseDRTable[slot->patch->RR][slot->rks]; | 662 | return dphaseDRTable[slot->patch->RR][slot->rks]; |
663 | 663 | ||
664 | case RELEASE: | 664 | case RELEASE: |
665 | if (slot->sustine) | 665 | if (slot->sustine) |
666 | return dphaseDRTable[5][slot->rks]; | 666 | return dphaseDRTable[5][slot->rks]; |
667 | else if (slot->patch->EG) | 667 | else if (slot->patch->EG) |
668 | return dphaseDRTable[slot->patch->RR][slot->rks]; | 668 | return dphaseDRTable[slot->patch->RR][slot->rks]; |
669 | else | 669 | else |
670 | return dphaseDRTable[7][slot->rks]; | 670 | return dphaseDRTable[7][slot->rks]; |
671 | 671 | ||
672 | case SETTLE: | 672 | case SETTLE: |
673 | return dphaseDRTable[15][0]; | 673 | return dphaseDRTable[15][0]; |
674 | 674 | ||
675 | case FINISH: | 675 | case FINISH: |
676 | return 0; | 676 | return 0; |
677 | 677 | ||
678 | default: | 678 | default: |
679 | return 0; | 679 | return 0; |
680 | } | 680 | } |
681 | } | 681 | } |
682 | 682 | ||
683 | /************************************************************* | 683 | /************************************************************* |
684 | 684 | ||
685 | OPLL internal interfaces | 685 | OPLL internal interfaces |
686 | 686 | ||
687 | *************************************************************/ | 687 | *************************************************************/ |
688 | #define SLOT_BD1 12 | 688 | #define SLOT_BD1 12 |
689 | #define SLOT_BD2 13 | 689 | #define SLOT_BD2 13 |
690 | #define SLOT_HH 14 | 690 | #define SLOT_HH 14 |
691 | #define SLOT_SD 15 | 691 | #define SLOT_SD 15 |
692 | #define SLOT_TOM 16 | 692 | #define SLOT_TOM 16 |
693 | #define SLOT_CYM 17 | 693 | #define SLOT_CYM 17 |
694 | 694 | ||
695 | /* We will set this dinamically, but not sure if this affects playback */ | 695 | /* We will set this dinamically, but not sure if this affects playback */ |
696 | #if defined(ROCKBOX) | 696 | #if defined(ROCKBOX) |
697 | INLINE static void | 697 | INLINE static void |
698 | UPDATE_PG(OPLL_SLOT * slot) | 698 | UPDATE_PG(OPLL_SLOT * slot) |
699 | { | 699 | { |
700 | static const e_uint32 mltable[16] = | 700 | static const e_uint32 mltable[16] = |
701 | { 1, 1 * 2, 2 * 2, 3 * 2, 4 * 2, 5 * 2, 6 * 2, 7 * 2, 8 * 2, 9 * 2, 10 * 2, 10 * 2, 12 * 2, 12 * 2, 15 * 2, 15 * 2 }; | 701 | { 1, 1 * 2, 2 * 2, 3 * 2, 4 * 2, 5 * 2, 6 * 2, 7 * 2, 8 * 2, 9 * 2, 10 * 2, 10 * 2, 12 * 2, 12 * 2, 15 * 2, 15 * 2 }; |
702 | 702 | ||
703 | slot->dphase = RATE_ADJUST (((slot->fnum * mltable[slot->patch->ML]) << slot->block) >> (20 - DP_BITS)); | 703 | slot->dphase = RATE_ADJUST (((slot->fnum * mltable[slot->patch->ML]) << slot->block) >> (20 - DP_BITS)); |
704 | } | 704 | } |
705 | #else | 705 | #else |
706 | #define UPDATE_PG(S) (S)->dphase = dphaseTable[(S)->fnum][(S)->block][(S)->patch->ML] | 706 | #define UPDATE_PG(S) (S)->dphase = dphaseTable[(S)->fnum][(S)->block][(S)->patch->ML] |
707 | #endif | 707 | #endif |
708 | 708 | ||
709 | #define UPDATE_TLL(S)\ | 709 | #define UPDATE_TLL(S)\ |
710 | (((S)->type==0)?\ | 710 | (((S)->type==0)?\ |
711 | ((S)->tll = tllTable[((S)->fnum)>>5][(S)->block][(S)->patch->TL][(S)->patch->KL]):\ | 711 | ((S)->tll = tllTable[((S)->fnum)>>5][(S)->block][(S)->patch->TL][(S)->patch->KL]):\ |
712 | ((S)->tll = tllTable[((S)->fnum)>>5][(S)->block][(S)->volume][(S)->patch->KL])) | 712 | ((S)->tll = tllTable[((S)->fnum)>>5][(S)->block][(S)->volume][(S)->patch->KL])) |
713 | #define UPDATE_RKS(S) (S)->rks = rksTable[((S)->fnum)>>8][(S)->block][(S)->patch->KR] | 713 | #define UPDATE_RKS(S) (S)->rks = rksTable[((S)->fnum)>>8][(S)->block][(S)->patch->KR] |
714 | #define UPDATE_WF(S) (S)->sintbl = waveform[(S)->patch->WF] | 714 | #define UPDATE_WF(S) (S)->sintbl = waveform[(S)->patch->WF] |
715 | #define UPDATE_EG(S) (S)->eg_dphase = calc_eg_dphase(S) | 715 | #define UPDATE_EG(S) (S)->eg_dphase = calc_eg_dphase(S) |
716 | #define UPDATE_ALL(S)\ | 716 | #define UPDATE_ALL(S)\ |
717 | UPDATE_PG(S);\ | 717 | UPDATE_PG(S);\ |
718 | UPDATE_TLL(S);\ | 718 | UPDATE_TLL(S);\ |
719 | UPDATE_RKS(S);\ | 719 | UPDATE_RKS(S);\ |
720 | UPDATE_WF(S); \ | 720 | UPDATE_WF(S); \ |
721 | UPDATE_EG(S) /* EG should be updated last. */ | 721 | UPDATE_EG(S) /* EG should be updated last. */ |
722 | 722 | ||
723 | 723 | ||
724 | /* Slot key on */ | 724 | /* Slot key on */ |
725 | INLINE static void | 725 | INLINE static void |
726 | slotOn (OPLL_SLOT * slot) | 726 | slotOn (OPLL_SLOT * slot) |
727 | { | 727 | { |
728 | slot->eg_mode = ATTACK; | 728 | slot->eg_mode = ATTACK; |
729 | slot->eg_phase = 0; | 729 | slot->eg_phase = 0; |
730 | slot->phase = 0; | 730 | slot->phase = 0; |
731 | UPDATE_EG(slot); | 731 | UPDATE_EG(slot); |
732 | } | 732 | } |
733 | 733 | ||
734 | /* Slot key on without reseting the phase */ | 734 | /* Slot key on without reseting the phase */ |
735 | INLINE static void | 735 | INLINE static void |
736 | slotOn2 (OPLL_SLOT * slot) | 736 | slotOn2 (OPLL_SLOT * slot) |
737 | { | 737 | { |
738 | slot->eg_mode = ATTACK; | 738 | slot->eg_mode = ATTACK; |
739 | slot->eg_phase = 0; | 739 | slot->eg_phase = 0; |
740 | UPDATE_EG(slot); | 740 | UPDATE_EG(slot); |
741 | } | 741 | } |
742 | 742 | ||
743 | /* Slot key off */ | 743 | /* Slot key off */ |
744 | INLINE static void | 744 | INLINE static void |
745 | slotOff (OPLL_SLOT * slot) | 745 | slotOff (OPLL_SLOT * slot) |
746 | { | 746 | { |
747 | if (slot->eg_mode == ATTACK) | 747 | if (slot->eg_mode == ATTACK) |
748 | slot->eg_phase = EXPAND_BITS (AR_ADJUST_TABLE(HIGHBITS (slot->eg_phase, EG_DP_BITS - EG_BITS)), EG_BITS, EG_DP_BITS); | 748 | slot->eg_phase = EXPAND_BITS (AR_ADJUST_TABLE(HIGHBITS (slot->eg_phase, EG_DP_BITS - EG_BITS)), EG_BITS, EG_DP_BITS); |
749 | slot->eg_mode = RELEASE; | 749 | slot->eg_mode = RELEASE; |
750 | UPDATE_EG(slot); | 750 | UPDATE_EG(slot); |
751 | } | 751 | } |
752 | 752 | ||
753 | /* Channel key on */ | 753 | /* Channel key on */ |
754 | INLINE static void | 754 | INLINE static void |
755 | keyOn (OPLL * opll, e_int32 i) | 755 | keyOn (OPLL * opll, e_int32 i) |
756 | { | 756 | { |
757 | if (!opll->slot_on_flag[i * 2]) | 757 | if (!opll->slot_on_flag[i * 2]) |
758 | slotOn (MOD(opll,i)); | 758 | slotOn (MOD(opll,i)); |
759 | if (!opll->slot_on_flag[i * 2 + 1]) | 759 | if (!opll->slot_on_flag[i * 2 + 1]) |
760 | slotOn (CAR(opll,i)); | 760 | slotOn (CAR(opll,i)); |
761 | opll->key_status[i] = 1; | 761 | opll->key_status[i] = 1; |
762 | } | 762 | } |
763 | 763 | ||
764 | /* Channel key off */ | 764 | /* Channel key off */ |
765 | INLINE static void | 765 | INLINE static void |
766 | keyOff (OPLL * opll, e_int32 i) | 766 | keyOff (OPLL * opll, e_int32 i) |
767 | { | 767 | { |
768 | if (opll->slot_on_flag[i * 2 + 1]) | 768 | if (opll->slot_on_flag[i * 2 + 1]) |
769 | slotOff (CAR(opll,i)); | 769 | slotOff (CAR(opll,i)); |
770 | opll->key_status[i] = 0; | 770 | opll->key_status[i] = 0; |
771 | } | 771 | } |
772 | 772 | ||
773 | INLINE static void | 773 | INLINE static void |
774 | keyOn_BD (OPLL * opll) | 774 | keyOn_BD (OPLL * opll) |
775 | { | 775 | { |
776 | keyOn (opll, 6); | 776 | keyOn (opll, 6); |
777 | } | 777 | } |
778 | INLINE static void | 778 | INLINE static void |
779 | keyOn_SD (OPLL * opll) | 779 | keyOn_SD (OPLL * opll) |
780 | { | 780 | { |
781 | if (!opll->slot_on_flag[SLOT_SD]) | 781 | if (!opll->slot_on_flag[SLOT_SD]) |
782 | slotOn (CAR(opll,7)); | 782 | slotOn (CAR(opll,7)); |
783 | } | 783 | } |
784 | INLINE static void | 784 | INLINE static void |
785 | keyOn_TOM (OPLL * opll) | 785 | keyOn_TOM (OPLL * opll) |
786 | { | 786 | { |
787 | if (!opll->slot_on_flag[SLOT_TOM]) | 787 | if (!opll->slot_on_flag[SLOT_TOM]) |
788 | slotOn (MOD(opll,8)); | 788 | slotOn (MOD(opll,8)); |
789 | } | 789 | } |
790 | INLINE static void | 790 | INLINE static void |
791 | keyOn_HH (OPLL * opll) | 791 | keyOn_HH (OPLL * opll) |
792 | { | 792 | { |
793 | if (!opll->slot_on_flag[SLOT_HH]) | 793 | if (!opll->slot_on_flag[SLOT_HH]) |
794 | slotOn2 (MOD(opll,7)); | 794 | slotOn2 (MOD(opll,7)); |
795 | } | 795 | } |
796 | INLINE static void | 796 | INLINE static void |
797 | keyOn_CYM (OPLL * opll) | 797 | keyOn_CYM (OPLL * opll) |
798 | { | 798 | { |
799 | if (!opll->slot_on_flag[SLOT_CYM]) | 799 | if (!opll->slot_on_flag[SLOT_CYM]) |
800 | slotOn2 (CAR(opll,8)); | 800 | slotOn2 (CAR(opll,8)); |
801 | } | 801 | } |
802 | 802 | ||
803 | /* Drum key off */ | 803 | /* Drum key off */ |
804 | INLINE static void | 804 | INLINE static void |
805 | keyOff_BD (OPLL * opll) | 805 | keyOff_BD (OPLL * opll) |
806 | { | 806 | { |
807 | keyOff (opll, 6); | 807 | keyOff (opll, 6); |
808 | } | 808 | } |
809 | INLINE static void | 809 | INLINE static void |
810 | keyOff_SD (OPLL * opll) | 810 | keyOff_SD (OPLL * opll) |
811 | { | 811 | { |
812 | if (opll->slot_on_flag[SLOT_SD]) | 812 | if (opll->slot_on_flag[SLOT_SD]) |
813 | slotOff (CAR(opll,7)); | 813 | slotOff (CAR(opll,7)); |
814 | } | 814 | } |
815 | INLINE static void | 815 | INLINE static void |
816 | keyOff_TOM (OPLL * opll) | 816 | keyOff_TOM (OPLL * opll) |
817 | { | 817 | { |
818 | if (opll->slot_on_flag[SLOT_TOM]) | 818 | if (opll->slot_on_flag[SLOT_TOM]) |
819 | slotOff (MOD(opll,8)); | 819 | slotOff (MOD(opll,8)); |
820 | } | 820 | } |
821 | INLINE static void | 821 | INLINE static void |
822 | keyOff_HH (OPLL * opll) | 822 | keyOff_HH (OPLL * opll) |
823 | { | 823 | { |
824 | if (opll->slot_on_flag[SLOT_HH]) | 824 | if (opll->slot_on_flag[SLOT_HH]) |
825 | slotOff (MOD(opll,7)); | 825 | slotOff (MOD(opll,7)); |
826 | } | 826 | } |
827 | INLINE static void | 827 | INLINE static void |
828 | keyOff_CYM (OPLL * opll) | 828 | keyOff_CYM (OPLL * opll) |
829 | { | 829 | { |
830 | if (opll->slot_on_flag[SLOT_CYM]) | 830 | if (opll->slot_on_flag[SLOT_CYM]) |
831 | slotOff (CAR(opll,8)); | 831 | slotOff (CAR(opll,8)); |
832 | } | 832 | } |
833 | 833 | ||
834 | /* Change a voice */ | 834 | /* Change a voice */ |
835 | INLINE static void | 835 | INLINE static void |
836 | setPatch (OPLL * opll, e_int32 i, e_int32 num) | 836 | setPatch (OPLL * opll, e_int32 i, e_int32 num) |
837 | { | 837 | { |
838 | opll->patch_number[i] = num; | 838 | opll->patch_number[i] = num; |
839 | MOD(opll,i)->patch = &opll->patch[num * 2 + 0]; | 839 | MOD(opll,i)->patch = &opll->patch[num * 2 + 0]; |
840 | CAR(opll,i)->patch = &opll->patch[num * 2 + 1]; | 840 | CAR(opll,i)->patch = &opll->patch[num * 2 + 1]; |
841 | } | 841 | } |
842 | 842 | ||
843 | /* Change a rhythm voice */ | 843 | /* Change a rhythm voice */ |
844 | INLINE static void | 844 | INLINE static void |
845 | setSlotPatch (OPLL_SLOT * slot, OPLL_PATCH * patch) | 845 | setSlotPatch (OPLL_SLOT * slot, OPLL_PATCH * patch) |
846 | { | 846 | { |
847 | slot->patch = patch; | 847 | slot->patch = patch; |
848 | } | 848 | } |
849 | 849 | ||
850 | /* Set sustine parameter */ | 850 | /* Set sustine parameter */ |
851 | INLINE static void | 851 | INLINE static void |
852 | setSustine (OPLL * opll, e_int32 c, e_int32 sustine) | 852 | setSustine (OPLL * opll, e_int32 c, e_int32 sustine) |
853 | { | 853 | { |
854 | CAR(opll,c)->sustine = sustine; | 854 | CAR(opll,c)->sustine = sustine; |
855 | if (MOD(opll,c)->type) | 855 | if (MOD(opll,c)->type) |
856 | MOD(opll,c)->sustine = sustine; | 856 | MOD(opll,c)->sustine = sustine; |
857 | } | 857 | } |
858 | 858 | ||
859 | /* Volume : 6bit ( Volume register << 2 ) */ | 859 | /* Volume : 6bit ( Volume register << 2 ) */ |
860 | INLINE static void | 860 | INLINE static void |
861 | setVolume (OPLL * opll, e_int32 c, e_int32 volume) | 861 | setVolume (OPLL * opll, e_int32 c, e_int32 volume) |
862 | { | 862 | { |
863 | CAR(opll,c)->volume = volume; | 863 | CAR(opll,c)->volume = volume; |
864 | } | 864 | } |
865 | 865 | ||
866 | INLINE static void | 866 | INLINE static void |
867 | setSlotVolume (OPLL_SLOT * slot, e_int32 volume) | 867 | setSlotVolume (OPLL_SLOT * slot, e_int32 volume) |
868 | { | 868 | { |
869 | slot->volume = volume; | 869 | slot->volume = volume; |
870 | } | 870 | } |
871 | 871 | ||
872 | /* Set F-Number ( fnum : 9bit ) */ | 872 | /* Set F-Number ( fnum : 9bit ) */ |
873 | INLINE static void | 873 | INLINE static void |
874 | setFnumber (OPLL * opll, e_int32 c, e_int32 fnum) | 874 | setFnumber (OPLL * opll, e_int32 c, e_int32 fnum) |
875 | { | 875 | { |
876 | CAR(opll,c)->fnum = fnum; | 876 | CAR(opll,c)->fnum = fnum; |
877 | MOD(opll,c)->fnum = fnum; | 877 | MOD(opll,c)->fnum = fnum; |
878 | } | 878 | } |
879 | 879 | ||
880 | /* Set Block data (block : 3bit ) */ | 880 | /* Set Block data (block : 3bit ) */ |
881 | INLINE static void | 881 | INLINE static void |
882 | setBlock (OPLL * opll, e_int32 c, e_int32 block) | 882 | setBlock (OPLL * opll, e_int32 c, e_int32 block) |
883 | { | 883 | { |
884 | CAR(opll,c)->block = block; | 884 | CAR(opll,c)->block = block; |
885 | MOD(opll,c)->block = block; | 885 | MOD(opll,c)->block = block; |
886 | } | 886 | } |
887 | 887 | ||
888 | /* Change Rhythm Mode */ | 888 | /* Change Rhythm Mode */ |
889 | INLINE static void | 889 | INLINE static void |
890 | update_rhythm_mode (OPLL * opll) | 890 | update_rhythm_mode (OPLL * opll) |
891 | { | 891 | { |
892 | if (opll->patch_number[6] & 0x10) | 892 | if (opll->patch_number[6] & 0x10) |
893 | { | 893 | { |
894 | if (!(opll->slot_on_flag[SLOT_BD2] | (opll->reg[0x0e] & 32))) | 894 | if (!(opll->slot_on_flag[SLOT_BD2] | (opll->reg[0x0e] & 32))) |
895 | { | 895 | { |
896 | opll->slot[SLOT_BD1].eg_mode = FINISH; | 896 | opll->slot[SLOT_BD1].eg_mode = FINISH; |
897 | opll->slot[SLOT_BD2].eg_mode = FINISH; | 897 | opll->slot[SLOT_BD2].eg_mode = FINISH; |
898 | setPatch (opll, 6, opll->reg[0x36] >> 4); | 898 | setPatch (opll, 6, opll->reg[0x36] >> 4); |
899 | } | 899 | } |
900 | } | 900 | } |
901 | else if (opll->reg[0x0e] & 32) | 901 | else if (opll->reg[0x0e] & 32) |
902 | { | 902 | { |
903 | opll->patch_number[6] = 16; | 903 | opll->patch_number[6] = 16; |
904 | opll->slot[SLOT_BD1].eg_mode = FINISH; | 904 | opll->slot[SLOT_BD1].eg_mode = FINISH; |
905 | opll->slot[SLOT_BD2].eg_mode = FINISH; | 905 | opll->slot[SLOT_BD2].eg_mode = FINISH; |
906 | setSlotPatch (&opll->slot[SLOT_BD1], &opll->patch[16 * 2 + 0]); | 906 | setSlotPatch (&opll->slot[SLOT_BD1], &opll->patch[16 * 2 + 0]); |
907 | setSlotPatch (&opll->slot[SLOT_BD2], &opll->patch[16 * 2 + 1]); | 907 | setSlotPatch (&opll->slot[SLOT_BD2], &opll->patch[16 * 2 + 1]); |
908 | } | 908 | } |
909 | 909 | ||
910 | if (opll->patch_number[7] & 0x10) | 910 | if (opll->patch_number[7] & 0x10) |
911 | { | 911 | { |
912 | if (!((opll->slot_on_flag[SLOT_HH] && opll->slot_on_flag[SLOT_SD]) | (opll->reg[0x0e] & 32))) | 912 | if (!((opll->slot_on_flag[SLOT_HH] && opll->slot_on_flag[SLOT_SD]) | (opll->reg[0x0e] & 32))) |
913 | { | 913 | { |
914 | opll->slot[SLOT_HH].type = 0; | 914 | opll->slot[SLOT_HH].type = 0; |
915 | opll->slot[SLOT_HH].eg_mode = FINISH; | 915 | opll->slot[SLOT_HH].eg_mode = FINISH; |
916 | opll->slot[SLOT_SD].eg_mode = FINISH; | 916 | opll->slot[SLOT_SD].eg_mode = FINISH; |
917 | setPatch (opll, 7, opll->reg[0x37] >> 4); | 917 | setPatch (opll, 7, opll->reg[0x37] >> 4); |
918 | } | 918 | } |
919 | } | 919 | } |
920 | else if (opll->reg[0x0e] & 32) | 920 | else if (opll->reg[0x0e] & 32) |
921 | { | 921 | { |
922 | opll->patch_number[7] = 17; | 922 | opll->patch_number[7] = 17; |
923 | opll->slot[SLOT_HH].type = 1; | 923 | opll->slot[SLOT_HH].type = 1; |
924 | opll->slot[SLOT_HH].eg_mode = FINISH; | 924 | opll->slot[SLOT_HH].eg_mode = FINISH; |
925 | opll->slot[SLOT_SD].eg_mode = FINISH; | 925 | opll->slot[SLOT_SD].eg_mode = FINISH; |
926 | setSlotPatch (&opll->slot[SLOT_HH], &opll->patch[17 * 2 + 0]); | 926 | setSlotPatch (&opll->slot[SLOT_HH], &opll->patch[17 * 2 + 0]); |
927 | setSlotPatch (&opll->slot[SLOT_SD], &opll->patch[17 * 2 + 1]); | 927 | setSlotPatch (&opll->slot[SLOT_SD], &opll->patch[17 * 2 + 1]); |
928 | } | 928 | } |
929 | 929 | ||
930 | if (opll->patch_number[8] & 0x10) | 930 | if (opll->patch_number[8] & 0x10) |
931 | { | 931 | { |
932 | if (!((opll->slot_on_flag[SLOT_CYM] && opll->slot_on_flag[SLOT_TOM]) | (opll->reg[0x0e] & 32))) | 932 | if (!((opll->slot_on_flag[SLOT_CYM] && opll->slot_on_flag[SLOT_TOM]) | (opll->reg[0x0e] & 32))) |
933 | { | 933 | { |
934 | opll->slot[SLOT_TOM].type = 0; | 934 | opll->slot[SLOT_TOM].type = 0; |
935 | opll->slot[SLOT_TOM].eg_mode = FINISH; | 935 | opll->slot[SLOT_TOM].eg_mode = FINISH; |
936 | opll->slot[SLOT_CYM].eg_mode = FINISH; | 936 | opll->slot[SLOT_CYM].eg_mode = FINISH; |
937 | setPatch (opll, 8, opll->reg[0x38] >> 4); | 937 | setPatch (opll, 8, opll->reg[0x38] >> 4); |
938 | } | 938 | } |
939 | } | 939 | } |
940 | else if (opll->reg[0x0e] & 32) | 940 | else if (opll->reg[0x0e] & 32) |
941 | { | 941 | { |
942 | opll->patch_number[8] = 18; | 942 | opll->patch_number[8] = 18; |
943 | opll->slot[SLOT_TOM].type = 1; | 943 | opll->slot[SLOT_TOM].type = 1; |
944 | opll->slot[SLOT_TOM].eg_mode = FINISH; | 944 | opll->slot[SLOT_TOM].eg_mode = FINISH; |
945 | opll->slot[SLOT_CYM].eg_mode = FINISH; | 945 | opll->slot[SLOT_CYM].eg_mode = FINISH; |
946 | setSlotPatch (&opll->slot[SLOT_TOM], &opll->patch[18 * 2 + 0]); | 946 | setSlotPatch (&opll->slot[SLOT_TOM], &opll->patch[18 * 2 + 0]); |
947 | setSlotPatch (&opll->slot[SLOT_CYM], &opll->patch[18 * 2 + 1]); | 947 | setSlotPatch (&opll->slot[SLOT_CYM], &opll->patch[18 * 2 + 1]); |
948 | } | 948 | } |
949 | } | 949 | } |
950 | 950 | ||
951 | INLINE static void | 951 | INLINE static void |
952 | update_key_status (OPLL * opll) | 952 | update_key_status (OPLL * opll) |
953 | { | 953 | { |
954 | int ch; | 954 | int ch; |
955 | 955 | ||
956 | for (ch = 0; ch < 9; ch++) | 956 | for (ch = 0; ch < 9; ch++) |
957 | opll->slot_on_flag[ch * 2] = opll->slot_on_flag[ch * 2 + 1] = (opll->reg[0x20 + ch]) & 0x10; | 957 | opll->slot_on_flag[ch * 2] = opll->slot_on_flag[ch * 2 + 1] = (opll->reg[0x20 + ch]) & 0x10; |
958 | 958 | ||
959 | if (opll->reg[0x0e] & 32) | 959 | if (opll->reg[0x0e] & 32) |
960 | { | 960 | { |
961 | opll->slot_on_flag[SLOT_BD1] |= (opll->reg[0x0e] & 0x10); | 961 | opll->slot_on_flag[SLOT_BD1] |= (opll->reg[0x0e] & 0x10); |
962 | opll->slot_on_flag[SLOT_BD2] |= (opll->reg[0x0e] & 0x10); | 962 | opll->slot_on_flag[SLOT_BD2] |= (opll->reg[0x0e] & 0x10); |
963 | opll->slot_on_flag[SLOT_SD] |= (opll->reg[0x0e] & 0x08); | 963 | opll->slot_on_flag[SLOT_SD] |= (opll->reg[0x0e] & 0x08); |
964 | opll->slot_on_flag[SLOT_HH] |= (opll->reg[0x0e] & 0x01); | 964 | opll->slot_on_flag[SLOT_HH] |= (opll->reg[0x0e] & 0x01); |
965 | opll->slot_on_flag[SLOT_TOM] |= (opll->reg[0x0e] & 0x04); | 965 | opll->slot_on_flag[SLOT_TOM] |= (opll->reg[0x0e] & 0x04); |
966 | opll->slot_on_flag[SLOT_CYM] |= (opll->reg[0x0e] & 0x02); | 966 | opll->slot_on_flag[SLOT_CYM] |= (opll->reg[0x0e] & 0x02); |
967 | } | 967 | } |
968 | } | 968 | } |
969 | 969 | ||
970 | void | 970 | void |
971 | OPLL_copyPatch (OPLL * opll, e_int32 num, OPLL_PATCH * patch) | 971 | OPLL_copyPatch (OPLL * opll, e_int32 num, OPLL_PATCH * patch) |
972 | { | 972 | { |
973 | memcpy (&opll->patch[num], patch, sizeof (OPLL_PATCH)); | 973 | memcpy (&opll->patch[num], patch, sizeof (OPLL_PATCH)); |
974 | } | 974 | } |
975 | 975 | ||
976 | /*********************************************************** | 976 | /*********************************************************** |
977 | 977 | ||
978 | Initializing | 978 | Initializing |
979 | 979 | ||
980 | ***********************************************************/ | 980 | ***********************************************************/ |
981 | 981 | ||
982 | static void | 982 | static void |
983 | OPLL_SLOT_reset (OPLL_SLOT * slot, int type) | 983 | OPLL_SLOT_reset (OPLL_SLOT * slot, int type) |
984 | { | 984 | { |
985 | slot->type = type; | 985 | slot->type = type; |
986 | slot->sintbl = waveform[0]; | 986 | slot->sintbl = waveform[0]; |
987 | slot->phase = 0; | 987 | slot->phase = 0; |
988 | slot->dphase = 0; | 988 | slot->dphase = 0; |
989 | slot->output[0] = 0; | 989 | slot->output[0] = 0; |
990 | slot->output[1] = 0; | 990 | slot->output[1] = 0; |
991 | slot->feedback = 0; | 991 | slot->feedback = 0; |
992 | slot->eg_mode = FINISH; | 992 | slot->eg_mode = FINISH; |
993 | slot->eg_phase = EG_DP_WIDTH; | 993 | slot->eg_phase = EG_DP_WIDTH; |
994 | slot->eg_dphase = 0; | 994 | slot->eg_dphase = 0; |
995 | slot->rks = 0; | 995 | slot->rks = 0; |
996 | slot->tll = 0; | 996 | slot->tll = 0; |
997 | slot->sustine = 0; | 997 | slot->sustine = 0; |
998 | slot->fnum = 0; | 998 | slot->fnum = 0; |
999 | slot->block = 0; | 999 | slot->block = 0; |
1000 | slot->volume = 0; | 1000 | slot->volume = 0; |
1001 | slot->pgout = 0; | 1001 | slot->pgout = 0; |
1002 | slot->egout = 0; | 1002 | slot->egout = 0; |
1003 | slot->patch = &null_patch; | 1003 | slot->patch = &null_patch; |
1004 | } | 1004 | } |
1005 | 1005 | ||
1006 | static void | 1006 | static void |
1007 | internal_refresh (void) | 1007 | internal_refresh (void) |
1008 | { | 1008 | { |
1009 | #if !defined(ROCKBOX) | 1009 | #if !defined(ROCKBOX) |
1010 | makeDphaseTable (); | 1010 | makeDphaseTable (); |
1011 | #endif | 1011 | #endif |
1012 | makeDphaseARTable (); | 1012 | makeDphaseARTable (); |
1013 | makeDphaseDRTable (); | 1013 | makeDphaseDRTable (); |
1014 | pm_dphase = (e_uint32) RATE_ADJUST ((int)(PM_SPEED * PM_DP_WIDTH) / (clk / 72)); | 1014 | pm_dphase = (e_uint32) RATE_ADJUST ((int)(PM_SPEED * PM_DP_WIDTH) / (clk / 72)); |
1015 | am_dphase = (e_uint32) RATE_ADJUST ((int)(AM_SPEED * AM_DP_WIDTH) / (clk / 72)); | 1015 | am_dphase = (e_uint32) RATE_ADJUST ((int)(AM_SPEED * AM_DP_WIDTH) / (clk / 72)); |
1016 | } | 1016 | } |
1017 | 1017 | ||
1018 | static void | 1018 | static void |
1019 | maketables (e_uint32 c, e_uint32 r) | 1019 | maketables (e_uint32 c, e_uint32 r) |
1020 | { | 1020 | { |
1021 | if (c != clk) | 1021 | if (c != clk) |
1022 | { | 1022 | { |
1023 | clk = c; | 1023 | clk = c; |
1024 | #ifdef EMU2413_CALCUL_TABLES | 1024 | #ifdef EMU2413_CALCUL_TABLES |
1025 | makePmTable (); | 1025 | makePmTable (); |
1026 | makeAmTable (); | 1026 | makeAmTable (); |
1027 | makeAdjustTable (); | 1027 | makeAdjustTable (); |
1028 | #endif | 1028 | #endif |
1029 | makeDB2LinTable (); | 1029 | makeDB2LinTable (); |
1030 | makeTllTable (); | 1030 | makeTllTable (); |
1031 | makeRksTable (); | 1031 | makeRksTable (); |
1032 | makeSinTable (); | 1032 | makeSinTable (); |
1033 | makeDefaultPatch (); | 1033 | makeDefaultPatch (); |
1034 | } | 1034 | } |
1035 | 1035 | ||
1036 | if (r != rate) | 1036 | if (r != rate) |
1037 | { | 1037 | { |
1038 | rate = r; | 1038 | rate = r; |
1039 | internal_refresh (); | 1039 | internal_refresh (); |
1040 | } | 1040 | } |
1041 | } | 1041 | } |
1042 | 1042 | ||
1043 | void | 1043 | void |
1044 | OPLL_new (OPLL *opll, e_uint32 clk, e_uint32 rate) | 1044 | OPLL_new (OPLL *opll, e_uint32 clk, e_uint32 rate) |
1045 | { | 1045 | { |
1046 | e_int32 i; | 1046 | e_int32 i; |
1047 | 1047 | ||
1048 | maketables (clk, rate); | 1048 | maketables (clk, rate); |
1049 | 1049 | ||
1050 | memset(opll, 0, sizeof (OPLL)); | 1050 | memset(opll, 0, sizeof (OPLL)); |
1051 | for (i = 0; i < 19 * 2; i++) | 1051 | for (i = 0; i < 19 * 2; i++) |
1052 | memcpy(&opll->patch[i],&null_patch,sizeof(OPLL_PATCH)); | 1052 | memcpy(&opll->patch[i],&null_patch,sizeof(OPLL_PATCH)); |
1053 | 1053 | ||
1054 | opll->mask = 0; | 1054 | opll->mask = 0; |
1055 | 1055 | ||
1056 | OPLL_reset (opll); | 1056 | OPLL_reset (opll); |
1057 | OPLL_reset_patch (opll, 0); | 1057 | OPLL_reset_patch (opll, 0); |
1058 | } | 1058 | } |
1059 | 1059 | ||
1060 | 1060 | ||
1061 | void | 1061 | void |
1062 | OPLL_delete (OPLL * opll) | 1062 | OPLL_delete (OPLL * opll) |
1063 | { | 1063 | { |
1064 | (void) opll; | 1064 | (void) opll; |
1065 | } | 1065 | } |
1066 | 1066 | ||
1067 | 1067 | ||
1068 | /* Reset patch datas by system default. */ | 1068 | /* Reset patch datas by system default. */ |
1069 | void | 1069 | void |
1070 | OPLL_reset_patch (OPLL * opll, e_int32 type) | 1070 | OPLL_reset_patch (OPLL * opll, e_int32 type) |
1071 | { | 1071 | { |
1072 | e_int32 i; | 1072 | e_int32 i; |
1073 | 1073 | ||
1074 | for (i = 0; i < 19 * 2; i++) | 1074 | for (i = 0; i < 19 * 2; i++) |
1075 | OPLL_copyPatch (opll, i, &default_patch[type % OPLL_TONE_NUM][i]); | 1075 | OPLL_copyPatch (opll, i, &default_patch[type % OPLL_TONE_NUM][i]); |
1076 | } | 1076 | } |
1077 | 1077 | ||
1078 | /* Reset whole of OPLL except patch datas. */ | 1078 | /* Reset whole of OPLL except patch datas. */ |
1079 | void | 1079 | void |
1080 | OPLL_reset (OPLL * opll) | 1080 | OPLL_reset (OPLL * opll) |
1081 | { | 1081 | { |
1082 | e_int32 i; | 1082 | e_int32 i; |
1083 | 1083 | ||
1084 | if (!opll) | 1084 | if (!opll) |
1085 | return; | 1085 | return; |
1086 | 1086 | ||
1087 | opll->adr = 0; | 1087 | opll->adr = 0; |
1088 | opll->out = 0; | 1088 | opll->out = 0; |
1089 | 1089 | ||
1090 | opll->pm_phase = 0; | 1090 | opll->pm_phase = 0; |
1091 | opll->am_phase = 0; | 1091 | opll->am_phase = 0; |
1092 | 1092 | ||
1093 | opll->noise_seed = 0xffff; | 1093 | opll->noise_seed = 0xffff; |
1094 | opll->mask = 0; | 1094 | opll->mask = 0; |
1095 | 1095 | ||
1096 | for (i = 0; i <18; i++) | 1096 | for (i = 0; i <18; i++) |
1097 | OPLL_SLOT_reset(&opll->slot[i], i%2); | 1097 | OPLL_SLOT_reset(&opll->slot[i], i%2); |
1098 | 1098 | ||
1099 | for (i = 0; i < 9; i++) | 1099 | for (i = 0; i < 9; i++) |
1100 | { | 1100 | { |
1101 | opll->key_status[i] = 0; | 1101 | opll->key_status[i] = 0; |
1102 | setPatch (opll, i, 0); | 1102 | setPatch (opll, i, 0); |
1103 | } | 1103 | } |
1104 | 1104 | ||
1105 | for (i = 0; i < 0x40; i++) | 1105 | for (i = 0; i < 0x40; i++) |
1106 | OPLL_writeReg (opll, i, 0); | 1106 | OPLL_writeReg (opll, i, 0); |
1107 | 1107 | ||
1108 | #ifndef EMU2413_COMPACTION | 1108 | #ifndef EMU2413_COMPACTION |
1109 | opll->realstep = (e_uint32) ((1 << 31) / rate); | 1109 | opll->realstep = (e_uint32) ((1 << 31) / rate); |
1110 | opll->opllstep = (e_uint32) ((1 << 31) / (clk / 72)); | 1110 | opll->opllstep = (e_uint32) ((1 << 31) / (clk / 72)); |
1111 | opll->oplltime = 0; | 1111 | opll->oplltime = 0; |
1112 | for (i = 0; i < 14; i++) | 1112 | for (i = 0; i < 14; i++) |
1113 | opll->pan[i] = 2; | 1113 | opll->pan[i] = 2; |
1114 | opll->sprev[0] = opll->sprev[1] = 0; | 1114 | opll->sprev[0] = opll->sprev[1] = 0; |
1115 | opll->snext[0] = opll->snext[1] = 0; | 1115 | opll->snext[0] = opll->snext[1] = 0; |
1116 | #endif | 1116 | #endif |
1117 | } | 1117 | } |
1118 | 1118 | ||
1119 | /* Force Refresh (When external program changes some parameters). */ | 1119 | /* Force Refresh (When external program changes some parameters). */ |
1120 | void | 1120 | void |
1121 | OPLL_forceRefresh (OPLL * opll) | 1121 | OPLL_forceRefresh (OPLL * opll) |
1122 | { | 1122 | { |
1123 | e_int32 i; | 1123 | e_int32 i; |
1124 | 1124 | ||
1125 | if (opll == NULL) | 1125 | if (opll == NULL) |
1126 | return; | 1126 | return; |
1127 | 1127 | ||
1128 | for (i = 0; i < 9; i++) | 1128 | for (i = 0; i < 9; i++) |
1129 | setPatch(opll,i,opll->patch_number[i]); | 1129 | setPatch(opll,i,opll->patch_number[i]); |
1130 | 1130 | ||
1131 | for (i = 0; i < 18; i++) | 1131 | for (i = 0; i < 18; i++) |
1132 | { | 1132 | { |
1133 | UPDATE_PG (&opll->slot[i]); | 1133 | UPDATE_PG (&opll->slot[i]); |
1134 | UPDATE_RKS (&opll->slot[i]); | 1134 | UPDATE_RKS (&opll->slot[i]); |
1135 | UPDATE_TLL (&opll->slot[i]); | 1135 | UPDATE_TLL (&opll->slot[i]); |
1136 | UPDATE_WF (&opll->slot[i]); | 1136 | UPDATE_WF (&opll->slot[i]); |
1137 | UPDATE_EG (&opll->slot[i]); | 1137 | UPDATE_EG (&opll->slot[i]); |
1138 | } | 1138 | } |
1139 | } | 1139 | } |
1140 | 1140 | ||
1141 | void | 1141 | void |
1142 | OPLL_set_rate (OPLL * opll, e_uint32 r) | 1142 | OPLL_set_rate (OPLL * opll, e_uint32 r) |
1143 | { | 1143 | { |
1144 | if (rate == r) return; | 1144 | if (rate == r) return; |
1145 | if (opll->quality) | 1145 | if (opll->quality) |
1146 | rate = 49716; | 1146 | rate = 49716; |
1147 | else | 1147 | else |
1148 | rate = r; | 1148 | rate = r; |
1149 | internal_refresh (); | 1149 | internal_refresh (); |
1150 | rate = r; | 1150 | rate = r; |
1151 | } | 1151 | } |
1152 | 1152 | ||
1153 | void | 1153 | void |
1154 | OPLL_set_quality (OPLL * opll, e_uint32 q) | 1154 | OPLL_set_quality (OPLL * opll, e_uint32 q) |
1155 | { | 1155 | { |
1156 | opll->quality = q; | 1156 | opll->quality = q; |
1157 | OPLL_set_rate (opll, rate); | 1157 | OPLL_set_rate (opll, rate); |
1158 | } | 1158 | } |
1159 | 1159 | ||
1160 | /********************************************************* | 1160 | /********************************************************* |
1161 | 1161 | ||
1162 | Generate wave data | 1162 | Generate wave data |
1163 | 1163 | ||
1164 | *********************************************************/ | 1164 | *********************************************************/ |
1165 | /* Convert Amp(0 to EG_HEIGHT) to Phase(0 to 2PI). */ | 1165 | /* Convert Amp(0 to EG_HEIGHT) to Phase(0 to 2PI). */ |
1166 | #if ( SLOT_AMP_BITS - PG_BITS ) > 0 | 1166 | #if ( SLOT_AMP_BITS - PG_BITS ) > 0 |
1167 | #define wave2_2pi(e) ( (e) >> ( SLOT_AMP_BITS - PG_BITS )) | 1167 | #define wave2_2pi(e) ( (e) >> ( SLOT_AMP_BITS - PG_BITS )) |
1168 | #else | 1168 | #else |
1169 | #define wave2_2pi(e) ( (e) << ( PG_BITS - SLOT_AMP_BITS )) | 1169 | #define wave2_2pi(e) ( (e) << ( PG_BITS - SLOT_AMP_BITS )) |
1170 | #endif | 1170 | #endif |
1171 | 1171 | ||
1172 | /* Convert Amp(0 to EG_HEIGHT) to Phase(0 to 4PI). */ | 1172 | /* Convert Amp(0 to EG_HEIGHT) to Phase(0 to 4PI). */ |
1173 | #if ( SLOT_AMP_BITS - PG_BITS - 1 ) == 0 | 1173 | #if ( SLOT_AMP_BITS - PG_BITS - 1 ) == 0 |
1174 | #define wave2_4pi(e) (e) | 1174 | #define wave2_4pi(e) (e) |
1175 | #elif ( SLOT_AMP_BITS - PG_BITS - 1 ) > 0 | 1175 | #elif ( SLOT_AMP_BITS - PG_BITS - 1 ) > 0 |
1176 | #define wave2_4pi(e) ( (e) >> ( SLOT_AMP_BITS - PG_BITS - 1 )) | 1176 | #define wave2_4pi(e) ( (e) >> ( SLOT_AMP_BITS - PG_BITS - 1 )) |
1177 | #else | 1177 | #else |
1178 | #define wave2_4pi(e) ( (e) << ( 1 + PG_BITS - SLOT_AMP_BITS )) | 1178 | #define wave2_4pi(e) ( (e) << ( 1 + PG_BITS - SLOT_AMP_BITS )) |
1179 | #endif | 1179 | #endif |
1180 | 1180 | ||
1181 | /* Convert Amp(0 to EG_HEIGHT) to Phase(0 to 8PI). */ | 1181 | /* Convert Amp(0 to EG_HEIGHT) to Phase(0 to 8PI). */ |
1182 | #if ( SLOT_AMP_BITS - PG_BITS - 2 ) == 0 | 1182 | #if ( SLOT_AMP_BITS - PG_BITS - 2 ) == 0 |
1183 | #define wave2_8pi(e) (e) | 1183 | #define wave2_8pi(e) (e) |
1184 | #elif ( SLOT_AMP_BITS - PG_BITS - 2 ) > 0 | 1184 | #elif ( SLOT_AMP_BITS - PG_BITS - 2 ) > 0 |
1185 | #define wave2_8pi(e) ( (e) >> ( SLOT_AMP_BITS - PG_BITS - 2 )) | 1185 | #define wave2_8pi(e) ( (e) >> ( SLOT_AMP_BITS - PG_BITS - 2 )) |
1186 | #else | 1186 | #else |
1187 | #define wave2_8pi(e) ( (e) << ( 2 + PG_BITS - SLOT_AMP_BITS )) | 1187 | #define wave2_8pi(e) ( (e) << ( 2 + PG_BITS - SLOT_AMP_BITS )) |
1188 | #endif | 1188 | #endif |
1189 | 1189 | ||
1190 | /* Update AM, PM unit */ | 1190 | /* Update AM, PM unit */ |
1191 | INLINE static void | 1191 | INLINE static void |
1192 | update_ampm (OPLL * opll) | 1192 | update_ampm (OPLL * opll) |
1193 | { | 1193 | { |
1194 | opll->pm_phase = (opll->pm_phase + pm_dphase) & (PM_DP_WIDTH - 1); | 1194 | opll->pm_phase = (opll->pm_phase + pm_dphase) & (PM_DP_WIDTH - 1); |
1195 | opll->am_phase = (opll->am_phase + am_dphase) & (AM_DP_WIDTH - 1); | 1195 | opll->am_phase = (opll->am_phase + am_dphase) & (AM_DP_WIDTH - 1); |
1196 | opll->lfo_am = AMTABLE(HIGHBITS (opll->am_phase, AM_DP_BITS - AM_PG_BITS)); | 1196 | opll->lfo_am = AMTABLE(HIGHBITS (opll->am_phase, AM_DP_BITS - AM_PG_BITS)); |
1197 | opll->lfo_pm = PMTABLE(HIGHBITS (opll->pm_phase, PM_DP_BITS - PM_PG_BITS)); | 1197 | opll->lfo_pm = PMTABLE(HIGHBITS (opll->pm_phase, PM_DP_BITS - PM_PG_BITS)); |
1198 | } | 1198 | } |
1199 | 1199 | ||
1200 | /* PG */ | 1200 | /* PG */ |
1201 | INLINE static void | 1201 | INLINE static void |
1202 | calc_phase (OPLL_SLOT * slot, e_int32 lfo) | 1202 | calc_phase (OPLL_SLOT * slot, e_int32 lfo) |
1203 | { | 1203 | { |
1204 | if (slot->patch->PM) | 1204 | if (slot->patch->PM) |
1205 | slot->phase += (slot->dphase * lfo) >> PM_AMP_BITS; | 1205 | slot->phase += (slot->dphase * lfo) >> PM_AMP_BITS; |
1206 | else | 1206 | else |
1207 | slot->phase += slot->dphase; | 1207 | slot->phase += slot->dphase; |
1208 | 1208 | ||
1209 | slot->phase &= (DP_WIDTH - 1); | 1209 | slot->phase &= (DP_WIDTH - 1); |
1210 | 1210 | ||
1211 | slot->pgout = HIGHBITS (slot->phase, DP_BASE_BITS); | 1211 | slot->pgout = HIGHBITS (slot->phase, DP_BASE_BITS); |
1212 | } | 1212 | } |
1213 | 1213 | ||
1214 | /* Update Noise unit */ | 1214 | /* Update Noise unit */ |
1215 | INLINE static void | 1215 | INLINE static void |
1216 | update_noise (OPLL * opll) | 1216 | update_noise (OPLL * opll) |
1217 | { | 1217 | { |
1218 | if(opll->noise_seed&1) opll->noise_seed ^= 0x8003020; | 1218 | if(opll->noise_seed&1) opll->noise_seed ^= 0x8003020; |
1219 | opll->noise_seed >>= 1; | 1219 | opll->noise_seed >>= 1; |
1220 | } | 1220 | } |
1221 | 1221 | ||
1222 | /* EG */ | 1222 | /* EG */ |
1223 | INLINE static void | 1223 | INLINE static void |
1224 | calc_envelope (OPLL_SLOT * slot, e_int32 lfo) | 1224 | calc_envelope (OPLL_SLOT * slot, e_int32 lfo) |
1225 | { | 1225 | { |
1226 | #define S2E(x) (SL2EG((e_int32)(x/SL_STEP))<<(EG_DP_BITS-EG_BITS)) | 1226 | #define S2E(x) (SL2EG((e_int32)(x/SL_STEP))<<(EG_DP_BITS-EG_BITS)) |
1227 | 1227 | ||
1228 | static e_uint32 SL[16] = { | 1228 | static e_uint32 SL[16] = { |
1229 | S2E (0.0), S2E (3.0), S2E (6.0), S2E (9.0), S2E (12.0), S2E (15.0), S2E (18.0), S2E (21.0), | 1229 | S2E (0.0), S2E (3.0), S2E (6.0), S2E (9.0), S2E (12.0), S2E (15.0), S2E (18.0), S2E (21.0), |
1230 | S2E (24.0), S2E (27.0), S2E (30.0), S2E (33.0), S2E (36.0), S2E (39.0), S2E (42.0), S2E (48.0) | 1230 | S2E (24.0), S2E (27.0), S2E (30.0), S2E (33.0), S2E (36.0), S2E (39.0), S2E (42.0), S2E (48.0) |
1231 | }; | 1231 | }; |
1232 | 1232 | ||
1233 | e_uint32 egout; | 1233 | e_uint32 egout; |
1234 | 1234 | ||
1235 | switch (slot->eg_mode) | 1235 | switch (slot->eg_mode) |
1236 | { | 1236 | { |
1237 | case ATTACK: | 1237 | case ATTACK: |
1238 | egout = AR_ADJUST_TABLE(HIGHBITS (slot->eg_phase, EG_DP_BITS - EG_BITS)); | 1238 | egout = AR_ADJUST_TABLE(HIGHBITS (slot->eg_phase, EG_DP_BITS - EG_BITS)); |
1239 | slot->eg_phase += slot->eg_dphase; | 1239 | slot->eg_phase += slot->eg_dphase; |
1240 | if((EG_DP_WIDTH & slot->eg_phase)||(slot->patch->AR==15)) | 1240 | if((EG_DP_WIDTH & slot->eg_phase)||(slot->patch->AR==15)) |
1241 | { | 1241 | { |
1242 | egout = 0; | 1242 | egout = 0; |
1243 | slot->eg_phase = 0; | 1243 | slot->eg_phase = 0; |
1244 | slot->eg_mode = DECAY; | 1244 | slot->eg_mode = DECAY; |
1245 | UPDATE_EG (slot); | 1245 | UPDATE_EG (slot); |
1246 | } | 1246 | } |
1247 | break; | 1247 | break; |
1248 | 1248 | ||
1249 | case DECAY: | 1249 | case DECAY: |
1250 | egout = HIGHBITS (slot->eg_phase, EG_DP_BITS - EG_BITS); | 1250 | egout = HIGHBITS (slot->eg_phase, EG_DP_BITS - EG_BITS); |
1251 | slot->eg_phase += slot->eg_dphase; | 1251 | slot->eg_phase += slot->eg_dphase; |
1252 | if (slot->eg_phase >= SL[slot->patch->SL]) | 1252 | if (slot->eg_phase >= SL[slot->patch->SL]) |
1253 | { | 1253 | { |
1254 | if (slot->patch->EG) | 1254 | if (slot->patch->EG) |
1255 | { | 1255 | { |
1256 | slot->eg_phase = SL[slot->patch->SL]; | 1256 | slot->eg_phase = SL[slot->patch->SL]; |
1257 | slot->eg_mode = SUSHOLD; | 1257 | slot->eg_mode = SUSHOLD; |
1258 | UPDATE_EG (slot); | 1258 | UPDATE_EG (slot); |
1259 | } | 1259 | } |
1260 | else | 1260 | else |
1261 | { | 1261 | { |
1262 | slot->eg_phase = SL[slot->patch->SL]; | 1262 | slot->eg_phase = SL[slot->patch->SL]; |
1263 | slot->eg_mode = SUSTINE; | 1263 | slot->eg_mode = SUSTINE; |
1264 | UPDATE_EG (slot); | 1264 | UPDATE_EG (slot); |
1265 | } | 1265 | } |
1266 | } | 1266 | } |
1267 | break; | 1267 | break; |
1268 | 1268 | ||
1269 | case SUSHOLD: | 1269 | case SUSHOLD: |
1270 | egout = HIGHBITS (slot->eg_phase, EG_DP_BITS - EG_BITS); | 1270 | egout = HIGHBITS (slot->eg_phase, EG_DP_BITS - EG_BITS); |
1271 | if (slot->patch->EG == 0) | 1271 | if (slot->patch->EG == 0) |
1272 | { | 1272 | { |
1273 | slot->eg_mode = SUSTINE; | 1273 | slot->eg_mode = SUSTINE; |
1274 | UPDATE_EG (slot); | 1274 | UPDATE_EG (slot); |
1275 | } | 1275 | } |
1276 | break; | 1276 | break; |
1277 | 1277 | ||
1278 | case SUSTINE: | 1278 | case SUSTINE: |
1279 | case RELEASE: | 1279 | case RELEASE: |
1280 | egout = HIGHBITS (slot->eg_phase, EG_DP_BITS - EG_BITS); | 1280 | egout = HIGHBITS (slot->eg_phase, EG_DP_BITS - EG_BITS); |
1281 | slot->eg_phase += slot->eg_dphase; | 1281 | slot->eg_phase += slot->eg_dphase; |
1282 | if (egout >= (1 << EG_BITS)) | 1282 | if (egout >= (1 << EG_BITS)) |
1283 | { | 1283 | { |
1284 | slot->eg_mode = FINISH; | 1284 | slot->eg_mode = FINISH; |
1285 | egout = (1 << EG_BITS) - 1; | 1285 | egout = (1 << EG_BITS) - 1; |
1286 | } | 1286 | } |
1287 | break; | 1287 | break; |
1288 | 1288 | ||
1289 | case SETTLE: | 1289 | case SETTLE: |
1290 | egout = HIGHBITS (slot->eg_phase, EG_DP_BITS - EG_BITS); | 1290 | egout = HIGHBITS (slot->eg_phase, EG_DP_BITS - EG_BITS); |
1291 | slot->eg_phase += slot->eg_dphase; | 1291 | slot->eg_phase += slot->eg_dphase; |
1292 | if (egout >= (1 << EG_BITS)) | 1292 | if (egout >= (1 << EG_BITS)) |
1293 | { | 1293 | { |
1294 | slot->eg_mode = ATTACK; | 1294 | slot->eg_mode = ATTACK; |
1295 | egout = (1 << EG_BITS) - 1; | 1295 | egout = (1 << EG_BITS) - 1; |
1296 | UPDATE_EG(slot); | 1296 | UPDATE_EG(slot); |
1297 | } | 1297 | } |
1298 | break; | 1298 | break; |
1299 | 1299 | ||
1300 | case FINISH: | 1300 | case FINISH: |
1301 | egout = (1 << EG_BITS) - 1; | 1301 | egout = (1 << EG_BITS) - 1; |
1302 | break; | 1302 | break; |
1303 | 1303 | ||
1304 | default: | 1304 | default: |
1305 | egout = (1 << EG_BITS) - 1; | 1305 | egout = (1 << EG_BITS) - 1; |
1306 | break; | 1306 | break; |
1307 | } | 1307 | } |
1308 | 1308 | ||
1309 | if (slot->patch->AM) | 1309 | if (slot->patch->AM) |
1310 | egout = EG2DB (egout + slot->tll) + lfo; | 1310 | egout = EG2DB (egout + slot->tll) + lfo; |
1311 | else | 1311 | else |
1312 | egout = EG2DB (egout + slot->tll); | 1312 | egout = EG2DB (egout + slot->tll); |
1313 | 1313 | ||
1314 | if (egout >= DB_MUTE) | 1314 | if (egout >= DB_MUTE) |
1315 | egout = DB_MUTE - 1; | 1315 | egout = DB_MUTE - 1; |
1316 | 1316 | ||
1317 | slot->egout = egout | 3; | 1317 | slot->egout = egout | 3; |
1318 | } | 1318 | } |
1319 | 1319 | ||
1320 | /* CARRIOR */ | 1320 | /* CARRIOR */ |
1321 | INLINE static e_int32 | 1321 | INLINE static e_int32 |
1322 | calc_slot_car (OPLL_SLOT * slot, e_int32 fm) | 1322 | calc_slot_car (OPLL_SLOT * slot, e_int32 fm) |
1323 | { | 1323 | { |
1324 | if (slot->egout >= (DB_MUTE - 1)) | 1324 | if (slot->egout >= (DB_MUTE - 1)) |
1325 | { | 1325 | { |
1326 | slot->output[0] = 0; | 1326 | slot->output[0] = 0; |
1327 | } | 1327 | } |
1328 | else | 1328 | else |
1329 | { | 1329 | { |
1330 | slot->output[0] = DB2LIN_TABLE[slot->sintbl[(slot->pgout+wave2_8pi(fm))&(PG_WIDTH-1)] + slot->egout]; | 1330 | slot->output[0] = DB2LIN_TABLE[slot->sintbl[(slot->pgout+wave2_8pi(fm))&(PG_WIDTH-1)] + slot->egout]; |
1331 | } | 1331 | } |
1332 | 1332 | ||
1333 | slot->output[1] = (slot->output[1] + slot->output[0]) >> 1; | 1333 | slot->output[1] = (slot->output[1] + slot->output[0]) >> 1; |
1334 | return slot->output[1]; | 1334 | return slot->output[1]; |
1335 | } | 1335 | } |
1336 | 1336 | ||
1337 | /* MODULATOR */ | 1337 | /* MODULATOR */ |
1338 | INLINE static e_int32 | 1338 | INLINE static e_int32 |
1339 | calc_slot_mod (OPLL_SLOT * slot) | 1339 | calc_slot_mod (OPLL_SLOT * slot) |
1340 | { | 1340 | { |
1341 | e_int32 fm; | 1341 | e_int32 fm; |
1342 | 1342 | ||
1343 | slot->output[1] = slot->output[0]; | 1343 | slot->output[1] = slot->output[0]; |
1344 | 1344 | ||
1345 | if (slot->egout >= (DB_MUTE - 1)) | 1345 | if (slot->egout >= (DB_MUTE - 1)) |
1346 | { | 1346 | { |
1347 | slot->output[0] = 0; | 1347 | slot->output[0] = 0; |
1348 | } | 1348 | } |
1349 | else if (slot->patch->FB != 0) | 1349 | else if (slot->patch->FB != 0) |
1350 | { | 1350 | { |
1351 | fm = wave2_4pi (slot->feedback) >> (7 - slot->patch->FB); | 1351 | fm = wave2_4pi (slot->feedback) >> (7 - slot->patch->FB); |
1352 | slot->output[0] = DB2LIN_TABLE[slot->sintbl[(slot->pgout+fm)&(PG_WIDTH-1)] + slot->egout]; | 1352 | slot->output[0] = DB2LIN_TABLE[slot->sintbl[(slot->pgout+fm)&(PG_WIDTH-1)] + slot->egout]; |
1353 | } | 1353 | } |
1354 | else | 1354 | else |
1355 | { | 1355 | { |
1356 | slot->output[0] = DB2LIN_TABLE[slot->sintbl[slot->pgout] + slot->egout]; | 1356 | slot->output[0] = DB2LIN_TABLE[slot->sintbl[slot->pgout] + slot->egout]; |
1357 | } | 1357 | } |
1358 | 1358 | ||
1359 | slot->feedback = (slot->output[1] + slot->output[0]) >> 1; | 1359 | slot->feedback = (slot->output[1] + slot->output[0]) >> 1; |
1360 | 1360 | ||
1361 | return slot->feedback; | 1361 | return slot->feedback; |
1362 | 1362 | ||
1363 | } | 1363 | } |
1364 | 1364 | ||
1365 | /* TOM */ | 1365 | /* TOM */ |
1366 | INLINE static e_int32 | 1366 | INLINE static e_int32 |
1367 | calc_slot_tom (OPLL_SLOT * slot) | 1367 | calc_slot_tom (OPLL_SLOT * slot) |
1368 | { | 1368 | { |
1369 | if (slot->egout >= (DB_MUTE - 1)) | 1369 | if (slot->egout >= (DB_MUTE - 1)) |
1370 | return 0; | 1370 | return 0; |
1371 | 1371 | ||
1372 | return DB2LIN_TABLE[slot->sintbl[slot->pgout] + slot->egout]; | 1372 | return DB2LIN_TABLE[slot->sintbl[slot->pgout] + slot->egout]; |
1373 | 1373 | ||
1374 | } | 1374 | } |
1375 | 1375 | ||
1376 | /* SNARE */ | 1376 | /* SNARE */ |
1377 | INLINE static e_int32 | 1377 | INLINE static e_int32 |
1378 | calc_slot_snare (OPLL_SLOT * slot, e_uint32 noise) | 1378 | calc_slot_snare (OPLL_SLOT * slot, e_uint32 noise) |
1379 | { | 1379 | { |
1380 | if(slot->egout>=(DB_MUTE-1)) | 1380 | if(slot->egout>=(DB_MUTE-1)) |
1381 | return 0; | 1381 | return 0; |
1382 | 1382 | ||
1383 | if(BIT(slot->pgout,7)) | 1383 | if(BIT(slot->pgout,7)) |
1384 | return DB2LIN_TABLE[(noise?DB_POS(0):DB_POS(15))+slot->egout]; | 1384 | return DB2LIN_TABLE[(noise?DB_POS(0):DB_POS(15))+slot->egout]; |
1385 | else | 1385 | else |
1386 | return DB2LIN_TABLE[(noise?DB_NEG(0):DB_NEG(15))+slot->egout]; | 1386 | return DB2LIN_TABLE[(noise?DB_NEG(0):DB_NEG(15))+slot->egout]; |
1387 | } | 1387 | } |
1388 | 1388 | ||
1389 | /* | 1389 | /* |
1390 | TOP-CYM | 1390 | TOP-CYM |
1391 | */ | 1391 | */ |
1392 | INLINE static e_int32 | 1392 | INLINE static e_int32 |
1393 | calc_slot_cym (OPLL_SLOT * slot, e_uint32 pgout_hh) | 1393 | calc_slot_cym (OPLL_SLOT * slot, e_uint32 pgout_hh) |
1394 | { | 1394 | { |
1395 | e_uint32 dbout; | 1395 | e_uint32 dbout; |
1396 | 1396 | ||
1397 | if (slot->egout >= (DB_MUTE - 1)) | 1397 | if (slot->egout >= (DB_MUTE - 1)) |
1398 | return 0; | 1398 | return 0; |
1399 | else if( | 1399 | else if( |
1400 | /* the same as fmopl.c */ | 1400 | /* the same as fmopl.c */ |
1401 | ((BIT(pgout_hh,PG_BITS-8)^BIT(pgout_hh,PG_BITS-1))|BIT(pgout_hh,PG_BITS-7)) ^ | 1401 | ((BIT(pgout_hh,PG_BITS-8)^BIT(pgout_hh,PG_BITS-1))|BIT(pgout_hh,PG_BITS-7)) ^ |
1402 | /* different from fmopl.c */ | 1402 | /* different from fmopl.c */ |
1403 | (BIT(slot->pgout,PG_BITS-7)&!BIT(slot->pgout,PG_BITS-5)) | 1403 | (BIT(slot->pgout,PG_BITS-7)&!BIT(slot->pgout,PG_BITS-5)) |
1404 | ) | 1404 | ) |
1405 | dbout = DB_NEG(3); | 1405 | dbout = DB_NEG(3); |
1406 | else | 1406 | else |
1407 | dbout = DB_POS(3); | 1407 | dbout = DB_POS(3); |
1408 | 1408 | ||
1409 | return DB2LIN_TABLE[dbout + slot->egout]; | 1409 | return DB2LIN_TABLE[dbout + slot->egout]; |
1410 | } | 1410 | } |
1411 | 1411 | ||
1412 | /* | 1412 | /* |
1413 | HI-HAT | 1413 | HI-HAT |
1414 | */ | 1414 | */ |
1415 | INLINE static e_int32 | 1415 | INLINE static e_int32 |
1416 | calc_slot_hat (OPLL_SLOT *slot, e_int32 pgout_cym, e_uint32 noise) | 1416 | calc_slot_hat (OPLL_SLOT *slot, e_int32 pgout_cym, e_uint32 noise) |
1417 | { | 1417 | { |
1418 | e_uint32 dbout; | 1418 | e_uint32 dbout; |
1419 | 1419 | ||
1420 | if (slot->egout >= (DB_MUTE - 1)) | 1420 | if (slot->egout >= (DB_MUTE - 1)) |
1421 | return 0; | 1421 | return 0; |
1422 | else if( | 1422 | else if( |
1423 | /* the same as fmopl.c */ | 1423 | /* the same as fmopl.c */ |
1424 | ((BIT(slot->pgout,PG_BITS-8)^BIT(slot->pgout,PG_BITS-1))|BIT(slot->pgout,PG_BITS-7)) ^ | 1424 | ((BIT(slot->pgout,PG_BITS-8)^BIT(slot->pgout,PG_BITS-1))|BIT(slot->pgout,PG_BITS-7)) ^ |
1425 | /* different from fmopl.c */ | 1425 | /* different from fmopl.c */ |
1426 | (BIT(pgout_cym,PG_BITS-7)&!BIT(pgout_cym,PG_BITS-5)) | 1426 | (BIT(pgout_cym,PG_BITS-7)&!BIT(pgout_cym,PG_BITS-5)) |
1427 | ) | 1427 | ) |
1428 | { | 1428 | { |
1429 | if(noise) | 1429 | if(noise) |
1430 | dbout = DB_NEG(12); | 1430 | dbout = DB_NEG(12); |
1431 | else | 1431 | else |
1432 | dbout = DB_NEG(24); | 1432 | dbout = DB_NEG(24); |
1433 | } | 1433 | } |
1434 | else | 1434 | else |
1435 | { | 1435 | { |
1436 | if(noise) | 1436 | if(noise) |
1437 | dbout = DB_POS(12); | 1437 | dbout = DB_POS(12); |
1438 | else | 1438 | else |
1439 | dbout = DB_POS(24); | 1439 | dbout = DB_POS(24); |
1440 | } | 1440 | } |
1441 | 1441 | ||
1442 | return DB2LIN_TABLE[dbout + slot->egout]; | 1442 | return DB2LIN_TABLE[dbout + slot->egout]; |
1443 | } | 1443 | } |
1444 | 1444 | ||
1445 | static e_int16 | 1445 | static e_int16 |
1446 | calc (OPLL * opll) EMU2413_CALC_ICODE; | 1446 | calc (OPLL * opll) EMU2413_CALC_ICODE; |
1447 | static e_int16 | 1447 | static e_int16 |
1448 | calc (OPLL * opll) | 1448 | calc (OPLL * opll) |
1449 | { | 1449 | { |
1450 | e_int32 i; | 1450 | e_int32 i; |
1451 | 1451 | ||
1452 | update_ampm (opll); | 1452 | update_ampm (opll); |
1453 | update_noise (opll); | 1453 | update_noise (opll); |
1454 | 1454 | ||
1455 | for (i = 0; i < 18; i++) | 1455 | for (i = 0; i < 18; i++) |
1456 | { | 1456 | { |
1457 | calc_phase(&opll->slot[i],opll->lfo_pm); | 1457 | calc_phase(&opll->slot[i],opll->lfo_pm); |
1458 | calc_envelope(&opll->slot[i],opll->lfo_am); | 1458 | calc_envelope(&opll->slot[i],opll->lfo_am); |
1459 | } | 1459 | } |
1460 | 1460 | ||
1461 | e_uint32 channel_mask = opll->mask; | 1461 | e_uint32 channel_mask = opll->mask; |
1462 | for (i = 0; i < 9; i++) { | 1462 | for (i = 0; i < 9; i++) { |
1463 | if (CAR(opll,i)->eg_mode != FINISH) | 1463 | if (CAR(opll,i)->eg_mode != FINISH) |
1464 | channel_mask |= (1 << i); | 1464 | channel_mask |= (1 << i); |
1465 | } | 1465 | } |
1466 | 1466 | ||
1467 | e_int32 mix = 0; | 1467 | e_int32 mix = 0; |
1468 | 1468 | ||
1469 | /* CH6 */ | 1469 | /* CH6 */ |
1470 | if (opll->patch_number[6] & 0x10) { | 1470 | if (opll->patch_number[6] & 0x10) { |
1471 | if (channel_mask & OPLL_MASK_CH (6)) { | 1471 | if (channel_mask & OPLL_MASK_CH (6)) { |
1472 | mix += calc_slot_car (CAR(opll,6), calc_slot_mod(MOD(opll,6))); | 1472 | mix += calc_slot_car (CAR(opll,6), calc_slot_mod(MOD(opll,6))); |
1473 | channel_mask &= ~(1 << 6); | 1473 | channel_mask &= ~(1 << 6); |
1474 | } | 1474 | } |
1475 | } | 1475 | } |
1476 | 1476 | ||
1477 | /* CH7 */ | 1477 | /* CH7 */ |
1478 | if (opll->patch_number[7] & 0x10) { | 1478 | if (opll->patch_number[7] & 0x10) { |
1479 | if (MOD(opll,7)->eg_mode != FINISH) | 1479 | if (MOD(opll,7)->eg_mode != FINISH) |
1480 | mix += calc_slot_hat (MOD(opll,7), CAR(opll,8)->pgout, opll->noise_seed&1); | 1480 | mix += calc_slot_hat (MOD(opll,7), CAR(opll,8)->pgout, opll->noise_seed&1); |
1481 | if (channel_mask & OPLL_MASK_SD) { | 1481 | if (channel_mask & OPLL_MASK_SD) { |
1482 | mix -= calc_slot_snare (CAR(opll,7), opll->noise_seed&1); | 1482 | mix -= calc_slot_snare (CAR(opll,7), opll->noise_seed&1); |
1483 | channel_mask &= ~OPLL_MASK_SD; | 1483 | channel_mask &= ~OPLL_MASK_SD; |
1484 | } | 1484 | } |
1485 | } | 1485 | } |
1486 | 1486 | ||
1487 | /* CH8 */ | 1487 | /* CH8 */ |
1488 | if (opll->patch_number[8] & 0x10) { | 1488 | if (opll->patch_number[8] & 0x10) { |
1489 | if (MOD(opll,8)->eg_mode != FINISH) | 1489 | if (MOD(opll,8)->eg_mode != FINISH) |
1490 | mix += calc_slot_tom (MOD(opll,8)); | 1490 | mix += calc_slot_tom (MOD(opll,8)); |
1491 | if (channel_mask & OPLL_MASK_CYM) { | 1491 | if (channel_mask & OPLL_MASK_CYM) { |
1492 | mix -= calc_slot_cym (CAR(opll,8), MOD(opll,7)->pgout); | 1492 | mix -= calc_slot_cym (CAR(opll,8), MOD(opll,7)->pgout); |
1493 | channel_mask &= ~OPLL_MASK_CYM; | 1493 | channel_mask &= ~OPLL_MASK_CYM; |
1494 | } | 1494 | } |
1495 | } | 1495 | } |
1496 | 1496 | ||
1497 | mix <<= 1; | 1497 | mix <<= 1; |
1498 | 1498 | ||
1499 | opll->current_mask = channel_mask; | 1499 | opll->current_mask = channel_mask; |
1500 | for (i = 0; channel_mask; channel_mask >>= 1, ++i) { | 1500 | for (i = 0; channel_mask; channel_mask >>= 1, ++i) { |
1501 | if (channel_mask & 1) { | 1501 | if (channel_mask & 1) { |
1502 | mix += calc_slot_car (CAR(opll,i), calc_slot_mod(MOD(opll,i))); | 1502 | mix += calc_slot_car (CAR(opll,i), calc_slot_mod(MOD(opll,i))); |
1503 | } | 1503 | } |
1504 | } | 1504 | } |
1505 | 1505 | ||
1506 | return (e_int16) mix << 3; | 1506 | return (e_int16) mix << 3; |
1507 | } | 1507 | } |
1508 | 1508 | ||
1509 | void | 1509 | void |
1510 | OPLL_set_internal_mute(OPLL * opll, e_uint32 mute) | 1510 | OPLL_set_internal_mute(OPLL * opll, e_uint32 mute) |
1511 | { | 1511 | { |
1512 | opll->internal_mute = mute; | 1512 | opll->internal_mute = mute; |
1513 | } | 1513 | } |
1514 | 1514 | ||
1515 | e_uint32 | 1515 | e_uint32 |
1516 | OPLL_is_internal_muted(OPLL * opll) | 1516 | OPLL_is_internal_muted(OPLL * opll) |
1517 | { | 1517 | { |
1518 | return opll->internal_mute; | 1518 | return opll->internal_mute; |
1519 | } | 1519 | } |
1520 | 1520 | ||
1521 | static e_uint32 | 1521 | static e_uint32 |
1522 | check_mute_helper(OPLL * opll) | 1522 | check_mute_helper(OPLL * opll) |
1523 | { | 1523 | { |
1524 | for (int i = 0; i < 6; i++) { | 1524 | for (int i = 0; i < 6; i++) { |
1525 | /* if (ch[i].car.eg_mode != FINISH) return 0; */ | 1525 | /* if (ch[i].car.eg_mode != FINISH) return 0; */ |
1526 | if (!(opll->current_mask & OPLL_MASK_CH (i)) && (CAR(opll,i)->eg_mode != FINISH)) return 0; | 1526 | if (!(opll->current_mask & OPLL_MASK_CH (i)) && (CAR(opll,i)->eg_mode != FINISH)) return 0; |
1527 | } | 1527 | } |
1528 | 1528 | ||
1529 | if (!(opll->reg[0x0e] & 0x20)) { | 1529 | if (!(opll->reg[0x0e] & 0x20)) { |
1530 | for(int i = 6; i < 9; i++) { | 1530 | for(int i = 6; i < 9; i++) { |
1531 | /* if (ch[i].car.eg_mode != FINISH) return 0; */ | 1531 | /* if (ch[i].car.eg_mode != FINISH) return 0; */ |
1532 | if (!(opll->current_mask & OPLL_MASK_CH (i)) && (CAR(opll,i)->eg_mode != FINISH)) return 0; | 1532 | if (!(opll->current_mask & OPLL_MASK_CH (i)) && (CAR(opll,i)->eg_mode != FINISH)) return 0; |
1533 | } | 1533 | } |
1534 | } else { | 1534 | } else { |
1535 | /* if (ch[6].car.eg_mode != FINISH) return false; | 1535 | /* if (ch[6].car.eg_mode != FINISH) return false; |
1536 | if (ch[7].mod.eg_mode != FINISH) return false; | 1536 | if (ch[7].mod.eg_mode != FINISH) return false; |
1537 | if (ch[7].car.eg_mode != FINISH) return false; | 1537 | if (ch[7].car.eg_mode != FINISH) return false; |
1538 | if (ch[8].mod.eg_mode != FINISH) return false; | 1538 | if (ch[8].mod.eg_mode != FINISH) return false; |
1539 | if (ch[8].car.eg_mode != FINISH) return false; */ | 1539 | if (ch[8].car.eg_mode != FINISH) return false; */ |
1540 | if (!(opll->current_mask & OPLL_MASK_CH (6)) && (CAR(opll,6)->eg_mode != FINISH)) return 0; | 1540 | if (!(opll->current_mask & OPLL_MASK_CH (6)) && (CAR(opll,6)->eg_mode != FINISH)) return 0; |
1541 | if (!(opll->current_mask & OPLL_MASK_CH (7)) && (MOD(opll,7)->eg_mode != FINISH)) return 0; | 1541 | if (!(opll->current_mask & OPLL_MASK_CH (7)) && (MOD(opll,7)->eg_mode != FINISH)) return 0; |
1542 | if (!(opll->current_mask & OPLL_MASK_CH (7)) && (CAR(opll,7)->eg_mode != FINISH)) return 0; | 1542 | if (!(opll->current_mask & OPLL_MASK_CH (7)) && (CAR(opll,7)->eg_mode != FINISH)) return 0; |
1543 | if (!(opll->current_mask & OPLL_MASK_CH (8)) && (MOD(opll,8)->eg_mode != FINISH)) return 0; | 1543 | if (!(opll->current_mask & OPLL_MASK_CH (8)) && (MOD(opll,8)->eg_mode != FINISH)) return 0; |
1544 | if (!(opll->current_mask & OPLL_MASK_CH (8)) && (CAR(opll,8)->eg_mode != FINISH)) return 0; | 1544 | if (!(opll->current_mask & OPLL_MASK_CH (8)) && (CAR(opll,8)->eg_mode != FINISH)) return 0; |
1545 | } | 1545 | } |
1546 | 1546 | ||
1547 | return 1; /* nothing is playing, then mute */ | 1547 | return 1; /* nothing is playing, then mute */ |
1548 | } | 1548 | } |
1549 | 1549 | ||
1550 | static void | 1550 | static void |
1551 | check_mute(OPLL * opll) | 1551 | check_mute(OPLL * opll) |
1552 | { | 1552 | { |
1553 | OPLL_set_internal_mute (opll, check_mute_helper (opll)); | 1553 | OPLL_set_internal_mute (opll, check_mute_helper (opll)); |
1554 | } | 1554 | } |
1555 | 1555 | ||
1556 | EMU2413_API e_int16 *OPLL_update_buffer(OPLL * opll, e_uint32 length) | 1556 | EMU2413_API e_int16 *OPLL_update_buffer(OPLL * opll, e_uint32 length) |
1557 | { | 1557 | { |
1558 | e_int16* buf = opll->buffer; | 1558 | e_int16* buf = opll->buffer; |
1559 | while (length--) { | 1559 | while (length--) { |
1560 | *(buf++) = calc (opll); | 1560 | *(buf++) = calc (opll); |
1561 | } | 1561 | } |
1562 | check_mute (opll); | 1562 | check_mute (opll); |
1563 | 1563 | ||
1564 | return opll->buffer; | 1564 | return opll->buffer; |
1565 | } | 1565 | } |
1566 | 1566 | ||
1567 | #ifdef EMU2413_COMPACTION | 1567 | #ifdef EMU2413_COMPACTION |
1568 | e_int16 | 1568 | e_int16 |
1569 | OPLL_calc (OPLL * opll) | 1569 | OPLL_calc (OPLL * opll) |
1570 | { | 1570 | { |
1571 | return calc (opll); | 1571 | return calc (opll); |
1572 | } | 1572 | } |
1573 | #else | 1573 | #else |
1574 | e_int16 | 1574 | e_int16 |
1575 | OPLL_calc (OPLL * opll) | 1575 | OPLL_calc (OPLL * opll) |
1576 | { | 1576 | { |
1577 | if (!opll->quality) | 1577 | if (!opll->quality) |
1578 | return calc (opll); | 1578 | return calc (opll); |
1579 | 1579 | ||
1580 | while (opll->realstep > opll->oplltime) | 1580 | while (opll->realstep > opll->oplltime) |
1581 | { | 1581 | { |
1582 | opll->oplltime += opll->opllstep; | 1582 | opll->oplltime += opll->opllstep; |
1583 | opll->prev = opll->next; | 1583 | opll->prev = opll->next; |
1584 | opll->next = calc (opll); | 1584 | opll->next = calc (opll); |
1585 | } | 1585 | } |
1586 | 1586 | ||
1587 | opll->oplltime -= opll->realstep; | 1587 | opll->oplltime -= opll->realstep; |
1588 | opll->out = (e_int16) (((double) opll->next * (opll->opllstep - opll->oplltime) | 1588 | opll->out = (e_int16) (((double) opll->next * (opll->opllstep - opll->oplltime) |
1589 | + (double) opll->prev * opll->oplltime) / opll->opllstep); | 1589 | + (double) opll->prev * opll->oplltime) / opll->opllstep); |
1590 | 1590 | ||
1591 | return (e_int16) opll->out; | 1591 | return (e_int16) opll->out; |
1592 | } | 1592 | } |
1593 | #endif | 1593 | #endif |
1594 | 1594 | ||
1595 | e_uint32 | 1595 | e_uint32 |
1596 | OPLL_setMask (OPLL * opll, e_uint32 mask) | 1596 | OPLL_setMask (OPLL * opll, e_uint32 mask) |
1597 | { | 1597 | { |
1598 | e_uint32 ret; | 1598 | e_uint32 ret; |
1599 | 1599 | ||
1600 | if (opll) | 1600 | if (opll) |
1601 | { | 1601 | { |
1602 | ret = opll->mask; | 1602 | ret = opll->mask; |
1603 | opll->mask = mask; | 1603 | opll->mask = mask; |
1604 | return ret; | 1604 | return ret; |
1605 | } | 1605 | } |
1606 | else | 1606 | else |
1607 | return 0; | 1607 | return 0; |
1608 | } | 1608 | } |
1609 | 1609 | ||
1610 | e_uint32 | 1610 | e_uint32 |
1611 | OPLL_toggleMask (OPLL * opll, e_uint32 mask) | 1611 | OPLL_toggleMask (OPLL * opll, e_uint32 mask) |
1612 | { | 1612 | { |
1613 | e_uint32 ret; | 1613 | e_uint32 ret; |
1614 | 1614 | ||
1615 | if (opll) | 1615 | if (opll) |
1616 | { | 1616 | { |
1617 | ret = opll->mask; | 1617 | ret = opll->mask; |
1618 | opll->mask ^= mask; | 1618 | opll->mask ^= mask; |
1619 | return ret; | 1619 | return ret; |
1620 | } | 1620 | } |
1621 | else | 1621 | else |
1622 | return 0; | 1622 | return 0; |
1623 | } | 1623 | } |
1624 | 1624 | ||
1625 | /**************************************************** | 1625 | /**************************************************** |
1626 | 1626 | ||
1627 | I/O Ctrl | 1627 | I/O Ctrl |
1628 | 1628 | ||
1629 | *****************************************************/ | 1629 | *****************************************************/ |
1630 | 1630 | ||
1631 | void | 1631 | void |
1632 | OPLL_writeReg (OPLL * opll, e_uint32 reg, e_uint32 data) | 1632 | OPLL_writeReg (OPLL * opll, e_uint32 reg, e_uint32 data) |
1633 | { | 1633 | { |
1634 | e_int32 i, v, ch; | 1634 | e_int32 i, v, ch; |
1635 | 1635 | ||
1636 | data = data & 0xff; | 1636 | data = data & 0xff; |
1637 | reg = reg & 0x3f; | 1637 | reg = reg & 0x3f; |
1638 | opll->reg[reg] = (e_uint8) data; | 1638 | opll->reg[reg] = (e_uint8) data; |
1639 | 1639 | ||
1640 | switch (reg) | 1640 | switch (reg) |
1641 | { | 1641 | { |
1642 | case 0x00: | 1642 | case 0x00: |
1643 | opll->patch[0].AM = (data >> 7) & 1; | 1643 | opll->patch[0].AM = (data >> 7) & 1; |
1644 | opll->patch[0].PM = (data >> 6) & 1; | 1644 | opll->patch[0].PM = (data >> 6) & 1; |
1645 | opll->patch[0].EG = (data >> 5) & 1; | 1645 | opll->patch[0].EG = (data >> 5) & 1; |
1646 | opll->patch[0].KR = (data >> 4) & 1; | 1646 | opll->patch[0].KR = (data >> 4) & 1; |
1647 | opll->patch[0].ML = (data) & 15; | 1647 | opll->patch[0].ML = (data) & 15; |
1648 | for (i = 0; i < 9; i++) | 1648 | for (i = 0; i < 9; i++) |
1649 | { | 1649 | { |
1650 | if (opll->patch_number[i] == 0) | 1650 | if (opll->patch_number[i] == 0) |
1651 | { | 1651 | { |
1652 | UPDATE_PG (MOD(opll,i)); | 1652 | UPDATE_PG (MOD(opll,i)); |
1653 | UPDATE_RKS (MOD(opll,i)); | 1653 | UPDATE_RKS (MOD(opll,i)); |
1654 | UPDATE_EG (MOD(opll,i)); | 1654 | UPDATE_EG (MOD(opll,i)); |
1655 | } | 1655 | } |
1656 | } | 1656 | } |
1657 | break; | 1657 | break; |
1658 | 1658 | ||
1659 | case 0x01: | 1659 | case 0x01: |
1660 | opll->patch[1].AM = (data >> 7) & 1; | 1660 | opll->patch[1].AM = (data >> 7) & 1; |
1661 | opll->patch[1].PM = (data >> 6) & 1; | 1661 | opll->patch[1].PM = (data >> 6) & 1; |
1662 | opll->patch[1].EG = (data >> 5) & 1; | 1662 | opll->patch[1].EG = (data >> 5) & 1; |
1663 | opll->patch[1].KR = (data >> 4) & 1; | 1663 | opll->patch[1].KR = (data >> 4) & 1; |
1664 | opll->patch[1].ML = (data) & 15; | 1664 | opll->patch[1].ML = (data) & 15; |
1665 | for (i = 0; i < 9; i++) | 1665 | for (i = 0; i < 9; i++) |
1666 | { | 1666 | { |
1667 | if (opll->patch_number[i] == 0) | 1667 | if (opll->patch_number[i] == 0) |
1668 | { | 1668 | { |
1669 | UPDATE_PG (CAR(opll,i)); | 1669 | UPDATE_PG (CAR(opll,i)); |
1670 | UPDATE_RKS (CAR(opll,i)); | 1670 | UPDATE_RKS (CAR(opll,i)); |
1671 | UPDATE_EG (CAR(opll,i)); | 1671 | UPDATE_EG (CAR(opll,i)); |
1672 | } | 1672 | } |
1673 | } | 1673 | } |
1674 | break; | 1674 | break; |
1675 | 1675 | ||
1676 | case 0x02: | 1676 | case 0x02: |
1677 | opll->patch[0].KL = (data >> 6) & 3; | 1677 | opll->patch[0].KL = (data >> 6) & 3; |
1678 | opll->patch[0].TL = (data) & 63; | 1678 | opll->patch[0].TL = (data) & 63; |
1679 | for (i = 0; i < 9; i++) | 1679 | for (i = 0; i < 9; i++) |
1680 | { | 1680 | { |
1681 | if (opll->patch_number[i] == 0) | 1681 | if (opll->patch_number[i] == 0) |
1682 | { | 1682 | { |
1683 | UPDATE_TLL(MOD(opll,i)); | 1683 | UPDATE_TLL(MOD(opll,i)); |
1684 | } | 1684 | } |
1685 | } | 1685 | } |
1686 | break; | 1686 | break; |
1687 | 1687 | ||
1688 | case 0x03: | 1688 | case 0x03: |
1689 | opll->patch[1].KL = (data >> 6) & 3; | 1689 | opll->patch[1].KL = (data >> 6) & 3; |
1690 | opll->patch[1].WF = (data >> 4) & 1; | 1690 | opll->patch[1].WF = (data >> 4) & 1; |
1691 | opll->patch[0].WF = (data >> 3) & 1; | 1691 | opll->patch[0].WF = (data >> 3) & 1; |
1692 | opll->patch[0].FB = (data) & 7; | 1692 | opll->patch[0].FB = (data) & 7; |
1693 | for (i = 0; i < 9; i++) | 1693 | for (i = 0; i < 9; i++) |
1694 | { | 1694 | { |
1695 | if (opll->patch_number[i] == 0) | 1695 | if (opll->patch_number[i] == 0) |
1696 | { | 1696 | { |
1697 | UPDATE_WF(MOD(opll,i)); | 1697 | UPDATE_WF(MOD(opll,i)); |
1698 | UPDATE_WF(CAR(opll,i)); | 1698 | UPDATE_WF(CAR(opll,i)); |
1699 | } | 1699 | } |
1700 | } | 1700 | } |
1701 | break; | 1701 | break; |
1702 | 1702 | ||
1703 | case 0x04: | 1703 | case 0x04: |
1704 | opll->patch[0].AR = (data >> 4) & 15; | 1704 | opll->patch[0].AR = (data >> 4) & 15; |
1705 | opll->patch[0].DR = (data) & 15; | 1705 | opll->patch[0].DR = (data) & 15; |
1706 | for (i = 0; i < 9; i++) | 1706 | for (i = 0; i < 9; i++) |
1707 | { | 1707 | { |
1708 | if (opll->patch_number[i] == 0) | 1708 | if (opll->patch_number[i] == 0) |
1709 | { | 1709 | { |
1710 | UPDATE_EG (MOD(opll,i)); | 1710 | UPDATE_EG (MOD(opll,i)); |
1711 | } | 1711 | } |
1712 | } | 1712 | } |
1713 | break; | 1713 | break; |
1714 | 1714 | ||
1715 | case 0x05: | 1715 | case 0x05: |
1716 | opll->patch[1].AR = (data >> 4) & 15; | 1716 | opll->patch[1].AR = (data >> 4) & 15; |
1717 | opll->patch[1].DR = (data) & 15; | 1717 | opll->patch[1].DR = (data) & 15; |
1718 | for (i = 0; i < 9; i++) | 1718 | for (i = 0; i < 9; i++) |
1719 | { | 1719 | { |
1720 | if (opll->patch_number[i] == 0) | 1720 | if (opll->patch_number[i] == 0) |
1721 | { | 1721 | { |
1722 | UPDATE_EG(CAR(opll,i)); | 1722 | UPDATE_EG(CAR(opll,i)); |
1723 | } | 1723 | } |
1724 | } | 1724 | } |
1725 | break; | 1725 | break; |
1726 | 1726 | ||
1727 | case 0x06: | 1727 | case 0x06: |
1728 | opll->patch[0].SL = (data >> 4) & 15; | 1728 | opll->patch[0].SL = (data >> 4) & 15; |
1729 | opll->patch[0].RR = (data) & 15; | 1729 | opll->patch[0].RR = (data) & 15; |
1730 | for (i = 0; i < 9; i++) | 1730 | for (i = 0; i < 9; i++) |
1731 | { | 1731 | { |
1732 | if (opll->patch_number[i] == 0) | 1732 | if (opll->patch_number[i] == 0) |
1733 | { | 1733 | { |
1734 | UPDATE_EG (MOD(opll,i)); | 1734 | UPDATE_EG (MOD(opll,i)); |
1735 | } | 1735 | } |
1736 | } | 1736 | } |
1737 | break; | 1737 | break; |
1738 | 1738 | ||
1739 | case 0x07: | 1739 | case 0x07: |
1740 | opll->patch[1].SL = (data >> 4) & 15; | 1740 | opll->patch[1].SL = (data >> 4) & 15; |
1741 | opll->patch[1].RR = (data) & 15; | 1741 | opll->patch[1].RR = (data) & 15; |
1742 | for (i = 0; i < 9; i++) | 1742 | for (i = 0; i < 9; i++) |
1743 | { | 1743 | { |
1744 | if (opll->patch_number[i] == 0) | 1744 | if (opll->patch_number[i] == 0) |
1745 | { | 1745 | { |
1746 | UPDATE_EG (CAR(opll,i)); | 1746 | UPDATE_EG (CAR(opll,i)); |
1747 | } | 1747 | } |
1748 | } | 1748 | } |
1749 | break; | 1749 | break; |
1750 | 1750 | ||
1751 | case 0x0e: | 1751 | case 0x0e: |
1752 | update_rhythm_mode (opll); | 1752 | update_rhythm_mode (opll); |
1753 | if (data & 32) | 1753 | if (data & 32) |
1754 | { | 1754 | { |
1755 | if (data & 0x10) | 1755 | if (data & 0x10) |
1756 | keyOn_BD (opll); | 1756 | keyOn_BD (opll); |
1757 | else | 1757 | else |
1758 | keyOff_BD (opll); | 1758 | keyOff_BD (opll); |
1759 | if (data & 0x8) | 1759 | if (data & 0x8) |
1760 | keyOn_SD (opll); | 1760 | keyOn_SD (opll); |
1761 | else | 1761 | else |
1762 | keyOff_SD (opll); | 1762 | keyOff_SD (opll); |
1763 | if (data & 0x4) | 1763 | if (data & 0x4) |
1764 | keyOn_TOM (opll); | 1764 | keyOn_TOM (opll); |
1765 | else | 1765 | else |
1766 | keyOff_TOM (opll); | 1766 | keyOff_TOM (opll); |
1767 | if (data & 0x2) | 1767 | if (data & 0x2) |
1768 | keyOn_CYM (opll); | 1768 | keyOn_CYM (opll); |
1769 | else | 1769 | else |
1770 | keyOff_CYM (opll); | 1770 | keyOff_CYM (opll); |
1771 | if (data & 0x1) | 1771 | if (data & 0x1) |
1772 | keyOn_HH (opll); | 1772 | keyOn_HH (opll); |
1773 | else | 1773 | else |
1774 | keyOff_HH (opll); | 1774 | keyOff_HH (opll); |
1775 | } | 1775 | } |
1776 | update_key_status (opll); | 1776 | update_key_status (opll); |
1777 | 1777 | ||
1778 | UPDATE_ALL (MOD(opll,6)); | 1778 | UPDATE_ALL (MOD(opll,6)); |
1779 | UPDATE_ALL (CAR(opll,6)); | 1779 | UPDATE_ALL (CAR(opll,6)); |
1780 | UPDATE_ALL (MOD(opll,7)); | 1780 | UPDATE_ALL (MOD(opll,7)); |
1781 | UPDATE_ALL (CAR(opll,7)); | 1781 | UPDATE_ALL (CAR(opll,7)); |
1782 | UPDATE_ALL (MOD(opll,8)); | 1782 | UPDATE_ALL (MOD(opll,8)); |
1783 | UPDATE_ALL (CAR(opll,8)); | 1783 | UPDATE_ALL (CAR(opll,8)); |
1784 | 1784 | ||
1785 | break; | 1785 | break; |
1786 | 1786 | ||
1787 | case 0x0f: | 1787 | case 0x0f: |
1788 | break; | 1788 | break; |
1789 | 1789 | ||
1790 | case 0x10: | 1790 | case 0x10: |
1791 | case 0x11: | 1791 | case 0x11: |
1792 | case 0x12: | 1792 | case 0x12: |
1793 | case 0x13: | 1793 | case 0x13: |
1794 | case 0x14: | 1794 | case 0x14: |
1795 | case 0x15: | 1795 | case 0x15: |
1796 | case 0x16: | 1796 | case 0x16: |
1797 | case 0x17: | 1797 | case 0x17: |
1798 | case 0x18: | 1798 | case 0x18: |
1799 | ch = reg - 0x10; | 1799 | ch = reg - 0x10; |
1800 | setFnumber (opll, ch, data + ((opll->reg[0x20 + ch] & 1) << 8)); | 1800 | setFnumber (opll, ch, data + ((opll->reg[0x20 + ch] & 1) << 8)); |
1801 | UPDATE_ALL (MOD(opll,ch)); | 1801 | UPDATE_ALL (MOD(opll,ch)); |
1802 | UPDATE_ALL (CAR(opll,ch)); | 1802 | UPDATE_ALL (CAR(opll,ch)); |
1803 | break; | 1803 | break; |
1804 | 1804 | ||
1805 | case 0x20: | 1805 | case 0x20: |
1806 | case 0x21: | 1806 | case 0x21: |
1807 | case 0x22: | 1807 | case 0x22: |
1808 | case 0x23: | 1808 | case 0x23: |
1809 | case 0x24: | 1809 | case 0x24: |
1810 | case 0x25: | 1810 | case 0x25: |
1811 | case 0x26: | 1811 | case 0x26: |
1812 | case 0x27: | 1812 | case 0x27: |
1813 | case 0x28: | 1813 | case 0x28: |
1814 | ch = reg - 0x20; | 1814 | ch = reg - 0x20; |
1815 | setFnumber (opll, ch, ((data & 1) << 8) + opll->reg[0x10 + ch]); | 1815 | setFnumber (opll, ch, ((data & 1) << 8) + opll->reg[0x10 + ch]); |
1816 | setBlock (opll, ch, (data >> 1) & 7); | 1816 | setBlock (opll, ch, (data >> 1) & 7); |
1817 | setSustine (opll, ch, (data >> 5) & 1); | 1817 | setSustine (opll, ch, (data >> 5) & 1); |
1818 | if (data & 0x10) | 1818 | if (data & 0x10) |
1819 | keyOn (opll, ch); | 1819 | keyOn (opll, ch); |
1820 | else | 1820 | else |
1821 | keyOff (opll, ch); | 1821 | keyOff (opll, ch); |
1822 | UPDATE_ALL (MOD(opll,ch)); | 1822 | UPDATE_ALL (MOD(opll,ch)); |
1823 | UPDATE_ALL (CAR(opll,ch)); | 1823 | UPDATE_ALL (CAR(opll,ch)); |
1824 | update_key_status (opll); | 1824 | update_key_status (opll); |
1825 | update_rhythm_mode (opll); | 1825 | update_rhythm_mode (opll); |
1826 | break; | 1826 | break; |
1827 | 1827 | ||
1828 | case 0x30: | 1828 | case 0x30: |
1829 | case 0x31: | 1829 | case 0x31: |
1830 | case 0x32: | 1830 | case 0x32: |
1831 | case 0x33: | 1831 | case 0x33: |
1832 | case 0x34: | 1832 | case 0x34: |
1833 | case 0x35: | 1833 | case 0x35: |
1834 | case 0x36: | 1834 | case 0x36: |
1835 | case 0x37: | 1835 | case 0x37: |
1836 | case 0x38: | 1836 | case 0x38: |
1837 | i = (data >> 4) & 15; | 1837 | i = (data >> 4) & 15; |
1838 | v = data & 15; | 1838 | v = data & 15; |
1839 | if ((opll->reg[0x0e] & 32) && (reg >= 0x36)) | 1839 | if ((opll->reg[0x0e] & 32) && (reg >= 0x36)) |
1840 | { | 1840 | { |
1841 | switch (reg) | 1841 | switch (reg) |
1842 | { | 1842 | { |
1843 | case 0x37: | 1843 | case 0x37: |
1844 | setSlotVolume (MOD(opll,7), i << 2); | 1844 | setSlotVolume (MOD(opll,7), i << 2); |
1845 | break; | 1845 | break; |
1846 | case 0x38: | 1846 | case 0x38: |
1847 | setSlotVolume (MOD(opll,8), i << 2); | 1847 | setSlotVolume (MOD(opll,8), i << 2); |
1848 | break; | 1848 | break; |
1849 | default: | 1849 | default: |
1850 | break; | 1850 | break; |
1851 | } | 1851 | } |
1852 | } | 1852 | } |
1853 | else | 1853 | else |
1854 | { | 1854 | { |
1855 | setPatch (opll, reg - 0x30, i); | 1855 | setPatch (opll, reg - 0x30, i); |
1856 | } | 1856 | } |
1857 | setVolume (opll, reg - 0x30, v << 2); | 1857 | setVolume (opll, reg - 0x30, v << 2); |
1858 | UPDATE_ALL (MOD(opll,reg - 0x30)); | 1858 | UPDATE_ALL (MOD(opll,reg - 0x30)); |
1859 | UPDATE_ALL (CAR(opll,reg - 0x30)); | 1859 | UPDATE_ALL (CAR(opll,reg - 0x30)); |
1860 | break; | 1860 | break; |
1861 | 1861 | ||
1862 | default: | 1862 | default: |
1863 | break; | 1863 | break; |
1864 | 1864 | ||
1865 | } | 1865 | } |
1866 | } | 1866 | } |
1867 | 1867 | ||
1868 | void | 1868 | void |
1869 | OPLL_writeIO (OPLL * opll, e_uint32 adr, e_uint32 val) | 1869 | OPLL_writeIO (OPLL * opll, e_uint32 adr, e_uint32 val) |
1870 | { | 1870 | { |
1871 | if (adr & 1) | 1871 | if (adr & 1) |
1872 | OPLL_writeReg (opll, opll->adr, val); | 1872 | OPLL_writeReg (opll, opll->adr, val); |
1873 | else | 1873 | else |
1874 | opll->adr = val; | 1874 | opll->adr = val; |
1875 | } | 1875 | } |
1876 | 1876 | ||
1877 | e_uint32 | 1877 | e_uint32 |
1878 | OPLL_read(OPLL * opll, e_uint32 a) | 1878 | OPLL_read(OPLL * opll, e_uint32 a) |
1879 | { | 1879 | { |
1880 | if( !(a&1) ) | 1880 | if( !(a&1) ) |
1881 | { | 1881 | { |
1882 | /* status port */ | 1882 | /* status port */ |
1883 | return opll->status; | 1883 | return opll->status; |
1884 | } | 1884 | } |
1885 | return 0xff; | 1885 | return 0xff; |
1886 | } | 1886 | } |
1887 | 1887 | ||
1888 | #ifndef EMU2413_COMPACTION | 1888 | #ifndef EMU2413_COMPACTION |
1889 | /* STEREO MODE (OPT) */ | 1889 | /* STEREO MODE (OPT) */ |
1890 | void | 1890 | void |
1891 | OPLL_set_pan (OPLL * opll, e_uint32 ch, e_uint32 pan) | 1891 | OPLL_set_pan (OPLL * opll, e_uint32 ch, e_uint32 pan) |
1892 | { | 1892 | { |
1893 | opll->pan[ch & 15] = pan & 3; | 1893 | opll->pan[ch & 15] = pan & 3; |
1894 | } | 1894 | } |
1895 | 1895 | ||
1896 | static void | 1896 | static void |
1897 | calc_stereo (OPLL * opll, e_int32 out[2]) | 1897 | calc_stereo (OPLL * opll, e_int32 out[2]) |
1898 | { | 1898 | { |
1899 | e_int32 b[4] = { 0, 0, 0, 0 }; /* Ignore, Right, Left, Center */ | 1899 | e_int32 b[4] = { 0, 0, 0, 0 }; /* Ignore, Right, Left, Center */ |
1900 | e_int32 r[4] = { 0, 0, 0, 0 }; /* Ignore, Right, Left, Center */ | 1900 | e_int32 r[4] = { 0, 0, 0, 0 }; /* Ignore, Right, Left, Center */ |
1901 | e_int32 i; | 1901 | e_int32 i; |
1902 | 1902 | ||
1903 | update_ampm (opll); | 1903 | update_ampm (opll); |
1904 | update_noise (opll); | 1904 | update_noise (opll); |
1905 | 1905 | ||
1906 | for(i=0;i<18;i++) | 1906 | for(i=0;i<18;i++) |
1907 | { | 1907 | { |
1908 | calc_phase(&opll->slot[i],opll->lfo_pm); | 1908 | calc_phase(&opll->slot[i],opll->lfo_pm); |
1909 | calc_envelope(&opll->slot[i],opll->lfo_am); | 1909 | calc_envelope(&opll->slot[i],opll->lfo_am); |
1910 | } | 1910 | } |
1911 | 1911 | ||
1912 | for (i = 0; i < 6; i++) | 1912 | for (i = 0; i < 6; i++) |
1913 | if (!(opll->mask & OPLL_MASK_CH (i)) && (CAR(opll,i)->eg_mode != FINISH)) | 1913 | if (!(opll->mask & OPLL_MASK_CH (i)) && (CAR(opll,i)->eg_mode != FINISH)) |
1914 | b[opll->pan[i]] += calc_slot_car (CAR(opll,i), calc_slot_mod (MOD(opll,i))); | 1914 | b[opll->pan[i]] += calc_slot_car (CAR(opll,i), calc_slot_mod (MOD(opll,i))); |
1915 | 1915 | ||
1916 | 1916 | ||
1917 | if (opll->patch_number[6] <= 15) | 1917 | if (opll->patch_number[6] <= 15) |
1918 | { | 1918 | { |
1919 | if (!(opll->mask & OPLL_MASK_CH (6)) && (CAR(opll,6)->eg_mode != FINISH)) | 1919 | if (!(opll->mask & OPLL_MASK_CH (6)) && (CAR(opll,6)->eg_mode != FINISH)) |
1920 | b[opll->pan[6]] += calc_slot_car (CAR(opll,6), calc_slot_mod (MOD(opll,6))); | 1920 | b[opll->pan[6]] += calc_slot_car (CAR(opll,6), calc_slot_mod (MOD(opll,6))); |
1921 | } | 1921 | } |
1922 | else | 1922 | else |
1923 | { | 1923 | { |
1924 | if (!(opll->mask & OPLL_MASK_BD) && (CAR(opll,6)->eg_mode != FINISH)) | 1924 | if (!(opll->mask & OPLL_MASK_BD) && (CAR(opll,6)->eg_mode != FINISH)) |
1925 | r[opll->pan[9]] += calc_slot_car (CAR(opll,6), calc_slot_mod (MOD(opll,6))); | 1925 | r[opll->pan[9]] += calc_slot_car (CAR(opll,6), calc_slot_mod (MOD(opll,6))); |
1926 | } | 1926 | } |
1927 | 1927 | ||
1928 | if (opll->patch_number[7] <= 15) | 1928 | if (opll->patch_number[7] <= 15) |
1929 | { | 1929 | { |
1930 | if (!(opll->mask & OPLL_MASK_CH (7)) && (CAR (opll,7)->eg_mode != FINISH)) | 1930 | if (!(opll->mask & OPLL_MASK_CH (7)) && (CAR (opll,7)->eg_mode != FINISH)) |
1931 | b[opll->pan[7]] += calc_slot_car (CAR (opll,7), calc_slot_mod (MOD (opll,7))); | 1931 | b[opll->pan[7]] += calc_slot_car (CAR (opll,7), calc_slot_mod (MOD (opll,7))); |
1932 | } | 1932 | } |
1933 | else | 1933 | else |
1934 | { | 1934 | { |
1935 | if (!(opll->mask & OPLL_MASK_HH) && (MOD (opll,7)->eg_mode != FINISH)) | 1935 | if (!(opll->mask & OPLL_MASK_HH) && (MOD (opll,7)->eg_mode != FINISH)) |
1936 | r[opll->pan[10]] += calc_slot_hat (MOD (opll,7), CAR(opll,8)->pgout, opll->noise_seed&1); | 1936 | r[opll->pan[10]] += calc_slot_hat (MOD (opll,7), CAR(opll,8)->pgout, opll->noise_seed&1); |
1937 | if (!(opll->mask & OPLL_MASK_SD) && (CAR (opll,7)->eg_mode != FINISH)) | 1937 | if (!(opll->mask & OPLL_MASK_SD) && (CAR (opll,7)->eg_mode != FINISH)) |
1938 | r[opll->pan[11]] -= calc_slot_snare (CAR (opll,7), opll->noise_seed&1); | 1938 | r[opll->pan[11]] -= calc_slot_snare (CAR (opll,7), opll->noise_seed&1); |
1939 | } | 1939 | } |
1940 | 1940 | ||
1941 | if (opll->patch_number[8] <= 15) | 1941 | if (opll->patch_number[8] <= 15) |
1942 | { | 1942 | { |
1943 | if (!(opll->mask & OPLL_MASK_CH (8)) && (CAR (opll,8)->eg_mode != FINISH)) | 1943 | if (!(opll->mask & OPLL_MASK_CH (8)) && (CAR (opll,8)->eg_mode != FINISH)) |
1944 | b[opll->pan[8]] += calc_slot_car (CAR (opll,8), calc_slot_mod (MOD (opll,8))); | 1944 | b[opll->pan[8]] += calc_slot_car (CAR (opll,8), calc_slot_mod (MOD (opll,8))); |
1945 | } | 1945 | } |
1946 | else | 1946 | else |
1947 | { | 1947 | { |
1948 | if (!(opll->mask & OPLL_MASK_TOM) && (MOD (opll,8)->eg_mode != FINISH)) | 1948 | if (!(opll->mask & OPLL_MASK_TOM) && (MOD (opll,8)->eg_mode != FINISH)) |
1949 | r[opll->pan[12]] += calc_slot_tom (MOD (opll,8)); | 1949 | r[opll->pan[12]] += calc_slot_tom (MOD (opll,8)); |
1950 | if (!(opll->mask & OPLL_MASK_CYM) && (CAR (opll,8)->eg_mode != FINISH)) | 1950 | if (!(opll->mask & OPLL_MASK_CYM) && (CAR (opll,8)->eg_mode != FINISH)) |
1951 | r[opll->pan[13]] -= calc_slot_cym (CAR (opll,8), MOD(opll,7)->pgout); | 1951 | r[opll->pan[13]] -= calc_slot_cym (CAR (opll,8), MOD(opll,7)->pgout); |
1952 | } | 1952 | } |
1953 | 1953 | ||
1954 | out[1] = (b[1] + b[3] + ((r[1] + r[3]) << 1)) <<3; | 1954 | out[1] = (b[1] + b[3] + ((r[1] + r[3]) << 1)) <<3; |
1955 | out[0] = (b[2] + b[3] + ((r[2] + r[3]) << 1)) <<3; | 1955 | out[0] = (b[2] + b[3] + ((r[2] + r[3]) << 1)) <<3; |
1956 | } | 1956 | } |
1957 | 1957 | ||
1958 | void | 1958 | void |
1959 | OPLL_calc_stereo (OPLL * opll, e_int32 out[2]) | 1959 | OPLL_calc_stereo (OPLL * opll, e_int32 out[2]) |
1960 | { | 1960 | { |
1961 | if (!opll->quality) | 1961 | if (!opll->quality) |
1962 | { | 1962 | { |
1963 | calc_stereo (opll, out); | 1963 | calc_stereo (opll, out); |
1964 | return; | 1964 | return; |
1965 | } | 1965 | } |
1966 | 1966 | ||
1967 | while (opll->realstep > opll->oplltime) | 1967 | while (opll->realstep > opll->oplltime) |
1968 | { | 1968 | { |
1969 | opll->oplltime += opll->opllstep; | 1969 | opll->oplltime += opll->opllstep; |
1970 | opll->sprev[0] = opll->snext[0]; | 1970 | opll->sprev[0] = opll->snext[0]; |
1971 | opll->sprev[1] = opll->snext[1]; | 1971 | opll->sprev[1] = opll->snext[1]; |
1972 | calc_stereo (opll, opll->snext); | 1972 | calc_stereo (opll, opll->snext); |
1973 | } | 1973 | } |
1974 | 1974 | ||
1975 | opll->oplltime -= opll->realstep; | 1975 | opll->oplltime -= opll->realstep; |
1976 | out[0] = (e_int16) (((double) opll->snext[0] * (opll->opllstep - opll->oplltime) | 1976 | out[0] = (e_int16) (((double) opll->snext[0] * (opll->opllstep - opll->oplltime) |
1977 | + (double) opll->sprev[0] * opll->oplltime) / opll->opllstep); | 1977 | + (double) opll->sprev[0] * opll->oplltime) / opll->opllstep); |
1978 | out[1] = (e_int16) (((double) opll->snext[1] * (opll->opllstep - opll->oplltime) | 1978 | out[1] = (e_int16) (((double) opll->snext[1] * (opll->opllstep - opll->oplltime) |
1979 | + (double) opll->sprev[1] * opll->oplltime) / opll->opllstep); | 1979 | + (double) opll->sprev[1] * opll->oplltime) / opll->opllstep); |
1980 | } | 1980 | } |
1981 | #endif /* EMU2413_COMPACTION */ | 1981 | #endif /* EMU2413_COMPACTION */ |
diff --git a/apps/codecs/libgme/emu2413.h b/apps/codecs/libgme/emu2413.h index 6a19b102a1..254f042957 100644 --- a/apps/codecs/libgme/emu2413.h +++ b/apps/codecs/libgme/emu2413.h | |||
@@ -1,164 +1,164 @@ | |||
1 | #ifndef _EMU2413_H_ | 1 | #ifndef _EMU2413_H_ |
2 | #define _EMU2413_H_ | 2 | #define _EMU2413_H_ |
3 | 3 | ||
4 | #include "blargg_common.h" | 4 | #include "blargg_common.h" |
5 | #include "emutypes.h" | 5 | #include "emutypes.h" |
6 | 6 | ||
7 | #ifdef EMU2413_DLL_EXPORTS | 7 | #ifdef EMU2413_DLL_EXPORTS |
8 | #define EMU2413_API __declspec(dllexport) | 8 | #define EMU2413_API __declspec(dllexport) |
9 | #elif defined(EMU2413_DLL_IMPORTS) | 9 | #elif defined(EMU2413_DLL_IMPORTS) |
10 | #define EMU2413_API __declspec(dllimport) | 10 | #define EMU2413_API __declspec(dllimport) |
11 | #else | 11 | #else |
12 | #define EMU2413_API | 12 | #define EMU2413_API |
13 | #endif | 13 | #endif |
14 | 14 | ||
15 | #ifdef __cplusplus | 15 | #ifdef __cplusplus |
16 | extern "C" { | 16 | extern "C" { |
17 | #endif | 17 | #endif |
18 | 18 | ||
19 | #define AUDIO_MONO_BUFFER_SIZE 1024 | 19 | #define AUDIO_MONO_BUFFER_SIZE 1024 |
20 | 20 | ||
21 | #define PI 3.14159265358979323846 | 21 | #define PI 3.14159265358979323846 |
22 | 22 | ||
23 | enum OPLL_TONE_ENUM {OPLL_2413_TONE=0, OPLL_VRC7_TONE=1, OPLL_281B_TONE=2} ; | 23 | enum OPLL_TONE_ENUM {OPLL_2413_TONE=0, OPLL_VRC7_TONE=1, OPLL_281B_TONE=2} ; |
24 | 24 | ||
25 | /* voice data */ | 25 | /* voice data */ |
26 | typedef struct __OPLL_PATCH { | 26 | typedef struct __OPLL_PATCH { |
27 | e_uint32 TL,FB,EG,ML,AR,DR,SL,RR,KR,KL,AM,PM,WF ; | 27 | e_uint32 TL,FB,EG,ML,AR,DR,SL,RR,KR,KL,AM,PM,WF ; |
28 | } OPLL_PATCH ; | 28 | } OPLL_PATCH ; |
29 | 29 | ||
30 | /* slot */ | 30 | /* slot */ |
31 | typedef struct __OPLL_SLOT { | 31 | typedef struct __OPLL_SLOT { |
32 | 32 | ||
33 | OPLL_PATCH *patch; | 33 | OPLL_PATCH *patch; |
34 | 34 | ||
35 | e_int32 type ; /* 0 : modulator 1 : carrier */ | 35 | e_int32 type ; /* 0 : modulator 1 : carrier */ |
36 | 36 | ||
37 | /* OUTPUT */ | 37 | /* OUTPUT */ |
38 | e_int32 feedback ; | 38 | e_int32 feedback ; |
39 | e_int32 output[2] ; /* Output value of slot */ | 39 | e_int32 output[2] ; /* Output value of slot */ |
40 | 40 | ||
41 | /* for Phase Generator (PG) */ | 41 | /* for Phase Generator (PG) */ |
42 | e_uint16 *sintbl ; /* Wavetable */ | 42 | e_uint16 *sintbl ; /* Wavetable */ |
43 | e_uint32 phase ; /* Phase */ | 43 | e_uint32 phase ; /* Phase */ |
44 | e_uint32 dphase ; /* Phase increment amount */ | 44 | e_uint32 dphase ; /* Phase increment amount */ |
45 | e_uint32 pgout ; /* output */ | 45 | e_uint32 pgout ; /* output */ |
46 | 46 | ||
47 | /* for Envelope Generator (EG) */ | 47 | /* for Envelope Generator (EG) */ |
48 | e_int32 fnum ; /* F-Number */ | 48 | e_int32 fnum ; /* F-Number */ |
49 | e_int32 block ; /* Block */ | 49 | e_int32 block ; /* Block */ |
50 | e_int32 volume ; /* Current volume */ | 50 | e_int32 volume ; /* Current volume */ |
51 | e_int32 sustine ; /* Sustine 1 = ON, 0 = OFF */ | 51 | e_int32 sustine ; /* Sustine 1 = ON, 0 = OFF */ |
52 | e_uint32 tll ; /* Total Level + Key scale level*/ | 52 | e_uint32 tll ; /* Total Level + Key scale level*/ |
53 | e_uint32 rks ; /* Key scale offset (Rks) */ | 53 | e_uint32 rks ; /* Key scale offset (Rks) */ |
54 | e_int32 eg_mode ; /* Current state */ | 54 | e_int32 eg_mode ; /* Current state */ |
55 | e_uint32 eg_phase ; /* Phase */ | 55 | e_uint32 eg_phase ; /* Phase */ |
56 | e_uint32 eg_dphase ; /* Phase increment amount */ | 56 | e_uint32 eg_dphase ; /* Phase increment amount */ |
57 | e_uint32 egout ; /* output */ | 57 | e_uint32 egout ; /* output */ |
58 | 58 | ||
59 | } OPLL_SLOT ; | 59 | } OPLL_SLOT ; |
60 | 60 | ||
61 | /* Mask */ | 61 | /* Mask */ |
62 | #define OPLL_MASK_CH(x) (1<<(x)) | 62 | #define OPLL_MASK_CH(x) (1<<(x)) |
63 | #define OPLL_MASK_HH (1<<(9)) | 63 | #define OPLL_MASK_HH (1<<(9)) |
64 | #define OPLL_MASK_CYM (1<<(10)) | 64 | #define OPLL_MASK_CYM (1<<(10)) |
65 | #define OPLL_MASK_TOM (1<<(11)) | 65 | #define OPLL_MASK_TOM (1<<(11)) |
66 | #define OPLL_MASK_SD (1<<(12)) | 66 | #define OPLL_MASK_SD (1<<(12)) |
67 | #define OPLL_MASK_BD (1<<(13)) | 67 | #define OPLL_MASK_BD (1<<(13)) |
68 | #define OPLL_MASK_RHYTHM ( OPLL_MASK_HH | OPLL_MASK_CYM | OPLL_MASK_TOM | OPLL_MASK_SD | OPLL_MASK_BD ) | 68 | #define OPLL_MASK_RHYTHM ( OPLL_MASK_HH | OPLL_MASK_CYM | OPLL_MASK_TOM | OPLL_MASK_SD | OPLL_MASK_BD ) |
69 | 69 | ||
70 | /* opll */ | 70 | /* opll */ |
71 | typedef struct __OPLL { | 71 | typedef struct __OPLL { |
72 | 72 | ||
73 | e_uint32 adr ; | 73 | e_uint32 adr ; |
74 | e_int32 out ; | 74 | e_int32 out ; |
75 | 75 | ||
76 | #ifndef EMU2413_COMPACTION | 76 | #ifndef EMU2413_COMPACTION |
77 | e_uint32 realstep ; | 77 | e_uint32 realstep ; |
78 | e_uint32 oplltime ; | 78 | e_uint32 oplltime ; |
79 | e_uint32 opllstep ; | 79 | e_uint32 opllstep ; |
80 | e_int32 prev, next ; | 80 | e_int32 prev, next ; |
81 | e_int32 sprev[2],snext[2]; | 81 | e_int32 sprev[2],snext[2]; |
82 | e_uint32 pan[16]; | 82 | e_uint32 pan[16]; |
83 | #endif | 83 | #endif |
84 | 84 | ||
85 | /* Register */ | 85 | /* Register */ |
86 | e_uint8 reg[0x40] ; | 86 | e_uint8 reg[0x40] ; |
87 | e_int32 slot_on_flag[18] ; | 87 | e_int32 slot_on_flag[18] ; |
88 | 88 | ||
89 | /* Pitch Modulator */ | 89 | /* Pitch Modulator */ |
90 | e_uint32 pm_phase ; | 90 | e_uint32 pm_phase ; |
91 | e_int32 lfo_pm ; | 91 | e_int32 lfo_pm ; |
92 | 92 | ||
93 | /* Amp Modulator */ | 93 | /* Amp Modulator */ |
94 | e_int32 am_phase ; | 94 | e_int32 am_phase ; |
95 | e_int32 lfo_am ; | 95 | e_int32 lfo_am ; |
96 | 96 | ||
97 | e_uint32 quality; | 97 | e_uint32 quality; |
98 | 98 | ||
99 | /* Noise Generator */ | 99 | /* Noise Generator */ |
100 | e_uint32 noise_seed ; | 100 | e_uint32 noise_seed ; |
101 | 101 | ||
102 | /* Channel Data */ | 102 | /* Channel Data */ |
103 | e_int32 patch_number[9]; | 103 | e_int32 patch_number[9]; |
104 | e_int32 key_status[9] ; | 104 | e_int32 key_status[9] ; |
105 | 105 | ||
106 | /* Slot */ | 106 | /* Slot */ |
107 | OPLL_SLOT slot[18] ; | 107 | OPLL_SLOT slot[18] ; |
108 | 108 | ||
109 | /* Voice Data */ | 109 | /* Voice Data */ |
110 | OPLL_PATCH patch[19*2] ; | 110 | OPLL_PATCH patch[19*2] ; |
111 | e_int32 patch_update[2] ; /* flag for check patch update */ | 111 | e_int32 patch_update[2] ; /* flag for check patch update */ |
112 | 112 | ||
113 | e_uint32 mask ; | 113 | e_uint32 mask ; |
114 | e_uint32 current_mask; | 114 | e_uint32 current_mask; |
115 | e_uint32 status; | 115 | e_uint32 status; |
116 | 116 | ||
117 | e_uint32 internal_mute; | 117 | e_uint32 internal_mute; |
118 | e_int16 buffer[AUDIO_MONO_BUFFER_SIZE]; | 118 | e_int16 buffer[AUDIO_MONO_BUFFER_SIZE]; |
119 | } OPLL ; | 119 | } OPLL ; |
120 | 120 | ||
121 | /* Create Object */ | 121 | /* Create Object */ |
122 | EMU2413_API void OPLL_new(OPLL *, e_uint32 clk, e_uint32 rate) ; | 122 | EMU2413_API void OPLL_new(OPLL *, e_uint32 clk, e_uint32 rate) ; |
123 | EMU2413_API void OPLL_delete(OPLL *) ; | 123 | EMU2413_API void OPLL_delete(OPLL *) ; |
124 | 124 | ||
125 | /* Setup */ | 125 | /* Setup */ |
126 | EMU2413_API void OPLL_reset(OPLL *) ; | 126 | EMU2413_API void OPLL_reset(OPLL *) ; |
127 | EMU2413_API void OPLL_reset_patch(OPLL *, e_int32) ; | 127 | EMU2413_API void OPLL_reset_patch(OPLL *, e_int32) ; |
128 | EMU2413_API void OPLL_set_rate(OPLL *opll, e_uint32 r) ; | 128 | EMU2413_API void OPLL_set_rate(OPLL *opll, e_uint32 r) ; |
129 | EMU2413_API void OPLL_set_quality(OPLL *opll, e_uint32 q) ; | 129 | EMU2413_API void OPLL_set_quality(OPLL *opll, e_uint32 q) ; |
130 | EMU2413_API void OPLL_set_pan(OPLL *, e_uint32 ch, e_uint32 pan); | 130 | EMU2413_API void OPLL_set_pan(OPLL *, e_uint32 ch, e_uint32 pan); |
131 | EMU2413_API void OPLL_set_internal_mute(OPLL *, e_uint32 mute); | 131 | EMU2413_API void OPLL_set_internal_mute(OPLL *, e_uint32 mute); |
132 | EMU2413_API e_uint32 OPLL_is_internal_muted(OPLL *); | 132 | EMU2413_API e_uint32 OPLL_is_internal_muted(OPLL *); |
133 | 133 | ||
134 | /* Port/Register access */ | 134 | /* Port/Register access */ |
135 | EMU2413_API void OPLL_writeIO(OPLL *, e_uint32 reg, e_uint32 val); | 135 | EMU2413_API void OPLL_writeIO(OPLL *, e_uint32 reg, e_uint32 val); |
136 | EMU2413_API void OPLL_writeReg(OPLL *, e_uint32 reg, e_uint32 val); | 136 | EMU2413_API void OPLL_writeReg(OPLL *, e_uint32 reg, e_uint32 val); |
137 | EMU2413_API e_uint32 OPLL_read(OPLL *, e_uint32 port); | 137 | EMU2413_API e_uint32 OPLL_read(OPLL *, e_uint32 port); |
138 | 138 | ||
139 | /* Synthsize */ | 139 | /* Synthsize */ |
140 | EMU2413_API e_int16 OPLL_calc(OPLL *) EMU2413_CALC_ICODE; | 140 | EMU2413_API e_int16 OPLL_calc(OPLL *) EMU2413_CALC_ICODE; |
141 | EMU2413_API void OPLL_calc_stereo(OPLL *, e_int32 out[2]) ; | 141 | EMU2413_API void OPLL_calc_stereo(OPLL *, e_int32 out[2]) ; |
142 | EMU2413_API e_int16 *OPLL_update_buffer(OPLL *, e_uint32 length) ; | 142 | EMU2413_API e_int16 *OPLL_update_buffer(OPLL *, e_uint32 length) ; |
143 | 143 | ||
144 | /* Misc */ | 144 | /* Misc */ |
145 | EMU2413_API void OPLL_setPatch(OPLL *, const e_uint8 *dump) ; | 145 | EMU2413_API void OPLL_setPatch(OPLL *, const e_uint8 *dump) ; |
146 | EMU2413_API void OPLL_copyPatch(OPLL *, e_int32, OPLL_PATCH *) ; | 146 | EMU2413_API void OPLL_copyPatch(OPLL *, e_int32, OPLL_PATCH *) ; |
147 | EMU2413_API void OPLL_forceRefresh(OPLL *) ; | 147 | EMU2413_API void OPLL_forceRefresh(OPLL *) ; |
148 | /* Utility */ | 148 | /* Utility */ |
149 | EMU2413_API void OPLL_dump2patch(const e_uint8 *dump, OPLL_PATCH *patch) ; | 149 | EMU2413_API void OPLL_dump2patch(const e_uint8 *dump, OPLL_PATCH *patch) ; |
150 | EMU2413_API void OPLL_patch2dump(const OPLL_PATCH *patch, e_uint8 *dump) ; | 150 | EMU2413_API void OPLL_patch2dump(const OPLL_PATCH *patch, e_uint8 *dump) ; |
151 | EMU2413_API void OPLL_getDefaultPatch(e_int32 type, e_int32 num, OPLL_PATCH *) ; | 151 | EMU2413_API void OPLL_getDefaultPatch(e_int32 type, e_int32 num, OPLL_PATCH *) ; |
152 | 152 | ||
153 | /* Channel Mask */ | 153 | /* Channel Mask */ |
154 | EMU2413_API e_uint32 OPLL_setMask(OPLL *, e_uint32 mask) ; | 154 | EMU2413_API e_uint32 OPLL_setMask(OPLL *, e_uint32 mask) ; |
155 | EMU2413_API e_uint32 OPLL_toggleMask(OPLL *, e_uint32 mask) ; | 155 | EMU2413_API e_uint32 OPLL_toggleMask(OPLL *, e_uint32 mask) ; |
156 | 156 | ||
157 | #define dump2patch OPLL_dump2patch | 157 | #define dump2patch OPLL_dump2patch |
158 | 158 | ||
159 | #ifdef __cplusplus | 159 | #ifdef __cplusplus |
160 | } | 160 | } |
161 | #endif | 161 | #endif |
162 | 162 | ||
163 | #endif | 163 | #endif |
164 | 164 | ||
diff --git a/apps/codecs/libgme/emutables.h b/apps/codecs/libgme/emutables.h index e34f100bc4..739c8c390a 100644 --- a/apps/codecs/libgme/emutables.h +++ b/apps/codecs/libgme/emutables.h | |||
@@ -1,210 +1,210 @@ | |||
1 | #ifndef _EMUTABLES_H_ | 1 | #ifndef _EMUTABLES_H_ |
2 | #define _EMUTABLES_H_ | 2 | #define _EMUTABLES_H_ |
3 | 3 | ||
4 | /* Precalculated emu2413 tables for use in Rockbox, | 4 | /* Precalculated emu2413 tables for use in Rockbox, |
5 | Calculated for 44Khz sampling rate */ | 5 | Calculated for 44Khz sampling rate */ |
6 | 6 | ||
7 | #include "emutypes.h" | 7 | #include "emutypes.h" |
8 | 8 | ||
9 | static const e_uint16 sin_coeff[] = { | 9 | static const e_uint16 sin_coeff[] = { |
10 | 255, 203, 171, 152, 139, 129, 120, | 10 | 255, 203, 171, 152, 139, 129, 120, |
11 | 113, 107, 102, 97, 92, 88, 85, | 11 | 113, 107, 102, 97, 92, 88, 85, |
12 | 81, 78, 75, 72, 70, 67, 65, | 12 | 81, 78, 75, 72, 70, 67, 65, |
13 | 63, 61, 59, 57, 55, 53, 52, | 13 | 63, 61, 59, 57, 55, 53, 52, |
14 | 50, 48, 47, 45, 44, 43, 41, | 14 | 50, 48, 47, 45, 44, 43, 41, |
15 | 40, 39, 38, 37, 35, 34, 33, | 15 | 40, 39, 38, 37, 35, 34, 33, |
16 | 32, 31, 30, 29, 28, 28, 27, | 16 | 32, 31, 30, 29, 28, 28, 27, |
17 | 26, 25, 24, 23, 23, 22, 21, | 17 | 26, 25, 24, 23, 23, 22, 21, |
18 | 21, 20, 19, 19, 18, 17, 17, | 18 | 21, 20, 19, 19, 18, 17, 17, |
19 | 16, 16, 15, 14, 14, 13, 13, | 19 | 16, 16, 15, 14, 14, 13, 13, |
20 | 12, 12, 11, 11, 11, 10, 10, | 20 | 12, 12, 11, 11, 11, 10, 10, |
21 | 9, 9, 8, 8, 8, 7, 7, | 21 | 9, 9, 8, 8, 8, 7, 7, |
22 | 7, 6, 6, 6, 5, 5, 5, | 22 | 7, 6, 6, 6, 5, 5, 5, |
23 | 4, 4, 4, 4, 3, 3, 3, | 23 | 4, 4, 4, 4, 3, 3, 3, |
24 | 3, 2, 2, 2, 2, 2, 2, | 24 | 3, 2, 2, 2, 2, 2, 2, |
25 | 1, 1, 1, 1, 1, 1, 1, | 25 | 1, 1, 1, 1, 1, 1, 1, |
26 | 0, 0, 0, 0, 0, 0, 0, | 26 | 0, 0, 0, 0, 0, 0, 0, |
27 | 0, 0, 0, 0, 0, 0, 0, | 27 | 0, 0, 0, 0, 0, 0, 0, |
28 | 0, 0, | 28 | 0, 0, |
29 | }; | 29 | }; |
30 | 30 | ||
31 | static const e_int16 pm_coeff[] = { | 31 | static const e_int16 pm_coeff[] = { |
32 | 256, 256, 256, 256, 256, 256, 256, | 32 | 256, 256, 256, 256, 256, 256, 256, |
33 | 256, 256, 256, 256, 256, 256, 256, | 33 | 256, 256, 256, 256, 256, 256, 256, |
34 | 256, 256, 256, 256, 256, 256, 256, | 34 | 256, 256, 256, 256, 256, 256, 256, |
35 | 256, 256, 256, 256, 256, 256, 256, | 35 | 256, 256, 256, 256, 256, 256, 256, |
36 | 256, 256, 256, 256, 257, 257, 257, | 36 | 256, 256, 256, 256, 257, 257, 257, |
37 | 257, 257, 257, 257, 257, 257, 257, | 37 | 257, 257, 257, 257, 257, 257, 257, |
38 | 257, 257, 257, 257, 257, 257, 257, | 38 | 257, 257, 257, 257, 257, 257, 257, |
39 | 257, 257, 257, 257, 257, 257, 257, | 39 | 257, 257, 257, 257, 257, 257, 257, |
40 | 257, 257, 257, 257, 257, 257, 257, | 40 | 257, 257, 257, 257, 257, 257, 257, |
41 | 258, 258, 258, 257, 257, 257, 257, | 41 | 258, 258, 258, 257, 257, 257, 257, |
42 | 257, 257, 257, 257, 257, 257, 257, | 42 | 257, 257, 257, 257, 257, 257, 257, |
43 | 257, 257, 257, 257, 257, 257, 257, | 43 | 257, 257, 257, 257, 257, 257, 257, |
44 | 257, 257, 257, 257, 257, 257, 257, | 44 | 257, 257, 257, 257, 257, 257, 257, |
45 | 257, 257, 257, 257, 257, 257, 256, | 45 | 257, 257, 257, 257, 257, 257, 256, |
46 | 256, 256, 256, 256, 256, 256, 256, | 46 | 256, 256, 256, 256, 256, 256, 256, |
47 | 256, 256, 256, 256, 256, 256, 256, | 47 | 256, 256, 256, 256, 256, 256, 256, |
48 | 256, 256, 256, 256, 256, 256, 256, | 48 | 256, 256, 256, 256, 256, 256, 256, |
49 | 256, 256, 256, 256, 256, 256, 256, | 49 | 256, 256, 256, 256, 256, 256, 256, |
50 | 256, 256, 256, 255, 255, 255, 255, | 50 | 256, 256, 256, 255, 255, 255, 255, |
51 | 255, 255, 255, 255, 255, 255, 255, | 51 | 255, 255, 255, 255, 255, 255, 255, |
52 | 255, 255, 255, 255, 255, 255, 255, | 52 | 255, 255, 255, 255, 255, 255, 255, |
53 | 255, 255, 255, 255, 255, 255, 255, | 53 | 255, 255, 255, 255, 255, 255, 255, |
54 | 255, 255, 255, 255, 255, 255, 254, | 54 | 255, 255, 255, 255, 255, 255, 254, |
55 | 254, 254, 254, 254, 254, 254, 254, | 55 | 254, 254, 254, 254, 254, 254, 254, |
56 | 254, 254, 254, 254, 254, 254, 254, | 56 | 254, 254, 254, 254, 254, 254, 254, |
57 | 254, 254, 254, 254, 254, 254, 254, | 57 | 254, 254, 254, 254, 254, 254, 254, |
58 | 254, 254, 254, 254, 254, 254, 254, | 58 | 254, 254, 254, 254, 254, 254, 254, |
59 | 254, 254, 254, 253, 254, 254, 254, | 59 | 254, 254, 254, 253, 254, 254, 254, |
60 | 254, 254, 254, 254, 254, 254, 254, | 60 | 254, 254, 254, 254, 254, 254, 254, |
61 | 254, 254, 254, 254, 254, 254, 254, | 61 | 254, 254, 254, 254, 254, 254, 254, |
62 | 254, 254, 254, 254, 254, 254, 254, | 62 | 254, 254, 254, 254, 254, 254, 254, |
63 | 254, 254, 254, 254, 254, 254, 254, | 63 | 254, 254, 254, 254, 254, 254, 254, |
64 | 254, 255, 255, 255, 255, 255, 255, | 64 | 254, 255, 255, 255, 255, 255, 255, |
65 | 255, 255, 255, 255, 255, 255, 255, | 65 | 255, 255, 255, 255, 255, 255, 255, |
66 | 255, 255, 255, 255, 255, 255, 255, | 66 | 255, 255, 255, 255, 255, 255, 255, |
67 | 255, 255, 255, 255, 255, 255, 255, | 67 | 255, 255, 255, 255, 255, 255, 255, |
68 | 255, 255, 255, 255, | 68 | 255, 255, 255, 255, |
69 | }; | 69 | }; |
70 | 70 | ||
71 | static const e_int8 am_coeff[] = { | 71 | static const e_int8 am_coeff[] = { |
72 | 13, 13, 13, 13, 13, 14, 14, | 72 | 13, 13, 13, 13, 13, 14, 14, |
73 | 14, 14, 14, 15, 15, 15, 15, | 73 | 14, 14, 14, 15, 15, 15, 15, |
74 | 15, 16, 16, 16, 16, 16, 17, | 74 | 15, 16, 16, 16, 16, 16, 17, |
75 | 17, 17, 17, 17, 18, 18, 18, | 75 | 17, 17, 17, 17, 18, 18, 18, |
76 | 18, 18, 19, 19, 19, 19, 19, | 76 | 18, 18, 19, 19, 19, 19, 19, |
77 | 20, 20, 20, 20, 20, 21, 21, | 77 | 20, 20, 20, 20, 20, 21, 21, |
78 | 21, 21, 21, 22, 22, 22, 22, | 78 | 21, 21, 21, 22, 22, 22, 22, |
79 | 22, 23, 23, 23, 23, 23, 24, | 79 | 22, 23, 23, 23, 23, 23, 24, |
80 | 24, 24, 24, 24, 25, 25, 25, | 80 | 24, 24, 24, 24, 25, 25, 25, |
81 | 25, 26, 25, 25, 25, 25, 24, | 81 | 25, 26, 25, 25, 25, 25, 24, |
82 | 24, 24, 24, 24, 23, 23, 23, | 82 | 24, 24, 24, 24, 23, 23, 23, |
83 | 23, 23, 22, 22, 22, 22, 22, | 83 | 23, 23, 22, 22, 22, 22, 22, |
84 | 21, 21, 21, 21, 21, 20, 20, | 84 | 21, 21, 21, 21, 21, 20, 20, |
85 | 20, 20, 20, 19, 19, 19, 19, | 85 | 20, 20, 20, 19, 19, 19, 19, |
86 | 19, 18, 18, 18, 18, 18, 17, | 86 | 19, 18, 18, 18, 18, 18, 17, |
87 | 17, 17, 17, 17, 16, 16, 16, | 87 | 17, 17, 17, 17, 16, 16, 16, |
88 | 16, 16, 15, 15, 15, 15, 15, | 88 | 16, 16, 15, 15, 15, 15, 15, |
89 | 14, 14, 14, 14, 14, 13, 13, | 89 | 14, 14, 14, 14, 14, 13, 13, |
90 | 13, 13, 13, 12, 12, 12, 12, | 90 | 13, 13, 13, 12, 12, 12, 12, |
91 | 11, 11, 11, 11, 11, 10, 10, | 91 | 11, 11, 11, 11, 11, 10, 10, |
92 | 10, 10, 10, 9, 9, 9, 9, | 92 | 10, 10, 10, 9, 9, 9, 9, |
93 | 9, 8, 8, 8, 8, 8, 7, | 93 | 9, 8, 8, 8, 8, 8, 7, |
94 | 7, 7, 7, 7, 6, 6, 6, | 94 | 7, 7, 7, 7, 6, 6, 6, |
95 | 6, 6, 5, 5, 5, 5, 5, | 95 | 6, 6, 5, 5, 5, 5, 5, |
96 | 4, 4, 4, 4, 4, 3, 3, | 96 | 4, 4, 4, 4, 4, 3, 3, |
97 | 3, 3, 3, 2, 2, 2, 2, | 97 | 3, 3, 3, 2, 2, 2, 2, |
98 | 2, 1, 1, 1, 1, 1, 0, | 98 | 2, 1, 1, 1, 1, 1, 0, |
99 | 0, 0, 0, 0, 0, 0, 0, | 99 | 0, 0, 0, 0, 0, 0, 0, |
100 | 0, 1, 1, 1, 1, 1, 2, | 100 | 0, 1, 1, 1, 1, 1, 2, |
101 | 2, 2, 2, 2, 3, 3, 3, | 101 | 2, 2, 2, 2, 3, 3, 3, |
102 | 3, 3, 4, 4, 4, 4, 4, | 102 | 3, 3, 4, 4, 4, 4, 4, |
103 | 5, 5, 5, 5, 5, 6, 6, | 103 | 5, 5, 5, 5, 5, 6, 6, |
104 | 6, 6, 6, 7, 7, 7, 7, | 104 | 6, 6, 6, 7, 7, 7, 7, |
105 | 7, 8, 8, 8, 8, 8, 9, | 105 | 7, 8, 8, 8, 8, 8, 9, |
106 | 9, 9, 9, 9, 10, 10, 10, | 106 | 9, 9, 9, 9, 10, 10, 10, |
107 | 10, 10, 11, 11, 11, 11, 11, | 107 | 10, 10, 11, 11, 11, 11, 11, |
108 | 12, 12, 12, 12, | 108 | 12, 12, 12, 12, |
109 | }; | 109 | }; |
110 | 110 | ||
111 | static const e_int16 db2lin_coeff[] = { | 111 | static const e_int16 db2lin_coeff[] = { |
112 | 255, 249, 244, 239, 233, 228, 224, | 112 | 255, 249, 244, 239, 233, 228, 224, |
113 | 219, 214, 209, 205, 201, 196, 192, | 113 | 219, 214, 209, 205, 201, 196, 192, |
114 | 188, 184, 180, 176, 172, 169, 165, | 114 | 188, 184, 180, 176, 172, 169, 165, |
115 | 162, 158, 155, 151, 148, 145, 142, | 115 | 162, 158, 155, 151, 148, 145, 142, |
116 | 139, 136, 133, 130, 127, 125, 122, | 116 | 139, 136, 133, 130, 127, 125, 122, |
117 | 119, 117, 114, 112, 109, 107, 105, | 117 | 119, 117, 114, 112, 109, 107, 105, |
118 | 102, 100, 98, 96, 94, 92, 90, | 118 | 102, 100, 98, 96, 94, 92, 90, |
119 | 88, 86, 84, 82, 81, 79, 77, | 119 | 88, 86, 84, 82, 81, 79, 77, |
120 | 76, 74, 72, 71, 69, 68, 66, | 120 | 76, 74, 72, 71, 69, 68, 66, |
121 | 65, 64, 62, 61, 60, 58, 57, | 121 | 65, 64, 62, 61, 60, 58, 57, |
122 | 56, 55, 53, 52, 51, 50, 49, | 122 | 56, 55, 53, 52, 51, 50, 49, |
123 | 48, 47, 46, 45, 44, 43, 42, | 123 | 48, 47, 46, 45, 44, 43, 42, |
124 | 41, 40, 39, 38, 38, 37, 36, | 124 | 41, 40, 39, 38, 38, 37, 36, |
125 | 35, 34, 34, 33, 32, 32, 31, | 125 | 35, 34, 34, 33, 32, 32, 31, |
126 | 30, 30, 29, 28, 28, 27, 27, | 126 | 30, 30, 29, 28, 28, 27, 27, |
127 | 26, 25, 25, 24, 24, 23, 23, | 127 | 26, 25, 25, 24, 24, 23, 23, |
128 | 22, 22, 21, 21, 20, 20, 19, | 128 | 22, 22, 21, 21, 20, 20, 19, |
129 | 19, 19, 18, 18, 17, 17, 17, | 129 | 19, 19, 18, 18, 17, 17, 17, |
130 | 16, 16, 16, 15, 15, 15, 14, | 130 | 16, 16, 16, 15, 15, 15, 14, |
131 | 14, 14, 13, 13, 13, 12, 12, | 131 | 14, 14, 13, 13, 13, 12, 12, |
132 | 12, 12, 11, 11, 11, 11, 10, | 132 | 12, 12, 11, 11, 11, 11, 10, |
133 | 10, 10, 10, 10, 9, 9, 9, | 133 | 10, 10, 10, 10, 9, 9, 9, |
134 | 9, 8, 8, 8, 8, 8, 8, | 134 | 9, 8, 8, 8, 8, 8, 8, |
135 | 7, 7, 7, 7, 7, 7, 6, | 135 | 7, 7, 7, 7, 7, 7, 6, |
136 | 6, 6, 6, 6, 6, 6, 5, | 136 | 6, 6, 6, 6, 6, 6, 5, |
137 | 5, 5, 5, 5, 5, 5, 5, | 137 | 5, 5, 5, 5, 5, 5, 5, |
138 | 5, 4, 4, 4, 4, 4, 4, | 138 | 5, 4, 4, 4, 4, 4, 4, |
139 | 4, 4, 4, 4, 3, 3, 3, | 139 | 4, 4, 4, 4, 3, 3, 3, |
140 | 3, 3, 3, 3, 3, 3, 3, | 140 | 3, 3, 3, 3, 3, 3, 3, |
141 | 3, 3, 3, 2, 2, 2, 2, | 141 | 3, 3, 3, 2, 2, 2, 2, |
142 | 2, 2, 2, 2, 2, 2, 2, | 142 | 2, 2, 2, 2, 2, 2, 2, |
143 | 2, 2, 2, 2, 2, 2, 2, | 143 | 2, 2, 2, 2, 2, 2, 2, |
144 | 2, 1, 1, 1, 1, 1, 1, | 144 | 2, 1, 1, 1, 1, 1, 1, |
145 | 1, 1, 1, 1, 1, 1, 1, | 145 | 1, 1, 1, 1, 1, 1, 1, |
146 | 1, 1, 1, 1, 1, 1, 1, | 146 | 1, 1, 1, 1, 1, 1, 1, |
147 | 1, 1, 1, 1, 1, 1, 1, | 147 | 1, 1, 1, 1, 1, 1, 1, |
148 | 1, 1, 1, 1, 1, 0, 0, | 148 | 1, 1, 1, 1, 1, 0, 0, |
149 | 0, 0, 0, 0, 0, 0, 0, | 149 | 0, 0, 0, 0, 0, 0, 0, |
150 | 0, 0, 0, 0, 0, 0, 0, | 150 | 0, 0, 0, 0, 0, 0, 0, |
151 | 0, 0, 0, 0, 0, 0, 0, | 151 | 0, 0, 0, 0, 0, 0, 0, |
152 | 0, 0, 0, 0, 0, 0, 0, | 152 | 0, 0, 0, 0, 0, 0, 0, |
153 | 0, 0, 0, 0, 0, 0, 0, | 153 | 0, 0, 0, 0, 0, 0, 0, |
154 | 0, 0, 0, 0, 0, 0, 0, | 154 | 0, 0, 0, 0, 0, 0, 0, |
155 | 0, 0, 0, 0, 0, 0, 0, | 155 | 0, 0, 0, 0, 0, 0, 0, |
156 | 0, 0, 0, 0, 0, 0, 0, | 156 | 0, 0, 0, 0, 0, 0, 0, |
157 | 0, 0, 0, 0, 0, 0, 0, | 157 | 0, 0, 0, 0, 0, 0, 0, |
158 | 0, 0, 0, 0, 0, 0, 0, | 158 | 0, 0, 0, 0, 0, 0, 0, |
159 | 0, 0, 0, 0, 0, 0, 0, | 159 | 0, 0, 0, 0, 0, 0, 0, |
160 | 0, 0, 0, 0, 0, 0, 0, | 160 | 0, 0, 0, 0, 0, 0, 0, |
161 | 0, 0, 0, 0, 0, 0, 0, | 161 | 0, 0, 0, 0, 0, 0, 0, |
162 | 0, 0, 0, 0, 0, 0, 0, | 162 | 0, 0, 0, 0, 0, 0, 0, |
163 | 0, 0, 0, 0, 0, 0, 0, | 163 | 0, 0, 0, 0, 0, 0, 0, |
164 | 0, 0, 0, 0, 0, 0, 0, | 164 | 0, 0, 0, 0, 0, 0, 0, |
165 | 0, 0, 0, 0, 0, 0, 0, | 165 | 0, 0, 0, 0, 0, 0, 0, |
166 | 0, 0, 0, 0, 0, 0, 0, | 166 | 0, 0, 0, 0, 0, 0, 0, |
167 | 0, 0, 0, 0, 0, 0, 0, | 167 | 0, 0, 0, 0, 0, 0, 0, |
168 | 0, 0, 0, 0, 0, 0, 0, | 168 | 0, 0, 0, 0, 0, 0, 0, |
169 | 0, 0, 0, 0, 0, 0, 0, | 169 | 0, 0, 0, 0, 0, 0, 0, |
170 | 0, 0, 0, 0, 0, 0, 0, | 170 | 0, 0, 0, 0, 0, 0, 0, |
171 | 0, 0, 0, 0, 0, 0, 0, | 171 | 0, 0, 0, 0, 0, 0, 0, |
172 | 0, 0, 0, 0, 0, 0, 0, | 172 | 0, 0, 0, 0, 0, 0, 0, |
173 | 0, 0, 0, 0, 0, 0, 0, | 173 | 0, 0, 0, 0, 0, 0, 0, |
174 | 0, 0, 0, 0, 0, 0, 0, | 174 | 0, 0, 0, 0, 0, 0, 0, |
175 | 0, 0, 0, 0, 0, 0, 0, | 175 | 0, 0, 0, 0, 0, 0, 0, |
176 | 0, 0, 0, 0, 0, 0, 0, | 176 | 0, 0, 0, 0, 0, 0, 0, |
177 | 0, 0, 0, 0, 0, 0, 0, | 177 | 0, 0, 0, 0, 0, 0, 0, |
178 | 0, 0, 0, 0, 0, 0, 0, | 178 | 0, 0, 0, 0, 0, 0, 0, |
179 | 0, 0, 0, 0, 0, 0, 0, | 179 | 0, 0, 0, 0, 0, 0, 0, |
180 | 0, 0, 0, 0, 0, 0, 0, | 180 | 0, 0, 0, 0, 0, 0, 0, |
181 | 0, 0, 0, 0, 0, 0, 0, | 181 | 0, 0, 0, 0, 0, 0, 0, |
182 | 0, 0, 0, 0, 0, 0, 0, | 182 | 0, 0, 0, 0, 0, 0, 0, |
183 | 0, 0, 0, 0, 0, 0, 0, | 183 | 0, 0, 0, 0, 0, 0, 0, |
184 | 0, 0, 0, 0, 0, 0, 0, | 184 | 0, 0, 0, 0, 0, 0, 0, |
185 | 0, | 185 | 0, |
186 | }; | 186 | }; |
187 | 187 | ||
188 | static const e_uint16 ar_adjust_coeff[] = { | 188 | static const e_uint16 ar_adjust_coeff[] = { |
189 | 127, 108, 98, 90, 84, 80, 75, | 189 | 127, 108, 98, 90, 84, 80, 75, |
190 | 72, 69, 66, 64, 61, 59, 57, | 190 | 72, 69, 66, 64, 61, 59, 57, |
191 | 56, 54, 52, 51, 49, 48, 47, | 191 | 56, 54, 52, 51, 49, 48, 47, |
192 | 45, 44, 43, 42, 41, 40, 39, | 192 | 45, 44, 43, 42, 41, 40, 39, |
193 | 38, 37, 36, 36, 35, 34, 33, | 193 | 38, 37, 36, 36, 35, 34, 33, |
194 | 33, 32, 31, 30, 30, 29, 29, | 194 | 33, 32, 31, 30, 30, 29, 29, |
195 | 28, 27, 27, 26, 26, 25, 24, | 195 | 28, 27, 27, 26, 26, 25, 24, |
196 | 24, 23, 23, 22, 22, 21, 21, | 196 | 24, 23, 23, 22, 22, 21, 21, |
197 | 21, 20, 20, 19, 19, 18, 18, | 197 | 21, 20, 20, 19, 19, 18, 18, |
198 | 17, 17, 17, 16, 16, 15, 15, | 198 | 17, 17, 17, 16, 16, 15, 15, |
199 | 15, 14, 14, 14, 13, 13, 13, | 199 | 15, 14, 14, 14, 13, 13, 13, |
200 | 12, 12, 12, 11, 11, 11, 10, | 200 | 12, 12, 12, 11, 11, 11, 10, |
201 | 10, 10, 9, 9, 9, 9, 8, | 201 | 10, 10, 9, 9, 9, 9, 8, |
202 | 8, 8, 7, 7, 7, 7, 6, | 202 | 8, 8, 7, 7, 7, 7, 6, |
203 | 6, 6, 6, 5, 5, 5, 4, | 203 | 6, 6, 6, 5, 5, 5, 4, |
204 | 4, 4, 4, 4, 3, 3, 3, | 204 | 4, 4, 4, 4, 3, 3, 3, |
205 | 3, 2, 2, 2, 2, 1, 1, | 205 | 3, 2, 2, 2, 2, 1, 1, |
206 | 1, 1, 1, 0, 0, 0, 0, | 206 | 1, 1, 1, 0, 0, 0, 0, |
207 | 0, | 207 | 0, |
208 | }; | 208 | }; |
209 | 209 | ||
210 | #endif | 210 | #endif |
diff --git a/apps/codecs/libgme/emutypes.h b/apps/codecs/libgme/emutypes.h index bf5d7e1bf2..bc523db072 100644 --- a/apps/codecs/libgme/emutypes.h +++ b/apps/codecs/libgme/emutypes.h | |||
@@ -1,41 +1,41 @@ | |||
1 | #ifndef _EMUTYPES_H_ | 1 | #ifndef _EMUTYPES_H_ |
2 | #define _EMUTYPES_H_ | 2 | #define _EMUTYPES_H_ |
3 | 3 | ||
4 | #if defined(_MSC_VER) | 4 | #if defined(_MSC_VER) |
5 | #define INLINE __forceinline | 5 | #define INLINE __forceinline |
6 | #elif defined(__GNUC__) | 6 | #elif defined(__GNUC__) |
7 | #define INLINE __inline__ | 7 | #define INLINE __inline__ |
8 | #elif defined(_MWERKS_) | 8 | #elif defined(_MWERKS_) |
9 | #define INLINE inline | 9 | #define INLINE inline |
10 | #else | 10 | #else |
11 | #define INLINE | 11 | #define INLINE |
12 | #endif | 12 | #endif |
13 | 13 | ||
14 | #if defined(EMU_DLL_IMPORTS) | 14 | #if defined(EMU_DLL_IMPORTS) |
15 | #define EMU2149_DLL_IMPORTS | 15 | #define EMU2149_DLL_IMPORTS |
16 | #define EMU2212_DLL_IMPORTS | 16 | #define EMU2212_DLL_IMPORTS |
17 | #define EMU2413_DLL_IMPORTS | 17 | #define EMU2413_DLL_IMPORTS |
18 | #define EMU8950_DLL_IMPORTS | 18 | #define EMU8950_DLL_IMPORTS |
19 | #define EMU76489_DLL_IMPORTS | 19 | #define EMU76489_DLL_IMPORTS |
20 | #endif | 20 | #endif |
21 | 21 | ||
22 | #ifdef __cplusplus | 22 | #ifdef __cplusplus |
23 | extern "C" { | 23 | extern "C" { |
24 | #endif | 24 | #endif |
25 | 25 | ||
26 | typedef unsigned int e_uint; | 26 | typedef unsigned int e_uint; |
27 | typedef signed int e_int; | 27 | typedef signed int e_int; |
28 | 28 | ||
29 | typedef unsigned char e_uint8 ; | 29 | typedef unsigned char e_uint8 ; |
30 | typedef signed char e_int8 ; | 30 | typedef signed char e_int8 ; |
31 | 31 | ||
32 | typedef unsigned short e_uint16 ; | 32 | typedef unsigned short e_uint16 ; |
33 | typedef signed short e_int16 ; | 33 | typedef signed short e_int16 ; |
34 | 34 | ||
35 | typedef unsigned int e_uint32 ; | 35 | typedef unsigned int e_uint32 ; |
36 | typedef signed int e_int32 ; | 36 | typedef signed int e_int32 ; |
37 | 37 | ||
38 | #ifdef __cplusplus | 38 | #ifdef __cplusplus |
39 | } | 39 | } |
40 | #endif | 40 | #endif |
41 | #endif | 41 | #endif |
diff --git a/apps/codecs/libgme/hes_apu_adpcm.c b/apps/codecs/libgme/hes_apu_adpcm.c index 69ac7120d0..de9b894f5d 100644 --- a/apps/codecs/libgme/hes_apu_adpcm.c +++ b/apps/codecs/libgme/hes_apu_adpcm.c | |||
@@ -1,297 +1,297 @@ | |||
1 | // Game_Music_Emu 0.6-pre. http://www.slack.net/~ant/ | 1 | // Game_Music_Emu 0.6-pre. http://www.slack.net/~ant/ |
2 | 2 | ||
3 | #include "hes_apu_adpcm.h" | 3 | #include "hes_apu_adpcm.h" |
4 | 4 | ||
5 | /* Copyright (C) 2006-2008 Shay Green. This module is free software; you | 5 | /* Copyright (C) 2006-2008 Shay Green. This module is free software; you |
6 | can redistribute it and/or modify it under the terms of the GNU Lesser | 6 | can redistribute it and/or modify it under the terms of the GNU Lesser |
7 | General Public License as published by the Free Software Foundation; either | 7 | General Public License as published by the Free Software Foundation; either |
8 | version 2.1 of the License, or (at your option) any later version. This | 8 | version 2.1 of the License, or (at your option) any later version. This |
9 | module is distributed in the hope that it will be useful, but WITHOUT ANY | 9 | module is distributed in the hope that it will be useful, but WITHOUT ANY |
10 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | 10 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
11 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more | 11 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
12 | details. You should have received a copy of the GNU Lesser General Public | 12 | details. You should have received a copy of the GNU Lesser General Public |
13 | License along with this module; if not, write to the Free Software Foundation, | 13 | License along with this module; if not, write to the Free Software Foundation, |
14 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ | 14 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ |
15 | 15 | ||
16 | 16 | ||
17 | void Adpcm_init( struct Hes_Apu_Adpcm* this ) | 17 | void Adpcm_init( struct Hes_Apu_Adpcm* this ) |
18 | { | 18 | { |
19 | this->output = NULL; | 19 | this->output = NULL; |
20 | memset( &this->state, 0, sizeof( this->state ) ); | 20 | memset( &this->state, 0, sizeof( this->state ) ); |
21 | Adpcm_reset( this ); | 21 | Adpcm_reset( this ); |
22 | } | 22 | } |
23 | 23 | ||
24 | void Adpcm_reset( struct Hes_Apu_Adpcm* this ) | 24 | void Adpcm_reset( struct Hes_Apu_Adpcm* this ) |
25 | { | 25 | { |
26 | this->last_time = 0; | 26 | this->last_time = 0; |
27 | this->next_timer = 0; | 27 | this->next_timer = 0; |
28 | this->last_amp = 0; | 28 | this->last_amp = 0; |
29 | 29 | ||
30 | memset( &this->state.pcmbuf, 0, sizeof(this->state.pcmbuf) ); | 30 | memset( &this->state.pcmbuf, 0, sizeof(this->state.pcmbuf) ); |
31 | memset( &this->state.port, 0, sizeof(this->state.port) ); | 31 | memset( &this->state.port, 0, sizeof(this->state.port) ); |
32 | 32 | ||
33 | this->state.ad_sample = 0; | 33 | this->state.ad_sample = 0; |
34 | this->state.ad_ref_index = 0; | 34 | this->state.ad_ref_index = 0; |
35 | 35 | ||
36 | this->state.addr = 0; | 36 | this->state.addr = 0; |
37 | this->state.freq = 0; | 37 | this->state.freq = 0; |
38 | this->state.writeptr = 0; | 38 | this->state.writeptr = 0; |
39 | this->state.readptr = 0; | 39 | this->state.readptr = 0; |
40 | this->state.playflag = 0; | 40 | this->state.playflag = 0; |
41 | this->state.repeatflag = 0; | 41 | this->state.repeatflag = 0; |
42 | this->state.length = 0; | 42 | this->state.length = 0; |
43 | this->state.volume = 0xFF; | 43 | this->state.volume = 0xFF; |
44 | this->state.fadetimer = 0; | 44 | this->state.fadetimer = 0; |
45 | this->state.fadecount = 0; | 45 | this->state.fadecount = 0; |
46 | } | 46 | } |
47 | 47 | ||
48 | static short stepsize[49] = { | 48 | static short stepsize[49] = { |
49 | 16, 17, 19, 21, 23, 25, 28, | 49 | 16, 17, 19, 21, 23, 25, 28, |
50 | 31, 34, 37, 41, 45, 50, 55, | 50 | 31, 34, 37, 41, 45, 50, 55, |
51 | 60, 66, 73, 80, 88, 97, 107, | 51 | 60, 66, 73, 80, 88, 97, 107, |
52 | 118, 130, 143, 157, 173, 190, 209, | 52 | 118, 130, 143, 157, 173, 190, 209, |
53 | 230, 253, 279, 307, 337, 371, 408, | 53 | 230, 253, 279, 307, 337, 371, 408, |
54 | 449, 494, 544, 598, 658, 724, 796, | 54 | 449, 494, 544, 598, 658, 724, 796, |
55 | 876, 963,1060,1166,1282,1411,1552 | 55 | 876, 963,1060,1166,1282,1411,1552 |
56 | }; | 56 | }; |
57 | 57 | ||
58 | static int Adpcm_decode( struct Hes_Apu_Adpcm* this,int code ); | 58 | static int Adpcm_decode( struct Hes_Apu_Adpcm* this,int code ); |
59 | static int Adpcm_decode( struct Hes_Apu_Adpcm* this,int code ) | 59 | static int Adpcm_decode( struct Hes_Apu_Adpcm* this,int code ) |
60 | { | 60 | { |
61 | struct State* state = &this->state; | 61 | struct State* state = &this->state; |
62 | int step = stepsize[state->ad_ref_index]; | 62 | int step = stepsize[state->ad_ref_index]; |
63 | int delta; | 63 | int delta; |
64 | int c = code & 7; | 64 | int c = code & 7; |
65 | #if 1 | 65 | #if 1 |
66 | delta = 0; | 66 | delta = 0; |
67 | if ( c & 4 ) delta += step; | 67 | if ( c & 4 ) delta += step; |
68 | step >>= 1; | 68 | step >>= 1; |
69 | if ( c & 2 ) delta += step; | 69 | if ( c & 2 ) delta += step; |
70 | step >>= 1; | 70 | step >>= 1; |
71 | if ( c & 1 ) delta += step; | 71 | if ( c & 1 ) delta += step; |
72 | step >>= 1; | 72 | step >>= 1; |
73 | delta += step; | 73 | delta += step; |
74 | #else | 74 | #else |
75 | delta = ( ( c + c + 1 ) * step ) / 8; // maybe faster, but introduces rounding | 75 | delta = ( ( c + c + 1 ) * step ) / 8; // maybe faster, but introduces rounding |
76 | #endif | 76 | #endif |
77 | if ( c != code ) | 77 | if ( c != code ) |
78 | { | 78 | { |
79 | state->ad_sample -= delta; | 79 | state->ad_sample -= delta; |
80 | if ( state->ad_sample < -2048 ) | 80 | if ( state->ad_sample < -2048 ) |
81 | state->ad_sample = -2048; | 81 | state->ad_sample = -2048; |
82 | } | 82 | } |
83 | else | 83 | else |
84 | { | 84 | { |
85 | state->ad_sample += delta; | 85 | state->ad_sample += delta; |
86 | if ( state->ad_sample > 2047 ) | 86 | if ( state->ad_sample > 2047 ) |
87 | state->ad_sample = 2047; | 87 | state->ad_sample = 2047; |
88 | } | 88 | } |
89 | 89 | ||
90 | static int const steps [8] = { | 90 | static int const steps [8] = { |
91 | -1, -1, -1, -1, 2, 4, 6, 8 | 91 | -1, -1, -1, -1, 2, 4, 6, 8 |
92 | }; | 92 | }; |
93 | state->ad_ref_index += steps [c]; | 93 | state->ad_ref_index += steps [c]; |
94 | if ( state->ad_ref_index < 0 ) | 94 | if ( state->ad_ref_index < 0 ) |
95 | state->ad_ref_index = 0; | 95 | state->ad_ref_index = 0; |
96 | else if ( state->ad_ref_index > 48 ) | 96 | else if ( state->ad_ref_index > 48 ) |
97 | state->ad_ref_index = 48; | 97 | state->ad_ref_index = 48; |
98 | 98 | ||
99 | return state->ad_sample; | 99 | return state->ad_sample; |
100 | } | 100 | } |
101 | 101 | ||
102 | static void Adpcm_run_until( struct Hes_Apu_Adpcm* this, blip_time_t end_time ); | 102 | static void Adpcm_run_until( struct Hes_Apu_Adpcm* this, blip_time_t end_time ); |
103 | static void Adpcm_run_until( struct Hes_Apu_Adpcm* this, blip_time_t end_time ) | 103 | static void Adpcm_run_until( struct Hes_Apu_Adpcm* this, blip_time_t end_time ) |
104 | { | 104 | { |
105 | struct State* state = &this->state; | 105 | struct State* state = &this->state; |
106 | int volume = state->volume; | 106 | int volume = state->volume; |
107 | int fadetimer = state->fadetimer; | 107 | int fadetimer = state->fadetimer; |
108 | int fadecount = state->fadecount; | 108 | int fadecount = state->fadecount; |
109 | int last_time = this->last_time; | 109 | int last_time = this->last_time; |
110 | int next_timer = this->next_timer; | 110 | int next_timer = this->next_timer; |
111 | int last_amp = this->last_amp; | 111 | int last_amp = this->last_amp; |
112 | 112 | ||
113 | struct Blip_Buffer* output = this->output; // cache often-used values | 113 | struct Blip_Buffer* output = this->output; // cache often-used values |
114 | 114 | ||
115 | while ( state->playflag && last_time < end_time ) | 115 | while ( state->playflag && last_time < end_time ) |
116 | { | 116 | { |
117 | while ( last_time >= next_timer ) | 117 | while ( last_time >= next_timer ) |
118 | { | 118 | { |
119 | if ( fadetimer ) | 119 | if ( fadetimer ) |
120 | { | 120 | { |
121 | if ( fadecount > 0 ) | 121 | if ( fadecount > 0 ) |
122 | { | 122 | { |
123 | fadecount--; | 123 | fadecount--; |
124 | volume = 0xFF * fadecount / fadetimer; | 124 | volume = 0xFF * fadecount / fadetimer; |
125 | } | 125 | } |
126 | else if ( fadecount < 0 ) | 126 | else if ( fadecount < 0 ) |
127 | { | 127 | { |
128 | fadecount++; | 128 | fadecount++; |
129 | volume = 0xFF - ( 0xFF * fadecount / fadetimer ); | 129 | volume = 0xFF - ( 0xFF * fadecount / fadetimer ); |
130 | } | 130 | } |
131 | } | 131 | } |
132 | next_timer += 7159; // 7159091/1000; | 132 | next_timer += 7159; // 7159091/1000; |
133 | } | 133 | } |
134 | int amp; | 134 | int amp; |
135 | if ( state->ad_low_nibble ) | 135 | if ( state->ad_low_nibble ) |
136 | { | 136 | { |
137 | amp = Adpcm_decode( this, state->pcmbuf[ state->playptr ] & 0x0F ); | 137 | amp = Adpcm_decode( this, state->pcmbuf[ state->playptr ] & 0x0F ); |
138 | state->ad_low_nibble = false; | 138 | state->ad_low_nibble = false; |
139 | state->playptr++; | 139 | state->playptr++; |
140 | state->playedsamplecount++; | 140 | state->playedsamplecount++; |
141 | if ( state->playedsamplecount == state->playlength ) | 141 | if ( state->playedsamplecount == state->playlength ) |
142 | { | 142 | { |
143 | state->playflag = 0; | 143 | state->playflag = 0; |
144 | } | 144 | } |
145 | } | 145 | } |
146 | else | 146 | else |
147 | { | 147 | { |
148 | amp = Adpcm_decode( this, state->pcmbuf[ state->playptr ] >> 4 ); | 148 | amp = Adpcm_decode( this, state->pcmbuf[ state->playptr ] >> 4 ); |
149 | state->ad_low_nibble = true; | 149 | state->ad_low_nibble = true; |
150 | } | 150 | } |
151 | amp = amp * volume / 0xFF; | 151 | amp = amp * volume / 0xFF; |
152 | int delta = amp - last_amp; | 152 | int delta = amp - last_amp; |
153 | if ( output && delta ) | 153 | if ( output && delta ) |
154 | { | 154 | { |
155 | last_amp = amp; | 155 | last_amp = amp; |
156 | Synth_offset_inline( &this->synth, last_time, delta, output ); | 156 | Synth_offset_inline( &this->synth, last_time, delta, output ); |
157 | } | 157 | } |
158 | last_time += state->freq; | 158 | last_time += state->freq; |
159 | } | 159 | } |
160 | 160 | ||
161 | if ( !state->playflag ) | 161 | if ( !state->playflag ) |
162 | { | 162 | { |
163 | while ( next_timer <= end_time ) next_timer += 7159; // 7159091/1000 | 163 | while ( next_timer <= end_time ) next_timer += 7159; // 7159091/1000 |
164 | last_time = end_time; | 164 | last_time = end_time; |
165 | } | 165 | } |
166 | 166 | ||
167 | this->last_time = last_time; | 167 | this->last_time = last_time; |
168 | this->next_timer = next_timer; | 168 | this->next_timer = next_timer; |
169 | this->last_amp = last_amp; | 169 | this->last_amp = last_amp; |
170 | state->volume = volume; | 170 | state->volume = volume; |
171 | state->fadetimer = fadetimer; | 171 | state->fadetimer = fadetimer; |
172 | state->fadecount = fadecount; | 172 | state->fadecount = fadecount; |
173 | } | 173 | } |
174 | 174 | ||
175 | void Adpcm_write_data( struct Hes_Apu_Adpcm* this, blip_time_t time, int addr, int data ) | 175 | void Adpcm_write_data( struct Hes_Apu_Adpcm* this, blip_time_t time, int addr, int data ) |
176 | { | 176 | { |
177 | if ( time > this->last_time ) Adpcm_run_until( this, time ); | 177 | if ( time > this->last_time ) Adpcm_run_until( this, time ); |
178 | struct State* state = &this->state; | 178 | struct State* state = &this->state; |
179 | 179 | ||
180 | data &= 0xFF; | 180 | data &= 0xFF; |
181 | state->port[ addr & 15 ] = data; | 181 | state->port[ addr & 15 ] = data; |
182 | switch ( addr & 15 ) | 182 | switch ( addr & 15 ) |
183 | { | 183 | { |
184 | case 8: | 184 | case 8: |
185 | state->addr &= 0xFF00; | 185 | state->addr &= 0xFF00; |
186 | state->addr |= data; | 186 | state->addr |= data; |
187 | break; | 187 | break; |
188 | case 9: | 188 | case 9: |
189 | state->addr &= 0xFF; | 189 | state->addr &= 0xFF; |
190 | state->addr |= data << 8; | 190 | state->addr |= data << 8; |
191 | break; | 191 | break; |
192 | case 10: | 192 | case 10: |
193 | state->pcmbuf[ state->writeptr++ ] = data; | 193 | state->pcmbuf[ state->writeptr++ ] = data; |
194 | state->playlength ++; | 194 | state->playlength ++; |
195 | break; | 195 | break; |
196 | case 11: | 196 | case 11: |
197 | dprintf("ADPCM DMA 0x%02X", data); | 197 | dprintf("ADPCM DMA 0x%02X", data); |
198 | break; | 198 | break; |
199 | case 13: | 199 | case 13: |
200 | if ( data & 0x80 ) | 200 | if ( data & 0x80 ) |
201 | { | 201 | { |
202 | state->addr = 0; | 202 | state->addr = 0; |
203 | state->freq = 0; | 203 | state->freq = 0; |
204 | state->writeptr = 0; | 204 | state->writeptr = 0; |
205 | state->readptr = 0; | 205 | state->readptr = 0; |
206 | state->playflag = 0; | 206 | state->playflag = 0; |
207 | state->repeatflag = 0; | 207 | state->repeatflag = 0; |
208 | state->length = 0; | 208 | state->length = 0; |
209 | state->volume = 0xFF; | 209 | state->volume = 0xFF; |
210 | } | 210 | } |
211 | if ( ( data & 3 ) == 3 ) | 211 | if ( ( data & 3 ) == 3 ) |
212 | { | 212 | { |
213 | state->writeptr = state->addr; | 213 | state->writeptr = state->addr; |
214 | } | 214 | } |
215 | if ( data & 8 ) | 215 | if ( data & 8 ) |
216 | { | 216 | { |
217 | state->readptr = state->addr ? state->addr - 1 : state->addr; | 217 | state->readptr = state->addr ? state->addr - 1 : state->addr; |
218 | } | 218 | } |
219 | if ( data & 0x10 ) | 219 | if ( data & 0x10 ) |
220 | { | 220 | { |
221 | state->length = state->addr; | 221 | state->length = state->addr; |
222 | } | 222 | } |
223 | state->repeatflag = data & 0x20; | 223 | state->repeatflag = data & 0x20; |
224 | state->playflag = data & 0x40; | 224 | state->playflag = data & 0x40; |
225 | if ( state->playflag ) | 225 | if ( state->playflag ) |
226 | { | 226 | { |
227 | state->playptr = state->readptr; | 227 | state->playptr = state->readptr; |
228 | state->playlength = state->length + 1; | 228 | state->playlength = state->length + 1; |
229 | state->playedsamplecount = 0; | 229 | state->playedsamplecount = 0; |
230 | state->ad_sample = 0; | 230 | state->ad_sample = 0; |
231 | state->ad_low_nibble = false; | 231 | state->ad_low_nibble = false; |
232 | } | 232 | } |
233 | break; | 233 | break; |
234 | case 14: | 234 | case 14: |
235 | state->freq = 7159091 / ( 32000 / ( 16 - ( data & 15 ) ) ); | 235 | state->freq = 7159091 / ( 32000 / ( 16 - ( data & 15 ) ) ); |
236 | break; | 236 | break; |
237 | case 15: | 237 | case 15: |
238 | switch ( data & 15 ) | 238 | switch ( data & 15 ) |
239 | { | 239 | { |
240 | case 0: | 240 | case 0: |
241 | case 8: | 241 | case 8: |
242 | case 12: | 242 | case 12: |
243 | state->fadetimer = -100; | 243 | state->fadetimer = -100; |
244 | state->fadecount = state->fadetimer; | 244 | state->fadecount = state->fadetimer; |
245 | break; | 245 | break; |
246 | case 10: | 246 | case 10: |
247 | state->fadetimer = 5000; | 247 | state->fadetimer = 5000; |
248 | state->fadecount = state->fadetimer; | 248 | state->fadecount = state->fadetimer; |
249 | break; | 249 | break; |
250 | case 14: | 250 | case 14: |
251 | state->fadetimer = 1500; | 251 | state->fadetimer = 1500; |
252 | state->fadecount = state->fadetimer; | 252 | state->fadecount = state->fadetimer; |
253 | break; | 253 | break; |
254 | } | 254 | } |
255 | break; | 255 | break; |
256 | } | 256 | } |
257 | } | 257 | } |
258 | 258 | ||
259 | int Adpcm_read_data( struct Hes_Apu_Adpcm* this, blip_time_t time, int addr ) | 259 | int Adpcm_read_data( struct Hes_Apu_Adpcm* this, blip_time_t time, int addr ) |
260 | { | 260 | { |
261 | if ( time > this->last_time ) Adpcm_run_until( this, time ); | 261 | if ( time > this->last_time ) Adpcm_run_until( this, time ); |
262 | 262 | ||
263 | struct State* state = &this->state; | 263 | struct State* state = &this->state; |
264 | switch ( addr & 15 ) | 264 | switch ( addr & 15 ) |
265 | { | 265 | { |
266 | case 10: | 266 | case 10: |
267 | return state->pcmbuf [state->readptr++]; | 267 | return state->pcmbuf [state->readptr++]; |
268 | case 11: | 268 | case 11: |
269 | return state->port [11] & ~1; | 269 | return state->port [11] & ~1; |
270 | case 12: | 270 | case 12: |
271 | if (!state->playflag) | 271 | if (!state->playflag) |
272 | { | 272 | { |
273 | state->port [12] |= 1; | 273 | state->port [12] |= 1; |
274 | state->port [12] &= ~8; | 274 | state->port [12] &= ~8; |
275 | } | 275 | } |
276 | else | 276 | else |
277 | { | 277 | { |
278 | state->port [12] &= ~1; | 278 | state->port [12] &= ~1; |
279 | state->port [12] |= 8; | 279 | state->port [12] |= 8; |
280 | } | 280 | } |
281 | return state->port [12]; | 281 | return state->port [12]; |
282 | case 13: | 282 | case 13: |
283 | return state->port [13]; | 283 | return state->port [13]; |
284 | } | 284 | } |
285 | 285 | ||
286 | return 0xFF; | 286 | return 0xFF; |
287 | } | 287 | } |
288 | 288 | ||
289 | void Adpcm_end_frame( struct Hes_Apu_Adpcm* this, blip_time_t end_time ) | 289 | void Adpcm_end_frame( struct Hes_Apu_Adpcm* this, blip_time_t end_time ) |
290 | { | 290 | { |
291 | Adpcm_run_until( this, end_time ); | 291 | Adpcm_run_until( this, end_time ); |
292 | this->last_time -= end_time; | 292 | this->last_time -= end_time; |
293 | this->next_timer -= end_time; | 293 | this->next_timer -= end_time; |
294 | check( last_time >= 0 ); | 294 | check( last_time >= 0 ); |
295 | if ( this->output ) | 295 | if ( this->output ) |
296 | Blip_set_modified( this->output ); | 296 | Blip_set_modified( this->output ); |
297 | } | 297 | } |
diff --git a/apps/codecs/libgme/inflate/mbreader.c b/apps/codecs/libgme/inflate/mbreader.c index 96e45cd6c8..825787927c 100644 --- a/apps/codecs/libgme/inflate/mbreader.c +++ b/apps/codecs/libgme/inflate/mbreader.c | |||
@@ -1,16 +1,16 @@ | |||
1 | 1 | ||
2 | /* Memory buffer reader, simulates file read | 2 | /* Memory buffer reader, simulates file read |
3 | @ gama | 3 | @ gama |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "mbreader.h" | 6 | #include "mbreader.h" |
7 | 7 | ||
8 | int mbread(struct mbreader_t *md, void *buf, size_t n) | 8 | int mbread(struct mbreader_t *md, void *buf, size_t n) |
9 | { | 9 | { |
10 | if (!md) return -1; | 10 | if (!md) return -1; |
11 | size_t read_bytes = (md->offset+n) > md->size ? | 11 | size_t read_bytes = (md->offset+n) > md->size ? |
12 | md->size-md->offset : n; | 12 | md->size-md->offset : n; |
13 | memcpy(buf,md->ptr + md->offset,read_bytes); | 13 | memcpy(buf,md->ptr + md->offset,read_bytes); |
14 | md->offset += read_bytes; | 14 | md->offset += read_bytes; |
15 | return read_bytes; | 15 | return read_bytes; |
16 | } | 16 | } |
diff --git a/apps/codecs/libgme/inflate/mbreader.h b/apps/codecs/libgme/inflate/mbreader.h index 6427f18231..d345c0c424 100644 --- a/apps/codecs/libgme/inflate/mbreader.h +++ b/apps/codecs/libgme/inflate/mbreader.h | |||
@@ -1,15 +1,15 @@ | |||
1 | 1 | ||
2 | #ifndef MBREADER_H | 2 | #ifndef MBREADER_H |
3 | #define MBREADER_H | 3 | #define MBREADER_H |
4 | 4 | ||
5 | #include "codeclib.h" | 5 | #include "codeclib.h" |
6 | 6 | ||
7 | struct mbreader_t { | 7 | struct mbreader_t { |
8 | const char *ptr; | 8 | const char *ptr; |
9 | size_t size; | 9 | size_t size; |
10 | size_t offset; | 10 | size_t offset; |
11 | }; | 11 | }; |
12 | 12 | ||
13 | int mbread(struct mbreader_t *md, void *buf, size_t n); | 13 | int mbread(struct mbreader_t *md, void *buf, size_t n); |
14 | 14 | ||
15 | #endif | 15 | #endif |
diff --git a/apps/codecs/libgme/kss_cpu.c b/apps/codecs/libgme/kss_cpu.c index 891a7df255..20601e608f 100644 --- a/apps/codecs/libgme/kss_cpu.c +++ b/apps/codecs/libgme/kss_cpu.c | |||
@@ -1,35 +1,35 @@ | |||
1 | // Game_Music_Emu 0.6-pre. http://www.slack.net/~ant/ | 1 | // Game_Music_Emu 0.6-pre. http://www.slack.net/~ant/ |
2 | 2 | ||
3 | #include "kss_emu.h" | 3 | #include "kss_emu.h" |
4 | 4 | ||
5 | #include "blargg_endian.h" | 5 | #include "blargg_endian.h" |
6 | //#include "z80_cpu_log.h" | 6 | //#include "z80_cpu_log.h" |
7 | 7 | ||
8 | /* Copyright (C) 2006-2008 Shay Green. This module is free software; you | 8 | /* Copyright (C) 2006-2008 Shay Green. This module is free software; you |
9 | can redistribute it and/or modify it under the terms of the GNU Lesser | 9 | can redistribute it and/or modify it under the terms of the GNU Lesser |
10 | General Public License as published by the Free Software Foundation; either | 10 | General Public License as published by the Free Software Foundation; either |
11 | version 2.1 of the License, or (at your option) any later version. This | 11 | version 2.1 of the License, or (at your option) any later version. This |
12 | module is distributed in the hope that it will be useful, but WITHOUT ANY | 12 | module is distributed in the hope that it will be useful, but WITHOUT ANY |
13 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | 13 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
14 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more | 14 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
15 | details. You should have received a copy of the GNU Lesser General Public | 15 | details. You should have received a copy of the GNU Lesser General Public |
16 | License along with this module; if not, write to the Free Software Foundation, | 16 | License along with this module; if not, write to the Free Software Foundation, |
17 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ | 17 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ |
18 | 18 | ||
19 | #include "blargg_source.h" | 19 | #include "blargg_source.h" |
20 | 20 | ||
21 | #define OUT_PORT( addr, data ) cpu_out( this, TIME(), addr, data ) | 21 | #define OUT_PORT( addr, data ) cpu_out( this, TIME(), addr, data ) |
22 | #define IN_PORT( addr ) cpu_in( this, TIME(), addr ) | 22 | #define IN_PORT( addr ) cpu_in( this, TIME(), addr ) |
23 | #define WRITE_MEM( addr, data ) {FLUSH_TIME(); cpu_write( this, addr, data );} | 23 | #define WRITE_MEM( addr, data ) {FLUSH_TIME(); cpu_write( this, addr, data );} |
24 | #define IDLE_ADDR idle_addr | 24 | #define IDLE_ADDR idle_addr |
25 | 25 | ||
26 | #define CPU_BEGIN \ | 26 | #define CPU_BEGIN \ |
27 | bool run_cpu( struct Kss_Emu* this, kss_time_t end_time )\ | 27 | bool run_cpu( struct Kss_Emu* this, kss_time_t end_time )\ |
28 | {\ | 28 | {\ |
29 | struct Z80_Cpu *cpu = &this->cpu; \ | 29 | struct Z80_Cpu *cpu = &this->cpu; \ |
30 | Z80_set_end_time( cpu, end_time ); | 30 | Z80_set_end_time( cpu, end_time ); |
31 | 31 | ||
32 | #include "z80_cpu_run.h" | 32 | #include "z80_cpu_run.h" |
33 | 33 | ||
34 | return warning; | 34 | return warning; |
35 | } | 35 | } |
diff --git a/apps/codecs/libgme/nes_cpu_run.h b/apps/codecs/libgme/nes_cpu_run.h index 5b964d5070..fd1fea9659 100644 --- a/apps/codecs/libgme/nes_cpu_run.h +++ b/apps/codecs/libgme/nes_cpu_run.h | |||
@@ -1,1122 +1,1122 @@ | |||
1 | // NES 6502 cpu emulator run function | 1 | // NES 6502 cpu emulator run function |
2 | 2 | ||
3 | #if 0 | 3 | #if 0 |
4 | /* Define these macros in the source file before #including this file. | 4 | /* Define these macros in the source file before #including this file. |
5 | - Parameters might be expressions, so they are best evaluated only once, | 5 | - Parameters might be expressions, so they are best evaluated only once, |
6 | though they NEVER have side-effects, so multiple evaluation is OK. | 6 | though they NEVER have side-effects, so multiple evaluation is OK. |
7 | - Output parameters might be a multiple-assignment expression like "a=x", | 7 | - Output parameters might be a multiple-assignment expression like "a=x", |
8 | so they must NOT be parenthesized. | 8 | so they must NOT be parenthesized. |
9 | - Except where noted, time() and related functions will NOT work | 9 | - Except where noted, time() and related functions will NOT work |
10 | correctly inside a macro. TIME() is always correct, and FLUSH_TIME() and | 10 | correctly inside a macro. TIME() is always correct, and FLUSH_TIME() and |
11 | CACHE_TIME() allow the time changing functions to work. | 11 | CACHE_TIME() allow the time changing functions to work. |
12 | - Macros "returning" void may use a {} statement block. */ | 12 | - Macros "returning" void may use a {} statement block. */ |
13 | 13 | ||
14 | // 0 <= addr <= 0xFFFF + page_size | 14 | // 0 <= addr <= 0xFFFF + page_size |
15 | // time functions can be used | 15 | // time functions can be used |
16 | int READ_MEM( addr_t ); | 16 | int READ_MEM( addr_t ); |
17 | void WRITE_MEM( addr_t, int data ); | 17 | void WRITE_MEM( addr_t, int data ); |
18 | // 0 <= READ_MEM() <= 0xFF | 18 | // 0 <= READ_MEM() <= 0xFF |
19 | 19 | ||
20 | // 0 <= addr <= 0x1FF | 20 | // 0 <= addr <= 0x1FF |
21 | int READ_LOW( addr_t ); | 21 | int READ_LOW( addr_t ); |
22 | void WRITE_LOW( addr_t, int data ); | 22 | void WRITE_LOW( addr_t, int data ); |
23 | // 0 <= READ_LOW() <= 0xFF | 23 | // 0 <= READ_LOW() <= 0xFF |
24 | 24 | ||
25 | // Often-used instructions attempt these before using a normal memory access. | 25 | // Often-used instructions attempt these before using a normal memory access. |
26 | // Optional; defaults to READ_MEM() and WRITE_MEM() | 26 | // Optional; defaults to READ_MEM() and WRITE_MEM() |
27 | bool CAN_READ_FAST( addr_t ); // if true, uses result of READ_FAST | 27 | bool CAN_READ_FAST( addr_t ); // if true, uses result of READ_FAST |
28 | void READ_FAST( addr_t, int& out ); // ALWAYS called BEFORE CAN_READ_FAST | 28 | void READ_FAST( addr_t, int& out ); // ALWAYS called BEFORE CAN_READ_FAST |
29 | bool CAN_WRITE_FAST( addr_t ); // if true, uses WRITE_FAST instead of WRITE_MEM | 29 | bool CAN_WRITE_FAST( addr_t ); // if true, uses WRITE_FAST instead of WRITE_MEM |
30 | void WRITE_FAST( addr_t, int data ); | 30 | void WRITE_FAST( addr_t, int data ); |
31 | 31 | ||
32 | // Used by instructions most often used to access the NES PPU (LDA abs and BIT abs). | 32 | // Used by instructions most often used to access the NES PPU (LDA abs and BIT abs). |
33 | // Optional; defaults to READ_MEM. | 33 | // Optional; defaults to READ_MEM. |
34 | void READ_PPU( addr_t, int& out ); | 34 | void READ_PPU( addr_t, int& out ); |
35 | // 0 <= out <= 0xFF | 35 | // 0 <= out <= 0xFF |
36 | 36 | ||
37 | // The following can be used within macros: | 37 | // The following can be used within macros: |
38 | 38 | ||
39 | // Current time | 39 | // Current time |
40 | time_t TIME(); | 40 | time_t TIME(); |
41 | 41 | ||
42 | // Allows use of time functions | 42 | // Allows use of time functions |
43 | void FLUSH_TIME(); | 43 | void FLUSH_TIME(); |
44 | 44 | ||
45 | // Must be used before end of macro if FLUSH_TIME() was used earlier | 45 | // Must be used before end of macro if FLUSH_TIME() was used earlier |
46 | void CACHE_TIME(); | 46 | void CACHE_TIME(); |
47 | 47 | ||
48 | // Configuration (optional; commented behavior if defined) | 48 | // Configuration (optional; commented behavior if defined) |
49 | 49 | ||
50 | // Emulates dummy reads for indexed instructions | 50 | // Emulates dummy reads for indexed instructions |
51 | #define NES_CPU_DUMMY_READS 1 | 51 | #define NES_CPU_DUMMY_READS 1 |
52 | 52 | ||
53 | // Optimizes as if map_code( 0, 0x10000 + cpu_padding, FLAT_MEM ) is always in effect | 53 | // Optimizes as if map_code( 0, 0x10000 + cpu_padding, FLAT_MEM ) is always in effect |
54 | #define FLAT_MEM my_mem_array | 54 | #define FLAT_MEM my_mem_array |
55 | 55 | ||
56 | // Expanded just before beginning of code, to help debugger | 56 | // Expanded just before beginning of code, to help debugger |
57 | #define CPU_BEGIN void my_run_cpu() { | 57 | #define CPU_BEGIN void my_run_cpu() { |
58 | 58 | ||
59 | #endif | 59 | #endif |
60 | 60 | ||
61 | /* Copyright (C) 2003-2008 Shay Green. This module is free software; you | 61 | /* Copyright (C) 2003-2008 Shay Green. This module is free software; you |
62 | can redistribute it and/or modify it under the terms of the GNU Lesser | 62 | can redistribute it and/or modify it under the terms of the GNU Lesser |
63 | General Public License as published by the Free Software Foundation; either | 63 | General Public License as published by the Free Software Foundation; either |
64 | version 2.1 of the License, or (at your option) any later version. This | 64 | version 2.1 of the License, or (at your option) any later version. This |
65 | module is distributed in the hope that it will be useful, but WITHOUT ANY | 65 | module is distributed in the hope that it will be useful, but WITHOUT ANY |
66 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | 66 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
67 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more | 67 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
68 | details. You should have received a copy of the GNU Lesser General Public | 68 | details. You should have received a copy of the GNU Lesser General Public |
69 | License along with this module; if not, write to the Free Software Foundation, | 69 | License along with this module; if not, write to the Free Software Foundation, |
70 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ | 70 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ |
71 | 71 | ||
72 | // Allows MWCW debugger to step through code properly | 72 | // Allows MWCW debugger to step through code properly |
73 | #ifdef CPU_BEGIN | 73 | #ifdef CPU_BEGIN |
74 | CPU_BEGIN | 74 | CPU_BEGIN |
75 | #endif | 75 | #endif |
76 | 76 | ||
77 | // Time | 77 | // Time |
78 | #define TIME() (s_time + s.base) | 78 | #define TIME() (s_time + s.base) |
79 | #define FLUSH_TIME() {s.time = s_time - time_offset;} | 79 | #define FLUSH_TIME() {s.time = s_time - time_offset;} |
80 | #define CACHE_TIME() {s_time = s.time + time_offset;} | 80 | #define CACHE_TIME() {s_time = s.time + time_offset;} |
81 | 81 | ||
82 | // Defaults | 82 | // Defaults |
83 | #ifndef CAN_WRITE_FAST | 83 | #ifndef CAN_WRITE_FAST |
84 | #define CAN_WRITE_FAST( addr ) 0 | 84 | #define CAN_WRITE_FAST( addr ) 0 |
85 | #define WRITE_FAST( addr, data ) | 85 | #define WRITE_FAST( addr, data ) |
86 | #endif | 86 | #endif |
87 | 87 | ||
88 | #ifndef CAN_READ_FAST | 88 | #ifndef CAN_READ_FAST |
89 | #define CAN_READ_FAST( addr ) 0 | 89 | #define CAN_READ_FAST( addr ) 0 |
90 | #define READ_FAST( addr, out ) | 90 | #define READ_FAST( addr, out ) |
91 | #endif | 91 | #endif |
92 | 92 | ||
93 | #ifndef READ_PPU | 93 | #ifndef READ_PPU |
94 | #define READ_PPU( addr, out )\ | 94 | #define READ_PPU( addr, out )\ |
95 | {\ | 95 | {\ |
96 | FLUSH_TIME();\ | 96 | FLUSH_TIME();\ |
97 | out = READ_MEM( addr );\ | 97 | out = READ_MEM( addr );\ |
98 | CACHE_TIME();\ | 98 | CACHE_TIME();\ |
99 | } | 99 | } |
100 | #endif | 100 | #endif |
101 | 101 | ||
102 | #define READ_STACK READ_LOW | 102 | #define READ_STACK READ_LOW |
103 | #define WRITE_STACK WRITE_LOW | 103 | #define WRITE_STACK WRITE_LOW |
104 | 104 | ||
105 | // Dummy reads | 105 | // Dummy reads |
106 | #ifdef NES_CPU_DUMMY_READS | 106 | #ifdef NES_CPU_DUMMY_READS |
107 | // TODO: optimize time handling | 107 | // TODO: optimize time handling |
108 | #define DUMMY_READ( addr, idx ) \ | 108 | #define DUMMY_READ( addr, idx ) \ |
109 | if ( (addr & 0xFF) < idx )\ | 109 | if ( (addr & 0xFF) < idx )\ |
110 | {\ | 110 | {\ |
111 | int const time_offset = 1;\ | 111 | int const time_offset = 1;\ |
112 | FLUSH_TIME();\ | 112 | FLUSH_TIME();\ |
113 | READ_MEM( (addr - 0x100) );\ | 113 | READ_MEM( (addr - 0x100) );\ |
114 | CACHE_TIME();\ | 114 | CACHE_TIME();\ |
115 | } | 115 | } |
116 | #else | 116 | #else |
117 | #define DUMMY_READ( addr, idx ) | 117 | #define DUMMY_READ( addr, idx ) |
118 | #endif | 118 | #endif |
119 | 119 | ||
120 | // Code | 120 | // Code |
121 | #ifdef FLAT_MEM | 121 | #ifdef FLAT_MEM |
122 | #define CODE_PAGE( addr ) (FLAT_MEM) | 122 | #define CODE_PAGE( addr ) (FLAT_MEM) |
123 | #define CODE_OFFSET( addr ) (addr) | 123 | #define CODE_OFFSET( addr ) (addr) |
124 | #else | 124 | #else |
125 | #define CODE_PAGE( addr ) (s.code_map [NES_CPU_PAGE( addr )]) | 125 | #define CODE_PAGE( addr ) (s.code_map [NES_CPU_PAGE( addr )]) |
126 | #define CODE_OFFSET( addr ) NES_CPU_OFFSET( addr ) | 126 | #define CODE_OFFSET( addr ) NES_CPU_OFFSET( addr ) |
127 | #endif | 127 | #endif |
128 | #define READ_CODE( addr ) (CODE_PAGE( addr ) [CODE_OFFSET( addr )]) | 128 | #define READ_CODE( addr ) (CODE_PAGE( addr ) [CODE_OFFSET( addr )]) |
129 | 129 | ||
130 | // Stack | 130 | // Stack |
131 | #define SET_SP( v ) (sp = ((v) + 1) | 0x100) | 131 | #define SET_SP( v ) (sp = ((v) + 1) | 0x100) |
132 | #define GET_SP() ((sp - 1) & 0xFF) | 132 | #define GET_SP() ((sp - 1) & 0xFF) |
133 | #define SP( o ) ((sp + (o - (o>0)*0x100)) | 0x100) | 133 | #define SP( o ) ((sp + (o - (o>0)*0x100)) | 0x100) |
134 | 134 | ||
135 | // Truncation | 135 | // Truncation |
136 | #define BYTE( n ) ((uint8_t ) (n)) /* (unsigned) n & 0xFF */ | 136 | #define BYTE( n ) ((uint8_t ) (n)) /* (unsigned) n & 0xFF */ |
137 | #define SBYTE( n ) ((int8_t ) (n)) /* (BYTE( n ) ^ 0x80) - 0x80 */ | 137 | #define SBYTE( n ) ((int8_t ) (n)) /* (BYTE( n ) ^ 0x80) - 0x80 */ |
138 | #define WORD( n ) ((uint16_t) (n)) /* (unsigned) n & 0xFFFF */ | 138 | #define WORD( n ) ((uint16_t) (n)) /* (unsigned) n & 0xFFFF */ |
139 | 139 | ||
140 | // Flags with hex value for clarity when used as mask. | 140 | // Flags with hex value for clarity when used as mask. |
141 | // Stored in indicated variable during emulation. | 141 | // Stored in indicated variable during emulation. |
142 | int const n80 = 0x80; // nz | 142 | int const n80 = 0x80; // nz |
143 | int const v40 = 0x40; // flags | 143 | int const v40 = 0x40; // flags |
144 | int const r20 = 0x20; | 144 | int const r20 = 0x20; |
145 | int const b10 = 0x10; | 145 | int const b10 = 0x10; |
146 | int const d08 = 0x08; // flags | 146 | int const d08 = 0x08; // flags |
147 | int const i04 = 0x04; // flags | 147 | int const i04 = 0x04; // flags |
148 | int const z02 = 0x02; // nz | 148 | int const z02 = 0x02; // nz |
149 | int const c01 = 0x01; // c | 149 | int const c01 = 0x01; // c |
150 | 150 | ||
151 | #define IS_NEG (nz & 0x8080) | 151 | #define IS_NEG (nz & 0x8080) |
152 | 152 | ||
153 | #define GET_FLAGS( out ) \ | 153 | #define GET_FLAGS( out ) \ |
154 | {\ | 154 | {\ |
155 | out = flags & (v40 | d08 | i04);\ | 155 | out = flags & (v40 | d08 | i04);\ |
156 | out += ((nz >> 8) | nz) & n80;\ | 156 | out += ((nz >> 8) | nz) & n80;\ |
157 | out += c >> 8 & c01;\ | 157 | out += c >> 8 & c01;\ |
158 | if ( !BYTE( nz ) )\ | 158 | if ( !BYTE( nz ) )\ |
159 | out += z02;\ | 159 | out += z02;\ |
160 | } | 160 | } |
161 | 161 | ||
162 | #define SET_FLAGS( in ) \ | 162 | #define SET_FLAGS( in ) \ |
163 | {\ | 163 | {\ |
164 | flags = in & (v40 | d08 | i04);\ | 164 | flags = in & (v40 | d08 | i04);\ |
165 | c = nz = in << 8;\ | 165 | c = nz = in << 8;\ |
166 | nz += ~in & z02;\ | 166 | nz += ~in & z02;\ |
167 | } | 167 | } |
168 | 168 | ||
169 | { | 169 | { |
170 | int const time_offset = 0; | 170 | int const time_offset = 0; |
171 | 171 | ||
172 | // Local state | 172 | // Local state |
173 | struct cpu_state_t s; | 173 | struct cpu_state_t s; |
174 | #ifdef FLAT_MEM | 174 | #ifdef FLAT_MEM |
175 | s.base = cpu->cpu_state_.base; | 175 | s.base = cpu->cpu_state_.base; |
176 | #else | 176 | #else |
177 | s = cpu->cpu_state_; | 177 | s = cpu->cpu_state_; |
178 | #endif | 178 | #endif |
179 | cpu->cpu_state = &s; | 179 | cpu->cpu_state = &s; |
180 | int s_time = cpu->cpu_state_.time; // helps even on x86 | 180 | int s_time = cpu->cpu_state_.time; // helps even on x86 |
181 | 181 | ||
182 | // Registers | 182 | // Registers |
183 | int pc = cpu->r.pc; | 183 | int pc = cpu->r.pc; |
184 | int a = cpu->r.a; | 184 | int a = cpu->r.a; |
185 | int x = cpu->r.x; | 185 | int x = cpu->r.x; |
186 | int y = cpu->r.y; | 186 | int y = cpu->r.y; |
187 | int sp; | 187 | int sp; |
188 | SET_SP( cpu->r.sp ); | 188 | SET_SP( cpu->r.sp ); |
189 | 189 | ||
190 | // Flags | 190 | // Flags |
191 | int flags; | 191 | int flags; |
192 | int c; // carry set if (c & 0x100) != 0 | 192 | int c; // carry set if (c & 0x100) != 0 |
193 | int nz; // Z set if (nz & 0xFF) == 0, N set if (nz & 0x8080) != 0 | 193 | int nz; // Z set if (nz & 0xFF) == 0, N set if (nz & 0x8080) != 0 |
194 | { | 194 | { |
195 | int temp = cpu->r.flags; | 195 | int temp = cpu->r.flags; |
196 | SET_FLAGS( temp ); | 196 | SET_FLAGS( temp ); |
197 | } | 197 | } |
198 | 198 | ||
199 | loop: | 199 | loop: |
200 | 200 | ||
201 | // Check all values | 201 | // Check all values |
202 | check( (unsigned) sp - 0x100 < 0x100 ); | 202 | check( (unsigned) sp - 0x100 < 0x100 ); |
203 | check( (unsigned) pc < 0x10000 ); | 203 | check( (unsigned) pc < 0x10000 ); |
204 | check( (unsigned) a < 0x100 ); | 204 | check( (unsigned) a < 0x100 ); |
205 | check( (unsigned) x < 0x100 ); | 205 | check( (unsigned) x < 0x100 ); |
206 | check( (unsigned) y < 0x100 ); | 206 | check( (unsigned) y < 0x100 ); |
207 | 207 | ||
208 | // Read instruction | 208 | // Read instruction |
209 | byte const* instr = CODE_PAGE( pc ); | 209 | byte const* instr = CODE_PAGE( pc ); |
210 | int opcode; | 210 | int opcode; |
211 | 211 | ||
212 | if ( CODE_OFFSET(~0) == ~0 ) | 212 | if ( CODE_OFFSET(~0) == ~0 ) |
213 | { | 213 | { |
214 | opcode = instr [pc]; | 214 | opcode = instr [pc]; |
215 | pc++; | 215 | pc++; |
216 | instr += pc; | 216 | instr += pc; |
217 | } | 217 | } |
218 | else | 218 | else |
219 | { | 219 | { |
220 | instr += CODE_OFFSET( pc ); | 220 | instr += CODE_OFFSET( pc ); |
221 | opcode = *instr++; | 221 | opcode = *instr++; |
222 | pc++; | 222 | pc++; |
223 | } | 223 | } |
224 | 224 | ||
225 | // local to function in case it helps optimizer | 225 | // local to function in case it helps optimizer |
226 | static byte const clock_table [256] = | 226 | static byte const clock_table [256] = |
227 | {// 0 1 2 3 4 5 6 7 8 9 A B C D E F | 227 | {// 0 1 2 3 4 5 6 7 8 9 A B C D E F |
228 | 0,6,2,8,3,3,5,5,3,2,2,2,4,4,6,6,// 0 | 228 | 0,6,2,8,3,3,5,5,3,2,2,2,4,4,6,6,// 0 |
229 | 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// 1 | 229 | 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// 1 |
230 | 6,6,0,8,3,3,5,5,4,2,2,2,4,4,6,6,// 2 | 230 | 6,6,0,8,3,3,5,5,4,2,2,2,4,4,6,6,// 2 |
231 | 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// 3 | 231 | 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// 3 |
232 | 6,6,2,8,3,3,5,5,3,2,2,2,3,4,6,6,// 4 | 232 | 6,6,2,8,3,3,5,5,3,2,2,2,3,4,6,6,// 4 |
233 | 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// 5 | 233 | 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// 5 |
234 | 6,6,2,8,3,3,5,5,4,2,2,2,5,4,6,6,// 6 | 234 | 6,6,2,8,3,3,5,5,4,2,2,2,5,4,6,6,// 6 |
235 | 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// 7 | 235 | 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// 7 |
236 | 2,6,2,6,3,3,3,3,2,2,2,2,4,4,4,4,// 8 | 236 | 2,6,2,6,3,3,3,3,2,2,2,2,4,4,4,4,// 8 |
237 | 2,6,2,6,4,4,4,4,2,5,2,5,5,5,5,5,// 9 | 237 | 2,6,2,6,4,4,4,4,2,5,2,5,5,5,5,5,// 9 |
238 | 2,6,2,6,3,3,3,3,2,2,2,2,4,4,4,4,// A | 238 | 2,6,2,6,3,3,3,3,2,2,2,2,4,4,4,4,// A |
239 | 2,5,2,5,4,4,4,4,2,4,2,4,4,4,4,4,// B | 239 | 2,5,2,5,4,4,4,4,2,4,2,4,4,4,4,4,// B |
240 | 2,6,2,8,3,3,5,5,2,2,2,2,4,4,6,6,// C | 240 | 2,6,2,8,3,3,5,5,2,2,2,2,4,4,6,6,// C |
241 | 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// D | 241 | 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// D |
242 | 2,6,2,8,3,3,5,5,2,2,2,2,4,4,6,6,// E | 242 | 2,6,2,8,3,3,5,5,2,2,2,2,4,4,6,6,// E |
243 | 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7 // F | 243 | 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7 // F |
244 | }; // 0x00 was 7 and 0x22 was 2 | 244 | }; // 0x00 was 7 and 0x22 was 2 |
245 | 245 | ||
246 | // Update time | 246 | // Update time |
247 | if ( s_time >= 0 ) | 247 | if ( s_time >= 0 ) |
248 | goto out_of_time; | 248 | goto out_of_time; |
249 | 249 | ||
250 | #ifdef CPU_INSTR_HOOK | 250 | #ifdef CPU_INSTR_HOOK |
251 | { CPU_INSTR_HOOK( (pc-1), (&instr [-1]), a, x, y, GET_SP(), TIME() ); } | 251 | { CPU_INSTR_HOOK( (pc-1), (&instr [-1]), a, x, y, GET_SP(), TIME() ); } |
252 | #endif | 252 | #endif |
253 | 253 | ||
254 | s_time += clock_table [opcode]; | 254 | s_time += clock_table [opcode]; |
255 | 255 | ||
256 | int data; | 256 | int data; |
257 | data = *instr; | 257 | data = *instr; |
258 | 258 | ||
259 | switch ( opcode ) | 259 | switch ( opcode ) |
260 | { | 260 | { |
261 | 261 | ||
262 | // Macros | 262 | // Macros |
263 | 263 | ||
264 | #define GET_MSB() (instr [1]) | 264 | #define GET_MSB() (instr [1]) |
265 | #define ADD_PAGE( out ) (pc++, out = data + 0x100 * GET_MSB()) | 265 | #define ADD_PAGE( out ) (pc++, out = data + 0x100 * GET_MSB()) |
266 | #define GET_ADDR() GET_LE16( instr ) | 266 | #define GET_ADDR() GET_LE16( instr ) |
267 | 267 | ||
268 | #define PAGE_PENALTY( lsb ) s_time += (lsb) >> 8; | 268 | #define PAGE_PENALTY( lsb ) s_time += (lsb) >> 8; |
269 | 269 | ||
270 | #define INC_DEC( reg, n ) reg = BYTE( nz = reg + n ); goto loop; | 270 | #define INC_DEC( reg, n ) reg = BYTE( nz = reg + n ); goto loop; |
271 | 271 | ||
272 | #define IND_Y( cross, out ) {\ | 272 | #define IND_Y( cross, out ) {\ |
273 | int temp = READ_LOW( data ) + y;\ | 273 | int temp = READ_LOW( data ) + y;\ |
274 | out = temp + 0x100 * READ_LOW( BYTE( data + 1 ) );\ | 274 | out = temp + 0x100 * READ_LOW( BYTE( data + 1 ) );\ |
275 | cross( temp );\ | 275 | cross( temp );\ |
276 | } | 276 | } |
277 | 277 | ||
278 | #define IND_X( out ) {\ | 278 | #define IND_X( out ) {\ |
279 | int temp = data + x;\ | 279 | int temp = data + x;\ |
280 | out = 0x100 * READ_LOW( BYTE( temp + 1 ) ) + READ_LOW( BYTE( temp ) );\ | 280 | out = 0x100 * READ_LOW( BYTE( temp + 1 ) ) + READ_LOW( BYTE( temp ) );\ |
281 | } | 281 | } |
282 | 282 | ||
283 | #define ARITH_ADDR_MODES( op )\ | 283 | #define ARITH_ADDR_MODES( op )\ |
284 | case op - 0x04: /* (ind,x) */\ | 284 | case op - 0x04: /* (ind,x) */\ |
285 | IND_X( data )\ | 285 | IND_X( data )\ |
286 | goto ptr##op;\ | 286 | goto ptr##op;\ |
287 | case op + 0x0C: /* (ind),y */\ | 287 | case op + 0x0C: /* (ind),y */\ |
288 | IND_Y( PAGE_PENALTY, data )\ | 288 | IND_Y( PAGE_PENALTY, data )\ |
289 | goto ptr##op;\ | 289 | goto ptr##op;\ |
290 | case op + 0x10: /* zp,X */\ | 290 | case op + 0x10: /* zp,X */\ |
291 | data = BYTE( data + x );\ | 291 | data = BYTE( data + x );\ |
292 | case op + 0x00: /* zp */\ | 292 | case op + 0x00: /* zp */\ |
293 | data = READ_LOW( data );\ | 293 | data = READ_LOW( data );\ |
294 | goto imm##op;\ | 294 | goto imm##op;\ |
295 | case op + 0x14: /* abs,Y */\ | 295 | case op + 0x14: /* abs,Y */\ |
296 | data += y;\ | 296 | data += y;\ |
297 | goto ind##op;\ | 297 | goto ind##op;\ |
298 | case op + 0x18: /* abs,X */\ | 298 | case op + 0x18: /* abs,X */\ |
299 | data += x;\ | 299 | data += x;\ |
300 | ind##op:\ | 300 | ind##op:\ |
301 | PAGE_PENALTY( data );\ | 301 | PAGE_PENALTY( data );\ |
302 | case op + 0x08: /* abs */\ | 302 | case op + 0x08: /* abs */\ |
303 | ADD_PAGE( data );\ | 303 | ADD_PAGE( data );\ |
304 | ptr##op:\ | 304 | ptr##op:\ |
305 | FLUSH_TIME();\ | 305 | FLUSH_TIME();\ |
306 | data = READ_MEM( data );\ | 306 | data = READ_MEM( data );\ |
307 | CACHE_TIME();\ | 307 | CACHE_TIME();\ |
308 | case op + 0x04: /* imm */\ | 308 | case op + 0x04: /* imm */\ |
309 | imm##op: | 309 | imm##op: |
310 | 310 | ||
311 | // TODO: more efficient way to handle negative branch that wraps PC around | 311 | // TODO: more efficient way to handle negative branch that wraps PC around |
312 | #define BRANCH( cond )\ | 312 | #define BRANCH( cond )\ |
313 | {\ | 313 | {\ |
314 | ++pc;\ | 314 | ++pc;\ |
315 | if ( !(cond) ) goto loop;\ | 315 | if ( !(cond) ) goto loop;\ |
316 | s_time++;\ | 316 | s_time++;\ |
317 | int offset = SBYTE( data );\ | 317 | int offset = SBYTE( data );\ |
318 | s_time += (BYTE(pc) + offset) >> 8 & 1;\ | 318 | s_time += (BYTE(pc) + offset) >> 8 & 1;\ |
319 | pc = WORD( pc + offset );\ | 319 | pc = WORD( pc + offset );\ |
320 | goto loop;\ | 320 | goto loop;\ |
321 | } | 321 | } |
322 | 322 | ||
323 | // Often-Used | 323 | // Often-Used |
324 | 324 | ||
325 | case 0xB5: // LDA zp,x | 325 | case 0xB5: // LDA zp,x |
326 | a = nz = READ_LOW( BYTE( data + x ) ); | 326 | a = nz = READ_LOW( BYTE( data + x ) ); |
327 | pc++; | 327 | pc++; |
328 | goto loop; | 328 | goto loop; |
329 | 329 | ||
330 | case 0xA5: // LDA zp | 330 | case 0xA5: // LDA zp |
331 | a = nz = READ_LOW( data ); | 331 | a = nz = READ_LOW( data ); |
332 | pc++; | 332 | pc++; |
333 | goto loop; | 333 | goto loop; |
334 | 334 | ||
335 | case 0xD0: // BNE | 335 | case 0xD0: // BNE |
336 | BRANCH( BYTE( nz ) ); | 336 | BRANCH( BYTE( nz ) ); |
337 | 337 | ||
338 | case 0x20: { // JSR | 338 | case 0x20: { // JSR |
339 | int temp = pc + 1; | 339 | int temp = pc + 1; |
340 | pc = GET_ADDR(); | 340 | pc = GET_ADDR(); |
341 | WRITE_STACK( SP( -1 ), temp >> 8 ); | 341 | WRITE_STACK( SP( -1 ), temp >> 8 ); |
342 | sp = SP( -2 ); | 342 | sp = SP( -2 ); |
343 | WRITE_STACK( sp, temp ); | 343 | WRITE_STACK( sp, temp ); |
344 | goto loop; | 344 | goto loop; |
345 | } | 345 | } |
346 | 346 | ||
347 | case 0x4C: // JMP abs | 347 | case 0x4C: // JMP abs |
348 | pc = GET_ADDR(); | 348 | pc = GET_ADDR(); |
349 | goto loop; | 349 | goto loop; |
350 | 350 | ||
351 | case 0xE8: // INX | 351 | case 0xE8: // INX |
352 | INC_DEC( x, 1 ) | 352 | INC_DEC( x, 1 ) |
353 | 353 | ||
354 | case 0x10: // BPL | 354 | case 0x10: // BPL |
355 | BRANCH( !IS_NEG ) | 355 | BRANCH( !IS_NEG ) |
356 | 356 | ||
357 | ARITH_ADDR_MODES( 0xC5 ) // CMP | 357 | ARITH_ADDR_MODES( 0xC5 ) // CMP |
358 | nz = a - data; | 358 | nz = a - data; |
359 | pc++; | 359 | pc++; |
360 | c = ~nz; | 360 | c = ~nz; |
361 | nz &= 0xFF; | 361 | nz &= 0xFF; |
362 | goto loop; | 362 | goto loop; |
363 | 363 | ||
364 | case 0x30: // BMI | 364 | case 0x30: // BMI |
365 | BRANCH( IS_NEG ) | 365 | BRANCH( IS_NEG ) |
366 | 366 | ||
367 | case 0xF0: // BEQ | 367 | case 0xF0: // BEQ |
368 | BRANCH( !BYTE( nz ) ); | 368 | BRANCH( !BYTE( nz ) ); |
369 | 369 | ||
370 | case 0x95: // STA zp,x | 370 | case 0x95: // STA zp,x |
371 | data = BYTE( data + x ); | 371 | data = BYTE( data + x ); |
372 | case 0x85: // STA zp | 372 | case 0x85: // STA zp |
373 | pc++; | 373 | pc++; |
374 | WRITE_LOW( data, a ); | 374 | WRITE_LOW( data, a ); |
375 | goto loop; | 375 | goto loop; |
376 | 376 | ||
377 | case 0xC8: // INY | 377 | case 0xC8: // INY |
378 | INC_DEC( y, 1 ) | 378 | INC_DEC( y, 1 ) |
379 | 379 | ||
380 | case 0xA8: // TAY | 380 | case 0xA8: // TAY |
381 | y = a; | 381 | y = a; |
382 | nz = a; | 382 | nz = a; |
383 | goto loop; | 383 | goto loop; |
384 | 384 | ||
385 | case 0x98: // TYA | 385 | case 0x98: // TYA |
386 | a = y; | 386 | a = y; |
387 | nz = y; | 387 | nz = y; |
388 | goto loop; | 388 | goto loop; |
389 | 389 | ||
390 | case 0xAD:{// LDA abs | 390 | case 0xAD:{// LDA abs |
391 | int addr = GET_ADDR(); | 391 | int addr = GET_ADDR(); |
392 | pc += 2; | 392 | pc += 2; |
393 | READ_PPU( addr, a = nz ); | 393 | READ_PPU( addr, a = nz ); |
394 | goto loop; | 394 | goto loop; |
395 | } | 395 | } |
396 | 396 | ||
397 | case 0x60: // RTS | 397 | case 0x60: // RTS |
398 | pc = 1 + READ_STACK( sp ); | 398 | pc = 1 + READ_STACK( sp ); |
399 | pc += 0x100 * READ_STACK( SP( 1 ) ); | 399 | pc += 0x100 * READ_STACK( SP( 1 ) ); |
400 | sp = SP( 2 ); | 400 | sp = SP( 2 ); |
401 | goto loop; | 401 | goto loop; |
402 | 402 | ||
403 | { | 403 | { |
404 | int addr; | 404 | int addr; |
405 | 405 | ||
406 | case 0x8D: // STA abs | 406 | case 0x8D: // STA abs |
407 | addr = GET_ADDR(); | 407 | addr = GET_ADDR(); |
408 | pc += 2; | 408 | pc += 2; |
409 | if ( CAN_WRITE_FAST( addr ) ) | 409 | if ( CAN_WRITE_FAST( addr ) ) |
410 | { | 410 | { |
411 | WRITE_FAST( addr, a ); | 411 | WRITE_FAST( addr, a ); |
412 | goto loop; | 412 | goto loop; |
413 | } | 413 | } |
414 | sta_ptr: | 414 | sta_ptr: |
415 | FLUSH_TIME(); | 415 | FLUSH_TIME(); |
416 | WRITE_MEM( addr, a ); | 416 | WRITE_MEM( addr, a ); |
417 | CACHE_TIME(); | 417 | CACHE_TIME(); |
418 | goto loop; | 418 | goto loop; |
419 | 419 | ||
420 | case 0x99: // STA abs,Y | 420 | case 0x99: // STA abs,Y |
421 | addr = y + GET_ADDR(); | 421 | addr = y + GET_ADDR(); |
422 | pc += 2; | 422 | pc += 2; |
423 | if ( CAN_WRITE_FAST( addr ) ) | 423 | if ( CAN_WRITE_FAST( addr ) ) |
424 | { | 424 | { |
425 | WRITE_FAST( addr, a ); | 425 | WRITE_FAST( addr, a ); |
426 | goto loop; | 426 | goto loop; |
427 | } | 427 | } |
428 | goto sta_abs_x; | 428 | goto sta_abs_x; |
429 | 429 | ||
430 | case 0x9D: // STA abs,X (slightly more common than STA abs) | 430 | case 0x9D: // STA abs,X (slightly more common than STA abs) |
431 | addr = x + GET_ADDR(); | 431 | addr = x + GET_ADDR(); |
432 | pc += 2; | 432 | pc += 2; |
433 | if ( CAN_WRITE_FAST( addr ) ) | 433 | if ( CAN_WRITE_FAST( addr ) ) |
434 | { | 434 | { |
435 | WRITE_FAST( addr, a ); | 435 | WRITE_FAST( addr, a ); |
436 | goto loop; | 436 | goto loop; |
437 | } | 437 | } |
438 | DUMMY_READ( addr, x ); | 438 | DUMMY_READ( addr, x ); |
439 | sta_abs_x: | 439 | sta_abs_x: |
440 | FLUSH_TIME(); | 440 | FLUSH_TIME(); |
441 | WRITE_MEM( addr, a ); | 441 | WRITE_MEM( addr, a ); |
442 | CACHE_TIME(); | 442 | CACHE_TIME(); |
443 | goto loop; | 443 | goto loop; |
444 | 444 | ||
445 | case 0x91: // STA (ind),Y | 445 | case 0x91: // STA (ind),Y |
446 | #define NO_PAGE_PENALTY( lsb ) | 446 | #define NO_PAGE_PENALTY( lsb ) |
447 | IND_Y( NO_PAGE_PENALTY, addr ) | 447 | IND_Y( NO_PAGE_PENALTY, addr ) |
448 | pc++; | 448 | pc++; |
449 | DUMMY_READ( addr, y ); | 449 | DUMMY_READ( addr, y ); |
450 | goto sta_ptr; | 450 | goto sta_ptr; |
451 | 451 | ||
452 | case 0x81: // STA (ind,X) | 452 | case 0x81: // STA (ind,X) |
453 | IND_X( addr ) | 453 | IND_X( addr ) |
454 | pc++; | 454 | pc++; |
455 | goto sta_ptr; | 455 | goto sta_ptr; |
456 | 456 | ||
457 | } | 457 | } |
458 | 458 | ||
459 | case 0xA9: // LDA #imm | 459 | case 0xA9: // LDA #imm |
460 | pc++; | 460 | pc++; |
461 | a = data; | 461 | a = data; |
462 | nz = data; | 462 | nz = data; |
463 | goto loop; | 463 | goto loop; |
464 | 464 | ||
465 | // common read instructions | 465 | // common read instructions |
466 | { | 466 | { |
467 | int addr; | 467 | int addr; |
468 | 468 | ||
469 | case 0xA1: // LDA (ind,X) | 469 | case 0xA1: // LDA (ind,X) |
470 | IND_X( addr ) | 470 | IND_X( addr ) |
471 | pc++; | 471 | pc++; |
472 | goto a_nz_read_addr; | 472 | goto a_nz_read_addr; |
473 | 473 | ||
474 | case 0xB1:// LDA (ind),Y | 474 | case 0xB1:// LDA (ind),Y |
475 | addr = READ_LOW( data ) + y; | 475 | addr = READ_LOW( data ) + y; |
476 | PAGE_PENALTY( addr ); | 476 | PAGE_PENALTY( addr ); |
477 | addr += 0x100 * READ_LOW( BYTE( data + 1 ) ); | 477 | addr += 0x100 * READ_LOW( BYTE( data + 1 ) ); |
478 | pc++; | 478 | pc++; |
479 | READ_FAST( addr, a = nz ); | 479 | READ_FAST( addr, a = nz ); |
480 | if ( CAN_READ_FAST( addr ) ) | 480 | if ( CAN_READ_FAST( addr ) ) |
481 | goto loop; | 481 | goto loop; |
482 | DUMMY_READ( addr, y ); | 482 | DUMMY_READ( addr, y ); |
483 | goto a_nz_read_addr; | 483 | goto a_nz_read_addr; |
484 | 484 | ||
485 | case 0xB9: // LDA abs,Y | 485 | case 0xB9: // LDA abs,Y |
486 | PAGE_PENALTY( data + y ); | 486 | PAGE_PENALTY( data + y ); |
487 | addr = GET_ADDR() + y; | 487 | addr = GET_ADDR() + y; |
488 | pc += 2; | 488 | pc += 2; |
489 | READ_FAST( addr, a = nz ); | 489 | READ_FAST( addr, a = nz ); |
490 | if ( CAN_READ_FAST( addr ) ) | 490 | if ( CAN_READ_FAST( addr ) ) |
491 | goto loop; | 491 | goto loop; |
492 | goto a_nz_read_addr; | 492 | goto a_nz_read_addr; |
493 | 493 | ||
494 | case 0xBD: // LDA abs,X | 494 | case 0xBD: // LDA abs,X |
495 | PAGE_PENALTY( data + x ); | 495 | PAGE_PENALTY( data + x ); |
496 | addr = GET_ADDR() + x; | 496 | addr = GET_ADDR() + x; |
497 | pc += 2; | 497 | pc += 2; |
498 | READ_FAST( addr, a = nz ); | 498 | READ_FAST( addr, a = nz ); |
499 | if ( CAN_READ_FAST( addr ) ) | 499 | if ( CAN_READ_FAST( addr ) ) |
500 | goto loop; | 500 | goto loop; |
501 | DUMMY_READ( addr, x ); | 501 | DUMMY_READ( addr, x ); |
502 | a_nz_read_addr: | 502 | a_nz_read_addr: |
503 | FLUSH_TIME(); | 503 | FLUSH_TIME(); |
504 | a = nz = READ_MEM( addr ); | 504 | a = nz = READ_MEM( addr ); |
505 | CACHE_TIME(); | 505 | CACHE_TIME(); |
506 | goto loop; | 506 | goto loop; |
507 | 507 | ||
508 | } | 508 | } |
509 | 509 | ||
510 | // Branch | 510 | // Branch |
511 | 511 | ||
512 | case 0x50: // BVC | 512 | case 0x50: // BVC |
513 | BRANCH( !(flags & v40) ) | 513 | BRANCH( !(flags & v40) ) |
514 | 514 | ||
515 | case 0x70: // BVS | 515 | case 0x70: // BVS |
516 | BRANCH( flags & v40 ) | 516 | BRANCH( flags & v40 ) |
517 | 517 | ||
518 | case 0xB0: // BCS | 518 | case 0xB0: // BCS |
519 | BRANCH( c & 0x100 ) | 519 | BRANCH( c & 0x100 ) |
520 | 520 | ||
521 | case 0x90: // BCC | 521 | case 0x90: // BCC |
522 | BRANCH( !(c & 0x100) ) | 522 | BRANCH( !(c & 0x100) ) |
523 | 523 | ||
524 | // Load/store | 524 | // Load/store |
525 | 525 | ||
526 | case 0x94: // STY zp,x | 526 | case 0x94: // STY zp,x |
527 | data = BYTE( data + x ); | 527 | data = BYTE( data + x ); |
528 | case 0x84: // STY zp | 528 | case 0x84: // STY zp |
529 | pc++; | 529 | pc++; |
530 | WRITE_LOW( data, y ); | 530 | WRITE_LOW( data, y ); |
531 | goto loop; | 531 | goto loop; |
532 | 532 | ||
533 | case 0x96: // STX zp,y | 533 | case 0x96: // STX zp,y |
534 | data = BYTE( data + y ); | 534 | data = BYTE( data + y ); |
535 | case 0x86: // STX zp | 535 | case 0x86: // STX zp |
536 | pc++; | 536 | pc++; |
537 | WRITE_LOW( data, x ); | 537 | WRITE_LOW( data, x ); |
538 | goto loop; | 538 | goto loop; |
539 | 539 | ||
540 | case 0xB6: // LDX zp,y | 540 | case 0xB6: // LDX zp,y |
541 | data = BYTE( data + y ); | 541 | data = BYTE( data + y ); |
542 | case 0xA6: // LDX zp | 542 | case 0xA6: // LDX zp |
543 | data = READ_LOW( data ); | 543 | data = READ_LOW( data ); |
544 | case 0xA2: // LDX #imm | 544 | case 0xA2: // LDX #imm |
545 | pc++; | 545 | pc++; |
546 | x = data; | 546 | x = data; |
547 | nz = data; | 547 | nz = data; |
548 | goto loop; | 548 | goto loop; |
549 | 549 | ||
550 | case 0xB4: // LDY zp,x | 550 | case 0xB4: // LDY zp,x |
551 | data = BYTE( data + x ); | 551 | data = BYTE( data + x ); |
552 | case 0xA4: // LDY zp | 552 | case 0xA4: // LDY zp |
553 | data = READ_LOW( data ); | 553 | data = READ_LOW( data ); |
554 | case 0xA0: // LDY #imm | 554 | case 0xA0: // LDY #imm |
555 | pc++; | 555 | pc++; |
556 | y = data; | 556 | y = data; |
557 | nz = data; | 557 | nz = data; |
558 | goto loop; | 558 | goto loop; |
559 | 559 | ||
560 | case 0xBC: // LDY abs,X | 560 | case 0xBC: // LDY abs,X |
561 | data += x; | 561 | data += x; |
562 | PAGE_PENALTY( data ); | 562 | PAGE_PENALTY( data ); |
563 | case 0xAC:{// LDY abs | 563 | case 0xAC:{// LDY abs |
564 | int addr = data + 0x100 * GET_MSB(); | 564 | int addr = data + 0x100 * GET_MSB(); |
565 | pc += 2; | 565 | pc += 2; |
566 | FLUSH_TIME(); | 566 | FLUSH_TIME(); |
567 | y = nz = READ_MEM( addr ); | 567 | y = nz = READ_MEM( addr ); |
568 | CACHE_TIME(); | 568 | CACHE_TIME(); |
569 | goto loop; | 569 | goto loop; |
570 | } | 570 | } |
571 | 571 | ||
572 | case 0xBE: // LDX abs,y | 572 | case 0xBE: // LDX abs,y |
573 | data += y; | 573 | data += y; |
574 | PAGE_PENALTY( data ); | 574 | PAGE_PENALTY( data ); |
575 | case 0xAE:{// LDX abs | 575 | case 0xAE:{// LDX abs |
576 | int addr = data + 0x100 * GET_MSB(); | 576 | int addr = data + 0x100 * GET_MSB(); |
577 | pc += 2; | 577 | pc += 2; |
578 | FLUSH_TIME(); | 578 | FLUSH_TIME(); |
579 | x = nz = READ_MEM( addr ); | 579 | x = nz = READ_MEM( addr ); |
580 | CACHE_TIME(); | 580 | CACHE_TIME(); |
581 | goto loop; | 581 | goto loop; |
582 | } | 582 | } |
583 | 583 | ||
584 | { | 584 | { |
585 | int temp; | 585 | int temp; |
586 | case 0x8C: // STY abs | 586 | case 0x8C: // STY abs |
587 | temp = y; | 587 | temp = y; |
588 | goto store_abs; | 588 | goto store_abs; |
589 | 589 | ||
590 | case 0x8E: // STX abs | 590 | case 0x8E: // STX abs |
591 | temp = x; | 591 | temp = x; |
592 | store_abs: | 592 | store_abs: |
593 | { | 593 | { |
594 | int addr = GET_ADDR(); | 594 | int addr = GET_ADDR(); |
595 | pc += 2; | 595 | pc += 2; |
596 | if ( CAN_WRITE_FAST( addr ) ) | 596 | if ( CAN_WRITE_FAST( addr ) ) |
597 | { | 597 | { |
598 | WRITE_FAST( addr, temp ); | 598 | WRITE_FAST( addr, temp ); |
599 | goto loop; | 599 | goto loop; |
600 | } | 600 | } |
601 | FLUSH_TIME(); | 601 | FLUSH_TIME(); |
602 | WRITE_MEM( addr, temp ); | 602 | WRITE_MEM( addr, temp ); |
603 | CACHE_TIME(); | 603 | CACHE_TIME(); |
604 | goto loop; | 604 | goto loop; |
605 | } | 605 | } |
606 | } | 606 | } |
607 | 607 | ||
608 | // Compare | 608 | // Compare |
609 | 609 | ||
610 | case 0xEC: {// CPX abs | 610 | case 0xEC: {// CPX abs |
611 | int addr = GET_ADDR(); | 611 | int addr = GET_ADDR(); |
612 | pc++; | 612 | pc++; |
613 | FLUSH_TIME(); | 613 | FLUSH_TIME(); |
614 | data = READ_MEM( addr ); | 614 | data = READ_MEM( addr ); |
615 | CACHE_TIME(); | 615 | CACHE_TIME(); |
616 | goto cpx_data; | 616 | goto cpx_data; |
617 | } | 617 | } |
618 | 618 | ||
619 | case 0xE4: // CPX zp | 619 | case 0xE4: // CPX zp |
620 | data = READ_LOW( data ); | 620 | data = READ_LOW( data ); |
621 | case 0xE0: // CPX #imm | 621 | case 0xE0: // CPX #imm |
622 | cpx_data: | 622 | cpx_data: |
623 | nz = x - data; | 623 | nz = x - data; |
624 | pc++; | 624 | pc++; |
625 | c = ~nz; | 625 | c = ~nz; |
626 | nz &= 0xFF; | 626 | nz &= 0xFF; |
627 | goto loop; | 627 | goto loop; |
628 | 628 | ||
629 | case 0xCC:{// CPY abs | 629 | case 0xCC:{// CPY abs |
630 | int addr = GET_ADDR(); | 630 | int addr = GET_ADDR(); |
631 | pc++; | 631 | pc++; |
632 | FLUSH_TIME(); | 632 | FLUSH_TIME(); |
633 | data = READ_MEM( addr ); | 633 | data = READ_MEM( addr ); |
634 | CACHE_TIME(); | 634 | CACHE_TIME(); |
635 | goto cpy_data; | 635 | goto cpy_data; |
636 | } | 636 | } |
637 | 637 | ||
638 | case 0xC4: // CPY zp | 638 | case 0xC4: // CPY zp |
639 | data = READ_LOW( data ); | 639 | data = READ_LOW( data ); |
640 | case 0xC0: // CPY #imm | 640 | case 0xC0: // CPY #imm |
641 | cpy_data: | 641 | cpy_data: |
642 | nz = y - data; | 642 | nz = y - data; |
643 | pc++; | 643 | pc++; |
644 | c = ~nz; | 644 | c = ~nz; |
645 | nz &= 0xFF; | 645 | nz &= 0xFF; |
646 | goto loop; | 646 | goto loop; |
647 | 647 | ||
648 | // Logical | 648 | // Logical |
649 | 649 | ||
650 | ARITH_ADDR_MODES( 0x25 ) // AND | 650 | ARITH_ADDR_MODES( 0x25 ) // AND |
651 | nz = (a &= data); | 651 | nz = (a &= data); |
652 | pc++; | 652 | pc++; |
653 | goto loop; | 653 | goto loop; |
654 | 654 | ||
655 | ARITH_ADDR_MODES( 0x45 ) // EOR | 655 | ARITH_ADDR_MODES( 0x45 ) // EOR |
656 | nz = (a ^= data); | 656 | nz = (a ^= data); |
657 | pc++; | 657 | pc++; |
658 | goto loop; | 658 | goto loop; |
659 | 659 | ||
660 | ARITH_ADDR_MODES( 0x05 ) // ORA | 660 | ARITH_ADDR_MODES( 0x05 ) // ORA |
661 | nz = (a |= data); | 661 | nz = (a |= data); |
662 | pc++; | 662 | pc++; |
663 | goto loop; | 663 | goto loop; |
664 | 664 | ||
665 | case 0x2C:{// BIT abs | 665 | case 0x2C:{// BIT abs |
666 | int addr = GET_ADDR(); | 666 | int addr = GET_ADDR(); |
667 | pc += 2; | 667 | pc += 2; |
668 | READ_PPU( addr, nz ); | 668 | READ_PPU( addr, nz ); |
669 | flags = (flags & ~v40) + (nz & v40); | 669 | flags = (flags & ~v40) + (nz & v40); |
670 | if ( a & nz ) | 670 | if ( a & nz ) |
671 | goto loop; | 671 | goto loop; |
672 | nz <<= 8; // result must be zero, even if N bit is set | 672 | nz <<= 8; // result must be zero, even if N bit is set |
673 | goto loop; | 673 | goto loop; |
674 | } | 674 | } |
675 | 675 | ||
676 | case 0x24: // BIT zp | 676 | case 0x24: // BIT zp |
677 | nz = READ_LOW( data ); | 677 | nz = READ_LOW( data ); |
678 | pc++; | 678 | pc++; |
679 | flags = (flags & ~v40) + (nz & v40); | 679 | flags = (flags & ~v40) + (nz & v40); |
680 | if ( a & nz ) | 680 | if ( a & nz ) |
681 | goto loop; // Z should be clear, and nz must be non-zero if nz & a is | 681 | goto loop; // Z should be clear, and nz must be non-zero if nz & a is |
682 | nz <<= 8; // set Z flag without affecting N flag | 682 | nz <<= 8; // set Z flag without affecting N flag |
683 | goto loop; | 683 | goto loop; |
684 | 684 | ||
685 | // Add/subtract | 685 | // Add/subtract |
686 | 686 | ||
687 | ARITH_ADDR_MODES( 0xE5 ) // SBC | 687 | ARITH_ADDR_MODES( 0xE5 ) // SBC |
688 | case 0xEB: // unofficial equivalent | 688 | case 0xEB: // unofficial equivalent |
689 | data ^= 0xFF; | 689 | data ^= 0xFF; |
690 | goto adc_imm; | 690 | goto adc_imm; |
691 | 691 | ||
692 | ARITH_ADDR_MODES( 0x65 ) // ADC | 692 | ARITH_ADDR_MODES( 0x65 ) // ADC |
693 | adc_imm: { | 693 | adc_imm: { |
694 | int carry = c >> 8 & 1; | 694 | int carry = c >> 8 & 1; |
695 | int ov = (a ^ 0x80) + carry + SBYTE( data ); | 695 | int ov = (a ^ 0x80) + carry + SBYTE( data ); |
696 | flags = (flags & ~v40) + (ov >> 2 & v40); | 696 | flags = (flags & ~v40) + (ov >> 2 & v40); |
697 | c = nz = a + data + carry; | 697 | c = nz = a + data + carry; |
698 | pc++; | 698 | pc++; |
699 | a = BYTE( nz ); | 699 | a = BYTE( nz ); |
700 | goto loop; | 700 | goto loop; |
701 | } | 701 | } |
702 | 702 | ||
703 | // Shift/rotate | 703 | // Shift/rotate |
704 | 704 | ||
705 | case 0x4A: // LSR A | 705 | case 0x4A: // LSR A |
706 | c = 0; | 706 | c = 0; |
707 | case 0x6A: // ROR A | 707 | case 0x6A: // ROR A |
708 | nz = c >> 1 & 0x80; | 708 | nz = c >> 1 & 0x80; |
709 | c = a << 8; | 709 | c = a << 8; |
710 | nz += a >> 1; | 710 | nz += a >> 1; |
711 | a = nz; | 711 | a = nz; |
712 | goto loop; | 712 | goto loop; |
713 | 713 | ||
714 | case 0x0A: // ASL A | 714 | case 0x0A: // ASL A |
715 | nz = a << 1; | 715 | nz = a << 1; |
716 | c = nz; | 716 | c = nz; |
717 | a = BYTE( nz ); | 717 | a = BYTE( nz ); |
718 | goto loop; | 718 | goto loop; |
719 | 719 | ||
720 | case 0x2A: { // ROL A | 720 | case 0x2A: { // ROL A |
721 | nz = a << 1; | 721 | nz = a << 1; |
722 | int temp = c >> 8 & 1; | 722 | int temp = c >> 8 & 1; |
723 | c = nz; | 723 | c = nz; |
724 | nz += temp; | 724 | nz += temp; |
725 | a = BYTE( nz ); | 725 | a = BYTE( nz ); |
726 | goto loop; | 726 | goto loop; |
727 | } | 727 | } |
728 | 728 | ||
729 | case 0x5E: // LSR abs,X | 729 | case 0x5E: // LSR abs,X |
730 | data += x; | 730 | data += x; |
731 | case 0x4E: // LSR abs | 731 | case 0x4E: // LSR abs |
732 | c = 0; | 732 | c = 0; |
733 | case 0x6E: // ROR abs | 733 | case 0x6E: // ROR abs |
734 | ror_abs: { | 734 | ror_abs: { |
735 | ADD_PAGE( data ); | 735 | ADD_PAGE( data ); |
736 | FLUSH_TIME(); | 736 | FLUSH_TIME(); |
737 | int temp = READ_MEM( data ); | 737 | int temp = READ_MEM( data ); |
738 | nz = (c >> 1 & 0x80) + (temp >> 1); | 738 | nz = (c >> 1 & 0x80) + (temp >> 1); |
739 | c = temp << 8; | 739 | c = temp << 8; |
740 | goto rotate_common; | 740 | goto rotate_common; |
741 | } | 741 | } |
742 | 742 | ||
743 | case 0x3E: // ROL abs,X | 743 | case 0x3E: // ROL abs,X |
744 | data += x; | 744 | data += x; |
745 | goto rol_abs; | 745 | goto rol_abs; |
746 | 746 | ||
747 | case 0x1E: // ASL abs,X | 747 | case 0x1E: // ASL abs,X |
748 | data += x; | 748 | data += x; |
749 | case 0x0E: // ASL abs | 749 | case 0x0E: // ASL abs |
750 | c = 0; | 750 | c = 0; |
751 | case 0x2E: // ROL abs | 751 | case 0x2E: // ROL abs |
752 | rol_abs: | 752 | rol_abs: |
753 | ADD_PAGE( data ); | 753 | ADD_PAGE( data ); |
754 | nz = c >> 8 & 1; | 754 | nz = c >> 8 & 1; |
755 | FLUSH_TIME(); | 755 | FLUSH_TIME(); |
756 | nz += (c = READ_MEM( data ) << 1); | 756 | nz += (c = READ_MEM( data ) << 1); |
757 | rotate_common: | 757 | rotate_common: |
758 | pc++; | 758 | pc++; |
759 | WRITE_MEM( data, BYTE( nz ) ); | 759 | WRITE_MEM( data, BYTE( nz ) ); |
760 | CACHE_TIME(); | 760 | CACHE_TIME(); |
761 | goto loop; | 761 | goto loop; |
762 | 762 | ||
763 | case 0x7E: // ROR abs,X | 763 | case 0x7E: // ROR abs,X |
764 | data += x; | 764 | data += x; |
765 | goto ror_abs; | 765 | goto ror_abs; |
766 | 766 | ||
767 | case 0x76: // ROR zp,x | 767 | case 0x76: // ROR zp,x |
768 | data = BYTE( data + x ); | 768 | data = BYTE( data + x ); |
769 | goto ror_zp; | 769 | goto ror_zp; |
770 | 770 | ||
771 | case 0x56: // LSR zp,x | 771 | case 0x56: // LSR zp,x |
772 | data = BYTE( data + x ); | 772 | data = BYTE( data + x ); |
773 | case 0x46: // LSR zp | 773 | case 0x46: // LSR zp |
774 | c = 0; | 774 | c = 0; |
775 | case 0x66: // ROR zp | 775 | case 0x66: // ROR zp |
776 | ror_zp: { | 776 | ror_zp: { |
777 | int temp = READ_LOW( data ); | 777 | int temp = READ_LOW( data ); |
778 | nz = (c >> 1 & 0x80) + (temp >> 1); | 778 | nz = (c >> 1 & 0x80) + (temp >> 1); |
779 | c = temp << 8; | 779 | c = temp << 8; |
780 | goto write_nz_zp; | 780 | goto write_nz_zp; |
781 | } | 781 | } |
782 | 782 | ||
783 | case 0x36: // ROL zp,x | 783 | case 0x36: // ROL zp,x |
784 | data = BYTE( data + x ); | 784 | data = BYTE( data + x ); |
785 | goto rol_zp; | 785 | goto rol_zp; |
786 | 786 | ||
787 | case 0x16: // ASL zp,x | 787 | case 0x16: // ASL zp,x |
788 | data = BYTE( data + x ); | 788 | data = BYTE( data + x ); |
789 | case 0x06: // ASL zp | 789 | case 0x06: // ASL zp |
790 | c = 0; | 790 | c = 0; |
791 | case 0x26: // ROL zp | 791 | case 0x26: // ROL zp |
792 | rol_zp: | 792 | rol_zp: |
793 | nz = c >> 8 & 1; | 793 | nz = c >> 8 & 1; |
794 | nz += (c = READ_LOW( data ) << 1); | 794 | nz += (c = READ_LOW( data ) << 1); |
795 | goto write_nz_zp; | 795 | goto write_nz_zp; |
796 | 796 | ||
797 | // Increment/decrement | 797 | // Increment/decrement |
798 | 798 | ||
799 | case 0xCA: // DEX | 799 | case 0xCA: // DEX |
800 | INC_DEC( x, -1 ) | 800 | INC_DEC( x, -1 ) |
801 | 801 | ||
802 | case 0x88: // DEY | 802 | case 0x88: // DEY |
803 | INC_DEC( y, -1 ) | 803 | INC_DEC( y, -1 ) |
804 | 804 | ||
805 | case 0xF6: // INC zp,x | 805 | case 0xF6: // INC zp,x |
806 | data = BYTE( data + x ); | 806 | data = BYTE( data + x ); |
807 | case 0xE6: // INC zp | 807 | case 0xE6: // INC zp |
808 | nz = 1; | 808 | nz = 1; |
809 | goto add_nz_zp; | 809 | goto add_nz_zp; |
810 | 810 | ||
811 | case 0xD6: // DEC zp,x | 811 | case 0xD6: // DEC zp,x |
812 | data = BYTE( data + x ); | 812 | data = BYTE( data + x ); |
813 | case 0xC6: // DEC zp | 813 | case 0xC6: // DEC zp |
814 | nz = -1; | 814 | nz = -1; |
815 | add_nz_zp: | 815 | add_nz_zp: |
816 | nz += READ_LOW( data ); | 816 | nz += READ_LOW( data ); |
817 | write_nz_zp: | 817 | write_nz_zp: |
818 | pc++; | 818 | pc++; |
819 | WRITE_LOW( data, nz ); | 819 | WRITE_LOW( data, nz ); |
820 | goto loop; | 820 | goto loop; |
821 | 821 | ||
822 | case 0xFE: // INC abs,x | 822 | case 0xFE: // INC abs,x |
823 | data = x + GET_ADDR(); | 823 | data = x + GET_ADDR(); |
824 | goto inc_ptr; | 824 | goto inc_ptr; |
825 | 825 | ||
826 | case 0xEE: // INC abs | 826 | case 0xEE: // INC abs |
827 | data = GET_ADDR(); | 827 | data = GET_ADDR(); |
828 | inc_ptr: | 828 | inc_ptr: |
829 | nz = 1; | 829 | nz = 1; |
830 | goto inc_common; | 830 | goto inc_common; |
831 | 831 | ||
832 | case 0xDE: // DEC abs,x | 832 | case 0xDE: // DEC abs,x |
833 | data = x + GET_ADDR(); | 833 | data = x + GET_ADDR(); |
834 | goto dec_ptr; | 834 | goto dec_ptr; |
835 | 835 | ||
836 | case 0xCE: // DEC abs | 836 | case 0xCE: // DEC abs |
837 | data = GET_ADDR(); | 837 | data = GET_ADDR(); |
838 | dec_ptr: | 838 | dec_ptr: |
839 | nz = -1; | 839 | nz = -1; |
840 | inc_common: | 840 | inc_common: |
841 | FLUSH_TIME(); | 841 | FLUSH_TIME(); |
842 | pc += 2; | 842 | pc += 2; |
843 | nz += READ_MEM( data ); | 843 | nz += READ_MEM( data ); |
844 | WRITE_MEM( data, BYTE( nz ) ); | 844 | WRITE_MEM( data, BYTE( nz ) ); |
845 | CACHE_TIME(); | 845 | CACHE_TIME(); |
846 | goto loop; | 846 | goto loop; |
847 | 847 | ||
848 | // Transfer | 848 | // Transfer |
849 | 849 | ||
850 | case 0xAA: // TAX | 850 | case 0xAA: // TAX |
851 | x = nz = a; | 851 | x = nz = a; |
852 | goto loop; | 852 | goto loop; |
853 | 853 | ||
854 | case 0x8A: // TXA | 854 | case 0x8A: // TXA |
855 | a = nz = x; | 855 | a = nz = x; |
856 | goto loop; | 856 | goto loop; |
857 | 857 | ||
858 | case 0x9A: // TXS | 858 | case 0x9A: // TXS |
859 | SET_SP( x ); // verified (no flag change) | 859 | SET_SP( x ); // verified (no flag change) |
860 | goto loop; | 860 | goto loop; |
861 | 861 | ||
862 | case 0xBA: // TSX | 862 | case 0xBA: // TSX |
863 | x = nz = GET_SP(); | 863 | x = nz = GET_SP(); |
864 | goto loop; | 864 | goto loop; |
865 | 865 | ||
866 | // Stack | 866 | // Stack |
867 | 867 | ||
868 | case 0x48: // PHA | 868 | case 0x48: // PHA |
869 | sp = SP( -1 ); | 869 | sp = SP( -1 ); |
870 | WRITE_STACK( sp, a ); | 870 | WRITE_STACK( sp, a ); |
871 | goto loop; | 871 | goto loop; |
872 | 872 | ||
873 | case 0x68: // PLA | 873 | case 0x68: // PLA |
874 | a = nz = READ_STACK( sp ); | 874 | a = nz = READ_STACK( sp ); |
875 | sp = SP( 1 ); | 875 | sp = SP( 1 ); |
876 | goto loop; | 876 | goto loop; |
877 | 877 | ||
878 | case 0x40:{// RTI | 878 | case 0x40:{// RTI |
879 | pc = READ_STACK( SP( 1 ) ); | 879 | pc = READ_STACK( SP( 1 ) ); |
880 | pc += READ_STACK( SP( 2 ) ) * 0x100; | 880 | pc += READ_STACK( SP( 2 ) ) * 0x100; |
881 | int temp = READ_STACK( sp ); | 881 | int temp = READ_STACK( sp ); |
882 | sp = SP( 3 ); | 882 | sp = SP( 3 ); |
883 | data = flags; | 883 | data = flags; |
884 | SET_FLAGS( temp ); | 884 | SET_FLAGS( temp ); |
885 | cpu->r.flags = flags; // update externally-visible I flag | 885 | cpu->r.flags = flags; // update externally-visible I flag |
886 | int delta = s.base - cpu->irq_time; | 886 | int delta = s.base - cpu->irq_time; |
887 | if ( delta <= 0 ) goto loop; // end_time < irq_time | 887 | if ( delta <= 0 ) goto loop; // end_time < irq_time |
888 | if ( flags & i04 ) goto loop; | 888 | if ( flags & i04 ) goto loop; |
889 | s_time += delta; | 889 | s_time += delta; |
890 | s.base = cpu->irq_time; | 890 | s.base = cpu->irq_time; |
891 | goto loop; | 891 | goto loop; |
892 | } | 892 | } |
893 | 893 | ||
894 | case 0x28:{// PLP | 894 | case 0x28:{// PLP |
895 | int temp = READ_STACK( sp ); | 895 | int temp = READ_STACK( sp ); |
896 | sp = SP( 1 ); | 896 | sp = SP( 1 ); |
897 | int changed = flags ^ temp; | 897 | int changed = flags ^ temp; |
898 | SET_FLAGS( temp ); | 898 | SET_FLAGS( temp ); |
899 | if ( !(changed & i04) ) | 899 | if ( !(changed & i04) ) |
900 | goto loop; // I flag didn't change | 900 | goto loop; // I flag didn't change |
901 | if ( flags & i04 ) | 901 | if ( flags & i04 ) |
902 | goto handle_sei; | 902 | goto handle_sei; |
903 | goto handle_cli; | 903 | goto handle_cli; |
904 | } | 904 | } |
905 | 905 | ||
906 | case 0x08:{// PHP | 906 | case 0x08:{// PHP |
907 | int temp; | 907 | int temp; |
908 | GET_FLAGS( temp ); | 908 | GET_FLAGS( temp ); |
909 | sp = SP( -1 ); | 909 | sp = SP( -1 ); |
910 | WRITE_STACK( sp, temp | (b10 | r20) ); | 910 | WRITE_STACK( sp, temp | (b10 | r20) ); |
911 | goto loop; | 911 | goto loop; |
912 | } | 912 | } |
913 | 913 | ||
914 | case 0x6C:{// JMP (ind) | 914 | case 0x6C:{// JMP (ind) |
915 | data = GET_ADDR(); | 915 | data = GET_ADDR(); |
916 | byte const* page = CODE_PAGE( data ); | 916 | byte const* page = CODE_PAGE( data ); |
917 | pc = page [CODE_OFFSET( data )]; | 917 | pc = page [CODE_OFFSET( data )]; |
918 | data = (data & 0xFF00) + ((data + 1) & 0xFF); | 918 | data = (data & 0xFF00) + ((data + 1) & 0xFF); |
919 | pc += page [CODE_OFFSET( data )] * 0x100; | 919 | pc += page [CODE_OFFSET( data )] * 0x100; |
920 | goto loop; | 920 | goto loop; |
921 | } | 921 | } |
922 | 922 | ||
923 | case 0x00: // BRK | 923 | case 0x00: // BRK |
924 | goto handle_brk; | 924 | goto handle_brk; |
925 | 925 | ||
926 | // Flags | 926 | // Flags |
927 | 927 | ||
928 | case 0x38: // SEC | 928 | case 0x38: // SEC |
929 | c = 0x100; | 929 | c = 0x100; |
930 | goto loop; | 930 | goto loop; |
931 | 931 | ||
932 | case 0x18: // CLC | 932 | case 0x18: // CLC |
933 | c = 0; | 933 | c = 0; |
934 | goto loop; | 934 | goto loop; |
935 | 935 | ||
936 | case 0xB8: // CLV | 936 | case 0xB8: // CLV |
937 | flags &= ~v40; | 937 | flags &= ~v40; |
938 | goto loop; | 938 | goto loop; |
939 | 939 | ||
940 | case 0xD8: // CLD | 940 | case 0xD8: // CLD |
941 | flags &= ~d08; | 941 | flags &= ~d08; |
942 | goto loop; | 942 | goto loop; |
943 | 943 | ||
944 | case 0xF8: // SED | 944 | case 0xF8: // SED |
945 | flags |= d08; | 945 | flags |= d08; |
946 | goto loop; | 946 | goto loop; |
947 | 947 | ||
948 | case 0x58: // CLI | 948 | case 0x58: // CLI |
949 | if ( !(flags & i04) ) | 949 | if ( !(flags & i04) ) |
950 | goto loop; | 950 | goto loop; |
951 | flags &= ~i04; | 951 | flags &= ~i04; |
952 | handle_cli: { | 952 | handle_cli: { |
953 | //dprintf( "CLI at %d\n", TIME ); | 953 | //dprintf( "CLI at %d\n", TIME ); |
954 | cpu->r.flags = flags; // update externally-visible I flag | 954 | cpu->r.flags = flags; // update externally-visible I flag |
955 | int delta = s.base - cpu->irq_time; | 955 | int delta = s.base - cpu->irq_time; |
956 | if ( delta <= 0 ) | 956 | if ( delta <= 0 ) |
957 | { | 957 | { |
958 | if ( TIME() < cpu->irq_time ) | 958 | if ( TIME() < cpu->irq_time ) |
959 | goto loop; | 959 | goto loop; |
960 | goto delayed_cli; | 960 | goto delayed_cli; |
961 | } | 961 | } |
962 | s.base = cpu->irq_time; | 962 | s.base = cpu->irq_time; |
963 | s_time += delta; | 963 | s_time += delta; |
964 | if ( s_time < 0 ) | 964 | if ( s_time < 0 ) |
965 | goto loop; | 965 | goto loop; |
966 | 966 | ||
967 | if ( delta >= s_time + 1 ) | 967 | if ( delta >= s_time + 1 ) |
968 | { | 968 | { |
969 | // delayed irq until after next instruction | 969 | // delayed irq until after next instruction |
970 | s.base += s_time + 1; | 970 | s.base += s_time + 1; |
971 | s_time = -1; | 971 | s_time = -1; |
972 | goto loop; | 972 | goto loop; |
973 | } | 973 | } |
974 | 974 | ||
975 | // TODO: implement | 975 | // TODO: implement |
976 | delayed_cli: | 976 | delayed_cli: |
977 | dprintf( "Delayed CLI not emulated\n" ); | 977 | dprintf( "Delayed CLI not emulated\n" ); |
978 | goto loop; | 978 | goto loop; |
979 | } | 979 | } |
980 | 980 | ||
981 | case 0x78: // SEI | 981 | case 0x78: // SEI |
982 | if ( flags & i04 ) | 982 | if ( flags & i04 ) |
983 | goto loop; | 983 | goto loop; |
984 | flags |= i04; | 984 | flags |= i04; |
985 | handle_sei: { | 985 | handle_sei: { |
986 | cpu->r.flags = flags; // update externally-visible I flag | 986 | cpu->r.flags = flags; // update externally-visible I flag |
987 | int delta = s.base - cpu->end_time; | 987 | int delta = s.base - cpu->end_time; |
988 | s.base = cpu->end_time; | 988 | s.base = cpu->end_time; |
989 | s_time += delta; | 989 | s_time += delta; |
990 | if ( s_time < 0 ) | 990 | if ( s_time < 0 ) |
991 | goto loop; | 991 | goto loop; |
992 | 992 | ||
993 | dprintf( "Delayed SEI not emulated\n" ); | 993 | dprintf( "Delayed SEI not emulated\n" ); |
994 | goto loop; | 994 | goto loop; |
995 | } | 995 | } |
996 | 996 | ||
997 | // Unofficial | 997 | // Unofficial |
998 | 998 | ||
999 | // SKW - skip word | 999 | // SKW - skip word |
1000 | case 0x1C: case 0x3C: case 0x5C: case 0x7C: case 0xDC: case 0xFC: | 1000 | case 0x1C: case 0x3C: case 0x5C: case 0x7C: case 0xDC: case 0xFC: |
1001 | PAGE_PENALTY( data + x ); | 1001 | PAGE_PENALTY( data + x ); |
1002 | case 0x0C: | 1002 | case 0x0C: |
1003 | pc++; | 1003 | pc++; |
1004 | // SKB - skip byte | 1004 | // SKB - skip byte |
1005 | case 0x74: case 0x04: case 0x14: case 0x34: case 0x44: case 0x54: case 0x64: | 1005 | case 0x74: case 0x04: case 0x14: case 0x34: case 0x44: case 0x54: case 0x64: |
1006 | case 0x80: case 0x82: case 0x89: case 0xC2: case 0xD4: case 0xE2: case 0xF4: | 1006 | case 0x80: case 0x82: case 0x89: case 0xC2: case 0xD4: case 0xE2: case 0xF4: |
1007 | pc++; | 1007 | pc++; |
1008 | goto loop; | 1008 | goto loop; |
1009 | 1009 | ||
1010 | // NOP | 1010 | // NOP |
1011 | case 0xEA: case 0x1A: case 0x3A: case 0x5A: case 0x7A: case 0xDA: case 0xFA: | 1011 | case 0xEA: case 0x1A: case 0x3A: case 0x5A: case 0x7A: case 0xDA: case 0xFA: |
1012 | goto loop; | 1012 | goto loop; |
1013 | 1013 | ||
1014 | case halt_opcode: // HLT - halt processor | 1014 | case halt_opcode: // HLT - halt processor |
1015 | if ( pc-- > 0x10000 ) | 1015 | if ( pc-- > 0x10000 ) |
1016 | { | 1016 | { |
1017 | // handle wrap-around (assumes caller has put page of HLT at 0x10000) | 1017 | // handle wrap-around (assumes caller has put page of HLT at 0x10000) |
1018 | pc = WORD( pc ); | 1018 | pc = WORD( pc ); |
1019 | goto loop; | 1019 | goto loop; |
1020 | } | 1020 | } |
1021 | case 0x02: case 0x12: case 0x32: case 0x42: case 0x52: | 1021 | case 0x02: case 0x12: case 0x32: case 0x42: case 0x52: |
1022 | case 0x62: case 0x72: case 0x92: case 0xB2: case 0xD2: case 0xF2: | 1022 | case 0x62: case 0x72: case 0x92: case 0xB2: case 0xD2: case 0xF2: |
1023 | goto stop; | 1023 | goto stop; |
1024 | 1024 | ||
1025 | // Unimplemented | 1025 | // Unimplemented |
1026 | 1026 | ||
1027 | case 0xFF: // force 256-entry jump table for optimization purposes | 1027 | case 0xFF: // force 256-entry jump table for optimization purposes |
1028 | c |= 1; // compiler doesn't know that this won't affect anything | 1028 | c |= 1; // compiler doesn't know that this won't affect anything |
1029 | default: | 1029 | default: |
1030 | check( (unsigned) opcode < 0x100 ); | 1030 | check( (unsigned) opcode < 0x100 ); |
1031 | 1031 | ||
1032 | #ifdef UNIMPL_INSTR | 1032 | #ifdef UNIMPL_INSTR |
1033 | UNIMPL_INSTR(); | 1033 | UNIMPL_INSTR(); |
1034 | #endif | 1034 | #endif |
1035 | 1035 | ||
1036 | // At least skip over proper number of bytes instruction uses | 1036 | // At least skip over proper number of bytes instruction uses |
1037 | static unsigned char const illop_lens [8] = { | 1037 | static unsigned char const illop_lens [8] = { |
1038 | 0x40, 0x40, 0x40, 0x80, 0x40, 0x40, 0x80, 0xA0 | 1038 | 0x40, 0x40, 0x40, 0x80, 0x40, 0x40, 0x80, 0xA0 |
1039 | }; | 1039 | }; |
1040 | int opcode = instr [-1]; | 1040 | int opcode = instr [-1]; |
1041 | int len = illop_lens [opcode >> 2 & 7] >> (opcode << 1 & 6) & 3; | 1041 | int len = illop_lens [opcode >> 2 & 7] >> (opcode << 1 & 6) & 3; |
1042 | if ( opcode == 0x9C ) | 1042 | if ( opcode == 0x9C ) |
1043 | len = 2; | 1043 | len = 2; |
1044 | pc += len; | 1044 | pc += len; |
1045 | 1045 | ||
1046 | // Account for extra clock | 1046 | // Account for extra clock |
1047 | if ( (opcode >> 4) == 0x0B ) | 1047 | if ( (opcode >> 4) == 0x0B ) |
1048 | { | 1048 | { |
1049 | if ( opcode == 0xB3 ) | 1049 | if ( opcode == 0xB3 ) |
1050 | data = READ_LOW( data ); | 1050 | data = READ_LOW( data ); |
1051 | if ( opcode != 0xB7 ) | 1051 | if ( opcode != 0xB7 ) |
1052 | PAGE_PENALTY( data + y ); | 1052 | PAGE_PENALTY( data + y ); |
1053 | } | 1053 | } |
1054 | goto loop; | 1054 | goto loop; |
1055 | } | 1055 | } |
1056 | assert( false ); // catch missing 'goto loop' or accidental 'break' | 1056 | assert( false ); // catch missing 'goto loop' or accidental 'break' |
1057 | 1057 | ||
1058 | int result_; | 1058 | int result_; |
1059 | handle_brk: | 1059 | handle_brk: |
1060 | pc++; | 1060 | pc++; |
1061 | result_ = b10 | 4; | 1061 | result_ = b10 | 4; |
1062 | 1062 | ||
1063 | #ifdef CPU_DONE | 1063 | #ifdef CPU_DONE |
1064 | interrupt: | 1064 | interrupt: |
1065 | #endif | 1065 | #endif |
1066 | { | 1066 | { |
1067 | s_time += 7; | 1067 | s_time += 7; |
1068 | 1068 | ||
1069 | // Save PC and read vector | 1069 | // Save PC and read vector |
1070 | WRITE_STACK( SP( -1 ), pc >> 8 ); | 1070 | WRITE_STACK( SP( -1 ), pc >> 8 ); |
1071 | WRITE_STACK( SP( -2 ), pc ); | 1071 | WRITE_STACK( SP( -2 ), pc ); |
1072 | pc = GET_LE16( &READ_CODE( 0xFFFA ) + (result_ & 4) ); | 1072 | pc = GET_LE16( &READ_CODE( 0xFFFA ) + (result_ & 4) ); |
1073 | 1073 | ||
1074 | // Save flags | 1074 | // Save flags |
1075 | int temp; | 1075 | int temp; |
1076 | GET_FLAGS( temp ); | 1076 | GET_FLAGS( temp ); |
1077 | temp |= r20 + (result_ & b10); // B flag set for BRK | 1077 | temp |= r20 + (result_ & b10); // B flag set for BRK |
1078 | sp = SP( -3 ); | 1078 | sp = SP( -3 ); |
1079 | WRITE_STACK( sp, temp ); | 1079 | WRITE_STACK( sp, temp ); |
1080 | 1080 | ||
1081 | // Update I flag in externally-visible flags | 1081 | // Update I flag in externally-visible flags |
1082 | cpu->r.flags = (flags |= i04); | 1082 | cpu->r.flags = (flags |= i04); |
1083 | 1083 | ||
1084 | // Update time | 1084 | // Update time |
1085 | int delta = s.base - cpu->end_time; | 1085 | int delta = s.base - cpu->end_time; |
1086 | if ( delta >= 0 ) | 1086 | if ( delta >= 0 ) |
1087 | goto loop; | 1087 | goto loop; |
1088 | s_time += delta; | 1088 | s_time += delta; |
1089 | s.base = cpu->end_time; | 1089 | s.base = cpu->end_time; |
1090 | goto loop; | 1090 | goto loop; |
1091 | } | 1091 | } |
1092 | 1092 | ||
1093 | out_of_time: | 1093 | out_of_time: |
1094 | pc--; | 1094 | pc--; |
1095 | 1095 | ||
1096 | // Optional action that triggers interrupt or changes irq/end time | 1096 | // Optional action that triggers interrupt or changes irq/end time |
1097 | #ifdef CPU_DONE | 1097 | #ifdef CPU_DONE |
1098 | { | 1098 | { |
1099 | CPU_DONE( result_ ); | 1099 | CPU_DONE( result_ ); |
1100 | if ( result_ >= 0 ) | 1100 | if ( result_ >= 0 ) |
1101 | goto interrupt; | 1101 | goto interrupt; |
1102 | if ( s_time < 0 ) | 1102 | if ( s_time < 0 ) |
1103 | goto loop; | 1103 | goto loop; |
1104 | } | 1104 | } |
1105 | #endif | 1105 | #endif |
1106 | stop: | 1106 | stop: |
1107 | 1107 | ||
1108 | // Flush cached state | 1108 | // Flush cached state |
1109 | cpu->r.pc = pc; | 1109 | cpu->r.pc = pc; |
1110 | cpu->r.sp = GET_SP(); | 1110 | cpu->r.sp = GET_SP(); |
1111 | cpu->r.a = a; | 1111 | cpu->r.a = a; |
1112 | cpu->r.x = x; | 1112 | cpu->r.x = x; |
1113 | cpu->r.y = y; | 1113 | cpu->r.y = y; |
1114 | 1114 | ||
1115 | int temp; | 1115 | int temp; |
1116 | GET_FLAGS( temp ); | 1116 | GET_FLAGS( temp ); |
1117 | cpu->r.flags = temp; | 1117 | cpu->r.flags = temp; |
1118 | 1118 | ||
1119 | cpu->cpu_state_.base = s.base; | 1119 | cpu->cpu_state_.base = s.base; |
1120 | cpu->cpu_state_.time = s_time; | 1120 | cpu->cpu_state_.time = s_time; |
1121 | cpu->cpu_state = &cpu->cpu_state_; | 1121 | cpu->cpu_state = &cpu->cpu_state_; |
1122 | } | 1122 | } |
diff --git a/apps/codecs/libgme/nes_vrc7_apu.c b/apps/codecs/libgme/nes_vrc7_apu.c index 95bc676c26..8d3c2e88a6 100644 --- a/apps/codecs/libgme/nes_vrc7_apu.c +++ b/apps/codecs/libgme/nes_vrc7_apu.c | |||
@@ -1,88 +1,88 @@ | |||
1 | 1 | ||
2 | #include "nes_vrc7_apu.h" | 2 | #include "nes_vrc7_apu.h" |
3 | #include "blargg_source.h" | 3 | #include "blargg_source.h" |
4 | 4 | ||
5 | int const period = 36; // NES CPU clocks per FM clock | 5 | int const period = 36; // NES CPU clocks per FM clock |
6 | 6 | ||
7 | void Vrc7_init( struct Nes_Vrc7_Apu* this ) | 7 | void Vrc7_init( struct Nes_Vrc7_Apu* this ) |
8 | { | 8 | { |
9 | Synth_init( &this->synth ); | 9 | Synth_init( &this->synth ); |
10 | 10 | ||
11 | OPLL_new ( &this->opll, 3579545, 3579545 / 72 ); | 11 | OPLL_new ( &this->opll, 3579545, 3579545 / 72 ); |
12 | OPLL_reset_patch( &this->opll, OPLL_VRC7_TONE ); | 12 | OPLL_reset_patch( &this->opll, OPLL_VRC7_TONE ); |
13 | 13 | ||
14 | this->osc.output = 0; | 14 | this->osc.output = 0; |
15 | this->osc.last_amp = 0; | 15 | this->osc.last_amp = 0; |
16 | this->mask = 0; | 16 | this->mask = 0; |
17 | 17 | ||
18 | Vrc7_volume( this, (int)FP_ONE_VOLUME ); | 18 | Vrc7_volume( this, (int)FP_ONE_VOLUME ); |
19 | Vrc7_reset( this ); | 19 | Vrc7_reset( this ); |
20 | } | 20 | } |
21 | 21 | ||
22 | void Vrc7_reset( struct Nes_Vrc7_Apu* this ) | 22 | void Vrc7_reset( struct Nes_Vrc7_Apu* this ) |
23 | { | 23 | { |
24 | this->addr = 0; | 24 | this->addr = 0; |
25 | this->next_time = 0; | 25 | this->next_time = 0; |
26 | this->osc.last_amp = 0; | 26 | this->osc.last_amp = 0; |
27 | 27 | ||
28 | OPLL_reset (&this->opll); | 28 | OPLL_reset (&this->opll); |
29 | OPLL_setMask(&this->opll, this->mask); | 29 | OPLL_setMask(&this->opll, this->mask); |
30 | } | 30 | } |
31 | 31 | ||
32 | void Vrc7_set_rate( struct Nes_Vrc7_Apu* this, int r ) | 32 | void Vrc7_set_rate( struct Nes_Vrc7_Apu* this, int r ) |
33 | { | 33 | { |
34 | OPLL_set_quality( &this->opll, r < 44100 ? 0 : 1 ); | 34 | OPLL_set_quality( &this->opll, r < 44100 ? 0 : 1 ); |
35 | } | 35 | } |
36 | 36 | ||
37 | void Vrc7_write_reg( struct Nes_Vrc7_Apu* this, int data ) | 37 | void Vrc7_write_reg( struct Nes_Vrc7_Apu* this, int data ) |
38 | { | 38 | { |
39 | this->addr = data; | 39 | this->addr = data; |
40 | } | 40 | } |
41 | 41 | ||
42 | void Vrc7_run_until( struct Nes_Vrc7_Apu* this, blip_time_t end_time ); | 42 | void Vrc7_run_until( struct Nes_Vrc7_Apu* this, blip_time_t end_time ); |
43 | void Vrc7_write_data( struct Nes_Vrc7_Apu* this, blip_time_t time, int data ) | 43 | void Vrc7_write_data( struct Nes_Vrc7_Apu* this, blip_time_t time, int data ) |
44 | { | 44 | { |
45 | if ( time > this->next_time ) | 45 | if ( time > this->next_time ) |
46 | Vrc7_run_until( this, time ); | 46 | Vrc7_run_until( this, time ); |
47 | 47 | ||
48 | OPLL_writeIO( &this->opll, 0, this->addr ); | 48 | OPLL_writeIO( &this->opll, 0, this->addr ); |
49 | OPLL_writeIO( &this->opll, 1, data ); | 49 | OPLL_writeIO( &this->opll, 1, data ); |
50 | } | 50 | } |
51 | 51 | ||
52 | void Vrc7_end_frame( struct Nes_Vrc7_Apu* this, blip_time_t time ) | 52 | void Vrc7_end_frame( struct Nes_Vrc7_Apu* this, blip_time_t time ) |
53 | { | 53 | { |
54 | if ( time > this->next_time ) | 54 | if ( time > this->next_time ) |
55 | Vrc7_run_until( this, time ); | 55 | Vrc7_run_until( this, time ); |
56 | 56 | ||
57 | this->next_time -= time; | 57 | this->next_time -= time; |
58 | assert( this->next_time >= 0 ); | 58 | assert( this->next_time >= 0 ); |
59 | 59 | ||
60 | if ( this->osc.output ) | 60 | if ( this->osc.output ) |
61 | Blip_set_modified( this->osc.output ); | 61 | Blip_set_modified( this->osc.output ); |
62 | } | 62 | } |
63 | 63 | ||
64 | void Vrc7_run_until( struct Nes_Vrc7_Apu* this, blip_time_t end_time ) | 64 | void Vrc7_run_until( struct Nes_Vrc7_Apu* this, blip_time_t end_time ) |
65 | { | 65 | { |
66 | require( end_time > this->next_time ); | 66 | require( end_time > this->next_time ); |
67 | 67 | ||
68 | blip_time_t time = this->next_time; | 68 | blip_time_t time = this->next_time; |
69 | OPLL* opll = &this->opll; // cache | 69 | OPLL* opll = &this->opll; // cache |
70 | struct Blip_Buffer* const output = this-> osc.output; | 70 | struct Blip_Buffer* const output = this-> osc.output; |
71 | if ( output ) | 71 | if ( output ) |
72 | { | 72 | { |
73 | do | 73 | do |
74 | { | 74 | { |
75 | int amp = OPLL_calc( opll ) << 1; | 75 | int amp = OPLL_calc( opll ) << 1; |
76 | int delta = amp - this->osc.last_amp; | 76 | int delta = amp - this->osc.last_amp; |
77 | if ( delta ) | 77 | if ( delta ) |
78 | { | 78 | { |
79 | this->osc.last_amp = amp; | 79 | this->osc.last_amp = amp; |
80 | Synth_offset_inline( &this->synth, time, delta, output ); | 80 | Synth_offset_inline( &this->synth, time, delta, output ); |
81 | } | 81 | } |
82 | time += period; | 82 | time += period; |
83 | } | 83 | } |
84 | while ( time < end_time ); | 84 | while ( time < end_time ); |
85 | } | 85 | } |
86 | 86 | ||
87 | this->next_time = time; | 87 | this->next_time = time; |
88 | } | 88 | } |
diff --git a/apps/codecs/libgme/opl_apu.c b/apps/codecs/libgme/opl_apu.c index 64b2714b81..b573baef11 100644 --- a/apps/codecs/libgme/opl_apu.c +++ b/apps/codecs/libgme/opl_apu.c | |||
@@ -1,198 +1,198 @@ | |||
1 | #include "opl_apu.h" | 1 | #include "opl_apu.h" |
2 | 2 | ||
3 | #include "blargg_source.h" | 3 | #include "blargg_source.h" |
4 | 4 | ||
5 | /* NOTE: Removed unused chips ~ gama */ | 5 | /* NOTE: Removed unused chips ~ gama */ |
6 | 6 | ||
7 | blargg_err_t Opl_init( struct Opl_Apu* this, long clock, long rate, blip_time_t period, enum opl_type_t type ) | 7 | blargg_err_t Opl_init( struct Opl_Apu* this, long clock, long rate, blip_time_t period, enum opl_type_t type ) |
8 | { | 8 | { |
9 | Synth_init( &this->synth ); | 9 | Synth_init( &this->synth ); |
10 | 10 | ||
11 | this->type_ = type; | 11 | this->type_ = type; |
12 | this->clock_ = clock; | 12 | this->clock_ = clock; |
13 | this->rate_ = rate; | 13 | this->rate_ = rate; |
14 | this->period_ = period; | 14 | this->period_ = period; |
15 | Opl_set_output( this, 0 ); | 15 | Opl_set_output( this, 0 ); |
16 | Opl_volume( this, (int)FP_ONE_VOLUME ); | 16 | Opl_volume( this, (int)FP_ONE_VOLUME ); |
17 | 17 | ||
18 | switch (type) | 18 | switch (type) |
19 | { | 19 | { |
20 | case type_opll: | 20 | case type_opll: |
21 | case type_msxmusic: | 21 | case type_msxmusic: |
22 | case type_smsfmunit: | 22 | case type_smsfmunit: |
23 | OPLL_new ( &this->opll, clock, rate ); | 23 | OPLL_new ( &this->opll, clock, rate ); |
24 | OPLL_reset_patch( &this->opll, OPLL_2413_TONE ); | 24 | OPLL_reset_patch( &this->opll, OPLL_2413_TONE ); |
25 | break; | 25 | break; |
26 | case type_vrc7: | 26 | case type_vrc7: |
27 | OPLL_new ( &this->opll, clock, rate ); | 27 | OPLL_new ( &this->opll, clock, rate ); |
28 | OPLL_reset_patch( &this->opll, OPLL_VRC7_TONE ); | 28 | OPLL_reset_patch( &this->opll, OPLL_VRC7_TONE ); |
29 | break; | 29 | break; |
30 | case type_msxaudio: | 30 | case type_msxaudio: |
31 | OPL_init( &this->opl, this->opl_memory, sizeof this->opl_memory ); | 31 | OPL_init( &this->opl, this->opl_memory, sizeof this->opl_memory ); |
32 | OPL_setSampleRate( &this->opl, rate, clock ); | 32 | OPL_setSampleRate( &this->opl, rate, clock ); |
33 | OPL_setInternalVolume(&this->opl, 1 << 13); | 33 | OPL_setInternalVolume(&this->opl, 1 << 13); |
34 | break; | 34 | break; |
35 | } | 35 | } |
36 | 36 | ||
37 | Opl_reset( this ); | 37 | Opl_reset( this ); |
38 | return 0; | 38 | return 0; |
39 | } | 39 | } |
40 | 40 | ||
41 | void Opl_shutdown( struct Opl_Apu* this ) | 41 | void Opl_shutdown( struct Opl_Apu* this ) |
42 | { | 42 | { |
43 | switch (this->type_) | 43 | switch (this->type_) |
44 | { | 44 | { |
45 | case type_opll: | 45 | case type_opll: |
46 | case type_msxmusic: | 46 | case type_msxmusic: |
47 | case type_smsfmunit: | 47 | case type_smsfmunit: |
48 | case type_vrc7: | 48 | case type_vrc7: |
49 | OPLL_delete( &this->opll ); | 49 | OPLL_delete( &this->opll ); |
50 | break; | 50 | break; |
51 | case type_msxaudio: break; | 51 | case type_msxaudio: break; |
52 | } | 52 | } |
53 | } | 53 | } |
54 | 54 | ||
55 | void Opl_reset( struct Opl_Apu* this ) | 55 | void Opl_reset( struct Opl_Apu* this ) |
56 | { | 56 | { |
57 | this->addr = 0; | 57 | this->addr = 0; |
58 | this->next_time = 0; | 58 | this->next_time = 0; |
59 | this->last_amp = 0; | 59 | this->last_amp = 0; |
60 | 60 | ||
61 | switch (this->type_) | 61 | switch (this->type_) |
62 | { | 62 | { |
63 | case type_opll: | 63 | case type_opll: |
64 | case type_msxmusic: | 64 | case type_msxmusic: |
65 | case type_smsfmunit: | 65 | case type_smsfmunit: |
66 | case type_vrc7: | 66 | case type_vrc7: |
67 | OPLL_reset( &this->opll ); | 67 | OPLL_reset( &this->opll ); |
68 | OPLL_setMask( &this->opll, 0 ); | 68 | OPLL_setMask( &this->opll, 0 ); |
69 | break; | 69 | break; |
70 | case type_msxaudio: | 70 | case type_msxaudio: |
71 | OPL_reset( &this->opl ); | 71 | OPL_reset( &this->opl ); |
72 | break; | 72 | break; |
73 | } | 73 | } |
74 | } | 74 | } |
75 | 75 | ||
76 | static void run_until( struct Opl_Apu* this, blip_time_t end_time ); | 76 | static void run_until( struct Opl_Apu* this, blip_time_t end_time ); |
77 | void Opl_write_data( struct Opl_Apu* this, blip_time_t time, int data ) | 77 | void Opl_write_data( struct Opl_Apu* this, blip_time_t time, int data ) |
78 | { | 78 | { |
79 | run_until( this, time ); | 79 | run_until( this, time ); |
80 | switch (this->type_) | 80 | switch (this->type_) |
81 | { | 81 | { |
82 | case type_opll: | 82 | case type_opll: |
83 | case type_msxmusic: | 83 | case type_msxmusic: |
84 | case type_smsfmunit: | 84 | case type_smsfmunit: |
85 | case type_vrc7: | 85 | case type_vrc7: |
86 | OPLL_writeIO( &this->opll, 0, this->addr ); | 86 | OPLL_writeIO( &this->opll, 0, this->addr ); |
87 | OPLL_writeIO( &this->opll, 1, data ); | 87 | OPLL_writeIO( &this->opll, 1, data ); |
88 | break; | 88 | break; |
89 | case type_msxaudio: | 89 | case type_msxaudio: |
90 | OPL_writeReg( &this->opl, this->addr, data ); | 90 | OPL_writeReg( &this->opl, this->addr, data ); |
91 | break; | 91 | break; |
92 | } | 92 | } |
93 | } | 93 | } |
94 | 94 | ||
95 | int Opl_read( struct Opl_Apu* this, blip_time_t time, int port ) | 95 | int Opl_read( struct Opl_Apu* this, blip_time_t time, int port ) |
96 | { | 96 | { |
97 | run_until( this, time ); | 97 | run_until( this, time ); |
98 | switch (this->type_) | 98 | switch (this->type_) |
99 | { | 99 | { |
100 | case type_opll: | 100 | case type_opll: |
101 | case type_msxmusic: | 101 | case type_msxmusic: |
102 | case type_smsfmunit: | 102 | case type_smsfmunit: |
103 | case type_vrc7: | 103 | case type_vrc7: |
104 | return OPLL_read( &this->opll, port ); | 104 | return OPLL_read( &this->opll, port ); |
105 | case type_msxaudio: | 105 | case type_msxaudio: |
106 | return OPL_readStatus( &this->opl ); | 106 | return OPL_readStatus( &this->opl ); |
107 | } | 107 | } |
108 | 108 | ||
109 | return 0; | 109 | return 0; |
110 | } | 110 | } |
111 | 111 | ||
112 | void Opl_end_frame( struct Opl_Apu* this, blip_time_t time ) | 112 | void Opl_end_frame( struct Opl_Apu* this, blip_time_t time ) |
113 | { | 113 | { |
114 | run_until( this, time ); | 114 | run_until( this, time ); |
115 | this->next_time -= time; | 115 | this->next_time -= time; |
116 | 116 | ||
117 | if ( this->output_ ) | 117 | if ( this->output_ ) |
118 | Blip_set_modified( this->output_ ); | 118 | Blip_set_modified( this->output_ ); |
119 | } | 119 | } |
120 | 120 | ||
121 | static void run_until( struct Opl_Apu* this, blip_time_t end_time ) | 121 | static void run_until( struct Opl_Apu* this, blip_time_t end_time ) |
122 | { | 122 | { |
123 | if ( end_time > this->next_time ) | 123 | if ( end_time > this->next_time ) |
124 | { | 124 | { |
125 | blip_time_t time_delta = end_time - this->next_time; | 125 | blip_time_t time_delta = end_time - this->next_time; |
126 | blip_time_t time = this->next_time; | 126 | blip_time_t time = this->next_time; |
127 | unsigned count = time_delta / this->period_ + 1; | 127 | unsigned count = time_delta / this->period_ + 1; |
128 | switch (this->type_) | 128 | switch (this->type_) |
129 | { | 129 | { |
130 | case type_opll: | 130 | case type_opll: |
131 | case type_msxmusic: | 131 | case type_msxmusic: |
132 | case type_smsfmunit: | 132 | case type_smsfmunit: |
133 | case type_vrc7: | 133 | case type_vrc7: |
134 | { | 134 | { |
135 | OPLL* opll = &this->opll; // cache | 135 | OPLL* opll = &this->opll; // cache |
136 | struct Blip_Buffer* const output = this->output_; | 136 | struct Blip_Buffer* const output = this->output_; |
137 | while ( count > 0 ) | 137 | while ( count > 0 ) |
138 | { | 138 | { |
139 | unsigned todo = count; | 139 | unsigned todo = count; |
140 | if ( todo > 1024 ) todo = 1024; | 140 | if ( todo > 1024 ) todo = 1024; |
141 | short *buffer = OPLL_update_buffer(opll, todo); | 141 | short *buffer = OPLL_update_buffer(opll, todo); |
142 | 142 | ||
143 | if ( output && buffer ) | 143 | if ( output && buffer ) |
144 | { | 144 | { |
145 | int last_amp = this->last_amp; | 145 | int last_amp = this->last_amp; |
146 | unsigned i; | 146 | unsigned i; |
147 | for ( i = 0; i < todo; i++ ) | 147 | for ( i = 0; i < todo; i++ ) |
148 | { | 148 | { |
149 | int amp = buffer [i]; | 149 | int amp = buffer [i]; |
150 | int delta = amp - last_amp; | 150 | int delta = amp - last_amp; |
151 | if ( delta ) | 151 | if ( delta ) |
152 | { | 152 | { |
153 | last_amp = amp; | 153 | last_amp = amp; |
154 | Synth_offset_inline( &this->synth, time, delta, output ); | 154 | Synth_offset_inline( &this->synth, time, delta, output ); |
155 | } | 155 | } |
156 | time += this->period_; | 156 | time += this->period_; |
157 | } | 157 | } |
158 | this->last_amp = last_amp; | 158 | this->last_amp = last_amp; |
159 | } | 159 | } |
160 | count -= todo; | 160 | count -= todo; |
161 | } | 161 | } |
162 | } | 162 | } |
163 | break; | 163 | break; |
164 | case type_msxaudio: | 164 | case type_msxaudio: |
165 | { | 165 | { |
166 | struct Y8950* opl = &this->opl; | 166 | struct Y8950* opl = &this->opl; |
167 | struct Blip_Buffer* const output = this->output_; | 167 | struct Blip_Buffer* const output = this->output_; |
168 | while ( count > 0 ) | 168 | while ( count > 0 ) |
169 | { | 169 | { |
170 | unsigned todo = count; | 170 | unsigned todo = count; |
171 | if ( todo > 1024 ) todo = 1024; | 171 | if ( todo > 1024 ) todo = 1024; |
172 | int *buffer = OPL_updateBuffer(opl, todo); | 172 | int *buffer = OPL_updateBuffer(opl, todo); |
173 | 173 | ||
174 | if ( output && buffer ) | 174 | if ( output && buffer ) |
175 | { | 175 | { |
176 | int last_amp = this->last_amp; | 176 | int last_amp = this->last_amp; |
177 | unsigned i; | 177 | unsigned i; |
178 | for ( i = 0; i < todo; i++ ) | 178 | for ( i = 0; i < todo; i++ ) |
179 | { | 179 | { |
180 | int amp = buffer [i]; | 180 | int amp = buffer [i]; |
181 | int delta = amp - last_amp; | 181 | int delta = amp - last_amp; |
182 | if ( delta ) | 182 | if ( delta ) |
183 | { | 183 | { |
184 | last_amp = amp; | 184 | last_amp = amp; |
185 | Synth_offset_inline( &this->synth, time, delta, output ); | 185 | Synth_offset_inline( &this->synth, time, delta, output ); |
186 | } | 186 | } |
187 | time += this->period_; | 187 | time += this->period_; |
188 | } | 188 | } |
189 | this->last_amp = last_amp; | 189 | this->last_amp = last_amp; |
190 | } | 190 | } |
191 | count -= todo; | 191 | count -= todo; |
192 | } | 192 | } |
193 | } | 193 | } |
194 | break; | 194 | break; |
195 | } | 195 | } |
196 | this->next_time = time; | 196 | this->next_time = time; |
197 | } | 197 | } |
198 | } | 198 | } |
diff --git a/apps/codecs/libgme/opl_apu.h b/apps/codecs/libgme/opl_apu.h index f24a8d60c2..76fa766492 100644 --- a/apps/codecs/libgme/opl_apu.h +++ b/apps/codecs/libgme/opl_apu.h | |||
@@ -1,63 +1,63 @@ | |||
1 | #ifndef OPL_APU_H | 1 | #ifndef OPL_APU_H |
2 | #define OPL_APU_H | 2 | #define OPL_APU_H |
3 | 3 | ||
4 | #include "blargg_common.h" | 4 | #include "blargg_common.h" |
5 | #include "blargg_source.h" | 5 | #include "blargg_source.h" |
6 | #include "blip_buffer.h" | 6 | #include "blip_buffer.h" |
7 | 7 | ||
8 | #include "emu8950.h" | 8 | #include "emu8950.h" |
9 | #include "emu2413.h" | 9 | #include "emu2413.h" |
10 | 10 | ||
11 | enum opl_type_t { type_opll = 0x10, type_msxmusic = 0x11, type_smsfmunit = 0x12, | 11 | enum opl_type_t { type_opll = 0x10, type_msxmusic = 0x11, type_smsfmunit = 0x12, |
12 | type_vrc7 = 0x13, type_msxaudio = 0x21 }; | 12 | type_vrc7 = 0x13, type_msxaudio = 0x21 }; |
13 | 13 | ||
14 | enum { opl_osc_count = 1 }; | 14 | enum { opl_osc_count = 1 }; |
15 | 15 | ||
16 | struct Opl_Apu { | 16 | struct Opl_Apu { |
17 | struct Blip_Buffer* output_; | 17 | struct Blip_Buffer* output_; |
18 | enum opl_type_t type_; | 18 | enum opl_type_t type_; |
19 | 19 | ||
20 | blip_time_t next_time; | 20 | blip_time_t next_time; |
21 | int last_amp; | 21 | int last_amp; |
22 | int addr; | 22 | int addr; |
23 | 23 | ||
24 | long clock_; | 24 | long clock_; |
25 | long rate_; | 25 | long rate_; |
26 | blip_time_t period_; | 26 | blip_time_t period_; |
27 | 27 | ||
28 | struct Blip_Synth synth; | 28 | struct Blip_Synth synth; |
29 | 29 | ||
30 | // OPL chips | 30 | // OPL chips |
31 | struct Y8950 opl; | 31 | struct Y8950 opl; |
32 | OPLL opll; | 32 | OPLL opll; |
33 | 33 | ||
34 | unsigned char regs[ 0x100 ]; | 34 | unsigned char regs[ 0x100 ]; |
35 | unsigned char opl_memory[ 32768 ]; | 35 | unsigned char opl_memory[ 32768 ]; |
36 | }; | 36 | }; |
37 | 37 | ||
38 | blargg_err_t Opl_init( struct Opl_Apu* this, long clock, long rate, blip_time_t period, enum opl_type_t type ); | 38 | blargg_err_t Opl_init( struct Opl_Apu* this, long clock, long rate, blip_time_t period, enum opl_type_t type ); |
39 | void Opl_shutdown( struct Opl_Apu* this ); | 39 | void Opl_shutdown( struct Opl_Apu* this ); |
40 | 40 | ||
41 | void Opl_reset( struct Opl_Apu* this ); | 41 | void Opl_reset( struct Opl_Apu* this ); |
42 | static inline void Opl_volume( struct Opl_Apu* this, int v ) { Synth_volume( &this->synth, v / (4096 * 6) ); } | 42 | static inline void Opl_volume( struct Opl_Apu* this, int v ) { Synth_volume( &this->synth, v / (4096 * 6) ); } |
43 | 43 | ||
44 | static inline void Opl_osc_output( struct Opl_Apu* this, int i, struct Blip_Buffer* buf ) | 44 | static inline void Opl_osc_output( struct Opl_Apu* this, int i, struct Blip_Buffer* buf ) |
45 | { | 45 | { |
46 | #if defined(ROCKBOX) | 46 | #if defined(ROCKBOX) |
47 | (void) i; | 47 | (void) i; |
48 | #endif | 48 | #endif |
49 | assert( (unsigned) i < opl_osc_count ); | 49 | assert( (unsigned) i < opl_osc_count ); |
50 | this->output_ = buf; | 50 | this->output_ = buf; |
51 | } | 51 | } |
52 | 52 | ||
53 | static inline void Opl_set_output( struct Opl_Apu* this, struct Blip_Buffer* buf ) { Opl_osc_output( this, 0, buf ); } | 53 | static inline void Opl_set_output( struct Opl_Apu* this, struct Blip_Buffer* buf ) { Opl_osc_output( this, 0, buf ); } |
54 | void Opl_end_frame( struct Opl_Apu* this, blip_time_t ); | 54 | void Opl_end_frame( struct Opl_Apu* this, blip_time_t ); |
55 | 55 | ||
56 | static inline void Opl_write_addr( struct Opl_Apu* this, int data ) { this->addr = data; } | 56 | static inline void Opl_write_addr( struct Opl_Apu* this, int data ) { this->addr = data; } |
57 | void Opl_write_data( struct Opl_Apu* this, blip_time_t, int data ); | 57 | void Opl_write_data( struct Opl_Apu* this, blip_time_t, int data ); |
58 | 58 | ||
59 | int Opl_read( struct Opl_Apu* this, blip_time_t, int port ); | 59 | int Opl_read( struct Opl_Apu* this, blip_time_t, int port ); |
60 | 60 | ||
61 | static inline bool Opl_supported( void ) { return true; } | 61 | static inline bool Opl_supported( void ) { return true; } |
62 | 62 | ||
63 | #endif | 63 | #endif |
diff --git a/apps/codecs/libgme/opltables.h b/apps/codecs/libgme/opltables.h index 6ec10eaa6e..50fc0a86c6 100644 --- a/apps/codecs/libgme/opltables.h +++ b/apps/codecs/libgme/opltables.h | |||
@@ -1,242 +1,242 @@ | |||
1 | #ifndef _OPLTABLES_H_ | 1 | #ifndef _OPLTABLES_H_ |
2 | #define _OPLTABLES_H_ | 2 | #define _OPLTABLES_H_ |
3 | 3 | ||
4 | /* Precalculated emu8950 tables for use in Rockbox, | 4 | /* Precalculated emu8950 tables for use in Rockbox, |
5 | Calculated for 44Khz sampling rate */ | 5 | Calculated for 44Khz sampling rate */ |
6 | 6 | ||
7 | static const short ar_adjust_coeff[] = { | 7 | static const short ar_adjust_coeff[] = { |
8 | 255, 227, 210, 198, 189, 181, 175, 170, 165, 161, 157, | 8 | 255, 227, 210, 198, 189, 181, 175, 170, 165, 161, 157, |
9 | 153, 150, 147, 144, 141, 139, 136, 134, 132, 130, 128, | 9 | 153, 150, 147, 144, 141, 139, 136, 134, 132, 130, 128, |
10 | 126, 125, 123, 121, 120, 118, 117, 115, 114, 113, 112, | 10 | 126, 125, 123, 121, 120, 118, 117, 115, 114, 113, 112, |
11 | 110, 109, 108, 107, 106, 105, 104, 103, 102, 101, 100, | 11 | 110, 109, 108, 107, 106, 105, 104, 103, 102, 101, 100, |
12 | 99, 98, 97, 96, 95, 94, 94, 93, 92, 91, 91, | 12 | 99, 98, 97, 96, 95, 94, 94, 93, 92, 91, 91, |
13 | 90, 89, 88, 88, 87, 86, 86, 85, 84, 84, 83, | 13 | 90, 89, 88, 88, 87, 86, 86, 85, 84, 84, 83, |
14 | 82, 82, 81, 81, 80, 79, 79, 78, 78, 77, 77, | 14 | 82, 82, 81, 81, 80, 79, 79, 78, 78, 77, 77, |
15 | 76, 76, 75, 75, 74, 74, 73, 73, 72, 72, 71, | 15 | 76, 76, 75, 75, 74, 74, 73, 73, 72, 72, 71, |
16 | 71, 70, 70, 69, 69, 69, 68, 68, 67, 67, 66, | 16 | 71, 70, 70, 69, 69, 69, 68, 68, 67, 67, 66, |
17 | 66, 66, 65, 65, 64, 64, 64, 63, 63, 62, 62, | 17 | 66, 66, 65, 65, 64, 64, 64, 63, 63, 62, 62, |
18 | 62, 61, 61, 61, 60, 60, 60, 59, 59, 59, 58, | 18 | 62, 61, 61, 61, 60, 60, 60, 59, 59, 59, 58, |
19 | 58, 58, 57, 57, 57, 56, 56, 56, 55, 55, 55, | 19 | 58, 58, 57, 57, 57, 56, 56, 56, 55, 55, 55, |
20 | 54, 54, 54, 53, 53, 53, 53, 52, 52, 52, 51, | 20 | 54, 54, 54, 53, 53, 53, 53, 52, 52, 52, 51, |
21 | 51, 51, 50, 50, 50, 50, 49, 49, 49, 49, 48, | 21 | 51, 51, 50, 50, 50, 50, 49, 49, 49, 49, 48, |
22 | 48, 48, 48, 47, 47, 47, 46, 46, 46, 46, 45, | 22 | 48, 48, 48, 47, 47, 47, 46, 46, 46, 46, 45, |
23 | 45, 45, 45, 44, 44, 44, 44, 44, 43, 43, 43, | 23 | 45, 45, 45, 44, 44, 44, 44, 44, 43, 43, 43, |
24 | 43, 42, 42, 42, 42, 41, 41, 41, 41, 41, 40, | 24 | 43, 42, 42, 42, 42, 41, 41, 41, 41, 41, 40, |
25 | 40, 40, 40, 39, 39, 39, 39, 39, 38, 38, 38, | 25 | 40, 40, 40, 39, 39, 39, 39, 39, 38, 38, 38, |
26 | 38, 38, 37, 37, 37, 37, 37, 36, 36, 36, 36, | 26 | 38, 38, 37, 37, 37, 37, 37, 36, 36, 36, 36, |
27 | 36, 35, 35, 35, 35, 35, 34, 34, 34, 34, 34, | 27 | 36, 35, 35, 35, 35, 35, 34, 34, 34, 34, 34, |
28 | 33, 33, 33, 33, 33, 33, 32, 32, 32, 32, 32, | 28 | 33, 33, 33, 33, 33, 33, 32, 32, 32, 32, 32, |
29 | 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, | 29 | 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, |
30 | 30, 29, 29, 29, 29, 29, 29, 28, 28, 28, 28, | 30 | 30, 29, 29, 29, 29, 29, 29, 28, 28, 28, 28, |
31 | 28, 28, 27, 27, 27, 27, 27, 27, 26, 26, 26, | 31 | 28, 28, 27, 27, 27, 27, 27, 27, 26, 26, 26, |
32 | 26, 26, 26, 26, 25, 25, 25, 25, 25, 25, 25, | 32 | 26, 26, 26, 26, 25, 25, 25, 25, 25, 25, 25, |
33 | 24, 24, 24, 24, 24, 24, 23, 23, 23, 23, 23, | 33 | 24, 24, 24, 24, 24, 24, 23, 23, 23, 23, 23, |
34 | 23, 23, 22, 22, 22, 22, 22, 22, 22, 21, 21, | 34 | 23, 23, 22, 22, 22, 22, 22, 22, 22, 21, 21, |
35 | 21, 21, 21, 21, 21, 21, 20, 20, 20, 20, 20, | 35 | 21, 21, 21, 21, 21, 21, 20, 20, 20, 20, 20, |
36 | 20, 20, 19, 19, 19, 19, 19, 19, 19, 19, 18, | 36 | 20, 20, 19, 19, 19, 19, 19, 19, 19, 19, 18, |
37 | 18, 18, 18, 18, 18, 18, 18, 17, 17, 17, 17, | 37 | 18, 18, 18, 18, 18, 18, 18, 17, 17, 17, 17, |
38 | 17, 17, 17, 17, 16, 16, 16, 16, 16, 16, 16, | 38 | 17, 17, 17, 17, 16, 16, 16, 16, 16, 16, 16, |
39 | 16, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, | 39 | 16, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, |
40 | 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, | 40 | 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, |
41 | 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, | 41 | 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, |
42 | 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11, | 42 | 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11, |
43 | 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, | 43 | 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, |
44 | 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, | 44 | 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, |
45 | 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, | 45 | 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, |
46 | 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, | 46 | 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, |
47 | 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, | 47 | 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, |
48 | 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, | 48 | 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, |
49 | 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, | 49 | 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, |
50 | 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, | 50 | 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, |
51 | 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, | 51 | 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, |
52 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, | 52 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, |
53 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 53 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
54 | 0, 0, 0, 0, 0 | 54 | 0, 0, 0, 0, 0 |
55 | }; | 55 | }; |
56 | 56 | ||
57 | static const short db2lin_coeff[] = { | 57 | static const short db2lin_coeff[] = { |
58 | 2047, 2003, 1960, 1918, 1877, 1837, 1798, 1759, 1722, 1685, 1649, | 58 | 2047, 2003, 1960, 1918, 1877, 1837, 1798, 1759, 1722, 1685, 1649, |
59 | 1614, 1579, 1546, 1513, 1480, 1449, 1418, 1387, 1358, 1329, 1300, | 59 | 1614, 1579, 1546, 1513, 1480, 1449, 1418, 1387, 1358, 1329, 1300, |
60 | 1273, 1245, 1219, 1193, 1167, 1142, 1118, 1094, 1071, 1048, 1025, | 60 | 1273, 1245, 1219, 1193, 1167, 1142, 1118, 1094, 1071, 1048, 1025, |
61 | 1004, 982, 961, 941, 920, 901, 882, 863, 844, 826, 809, | 61 | 1004, 982, 961, 941, 920, 901, 882, 863, 844, 826, 809, |
62 | 791, 774, 758, 742, 726, 710, 695, 680, 666, 651, 638, | 62 | 791, 774, 758, 742, 726, 710, 695, 680, 666, 651, 638, |
63 | 624, 611, 598, 585, 572, 560, 548, 536, 525, 514, 503, | 63 | 624, 611, 598, 585, 572, 560, 548, 536, 525, 514, 503, |
64 | 492, 481, 471, 461, 451, 442, 432, 423, 414, 405, 396, | 64 | 492, 481, 471, 461, 451, 442, 432, 423, 414, 405, 396, |
65 | 388, 380, 371, 364, 356, 348, 341, 333, 326, 319, 312, | 65 | 388, 380, 371, 364, 356, 348, 341, 333, 326, 319, 312, |
66 | 306, 299, 293, 287, 280, 274, 269, 263, 257, 252, 246, | 66 | 306, 299, 293, 287, 280, 274, 269, 263, 257, 252, 246, |
67 | 241, 236, 231, 226, 221, 216, 212, 207, 203, 198, 194, | 67 | 241, 236, 231, 226, 221, 216, 212, 207, 203, 198, 194, |
68 | 190, 186, 182, 178, 174, 170, 167, 163, 160, 156, 153, | 68 | 190, 186, 182, 178, 174, 170, 167, 163, 160, 156, 153, |
69 | 150, 147, 143, 140, 137, 134, 131, 129, 126, 123, 121, | 69 | 150, 147, 143, 140, 137, 134, 131, 129, 126, 123, 121, |
70 | 118, 115, 113, 111, 108, 106, 104, 101, 99, 97, 95, | 70 | 118, 115, 113, 111, 108, 106, 104, 101, 99, 97, 95, |
71 | 93, 91, 89, 87, 85, 83, 82, 80, 78, 76, 75, | 71 | 93, 91, 89, 87, 85, 83, 82, 80, 78, 76, 75, |
72 | 73, 72, 70, 69, 67, 66, 64, 63, 61, 60, 59, | 72 | 73, 72, 70, 69, 67, 66, 64, 63, 61, 60, 59, |
73 | 58, 56, 55, 54, 53, 52, 51, 49, 48, 47, 46, | 73 | 58, 56, 55, 54, 53, 52, 51, 49, 48, 47, 46, |
74 | 45, 44, 43, 42, 42, 41, 40, 39, 38, 37, 36, | 74 | 45, 44, 43, 42, 42, 41, 40, 39, 38, 37, 36, |
75 | 36, 35, 34, 33, 33, 32, 31, 31, 30, 29, 29, | 75 | 36, 35, 34, 33, 33, 32, 31, 31, 30, 29, 29, |
76 | 28, 27, 27, 26, 26, 25, 25, 24, 23, 23, 22, | 76 | 28, 27, 27, 26, 26, 25, 25, 24, 23, 23, 22, |
77 | 22, 21, 21, 21, 20, 20, 19, 19, 18, 18, 18, | 77 | 22, 21, 21, 21, 20, 20, 19, 19, 18, 18, 18, |
78 | 17, 17, 16, 16, 16, 15, 15, 15, 14, 14, 14, | 78 | 17, 17, 16, 16, 16, 15, 15, 15, 14, 14, 14, |
79 | 13, 13, 13, 13, 12, 12, 12, 12, 11, 11, 11, | 79 | 13, 13, 13, 13, 12, 12, 12, 12, 11, 11, 11, |
80 | 11, 10, 10, 10, 10, 9, 9, 9, 9, 9, 8, | 80 | 11, 10, 10, 10, 10, 9, 9, 9, 9, 9, 8, |
81 | 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, | 81 | 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, |
82 | 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, | 82 | 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, |
83 | 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, | 83 | 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, |
84 | 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, | 84 | 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, |
85 | 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, | 85 | 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, |
86 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | 86 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
87 | 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, | 87 | 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, |
88 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | 88 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
89 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | 89 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
90 | 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 90 | 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
91 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 91 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
92 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 92 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
93 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 93 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
94 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 94 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
95 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 95 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
96 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 96 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
97 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 97 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
98 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 98 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
99 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 99 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
100 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 100 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
101 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 101 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
102 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 102 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
103 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 103 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
104 | 0, 0, 0, 0, 0, 0 | 104 | 0, 0, 0, 0, 0, 0 |
105 | }; | 105 | }; |
106 | 106 | ||
107 | static const short sin_coeff[] = { | 107 | static const short sin_coeff[] = { |
108 | 511, 235, 203, 185, 171, 161, 152, 145, 139, 134, 129, | 108 | 511, 235, 203, 185, 171, 161, 152, 145, 139, 134, 129, |
109 | 124, 120, 117, 113, 110, 107, 104, 102, 99, 97, 95, | 109 | 124, 120, 117, 113, 110, 107, 104, 102, 99, 97, 95, |
110 | 92, 90, 88, 87, 85, 83, 81, 80, 78, 77, 75, | 110 | 92, 90, 88, 87, 85, 83, 81, 80, 78, 77, 75, |
111 | 74, 72, 71, 70, 69, 67, 66, 65, 64, 63, 62, | 111 | 74, 72, 71, 70, 69, 67, 66, 65, 64, 63, 62, |
112 | 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 52, | 112 | 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 52, |
113 | 51, 50, 49, 48, 48, 47, 46, 45, 45, 44, 43, | 113 | 51, 50, 49, 48, 48, 47, 46, 45, 45, 44, 43, |
114 | 43, 42, 41, 41, 40, 39, 39, 38, 38, 37, 37, | 114 | 43, 42, 41, 41, 40, 39, 39, 38, 38, 37, 37, |
115 | 36, 35, 35, 34, 34, 33, 33, 32, 32, 31, 31, | 115 | 36, 35, 35, 34, 34, 33, 33, 32, 32, 31, 31, |
116 | 30, 30, 29, 29, 28, 28, 28, 27, 27, 26, 26, | 116 | 30, 30, 29, 29, 28, 28, 28, 27, 27, 26, 26, |
117 | 25, 25, 25, 24, 24, 23, 23, 23, 22, 22, 22, | 117 | 25, 25, 25, 24, 24, 23, 23, 23, 22, 22, 22, |
118 | 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, | 118 | 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, |
119 | 18, 17, 17, 17, 16, 16, 16, 16, 15, 15, 15, | 119 | 18, 17, 17, 17, 16, 16, 16, 16, 15, 15, 15, |
120 | 14, 14, 14, 14, 13, 13, 13, 13, 12, 12, 12, | 120 | 14, 14, 14, 14, 13, 13, 13, 13, 12, 12, 12, |
121 | 12, 11, 11, 11, 11, 11, 10, 10, 10, 10, 9, | 121 | 12, 11, 11, 11, 11, 11, 10, 10, 10, 10, 9, |
122 | 9, 9, 9, 9, 8, 8, 8, 8, 8, 7, 7, | 122 | 9, 9, 9, 9, 8, 8, 8, 8, 8, 7, 7, |
123 | 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 5, | 123 | 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 5, |
124 | 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, | 124 | 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, |
125 | 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, | 125 | 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, |
126 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | 126 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
127 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | 127 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
128 | 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, | 128 | 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, |
129 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 129 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
130 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 130 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
131 | 0, 0, 0, | 131 | 0, 0, 0, |
132 | }; | 132 | }; |
133 | 133 | ||
134 | static const short pm0_coeff[] = { | 134 | static const short pm0_coeff[] = { |
135 | 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, | 135 | 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, |
136 | 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, | 136 | 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, |
137 | 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, | 137 | 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, |
138 | 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, | 138 | 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, |
139 | 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, | 139 | 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, |
140 | 256, 256, 257, 257, 257, 257, 257, 257, 257, 257, 257, | 140 | 256, 256, 257, 257, 257, 257, 257, 257, 257, 257, 257, |
141 | 257, 257, 257, 257, 257, 257, 256, 256, 256, 256, 256, | 141 | 257, 257, 257, 257, 257, 257, 256, 256, 256, 256, 256, |
142 | 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, | 142 | 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, |
143 | 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, | 143 | 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, |
144 | 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, | 144 | 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, |
145 | 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, | 145 | 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, |
146 | 256, 256, 256, 256, 256, 256, 256, 256, 255, 255, 255, | 146 | 256, 256, 256, 256, 256, 256, 256, 256, 255, 255, 255, |
147 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | 147 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, |
148 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | 148 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, |
149 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | 149 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, |
150 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | 150 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, |
151 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, | 151 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, |
152 | 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, | 152 | 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, |
153 | 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | 153 | 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, |
154 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | 154 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, |
155 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | 155 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, |
156 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | 156 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, |
157 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | 157 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, |
158 | 255, 255, 255, | 158 | 255, 255, 255, |
159 | }; | 159 | }; |
160 | 160 | ||
161 | static const short pm1_coeff[] = { | 161 | static const short pm1_coeff[] = { |
162 | 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, | 162 | 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, |
163 | 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 257, | 163 | 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 257, |
164 | 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, | 164 | 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, |
165 | 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, | 165 | 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, |
166 | 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, | 166 | 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, |
167 | 257, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, | 167 | 257, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, |
168 | 258, 258, 258, 258, 258, 258, 258, 257, 257, 257, 257, | 168 | 258, 258, 258, 258, 258, 258, 258, 257, 257, 257, 257, |
169 | 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, | 169 | 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, |
170 | 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, | 170 | 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, |
171 | 257, 257, 257, 257, 257, 257, 257, 257, 257, 256, 256, | 171 | 257, 257, 257, 257, 257, 257, 257, 257, 257, 256, 256, |
172 | 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, | 172 | 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, |
173 | 256, 256, 256, 256, 256, 256, 256, 256, 255, 255, 255, | 173 | 256, 256, 256, 256, 256, 256, 256, 256, 255, 255, 255, |
174 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | 174 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, |
175 | 255, 255, 255, 255, 255, 255, 254, 254, 254, 254, 254, | 175 | 255, 255, 255, 255, 255, 255, 254, 254, 254, 254, 254, |
176 | 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, | 176 | 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, |
177 | 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, | 177 | 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, |
178 | 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 253, | 178 | 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 253, |
179 | 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, | 179 | 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, |
180 | 253, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, | 180 | 253, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, |
181 | 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, | 181 | 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, |
182 | 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, | 182 | 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, |
183 | 254, 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, | 183 | 254, 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, |
184 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | 184 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, |
185 | 255, 255, 255, | 185 | 255, 255, 255, |
186 | }; | 186 | }; |
187 | 187 | ||
188 | static const short am0_coeff[] = { | 188 | static const short am0_coeff[] = { |
189 | 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, | 189 | 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, |
190 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, | 190 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, |
191 | 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, | 191 | 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, |
192 | 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, | 192 | 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, |
193 | 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, | 193 | 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, |
194 | 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, | 194 | 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, |
195 | 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, | 195 | 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, |
196 | 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, | 196 | 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, |
197 | 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, | 197 | 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, |
198 | 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, | 198 | 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, |
199 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, | 199 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, |
200 | 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, | 200 | 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
201 | 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, | 201 | 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, |
202 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | 202 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
203 | 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 203 | 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
204 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 204 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
205 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 205 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
206 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 206 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
207 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 207 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
208 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 208 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
209 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, | 209 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, |
210 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | 210 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
211 | 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, | 211 | 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, |
212 | 2, 2, 2, | 212 | 2, 2, 2, |
213 | }; | 213 | }; |
214 | 214 | ||
215 | static const short am1_coeff[] = { | 215 | static const short am1_coeff[] = { |
216 | 12, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, | 216 | 12, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, |
217 | 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 19, | 217 | 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 19, |
218 | 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, | 218 | 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, |
219 | 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, | 219 | 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, |
220 | 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, | 220 | 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, |
221 | 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | 221 | 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, |
222 | 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | 222 | 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, |
223 | 24, 24, 24, 24, 24, 24, 24, 24, 23, 23, 23, | 223 | 24, 24, 24, 24, 24, 24, 24, 24, 23, 23, 23, |
224 | 23, 23, 23, 22, 22, 22, 22, 22, 21, 21, 21, | 224 | 23, 23, 23, 22, 22, 22, 22, 22, 21, 21, 21, |
225 | 21, 20, 20, 20, 20, 19, 19, 19, 19, 18, 18, | 225 | 21, 20, 20, 20, 20, 19, 19, 19, 19, 18, 18, |
226 | 18, 17, 17, 17, 17, 16, 16, 16, 15, 15, 15, | 226 | 18, 17, 17, 17, 17, 16, 16, 16, 15, 15, 15, |
227 | 14, 14, 14, 14, 13, 13, 13, 12, 12, 12, 11, | 227 | 14, 14, 14, 14, 13, 13, 13, 12, 12, 12, 11, |
228 | 11, 11, 10, 10, 10, 9, 9, 9, 9, 8, 8, | 228 | 11, 11, 10, 10, 10, 9, 9, 9, 9, 8, 8, |
229 | 8, 7, 7, 7, 7, 6, 6, 6, 5, 5, 5, | 229 | 8, 7, 7, 7, 7, 6, 6, 6, 5, 5, 5, |
230 | 5, 4, 4, 4, 4, 3, 3, 3, 3, 3, 2, | 230 | 5, 4, 4, 4, 4, 3, 3, 3, 3, 3, 2, |
231 | 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, | 231 | 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, |
232 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 232 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
233 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 233 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
234 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 234 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
235 | 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, | 235 | 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, |
236 | 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, | 236 | 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, |
237 | 5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 8, | 237 | 5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 8, |
238 | 8, 8, 9, 9, 9, 9, 10, 10, 10, 11, 11, | 238 | 8, 8, 9, 9, 9, 9, 10, 10, 10, 11, 11, |
239 | 11, 12, 12, | 239 | 11, 12, 12, |
240 | }; | 240 | }; |
241 | 241 | ||
242 | #endif | 242 | #endif |
diff --git a/apps/codecs/libgme/sgc_cpu.c b/apps/codecs/libgme/sgc_cpu.c index 3bd2d15df9..d23c01499b 100644 --- a/apps/codecs/libgme/sgc_cpu.c +++ b/apps/codecs/libgme/sgc_cpu.c | |||
@@ -1,36 +1,36 @@ | |||
1 | // Game_Music_Emu 0.6-pre. http://www.slack.net/~ant/ | 1 | // Game_Music_Emu 0.6-pre. http://www.slack.net/~ant/ |
2 | 2 | ||
3 | #include "sgc_emu.h" | 3 | #include "sgc_emu.h" |
4 | 4 | ||
5 | #include "blargg_endian.h" | 5 | #include "blargg_endian.h" |
6 | //#include "z80_cpu_log.h" | 6 | //#include "z80_cpu_log.h" |
7 | 7 | ||
8 | /* Copyright (C) 2009 Shay Green. This module is free software; you | 8 | /* Copyright (C) 2009 Shay Green. This module is free software; you |
9 | can redistribute it and/or modify it under the terms of the GNU Lesser | 9 | can redistribute it and/or modify it under the terms of the GNU Lesser |
10 | General Public License as published by the Free Software Foundation; either | 10 | General Public License as published by the Free Software Foundation; either |
11 | version 2.1 of the License, or (at your option) any later version. This | 11 | version 2.1 of the License, or (at your option) any later version. This |
12 | module is distributed in the hope that it will be useful, but WITHOUT ANY | 12 | module is distributed in the hope that it will be useful, but WITHOUT ANY |
13 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | 13 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
14 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more | 14 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
15 | details. You should have received a copy of the GNU Lesser General Public | 15 | details. You should have received a copy of the GNU Lesser General Public |
16 | License along with this module; if not, write to the Free Software Foundation, | 16 | License along with this module; if not, write to the Free Software Foundation, |
17 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ | 17 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ |
18 | 18 | ||
19 | #include "blargg_source.h" | 19 | #include "blargg_source.h" |
20 | 20 | ||
21 | #define OUT_PORT( addr, data ) cpu_out( this, TIME(), addr, data ) | 21 | #define OUT_PORT( addr, data ) cpu_out( this, TIME(), addr, data ) |
22 | #define IN_PORT( addr ) 0 // cpu in | 22 | #define IN_PORT( addr ) 0 // cpu in |
23 | #define WRITE_MEM( addr, data ) cpu_write( this, addr, data ) | 23 | #define WRITE_MEM( addr, data ) cpu_write( this, addr, data ) |
24 | #define IDLE_ADDR this->idle_addr | 24 | #define IDLE_ADDR this->idle_addr |
25 | #define RST_BASE this->vectors_addr | 25 | #define RST_BASE this->vectors_addr |
26 | 26 | ||
27 | #define CPU_BEGIN \ | 27 | #define CPU_BEGIN \ |
28 | bool run_cpu( struct Sgc_Emu* this, cpu_time_t end_time )\ | 28 | bool run_cpu( struct Sgc_Emu* this, cpu_time_t end_time )\ |
29 | {\ | 29 | {\ |
30 | Sgc_Cpu* cpu = &this->cpu; \ | 30 | Sgc_Cpu* cpu = &this->cpu; \ |
31 | Z80_set_end_time( cpu, end_time ); | 31 | Z80_set_end_time( cpu, end_time ); |
32 | 32 | ||
33 | #include "z80_cpu_run.h" | 33 | #include "z80_cpu_run.h" |
34 | 34 | ||
35 | return warning; | 35 | return warning; |
36 | } | 36 | } |
diff --git a/apps/codecs/libgme/sgc_emu.c b/apps/codecs/libgme/sgc_emu.c index e7253a8d5b..267f2c9271 100644 --- a/apps/codecs/libgme/sgc_emu.c +++ b/apps/codecs/libgme/sgc_emu.c | |||
@@ -1,480 +1,480 @@ | |||
1 | // Game_Music_Emu 0.6-pre. http://www.slack.net/~ant/ | 1 | // Game_Music_Emu 0.6-pre. http://www.slack.net/~ant/ |
2 | 2 | ||
3 | #include "sgc_emu.h" | 3 | #include "sgc_emu.h" |
4 | 4 | ||
5 | /* Copyright (C) 2009 Shay Green. This module is free software; you | 5 | /* Copyright (C) 2009 Shay Green. This module is free software; you |
6 | can redistribute it and/or modify it under the terms of the GNU Lesser | 6 | can redistribute it and/or modify it under the terms of the GNU Lesser |
7 | General Public License as published by the Free Software Foundation; either | 7 | General Public License as published by the Free Software Foundation; either |
8 | version 2.1 of the License, or (at your option) any later version. This | 8 | version 2.1 of the License, or (at your option) any later version. This |
9 | module is distributed in the hope that it will be useful, but WITHOUT ANY | 9 | module is distributed in the hope that it will be useful, but WITHOUT ANY |
10 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | 10 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
11 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more | 11 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
12 | details. You should have received a copy of the GNU Lesser General Public | 12 | details. You should have received a copy of the GNU Lesser General Public |
13 | License aint with this module; if not, write to the Free Software Foundation, | 13 | License aint with this module; if not, write to the Free Software Foundation, |
14 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ | 14 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ |
15 | 15 | ||
16 | #include "blargg_source.h" | 16 | #include "blargg_source.h" |
17 | 17 | ||
18 | int const osc_count = sms_osc_count + fm_apu_osc_count; | 18 | int const osc_count = sms_osc_count + fm_apu_osc_count; |
19 | 19 | ||
20 | const char gme_wrong_file_type [] = "Wrong file type for this emulator"; | 20 | const char gme_wrong_file_type [] = "Wrong file type for this emulator"; |
21 | 21 | ||
22 | static void clear_track_vars( struct Sgc_Emu* this ) | 22 | static void clear_track_vars( struct Sgc_Emu* this ) |
23 | { | 23 | { |
24 | this->current_track = -1; | 24 | this->current_track = -1; |
25 | track_stop( &this->track_filter ); | 25 | track_stop( &this->track_filter ); |
26 | } | 26 | } |
27 | 27 | ||
28 | void Sgc_init( struct Sgc_Emu* this ) | 28 | void Sgc_init( struct Sgc_Emu* this ) |
29 | { | 29 | { |
30 | assert( offsetof (struct header_t,copyright [32]) == header_size ); | 30 | assert( offsetof (struct header_t,copyright [32]) == header_size ); |
31 | 31 | ||
32 | this->sample_rate = 0; | 32 | this->sample_rate = 0; |
33 | this->mute_mask_ = 0; | 33 | this->mute_mask_ = 0; |
34 | this->tempo = (int)FP_ONE_TEMPO; | 34 | this->tempo = (int)FP_ONE_TEMPO; |
35 | this->gain = (int)FP_ONE_GAIN; | 35 | this->gain = (int)FP_ONE_GAIN; |
36 | 36 | ||
37 | // defaults | 37 | // defaults |
38 | this->tfilter = *track_get_setup( &this->track_filter ); | 38 | this->tfilter = *track_get_setup( &this->track_filter ); |
39 | this->tfilter.max_initial = 2; | 39 | this->tfilter.max_initial = 2; |
40 | this->tfilter.lookahead = 6; | 40 | this->tfilter.lookahead = 6; |
41 | this->track_filter.silence_ignored_ = false; | 41 | this->track_filter.silence_ignored_ = false; |
42 | 42 | ||
43 | Sms_apu_init( &this->apu ); | 43 | Sms_apu_init( &this->apu ); |
44 | Fm_apu_create( &this->fm_apu ); | 44 | Fm_apu_create( &this->fm_apu ); |
45 | 45 | ||
46 | Rom_init( &this->rom, 0x4000 ); | 46 | Rom_init( &this->rom, 0x4000 ); |
47 | Z80_init( &this->cpu ); | 47 | Z80_init( &this->cpu ); |
48 | 48 | ||
49 | Sound_set_gain( this, (int)(FP_ONE_GAIN*1.2) ); | 49 | Sound_set_gain( this, (int)(FP_ONE_GAIN*1.2) ); |
50 | 50 | ||
51 | // Unload | 51 | // Unload |
52 | this->voice_count = 0; | 52 | this->voice_count = 0; |
53 | this->voice_types = 0; | 53 | this->voice_types = 0; |
54 | clear_track_vars( this ); | 54 | clear_track_vars( this ); |
55 | } | 55 | } |
56 | 56 | ||
57 | // Setup | 57 | // Setup |
58 | 58 | ||
59 | blargg_err_t Sgc_load_mem( struct Sgc_Emu* this, const void* data, long size ) | 59 | blargg_err_t Sgc_load_mem( struct Sgc_Emu* this, const void* data, long size ) |
60 | { | 60 | { |
61 | RETURN_ERR( Rom_load( &this->rom, data, size, header_size, &this->header, 0 ) ); | 61 | RETURN_ERR( Rom_load( &this->rom, data, size, header_size, &this->header, 0 ) ); |
62 | 62 | ||
63 | if ( !valid_tag( &this->header ) ) | 63 | if ( !valid_tag( &this->header ) ) |
64 | return gme_wrong_file_type; | 64 | return gme_wrong_file_type; |
65 | 65 | ||
66 | /* if ( header.vers != 1 ) | 66 | /* if ( header.vers != 1 ) |
67 | warning( "Unknown file version" ); */ | 67 | warning( "Unknown file version" ); */ |
68 | 68 | ||
69 | /* if ( header.system > 2 ) | 69 | /* if ( header.system > 2 ) |
70 | warning( "Unknown system" ); */ | 70 | warning( "Unknown system" ); */ |
71 | 71 | ||
72 | addr_t load_addr = get_le16( this->header.load_addr ); | 72 | addr_t load_addr = get_le16( this->header.load_addr ); |
73 | /* if ( load_addr < 0x400 ) | 73 | /* if ( load_addr < 0x400 ) |
74 | set_warning( "Invalid load address" ); */ | 74 | set_warning( "Invalid load address" ); */ |
75 | 75 | ||
76 | Rom_set_addr( &this->rom, load_addr ); | 76 | Rom_set_addr( &this->rom, load_addr ); |
77 | this->play_period = clock_rate( this ) / 60; | 77 | this->play_period = clock_rate( this ) / 60; |
78 | 78 | ||
79 | if ( sega_mapping( this ) && Fm_apu_supported() ) | 79 | if ( sega_mapping( this ) && Fm_apu_supported() ) |
80 | RETURN_ERR( Fm_apu_init( &this->fm_apu, clock_rate( this ), clock_rate( this ) / 72 ) ); | 80 | RETURN_ERR( Fm_apu_init( &this->fm_apu, clock_rate( this ), clock_rate( this ) / 72 ) ); |
81 | 81 | ||
82 | this->m3u.size = 0; | 82 | this->m3u.size = 0; |
83 | this->track_count = this->header.song_count; | 83 | this->track_count = this->header.song_count; |
84 | this->voice_count = sega_mapping( this ) ? osc_count : sms_osc_count; | 84 | this->voice_count = sega_mapping( this ) ? osc_count : sms_osc_count; |
85 | static int const types [sms_osc_count + fm_apu_osc_count] = { | 85 | static int const types [sms_osc_count + fm_apu_osc_count] = { |
86 | wave_type+1, wave_type+2, wave_type+3, mixed_type+1, mixed_type+2 | 86 | wave_type+1, wave_type+2, wave_type+3, mixed_type+1, mixed_type+2 |
87 | }; | 87 | }; |
88 | this->voice_types = types; | 88 | this->voice_types = types; |
89 | 89 | ||
90 | Sms_apu_volume( &this->apu, this->gain ); | 90 | Sms_apu_volume( &this->apu, this->gain ); |
91 | Fm_apu_volume( &this->fm_apu, this->gain ); | 91 | Fm_apu_volume( &this->fm_apu, this->gain ); |
92 | 92 | ||
93 | // Setup buffer | 93 | // Setup buffer |
94 | this->clock_rate_ = clock_rate( this ); | 94 | this->clock_rate_ = clock_rate( this ); |
95 | Buffer_clock_rate( &this->stereo_buf, clock_rate( this ) ); | 95 | Buffer_clock_rate( &this->stereo_buf, clock_rate( this ) ); |
96 | RETURN_ERR( Buffer_set_channel_count( &this->stereo_buf, this->voice_count, this->voice_types ) ); | 96 | RETURN_ERR( Buffer_set_channel_count( &this->stereo_buf, this->voice_count, this->voice_types ) ); |
97 | this->buf_changed_count = Buffer_channels_changed_count( &this->stereo_buf ); | 97 | this->buf_changed_count = Buffer_channels_changed_count( &this->stereo_buf ); |
98 | 98 | ||
99 | Sound_set_tempo( this, this->tempo ); | 99 | Sound_set_tempo( this, this->tempo ); |
100 | Sound_mute_voices( this, this->mute_mask_ ); | 100 | Sound_mute_voices( this, this->mute_mask_ ); |
101 | return 0; | 101 | return 0; |
102 | } | 102 | } |
103 | 103 | ||
104 | static void Sound_set_voice( struct Sgc_Emu* this, int i, struct Blip_Buffer* c, struct Blip_Buffer* l, struct Blip_Buffer* r ) | 104 | static void Sound_set_voice( struct Sgc_Emu* this, int i, struct Blip_Buffer* c, struct Blip_Buffer* l, struct Blip_Buffer* r ) |
105 | { | 105 | { |
106 | if ( i < sms_osc_count ) | 106 | if ( i < sms_osc_count ) |
107 | Sms_apu_set_output( &this->apu, i, c, l, r ); | 107 | Sms_apu_set_output( &this->apu, i, c, l, r ); |
108 | else | 108 | else |
109 | Fm_apu_set_output( &this->fm_apu, c ); | 109 | Fm_apu_set_output( &this->fm_apu, c ); |
110 | } | 110 | } |
111 | 111 | ||
112 | static blargg_err_t run_clocks( struct Sgc_Emu* this, blip_time_t* duration, int msec ) | 112 | static blargg_err_t run_clocks( struct Sgc_Emu* this, blip_time_t* duration, int msec ) |
113 | { | 113 | { |
114 | #if defined(ROCKBOX) | 114 | #if defined(ROCKBOX) |
115 | (void) msec; | 115 | (void) msec; |
116 | #endif | 116 | #endif |
117 | 117 | ||
118 | cpu_time_t t = *duration; | 118 | cpu_time_t t = *duration; |
119 | while ( Z80_time( &this->cpu ) < t ) | 119 | while ( Z80_time( &this->cpu ) < t ) |
120 | { | 120 | { |
121 | cpu_time_t next = min( t, this->next_play ); | 121 | cpu_time_t next = min( t, this->next_play ); |
122 | if ( run_cpu( this, next ) ) | 122 | if ( run_cpu( this, next ) ) |
123 | { | 123 | { |
124 | /* warning( "Unsupported CPU instruction" ); */ | 124 | /* warning( "Unsupported CPU instruction" ); */ |
125 | Z80_set_time( &this->cpu, next ); | 125 | Z80_set_time( &this->cpu, next ); |
126 | } | 126 | } |
127 | 127 | ||
128 | if ( this->cpu.r.pc == this->idle_addr ) | 128 | if ( this->cpu.r.pc == this->idle_addr ) |
129 | Z80_set_time( &this->cpu, next ); | 129 | Z80_set_time( &this->cpu, next ); |
130 | 130 | ||
131 | if ( Z80_time( &this->cpu ) >= this->next_play ) | 131 | if ( Z80_time( &this->cpu ) >= this->next_play ) |
132 | { | 132 | { |
133 | this->next_play += this->play_period; | 133 | this->next_play += this->play_period; |
134 | if ( this->cpu.r.pc == this->idle_addr ) | 134 | if ( this->cpu.r.pc == this->idle_addr ) |
135 | jsr( this, this->header.play_addr ); | 135 | jsr( this, this->header.play_addr ); |
136 | } | 136 | } |
137 | } | 137 | } |
138 | 138 | ||
139 | this->next_play -= t; | 139 | this->next_play -= t; |
140 | check( this->next_play >= 0 ); | 140 | check( this->next_play >= 0 ); |
141 | Z80_adjust_time( &this->cpu, -t ); | 141 | Z80_adjust_time( &this->cpu, -t ); |
142 | 142 | ||
143 | Sms_apu_end_frame( &this->apu, t ); | 143 | Sms_apu_end_frame( &this->apu, t ); |
144 | if ( sega_mapping( this ) && this->fm_accessed ) | 144 | if ( sega_mapping( this ) && this->fm_accessed ) |
145 | { | 145 | { |
146 | if ( Fm_apu_supported() ) | 146 | if ( Fm_apu_supported() ) |
147 | Fm_apu_end_frame( &this->fm_apu, t ); | 147 | Fm_apu_end_frame( &this->fm_apu, t ); |
148 | /* else | 148 | /* else |
149 | warning( "FM sound not supported" ); */ | 149 | warning( "FM sound not supported" ); */ |
150 | } | 150 | } |
151 | 151 | ||
152 | return 0; | 152 | return 0; |
153 | } | 153 | } |
154 | 154 | ||
155 | // Emulation | 155 | // Emulation |
156 | 156 | ||
157 | void cpu_out( struct Sgc_Emu* this, cpu_time_t time, addr_t addr, int data ) | 157 | void cpu_out( struct Sgc_Emu* this, cpu_time_t time, addr_t addr, int data ) |
158 | { | 158 | { |
159 | int port = addr & 0xFF; | 159 | int port = addr & 0xFF; |
160 | 160 | ||
161 | if ( sega_mapping( this ) ) | 161 | if ( sega_mapping( this ) ) |
162 | { | 162 | { |
163 | switch ( port ) | 163 | switch ( port ) |
164 | { | 164 | { |
165 | case 0x06: | 165 | case 0x06: |
166 | Sms_apu_write_ggstereo( &this->apu, time, data ); | 166 | Sms_apu_write_ggstereo( &this->apu, time, data ); |
167 | return; | 167 | return; |
168 | 168 | ||
169 | case 0x7E: | 169 | case 0x7E: |
170 | case 0x7F: | 170 | case 0x7F: |
171 | Sms_apu_write_data( &this->apu, time, data ); /* dprintf( "$7E<-%02X\n", data ); */ | 171 | Sms_apu_write_data( &this->apu, time, data ); /* dprintf( "$7E<-%02X\n", data ); */ |
172 | return; | 172 | return; |
173 | 173 | ||
174 | case 0xF0: | 174 | case 0xF0: |
175 | this->fm_accessed = true; | 175 | this->fm_accessed = true; |
176 | if ( Fm_apu_supported() ) | 176 | if ( Fm_apu_supported() ) |
177 | Fm_apu_write_addr( &this->fm_apu, data );//, dprintf( "$F0<-%02X\n", data ); | 177 | Fm_apu_write_addr( &this->fm_apu, data );//, dprintf( "$F0<-%02X\n", data ); |
178 | return; | 178 | return; |
179 | 179 | ||
180 | case 0xF1: | 180 | case 0xF1: |
181 | this->fm_accessed = true; | 181 | this->fm_accessed = true; |
182 | if ( Fm_apu_supported() ) | 182 | if ( Fm_apu_supported() ) |
183 | Fm_apu_write_data( &this->fm_apu, time, data );//, dprintf( "$F1<-%02X\n", data ); | 183 | Fm_apu_write_data( &this->fm_apu, time, data );//, dprintf( "$F1<-%02X\n", data ); |
184 | return; | 184 | return; |
185 | } | 185 | } |
186 | } | 186 | } |
187 | else if ( port >= 0xE0 ) | 187 | else if ( port >= 0xE0 ) |
188 | { | 188 | { |
189 | Sms_apu_write_data( &this->apu, time, data ); | 189 | Sms_apu_write_data( &this->apu, time, data ); |
190 | return; | 190 | return; |
191 | } | 191 | } |
192 | } | 192 | } |
193 | 193 | ||
194 | void jsr( struct Sgc_Emu* this, byte addr [2] ) | 194 | void jsr( struct Sgc_Emu* this, byte addr [2] ) |
195 | { | 195 | { |
196 | *Z80_write( &this->cpu, --this->cpu.r.sp ) = this->idle_addr >> 8; | 196 | *Z80_write( &this->cpu, --this->cpu.r.sp ) = this->idle_addr >> 8; |
197 | *Z80_write( &this->cpu, --this->cpu.r.sp ) = this->idle_addr & 0xFF; | 197 | *Z80_write( &this->cpu, --this->cpu.r.sp ) = this->idle_addr & 0xFF; |
198 | this->cpu.r.pc = get_le16( addr ); | 198 | this->cpu.r.pc = get_le16( addr ); |
199 | } | 199 | } |
200 | 200 | ||
201 | static void set_bank( struct Sgc_Emu* this, int bank, void const* data ) | 201 | static void set_bank( struct Sgc_Emu* this, int bank, void const* data ) |
202 | { | 202 | { |
203 | //dprintf( "map bank %d to %p\n", bank, (byte*) data - rom.at_addr( 0 ) ); | 203 | //dprintf( "map bank %d to %p\n", bank, (byte*) data - rom.at_addr( 0 ) ); |
204 | Z80_map_mem( &this->cpu, bank * this->rom.bank_size, this->rom.bank_size, this->unmapped_write, data ); | 204 | Z80_map_mem( &this->cpu, bank * this->rom.bank_size, this->rom.bank_size, this->unmapped_write, data ); |
205 | } | 205 | } |
206 | 206 | ||
207 | void cpu_write( struct Sgc_Emu* this, addr_t addr, int data ) | 207 | void cpu_write( struct Sgc_Emu* this, addr_t addr, int data ) |
208 | { | 208 | { |
209 | if ( (addr ^ 0xFFFC) > 3 || !sega_mapping( this ) ) | 209 | if ( (addr ^ 0xFFFC) > 3 || !sega_mapping( this ) ) |
210 | { | 210 | { |
211 | *Z80_write( &this->cpu, addr ) = data; | 211 | *Z80_write( &this->cpu, addr ) = data; |
212 | return; | 212 | return; |
213 | } | 213 | } |
214 | 214 | ||
215 | switch ( addr ) | 215 | switch ( addr ) |
216 | { | 216 | { |
217 | case 0xFFFC: | 217 | case 0xFFFC: |
218 | Z80_map_mem_rw( &this->cpu, 2 * this->rom.bank_size, this->rom.bank_size, this->ram2 ); | 218 | Z80_map_mem_rw( &this->cpu, 2 * this->rom.bank_size, this->rom.bank_size, this->ram2 ); |
219 | if ( data & 0x08 ) | 219 | if ( data & 0x08 ) |
220 | break; | 220 | break; |
221 | 221 | ||
222 | this->bank2 = this->ram2; | 222 | this->bank2 = this->ram2; |
223 | // FALL THROUGH | 223 | // FALL THROUGH |
224 | 224 | ||
225 | case 0xFFFF: { | 225 | case 0xFFFF: { |
226 | bool rom_mapped = (Z80_read( &this->cpu, 2 * this->rom.bank_size ) == this->bank2); | 226 | bool rom_mapped = (Z80_read( &this->cpu, 2 * this->rom.bank_size ) == this->bank2); |
227 | this->bank2 = Rom_at_addr( &this->rom, data * this->rom.bank_size ); | 227 | this->bank2 = Rom_at_addr( &this->rom, data * this->rom.bank_size ); |
228 | if ( rom_mapped ) | 228 | if ( rom_mapped ) |
229 | set_bank( this, 2, this->bank2 ); | 229 | set_bank( this, 2, this->bank2 ); |
230 | break; | 230 | break; |
231 | } | 231 | } |
232 | 232 | ||
233 | case 0xFFFD: | 233 | case 0xFFFD: |
234 | set_bank( this, 0, Rom_at_addr( &this->rom, data * this->rom.bank_size ) ); | 234 | set_bank( this, 0, Rom_at_addr( &this->rom, data * this->rom.bank_size ) ); |
235 | break; | 235 | break; |
236 | 236 | ||
237 | case 0xFFFE: | 237 | case 0xFFFE: |
238 | set_bank( this, 1, Rom_at_addr( &this->rom, data * this->rom.bank_size ) ); | 238 | set_bank( this, 1, Rom_at_addr( &this->rom, data * this->rom.bank_size ) ); |
239 | break; | 239 | break; |
240 | } | 240 | } |
241 | } | 241 | } |
242 | 242 | ||
243 | blargg_err_t Sgc_set_sample_rate( struct Sgc_Emu* this, int rate ) | 243 | blargg_err_t Sgc_set_sample_rate( struct Sgc_Emu* this, int rate ) |
244 | { | 244 | { |
245 | require( !this->sample_rate ); // sample rate can't be changed once set | 245 | require( !this->sample_rate ); // sample rate can't be changed once set |
246 | Buffer_init( &this->stereo_buf ); | 246 | Buffer_init( &this->stereo_buf ); |
247 | Buffer_set_sample_rate( &this->stereo_buf, rate, 1000 / 20 ); | 247 | Buffer_set_sample_rate( &this->stereo_buf, rate, 1000 / 20 ); |
248 | 248 | ||
249 | // Set buffer bass | 249 | // Set buffer bass |
250 | Buffer_bass_freq( &this->stereo_buf, 80 ); | 250 | Buffer_bass_freq( &this->stereo_buf, 80 ); |
251 | 251 | ||
252 | this->sample_rate = rate; | 252 | this->sample_rate = rate; |
253 | RETURN_ERR( track_init( &this->track_filter, this ) ); | 253 | RETURN_ERR( track_init( &this->track_filter, this ) ); |
254 | this->tfilter.max_silence = 6 * stereo * this->sample_rate; | 254 | this->tfilter.max_silence = 6 * stereo * this->sample_rate; |
255 | return 0; | 255 | return 0; |
256 | } | 256 | } |
257 | 257 | ||
258 | void Sound_mute_voice( struct Sgc_Emu* this, int index, bool mute ) | 258 | void Sound_mute_voice( struct Sgc_Emu* this, int index, bool mute ) |
259 | { | 259 | { |
260 | require( (unsigned) index < (unsigned) this->voice_count ); | 260 | require( (unsigned) index < (unsigned) this->voice_count ); |
261 | int bit = 1 << index; | 261 | int bit = 1 << index; |
262 | int mask = this->mute_mask_ | bit; | 262 | int mask = this->mute_mask_ | bit; |
263 | if ( !mute ) | 263 | if ( !mute ) |
264 | mask ^= bit; | 264 | mask ^= bit; |
265 | Sound_mute_voices( this, mask ); | 265 | Sound_mute_voices( this, mask ); |
266 | } | 266 | } |
267 | 267 | ||
268 | void Sound_mute_voices( struct Sgc_Emu* this, int mask ) | 268 | void Sound_mute_voices( struct Sgc_Emu* this, int mask ) |
269 | { | 269 | { |
270 | require( this->sample_rate ); // sample rate must be set first | 270 | require( this->sample_rate ); // sample rate must be set first |
271 | this->mute_mask_ = mask; | 271 | this->mute_mask_ = mask; |
272 | 272 | ||
273 | int i; | 273 | int i; |
274 | for ( i = this->voice_count; i--; ) | 274 | for ( i = this->voice_count; i--; ) |
275 | { | 275 | { |
276 | if ( mask & (1 << i) ) | 276 | if ( mask & (1 << i) ) |
277 | { | 277 | { |
278 | Sound_set_voice( this, i, 0, 0, 0 ); | 278 | Sound_set_voice( this, i, 0, 0, 0 ); |
279 | } | 279 | } |
280 | else | 280 | else |
281 | { | 281 | { |
282 | struct channel_t ch = Buffer_channel( &this->stereo_buf, i ); | 282 | struct channel_t ch = Buffer_channel( &this->stereo_buf, i ); |
283 | assert( (ch.center && ch.left && ch.right) || | 283 | assert( (ch.center && ch.left && ch.right) || |
284 | (!ch.center && !ch.left && !ch.right) ); // all or nothing | 284 | (!ch.center && !ch.left && !ch.right) ); // all or nothing |
285 | Sound_set_voice( this, i, ch.center, ch.left, ch.right ); | 285 | Sound_set_voice( this, i, ch.center, ch.left, ch.right ); |
286 | } | 286 | } |
287 | } | 287 | } |
288 | } | 288 | } |
289 | 289 | ||
290 | void Sound_set_tempo( struct Sgc_Emu* this, int t ) | 290 | void Sound_set_tempo( struct Sgc_Emu* this, int t ) |
291 | { | 291 | { |
292 | require( this->sample_rate ); // sample rate must be set first | 292 | require( this->sample_rate ); // sample rate must be set first |
293 | int const min = (int)(FP_ONE_TEMPO*0.02); | 293 | int const min = (int)(FP_ONE_TEMPO*0.02); |
294 | int const max = (int)(FP_ONE_TEMPO*4.00); | 294 | int const max = (int)(FP_ONE_TEMPO*4.00); |
295 | if ( t < min ) t = min; | 295 | if ( t < min ) t = min; |
296 | if ( t > max ) t = max; | 296 | if ( t > max ) t = max; |
297 | this->tempo = t; | 297 | this->tempo = t; |
298 | 298 | ||
299 | this->play_period = (int) ((clock_rate( this ) * FP_ONE_TEMPO) / (this->header.rate ? 50 : 60) / t); | 299 | this->play_period = (int) ((clock_rate( this ) * FP_ONE_TEMPO) / (this->header.rate ? 50 : 60) / t); |
300 | } | 300 | } |
301 | 301 | ||
302 | blargg_err_t Sgc_start_track( struct Sgc_Emu* this, int track ) | 302 | blargg_err_t Sgc_start_track( struct Sgc_Emu* this, int track ) |
303 | { | 303 | { |
304 | clear_track_vars( this ); | 304 | clear_track_vars( this ); |
305 | 305 | ||
306 | // Remap track if playlist available | 306 | // Remap track if playlist available |
307 | if ( this->m3u.size > 0 ) { | 307 | if ( this->m3u.size > 0 ) { |
308 | struct entry_t* e = &this->m3u.entries[track]; | 308 | struct entry_t* e = &this->m3u.entries[track]; |
309 | track = e->track; | 309 | track = e->track; |
310 | } | 310 | } |
311 | 311 | ||
312 | this->current_track = track; | 312 | this->current_track = track; |
313 | 313 | ||
314 | if ( sega_mapping( this ) ) | 314 | if ( sega_mapping( this ) ) |
315 | { | 315 | { |
316 | Sms_apu_reset( &this->apu, 0, 0 ); | 316 | Sms_apu_reset( &this->apu, 0, 0 ); |
317 | Fm_apu_reset( &this->fm_apu ); | 317 | Fm_apu_reset( &this->fm_apu ); |
318 | this->fm_accessed = false; | 318 | this->fm_accessed = false; |
319 | } | 319 | } |
320 | else | 320 | else |
321 | { | 321 | { |
322 | Sms_apu_reset( &this->apu, 0x0003, 15 ); | 322 | Sms_apu_reset( &this->apu, 0x0003, 15 ); |
323 | } | 323 | } |
324 | 324 | ||
325 | memset( this->ram , 0, sizeof this->ram ); | 325 | memset( this->ram , 0, sizeof this->ram ); |
326 | memset( this->ram2, 0, sizeof this->ram2 ); | 326 | memset( this->ram2, 0, sizeof this->ram2 ); |
327 | memset( this->vectors, 0xFF, sizeof this->vectors ); | 327 | memset( this->vectors, 0xFF, sizeof this->vectors ); |
328 | Z80_reset( &this->cpu, this->unmapped_write, this->rom.unmapped ); | 328 | Z80_reset( &this->cpu, this->unmapped_write, this->rom.unmapped ); |
329 | 329 | ||
330 | if ( sega_mapping( this ) ) | 330 | if ( sega_mapping( this ) ) |
331 | { | 331 | { |
332 | this->vectors_addr = 0x10000 - page_size; | 332 | this->vectors_addr = 0x10000 - page_size; |
333 | this->idle_addr = this->vectors_addr; | 333 | this->idle_addr = this->vectors_addr; |
334 | int i; | 334 | int i; |
335 | for ( i = 1; i < 8; ++i ) | 335 | for ( i = 1; i < 8; ++i ) |
336 | { | 336 | { |
337 | this->vectors [i*8 + 0] = 0xC3; // JP addr | 337 | this->vectors [i*8 + 0] = 0xC3; // JP addr |
338 | this->vectors [i*8 + 1] = this->header.rst_addrs [i - 1] & 0xff; | 338 | this->vectors [i*8 + 1] = this->header.rst_addrs [i - 1] & 0xff; |
339 | this->vectors [i*8 + 2] = this->header.rst_addrs [i - 1] >> 8; | 339 | this->vectors [i*8 + 2] = this->header.rst_addrs [i - 1] >> 8; |
340 | } | 340 | } |
341 | 341 | ||
342 | Z80_map_mem_rw( &this->cpu, 0xC000, 0x2000, this->ram ); | 342 | Z80_map_mem_rw( &this->cpu, 0xC000, 0x2000, this->ram ); |
343 | Z80_map_mem( &this->cpu, this->vectors_addr, page_size, this->unmapped_write, this->vectors ); | 343 | Z80_map_mem( &this->cpu, this->vectors_addr, page_size, this->unmapped_write, this->vectors ); |
344 | 344 | ||
345 | this->bank2 = NULL; | 345 | this->bank2 = NULL; |
346 | for ( i = 0; i < 4; ++i ) | 346 | for ( i = 0; i < 4; ++i ) |
347 | cpu_write( this, 0xFFFC + i, this->header.mapping [i] ); | 347 | cpu_write( this, 0xFFFC + i, this->header.mapping [i] ); |
348 | } | 348 | } |
349 | else | 349 | else |
350 | { | 350 | { |
351 | if ( !this->coleco_bios ) | 351 | if ( !this->coleco_bios ) |
352 | return "Coleco BIOS not set"; /* BLARGG_ERR( BLARGG_ERR_CALLER, "Coleco BIOS not set" ); */ | 352 | return "Coleco BIOS not set"; /* BLARGG_ERR( BLARGG_ERR_CALLER, "Coleco BIOS not set" ); */ |
353 | 353 | ||
354 | this->vectors_addr = 0; | 354 | this->vectors_addr = 0; |
355 | Z80_map_mem( &this->cpu, 0, 0x2000, this->unmapped_write, this->coleco_bios ); | 355 | Z80_map_mem( &this->cpu, 0, 0x2000, this->unmapped_write, this->coleco_bios ); |
356 | int i; | 356 | int i; |
357 | for ( i = 0; i < 8; ++i ) | 357 | for ( i = 0; i < 8; ++i ) |
358 | Z80_map_mem_rw( &this->cpu, 0x6000 + i*0x400, 0x400, this->ram ); | 358 | Z80_map_mem_rw( &this->cpu, 0x6000 + i*0x400, 0x400, this->ram ); |
359 | 359 | ||
360 | this->idle_addr = 0x2000; | 360 | this->idle_addr = 0x2000; |
361 | Z80_map_mem( &this->cpu, 0x2000, page_size, this->unmapped_write, this->vectors ); | 361 | Z80_map_mem( &this->cpu, 0x2000, page_size, this->unmapped_write, this->vectors ); |
362 | 362 | ||
363 | for ( i = 0; i < 0x8000 / this->rom.bank_size; ++i ) | 363 | for ( i = 0; i < 0x8000 / this->rom.bank_size; ++i ) |
364 | { | 364 | { |
365 | int addr = 0x8000 + i*this->rom.bank_size; | 365 | int addr = 0x8000 + i*this->rom.bank_size; |
366 | Z80_map_mem( &this->cpu, addr, this->rom.bank_size, this->unmapped_write, Rom_at_addr( &this->rom, addr ) ); | 366 | Z80_map_mem( &this->cpu, addr, this->rom.bank_size, this->unmapped_write, Rom_at_addr( &this->rom, addr ) ); |
367 | } | 367 | } |
368 | } | 368 | } |
369 | 369 | ||
370 | this->cpu.r.sp = get_le16( this->header.stack_ptr ); | 370 | this->cpu.r.sp = get_le16( this->header.stack_ptr ); |
371 | this->cpu.r.b.a = track; | 371 | this->cpu.r.b.a = track; |
372 | this->next_play = this->play_period; | 372 | this->next_play = this->play_period; |
373 | 373 | ||
374 | jsr( this, this->header.init_addr ); | 374 | jsr( this, this->header.init_addr ); |
375 | 375 | ||
376 | Buffer_clear( &this->stereo_buf ); | 376 | Buffer_clear( &this->stereo_buf ); |
377 | 377 | ||
378 | // convert filter times to samples | 378 | // convert filter times to samples |
379 | struct setup_t s = this->tfilter; | 379 | struct setup_t s = this->tfilter; |
380 | s.max_initial *= this->sample_rate * stereo; | 380 | s.max_initial *= this->sample_rate * stereo; |
381 | #ifdef GME_DISABLE_SILENCE_LOOKAHEAD | 381 | #ifdef GME_DISABLE_SILENCE_LOOKAHEAD |
382 | s.lookahead = 1; | 382 | s.lookahead = 1; |
383 | #endif | 383 | #endif |
384 | track_setup( &this->track_filter, &s ); | 384 | track_setup( &this->track_filter, &s ); |
385 | 385 | ||
386 | return track_start( &this->track_filter ); | 386 | return track_start( &this->track_filter ); |
387 | } | 387 | } |
388 | 388 | ||
389 | // Tell/Seek | 389 | // Tell/Seek |
390 | 390 | ||
391 | static int msec_to_samples( int msec, int sample_rate ) | 391 | static int msec_to_samples( int msec, int sample_rate ) |
392 | { | 392 | { |
393 | int sec = msec / 1000; | 393 | int sec = msec / 1000; |
394 | msec -= sec * 1000; | 394 | msec -= sec * 1000; |
395 | return (sec * sample_rate + msec * sample_rate / 1000) * stereo; | 395 | return (sec * sample_rate + msec * sample_rate / 1000) * stereo; |
396 | } | 396 | } |
397 | 397 | ||
398 | int Track_tell( struct Sgc_Emu* this ) | 398 | int Track_tell( struct Sgc_Emu* this ) |
399 | { | 399 | { |
400 | int rate = this->sample_rate * stereo; | 400 | int rate = this->sample_rate * stereo; |
401 | int sec = track_sample_count( &this->track_filter ) / rate; | 401 | int sec = track_sample_count( &this->track_filter ) / rate; |
402 | return sec * 1000 + (track_sample_count( &this->track_filter ) - sec * rate) * 1000 / rate; | 402 | return sec * 1000 + (track_sample_count( &this->track_filter ) - sec * rate) * 1000 / rate; |
403 | } | 403 | } |
404 | 404 | ||
405 | blargg_err_t Track_seek( struct Sgc_Emu* this, int msec ) | 405 | blargg_err_t Track_seek( struct Sgc_Emu* this, int msec ) |
406 | { | 406 | { |
407 | int time = msec_to_samples( msec, this->sample_rate ); | 407 | int time = msec_to_samples( msec, this->sample_rate ); |
408 | if ( time < track_sample_count( &this->track_filter ) ) | 408 | if ( time < track_sample_count( &this->track_filter ) ) |
409 | RETURN_ERR( Sgc_start_track( this, this->current_track ) ); | 409 | RETURN_ERR( Sgc_start_track( this, this->current_track ) ); |
410 | return Track_skip( this, time - track_sample_count( &this->track_filter ) ); | 410 | return Track_skip( this, time - track_sample_count( &this->track_filter ) ); |
411 | } | 411 | } |
412 | 412 | ||
413 | blargg_err_t Track_skip( struct Sgc_Emu* this, int count ) | 413 | blargg_err_t Track_skip( struct Sgc_Emu* this, int count ) |
414 | { | 414 | { |
415 | require( this->current_track >= 0 ); // start_track() must have been called already | 415 | require( this->current_track >= 0 ); // start_track() must have been called already |
416 | return track_skip( &this->track_filter, count ); | 416 | return track_skip( &this->track_filter, count ); |
417 | } | 417 | } |
418 | 418 | ||
419 | blargg_err_t skip_( void* emu, int count ) | 419 | blargg_err_t skip_( void* emu, int count ) |
420 | { | 420 | { |
421 | struct Sgc_Emu* this = (struct Sgc_Emu*) emu; | 421 | struct Sgc_Emu* this = (struct Sgc_Emu*) emu; |
422 | 422 | ||
423 | // for long skip, mute sound | 423 | // for long skip, mute sound |
424 | const int threshold = 32768; | 424 | const int threshold = 32768; |
425 | if ( count > threshold ) | 425 | if ( count > threshold ) |
426 | { | 426 | { |
427 | int saved_mute = this->mute_mask_; | 427 | int saved_mute = this->mute_mask_; |
428 | Sound_mute_voices( this, ~0 ); | 428 | Sound_mute_voices( this, ~0 ); |
429 | 429 | ||
430 | int n = count - threshold/2; | 430 | int n = count - threshold/2; |
431 | n &= ~(2048-1); // round to multiple of 2048 | 431 | n &= ~(2048-1); // round to multiple of 2048 |
432 | count -= n; | 432 | count -= n; |
433 | RETURN_ERR( skippy_( &this->track_filter, n ) ); | 433 | RETURN_ERR( skippy_( &this->track_filter, n ) ); |
434 | 434 | ||
435 | Sound_mute_voices( this, saved_mute ); | 435 | Sound_mute_voices( this, saved_mute ); |
436 | } | 436 | } |
437 | 437 | ||
438 | return skippy_( &this->track_filter, count ); | 438 | return skippy_( &this->track_filter, count ); |
439 | } | 439 | } |
440 | 440 | ||
441 | void Track_set_fade( struct Sgc_Emu* this, int start_msec, int length_msec ) | 441 | void Track_set_fade( struct Sgc_Emu* this, int start_msec, int length_msec ) |
442 | { | 442 | { |
443 | track_set_fade( &this->track_filter, msec_to_samples( start_msec, this->sample_rate ), | 443 | track_set_fade( &this->track_filter, msec_to_samples( start_msec, this->sample_rate ), |
444 | length_msec * this->sample_rate / (1000 / stereo) ); | 444 | length_msec * this->sample_rate / (1000 / stereo) ); |
445 | } | 445 | } |
446 | 446 | ||
447 | blargg_err_t Sgc_play( struct Sgc_Emu* this, int out_count, sample_t* out ) | 447 | blargg_err_t Sgc_play( struct Sgc_Emu* this, int out_count, sample_t* out ) |
448 | { | 448 | { |
449 | require( this->current_track >= 0 ); | 449 | require( this->current_track >= 0 ); |
450 | require( out_count % stereo == 0 ); | 450 | require( out_count % stereo == 0 ); |
451 | return track_play( &this->track_filter, out_count, out ); | 451 | return track_play( &this->track_filter, out_count, out ); |
452 | } | 452 | } |
453 | 453 | ||
454 | blargg_err_t play_( void* emu, int count, sample_t out [] ) | 454 | blargg_err_t play_( void* emu, int count, sample_t out [] ) |
455 | { | 455 | { |
456 | struct Sgc_Emu* this = (struct Sgc_Emu*) emu; | 456 | struct Sgc_Emu* this = (struct Sgc_Emu*) emu; |
457 | 457 | ||
458 | int remain = count; | 458 | int remain = count; |
459 | while ( remain ) | 459 | while ( remain ) |
460 | { | 460 | { |
461 | Buffer_disable_immediate_removal( &this->stereo_buf ); | 461 | Buffer_disable_immediate_removal( &this->stereo_buf ); |
462 | remain -= Buffer_read_samples( &this->stereo_buf, &out [count - remain], remain ); | 462 | remain -= Buffer_read_samples( &this->stereo_buf, &out [count - remain], remain ); |
463 | if ( remain ) | 463 | if ( remain ) |
464 | { | 464 | { |
465 | if ( this->buf_changed_count != Buffer_channels_changed_count( &this->stereo_buf ) ) | 465 | if ( this->buf_changed_count != Buffer_channels_changed_count( &this->stereo_buf ) ) |
466 | { | 466 | { |
467 | this->buf_changed_count = Buffer_channels_changed_count( &this->stereo_buf ); | 467 | this->buf_changed_count = Buffer_channels_changed_count( &this->stereo_buf ); |
468 | 468 | ||
469 | // Remute voices | 469 | // Remute voices |
470 | Sound_mute_voices( this, this->mute_mask_ ); | 470 | Sound_mute_voices( this, this->mute_mask_ ); |
471 | } | 471 | } |
472 | int msec = Buffer_length( &this->stereo_buf ); | 472 | int msec = Buffer_length( &this->stereo_buf ); |
473 | blip_time_t clocks_emulated = msec * this->clock_rate_ / 1000 - 100; | 473 | blip_time_t clocks_emulated = msec * this->clock_rate_ / 1000 - 100; |
474 | RETURN_ERR( run_clocks( this, &clocks_emulated, msec ) ); | 474 | RETURN_ERR( run_clocks( this, &clocks_emulated, msec ) ); |
475 | assert( clocks_emulated ); | 475 | assert( clocks_emulated ); |
476 | Buffer_end_frame( &this->stereo_buf, clocks_emulated ); | 476 | Buffer_end_frame( &this->stereo_buf, clocks_emulated ); |
477 | } | 477 | } |
478 | } | 478 | } |
479 | return 0; | 479 | return 0; |
480 | } | 480 | } |
diff --git a/apps/codecs/libgme/sgc_emu.h b/apps/codecs/libgme/sgc_emu.h index 6595c02daf..83cde1e6ae 100644 --- a/apps/codecs/libgme/sgc_emu.h +++ b/apps/codecs/libgme/sgc_emu.h | |||
@@ -1,195 +1,195 @@ | |||
1 | // Sega/Game Gear/Coleco SGC music file emulator | 1 | // Sega/Game Gear/Coleco SGC music file emulator |
2 | 2 | ||
3 | // Game_Music_Emu 0.6-pre | 3 | // Game_Music_Emu 0.6-pre |
4 | #ifndef SGC_EMU_H | 4 | #ifndef SGC_EMU_H |
5 | #define SGC_EMU_H | 5 | #define SGC_EMU_H |
6 | 6 | ||
7 | #include "blargg_common.h" | 7 | #include "blargg_common.h" |
8 | #include "multi_buffer.h" | 8 | #include "multi_buffer.h" |
9 | 9 | ||
10 | #include "rom_data.h" | 10 | #include "rom_data.h" |
11 | #include "z80_cpu.h" | 11 | #include "z80_cpu.h" |
12 | #include "sms_fm_apu.h" | 12 | #include "sms_fm_apu.h" |
13 | #include "sms_apu.h" | 13 | #include "sms_apu.h" |
14 | #include "m3u_playlist.h" | 14 | #include "m3u_playlist.h" |
15 | #include "track_filter.h" | 15 | #include "track_filter.h" |
16 | 16 | ||
17 | typedef struct Z80_Cpu Sgc_Cpu; | 17 | typedef struct Z80_Cpu Sgc_Cpu; |
18 | 18 | ||
19 | // SGC file header | 19 | // SGC file header |
20 | enum { header_size = 0xA0 }; | 20 | enum { header_size = 0xA0 }; |
21 | struct header_t | 21 | struct header_t |
22 | { | 22 | { |
23 | char tag [4]; // "SGC\x1A" | 23 | char tag [4]; // "SGC\x1A" |
24 | byte vers; // 0x01 | 24 | byte vers; // 0x01 |
25 | byte rate; // 0=NTSC 1=PAL | 25 | byte rate; // 0=NTSC 1=PAL |
26 | byte reserved1 [2]; | 26 | byte reserved1 [2]; |
27 | byte load_addr [2]; | 27 | byte load_addr [2]; |
28 | byte init_addr [2]; | 28 | byte init_addr [2]; |
29 | byte play_addr [2]; | 29 | byte play_addr [2]; |
30 | byte stack_ptr [2]; | 30 | byte stack_ptr [2]; |
31 | byte reserved2 [2]; | 31 | byte reserved2 [2]; |
32 | byte rst_addrs [7*2]; | 32 | byte rst_addrs [7*2]; |
33 | byte mapping [4]; // Used by Sega only | 33 | byte mapping [4]; // Used by Sega only |
34 | byte first_song; // Song to start playing first | 34 | byte first_song; // Song to start playing first |
35 | byte song_count; | 35 | byte song_count; |
36 | byte first_effect; | 36 | byte first_effect; |
37 | byte last_effect; | 37 | byte last_effect; |
38 | byte system; // 0=Master System 1=Game Gear 2=Colecovision | 38 | byte system; // 0=Master System 1=Game Gear 2=Colecovision |
39 | byte reserved3 [23]; | 39 | byte reserved3 [23]; |
40 | char game [32]; // strings can be 32 chars, NOT terminated | 40 | char game [32]; // strings can be 32 chars, NOT terminated |
41 | char author [32]; | 41 | char author [32]; |
42 | char copyright [32]; | 42 | char copyright [32]; |
43 | }; | 43 | }; |
44 | 44 | ||
45 | // True if header has valid file signature | 45 | // True if header has valid file signature |
46 | static inline bool valid_tag( struct header_t* h ) | 46 | static inline bool valid_tag( struct header_t* h ) |
47 | { | 47 | { |
48 | return 0 == memcmp( h->tag, "SGC\x1A", 4 ); | 48 | return 0 == memcmp( h->tag, "SGC\x1A", 4 ); |
49 | } | 49 | } |
50 | 50 | ||
51 | static inline int effect_count( struct header_t* h ) { return h->last_effect ? h->last_effect - h->first_effect + 1 : 0; } | 51 | static inline int effect_count( struct header_t* h ) { return h->last_effect ? h->last_effect - h->first_effect + 1 : 0; } |
52 | 52 | ||
53 | struct Sgc_Emu { | 53 | struct Sgc_Emu { |
54 | bool fm_accessed; | 54 | bool fm_accessed; |
55 | 55 | ||
56 | cpu_time_t play_period; | 56 | cpu_time_t play_period; |
57 | cpu_time_t next_play; | 57 | cpu_time_t next_play; |
58 | void const* bank2; // ROM selected for bank 2, in case RAM is currently hiding it | 58 | void const* bank2; // ROM selected for bank 2, in case RAM is currently hiding it |
59 | addr_t vectors_addr; // RST vectors start here | 59 | addr_t vectors_addr; // RST vectors start here |
60 | addr_t idle_addr; // return address for init/play routines | 60 | addr_t idle_addr; // return address for init/play routines |
61 | void* coleco_bios; | 61 | void* coleco_bios; |
62 | 62 | ||
63 | // general | 63 | // general |
64 | int voice_count; | 64 | int voice_count; |
65 | int const* voice_types; | 65 | int const* voice_types; |
66 | int mute_mask_; | 66 | int mute_mask_; |
67 | int tempo; | 67 | int tempo; |
68 | int gain; | 68 | int gain; |
69 | 69 | ||
70 | int sample_rate; | 70 | int sample_rate; |
71 | 71 | ||
72 | // track-specific | 72 | // track-specific |
73 | int current_track; | 73 | int current_track; |
74 | int track_count; | 74 | int track_count; |
75 | 75 | ||
76 | int clock_rate_; | 76 | int clock_rate_; |
77 | unsigned buf_changed_count; | 77 | unsigned buf_changed_count; |
78 | 78 | ||
79 | // M3u Playlist | 79 | // M3u Playlist |
80 | struct M3u_Playlist m3u; | 80 | struct M3u_Playlist m3u; |
81 | struct header_t header; | 81 | struct header_t header; |
82 | 82 | ||
83 | struct setup_t tfilter; | 83 | struct setup_t tfilter; |
84 | struct Track_Filter track_filter; | 84 | struct Track_Filter track_filter; |
85 | 85 | ||
86 | struct Multi_Buffer stereo_buf; | 86 | struct Multi_Buffer stereo_buf; |
87 | 87 | ||
88 | struct Sms_Apu apu; | 88 | struct Sms_Apu apu; |
89 | struct Sms_Fm_Apu fm_apu; | 89 | struct Sms_Fm_Apu fm_apu; |
90 | 90 | ||
91 | Sgc_Cpu cpu; | 91 | Sgc_Cpu cpu; |
92 | 92 | ||
93 | // large items | 93 | // large items |
94 | struct Rom_Data rom; | 94 | struct Rom_Data rom; |
95 | byte vectors [page_size + page_padding]; | 95 | byte vectors [page_size + page_padding]; |
96 | byte unmapped_write [0x4000]; | 96 | byte unmapped_write [0x4000]; |
97 | byte ram [0x2000 + page_padding]; | 97 | byte ram [0x2000 + page_padding]; |
98 | byte ram2 [0x4000 + page_padding]; | 98 | byte ram2 [0x4000 + page_padding]; |
99 | }; | 99 | }; |
100 | 100 | ||
101 | // Basic functionality (see Gme_File.h for file loading/track info functions) | 101 | // Basic functionality (see Gme_File.h for file loading/track info functions) |
102 | 102 | ||
103 | void Sgc_init( struct Sgc_Emu* this ); | 103 | void Sgc_init( struct Sgc_Emu* this ); |
104 | 104 | ||
105 | blargg_err_t Sgc_load_mem( struct Sgc_Emu* this, const void* data, long size ); | 105 | blargg_err_t Sgc_load_mem( struct Sgc_Emu* this, const void* data, long size ); |
106 | 106 | ||
107 | static inline int clock_rate( struct Sgc_Emu* this ) { return this->header.rate ? 3546893 : 3579545; } | 107 | static inline int clock_rate( struct Sgc_Emu* this ) { return this->header.rate ? 3546893 : 3579545; } |
108 | 108 | ||
109 | // 0x2000 bytes | 109 | // 0x2000 bytes |
110 | static inline void set_coleco_bios( struct Sgc_Emu* this, void* p ) { this->coleco_bios = p; } | 110 | static inline void set_coleco_bios( struct Sgc_Emu* this, void* p ) { this->coleco_bios = p; } |
111 | 111 | ||
112 | // Set output sample rate. Must be called only once before loading file. | 112 | // Set output sample rate. Must be called only once before loading file. |
113 | blargg_err_t Sgc_set_sample_rate( struct Sgc_Emu* this, int sample_rate ); | 113 | blargg_err_t Sgc_set_sample_rate( struct Sgc_Emu* this, int sample_rate ); |
114 | 114 | ||
115 | // Start a track, where 0 is the first track. Also clears warning string. | 115 | // Start a track, where 0 is the first track. Also clears warning string. |
116 | blargg_err_t Sgc_start_track( struct Sgc_Emu* this, int track ); | 116 | blargg_err_t Sgc_start_track( struct Sgc_Emu* this, int track ); |
117 | 117 | ||
118 | // Generate 'count' samples info 'buf'. Output is in stereo. Any emulation | 118 | // Generate 'count' samples info 'buf'. Output is in stereo. Any emulation |
119 | // errors set warning string, and major errors also end track. | 119 | // errors set warning string, and major errors also end track. |
120 | blargg_err_t Sgc_play( struct Sgc_Emu* this, int count, sample_t* buf ); | 120 | blargg_err_t Sgc_play( struct Sgc_Emu* this, int count, sample_t* buf ); |
121 | 121 | ||
122 | // Track status/control | 122 | // Track status/control |
123 | 123 | ||
124 | // Number of milliseconds (1000 msec = 1 second) played since beginning of track | 124 | // Number of milliseconds (1000 msec = 1 second) played since beginning of track |
125 | int Track_tell( struct Sgc_Emu* this ); | 125 | int Track_tell( struct Sgc_Emu* this ); |
126 | 126 | ||
127 | // Seek to new time in track. Seeking backwards or far forward can take a while. | 127 | // Seek to new time in track. Seeking backwards or far forward can take a while. |
128 | blargg_err_t Track_seek( struct Sgc_Emu* this, int msec ); | 128 | blargg_err_t Track_seek( struct Sgc_Emu* this, int msec ); |
129 | 129 | ||
130 | // Skip n samples | 130 | // Skip n samples |
131 | blargg_err_t Track_skip( struct Sgc_Emu* this, int n ); | 131 | blargg_err_t Track_skip( struct Sgc_Emu* this, int n ); |
132 | 132 | ||
133 | // Set start time and length of track fade out. Once fade ends track_ended() returns | 133 | // Set start time and length of track fade out. Once fade ends track_ended() returns |
134 | // true. Fade time can be changed while track is playing. | 134 | // true. Fade time can be changed while track is playing. |
135 | void Track_set_fade( struct Sgc_Emu* this, int start_msec, int length_msec ); | 135 | void Track_set_fade( struct Sgc_Emu* this, int start_msec, int length_msec ); |
136 | 136 | ||
137 | // True if a track has reached its end | 137 | // True if a track has reached its end |
138 | static inline bool Track_ended( struct Sgc_Emu* this ) | 138 | static inline bool Track_ended( struct Sgc_Emu* this ) |
139 | { | 139 | { |
140 | return track_ended( &this->track_filter ); | 140 | return track_ended( &this->track_filter ); |
141 | } | 141 | } |
142 | 142 | ||
143 | // Disables automatic end-of-track detection and skipping of silence at beginning | 143 | // Disables automatic end-of-track detection and skipping of silence at beginning |
144 | static inline void Track_ignore_silence( struct Sgc_Emu* this, bool disable ) | 144 | static inline void Track_ignore_silence( struct Sgc_Emu* this, bool disable ) |
145 | { | 145 | { |
146 | this->track_filter.silence_ignored_ = disable; | 146 | this->track_filter.silence_ignored_ = disable; |
147 | } | 147 | } |
148 | 148 | ||
149 | // Get track length in milliseconds | 149 | // Get track length in milliseconds |
150 | static inline int Track_get_length( struct Sgc_Emu* this, int n ) | 150 | static inline int Track_get_length( struct Sgc_Emu* this, int n ) |
151 | { | 151 | { |
152 | int length = 120 * 1000; /* 2 minutes */ | 152 | int length = 120 * 1000; /* 2 minutes */ |
153 | if ( (this->m3u.size > 0) && (n < this->m3u.size) ) { | 153 | if ( (this->m3u.size > 0) && (n < this->m3u.size) ) { |
154 | struct entry_t* entry = &this->m3u.entries [n]; | 154 | struct entry_t* entry = &this->m3u.entries [n]; |
155 | length = entry->length; | 155 | length = entry->length; |
156 | } | 156 | } |
157 | 157 | ||
158 | return length; | 158 | return length; |
159 | } | 159 | } |
160 | 160 | ||
161 | // Sound customization | 161 | // Sound customization |
162 | 162 | ||
163 | // Adjust song tempo, where 1.0 = normal, 0.5 = half speed, 2.0 = double speed. | 163 | // Adjust song tempo, where 1.0 = normal, 0.5 = half speed, 2.0 = double speed. |
164 | // Track length as returned by track_info() assumes a tempo of 1.0. | 164 | // Track length as returned by track_info() assumes a tempo of 1.0. |
165 | void Sound_set_tempo( struct Sgc_Emu* this, int t ); | 165 | void Sound_set_tempo( struct Sgc_Emu* this, int t ); |
166 | 166 | ||
167 | // Mute/unmute voice i, where voice 0 is first voice | 167 | // Mute/unmute voice i, where voice 0 is first voice |
168 | void Sound_mute_voice( struct Sgc_Emu* this, int index, bool mute ); | 168 | void Sound_mute_voice( struct Sgc_Emu* this, int index, bool mute ); |
169 | 169 | ||
170 | // Set muting state of all voices at once using a bit mask, where -1 mutes them all, | 170 | // Set muting state of all voices at once using a bit mask, where -1 mutes them all, |
171 | // 0 unmutes them all, 0x01 mutes just the first voice, etc. | 171 | // 0 unmutes them all, 0x01 mutes just the first voice, etc. |
172 | void Sound_mute_voices( struct Sgc_Emu* this, int mask ); | 172 | void Sound_mute_voices( struct Sgc_Emu* this, int mask ); |
173 | 173 | ||
174 | // Change overall output amplitude, where 1.0 results in minimal clamping. | 174 | // Change overall output amplitude, where 1.0 results in minimal clamping. |
175 | // Must be called before set_sample_rate(). | 175 | // Must be called before set_sample_rate(). |
176 | static inline void Sound_set_gain( struct Sgc_Emu* this, int g ) | 176 | static inline void Sound_set_gain( struct Sgc_Emu* this, int g ) |
177 | { | 177 | { |
178 | assert( !this->sample_rate ); // you must set gain before setting sample rate | 178 | assert( !this->sample_rate ); // you must set gain before setting sample rate |
179 | this->gain = g; | 179 | this->gain = g; |
180 | } | 180 | } |
181 | 181 | ||
182 | // True if Master System or Game Gear | 182 | // True if Master System or Game Gear |
183 | static inline bool sega_mapping( struct Sgc_Emu* this ) | 183 | static inline bool sega_mapping( struct Sgc_Emu* this ) |
184 | { | 184 | { |
185 | return this->header.system <= 1; | 185 | return this->header.system <= 1; |
186 | } | 186 | } |
187 | 187 | ||
188 | // Emulation (You shouldn't touch these) | 188 | // Emulation (You shouldn't touch these) |
189 | 189 | ||
190 | bool run_cpu( struct Sgc_Emu* this, cpu_time_t end_time ); | 190 | bool run_cpu( struct Sgc_Emu* this, cpu_time_t end_time ); |
191 | void cpu_out( struct Sgc_Emu* this, cpu_time_t time, addr_t addr, int data ); | 191 | void cpu_out( struct Sgc_Emu* this, cpu_time_t time, addr_t addr, int data ); |
192 | void cpu_write( struct Sgc_Emu* this, addr_t addr, int data ); | 192 | void cpu_write( struct Sgc_Emu* this, addr_t addr, int data ); |
193 | void jsr( struct Sgc_Emu* this, byte addr [2] ); | 193 | void jsr( struct Sgc_Emu* this, byte addr [2] ); |
194 | 194 | ||
195 | #endif | 195 | #endif |
diff --git a/apps/codecs/libgme/sms_fm_apu.c b/apps/codecs/libgme/sms_fm_apu.c index 6fd00545d6..ee5ce48932 100644 --- a/apps/codecs/libgme/sms_fm_apu.c +++ b/apps/codecs/libgme/sms_fm_apu.c | |||
@@ -1,82 +1,82 @@ | |||
1 | #include "sms_fm_apu.h" | 1 | #include "sms_fm_apu.h" |
2 | 2 | ||
3 | #include "blargg_source.h" | 3 | #include "blargg_source.h" |
4 | 4 | ||
5 | void Fm_apu_create( struct Sms_Fm_Apu* this ) | 5 | void Fm_apu_create( struct Sms_Fm_Apu* this ) |
6 | { | 6 | { |
7 | Synth_init( &this->synth ); | 7 | Synth_init( &this->synth ); |
8 | Ym2413_init( &this->apu ); | 8 | Ym2413_init( &this->apu ); |
9 | } | 9 | } |
10 | 10 | ||
11 | blargg_err_t Fm_apu_init( struct Sms_Fm_Apu* this, int clock_rate, int sample_rate ) | 11 | blargg_err_t Fm_apu_init( struct Sms_Fm_Apu* this, int clock_rate, int sample_rate ) |
12 | { | 12 | { |
13 | this->period_ = (blip_time_t) (clock_rate / sample_rate); | 13 | this->period_ = (blip_time_t) (clock_rate / sample_rate); |
14 | CHECK_ALLOC( !Ym2413_set_rate( &this->apu, sample_rate, clock_rate ) ); | 14 | CHECK_ALLOC( !Ym2413_set_rate( &this->apu, sample_rate, clock_rate ) ); |
15 | 15 | ||
16 | Fm_apu_set_output( this, 0 ); | 16 | Fm_apu_set_output( this, 0 ); |
17 | Fm_apu_volume( this, (int)FP_ONE_VOLUME ); | 17 | Fm_apu_volume( this, (int)FP_ONE_VOLUME ); |
18 | Fm_apu_reset( this ); | 18 | Fm_apu_reset( this ); |
19 | return 0; | 19 | return 0; |
20 | } | 20 | } |
21 | 21 | ||
22 | void Fm_apu_reset( struct Sms_Fm_Apu* this ) | 22 | void Fm_apu_reset( struct Sms_Fm_Apu* this ) |
23 | { | 23 | { |
24 | this->addr = 0; | 24 | this->addr = 0; |
25 | this->next_time = 0; | 25 | this->next_time = 0; |
26 | this->last_amp = 0; | 26 | this->last_amp = 0; |
27 | 27 | ||
28 | Ym2413_reset( &this->apu ); | 28 | Ym2413_reset( &this->apu ); |
29 | } | 29 | } |
30 | 30 | ||
31 | void fm_run_until( struct Sms_Fm_Apu* this, blip_time_t end_time ); | 31 | void fm_run_until( struct Sms_Fm_Apu* this, blip_time_t end_time ); |
32 | void Fm_apu_write_data( struct Sms_Fm_Apu* this, blip_time_t time, int data ) | 32 | void Fm_apu_write_data( struct Sms_Fm_Apu* this, blip_time_t time, int data ) |
33 | { | 33 | { |
34 | if ( time > this->next_time ) | 34 | if ( time > this->next_time ) |
35 | fm_run_until( this, time ); | 35 | fm_run_until( this, time ); |
36 | 36 | ||
37 | Ym2413_write( &this->apu, this->addr, data ); | 37 | Ym2413_write( &this->apu, this->addr, data ); |
38 | } | 38 | } |
39 | 39 | ||
40 | void fm_run_until( struct Sms_Fm_Apu* this, blip_time_t end_time ) | 40 | void fm_run_until( struct Sms_Fm_Apu* this, blip_time_t end_time ) |
41 | { | 41 | { |
42 | assert( end_time > this->next_time ); | 42 | assert( end_time > this->next_time ); |
43 | 43 | ||
44 | struct Blip_Buffer* const output = this->output_; | 44 | struct Blip_Buffer* const output = this->output_; |
45 | if ( !output ) | 45 | if ( !output ) |
46 | { | 46 | { |
47 | this->next_time = end_time; | 47 | this->next_time = end_time; |
48 | return; | 48 | return; |
49 | } | 49 | } |
50 | 50 | ||
51 | blip_time_t time = this->next_time; | 51 | blip_time_t time = this->next_time; |
52 | struct Ym2413_Emu* emu = &this->apu; | 52 | struct Ym2413_Emu* emu = &this->apu; |
53 | do | 53 | do |
54 | { | 54 | { |
55 | short samples [2]; | 55 | short samples [2]; |
56 | Ym2413_run( emu, 1, samples ); | 56 | Ym2413_run( emu, 1, samples ); |
57 | int amp = (samples [0] + samples [1]) >> 1; | 57 | int amp = (samples [0] + samples [1]) >> 1; |
58 | 58 | ||
59 | int delta = amp - this->last_amp; | 59 | int delta = amp - this->last_amp; |
60 | if ( delta ) | 60 | if ( delta ) |
61 | { | 61 | { |
62 | this->last_amp = amp; | 62 | this->last_amp = amp; |
63 | Synth_offset_inline( &this->synth, time, delta, output ); | 63 | Synth_offset_inline( &this->synth, time, delta, output ); |
64 | } | 64 | } |
65 | time += this->period_; | 65 | time += this->period_; |
66 | } | 66 | } |
67 | while ( time < end_time ); | 67 | while ( time < end_time ); |
68 | 68 | ||
69 | this->next_time = time; | 69 | this->next_time = time; |
70 | } | 70 | } |
71 | 71 | ||
72 | void Fm_apu_end_frame( struct Sms_Fm_Apu* this, blip_time_t time ) | 72 | void Fm_apu_end_frame( struct Sms_Fm_Apu* this, blip_time_t time ) |
73 | { | 73 | { |
74 | if ( time > this->next_time ) | 74 | if ( time > this->next_time ) |
75 | fm_run_until( this, time ); | 75 | fm_run_until( this, time ); |
76 | 76 | ||
77 | this->next_time -= time; | 77 | this->next_time -= time; |
78 | assert( this->next_time >= 0 ); | 78 | assert( this->next_time >= 0 ); |
79 | 79 | ||
80 | if ( this->output_ ) | 80 | if ( this->output_ ) |
81 | Blip_set_modified( this->output_ ); | 81 | Blip_set_modified( this->output_ ); |
82 | } | 82 | } |
diff --git a/apps/codecs/libgme/sms_fm_apu.h b/apps/codecs/libgme/sms_fm_apu.h index 00bc2b409c..921db6cef1 100644 --- a/apps/codecs/libgme/sms_fm_apu.h +++ b/apps/codecs/libgme/sms_fm_apu.h | |||
@@ -1,43 +1,43 @@ | |||
1 | #ifndef SMS_FM_APU_H | 1 | #ifndef SMS_FM_APU_H |
2 | #define SMS_FM_APU_H | 2 | #define SMS_FM_APU_H |
3 | 3 | ||
4 | #include "blargg_common.h" | 4 | #include "blargg_common.h" |
5 | #include "blip_buffer.h" | 5 | #include "blip_buffer.h" |
6 | #include "ym2413_emu.h" | 6 | #include "ym2413_emu.h" |
7 | 7 | ||
8 | enum { fm_apu_osc_count = 1 }; | 8 | enum { fm_apu_osc_count = 1 }; |
9 | 9 | ||
10 | struct Sms_Fm_Apu { | 10 | struct Sms_Fm_Apu { |
11 | struct Blip_Buffer* output_; | 11 | struct Blip_Buffer* output_; |
12 | blip_time_t next_time; | 12 | blip_time_t next_time; |
13 | int last_amp; | 13 | int last_amp; |
14 | int addr; | 14 | int addr; |
15 | 15 | ||
16 | int clock_; | 16 | int clock_; |
17 | int rate_; | 17 | int rate_; |
18 | blip_time_t period_; | 18 | blip_time_t period_; |
19 | 19 | ||
20 | struct Blip_Synth synth; | 20 | struct Blip_Synth synth; |
21 | struct Ym2413_Emu apu; | 21 | struct Ym2413_Emu apu; |
22 | }; | 22 | }; |
23 | 23 | ||
24 | void Fm_apu_create( struct Sms_Fm_Apu* this ); | 24 | void Fm_apu_create( struct Sms_Fm_Apu* this ); |
25 | 25 | ||
26 | static inline bool Fm_apu_supported( void ) { return Ym2413_supported(); } | 26 | static inline bool Fm_apu_supported( void ) { return Ym2413_supported(); } |
27 | blargg_err_t Fm_apu_init( struct Sms_Fm_Apu* this, int clock_rate, int sample_rate ); | 27 | blargg_err_t Fm_apu_init( struct Sms_Fm_Apu* this, int clock_rate, int sample_rate ); |
28 | 28 | ||
29 | static inline void Fm_apu_set_output( struct Sms_Fm_Apu* this, struct Blip_Buffer* b ) | 29 | static inline void Fm_apu_set_output( struct Sms_Fm_Apu* this, struct Blip_Buffer* b ) |
30 | { | 30 | { |
31 | this->output_ = b; | 31 | this->output_ = b; |
32 | } | 32 | } |
33 | 33 | ||
34 | static inline void Fm_apu_volume( struct Sms_Fm_Apu* this, int v ) { Synth_volume( &this->synth, (v*2) / 5 / 4096 ); } | 34 | static inline void Fm_apu_volume( struct Sms_Fm_Apu* this, int v ) { Synth_volume( &this->synth, (v*2) / 5 / 4096 ); } |
35 | 35 | ||
36 | void Fm_apu_reset( struct Sms_Fm_Apu* this ); | 36 | void Fm_apu_reset( struct Sms_Fm_Apu* this ); |
37 | 37 | ||
38 | static inline void Fm_apu_write_addr( struct Sms_Fm_Apu* this, int data ) { this->addr = data; } | 38 | static inline void Fm_apu_write_addr( struct Sms_Fm_Apu* this, int data ) { this->addr = data; } |
39 | void Fm_apu_write_data( struct Sms_Fm_Apu* this, blip_time_t, int data ); | 39 | void Fm_apu_write_data( struct Sms_Fm_Apu* this, blip_time_t, int data ); |
40 | 40 | ||
41 | void Fm_apu_end_frame( struct Sms_Fm_Apu* this, blip_time_t t ); | 41 | void Fm_apu_end_frame( struct Sms_Fm_Apu* this, blip_time_t t ); |
42 | 42 | ||
43 | #endif | 43 | #endif |
diff --git a/apps/codecs/libgme/track_filter.c b/apps/codecs/libgme/track_filter.c index 4776dcc7df..d0d75f2ded 100644 --- a/apps/codecs/libgme/track_filter.c +++ b/apps/codecs/libgme/track_filter.c | |||
@@ -1,294 +1,294 @@ | |||
1 | // Game_Music_Emu 0.6-pre. http://www.slack.net/~ant/ | 1 | // Game_Music_Emu 0.6-pre. http://www.slack.net/~ant/ |
2 | 2 | ||
3 | #include "track_filter.h" | 3 | #include "track_filter.h" |
4 | 4 | ||
5 | /* Copyright (C) 2003-2008 Shay Green. This module is free software; you | 5 | /* Copyright (C) 2003-2008 Shay Green. This module is free software; you |
6 | can redistribute it and/or modify it under the terms of the GNU Lesser | 6 | can redistribute it and/or modify it under the terms of the GNU Lesser |
7 | General Public License as published by the Free Software Foundation; either | 7 | General Public License as published by the Free Software Foundation; either |
8 | version 2.1 of the License, or (at your option) any later version. This | 8 | version 2.1 of the License, or (at your option) any later version. This |
9 | module is distributed in the hope that it will be useful, but WITHOUT ANY | 9 | module is distributed in the hope that it will be useful, but WITHOUT ANY |
10 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | 10 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
11 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more | 11 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
12 | details. You should have received a copy of the GNU Lesser General Public | 12 | details. You should have received a copy of the GNU Lesser General Public |
13 | License along with this module; if not, write to the Free Software Foundation, | 13 | License along with this module; if not, write to the Free Software Foundation, |
14 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ | 14 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ |
15 | 15 | ||
16 | #include "blargg_source.h" | 16 | #include "blargg_source.h" |
17 | 17 | ||
18 | int const fade_block_size = 512; | 18 | int const fade_block_size = 512; |
19 | int const fade_shift = 8; // fade ends with gain at 1.0 / (1 << fade_shift) | 19 | int const fade_shift = 8; // fade ends with gain at 1.0 / (1 << fade_shift) |
20 | int const silence_threshold = 8; | 20 | int const silence_threshold = 8; |
21 | 21 | ||
22 | void track_create( struct Track_Filter* this ) | 22 | void track_create( struct Track_Filter* this ) |
23 | { | 23 | { |
24 | this->emu_ = NULL; | 24 | this->emu_ = NULL; |
25 | this->setup_.max_initial = 0; | 25 | this->setup_.max_initial = 0; |
26 | this->setup_.lookahead = 0; | 26 | this->setup_.lookahead = 0; |
27 | this->setup_.max_silence = indefinite_count; | 27 | this->setup_.max_silence = indefinite_count; |
28 | this->silence_ignored_ = false; | 28 | this->silence_ignored_ = false; |
29 | track_stop( this ); | 29 | track_stop( this ); |
30 | } | 30 | } |
31 | 31 | ||
32 | blargg_err_t track_init( struct Track_Filter* this, void* emu ) | 32 | blargg_err_t track_init( struct Track_Filter* this, void* emu ) |
33 | { | 33 | { |
34 | this->emu_ = emu; | 34 | this->emu_ = emu; |
35 | return 0; | 35 | return 0; |
36 | } | 36 | } |
37 | 37 | ||
38 | static void clear_time_vars( struct Track_Filter* this ) | 38 | static void clear_time_vars( struct Track_Filter* this ) |
39 | { | 39 | { |
40 | this->emu_time = this->buf_remain; | 40 | this->emu_time = this->buf_remain; |
41 | this->out_time = 0; | 41 | this->out_time = 0; |
42 | this->silence_time = 0; | 42 | this->silence_time = 0; |
43 | this->silence_count = 0; | 43 | this->silence_count = 0; |
44 | } | 44 | } |
45 | 45 | ||
46 | void track_stop( struct Track_Filter* this ) | 46 | void track_stop( struct Track_Filter* this ) |
47 | { | 47 | { |
48 | this->emu_track_ended_ = true; | 48 | this->emu_track_ended_ = true; |
49 | this->track_ended_ = true; | 49 | this->track_ended_ = true; |
50 | this->fade_start = indefinite_count; | 50 | this->fade_start = indefinite_count; |
51 | this->fade_step = 1; | 51 | this->fade_step = 1; |
52 | this->buf_remain = 0; | 52 | this->buf_remain = 0; |
53 | this->emu_error = NULL; | 53 | this->emu_error = NULL; |
54 | clear_time_vars( this ); | 54 | clear_time_vars( this ); |
55 | } | 55 | } |
56 | 56 | ||
57 | blargg_err_t track_start( struct Track_Filter* this ) | 57 | blargg_err_t track_start( struct Track_Filter* this ) |
58 | { | 58 | { |
59 | this->emu_error = NULL; | 59 | this->emu_error = NULL; |
60 | track_stop( this ); | 60 | track_stop( this ); |
61 | 61 | ||
62 | this->emu_track_ended_ = false; | 62 | this->emu_track_ended_ = false; |
63 | this->track_ended_ = false; | 63 | this->track_ended_ = false; |
64 | 64 | ||
65 | if ( !this->silence_ignored_ ) | 65 | if ( !this->silence_ignored_ ) |
66 | { | 66 | { |
67 | // play until non-silence or end of track | 67 | // play until non-silence or end of track |
68 | while ( this->emu_time < this->setup_.max_initial ) | 68 | while ( this->emu_time < this->setup_.max_initial ) |
69 | { | 69 | { |
70 | fill_buf( this ); | 70 | fill_buf( this ); |
71 | if ( this->buf_remain | this->emu_track_ended_ ) | 71 | if ( this->buf_remain | this->emu_track_ended_ ) |
72 | break; | 72 | break; |
73 | } | 73 | } |
74 | } | 74 | } |
75 | 75 | ||
76 | clear_time_vars( this ); | 76 | clear_time_vars( this ); |
77 | return this->emu_error; | 77 | return this->emu_error; |
78 | } | 78 | } |
79 | 79 | ||
80 | static void end_track_if_error( struct Track_Filter* this, blargg_err_t err ) | 80 | static void end_track_if_error( struct Track_Filter* this, blargg_err_t err ) |
81 | { | 81 | { |
82 | if ( err ) | 82 | if ( err ) |
83 | { | 83 | { |
84 | this->emu_error = err; | 84 | this->emu_error = err; |
85 | this->emu_track_ended_ = true; | 85 | this->emu_track_ended_ = true; |
86 | } | 86 | } |
87 | } | 87 | } |
88 | 88 | ||
89 | blargg_err_t track_skip( struct Track_Filter* this, int count ) | 89 | blargg_err_t track_skip( struct Track_Filter* this, int count ) |
90 | { | 90 | { |
91 | this->emu_error = NULL; | 91 | this->emu_error = NULL; |
92 | this->out_time += count; | 92 | this->out_time += count; |
93 | 93 | ||
94 | // remove from silence and buf first | 94 | // remove from silence and buf first |
95 | { | 95 | { |
96 | int n = min( count, this->silence_count ); | 96 | int n = min( count, this->silence_count ); |
97 | this->silence_count -= n; | 97 | this->silence_count -= n; |
98 | count -= n; | 98 | count -= n; |
99 | 99 | ||
100 | n = min( count, this->buf_remain ); | 100 | n = min( count, this->buf_remain ); |
101 | this->buf_remain -= n; | 101 | this->buf_remain -= n; |
102 | count -= n; | 102 | count -= n; |
103 | } | 103 | } |
104 | 104 | ||
105 | if ( count && !this->emu_track_ended_ ) | 105 | if ( count && !this->emu_track_ended_ ) |
106 | { | 106 | { |
107 | this->emu_time += count; | 107 | this->emu_time += count; |
108 | this->silence_time = this->emu_time; // would otherwise be invalid | 108 | this->silence_time = this->emu_time; // would otherwise be invalid |
109 | end_track_if_error( this, skip_( this->emu_, count ) ); | 109 | end_track_if_error( this, skip_( this->emu_, count ) ); |
110 | } | 110 | } |
111 | 111 | ||
112 | if ( !(this->silence_count | this->buf_remain) ) // caught up to emulator, so update track ended | 112 | if ( !(this->silence_count | this->buf_remain) ) // caught up to emulator, so update track ended |
113 | this->track_ended_ |= this->emu_track_ended_; | 113 | this->track_ended_ |= this->emu_track_ended_; |
114 | 114 | ||
115 | return this->emu_error; | 115 | return this->emu_error; |
116 | } | 116 | } |
117 | 117 | ||
118 | blargg_err_t skippy_( struct Track_Filter* this, int count ) | 118 | blargg_err_t skippy_( struct Track_Filter* this, int count ) |
119 | { | 119 | { |
120 | while ( count && !this->emu_track_ended_ ) | 120 | while ( count && !this->emu_track_ended_ ) |
121 | { | 121 | { |
122 | int n = buf_size; | 122 | int n = buf_size; |
123 | if ( n > count ) | 123 | if ( n > count ) |
124 | n = count; | 124 | n = count; |
125 | count -= n; | 125 | count -= n; |
126 | RETURN_ERR( play_( this->emu_, n, this->buf ) ); | 126 | RETURN_ERR( play_( this->emu_, n, this->buf ) ); |
127 | } | 127 | } |
128 | return 0; | 128 | return 0; |
129 | } | 129 | } |
130 | 130 | ||
131 | // Fading | 131 | // Fading |
132 | 132 | ||
133 | void track_set_fade( struct Track_Filter* this, int start, int length ) | 133 | void track_set_fade( struct Track_Filter* this, int start, int length ) |
134 | { | 134 | { |
135 | this->fade_start = start; | 135 | this->fade_start = start; |
136 | this->fade_step = length / (fade_block_size * fade_shift); | 136 | this->fade_step = length / (fade_block_size * fade_shift); |
137 | if ( this->fade_step < 1 ) | 137 | if ( this->fade_step < 1 ) |
138 | this->fade_step = 1; | 138 | this->fade_step = 1; |
139 | } | 139 | } |
140 | 140 | ||
141 | static bool is_fading( struct Track_Filter* this ) | 141 | static bool is_fading( struct Track_Filter* this ) |
142 | { | 142 | { |
143 | return this->out_time >= this->fade_start && this->fade_start != indefinite_count; | 143 | return this->out_time >= this->fade_start && this->fade_start != indefinite_count; |
144 | } | 144 | } |
145 | 145 | ||
146 | // unit / pow( 2.0, (double) x / step ) | 146 | // unit / pow( 2.0, (double) x / step ) |
147 | static int int_log( int x, int step, int unit ) | 147 | static int int_log( int x, int step, int unit ) |
148 | { | 148 | { |
149 | int shift = x / step; | 149 | int shift = x / step; |
150 | int fraction = (x - shift * step) * unit / step; | 150 | int fraction = (x - shift * step) * unit / step; |
151 | return ((unit - fraction) + (fraction >> 1)) >> shift; | 151 | return ((unit - fraction) + (fraction >> 1)) >> shift; |
152 | } | 152 | } |
153 | 153 | ||
154 | static void handle_fade( struct Track_Filter* this, sample_t out [], int out_count ) | 154 | static void handle_fade( struct Track_Filter* this, sample_t out [], int out_count ) |
155 | { | 155 | { |
156 | int i; | 156 | int i; |
157 | for ( i = 0; i < out_count; i += fade_block_size ) | 157 | for ( i = 0; i < out_count; i += fade_block_size ) |
158 | { | 158 | { |
159 | int const shift = 14; | 159 | int const shift = 14; |
160 | int const unit = 1 << shift; | 160 | int const unit = 1 << shift; |
161 | int gain = int_log( (this->out_time + i - this->fade_start) / fade_block_size, | 161 | int gain = int_log( (this->out_time + i - this->fade_start) / fade_block_size, |
162 | this->fade_step, unit ); | 162 | this->fade_step, unit ); |
163 | if ( gain < (unit >> fade_shift) ) | 163 | if ( gain < (unit >> fade_shift) ) |
164 | this->track_ended_ = this->emu_track_ended_ = true; | 164 | this->track_ended_ = this->emu_track_ended_ = true; |
165 | 165 | ||
166 | sample_t* io = &out [i]; | 166 | sample_t* io = &out [i]; |
167 | for ( int count = min( fade_block_size, out_count - i ); count; --count ) | 167 | for ( int count = min( fade_block_size, out_count - i ); count; --count ) |
168 | { | 168 | { |
169 | *io = (sample_t) ((*io * gain) >> shift); | 169 | *io = (sample_t) ((*io * gain) >> shift); |
170 | ++io; | 170 | ++io; |
171 | } | 171 | } |
172 | } | 172 | } |
173 | } | 173 | } |
174 | 174 | ||
175 | // Silence detection | 175 | // Silence detection |
176 | 176 | ||
177 | static void emu_play( struct Track_Filter* this, sample_t out [], int count ) | 177 | static void emu_play( struct Track_Filter* this, sample_t out [], int count ) |
178 | { | 178 | { |
179 | this->emu_time += count; | 179 | this->emu_time += count; |
180 | if ( !this->emu_track_ended_ ) | 180 | if ( !this->emu_track_ended_ ) |
181 | end_track_if_error( this, play_( this->emu_, count, out ) ); | 181 | end_track_if_error( this, play_( this->emu_, count, out ) ); |
182 | else | 182 | else |
183 | memset( out, 0, count * sizeof *out ); | 183 | memset( out, 0, count * sizeof *out ); |
184 | } | 184 | } |
185 | 185 | ||
186 | // number of consecutive silent samples at end | 186 | // number of consecutive silent samples at end |
187 | static int count_silence( sample_t begin [], int size ) | 187 | static int count_silence( sample_t begin [], int size ) |
188 | { | 188 | { |
189 | sample_t first = *begin; | 189 | sample_t first = *begin; |
190 | *begin = silence_threshold * 2; // sentinel | 190 | *begin = silence_threshold * 2; // sentinel |
191 | sample_t* p = begin + size; | 191 | sample_t* p = begin + size; |
192 | while ( (unsigned) (*--p + silence_threshold) <= (unsigned) silence_threshold * 2 ) { } | 192 | while ( (unsigned) (*--p + silence_threshold) <= (unsigned) silence_threshold * 2 ) { } |
193 | *begin = first; | 193 | *begin = first; |
194 | return size - (p - begin); | 194 | return size - (p - begin); |
195 | } | 195 | } |
196 | 196 | ||
197 | // fill internal buffer and check it for silence | 197 | // fill internal buffer and check it for silence |
198 | void fill_buf( struct Track_Filter* this ) | 198 | void fill_buf( struct Track_Filter* this ) |
199 | { | 199 | { |
200 | assert( !this->buf_remain ); | 200 | assert( !this->buf_remain ); |
201 | if ( !this->emu_track_ended_ ) | 201 | if ( !this->emu_track_ended_ ) |
202 | { | 202 | { |
203 | emu_play( this, this->buf, buf_size ); | 203 | emu_play( this, this->buf, buf_size ); |
204 | int silence = count_silence( this->buf, buf_size ); | 204 | int silence = count_silence( this->buf, buf_size ); |
205 | if ( silence < buf_size ) | 205 | if ( silence < buf_size ) |
206 | { | 206 | { |
207 | this->silence_time = this->emu_time - silence; | 207 | this->silence_time = this->emu_time - silence; |
208 | this->buf_remain = buf_size; | 208 | this->buf_remain = buf_size; |
209 | return; | 209 | return; |
210 | } | 210 | } |
211 | } | 211 | } |
212 | this->silence_count += buf_size; | 212 | this->silence_count += buf_size; |
213 | } | 213 | } |
214 | 214 | ||
215 | blargg_err_t track_play( struct Track_Filter* this, int out_count, sample_t out [] ) | 215 | blargg_err_t track_play( struct Track_Filter* this, int out_count, sample_t out [] ) |
216 | { | 216 | { |
217 | this->emu_error = NULL; | 217 | this->emu_error = NULL; |
218 | if ( this->track_ended_ ) | 218 | if ( this->track_ended_ ) |
219 | { | 219 | { |
220 | memset( out, 0, out_count * sizeof *out ); | 220 | memset( out, 0, out_count * sizeof *out ); |
221 | } | 221 | } |
222 | else | 222 | else |
223 | { | 223 | { |
224 | assert( this->emu_time >= this->out_time ); | 224 | assert( this->emu_time >= this->out_time ); |
225 | 225 | ||
226 | // prints nifty graph of how far ahead we are when searching for silence | 226 | // prints nifty graph of how far ahead we are when searching for silence |
227 | //dprintf( "%*s \n", int ((emu_time - out_time) * 7 / 44100), "*" ); | 227 | //dprintf( "%*s \n", int ((emu_time - out_time) * 7 / 44100), "*" ); |
228 | 228 | ||
229 | // use any remaining silence samples | 229 | // use any remaining silence samples |
230 | int pos = 0; | 230 | int pos = 0; |
231 | if ( this->silence_count ) | 231 | if ( this->silence_count ) |
232 | { | 232 | { |
233 | if ( !this->silence_ignored_ ) | 233 | if ( !this->silence_ignored_ ) |
234 | { | 234 | { |
235 | // during a run of silence, run emulator at >=2x speed so it gets ahead | 235 | // during a run of silence, run emulator at >=2x speed so it gets ahead |
236 | int ahead_time = this->setup_.lookahead * (this->out_time + out_count - this->silence_time) + | 236 | int ahead_time = this->setup_.lookahead * (this->out_time + out_count - this->silence_time) + |
237 | this->silence_time; | 237 | this->silence_time; |
238 | while ( this->emu_time < ahead_time && !(this->buf_remain | this->emu_track_ended_) ) | 238 | while ( this->emu_time < ahead_time && !(this->buf_remain | this->emu_track_ended_) ) |
239 | fill_buf( this ); | 239 | fill_buf( this ); |
240 | 240 | ||
241 | // end track if sufficient silence has been found | 241 | // end track if sufficient silence has been found |
242 | if ( this->emu_time - this->silence_time > this->setup_.max_silence ) | 242 | if ( this->emu_time - this->silence_time > this->setup_.max_silence ) |
243 | { | 243 | { |
244 | this->track_ended_ = this->emu_track_ended_ = true; | 244 | this->track_ended_ = this->emu_track_ended_ = true; |
245 | this->silence_count = out_count; | 245 | this->silence_count = out_count; |
246 | this->buf_remain = 0; | 246 | this->buf_remain = 0; |
247 | } | 247 | } |
248 | } | 248 | } |
249 | 249 | ||
250 | // fill from remaining silence | 250 | // fill from remaining silence |
251 | pos = min( this->silence_count, out_count ); | 251 | pos = min( this->silence_count, out_count ); |
252 | memset( out, 0, pos * sizeof *out ); | 252 | memset( out, 0, pos * sizeof *out ); |
253 | this->silence_count -= pos; | 253 | this->silence_count -= pos; |
254 | } | 254 | } |
255 | 255 | ||
256 | // use any remaining samples from buffer | 256 | // use any remaining samples from buffer |
257 | if ( this->buf_remain ) | 257 | if ( this->buf_remain ) |
258 | { | 258 | { |
259 | int n = min( this->buf_remain, (int) (out_count - pos) ); | 259 | int n = min( this->buf_remain, (int) (out_count - pos) ); |
260 | memcpy( out + pos, this->buf + (buf_size - this->buf_remain), n * sizeof *out ); | 260 | memcpy( out + pos, this->buf + (buf_size - this->buf_remain), n * sizeof *out ); |
261 | this->buf_remain -= n; | 261 | this->buf_remain -= n; |
262 | pos += n; | 262 | pos += n; |
263 | } | 263 | } |
264 | 264 | ||
265 | // generate remaining samples normally | 265 | // generate remaining samples normally |
266 | int remain = out_count - pos; | 266 | int remain = out_count - pos; |
267 | if ( remain ) | 267 | if ( remain ) |
268 | { | 268 | { |
269 | emu_play( this, out + pos, remain ); | 269 | emu_play( this, out + pos, remain ); |
270 | this->track_ended_ |= this->emu_track_ended_; | 270 | this->track_ended_ |= this->emu_track_ended_; |
271 | 271 | ||
272 | if ( this->silence_ignored_ && !is_fading( this ) ) | 272 | if ( this->silence_ignored_ && !is_fading( this ) ) |
273 | { | 273 | { |
274 | // if left unupdated, ahead_time could become too large | 274 | // if left unupdated, ahead_time could become too large |
275 | this->silence_time = this->emu_time; | 275 | this->silence_time = this->emu_time; |
276 | } | 276 | } |
277 | else | 277 | else |
278 | { | 278 | { |
279 | // check end for a new run of silence | 279 | // check end for a new run of silence |
280 | int silence = count_silence( out + pos, remain ); | 280 | int silence = count_silence( out + pos, remain ); |
281 | if ( silence < remain ) | 281 | if ( silence < remain ) |
282 | this->silence_time = this->emu_time - silence; | 282 | this->silence_time = this->emu_time - silence; |
283 | 283 | ||
284 | if ( this->emu_time - this->silence_time >= buf_size ) | 284 | if ( this->emu_time - this->silence_time >= buf_size ) |
285 | fill_buf( this ); // cause silence detection on next play() | 285 | fill_buf( this ); // cause silence detection on next play() |
286 | } | 286 | } |
287 | } | 287 | } |
288 | 288 | ||
289 | if ( is_fading( this ) ) | 289 | if ( is_fading( this ) ) |
290 | handle_fade( this, out, out_count ); | 290 | handle_fade( this, out, out_count ); |
291 | } | 291 | } |
292 | this->out_time += out_count; | 292 | this->out_time += out_count; |
293 | return this->emu_error; | 293 | return this->emu_error; |
294 | } | 294 | } |
diff --git a/apps/codecs/libgme/track_filter.h b/apps/codecs/libgme/track_filter.h index 35049b91bb..3689be9620 100644 --- a/apps/codecs/libgme/track_filter.h +++ b/apps/codecs/libgme/track_filter.h | |||
@@ -1,90 +1,90 @@ | |||
1 | // Removes silence from beginning of track, fades end of track. Also looks ahead | 1 | // Removes silence from beginning of track, fades end of track. Also looks ahead |
2 | // for excessive silence, and if found, ends track. | 2 | // for excessive silence, and if found, ends track. |
3 | 3 | ||
4 | // Game_Music_Emu 0.6-pre | 4 | // Game_Music_Emu 0.6-pre |
5 | #ifndef TRACK_FILTER_H | 5 | #ifndef TRACK_FILTER_H |
6 | #define TRACK_FILTER_H | 6 | #define TRACK_FILTER_H |
7 | 7 | ||
8 | #include "blargg_common.h" | 8 | #include "blargg_common.h" |
9 | 9 | ||
10 | typedef short sample_t; | 10 | typedef short sample_t; |
11 | typedef int sample_count_t; | 11 | typedef int sample_count_t; |
12 | 12 | ||
13 | enum { indefinite_count = INT_MAX/2 + 1 }; | 13 | enum { indefinite_count = INT_MAX/2 + 1 }; |
14 | enum { buf_size = 2048 }; | 14 | enum { buf_size = 2048 }; |
15 | 15 | ||
16 | struct setup_t { | 16 | struct setup_t { |
17 | sample_count_t max_initial; // maximum silence to strip from beginning of track | 17 | sample_count_t max_initial; // maximum silence to strip from beginning of track |
18 | sample_count_t max_silence; // maximum silence in middle of track without it ending | 18 | sample_count_t max_silence; // maximum silence in middle of track without it ending |
19 | int lookahead; // internal speed when looking ahead for silence (2=200% etc.) | 19 | int lookahead; // internal speed when looking ahead for silence (2=200% etc.) |
20 | }; | 20 | }; |
21 | 21 | ||
22 | struct Track_Filter { | 22 | struct Track_Filter { |
23 | void* emu_; | 23 | void* emu_; |
24 | struct setup_t setup_; | 24 | struct setup_t setup_; |
25 | const char* emu_error; | 25 | const char* emu_error; |
26 | bool silence_ignored_; | 26 | bool silence_ignored_; |
27 | 27 | ||
28 | // Timing | 28 | // Timing |
29 | int out_time; // number of samples played since start of track | 29 | int out_time; // number of samples played since start of track |
30 | int emu_time; // number of samples emulator has generated since start of track | 30 | int emu_time; // number of samples emulator has generated since start of track |
31 | int emu_track_ended_; // emulator has reached end of track | 31 | int emu_track_ended_; // emulator has reached end of track |
32 | volatile int track_ended_; | 32 | volatile int track_ended_; |
33 | 33 | ||
34 | // Fading | 34 | // Fading |
35 | int fade_start; | 35 | int fade_start; |
36 | int fade_step; | 36 | int fade_step; |
37 | 37 | ||
38 | // Silence detection | 38 | // Silence detection |
39 | int silence_time; // absolute number of samples where most recent silence began | 39 | int silence_time; // absolute number of samples where most recent silence began |
40 | int silence_count; // number of samples of silence to play before using buf | 40 | int silence_count; // number of samples of silence to play before using buf |
41 | int buf_remain; // number of samples left in silence buffer | 41 | int buf_remain; // number of samples left in silence buffer |
42 | sample_t buf [buf_size]; | 42 | sample_t buf [buf_size]; |
43 | }; | 43 | }; |
44 | 44 | ||
45 | // Initializes filter. Must be done once before using object. | 45 | // Initializes filter. Must be done once before using object. |
46 | blargg_err_t track_init( struct Track_Filter* this, void* ); | 46 | blargg_err_t track_init( struct Track_Filter* this, void* ); |
47 | void track_create( struct Track_Filter* this ); | 47 | void track_create( struct Track_Filter* this ); |
48 | 48 | ||
49 | // Gets/sets setup | 49 | // Gets/sets setup |
50 | static inline struct setup_t const* track_get_setup( struct Track_Filter* this ) { return &this->setup_; } | 50 | static inline struct setup_t const* track_get_setup( struct Track_Filter* this ) { return &this->setup_; } |
51 | static inline void track_setup( struct Track_Filter* this, struct setup_t const* s ) { this->setup_ = *s; } | 51 | static inline void track_setup( struct Track_Filter* this, struct setup_t const* s ) { this->setup_ = *s; } |
52 | 52 | ||
53 | // Disables automatic end-of-track detection and skipping of silence at beginning | 53 | // Disables automatic end-of-track detection and skipping of silence at beginning |
54 | static inline void track_ignore_silence( struct Track_Filter* this, bool disable ) { this->silence_ignored_ = disable; } | 54 | static inline void track_ignore_silence( struct Track_Filter* this, bool disable ) { this->silence_ignored_ = disable; } |
55 | 55 | ||
56 | // Clears state and skips initial silence in track | 56 | // Clears state and skips initial silence in track |
57 | blargg_err_t track_start( struct Track_Filter* this ); | 57 | blargg_err_t track_start( struct Track_Filter* this ); |
58 | 58 | ||
59 | // Sets time that fade starts, and how long until track ends. | 59 | // Sets time that fade starts, and how long until track ends. |
60 | void track_set_fade( struct Track_Filter* this, sample_count_t start, sample_count_t length ); | 60 | void track_set_fade( struct Track_Filter* this, sample_count_t start, sample_count_t length ); |
61 | 61 | ||
62 | // Generates n samples into buf | 62 | // Generates n samples into buf |
63 | blargg_err_t track_play( struct Track_Filter* this, int n, sample_t buf [] ); | 63 | blargg_err_t track_play( struct Track_Filter* this, int n, sample_t buf [] ); |
64 | 64 | ||
65 | // Skips n samples | 65 | // Skips n samples |
66 | blargg_err_t track_skip( struct Track_Filter* this, int n ); | 66 | blargg_err_t track_skip( struct Track_Filter* this, int n ); |
67 | 67 | ||
68 | // Number of samples played/skipped since start_track() | 68 | // Number of samples played/skipped since start_track() |
69 | static inline int track_sample_count( struct Track_Filter* this ) { return this->out_time; } | 69 | static inline int track_sample_count( struct Track_Filter* this ) { return this->out_time; } |
70 | 70 | ||
71 | // True if track ended. Causes are end of source samples, end of fade, | 71 | // True if track ended. Causes are end of source samples, end of fade, |
72 | // or excessive silence. | 72 | // or excessive silence. |
73 | static inline bool track_ended( struct Track_Filter* this ) { return this->track_ended_; } | 73 | static inline bool track_ended( struct Track_Filter* this ) { return this->track_ended_; } |
74 | 74 | ||
75 | // Clears state | 75 | // Clears state |
76 | void track_stop( struct Track_Filter* this ); | 76 | void track_stop( struct Track_Filter* this ); |
77 | 77 | ||
78 | // For use by callbacks | 78 | // For use by callbacks |
79 | 79 | ||
80 | // Sets internal "track ended" flag and stops generation of further source samples | 80 | // Sets internal "track ended" flag and stops generation of further source samples |
81 | static inline void track_set_end( struct Track_Filter* this ) { this->emu_track_ended_ = true; } | 81 | static inline void track_set_end( struct Track_Filter* this ) { this->emu_track_ended_ = true; } |
82 | 82 | ||
83 | // For use by skip_() callback | 83 | // For use by skip_() callback |
84 | blargg_err_t skippy_( struct Track_Filter* this, int count ); | 84 | blargg_err_t skippy_( struct Track_Filter* this, int count ); |
85 | void fill_buf( struct Track_Filter* this ); | 85 | void fill_buf( struct Track_Filter* this ); |
86 | 86 | ||
87 | // Skip and play callbacks | 87 | // Skip and play callbacks |
88 | blargg_err_t skip_( void* emu, int count ); | 88 | blargg_err_t skip_( void* emu, int count ); |
89 | blargg_err_t play_( void* emu, int count, sample_t out [] ); | 89 | blargg_err_t play_( void* emu, int count, sample_t out [] ); |
90 | #endif | 90 | #endif |
diff --git a/apps/codecs/libgme/vrc7tone.h b/apps/codecs/libgme/vrc7tone.h index a256c80ba6..c589335c3c 100644 --- a/apps/codecs/libgme/vrc7tone.h +++ b/apps/codecs/libgme/vrc7tone.h | |||
@@ -1,20 +1,20 @@ | |||
1 | /* VRC7 TONES by okazaki@angel.ne.jp */ | 1 | /* VRC7 TONES by okazaki@angel.ne.jp */ |
2 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 2 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
3 | 0x33,0x01,0x09,0x0e,0x94,0x90,0x40,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 3 | 0x33,0x01,0x09,0x0e,0x94,0x90,0x40,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
4 | 0x13,0x41,0x0f,0x0d,0xce,0xd3,0x43,0x13,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 4 | 0x13,0x41,0x0f,0x0d,0xce,0xd3,0x43,0x13,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
5 | 0x01,0x12,0x1b,0x06,0xff,0xd2,0x00,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 5 | 0x01,0x12,0x1b,0x06,0xff,0xd2,0x00,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
6 | 0x61,0x61,0x1b,0x07,0xaf,0x63,0x20,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 6 | 0x61,0x61,0x1b,0x07,0xaf,0x63,0x20,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
7 | 0x22,0x21,0x1e,0x06,0xf0,0x76,0x08,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 7 | 0x22,0x21,0x1e,0x06,0xf0,0x76,0x08,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
8 | 0x66,0x21,0x15,0x00,0x93,0x94,0x20,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 8 | 0x66,0x21,0x15,0x00,0x93,0x94,0x20,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
9 | 0x21,0x61,0x1c,0x07,0x82,0x81,0x10,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 9 | 0x21,0x61,0x1c,0x07,0x82,0x81,0x10,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
10 | 0x23,0x21,0x20,0x1f,0xc0,0x71,0x07,0x47,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 10 | 0x23,0x21,0x20,0x1f,0xc0,0x71,0x07,0x47,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
11 | 0x25,0x31,0x26,0x05,0x64,0x41,0x18,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 11 | 0x25,0x31,0x26,0x05,0x64,0x41,0x18,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
12 | 0x17,0x21,0x28,0x07,0xff,0x83,0x02,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 12 | 0x17,0x21,0x28,0x07,0xff,0x83,0x02,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
13 | 0x97,0x81,0x25,0x07,0xcf,0xc8,0x02,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 13 | 0x97,0x81,0x25,0x07,0xcf,0xc8,0x02,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
14 | 0x21,0x21,0x54,0x0f,0x80,0x7f,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 14 | 0x21,0x21,0x54,0x0f,0x80,0x7f,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
15 | 0x01,0x01,0x56,0x03,0xd3,0xb2,0x43,0x58,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 15 | 0x01,0x01,0x56,0x03,0xd3,0xb2,0x43,0x58,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
16 | 0x31,0x21,0x0c,0x03,0x82,0xc0,0x40,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 16 | 0x31,0x21,0x0c,0x03,0x82,0xc0,0x40,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
17 | 0x21,0x01,0x0c,0x03,0xd4,0xd3,0x40,0x84,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 17 | 0x21,0x01,0x0c,0x03,0xd4,0xd3,0x40,0x84,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
18 | 0x07,0x21,0x14,0x00,0xee,0xf8,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 18 | 0x07,0x21,0x14,0x00,0xee,0xf8,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
19 | 0x01,0x31,0x00,0x00,0xf8,0xf7,0xf8,0xf7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 19 | 0x01,0x31,0x00,0x00,0xf8,0xf7,0xf8,0xf7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
20 | 0x25,0x11,0x00,0x00,0xf8,0xfa,0xf8,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 | 20 | 0x25,0x11,0x00,0x00,0xf8,0xfa,0xf8,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
diff --git a/apps/codecs/libgme/ym2413_emu.c b/apps/codecs/libgme/ym2413_emu.c index 9efd3dcc3d..d9ada431ca 100644 --- a/apps/codecs/libgme/ym2413_emu.c +++ b/apps/codecs/libgme/ym2413_emu.c | |||
@@ -1,45 +1,45 @@ | |||
1 | // Game_Music_Emu 0.5.5. http://www.slack.net/~ant/ | 1 | // Game_Music_Emu 0.5.5. http://www.slack.net/~ant/ |
2 | 2 | ||
3 | #include "ym2413_emu.h" | 3 | #include "ym2413_emu.h" |
4 | 4 | ||
5 | void Ym2413_init( struct Ym2413_Emu* this ) | 5 | void Ym2413_init( struct Ym2413_Emu* this ) |
6 | { | 6 | { |
7 | this->last_time = disabled_time; this->out = 0; | 7 | this->last_time = disabled_time; this->out = 0; |
8 | } | 8 | } |
9 | 9 | ||
10 | int Ym2413_set_rate( struct Ym2413_Emu* this, int sample_rate, int clock_rate ) | 10 | int Ym2413_set_rate( struct Ym2413_Emu* this, int sample_rate, int clock_rate ) |
11 | { | 11 | { |
12 | OPLL_new ( &this->opll, clock_rate, sample_rate ); | 12 | OPLL_new ( &this->opll, clock_rate, sample_rate ); |
13 | OPLL_reset_patch( &this->opll, OPLL_2413_TONE ); | 13 | OPLL_reset_patch( &this->opll, OPLL_2413_TONE ); |
14 | 14 | ||
15 | Ym2413_reset( this ); | 15 | Ym2413_reset( this ); |
16 | return 0; | 16 | return 0; |
17 | } | 17 | } |
18 | 18 | ||
19 | void Ym2413_reset( struct Ym2413_Emu* this ) | 19 | void Ym2413_reset( struct Ym2413_Emu* this ) |
20 | { | 20 | { |
21 | OPLL_reset( &this->opll ); | 21 | OPLL_reset( &this->opll ); |
22 | OPLL_setMask( &this->opll, 0 ); | 22 | OPLL_setMask( &this->opll, 0 ); |
23 | } | 23 | } |
24 | 24 | ||
25 | void Ym2413_write( struct Ym2413_Emu* this, int addr, int data ) | 25 | void Ym2413_write( struct Ym2413_Emu* this, int addr, int data ) |
26 | { | 26 | { |
27 | OPLL_writeIO( &this->opll, 0, addr ); | 27 | OPLL_writeIO( &this->opll, 0, addr ); |
28 | OPLL_writeIO( &this->opll, 1, data ); | 28 | OPLL_writeIO( &this->opll, 1, data ); |
29 | } | 29 | } |
30 | 30 | ||
31 | void Ym2413_mute_voices( struct Ym2413_Emu* this, int mask ) | 31 | void Ym2413_mute_voices( struct Ym2413_Emu* this, int mask ) |
32 | { | 32 | { |
33 | OPLL_setMask( &this->opll, mask ); | 33 | OPLL_setMask( &this->opll, mask ); |
34 | } | 34 | } |
35 | 35 | ||
36 | void Ym2413_run( struct Ym2413_Emu* this, int pair_count, short* out ) | 36 | void Ym2413_run( struct Ym2413_Emu* this, int pair_count, short* out ) |
37 | { | 37 | { |
38 | while ( pair_count-- ) | 38 | while ( pair_count-- ) |
39 | { | 39 | { |
40 | int s = OPLL_calc( &this->opll ) << 1; | 40 | int s = OPLL_calc( &this->opll ) << 1; |
41 | out [0] = s; | 41 | out [0] = s; |
42 | out [1] = s; | 42 | out [1] = s; |
43 | out += 2; | 43 | out += 2; |
44 | } | 44 | } |
45 | } | 45 | } |
diff --git a/apps/codecs/libgme/ym2413_emu.h b/apps/codecs/libgme/ym2413_emu.h index 68d8fe3d8f..8f52b04fbd 100644 --- a/apps/codecs/libgme/ym2413_emu.h +++ b/apps/codecs/libgme/ym2413_emu.h | |||
@@ -1,61 +1,61 @@ | |||
1 | // YM2413 FM sound chip emulator interface | 1 | // YM2413 FM sound chip emulator interface |
2 | 2 | ||
3 | // Game_Music_Emu 0.6-pre | 3 | // Game_Music_Emu 0.6-pre |
4 | #ifndef YM2413_EMU_H | 4 | #ifndef YM2413_EMU_H |
5 | #define YM2413_EMU_H | 5 | #define YM2413_EMU_H |
6 | 6 | ||
7 | #include "blargg_common.h" | 7 | #include "blargg_common.h" |
8 | #include "emu2413.h" | 8 | #include "emu2413.h" |
9 | 9 | ||
10 | enum { out_chan_count = 2 }; // stereo | 10 | enum { out_chan_count = 2 }; // stereo |
11 | enum { channel_count = 14 }; | 11 | enum { channel_count = 14 }; |
12 | enum { disabled_time = -1 }; | 12 | enum { disabled_time = -1 }; |
13 | 13 | ||
14 | struct Ym2413_Emu { | 14 | struct Ym2413_Emu { |
15 | OPLL opll; | 15 | OPLL opll; |
16 | 16 | ||
17 | // Impl | 17 | // Impl |
18 | int last_time; | 18 | int last_time; |
19 | short* out; | 19 | short* out; |
20 | }; | 20 | }; |
21 | 21 | ||
22 | void Ym2413_init( struct Ym2413_Emu* this ); | 22 | void Ym2413_init( struct Ym2413_Emu* this ); |
23 | 23 | ||
24 | static inline bool Ym2413_supported( void ) { return true; } | 24 | static inline bool Ym2413_supported( void ) { return true; } |
25 | 25 | ||
26 | // Sets output sample rate and chip clock rates, in Hz. Returns non-zero | 26 | // Sets output sample rate and chip clock rates, in Hz. Returns non-zero |
27 | // if error. | 27 | // if error. |
28 | int Ym2413_set_rate( struct Ym2413_Emu* this, int sample_rate, int clock_rate ); | 28 | int Ym2413_set_rate( struct Ym2413_Emu* this, int sample_rate, int clock_rate ); |
29 | 29 | ||
30 | // Resets to power-up state | 30 | // Resets to power-up state |
31 | void Ym2413_reset( struct Ym2413_Emu* this ); | 31 | void Ym2413_reset( struct Ym2413_Emu* this ); |
32 | 32 | ||
33 | // Mutes voice n if bit n (1 << n) of mask is set | 33 | // Mutes voice n if bit n (1 << n) of mask is set |
34 | void Ym2413_mute_voices( struct Ym2413_Emu* this, int mask ); | 34 | void Ym2413_mute_voices( struct Ym2413_Emu* this, int mask ); |
35 | 35 | ||
36 | // Writes data to addr | 36 | // Writes data to addr |
37 | void Ym2413_write( struct Ym2413_Emu* this, int addr, int data ); | 37 | void Ym2413_write( struct Ym2413_Emu* this, int addr, int data ); |
38 | 38 | ||
39 | // Runs and writes pair_count*2 samples to output | 39 | // Runs and writes pair_count*2 samples to output |
40 | void Ym2413_run( struct Ym2413_Emu* this, int pair_count, short* out ); | 40 | void Ym2413_run( struct Ym2413_Emu* this, int pair_count, short* out ); |
41 | 41 | ||
42 | static inline void Ym2413_enable( struct Ym2413_Emu* this, bool b ) { this->last_time = b ? 0 : disabled_time; } | 42 | static inline void Ym2413_enable( struct Ym2413_Emu* this, bool b ) { this->last_time = b ? 0 : disabled_time; } |
43 | static inline bool Ym2413_enabled( struct Ym2413_Emu* this ) { return this->last_time != disabled_time; } | 43 | static inline bool Ym2413_enabled( struct Ym2413_Emu* this ) { return this->last_time != disabled_time; } |
44 | static inline void Ym2413_begin_frame( struct Ym2413_Emu* this, short* buf ) { this->out = buf; this->last_time = 0; } | 44 | static inline void Ym2413_begin_frame( struct Ym2413_Emu* this, short* buf ) { this->out = buf; this->last_time = 0; } |
45 | 45 | ||
46 | static inline int Ym2413_run_until( struct Ym2413_Emu* this, int time ) | 46 | static inline int Ym2413_run_until( struct Ym2413_Emu* this, int time ) |
47 | { | 47 | { |
48 | int count = time - this->last_time; | 48 | int count = time - this->last_time; |
49 | if ( count > 0 ) | 49 | if ( count > 0 ) |
50 | { | 50 | { |
51 | if ( this->last_time < 0 ) | 51 | if ( this->last_time < 0 ) |
52 | return false; | 52 | return false; |
53 | this->last_time = time; | 53 | this->last_time = time; |
54 | short* p = this->out; | 54 | short* p = this->out; |
55 | this->out += count * out_chan_count; | 55 | this->out += count * out_chan_count; |
56 | Ym2413_run( this, count, p ); | 56 | Ym2413_run( this, count, p ); |
57 | } | 57 | } |
58 | return true; | 58 | return true; |
59 | } | 59 | } |
60 | 60 | ||
61 | #endif | 61 | #endif |
diff --git a/apps/codecs/libgme/ymtables.h b/apps/codecs/libgme/ymtables.h index 51812c1b57..c1619026b2 100644 --- a/apps/codecs/libgme/ymtables.h +++ b/apps/codecs/libgme/ymtables.h | |||
@@ -1,559 +1,559 @@ | |||
1 | #ifndef _EMUTABLES_H_ | 1 | #ifndef _EMUTABLES_H_ |
2 | #define _EMUTABLES_H_ | 2 | #define _EMUTABLES_H_ |
3 | 3 | ||
4 | /* Precompiled ym2612 tables for use in Rockbox */ | 4 | /* Precompiled ym2612 tables for use in Rockbox */ |
5 | 5 | ||
6 | static const int tl_coeff[] = { | 6 | static const int tl_coeff[] = { |
7 | 268435455, 267712100, 266990695, 266271234, 265553712, 264838123, 264124462, 263412725, 262702906, 261994999, 261289000, | 7 | 268435455, 267712100, 266990695, 266271234, 265553712, 264838123, 264124462, 263412725, 262702906, 261994999, 261289000, |
8 | 260584903, 259882704, 259182396, 258483976, 257787438, 257092777, 256399988, 255709066, 255020006, 254332802, 253647450, | 8 | 260584903, 259882704, 259182396, 258483976, 257787438, 257092777, 256399988, 255709066, 255020006, 254332802, 253647450, |
9 | 252963945, 252282282, 251602456, 250924462, 250248294, 249573949, 248901421, 248230705, 247561797, 246894691, 246229383, | 9 | 252963945, 252282282, 251602456, 250924462, 250248294, 249573949, 248901421, 248230705, 247561797, 246894691, 246229383, |
10 | 245565867, 244904140, 244244195, 243586029, 242929637, 242275013, 241622154, 240971053, 240321708, 239674112, 239028261, | 10 | 245565867, 244904140, 244244195, 243586029, 242929637, 242275013, 241622154, 240971053, 240321708, 239674112, 239028261, |
11 | 238384150, 237741775, 237101131, 236462214, 235825018, 235189539, 234555773, 233923714, 233293359, 232664702, 232037740, | 11 | 238384150, 237741775, 237101131, 236462214, 235825018, 235189539, 234555773, 233923714, 233293359, 232664702, 232037740, |
12 | 231412466, 230788878, 230166970, 229546738, 228928178, 228311284, 227696052, 227082479, 226470558, 225860287, 225251660, | 12 | 231412466, 230788878, 230166970, 229546738, 228928178, 228311284, 227696052, 227082479, 226470558, 225860287, 225251660, |
13 | 224644674, 224039323, 223435603, 222833510, 222233039, 221634187, 221036948, 220441319, 219847295, 219254871, 218664044, | 13 | 224644674, 224039323, 223435603, 222833510, 222233039, 221634187, 221036948, 220441319, 219847295, 219254871, 218664044, |
14 | 218074809, 217487162, 216901098, 216316614, 215733704, 215152366, 214572594, 213994384, 213417732, 212842635, 212269087, | 14 | 218074809, 217487162, 216901098, 216316614, 215733704, 215152366, 214572594, 213994384, 213417732, 212842635, 212269087, |
15 | 211697084, 211126623, 210557699, 209990308, 209424446, 208860109, 208297293, 207735993, 207176206, 206617927, 206061153, | 15 | 211697084, 211126623, 210557699, 209990308, 209424446, 208860109, 208297293, 207735993, 207176206, 206617927, 206061153, |
16 | 205505879, 204952102, 204399816, 203849019, 203299706, 202751873, 202205517, 201660633, 201117217, 200575266, 200034774, | 16 | 205505879, 204952102, 204399816, 203849019, 203299706, 202751873, 202205517, 201660633, 201117217, 200575266, 200034774, |
17 | 199495740, 198958158, 198422024, 197887335, 197354088, 196822277, 196291899, 195762950, 195235427, 194709325, 194184641, | 17 | 199495740, 198958158, 198422024, 197887335, 197354088, 196822277, 196291899, 195762950, 195235427, 194709325, 194184641, |
18 | 193661370, 193139510, 192619056, 192100005, 191582352, 191066094, 190551228, 190037748, 189525653, 189014937, 188505598, | 18 | 193661370, 193139510, 192619056, 192100005, 191582352, 191066094, 190551228, 190037748, 189525653, 189014937, 188505598, |
19 | 187997631, 187491033, 186985800, 186481928, 185979414, 185478255, 184978446, 184479983, 183982864, 183487085, 182992641, | 19 | 187997631, 187491033, 186985800, 186481928, 185979414, 185478255, 184978446, 184479983, 183982864, 183487085, 182992641, |
20 | 182499530, 182007748, 181517291, 181028155, 180540338, 180053835, 179568643, 179084759, 178602178, 178120898, 177640915, | 20 | 182499530, 182007748, 181517291, 181028155, 180540338, 180053835, 179568643, 179084759, 178602178, 178120898, 177640915, |
21 | 177162225, 176684825, 176208712, 175733881, 175260330, 174788055, 174317053, 173847320, 173378853, 172911648, 172445702, | 21 | 177162225, 176684825, 176208712, 175733881, 175260330, 174788055, 174317053, 173847320, 173378853, 172911648, 172445702, |
22 | 171981012, 171517574, 171055385, 170594441, 170134740, 169676277, 169219049, 168763054, 168308287, 167854746, 167402427, | 22 | 171981012, 171517574, 171055385, 170594441, 170134740, 169676277, 169219049, 168763054, 168308287, 167854746, 167402427, |
23 | 166951327, 166501443, 166052770, 165605307, 165159050, 164713995, 164270139, 163827480, 163386013, 162945736, 162506646, | 23 | 166951327, 166501443, 166052770, 165605307, 165159050, 164713995, 164270139, 163827480, 163386013, 162945736, 162506646, |
24 | 162068738, 161632011, 161196460, 160762083, 160328877, 159896838, 159465963, 159036250, 158607694, 158180293, 157754044, | 24 | 162068738, 161632011, 161196460, 160762083, 160328877, 159896838, 159465963, 159036250, 158607694, 158180293, 157754044, |
25 | 157328943, 156904988, 156482176, 156060502, 155639965, 155220562, 154802288, 154385142, 153969119, 153554218, 153140435, | 25 | 157328943, 156904988, 156482176, 156060502, 155639965, 155220562, 154802288, 154385142, 153969119, 153554218, 153140435, |
26 | 152727766, 152316210, 151905763, 151496422, 151088184, 150681046, 150275005, 149870058, 149466203, 149063435, 148661753, | 26 | 152727766, 152316210, 151905763, 151496422, 151088184, 150681046, 150275005, 149870058, 149466203, 149063435, 148661753, |
27 | 148261154, 147861634, 147463190, 147065821, 146669522, 146274291, 145880125, 145487021, 145094976, 144703988, 144314054, | 27 | 148261154, 147861634, 147463190, 147065821, 146669522, 146274291, 145880125, 145487021, 145094976, 144703988, 144314054, |
28 | 143925170, 143537334, 143150543, 142764795, 142380086, 141996414, 141613775, 141232168, 140851589, 140472035, 140093505, | 28 | 143925170, 143537334, 143150543, 142764795, 142380086, 141996414, 141613775, 141232168, 140851589, 140472035, 140093505, |
29 | 139715994, 139339501, 138964022, 138589555, 138216097, 137843646, 137472198, 137101751, 136732302, 136363849, 135996388, | 29 | 139715994, 139339501, 138964022, 138589555, 138216097, 137843646, 137472198, 137101751, 136732302, 136363849, 135996388, |
30 | 135629918, 135264436, 134899938, 134536423, 134173887, 133812328, 133451743, 133092130, 132733486, 132375808, 132019095, | 30 | 135629918, 135264436, 134899938, 134536423, 134173887, 133812328, 133451743, 133092130, 132733486, 132375808, 132019095, |
31 | 131663342, 131308548, 130954711, 130601826, 130249893, 129898908, 129548869, 129199773, 128851618, 128504401, 128158119, | 31 | 131663342, 131308548, 130954711, 130601826, 130249893, 129898908, 129548869, 129199773, 128851618, 128504401, 128158119, |
32 | 127812771, 127468353, 127124864, 126782300, 126440659, 126099939, 125760137, 125421250, 125083277, 124746214, 124410060, | 32 | 127812771, 127468353, 127124864, 126782300, 126440659, 126099939, 125760137, 125421250, 125083277, 124746214, 124410060, |
33 | 124074812, 123740467, 123407023, 123074477, 122742828, 122412072, 122082208, 121753232, 121425143, 121097939, 120771615, | 33 | 124074812, 123740467, 123407023, 123074477, 122742828, 122412072, 122082208, 121753232, 121425143, 121097939, 120771615, |
34 | 120446172, 120121605, 119797912, 119475092, 119153142, 118832060, 118511843, 118192488, 117873994, 117556359, 117239579, | 34 | 120446172, 120121605, 119797912, 119475092, 119153142, 118832060, 118511843, 118192488, 117873994, 117556359, 117239579, |
35 | 116923653, 116608578, 116294353, 115980974, 115668439, 115356747, 115045894, 114735880, 114426700, 114118354, 113810839, | 35 | 116923653, 116608578, 116294353, 115980974, 115668439, 115356747, 115045894, 114735880, 114426700, 114118354, 113810839, |
36 | 113504152, 113198292, 112893256, 112589042, 112285648, 111983071, 111681310, 111380362, 111080225, 110780896, 110482375, | 36 | 113504152, 113198292, 112893256, 112589042, 112285648, 111983071, 111681310, 111380362, 111080225, 110780896, 110482375, |
37 | 110184657, 109887742, 109591627, 109296310, 109001789, 108708061, 108415125, 108122978, 107831619, 107541044, 107251253, | 37 | 110184657, 109887742, 109591627, 109296310, 109001789, 108708061, 108415125, 108122978, 107831619, 107541044, 107251253, |
38 | 106962243, 106674011, 106386556, 106099876, 105813968, 105528830, 105244461, 104960859, 104678020, 104395944, 104114628, | 38 | 106962243, 106674011, 106386556, 106099876, 105813968, 105528830, 105244461, 104960859, 104678020, 104395944, 104114628, |
39 | 103834069, 103554267, 103275219, 102996923, 102719377, 102442578, 102166526, 101891217, 101616650, 101342823, 101069734, | 39 | 103834069, 103554267, 103275219, 102996923, 102719377, 102442578, 102166526, 101891217, 101616650, 101342823, 101069734, |
40 | 100797381, 100525762, 100254875, 99984718, 99715288, 99446585, 99178606, 98911349, 98644812, 98378993, 98113891, | 40 | 100797381, 100525762, 100254875, 99984718, 99715288, 99446585, 99178606, 98911349, 98644812, 98378993, 98113891, |
41 | 97849503, 97585828, 97322863, 97060606, 96799057, 96538212, 96278070, 96018629, 95759887, 95501842, 95244493, | 41 | 97849503, 97585828, 97322863, 97060606, 96799057, 96538212, 96278070, 96018629, 95759887, 95501842, 95244493, |
42 | 94987837, 94731873, 94476599, 94222012, 93968112, 93714895, 93462361, 93210508, 92959333, 92708835, 92459012, | 42 | 94987837, 94731873, 94476599, 94222012, 93968112, 93714895, 93462361, 93210508, 92959333, 92708835, 92459012, |
43 | 92209863, 91961384, 91713575, 91466434, 91219959, 90974149, 90729000, 90484512, 90240683, 89997511, 89754994, | 43 | 92209863, 91961384, 91713575, 91466434, 91219959, 90974149, 90729000, 90484512, 90240683, 89997511, 89754994, |
44 | 89513131, 89271920, 89031358, 88791445, 88552178, 88313556, 88075578, 87838240, 87601542, 87365481, 87130057, | 44 | 89513131, 89271920, 89031358, 88791445, 88552178, 88313556, 88075578, 87838240, 87601542, 87365481, 87130057, |
45 | 86895267, 86661110, 86427584, 86194687, 85962418, 85730775, 85499756, 85269359, 85039583, 84810427, 84581888, | 45 | 86895267, 86661110, 86427584, 86194687, 85962418, 85730775, 85499756, 85269359, 85039583, 84810427, 84581888, |
46 | 84353965, 84126656, 83899959, 83673874, 83448397, 83223528, 82999266, 82775607, 82552551, 82330096, 82108241, | 46 | 84353965, 84126656, 83899959, 83673874, 83448397, 83223528, 82999266, 82775607, 82552551, 82330096, 82108241, |
47 | 81886984, 81666322, 81446256, 81226782, 81007900, 80789608, 80571904, 80354786, 80138254, 79922305, 79706938, | 47 | 81886984, 81666322, 81446256, 81226782, 81007900, 80789608, 80571904, 80354786, 80138254, 79922305, 79706938, |
48 | 79492151, 79277943, 79064313, 78851258, 78638777, 78426868, 78215531, 78004763, 77794564, 77584930, 77375862, | 48 | 79492151, 79277943, 79064313, 78851258, 78638777, 78426868, 78215531, 78004763, 77794564, 77584930, 77375862, |
49 | 77167357, 76959413, 76752031, 76545207, 76338940, 76133229, 75928072, 75723469, 75519416, 75315914, 75112960, | 49 | 77167357, 76959413, 76752031, 76545207, 76338940, 76133229, 75928072, 75723469, 75519416, 75315914, 75112960, |
50 | 74910552, 74708690, 74507373, 74306597, 74106363, 73906668, 73707512, 73508892, 73310807, 73113256, 72916237, | 50 | 74910552, 74708690, 74507373, 74306597, 74106363, 73906668, 73707512, 73508892, 73310807, 73113256, 72916237, |
51 | 72719749, 72523791, 72328361, 72133457, 71939079, 71745225, 71551892, 71359081, 71166789, 70975016, 70783759, | 51 | 72719749, 72523791, 72328361, 72133457, 71939079, 71745225, 71551892, 71359081, 71166789, 70975016, 70783759, |
52 | 70593018, 70402791, 70213076, 70023872, 69835179, 69646994, 69459315, 69272143, 69085475, 68899310, 68713647, | 52 | 70593018, 70402791, 70213076, 70023872, 69835179, 69646994, 69459315, 69272143, 69085475, 68899310, 68713647, |
53 | 68528484, 68343820, 68159653, 67975983, 67792808, 67610127, 67427937, 67246239, 67065030, 66884310, 66704076, | 53 | 68528484, 68343820, 68159653, 67975983, 67792808, 67610127, 67427937, 67246239, 67065030, 66884310, 66704076, |
54 | 66524328, 66345065, 66166285, 65987986, 65810168, 65632829, 65455968, 65279583, 65103674, 64928239, 64753277, | 54 | 66524328, 66345065, 66166285, 65987986, 65810168, 65632829, 65455968, 65279583, 65103674, 64928239, 64753277, |
55 | 64578786, 64404765, 64231213, 64058129, 63885511, 63713359, 63541670, 63370444, 63199679, 63029375, 62859529, | 55 | 64578786, 64404765, 64231213, 64058129, 63885511, 63713359, 63541670, 63370444, 63199679, 63029375, 62859529, |
56 | 62690141, 62521210, 62352734, 62184711, 62017142, 61850024, 61683357, 61517138, 61351368, 61186044, 61021166, | 56 | 62690141, 62521210, 62352734, 62184711, 62017142, 61850024, 61683357, 61517138, 61351368, 61186044, 61021166, |
57 | 60856731, 60692741, 60529192, 60366083, 60203414, 60041184, 59879391, 59718034, 59557111, 59396622, 59236566, | 57 | 60856731, 60692741, 60529192, 60366083, 60203414, 60041184, 59879391, 59718034, 59557111, 59396622, 59236566, |
58 | 59076941, 58917746, 58758980, 58600642, 58442730, 58285245, 58128183, 57971545, 57815329, 57659533, 57504158, | 58 | 59076941, 58917746, 58758980, 58600642, 58442730, 58285245, 58128183, 57971545, 57815329, 57659533, 57504158, |
59 | 57349201, 57194662, 57040539, 56886832, 56733539, 56580659, 56428190, 56276133, 56124486, 55973247, 55822415, | 59 | 57349201, 57194662, 57040539, 56886832, 56733539, 56580659, 56428190, 56276133, 56124486, 55973247, 55822415, |
60 | 55671990, 55521971, 55372355, 55223143, 55074333, 54925924, 54777915, 54630305, 54483092, 54336276, 54189856, | 60 | 55671990, 55521971, 55372355, 55223143, 55074333, 54925924, 54777915, 54630305, 54483092, 54336276, 54189856, |
61 | 54043830, 53898198, 53752959, 53608110, 53463652, 53319583, 53175903, 53032610, 52889702, 52747180, 52605042, | 61 | 54043830, 53898198, 53752959, 53608110, 53463652, 53319583, 53175903, 53032610, 52889702, 52747180, 52605042, |
62 | 52463287, 52321914, 52180922, 52040310, 51900076, 51760221, 51620743, 51481640, 51342912, 51204558, 51066577, | 62 | 52463287, 52321914, 52180922, 52040310, 51900076, 51760221, 51620743, 51481640, 51342912, 51204558, 51066577, |
63 | 50928968, 50791729, 50654860, 50518360, 50382228, 50246463, 50111064, 49976029, 49841359, 49707051, 49573105, | 63 | 50928968, 50791729, 50654860, 50518360, 50382228, 50246463, 50111064, 49976029, 49841359, 49707051, 49573105, |
64 | 49439520, 49306295, 49173429, 49040922, 48908771, 48776976, 48645537, 48514451, 48383719, 48253339, 48123311, | 64 | 49439520, 49306295, 49173429, 49040922, 48908771, 48776976, 48645537, 48514451, 48383719, 48253339, 48123311, |
65 | 47993633, 47864304, 47735324, 47606691, 47478405, 47350465, 47222869, 47095618, 46968709, 46842142, 46715916, | 65 | 47993633, 47864304, 47735324, 47606691, 47478405, 47350465, 47222869, 47095618, 46968709, 46842142, 46715916, |
66 | 46590031, 46464484, 46339276, 46214406, 46089871, 45965673, 45841809, 45718279, 45595082, 45472216, 45349682, | 66 | 46590031, 46464484, 46339276, 46214406, 46089871, 45965673, 45841809, 45718279, 45595082, 45472216, 45349682, |
67 | 45227478, 45105603, 44984057, 44862838, 44741946, 44621380, 44501139, 44381221, 44261627, 44142355, 44023404, | 67 | 45227478, 45105603, 44984057, 44862838, 44741946, 44621380, 44501139, 44381221, 44261627, 44142355, 44023404, |
68 | 43904774, 43786464, 43668472, 43550798, 43433442, 43316402, 43199677, 43083266, 42967170, 42851386, 42735914, | 68 | 43904774, 43786464, 43668472, 43550798, 43433442, 43316402, 43199677, 43083266, 42967170, 42851386, 42735914, |
69 | 42620753, 42505903, 42391362, 42277130, 42163206, 42049588, 41936277, 41823271, 41710570, 41598172, 41486077, | 69 | 42620753, 42505903, 42391362, 42277130, 42163206, 42049588, 41936277, 41823271, 41710570, 41598172, 41486077, |
70 | 41374285, 41262793, 41151602, 41040711, 40930118, 40819823, 40709826, 40600125, 40490720, 40381609, 40272793, | 70 | 41374285, 41262793, 41151602, 41040711, 40930118, 40819823, 40709826, 40600125, 40490720, 40381609, 40272793, |
71 | 40164269, 40056039, 39948099, 39840451, 39733093, 39626024, 39519243, 39412751, 39306545, 39200625, 39094991, | 71 | 40164269, 40056039, 39948099, 39840451, 39733093, 39626024, 39519243, 39412751, 39306545, 39200625, 39094991, |
72 | 38989642, 38884576, 38779794, 38675294, 38571075, 38467138, 38363480, 38260102, 38157002, 38054180, 37951635, | 72 | 38989642, 38884576, 38779794, 38675294, 38571075, 38467138, 38363480, 38260102, 38157002, 38054180, 37951635, |
73 | 37849367, 37747374, 37645656, 37544212, 37443042, 37342144, 37241518, 37141163, 37041078, 36941264, 36841718, | 73 | 37849367, 37747374, 37645656, 37544212, 37443042, 37342144, 37241518, 37141163, 37041078, 36941264, 36841718, |
74 | 36742440, 36643430, 36544687, 36446210, 36347998, 36250051, 36152368, 36054948, 35957790, 35860895, 35764260, | 74 | 36742440, 36643430, 36544687, 36446210, 36347998, 36250051, 36152368, 36054948, 35957790, 35860895, 35764260, |
75 | 35667886, 35571772, 35475916, 35380319, 35284980, 35189897, 35095071, 35000500, 34906184, 34812122, 34718314, | 75 | 35667886, 35571772, 35475916, 35380319, 35284980, 35189897, 35095071, 35000500, 34906184, 34812122, 34718314, |
76 | 34624758, 34531454, 34438402, 34345601, 34253050, 34160748, 34068695, 33976890, 33885332, 33794021, 33702956, | 76 | 34624758, 34531454, 34438402, 34345601, 34253050, 34160748, 34068695, 33976890, 33885332, 33794021, 33702956, |
77 | 33612137, 33521562, 33431231, 33341144, 33251299, 33161697, 33072336, 32983216, 32894336, 32805695, 32717294, | 77 | 33612137, 33521562, 33431231, 33341144, 33251299, 33161697, 33072336, 32983216, 32894336, 32805695, 32717294, |
78 | 32629130, 32541204, 32453515, 32366063, 32278846, 32191864, 32105116, 32018602, 31932322, 31846273, 31760457, | 78 | 32629130, 32541204, 32453515, 32366063, 32278846, 32191864, 32105116, 32018602, 31932322, 31846273, 31760457, |
79 | 31674872, 31589518, 31504393, 31419498, 31334832, 31250394, 31166183, 31082200, 30998442, 30914911, 30831604, | 79 | 31674872, 31589518, 31504393, 31419498, 31334832, 31250394, 31166183, 31082200, 30998442, 30914911, 30831604, |
80 | 30748522, 30665664, 30583029, 30500617, 30418426, 30336458, 30254710, 30173183, 30091875, 30010786, 29929916, | 80 | 30748522, 30665664, 30583029, 30500617, 30418426, 30336458, 30254710, 30173183, 30091875, 30010786, 29929916, |
81 | 29849263, 29768829, 29688610, 29608608, 29528822, 29449250, 29369893, 29290750, 29211820, 29133103, 29054598, | 81 | 29849263, 29768829, 29688610, 29608608, 29528822, 29449250, 29369893, 29290750, 29211820, 29133103, 29054598, |
82 | 28976304, 28898222, 28820350, 28742687, 28665234, 28587990, 28510954, 28434125, 28357503, 28281088, 28204879, | 82 | 28976304, 28898222, 28820350, 28742687, 28665234, 28587990, 28510954, 28434125, 28357503, 28281088, 28204879, |
83 | 28128875, 28053076, 27977482, 27902091, 27826903, 27751917, 27677134, 27602552, 27528172, 27453991, 27380011, | 83 | 28128875, 28053076, 27977482, 27902091, 27826903, 27751917, 27677134, 27602552, 27528172, 27453991, 27380011, |
84 | 27306230, 27232648, 27159264, 27086078, 27013089, 26940296, 26867700, 26795300, 26723094, 26651083, 26579267, | 84 | 27306230, 27232648, 27159264, 27086078, 27013089, 26940296, 26867700, 26795300, 26723094, 26651083, 26579267, |
85 | 26507643, 26436213, 26364975, 26293929, 26223075, 26152412, 26081939, 26011656, 25941562, 25871657, 25801940, | 85 | 26507643, 26436213, 26364975, 26293929, 26223075, 26152412, 26081939, 26011656, 25941562, 25871657, 25801940, |
86 | 25732412, 25663071, 25593916, 25524948, 25456166, 25387569, 25319157, 25250929, 25182886, 25115025, 25047348, | 86 | 25732412, 25663071, 25593916, 25524948, 25456166, 25387569, 25319157, 25250929, 25182886, 25115025, 25047348, |
87 | 24979852, 24912539, 24845407, 24778456, 24711686, 24645095, 24578684, 24512451, 24446397, 24380522, 24314823, | 87 | 24979852, 24912539, 24845407, 24778456, 24711686, 24645095, 24578684, 24512451, 24446397, 24380522, 24314823, |
88 | 24249302, 24183957, 24118789, 24053796, 23988978, 23924335, 23859866, 23795570, 23731448, 23667499, 23603722, | 88 | 24249302, 24183957, 24118789, 24053796, 23988978, 23924335, 23859866, 23795570, 23731448, 23667499, 23603722, |
89 | 23540117, 23476683, 23413421, 23350328, 23287406, 23224653, 23162070, 23099655, 23037408, 22975329, 22913417, | 89 | 23540117, 23476683, 23413421, 23350328, 23287406, 23224653, 23162070, 23099655, 23037408, 22975329, 22913417, |
90 | 22851673, 22790094, 22728681, 22667434, 22606352, 22545435, 22484682, 22424092, 22363666, 22303402, 22243301, | 90 | 22851673, 22790094, 22728681, 22667434, 22606352, 22545435, 22484682, 22424092, 22363666, 22303402, 22243301, |
91 | 22183362, 22123584, 22063968, 22004512, 21945216, 21886080, 21827104, 21768286, 21709627, 21651126, 21592783, | 91 | 22183362, 22123584, 22063968, 22004512, 21945216, 21886080, 21827104, 21768286, 21709627, 21651126, 21592783, |
92 | 21534597, 21476567, 21418694, 21360977, 21303416, 21246009, 21188758, 21131660, 21074717, 21017926, 20961289, | 92 | 21534597, 21476567, 21418694, 21360977, 21303416, 21246009, 21188758, 21131660, 21074717, 21017926, 20961289, |
93 | 20904805, 20848473, 20792292, 20736263, 20680385, 20624657, 20569080, 20513652, 20458374, 20403245, 20348264, | 93 | 20904805, 20848473, 20792292, 20736263, 20680385, 20624657, 20569080, 20513652, 20458374, 20403245, 20348264, |
94 | 20293432, 20238747, 20184209, 20129819, 20075575, 20021477, 19967525, 19913719, 19860057, 19806540, 19753167, | 94 | 20293432, 20238747, 20184209, 20129819, 20075575, 20021477, 19967525, 19913719, 19860057, 19806540, 19753167, |
95 | 19699938, 19646853, 19593910, 19541111, 19488453, 19435937, 19383563, 19331330, 19279238, 19227286, 19175474, | 95 | 19699938, 19646853, 19593910, 19541111, 19488453, 19435937, 19383563, 19331330, 19279238, 19227286, 19175474, |
96 | 19123802, 19072269, 19020875, 18969619, 18918502, 18867522, 18816680, 18765974, 18715405, 18664973, 18614676, | 96 | 19123802, 19072269, 19020875, 18969619, 18918502, 18867522, 18816680, 18765974, 18715405, 18664973, 18614676, |
97 | 18564515, 18514489, 18464598, 18414842, 18365219, 18315730, 18266375, 18217152, 18168062, 18119105, 18070279, | 97 | 18564515, 18514489, 18464598, 18414842, 18365219, 18315730, 18266375, 18217152, 18168062, 18119105, 18070279, |
98 | 18021585, 17973022, 17924590, 17876289, 17828118, 17780076, 17732164, 17684381, 17636727, 17589201, 17541803, | 98 | 18021585, 17973022, 17924590, 17876289, 17828118, 17780076, 17732164, 17684381, 17636727, 17589201, 17541803, |
99 | 17494533, 17447391, 17400375, 17353486, 17306724, 17260087, 17213577, 17167191, 17120930, 17074795, 17028783, | 99 | 17494533, 17447391, 17400375, 17353486, 17306724, 17260087, 17213577, 17167191, 17120930, 17074795, 17028783, |
100 | 16982896, 16937132, 16891491, 16845974, 16800579, 16755306, 16710155, 16665126, 16620219, 16575432, 16530766, | 100 | 16982896, 16937132, 16891491, 16845974, 16800579, 16755306, 16710155, 16665126, 16620219, 16575432, 16530766, |
101 | 16486221, 16441795, 16397490, 16353303, 16309236, 16265287, 16221457, 16177745, 16134151, 16090674, 16047314, | 101 | 16486221, 16441795, 16397490, 16353303, 16309236, 16265287, 16221457, 16177745, 16134151, 16090674, 16047314, |
102 | 16004072, 15960945, 15917935, 15875041, 15832263, 15789599, 15747051, 15704617, 15662298, 15620093, 15578001, | 102 | 16004072, 15960945, 15917935, 15875041, 15832263, 15789599, 15747051, 15704617, 15662298, 15620093, 15578001, |
103 | 15536023, 15494158, 15452406, 15410766, 15369239, 15327823, 15286519, 15245327, 15204245, 15163274, 15122414, | 103 | 15536023, 15494158, 15452406, 15410766, 15369239, 15327823, 15286519, 15245327, 15204245, 15163274, 15122414, |
104 | 15081663, 15041023, 15000491, 14960070, 14919757, 14879552, 14839456, 14799468, 14759588, 14719815, 14680150, | 104 | 15081663, 15041023, 15000491, 14960070, 14919757, 14879552, 14839456, 14799468, 14759588, 14719815, 14680150, |
105 | 14640591, 14601139, 14561793, 14522554, 14483420, 14444391, 14405468, 14366649, 14327935, 14289326, 14250820, | 105 | 14640591, 14601139, 14561793, 14522554, 14483420, 14444391, 14405468, 14366649, 14327935, 14289326, 14250820, |
106 | 14212418, 14174120, 14135925, 14097833, 14059843, 14021956, 13984171, 13946488, 13908906, 13871426, 13834047, | 106 | 14212418, 14174120, 14135925, 14097833, 14059843, 14021956, 13984171, 13946488, 13908906, 13871426, 13834047, |
107 | 13796768, 13759590, 13722512, 13685534, 13648655, 13611876, 13575196, 13538615, 13502132, 13465748, 13429462, | 107 | 13796768, 13759590, 13722512, 13685534, 13648655, 13611876, 13575196, 13538615, 13502132, 13465748, 13429462, |
108 | 13393273, 13357183, 13321189, 13285292, 13249492, 13213789, 13178182, 13142670, 13107255, 13071934, 13036709, | 108 | 13393273, 13357183, 13321189, 13285292, 13249492, 13213789, 13178182, 13142670, 13107255, 13071934, 13036709, |
109 | 13001579, 12966544, 12931603, 12896756, 12862003, 12827344, 12792778, 12758305, 12723925, 12689638, 12655443, | 109 | 13001579, 12966544, 12931603, 12896756, 12862003, 12827344, 12792778, 12758305, 12723925, 12689638, 12655443, |
110 | 12621341, 12587330, 12553411, 12519583, 12485846, 12452201, 12418646, 12385181, 12351807, 12318522, 12285327, | 110 | 12621341, 12587330, 12553411, 12519583, 12485846, 12452201, 12418646, 12385181, 12351807, 12318522, 12285327, |
111 | 12252222, 12219206, 12186279, 12153440, 12120690, 12088029, 12055455, 12022969, 11990571, 11958260, 11926036, | 111 | 12252222, 12219206, 12186279, 12153440, 12120690, 12088029, 12055455, 12022969, 11990571, 11958260, 11926036, |
112 | 11893899, 11861848, 11829884, 11798006, 11766214, 11734507, 11702886, 11671350, 11639900, 11608533, 11577252, | 112 | 11893899, 11861848, 11829884, 11798006, 11766214, 11734507, 11702886, 11671350, 11639900, 11608533, 11577252, |
113 | 11546055, 11514941, 11483912, 11452966, 11422104, 11391325, 11360628, 11330015, 11299484, 11269035, 11238668, | 113 | 11546055, 11514941, 11483912, 11452966, 11422104, 11391325, 11360628, 11330015, 11299484, 11269035, 11238668, |
114 | 11208384, 11178180, 11148058, 11118018, 11088058, 11058179, 11028380, 10998662, 10969024, 10939466, 10909987, | 114 | 11208384, 11178180, 11148058, 11118018, 11088058, 11058179, 11028380, 10998662, 10969024, 10939466, 10909987, |
115 | 10880588, 10851268, 10822027, 10792865, 10763781, 10734776, 10705849, 10677000, 10648228, 10619535, 10590918, | 115 | 10880588, 10851268, 10822027, 10792865, 10763781, 10734776, 10705849, 10677000, 10648228, 10619535, 10590918, |
116 | 10562379, 10533916, 10505530, 10477221, 10448988, 10420831, 10392750, 10364745, 10336815, 10308960, 10281180, | 116 | 10562379, 10533916, 10505530, 10477221, 10448988, 10420831, 10392750, 10364745, 10336815, 10308960, 10281180, |
117 | 10253476, 10225846, 10198290, 10170809, 10143401, 10116068, 10088808, 10061622, 10034509, 10007468, 9980501, | 117 | 10253476, 10225846, 10198290, 10170809, 10143401, 10116068, 10088808, 10061622, 10034509, 10007468, 9980501, |
118 | 9953607, 9926785, 9900035, 9873357, 9846752, 9820217, 9793755, 9767364, 9741043, 9714794, 9688616, | 118 | 9953607, 9926785, 9900035, 9873357, 9846752, 9820217, 9793755, 9767364, 9741043, 9714794, 9688616, |
119 | 9662508, 9636470, 9610503, 9584605, 9558778, 9533019, 9507331, 9481711, 9456161, 9430679, 9405266, | 119 | 9662508, 9636470, 9610503, 9584605, 9558778, 9533019, 9507331, 9481711, 9456161, 9430679, 9405266, |
120 | 9379922, 9354646, 9329438, 9304298, 9279225, 9254221, 9229283, 9204413, 9179610, 9154874, 9130204, | 120 | 9379922, 9354646, 9329438, 9304298, 9279225, 9254221, 9229283, 9204413, 9179610, 9154874, 9130204, |
121 | 9105601, 9081064, 9056593, 9032188, 9007849, 8983576, 8959368, 8935225, 8911147, 8887134, 8863186, | 121 | 9105601, 9081064, 9056593, 9032188, 9007849, 8983576, 8959368, 8935225, 8911147, 8887134, 8863186, |
122 | 8839302, 8815483, 8791728, 8768037, 8744409, 8720846, 8697346, 8673909, 8650535, 8627225, 8603977, | 122 | 8839302, 8815483, 8791728, 8768037, 8744409, 8720846, 8697346, 8673909, 8650535, 8627225, 8603977, |
123 | 8580792, 8557669, 8534608, 8511610, 8488674, 8465799, 8442987, 8420235, 8397545, 8374916, 8352348, | 123 | 8580792, 8557669, 8534608, 8511610, 8488674, 8465799, 8442987, 8420235, 8397545, 8374916, 8352348, |
124 | 8329841, 8307395, 8285009, 8262683, 8240418, 8218212, 8196067, 8173981, 8151954, 8129987, 8108079, | 124 | 8329841, 8307395, 8285009, 8262683, 8240418, 8218212, 8196067, 8173981, 8151954, 8129987, 8108079, |
125 | 8086230, 8064440, 8042709, 8021036, 7999422, 7977866, 7956368, 7934928, 7913545, 7892221, 7870954, | 125 | 8086230, 8064440, 8042709, 8021036, 7999422, 7977866, 7956368, 7934928, 7913545, 7892221, 7870954, |
126 | 7849744, 7828591, 7807495, 7786456, 7765474, 7744548, 7723679, 7702866, 7682109, 7661408, 7640763, | 126 | 7849744, 7828591, 7807495, 7786456, 7765474, 7744548, 7723679, 7702866, 7682109, 7661408, 7640763, |
127 | 7620173, 7599639, 7579160, 7558737, 7538368, 7518055, 7497796, 7477591, 7457441, 7437346, 7417304, | 127 | 7620173, 7599639, 7579160, 7558737, 7538368, 7518055, 7497796, 7477591, 7457441, 7437346, 7417304, |
128 | 7397317, 7377383, 7357503, 7337677, 7317904, 7298185, 7278518, 7258905, 7239344, 7219836, 7200381, | 128 | 7397317, 7377383, 7357503, 7337677, 7317904, 7298185, 7278518, 7258905, 7239344, 7219836, 7200381, |
129 | 7180978, 7161627, 7142329, 7123082, 7103888, 7084745, 7065654, 7046614, 7027625, 7008688, 6989802, | 129 | 7180978, 7161627, 7142329, 7123082, 7103888, 7084745, 7065654, 7046614, 7027625, 7008688, 6989802, |
130 | 6970966, 6952181, 6933447, 6914764, 6896130, 6877547, 6859014, 6840531, 6822098, 6803715, 6785381, | 130 | 6970966, 6952181, 6933447, 6914764, 6896130, 6877547, 6859014, 6840531, 6822098, 6803715, 6785381, |
131 | 6767096, 6748861, 6730675, 6712537, 6694449, 6676410, 6658419, 6640476, 6622582, 6604736, 6586938, | 131 | 6767096, 6748861, 6730675, 6712537, 6694449, 6676410, 6658419, 6640476, 6622582, 6604736, 6586938, |
132 | 6569188, 6551486, 6533832, 6516225, 6498666, 6481154, 6463689, 6446272, 6428901, 6411577, 6394299, | 132 | 6569188, 6551486, 6533832, 6516225, 6498666, 6481154, 6463689, 6446272, 6428901, 6411577, 6394299, |
133 | 6377069, 6359884, 6342746, 6325655, 6308609, 6291609, 6274655, 6257747, 6240884, 6224066, 6207294, | 133 | 6377069, 6359884, 6342746, 6325655, 6308609, 6291609, 6274655, 6257747, 6240884, 6224066, 6207294, |
134 | 6190568, 6173886, 6157249, 6140657, 6124110, 6107607, 6091149, 6074735, 6058365, 6042040, 6025758, | 134 | 6190568, 6173886, 6157249, 6140657, 6124110, 6107607, 6091149, 6074735, 6058365, 6042040, 6025758, |
135 | 6009521, 5993327, 5977177, 5961070, 5945007, 5928987, 5913010, 5897076, 5881185, 5865337, 5849532, | 135 | 6009521, 5993327, 5977177, 5961070, 5945007, 5928987, 5913010, 5897076, 5881185, 5865337, 5849532, |
136 | 5833769, 5818049, 5802371, 5786735, 5771141, 5755590, 5740080, 5724612, 5709186, 5693802, 5678459, | 136 | 5833769, 5818049, 5802371, 5786735, 5771141, 5755590, 5740080, 5724612, 5709186, 5693802, 5678459, |
137 | 5663157, 5647896, 5632677, 5617498, 5602361, 5587264, 5572208, 5557193, 5542218, 5527283, 5512389, | 137 | 5663157, 5647896, 5632677, 5617498, 5602361, 5587264, 5572208, 5557193, 5542218, 5527283, 5512389, |
138 | 5497534, 5482720, 5467946, 5453211, 5438517, 5423861, 5409246, 5394669, 5380132, 5365635, 5351176, | 138 | 5497534, 5482720, 5467946, 5453211, 5438517, 5423861, 5409246, 5394669, 5380132, 5365635, 5351176, |
139 | 5336756, 5322375, 5308033, 5293729, 5279464, 5265237, 5251049, 5236899, 5222787, 5208713, 5194677, | 139 | 5336756, 5322375, 5308033, 5293729, 5279464, 5265237, 5251049, 5236899, 5222787, 5208713, 5194677, |
140 | 5180679, 5166719, 5152796, 5138911, 5125063, 5111252, 5097479, 5083743, 5070044, 5056382, 5042756, | 140 | 5180679, 5166719, 5152796, 5138911, 5125063, 5111252, 5097479, 5083743, 5070044, 5056382, 5042756, |
141 | 5029167, 5015615, 5002100, 4988620, 4975178, 4961771, 4948400, 4935066, 4921767, 4908505, 4895278, | 141 | 5029167, 5015615, 5002100, 4988620, 4975178, 4961771, 4948400, 4935066, 4921767, 4908505, 4895278, |
142 | 4882086, 4868931, 4855810, 4842725, 4829676, 4816661, 4803682, 4790737, 4777827, 4764953, 4752112, | 142 | 4882086, 4868931, 4855810, 4842725, 4829676, 4816661, 4803682, 4790737, 4777827, 4764953, 4752112, |
143 | 4739307, 4726536, 4713799, 4701097, 4688429, 4675795, 4663195, 4650629, 4638097, 4625599, 4613134, | 143 | 4739307, 4726536, 4713799, 4701097, 4688429, 4675795, 4663195, 4650629, 4638097, 4625599, 4613134, |
144 | 4600703, 4588306, 4575941, 4563611, 4551313, 4539049, 4526817, 4514619, 4502453, 4490320, 4478220, | 144 | 4600703, 4588306, 4575941, 4563611, 4551313, 4539049, 4526817, 4514619, 4502453, 4490320, 4478220, |
145 | 4466153, 4454118, 4442115, 4430145, 4418207, 4406301, 4394428, 4382586, 4370776, 4358998, 4347252, | 145 | 4466153, 4454118, 4442115, 4430145, 4418207, 4406301, 4394428, 4382586, 4370776, 4358998, 4347252, |
146 | 4335538, 4323855, 4312203, 4300583, 4288994, 4277437, 4265910, 4254415, 4242950, 4231517, 4220114, | 146 | 4335538, 4323855, 4312203, 4300583, 4288994, 4277437, 4265910, 4254415, 4242950, 4231517, 4220114, |
147 | 4208742, 4197401, 4186090, 4174810, 4163560, 4152340, 4141151, 4129992, 4118863, 4107764, 4096694, | 147 | 4208742, 4197401, 4186090, 4174810, 4163560, 4152340, 4141151, 4129992, 4118863, 4107764, 4096694, |
148 | 4085655, 4074645, 4063665, 4052715, 4041794, 4030903, 4020041, 4009208, 3998404, 3987630, 3976884, | 148 | 4085655, 4074645, 4063665, 4052715, 4041794, 4030903, 4020041, 4009208, 3998404, 3987630, 3976884, |
149 | 3966168, 3955480, 3944821, 3934191, 3923590, 3913017, 3902472, 3891956, 3881469, 3871009, 3860578, | 149 | 3966168, 3955480, 3944821, 3934191, 3923590, 3913017, 3902472, 3891956, 3881469, 3871009, 3860578, |
150 | 3850175, 3839800, 3829453, 3819133, 3808842, 3798578, 3788342, 3778134, 3767953, 3757799, 3747673, | 150 | 3850175, 3839800, 3829453, 3819133, 3808842, 3798578, 3788342, 3778134, 3767953, 3757799, 3747673, |
151 | 3737574, 3727503, 3717458, 3707441, 3697450, 3687487, 3677550, 3667640, 3657757, 3647900, 3638070, | 151 | 3737574, 3727503, 3717458, 3707441, 3697450, 3687487, 3677550, 3667640, 3657757, 3647900, 3638070, |
152 | 3628267, 3618490, 3608739, 3599014, 3589316, 3579644, 3569998, 3560378, 3550783, 3541215, 3531673, | 152 | 3628267, 3618490, 3608739, 3599014, 3589316, 3579644, 3569998, 3560378, 3550783, 3541215, 3531673, |
153 | 3522156, 3512665, 3503199, 3493759, 3484344, 3474955, 3465591, 3456252, 3446939, 3437650, 3428387, | 153 | 3522156, 3512665, 3503199, 3493759, 3484344, 3474955, 3465591, 3456252, 3446939, 3437650, 3428387, |
154 | 3419148, 3409935, 3400746, 3391582, 3382443, 3373328, 3364238, 3355172, 3346131, 3337114, 3328122, | 154 | 3419148, 3409935, 3400746, 3391582, 3382443, 3373328, 3364238, 3355172, 3346131, 3337114, 3328122, |
155 | 3319153, 3310209, 3301289, 3292393, 3283521, 3274673, 3265849, 3257048, 3248271, 3239518, 3230789, | 155 | 3319153, 3310209, 3301289, 3292393, 3283521, 3274673, 3265849, 3257048, 3248271, 3239518, 3230789, |
156 | 3222083, 3213400, 3204741, 3196105, 3187493, 3178903, 3170337, 3161794, 3153274, 3144777, 3136302, | 156 | 3222083, 3213400, 3204741, 3196105, 3187493, 3178903, 3170337, 3161794, 3153274, 3144777, 3136302, |
157 | 3127851, 3119422, 3111016, 3102633, 3094272, 3085934, 3077619, 3069325, 3061054, 3052806, 3044579, | 157 | 3127851, 3119422, 3111016, 3102633, 3094272, 3085934, 3077619, 3069325, 3061054, 3052806, 3044579, |
158 | 3036375, 3028193, 3020033, 3011895, 3003779, 2995684, 2987612, 2979561, 2971532, 2963525, 2955539, | 158 | 3036375, 3028193, 3020033, 3011895, 3003779, 2995684, 2987612, 2979561, 2971532, 2963525, 2955539, |
159 | 2947575, 2939632, 2931710, 2923810, 2915931, 2908074, 2900237, 2892422, 2884628, 2876855, 2869102, | 159 | 2947575, 2939632, 2931710, 2923810, 2915931, 2908074, 2900237, 2892422, 2884628, 2876855, 2869102, |
160 | 2861371, 2853660, 2845971, 2838302, 2830653, 2823025, 2815418, 2807832, 2800265, 2792719, 2785194, | 160 | 2861371, 2853660, 2845971, 2838302, 2830653, 2823025, 2815418, 2807832, 2800265, 2792719, 2785194, |
161 | 2777689, 2770203, 2762739, 2755294, 2747869, 2740464, 2733080, 2725715, 2718370, 2711045, 2703739, | 161 | 2777689, 2770203, 2762739, 2755294, 2747869, 2740464, 2733080, 2725715, 2718370, 2711045, 2703739, |
162 | 2696453, 2689187, 2681941, 2674714, 2667506, 2660318, 2653149, 2646000, 2638870, 2631759, 2624667, | 162 | 2696453, 2689187, 2681941, 2674714, 2667506, 2660318, 2653149, 2646000, 2638870, 2631759, 2624667, |
163 | 2617594, 2610540, 2603506, 2596490, 2589493, 2582515, 2575556, 2568616, 2561694, 2554791, 2547907, | 163 | 2617594, 2610540, 2603506, 2596490, 2589493, 2582515, 2575556, 2568616, 2561694, 2554791, 2547907, |
164 | 2541041, 2534194, 2527365, 2520554, 2513762, 2506988, 2500233, 2493495, 2486776, 2480075, 2473392, | 164 | 2541041, 2534194, 2527365, 2520554, 2513762, 2506988, 2500233, 2493495, 2486776, 2480075, 2473392, |
165 | 2466727, 2460080, 2453450, 2446839, 2440246, 2433670, 2427112, 2420571, 2414049, 2407544, 2401056, | 165 | 2466727, 2460080, 2453450, 2446839, 2440246, 2433670, 2427112, 2420571, 2414049, 2407544, 2401056, |
166 | 2394586, 2388133, 2381698, 2375280, 2368879, 2362496, 2356130, 2349780, 2343448, 2337134, 2330836, | 166 | 2394586, 2388133, 2381698, 2375280, 2368879, 2362496, 2356130, 2349780, 2343448, 2337134, 2330836, |
167 | 2324555, 2318291, 2312044, 2305813, 2299600, 2293403, 2287223, 2281060, 2274913, 2268783, 2262669, | 167 | 2324555, 2318291, 2312044, 2305813, 2299600, 2293403, 2287223, 2281060, 2274913, 2268783, 2262669, |
168 | 2256572, 2250491, 2244427, 2238379, 2232347, 2226331, 2220332, 2214349, 2208382, 2202431, 2196496, | 168 | 2256572, 2250491, 2244427, 2238379, 2232347, 2226331, 2220332, 2214349, 2208382, 2202431, 2196496, |
169 | 2190577, 2184674, 2178787, 2172916, 2167060, 2161221, 2155397, 2149589, 2143796, 2138019, 2132258, | 169 | 2190577, 2184674, 2178787, 2172916, 2167060, 2161221, 2155397, 2149589, 2143796, 2138019, 2132258, |
170 | 2126512, 2120782, 2115067, 2109368, 2103683, 2098015, 2092361, 2086723, 2081100, 2075492, 2069899, | 170 | 2126512, 2120782, 2115067, 2109368, 2103683, 2098015, 2092361, 2086723, 2081100, 2075492, 2069899, |
171 | 2064321, 2058758, 2053211, 2047678, 2042160, 2036657, 2031169, 2025695, 2020237, 2014793, 2009364, | 171 | 2064321, 2058758, 2053211, 2047678, 2042160, 2036657, 2031169, 2025695, 2020237, 2014793, 2009364, |
172 | 2003949, 1998549, 1993163, 1987792, 1982436, 1977094, 1971766, 1966453, 1961154, 1955869, 1950599, | 172 | 2003949, 1998549, 1993163, 1987792, 1982436, 1977094, 1971766, 1966453, 1961154, 1955869, 1950599, |
173 | 1945342, 1940100, 1934872, 1929658, 1924458, 1919272, 1914101, 1908943, 1903799, 1898668, 1893552, | 173 | 1945342, 1940100, 1934872, 1929658, 1924458, 1919272, 1914101, 1908943, 1903799, 1898668, 1893552, |
174 | 1888450, 1883361, 1878286, 1873224, 1868176, 1863142, 1858122, 1853115, 1848121, 1843141, 1838174, | 174 | 1888450, 1883361, 1878286, 1873224, 1868176, 1863142, 1858122, 1853115, 1848121, 1843141, 1838174, |
175 | 1833221, 1828281, 1823354, 1818441, 1813540, 1808654, 1803780, 1798919, 1794072, 1789237, 1784416, | 175 | 1833221, 1828281, 1823354, 1818441, 1813540, 1808654, 1803780, 1798919, 1794072, 1789237, 1784416, |
176 | 1779607, 1774812, 1770029, 1765259, 1760502, 1755758, 1751027, 1746309, 1741603, 1736910, 1732229, | 176 | 1779607, 1774812, 1770029, 1765259, 1760502, 1755758, 1751027, 1746309, 1741603, 1736910, 1732229, |
177 | 1727561, 1722906, 1718263, 1713633, 1709015, 1704410, 1699817, 1695237, 1690669, 1686113, 1681569, | 177 | 1727561, 1722906, 1718263, 1713633, 1709015, 1704410, 1699817, 1695237, 1690669, 1686113, 1681569, |
178 | 1677038, 1672519, 1668012, 1663517, 1659034, 1654564, 1650105, 1645659, 1641224, 1636801, 1632391, | 178 | 1677038, 1672519, 1668012, 1663517, 1659034, 1654564, 1650105, 1645659, 1641224, 1636801, 1632391, |
179 | 1627992, 1623605, 1619230, 1614866, 1610515, 1606175, 1601847, 1597530, 1593225, 1588932, 1584650, | 179 | 1627992, 1623605, 1619230, 1614866, 1610515, 1606175, 1601847, 1597530, 1593225, 1588932, 1584650, |
180 | 1580380, 1576122, 1571874, 1567639, 1563414, 1559201, 1555000, 1550810, 1546631, 1542463, 1538306, | 180 | 1580380, 1576122, 1571874, 1567639, 1563414, 1559201, 1555000, 1550810, 1546631, 1542463, 1538306, |
181 | 1534161, 1530027, 1525904, 1521792, 1517691, 1513602, 1509523, 1505455, 1501399, 1497353, 1493318, | 181 | 1534161, 1530027, 1525904, 1521792, 1517691, 1513602, 1509523, 1505455, 1501399, 1497353, 1493318, |
182 | 1489294, 1485281, 1481278, 1477287, 1473306, 1469336, 1465376, 1461427, 1457489, 1453562, 1449645, | 182 | 1489294, 1485281, 1481278, 1477287, 1473306, 1469336, 1465376, 1461427, 1457489, 1453562, 1449645, |
183 | 1445738, 1441843, 1437957, 1434082, 1430218, 1426364, 1422520, 1418687, 1414864, 1411051, 1407249, | 183 | 1445738, 1441843, 1437957, 1434082, 1430218, 1426364, 1422520, 1418687, 1414864, 1411051, 1407249, |
184 | 1403457, 1399675, 1395903, 1392142, 1388390, 1384649, 1380918, 1377197, 1373486, 1369784, 1366093, | 184 | 1403457, 1399675, 1395903, 1392142, 1388390, 1384649, 1380918, 1377197, 1373486, 1369784, 1366093, |
185 | 1362412, 1358741, 1355079, 1351428, 1347786, 1344154, 1340532, 1336920, 1333317, 1329724, 1326141, | 185 | 1362412, 1358741, 1355079, 1351428, 1347786, 1344154, 1340532, 1336920, 1333317, 1329724, 1326141, |
186 | 1322567, 1319004, 1315449, 1311904, 1308369, 1304844, 1301327, 1297821, 1294323, 1290836, 1287357, | 186 | 1322567, 1319004, 1315449, 1311904, 1308369, 1304844, 1301327, 1297821, 1294323, 1290836, 1287357, |
187 | 1283888, 1280429, 1276978, 1273537, 1270105, 1266683, 1263269, 1259865, 1256470, 1253084, 1249708, | 187 | 1283888, 1280429, 1276978, 1273537, 1270105, 1266683, 1263269, 1259865, 1256470, 1253084, 1249708, |
188 | 1246340, 1242982, 1239632, 1236292, 1232960, 1229638, 1226324, 1223020, 1219724, 1216437, 1213159, | 188 | 1246340, 1242982, 1239632, 1236292, 1232960, 1229638, 1226324, 1223020, 1219724, 1216437, 1213159, |
189 | 1209890, 1206630, 1203378, 1200136, 1196902, 1193676, 1190460, 1187252, 1184052, 1180862, 1177680, | 189 | 1209890, 1206630, 1203378, 1200136, 1196902, 1193676, 1190460, 1187252, 1184052, 1180862, 1177680, |
190 | 1174506, 1171341, 1168185, 1165037, 1161897, 1158767, 1155644, 1152530, 1149424, 1146327, 1143238, | 190 | 1174506, 1171341, 1168185, 1165037, 1161897, 1158767, 1155644, 1152530, 1149424, 1146327, 1143238, |
191 | 1140157, 1137085, 1134021, 1130965, 1127917, 1124878, 1121846, 1118823, 1115809, 1112802, 1109803, | 191 | 1140157, 1137085, 1134021, 1130965, 1127917, 1124878, 1121846, 1118823, 1115809, 1112802, 1109803, |
192 | 1106813, 1103830, 1100855, 1097889, 1094931, 1091980, 1089037, 1086103, 1083176, 1080257, 1077346, | 192 | 1106813, 1103830, 1100855, 1097889, 1094931, 1091980, 1089037, 1086103, 1083176, 1080257, 1077346, |
193 | 1074443, 1071548, 1068660, 1065781, 1062909, 1060044, 1057188, 1054339, 1051498, 1048664, 1045839, | 193 | 1074443, 1071548, 1068660, 1065781, 1062909, 1060044, 1057188, 1054339, 1051498, 1048664, 1045839, |
194 | 1043020, 1040210, 1037407, 1034611, 1031823, 1029043, 1026270, 1023504, 1020746, 1017996, 1015252, | 194 | 1043020, 1040210, 1037407, 1034611, 1031823, 1029043, 1026270, 1023504, 1020746, 1017996, 1015252, |
195 | 1012517, 1009788, 1007067, 1004353, 1001647, 998948, 996256, 993571, 990894, 988224, 985561, | 195 | 1012517, 1009788, 1007067, 1004353, 1001647, 998948, 996256, 993571, 990894, 988224, 985561, |
196 | 982905, 980256, 977615, 974980, 972353, 969733, 967120, 964514, 961915, 959323, 956737, | 196 | 982905, 980256, 977615, 974980, 972353, 969733, 967120, 964514, 961915, 959323, 956737, |
197 | 954159, 951588, 949024, 946467, 943916, 941373, 938836, 936306, 933783, 931267, 928757, | 197 | 954159, 951588, 949024, 946467, 943916, 941373, 938836, 936306, 933783, 931267, 928757, |
198 | 926254, 923758, 921269, 918787, 916311, 913842, 911379, 908923, 906474, 904031, 901595, | 198 | 926254, 923758, 921269, 918787, 916311, 913842, 911379, 908923, 906474, 904031, 901595, |
199 | 899166, 896743, 894326, 891916, 889513, 887116, 884725, 882341, 879963, 877592, 875227, | 199 | 899166, 896743, 894326, 891916, 889513, 887116, 884725, 882341, 879963, 877592, 875227, |
200 | 872869, 870517, 868171, 865831, 863498, 861171, 858851, 856536, 854228, 851926, 849631, | 200 | 872869, 870517, 868171, 865831, 863498, 861171, 858851, 856536, 854228, 851926, 849631, |
201 | 847341, 845058, 842781, 840510, 838245, 835986, 833733, 831487, 829246, 827011, 824783, | 201 | 847341, 845058, 842781, 840510, 838245, 835986, 833733, 831487, 829246, 827011, 824783, |
202 | 822560, 820344, 818133, 815929, 813730, 811537, 809350, 807169, 804994, 802825, 800662, | 202 | 822560, 820344, 818133, 815929, 813730, 811537, 809350, 807169, 804994, 802825, 800662, |
203 | 798504, 796352, 794206, 792066, 789932, 787803, 785680, 783563, 781452, 779346, 777246, | 203 | 798504, 796352, 794206, 792066, 789932, 787803, 785680, 783563, 781452, 779346, 777246, |
204 | 775151, 773062, 770979, 768902, 766830, 764763, 762703, 760647, 758598, 756553, 754515, | 204 | 775151, 773062, 770979, 768902, 766830, 764763, 762703, 760647, 758598, 756553, 754515, |
205 | 752482, 750454, 748432, 746415, 744403, 742397, 740397, 738402, 736412, 734428, 732448, | 205 | 752482, 750454, 748432, 746415, 744403, 742397, 740397, 738402, 736412, 734428, 732448, |
206 | 730475, 728506, 726543, 724585, 722633, 720686, 718744, 716807, 714875, 712949, 711028, | 206 | 730475, 728506, 726543, 724585, 722633, 720686, 718744, 716807, 714875, 712949, 711028, |
207 | 709112, 707201, 705295, 703394, 701499, 699609, 697723, 695843, 693968, 692098, 690233, | 207 | 709112, 707201, 705295, 703394, 701499, 699609, 697723, 695843, 693968, 692098, 690233, |
208 | 688373, 686518, 684668, 682823, 680983, 679148, 677318, 675493, 673673, 671857, 670047, | 208 | 688373, 686518, 684668, 682823, 680983, 679148, 677318, 675493, 673673, 671857, 670047, |
209 | 668241, 666441, 664645, 662854, 661067, 659286, 657510, 655738, 653971, 652208, 650451, | 209 | 668241, 666441, 664645, 662854, 661067, 659286, 657510, 655738, 653971, 652208, 650451, |
210 | 648698, 646950, 645207, 643468, 641734, 640005, 638280, 636560, 634845, 633134, 631428, | 210 | 648698, 646950, 645207, 643468, 641734, 640005, 638280, 636560, 634845, 633134, 631428, |
211 | 629727, 628030, 626337, 624650, 622966, 621288, 619613, 617944, 616279, 614618, 612962, | 211 | 629727, 628030, 626337, 624650, 622966, 621288, 619613, 617944, 616279, 614618, 612962, |
212 | 611310, 609663, 608020, 606381, 604747, 603118, 601492, 599872, 598255, 596643, 595035, | 212 | 611310, 609663, 608020, 606381, 604747, 603118, 601492, 599872, 598255, 596643, 595035, |
213 | 593432, 591833, 590238, 588647, 587061, 585479, 583901, 582328, 580759, 579194, 577633, | 213 | 593432, 591833, 590238, 588647, 587061, 585479, 583901, 582328, 580759, 579194, 577633, |
214 | 576076, 574524, 572976, 571432, 569892, 568356, 566825, 565297, 563774, 562255, 560740, | 214 | 576076, 574524, 572976, 571432, 569892, 568356, 566825, 565297, 563774, 562255, 560740, |
215 | 559229, 557722, 556219, 554720, 553225, 551734, 550248, 548765, 547286, 545811, 544341, | 215 | 559229, 557722, 556219, 554720, 553225, 551734, 550248, 548765, 547286, 545811, 544341, |
216 | 542874, 541411, 539952, 538497, 537046, 535599, 534155, 532716, 531280, 529849, 528421, | 216 | 542874, 541411, 539952, 538497, 537046, 535599, 534155, 532716, 531280, 529849, 528421, |
217 | 526997, 525577, 524161, 522748, 521340, 519935, 518534, 517136, 515743, 514353, 512967, | 217 | 526997, 525577, 524161, 522748, 521340, 519935, 518534, 517136, 515743, 514353, 512967, |
218 | 511585, 510206, 508831, 507460, 506093, 504729, 503369, 502012, 500660, 499310, 497965, | 218 | 511585, 510206, 508831, 507460, 506093, 504729, 503369, 502012, 500660, 499310, 497965, |
219 | 496623, 495285, 493950, 492619, 491292, 489968, 488648, 487331, 486018, 484708, 483402, | 219 | 496623, 495285, 493950, 492619, 491292, 489968, 488648, 487331, 486018, 484708, 483402, |
220 | 482099, 480800, 479504, 478212, 476924, 475638, 474357, 473078, 471804, 470532, 469264, | 220 | 482099, 480800, 479504, 478212, 476924, 475638, 474357, 473078, 471804, 470532, 469264, |
221 | 468000, 466739, 465481, 464227, 462976, 461728, 460484, 459243, 458005, 456771, 455540, | 221 | 468000, 466739, 465481, 464227, 462976, 461728, 460484, 459243, 458005, 456771, 455540, |
222 | 454313, 453089, 451868, 450650, 449436, 448225, 447017, 445812, 444611, 443413, 442218, | 222 | 454313, 453089, 451868, 450650, 449436, 448225, 447017, 445812, 444611, 443413, 442218, |
223 | 441026, 439838, 438653, 437470, 436292, 435116, 433943, 432774, 431608, 430445, 429285, | 223 | 441026, 439838, 438653, 437470, 436292, 435116, 433943, 432774, 431608, 430445, 429285, |
224 | 428128, 426974, 425824, 424676, 423532, 422391, 421252, 420117, 418985, 417856, 416730, | 224 | 428128, 426974, 425824, 424676, 423532, 422391, 421252, 420117, 418985, 417856, 416730, |
225 | 415607, 414487, 413370, 412256, 411146, 410038, 408933, 407831, 406732, 405636, 404543, | 225 | 415607, 414487, 413370, 412256, 411146, 410038, 408933, 407831, 406732, 405636, 404543, |
226 | 403453, 402365, 401281, 400200, 399121, 398046, 396973, 395903, 394837, 393773, 392712, | 226 | 403453, 402365, 401281, 400200, 399121, 398046, 396973, 395903, 394837, 393773, 392712, |
227 | 391653, 390598, 389545, 388496, 387449, 386405, 385363, 384325, 383289, 382257, 381226, | 227 | 391653, 390598, 389545, 388496, 387449, 386405, 385363, 384325, 383289, 382257, 381226, |
228 | 380199, 379175, 378153, 377134, 376118, 375104, 374093, 373085, 372080, 371077, 370077, | 228 | 380199, 379175, 378153, 377134, 376118, 375104, 374093, 373085, 372080, 371077, 370077, |
229 | 369080, 368085, 367094, 366104, 365118, 364134, 363153, 362174, 361198, 360225, 359254, | 229 | 369080, 368085, 367094, 366104, 365118, 364134, 363153, 362174, 361198, 360225, 359254, |
230 | 358286, 357321, 356358, 355397, 354440, 353485, 352532, 351582, 350635, 349690, 348748, | 230 | 358286, 357321, 356358, 355397, 354440, 353485, 352532, 351582, 350635, 349690, 348748, |
231 | 347808, 346871, 345936, 345004, 344074, 343147, 342222, 341300, 340380, 339463, 338548, | 231 | 347808, 346871, 345936, 345004, 344074, 343147, 342222, 341300, 340380, 339463, 338548, |
232 | 337636, 336726, 335819, 334914, 334011, 333111, 332214, 331318, 330426, 329535, 328647, | 232 | 337636, 336726, 335819, 334914, 334011, 333111, 332214, 331318, 330426, 329535, 328647, |
233 | 327762, 326878, 325997, 325119, 324243, 323369, 322498, 321629, 320762, 319898, 319036, | 233 | 327762, 326878, 325997, 325119, 324243, 323369, 322498, 321629, 320762, 319898, 319036, |
234 | 318176, 317319, 316463, 315611, 314760, 313912, 313066, 312222, 311381, 310542, 309705, | 234 | 318176, 317319, 316463, 315611, 314760, 313912, 313066, 312222, 311381, 310542, 309705, |
235 | 308871, 308038, 307208, 306380, 305555, 304731, 303910, 303091, 302275, 301460, 300648, | 235 | 308871, 308038, 307208, 306380, 305555, 304731, 303910, 303091, 302275, 301460, 300648, |
236 | 299838, 299030, 298224, 297420, 296619, 295819, 295022, 294227, 293434, 292644, 291855, | 236 | 299838, 299030, 298224, 297420, 296619, 295819, 295022, 294227, 293434, 292644, 291855, |
237 | 291069, 290284, 289502, 288722, 287944, 287168, 286394, 285622, 284853, 284085, 283320, | 237 | 291069, 290284, 289502, 288722, 287944, 287168, 286394, 285622, 284853, 284085, 283320, |
238 | 282556, 281795, 281035, 280278, 279523, 278770, 278018, 277269, 276522, 275777, 275034, | 238 | 282556, 281795, 281035, 280278, 279523, 278770, 278018, 277269, 276522, 275777, 275034, |
239 | 274293, 273553, 272816, 272081, 271348, 270617, 269888, 269160, 268435, 267712, 266990, | 239 | 274293, 273553, 272816, 272081, 271348, 270617, 269888, 269160, 268435, 267712, 266990, |
240 | 266271, 265553, 264838, 264124, 263412, 262702, 261994, 261289, 260584, 259882, 259182, | 240 | 266271, 265553, 264838, 264124, 263412, 262702, 261994, 261289, 260584, 259882, 259182, |
241 | 258483, 257787, 257092, 256399, 255709, 255020, 254332, 253647, 252963, 252282, 251602, | 241 | 258483, 257787, 257092, 256399, 255709, 255020, 254332, 253647, 252963, 252282, 251602, |
242 | 250924, 250248, 249573, 248901, 248230, 247561, 246894, 246229, 245565, 244904, 244244, | 242 | 250924, 250248, 249573, 248901, 248230, 247561, 246894, 246229, 245565, 244904, 244244, |
243 | 243586, 242929, 242275, 241622, 240971, 240321, 239674, 239028, 238384, 237741, 237101, | 243 | 243586, 242929, 242275, 241622, 240971, 240321, 239674, 239028, 238384, 237741, 237101, |
244 | 236462, 235825, 235189, 234555, 233923, 233293, 232664, 232037, 231412, 230788, 230166, | 244 | 236462, 235825, 235189, 234555, 233923, 233293, 232664, 232037, 231412, 230788, 230166, |
245 | 229546, 228928, 228311, 227696, 227082, 226470, 225860, 225251, 224644, 224039, 223435, | 245 | 229546, 228928, 228311, 227696, 227082, 226470, 225860, 225251, 224644, 224039, 223435, |
246 | 222833, 222233, 221634, 221036, 220441, 219847, 219254, 218664, 218074, 217487, 216901, | 246 | 222833, 222233, 221634, 221036, 220441, 219847, 219254, 218664, 218074, 217487, 216901, |
247 | 216316, 215733, 215152, 214572, 213994, 213417, 212842, 212269, 211697, 211126, 210557, | 247 | 216316, 215733, 215152, 214572, 213994, 213417, 212842, 212269, 211697, 211126, 210557, |
248 | 209990, 209424, 208860, 208297, 207735, 207176, 206617, 206061, 205505, 204952, 204399, | 248 | 209990, 209424, 208860, 208297, 207735, 207176, 206617, 206061, 205505, 204952, 204399, |
249 | 203849, 203299, 202751, 202205, 201660, 201117, 200575, 200034, 199495, 198958, 198422, | 249 | 203849, 203299, 202751, 202205, 201660, 201117, 200575, 200034, 199495, 198958, 198422, |
250 | 197887, 197354, 196822, 196291, 195762, 195235, 194709, 194184, 193661, 193139, 192619, | 250 | 197887, 197354, 196822, 196291, 195762, 195235, 194709, 194184, 193661, 193139, 192619, |
251 | 192100, 191582, 191066, 190551, 190037, 189525, 189014, 188505, 187997, 187491, 186985, | 251 | 192100, 191582, 191066, 190551, 190037, 189525, 189014, 188505, 187997, 187491, 186985, |
252 | 186481, 185979, 185478, 184978, 184479, 183982, 183487, 182992, 182499, 182007, 181517, | 252 | 186481, 185979, 185478, 184978, 184479, 183982, 183487, 182992, 182499, 182007, 181517, |
253 | 181028, 180540, 180053, 179568, 179084, 178602, 178120, 177640, 177162, 176684, 176208, | 253 | 181028, 180540, 180053, 179568, 179084, 178602, 178120, 177640, 177162, 176684, 176208, |
254 | 175733, 175260, 174788, 174317, 173847, 173378, 172911, 172445, 171981, 171517, 171055, | 254 | 175733, 175260, 174788, 174317, 173847, 173378, 172911, 172445, 171981, 171517, 171055, |
255 | 170594, 170134, 169676, 169219, 168763, 168308, 167854, 167402, 166951, 166501, 166052, | 255 | 170594, 170134, 169676, 169219, 168763, 168308, 167854, 167402, 166951, 166501, 166052, |
256 | 165605, 165159, 164713, 164270, 163827, 163386, 162945, 162506, 162068, 161632, 161196, | 256 | 165605, 165159, 164713, 164270, 163827, 163386, 162945, 162506, 162068, 161632, 161196, |
257 | 160762, 160328, 159896, 159465, 159036, 158607, 158180, 157754, 157328, 156904, 156482, | 257 | 160762, 160328, 159896, 159465, 159036, 158607, 158180, 157754, 157328, 156904, 156482, |
258 | 156060, 155639, 155220, 154802, 154385, 153969, 153554, 153140, 152727, 152316, 151905, | 258 | 156060, 155639, 155220, 154802, 154385, 153969, 153554, 153140, 152727, 152316, 151905, |
259 | 151496, 151088, 150681, 150275, 149870, 149466, 149063, 148661, 148261, 147861, 147463, | 259 | 151496, 151088, 150681, 150275, 149870, 149466, 149063, 148661, 148261, 147861, 147463, |
260 | 147065, 146669, 146274, 145880, 145487, 145094, 144703, 144314, 143925, 143537, 143150, | 260 | 147065, 146669, 146274, 145880, 145487, 145094, 144703, 144314, 143925, 143537, 143150, |
261 | 142764, 142380, 141996, 141613, 141232, 140851, 140472, 140093, 139715, 139339, 138964, | 261 | 142764, 142380, 141996, 141613, 141232, 140851, 140472, 140093, 139715, 139339, 138964, |
262 | 138589, 138216, 137843, 137472, 137101, 136732, 136363, 135996, 135629, 135264, 134899, | 262 | 138589, 138216, 137843, 137472, 137101, 136732, 136363, 135996, 135629, 135264, 134899, |
263 | 134536, 134173, 133812, 133451, 133092, 132733, 132375, 132019, 131663, 131308, 130954, | 263 | 134536, 134173, 133812, 133451, 133092, 132733, 132375, 132019, 131663, 131308, 130954, |
264 | 130601, 130249, 129898, 129548, 129199, 128851, 128504, 128158, 127812, 127468, 127124, | 264 | 130601, 130249, 129898, 129548, 129199, 128851, 128504, 128158, 127812, 127468, 127124, |
265 | 126782, 126440, 126099, 125760, 125421, 125083, 124746, 124410, 124074, 123740, 123407, | 265 | 126782, 126440, 126099, 125760, 125421, 125083, 124746, 124410, 124074, 123740, 123407, |
266 | 123074, 122742, 122412, 122082, 121753, 121425, 121097, 120771, 120446, 120121, 119797, | 266 | 123074, 122742, 122412, 122082, 121753, 121425, 121097, 120771, 120446, 120121, 119797, |
267 | 119475, 119153, 118832, 118511, 118192, 117873, 117556, 117239, 116923, 116608, 116294, | 267 | 119475, 119153, 118832, 118511, 118192, 117873, 117556, 117239, 116923, 116608, 116294, |
268 | 115980, 115668, 115356, 115045, 114735, 114426, 114118, 113810, 113504, 113198, 112893, | 268 | 115980, 115668, 115356, 115045, 114735, 114426, 114118, 113810, 113504, 113198, 112893, |
269 | 112589, 112285, 111983, 111681, 111380, 111080, 110780, 110482, 110184, 109887, 109591, | 269 | 112589, 112285, 111983, 111681, 111380, 111080, 110780, 110482, 110184, 109887, 109591, |
270 | 109296, 109001, 108708, 108415, 108122, 107831, 107541, 107251, 106962, 106674, 106386, | 270 | 109296, 109001, 108708, 108415, 108122, 107831, 107541, 107251, 106962, 106674, 106386, |
271 | 106099, 105813, 105528, 105244, 104960, 104678, 104395, 104114, 103834, 103554, 103275, | 271 | 106099, 105813, 105528, 105244, 104960, 104678, 104395, 104114, 103834, 103554, 103275, |
272 | 102996, 102719, 102442, 102166, 101891, 101616, 101342, 101069, 100797, 100525, 100254, | 272 | 102996, 102719, 102442, 102166, 101891, 101616, 101342, 101069, 100797, 100525, 100254, |
273 | 99984, 99715, 99446, 99178, 98911, 98644, 98378, 98113, 97849, 97585, 97322, | 273 | 99984, 99715, 99446, 99178, 98911, 98644, 98378, 98113, 97849, 97585, 97322, |
274 | 97060, 96799, 96538, 96278, 96018, 95759, 95501, 95244, 94987, 94731, 94476, | 274 | 97060, 96799, 96538, 96278, 96018, 95759, 95501, 95244, 94987, 94731, 94476, |
275 | 94222, 93968, 93714, 93462, 93210, 92959, 92708, 92459, 92209, 91961, 91713, | 275 | 94222, 93968, 93714, 93462, 93210, 92959, 92708, 92459, 92209, 91961, 91713, |
276 | 91466, 91219, 90974, 90729, 90484, 90240, 89997, 89754, 89513, 89271, 89031, | 276 | 91466, 91219, 90974, 90729, 90484, 90240, 89997, 89754, 89513, 89271, 89031, |
277 | 88791, 88552, 88313, 88075, 87838, 87601, 87365, 87130, 86895, 86661, 86427, | 277 | 88791, 88552, 88313, 88075, 87838, 87601, 87365, 87130, 86895, 86661, 86427, |
278 | 86194, 85962, 85730, 85499, 85269, 85039, 84810, 84581, 84353, 84126, 83899, | 278 | 86194, 85962, 85730, 85499, 85269, 85039, 84810, 84581, 84353, 84126, 83899, |
279 | 83673, 83448, 83223, 82999, 82775, 82552, 82330, 82108, 81886, 81666, 81446, | 279 | 83673, 83448, 83223, 82999, 82775, 82552, 82330, 82108, 81886, 81666, 81446, |
280 | 81226, 81007, 80789, 80571, 80354, 80138, 79922, 79706, 79492, 79277, 79064, | 280 | 81226, 81007, 80789, 80571, 80354, 80138, 79922, 79706, 79492, 79277, 79064, |
281 | 78851, 78638, 78426, 78215, 78004, 77794, 77584, 77375, 77167, 76959, 76752, | 281 | 78851, 78638, 78426, 78215, 78004, 77794, 77584, 77375, 77167, 76959, 76752, |
282 | 76545, 76338, 76133, 75928, 75723, 75519, 75315, 75112, 74910, 74708, 74507, | 282 | 76545, 76338, 76133, 75928, 75723, 75519, 75315, 75112, 74910, 74708, 74507, |
283 | 74306, 74106, 73906, 73707, 73508, 73310, 73113, 72916, 72719, 72523, 72328, | 283 | 74306, 74106, 73906, 73707, 73508, 73310, 73113, 72916, 72719, 72523, 72328, |
284 | 72133, 71939, 71745, 71551, 71359, 71166, 70975, 70783, 70593, 70402, 70213, | 284 | 72133, 71939, 71745, 71551, 71359, 71166, 70975, 70783, 70593, 70402, 70213, |
285 | 70023, 69835, 69646, 69459, 69272, 69085, 68899, 68713, 68528, 68343, 68159, | 285 | 70023, 69835, 69646, 69459, 69272, 69085, 68899, 68713, 68528, 68343, 68159, |
286 | 67975, 67792, 67610, 67427, 67246, 67065, 66884, 66704, 66524, 66345, 66166, | 286 | 67975, 67792, 67610, 67427, 67246, 67065, 66884, 66704, 66524, 66345, 66166, |
287 | 65987, 65810, 65632, 65455, 65279, 65103, 64928, 64753, 64578, 64404, 64231, | 287 | 65987, 65810, 65632, 65455, 65279, 65103, 64928, 64753, 64578, 64404, 64231, |
288 | 64058, 63885, 63713, 63541, 63370, 63199, 63029, 62859, 62690, 62521, 62352, | 288 | 64058, 63885, 63713, 63541, 63370, 63199, 63029, 62859, 62690, 62521, 62352, |
289 | 62184, 62017, 61850, 61683, 61517, 61351, 61186, 61021, 60856, 60692, 60529, | 289 | 62184, 62017, 61850, 61683, 61517, 61351, 61186, 61021, 60856, 60692, 60529, |
290 | 60366, 60203, 60041, 59879, 59718, 59557, 59396, 59236, 59076, 58917, 58758, | 290 | 60366, 60203, 60041, 59879, 59718, 59557, 59396, 59236, 59076, 58917, 58758, |
291 | 58600, 58442, 58285, 58128, 57971, 57815, 57659, 57504, 57349, 57194, 57040, | 291 | 58600, 58442, 58285, 58128, 57971, 57815, 57659, 57504, 57349, 57194, 57040, |
292 | 56886, 56733, 56580, 56428, 56276, 56124, 55973, 55822, 55671, 55521, 55372, | 292 | 56886, 56733, 56580, 56428, 56276, 56124, 55973, 55822, 55671, 55521, 55372, |
293 | 55223, 55074, 54925, 54777, 54630, 54483, 54336, 54189, 54043, 53898, 53752, | 293 | 55223, 55074, 54925, 54777, 54630, 54483, 54336, 54189, 54043, 53898, 53752, |
294 | 53608, 53463, 53319, 53175, 53032, 52889, 52747, 52605, 52463, 52321, 52180, | 294 | 53608, 53463, 53319, 53175, 53032, 52889, 52747, 52605, 52463, 52321, 52180, |
295 | 52040, 51900, 51760, 51620, 51481, 51342, 51204, 51066, 50928, 50791, 50654, | 295 | 52040, 51900, 51760, 51620, 51481, 51342, 51204, 51066, 50928, 50791, 50654, |
296 | 50518, 50382, 50246, 50111, 49976, 49841, 49707, 49573, 49439, 49306, 49173, | 296 | 50518, 50382, 50246, 50111, 49976, 49841, 49707, 49573, 49439, 49306, 49173, |
297 | 49040, 48908, 48776, 48645, 48514, 48383, 48253, 48123, 47993, 47864, 47735, | 297 | 49040, 48908, 48776, 48645, 48514, 48383, 48253, 48123, 47993, 47864, 47735, |
298 | 47606, 47478, 47350, 47222, 47095, 46968, 46842, 46715, 46590, 46464, 46339, | 298 | 47606, 47478, 47350, 47222, 47095, 46968, 46842, 46715, 46590, 46464, 46339, |
299 | 46214, 46089, 45965, 45841, 45718, 45595, 45472, 45349, 45227, 45105, 44984, | 299 | 46214, 46089, 45965, 45841, 45718, 45595, 45472, 45349, 45227, 45105, 44984, |
300 | 44862, 44741, 44621, 44501, 44381, 44261, 44142, 44023, 43904, 43786, 43668, | 300 | 44862, 44741, 44621, 44501, 44381, 44261, 44142, 44023, 43904, 43786, 43668, |
301 | 43550, 43433, 43316, 43199, 43083, 42967, 42851, 42735, 42620, 42505, 42391, | 301 | 43550, 43433, 43316, 43199, 43083, 42967, 42851, 42735, 42620, 42505, 42391, |
302 | 42277, 42163, 42049, 41936, 41823, 41710, 41598, 41486, 41374, 41262, 41151, | 302 | 42277, 42163, 42049, 41936, 41823, 41710, 41598, 41486, 41374, 41262, 41151, |
303 | 41040, 40930, 40819, 40709, 40600, 40490, 40381, 40272, 40164, 40056, 39948, | 303 | 41040, 40930, 40819, 40709, 40600, 40490, 40381, 40272, 40164, 40056, 39948, |
304 | 39840, 39733, 39626, 39519, 39412, 39306, 39200, 39094, 38989, 38884, 38779, | 304 | 39840, 39733, 39626, 39519, 39412, 39306, 39200, 39094, 38989, 38884, 38779, |
305 | 38675, 38571, 38467, 38363, 38260, 38157, 38054, 37951, 37849, 37747, 37645, | 305 | 38675, 38571, 38467, 38363, 38260, 38157, 38054, 37951, 37849, 37747, 37645, |
306 | 37544, 37443, 37342, 37241, 37141, 37041, 36941, 36841, 36742, 36643, 36544, | 306 | 37544, 37443, 37342, 37241, 37141, 37041, 36941, 36841, 36742, 36643, 36544, |
307 | 36446, 36347, 36250, 36152, 36054, 35957, 35860, 35764, 35667, 35571, 35475, | 307 | 36446, 36347, 36250, 36152, 36054, 35957, 35860, 35764, 35667, 35571, 35475, |
308 | 35380, 35284, 35189, 35095, 35000, 34906, 34812, 34718, 34624, 34531, 34438, | 308 | 35380, 35284, 35189, 35095, 35000, 34906, 34812, 34718, 34624, 34531, 34438, |
309 | 34345, 34253, 34160, 34068, 33976, 33885 | 309 | 34345, 34253, 34160, 34068, 33976, 33885 |
310 | }; | 310 | }; |
311 | 311 | ||
312 | static const short sindb_coeff[] = { | 312 | static const short sindb_coeff[] = { |
313 | 2401, 2144, 1994, 1887, 1804, 1737, 1680, 1630, 1587, 1548, 1512, 1480, 1450, | 313 | 2401, 2144, 1994, 1887, 1804, 1737, 1680, 1630, 1587, 1548, 1512, 1480, 1450, |
314 | 1423, 1397, 1373, 1351, 1330, 1310, 1291, 1273, 1255, 1239, 1223, 1208, 1194, | 314 | 1423, 1397, 1373, 1351, 1330, 1310, 1291, 1273, 1255, 1239, 1223, 1208, 1194, |
315 | 1180, 1166, 1153, 1141, 1128, 1117, 1105, 1094, 1084, 1073, 1063, 1053, 1043, | 315 | 1180, 1166, 1153, 1141, 1128, 1117, 1105, 1094, 1084, 1073, 1063, 1053, 1043, |
316 | 1034, 1025, 1016, 1007, 999, 990, 982, 974, 967, 959, 952, 944, 937, | 316 | 1034, 1025, 1016, 1007, 999, 990, 982, 974, 967, 959, 952, 944, 937, |
317 | 930, 923, 916, 910, 903, 897, 890, 884, 878, 872, 866, 860, 855, | 317 | 930, 923, 916, 910, 903, 897, 890, 884, 878, 872, 866, 860, 855, |
318 | 849, 843, 838, 832, 827, 822, 817, 812, 807, 802, 797, 792, 787, | 318 | 849, 843, 838, 832, 827, 822, 817, 812, 807, 802, 797, 792, 787, |
319 | 783, 778, 773, 769, 764, 760, 756, 751, 747, 743, 739, 734, 730, | 319 | 783, 778, 773, 769, 764, 760, 756, 751, 747, 743, 739, 734, 730, |
320 | 726, 722, 718, 715, 711, 707, 703, 699, 696, 692, 688, 685, 681, | 320 | 726, 722, 718, 715, 711, 707, 703, 699, 696, 692, 688, 685, 681, |
321 | 678, 674, 671, 667, 664, 661, 657, 654, 651, 648, 644, 641, 638, | 321 | 678, 674, 671, 667, 664, 661, 657, 654, 651, 648, 644, 641, 638, |
322 | 635, 632, 629, 626, 623, 620, 617, 614, 611, 608, 605, 602, 599, | 322 | 635, 632, 629, 626, 623, 620, 617, 614, 611, 608, 605, 602, 599, |
323 | 597, 594, 591, 588, 586, 583, 580, 578, 575, 572, 570, 567, 565, | 323 | 597, 594, 591, 588, 586, 583, 580, 578, 575, 572, 570, 567, 565, |
324 | 562, 560, 557, 555, 552, 550, 547, 545, 542, 540, 538, 535, 533, | 324 | 562, 560, 557, 555, 552, 550, 547, 545, 542, 540, 538, 535, 533, |
325 | 531, 528, 526, 524, 522, 519, 517, 515, 513, 510, 508, 506, 504, | 325 | 531, 528, 526, 524, 522, 519, 517, 515, 513, 510, 508, 506, 504, |
326 | 502, 500, 498, 495, 493, 491, 489, 487, 485, 483, 481, 479, 477, | 326 | 502, 500, 498, 495, 493, 491, 489, 487, 485, 483, 481, 479, 477, |
327 | 475, 473, 471, 469, 467, 465, 464, 462, 460, 458, 456, 454, 452, | 327 | 475, 473, 471, 469, 467, 465, 464, 462, 460, 458, 456, 454, 452, |
328 | 450, 449, 447, 445, 443, 441, 440, 438, 436, 434, 433, 431, 429, | 328 | 450, 449, 447, 445, 443, 441, 440, 438, 436, 434, 433, 431, 429, |
329 | 427, 426, 424, 422, 421, 419, 417, 416, 414, 412, 411, 409, 408, | 329 | 427, 426, 424, 422, 421, 419, 417, 416, 414, 412, 411, 409, 408, |
330 | 406, 404, 403, 401, 400, 398, 396, 395, 393, 392, 390, 389, 387, | 330 | 406, 404, 403, 401, 400, 398, 396, 395, 393, 392, 390, 389, 387, |
331 | 386, 384, 383, 381, 380, 378, 377, 375, 374, 372, 371, 370, 368, | 331 | 386, 384, 383, 381, 380, 378, 377, 375, 374, 372, 371, 370, 368, |
332 | 367, 365, 364, 362, 361, 360, 358, 357, 355, 354, 353, 351, 350, | 332 | 367, 365, 364, 362, 361, 360, 358, 357, 355, 354, 353, 351, 350, |
333 | 349, 347, 346, 345, 343, 342, 341, 339, 338, 337, 336, 334, 333, | 333 | 349, 347, 346, 345, 343, 342, 341, 339, 338, 337, 336, 334, 333, |
334 | 332, 330, 329, 328, 327, 325, 324, 323, 322, 320, 319, 318, 317, | 334 | 332, 330, 329, 328, 327, 325, 324, 323, 322, 320, 319, 318, 317, |
335 | 316, 314, 313, 312, 311, 310, 308, 307, 306, 305, 304, 303, 301, | 335 | 316, 314, 313, 312, 311, 310, 308, 307, 306, 305, 304, 303, 301, |
336 | 300, 299, 298, 297, 296, 295, 293, 292, 291, 290, 289, 288, 287, | 336 | 300, 299, 298, 297, 296, 295, 293, 292, 291, 290, 289, 288, 287, |
337 | 286, 285, 284, 282, 281, 280, 279, 278, 277, 276, 275, 274, 273, | 337 | 286, 285, 284, 282, 281, 280, 279, 278, 277, 276, 275, 274, 273, |
338 | 272, 271, 270, 269, 268, 267, 266, 265, 264, 263, 262, 261, 260, | 338 | 272, 271, 270, 269, 268, 267, 266, 265, 264, 263, 262, 261, 260, |
339 | 259, 258, 257, 256, 255, 254, 253, 252, 251, 250, 249, 248, 247, | 339 | 259, 258, 257, 256, 255, 254, 253, 252, 251, 250, 249, 248, 247, |
340 | 246, 245, 244, 243, 242, 241, 240, 240, 239, 238, 237, 236, 235, | 340 | 246, 245, 244, 243, 242, 241, 240, 240, 239, 238, 237, 236, 235, |
341 | 234, 233, 232, 231, 230, 230, 229, 228, 227, 226, 225, 224, 223, | 341 | 234, 233, 232, 231, 230, 230, 229, 228, 227, 226, 225, 224, 223, |
342 | 222, 222, 221, 220, 219, 218, 217, 216, 216, 215, 214, 213, 212, | 342 | 222, 222, 221, 220, 219, 218, 217, 216, 216, 215, 214, 213, 212, |
343 | 211, 211, 210, 209, 208, 207, 206, 206, 205, 204, 203, 202, 202, | 343 | 211, 211, 210, 209, 208, 207, 206, 206, 205, 204, 203, 202, 202, |
344 | 201, 200, 199, 198, 198, 197, 196, 195, 195, 194, 193, 192, 191, | 344 | 201, 200, 199, 198, 198, 197, 196, 195, 195, 194, 193, 192, 191, |
345 | 191, 190, 189, 188, 188, 187, 186, 185, 185, 184, 183, 182, 182, | 345 | 191, 190, 189, 188, 188, 187, 186, 185, 185, 184, 183, 182, 182, |
346 | 181, 180, 180, 179, 178, 177, 177, 176, 175, 174, 174, 173, 172, | 346 | 181, 180, 180, 179, 178, 177, 177, 176, 175, 174, 174, 173, 172, |
347 | 172, 171, 170, 170, 169, 168, 167, 167, 166, 165, 165, 164, 163, | 347 | 172, 171, 170, 170, 169, 168, 167, 167, 166, 165, 165, 164, 163, |
348 | 163, 162, 161, 161, 160, 159, 159, 158, 157, 157, 156, 155, 155, | 348 | 163, 162, 161, 161, 160, 159, 159, 158, 157, 157, 156, 155, 155, |
349 | 154, 153, 153, 152, 151, 151, 150, 150, 149, 148, 148, 147, 146, | 349 | 154, 153, 153, 152, 151, 151, 150, 150, 149, 148, 148, 147, 146, |
350 | 146, 145, 145, 144, 143, 143, 142, 141, 141, 140, 140, 139, 138, | 350 | 146, 145, 145, 144, 143, 143, 142, 141, 141, 140, 140, 139, 138, |
351 | 138, 137, 137, 136, 135, 135, 134, 134, 133, 133, 132, 131, 131, | 351 | 138, 137, 137, 136, 135, 135, 134, 134, 133, 133, 132, 131, 131, |
352 | 130, 130, 129, 129, 128, 127, 127, 126, 126, 125, 125, 124, 123, | 352 | 130, 130, 129, 129, 128, 127, 127, 126, 126, 125, 125, 124, 123, |
353 | 123, 122, 122, 121, 121, 120, 120, 119, 119, 118, 117, 117, 116, | 353 | 123, 122, 122, 121, 121, 120, 120, 119, 119, 118, 117, 117, 116, |
354 | 116, 115, 115, 114, 114, 113, 113, 112, 112, 111, 111, 110, 110, | 354 | 116, 115, 115, 114, 114, 113, 113, 112, 112, 111, 111, 110, 110, |
355 | 109, 109, 108, 108, 107, 107, 106, 106, 105, 105, 104, 104, 103, | 355 | 109, 109, 108, 108, 107, 107, 106, 106, 105, 105, 104, 104, 103, |
356 | 103, 102, 102, 101, 101, 100, 100, 99, 99, 98, 98, 97, 97, | 356 | 103, 102, 102, 101, 101, 100, 100, 99, 99, 98, 98, 97, 97, |
357 | 96, 96, 95, 95, 94, 94, 94, 93, 93, 92, 92, 91, 91, | 357 | 96, 96, 95, 95, 94, 94, 94, 93, 93, 92, 92, 91, 91, |
358 | 90, 90, 89, 89, 89, 88, 88, 87, 87, 86, 86, 85, 85, | 358 | 90, 90, 89, 89, 89, 88, 88, 87, 87, 86, 86, 85, 85, |
359 | 85, 84, 84, 83, 83, 82, 82, 82, 81, 81, 80, 80, 79, | 359 | 85, 84, 84, 83, 83, 82, 82, 82, 81, 81, 80, 80, 79, |
360 | 79, 79, 78, 78, 77, 77, 77, 76, 76, 75, 75, 75, 74, | 360 | 79, 79, 78, 78, 77, 77, 77, 76, 76, 75, 75, 75, 74, |
361 | 74, 73, 73, 73, 72, 72, 71, 71, 71, 70, 70, 69, 69, | 361 | 74, 73, 73, 73, 72, 72, 71, 71, 71, 70, 70, 69, 69, |
362 | 69, 68, 68, 68, 67, 67, 66, 66, 66, 65, 65, 65, 64, | 362 | 69, 68, 68, 68, 67, 67, 66, 66, 66, 65, 65, 65, 64, |
363 | 64, 63, 63, 63, 62, 62, 62, 61, 61, 61, 60, 60, 59, | 363 | 64, 63, 63, 63, 62, 62, 62, 61, 61, 61, 60, 60, 59, |
364 | 59, 59, 58, 58, 58, 57, 57, 57, 56, 56, 56, 55, 55, | 364 | 59, 59, 58, 58, 58, 57, 57, 57, 56, 56, 56, 55, 55, |
365 | 55, 54, 54, 54, 53, 53, 53, 52, 52, 52, 51, 51, 51, | 365 | 55, 54, 54, 54, 53, 53, 53, 52, 52, 52, 51, 51, 51, |
366 | 50, 50, 50, 49, 49, 49, 49, 48, 48, 48, 47, 47, 47, | 366 | 50, 50, 50, 49, 49, 49, 49, 48, 48, 48, 47, 47, 47, |
367 | 46, 46, 46, 45, 45, 45, 45, 44, 44, 44, 43, 43, 43, | 367 | 46, 46, 46, 45, 45, 45, 45, 44, 44, 44, 43, 43, 43, |
368 | 43, 42, 42, 42, 41, 41, 41, 40, 40, 40, 40, 39, 39, | 368 | 43, 42, 42, 42, 41, 41, 41, 40, 40, 40, 40, 39, 39, |
369 | 39, 39, 38, 38, 38, 37, 37, 37, 37, 36, 36, 36, 36, | 369 | 39, 39, 38, 38, 38, 37, 37, 37, 37, 36, 36, 36, 36, |
370 | 35, 35, 35, 35, 34, 34, 34, 34, 33, 33, 33, 32, 32, | 370 | 35, 35, 35, 35, 34, 34, 34, 34, 33, 33, 33, 32, 32, |
371 | 32, 32, 31, 31, 31, 31, 31, 30, 30, 30, 30, 29, 29, | 371 | 32, 32, 31, 31, 31, 31, 31, 30, 30, 30, 30, 29, 29, |
372 | 29, 29, 28, 28, 28, 28, 27, 27, 27, 27, 27, 26, 26, | 372 | 29, 29, 28, 28, 28, 28, 27, 27, 27, 27, 27, 26, 26, |
373 | 26, 26, 25, 25, 25, 25, 25, 24, 24, 24, 24, 23, 23, | 373 | 26, 26, 25, 25, 25, 25, 25, 24, 24, 24, 24, 23, 23, |
374 | 23, 23, 23, 22, 22, 22, 22, 22, 21, 21, 21, 21, 21, | 374 | 23, 23, 23, 22, 22, 22, 22, 22, 21, 21, 21, 21, 21, |
375 | 20, 20, 20, 20, 20, 19, 19, 19, 19, 19, 19, 18, 18, | 375 | 20, 20, 20, 20, 20, 19, 19, 19, 19, 19, 19, 18, 18, |
376 | 18, 18, 18, 17, 17, 17, 17, 17, 17, 16, 16, 16, 16, | 376 | 18, 18, 18, 17, 17, 17, 17, 17, 17, 16, 16, 16, 16, |
377 | 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, | 377 | 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, |
378 | 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, | 378 | 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, |
379 | 11, 11, 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, | 379 | 11, 11, 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, |
380 | 10, 10, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, | 380 | 10, 10, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, |
381 | 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, | 381 | 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, |
382 | 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, | 382 | 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, |
383 | 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, | 383 | 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, |
384 | 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, | 384 | 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, |
385 | 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, | 385 | 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, |
386 | 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, | 386 | 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, |
387 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | 387 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
388 | 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 388 | 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
389 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 389 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
390 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 390 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
391 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 | 391 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
392 | }; | 392 | }; |
393 | 393 | ||
394 | 394 | ||
395 | static const short lfo_freq_coeff[] = { | 395 | static const short lfo_freq_coeff[] = { |
396 | 0, 3, 6, 9, 12, 15, 18, 21, 25, 28, 31, 34, 37, | 396 | 0, 3, 6, 9, 12, 15, 18, 21, 25, 28, 31, 34, 37, |
397 | 40, 43, 46, 50, 53, 56, 59, 62, 65, 68, 71, 74, 78, | 397 | 40, 43, 46, 50, 53, 56, 59, 62, 65, 68, 71, 74, 78, |
398 | 81, 84, 87, 90, 93, 96, 99, 102, 105, 108, 111, 115, 118, | 398 | 81, 84, 87, 90, 93, 96, 99, 102, 105, 108, 111, 115, 118, |
399 | 121, 124, 127, 130, 133, 136, 139, 142, 145, 148, 151, 154, 157, | 399 | 121, 124, 127, 130, 133, 136, 139, 142, 145, 148, 151, 154, 157, |
400 | 160, 163, 166, 169, 172, 175, 178, 180, 183, 186, 189, 192, 195, | 400 | 160, 163, 166, 169, 172, 175, 178, 180, 183, 186, 189, 192, 195, |
401 | 198, 201, 204, 207, 209, 212, 215, 218, 221, 224, 226, 229, 232, | 401 | 198, 201, 204, 207, 209, 212, 215, 218, 221, 224, 226, 229, 232, |
402 | 235, 238, 240, 243, 246, 249, 251, 254, 257, 260, 262, 265, 268, | 402 | 235, 238, 240, 243, 246, 249, 251, 254, 257, 260, 262, 265, 268, |
403 | 270, 273, 276, 278, 281, 283, 286, 289, 291, 294, 296, 299, 301, | 403 | 270, 273, 276, 278, 281, 283, 286, 289, 291, 294, 296, 299, 301, |
404 | 304, 306, 309, 311, 314, 316, 319, 321, 324, 326, 328, 331, 333, | 404 | 304, 306, 309, 311, 314, 316, 319, 321, 324, 326, 328, 331, 333, |
405 | 336, 338, 340, 343, 345, 347, 350, 352, 354, 356, 359, 361, 363, | 405 | 336, 338, 340, 343, 345, 347, 350, 352, 354, 356, 359, 361, 363, |
406 | 365, 367, 370, 372, 374, 376, 378, 380, 382, 384, 386, 388, 391, | 406 | 365, 367, 370, 372, 374, 376, 378, 380, 382, 384, 386, 388, 391, |
407 | 393, 395, 396, 398, 400, 402, 404, 406, 408, 410, 412, 414, 415, | 407 | 393, 395, 396, 398, 400, 402, 404, 406, 408, 410, 412, 414, 415, |
408 | 417, 419, 421, 423, 424, 426, 428, 430, 431, 433, 435, 436, 438, | 408 | 417, 419, 421, 423, 424, 426, 428, 430, 431, 433, 435, 436, 438, |
409 | 439, 441, 443, 444, 446, 447, 449, 450, 452, 453, 455, 456, 457, | 409 | 439, 441, 443, 444, 446, 447, 449, 450, 452, 453, 455, 456, 457, |
410 | 459, 460, 461, 463, 464, 465, 467, 468, 469, 470, 472, 473, 474, | 410 | 459, 460, 461, 463, 464, 465, 467, 468, 469, 470, 472, 473, 474, |
411 | 475, 476, 477, 478, 480, 481, 482, 483, 484, 485, 486, 487, 488, | 411 | 475, 476, 477, 478, 480, 481, 482, 483, 484, 485, 486, 487, 488, |
412 | 488, 489, 490, 491, 492, 493, 494, 494, 495, 496, 497, 497, 498, | 412 | 488, 489, 490, 491, 492, 493, 494, 494, 495, 496, 497, 497, 498, |
413 | 499, 499, 500, 501, 501, 502, 502, 503, 504, 504, 504, 505, 505, | 413 | 499, 499, 500, 501, 501, 502, 502, 503, 504, 504, 504, 505, 505, |
414 | 506, 506, 507, 507, 507, 508, 508, 508, 509, 509, 509, 509, 510, | 414 | 506, 506, 507, 507, 507, 508, 508, 508, 509, 509, 509, 509, 510, |
415 | 510, 510, 510, 510, 510, 510, 510, 510, 510, 511, 510, 510, 510, | 415 | 510, 510, 510, 510, 510, 510, 510, 510, 510, 511, 510, 510, 510, |
416 | 510, 510, 510, 510, 510, 510, 510, 509, 509, 509, 509, 508, 508, | 416 | 510, 510, 510, 510, 510, 510, 510, 509, 509, 509, 509, 508, 508, |
417 | 508, 507, 507, 507, 506, 506, 505, 505, 504, 504, 504, 503, 502, | 417 | 508, 507, 507, 507, 506, 506, 505, 505, 504, 504, 504, 503, 502, |
418 | 502, 501, 501, 500, 499, 499, 498, 497, 497, 496, 495, 494, 494, | 418 | 502, 501, 501, 500, 499, 499, 498, 497, 497, 496, 495, 494, 494, |
419 | 493, 492, 491, 490, 489, 488, 488, 487, 486, 485, 484, 483, 482, | 419 | 493, 492, 491, 490, 489, 488, 488, 487, 486, 485, 484, 483, 482, |
420 | 481, 480, 478, 477, 476, 475, 474, 473, 472, 470, 469, 468, 467, | 420 | 481, 480, 478, 477, 476, 475, 474, 473, 472, 470, 469, 468, 467, |
421 | 465, 464, 463, 461, 460, 459, 457, 456, 455, 453, 452, 450, 449, | 421 | 465, 464, 463, 461, 460, 459, 457, 456, 455, 453, 452, 450, 449, |
422 | 447, 446, 444, 443, 441, 439, 438, 436, 435, 433, 431, 430, 428, | 422 | 447, 446, 444, 443, 441, 439, 438, 436, 435, 433, 431, 430, 428, |
423 | 426, 424, 423, 421, 419, 417, 415, 414, 412, 410, 408, 406, 404, | 423 | 426, 424, 423, 421, 419, 417, 415, 414, 412, 410, 408, 406, 404, |
424 | 402, 400, 398, 396, 395, 393, 391, 388, 386, 384, 382, 380, 378, | 424 | 402, 400, 398, 396, 395, 393, 391, 388, 386, 384, 382, 380, 378, |
425 | 376, 374, 372, 370, 367, 365, 363, 361, 359, 356, 354, 352, 350, | 425 | 376, 374, 372, 370, 367, 365, 363, 361, 359, 356, 354, 352, 350, |
426 | 347, 345, 343, 340, 338, 336, 333, 331, 328, 326, 324, 321, 319, | 426 | 347, 345, 343, 340, 338, 336, 333, 331, 328, 326, 324, 321, 319, |
427 | 316, 314, 311, 309, 306, 304, 301, 299, 296, 294, 291, 289, 286, | 427 | 316, 314, 311, 309, 306, 304, 301, 299, 296, 294, 291, 289, 286, |
428 | 283, 281, 278, 276, 273, 270, 268, 265, 262, 260, 257, 254, 251, | 428 | 283, 281, 278, 276, 273, 270, 268, 265, 262, 260, 257, 254, 251, |
429 | 249, 246, 243, 240, 238, 235, 232, 229, 226, 224, 221, 218, 215, | 429 | 249, 246, 243, 240, 238, 235, 232, 229, 226, 224, 221, 218, 215, |
430 | 212, 209, 207, 204, 201, 198, 195, 192, 189, 186, 183, 180, 178, | 430 | 212, 209, 207, 204, 201, 198, 195, 192, 189, 186, 183, 180, 178, |
431 | 175, 172, 169, 166, 163, 160, 157, 154, 151, 148, 145, 142, 139, | 431 | 175, 172, 169, 166, 163, 160, 157, 154, 151, 148, 145, 142, 139, |
432 | 136, 133, 130, 127, 124, 121, 118, 115, 111, 108, 105, 102, 99, | 432 | 136, 133, 130, 127, 124, 121, 118, 115, 111, 108, 105, 102, 99, |
433 | 96, 93, 90, 87, 84, 81, 78, 74, 71, 68, 65, 62, 59, | 433 | 96, 93, 90, 87, 84, 81, 78, 74, 71, 68, 65, 62, 59, |
434 | 56, 53, 50, 46, 43, 40, 37, 34, 31, 28, 25, 21, 18, | 434 | 56, 53, 50, 46, 43, 40, 37, 34, 31, 28, 25, 21, 18, |
435 | 15, 12, 9, 6, 3, 0, -3, -6, -9, -12, -15, -18, -21, | 435 | 15, 12, 9, 6, 3, 0, -3, -6, -9, -12, -15, -18, -21, |
436 | -25, -28, -31, -34, -37, -40, -43, -46, -50, -53, -56, -59, -62, | 436 | -25, -28, -31, -34, -37, -40, -43, -46, -50, -53, -56, -59, -62, |
437 | -65, -68, -71, -74, -78, -81, -84, -87, -90, -93, -96, -99, -102, | 437 | -65, -68, -71, -74, -78, -81, -84, -87, -90, -93, -96, -99, -102, |
438 | -105, -108, -111, -115, -118, -121, -124, -127, -130, -133, -136, -139, -142, | 438 | -105, -108, -111, -115, -118, -121, -124, -127, -130, -133, -136, -139, -142, |
439 | -145, -148, -151, -154, -157, -160, -163, -166, -169, -172, -175, -178, -180, | 439 | -145, -148, -151, -154, -157, -160, -163, -166, -169, -172, -175, -178, -180, |
440 | -183, -186, -189, -192, -195, -198, -201, -204, -207, -209, -212, -215, -218, | 440 | -183, -186, -189, -192, -195, -198, -201, -204, -207, -209, -212, -215, -218, |
441 | -221, -224, -226, -229, -232, -235, -238, -240, -243, -246, -249, -251, -254, | 441 | -221, -224, -226, -229, -232, -235, -238, -240, -243, -246, -249, -251, -254, |
442 | -257, -260, -262, -265, -268, -270, -273, -276, -278, -281, -283, -286, -289, | 442 | -257, -260, -262, -265, -268, -270, -273, -276, -278, -281, -283, -286, -289, |
443 | -291, -294, -296, -299, -301, -304, -306, -309, -311, -314, -316, -319, -321, | 443 | -291, -294, -296, -299, -301, -304, -306, -309, -311, -314, -316, -319, -321, |
444 | -324, -326, -328, -331, -333, -336, -338, -340, -343, -345, -347, -350, -352, | 444 | -324, -326, -328, -331, -333, -336, -338, -340, -343, -345, -347, -350, -352, |
445 | -354, -356, -359, -361, -363, -365, -367, -370, -372, -374, -376, -378, -380, | 445 | -354, -356, -359, -361, -363, -365, -367, -370, -372, -374, -376, -378, -380, |
446 | -382, -384, -386, -388, -391, -393, -395, -396, -398, -400, -402, -404, -406, | 446 | -382, -384, -386, -388, -391, -393, -395, -396, -398, -400, -402, -404, -406, |
447 | -408, -410, -412, -414, -415, -417, -419, -421, -423, -424, -426, -428, -430, | 447 | -408, -410, -412, -414, -415, -417, -419, -421, -423, -424, -426, -428, -430, |
448 | -431, -433, -435, -436, -438, -439, -441, -443, -444, -446, -447, -449, -450, | 448 | -431, -433, -435, -436, -438, -439, -441, -443, -444, -446, -447, -449, -450, |
449 | -452, -453, -455, -456, -457, -459, -460, -461, -463, -464, -465, -467, -468, | 449 | -452, -453, -455, -456, -457, -459, -460, -461, -463, -464, -465, -467, -468, |
450 | -469, -470, -472, -473, -474, -475, -476, -477, -478, -480, -481, -482, -483, | 450 | -469, -470, -472, -473, -474, -475, -476, -477, -478, -480, -481, -482, -483, |
451 | -484, -485, -486, -487, -488, -488, -489, -490, -491, -492, -493, -494, -494, | 451 | -484, -485, -486, -487, -488, -488, -489, -490, -491, -492, -493, -494, -494, |
452 | -495, -496, -497, -497, -498, -499, -499, -500, -501, -501, -502, -502, -503, | 452 | -495, -496, -497, -497, -498, -499, -499, -500, -501, -501, -502, -502, -503, |
453 | -504, -504, -504, -505, -505, -506, -506, -507, -507, -507, -508, -508, -508, | 453 | -504, -504, -504, -505, -505, -506, -506, -507, -507, -507, -508, -508, -508, |
454 | -509, -509, -509, -509, -510, -510, -510, -510, -510, -510, -510, -510, -510, | 454 | -509, -509, -509, -509, -510, -510, -510, -510, -510, -510, -510, -510, -510, |
455 | -510, -511, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -509, | 455 | -510, -511, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -509, |
456 | -509, -509, -509, -508, -508, -508, -507, -507, -507, -506, -506, -505, -505, | 456 | -509, -509, -509, -508, -508, -508, -507, -507, -507, -506, -506, -505, -505, |
457 | -504, -504, -504, -503, -502, -502, -501, -501, -500, -499, -499, -498, -497, | 457 | -504, -504, -504, -503, -502, -502, -501, -501, -500, -499, -499, -498, -497, |
458 | -497, -496, -495, -494, -494, -493, -492, -491, -490, -489, -488, -488, -487, | 458 | -497, -496, -495, -494, -494, -493, -492, -491, -490, -489, -488, -488, -487, |
459 | -486, -485, -484, -483, -482, -481, -480, -478, -477, -476, -475, -474, -473, | 459 | -486, -485, -484, -483, -482, -481, -480, -478, -477, -476, -475, -474, -473, |
460 | -472, -470, -469, -468, -467, -465, -464, -463, -461, -460, -459, -457, -456, | 460 | -472, -470, -469, -468, -467, -465, -464, -463, -461, -460, -459, -457, -456, |
461 | -455, -453, -452, -450, -449, -447, -446, -444, -443, -441, -439, -438, -436, | 461 | -455, -453, -452, -450, -449, -447, -446, -444, -443, -441, -439, -438, -436, |
462 | -435, -433, -431, -430, -428, -426, -424, -423, -421, -419, -417, -415, -414, | 462 | -435, -433, -431, -430, -428, -426, -424, -423, -421, -419, -417, -415, -414, |
463 | -412, -410, -408, -406, -404, -402, -400, -398, -396, -395, -393, -391, -388, | 463 | -412, -410, -408, -406, -404, -402, -400, -398, -396, -395, -393, -391, -388, |
464 | -386, -384, -382, -380, -378, -376, -374, -372, -370, -367, -365, -363, -361, | 464 | -386, -384, -382, -380, -378, -376, -374, -372, -370, -367, -365, -363, -361, |
465 | -359, -356, -354, -352, -350, -347, -345, -343, -340, -338, -336, -333, -331, | 465 | -359, -356, -354, -352, -350, -347, -345, -343, -340, -338, -336, -333, -331, |
466 | -328, -326, -324, -321, -319, -316, -314, -311, -309, -306, -304, -301, -299, | 466 | -328, -326, -324, -321, -319, -316, -314, -311, -309, -306, -304, -301, -299, |
467 | -296, -294, -291, -289, -286, -283, -281, -278, -276, -273, -270, -268, -265, | 467 | -296, -294, -291, -289, -286, -283, -281, -278, -276, -273, -270, -268, -265, |
468 | -262, -260, -257, -254, -251, -249, -246, -243, -240, -238, -235, -232, -229, | 468 | -262, -260, -257, -254, -251, -249, -246, -243, -240, -238, -235, -232, -229, |
469 | -226, -224, -221, -218, -215, -212, -209, -207, -204, -201, -198, -195, -192, | 469 | -226, -224, -221, -218, -215, -212, -209, -207, -204, -201, -198, -195, -192, |
470 | -189, -186, -183, -180, -178, -175, -172, -169, -166, -163, -160, -157, -154, | 470 | -189, -186, -183, -180, -178, -175, -172, -169, -166, -163, -160, -157, -154, |
471 | -151, -148, -145, -142, -139, -136, -133, -130, -127, -124, -121, -118, -115, | 471 | -151, -148, -145, -142, -139, -136, -133, -130, -127, -124, -121, -118, -115, |
472 | -111, -108, -105, -102, -99, -96, -93, -90, -87, -84, -81, -78, -74, | 472 | -111, -108, -105, -102, -99, -96, -93, -90, -87, -84, -81, -78, -74, |
473 | -71, -68, -65, -62, -59, -56, -53, -50, -46, -43, -40, -37, -34, | 473 | -71, -68, -65, -62, -59, -56, -53, -50, -46, -43, -40, -37, -34, |
474 | -31, -28, -25, -21, -18, -15, -12, -9, -6, -3 | 474 | -31, -28, -25, -21, -18, -15, -12, -9, -6, -3 |
475 | }; | 475 | }; |
476 | 476 | ||
477 | static const short lfo_env_coeff[] = { | 477 | static const short lfo_env_coeff[] = { |
478 | 251, 253, 254, 256, 257, 259, 260, 262, 264, 265, 267, 268, 270, | 478 | 251, 253, 254, 256, 257, 259, 260, 262, 264, 265, 267, 268, 270, |
479 | 271, 273, 274, 276, 277, 279, 281, 282, 284, 285, 287, 288, 290, | 479 | 271, 273, 274, 276, 277, 279, 281, 282, 284, 285, 287, 288, 290, |
480 | 291, 293, 294, 296, 297, 299, 300, 302, 303, 305, 306, 308, 309, | 480 | 291, 293, 294, 296, 297, 299, 300, 302, 303, 305, 306, 308, 309, |
481 | 311, 312, 314, 315, 317, 318, 320, 321, 323, 324, 326, 327, 329, | 481 | 311, 312, 314, 315, 317, 318, 320, 321, 323, 324, 326, 327, 329, |
482 | 330, 332, 333, 335, 336, 337, 339, 340, 342, 343, 345, 346, 348, | 482 | 330, 332, 333, 335, 336, 337, 339, 340, 342, 343, 345, 346, 348, |
483 | 349, 350, 352, 353, 355, 356, 357, 359, 360, 362, 363, 364, 366, | 483 | 349, 350, 352, 353, 355, 356, 357, 359, 360, 362, 363, 364, 366, |
484 | 367, 369, 370, 371, 373, 374, 375, 377, 378, 379, 381, 382, 383, | 484 | 367, 369, 370, 371, 373, 374, 375, 377, 378, 379, 381, 382, 383, |
485 | 385, 386, 387, 389, 390, 391, 392, 394, 395, 396, 397, 399, 400, | 485 | 385, 386, 387, 389, 390, 391, 392, 394, 395, 396, 397, 399, 400, |
486 | 401, 402, 404, 405, 406, 407, 409, 410, 411, 412, 413, 414, 416, | 486 | 401, 402, 404, 405, 406, 407, 409, 410, 411, 412, 413, 414, 416, |
487 | 417, 418, 419, 420, 421, 423, 424, 425, 426, 427, 428, 429, 430, | 487 | 417, 418, 419, 420, 421, 423, 424, 425, 426, 427, 428, 429, 430, |
488 | 431, 432, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, | 488 | 431, 432, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, |
489 | 445, 446, 447, 448, 449, 450, 451, 452, 453, 453, 454, 455, 456, | 489 | 445, 446, 447, 448, 449, 450, 451, 452, 453, 453, 454, 455, 456, |
490 | 457, 458, 459, 460, 461, 461, 462, 463, 464, 465, 466, 466, 467, | 490 | 457, 458, 459, 460, 461, 461, 462, 463, 464, 465, 466, 466, 467, |
491 | 468, 469, 469, 470, 471, 472, 473, 473, 474, 475, 475, 476, 477, | 491 | 468, 469, 469, 470, 471, 472, 473, 473, 474, 475, 475, 476, 477, |
492 | 477, 478, 479, 479, 480, 481, 481, 482, 483, 483, 484, 484, 485, | 492 | 477, 478, 479, 479, 480, 481, 481, 482, 483, 483, 484, 484, 485, |
493 | 486, 486, 487, 487, 488, 488, 489, 489, 490, 490, 491, 491, 492, | 493 | 486, 486, 487, 487, 488, 488, 489, 489, 490, 490, 491, 491, 492, |
494 | 492, 493, 493, 493, 494, 494, 495, 495, 495, 496, 496, 497, 497, | 494 | 492, 493, 493, 493, 494, 494, 495, 495, 495, 496, 496, 497, 497, |
495 | 497, 498, 498, 498, 498, 499, 499, 499, 500, 500, 500, 500, 500, | 495 | 497, 498, 498, 498, 498, 499, 499, 499, 500, 500, 500, 500, 500, |
496 | 501, 501, 501, 501, 501, 502, 502, 502, 502, 502, 502, 502, 502, | 496 | 501, 501, 501, 501, 501, 502, 502, 502, 502, 502, 502, 502, 502, |
497 | 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, | 497 | 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, |
498 | 503, 503, 503, 503, 503, 503, 502, 502, 502, 502, 502, 502, 502, | 498 | 503, 503, 503, 503, 503, 503, 502, 502, 502, 502, 502, 502, 502, |
499 | 502, 501, 501, 501, 501, 501, 500, 500, 500, 500, 500, 499, 499, | 499 | 502, 501, 501, 501, 501, 501, 500, 500, 500, 500, 500, 499, 499, |
500 | 499, 498, 498, 498, 498, 497, 497, 497, 496, 496, 495, 495, 495, | 500 | 499, 498, 498, 498, 498, 497, 497, 497, 496, 496, 495, 495, 495, |
501 | 494, 494, 493, 493, 493, 492, 492, 491, 491, 490, 490, 489, 489, | 501 | 494, 494, 493, 493, 493, 492, 492, 491, 491, 490, 490, 489, 489, |
502 | 488, 488, 487, 487, 486, 486, 485, 484, 484, 483, 483, 482, 481, | 502 | 488, 488, 487, 487, 486, 486, 485, 484, 484, 483, 483, 482, 481, |
503 | 481, 480, 479, 479, 478, 477, 477, 476, 475, 475, 474, 473, 473, | 503 | 481, 480, 479, 479, 478, 477, 477, 476, 475, 475, 474, 473, 473, |
504 | 472, 471, 470, 469, 469, 468, 467, 466, 466, 465, 464, 463, 462, | 504 | 472, 471, 470, 469, 469, 468, 467, 466, 466, 465, 464, 463, 462, |
505 | 461, 461, 460, 459, 458, 457, 456, 455, 454, 453, 453, 452, 451, | 505 | 461, 461, 460, 459, 458, 457, 456, 455, 454, 453, 453, 452, 451, |
506 | 450, 449, 448, 447, 446, 445, 444, 443, 442, 441, 440, 439, 438, | 506 | 450, 449, 448, 447, 446, 445, 444, 443, 442, 441, 440, 439, 438, |
507 | 437, 436, 435, 434, 432, 431, 430, 429, 428, 427, 426, 425, 424, | 507 | 437, 436, 435, 434, 432, 431, 430, 429, 428, 427, 426, 425, 424, |
508 | 423, 421, 420, 419, 418, 417, 416, 414, 413, 412, 411, 410, 409, | 508 | 423, 421, 420, 419, 418, 417, 416, 414, 413, 412, 411, 410, 409, |
509 | 407, 406, 405, 404, 402, 401, 400, 399, 397, 396, 395, 394, 392, | 509 | 407, 406, 405, 404, 402, 401, 400, 399, 397, 396, 395, 394, 392, |
510 | 391, 390, 389, 387, 386, 385, 383, 382, 381, 379, 378, 377, 375, | 510 | 391, 390, 389, 387, 386, 385, 383, 382, 381, 379, 378, 377, 375, |
511 | 374, 373, 371, 370, 369, 367, 366, 364, 363, 362, 360, 359, 357, | 511 | 374, 373, 371, 370, 369, 367, 366, 364, 363, 362, 360, 359, 357, |
512 | 356, 355, 353, 352, 350, 349, 348, 346, 345, 343, 342, 340, 339, | 512 | 356, 355, 353, 352, 350, 349, 348, 346, 345, 343, 342, 340, 339, |
513 | 337, 336, 335, 333, 332, 330, 329, 327, 326, 324, 323, 321, 320, | 513 | 337, 336, 335, 333, 332, 330, 329, 327, 326, 324, 323, 321, 320, |
514 | 318, 317, 315, 314, 312, 311, 309, 308, 306, 305, 303, 302, 300, | 514 | 318, 317, 315, 314, 312, 311, 309, 308, 306, 305, 303, 302, 300, |
515 | 299, 297, 296, 294, 293, 291, 290, 288, 287, 285, 284, 282, 281, | 515 | 299, 297, 296, 294, 293, 291, 290, 288, 287, 285, 284, 282, 281, |
516 | 279, 277, 276, 274, 273, 271, 270, 268, 267, 265, 264, 262, 260, | 516 | 279, 277, 276, 274, 273, 271, 270, 268, 267, 265, 264, 262, 260, |
517 | 259, 257, 256, 254, 253, 251, 250, 248, 247, 245, 244, 242, 240, | 517 | 259, 257, 256, 254, 253, 251, 250, 248, 247, 245, 244, 242, 240, |
518 | 239, 237, 236, 234, 233, 231, 230, 228, 227, 225, 223, 222, 220, | 518 | 239, 237, 236, 234, 233, 231, 230, 228, 227, 225, 223, 222, 220, |
519 | 219, 217, 216, 214, 213, 211, 210, 208, 207, 205, 204, 202, 201, | 519 | 219, 217, 216, 214, 213, 211, 210, 208, 207, 205, 204, 202, 201, |
520 | 199, 198, 196, 195, 193, 192, 190, 189, 187, 186, 184, 183, 181, | 520 | 199, 198, 196, 195, 193, 192, 190, 189, 187, 186, 184, 183, 181, |
521 | 180, 178, 177, 175, 174, 172, 171, 169, 168, 166, 165, 164, 162, | 521 | 180, 178, 177, 175, 174, 172, 171, 169, 168, 166, 165, 164, 162, |
522 | 161, 159, 158, 156, 155, 153, 152, 151, 149, 148, 146, 145, 144, | 522 | 161, 159, 158, 156, 155, 153, 152, 151, 149, 148, 146, 145, 144, |
523 | 142, 141, 139, 138, 137, 135, 134, 133, 131, 130, 129, 127, 126, | 523 | 142, 141, 139, 138, 137, 135, 134, 133, 131, 130, 129, 127, 126, |
524 | 124, 123, 122, 120, 119, 118, 117, 115, 114, 113, 111, 110, 109, | 524 | 124, 123, 122, 120, 119, 118, 117, 115, 114, 113, 111, 110, 109, |
525 | 108, 106, 105, 104, 103, 101, 100, 99, 98, 96, 95, 94, 93, | 525 | 108, 106, 105, 104, 103, 101, 100, 99, 98, 96, 95, 94, 93, |
526 | 92, 90, 89, 88, 87, 86, 84, 83, 82, 81, 80, 79, 78, | 526 | 92, 90, 89, 88, 87, 86, 84, 83, 82, 81, 80, 79, 78, |
527 | 77, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64, | 527 | 77, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64, |
528 | 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, | 528 | 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, |
529 | 50, 49, 48, 47, 46, 45, 45, 44, 43, 42, 41, 40, 39, | 529 | 50, 49, 48, 47, 46, 45, 45, 44, 43, 42, 41, 40, 39, |
530 | 39, 38, 37, 36, 35, 35, 34, 33, 32, 31, 31, 30, 29, | 530 | 39, 38, 37, 36, 35, 35, 34, 33, 32, 31, 31, 30, 29, |
531 | 29, 28, 27, 26, 26, 25, 24, 24, 23, 22, 22, 21, 20, | 531 | 29, 28, 27, 26, 26, 25, 24, 24, 23, 22, 22, 21, 20, |
532 | 20, 19, 19, 18, 17, 17, 16, 16, 15, 15, 14, 14, 13, | 532 | 20, 19, 19, 18, 17, 17, 16, 16, 15, 15, 14, 14, 13, |
533 | 13, 12, 12, 11, 11, 10, 10, 9, 9, 9, 8, 8, 7, | 533 | 13, 12, 12, 11, 11, 10, 10, 9, 9, 9, 8, 8, 7, |
534 | 7, 7, 6, 6, 6, 5, 5, 5, 4, 4, 4, 3, 3, | 534 | 7, 7, 6, 6, 6, 5, 5, 5, 4, 4, 4, 3, 3, |
535 | 3, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, | 535 | 3, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, |
536 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 536 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
537 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 537 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
538 | 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, | 538 | 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, |
539 | 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, | 539 | 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, |
540 | 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, | 540 | 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, |
541 | 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, | 541 | 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, |
542 | 19, 19, 20, 20, 21, 22, 22, 23, 24, 24, 25, 26, 26, | 542 | 19, 19, 20, 20, 21, 22, 22, 23, 24, 24, 25, 26, 26, |
543 | 27, 28, 29, 29, 30, 31, 31, 32, 33, 34, 35, 35, 36, | 543 | 27, 28, 29, 29, 30, 31, 31, 32, 33, 34, 35, 35, 36, |
544 | 37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 45, 46, 47, | 544 | 37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 45, 46, 47, |
545 | 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, | 545 | 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, |
546 | 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, | 546 | 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, |
547 | 74, 75, 77, 78, 79, 80, 81, 82, 83, 84, 86, 87, 88, | 547 | 74, 75, 77, 78, 79, 80, 81, 82, 83, 84, 86, 87, 88, |
548 | 89, 90, 92, 93, 94, 95, 96, 98, 99, 100, 101, 103, 104, | 548 | 89, 90, 92, 93, 94, 95, 96, 98, 99, 100, 101, 103, 104, |
549 | 105, 106, 108, 109, 110, 111, 113, 114, 115, 117, 118, 119, 120, | 549 | 105, 106, 108, 109, 110, 111, 113, 114, 115, 117, 118, 119, 120, |
550 | 122, 123, 124, 126, 127, 129, 130, 131, 133, 134, 135, 137, 138, | 550 | 122, 123, 124, 126, 127, 129, 130, 131, 133, 134, 135, 137, 138, |
551 | 139, 141, 142, 144, 145, 146, 148, 149, 151, 152, 153, 155, 156, | 551 | 139, 141, 142, 144, 145, 146, 148, 149, 151, 152, 153, 155, 156, |
552 | 158, 159, 161, 162, 164, 165, 166, 168, 169, 171, 172, 174, 175, | 552 | 158, 159, 161, 162, 164, 165, 166, 168, 169, 171, 172, 174, 175, |
553 | 177, 178, 180, 181, 183, 184, 186, 187, 189, 190, 192, 193, 195, | 553 | 177, 178, 180, 181, 183, 184, 186, 187, 189, 190, 192, 193, 195, |
554 | 196, 198, 199, 201, 202, 204, 205, 207, 208, 210, 211, 213, 214, | 554 | 196, 198, 199, 201, 202, 204, 205, 207, 208, 210, 211, 213, 214, |
555 | 216, 217, 219, 220, 222, 223, 225, 227, 228, 230, 231, 233, 234, | 555 | 216, 217, 219, 220, 222, 223, 225, 227, 228, 230, 231, 233, 234, |
556 | 236, 237, 239, 240, 242, 244, 245, 247, 248, 250 | 556 | 236, 237, 239, 240, 242, 244, 245, 247, 248, 250 |
557 | }; | 557 | }; |
558 | 558 | ||
559 | #endif | 559 | #endif |
diff --git a/apps/codecs/libgme/z80_cpu.h b/apps/codecs/libgme/z80_cpu.h index 15115b7e53..341119b6b1 100644 --- a/apps/codecs/libgme/z80_cpu.h +++ b/apps/codecs/libgme/z80_cpu.h | |||
@@ -1,116 +1,116 @@ | |||
1 | // Z80 CPU emulator | 1 | // Z80 CPU emulator |
2 | 2 | ||
3 | // Game_Music_Emu 0.6-pre | 3 | // Game_Music_Emu 0.6-pre |
4 | #ifndef Z80_CPU_H | 4 | #ifndef Z80_CPU_H |
5 | #define Z80_CPU_H | 5 | #define Z80_CPU_H |
6 | 6 | ||
7 | #include "blargg_source.h" | 7 | #include "blargg_source.h" |
8 | #include "blargg_endian.h" | 8 | #include "blargg_endian.h" |
9 | 9 | ||
10 | typedef int cpu_time_t; | 10 | typedef int cpu_time_t; |
11 | typedef int addr_t; | 11 | typedef int addr_t; |
12 | 12 | ||
13 | enum { page_bits = 10 }; | 13 | enum { page_bits = 10 }; |
14 | enum { page_size = 1 << page_bits }; | 14 | enum { page_size = 1 << page_bits }; |
15 | enum { page_count = 0x10000 / page_size }; | 15 | enum { page_count = 0x10000 / page_size }; |
16 | 16 | ||
17 | // Can read this far past end of memory | 17 | // Can read this far past end of memory |
18 | enum { cpu_padding = 0x100 }; | 18 | enum { cpu_padding = 0x100 }; |
19 | 19 | ||
20 | // Can read this many bytes past end of a page | 20 | // Can read this many bytes past end of a page |
21 | enum { page_padding = 4 }; | 21 | enum { page_padding = 4 }; |
22 | 22 | ||
23 | #ifdef BLARGG_BIG_ENDIAN | 23 | #ifdef BLARGG_BIG_ENDIAN |
24 | struct regs_t { byte b,c, d,e, h,l, flags,a; }; | 24 | struct regs_t { byte b,c, d,e, h,l, flags,a; }; |
25 | #else | 25 | #else |
26 | struct regs_t { byte c,b, e,d, l,h, a,flags; }; | 26 | struct regs_t { byte c,b, e,d, l,h, a,flags; }; |
27 | #endif | 27 | #endif |
28 | // BOOST_STATIC_ASSERT( sizeof (regs_t) == 8 ); | 28 | // BOOST_STATIC_ASSERT( sizeof (regs_t) == 8 ); |
29 | 29 | ||
30 | struct pairs_t { uint16_t bc, de, hl, fa; }; | 30 | struct pairs_t { uint16_t bc, de, hl, fa; }; |
31 | 31 | ||
32 | // Registers are not updated until run() returns | 32 | // Registers are not updated until run() returns |
33 | struct registers_t { | 33 | struct registers_t { |
34 | uint16_t pc; | 34 | uint16_t pc; |
35 | uint16_t sp; | 35 | uint16_t sp; |
36 | uint16_t ix; | 36 | uint16_t ix; |
37 | uint16_t iy; | 37 | uint16_t iy; |
38 | union { | 38 | union { |
39 | struct regs_t b; // b.b, b.c, b.d, b.e, b.h, b.l, b.flags, b.a | 39 | struct regs_t b; // b.b, b.c, b.d, b.e, b.h, b.l, b.flags, b.a |
40 | struct pairs_t w; // w.bc, w.de, w.hl. w.fa | 40 | struct pairs_t w; // w.bc, w.de, w.hl. w.fa |
41 | }; | 41 | }; |
42 | union { | 42 | union { |
43 | struct regs_t b; | 43 | struct regs_t b; |
44 | struct pairs_t w; | 44 | struct pairs_t w; |
45 | } alt; | 45 | } alt; |
46 | byte iff1; | 46 | byte iff1; |
47 | byte iff2; | 47 | byte iff2; |
48 | byte r; | 48 | byte r; |
49 | byte i; | 49 | byte i; |
50 | byte im; | 50 | byte im; |
51 | }; | 51 | }; |
52 | 52 | ||
53 | struct cpu_state_t { | 53 | struct cpu_state_t { |
54 | byte const* read [page_count + 1]; | 54 | byte const* read [page_count + 1]; |
55 | byte * write [page_count + 1]; | 55 | byte * write [page_count + 1]; |
56 | cpu_time_t base; | 56 | cpu_time_t base; |
57 | cpu_time_t time; | 57 | cpu_time_t time; |
58 | }; | 58 | }; |
59 | 59 | ||
60 | struct Z80_Cpu { | 60 | struct Z80_Cpu { |
61 | byte szpc [0x200]; | 61 | byte szpc [0x200]; |
62 | cpu_time_t end_time_; | 62 | cpu_time_t end_time_; |
63 | 63 | ||
64 | struct cpu_state_t* cpu_state; // points to cpu_state_ or a local copy within run() | 64 | struct cpu_state_t* cpu_state; // points to cpu_state_ or a local copy within run() |
65 | struct cpu_state_t cpu_state_; | 65 | struct cpu_state_t cpu_state_; |
66 | 66 | ||
67 | struct registers_t r; | 67 | struct registers_t r; |
68 | }; | 68 | }; |
69 | 69 | ||
70 | void Z80_init( struct Z80_Cpu* this ); | 70 | void Z80_init( struct Z80_Cpu* this ); |
71 | 71 | ||
72 | // Clears registers and maps all pages to unmapped | 72 | // Clears registers and maps all pages to unmapped |
73 | void Z80_reset( struct Z80_Cpu* this, void* unmapped_write, void const* unmapped_read ); | 73 | void Z80_reset( struct Z80_Cpu* this, void* unmapped_write, void const* unmapped_read ); |
74 | 74 | ||
75 | // TODO: split mapping out of CPU | 75 | // TODO: split mapping out of CPU |
76 | 76 | ||
77 | // Maps memory. Start and size must be multiple of page_size. | 77 | // Maps memory. Start and size must be multiple of page_size. |
78 | void Z80_map_mem( struct Z80_Cpu* this, addr_t addr, int size, void* write, void const* read ); | 78 | void Z80_map_mem( struct Z80_Cpu* this, addr_t addr, int size, void* write, void const* read ); |
79 | 79 | ||
80 | // Time of beginning of next instruction | 80 | // Time of beginning of next instruction |
81 | static inline cpu_time_t Z80_time( struct Z80_Cpu* this ) { return this->cpu_state->time + this->cpu_state->base; } | 81 | static inline cpu_time_t Z80_time( struct Z80_Cpu* this ) { return this->cpu_state->time + this->cpu_state->base; } |
82 | 82 | ||
83 | // Alter current time | 83 | // Alter current time |
84 | static inline void Z80_set_time( struct Z80_Cpu* this, cpu_time_t t ) { this->cpu_state->time = t - this->cpu_state->base; } | 84 | static inline void Z80_set_time( struct Z80_Cpu* this, cpu_time_t t ) { this->cpu_state->time = t - this->cpu_state->base; } |
85 | static inline void Z80_adjust_time( struct Z80_Cpu* this, int delta ) { this->cpu_state->time += delta; } | 85 | static inline void Z80_adjust_time( struct Z80_Cpu* this, int delta ) { this->cpu_state->time += delta; } |
86 | 86 | ||
87 | #ifdef BLARGG_NONPORTABLE | 87 | #ifdef BLARGG_NONPORTABLE |
88 | #define Z80_CPU_OFFSET( addr ) (addr) | 88 | #define Z80_CPU_OFFSET( addr ) (addr) |
89 | #else | 89 | #else |
90 | #define Z80_CPU_OFFSET( addr ) ((addr) & (page_size - 1)) | 90 | #define Z80_CPU_OFFSET( addr ) ((addr) & (page_size - 1)) |
91 | #endif | 91 | #endif |
92 | 92 | ||
93 | // Maps address to pointer to that byte | 93 | // Maps address to pointer to that byte |
94 | static inline byte* Z80_write( struct Z80_Cpu* this, addr_t addr ) | 94 | static inline byte* Z80_write( struct Z80_Cpu* this, addr_t addr ) |
95 | { | 95 | { |
96 | return this->cpu_state->write [(unsigned) addr >> page_bits] + Z80_CPU_OFFSET( addr ); | 96 | return this->cpu_state->write [(unsigned) addr >> page_bits] + Z80_CPU_OFFSET( addr ); |
97 | } | 97 | } |
98 | 98 | ||
99 | static inline byte const* Z80_read( struct Z80_Cpu* this, addr_t addr ) | 99 | static inline byte const* Z80_read( struct Z80_Cpu* this, addr_t addr ) |
100 | { | 100 | { |
101 | return this->cpu_state->read [(unsigned) addr >> page_bits] + Z80_CPU_OFFSET( addr ); | 101 | return this->cpu_state->read [(unsigned) addr >> page_bits] + Z80_CPU_OFFSET( addr ); |
102 | } | 102 | } |
103 | 103 | ||
104 | static inline void Z80_map_mem_rw( struct Z80_Cpu* this, addr_t addr, int size, void* p ) | 104 | static inline void Z80_map_mem_rw( struct Z80_Cpu* this, addr_t addr, int size, void* p ) |
105 | { | 105 | { |
106 | Z80_map_mem( this, addr, size, p, p ); | 106 | Z80_map_mem( this, addr, size, p, p ); |
107 | } | 107 | } |
108 | 108 | ||
109 | static inline void Z80_set_end_time( struct Z80_Cpu* this, cpu_time_t t ) | 109 | static inline void Z80_set_end_time( struct Z80_Cpu* this, cpu_time_t t ) |
110 | { | 110 | { |
111 | cpu_time_t delta = this->cpu_state->base - t; | 111 | cpu_time_t delta = this->cpu_state->base - t; |
112 | this->cpu_state->base = t; | 112 | this->cpu_state->base = t; |
113 | this->cpu_state->time += delta; | 113 | this->cpu_state->time += delta; |
114 | } | 114 | } |
115 | 115 | ||
116 | #endif | 116 | #endif |
diff --git a/apps/codecs/libgme/z80_cpu_run.h b/apps/codecs/libgme/z80_cpu_run.h index 18195ac92b..a453487bb0 100644 --- a/apps/codecs/libgme/z80_cpu_run.h +++ b/apps/codecs/libgme/z80_cpu_run.h | |||
@@ -1,1696 +1,1696 @@ | |||
1 | // Game_Music_Emu 0.6-pre. http://www.slack.net/~ant/ | 1 | // Game_Music_Emu 0.6-pre. http://www.slack.net/~ant/ |
2 | 2 | ||
3 | // Last validated with zexall 2009.12.05. | 3 | // Last validated with zexall 2009.12.05. |
4 | // Doesn't implement the R register or immediate interrupt after EI. | 4 | // Doesn't implement the R register or immediate interrupt after EI. |
5 | // Address wrap-around isn't completely correct, but is prevented from crashing emulator. | 5 | // Address wrap-around isn't completely correct, but is prevented from crashing emulator. |
6 | // 16-bit memory accesses are made directly to mapped memory, instead of using macro. | 6 | // 16-bit memory accesses are made directly to mapped memory, instead of using macro. |
7 | 7 | ||
8 | #if 0 | 8 | #if 0 |
9 | /* Define these macros in the source file before #including this file. | 9 | /* Define these macros in the source file before #including this file. |
10 | - Parameters might be expressions, so they are best evaluated only once, | 10 | - Parameters might be expressions, so they are best evaluated only once, |
11 | though they NEVER have side-effects, so multiple evaluation is OK. | 11 | though they NEVER have side-effects, so multiple evaluation is OK. |
12 | - Output parameters might be a multiple-assignment expression like "a=x", | 12 | - Output parameters might be a multiple-assignment expression like "a=x", |
13 | so they must NOT be parenthesized. | 13 | so they must NOT be parenthesized. |
14 | - Except where noted, time() and related functions will NOT work | 14 | - Except where noted, time() and related functions will NOT work |
15 | correctly inside a macro. TIME() is always correct, and between FLUSH_TIME() and | 15 | correctly inside a macro. TIME() is always correct, and between FLUSH_TIME() and |
16 | CACHE_TIME() the normal time changing functions can be used. | 16 | CACHE_TIME() the normal time changing functions can be used. |
17 | - Macros "returning" void may use a {} statement block. */ | 17 | - Macros "returning" void may use a {} statement block. */ |
18 | 18 | ||
19 | // 0 <= addr <= 0xFFFF + 0x100 | 19 | // 0 <= addr <= 0xFFFF + 0x100 |
20 | // Optional; default uses whatever was set with map_mem() | 20 | // Optional; default uses whatever was set with map_mem() |
21 | int READ_MEM( addr_t ); | 21 | int READ_MEM( addr_t ); |
22 | void WRITE_MEM( addr_t, int data ); | 22 | void WRITE_MEM( addr_t, int data ); |
23 | 23 | ||
24 | // 0 <= port <= 0xFFFF (apparently upper 8 bits are output by hardware) | 24 | // 0 <= port <= 0xFFFF (apparently upper 8 bits are output by hardware) |
25 | void OUT_PORT( int port, int data ); | 25 | void OUT_PORT( int port, int data ); |
26 | int IN_PORT int port ); | 26 | int IN_PORT int port ); |
27 | 27 | ||
28 | // Reference to Z80_Cpu object used for emulation | 28 | // Reference to Z80_Cpu object used for emulation |
29 | #define CPU cpu | 29 | #define CPU cpu |
30 | 30 | ||
31 | // The following can be used within macros: | 31 | // The following can be used within macros: |
32 | 32 | ||
33 | // Current time | 33 | // Current time |
34 | time_t TIME(); | 34 | time_t TIME(); |
35 | 35 | ||
36 | // Allows use of time functions | 36 | // Allows use of time functions |
37 | void FLUSH_TIME(); | 37 | void FLUSH_TIME(); |
38 | 38 | ||
39 | // Must be used before end of macro if FLUSH_TIME() was used earlier | 39 | // Must be used before end of macro if FLUSH_TIME() was used earlier |
40 | void CACHE_TIME(); | 40 | void CACHE_TIME(); |
41 | 41 | ||
42 | // Configuration (optional; commented behavior if defined) | 42 | // Configuration (optional; commented behavior if defined) |
43 | 43 | ||
44 | // Optimizes as if map_mem( 0, 0x10000, FLAT_MEM, FLAT_MEM ) is always in effect | 44 | // Optimizes as if map_mem( 0, 0x10000, FLAT_MEM, FLAT_MEM ) is always in effect |
45 | #define FLAT_MEM my_mem_array | 45 | #define FLAT_MEM my_mem_array |
46 | 46 | ||
47 | // If RST 7 ($FF) is encountered and PC = IDLE_ADDR, stops execution | 47 | // If RST 7 ($FF) is encountered and PC = IDLE_ADDR, stops execution |
48 | #define IDLE_ADDR 0x1234 | 48 | #define IDLE_ADDR 0x1234 |
49 | 49 | ||
50 | // Expanded just before beginning of code, to help debugger | 50 | // Expanded just before beginning of code, to help debugger |
51 | #define CPU_BEGIN void my_run_cpu() { | 51 | #define CPU_BEGIN void my_run_cpu() { |
52 | 52 | ||
53 | #endif | 53 | #endif |
54 | 54 | ||
55 | /* Copyright (C) 2006-2008 Shay Green. This module is free software; you | 55 | /* Copyright (C) 2006-2008 Shay Green. This module is free software; you |
56 | can redistribute it and/or modify it under the terms of the GNU Lesser | 56 | can redistribute it and/or modify it under the terms of the GNU Lesser |
57 | General Public License as published by the Free Software Foundation; either | 57 | General Public License as published by the Free Software Foundation; either |
58 | version 2.1 of the License, or (at your option) any later version. This | 58 | version 2.1 of the License, or (at your option) any later version. This |
59 | module is distributed in the hope that it will be useful, but WITHOUT ANY | 59 | module is distributed in the hope that it will be useful, but WITHOUT ANY |
60 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | 60 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
61 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more | 61 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
62 | details. You should have received a copy of the GNU Lesser General Public | 62 | details. You should have received a copy of the GNU Lesser General Public |
63 | License along with this module; if not, write to the Free Software Foundation, | 63 | License along with this module; if not, write to the Free Software Foundation, |
64 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ | 64 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ |
65 | 65 | ||
66 | #ifdef CPU_BEGIN | 66 | #ifdef CPU_BEGIN |
67 | CPU_BEGIN | 67 | CPU_BEGIN |
68 | #endif | 68 | #endif |
69 | 69 | ||
70 | #define R cpu->r | 70 | #define R cpu->r |
71 | 71 | ||
72 | // flags, named with hex value for clarity | 72 | // flags, named with hex value for clarity |
73 | int const S80 = 0x80; | 73 | int const S80 = 0x80; |
74 | int const Z40 = 0x40; | 74 | int const Z40 = 0x40; |
75 | int const F20 = 0x20; | 75 | int const F20 = 0x20; |
76 | int const H10 = 0x10; | 76 | int const H10 = 0x10; |
77 | int const F08 = 0x08; | 77 | int const F08 = 0x08; |
78 | int const V04 = 0x04; | 78 | int const V04 = 0x04; |
79 | int const P04 = 0x04; | 79 | int const P04 = 0x04; |
80 | int const N02 = 0x02; | 80 | int const N02 = 0x02; |
81 | int const C01 = 0x01; | 81 | int const C01 = 0x01; |
82 | 82 | ||
83 | #define SZ28P( n ) cpu->szpc [n] | 83 | #define SZ28P( n ) cpu->szpc [n] |
84 | #define SZ28PC( n ) cpu->szpc [n] | 84 | #define SZ28PC( n ) cpu->szpc [n] |
85 | #define SZ28C( n ) (cpu->szpc [n] & ~P04) | 85 | #define SZ28C( n ) (cpu->szpc [n] & ~P04) |
86 | #define SZ28( n ) SZ28C( n ) | 86 | #define SZ28( n ) SZ28C( n ) |
87 | 87 | ||
88 | #define SET_R( n ) (void) (R.r = n) | 88 | #define SET_R( n ) (void) (R.r = n) |
89 | #define GET_R() (R.r) | 89 | #define GET_R() (R.r) |
90 | 90 | ||
91 | // Time | 91 | // Time |
92 | #define TIME() (s_time + s.base) | 92 | #define TIME() (s_time + s.base) |
93 | #define FLUSH_TIME() {s.time = s_time;} | 93 | #define FLUSH_TIME() {s.time = s_time;} |
94 | #define CACHE_TIME() {s_time = s.time;} | 94 | #define CACHE_TIME() {s_time = s.time;} |
95 | 95 | ||
96 | // Memory | 96 | // Memory |
97 | #define RW_MEM( addr, rw ) RW_PAGE( addr, rw ) [RW_OFFSET( addr )] | 97 | #define RW_MEM( addr, rw ) RW_PAGE( addr, rw ) [RW_OFFSET( addr )] |
98 | #define READ_CODE( addr ) RW_MEM( addr, read ) | 98 | #define READ_CODE( addr ) RW_MEM( addr, read ) |
99 | 99 | ||
100 | #ifdef FLAT_MEM | 100 | #ifdef FLAT_MEM |
101 | #define RW_PAGE( addr, rw ) FLAT_MEM | 101 | #define RW_PAGE( addr, rw ) FLAT_MEM |
102 | #define RW_OFFSET( addr ) (addr) | 102 | #define RW_OFFSET( addr ) (addr) |
103 | #define INSTR( off, addr ) READ_CODE( addr ) | 103 | #define INSTR( off, addr ) READ_CODE( addr ) |
104 | #else | 104 | #else |
105 | #define RW_PAGE( addr, rw ) s.rw [(unsigned) (addr) >> page_bits] | 105 | #define RW_PAGE( addr, rw ) s.rw [(unsigned) (addr) >> page_bits] |
106 | #define RW_OFFSET( addr ) Z80_CPU_OFFSET( addr ) | 106 | #define RW_OFFSET( addr ) Z80_CPU_OFFSET( addr ) |
107 | #define INSTR( off, addr ) instr [off] | 107 | #define INSTR( off, addr ) instr [off] |
108 | #endif | 108 | #endif |
109 | 109 | ||
110 | #ifndef READ_MEM | 110 | #ifndef READ_MEM |
111 | #define READ_MEM( addr ) RW_MEM( addr, read ) | 111 | #define READ_MEM( addr ) RW_MEM( addr, read ) |
112 | #endif | 112 | #endif |
113 | 113 | ||
114 | #ifndef WRITE_MEM | 114 | #ifndef WRITE_MEM |
115 | #define WRITE_MEM( addr, data ) (RW_MEM( addr, write ) = data) | 115 | #define WRITE_MEM( addr, data ) (RW_MEM( addr, write ) = data) |
116 | #endif | 116 | #endif |
117 | 117 | ||
118 | #define READ_WORD( addr ) GET_LE16( &RW_MEM( addr, read ) ) | 118 | #define READ_WORD( addr ) GET_LE16( &RW_MEM( addr, read ) ) |
119 | #define WRITE_WORD( addr, data ) SET_LE16( &RW_MEM( addr, write ), data ) | 119 | #define WRITE_WORD( addr, data ) SET_LE16( &RW_MEM( addr, write ), data ) |
120 | 120 | ||
121 | // Truncation | 121 | // Truncation |
122 | #define BYTE( n ) ((uint8_t ) (n)) /* (unsigned) n & 0xFF */ | 122 | #define BYTE( n ) ((uint8_t ) (n)) /* (unsigned) n & 0xFF */ |
123 | #define SBYTE( n ) ((int8_t ) (n)) /* (BYTE( n ) ^ 0x80) - 0x80 */ | 123 | #define SBYTE( n ) ((int8_t ) (n)) /* (BYTE( n ) ^ 0x80) - 0x80 */ |
124 | #define WORD( n ) ((uint16_t) (n)) /* (unsigned) n & 0xFFFF */ | 124 | #define WORD( n ) ((uint16_t) (n)) /* (unsigned) n & 0xFFFF */ |
125 | 125 | ||
126 | // Misc | 126 | // Misc |
127 | #define CASE5( a, b, c, d, e ) case 0x##a:case 0x##b:case 0x##c:case 0x##d:case 0x##e | 127 | #define CASE5( a, b, c, d, e ) case 0x##a:case 0x##b:case 0x##c:case 0x##d:case 0x##e |
128 | #define CASE6( a, b, c, d, e, f ) CASE5( a, b, c, d, e ): case 0x##f | 128 | #define CASE6( a, b, c, d, e, f ) CASE5( a, b, c, d, e ): case 0x##f |
129 | #define CASE7( a, b, c, d, e, f, g ) CASE6( a, b, c, d, e, f ): case 0x##g | 129 | #define CASE7( a, b, c, d, e, f, g ) CASE6( a, b, c, d, e, f ): case 0x##g |
130 | #define CASE8( a, b, c, d, e, f, g, h ) CASE7( a, b, c, d, e, f, g ): case 0x##h | 130 | #define CASE8( a, b, c, d, e, f, g, h ) CASE7( a, b, c, d, e, f, g ): case 0x##h |
131 | 131 | ||
132 | #ifdef BLARGG_BIG_ENDIAN | 132 | #ifdef BLARGG_BIG_ENDIAN |
133 | #define R8( n, offset ) ((r.r8_ - offset) [n]) | 133 | #define R8( n, offset ) ((r.r8_ - offset) [n]) |
134 | #elif BLARGG_LITTLE_ENDIAN | 134 | #elif BLARGG_LITTLE_ENDIAN |
135 | #define R8( n, offset ) ((r.r8_ - offset) [(n) ^ 1]) | 135 | #define R8( n, offset ) ((r.r8_ - offset) [(n) ^ 1]) |
136 | #else | 136 | #else |
137 | #error "Byte order of CPU must be known" | 137 | #error "Byte order of CPU must be known" |
138 | #endif | 138 | #endif |
139 | 139 | ||
140 | #define R16( n, shift, offset ) (r.r16_ [((unsigned) (n) >> shift) - (offset >> shift)]) | 140 | #define R16( n, shift, offset ) (r.r16_ [((unsigned) (n) >> shift) - (offset >> shift)]) |
141 | 141 | ||
142 | #define EX( x, y ) \ | 142 | #define EX( x, y ) \ |
143 | {\ | 143 | {\ |
144 | int temp = x;\ | 144 | int temp = x;\ |
145 | x = y;\ | 145 | x = y;\ |
146 | y = temp;\ | 146 | y = temp;\ |
147 | } | 147 | } |
148 | 148 | ||
149 | #define EXX( name ) \ | 149 | #define EXX( name ) \ |
150 | EX( R.alt.name, r.name ) | 150 | EX( R.alt.name, r.name ) |
151 | 151 | ||
152 | bool warning = false; | 152 | bool warning = false; |
153 | { | 153 | { |
154 | struct cpu_state_t s; | 154 | struct cpu_state_t s; |
155 | #ifdef FLAT_MEM | 155 | #ifdef FLAT_MEM |
156 | s.base = cpu->cpu_state_.base; | 156 | s.base = cpu->cpu_state_.base; |
157 | #else | 157 | #else |
158 | s = cpu->cpu_state_; | 158 | s = cpu->cpu_state_; |
159 | #endif | 159 | #endif |
160 | cpu->cpu_state = &s; | 160 | cpu->cpu_state = &s; |
161 | 161 | ||
162 | 162 | ||
163 | union r_t { | 163 | union r_t { |
164 | struct regs_t b; | 164 | struct regs_t b; |
165 | struct pairs_t w; | 165 | struct pairs_t w; |
166 | byte r8_ [8]; // indexed | 166 | byte r8_ [8]; // indexed |
167 | uint16_t r16_ [4]; | 167 | uint16_t r16_ [4]; |
168 | } r; | 168 | } r; |
169 | r.b = R.b; | 169 | r.b = R.b; |
170 | 170 | ||
171 | cpu_time_t s_time = cpu->cpu_state_.time; | 171 | cpu_time_t s_time = cpu->cpu_state_.time; |
172 | int pc = R.pc; | 172 | int pc = R.pc; |
173 | int sp = R.sp; | 173 | int sp = R.sp; |
174 | int ix = R.ix; // TODO: keep in memory for direct access? | 174 | int ix = R.ix; // TODO: keep in memory for direct access? |
175 | int iy = R.iy; | 175 | int iy = R.iy; |
176 | int flags = R.b.flags; | 176 | int flags = R.b.flags; |
177 | 177 | ||
178 | //goto loop; // confuses optimizer | 178 | //goto loop; // confuses optimizer |
179 | s_time += 7; | 179 | s_time += 7; |
180 | pc -= 2; | 180 | pc -= 2; |
181 | 181 | ||
182 | call_not_taken: | 182 | call_not_taken: |
183 | s_time -= 7; | 183 | s_time -= 7; |
184 | jp_not_taken: | 184 | jp_not_taken: |
185 | pc += 2; | 185 | pc += 2; |
186 | loop: | 186 | loop: |
187 | 187 | ||
188 | check( (unsigned) pc < 0x10000 + 1 ); // +1 so emulator can catch wrap-around | 188 | check( (unsigned) pc < 0x10000 + 1 ); // +1 so emulator can catch wrap-around |
189 | check( (unsigned) sp < 0x10000 ); | 189 | check( (unsigned) sp < 0x10000 ); |
190 | check( (unsigned) flags < 0x100 ); | 190 | check( (unsigned) flags < 0x100 ); |
191 | check( (unsigned) ix < 0x10000 ); | 191 | check( (unsigned) ix < 0x10000 ); |
192 | check( (unsigned) iy < 0x10000 ); | 192 | check( (unsigned) iy < 0x10000 ); |
193 | 193 | ||
194 | byte const* instr = RW_PAGE( pc, read ); | 194 | byte const* instr = RW_PAGE( pc, read ); |
195 | 195 | ||
196 | int opcode; | 196 | int opcode; |
197 | 197 | ||
198 | if ( RW_OFFSET( ~0 ) == ~0 ) | 198 | if ( RW_OFFSET( ~0 ) == ~0 ) |
199 | { | 199 | { |
200 | opcode = instr [RW_OFFSET( pc )]; | 200 | opcode = instr [RW_OFFSET( pc )]; |
201 | pc++; | 201 | pc++; |
202 | instr += RW_OFFSET( pc ); | 202 | instr += RW_OFFSET( pc ); |
203 | } | 203 | } |
204 | else | 204 | else |
205 | { | 205 | { |
206 | instr += RW_OFFSET( pc ); | 206 | instr += RW_OFFSET( pc ); |
207 | opcode = *instr++; | 207 | opcode = *instr++; |
208 | pc++; | 208 | pc++; |
209 | } | 209 | } |
210 | 210 | ||
211 | static byte const clock_table [256 * 2] = { | 211 | static byte const clock_table [256 * 2] = { |
212 | // 0 1 2 3 4 5 6 7 8 9 A B C D E F | 212 | // 0 1 2 3 4 5 6 7 8 9 A B C D E F |
213 | 4,10, 7, 6, 4, 4, 7, 4, 4,11, 7, 6, 4, 4, 7, 4, // 0 | 213 | 4,10, 7, 6, 4, 4, 7, 4, 4,11, 7, 6, 4, 4, 7, 4, // 0 |
214 | 8,10, 7, 6, 4, 4, 7, 4,12,11, 7, 6, 4, 4, 7, 4, // 1 | 214 | 8,10, 7, 6, 4, 4, 7, 4,12,11, 7, 6, 4, 4, 7, 4, // 1 |
215 | 7,10,16, 6, 4, 4, 7, 4, 7,11,16, 6, 4, 4, 7, 4, // 2 | 215 | 7,10,16, 6, 4, 4, 7, 4, 7,11,16, 6, 4, 4, 7, 4, // 2 |
216 | 7,10,13, 6,11,11,10, 4, 7,11,13, 6, 4, 4, 7, 4, // 3 | 216 | 7,10,13, 6,11,11,10, 4, 7,11,13, 6, 4, 4, 7, 4, // 3 |
217 | 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 4 | 217 | 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 4 |
218 | 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 5 | 218 | 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 5 |
219 | 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 6 | 219 | 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 6 |
220 | 7, 7, 7, 7, 7, 7, 4, 7, 4, 4, 4, 4, 4, 4, 7, 4, // 7 | 220 | 7, 7, 7, 7, 7, 7, 4, 7, 4, 4, 4, 4, 4, 4, 7, 4, // 7 |
221 | 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 8 | 221 | 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 8 |
222 | 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 9 | 222 | 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 9 |
223 | 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // A | 223 | 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // A |
224 | 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // B | 224 | 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // B |
225 | 11,10,10,10,17,11, 7,11,11,10,10, 8,17,17, 7,11, // C | 225 | 11,10,10,10,17,11, 7,11,11,10,10, 8,17,17, 7,11, // C |
226 | 11,10,10,11,17,11, 7,11,11, 4,10,11,17, 8, 7,11, // D | 226 | 11,10,10,11,17,11, 7,11,11, 4,10,11,17, 8, 7,11, // D |
227 | 11,10,10,19,17,11, 7,11,11, 4,10, 4,17, 8, 7,11, // E | 227 | 11,10,10,19,17,11, 7,11,11, 4,10, 4,17, 8, 7,11, // E |
228 | 11,10,10, 4,17,11, 7,11,11, 6,10, 4,17, 8, 7,11, // F | 228 | 11,10,10, 4,17,11, 7,11,11, 6,10, 4,17, 8, 7,11, // F |
229 | 229 | ||
230 | // high four bits are $ED time - 8, low four bits are $DD/$FD time - 8 | 230 | // high four bits are $ED time - 8, low four bits are $DD/$FD time - 8 |
231 | //0 1 2 3 4 5 6 7 8 9 A B C D E F | 231 | //0 1 2 3 4 5 6 7 8 9 A B C D E F |
232 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00, | 232 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00, |
233 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00, | 233 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00, |
234 | 0x00,0x06,0x0C,0x02,0x00,0x00,0x03,0x00,0x00,0x07,0x0C,0x02,0x00,0x00,0x03,0x00, | 234 | 0x00,0x06,0x0C,0x02,0x00,0x00,0x03,0x00,0x00,0x07,0x0C,0x02,0x00,0x00,0x03,0x00, |
235 | 0x00,0x00,0x00,0x00,0x0F,0x0F,0x0B,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00, | 235 | 0x00,0x00,0x00,0x00,0x0F,0x0F,0x0B,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00, |
236 | 0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10, | 236 | 0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10, |
237 | 0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10, | 237 | 0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10, |
238 | 0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0xA0,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0xA0, | 238 | 0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0xA0,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0xA0, |
239 | 0x4B,0x4B,0x7B,0xCB,0x0B,0x6B,0x00,0x0B,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x00, | 239 | 0x4B,0x4B,0x7B,0xCB,0x0B,0x6B,0x00,0x0B,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x00, |
240 | 0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00, | 240 | 0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00, |
241 | 0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00, | 241 | 0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00, |
242 | 0x80,0x80,0x80,0x80,0x00,0x00,0x0B,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0B,0x00, | 242 | 0x80,0x80,0x80,0x80,0x00,0x00,0x0B,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0B,0x00, |
243 | 0xD0,0xD0,0xD0,0xD0,0x00,0x00,0x0B,0x00,0xD0,0xD0,0xD0,0xD0,0x00,0x00,0x0B,0x00, | 243 | 0xD0,0xD0,0xD0,0xD0,0x00,0x00,0x0B,0x00,0xD0,0xD0,0xD0,0xD0,0x00,0x00,0x0B,0x00, |
244 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00, | 244 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00, |
245 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 245 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
246 | 0x00,0x06,0x00,0x0F,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 246 | 0x00,0x06,0x00,0x0F,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
247 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00, | 247 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00, |
248 | }; | 248 | }; |
249 | 249 | ||
250 | if ( s_time >= 0 ) | 250 | if ( s_time >= 0 ) |
251 | goto out_of_time; | 251 | goto out_of_time; |
252 | s_time += clock_table [opcode]; | 252 | s_time += clock_table [opcode]; |
253 | 253 | ||
254 | #ifdef Z80_CPU_LOG_H | 254 | #ifdef Z80_CPU_LOG_H |
255 | //log_opcode( opcode, READ_CODE( pc ) ); | 255 | //log_opcode( opcode, READ_CODE( pc ) ); |
256 | z80_cpu_log( "log.txt", pc - 1, opcode, READ_CODE( pc ), | 256 | z80_cpu_log( "log.txt", pc - 1, opcode, READ_CODE( pc ), |
257 | READ_CODE( pc + 1 ), READ_CODE( pc + 2 ) ); | 257 | READ_CODE( pc + 1 ), READ_CODE( pc + 2 ) ); |
258 | z80_log_regs( r.b.a, r.w.bc, r.w.de, r.w.hl, sp, ix, iy ); | 258 | z80_log_regs( r.b.a, r.w.bc, r.w.de, r.w.hl, sp, ix, iy ); |
259 | #endif | 259 | #endif |
260 | 260 | ||
261 | #define GET_ADDR() GET_LE16( &INSTR( 0, pc ) ) | 261 | #define GET_ADDR() GET_LE16( &INSTR( 0, pc ) ) |
262 | 262 | ||
263 | int data; | 263 | int data; |
264 | data = INSTR( 0, pc ); | 264 | data = INSTR( 0, pc ); |
265 | 265 | ||
266 | switch ( opcode ) | 266 | switch ( opcode ) |
267 | { | 267 | { |
268 | // Common | 268 | // Common |
269 | 269 | ||
270 | case 0x00: // NOP | 270 | case 0x00: // NOP |
271 | CASE7( 40, 49, 52, 5B, 64, 6D, 7F ): // LD B,B etc. | 271 | CASE7( 40, 49, 52, 5B, 64, 6D, 7F ): // LD B,B etc. |
272 | goto loop; | 272 | goto loop; |
273 | 273 | ||
274 | case 0x08:{// EX AF,AF' | 274 | case 0x08:{// EX AF,AF' |
275 | EXX( b.a ); | 275 | EXX( b.a ); |
276 | EX( R.alt.b.flags, flags ); | 276 | EX( R.alt.b.flags, flags ); |
277 | goto loop; | 277 | goto loop; |
278 | } | 278 | } |
279 | 279 | ||
280 | case 0xD3: // OUT (imm),A | 280 | case 0xD3: // OUT (imm),A |
281 | pc++; | 281 | pc++; |
282 | OUT_PORT( (data + r.b.a * 0x100), r.b.a ); | 282 | OUT_PORT( (data + r.b.a * 0x100), r.b.a ); |
283 | goto loop; | 283 | goto loop; |
284 | 284 | ||
285 | case 0x2E: // LD L,imm | 285 | case 0x2E: // LD L,imm |
286 | pc++; | 286 | pc++; |
287 | r.b.l = data; | 287 | r.b.l = data; |
288 | goto loop; | 288 | goto loop; |
289 | 289 | ||
290 | case 0x3E: // LD A,imm | 290 | case 0x3E: // LD A,imm |
291 | pc++; | 291 | pc++; |
292 | r.b.a = data; | 292 | r.b.a = data; |
293 | goto loop; | 293 | goto loop; |
294 | 294 | ||
295 | case 0x3A:{// LD A,(addr) | 295 | case 0x3A:{// LD A,(addr) |
296 | int addr = GET_ADDR(); | 296 | int addr = GET_ADDR(); |
297 | pc += 2; | 297 | pc += 2; |
298 | r.b.a = READ_MEM( addr ); | 298 | r.b.a = READ_MEM( addr ); |
299 | goto loop; | 299 | goto loop; |
300 | } | 300 | } |
301 | 301 | ||
302 | // Conditional | 302 | // Conditional |
303 | 303 | ||
304 | #define ZERO (flags & Z40) | 304 | #define ZERO (flags & Z40) |
305 | #define CARRY (flags & C01) | 305 | #define CARRY (flags & C01) |
306 | #define EVEN (flags & P04) | 306 | #define EVEN (flags & P04) |
307 | #define MINUS (flags & S80) | 307 | #define MINUS (flags & S80) |
308 | 308 | ||
309 | // JR | 309 | // JR |
310 | // TODO: more efficient way to handle negative branch that wraps PC around | 310 | // TODO: more efficient way to handle negative branch that wraps PC around |
311 | #define JR_( cond, clocks ) {\ | 311 | #define JR_( cond, clocks ) {\ |
312 | pc++;\ | 312 | pc++;\ |
313 | if ( !(cond) )\ | 313 | if ( !(cond) )\ |
314 | goto loop;\ | 314 | goto loop;\ |
315 | int offset = SBYTE( data );\ | 315 | int offset = SBYTE( data );\ |
316 | pc = WORD( pc + offset );\ | 316 | pc = WORD( pc + offset );\ |
317 | s_time += clocks;\ | 317 | s_time += clocks;\ |
318 | goto loop;\ | 318 | goto loop;\ |
319 | } | 319 | } |
320 | 320 | ||
321 | #define JR( cond ) JR_( cond, 5 ) | 321 | #define JR( cond ) JR_( cond, 5 ) |
322 | 322 | ||
323 | case 0x20: JR( !ZERO ) // JR NZ,disp | 323 | case 0x20: JR( !ZERO ) // JR NZ,disp |
324 | case 0x28: JR( ZERO ) // JR Z,disp | 324 | case 0x28: JR( ZERO ) // JR Z,disp |
325 | case 0x30: JR( !CARRY ) // JR NC,disp | 325 | case 0x30: JR( !CARRY ) // JR NC,disp |
326 | case 0x38: JR( CARRY ) // JR C,disp | 326 | case 0x38: JR( CARRY ) // JR C,disp |
327 | case 0x18: JR_( true,0) // JR disp | 327 | case 0x18: JR_( true,0) // JR disp |
328 | 328 | ||
329 | case 0x10:{// DJNZ disp | 329 | case 0x10:{// DJNZ disp |
330 | int temp = r.b.b - 1; | 330 | int temp = r.b.b - 1; |
331 | r.b.b = temp; | 331 | r.b.b = temp; |
332 | JR( temp ) | 332 | JR( temp ) |
333 | } | 333 | } |
334 | 334 | ||
335 | // JP | 335 | // JP |
336 | #define JP( cond ) \ | 336 | #define JP( cond ) \ |
337 | if ( !(cond) )\ | 337 | if ( !(cond) )\ |
338 | goto jp_not_taken;\ | 338 | goto jp_not_taken;\ |
339 | pc = GET_ADDR();\ | 339 | pc = GET_ADDR();\ |
340 | goto loop; | 340 | goto loop; |
341 | 341 | ||
342 | case 0xC2: JP( !ZERO ) // JP NZ,addr | 342 | case 0xC2: JP( !ZERO ) // JP NZ,addr |
343 | case 0xCA: JP( ZERO ) // JP Z,addr | 343 | case 0xCA: JP( ZERO ) // JP Z,addr |
344 | case 0xD2: JP( !CARRY ) // JP NC,addr | 344 | case 0xD2: JP( !CARRY ) // JP NC,addr |
345 | case 0xDA: JP( CARRY ) // JP C,addr | 345 | case 0xDA: JP( CARRY ) // JP C,addr |
346 | case 0xE2: JP( !EVEN ) // JP PO,addr | 346 | case 0xE2: JP( !EVEN ) // JP PO,addr |
347 | case 0xEA: JP( EVEN ) // JP PE,addr | 347 | case 0xEA: JP( EVEN ) // JP PE,addr |
348 | case 0xF2: JP( !MINUS ) // JP P,addr | 348 | case 0xF2: JP( !MINUS ) // JP P,addr |
349 | case 0xFA: JP( MINUS ) // JP M,addr | 349 | case 0xFA: JP( MINUS ) // JP M,addr |
350 | 350 | ||
351 | case 0xC3: // JP addr | 351 | case 0xC3: // JP addr |
352 | pc = GET_ADDR(); | 352 | pc = GET_ADDR(); |
353 | goto loop; | 353 | goto loop; |
354 | 354 | ||
355 | case 0xE9: // JP HL | 355 | case 0xE9: // JP HL |
356 | pc = r.w.hl; | 356 | pc = r.w.hl; |
357 | goto loop; | 357 | goto loop; |
358 | 358 | ||
359 | // RET | 359 | // RET |
360 | #define RET( cond ) \ | 360 | #define RET( cond ) \ |
361 | if ( cond )\ | 361 | if ( cond )\ |
362 | goto ret_taken;\ | 362 | goto ret_taken;\ |
363 | s_time -= 6;\ | 363 | s_time -= 6;\ |
364 | goto loop; | 364 | goto loop; |
365 | 365 | ||
366 | case 0xC0: RET( !ZERO ) // RET NZ | 366 | case 0xC0: RET( !ZERO ) // RET NZ |
367 | case 0xC8: RET( ZERO ) // RET Z | 367 | case 0xC8: RET( ZERO ) // RET Z |
368 | case 0xD0: RET( !CARRY ) // RET NC | 368 | case 0xD0: RET( !CARRY ) // RET NC |
369 | case 0xD8: RET( CARRY ) // RET C | 369 | case 0xD8: RET( CARRY ) // RET C |
370 | case 0xE0: RET( !EVEN ) // RET PO | 370 | case 0xE0: RET( !EVEN ) // RET PO |
371 | case 0xE8: RET( EVEN ) // RET PE | 371 | case 0xE8: RET( EVEN ) // RET PE |
372 | case 0xF0: RET( !MINUS ) // RET P | 372 | case 0xF0: RET( !MINUS ) // RET P |
373 | case 0xF8: RET( MINUS ) // RET M | 373 | case 0xF8: RET( MINUS ) // RET M |
374 | 374 | ||
375 | case 0xC9: // RET | 375 | case 0xC9: // RET |
376 | ret_taken: | 376 | ret_taken: |
377 | pc = READ_WORD( sp ); | 377 | pc = READ_WORD( sp ); |
378 | sp = WORD( sp + 2 ); | 378 | sp = WORD( sp + 2 ); |
379 | goto loop; | 379 | goto loop; |
380 | 380 | ||
381 | // CALL | 381 | // CALL |
382 | #define CALL( cond ) \ | 382 | #define CALL( cond ) \ |
383 | if ( cond )\ | 383 | if ( cond )\ |
384 | goto call_taken;\ | 384 | goto call_taken;\ |
385 | goto call_not_taken; | 385 | goto call_not_taken; |
386 | 386 | ||
387 | case 0xC4: CALL( !ZERO ) // CALL NZ,addr | 387 | case 0xC4: CALL( !ZERO ) // CALL NZ,addr |
388 | case 0xCC: CALL( ZERO ) // CALL Z,addr | 388 | case 0xCC: CALL( ZERO ) // CALL Z,addr |
389 | case 0xD4: CALL( !CARRY ) // CALL NC,addr | 389 | case 0xD4: CALL( !CARRY ) // CALL NC,addr |
390 | case 0xDC: CALL( CARRY ) // CALL C,addr | 390 | case 0xDC: CALL( CARRY ) // CALL C,addr |
391 | case 0xE4: CALL( !EVEN ) // CALL PO,addr | 391 | case 0xE4: CALL( !EVEN ) // CALL PO,addr |
392 | case 0xEC: CALL( EVEN ) // CALL PE,addr | 392 | case 0xEC: CALL( EVEN ) // CALL PE,addr |
393 | case 0xF4: CALL( !MINUS ) // CALL P,addr | 393 | case 0xF4: CALL( !MINUS ) // CALL P,addr |
394 | case 0xFC: CALL( MINUS ) // CALL M,addr | 394 | case 0xFC: CALL( MINUS ) // CALL M,addr |
395 | 395 | ||
396 | case 0xCD:{// CALL addr | 396 | case 0xCD:{// CALL addr |
397 | call_taken: { | 397 | call_taken: { |
398 | int addr = pc + 2; | 398 | int addr = pc + 2; |
399 | pc = GET_ADDR(); | 399 | pc = GET_ADDR(); |
400 | sp = WORD( sp - 2 ); | 400 | sp = WORD( sp - 2 ); |
401 | WRITE_WORD( sp, addr ); | 401 | WRITE_WORD( sp, addr ); |
402 | goto loop; | 402 | goto loop; |
403 | } | 403 | } |
404 | } | 404 | } |
405 | 405 | ||
406 | case 0xFF: // RST | 406 | case 0xFF: // RST |
407 | #ifdef IDLE_ADDR | 407 | #ifdef IDLE_ADDR |
408 | if ( pc == IDLE_ADDR + 1 ) | 408 | if ( pc == IDLE_ADDR + 1 ) |
409 | goto hit_idle_addr; | 409 | goto hit_idle_addr; |
410 | #else | 410 | #else |
411 | if ( pc > 0x10000 ) | 411 | if ( pc > 0x10000 ) |
412 | { | 412 | { |
413 | pc = WORD( pc - 1 ); | 413 | pc = WORD( pc - 1 ); |
414 | s_time -= 11; | 414 | s_time -= 11; |
415 | goto loop; | 415 | goto loop; |
416 | } | 416 | } |
417 | #endif | 417 | #endif |
418 | CASE7( C7, CF, D7, DF, E7, EF, F7 ): | 418 | CASE7( C7, CF, D7, DF, E7, EF, F7 ): |
419 | data = pc; | 419 | data = pc; |
420 | pc = opcode & 0x38; | 420 | pc = opcode & 0x38; |
421 | #ifdef RST_BASE | 421 | #ifdef RST_BASE |
422 | pc += RST_BASE; | 422 | pc += RST_BASE; |
423 | #endif | 423 | #endif |
424 | goto push_data; | 424 | goto push_data; |
425 | 425 | ||
426 | // PUSH/POP | 426 | // PUSH/POP |
427 | case 0xF5: // PUSH AF | 427 | case 0xF5: // PUSH AF |
428 | data = r.b.a * 0x100u + flags; | 428 | data = r.b.a * 0x100u + flags; |
429 | goto push_data; | 429 | goto push_data; |
430 | 430 | ||
431 | case 0xC5: // PUSH BC | 431 | case 0xC5: // PUSH BC |
432 | case 0xD5: // PUSH DE | 432 | case 0xD5: // PUSH DE |
433 | case 0xE5: // PUSH HL | 433 | case 0xE5: // PUSH HL |
434 | data = R16( opcode, 4, 0xC5 ); | 434 | data = R16( opcode, 4, 0xC5 ); |
435 | push_data: | 435 | push_data: |
436 | sp = WORD( sp - 2 ); | 436 | sp = WORD( sp - 2 ); |
437 | WRITE_WORD( sp, data ); | 437 | WRITE_WORD( sp, data ); |
438 | goto loop; | 438 | goto loop; |
439 | 439 | ||
440 | case 0xF1: // POP AF | 440 | case 0xF1: // POP AF |
441 | flags = READ_MEM( sp ); | 441 | flags = READ_MEM( sp ); |
442 | r.b.a = READ_MEM( (sp + 1) ); | 442 | r.b.a = READ_MEM( (sp + 1) ); |
443 | sp = WORD( sp + 2 ); | 443 | sp = WORD( sp + 2 ); |
444 | goto loop; | 444 | goto loop; |
445 | 445 | ||
446 | case 0xC1: // POP BC | 446 | case 0xC1: // POP BC |
447 | case 0xD1: // POP DE | 447 | case 0xD1: // POP DE |
448 | case 0xE1: // POP HL | 448 | case 0xE1: // POP HL |
449 | R16( opcode, 4, 0xC1 ) = READ_WORD( sp ); | 449 | R16( opcode, 4, 0xC1 ) = READ_WORD( sp ); |
450 | sp = WORD( sp + 2 ); | 450 | sp = WORD( sp + 2 ); |
451 | goto loop; | 451 | goto loop; |
452 | 452 | ||
453 | // ADC/ADD/SBC/SUB | 453 | // ADC/ADD/SBC/SUB |
454 | case 0x96: // SUB (HL) | 454 | case 0x96: // SUB (HL) |
455 | case 0x86: // ADD (HL) | 455 | case 0x86: // ADD (HL) |
456 | flags &= ~C01; | 456 | flags &= ~C01; |
457 | case 0x9E: // SBC (HL) | 457 | case 0x9E: // SBC (HL) |
458 | case 0x8E: // ADC (HL) | 458 | case 0x8E: // ADC (HL) |
459 | data = READ_MEM( r.w.hl ); | 459 | data = READ_MEM( r.w.hl ); |
460 | goto adc_data; | 460 | goto adc_data; |
461 | 461 | ||
462 | case 0xD6: // SUB A,imm | 462 | case 0xD6: // SUB A,imm |
463 | case 0xC6: // ADD imm | 463 | case 0xC6: // ADD imm |
464 | flags &= ~C01; | 464 | flags &= ~C01; |
465 | case 0xDE: // SBC A,imm | 465 | case 0xDE: // SBC A,imm |
466 | case 0xCE: // ADC imm | 466 | case 0xCE: // ADC imm |
467 | pc++; | 467 | pc++; |
468 | goto adc_data; | 468 | goto adc_data; |
469 | 469 | ||
470 | CASE7( 90, 91, 92, 93, 94, 95, 97 ): // SUB r | 470 | CASE7( 90, 91, 92, 93, 94, 95, 97 ): // SUB r |
471 | CASE7( 80, 81, 82, 83, 84, 85, 87 ): // ADD r | 471 | CASE7( 80, 81, 82, 83, 84, 85, 87 ): // ADD r |
472 | flags &= ~C01; | 472 | flags &= ~C01; |
473 | CASE7( 98, 99, 9A, 9B, 9C, 9D, 9F ): // SBC r | 473 | CASE7( 98, 99, 9A, 9B, 9C, 9D, 9F ): // SBC r |
474 | CASE7( 88, 89, 8A, 8B, 8C, 8D, 8F ): // ADC r | 474 | CASE7( 88, 89, 8A, 8B, 8C, 8D, 8F ): // ADC r |
475 | data = R8( opcode & 7, 0 ); | 475 | data = R8( opcode & 7, 0 ); |
476 | adc_data: { | 476 | adc_data: { |
477 | int result = data + (flags & C01); | 477 | int result = data + (flags & C01); |
478 | data ^= r.b.a; | 478 | data ^= r.b.a; |
479 | flags = opcode >> 3 & N02; // bit 4 is set in subtract opcodes | 479 | flags = opcode >> 3 & N02; // bit 4 is set in subtract opcodes |
480 | if ( flags ) | 480 | if ( flags ) |
481 | result = -result; | 481 | result = -result; |
482 | result += r.b.a; | 482 | result += r.b.a; |
483 | data ^= result; | 483 | data ^= result; |
484 | flags +=(data & H10) + | 484 | flags +=(data & H10) + |
485 | ((data + 0x80) >> 6 & V04) + | 485 | ((data + 0x80) >> 6 & V04) + |
486 | SZ28C( result & 0x1FF ); | 486 | SZ28C( result & 0x1FF ); |
487 | r.b.a = result; | 487 | r.b.a = result; |
488 | goto loop; | 488 | goto loop; |
489 | } | 489 | } |
490 | 490 | ||
491 | // CP | 491 | // CP |
492 | case 0xBE: // CP (HL) | 492 | case 0xBE: // CP (HL) |
493 | data = READ_MEM( r.w.hl ); | 493 | data = READ_MEM( r.w.hl ); |
494 | goto cp_data; | 494 | goto cp_data; |
495 | 495 | ||
496 | case 0xFE: // CP imm | 496 | case 0xFE: // CP imm |
497 | pc++; | 497 | pc++; |
498 | goto cp_data; | 498 | goto cp_data; |
499 | 499 | ||
500 | CASE7( B8, B9, BA, BB, BC, BD, BF ): // CP r | 500 | CASE7( B8, B9, BA, BB, BC, BD, BF ): // CP r |
501 | data = R8( opcode, 0xB8 ); | 501 | data = R8( opcode, 0xB8 ); |
502 | cp_data: { | 502 | cp_data: { |
503 | int result = r.b.a - data; | 503 | int result = r.b.a - data; |
504 | flags = N02 + (data & (F20 | F08)) + (result >> 8 & C01); | 504 | flags = N02 + (data & (F20 | F08)) + (result >> 8 & C01); |
505 | data ^= r.b.a; | 505 | data ^= r.b.a; |
506 | flags +=(((result ^ r.b.a) & data) >> 5 & V04) + | 506 | flags +=(((result ^ r.b.a) & data) >> 5 & V04) + |
507 | (((data & H10) ^ result) & (S80 | H10)); | 507 | (((data & H10) ^ result) & (S80 | H10)); |
508 | if ( BYTE( result ) ) | 508 | if ( BYTE( result ) ) |
509 | goto loop; | 509 | goto loop; |
510 | flags += Z40; | 510 | flags += Z40; |
511 | goto loop; | 511 | goto loop; |
512 | } | 512 | } |
513 | 513 | ||
514 | // ADD HL,r.w | 514 | // ADD HL,r.w |
515 | 515 | ||
516 | case 0x39: // ADD HL,SP | 516 | case 0x39: // ADD HL,SP |
517 | data = sp; | 517 | data = sp; |
518 | goto add_hl_data; | 518 | goto add_hl_data; |
519 | 519 | ||
520 | case 0x09: // ADD HL,BC | 520 | case 0x09: // ADD HL,BC |
521 | case 0x19: // ADD HL,DE | 521 | case 0x19: // ADD HL,DE |
522 | case 0x29: // ADD HL,HL | 522 | case 0x29: // ADD HL,HL |
523 | data = R16( opcode, 4, 0x09 ); | 523 | data = R16( opcode, 4, 0x09 ); |
524 | add_hl_data: { | 524 | add_hl_data: { |
525 | int sum = r.w.hl + data; | 525 | int sum = r.w.hl + data; |
526 | data ^= r.w.hl; | 526 | data ^= r.w.hl; |
527 | r.w.hl = sum; | 527 | r.w.hl = sum; |
528 | flags = (flags & (S80 | Z40 | V04)) + | 528 | flags = (flags & (S80 | Z40 | V04)) + |
529 | (sum >> 16) + | 529 | (sum >> 16) + |
530 | (sum >> 8 & (F20 | F08)) + | 530 | (sum >> 8 & (F20 | F08)) + |
531 | ((data ^ sum) >> 8 & H10); | 531 | ((data ^ sum) >> 8 & H10); |
532 | goto loop; | 532 | goto loop; |
533 | } | 533 | } |
534 | 534 | ||
535 | case 0x27:{// DAA | 535 | case 0x27:{// DAA |
536 | int a = r.b.a; | 536 | int a = r.b.a; |
537 | if ( a > 0x99 ) | 537 | if ( a > 0x99 ) |
538 | flags |= C01; | 538 | flags |= C01; |
539 | 539 | ||
540 | int adjust = 0x60 * (flags & C01); | 540 | int adjust = 0x60 * (flags & C01); |
541 | 541 | ||
542 | if ( flags & H10 || (a & 0x0F) > 9 ) | 542 | if ( flags & H10 || (a & 0x0F) > 9 ) |
543 | adjust += 0x06; | 543 | adjust += 0x06; |
544 | 544 | ||
545 | if ( flags & N02 ) | 545 | if ( flags & N02 ) |
546 | adjust = -adjust; | 546 | adjust = -adjust; |
547 | a += adjust; | 547 | a += adjust; |
548 | 548 | ||
549 | flags = (flags & (C01 | N02)) + | 549 | flags = (flags & (C01 | N02)) + |
550 | ((r.b.a ^ a) & H10) + | 550 | ((r.b.a ^ a) & H10) + |
551 | SZ28P( BYTE( a ) ); | 551 | SZ28P( BYTE( a ) ); |
552 | r.b.a = a; | 552 | r.b.a = a; |
553 | goto loop; | 553 | goto loop; |
554 | } | 554 | } |
555 | 555 | ||
556 | // INC/DEC | 556 | // INC/DEC |
557 | case 0x34: // INC (HL) | 557 | case 0x34: // INC (HL) |
558 | data = READ_MEM( r.w.hl ) + 1; | 558 | data = READ_MEM( r.w.hl ) + 1; |
559 | WRITE_MEM( r.w.hl, data ); | 559 | WRITE_MEM( r.w.hl, data ); |
560 | goto inc_set_flags; | 560 | goto inc_set_flags; |
561 | 561 | ||
562 | CASE7( 04, 0C, 14, 1C, 24, 2C, 3C ): // INC r | 562 | CASE7( 04, 0C, 14, 1C, 24, 2C, 3C ): // INC r |
563 | data = ++R8( opcode >> 3, 0 ); | 563 | data = ++R8( opcode >> 3, 0 ); |
564 | inc_set_flags: | 564 | inc_set_flags: |
565 | flags = (flags & C01) + | 565 | flags = (flags & C01) + |
566 | (((data & 0x0F) - 1) & H10) + | 566 | (((data & 0x0F) - 1) & H10) + |
567 | SZ28( BYTE( data ) ); | 567 | SZ28( BYTE( data ) ); |
568 | if ( data != 0x80 ) | 568 | if ( data != 0x80 ) |
569 | goto loop; | 569 | goto loop; |
570 | flags += V04; | 570 | flags += V04; |
571 | goto loop; | 571 | goto loop; |
572 | 572 | ||
573 | case 0x35: // DEC (HL) | 573 | case 0x35: // DEC (HL) |
574 | data = READ_MEM( r.w.hl ) - 1; | 574 | data = READ_MEM( r.w.hl ) - 1; |
575 | WRITE_MEM( r.w.hl, data ); | 575 | WRITE_MEM( r.w.hl, data ); |
576 | goto dec_set_flags; | 576 | goto dec_set_flags; |
577 | 577 | ||
578 | CASE7( 05, 0D, 15, 1D, 25, 2D, 3D ): // DEC r | 578 | CASE7( 05, 0D, 15, 1D, 25, 2D, 3D ): // DEC r |
579 | data = --R8( opcode >> 3, 0 ); | 579 | data = --R8( opcode >> 3, 0 ); |
580 | dec_set_flags: | 580 | dec_set_flags: |
581 | flags = (flags & C01) + N02 + | 581 | flags = (flags & C01) + N02 + |
582 | (((data & 0x0F) + 1) & H10) + | 582 | (((data & 0x0F) + 1) & H10) + |
583 | SZ28( BYTE( data ) ); | 583 | SZ28( BYTE( data ) ); |
584 | if ( data != 0x7F ) | 584 | if ( data != 0x7F ) |
585 | goto loop; | 585 | goto loop; |
586 | flags += V04; | 586 | flags += V04; |
587 | goto loop; | 587 | goto loop; |
588 | 588 | ||
589 | case 0x03: // INC BC | 589 | case 0x03: // INC BC |
590 | case 0x13: // INC DE | 590 | case 0x13: // INC DE |
591 | case 0x23: // INC HL | 591 | case 0x23: // INC HL |
592 | R16( opcode, 4, 0x03 )++; | 592 | R16( opcode, 4, 0x03 )++; |
593 | goto loop; | 593 | goto loop; |
594 | 594 | ||
595 | case 0x33: // INC SP | 595 | case 0x33: // INC SP |
596 | sp = WORD( sp + 1 ); | 596 | sp = WORD( sp + 1 ); |
597 | goto loop; | 597 | goto loop; |
598 | 598 | ||
599 | case 0x0B: // DEC BC | 599 | case 0x0B: // DEC BC |
600 | case 0x1B: // DEC DE | 600 | case 0x1B: // DEC DE |
601 | case 0x2B: // DEC HL | 601 | case 0x2B: // DEC HL |
602 | R16( opcode, 4, 0x0B )--; | 602 | R16( opcode, 4, 0x0B )--; |
603 | goto loop; | 603 | goto loop; |
604 | 604 | ||
605 | case 0x3B: // DEC SP | 605 | case 0x3B: // DEC SP |
606 | sp = WORD( sp - 1 ); | 606 | sp = WORD( sp - 1 ); |
607 | goto loop; | 607 | goto loop; |
608 | 608 | ||
609 | // AND | 609 | // AND |
610 | case 0xA6: // AND (HL) | 610 | case 0xA6: // AND (HL) |
611 | data = READ_MEM( r.w.hl ); | 611 | data = READ_MEM( r.w.hl ); |
612 | goto and_data; | 612 | goto and_data; |
613 | 613 | ||
614 | case 0xE6: // AND imm | 614 | case 0xE6: // AND imm |
615 | pc++; | 615 | pc++; |
616 | goto and_data; | 616 | goto and_data; |
617 | 617 | ||
618 | CASE7( A0, A1, A2, A3, A4, A5, A7 ): // AND r | 618 | CASE7( A0, A1, A2, A3, A4, A5, A7 ): // AND r |
619 | data = R8( opcode, 0xA0 ); | 619 | data = R8( opcode, 0xA0 ); |
620 | and_data: | 620 | and_data: |
621 | r.b.a &= data; | 621 | r.b.a &= data; |
622 | flags = SZ28P( r.b.a ) + H10; | 622 | flags = SZ28P( r.b.a ) + H10; |
623 | goto loop; | 623 | goto loop; |
624 | 624 | ||
625 | // OR | 625 | // OR |
626 | case 0xB6: // OR (HL) | 626 | case 0xB6: // OR (HL) |
627 | data = READ_MEM( r.w.hl ); | 627 | data = READ_MEM( r.w.hl ); |
628 | goto or_data; | 628 | goto or_data; |
629 | 629 | ||
630 | case 0xF6: // OR imm | 630 | case 0xF6: // OR imm |
631 | pc++; | 631 | pc++; |
632 | goto or_data; | 632 | goto or_data; |
633 | 633 | ||
634 | CASE7( B0, B1, B2, B3, B4, B5, B7 ): // OR r | 634 | CASE7( B0, B1, B2, B3, B4, B5, B7 ): // OR r |
635 | data = R8( opcode, 0xB0 ); | 635 | data = R8( opcode, 0xB0 ); |
636 | or_data: | 636 | or_data: |
637 | r.b.a |= data; | 637 | r.b.a |= data; |
638 | flags = SZ28P( r.b.a ); | 638 | flags = SZ28P( r.b.a ); |
639 | goto loop; | 639 | goto loop; |
640 | 640 | ||
641 | // XOR | 641 | // XOR |
642 | case 0xAE: // XOR (HL) | 642 | case 0xAE: // XOR (HL) |
643 | data = READ_MEM( r.w.hl ); | 643 | data = READ_MEM( r.w.hl ); |
644 | goto xor_data; | 644 | goto xor_data; |
645 | 645 | ||
646 | case 0xEE: // XOR imm | 646 | case 0xEE: // XOR imm |
647 | pc++; | 647 | pc++; |
648 | goto xor_data; | 648 | goto xor_data; |
649 | 649 | ||
650 | CASE7( A8, A9, AA, AB, AC, AD, AF ): // XOR r | 650 | CASE7( A8, A9, AA, AB, AC, AD, AF ): // XOR r |
651 | data = R8( opcode, 0xA8 ); | 651 | data = R8( opcode, 0xA8 ); |
652 | xor_data: | 652 | xor_data: |
653 | r.b.a ^= data; | 653 | r.b.a ^= data; |
654 | flags = SZ28P( r.b.a ); | 654 | flags = SZ28P( r.b.a ); |
655 | goto loop; | 655 | goto loop; |
656 | 656 | ||
657 | // LD | 657 | // LD |
658 | CASE7( 70, 71, 72, 73, 74, 75, 77 ): // LD (HL),r | 658 | CASE7( 70, 71, 72, 73, 74, 75, 77 ): // LD (HL),r |
659 | WRITE_MEM( r.w.hl, R8( opcode, 0x70 ) ); | 659 | WRITE_MEM( r.w.hl, R8( opcode, 0x70 ) ); |
660 | goto loop; | 660 | goto loop; |
661 | 661 | ||
662 | CASE6( 41, 42, 43, 44, 45, 47 ): // LD B,r | 662 | CASE6( 41, 42, 43, 44, 45, 47 ): // LD B,r |
663 | CASE6( 48, 4A, 4B, 4C, 4D, 4F ): // LD C,r | 663 | CASE6( 48, 4A, 4B, 4C, 4D, 4F ): // LD C,r |
664 | CASE6( 50, 51, 53, 54, 55, 57 ): // LD D,r | 664 | CASE6( 50, 51, 53, 54, 55, 57 ): // LD D,r |
665 | CASE6( 58, 59, 5A, 5C, 5D, 5F ): // LD E,r | 665 | CASE6( 58, 59, 5A, 5C, 5D, 5F ): // LD E,r |
666 | CASE6( 60, 61, 62, 63, 65, 67 ): // LD H,r | 666 | CASE6( 60, 61, 62, 63, 65, 67 ): // LD H,r |
667 | CASE6( 68, 69, 6A, 6B, 6C, 6F ): // LD L,r | 667 | CASE6( 68, 69, 6A, 6B, 6C, 6F ): // LD L,r |
668 | CASE6( 78, 79, 7A, 7B, 7C, 7D ): // LD A,r | 668 | CASE6( 78, 79, 7A, 7B, 7C, 7D ): // LD A,r |
669 | R8( opcode >> 3 & 7, 0 ) = R8( opcode & 7, 0 ); | 669 | R8( opcode >> 3 & 7, 0 ) = R8( opcode & 7, 0 ); |
670 | goto loop; | 670 | goto loop; |
671 | 671 | ||
672 | CASE5( 06, 0E, 16, 1E, 26 ): // LD r,imm | 672 | CASE5( 06, 0E, 16, 1E, 26 ): // LD r,imm |
673 | R8( opcode >> 3, 0 ) = data; | 673 | R8( opcode >> 3, 0 ) = data; |
674 | pc++; | 674 | pc++; |
675 | goto loop; | 675 | goto loop; |
676 | 676 | ||
677 | case 0x36: // LD (HL),imm | 677 | case 0x36: // LD (HL),imm |
678 | pc++; | 678 | pc++; |
679 | WRITE_MEM( r.w.hl, data ); | 679 | WRITE_MEM( r.w.hl, data ); |
680 | goto loop; | 680 | goto loop; |
681 | 681 | ||
682 | CASE7( 46, 4E, 56, 5E, 66, 6E, 7E ): // LD r,(HL) | 682 | CASE7( 46, 4E, 56, 5E, 66, 6E, 7E ): // LD r,(HL) |
683 | R8( opcode >> 3, 8 ) = READ_MEM( r.w.hl ); | 683 | R8( opcode >> 3, 8 ) = READ_MEM( r.w.hl ); |
684 | goto loop; | 684 | goto loop; |
685 | 685 | ||
686 | case 0x01: // LD r.w,imm | 686 | case 0x01: // LD r.w,imm |
687 | case 0x11: | 687 | case 0x11: |
688 | case 0x21: | 688 | case 0x21: |
689 | R16( opcode, 4, 0x01 ) = GET_ADDR(); | 689 | R16( opcode, 4, 0x01 ) = GET_ADDR(); |
690 | pc += 2; | 690 | pc += 2; |
691 | goto loop; | 691 | goto loop; |
692 | 692 | ||
693 | case 0x31: // LD sp,imm | 693 | case 0x31: // LD sp,imm |
694 | sp = GET_ADDR(); | 694 | sp = GET_ADDR(); |
695 | pc += 2; | 695 | pc += 2; |
696 | goto loop; | 696 | goto loop; |
697 | 697 | ||
698 | case 0x2A:{// LD HL,(addr) | 698 | case 0x2A:{// LD HL,(addr) |
699 | int addr = GET_ADDR(); | 699 | int addr = GET_ADDR(); |
700 | pc += 2; | 700 | pc += 2; |
701 | r.w.hl = READ_WORD( addr ); | 701 | r.w.hl = READ_WORD( addr ); |
702 | goto loop; | 702 | goto loop; |
703 | } | 703 | } |
704 | 704 | ||
705 | case 0x32:{// LD (addr),A | 705 | case 0x32:{// LD (addr),A |
706 | int addr = GET_ADDR(); | 706 | int addr = GET_ADDR(); |
707 | pc += 2; | 707 | pc += 2; |
708 | WRITE_MEM( addr, r.b.a ); | 708 | WRITE_MEM( addr, r.b.a ); |
709 | goto loop; | 709 | goto loop; |
710 | } | 710 | } |
711 | 711 | ||
712 | case 0x22:{// LD (addr),HL | 712 | case 0x22:{// LD (addr),HL |
713 | int addr = GET_ADDR(); | 713 | int addr = GET_ADDR(); |
714 | pc += 2; | 714 | pc += 2; |
715 | WRITE_WORD( addr, r.w.hl ); | 715 | WRITE_WORD( addr, r.w.hl ); |
716 | goto loop; | 716 | goto loop; |
717 | } | 717 | } |
718 | 718 | ||
719 | case 0x02: // LD (BC),A | 719 | case 0x02: // LD (BC),A |
720 | case 0x12: // LD (DE),A | 720 | case 0x12: // LD (DE),A |
721 | WRITE_MEM( R16( opcode, 4, 0x02 ), r.b.a ); | 721 | WRITE_MEM( R16( opcode, 4, 0x02 ), r.b.a ); |
722 | goto loop; | 722 | goto loop; |
723 | 723 | ||
724 | case 0x0A: // LD A,(BC) | 724 | case 0x0A: // LD A,(BC) |
725 | case 0x1A: // LD A,(DE) | 725 | case 0x1A: // LD A,(DE) |
726 | r.b.a = READ_MEM( R16( opcode, 4, 0x0A ) ); | 726 | r.b.a = READ_MEM( R16( opcode, 4, 0x0A ) ); |
727 | goto loop; | 727 | goto loop; |
728 | 728 | ||
729 | case 0xF9: // LD SP,HL | 729 | case 0xF9: // LD SP,HL |
730 | sp = r.w.hl; | 730 | sp = r.w.hl; |
731 | goto loop; | 731 | goto loop; |
732 | 732 | ||
733 | // Rotate | 733 | // Rotate |
734 | 734 | ||
735 | case 0x07:{// RLCA | 735 | case 0x07:{// RLCA |
736 | int temp = r.b.a; | 736 | int temp = r.b.a; |
737 | temp = (temp << 1) + (temp >> 7); | 737 | temp = (temp << 1) + (temp >> 7); |
738 | flags = (flags & (S80 | Z40 | P04)) + | 738 | flags = (flags & (S80 | Z40 | P04)) + |
739 | (temp & (F20 | F08 | C01)); | 739 | (temp & (F20 | F08 | C01)); |
740 | r.b.a = temp; | 740 | r.b.a = temp; |
741 | goto loop; | 741 | goto loop; |
742 | } | 742 | } |
743 | 743 | ||
744 | case 0x0F:{// RRCA | 744 | case 0x0F:{// RRCA |
745 | int temp = r.b.a; | 745 | int temp = r.b.a; |
746 | flags = (flags & (S80 | Z40 | P04)) + | 746 | flags = (flags & (S80 | Z40 | P04)) + |
747 | (temp & C01); | 747 | (temp & C01); |
748 | temp = (temp << 7) + (temp >> 1); | 748 | temp = (temp << 7) + (temp >> 1); |
749 | flags += temp & (F20 | F08); | 749 | flags += temp & (F20 | F08); |
750 | r.b.a = temp; | 750 | r.b.a = temp; |
751 | goto loop; | 751 | goto loop; |
752 | } | 752 | } |
753 | 753 | ||
754 | case 0x17:{// RLA | 754 | case 0x17:{// RLA |
755 | int temp = (r.b.a << 1) + (flags & C01); | 755 | int temp = (r.b.a << 1) + (flags & C01); |
756 | flags = (flags & (S80 | Z40 | P04)) + | 756 | flags = (flags & (S80 | Z40 | P04)) + |
757 | (temp & (F20 | F08)) + | 757 | (temp & (F20 | F08)) + |
758 | (temp >> 8); | 758 | (temp >> 8); |
759 | r.b.a = temp; | 759 | r.b.a = temp; |
760 | goto loop; | 760 | goto loop; |
761 | } | 761 | } |
762 | 762 | ||
763 | case 0x1F:{// RRA | 763 | case 0x1F:{// RRA |
764 | int temp = (flags << 7) + (r.b.a >> 1); | 764 | int temp = (flags << 7) + (r.b.a >> 1); |
765 | flags = (flags & (S80 | Z40 | P04)) + | 765 | flags = (flags & (S80 | Z40 | P04)) + |
766 | (temp & (F20 | F08)) + | 766 | (temp & (F20 | F08)) + |
767 | (r.b.a & C01); | 767 | (r.b.a & C01); |
768 | r.b.a = temp; | 768 | r.b.a = temp; |
769 | goto loop; | 769 | goto loop; |
770 | } | 770 | } |
771 | 771 | ||
772 | // Misc | 772 | // Misc |
773 | case 0x2F:{// CPL | 773 | case 0x2F:{// CPL |
774 | int temp = ~r.b.a; | 774 | int temp = ~r.b.a; |
775 | flags = (flags & (S80 | Z40 | P04 | C01)) + | 775 | flags = (flags & (S80 | Z40 | P04 | C01)) + |
776 | (temp & (F20 | F08)) + | 776 | (temp & (F20 | F08)) + |
777 | (H10 | N02); | 777 | (H10 | N02); |
778 | r.b.a = temp; | 778 | r.b.a = temp; |
779 | goto loop; | 779 | goto loop; |
780 | } | 780 | } |
781 | 781 | ||
782 | case 0x3F:{// CCF | 782 | case 0x3F:{// CCF |
783 | flags = ((flags & (S80 | Z40 | P04 | C01)) ^ C01) + | 783 | flags = ((flags & (S80 | Z40 | P04 | C01)) ^ C01) + |
784 | (flags << 4 & H10) + | 784 | (flags << 4 & H10) + |
785 | (r.b.a & (F20 | F08)); | 785 | (r.b.a & (F20 | F08)); |
786 | goto loop; | 786 | goto loop; |
787 | } | 787 | } |
788 | 788 | ||
789 | case 0x37: // SCF | 789 | case 0x37: // SCF |
790 | flags = ((flags & (S80 | Z40 | P04)) | C01) + | 790 | flags = ((flags & (S80 | Z40 | P04)) | C01) + |
791 | (r.b.a & (F20 | F08)); | 791 | (r.b.a & (F20 | F08)); |
792 | goto loop; | 792 | goto loop; |
793 | 793 | ||
794 | case 0xDB: // IN A,(imm) | 794 | case 0xDB: // IN A,(imm) |
795 | pc++; | 795 | pc++; |
796 | r.b.a = IN_PORT( (data + r.b.a * 0x100) ); | 796 | r.b.a = IN_PORT( (data + r.b.a * 0x100) ); |
797 | goto loop; | 797 | goto loop; |
798 | 798 | ||
799 | case 0xE3:{// EX (SP),HL | 799 | case 0xE3:{// EX (SP),HL |
800 | int temp = READ_WORD( sp ); | 800 | int temp = READ_WORD( sp ); |
801 | WRITE_WORD( sp, r.w.hl ); | 801 | WRITE_WORD( sp, r.w.hl ); |
802 | r.w.hl = temp; | 802 | r.w.hl = temp; |
803 | goto loop; | 803 | goto loop; |
804 | } | 804 | } |
805 | 805 | ||
806 | case 0xEB: // EX DE,HL | 806 | case 0xEB: // EX DE,HL |
807 | EX( r.w.hl, r.w.de ); | 807 | EX( r.w.hl, r.w.de ); |
808 | goto loop; | 808 | goto loop; |
809 | 809 | ||
810 | case 0xD9: // EXX DE,HL | 810 | case 0xD9: // EXX DE,HL |
811 | EXX( w.bc ); | 811 | EXX( w.bc ); |
812 | EXX( w.de ); | 812 | EXX( w.de ); |
813 | EXX( w.hl ); | 813 | EXX( w.hl ); |
814 | goto loop; | 814 | goto loop; |
815 | 815 | ||
816 | case 0xF3: // DI | 816 | case 0xF3: // DI |
817 | R.iff1 = 0; | 817 | R.iff1 = 0; |
818 | R.iff2 = 0; | 818 | R.iff2 = 0; |
819 | goto loop; | 819 | goto loop; |
820 | 820 | ||
821 | case 0xFB: // EI | 821 | case 0xFB: // EI |
822 | R.iff1 = 1; | 822 | R.iff1 = 1; |
823 | R.iff2 = 1; | 823 | R.iff2 = 1; |
824 | // TODO: delayed effect | 824 | // TODO: delayed effect |
825 | goto loop; | 825 | goto loop; |
826 | 826 | ||
827 | case 0x76: // HALT | 827 | case 0x76: // HALT |
828 | goto halt; | 828 | goto halt; |
829 | 829 | ||
830 | //////////////////////////////////////// CB prefix | 830 | //////////////////////////////////////// CB prefix |
831 | { | 831 | { |
832 | case 0xCB: | 832 | case 0xCB: |
833 | pc++; | 833 | pc++; |
834 | switch ( data ) | 834 | switch ( data ) |
835 | { | 835 | { |
836 | 836 | ||
837 | // Rotate left | 837 | // Rotate left |
838 | 838 | ||
839 | #define RLC( read, write ) {\ | 839 | #define RLC( read, write ) {\ |
840 | int result = read;\ | 840 | int result = read;\ |
841 | result = BYTE( result << 1 ) + (result >> 7);\ | 841 | result = BYTE( result << 1 ) + (result >> 7);\ |
842 | flags = SZ28P( result ) + (result & C01);\ | 842 | flags = SZ28P( result ) + (result & C01);\ |
843 | write;\ | 843 | write;\ |
844 | goto loop;\ | 844 | goto loop;\ |
845 | } | 845 | } |
846 | 846 | ||
847 | case 0x06: // RLC (HL) | 847 | case 0x06: // RLC (HL) |
848 | s_time += 7; | 848 | s_time += 7; |
849 | data = r.w.hl; | 849 | data = r.w.hl; |
850 | rlc_data_addr: | 850 | rlc_data_addr: |
851 | RLC( READ_MEM( data ), WRITE_MEM( data, result ) ) | 851 | RLC( READ_MEM( data ), WRITE_MEM( data, result ) ) |
852 | 852 | ||
853 | CASE7( 00, 01, 02, 03, 04, 05, 07 ):{// RLC r | 853 | CASE7( 00, 01, 02, 03, 04, 05, 07 ):{// RLC r |
854 | byte* reg = &R8( data, 0 ); | 854 | byte* reg = &R8( data, 0 ); |
855 | RLC( *reg, *reg = result ) | 855 | RLC( *reg, *reg = result ) |
856 | } | 856 | } |
857 | 857 | ||
858 | #define RL( read, write ) {\ | 858 | #define RL( read, write ) {\ |
859 | int result = (read << 1) + (flags & C01);\ | 859 | int result = (read << 1) + (flags & C01);\ |
860 | flags = SZ28PC( result );\ | 860 | flags = SZ28PC( result );\ |
861 | write;\ | 861 | write;\ |
862 | goto loop;\ | 862 | goto loop;\ |
863 | } | 863 | } |
864 | 864 | ||
865 | case 0x16: // RL (HL) | 865 | case 0x16: // RL (HL) |
866 | s_time += 7; | 866 | s_time += 7; |
867 | data = r.w.hl; | 867 | data = r.w.hl; |
868 | rl_data_addr: | 868 | rl_data_addr: |
869 | RL( READ_MEM( data ), WRITE_MEM( data, result ) ) | 869 | RL( READ_MEM( data ), WRITE_MEM( data, result ) ) |
870 | 870 | ||
871 | CASE7( 10, 11, 12, 13, 14, 15, 17 ):{// RL r | 871 | CASE7( 10, 11, 12, 13, 14, 15, 17 ):{// RL r |
872 | byte* reg = &R8( data, 0x10 ); | 872 | byte* reg = &R8( data, 0x10 ); |
873 | RL( *reg, *reg = result ) | 873 | RL( *reg, *reg = result ) |
874 | } | 874 | } |
875 | 875 | ||
876 | #define SLA( read, low_bit, write ) {\ | 876 | #define SLA( read, low_bit, write ) {\ |
877 | int result = (read << 1) + low_bit;\ | 877 | int result = (read << 1) + low_bit;\ |
878 | flags = SZ28PC( result );\ | 878 | flags = SZ28PC( result );\ |
879 | write;\ | 879 | write;\ |
880 | goto loop;\ | 880 | goto loop;\ |
881 | } | 881 | } |
882 | 882 | ||
883 | case 0x26: // SLA (HL) | 883 | case 0x26: // SLA (HL) |
884 | s_time += 7; | 884 | s_time += 7; |
885 | data = r.w.hl; | 885 | data = r.w.hl; |
886 | sla_data_addr: | 886 | sla_data_addr: |
887 | SLA( READ_MEM( data ), 0, WRITE_MEM( data, result ) ) | 887 | SLA( READ_MEM( data ), 0, WRITE_MEM( data, result ) ) |
888 | 888 | ||
889 | CASE7( 20, 21, 22, 23, 24, 25, 27 ):{// SLA r | 889 | CASE7( 20, 21, 22, 23, 24, 25, 27 ):{// SLA r |
890 | byte* reg = &R8( data, 0x20 ); | 890 | byte* reg = &R8( data, 0x20 ); |
891 | SLA( *reg, 0, *reg = result ) | 891 | SLA( *reg, 0, *reg = result ) |
892 | } | 892 | } |
893 | 893 | ||
894 | case 0x36: // SLL (HL) | 894 | case 0x36: // SLL (HL) |
895 | s_time += 7; | 895 | s_time += 7; |
896 | data = r.w.hl; | 896 | data = r.w.hl; |
897 | sll_data_addr: | 897 | sll_data_addr: |
898 | SLA( READ_MEM( data ), 1, WRITE_MEM( data, result ) ) | 898 | SLA( READ_MEM( data ), 1, WRITE_MEM( data, result ) ) |
899 | 899 | ||
900 | CASE7( 30, 31, 32, 33, 34, 35, 37 ):{// SLL r | 900 | CASE7( 30, 31, 32, 33, 34, 35, 37 ):{// SLL r |
901 | byte* reg = &R8( data, 0x30 ); | 901 | byte* reg = &R8( data, 0x30 ); |
902 | SLA( *reg, 1, *reg = result ) | 902 | SLA( *reg, 1, *reg = result ) |
903 | } | 903 | } |
904 | 904 | ||
905 | // Rotate right | 905 | // Rotate right |
906 | 906 | ||
907 | #define RRC( read, write ) {\ | 907 | #define RRC( read, write ) {\ |
908 | int result = read;\ | 908 | int result = read;\ |
909 | flags = result & C01;\ | 909 | flags = result & C01;\ |
910 | result = BYTE( result << 7 ) + (result >> 1);\ | 910 | result = BYTE( result << 7 ) + (result >> 1);\ |
911 | flags += SZ28P( result );\ | 911 | flags += SZ28P( result );\ |
912 | write;\ | 912 | write;\ |
913 | goto loop;\ | 913 | goto loop;\ |
914 | } | 914 | } |
915 | 915 | ||
916 | case 0x0E: // RRC (HL) | 916 | case 0x0E: // RRC (HL) |
917 | s_time += 7; | 917 | s_time += 7; |
918 | data = r.w.hl; | 918 | data = r.w.hl; |
919 | rrc_data_addr: | 919 | rrc_data_addr: |
920 | RRC( READ_MEM( data ), WRITE_MEM( data, result ) ) | 920 | RRC( READ_MEM( data ), WRITE_MEM( data, result ) ) |
921 | 921 | ||
922 | CASE7( 08, 09, 0A, 0B, 0C, 0D, 0F ):{// RRC r | 922 | CASE7( 08, 09, 0A, 0B, 0C, 0D, 0F ):{// RRC r |
923 | byte* reg = &R8( data, 0x08 ); | 923 | byte* reg = &R8( data, 0x08 ); |
924 | RRC( *reg, *reg = result ) | 924 | RRC( *reg, *reg = result ) |
925 | } | 925 | } |
926 | 926 | ||
927 | #define RR( read, write ) {\ | 927 | #define RR( read, write ) {\ |
928 | int result = read;\ | 928 | int result = read;\ |
929 | int temp = result & C01;\ | 929 | int temp = result & C01;\ |
930 | result = BYTE( flags << 7 ) + (result >> 1);\ | 930 | result = BYTE( flags << 7 ) + (result >> 1);\ |
931 | flags = SZ28P( result ) + temp;\ | 931 | flags = SZ28P( result ) + temp;\ |
932 | write;\ | 932 | write;\ |
933 | goto loop;\ | 933 | goto loop;\ |
934 | } | 934 | } |
935 | 935 | ||
936 | case 0x1E: // RR (HL) | 936 | case 0x1E: // RR (HL) |
937 | s_time += 7; | 937 | s_time += 7; |
938 | data = r.w.hl; | 938 | data = r.w.hl; |
939 | rr_data_addr: | 939 | rr_data_addr: |
940 | RR( READ_MEM( data ), WRITE_MEM( data, result ) ) | 940 | RR( READ_MEM( data ), WRITE_MEM( data, result ) ) |
941 | 941 | ||
942 | CASE7( 18, 19, 1A, 1B, 1C, 1D, 1F ):{// RR r | 942 | CASE7( 18, 19, 1A, 1B, 1C, 1D, 1F ):{// RR r |
943 | byte* reg = &R8( data, 0x18 ); | 943 | byte* reg = &R8( data, 0x18 ); |
944 | RR( *reg, *reg = result ) | 944 | RR( *reg, *reg = result ) |
945 | } | 945 | } |
946 | 946 | ||
947 | #define SRA( read, write ) {\ | 947 | #define SRA( read, write ) {\ |
948 | int result = read;\ | 948 | int result = read;\ |
949 | flags = result & C01;\ | 949 | flags = result & C01;\ |
950 | result = (result & 0x80) + (result >> 1);\ | 950 | result = (result & 0x80) + (result >> 1);\ |
951 | flags += SZ28P( result );\ | 951 | flags += SZ28P( result );\ |
952 | write;\ | 952 | write;\ |
953 | goto loop;\ | 953 | goto loop;\ |
954 | } | 954 | } |
955 | 955 | ||
956 | case 0x2E: // SRA (HL) | 956 | case 0x2E: // SRA (HL) |
957 | data = r.w.hl; | 957 | data = r.w.hl; |
958 | s_time += 7; | 958 | s_time += 7; |
959 | sra_data_addr: | 959 | sra_data_addr: |
960 | SRA( READ_MEM( data ), WRITE_MEM( data, result ) ) | 960 | SRA( READ_MEM( data ), WRITE_MEM( data, result ) ) |
961 | 961 | ||
962 | CASE7( 28, 29, 2A, 2B, 2C, 2D, 2F ):{// SRA r | 962 | CASE7( 28, 29, 2A, 2B, 2C, 2D, 2F ):{// SRA r |
963 | byte* reg = &R8( data, 0x28 ); | 963 | byte* reg = &R8( data, 0x28 ); |
964 | SRA( *reg, *reg = result ) | 964 | SRA( *reg, *reg = result ) |
965 | } | 965 | } |
966 | 966 | ||
967 | #define SRL( read, write ) {\ | 967 | #define SRL( read, write ) {\ |
968 | int result = read;\ | 968 | int result = read;\ |
969 | flags = result & C01;\ | 969 | flags = result & C01;\ |
970 | result >>= 1;\ | 970 | result >>= 1;\ |
971 | flags += SZ28P( result );\ | 971 | flags += SZ28P( result );\ |
972 | write;\ | 972 | write;\ |
973 | goto loop;\ | 973 | goto loop;\ |
974 | } | 974 | } |
975 | 975 | ||
976 | case 0x3E: // SRL (HL) | 976 | case 0x3E: // SRL (HL) |
977 | s_time += 7; | 977 | s_time += 7; |
978 | data = r.w.hl; | 978 | data = r.w.hl; |
979 | srl_data_addr: | 979 | srl_data_addr: |
980 | SRL( READ_MEM( data ), WRITE_MEM( data, result ) ) | 980 | SRL( READ_MEM( data ), WRITE_MEM( data, result ) ) |
981 | 981 | ||
982 | CASE7( 38, 39, 3A, 3B, 3C, 3D, 3F ):{// SRL r | 982 | CASE7( 38, 39, 3A, 3B, 3C, 3D, 3F ):{// SRL r |
983 | byte* reg = &R8( data, 0x38 ); | 983 | byte* reg = &R8( data, 0x38 ); |
984 | SRL( *reg, *reg = result ) | 984 | SRL( *reg, *reg = result ) |
985 | } | 985 | } |
986 | 986 | ||
987 | // BIT | 987 | // BIT |
988 | { | 988 | { |
989 | int temp; | 989 | int temp; |
990 | CASE8( 46, 4E, 56, 5E, 66, 6E, 76, 7E ): // BIT b,(HL) | 990 | CASE8( 46, 4E, 56, 5E, 66, 6E, 76, 7E ): // BIT b,(HL) |
991 | s_time += 4; | 991 | s_time += 4; |
992 | temp = READ_MEM( r.w.hl ); | 992 | temp = READ_MEM( r.w.hl ); |
993 | flags &= C01; | 993 | flags &= C01; |
994 | goto bit_temp; | 994 | goto bit_temp; |
995 | CASE7( 40, 41, 42, 43, 44, 45, 47 ): // BIT 0,r | 995 | CASE7( 40, 41, 42, 43, 44, 45, 47 ): // BIT 0,r |
996 | CASE7( 48, 49, 4A, 4B, 4C, 4D, 4F ): // BIT 1,r | 996 | CASE7( 48, 49, 4A, 4B, 4C, 4D, 4F ): // BIT 1,r |
997 | CASE7( 50, 51, 52, 53, 54, 55, 57 ): // BIT 2,r | 997 | CASE7( 50, 51, 52, 53, 54, 55, 57 ): // BIT 2,r |
998 | CASE7( 58, 59, 5A, 5B, 5C, 5D, 5F ): // BIT 3,r | 998 | CASE7( 58, 59, 5A, 5B, 5C, 5D, 5F ): // BIT 3,r |
999 | CASE7( 60, 61, 62, 63, 64, 65, 67 ): // BIT 4,r | 999 | CASE7( 60, 61, 62, 63, 64, 65, 67 ): // BIT 4,r |
1000 | CASE7( 68, 69, 6A, 6B, 6C, 6D, 6F ): // BIT 5,r | 1000 | CASE7( 68, 69, 6A, 6B, 6C, 6D, 6F ): // BIT 5,r |
1001 | CASE7( 70, 71, 72, 73, 74, 75, 77 ): // BIT 6,r | 1001 | CASE7( 70, 71, 72, 73, 74, 75, 77 ): // BIT 6,r |
1002 | CASE7( 78, 79, 7A, 7B, 7C, 7D, 7F ): // BIT 7,r | 1002 | CASE7( 78, 79, 7A, 7B, 7C, 7D, 7F ): // BIT 7,r |
1003 | temp = R8( data & 7, 0 ); | 1003 | temp = R8( data & 7, 0 ); |
1004 | flags = (flags & C01) + (temp & (F20 | F08)); | 1004 | flags = (flags & C01) + (temp & (F20 | F08)); |
1005 | bit_temp: | 1005 | bit_temp: |
1006 | temp = temp & (1 << (data >> 3 & 7)); | 1006 | temp = temp & (1 << (data >> 3 & 7)); |
1007 | flags += (temp & S80) + H10; | 1007 | flags += (temp & S80) + H10; |
1008 | flags += (unsigned) --temp >> 8 & (Z40 | P04); | 1008 | flags += (unsigned) --temp >> 8 & (Z40 | P04); |
1009 | goto loop; | 1009 | goto loop; |
1010 | } | 1010 | } |
1011 | 1011 | ||
1012 | // SET/RES | 1012 | // SET/RES |
1013 | CASE8( 86, 8E, 96, 9E, A6, AE, B6, BE ): // RES b,(HL) | 1013 | CASE8( 86, 8E, 96, 9E, A6, AE, B6, BE ): // RES b,(HL) |
1014 | CASE8( C6, CE, D6, DE, E6, EE, F6, FE ):{// SET b,(HL) | 1014 | CASE8( C6, CE, D6, DE, E6, EE, F6, FE ):{// SET b,(HL) |
1015 | s_time += 7; | 1015 | s_time += 7; |
1016 | int temp = READ_MEM( r.w.hl ); | 1016 | int temp = READ_MEM( r.w.hl ); |
1017 | int bit = 1 << (data >> 3 & 7); | 1017 | int bit = 1 << (data >> 3 & 7); |
1018 | temp |= bit; // SET | 1018 | temp |= bit; // SET |
1019 | if ( !(data & 0x40) ) | 1019 | if ( !(data & 0x40) ) |
1020 | temp ^= bit; // RES | 1020 | temp ^= bit; // RES |
1021 | WRITE_MEM( r.w.hl, temp ); | 1021 | WRITE_MEM( r.w.hl, temp ); |
1022 | goto loop; | 1022 | goto loop; |
1023 | } | 1023 | } |
1024 | 1024 | ||
1025 | CASE7( C0, C1, C2, C3, C4, C5, C7 ): // SET 0,r | 1025 | CASE7( C0, C1, C2, C3, C4, C5, C7 ): // SET 0,r |
1026 | CASE7( C8, C9, CA, CB, CC, CD, CF ): // SET 1,r | 1026 | CASE7( C8, C9, CA, CB, CC, CD, CF ): // SET 1,r |
1027 | CASE7( D0, D1, D2, D3, D4, D5, D7 ): // SET 2,r | 1027 | CASE7( D0, D1, D2, D3, D4, D5, D7 ): // SET 2,r |
1028 | CASE7( D8, D9, DA, DB, DC, DD, DF ): // SET 3,r | 1028 | CASE7( D8, D9, DA, DB, DC, DD, DF ): // SET 3,r |
1029 | CASE7( E0, E1, E2, E3, E4, E5, E7 ): // SET 4,r | 1029 | CASE7( E0, E1, E2, E3, E4, E5, E7 ): // SET 4,r |
1030 | CASE7( E8, E9, EA, EB, EC, ED, EF ): // SET 5,r | 1030 | CASE7( E8, E9, EA, EB, EC, ED, EF ): // SET 5,r |
1031 | CASE7( F0, F1, F2, F3, F4, F5, F7 ): // SET 6,r | 1031 | CASE7( F0, F1, F2, F3, F4, F5, F7 ): // SET 6,r |
1032 | CASE7( F8, F9, FA, FB, FC, FD, FF ): // SET 7,r | 1032 | CASE7( F8, F9, FA, FB, FC, FD, FF ): // SET 7,r |
1033 | R8( data & 7, 0 ) |= 1 << (data >> 3 & 7); | 1033 | R8( data & 7, 0 ) |= 1 << (data >> 3 & 7); |
1034 | goto loop; | 1034 | goto loop; |
1035 | 1035 | ||
1036 | CASE7( 80, 81, 82, 83, 84, 85, 87 ): // RES 0,r | 1036 | CASE7( 80, 81, 82, 83, 84, 85, 87 ): // RES 0,r |
1037 | CASE7( 88, 89, 8A, 8B, 8C, 8D, 8F ): // RES 1,r | 1037 | CASE7( 88, 89, 8A, 8B, 8C, 8D, 8F ): // RES 1,r |
1038 | CASE7( 90, 91, 92, 93, 94, 95, 97 ): // RES 2,r | 1038 | CASE7( 90, 91, 92, 93, 94, 95, 97 ): // RES 2,r |
1039 | CASE7( 98, 99, 9A, 9B, 9C, 9D, 9F ): // RES 3,r | 1039 | CASE7( 98, 99, 9A, 9B, 9C, 9D, 9F ): // RES 3,r |
1040 | CASE7( A0, A1, A2, A3, A4, A5, A7 ): // RES 4,r | 1040 | CASE7( A0, A1, A2, A3, A4, A5, A7 ): // RES 4,r |
1041 | CASE7( A8, A9, AA, AB, AC, AD, AF ): // RES 5,r | 1041 | CASE7( A8, A9, AA, AB, AC, AD, AF ): // RES 5,r |
1042 | CASE7( B0, B1, B2, B3, B4, B5, B7 ): // RES 6,r | 1042 | CASE7( B0, B1, B2, B3, B4, B5, B7 ): // RES 6,r |
1043 | CASE7( B8, B9, BA, BB, BC, BD, BF ): // RES 7,r | 1043 | CASE7( B8, B9, BA, BB, BC, BD, BF ): // RES 7,r |
1044 | R8( data & 7, 0 ) &= ~(1 << (data >> 3 & 7)); | 1044 | R8( data & 7, 0 ) &= ~(1 << (data >> 3 & 7)); |
1045 | goto loop; | 1045 | goto loop; |
1046 | } | 1046 | } |
1047 | assert( false ); | 1047 | assert( false ); |
1048 | } | 1048 | } |
1049 | 1049 | ||
1050 | #undef GET_ADDR | 1050 | #undef GET_ADDR |
1051 | #define GET_ADDR() GET_LE16( &INSTR( 1, pc ) ) | 1051 | #define GET_ADDR() GET_LE16( &INSTR( 1, pc ) ) |
1052 | 1052 | ||
1053 | //////////////////////////////////////// ED prefix | 1053 | //////////////////////////////////////// ED prefix |
1054 | { | 1054 | { |
1055 | case 0xED: | 1055 | case 0xED: |
1056 | pc++; | 1056 | pc++; |
1057 | s_time += (clock_table + 256) [data] >> 4; | 1057 | s_time += (clock_table + 256) [data] >> 4; |
1058 | switch ( data ) | 1058 | switch ( data ) |
1059 | { | 1059 | { |
1060 | { | 1060 | { |
1061 | int temp; | 1061 | int temp; |
1062 | case 0x72: // SBC HL,SP | 1062 | case 0x72: // SBC HL,SP |
1063 | case 0x7A: // ADC HL,SP | 1063 | case 0x7A: // ADC HL,SP |
1064 | temp = sp; | 1064 | temp = sp; |
1065 | if ( 0 ) | 1065 | if ( 0 ) |
1066 | case 0x42: // SBC HL,BC | 1066 | case 0x42: // SBC HL,BC |
1067 | case 0x52: // SBC HL,DE | 1067 | case 0x52: // SBC HL,DE |
1068 | case 0x62: // SBC HL,HL | 1068 | case 0x62: // SBC HL,HL |
1069 | case 0x4A: // ADC HL,BC | 1069 | case 0x4A: // ADC HL,BC |
1070 | case 0x5A: // ADC HL,DE | 1070 | case 0x5A: // ADC HL,DE |
1071 | case 0x6A: // ADC HL,HL | 1071 | case 0x6A: // ADC HL,HL |
1072 | temp = R16( data >> 3 & 6, 1, 0 ); | 1072 | temp = R16( data >> 3 & 6, 1, 0 ); |
1073 | int sum = temp + (flags & C01); | 1073 | int sum = temp + (flags & C01); |
1074 | flags = ~data >> 2 & N02; | 1074 | flags = ~data >> 2 & N02; |
1075 | if ( flags ) | 1075 | if ( flags ) |
1076 | sum = -sum; | 1076 | sum = -sum; |
1077 | sum += r.w.hl; | 1077 | sum += r.w.hl; |
1078 | temp ^= r.w.hl; | 1078 | temp ^= r.w.hl; |
1079 | temp ^= sum; | 1079 | temp ^= sum; |
1080 | flags +=(sum >> 16 & C01) + | 1080 | flags +=(sum >> 16 & C01) + |
1081 | (temp >> 8 & H10) + | 1081 | (temp >> 8 & H10) + |
1082 | (sum >> 8 & (S80 | F20 | F08)) + | 1082 | (sum >> 8 & (S80 | F20 | F08)) + |
1083 | ((temp + 0x8000) >> 14 & V04); | 1083 | ((temp + 0x8000) >> 14 & V04); |
1084 | r.w.hl = sum; | 1084 | r.w.hl = sum; |
1085 | if ( WORD( sum ) ) | 1085 | if ( WORD( sum ) ) |
1086 | goto loop; | 1086 | goto loop; |
1087 | flags += Z40; | 1087 | flags += Z40; |
1088 | goto loop; | 1088 | goto loop; |
1089 | } | 1089 | } |
1090 | 1090 | ||
1091 | CASE8( 40, 48, 50, 58, 60, 68, 70, 78 ):{// IN r,(C) | 1091 | CASE8( 40, 48, 50, 58, 60, 68, 70, 78 ):{// IN r,(C) |
1092 | int temp = IN_PORT( r.w.bc ); | 1092 | int temp = IN_PORT( r.w.bc ); |
1093 | R8( data >> 3, 8 ) = temp; | 1093 | R8( data >> 3, 8 ) = temp; |
1094 | flags = (flags & C01) + SZ28P( temp ); | 1094 | flags = (flags & C01) + SZ28P( temp ); |
1095 | goto loop; | 1095 | goto loop; |
1096 | } | 1096 | } |
1097 | 1097 | ||
1098 | case 0x71: // OUT (C),0 | 1098 | case 0x71: // OUT (C),0 |
1099 | r.b.flags = 0; | 1099 | r.b.flags = 0; |
1100 | CASE7( 41, 49, 51, 59, 61, 69, 79 ): // OUT (C),r | 1100 | CASE7( 41, 49, 51, 59, 61, 69, 79 ): // OUT (C),r |
1101 | OUT_PORT( r.w.bc, R8( data >> 3, 8 ) ); | 1101 | OUT_PORT( r.w.bc, R8( data >> 3, 8 ) ); |
1102 | goto loop; | 1102 | goto loop; |
1103 | 1103 | ||
1104 | { | 1104 | { |
1105 | int temp; | 1105 | int temp; |
1106 | case 0x73: // LD (ADDR),SP | 1106 | case 0x73: // LD (ADDR),SP |
1107 | temp = sp; | 1107 | temp = sp; |
1108 | if ( 0 ) | 1108 | if ( 0 ) |
1109 | case 0x43: // LD (ADDR),BC | 1109 | case 0x43: // LD (ADDR),BC |
1110 | case 0x53: // LD (ADDR),DE | 1110 | case 0x53: // LD (ADDR),DE |
1111 | temp = R16( data, 4, 0x43 ); | 1111 | temp = R16( data, 4, 0x43 ); |
1112 | int addr = GET_ADDR(); | 1112 | int addr = GET_ADDR(); |
1113 | pc += 2; | 1113 | pc += 2; |
1114 | WRITE_WORD( addr, temp ); | 1114 | WRITE_WORD( addr, temp ); |
1115 | goto loop; | 1115 | goto loop; |
1116 | } | 1116 | } |
1117 | 1117 | ||
1118 | case 0x4B: // LD BC,(ADDR) | 1118 | case 0x4B: // LD BC,(ADDR) |
1119 | case 0x5B:{// LD DE,(ADDR) | 1119 | case 0x5B:{// LD DE,(ADDR) |
1120 | int addr = GET_ADDR(); | 1120 | int addr = GET_ADDR(); |
1121 | pc += 2; | 1121 | pc += 2; |
1122 | R16( data, 4, 0x4B ) = READ_WORD( addr ); | 1122 | R16( data, 4, 0x4B ) = READ_WORD( addr ); |
1123 | goto loop; | 1123 | goto loop; |
1124 | } | 1124 | } |
1125 | 1125 | ||
1126 | case 0x7B:{// LD SP,(ADDR) | 1126 | case 0x7B:{// LD SP,(ADDR) |
1127 | int addr = GET_ADDR(); | 1127 | int addr = GET_ADDR(); |
1128 | pc += 2; | 1128 | pc += 2; |
1129 | sp = READ_WORD( addr ); | 1129 | sp = READ_WORD( addr ); |
1130 | goto loop; | 1130 | goto loop; |
1131 | } | 1131 | } |
1132 | 1132 | ||
1133 | case 0x67:{// RRD | 1133 | case 0x67:{// RRD |
1134 | int temp = READ_MEM( r.w.hl ); | 1134 | int temp = READ_MEM( r.w.hl ); |
1135 | WRITE_MEM( r.w.hl, ((r.b.a << 4) + (temp >> 4)) ); | 1135 | WRITE_MEM( r.w.hl, ((r.b.a << 4) + (temp >> 4)) ); |
1136 | temp = (r.b.a & 0xF0) + (temp & 0x0F); | 1136 | temp = (r.b.a & 0xF0) + (temp & 0x0F); |
1137 | flags = (flags & C01) + SZ28P( temp ); | 1137 | flags = (flags & C01) + SZ28P( temp ); |
1138 | r.b.a = temp; | 1138 | r.b.a = temp; |
1139 | goto loop; | 1139 | goto loop; |
1140 | } | 1140 | } |
1141 | 1141 | ||
1142 | case 0x6F:{// RLD | 1142 | case 0x6F:{// RLD |
1143 | int temp = READ_MEM( r.w.hl ); | 1143 | int temp = READ_MEM( r.w.hl ); |
1144 | WRITE_MEM( r.w.hl, ((temp << 4) + (r.b.a & 0x0F)) ); | 1144 | WRITE_MEM( r.w.hl, ((temp << 4) + (r.b.a & 0x0F)) ); |
1145 | temp = (r.b.a & 0xF0) + (temp >> 4); | 1145 | temp = (r.b.a & 0xF0) + (temp >> 4); |
1146 | flags = (flags & C01) + SZ28P( temp ); | 1146 | flags = (flags & C01) + SZ28P( temp ); |
1147 | r.b.a = temp; | 1147 | r.b.a = temp; |
1148 | goto loop; | 1148 | goto loop; |
1149 | } | 1149 | } |
1150 | 1150 | ||
1151 | CASE8( 44, 4C, 54, 5C, 64, 6C, 74, 7C ): // NEG | 1151 | CASE8( 44, 4C, 54, 5C, 64, 6C, 74, 7C ): // NEG |
1152 | opcode = 0x10; // flag to do SBC instead of ADC | 1152 | opcode = 0x10; // flag to do SBC instead of ADC |
1153 | flags &= ~C01; | 1153 | flags &= ~C01; |
1154 | data = r.b.a; | 1154 | data = r.b.a; |
1155 | r.b.a = 0; | 1155 | r.b.a = 0; |
1156 | goto adc_data; | 1156 | goto adc_data; |
1157 | 1157 | ||
1158 | { | 1158 | { |
1159 | int inc; | 1159 | int inc; |
1160 | case 0xA9: // CPD | 1160 | case 0xA9: // CPD |
1161 | case 0xB9: // CPDR | 1161 | case 0xB9: // CPDR |
1162 | inc = -1; | 1162 | inc = -1; |
1163 | if ( 0 ) | 1163 | if ( 0 ) |
1164 | case 0xA1: // CPI | 1164 | case 0xA1: // CPI |
1165 | case 0xB1: // CPIR | 1165 | case 0xB1: // CPIR |
1166 | inc = +1; | 1166 | inc = +1; |
1167 | int addr = r.w.hl; | 1167 | int addr = r.w.hl; |
1168 | r.w.hl = addr + inc; | 1168 | r.w.hl = addr + inc; |
1169 | int temp = READ_MEM( addr ); | 1169 | int temp = READ_MEM( addr ); |
1170 | 1170 | ||
1171 | int result = r.b.a - temp; | 1171 | int result = r.b.a - temp; |
1172 | flags = (flags & C01) + N02 + | 1172 | flags = (flags & C01) + N02 + |
1173 | ((((temp ^ r.b.a) & H10) ^ result) & (S80 | H10)); | 1173 | ((((temp ^ r.b.a) & H10) ^ result) & (S80 | H10)); |
1174 | 1174 | ||
1175 | if ( !BYTE( result ) ) | 1175 | if ( !BYTE( result ) ) |
1176 | flags += Z40; | 1176 | flags += Z40; |
1177 | result -= (flags & H10) >> 4; | 1177 | result -= (flags & H10) >> 4; |
1178 | flags += result & F08; | 1178 | flags += result & F08; |
1179 | flags += result << 4 & F20; | 1179 | flags += result << 4 & F20; |
1180 | if ( !--r.w.bc ) | 1180 | if ( !--r.w.bc ) |
1181 | goto loop; | 1181 | goto loop; |
1182 | 1182 | ||
1183 | flags += V04; | 1183 | flags += V04; |
1184 | if ( flags & Z40 || data < 0xB0 ) | 1184 | if ( flags & Z40 || data < 0xB0 ) |
1185 | goto loop; | 1185 | goto loop; |
1186 | 1186 | ||
1187 | pc -= 2; | 1187 | pc -= 2; |
1188 | s_time += 5; | 1188 | s_time += 5; |
1189 | goto loop; | 1189 | goto loop; |
1190 | } | 1190 | } |
1191 | 1191 | ||
1192 | { | 1192 | { |
1193 | int inc; | 1193 | int inc; |
1194 | case 0xA8: // LDD | 1194 | case 0xA8: // LDD |
1195 | case 0xB8: // LDDR | 1195 | case 0xB8: // LDDR |
1196 | inc = -1; | 1196 | inc = -1; |
1197 | if ( 0 ) | 1197 | if ( 0 ) |
1198 | case 0xA0: // LDI | 1198 | case 0xA0: // LDI |
1199 | case 0xB0: // LDIR | 1199 | case 0xB0: // LDIR |
1200 | inc = +1; | 1200 | inc = +1; |
1201 | int addr = r.w.hl; | 1201 | int addr = r.w.hl; |
1202 | r.w.hl = addr + inc; | 1202 | r.w.hl = addr + inc; |
1203 | int temp = READ_MEM( addr ); | 1203 | int temp = READ_MEM( addr ); |
1204 | 1204 | ||
1205 | addr = r.w.de; | 1205 | addr = r.w.de; |
1206 | r.w.de = addr + inc; | 1206 | r.w.de = addr + inc; |
1207 | WRITE_MEM( addr, temp ); | 1207 | WRITE_MEM( addr, temp ); |
1208 | 1208 | ||
1209 | temp += r.b.a; | 1209 | temp += r.b.a; |
1210 | flags = (flags & (S80 | Z40 | C01)) + | 1210 | flags = (flags & (S80 | Z40 | C01)) + |
1211 | (temp & F08) + (temp << 4 & F20); | 1211 | (temp & F08) + (temp << 4 & F20); |
1212 | if ( !--r.w.bc ) | 1212 | if ( !--r.w.bc ) |
1213 | goto loop; | 1213 | goto loop; |
1214 | 1214 | ||
1215 | flags += V04; | 1215 | flags += V04; |
1216 | if ( data < 0xB0 ) | 1216 | if ( data < 0xB0 ) |
1217 | goto loop; | 1217 | goto loop; |
1218 | 1218 | ||
1219 | pc -= 2; | 1219 | pc -= 2; |
1220 | s_time += 5; | 1220 | s_time += 5; |
1221 | goto loop; | 1221 | goto loop; |
1222 | } | 1222 | } |
1223 | 1223 | ||
1224 | { | 1224 | { |
1225 | int inc; | 1225 | int inc; |
1226 | case 0xAB: // OUTD | 1226 | case 0xAB: // OUTD |
1227 | case 0xBB: // OTDR | 1227 | case 0xBB: // OTDR |
1228 | inc = -1; | 1228 | inc = -1; |
1229 | if ( 0 ) | 1229 | if ( 0 ) |
1230 | case 0xA3: // OUTI | 1230 | case 0xA3: // OUTI |
1231 | case 0xB3: // OTIR | 1231 | case 0xB3: // OTIR |
1232 | inc = +1; | 1232 | inc = +1; |
1233 | int addr = r.w.hl; | 1233 | int addr = r.w.hl; |
1234 | r.w.hl = addr + inc; | 1234 | r.w.hl = addr + inc; |
1235 | int temp = READ_MEM( addr ); | 1235 | int temp = READ_MEM( addr ); |
1236 | 1236 | ||
1237 | int b = --r.b.b; | 1237 | int b = --r.b.b; |
1238 | flags = (temp >> 6 & N02) + SZ28( b ); | 1238 | flags = (temp >> 6 & N02) + SZ28( b ); |
1239 | if ( b && data >= 0xB0 ) | 1239 | if ( b && data >= 0xB0 ) |
1240 | { | 1240 | { |
1241 | pc -= 2; | 1241 | pc -= 2; |
1242 | s_time += 5; | 1242 | s_time += 5; |
1243 | } | 1243 | } |
1244 | 1244 | ||
1245 | OUT_PORT( r.w.bc, temp ); | 1245 | OUT_PORT( r.w.bc, temp ); |
1246 | goto loop; | 1246 | goto loop; |
1247 | } | 1247 | } |
1248 | 1248 | ||
1249 | { | 1249 | { |
1250 | int inc; | 1250 | int inc; |
1251 | case 0xAA: // IND | 1251 | case 0xAA: // IND |
1252 | case 0xBA: // INDR | 1252 | case 0xBA: // INDR |
1253 | inc = -1; | 1253 | inc = -1; |
1254 | if ( 0 ) | 1254 | if ( 0 ) |
1255 | case 0xA2: // INI | 1255 | case 0xA2: // INI |
1256 | case 0xB2: // INIR | 1256 | case 0xB2: // INIR |
1257 | inc = +1; | 1257 | inc = +1; |
1258 | 1258 | ||
1259 | int addr = r.w.hl; | 1259 | int addr = r.w.hl; |
1260 | r.w.hl = addr + inc; | 1260 | r.w.hl = addr + inc; |
1261 | 1261 | ||
1262 | int temp = IN_PORT( r.w.bc ); | 1262 | int temp = IN_PORT( r.w.bc ); |
1263 | 1263 | ||
1264 | int b = --r.b.b; | 1264 | int b = --r.b.b; |
1265 | flags = (temp >> 6 & N02) + SZ28( b ); | 1265 | flags = (temp >> 6 & N02) + SZ28( b ); |
1266 | if ( b && data >= 0xB0 ) | 1266 | if ( b && data >= 0xB0 ) |
1267 | { | 1267 | { |
1268 | pc -= 2; | 1268 | pc -= 2; |
1269 | s_time += 5; | 1269 | s_time += 5; |
1270 | } | 1270 | } |
1271 | 1271 | ||
1272 | WRITE_MEM( addr, temp ); | 1272 | WRITE_MEM( addr, temp ); |
1273 | goto loop; | 1273 | goto loop; |
1274 | } | 1274 | } |
1275 | 1275 | ||
1276 | case 0x47: // LD I,A | 1276 | case 0x47: // LD I,A |
1277 | R.i = r.b.a; | 1277 | R.i = r.b.a; |
1278 | goto loop; | 1278 | goto loop; |
1279 | 1279 | ||
1280 | case 0x4F: // LD R,A | 1280 | case 0x4F: // LD R,A |
1281 | SET_R( r.b.a ); | 1281 | SET_R( r.b.a ); |
1282 | dprintf( "LD R,A not supported\n" ); | 1282 | dprintf( "LD R,A not supported\n" ); |
1283 | warning = true; | 1283 | warning = true; |
1284 | goto loop; | 1284 | goto loop; |
1285 | 1285 | ||
1286 | case 0x57: // LD A,I | 1286 | case 0x57: // LD A,I |
1287 | r.b.a = R.i; | 1287 | r.b.a = R.i; |
1288 | goto ld_ai_common; | 1288 | goto ld_ai_common; |
1289 | 1289 | ||
1290 | case 0x5F: // LD A,R | 1290 | case 0x5F: // LD A,R |
1291 | r.b.a = GET_R(); | 1291 | r.b.a = GET_R(); |
1292 | dprintf( "LD A,R not supported\n" ); | 1292 | dprintf( "LD A,R not supported\n" ); |
1293 | warning = true; | 1293 | warning = true; |
1294 | ld_ai_common: | 1294 | ld_ai_common: |
1295 | flags = (flags & C01) + SZ28( r.b.a ) + (R.iff2 << 2 & V04); | 1295 | flags = (flags & C01) + SZ28( r.b.a ) + (R.iff2 << 2 & V04); |
1296 | goto loop; | 1296 | goto loop; |
1297 | 1297 | ||
1298 | CASE8( 45, 4D, 55, 5D, 65, 6D, 75, 7D ): // RETI/RETN | 1298 | CASE8( 45, 4D, 55, 5D, 65, 6D, 75, 7D ): // RETI/RETN |
1299 | R.iff1 = R.iff2; | 1299 | R.iff1 = R.iff2; |
1300 | goto ret_taken; | 1300 | goto ret_taken; |
1301 | 1301 | ||
1302 | case 0x46: case 0x4E: case 0x66: case 0x6E: // IM 0 | 1302 | case 0x46: case 0x4E: case 0x66: case 0x6E: // IM 0 |
1303 | R.im = 0; | 1303 | R.im = 0; |
1304 | goto loop; | 1304 | goto loop; |
1305 | 1305 | ||
1306 | case 0x56: case 0x76: // IM 1 | 1306 | case 0x56: case 0x76: // IM 1 |
1307 | R.im = 1; | 1307 | R.im = 1; |
1308 | goto loop; | 1308 | goto loop; |
1309 | 1309 | ||
1310 | case 0x5E: case 0x7E: // IM 2 | 1310 | case 0x5E: case 0x7E: // IM 2 |
1311 | R.im = 2; | 1311 | R.im = 2; |
1312 | goto loop; | 1312 | goto loop; |
1313 | 1313 | ||
1314 | default: | 1314 | default: |
1315 | dprintf( "Opcode $ED $%02X not supported\n", data ); | 1315 | dprintf( "Opcode $ED $%02X not supported\n", data ); |
1316 | warning = true; | 1316 | warning = true; |
1317 | goto loop; | 1317 | goto loop; |
1318 | } | 1318 | } |
1319 | assert( false ); | 1319 | assert( false ); |
1320 | } | 1320 | } |
1321 | 1321 | ||
1322 | //////////////////////////////////////// DD/FD prefix | 1322 | //////////////////////////////////////// DD/FD prefix |
1323 | { | 1323 | { |
1324 | int ixy; | 1324 | int ixy; |
1325 | case 0xDD: | 1325 | case 0xDD: |
1326 | ixy = ix; | 1326 | ixy = ix; |
1327 | goto ix_prefix; | 1327 | goto ix_prefix; |
1328 | case 0xFD: | 1328 | case 0xFD: |
1329 | ixy = iy; | 1329 | ixy = iy; |
1330 | ix_prefix: | 1330 | ix_prefix: |
1331 | pc++; | 1331 | pc++; |
1332 | int data2 = READ_CODE( pc ); | 1332 | int data2 = READ_CODE( pc ); |
1333 | s_time += (clock_table + 256) [data] & 0x0F; | 1333 | s_time += (clock_table + 256) [data] & 0x0F; |
1334 | switch ( data ) | 1334 | switch ( data ) |
1335 | { | 1335 | { |
1336 | // TODO: more efficient way of avoid negative address | 1336 | // TODO: more efficient way of avoid negative address |
1337 | // TODO: avoid using this as argument to READ_MEM() since it is evaluated twice | 1337 | // TODO: avoid using this as argument to READ_MEM() since it is evaluated twice |
1338 | #define IXY_DISP( ixy, disp ) WORD( (ixy ) + (disp)) | 1338 | #define IXY_DISP( ixy, disp ) WORD( (ixy ) + (disp)) |
1339 | 1339 | ||
1340 | #define SET_IXY( in ) if ( opcode == 0xDD ) ix = in; else iy = in; | 1340 | #define SET_IXY( in ) if ( opcode == 0xDD ) ix = in; else iy = in; |
1341 | 1341 | ||
1342 | // ADD/ADC/SUB/SBC | 1342 | // ADD/ADC/SUB/SBC |
1343 | 1343 | ||
1344 | case 0x96: // SUB (IXY+disp) | 1344 | case 0x96: // SUB (IXY+disp) |
1345 | case 0x86: // ADD (IXY+disp) | 1345 | case 0x86: // ADD (IXY+disp) |
1346 | flags &= ~C01; | 1346 | flags &= ~C01; |
1347 | case 0x9E: // SBC (IXY+disp) | 1347 | case 0x9E: // SBC (IXY+disp) |
1348 | case 0x8E: // ADC (IXY+disp) | 1348 | case 0x8E: // ADC (IXY+disp) |
1349 | pc++; | 1349 | pc++; |
1350 | opcode = data; | 1350 | opcode = data; |
1351 | data = READ_MEM( IXY_DISP( ixy, SBYTE( data2 ) ) ); | 1351 | data = READ_MEM( IXY_DISP( ixy, SBYTE( data2 ) ) ); |
1352 | goto adc_data; | 1352 | goto adc_data; |
1353 | 1353 | ||
1354 | case 0x94: // SUB HXY | 1354 | case 0x94: // SUB HXY |
1355 | case 0x84: // ADD HXY | 1355 | case 0x84: // ADD HXY |
1356 | flags &= ~C01; | 1356 | flags &= ~C01; |
1357 | case 0x9C: // SBC HXY | 1357 | case 0x9C: // SBC HXY |
1358 | case 0x8C: // ADC HXY | 1358 | case 0x8C: // ADC HXY |
1359 | opcode = data; | 1359 | opcode = data; |
1360 | data = ixy >> 8; | 1360 | data = ixy >> 8; |
1361 | goto adc_data; | 1361 | goto adc_data; |
1362 | 1362 | ||
1363 | case 0x95: // SUB LXY | 1363 | case 0x95: // SUB LXY |
1364 | case 0x85: // ADD LXY | 1364 | case 0x85: // ADD LXY |
1365 | flags &= ~C01; | 1365 | flags &= ~C01; |
1366 | case 0x9D: // SBC LXY | 1366 | case 0x9D: // SBC LXY |
1367 | case 0x8D: // ADC LXY | 1367 | case 0x8D: // ADC LXY |
1368 | opcode = data; | 1368 | opcode = data; |
1369 | data = BYTE( ixy ); | 1369 | data = BYTE( ixy ); |
1370 | goto adc_data; | 1370 | goto adc_data; |
1371 | 1371 | ||
1372 | { | 1372 | { |
1373 | int temp; | 1373 | int temp; |
1374 | case 0x39: // ADD IXY,SP | 1374 | case 0x39: // ADD IXY,SP |
1375 | temp = sp; | 1375 | temp = sp; |
1376 | goto add_ixy_data; | 1376 | goto add_ixy_data; |
1377 | 1377 | ||
1378 | case 0x29: // ADD IXY,HL | 1378 | case 0x29: // ADD IXY,HL |
1379 | temp = ixy; | 1379 | temp = ixy; |
1380 | goto add_ixy_data; | 1380 | goto add_ixy_data; |
1381 | 1381 | ||
1382 | case 0x09: // ADD IXY,BC | 1382 | case 0x09: // ADD IXY,BC |
1383 | case 0x19: // ADD IXY,DE | 1383 | case 0x19: // ADD IXY,DE |
1384 | temp = R16( data, 4, 0x09 ); | 1384 | temp = R16( data, 4, 0x09 ); |
1385 | add_ixy_data: { | 1385 | add_ixy_data: { |
1386 | int sum = ixy + temp; | 1386 | int sum = ixy + temp; |
1387 | temp ^= ixy; | 1387 | temp ^= ixy; |
1388 | ixy = WORD( sum ); | 1388 | ixy = WORD( sum ); |
1389 | flags = (flags & (S80 | Z40 | V04)) + | 1389 | flags = (flags & (S80 | Z40 | V04)) + |
1390 | (sum >> 16) + | 1390 | (sum >> 16) + |
1391 | (sum >> 8 & (F20 | F08)) + | 1391 | (sum >> 8 & (F20 | F08)) + |
1392 | ((temp ^ sum) >> 8 & H10); | 1392 | ((temp ^ sum) >> 8 & H10); |
1393 | goto set_ixy; | 1393 | goto set_ixy; |
1394 | } | 1394 | } |
1395 | } | 1395 | } |
1396 | 1396 | ||
1397 | // AND | 1397 | // AND |
1398 | case 0xA6: // AND (IXY+disp) | 1398 | case 0xA6: // AND (IXY+disp) |
1399 | pc++; | 1399 | pc++; |
1400 | data = READ_MEM( IXY_DISP( ixy, SBYTE( data2 ) ) ); | 1400 | data = READ_MEM( IXY_DISP( ixy, SBYTE( data2 ) ) ); |
1401 | goto and_data; | 1401 | goto and_data; |
1402 | 1402 | ||
1403 | case 0xA4: // AND HXY | 1403 | case 0xA4: // AND HXY |
1404 | data = ixy >> 8; | 1404 | data = ixy >> 8; |
1405 | goto and_data; | 1405 | goto and_data; |
1406 | 1406 | ||
1407 | case 0xA5: // AND LXY | 1407 | case 0xA5: // AND LXY |
1408 | data = BYTE( ixy ); | 1408 | data = BYTE( ixy ); |
1409 | goto and_data; | 1409 | goto and_data; |
1410 | 1410 | ||
1411 | // OR | 1411 | // OR |
1412 | case 0xB6: // OR (IXY+disp) | 1412 | case 0xB6: // OR (IXY+disp) |
1413 | pc++; | 1413 | pc++; |
1414 | data = READ_MEM( IXY_DISP( ixy, SBYTE( data2 ) ) ); | 1414 | data = READ_MEM( IXY_DISP( ixy, SBYTE( data2 ) ) ); |
1415 | goto or_data; | 1415 | goto or_data; |
1416 | 1416 | ||
1417 | case 0xB4: // OR HXY | 1417 | case 0xB4: // OR HXY |
1418 | data = ixy >> 8; | 1418 | data = ixy >> 8; |
1419 | goto or_data; | 1419 | goto or_data; |
1420 | 1420 | ||
1421 | case 0xB5: // OR LXY | 1421 | case 0xB5: // OR LXY |
1422 | data = BYTE( ixy ); | 1422 | data = BYTE( ixy ); |
1423 | goto or_data; | 1423 | goto or_data; |
1424 | 1424 | ||
1425 | // XOR | 1425 | // XOR |
1426 | case 0xAE: // XOR (IXY+disp) | 1426 | case 0xAE: // XOR (IXY+disp) |
1427 | pc++; | 1427 | pc++; |
1428 | data = READ_MEM( IXY_DISP( ixy, SBYTE( data2 ) ) ); | 1428 | data = READ_MEM( IXY_DISP( ixy, SBYTE( data2 ) ) ); |
1429 | goto xor_data; | 1429 | goto xor_data; |
1430 | 1430 | ||
1431 | case 0xAC: // XOR HXY | 1431 | case 0xAC: // XOR HXY |
1432 | data = ixy >> 8; | 1432 | data = ixy >> 8; |
1433 | goto xor_data; | 1433 | goto xor_data; |
1434 | 1434 | ||
1435 | case 0xAD: // XOR LXY | 1435 | case 0xAD: // XOR LXY |
1436 | data = BYTE( ixy ); | 1436 | data = BYTE( ixy ); |
1437 | goto xor_data; | 1437 | goto xor_data; |
1438 | 1438 | ||
1439 | // CP | 1439 | // CP |
1440 | case 0xBE: // CP (IXY+disp) | 1440 | case 0xBE: // CP (IXY+disp) |
1441 | pc++; | 1441 | pc++; |
1442 | data = READ_MEM( IXY_DISP( ixy, SBYTE( data2 ) ) ); | 1442 | data = READ_MEM( IXY_DISP( ixy, SBYTE( data2 ) ) ); |
1443 | goto cp_data; | 1443 | goto cp_data; |
1444 | 1444 | ||
1445 | case 0xBC: // CP HXY | 1445 | case 0xBC: // CP HXY |
1446 | data = ixy >> 8; | 1446 | data = ixy >> 8; |
1447 | goto cp_data; | 1447 | goto cp_data; |
1448 | 1448 | ||
1449 | case 0xBD: // CP LXY | 1449 | case 0xBD: // CP LXY |
1450 | data = BYTE( ixy ); | 1450 | data = BYTE( ixy ); |
1451 | goto cp_data; | 1451 | goto cp_data; |
1452 | 1452 | ||
1453 | // LD | 1453 | // LD |
1454 | CASE7( 70, 71, 72, 73, 74, 75, 77 ): // LD (IXY+disp),r | 1454 | CASE7( 70, 71, 72, 73, 74, 75, 77 ): // LD (IXY+disp),r |
1455 | data = R8( data, 0x70 ); | 1455 | data = R8( data, 0x70 ); |
1456 | if ( 0 ) | 1456 | if ( 0 ) |
1457 | case 0x36: // LD (IXY+disp),imm | 1457 | case 0x36: // LD (IXY+disp),imm |
1458 | pc++, data = READ_CODE( pc ); | 1458 | pc++, data = READ_CODE( pc ); |
1459 | pc++; | 1459 | pc++; |
1460 | WRITE_MEM( IXY_DISP( ixy, SBYTE( data2 ) ), data ); | 1460 | WRITE_MEM( IXY_DISP( ixy, SBYTE( data2 ) ), data ); |
1461 | goto loop; | 1461 | goto loop; |
1462 | 1462 | ||
1463 | CASE5( 44, 4C, 54, 5C, 7C ): // LD r,HXY | 1463 | CASE5( 44, 4C, 54, 5C, 7C ): // LD r,HXY |
1464 | R8( data >> 3, 8 ) = ixy >> 8; | 1464 | R8( data >> 3, 8 ) = ixy >> 8; |
1465 | goto loop; | 1465 | goto loop; |
1466 | 1466 | ||
1467 | case 0x64: // LD HXY,HXY | 1467 | case 0x64: // LD HXY,HXY |
1468 | case 0x6D: // LD LXY,LXY | 1468 | case 0x6D: // LD LXY,LXY |
1469 | goto loop; | 1469 | goto loop; |
1470 | 1470 | ||
1471 | CASE5( 45, 4D, 55, 5D, 7D ): // LD r,LXY | 1471 | CASE5( 45, 4D, 55, 5D, 7D ): // LD r,LXY |
1472 | R8( data >> 3, 8 ) = ixy; | 1472 | R8( data >> 3, 8 ) = ixy; |
1473 | goto loop; | 1473 | goto loop; |
1474 | 1474 | ||
1475 | CASE7( 46, 4E, 56, 5E, 66, 6E, 7E ): // LD r,(IXY+disp) | 1475 | CASE7( 46, 4E, 56, 5E, 66, 6E, 7E ): // LD r,(IXY+disp) |
1476 | pc++; | 1476 | pc++; |
1477 | R8( data >> 3, 8 ) = READ_MEM( IXY_DISP( ixy, SBYTE( data2 ) ) ); | 1477 | R8( data >> 3, 8 ) = READ_MEM( IXY_DISP( ixy, SBYTE( data2 ) ) ); |
1478 | goto loop; | 1478 | goto loop; |
1479 | 1479 | ||
1480 | case 0x26: // LD HXY,imm | 1480 | case 0x26: // LD HXY,imm |
1481 | pc++; | 1481 | pc++; |
1482 | goto ld_hxy_data; | 1482 | goto ld_hxy_data; |
1483 | 1483 | ||
1484 | case 0x65: // LD HXY,LXY | 1484 | case 0x65: // LD HXY,LXY |
1485 | data2 = BYTE( ixy ); | 1485 | data2 = BYTE( ixy ); |
1486 | goto ld_hxy_data; | 1486 | goto ld_hxy_data; |
1487 | 1487 | ||
1488 | CASE5( 60, 61, 62, 63, 67 ): // LD HXY,r | 1488 | CASE5( 60, 61, 62, 63, 67 ): // LD HXY,r |
1489 | data2 = R8( data, 0x60 ); | 1489 | data2 = R8( data, 0x60 ); |
1490 | ld_hxy_data: | 1490 | ld_hxy_data: |
1491 | ixy = BYTE( ixy ) + (data2 << 8); | 1491 | ixy = BYTE( ixy ) + (data2 << 8); |
1492 | goto set_ixy; | 1492 | goto set_ixy; |
1493 | 1493 | ||
1494 | case 0x2E: // LD LXY,imm | 1494 | case 0x2E: // LD LXY,imm |
1495 | pc++; | 1495 | pc++; |
1496 | goto ld_lxy_data; | 1496 | goto ld_lxy_data; |
1497 | 1497 | ||
1498 | case 0x6C: // LD LXY,HXY | 1498 | case 0x6C: // LD LXY,HXY |
1499 | data2 = ixy >> 8; | 1499 | data2 = ixy >> 8; |
1500 | goto ld_lxy_data; | 1500 | goto ld_lxy_data; |
1501 | 1501 | ||
1502 | CASE5( 68, 69, 6A, 6B, 6F ): // LD LXY,r | 1502 | CASE5( 68, 69, 6A, 6B, 6F ): // LD LXY,r |
1503 | data2 = R8( data, 0x68 ); | 1503 | data2 = R8( data, 0x68 ); |
1504 | ld_lxy_data: | 1504 | ld_lxy_data: |
1505 | ixy = (ixy & 0xFF00) + data2; | 1505 | ixy = (ixy & 0xFF00) + data2; |
1506 | set_ixy: | 1506 | set_ixy: |
1507 | if ( opcode == 0xDD ) | 1507 | if ( opcode == 0xDD ) |
1508 | { | 1508 | { |
1509 | ix = ixy; | 1509 | ix = ixy; |
1510 | goto loop; | 1510 | goto loop; |
1511 | } | 1511 | } |
1512 | iy = ixy; | 1512 | iy = ixy; |
1513 | goto loop; | 1513 | goto loop; |
1514 | 1514 | ||
1515 | case 0xF9: // LD SP,IXY | 1515 | case 0xF9: // LD SP,IXY |
1516 | sp = ixy; | 1516 | sp = ixy; |
1517 | goto loop; | 1517 | goto loop; |
1518 | 1518 | ||
1519 | case 0x22:{// LD (ADDR),IXY | 1519 | case 0x22:{// LD (ADDR),IXY |
1520 | int addr = GET_ADDR(); | 1520 | int addr = GET_ADDR(); |
1521 | pc += 2; | 1521 | pc += 2; |
1522 | WRITE_WORD( addr, ixy ); | 1522 | WRITE_WORD( addr, ixy ); |
1523 | goto loop; | 1523 | goto loop; |
1524 | } | 1524 | } |
1525 | 1525 | ||
1526 | case 0x21: // LD IXY,imm | 1526 | case 0x21: // LD IXY,imm |
1527 | ixy = GET_ADDR(); | 1527 | ixy = GET_ADDR(); |
1528 | pc += 2; | 1528 | pc += 2; |
1529 | goto set_ixy; | 1529 | goto set_ixy; |
1530 | 1530 | ||
1531 | case 0x2A:{// LD IXY,(addr) | 1531 | case 0x2A:{// LD IXY,(addr) |
1532 | int addr = GET_ADDR(); | 1532 | int addr = GET_ADDR(); |
1533 | ixy = READ_WORD( addr ); | 1533 | ixy = READ_WORD( addr ); |
1534 | pc += 2; | 1534 | pc += 2; |
1535 | goto set_ixy; | 1535 | goto set_ixy; |
1536 | } | 1536 | } |
1537 | 1537 | ||
1538 | // DD/FD CB prefix | 1538 | // DD/FD CB prefix |
1539 | case 0xCB: { | 1539 | case 0xCB: { |
1540 | data = IXY_DISP( ixy, SBYTE( data2 ) ); | 1540 | data = IXY_DISP( ixy, SBYTE( data2 ) ); |
1541 | pc++; | 1541 | pc++; |
1542 | data2 = READ_CODE( pc ); | 1542 | data2 = READ_CODE( pc ); |
1543 | pc++; | 1543 | pc++; |
1544 | switch ( data2 ) | 1544 | switch ( data2 ) |
1545 | { | 1545 | { |
1546 | case 0x06: goto rlc_data_addr; // RLC (IXY) | 1546 | case 0x06: goto rlc_data_addr; // RLC (IXY) |
1547 | case 0x16: goto rl_data_addr; // RL (IXY) | 1547 | case 0x16: goto rl_data_addr; // RL (IXY) |
1548 | case 0x26: goto sla_data_addr; // SLA (IXY) | 1548 | case 0x26: goto sla_data_addr; // SLA (IXY) |
1549 | case 0x36: goto sll_data_addr; // SLL (IXY) | 1549 | case 0x36: goto sll_data_addr; // SLL (IXY) |
1550 | case 0x0E: goto rrc_data_addr; // RRC (IXY) | 1550 | case 0x0E: goto rrc_data_addr; // RRC (IXY) |
1551 | case 0x1E: goto rr_data_addr; // RR (IXY) | 1551 | case 0x1E: goto rr_data_addr; // RR (IXY) |
1552 | case 0x2E: goto sra_data_addr; // SRA (IXY) | 1552 | case 0x2E: goto sra_data_addr; // SRA (IXY) |
1553 | case 0x3E: goto srl_data_addr; // SRL (IXY) | 1553 | case 0x3E: goto srl_data_addr; // SRL (IXY) |
1554 | 1554 | ||
1555 | CASE8( 46, 4E, 56, 5E, 66, 6E, 76, 7E ):{// BIT b,(IXY+disp) | 1555 | CASE8( 46, 4E, 56, 5E, 66, 6E, 76, 7E ):{// BIT b,(IXY+disp) |
1556 | int temp = READ_MEM( data ); | 1556 | int temp = READ_MEM( data ); |
1557 | temp = temp & (1 << (data2 >> 3 & 7)); | 1557 | temp = temp & (1 << (data2 >> 3 & 7)); |
1558 | flags = (flags & C01) + H10 + (temp & S80); | 1558 | flags = (flags & C01) + H10 + (temp & S80); |
1559 | flags += (unsigned) --temp >> 8 & (Z40 | P04); | 1559 | flags += (unsigned) --temp >> 8 & (Z40 | P04); |
1560 | goto loop; | 1560 | goto loop; |
1561 | } | 1561 | } |
1562 | 1562 | ||
1563 | CASE8( 86, 8E, 96, 9E, A6, AE, B6, BE ): // RES b,(IXY+disp) | 1563 | CASE8( 86, 8E, 96, 9E, A6, AE, B6, BE ): // RES b,(IXY+disp) |
1564 | CASE8( C6, CE, D6, DE, E6, EE, F6, FE ):{// SET b,(IXY+disp) | 1564 | CASE8( C6, CE, D6, DE, E6, EE, F6, FE ):{// SET b,(IXY+disp) |
1565 | int temp = READ_MEM( data ); | 1565 | int temp = READ_MEM( data ); |
1566 | int bit = 1 << (data2 >> 3 & 7); | 1566 | int bit = 1 << (data2 >> 3 & 7); |
1567 | temp |= bit; // SET | 1567 | temp |= bit; // SET |
1568 | if ( !(data2 & 0x40) ) | 1568 | if ( !(data2 & 0x40) ) |
1569 | temp ^= bit; // RES | 1569 | temp ^= bit; // RES |
1570 | WRITE_MEM( data, temp ); | 1570 | WRITE_MEM( data, temp ); |
1571 | goto loop; | 1571 | goto loop; |
1572 | } | 1572 | } |
1573 | 1573 | ||
1574 | default: | 1574 | default: |
1575 | dprintf( "Opcode $%02X $CB $%02X not supported\n", opcode, data2 ); | 1575 | dprintf( "Opcode $%02X $CB $%02X not supported\n", opcode, data2 ); |
1576 | warning = true; | 1576 | warning = true; |
1577 | goto loop; | 1577 | goto loop; |
1578 | } | 1578 | } |
1579 | assert( false ); | 1579 | assert( false ); |
1580 | } | 1580 | } |
1581 | 1581 | ||
1582 | // INC/DEC | 1582 | // INC/DEC |
1583 | case 0x23: // INC IXY | 1583 | case 0x23: // INC IXY |
1584 | ixy = WORD( ixy + 1 ); | 1584 | ixy = WORD( ixy + 1 ); |
1585 | goto set_ixy; | 1585 | goto set_ixy; |
1586 | 1586 | ||
1587 | case 0x2B: // DEC IXY | 1587 | case 0x2B: // DEC IXY |
1588 | ixy = WORD( ixy - 1 ); | 1588 | ixy = WORD( ixy - 1 ); |
1589 | goto set_ixy; | 1589 | goto set_ixy; |
1590 | 1590 | ||
1591 | case 0x34: // INC (IXY+disp) | 1591 | case 0x34: // INC (IXY+disp) |
1592 | ixy = IXY_DISP( ixy, SBYTE( data2 ) ); | 1592 | ixy = IXY_DISP( ixy, SBYTE( data2 ) ); |
1593 | pc++; | 1593 | pc++; |
1594 | data = READ_MEM( ixy ) + 1; | 1594 | data = READ_MEM( ixy ) + 1; |
1595 | WRITE_MEM( ixy, data ); | 1595 | WRITE_MEM( ixy, data ); |
1596 | goto inc_set_flags; | 1596 | goto inc_set_flags; |
1597 | 1597 | ||
1598 | case 0x35: // DEC (IXY+disp) | 1598 | case 0x35: // DEC (IXY+disp) |
1599 | ixy = IXY_DISP( ixy, SBYTE( data2 ) ); | 1599 | ixy = IXY_DISP( ixy, SBYTE( data2 ) ); |
1600 | pc++; | 1600 | pc++; |
1601 | data = READ_MEM( ixy ) - 1; | 1601 | data = READ_MEM( ixy ) - 1; |
1602 | WRITE_MEM( ixy, data ); | 1602 | WRITE_MEM( ixy, data ); |
1603 | goto dec_set_flags; | 1603 | goto dec_set_flags; |
1604 | 1604 | ||
1605 | case 0x24: // INC HXY | 1605 | case 0x24: // INC HXY |
1606 | ixy = WORD( ixy + 0x100 ); | 1606 | ixy = WORD( ixy + 0x100 ); |
1607 | data = ixy >> 8; | 1607 | data = ixy >> 8; |
1608 | goto inc_xy_common; | 1608 | goto inc_xy_common; |
1609 | 1609 | ||
1610 | case 0x2C: // INC LXY | 1610 | case 0x2C: // INC LXY |
1611 | data = BYTE( ixy + 1 ); | 1611 | data = BYTE( ixy + 1 ); |
1612 | ixy = (ixy & 0xFF00) + data; | 1612 | ixy = (ixy & 0xFF00) + data; |
1613 | inc_xy_common: | 1613 | inc_xy_common: |
1614 | if ( opcode == 0xDD ) | 1614 | if ( opcode == 0xDD ) |
1615 | { | 1615 | { |
1616 | ix = ixy; | 1616 | ix = ixy; |
1617 | goto inc_set_flags; | 1617 | goto inc_set_flags; |
1618 | } | 1618 | } |
1619 | iy = ixy; | 1619 | iy = ixy; |
1620 | goto inc_set_flags; | 1620 | goto inc_set_flags; |
1621 | 1621 | ||
1622 | case 0x25: // DEC HXY | 1622 | case 0x25: // DEC HXY |
1623 | ixy = WORD( ixy - 0x100 ); | 1623 | ixy = WORD( ixy - 0x100 ); |
1624 | data = ixy >> 8; | 1624 | data = ixy >> 8; |
1625 | goto dec_xy_common; | 1625 | goto dec_xy_common; |
1626 | 1626 | ||
1627 | case 0x2D: // DEC LXY | 1627 | case 0x2D: // DEC LXY |
1628 | data = BYTE( ixy - 1 ); | 1628 | data = BYTE( ixy - 1 ); |
1629 | ixy = (ixy & 0xFF00) + data; | 1629 | ixy = (ixy & 0xFF00) + data; |
1630 | dec_xy_common: | 1630 | dec_xy_common: |
1631 | if ( opcode == 0xDD ) | 1631 | if ( opcode == 0xDD ) |
1632 | { | 1632 | { |
1633 | ix = ixy; | 1633 | ix = ixy; |
1634 | goto dec_set_flags; | 1634 | goto dec_set_flags; |
1635 | } | 1635 | } |
1636 | iy = ixy; | 1636 | iy = ixy; |
1637 | goto dec_set_flags; | 1637 | goto dec_set_flags; |
1638 | 1638 | ||
1639 | // PUSH/POP | 1639 | // PUSH/POP |
1640 | case 0xE5: // PUSH IXY | 1640 | case 0xE5: // PUSH IXY |
1641 | data = ixy; | 1641 | data = ixy; |
1642 | goto push_data; | 1642 | goto push_data; |
1643 | 1643 | ||
1644 | case 0xE1:{// POP IXY | 1644 | case 0xE1:{// POP IXY |
1645 | ixy = READ_WORD( sp ); | 1645 | ixy = READ_WORD( sp ); |
1646 | sp = WORD( sp + 2 ); | 1646 | sp = WORD( sp + 2 ); |
1647 | goto set_ixy; | 1647 | goto set_ixy; |
1648 | } | 1648 | } |
1649 | 1649 | ||
1650 | // Misc | 1650 | // Misc |
1651 | 1651 | ||
1652 | case 0xE9: // JP (IXY) | 1652 | case 0xE9: // JP (IXY) |
1653 | pc = ixy; | 1653 | pc = ixy; |
1654 | goto loop; | 1654 | goto loop; |
1655 | 1655 | ||
1656 | case 0xE3:{// EX (SP),IXY | 1656 | case 0xE3:{// EX (SP),IXY |
1657 | int temp = READ_WORD( sp ); | 1657 | int temp = READ_WORD( sp ); |
1658 | WRITE_WORD( sp, ixy ); | 1658 | WRITE_WORD( sp, ixy ); |
1659 | ixy = temp; | 1659 | ixy = temp; |
1660 | goto set_ixy; | 1660 | goto set_ixy; |
1661 | } | 1661 | } |
1662 | 1662 | ||
1663 | default: | 1663 | default: |
1664 | dprintf( "Unnecessary DD/FD prefix encountered\n" ); | 1664 | dprintf( "Unnecessary DD/FD prefix encountered\n" ); |
1665 | warning = true; | 1665 | warning = true; |
1666 | pc--; | 1666 | pc--; |
1667 | goto loop; | 1667 | goto loop; |
1668 | } | 1668 | } |
1669 | assert( false ); | 1669 | assert( false ); |
1670 | } | 1670 | } |
1671 | 1671 | ||
1672 | } | 1672 | } |
1673 | dprintf( "Unhandled main opcode: $%02X\n", opcode ); | 1673 | dprintf( "Unhandled main opcode: $%02X\n", opcode ); |
1674 | assert( false ); | 1674 | assert( false ); |
1675 | 1675 | ||
1676 | #ifdef IDLE_ADDR | 1676 | #ifdef IDLE_ADDR |
1677 | hit_idle_addr: | 1677 | hit_idle_addr: |
1678 | s_time -= 11; | 1678 | s_time -= 11; |
1679 | goto out_of_time; | 1679 | goto out_of_time; |
1680 | #endif | 1680 | #endif |
1681 | halt: | 1681 | halt: |
1682 | s_time &= 3; // increment by multiple of 4 | 1682 | s_time &= 3; // increment by multiple of 4 |
1683 | out_of_time: | 1683 | out_of_time: |
1684 | pc--; | 1684 | pc--; |
1685 | 1685 | ||
1686 | r.b.flags = flags; | 1686 | r.b.flags = flags; |
1687 | R.ix = ix; | 1687 | R.ix = ix; |
1688 | R.iy = iy; | 1688 | R.iy = iy; |
1689 | R.sp = sp; | 1689 | R.sp = sp; |
1690 | R.pc = pc; | 1690 | R.pc = pc; |
1691 | R.b = r.b; | 1691 | R.b = r.b; |
1692 | 1692 | ||
1693 | cpu->cpu_state_.base = s.base; | 1693 | cpu->cpu_state_.base = s.base; |
1694 | cpu->cpu_state_.time = s_time; | 1694 | cpu->cpu_state_.time = s_time; |
1695 | cpu->cpu_state = &cpu->cpu_state_; | 1695 | cpu->cpu_state = &cpu->cpu_state_; |
1696 | } | 1696 | } |