diff options
Diffstat (limited to 'apps/codecs/libasap/apokeysnd.c')
-rw-r--r-- | apps/codecs/libasap/apokeysnd.c | 586 |
1 files changed, 323 insertions, 263 deletions
diff --git a/apps/codecs/libasap/apokeysnd.c b/apps/codecs/libasap/apokeysnd.c index 1d48bc20d2..a461fa96da 100644 --- a/apps/codecs/libasap/apokeysnd.c +++ b/apps/codecs/libasap/apokeysnd.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * apokeysnd.c - another POKEY sound emulator | 2 | * apokeysnd.c - another POKEY sound emulator |
3 | * | 3 | * |
4 | * Copyright (C) 2007-2008 Piotr Fusik | 4 | * Copyright (C) 2007-2009 Piotr Fusik |
5 | * | 5 | * |
6 | * This file is part of ASAP (Another Slight Atari Player), | 6 | * This file is part of ASAP (Another Slight Atari Player), |
7 | * see http://asap.sourceforge.net | 7 | * see http://asap.sourceforge.net |
@@ -20,114 +20,109 @@ | |||
20 | * along with ASAP; if not, write to the Free Software Foundation, Inc., | 20 | * along with ASAP; if not, write to the Free Software Foundation, Inc., |
21 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 21 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
22 | */ | 22 | */ |
23 | #include "codeclib.h" | ||
24 | #if !defined(JAVA) && !defined(CSHARP) | ||
25 | #include <string.h> | ||
26 | #endif | ||
27 | 23 | ||
28 | #include "asap_internal.h" | 24 | #include "asap_internal.h" |
29 | 25 | ||
30 | #define memset ci->memset | ||
31 | #define ULTRASOUND_CYCLES 112 | 26 | #define ULTRASOUND_CYCLES 112 |
32 | 27 | ||
33 | #define MUTE_FREQUENCY 1 | 28 | #define MUTE_FREQUENCY 1 |
34 | #define MUTE_INIT 2 | 29 | #define MUTE_INIT 2 |
35 | #define MUTE_USER 4 | 30 | #define MUTE_USER 4 |
36 | 31 | ||
37 | CONST_LOOKUP(byte, poly4_lookup) = | 32 | CONST_ARRAY(byte, poly4_lookup) |
38 | { 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1 }; | 33 | 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1 |
39 | CONST_LOOKUP(byte, poly5_lookup) = | 34 | END_CONST_ARRAY; |
40 | { 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, | 35 | CONST_ARRAY(byte, poly5_lookup) |
41 | 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1 }; | 36 | 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, |
37 | 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1 | ||
38 | END_CONST_ARRAY; | ||
42 | 39 | ||
43 | FILE_FUNC void init_state(PokeyState PTR pst) | 40 | PRIVATE FUNC(void, PokeySound_InitializeChip, (P(PokeyState PTR, pst))) |
44 | { | 41 | { |
45 | PST audctl = 0; | 42 | pst _ audctl = 0; |
46 | PST init = FALSE; | 43 | pst _ init = FALSE; |
47 | PST poly_index = 15 * 31 * 131071; | 44 | pst _ poly_index = 15 * 31 * 131071; |
48 | PST div_cycles = 28; | 45 | pst _ div_cycles = 28; |
49 | PST mute1 = MUTE_FREQUENCY | MUTE_USER; | 46 | pst _ mute1 = MUTE_FREQUENCY | MUTE_USER; |
50 | PST mute2 = MUTE_FREQUENCY | MUTE_USER; | 47 | pst _ mute2 = MUTE_FREQUENCY | MUTE_USER; |
51 | PST mute3 = MUTE_FREQUENCY | MUTE_USER; | 48 | pst _ mute3 = MUTE_FREQUENCY | MUTE_USER; |
52 | PST mute4 = MUTE_FREQUENCY | MUTE_USER; | 49 | pst _ mute4 = MUTE_FREQUENCY | MUTE_USER; |
53 | PST audf1 = 0; | 50 | pst _ audf1 = 0; |
54 | PST audf2 = 0; | 51 | pst _ audf2 = 0; |
55 | PST audf3 = 0; | 52 | pst _ audf3 = 0; |
56 | PST audf4 = 0; | 53 | pst _ audf4 = 0; |
57 | PST audc1 = 0; | 54 | pst _ audc1 = 0; |
58 | PST audc2 = 0; | 55 | pst _ audc2 = 0; |
59 | PST audc3 = 0; | 56 | pst _ audc3 = 0; |
60 | PST audc4 = 0; | 57 | pst _ audc4 = 0; |
61 | PST tick_cycle1 = NEVER; | 58 | pst _ tick_cycle1 = NEVER; |
62 | PST tick_cycle2 = NEVER; | 59 | pst _ tick_cycle2 = NEVER; |
63 | PST tick_cycle3 = NEVER; | 60 | pst _ tick_cycle3 = NEVER; |
64 | PST tick_cycle4 = NEVER; | 61 | pst _ tick_cycle4 = NEVER; |
65 | PST period_cycles1 = 28; | 62 | pst _ period_cycles1 = 28; |
66 | PST period_cycles2 = 28; | 63 | pst _ period_cycles2 = 28; |
67 | PST period_cycles3 = 28; | 64 | pst _ period_cycles3 = 28; |
68 | PST period_cycles4 = 28; | 65 | pst _ period_cycles4 = 28; |
69 | PST reload_cycles1 = 28; | 66 | pst _ reload_cycles1 = 28; |
70 | PST reload_cycles3 = 28; | 67 | pst _ reload_cycles3 = 28; |
71 | PST out1 = 0; | 68 | pst _ out1 = 0; |
72 | PST out2 = 0; | 69 | pst _ out2 = 0; |
73 | PST out3 = 0; | 70 | pst _ out3 = 0; |
74 | PST out4 = 0; | 71 | pst _ out4 = 0; |
75 | PST delta1 = 0; | 72 | pst _ delta1 = 0; |
76 | PST delta2 = 0; | 73 | pst _ delta2 = 0; |
77 | PST delta3 = 0; | 74 | pst _ delta3 = 0; |
78 | PST delta4 = 0; | 75 | pst _ delta4 = 0; |
79 | PST skctl = 3; | 76 | pst _ skctl = 3; |
80 | ZERO_ARRAY(PST delta_buffer); | 77 | ZERO_ARRAY(pst _ delta_buffer); |
81 | } | 78 | } |
82 | 79 | ||
83 | ASAP_FUNC void PokeySound_Initialize(ASAP_State PTR ast) | 80 | FUNC(void, PokeySound_Initialize, (P(ASAP_State PTR, ast))) |
84 | { | 81 | { |
85 | int i; | 82 | V(int, i); |
86 | int reg; | 83 | V(int, reg); |
87 | reg = 0x1ff; | 84 | reg = 0x1ff; |
88 | for (i = 0; i < 511; i++) { | 85 | for (i = 0; i < 511; i++) { |
89 | reg = ((((reg >> 5) ^ reg) & 1) << 8) + (reg >> 1); | 86 | reg = ((((reg >> 5) ^ reg) & 1) << 8) + (reg >> 1); |
90 | AST poly9_lookup[i] = (byte) reg; | 87 | ast _ poly9_lookup[i] = TO_BYTE(reg); |
91 | } | 88 | } |
92 | reg = 0x1ffff; | 89 | reg = 0x1ffff; |
93 | for (i = 0; i < 16385; i++) { | 90 | for (i = 0; i < 16385; i++) { |
94 | reg = ((((reg >> 5) ^ reg) & 0xff) << 9) + (reg >> 8); | 91 | reg = ((((reg >> 5) ^ reg) & 0xff) << 9) + (reg >> 8); |
95 | AST poly17_lookup[i] = (byte) (reg >> 1); | 92 | ast _ poly17_lookup[i] = TO_BYTE(reg >> 1); |
96 | } | 93 | } |
97 | AST sample_offset = 0; | 94 | ast _ sample_offset = 0; |
98 | AST sample_index = 0; | 95 | ast _ sample_index = 0; |
99 | AST samples = 0; | 96 | ast _ samples = 0; |
100 | AST iir_acc_left = 0; | 97 | ast _ iir_acc_left = 0; |
101 | AST iir_acc_right = 0; | 98 | ast _ iir_acc_right = 0; |
102 | init_state(ADDRESSOF AST base_pokey); | 99 | PokeySound_InitializeChip(ADDRESSOF ast _ base_pokey); |
103 | init_state(ADDRESSOF AST extra_pokey); | 100 | PokeySound_InitializeChip(ADDRESSOF ast _ extra_pokey); |
104 | } | 101 | } |
105 | 102 | ||
106 | #define CYCLE_TO_SAMPLE(cycle) (((cycle) * ASAP_SAMPLE_RATE + AST sample_offset) / ASAP_MAIN_CLOCK) | ||
107 | |||
108 | #define DO_TICK(ch) \ | 103 | #define DO_TICK(ch) \ |
109 | if (PST init) { \ | 104 | if (pst _ init) { \ |
110 | switch (PST audc##ch >> 4) { \ | 105 | switch (pst _ audc##ch >> 4) { \ |
111 | case 10: \ | 106 | case 10: \ |
112 | case 14: \ | 107 | case 14: \ |
113 | PST out##ch ^= 1; \ | 108 | pst _ out##ch ^= 1; \ |
114 | PST delta_buffer[CYCLE_TO_SAMPLE(cycle)] += PST delta##ch = -PST delta##ch; \ | 109 | pst _ delta_buffer[CYCLE_TO_SAMPLE(cycle)] += pst _ delta##ch = -pst _ delta##ch; \ |
115 | break; \ | 110 | break; \ |
116 | default: \ | 111 | default: \ |
117 | break; \ | 112 | break; \ |
118 | } \ | 113 | } \ |
119 | } \ | 114 | } \ |
120 | else { \ | 115 | else { \ |
121 | int poly = cycle + PST poly_index - (ch - 1); \ | 116 | V(int, poly) = cycle + pst _ poly_index - (ch - 1); \ |
122 | int newout = PST out##ch; \ | 117 | V(int, newout) = pst _ out##ch; \ |
123 | switch (PST audc##ch >> 4) { \ | 118 | switch (pst _ audc##ch >> 4) { \ |
124 | case 0: \ | 119 | case 0: \ |
125 | if (poly5_lookup[poly % 31] != 0) { \ | 120 | if (poly5_lookup[poly % 31] != 0) { \ |
126 | if ((PST audctl & 0x80) != 0) \ | 121 | if ((pst _ audctl & 0x80) != 0) \ |
127 | newout = AST poly9_lookup[poly % 511] & 1; \ | 122 | newout = ast _ poly9_lookup[poly % 511] & 1; \ |
128 | else { \ | 123 | else { \ |
129 | poly %= 131071; \ | 124 | poly %= 131071; \ |
130 | newout = (AST poly17_lookup[poly >> 3] >> (poly & 7)) & 1; \ | 125 | newout = (ast _ poly17_lookup[poly >> 3] >> (poly & 7)) & 1; \ |
131 | } \ | 126 | } \ |
132 | } \ | 127 | } \ |
133 | break; \ | 128 | break; \ |
@@ -140,11 +135,11 @@ ASAP_FUNC void PokeySound_Initialize(ASAP_State PTR ast) | |||
140 | newout = poly4_lookup[poly % 15]; \ | 135 | newout = poly4_lookup[poly % 15]; \ |
141 | break; \ | 136 | break; \ |
142 | case 8: \ | 137 | case 8: \ |
143 | if ((PST audctl & 0x80) != 0) \ | 138 | if ((pst _ audctl & 0x80) != 0) \ |
144 | newout = AST poly9_lookup[poly % 511] & 1; \ | 139 | newout = ast _ poly9_lookup[poly % 511] & 1; \ |
145 | else { \ | 140 | else { \ |
146 | poly %= 131071; \ | 141 | poly %= 131071; \ |
147 | newout = (AST poly17_lookup[poly >> 3] >> (poly & 7)) & 1; \ | 142 | newout = (ast _ poly17_lookup[poly >> 3] >> (poly & 7)) & 1; \ |
148 | } \ | 143 | } \ |
149 | break; \ | 144 | break; \ |
150 | case 10: \ | 145 | case 10: \ |
@@ -157,125 +152,141 @@ ASAP_FUNC void PokeySound_Initialize(ASAP_State PTR ast) | |||
157 | default: \ | 152 | default: \ |
158 | break; \ | 153 | break; \ |
159 | } \ | 154 | } \ |
160 | if (newout != PST out##ch) { \ | 155 | if (newout != pst _ out##ch) { \ |
161 | PST out##ch = newout; \ | 156 | pst _ out##ch = newout; \ |
162 | PST delta_buffer[CYCLE_TO_SAMPLE(cycle)] += PST delta##ch = -PST delta##ch; \ | 157 | pst _ delta_buffer[CYCLE_TO_SAMPLE(cycle)] += pst _ delta##ch = -pst _ delta##ch; \ |
163 | } \ | 158 | } \ |
164 | } | 159 | } |
165 | 160 | ||
166 | FILE_FUNC void generate(ASAP_State PTR ast, PokeyState PTR pst, int current_cycle) | 161 | /* Fills delta_buffer up to current_cycle basing on current AUDF/AUDC/AUDCTL values. */ |
162 | PRIVATE FUNC(void, PokeySound_GenerateUntilCycle, (P(ASAP_State PTR, ast), P(PokeyState PTR, pst), P(int, current_cycle))) | ||
167 | { | 163 | { |
168 | for (;;) { | 164 | for (;;) { |
169 | int cycle = current_cycle; | 165 | V(int, cycle) = current_cycle; |
170 | if (cycle > PST tick_cycle1) | 166 | if (cycle > pst _ tick_cycle1) |
171 | cycle = PST tick_cycle1; | 167 | cycle = pst _ tick_cycle1; |
172 | if (cycle > PST tick_cycle2) | 168 | if (cycle > pst _ tick_cycle2) |
173 | cycle = PST tick_cycle2; | 169 | cycle = pst _ tick_cycle2; |
174 | if (cycle > PST tick_cycle3) | 170 | if (cycle > pst _ tick_cycle3) |
175 | cycle = PST tick_cycle3; | 171 | cycle = pst _ tick_cycle3; |
176 | if (cycle > PST tick_cycle4) | 172 | if (cycle > pst _ tick_cycle4) |
177 | cycle = PST tick_cycle4; | 173 | cycle = pst _ tick_cycle4; |
178 | if (cycle == current_cycle) | 174 | if (cycle == current_cycle) |
179 | break; | 175 | break; |
180 | if (cycle == PST tick_cycle3) { | 176 | if (cycle == pst _ tick_cycle3) { |
181 | PST tick_cycle3 += PST period_cycles3; | 177 | pst _ tick_cycle3 += pst _ period_cycles3; |
182 | if ((PST audctl & 4) != 0 && PST delta1 > 0 && PST mute1 == 0) | 178 | if ((pst _ audctl & 4) != 0 && pst _ delta1 > 0 && pst _ mute1 == 0) |
183 | PST delta_buffer[CYCLE_TO_SAMPLE(cycle)] += PST delta1 = -PST delta1; | 179 | pst _ delta_buffer[CYCLE_TO_SAMPLE(cycle)] += pst _ delta1 = -pst _ delta1; |
184 | DO_TICK(3); | 180 | DO_TICK(3); |
185 | } | 181 | } |
186 | if (cycle == PST tick_cycle4) { | 182 | if (cycle == pst _ tick_cycle4) { |
187 | PST tick_cycle4 += PST period_cycles4; | 183 | pst _ tick_cycle4 += pst _ period_cycles4; |
188 | if ((PST audctl & 8) != 0) | 184 | if ((pst _ audctl & 8) != 0) |
189 | PST tick_cycle3 = cycle + PST reload_cycles3; | 185 | pst _ tick_cycle3 = cycle + pst _ reload_cycles3; |
190 | if ((PST audctl & 2) != 0 && PST delta2 > 0 && PST mute2 == 0) | 186 | if ((pst _ audctl & 2) != 0 && pst _ delta2 > 0 && pst _ mute2 == 0) |
191 | PST delta_buffer[CYCLE_TO_SAMPLE(cycle)] += PST delta2 = -PST delta2; | 187 | pst _ delta_buffer[CYCLE_TO_SAMPLE(cycle)] += pst _ delta2 = -pst _ delta2; |
192 | DO_TICK(4); | 188 | DO_TICK(4); |
193 | } | 189 | } |
194 | if (cycle == PST tick_cycle1) { | 190 | if (cycle == pst _ tick_cycle1) { |
195 | PST tick_cycle1 += PST period_cycles1; | 191 | pst _ tick_cycle1 += pst _ period_cycles1; |
196 | if ((PST skctl & 0x88) == 8) | 192 | if ((pst _ skctl & 0x88) == 8) /* two-tone, sending 1 (i.e. timer1) */ |
197 | PST tick_cycle2 = cycle + PST period_cycles2; | 193 | pst _ tick_cycle2 = cycle + pst _ period_cycles2; |
198 | DO_TICK(1); | 194 | DO_TICK(1); |
199 | } | 195 | } |
200 | if (cycle == PST tick_cycle2) { | 196 | if (cycle == pst _ tick_cycle2) { |
201 | PST tick_cycle2 += PST period_cycles2; | 197 | pst _ tick_cycle2 += pst _ period_cycles2; |
202 | if ((PST audctl & 0x10) != 0) | 198 | if ((pst _ audctl & 0x10) != 0) |
203 | PST tick_cycle1 = cycle + PST reload_cycles1; | 199 | pst _ tick_cycle1 = cycle + pst _ reload_cycles1; |
204 | else if ((PST skctl & 8) != 0) | 200 | else if ((pst _ skctl & 8) != 0) /* two-tone */ |
205 | PST tick_cycle1 = cycle + PST period_cycles1; | 201 | pst _ tick_cycle1 = cycle + pst _ period_cycles1; |
206 | DO_TICK(2); | 202 | DO_TICK(2); |
207 | } | 203 | } |
208 | } | 204 | } |
209 | } | 205 | } |
210 | 206 | ||
207 | #ifdef APOKEYSND | ||
208 | |||
209 | #define CURRENT_CYCLE 0 | ||
210 | #define CURRENT_SAMPLE 0 | ||
211 | #define DO_STORE(reg) \ | ||
212 | if (data == pst _ reg) \ | ||
213 | break; \ | ||
214 | pst _ reg = data; | ||
215 | |||
216 | #else | ||
217 | |||
218 | #define CURRENT_CYCLE ast _ cycle | ||
219 | #define CURRENT_SAMPLE CYCLE_TO_SAMPLE(ast _ cycle) | ||
220 | #define DO_STORE(reg) \ | ||
221 | if (data == pst _ reg) \ | ||
222 | break; \ | ||
223 | PokeySound_GenerateUntilCycle(ast, pst, ast _ cycle); \ | ||
224 | pst _ reg = data; | ||
225 | |||
226 | #endif /* APOKEYSND */ | ||
227 | |||
211 | #define MUTE_CHANNEL(ch, cond, mask) \ | 228 | #define MUTE_CHANNEL(ch, cond, mask) \ |
212 | if (cond) { \ | 229 | if (cond) { \ |
213 | PST mute##ch |= mask; \ | 230 | pst _ mute##ch |= mask; \ |
214 | PST tick_cycle##ch = NEVER; \ | 231 | pst _ tick_cycle##ch = NEVER; \ |
215 | } \ | 232 | } \ |
216 | else { \ | 233 | else { \ |
217 | PST mute##ch &= ~mask; \ | 234 | pst _ mute##ch &= ~mask; \ |
218 | if (PST tick_cycle##ch == NEVER && PST mute##ch == 0) \ | 235 | if (pst _ tick_cycle##ch == NEVER && pst _ mute##ch == 0) \ |
219 | PST tick_cycle##ch = AST cycle; \ | 236 | pst _ tick_cycle##ch = CURRENT_CYCLE; \ |
220 | } | 237 | } |
221 | 238 | ||
222 | #define DO_ULTRASOUND(ch) \ | 239 | #define DO_ULTRASOUND(ch) \ |
223 | MUTE_CHANNEL(ch, PST period_cycles##ch <= ULTRASOUND_CYCLES && (PST audc##ch >> 4 == 10 || PST audc##ch >> 4 == 14), MUTE_FREQUENCY) | 240 | MUTE_CHANNEL(ch, pst _ period_cycles##ch <= ULTRASOUND_CYCLES && (pst _ audc##ch >> 4 == 10 || pst _ audc##ch >> 4 == 14), MUTE_FREQUENCY) |
224 | 241 | ||
225 | #define DO_AUDC(ch) \ | 242 | #define DO_AUDC(ch) \ |
226 | if (data == PST audc##ch) \ | 243 | DO_STORE(audc##ch); \ |
227 | break; \ | ||
228 | generate(ast, pst, AST cycle); \ | ||
229 | PST audc##ch = data; \ | ||
230 | if ((data & 0x10) != 0) { \ | 244 | if ((data & 0x10) != 0) { \ |
231 | data &= 0xf; \ | 245 | data = (data & 0xf) << DELTA_SHIFT_POKEY; \ |
232 | if ((PST mute##ch & MUTE_USER) == 0) \ | 246 | if ((pst _ mute##ch & MUTE_USER) == 0) \ |
233 | PST delta_buffer[CYCLE_TO_SAMPLE(AST cycle)] \ | 247 | pst _ delta_buffer[CURRENT_SAMPLE] \ |
234 | += PST delta##ch > 0 ? data - PST delta##ch : data; \ | 248 | += pst _ delta##ch > 0 ? data - pst _ delta##ch : data; \ |
235 | PST delta##ch = data; \ | 249 | pst _ delta##ch = data; \ |
236 | } \ | 250 | } \ |
237 | else { \ | 251 | else { \ |
238 | data &= 0xf; \ | 252 | data = (data & 0xf) << DELTA_SHIFT_POKEY; \ |
239 | DO_ULTRASOUND(ch); \ | 253 | DO_ULTRASOUND(ch); \ |
240 | if (PST delta##ch > 0) { \ | 254 | if (pst _ delta##ch > 0) { \ |
241 | if ((PST mute##ch & MUTE_USER) == 0) \ | 255 | if ((pst _ mute##ch & MUTE_USER) == 0) \ |
242 | PST delta_buffer[CYCLE_TO_SAMPLE(AST cycle)] \ | 256 | pst _ delta_buffer[CURRENT_SAMPLE] \ |
243 | += data - PST delta##ch; \ | 257 | += data - pst _ delta##ch; \ |
244 | PST delta##ch = data; \ | 258 | pst _ delta##ch = data; \ |
245 | } \ | 259 | } \ |
246 | else \ | 260 | else \ |
247 | PST delta##ch = -data; \ | 261 | pst _ delta##ch = -data; \ |
248 | } \ | 262 | } \ |
249 | break; | 263 | break; |
250 | 264 | ||
251 | #define DO_INIT(ch, cond) \ | 265 | #define DO_INIT(ch, cond) \ |
252 | MUTE_CHANNEL(ch, PST init && cond, MUTE_INIT) | 266 | MUTE_CHANNEL(ch, pst _ init && cond, MUTE_INIT) |
253 | 267 | ||
254 | ASAP_FUNC void PokeySound_PutByte(ASAP_State PTR ast, int addr, int data) | 268 | FUNC(void, PokeySound_PutByte, (P(ASAP_State PTR, ast), P(int, addr), P(int, data))) |
255 | { | 269 | { |
256 | PokeyState PTR pst = (addr & AST extra_pokey_mask) != 0 | 270 | V(PokeyState PTR, pst) = (addr & ast _ extra_pokey_mask) != 0 |
257 | ? ADDRESSOF AST extra_pokey : ADDRESSOF AST base_pokey; | 271 | ? ADDRESSOF ast _ extra_pokey : ADDRESSOF ast _ base_pokey; |
258 | switch (addr & 0xf) { | 272 | switch (addr & 0xf) { |
259 | case 0x00: | 273 | case 0x00: |
260 | if (data == PST audf1) | 274 | DO_STORE(audf1); |
261 | break; | 275 | switch (pst _ audctl & 0x50) { |
262 | generate(ast, pst, AST cycle); | ||
263 | PST audf1 = data; | ||
264 | switch (PST audctl & 0x50) { | ||
265 | case 0x00: | 276 | case 0x00: |
266 | PST period_cycles1 = PST div_cycles * (data + 1); | 277 | pst _ period_cycles1 = pst _ div_cycles * (data + 1); |
267 | break; | 278 | break; |
268 | case 0x10: | 279 | case 0x10: |
269 | PST period_cycles2 = PST div_cycles * (data + 256 * PST audf2 + 1); | 280 | pst _ period_cycles2 = pst _ div_cycles * (data + 256 * pst _ audf2 + 1); |
270 | PST reload_cycles1 = PST div_cycles * (data + 1); | 281 | pst _ reload_cycles1 = pst _ div_cycles * (data + 1); |
271 | DO_ULTRASOUND(2); | 282 | DO_ULTRASOUND(2); |
272 | break; | 283 | break; |
273 | case 0x40: | 284 | case 0x40: |
274 | PST period_cycles1 = data + 4; | 285 | pst _ period_cycles1 = data + 4; |
275 | break; | 286 | break; |
276 | case 0x50: | 287 | case 0x50: |
277 | PST period_cycles2 = data + 256 * PST audf2 + 7; | 288 | pst _ period_cycles2 = data + 256 * pst _ audf2 + 7; |
278 | PST reload_cycles1 = data + 4; | 289 | pst _ reload_cycles1 = data + 4; |
279 | DO_ULTRASOUND(2); | 290 | DO_ULTRASOUND(2); |
280 | break; | 291 | break; |
281 | } | 292 | } |
@@ -284,20 +295,17 @@ ASAP_FUNC void PokeySound_PutByte(ASAP_State PTR ast, int addr, int data) | |||
284 | case 0x01: | 295 | case 0x01: |
285 | DO_AUDC(1) | 296 | DO_AUDC(1) |
286 | case 0x02: | 297 | case 0x02: |
287 | if (data == PST audf2) | 298 | DO_STORE(audf2); |
288 | break; | 299 | switch (pst _ audctl & 0x50) { |
289 | generate(ast, pst, AST cycle); | ||
290 | PST audf2 = data; | ||
291 | switch (PST audctl & 0x50) { | ||
292 | case 0x00: | 300 | case 0x00: |
293 | case 0x40: | 301 | case 0x40: |
294 | PST period_cycles2 = PST div_cycles * (data + 1); | 302 | pst _ period_cycles2 = pst _ div_cycles * (data + 1); |
295 | break; | 303 | break; |
296 | case 0x10: | 304 | case 0x10: |
297 | PST period_cycles2 = PST div_cycles * (PST audf1 + 256 * data + 1); | 305 | pst _ period_cycles2 = pst _ div_cycles * (pst _ audf1 + 256 * data + 1); |
298 | break; | 306 | break; |
299 | case 0x50: | 307 | case 0x50: |
300 | PST period_cycles2 = PST audf1 + 256 * data + 7; | 308 | pst _ period_cycles2 = pst _ audf1 + 256 * data + 7; |
301 | break; | 309 | break; |
302 | } | 310 | } |
303 | DO_ULTRASOUND(2); | 311 | DO_ULTRASOUND(2); |
@@ -305,25 +313,22 @@ ASAP_FUNC void PokeySound_PutByte(ASAP_State PTR ast, int addr, int data) | |||
305 | case 0x03: | 313 | case 0x03: |
306 | DO_AUDC(2) | 314 | DO_AUDC(2) |
307 | case 0x04: | 315 | case 0x04: |
308 | if (data == PST audf3) | 316 | DO_STORE(audf3); |
309 | break; | 317 | switch (pst _ audctl & 0x28) { |
310 | generate(ast, pst, AST cycle); | ||
311 | PST audf3 = data; | ||
312 | switch (PST audctl & 0x28) { | ||
313 | case 0x00: | 318 | case 0x00: |
314 | PST period_cycles3 = PST div_cycles * (data + 1); | 319 | pst _ period_cycles3 = pst _ div_cycles * (data + 1); |
315 | break; | 320 | break; |
316 | case 0x08: | 321 | case 0x08: |
317 | PST period_cycles4 = PST div_cycles * (data + 256 * PST audf4 + 1); | 322 | pst _ period_cycles4 = pst _ div_cycles * (data + 256 * pst _ audf4 + 1); |
318 | PST reload_cycles3 = PST div_cycles * (data + 1); | 323 | pst _ reload_cycles3 = pst _ div_cycles * (data + 1); |
319 | DO_ULTRASOUND(4); | 324 | DO_ULTRASOUND(4); |
320 | break; | 325 | break; |
321 | case 0x20: | 326 | case 0x20: |
322 | PST period_cycles3 = data + 4; | 327 | pst _ period_cycles3 = data + 4; |
323 | break; | 328 | break; |
324 | case 0x28: | 329 | case 0x28: |
325 | PST period_cycles4 = data + 256 * PST audf4 + 7; | 330 | pst _ period_cycles4 = data + 256 * pst _ audf4 + 7; |
326 | PST reload_cycles3 = data + 4; | 331 | pst _ reload_cycles3 = data + 4; |
327 | DO_ULTRASOUND(4); | 332 | DO_ULTRASOUND(4); |
328 | break; | 333 | break; |
329 | } | 334 | } |
@@ -332,20 +337,17 @@ ASAP_FUNC void PokeySound_PutByte(ASAP_State PTR ast, int addr, int data) | |||
332 | case 0x05: | 337 | case 0x05: |
333 | DO_AUDC(3) | 338 | DO_AUDC(3) |
334 | case 0x06: | 339 | case 0x06: |
335 | if (data == PST audf4) | 340 | DO_STORE(audf4); |
336 | break; | 341 | switch (pst _ audctl & 0x28) { |
337 | generate(ast, pst, AST cycle); | ||
338 | PST audf4 = data; | ||
339 | switch (PST audctl & 0x28) { | ||
340 | case 0x00: | 342 | case 0x00: |
341 | case 0x20: | 343 | case 0x20: |
342 | PST period_cycles4 = PST div_cycles * (data + 1); | 344 | pst _ period_cycles4 = pst _ div_cycles * (data + 1); |
343 | break; | 345 | break; |
344 | case 0x08: | 346 | case 0x08: |
345 | PST period_cycles4 = PST div_cycles * (PST audf3 + 256 * data + 1); | 347 | pst _ period_cycles4 = pst _ div_cycles * (pst _ audf3 + 256 * data + 1); |
346 | break; | 348 | break; |
347 | case 0x28: | 349 | case 0x28: |
348 | PST period_cycles4 = PST audf3 + 256 * data + 7; | 350 | pst _ period_cycles4 = pst _ audf3 + 256 * data + 7; |
349 | break; | 351 | break; |
350 | } | 352 | } |
351 | DO_ULTRASOUND(4); | 353 | DO_ULTRASOUND(4); |
@@ -353,141 +355,153 @@ ASAP_FUNC void PokeySound_PutByte(ASAP_State PTR ast, int addr, int data) | |||
353 | case 0x07: | 355 | case 0x07: |
354 | DO_AUDC(4) | 356 | DO_AUDC(4) |
355 | case 0x08: | 357 | case 0x08: |
356 | if (data == PST audctl) | 358 | DO_STORE(audctl); |
357 | break; | 359 | pst _ div_cycles = ((data & 1) != 0) ? 114 : 28; |
358 | generate(ast, pst, AST cycle); | ||
359 | PST audctl = data; | ||
360 | PST div_cycles = ((data & 1) != 0) ? 114 : 28; | ||
361 | /* TODO: tick_cycles */ | 360 | /* TODO: tick_cycles */ |
362 | switch (data & 0x50) { | 361 | switch (data & 0x50) { |
363 | case 0x00: | 362 | case 0x00: |
364 | PST period_cycles1 = PST div_cycles * (PST audf1 + 1); | 363 | pst _ period_cycles1 = pst _ div_cycles * (pst _ audf1 + 1); |
365 | PST period_cycles2 = PST div_cycles * (PST audf2 + 1); | 364 | pst _ period_cycles2 = pst _ div_cycles * (pst _ audf2 + 1); |
366 | break; | 365 | break; |
367 | case 0x10: | 366 | case 0x10: |
368 | PST period_cycles1 = PST div_cycles * 256; | 367 | pst _ period_cycles1 = pst _ div_cycles * 256; |
369 | PST period_cycles2 = PST div_cycles * (PST audf1 + 256 * PST audf2 + 1); | 368 | pst _ period_cycles2 = pst _ div_cycles * (pst _ audf1 + 256 * pst _ audf2 + 1); |
370 | PST reload_cycles1 = PST div_cycles * (PST audf1 + 1); | 369 | pst _ reload_cycles1 = pst _ div_cycles * (pst _ audf1 + 1); |
371 | break; | 370 | break; |
372 | case 0x40: | 371 | case 0x40: |
373 | PST period_cycles1 = PST audf1 + 4; | 372 | pst _ period_cycles1 = pst _ audf1 + 4; |
374 | PST period_cycles2 = PST div_cycles * (PST audf2 + 1); | 373 | pst _ period_cycles2 = pst _ div_cycles * (pst _ audf2 + 1); |
375 | break; | 374 | break; |
376 | case 0x50: | 375 | case 0x50: |
377 | PST period_cycles1 = 256; | 376 | pst _ period_cycles1 = 256; |
378 | PST period_cycles2 = PST audf1 + 256 * PST audf2 + 7; | 377 | pst _ period_cycles2 = pst _ audf1 + 256 * pst _ audf2 + 7; |
379 | PST reload_cycles1 = PST audf1 + 4; | 378 | pst _ reload_cycles1 = pst _ audf1 + 4; |
380 | break; | 379 | break; |
381 | } | 380 | } |
382 | DO_ULTRASOUND(1); | 381 | DO_ULTRASOUND(1); |
383 | DO_ULTRASOUND(2); | 382 | DO_ULTRASOUND(2); |
384 | switch (data & 0x28) { | 383 | switch (data & 0x28) { |
385 | case 0x00: | 384 | case 0x00: |
386 | PST period_cycles3 = PST div_cycles * (PST audf3 + 1); | 385 | pst _ period_cycles3 = pst _ div_cycles * (pst _ audf3 + 1); |
387 | PST period_cycles4 = PST div_cycles * (PST audf4 + 1); | 386 | pst _ period_cycles4 = pst _ div_cycles * (pst _ audf4 + 1); |
388 | break; | 387 | break; |
389 | case 0x08: | 388 | case 0x08: |
390 | PST period_cycles3 = PST div_cycles * 256; | 389 | pst _ period_cycles3 = pst _ div_cycles * 256; |
391 | PST period_cycles4 = PST div_cycles * (PST audf3 + 256 * PST audf4 + 1); | 390 | pst _ period_cycles4 = pst _ div_cycles * (pst _ audf3 + 256 * pst _ audf4 + 1); |
392 | PST reload_cycles3 = PST div_cycles * (PST audf3 + 1); | 391 | pst _ reload_cycles3 = pst _ div_cycles * (pst _ audf3 + 1); |
393 | break; | 392 | break; |
394 | case 0x20: | 393 | case 0x20: |
395 | PST period_cycles3 = PST audf3 + 4; | 394 | pst _ period_cycles3 = pst _ audf3 + 4; |
396 | PST period_cycles4 = PST div_cycles * (PST audf4 + 1); | 395 | pst _ period_cycles4 = pst _ div_cycles * (pst _ audf4 + 1); |
397 | break; | 396 | break; |
398 | case 0x28: | 397 | case 0x28: |
399 | PST period_cycles3 = 256; | 398 | pst _ period_cycles3 = 256; |
400 | PST period_cycles4 = PST audf3 + 256 * PST audf4 + 7; | 399 | pst _ period_cycles4 = pst _ audf3 + 256 * pst _ audf4 + 7; |
401 | PST reload_cycles3 = PST audf3 + 4; | 400 | pst _ reload_cycles3 = pst _ audf3 + 4; |
402 | break; | 401 | break; |
403 | } | 402 | } |
404 | DO_ULTRASOUND(3); | 403 | DO_ULTRASOUND(3); |
405 | DO_ULTRASOUND(4); | 404 | DO_ULTRASOUND(4); |
405 | DO_INIT(1, (data & 0x40) == 0); | ||
406 | DO_INIT(2, (data & 0x50) != 0x50); | ||
407 | DO_INIT(3, (data & 0x20) == 0); | ||
408 | DO_INIT(4, (data & 0x28) != 0x28); | ||
406 | break; | 409 | break; |
407 | case 0x09: | 410 | case 0x09: |
408 | /* TODO: STIMER */ | 411 | /* TODO: STIMER */ |
409 | break; | 412 | break; |
410 | case 0x0f: | 413 | case 0x0f: |
411 | PST skctl = data; | 414 | DO_STORE(skctl); |
412 | PST init = ((data & 3) == 0); | 415 | pst _ init = ((data & 3) == 0); |
413 | DO_INIT(1, (PST audctl & 0x40) == 0); | 416 | DO_INIT(1, (pst _ audctl & 0x40) == 0); |
414 | DO_INIT(2, (PST audctl & 0x50) != 0x50); | 417 | DO_INIT(2, (pst _ audctl & 0x50) != 0x50); |
415 | DO_INIT(3, (PST audctl & 0x20) == 0); | 418 | DO_INIT(3, (pst _ audctl & 0x20) == 0); |
416 | DO_INIT(4, (PST audctl & 0x28) != 0x28); | 419 | DO_INIT(4, (pst _ audctl & 0x28) != 0x28); |
417 | break; | 420 | break; |
418 | default: | 421 | default: |
419 | break; | 422 | break; |
420 | } | 423 | } |
421 | } | 424 | } |
422 | 425 | ||
423 | ASAP_FUNC int PokeySound_GetRandom(ASAP_State PTR ast, int addr) | 426 | FUNC(int, PokeySound_GetRandom, (P(ASAP_State PTR, ast), P(int, addr), P(int, cycle))) |
424 | { | 427 | { |
425 | PokeyState PTR pst = (addr & AST extra_pokey_mask) != 0 | 428 | V(PokeyState PTR, pst) = (addr & ast _ extra_pokey_mask) != 0 |
426 | ? ADDRESSOF AST extra_pokey : ADDRESSOF AST base_pokey; | 429 | ? ADDRESSOF ast _ extra_pokey : ADDRESSOF ast _ base_pokey; |
427 | int i; | 430 | V(int, i); |
428 | if (PST init) | 431 | if (pst _ init) |
429 | return 0xff; | 432 | return 0xff; |
430 | i = AST cycle + PST poly_index; | 433 | i = cycle + pst _ poly_index; |
431 | if ((PST audctl & 0x80) != 0) | 434 | if ((pst _ audctl & 0x80) != 0) |
432 | return AST poly9_lookup[i % 511]; | 435 | return ast _ poly9_lookup[i % 511]; |
433 | else { | 436 | else { |
434 | int j; | 437 | V(int, j); |
435 | i %= 131071; | 438 | i %= 131071; |
436 | j = i >> 3; | 439 | j = i >> 3; |
437 | i &= 7; | 440 | i &= 7; |
438 | return ((AST poly17_lookup[j] >> i) + (AST poly17_lookup[j + 1] << (8 - i))) & 0xff; | 441 | return ((ast _ poly17_lookup[j] >> i) + (ast _ poly17_lookup[j + 1] << (8 - i))) & 0xff; |
439 | } | 442 | } |
440 | } | 443 | } |
441 | 444 | ||
442 | FILE_FUNC void end_frame(ASAP_State PTR ast, PokeyState PTR pst, int cycle_limit) | 445 | PRIVATE FUNC(void, end_frame, (P(ASAP_State PTR, ast), P(PokeyState PTR, pst), P(int, cycle_limit))) |
443 | { | 446 | { |
444 | int m; | 447 | V(int, m); |
445 | generate(ast, pst, cycle_limit); | 448 | PokeySound_GenerateUntilCycle(ast, pst, cycle_limit); |
446 | PST poly_index += cycle_limit; | 449 | pst _ poly_index += cycle_limit; |
447 | m = ((PST audctl & 0x80) != 0) ? 15 * 31 * 511 : 15 * 31 * 131071; | 450 | m = ((pst _ audctl & 0x80) != 0) ? 15 * 31 * 511 : 15 * 31 * 131071; |
448 | if (PST poly_index >= 2 * m) | 451 | if (pst _ poly_index >= 2 * m) |
449 | PST poly_index -= m; | 452 | pst _ poly_index -= m; |
450 | if (PST tick_cycle1 != NEVER) | 453 | if (pst _ tick_cycle1 != NEVER) |
451 | PST tick_cycle1 -= cycle_limit; | 454 | pst _ tick_cycle1 -= cycle_limit; |
452 | if (PST tick_cycle2 != NEVER) | 455 | if (pst _ tick_cycle2 != NEVER) |
453 | PST tick_cycle2 -= cycle_limit; | 456 | pst _ tick_cycle2 -= cycle_limit; |
454 | if (PST tick_cycle3 != NEVER) | 457 | if (pst _ tick_cycle3 != NEVER) |
455 | PST tick_cycle3 -= cycle_limit; | 458 | pst _ tick_cycle3 -= cycle_limit; |
456 | if (PST tick_cycle4 != NEVER) | 459 | if (pst _ tick_cycle4 != NEVER) |
457 | PST tick_cycle4 -= cycle_limit; | 460 | pst _ tick_cycle4 -= cycle_limit; |
458 | } | 461 | } |
459 | 462 | ||
460 | ASAP_FUNC void PokeySound_StartFrame(ASAP_State PTR ast) | 463 | FUNC(void, PokeySound_StartFrame, (P(ASAP_State PTR, ast))) |
461 | { | 464 | { |
462 | ZERO_ARRAY(AST base_pokey.delta_buffer); | 465 | ZERO_ARRAY(ast _ base_pokey.delta_buffer); |
463 | if (AST extra_pokey_mask != 0) | 466 | if (ast _ extra_pokey_mask != 0) |
464 | ZERO_ARRAY(AST extra_pokey.delta_buffer); | 467 | ZERO_ARRAY(ast _ extra_pokey.delta_buffer); |
465 | } | 468 | } |
466 | 469 | ||
467 | ASAP_FUNC void PokeySound_EndFrame(ASAP_State PTR ast, int current_cycle) | 470 | FUNC(void, PokeySound_EndFrame, (P(ASAP_State PTR, ast), P(int, current_cycle))) |
468 | { | 471 | { |
469 | end_frame(ast, ADDRESSOF AST base_pokey, current_cycle); | 472 | end_frame(ast, ADDRESSOF ast _ base_pokey, current_cycle); |
470 | if (AST extra_pokey_mask != 0) | 473 | if (ast _ extra_pokey_mask != 0) |
471 | end_frame(ast, ADDRESSOF AST extra_pokey, current_cycle); | 474 | end_frame(ast, ADDRESSOF ast _ extra_pokey, current_cycle); |
472 | AST sample_offset += current_cycle * ASAP_SAMPLE_RATE; | 475 | ast _ sample_offset += current_cycle * ASAP_SAMPLE_RATE; |
473 | AST sample_index = 0; | 476 | ast _ sample_index = 0; |
474 | AST samples = AST sample_offset / ASAP_MAIN_CLOCK; | 477 | ast _ samples = TO_INT(ast _ sample_offset / ASAP_MAIN_CLOCK); |
475 | AST sample_offset %= ASAP_MAIN_CLOCK; | 478 | ast _ sample_offset %= ASAP_MAIN_CLOCK; |
476 | } | 479 | } |
477 | 480 | ||
478 | ASAP_FUNC int PokeySound_Generate(ASAP_State PTR ast, byte ARRAY buffer, int buffer_offset, int blocks, ASAP_SampleFormat format) | 481 | /* Fills buffer with samples from delta_buffer. */ |
482 | FUNC(int, PokeySound_Generate, (P(ASAP_State PTR, ast), P(BYTEARRAY, buffer), P(int, buffer_offset), P(int, blocks), P(ASAP_SampleFormat, format))) | ||
479 | { | 483 | { |
480 | int i = AST sample_index; | 484 | V(int, i) = ast _ sample_index; |
481 | int samples = AST samples; | 485 | V(int, samples) = ast _ samples; |
482 | int acc_left = AST iir_acc_left; | 486 | V(int, acc_left) = ast _ iir_acc_left; |
483 | int acc_right = AST iir_acc_right; | 487 | V(int, acc_right) = ast _ iir_acc_right; |
484 | if (blocks < samples - i) | 488 | if (blocks < samples - i) |
485 | samples = i + blocks; | 489 | samples = i + blocks; |
486 | else | 490 | else |
487 | blocks = samples - i; | 491 | blocks = samples - i; |
488 | for (; i < samples; i++) { | 492 | for (; i < samples; i++) { |
489 | int sample; | 493 | #ifdef ACTIONSCRIPT |
490 | acc_left += (AST base_pokey.delta_buffer[i] << 20) - (acc_left * 3 >> 10); | 494 | acc_left += ast _ base_pokey.delta_buffer[i] - (acc_left * 3 >> 10); |
495 | var sample : Number = acc_left / 33553408; | ||
496 | buffer.writeFloat(sample); | ||
497 | if (ast.extra_pokey_mask != 0) { | ||
498 | acc_right += ast _ extra_pokey.delta_buffer[i] - (acc_right * 3 >> 10); | ||
499 | sample = acc_right / 33553408; | ||
500 | } | ||
501 | buffer.writeFloat(sample); | ||
502 | #else | ||
503 | V(int, sample); | ||
504 | acc_left += ast _ base_pokey.delta_buffer[i] - (acc_left * 3 >> 10); | ||
491 | sample = acc_left >> 10; | 505 | sample = acc_left >> 10; |
492 | #define STORE_SAMPLE \ | 506 | #define STORE_SAMPLE \ |
493 | if (sample < -32767) \ | 507 | if (sample < -32767) \ |
@@ -496,43 +510,89 @@ ASAP_FUNC int PokeySound_Generate(ASAP_State PTR ast, byte ARRAY buffer, int buf | |||
496 | sample = 32767; \ | 510 | sample = 32767; \ |
497 | switch (format) { \ | 511 | switch (format) { \ |
498 | case ASAP_FORMAT_U8: \ | 512 | case ASAP_FORMAT_U8: \ |
499 | buffer[buffer_offset++] = (byte) ((sample >> 8) + 128); \ | 513 | buffer[buffer_offset++] = CAST(byte) ((sample >> 8) + 128); \ |
500 | break; \ | 514 | break; \ |
501 | case ASAP_FORMAT_S16_LE: \ | 515 | case ASAP_FORMAT_S16_LE: \ |
502 | buffer[buffer_offset++] = (byte) sample; \ | 516 | buffer[buffer_offset++] = TO_BYTE(sample); \ |
503 | buffer[buffer_offset++] = (byte) (sample >> 8); \ | 517 | buffer[buffer_offset++] = TO_BYTE(sample >> 8); \ |
504 | break; \ | 518 | break; \ |
505 | case ASAP_FORMAT_S16_BE: \ | 519 | case ASAP_FORMAT_S16_BE: \ |
506 | buffer[buffer_offset++] = (byte) (sample >> 8); \ | 520 | buffer[buffer_offset++] = TO_BYTE(sample >> 8); \ |
507 | buffer[buffer_offset++] = (byte) sample; \ | 521 | buffer[buffer_offset++] = TO_BYTE(sample); \ |
508 | break; \ | 522 | break; \ |
509 | } | 523 | } |
510 | STORE_SAMPLE; | 524 | STORE_SAMPLE; |
511 | if (AST extra_pokey_mask != 0) { | 525 | if (ast _ extra_pokey_mask != 0) { |
512 | acc_right += (AST extra_pokey.delta_buffer[i] << 20) - (acc_right * 3 >> 10); | 526 | acc_right += ast _ extra_pokey.delta_buffer[i] - (acc_right * 3 >> 10); |
513 | sample = acc_right >> 10; | 527 | sample = acc_right >> 10; |
514 | STORE_SAMPLE; | 528 | STORE_SAMPLE; |
515 | } | 529 | } |
530 | #endif /* ACTIONSCRIPT */ | ||
516 | } | 531 | } |
517 | if (i == AST samples) { | 532 | if (i == ast _ samples) { |
518 | acc_left += AST base_pokey.delta_buffer[i] << 20; | 533 | acc_left += ast _ base_pokey.delta_buffer[i]; |
519 | acc_right += AST extra_pokey.delta_buffer[i] << 20; | 534 | acc_right += ast _ extra_pokey.delta_buffer[i]; |
520 | } | 535 | } |
521 | AST sample_index = i; | 536 | ast _ sample_index = i; |
522 | AST iir_acc_left = acc_left; | 537 | ast _ iir_acc_left = acc_left; |
523 | AST iir_acc_right = acc_right; | 538 | ast _ iir_acc_right = acc_right; |
539 | #ifdef APOKEYSND | ||
540 | return buffer_offset; | ||
541 | #else | ||
524 | return blocks; | 542 | return blocks; |
543 | #endif | ||
525 | } | 544 | } |
526 | 545 | ||
527 | ASAP_FUNC abool PokeySound_IsSilent(const PokeyState PTR pst) | 546 | FUNC(abool, PokeySound_IsSilent, (P(CONST PokeyState PTR, pst))) |
528 | { | 547 | { |
529 | return ((PST audc1 | PST audc2 | PST audc3 | PST audc4) & 0xf) == 0; | 548 | return ((pst _ audc1 | pst _ audc2 | pst _ audc3 | pst _ audc4) & 0xf) == 0; |
530 | } | 549 | } |
531 | 550 | ||
532 | ASAP_FUNC void PokeySound_Mute(const ASAP_State PTR ast, PokeyState PTR pst, int mask) | 551 | FUNC(void, PokeySound_Mute, (P(CONST ASAP_State PTR, ast), P(PokeyState PTR, pst), P(int, mask))) |
533 | { | 552 | { |
534 | MUTE_CHANNEL(1, (mask & 1) != 0, MUTE_USER); | 553 | MUTE_CHANNEL(1, (mask & 1) != 0, MUTE_USER); |
535 | MUTE_CHANNEL(2, (mask & 2) != 0, MUTE_USER); | 554 | MUTE_CHANNEL(2, (mask & 2) != 0, MUTE_USER); |
536 | MUTE_CHANNEL(3, (mask & 4) != 0, MUTE_USER); | 555 | MUTE_CHANNEL(3, (mask & 4) != 0, MUTE_USER); |
537 | MUTE_CHANNEL(4, (mask & 8) != 0, MUTE_USER); | 556 | MUTE_CHANNEL(4, (mask & 8) != 0, MUTE_USER); |
538 | } | 557 | } |
558 | |||
559 | #ifdef APOKEYSND | ||
560 | |||
561 | static ASAP_State asap; | ||
562 | |||
563 | __declspec(dllexport) void APokeySound_Initialize(abool stereo) | ||
564 | { | ||
565 | asap.extra_pokey_mask = stereo ? 0x10 : 0; | ||
566 | PokeySound_Initialize(&asap); | ||
567 | PokeySound_Mute(&asap, &asap.base_pokey, 0); | ||
568 | PokeySound_Mute(&asap, &asap.extra_pokey, 0); | ||
569 | PokeySound_StartFrame(&asap); | ||
570 | } | ||
571 | |||
572 | __declspec(dllexport) void APokeySound_PutByte(int addr, int data) | ||
573 | { | ||
574 | PokeySound_PutByte(&asap, addr, data); | ||
575 | } | ||
576 | |||
577 | __declspec(dllexport) int APokeySound_GetRandom(int addr, int cycle) | ||
578 | { | ||
579 | return PokeySound_GetRandom(&asap, addr, cycle); | ||
580 | } | ||
581 | |||
582 | __declspec(dllexport) int APokeySound_Generate(int cycles, byte buffer[], ASAP_SampleFormat format) | ||
583 | { | ||
584 | int len; | ||
585 | PokeySound_EndFrame(&asap, cycles); | ||
586 | len = PokeySound_Generate(&asap, buffer, 0, asap.samples, format); | ||
587 | PokeySound_StartFrame(&asap); | ||
588 | return len; | ||
589 | } | ||
590 | |||
591 | __declspec(dllexport) void APokeySound_About(const char **name, const char **author, const char **description) | ||
592 | { | ||
593 | *name = "Another POKEY sound emulator, v" ASAP_VERSION; | ||
594 | *author = "Piotr Fusik, (C) " ASAP_YEARS; | ||
595 | *description = "Part of ASAP, http://asap.sourceforge.net"; | ||
596 | } | ||
597 | |||
598 | #endif /* APOKEYSND */ | ||