1 // Based on MAME driver by Juergen Buchmueller, Mike Balfour, Howie Cohen, Olivier Galibert, Aaron Giles
2 
3 #include "burnint.h"
4 #include "upd7759.h"
5 
6 #define FRAC_BITS			20
7 #define FRAC_ONE			(1 << FRAC_BITS)
8 #define FRAC_MASK			(FRAC_ONE - 1)
9 
10 static INT32 SlaveMode;
11 
12 /* chip states */
13 enum
14 {
15 	STATE_IDLE,
16 	STATE_DROP_DRQ,
17 	STATE_START,
18 	STATE_FIRST_REQ,
19 	STATE_LAST_SAMPLE,
20 	STATE_DUMMY1,
21 	STATE_ADDR_MSB,
22 	STATE_ADDR_LSB,
23 	STATE_DUMMY2,
24 	STATE_BLOCK_HEADER,
25 	STATE_NIBBLE_COUNT,
26 	STATE_NIBBLE_MSN,
27 	STATE_NIBBLE_LSN
28 };
29 
30 struct upd7759_chip
31 {
32 	/* internal clock to output sample rate mapping */
33 	UINT32		pos;						/* current output sample position */
34 	UINT32		step;						/* step value per output sample */
35 
36 	/* I/O lines */
37 	UINT8		fifo_in;					/* last data written to the sound chip */
38 	UINT8		reset;						/* current state of the RESET line */
39 	UINT8		start;						/* current state of the START line */
40 	UINT8		drq;						/* current state of the DRQ line */
41 	void (*drqcallback)(INT32 param);			/* drq callback */
42 
43 	/* internal state machine */
44 	INT8		state;						/* current overall chip state */
45 	INT32		clocks_left;				/* number of clocks left in this state */
46 	UINT16		nibbles_left;				/* number of ADPCM nibbles left to process */
47 	UINT8		repeat_count;				/* number of repeats remaining in current repeat block */
48 	INT8		post_drq_state;				/* state we will be in after the DRQ line is dropped */
49 	INT32		post_drq_clocks;			/* clocks that will be left after the DRQ line is dropped */
50 	UINT8		req_sample;					/* requested sample number */
51 	UINT8		last_sample;				/* last sample number available */
52 	UINT8		block_header;				/* header byte */
53 	UINT8		sample_rate;				/* number of UPD clocks per ADPCM nibble */
54 	UINT8		first_valid_header;			/* did we get our first valid header yet? */
55 	UINT32		offset;						/* current ROM offset */
56 	UINT32		repeat_offset;				/* current ROM repeat offset */
57 
58 	/* ADPCM processing */
59 	INT8		adpcm_state;				/* ADPCM state index */
60 	UINT8		adpcm_data;					/* current byte of ADPCM data */
61 	INT16		sample;						/* current sample value */
62 
63 	/* ROM access */
64 	UINT8 *		rom;						/* pointer to ROM data or NULL for slave mode */
65 	UINT8 *		rombase;					/* pointer to ROM data or NULL for slave mode */
66 	UINT32		romoffset;					/* ROM offset to make save/restore easier */
67 
68 	/* route */
69 	double		volume;
70 	INT32		output_dir;
71 };
72 
73 static struct upd7759_chip *Chips[2] = { NULL, NULL }; // more?
74 static struct upd7759_chip *Chip = NULL;
75 
76 static INT32 nNumChips = 0;
77 
78 static const INT32 upd7759_step[16][16] =
79 {
80 	{ 0,  0,  1,  2,  3,   5,   7,  10,  0,   0,  -1,  -2,  -3,   -5,   -7,  -10 },
81 	{ 0,  1,  2,  3,  4,   6,   8,  13,  0,  -1,  -2,  -3,  -4,   -6,   -8,  -13 },
82 	{ 0,  1,  2,  4,  5,   7,  10,  15,  0,  -1,  -2,  -4,  -5,   -7,  -10,  -15 },
83 	{ 0,  1,  3,  4,  6,   9,  13,  19,  0,  -1,  -3,  -4,  -6,   -9,  -13,  -19 },
84 	{ 0,  2,  3,  5,  8,  11,  15,  23,  0,  -2,  -3,  -5,  -8,  -11,  -15,  -23 },
85 	{ 0,  2,  4,  7, 10,  14,  19,  29,  0,  -2,  -4,  -7, -10,  -14,  -19,  -29 },
86 	{ 0,  3,  5,  8, 12,  16,  22,  33,  0,  -3,  -5,  -8, -12,  -16,  -22,  -33 },
87 	{ 1,  4,  7, 10, 15,  20,  29,  43, -1,  -4,  -7, -10, -15,  -20,  -29,  -43 },
88 	{ 1,  4,  8, 13, 18,  25,  35,  53, -1,  -4,  -8, -13, -18,  -25,  -35,  -53 },
89 	{ 1,  6, 10, 16, 22,  31,  43,  64, -1,  -6, -10, -16, -22,  -31,  -43,  -64 },
90 	{ 2,  7, 12, 19, 27,  37,  51,  76, -2,  -7, -12, -19, -27,  -37,  -51,  -76 },
91 	{ 2,  9, 16, 24, 34,  46,  64,  96, -2,  -9, -16, -24, -34,  -46,  -64,  -96 },
92 	{ 3, 11, 19, 29, 41,  57,  79, 117, -3, -11, -19, -29, -41,  -57,  -79, -117 },
93 	{ 4, 13, 24, 36, 50,  69,  96, 143, -4, -13, -24, -36, -50,  -69,  -96, -143 },
94 	{ 4, 16, 29, 44, 62,  85, 118, 175, -4, -16, -29, -44, -62,  -85, -118, -175 },
95 	{ 6, 20, 36, 54, 76, 104, 144, 214, -6, -20, -36, -54, -76, -104, -144, -214 },
96 };
97 
98 static const INT32 upd7759_state[16] = { -1, -1, 0, 0, 1, 2, 2, 3, -1, -1, 0, 0, 1, 2, 2, 3 };
99 
UpdateAdpcm(INT32 Data)100 inline static void UpdateAdpcm(INT32 Data)
101 {
102 	Chip->sample += upd7759_step[Chip->adpcm_state][Data];
103 	Chip->adpcm_state += upd7759_state[Data];
104 
105 	/* clamp the state to 0..15 */
106 	if (Chip->adpcm_state < 0)
107 		Chip->adpcm_state = 0;
108 	else if (Chip->adpcm_state > 15)
109 		Chip->adpcm_state = 15;
110 }
111 
UPD7759AdvanceState()112 static void UPD7759AdvanceState()
113 {
114 	switch (Chip->state)
115 	{
116 		/* Idle state: we stick around here while there's nothing to do */
117 		case STATE_IDLE:
118 			Chip->clocks_left = 4;
119 			break;
120 
121 		/* drop DRQ state: update to the intended state */
122 		case STATE_DROP_DRQ:
123 			Chip->drq = 0;
124 
125 			Chip->clocks_left = Chip->post_drq_clocks;
126 			Chip->state = Chip->post_drq_state;
127 			break;
128 
129 		/* Start state: we begin here as soon as a sample is triggered */
130 		case STATE_START:
131 			Chip->req_sample = Chip->rom ? Chip->fifo_in : 0x10;
132 
133 			/* 35+ cycles after we get here, the /DRQ goes low
134              *     (first byte (number of samples in ROM) should be sent in response)
135              *
136              * (35 is the minimum number of cycles I found during heavy tests.
137              * Depending on the state the chip was in just before the /MD was set to 0 (reset, standby
138              * or just-finished-playing-previous-sample) this number can range from 35 up to ~24000).
139              * It also varies slightly from test to test, but not much - a few cycles at most.) */
140 			Chip->clocks_left = 70;	/* 35 - breaks cotton */
141 			Chip->state = STATE_FIRST_REQ;
142 			break;
143 
144 		/* First request state: issue a request for the first byte */
145 		/* The expected response will be the index of the last sample */
146 		case STATE_FIRST_REQ:
147 			Chip->drq = 1;
148 
149 			/* 44 cycles later, we will latch this value and request another byte */
150 			Chip->clocks_left = 44;
151 			Chip->state = STATE_LAST_SAMPLE;
152 			break;
153 
154 		/* Last sample state: latch the last sample value and issue a request for the second byte */
155 		/* The second byte read will be just a dummy */
156 		case STATE_LAST_SAMPLE:
157 			Chip->last_sample = Chip->rom ? Chip->rom[0] : Chip->fifo_in;
158 			Chip->drq = 1;
159 
160 			/* 28 cycles later, we will latch this value and request another byte */
161 			Chip->clocks_left = 28;	/* 28 - breaks cotton */
162 			Chip->state = (Chip->req_sample > Chip->last_sample) ? STATE_IDLE : STATE_DUMMY1;
163 			break;
164 
165 		/* First dummy state: ignore any data here and issue a request for the third byte */
166 		/* The expected response will be the MSB of the sample address */
167 		case STATE_DUMMY1:
168 			Chip->drq = 1;
169 
170 			/* 32 cycles later, we will latch this value and request another byte */
171 			Chip->clocks_left = 32;
172 			Chip->state = STATE_ADDR_MSB;
173 			break;
174 
175 		/* Address MSB state: latch the MSB of the sample address and issue a request for the fourth byte */
176 		/* The expected response will be the LSB of the sample address */
177 		case STATE_ADDR_MSB:
178 			Chip->offset = (Chip->rom ? Chip->rom[Chip->req_sample * 2 + 5] : Chip->fifo_in) << 9;
179 			Chip->drq = 1;
180 
181 			/* 44 cycles later, we will latch this value and request another byte */
182 			Chip->clocks_left = 44;
183 			Chip->state = STATE_ADDR_LSB;
184 			break;
185 
186 		/* Address LSB state: latch the LSB of the sample address and issue a request for the fifth byte */
187 		/* The expected response will be just a dummy */
188 		case STATE_ADDR_LSB:
189 			Chip->offset |= (Chip->rom ? Chip->rom[Chip->req_sample * 2 + 6] : Chip->fifo_in) << 1;
190 			Chip->drq = 1;
191 
192 			/* 36 cycles later, we will latch this value and request another byte */
193 			Chip->clocks_left = 36;
194 			Chip->state = STATE_DUMMY2;
195 			break;
196 
197 		/* Second dummy state: ignore any data here and issue a request for the the sixth byte */
198 		/* The expected response will be the first block header */
199 		case STATE_DUMMY2:
200 			Chip->offset++;
201 			Chip->first_valid_header = 0;
202 			Chip->drq = 1;
203 
204 			/* 36?? cycles later, we will latch this value and request another byte */
205 			Chip->clocks_left = 36;
206 			Chip->state = STATE_BLOCK_HEADER;
207 			break;
208 
209 		/* Block header state: latch the header and issue a request for the first byte afterwards */
210 		case STATE_BLOCK_HEADER:
211 
212 			/* if we're in a repeat loop, reset the offset to the repeat point and decrement the count */
213 			if (Chip->repeat_count)
214 			{
215 				Chip->repeat_count--;
216 				Chip->offset = Chip->repeat_offset;
217 			}
218 			Chip->block_header = Chip->rom ? Chip->rom[Chip->offset++ & 0x1ffff] : Chip->fifo_in;
219 			Chip->drq = 1;
220 
221 			/* our next step depends on the top two bits */
222 			switch (Chip->block_header & 0xc0)
223 			{
224 				case 0x00:	/* silence */
225 					Chip->clocks_left = 1024 * ((Chip->block_header & 0x3f) + 1);
226 					Chip->state = (Chip->block_header == 0 && Chip->first_valid_header) ? STATE_IDLE : STATE_BLOCK_HEADER;
227 					Chip->sample = 0;
228 					Chip->adpcm_state = 0;
229 					break;
230 
231 				case 0x40:	/* 256 nibbles */
232 					Chip->sample_rate = (Chip->block_header & 0x3f) + 1;
233 					Chip->nibbles_left = 256;
234 					Chip->clocks_left = 36;	/* just a guess */
235 					Chip->state = STATE_NIBBLE_MSN;
236 					break;
237 
238 				case 0x80:	/* n nibbles */
239 					Chip->sample_rate = (Chip->block_header & 0x3f) + 1;
240 					Chip->clocks_left = 36;	/* just a guess */
241 					Chip->state = STATE_NIBBLE_COUNT;
242 					break;
243 
244 				case 0xc0:	/* repeat loop */
245 					Chip->repeat_count = (Chip->block_header & 7) + 1;
246 					Chip->repeat_offset = Chip->offset;
247 					Chip->clocks_left = 36;	/* just a guess */
248 					Chip->state = STATE_BLOCK_HEADER;
249 					break;
250 			}
251 
252 			/* set a flag when we get the first non-zero header */
253 			if (Chip->block_header != 0)
254 				Chip->first_valid_header = 1;
255 			break;
256 
257 		/* Nibble count state: latch the number of nibbles to play and request another byte */
258 		/* The expected response will be the first data byte */
259 		case STATE_NIBBLE_COUNT:
260 			Chip->nibbles_left = (Chip->rom ? Chip->rom[Chip->offset++ & 0x1ffff] : Chip->fifo_in) + 1;
261 			Chip->drq = 1;
262 
263 			/* 36?? cycles later, we will latch this value and request another byte */
264 			Chip->clocks_left = 36;	/* just a guess */
265 			Chip->state = STATE_NIBBLE_MSN;
266 			break;
267 
268 		/* MSN state: latch the data for this pair of samples and request another byte */
269 		/* The expected response will be the next sample data or another header */
270 		case STATE_NIBBLE_MSN:
271 			Chip->adpcm_data = Chip->rom ? Chip->rom[Chip->offset++ & 0x1ffff] : Chip->fifo_in;
272 			UpdateAdpcm(Chip->adpcm_data >> 4);
273 			Chip->drq = 1;
274 
275 			/* we stay in this state until the time for this sample is complete */
276 			Chip->clocks_left = Chip->sample_rate * 4;
277 			if (--Chip->nibbles_left == 0)
278 				Chip->state = STATE_BLOCK_HEADER;
279 			else
280 				Chip->state = STATE_NIBBLE_LSN;
281 			break;
282 
283 		/* LSN state: process the lower nibble */
284 		case STATE_NIBBLE_LSN:
285 			UpdateAdpcm(Chip->adpcm_data & 15);
286 
287 			/* we stay in this state until the time for this sample is complete */
288 			Chip->clocks_left = Chip->sample_rate * 4;
289 			if (--Chip->nibbles_left == 0)
290 				Chip->state = STATE_BLOCK_HEADER;
291 			else
292 				Chip->state = STATE_NIBBLE_MSN;
293 			break;
294 	}
295 
296 	/* if there's a DRQ, fudge the state */
297 	if (Chip->drq)
298 	{
299 		Chip->post_drq_state = Chip->state;
300 		Chip->post_drq_clocks = Chip->clocks_left - 21;
301 		Chip->state = STATE_DROP_DRQ;
302 		Chip->clocks_left = 21;
303 	}
304 }
305 
UPD7759SlaveModeUpdate()306 static void UPD7759SlaveModeUpdate()
307 {
308 	UINT8 OldDrq = Chip->drq;
309 
310 	UPD7759AdvanceState();
311 
312 	if (OldDrq != Chip->drq && Chip->drqcallback) {
313 		(*Chip->drqcallback)(Chip->drq);
314 	}
315 }
316 
UPD7759Update(INT32 chip,INT16 * pSoundBuf,INT32 nLength)317 void UPD7759Update(INT32 chip, INT16 *pSoundBuf, INT32 nLength)
318 {
319 #if defined FBA_DEBUG
320 	if (!DebugSnd_UPD7759Initted) bprintf(PRINT_ERROR, _T("UPD7759Update called without init\n"));
321 	if (chip > nNumChips) bprintf(PRINT_ERROR, _T("UPD7759Update called with invalid chip %x\n"), chip);
322 #endif
323 
324 	Chip = Chips[chip];
325 
326 	INT32 ClocksLeft = Chip->clocks_left;
327 	INT16 Sample = Chip->sample;
328 	UINT32 Step = Chip->step;
329 	UINT32 Pos = Chip->pos;
330 
331 	/* loop until done */
332 	if (Chip->state != STATE_IDLE)
333 		while (nLength != 0)
334 		{
335 			/* store the current sample */
336 			INT32 nLeftSample = 0;
337 			INT32 nRightSample = 0;
338 
339 			if ((Chip->output_dir & BURN_SND_ROUTE_LEFT) == BURN_SND_ROUTE_LEFT) {
340 				nLeftSample += (INT32)((Sample << 7) * Chip->volume);
341 			}
342 			if ((Chip->output_dir & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) {
343 				nRightSample += (INT32)((Sample << 7) * Chip->volume);
344 			}
345 
346 			nLeftSample = BURN_SND_CLIP(nLeftSample);
347 			nRightSample = BURN_SND_CLIP(nRightSample);
348 
349 			pSoundBuf[0] = BURN_SND_CLIP(pSoundBuf[0] + nLeftSample);
350 			pSoundBuf[1] = BURN_SND_CLIP(pSoundBuf[1] + nRightSample);
351 			pSoundBuf += 2;
352 			nLength--;
353 
354 			/* advance by the number of clocks/output sample */
355 			Pos += Step;
356 
357 			/* handle clocks, but only in standalone mode */
358 			while (Chip->rom && Pos >= FRAC_ONE)
359 			{
360 				INT32 ClocksThisTime = Pos >> FRAC_BITS;
361 				if (ClocksThisTime > ClocksLeft)
362 					ClocksThisTime = ClocksLeft;
363 
364 				/* clock once */
365 				Pos -= ClocksThisTime * FRAC_ONE;
366 				ClocksLeft -= ClocksThisTime;
367 
368 				/* if we're out of clocks, time to handle the next state */
369 				if (ClocksLeft == 0)
370 				{
371 					/* advance one state; if we hit idle, bail */
372 					UPD7759AdvanceState();
373 					if (Chip->state == STATE_IDLE)
374 						break;
375 
376 					/* reimport the variables that we cached */
377 					ClocksLeft = Chip->clocks_left;
378 					Sample = Chip->sample;
379 				}
380 			}
381 		}
382 
383 	if (SlaveMode && ClocksLeft > 0) UPD7759SlaveModeUpdate();
384 
385 	Chip->clocks_left = ClocksLeft;
386 	Chip->pos = Pos;
387 }
388 
UPD7759Reset()389 void UPD7759Reset()
390 {
391 #if defined FBA_DEBUG
392 	if (!DebugSnd_UPD7759Initted) bprintf(PRINT_ERROR, _T("UPD7759Reset called without init\n"));
393 #endif
394 
395 	for (INT32 i = 0; i < 2; i++) {
396 		Chip = Chips[i];
397 		if (Chip == NULL) {
398 			continue;
399 		}
400 
401 		Chip->pos                = 0;
402 		Chip->fifo_in            = 0;
403 		Chip->drq                = 0;
404 		Chip->state              = STATE_IDLE;
405 		Chip->clocks_left        = 0;
406 		Chip->nibbles_left       = 0;
407 		Chip->repeat_count       = 0;
408 		Chip->post_drq_state     = STATE_IDLE;
409 		Chip->post_drq_clocks    = 0;
410 		Chip->req_sample         = 0;
411 		Chip->last_sample        = 0;
412 		Chip->block_header       = 0;
413 		Chip->sample_rate        = 0;
414 		Chip->first_valid_header = 0;
415 		Chip->offset             = 0;
416 		Chip->repeat_offset      = 0;
417 		Chip->adpcm_state        = 0;
418 		Chip->adpcm_data         = 0;
419 		Chip->sample             = 0;
420 	}
421 }
422 
UPD7759Init(INT32 chip,INT32 clock,UINT8 * pSoundData)423 void UPD7759Init(INT32 chip, INT32 clock, UINT8* pSoundData)
424 {
425 	DebugSnd_UPD7759Initted = 1;
426 
427 	Chips[chip] = (struct upd7759_chip*)BurnMalloc(sizeof(*Chip));
428 	Chip = Chips[chip];
429 
430 	memset(Chip, 0, sizeof(*Chip));
431 
432 	SlaveMode = 0;
433 
434 	float Rate = (float)clock / 4 / nBurnSoundRate;
435 	Chip->step = (INT32)(4 * FRAC_ONE * Rate);
436 	Chip->state = STATE_IDLE;
437 
438 	if (pSoundData) {
439 		Chip->rom = pSoundData;
440 	} else {
441 		SlaveMode = 1;
442 	}
443 
444 	Chip->reset = 1;
445 	Chip->start = 1;
446 	Chip->volume = 1.00;
447 	Chip->output_dir = BURN_SND_ROUTE_BOTH;
448 
449 	nNumChips = chip;
450 
451 	UPD7759Reset();
452 }
453 
UPD7759SetRoute(INT32 chip,double nVolume,INT32 nRouteDir)454 void UPD7759SetRoute(INT32 chip, double nVolume, INT32 nRouteDir)
455 {
456 #if defined FBA_DEBUG
457 	if (!DebugSnd_UPD7759Initted) bprintf(PRINT_ERROR, _T("UPD7759SetRoute called without init\n"));
458 	if (chip > nNumChips) bprintf(PRINT_ERROR, _T("UPD7759SetRoute called with invalid chip %i\n"), chip);
459 #endif
460 
461 	Chip = Chips[chip];
462 	Chip->volume = nVolume;
463 	Chip->output_dir = nRouteDir;
464 }
465 
UPD7759SetDrqCallback(INT32 chip,drqcallback Callback)466 void UPD7759SetDrqCallback(INT32 chip, drqcallback Callback)
467 {
468 #if defined FBA_DEBUG
469 	if (!DebugSnd_UPD7759Initted) bprintf(PRINT_ERROR, _T("UPD7759SetDrqCallback called without init\n"));
470 	if (chip > nNumChips) bprintf(PRINT_ERROR, _T("UPD7759SetDrqCallback called with invalid chip %x\n"), chip);
471 #endif
472 
473 	Chip = Chips[chip];
474 	Chip->drqcallback = Callback;
475 }
476 
UPD7759BusyRead(INT32 chip)477 INT32 UPD7759BusyRead(INT32 chip)
478 {
479 #if defined FBA_DEBUG
480 	if (!DebugSnd_UPD7759Initted) bprintf(PRINT_ERROR, _T("UPD7759BusyRead called without init\n"));
481 	if (chip > nNumChips) bprintf(PRINT_ERROR, _T("UPD7759BusyRead called with invalid chip %x\n"), chip);
482 #endif
483 
484 	Chip = Chips[chip];
485 	return (Chip->state == STATE_IDLE);
486 }
487 
UPD7759ResetWrite(INT32 chip,UINT8 Data)488 void UPD7759ResetWrite(INT32 chip, UINT8 Data)
489 {
490 #if defined FBA_DEBUG
491 	if (!DebugSnd_UPD7759Initted) bprintf(PRINT_ERROR, _T("UPD7759ResetWrite called without init\n"));
492 	if (chip > nNumChips) bprintf(PRINT_ERROR, _T("UPD7759ResetWrite called with invalid chip %x\n"), chip);
493 #endif
494 
495 	Chip = Chips[chip];
496 	UINT8 Oldreset = Chip->reset;
497 	Chip->reset = (Data != 0);
498 
499 	if (Oldreset && !Chip->reset) {
500 		UPD7759Reset();
501 	}
502 }
503 
UPD7759StartWrite(INT32 chip,UINT8 Data)504 void UPD7759StartWrite(INT32 chip, UINT8 Data)
505 {
506 #if defined FBA_DEBUG
507 	if (!DebugSnd_UPD7759Initted) bprintf(PRINT_ERROR, _T("UPD7759StartWrite called without init\n"));
508 	if (chip > nNumChips) bprintf(PRINT_ERROR, _T("UPD7759StartWrite called with invalid chip %x\n"), chip);
509 #endif
510 
511 	Chip = Chips[chip];
512 	UINT8 Oldstart = Chip->start;
513 	Chip->start = (Data != 0);
514 
515 	if (Chip->state == STATE_IDLE && !Oldstart && Chip->start && Chip->reset) {
516 		Chip->state = STATE_START;
517 
518 		if (SlaveMode) UPD7759SlaveModeUpdate();
519 	}
520 }
521 
UPD7759PortWrite(INT32 chip,UINT8 Data)522 void UPD7759PortWrite(INT32 chip, UINT8 Data)
523 {
524 #if defined FBA_DEBUG
525 	if (!DebugSnd_UPD7759Initted) bprintf(PRINT_ERROR, _T("UPD7759PortWrite called without init\n"));
526 	if (chip > nNumChips) bprintf(PRINT_ERROR, _T("UPD7759PortWrite called with invalid chip %x\n"), chip);
527 #endif
528 
529 	Chip = Chips[chip];
530 	Chip->fifo_in = Data;
531 }
532 
UPD7759Scan(INT32 nAction,INT32 * pnMin)533 void UPD7759Scan(INT32 nAction,INT32 *pnMin)
534 {
535 #if defined FBA_DEBUG
536 	if (!DebugSnd_UPD7759Initted) bprintf(PRINT_ERROR, _T("UPD7759Scan called without init\n"));
537 #endif
538 
539 	if ((nAction & ACB_DRIVER_DATA) == 0) {
540 		return;
541 	}
542 
543 	if (pnMin != NULL) {
544 		*pnMin = 0x029680;
545 	}
546 
547 	for (INT32 i = 0; i <= nNumChips; i++) // first chip 0, second chip 1...
548 	{
549 		Chip = Chips[i];
550 
551 		SCAN_VAR(Chip->pos);
552 		SCAN_VAR(Chip->step);
553 		SCAN_VAR(Chip->fifo_in);
554 		SCAN_VAR(Chip->reset);
555 		SCAN_VAR(Chip->start);
556 		SCAN_VAR(Chip->drq);
557 		SCAN_VAR(Chip->state);
558 		SCAN_VAR(Chip->clocks_left);
559 		SCAN_VAR(Chip->nibbles_left);
560 		SCAN_VAR(Chip->repeat_count);
561 		SCAN_VAR(Chip->post_drq_state);
562 		SCAN_VAR(Chip->post_drq_clocks);
563 		SCAN_VAR(Chip->req_sample);
564 		SCAN_VAR(Chip->last_sample);
565 		SCAN_VAR(Chip->block_header);
566 		SCAN_VAR(Chip->sample_rate);
567 		SCAN_VAR(Chip->first_valid_header);
568 		SCAN_VAR(Chip->offset);
569 		SCAN_VAR(Chip->repeat_offset);
570 		SCAN_VAR(Chip->adpcm_state);
571 		SCAN_VAR(Chip->adpcm_data);
572 		SCAN_VAR(Chip->sample);
573 		SCAN_VAR(Chip->romoffset);
574 		SCAN_VAR(Chip->volume);
575 		SCAN_VAR(Chip->output_dir);
576 	}
577 }
578 
UPD7759Exit()579 void UPD7759Exit()
580 {
581 #if defined FBA_DEBUG
582 	if (!DebugSnd_UPD7759Initted) bprintf(PRINT_ERROR, _T("UPD7759Exit called without init\n"));
583 #endif
584 
585 	BurnFree(Chips[0]);
586 	BurnFree(Chips[1]);
587 	SlaveMode = 0;
588 
589 	DebugSnd_UPD7759Initted = 0;
590 	nNumChips = 0;
591 }
592