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