1 /*****************************************************************************
2 *
3 * POKEY chip emulator 4.3
4 * Copyright (c) 2000 by The MAME Team
5 *
6 * Based on original info found in Ron Fries' Pokey emulator,
7 * with additions by Brad Oliver, Eric Smith and Juergen Buchmueller,
8 * paddle (a/d conversion) details from the Atari 400/800 Hardware Manual.
9 * Polynome algorithms according to info supplied by Perry McFarlane.
10 *
11 * This code is subject to the MAME license, which besides other
12 * things means it is distributed as is, no warranties whatsoever.
13 * For more details read the readme.txt that comes with MAME.
14 *
15 * 4.4:
16 * - reversed sample values to make OFF channels produce a zero signal.
17 * actually de-reversed them; don't remember that I reversed them ;-/
18 * 4.3:
19 * - for POT inputs returning zero, immediately assert the ALLPOT
20 * bit after POTGO is written, otherwise start trigger timer
21 * depending on SK_PADDLE mode, either 1-228 scanlines or 1-2
22 * scanlines, depending on the SK_PADDLE bit of SKCTL.
23 * 4.2:
24 * - half volume for channels which are inaudible (this should be
25 * close to the real thing).
26 * 4.1:
27 * - default gain increased to closely match the old code.
28 * - random numbers repeat rate depends on POLY9 flag too!
29 * - verified sound output with many, many Atari 800 games,
30 * including the SUPPRESS_INAUDIBLE optimizations.
31 * 4.0:
32 * - rewritten from scratch.
33 * - 16bit stream interface.
34 * - serout ready/complete delayed interrupts.
35 * - reworked pot analog/digital conversion timing.
36 * - optional non-indexing pokey update functions.
37 *
38 *****************************************************************************/
39
40 #include "driver.h"
41
42 /*
43 * Defining this produces much more (about twice as much)
44 * but also more efficient code. Ideally this should be set
45 * for processors with big code cache and for healthy compilers :)
46 */
47 #ifndef BIG_SWITCH
48 #ifndef HEAVY_MACRO_USAGE
49 #define HEAVY_MACRO_USAGE 1
50 #endif
51 #else
52 #define HEAVY_MACRO_USAGE BIG_SWITCH
53 #endif
54
55 #define SUPPRESS_INAUDIBLE 1
56
57 /* Four channels with a range of 0..32767 and volume 0..15 */
58 //#define POKEY_DEFAULT_GAIN (32767/15/4)
59
60 /*
61 * But we raise the gain and risk clipping, the old Pokey did
62 * this too. It defined POKEY_DEFAULT_GAIN 6 and this was
63 * 6 * 15 * 4 = 360, 360/256 = 1.40625
64 * I use 15/11 = 1.3636, so this is a little lower.
65 */
66 #define POKEY_DEFAULT_GAIN (32767/11/4)
67
68 #define VERBOSE 0
69 #define VERBOSE_SOUND 0
70 #define VERBOSE_TIMER 0
71 #define VERBOSE_POLY 0
72 #define VERBOSE_RAND 0
73
74 #if VERBOSE
75 #define LOG(x) logerror x
76 #else
77 #define LOG(x)
78 #endif
79
80 #if VERBOSE_SOUND
81 #define LOG_SOUND(x) logerror x
82 #else
83 #define LOG_SOUND(x)
84 #endif
85
86 #if VERBOSE_TIMER
87 #define LOG_TIMER(x) logerror x
88 #else
89 #define LOG_TIMER(x)
90 #endif
91
92 #if VERBOSE_POLY
93 #define LOG_POLY(x) logerror x
94 #else
95 #define LOG_POLY(x)
96 #endif
97
98 #if VERBOSE_RAND
99 #define LOG_RAND(x) logerror x
100 #else
101 #define LOG_RAND(x)
102 #endif
103
104 #define CHAN1 0
105 #define CHAN2 1
106 #define CHAN3 2
107 #define CHAN4 3
108
109 #define TIMER1 0
110 #define TIMER2 1
111 #define TIMER4 2
112
113 /* values to add to the divisors for the different modes */
114 #define DIVADD_LOCLK 1
115 #define DIVADD_HICLK 4
116 #define DIVADD_HICLK_JOINED 7
117
118 /* AUDCx */
119 #define NOTPOLY5 0x80 /* selects POLY5 or direct CLOCK */
120 #define POLY4 0x40 /* selects POLY4 or POLY17 */
121 #define PURE 0x20 /* selects POLY4/17 or PURE tone */
122 #define VOLUME_ONLY 0x10 /* selects VOLUME OUTPUT ONLY */
123 #define VOLUME_MASK 0x0f /* volume mask */
124
125 /* AUDCTL */
126 #define POLY9 0x80 /* selects POLY9 or POLY17 */
127 #define CH1_HICLK 0x40 /* selects 1.78979 MHz for Ch 1 */
128 #define CH3_HICLK 0x20 /* selects 1.78979 MHz for Ch 3 */
129 #define CH12_JOINED 0x10 /* clocks channel 1 w/channel 2 */
130 #define CH34_JOINED 0x08 /* clocks channel 3 w/channel 4 */
131 #define CH1_FILTER 0x04 /* selects channel 1 high pass filter */
132 #define CH2_FILTER 0x02 /* selects channel 2 high pass filter */
133 #define CLK_15KHZ 0x01 /* selects 15.6999 kHz or 63.9211 kHz */
134
135 /* IRQEN (D20E) */
136 #define IRQ_BREAK 0x80 /* BREAK key pressed interrupt */
137 #define IRQ_KEYBD 0x40 /* keyboard data ready interrupt */
138 #define IRQ_SERIN 0x20 /* serial input data ready interrupt */
139 #define IRQ_SEROR 0x10 /* serial output register ready interrupt */
140 #define IRQ_SEROC 0x08 /* serial output complete interrupt */
141 #define IRQ_TIMR4 0x04 /* timer channel #4 interrupt */
142 #define IRQ_TIMR2 0x02 /* timer channel #2 interrupt */
143 #define IRQ_TIMR1 0x01 /* timer channel #1 interrupt */
144
145 /* SKSTAT (R/D20F) */
146 #define SK_FRAME 0x80 /* serial framing error */
147 #define SK_OVERRUN 0x40 /* serial overrun error */
148 #define SK_KBERR 0x20 /* keyboard overrun error */
149 #define SK_SERIN 0x10 /* serial input high */
150 #define SK_SHIFT 0x08 /* shift key pressed */
151 #define SK_KEYBD 0x04 /* keyboard key pressed */
152 #define SK_SEROUT 0x02 /* serial output active */
153
154 /* SKCTL (W/D20F) */
155 #define SK_BREAK 0x80 /* serial out break signal */
156 #define SK_BPS 0x70 /* bits per second */
157 #define SK_FM 0x08 /* FM mode */
158 #define SK_PADDLE 0x04 /* fast paddle a/d conversion */
159 #define SK_RESET 0x03 /* reset serial/keyboard interface */
160
161 #define DIV_64 28 /* divisor for 1.78979 MHz clock to 63.9211 kHz */
162 #define DIV_15 114 /* divisor for 1.78979 MHz clock to 15.6999 kHz */
163
164 struct POKEYregisters {
165 INT32 counter[4]; /* channel counter */
166 INT32 divisor[4]; /* channel divisor (modulo value) */
167 UINT32 volume[4]; /* channel volume - derived */
168 UINT8 output[4]; /* channel output signal (1 active, 0 inactive) */
169 UINT8 audible[4]; /* channel plays an audible tone/effect */
170 UINT32 samplerate_24_8; /* sample rate in 24.8 format */
171 UINT32 samplepos_fract; /* sample position fractional part */
172 UINT32 samplepos_whole; /* sample position whole part */
173 UINT32 polyadjust; /* polynome adjustment */
174 UINT32 p4; /* poly4 index */
175 UINT32 p5; /* poly5 index */
176 UINT32 p9; /* poly9 index */
177 UINT32 p17; /* poly17 index */
178 UINT32 r9; /* rand9 index */
179 UINT32 r17; /* rand17 index */
180 UINT32 clockmult; /* clock multiplier */
181 int channel; /* streams channel */
182 void *timer[3]; /* timers for channel 1,2 and 4 events */
183 void *rtimer; /* timer for calculating the random offset */
184 void *ptimer[8]; /* pot timers */
185 mem_read_handler pot_r[8];
186 mem_read_handler allpot_r;
187 mem_read_handler serin_r;
188 mem_write_handler serout_w;
189 void (*interrupt_cb)(int mask);
190 UINT8 AUDF[4]; /* AUDFx (D200, D202, D204, D206) */
191 UINT8 AUDC[4]; /* AUDCx (D201, D203, D205, D207) */
192 UINT8 POTx[8]; /* POTx (R/D200-D207) */
193 UINT8 AUDCTL; /* AUDCTL (W/D208) */
194 UINT8 ALLPOT; /* ALLPOT (R/D208) */
195 UINT8 KBCODE; /* KBCODE (R/D209) */
196 UINT8 RANDOM; /* RANDOM (R/D20A) */
197 UINT8 SERIN; /* SERIN (R/D20D) */
198 UINT8 SEROUT; /* SEROUT (W/D20D) */
199 UINT8 IRQST; /* IRQST (R/D20E) */
200 UINT8 IRQEN; /* IRQEN (W/D20E) */
201 UINT8 SKSTAT; /* SKSTAT (R/D20F) */
202 UINT8 SKCTL; /* SKCTL (W/D20F) */
203 };
204
205 static struct POKEYinterface intf;
206 static struct POKEYregisters pokey[MAXPOKEYS];
207
208 static UINT8 poly4[0x0f];
209 static UINT8 poly5[0x1f];
210 static UINT8 *poly9;
211 static UINT8 *poly17;
212
213 #define P4(chip) poly4[pokey[chip].p4]
214 #define P5(chip) poly5[pokey[chip].p5]
215 #define P9(chip) poly9[pokey[chip].p9]
216 #define P17(chip) poly17[pokey[chip].p17]
217
218 /* 128K random values derived from the 17bit polynome */
219 static UINT8 *rand9;
220 static UINT8 *rand17;
221
222 #define SAMPLE -1
223
224 #define ADJUST_EVENT(chip) \
225 pokey[chip].counter[CHAN1] -= event; \
226 pokey[chip].counter[CHAN2] -= event; \
227 pokey[chip].counter[CHAN3] -= event; \
228 pokey[chip].counter[CHAN4] -= event; \
229 pokey[chip].samplepos_whole -= event; \
230 pokey[chip].polyadjust += event
231
232 #if SUPPRESS_INAUDIBLE
233
234 #define PROCESS_CHANNEL(chip,ch) \
235 int toggle = 0; \
236 ADJUST_EVENT(chip); \
237 /* reset the channel counter */ \
238 if( pokey[chip].audible[ch] ) \
239 pokey[chip].counter[ch] = pokey[chip].divisor[ch]; \
240 else \
241 pokey[chip].counter[ch] = 0x7fffffff; \
242 pokey[chip].p4 = (pokey[chip].p4+pokey[chip].polyadjust)%0x0000f; \
243 pokey[chip].p5 = (pokey[chip].p5+pokey[chip].polyadjust)%0x0001f; \
244 pokey[chip].p9 = (pokey[chip].p9+pokey[chip].polyadjust)%0x001ff; \
245 pokey[chip].p17 = (pokey[chip].p17+pokey[chip].polyadjust)%0x1ffff; \
246 pokey[chip].polyadjust = 0; \
247 if( (pokey[chip].AUDC[ch] & NOTPOLY5) || P5(chip) ) \
248 { \
249 if( pokey[chip].AUDC[ch] & PURE ) \
250 toggle = 1; \
251 else \
252 if( pokey[chip].AUDC[ch] & POLY4 ) \
253 toggle = pokey[chip].output[ch] == !P4(chip); \
254 else \
255 if( pokey[chip].AUDCTL & POLY9 ) \
256 toggle = pokey[chip].output[ch] == !P9(chip); \
257 else \
258 toggle = pokey[chip].output[ch] == !P17(chip); \
259 } \
260 if( toggle ) \
261 { \
262 if( pokey[chip].audible[ch] ) \
263 { \
264 if( pokey[chip].output[ch] ) \
265 sum -= pokey[chip].volume[ch]; \
266 else \
267 sum += pokey[chip].volume[ch]; \
268 } \
269 pokey[chip].output[ch] ^= 1; \
270 } \
271 /* is this a filtering channel (3/4) and is the filter active? */ \
272 if( pokey[chip].AUDCTL & ((CH1_FILTER|CH2_FILTER) & (0x10 >> ch)) ) \
273 { \
274 if( pokey[chip].output[ch-2] ) \
275 { \
276 pokey[chip].output[ch-2] = 0; \
277 if( pokey[chip].audible[ch] ) \
278 sum -= pokey[chip].volume[ch-2]; \
279 } \
280 } \
281
282 #else
283
284 #define PROCESS_CHANNEL(chip,ch) \
285 int toggle = 0; \
286 ADJUST_EVENT(chip); \
287 /* reset the channel counter */ \
288 pokey[chip].counter[ch] = p[chip].divisor[ch]; \
289 pokey[chip].p4 = (pokey[chip].p4+pokey[chip].polyadjust)%0x0000f; \
290 pokey[chip].p5 = (pokey[chip].p5+pokey[chip].polyadjust)%0x0001f; \
291 pokey[chip].p9 = (pokey[chip].p9+pokey[chip].polyadjust)%0x001ff; \
292 pokey[chip].p17 = (pokey[chip].p17+pokey[chip].polyadjust)%0x1ffff; \
293 pokey[chip].polyadjust = 0; \
294 if( (pokey[chip].AUDC[ch] & NOTPOLY5) || P5(chip) ) \
295 { \
296 if( pokey[chip].AUDC[ch] & PURE ) \
297 toggle = 1; \
298 else \
299 if( pokey[chip].AUDC[ch] & POLY4 ) \
300 toggle = pokey[chip].output[ch] == !P4(chip); \
301 else \
302 if( pokey[chip].AUDCTL & POLY9 ) \
303 toggle = pokey[chip].output[ch] == !P9(chip); \
304 else \
305 toggle = pokey[chip].output[ch] == !P17(chip); \
306 } \
307 if( toggle ) \
308 { \
309 if( pokey[chip].output[ch] ) \
310 sum -= pokey[chip].volume[ch]; \
311 else \
312 sum += pokey[chip].volume[ch]; \
313 pokey[chip].output[ch] ^= 1; \
314 } \
315 /* is this a filtering channel (3/4) and is the filter active? */ \
316 if( pokey[chip].AUDCTL & ((CH1_FILTER|CH2_FILTER) & (0x10 >> ch)) ) \
317 { \
318 if( pokey[chip].output[ch-2] ) \
319 { \
320 pokey[chip].output[ch-2] = 0; \
321 sum -= pokey[chip].volume[ch-2]; \
322 } \
323 } \
324
325 #endif
326
327 #define PROCESS_SAMPLE(chip) \
328 ADJUST_EVENT(chip); \
329 /* adjust the sample position */ \
330 pokey[chip].samplepos_fract += pokey[chip].samplerate_24_8; \
331 if( pokey[chip].samplepos_fract & 0xffffff00 ) \
332 { \
333 pokey[chip].samplepos_whole += pokey[chip].samplepos_fract>>8; \
334 pokey[chip].samplepos_fract &= 0x000000ff; \
335 } \
336 /* store sum of output signals into the buffer */ \
337 *buffer++ = (sum > 0x7fff) ? 0x7fff : sum; \
338 length--
339
340 #if HEAVY_MACRO_USAGE
341
342 /*
343 * This version of PROCESS_POKEY repeats the search for the minimum
344 * event value without using an index to the channel. That way the
345 * PROCESS_CHANNEL macros can be called with fixed values and expand
346 * to much more efficient code
347 */
348
349 #define PROCESS_POKEY(chip) \
350 UINT32 sum = 0; \
351 if( pokey[chip].output[CHAN1] ) \
352 sum += pokey[chip].volume[CHAN1]; \
353 if( pokey[chip].output[CHAN2] ) \
354 sum += pokey[chip].volume[CHAN2]; \
355 if( pokey[chip].output[CHAN3] ) \
356 sum += pokey[chip].volume[CHAN3]; \
357 if( pokey[chip].output[CHAN4] ) \
358 sum += pokey[chip].volume[CHAN4]; \
359 while( length > 0 ) \
360 { \
361 if( pokey[chip].counter[CHAN1] < pokey[chip].samplepos_whole ) \
362 { \
363 if( pokey[chip].counter[CHAN2] < pokey[chip].counter[CHAN1] ) \
364 { \
365 if( pokey[chip].counter[CHAN3] < pokey[chip].counter[CHAN2] ) \
366 { \
367 if( pokey[chip].counter[CHAN4] < pokey[chip].counter[CHAN3] ) \
368 { \
369 UINT32 event = pokey[chip].counter[CHAN4]; \
370 PROCESS_CHANNEL(chip,CHAN4); \
371 } \
372 else \
373 { \
374 UINT32 event = pokey[chip].counter[CHAN3]; \
375 PROCESS_CHANNEL(chip,CHAN3); \
376 } \
377 } \
378 else \
379 if( pokey[chip].counter[CHAN4] < pokey[chip].counter[CHAN2] ) \
380 { \
381 UINT32 event = pokey[chip].counter[CHAN4]; \
382 PROCESS_CHANNEL(chip,CHAN4); \
383 } \
384 else \
385 { \
386 UINT32 event = pokey[chip].counter[CHAN2]; \
387 PROCESS_CHANNEL(chip,CHAN2); \
388 } \
389 } \
390 else \
391 if( pokey[chip].counter[CHAN3] < pokey[chip].counter[CHAN1] ) \
392 { \
393 if( pokey[chip].counter[CHAN4] < pokey[chip].counter[CHAN3] ) \
394 { \
395 UINT32 event = pokey[chip].counter[CHAN4]; \
396 PROCESS_CHANNEL(chip,CHAN4); \
397 } \
398 else \
399 { \
400 UINT32 event = pokey[chip].counter[CHAN3]; \
401 PROCESS_CHANNEL(chip,CHAN3); \
402 } \
403 } \
404 else \
405 if( pokey[chip].counter[CHAN4] < pokey[chip].counter[CHAN1] ) \
406 { \
407 UINT32 event = pokey[chip].counter[CHAN4]; \
408 PROCESS_CHANNEL(chip,CHAN4); \
409 } \
410 else \
411 { \
412 UINT32 event = pokey[chip].counter[CHAN1]; \
413 PROCESS_CHANNEL(chip,CHAN1); \
414 } \
415 } \
416 else \
417 if( pokey[chip].counter[CHAN2] < pokey[chip].samplepos_whole ) \
418 { \
419 if( pokey[chip].counter[CHAN3] < pokey[chip].counter[CHAN2] ) \
420 { \
421 if( pokey[chip].counter[CHAN4] < pokey[chip].counter[CHAN3] ) \
422 { \
423 UINT32 event = pokey[chip].counter[CHAN4]; \
424 PROCESS_CHANNEL(chip,CHAN4); \
425 } \
426 else \
427 { \
428 UINT32 event = pokey[chip].counter[CHAN3]; \
429 PROCESS_CHANNEL(chip,CHAN3); \
430 } \
431 } \
432 else \
433 if( pokey[chip].counter[CHAN4] < pokey[chip].counter[CHAN2] ) \
434 { \
435 UINT32 event = pokey[chip].counter[CHAN4]; \
436 PROCESS_CHANNEL(chip,CHAN4); \
437 } \
438 else \
439 { \
440 UINT32 event = pokey[chip].counter[CHAN2]; \
441 PROCESS_CHANNEL(chip,CHAN2); \
442 } \
443 } \
444 else \
445 if( pokey[chip].counter[CHAN3] < pokey[chip].samplepos_whole ) \
446 { \
447 if( pokey[chip].counter[CHAN4] < pokey[chip].counter[CHAN3] ) \
448 { \
449 UINT32 event = pokey[chip].counter[CHAN4]; \
450 PROCESS_CHANNEL(chip,CHAN4); \
451 } \
452 else \
453 { \
454 UINT32 event = pokey[chip].counter[CHAN3]; \
455 PROCESS_CHANNEL(chip,CHAN3); \
456 } \
457 } \
458 else \
459 if( pokey[chip].counter[CHAN4] < pokey[chip].samplepos_whole ) \
460 { \
461 UINT32 event = pokey[chip].counter[CHAN4]; \
462 PROCESS_CHANNEL(chip,CHAN4); \
463 } \
464 else \
465 { \
466 UINT32 event = pokey[chip].samplepos_whole; \
467 PROCESS_SAMPLE(chip); \
468 } \
469 } \
470 timer_reset(pokey[chip].rtimer, TIME_NEVER)
471
pokey0_update(int param,INT16 * buffer,int length)472 void pokey0_update(int param, INT16 *buffer, int length) { PROCESS_POKEY(0); }
pokey1_update(int param,INT16 * buffer,int length)473 void pokey1_update(int param, INT16 *buffer, int length) { PROCESS_POKEY(1); }
pokey2_update(int param,INT16 * buffer,int length)474 void pokey2_update(int param, INT16 *buffer, int length) { PROCESS_POKEY(2); }
pokey3_update(int param,INT16 * buffer,int length)475 void pokey3_update(int param, INT16 *buffer, int length) { PROCESS_POKEY(3); }
476 void (*update[MAXPOKEYS])(int,INT16*,int) =
477 { pokey0_update,pokey1_update,pokey2_update,pokey3_update };
478
479 #else /* no HEAVY_MACRO_USAGE */
480 /*
481 * And this version of PROCESS_POKEY uses event and channel variables
482 * so that the PROCESS_CHANNEL macro needs to index memory at runtime.
483 */
484
485 #define PROCESS_POKEY(chip) \
486 UINT32 sum = 0; \
487 if( pokey[chip].output[CHAN1] ) \
488 sum += pokey[chip].volume[CHAN1]; \
489 if( pokey[chip].output[CHAN2] ) \
490 sum += pokey[chip].volume[CHAN2]; \
491 if( pokey[chip].output[CHAN3] ) \
492 sum += pokey[chip].volume[CHAN3]; \
493 if( pokey[chip].output[CHAN4] ) \
494 sum += pokey[chip].volume[CHAN4]; \
495 while( length > 0 ) \
496 { \
497 UINT32 event = pokey[chip].samplepos_whole; \
498 UINT32 channel = SAMPLE; \
499 if( pokey[chip].counter[CHAN1] < event ) \
500 { \
501 event = pokey[chip].counter[CHAN1]; \
502 channel = CHAN1; \
503 } \
504 if( pokey[chip].counter[CHAN2] < event ) \
505 { \
506 event = pokey[chip].counter[CHAN2]; \
507 channel = CHAN2; \
508 } \
509 if( pokey[chip].counter[CHAN3] < event ) \
510 { \
511 event = pokey[chip].counter[CHAN3]; \
512 channel = CHAN3; \
513 } \
514 if( pokey[chip].counter[CHAN4] < event ) \
515 { \
516 event = pokey[chip].counter[CHAN4]; \
517 channel = CHAN4; \
518 } \
519 if( channel == SAMPLE ) \
520 { \
521 PROCESS_SAMPLE(chip); \
522 } \
523 else \
524 { \
525 PROCESS_CHANNEL(chip,channel); \
526 } \
527 } \
528 timer_reset(pokey[chip].rtimer, TIME_NEVER)
529
pokey_update(int param,INT16 * buffer,int length)530 void pokey_update(int param, INT16 *buffer, int length) { PROCESS_POKEY(param); }
531 void (*update[MAXPOKEYS])(int,INT16*,int) =
532 { pokey_update,pokey_update,pokey_update,pokey_update };
533
534 #endif
535
pokey_sh_update(void)536 void pokey_sh_update(void)
537 {
538 int chip;
539
540 for( chip = 0; chip < intf.num; chip++ )
541 stream_update(pokey[chip].channel, 0);
542 }
543
poly_init(UINT8 * poly,int size,int left,int right,int add)544 static void poly_init(UINT8 *poly, int size, int left, int right, int add)
545 {
546 int mask = (1 << size) - 1;
547 int i, x = 0;
548
549 LOG_POLY(("poly %d\n", size));
550 for( i = 0; i < mask; i++ )
551 {
552 *poly++ = x & 1;
553 LOG_POLY(("%05x: %d\n", x, x&1));
554 /* calculate next bit */
555 x = ((x << left) + (x >> right) + add) & mask;
556 }
557 }
558
rand_init(UINT8 * rng,int size,int left,int right,int add)559 static void rand_init(UINT8 *rng, int size, int left, int right, int add)
560 {
561 int mask = (1 << size) - 1;
562 int i, x = 0;
563
564 LOG_RAND(("rand %d\n", size));
565 for( i = 0; i < mask; i++ )
566 {
567 *rng = x >> (size - 8); /* use the upper 8 bits */
568 LOG_RAND(("%05x: %02x\n", x, *rng));
569 rng++;
570 /* calculate next bit */
571 x = ((x << left) + (x >> right) + add) & mask;
572 }
573 }
574
pokey_sh_start(const struct MachineSound * msound)575 int pokey_sh_start(const struct MachineSound *msound)
576 {
577 int chip;
578
579 memcpy(&intf, msound->sound_interface, sizeof(struct POKEYinterface));
580
581 poly9 = (UINT8*)malloc(0x1ff+1);
582 rand9 = (UINT8*)malloc(0x1ff+1);
583 poly17 = (UINT8*)malloc(0x1ffff+1);
584 rand17 = (UINT8*)malloc(0x1ffff+1);
585 if( !poly9 || !rand9 || !poly17 || !rand17 )
586 {
587 pokey_sh_stop(); /* free any allocated memory again */
588 return 1;
589 }
590
591 /* initialize the poly counters */
592 poly_init(poly4, 4, 3, 1, 0x00004);
593 poly_init(poly5, 5, 3, 2, 0x00008);
594 poly_init(poly9, 9, 2, 7, 0x00080);
595 poly_init(poly17, 17, 7,10, 0x18000);
596
597 /* initialize the random arrays */
598 rand_init(rand9, 9, 2, 7, 0x00080);
599 rand_init(rand17, 17, 7,10, 0x18000);
600
601 for( chip = 0; chip < intf.num; chip++ )
602 {
603 struct POKEYregisters *p = &pokey[chip];
604 char name[40];
605
606 memset(p, 0, sizeof(struct POKEYregisters));
607
608 p->samplerate_24_8 = (Machine->sample_rate) ? (intf.baseclock << 8) / Machine->sample_rate : 1;
609 p->divisor[CHAN1] = 4;
610 p->divisor[CHAN2] = 4;
611 p->divisor[CHAN3] = 4;
612 p->divisor[CHAN4] = 4;
613 p->clockmult = DIV_64;
614 p->KBCODE = 0x09; /* Atari 800 'no key' */
615 p->SKCTL = SK_RESET; /* let the RNG run after reset */
616 p->rtimer = timer_set(TIME_NEVER, chip, NULL);
617
618 p->pot_r[0] = intf.pot0_r[chip];
619 p->pot_r[1] = intf.pot1_r[chip];
620 p->pot_r[2] = intf.pot2_r[chip];
621 p->pot_r[3] = intf.pot3_r[chip];
622 p->pot_r[4] = intf.pot4_r[chip];
623 p->pot_r[5] = intf.pot5_r[chip];
624 p->pot_r[6] = intf.pot6_r[chip];
625 p->pot_r[7] = intf.pot7_r[chip];
626 p->allpot_r = intf.allpot_r[chip];
627 p->serin_r = intf.serin_r[chip];
628 p->serout_w = intf.serout_w[chip];
629 p->interrupt_cb = intf.interrupt_cb[chip];
630
631 sprintf(name, "Pokey #%d", chip);
632 p->channel = stream_init(name, intf.mixing_level[chip], Machine->sample_rate, chip, update[chip]);
633
634 if( p->channel == -1 )
635 {
636 //logerror("failed to initialize sound channel\n");
637 return 1;
638 }
639 }
640
641 return 0;
642 }
643
pokey_sh_stop(void)644 void pokey_sh_stop (void)
645 {
646 if( rand17 ) free(rand17);
647 rand17 = NULL;
648 if( poly17 ) free(poly17);
649 poly17 = NULL;
650 if( rand9 ) free(rand9);
651 rand9 = NULL;
652 if( poly9 ) free(poly9);
653 poly9 = NULL;
654 }
655
pokey_timer_expire(int param)656 static void pokey_timer_expire(int param)
657 {
658 int chip = param >> 3;
659 int timers = param & 7;
660 struct POKEYregisters *p = &pokey[chip];
661
662 LOG_TIMER(("POKEY #%d timer %d with IRQEN $%02x\n", chip, param, p->IRQEN));
663
664 /* check if some of the requested timer interrupts are enabled */
665 timers &= p->IRQEN;
666
667 if( timers )
668 {
669 /* set the enabled timer irq status bits */
670 p->IRQST |= timers;
671 /* call back an application supplied function to handle the interrupt */
672 if( p->interrupt_cb )
673 (*p->interrupt_cb)(timers);
674 }
675 }
676
677 #if VERBOSE_SOUND
audc2str(int val)678 static char *audc2str(int val)
679 {
680 static char buff[80];
681 if( val & NOTPOLY5 )
682 {
683 if( val & PURE )
684 strcpy(buff,"pure");
685 else
686 if( val & POLY4 )
687 strcpy(buff,"poly4");
688 else
689 strcpy(buff,"poly9/17");
690 }
691 else
692 {
693 if( val & PURE )
694 strcpy(buff,"poly5");
695 else
696 if( val & POLY4 )
697 strcpy(buff,"poly4+poly5");
698 else
699 strcpy(buff,"poly9/17+poly5");
700 }
701 return buff;
702 }
703
audctl2str(int val)704 static char *audctl2str(int val)
705 {
706 static char buff[80];
707 if( val & POLY9 )
708 strcpy(buff,"poly9");
709 else
710 strcpy(buff,"poly17");
711 if( val & CH1_HICLK )
712 strcat(buff,"+ch1hi");
713 if( val & CH3_HICLK )
714 strcat(buff,"+ch3hi");
715 if( val & CH12_JOINED )
716 strcat(buff,"+ch1/2");
717 if( val & CH34_JOINED )
718 strcat(buff,"+ch3/4");
719 if( val & CH1_FILTER )
720 strcat(buff,"+ch1filter");
721 if( val & CH2_FILTER )
722 strcat(buff,"+ch2filter");
723 if( val & CLK_15KHZ )
724 strcat(buff,"+clk15");
725 return buff;
726 }
727 #endif
728
pokey_serin_ready(int chip)729 static void pokey_serin_ready(int chip)
730 {
731 struct POKEYregisters *p = &pokey[chip];
732 if( p->IRQEN & IRQ_SERIN )
733 {
734 /* set the enabled timer irq status bits */
735 p->IRQST |= IRQ_SERIN;
736 /* call back an application supplied function to handle the interrupt */
737 if( p->interrupt_cb )
738 (*p->interrupt_cb)(IRQ_SERIN);
739 }
740 }
741
pokey_serout_ready(int chip)742 static void pokey_serout_ready(int chip)
743 {
744 struct POKEYregisters *p = &pokey[chip];
745 if( p->IRQEN & IRQ_SEROR )
746 {
747 p->IRQST |= IRQ_SEROR;
748 if( p->interrupt_cb )
749 (*p->interrupt_cb)(IRQ_SEROR);
750 }
751 }
752
pokey_serout_complete(int chip)753 static void pokey_serout_complete(int chip)
754 {
755 struct POKEYregisters *p = &pokey[chip];
756 if( p->IRQEN & IRQ_SEROC )
757 {
758 p->IRQST |= IRQ_SEROC;
759 if( p->interrupt_cb )
760 (*p->interrupt_cb)(IRQ_SEROC);
761 }
762 }
763
pokey_pot_trigger(int param)764 static void pokey_pot_trigger(int param)
765 {
766 int chip = param >> 3;
767 int pot = param & 7;
768 struct POKEYregisters *p = &pokey[chip];
769
770 LOG(("POKEY #%d POT%d triggers after %dus\n", chip, pot, (int)(1000000ul*timer_timeelapsed(p->ptimer[pot]))));
771 p->ptimer[pot] = NULL;
772 p->ALLPOT &= ~(1 << pot); /* set the enabled timer irq status bits */
773 }
774
775 /* A/D conversion time:
776 * In normal, slow mode (SKCTL bit SK_PADDLE is clear) the conversion
777 * takes N scanlines, where N is the paddle value. A single scanline
778 * takes approximately 64us to finish (1.78979MHz clock).
779 * In quick mode (SK_PADDLE set) the conversion is done very fast
780 * (takes two scalines) but the result is not as accurate.
781 */
782 #define AD_TIME (float)(((p->SKCTL & SK_PADDLE) ? 64.0*2/228 : 64.0) * FREQ_17_EXACT / intf.baseclock)
783
pokey_potgo(int chip)784 static void pokey_potgo(int chip)
785 {
786 struct POKEYregisters *p = &pokey[chip];
787 int pot;
788
789 LOG(("POKEY #%d pokey_potgo\n", chip));
790
791 p->ALLPOT = 0xff;
792
793 for( pot = 0; pot < 8; pot++ )
794 {
795 if( p->ptimer[pot] )
796 {
797 timer_remove(p->ptimer[pot]);
798 p->ptimer[pot] = NULL;
799 p->POTx[pot] = 0xff;
800 }
801 if( p->pot_r[pot] )
802 {
803 int r = (*p->pot_r[pot])(pot);
804 LOG(("POKEY #%d pot_r(%d) returned $%02x\n", chip, pot, r));
805 if( r != -1 )
806 {
807 if (r > 228)
808 r = 228;
809 /* final value */
810 p->POTx[pot] = r;
811 p->ptimer[pot] = timer_set(TIME_IN_USEC(r * AD_TIME), (chip<<3)|pot, pokey_pot_trigger);
812 }
813 }
814 }
815 }
816
pokey_register_r(int chip,int offs)817 int pokey_register_r(int chip, int offs)
818 {
819 struct POKEYregisters *p = &pokey[chip];
820 int data = 0, pot;
821
822 switch (offs & 15)
823 {
824 case POT0_C: case POT1_C: case POT2_C: case POT3_C:
825 case POT4_C: case POT5_C: case POT6_C: case POT7_C:
826 pot = offs & 7;
827 if( p->pot_r[pot] )
828 {
829 /*
830 * If the conversion is not yet finished (ptimer running),
831 * get the current value by the linear interpolation of
832 * the final value using the elapsed time.
833 */
834 if( p->ALLPOT & (1 << pot) )
835 {
836 data = (UINT8)(timer_timeelapsed(p->ptimer[pot]) / (AD_TIME*TIME_ONE_SEC));
837 LOG(("POKEY #%d read POT%d (interpolated) $%02x\n", chip, pot, data));
838 }
839 else
840 {
841 data = p->POTx[pot];
842 LOG(("POKEY #%d read POT%d (final value) $%02x\n", chip, pot, data));
843 }
844 }
845 //else
846 //logerror("PC %04x: warning - read p[chip] #%d POT%d\n", cpu_get_pc(), chip, pot);
847 break;
848
849 case ALLPOT_C:
850 if( p->allpot_r )
851 {
852 data = (*p->allpot_r)(offs);
853 LOG(("POKEY #%d ALLPOT callback $%02x\n", chip, data));
854 }
855 else
856 {
857 data = p->ALLPOT;
858 LOG(("POKEY #%d ALLPOT internal $%02x\n", chip, data));
859 }
860 break;
861
862 case KBCODE_C:
863 data = p->KBCODE;
864 break;
865
866 case RANDOM_C:
867 /****************************************************************
868 * If the 2 least significant bits of SKCTL are 0, the random
869 * number generator is disabled (SKRESET). Thanks to Eric Smith
870 * for pointing out this critical bit of info! If the random
871 * number generator is enabled, get a new random number. Take
872 * the time gone since the last read into account and read the
873 * new value from an appropriate offset in the rand17 table.
874 ****************************************************************/
875 if( p->SKCTL & SK_RESET )
876 {
877 UINT32 adjust = (UINT32)( (((float)timer_timeelapsed(p->rtimer))/(float)TIME_ONE_SEC) * intf.baseclock);
878 p->r9 = (p->r9 + adjust) % 0x001ff;
879 p->r17 = (p->r17 + adjust) % 0x1ffff;
880 if( p->AUDCTL & POLY9 )
881 {
882 p->RANDOM = rand9[p->r9];
883 LOG_RAND(("POKEY #%d adjust %u rand9[$%05x]: $%02x\n", chip, adjust, p->r9, p->RANDOM));
884 }
885 else
886 {
887 p->RANDOM = rand17[p->r17];
888 LOG_RAND(("POKEY #%d adjust %u rand17[$%05x]: $%02x\n", chip, adjust, p->r17, p->RANDOM));
889 }
890 }
891 else
892 {
893 LOG_RAND(("POKEY #%d rand17 freezed (SKCTL): $%02x\n", chip, p->RANDOM));
894 }
895 timer_reset(p->rtimer, TIME_NEVER);
896 data = p->RANDOM;
897 break;
898
899 case SERIN_C:
900 if( p->serin_r )
901 p->SERIN = (*p->serin_r)(offs);
902 data = p->SERIN;
903 LOG(("POKEY #%d SERIN $%02x\n", chip, data));
904 break;
905
906 case IRQST_C:
907 /* IRQST is an active low input port; we keep it active high */
908 /* internally to ease the (un-)masking of bits */
909 data = p->IRQST ^ 0xff;
910 LOG(("POKEY #%d IRQST $%02x\n", chip, data));
911 break;
912
913 case SKSTAT_C:
914 /* SKSTAT is also an active low input port */
915 data = p->SKSTAT ^ 0xff;
916 LOG(("POKEY #%d SKSTAT $%02x\n", chip, data));
917 break;
918
919 default:
920 LOG(("POKEY #%d register $%02x\n", chip, offs));
921 break;
922 }
923 return data;
924 }
925
READ_HANDLER(pokey1_r)926 READ_HANDLER( pokey1_r )
927 {
928 return pokey_register_r(0, offset);
929 }
930
READ_HANDLER(pokey2_r)931 READ_HANDLER( pokey2_r )
932 {
933 return pokey_register_r(1, offset);
934 }
935
READ_HANDLER(pokey3_r)936 READ_HANDLER( pokey3_r )
937 {
938 return pokey_register_r(2, offset);
939 }
940
READ_HANDLER(pokey4_r)941 READ_HANDLER( pokey4_r )
942 {
943 return pokey_register_r(3, offset);
944 }
945
READ_HANDLER(quad_pokey_r)946 READ_HANDLER( quad_pokey_r )
947 {
948 int pokey_num = (offset >> 3) & ~0x04;
949 int control = (offset & 0x20) >> 2;
950 int pokey_reg = (offset % 8) | control;
951
952 return pokey_register_r(pokey_num, pokey_reg);
953 }
954
955
pokey_register_w(int chip,int offs,int data)956 void pokey_register_w(int chip, int offs, int data)
957 {
958 struct POKEYregisters *p = &pokey[chip];
959 int ch_mask = 0, new_val;
960
961 #ifndef MAME_FASTSOUND
962 stream_update(p->channel, 0);
963 #else
964 {
965 extern int fast_sound;
966 if (!fast_sound) stream_update(p->channel, 0);
967 }
968 #endif
969 /* determine which address was changed */
970 switch (offs & 15)
971 {
972 case AUDF1_C:
973 if( data == p->AUDF[CHAN1] )
974 return;
975 LOG_SOUND(("POKEY #%d AUDF1 $%02x\n", chip, data));
976 p->AUDF[CHAN1] = data;
977 ch_mask = 1 << CHAN1;
978 if( p->AUDCTL & CH12_JOINED ) /* if ch 1&2 tied together */
979 ch_mask |= 1 << CHAN2; /* then also change on ch2 */
980 break;
981
982 case AUDC1_C:
983 if( data == p->AUDC[CHAN1] )
984 return;
985 LOG_SOUND(("POKEY #%d AUDC1 $%02x (%s)\n", chip, data, audc2str(data)));
986 p->AUDC[CHAN1] = data;
987 ch_mask = 1 << CHAN1;
988 break;
989
990 case AUDF2_C:
991 if( data == p->AUDF[CHAN2] )
992 return;
993 LOG_SOUND(("POKEY #%d AUDF2 $%02x\n", chip, data));
994 p->AUDF[CHAN2] = data;
995 ch_mask = 1 << CHAN2;
996 break;
997
998 case AUDC2_C:
999 if( data == p->AUDC[CHAN2] )
1000 return;
1001 LOG_SOUND(("POKEY #%d AUDC2 $%02x (%s)\n", chip, data, audc2str(data)));
1002 p->AUDC[CHAN2] = data;
1003 ch_mask = 1 << CHAN2;
1004 break;
1005
1006 case AUDF3_C:
1007 if( data == p->AUDF[CHAN3] )
1008 return;
1009 LOG_SOUND(("POKEY #%d AUDF3 $%02x\n", chip, data));
1010 p->AUDF[CHAN3] = data;
1011 ch_mask = 1 << CHAN3;
1012
1013 if( p->AUDCTL & CH34_JOINED ) /* if ch 3&4 tied together */
1014 ch_mask |= 1 << CHAN4; /* then also change on ch4 */
1015 break;
1016
1017 case AUDC3_C:
1018 if( data == p->AUDC[CHAN3] )
1019 return;
1020 LOG_SOUND(("POKEY #%d AUDC3 $%02x (%s)\n", chip, data, audc2str(data)));
1021 p->AUDC[CHAN3] = data;
1022 ch_mask = 1 << CHAN3;
1023 break;
1024
1025 case AUDF4_C:
1026 if( data == p->AUDF[CHAN4] )
1027 return;
1028 LOG_SOUND(("POKEY #%d AUDF4 $%02x\n", chip, data));
1029 p->AUDF[CHAN4] = data;
1030 ch_mask = 1 << CHAN4;
1031 break;
1032
1033 case AUDC4_C:
1034 if( data == p->AUDC[CHAN4] )
1035 return;
1036 LOG_SOUND(("POKEY #%d AUDC4 $%02x (%s)\n", chip, data, audc2str(data)));
1037 p->AUDC[CHAN4] = data;
1038 ch_mask = 1 << CHAN4;
1039 break;
1040
1041 case AUDCTL_C:
1042 if( data == p->AUDCTL )
1043 return;
1044 LOG_SOUND(("POKEY #%d AUDCTL $%02x (%s)\n", chip, data, audctl2str(data)));
1045 p->AUDCTL = data;
1046 ch_mask = 15; /* all channels */
1047 /* determine the base multiplier for the 'div by n' calculations */
1048 p->clockmult = (p->AUDCTL & CLK_15KHZ) ? DIV_15 : DIV_64;
1049 break;
1050
1051 case STIMER_C:
1052 /* first remove any existing timers */
1053 LOG_TIMER(("POKEY #%d STIMER $%02x\n", chip, data));
1054 if( p->timer[TIMER1] )
1055 timer_remove(p->timer[TIMER1]);
1056 if( p->timer[TIMER2] )
1057 timer_remove(p->timer[TIMER2]);
1058 if( p->timer[TIMER4] )
1059 timer_remove(p->timer[TIMER4]);
1060 p->timer[TIMER1] = NULL;
1061 p->timer[TIMER2] = NULL;
1062 p->timer[TIMER4] = NULL;
1063
1064 /* reset all counters to zero (side effect) */
1065 p->polyadjust = 0;
1066 p->counter[CHAN1] = 0;
1067 p->counter[CHAN2] = 0;
1068 p->counter[CHAN3] = 0;
1069 p->counter[CHAN4] = 0;
1070
1071 /* joined chan#1 and chan#2 ? */
1072 if( p->AUDCTL & CH12_JOINED )
1073 {
1074 if( p->divisor[CHAN2] > 4 )
1075 {
1076 LOG_TIMER(("POKEY #%d timer1+2 after %d clocks\n", chip, p->divisor[CHAN2]));
1077 /* set timer #1 _and_ #2 event after timer_div clocks of joined CHAN1+CHAN2 */
1078 p->timer[TIMER2] =
1079 timer_pulse(TIME_IN_SEC(1.0 * p->divisor[CHAN2] / intf.baseclock),
1080 (chip<<3)|IRQ_TIMR2|IRQ_TIMR1, pokey_timer_expire);
1081 }
1082 }
1083 else
1084 {
1085 if( p->divisor[CHAN1] > 4 )
1086 {
1087 LOG_TIMER(("POKEY #%d timer1 after %d clocks\n", chip, p->divisor[CHAN1]));
1088 /* set timer #1 event after timer_div clocks of CHAN1 */
1089 p->timer[TIMER1] =
1090 timer_pulse(TIME_IN_SEC(1.0 * p->divisor[CHAN1] / intf.baseclock),
1091 (chip<<3)|IRQ_TIMR1, pokey_timer_expire);
1092 }
1093
1094 if( p->divisor[CHAN2] > 4 )
1095 {
1096 LOG_TIMER(("POKEY #%d timer2 after %d clocks\n", chip, p->divisor[CHAN2]));
1097 /* set timer #2 event after timer_div clocks of CHAN2 */
1098 p->timer[TIMER2] =
1099 timer_pulse(TIME_IN_SEC(1.0 * p->divisor[CHAN2] / intf.baseclock),
1100 (chip<<3)|IRQ_TIMR2, pokey_timer_expire);
1101 }
1102 }
1103
1104 /* Note: p[chip] does not have a timer #3 */
1105
1106 if( p->AUDCTL & CH34_JOINED )
1107 {
1108 /* not sure about this: if audc4 == 0000xxxx don't start timer 4 ? */
1109 if( p->AUDC[CHAN4] & 0xf0 )
1110 {
1111 if( p->divisor[CHAN4] > 4 )
1112 {
1113 LOG_TIMER(("POKEY #%d timer4 after %d clocks\n", chip, p->divisor[CHAN4]));
1114 /* set timer #4 event after timer_div clocks of CHAN4 */
1115 p->timer[TIMER4] =
1116 timer_pulse(TIME_IN_SEC(1.0 * p->divisor[CHAN4] / intf.baseclock),
1117 (chip<<3)|IRQ_TIMR4, pokey_timer_expire);
1118 }
1119 }
1120 }
1121 else
1122 {
1123 if( p->divisor[CHAN4] > 4 )
1124 {
1125 LOG_TIMER(("POKEY #%d timer4 after %d clocks\n", chip, p->divisor[CHAN4]));
1126 /* set timer #4 event after timer_div clocks of CHAN4 */
1127 p->timer[TIMER4] =
1128 timer_pulse(TIME_IN_SEC(1.0 * p->divisor[CHAN4] / intf.baseclock),
1129 (chip<<3)|IRQ_TIMR4, pokey_timer_expire);
1130 }
1131 }
1132 if( p->timer[TIMER1] )
1133 timer_enable(p->timer[TIMER1], p->IRQEN & IRQ_TIMR1);
1134 if( p->timer[TIMER2] )
1135 timer_enable(p->timer[TIMER2], p->IRQEN & IRQ_TIMR2);
1136 if( p->timer[TIMER4] )
1137 timer_enable(p->timer[TIMER4], p->IRQEN & IRQ_TIMR4);
1138 break;
1139
1140 case SKREST_C:
1141 /* reset SKSTAT */
1142 LOG(("POKEY #%d SKREST $%02x\n", chip, data));
1143 p->SKSTAT &= ~(SK_FRAME|SK_OVERRUN|SK_KBERR);
1144 break;
1145
1146 case POTGO_C:
1147 LOG(("POKEY #%d POTGO $%02x\n", chip, data));
1148 pokey_potgo(chip);
1149 break;
1150
1151 case SEROUT_C:
1152 LOG(("POKEY #%d SEROUT $%02x\n", chip, data));
1153 if (p->serout_w)
1154 (*p->serout_w)(offs, data);
1155 p->SKSTAT |= SK_SEROUT;
1156 /*
1157 * These are arbitrary values, tested with some custom boot
1158 * loaders from Ballblazer and Escape from Fractalus
1159 * The real times are unknown
1160 */
1161 timer_set(TIME_IN_USEC(200), chip, pokey_serout_ready);
1162 /* 10 bits (assumption 1 start, 8 data and 1 stop bit) take how long? */
1163 timer_set(TIME_IN_USEC(2000), chip, pokey_serout_complete);
1164 break;
1165
1166 case IRQEN_C:
1167 LOG(("POKEY #%d IRQEN $%02x\n", chip, data));
1168
1169 /* acknowledge one or more IRQST bits ? */
1170 if( p->IRQST & ~data )
1171 {
1172 /* reset IRQST bits that are masked now */
1173 p->IRQST &= data;
1174 }
1175 else
1176 {
1177 /* enable/disable timers now to avoid unneeded
1178 breaking of the CPU cores for masked timers */
1179 if( p->timer[TIMER1] && ((p->IRQEN^data) & IRQ_TIMR1) )
1180 timer_enable(p->timer[TIMER1], data & IRQ_TIMR1);
1181 if( p->timer[TIMER2] && ((p->IRQEN^data) & IRQ_TIMR2) )
1182 timer_enable(p->timer[TIMER2], data & IRQ_TIMR2);
1183 if( p->timer[TIMER4] && ((p->IRQEN^data) & IRQ_TIMR4) )
1184 timer_enable(p->timer[TIMER4], data & IRQ_TIMR4);
1185 }
1186 /* store irq enable */
1187 p->IRQEN = data;
1188 break;
1189
1190 case SKCTL_C:
1191 if( data == p->SKCTL )
1192 return;
1193 LOG(("POKEY #%d SKCTL $%02x\n", chip, data));
1194 p->SKCTL = data;
1195 if( !(data & SK_RESET) )
1196 {
1197 pokey_register_w(chip, IRQEN_C, 0);
1198 pokey_register_w(chip, SKREST_C, 0);
1199 }
1200 break;
1201 }
1202
1203 /************************************************************
1204 * As defined in the manual, the exact counter values are
1205 * different depending on the frequency and resolution:
1206 * 64 kHz or 15 kHz - AUDF + 1
1207 * 1.79 MHz, 8-bit - AUDF + 4
1208 * 1.79 MHz, 16-bit - AUDF[CHAN1]+256*AUDF[CHAN2] + 7
1209 ************************************************************/
1210
1211 /* only reset the channels that have changed */
1212
1213 if( ch_mask & (1 << CHAN1) )
1214 {
1215 /* process channel 1 frequency */
1216 if( p->AUDCTL & CH1_HICLK )
1217 new_val = p->AUDF[CHAN1] + DIVADD_HICLK;
1218 else
1219 new_val = (p->AUDF[CHAN1] + DIVADD_LOCLK) * p->clockmult;
1220
1221 LOG_SOUND(("POKEY #%d chan1 %d\n", chip, new_val));
1222
1223 p->volume[CHAN1] = (p->AUDC[CHAN1] & VOLUME_MASK) * POKEY_DEFAULT_GAIN;
1224 p->divisor[CHAN1] = new_val;
1225 if( new_val < p->counter[CHAN1] )
1226 p->counter[CHAN1] = new_val;
1227 if( p->interrupt_cb && p->timer[TIMER1] )
1228 timer_reset(p->timer[TIMER1], TIME_IN_SEC(1.0 * new_val / intf.baseclock));
1229 p->audible[CHAN1] = !(
1230 (p->AUDC[CHAN1] & VOLUME_ONLY) ||
1231 (p->AUDC[CHAN1] & VOLUME_MASK) == 0 ||
1232 ((p->AUDC[CHAN1] & PURE) && new_val < (p->samplerate_24_8 >> 8)));
1233 if( !p->audible[CHAN1] )
1234 {
1235 p->output[CHAN1] = 1;
1236 p->counter[CHAN1] = 0x7fffffff;
1237 /* 50% duty cycle should result in half volume */
1238 p->volume[CHAN1] >>= 1;
1239 }
1240 }
1241
1242 if( ch_mask & (1 << CHAN2) )
1243 {
1244 /* process channel 2 frequency */
1245 if( p->AUDCTL & CH12_JOINED )
1246 {
1247 if( p->AUDCTL & CH1_HICLK )
1248 new_val = p->AUDF[CHAN2] * 256 + p->AUDF[CHAN1] + DIVADD_HICLK_JOINED;
1249 else
1250 new_val = (p->AUDF[CHAN2] * 256 + p->AUDF[CHAN1] + DIVADD_LOCLK) * p->clockmult;
1251 LOG_SOUND(("POKEY #%d chan1+2 %d\n", chip, new_val));
1252 }
1253 else
1254 {
1255 new_val = (p->AUDF[CHAN2] + DIVADD_LOCLK) * p->clockmult;
1256 LOG_SOUND(("POKEY #%d chan2 %d\n", chip, new_val));
1257 }
1258
1259 p->volume[CHAN2] = (p->AUDC[CHAN2] & VOLUME_MASK) * POKEY_DEFAULT_GAIN;
1260 p->divisor[CHAN2] = new_val;
1261 if( new_val < p->counter[CHAN2] )
1262 p->counter[CHAN2] = new_val;
1263 if( p->interrupt_cb && p->timer[TIMER2] )
1264 timer_reset(p->timer[TIMER2], TIME_IN_SEC(1.0 * new_val / intf.baseclock));
1265 p->audible[CHAN2] = !(
1266 (p->AUDC[CHAN2] & VOLUME_ONLY) ||
1267 (p->AUDC[CHAN2] & VOLUME_MASK) == 0 ||
1268 ((p->AUDC[CHAN2] & PURE) && new_val < (p->samplerate_24_8 >> 8)));
1269 if( !p->audible[CHAN2] )
1270 {
1271 p->output[CHAN2] = 1;
1272 p->counter[CHAN2] = 0x7fffffff;
1273 /* 50% duty cycle should result in half volume */
1274 p->volume[CHAN2] >>= 1;
1275 }
1276 }
1277
1278 if( ch_mask & (1 << CHAN3) )
1279 {
1280 /* process channel 3 frequency */
1281 if( p->AUDCTL & CH3_HICLK )
1282 new_val = p->AUDF[CHAN3] + DIVADD_HICLK;
1283 else
1284 new_val = (p->AUDF[CHAN3] + DIVADD_LOCLK) * p->clockmult;
1285
1286 LOG_SOUND(("POKEY #%d chan3 %d\n", chip, new_val));
1287
1288 p->volume[CHAN3] = (p->AUDC[CHAN3] & VOLUME_MASK) * POKEY_DEFAULT_GAIN;
1289 p->divisor[CHAN3] = new_val;
1290 if( new_val < p->counter[CHAN3] )
1291 p->counter[CHAN3] = new_val;
1292 /* channel 3 does not have a timer associated */
1293 p->audible[CHAN3] = !(
1294 (p->AUDC[CHAN3] & VOLUME_ONLY) ||
1295 (p->AUDC[CHAN3] & VOLUME_MASK) == 0 ||
1296 ((p->AUDC[CHAN3] & PURE) && new_val < (p->samplerate_24_8 >> 8))) ||
1297 (p->AUDCTL & CH1_FILTER);
1298 if( !p->audible[CHAN3] )
1299 {
1300 p->output[CHAN3] = 1;
1301 p->counter[CHAN3] = 0x7fffffff;
1302 /* 50% duty cycle should result in half volume */
1303 p->volume[CHAN3] >>= 1;
1304 }
1305 }
1306
1307 if( ch_mask & (1 << CHAN4) )
1308 {
1309 /* process channel 4 frequency */
1310 if( p->AUDCTL & CH34_JOINED )
1311 {
1312 if( p->AUDCTL & CH3_HICLK )
1313 new_val = p->AUDF[CHAN4] * 256 + p->AUDF[CHAN3] + DIVADD_HICLK_JOINED;
1314 else
1315 new_val = (p->AUDF[CHAN4] * 256 + p->AUDF[CHAN3] + DIVADD_LOCLK) * p->clockmult;
1316 LOG_SOUND(("POKEY #%d chan3+4 %d\n", chip, new_val));
1317 }
1318 else
1319 {
1320 new_val = (p->AUDF[CHAN4] + DIVADD_LOCLK) * p->clockmult;
1321 LOG_SOUND(("POKEY #%d chan4 %d\n", chip, new_val));
1322 }
1323
1324 p->volume[CHAN4] = (p->AUDC[CHAN4] & VOLUME_MASK) * POKEY_DEFAULT_GAIN;
1325 p->divisor[CHAN4] = new_val;
1326 if( new_val < p->counter[CHAN4] )
1327 p->counter[CHAN4] = new_val;
1328 if( p->interrupt_cb && p->timer[TIMER4] )
1329 timer_reset(p->timer[TIMER4], TIME_IN_SEC(1.0 * new_val / intf.baseclock));
1330 p->audible[CHAN4] = !(
1331 (p->AUDC[CHAN4] & VOLUME_ONLY) ||
1332 (p->AUDC[CHAN4] & VOLUME_MASK) == 0 ||
1333 ((p->AUDC[CHAN4] & PURE) && new_val < (p->samplerate_24_8 >> 8))) ||
1334 (p->AUDCTL & CH2_FILTER);
1335 if( !p->audible[CHAN4] )
1336 {
1337 p->output[CHAN4] = 1;
1338 p->counter[CHAN4] = 0x7fffffff;
1339 /* 50% duty cycle should result in half volume */
1340 p->volume[CHAN4] >>= 1;
1341 }
1342 }
1343 }
1344
WRITE_HANDLER(pokey1_w)1345 WRITE_HANDLER( pokey1_w )
1346 {
1347 pokey_register_w(0,offset,data);
1348 }
1349
WRITE_HANDLER(pokey2_w)1350 WRITE_HANDLER( pokey2_w )
1351 {
1352 pokey_register_w(1,offset,data);
1353 }
1354
WRITE_HANDLER(pokey3_w)1355 WRITE_HANDLER( pokey3_w )
1356 {
1357 pokey_register_w(2,offset,data);
1358 }
1359
WRITE_HANDLER(pokey4_w)1360 WRITE_HANDLER( pokey4_w )
1361 {
1362 pokey_register_w(3,offset,data);
1363 }
1364
WRITE_HANDLER(quad_pokey_w)1365 WRITE_HANDLER( quad_pokey_w )
1366 {
1367 int pokey_num = (offset >> 3) & ~0x04;
1368 int control = (offset & 0x20) >> 2;
1369 int pokey_reg = (offset % 8) | control;
1370
1371 pokey_register_w(pokey_num, pokey_reg, data);
1372 }
1373
pokey1_serin_ready(int after)1374 void pokey1_serin_ready(int after)
1375 {
1376 timer_set(TIME_IN_SEC(1.0 * after / intf.baseclock), 0, pokey_serin_ready);
1377 }
1378
pokey2_serin_ready(int after)1379 void pokey2_serin_ready(int after)
1380 {
1381 timer_set(TIME_IN_SEC(1.0 * after / intf.baseclock), 1, pokey_serin_ready);
1382 }
1383
pokey3_serin_ready(int after)1384 void pokey3_serin_ready(int after)
1385 {
1386 timer_set(TIME_IN_SEC(1.0 * after / intf.baseclock), 2, pokey_serin_ready);
1387 }
1388
pokey4_serin_ready(int after)1389 void pokey4_serin_ready(int after)
1390 {
1391 timer_set(TIME_IN_SEC(1.0 * after / intf.baseclock), 3, pokey_serin_ready);
1392 }
1393
pokey_break_w(int chip,int shift)1394 void pokey_break_w(int chip, int shift)
1395 {
1396 struct POKEYregisters *p = &pokey[chip];
1397 if( shift ) /* shift code ? */
1398 p->SKSTAT |= SK_SHIFT;
1399 else
1400 p->SKSTAT &= ~SK_SHIFT;
1401 /* check if the break IRQ is enabled */
1402 if( p->IRQEN & IRQ_BREAK )
1403 {
1404 /* set break IRQ status and call back the interrupt handler */
1405 p->IRQST |= IRQ_BREAK;
1406 if( p->interrupt_cb )
1407 (*p->interrupt_cb)(IRQ_BREAK);
1408 }
1409 }
1410
pokey1_break_w(int shift)1411 void pokey1_break_w(int shift)
1412 {
1413 pokey_break_w(0, shift);
1414 }
1415
pokey2_break_w(int shift)1416 void pokey2_break_w(int shift)
1417 {
1418 pokey_break_w(1, shift);
1419 }
1420
pokey3_break_w(int shift)1421 void pokey3_break_w(int shift)
1422 {
1423 pokey_break_w(2, shift);
1424 }
1425
pokey4_break_w(int shift)1426 void pokey4_break_w(int shift)
1427 {
1428 pokey_break_w(3, shift);
1429 }
1430
pokey_kbcode_w(int chip,int kbcode,int make)1431 void pokey_kbcode_w(int chip, int kbcode, int make)
1432 {
1433 struct POKEYregisters *p = &pokey[chip];
1434 /* make code ? */
1435 if( make )
1436 {
1437 p->KBCODE = kbcode;
1438 p->SKSTAT |= SK_KEYBD;
1439 if( kbcode & 0x40 ) /* shift code ? */
1440 p->SKSTAT |= SK_SHIFT;
1441 else
1442 p->SKSTAT &= ~SK_SHIFT;
1443
1444 if( p->IRQEN & IRQ_KEYBD )
1445 {
1446 /* last interrupt not acknowledged ? */
1447 if( p->IRQST & IRQ_KEYBD )
1448 p->SKSTAT |= SK_KBERR;
1449 p->IRQST |= IRQ_KEYBD;
1450 if( p->interrupt_cb )
1451 (*p->interrupt_cb)(IRQ_KEYBD);
1452 }
1453 }
1454 else
1455 {
1456 p->KBCODE = kbcode;
1457 p->SKSTAT &= ~SK_KEYBD;
1458 }
1459 }
1460
pokey1_kbcode_w(int kbcode,int make)1461 void pokey1_kbcode_w(int kbcode, int make)
1462 {
1463 pokey_kbcode_w(0, kbcode, make);
1464 }
1465
pokey2_kbcode_w(int kbcode,int make)1466 void pokey2_kbcode_w(int kbcode, int make)
1467 {
1468 pokey_kbcode_w(1, kbcode, make);
1469 }
1470
pokey3_kbcode_w(int kbcode,int make)1471 void pokey3_kbcode_w(int kbcode, int make)
1472 {
1473 pokey_kbcode_w(2, kbcode, make);
1474 }
1475
pokey4_kbcode_w(int kbcode,int make)1476 void pokey4_kbcode_w(int kbcode, int make)
1477 {
1478 pokey_kbcode_w(3, kbcode, make);
1479 }
1480
1481