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