5 ** YAMAHA DELTA-T adpcm sound emulation subroutine
6 ** used by fmopl.c (Y8950) and fm.c (YM2608 and YM2610/B)
8 ** Base program is YM2610 emulator by Hiromitsu Shioya.
9 ** Written by Tatsuyuki Satoh
10 ** Improvements by Jarek Burczynski (bujar at mame dot net)
15 ** 03-08-2003 Jarek Burczynski:
16 ** - fixed BRDY flag implementation.
18 ** 24-07-2003 Jarek Burczynski, Frits Hilderink:
19 ** - fixed delault value for control2 in YM_DELTAT_ADPCM_Reset
21 ** 22-07-2003 Jarek Burczynski, Frits Hilderink:
22 ** - fixed external memory support
24 ** 15-06-2003 Jarek Burczynski:
25 ** - implemented CPU -> AUDIO ADPCM synthesis (via writes to the ADPCM data reg $08)
26 ** - implemented support for the Limit address register
27 ** - supported two bits from the control register 2 ($01): RAM TYPE (x1 bit/x8 bit), ROM/RAM
28 ** - implemented external memory access (read/write) via the ADPCM data reg reads/writes
29 ** Thanks go to Frits Hilderink for the example code.
31 ** 14-06-2003 Jarek Burczynski:
32 ** - various fixes to enable proper support for status register flags: BSRDY, PCM BSY, ZERO
33 ** - modified EOS handling
35 ** 05-04-2003 Jarek Burczynski:
36 ** - implemented partial support for external/processor memory on sample replay
38 ** 01-12-2002 Jarek Burczynski:
39 ** - fixed first missing sound in gigandes thanks to previous fix (interpolator) by ElSemi
40 ** - renamed/removed some YM_DELTAT struct fields
42 ** 28-12-2001 Acho A. Tang
43 ** - added EOS status report on ADPCM playback.
45 ** 05-08-2001 Jarek Burczynski:
46 ** - now_step is initialized with 0 at the start of play.
48 ** 12-06-2001 Jarek Burczynski:
49 ** - corrected end of sample bug in YM_DELTAT_ADPCM_CALC.
50 ** Checked on real YM2610 chip - address register is 24 bits wide.
51 ** Thanks go to Stefan Jokisch (stefan.jokisch@gmx.de) for tracking down the problem.
54 ** Check size of the address register on the other chips....
58 ** sound chips that have this unit:
66 #define INLINE __inline
67 #define logerror (void)
69 #define YM_DELTAT_DELTA_MAX (24576)
70 #define YM_DELTAT_DELTA_MIN (127)
71 #define YM_DELTAT_DELTA_DEF (127)
73 #define YM_DELTAT_DECODE_RANGE 32768
74 #define YM_DELTAT_DECODE_MIN (-(YM_DELTAT_DECODE_RANGE))
75 #define YM_DELTAT_DECODE_MAX ((YM_DELTAT_DECODE_RANGE)-1)
78 /* Forecast to next Forecast (rate = *8) */
79 /* 1/8 , 3/8 , 5/8 , 7/8 , 9/8 , 11/8 , 13/8 , 15/8 */
80 static const INT32 ym_deltat_decode_tableB1
[16] ICONST_ATTR
= {
81 1, 3, 5, 7, 9, 11, 13, 15,
82 -1, -3, -5, -7, -9, -11, -13, -15,
84 /* delta to next delta (rate= *64) */
85 /* 0.9 , 0.9 , 0.9 , 0.9 , 1.2 , 1.6 , 2.0 , 2.4 */
86 static const INT32 ym_deltat_decode_tableB2
[16] ICONST_ATTR
= {
87 57, 57, 57, 57, 77, 102, 128, 153,
88 57, 57, 57, 57, 77, 102, 128, 153
92 void YM_DELTAT_BRDY_callback(YM_DELTAT
*DELTAT
)
94 logerror("BRDY_callback reached (flag set) !\n");
96 /* set BRDY bit in status register */
97 if(DELTAT
->status_set_handler
)
98 if(DELTAT
->status_change_BRDY_bit
)
99 (DELTAT
->status_set_handler
)(DELTAT
->status_change_which_chip
, DELTAT
->status_change_BRDY_bit
);
103 UINT8
YM_DELTAT_ADPCM_Read(YM_DELTAT
*DELTAT
)
107 /* external memory read */
108 if ( (DELTAT
->portstate
& 0xe0)==0x20 )
110 /* two dummy reads */
113 DELTAT
->now_addr
= DELTAT
->start
<< 1;
119 if ( DELTAT
->now_addr
!= (DELTAT
->end
<<1) )
121 v
= DELTAT
->memory
[DELTAT
->now_addr
>>1];
123 /*logerror("YM Delta-T memory read $%08x, v=$%02x\n", DELTAT->now_addr >> 1, v);*/
125 DELTAT
->now_addr
+=2; /* two nibbles at a time */
127 /* reset BRDY bit in status register, which means we are reading the memory now */
128 if(DELTAT
->status_reset_handler
)
129 if(DELTAT
->status_change_BRDY_bit
)
130 (DELTAT
->status_reset_handler
)(DELTAT
->status_change_which_chip
, DELTAT
->status_change_BRDY_bit
);
132 /* setup a timer that will callback us in 10 master clock cycles for Y8950
133 * in the callback set the BRDY flag to 1 , which means we have another data ready.
134 * For now, we don't really do this; we simply reset and set the flag in zero time, so that the IRQ will work.
136 /* set BRDY bit in status register */
137 if(DELTAT
->status_set_handler
)
138 if(DELTAT
->status_change_BRDY_bit
)
139 (DELTAT
->status_set_handler
)(DELTAT
->status_change_which_chip
, DELTAT
->status_change_BRDY_bit
);
143 /* set EOS bit in status register */
144 if(DELTAT
->status_set_handler
)
145 if(DELTAT
->status_change_EOS_bit
)
146 (DELTAT
->status_set_handler
)(DELTAT
->status_change_which_chip
, DELTAT
->status_change_EOS_bit
);
154 /* 0-DRAM x1, 1-ROM, 2-DRAM x8, 3-ROM (3 is bad setting - not allowed by the manual) */
155 static const UINT8 dram_rightshift
[4] ICONST_ATTR
={3,0,0,0};
157 /* DELTA-T ADPCM write register */
158 void YM_DELTAT_ADPCM_Write(YM_DELTAT
*DELTAT
,int r
,int v
)
161 DELTAT
->reg
[r
] = v
; /* stock data */
168 Accessing *external* memory is started when START bit (D7) is set to "1", so
169 you must set all conditions needed for recording/playback before starting.
170 If you access *CPU-managed* memory, recording/playback starts after
171 read/write of ADPCM data register $08.
174 0 = ADPCM synthesis (playback)
175 1 = ADPCM analysis (record)
178 0 = processor (*CPU-managed*) memory (means: using register $08)
179 1 = external memory (using start/end/limit registers to access memory: RAM or ROM)
183 controls output pin that should disable the speaker while ADPCM analysis
185 RESET and REPEAT only work with external memory.
189 value: START, REC, MEMDAT, REPEAT, SPOFF, x,x,RESET meaning:
190 C8 1 1 0 0 1 0 0 0 Analysis (recording) from AUDIO to CPU (to reg $08), sample rate in PRESCALER register
191 E8 1 1 1 0 1 0 0 0 Analysis (recording) from AUDIO to EXT.MEMORY, sample rate in PRESCALER register
192 80 1 0 0 0 0 0 0 0 Synthesis (playing) from CPU (from reg $08) to AUDIO,sample rate in DELTA-N register
193 a0 1 0 1 0 0 0 0 0 Synthesis (playing) from EXT.MEMORY to AUDIO, sample rate in DELTA-N register
195 60 0 1 1 0 0 0 0 0 External memory write via ADPCM data register $08
196 20 0 0 1 0 0 0 0 0 External memory read via ADPCM data register $08
199 /* handle emulation mode */
200 if(DELTAT
->emulation_mode
== YM_DELTAT_EMULATION_MODE_YM2610
)
202 v
|= 0x20; /* YM2610 always uses external memory and doesn't even have memory flag bit. */
205 DELTAT
->portstate
= v
& (0x80|0x40|0x20|0x10|0x01); /* start, rec, memory mode, repeat flag copy, reset(bit0) */
207 if( DELTAT
->portstate
&0x80 )/* START,REC,MEMDATA,REPEAT,SPOFF,--,--,RESET */
209 /* set PCM BUSY bit */
213 DELTAT
->now_step
= 0;
215 DELTAT
->prev_acc
= 0;
217 DELTAT
->adpcmd
= YM_DELTAT_DELTA_DEF
;
218 DELTAT
->now_data
= 0;
222 if( DELTAT
->portstate
&0x20 ) /* do we access external memory? */
224 DELTAT
->now_addr
= DELTAT
->start
<< 1;
225 DELTAT
->memread
= 2; /* two dummy reads needed before accesing external memory via register $08*/
227 /* if yes, then let's check if ADPCM memory is mapped and big enough */
228 if(DELTAT
->memory
== 0)
230 logerror("YM Delta-T ADPCM rom not mapped\n");
231 DELTAT
->portstate
= 0x00;
236 if( DELTAT
->end
>= DELTAT
->memory_size
) /* Check End in Range */
238 /* logerror("YM Delta-T ADPCM end out of range: $%08x\n", DELTAT->end); */
239 DELTAT
->end
= DELTAT
->memory_size
- 1;
241 if( DELTAT
->start
>= DELTAT
->memory_size
) /* Check Start in Range */
243 /* logerror("YM Delta-T ADPCM start out of range: $%08x\n", DELTAT->start); */
244 DELTAT
->portstate
= 0x00;
249 else /* we access CPU memory (ADPCM data register $08) so we only reset now_addr here */
251 DELTAT
->now_addr
= 0;
254 if( DELTAT
->portstate
&0x01 )
256 DELTAT
->portstate
= 0x00;
258 /* clear PCM BUSY bit (in status register) */
262 if(DELTAT
->status_set_handler
)
263 if(DELTAT
->status_change_BRDY_bit
)
264 (DELTAT
->status_set_handler
)(DELTAT
->status_change_which_chip
, DELTAT
->status_change_BRDY_bit
);
267 case 0x01: /* L,R,-,-,SAMPLE,DA/AD,RAMTYPE,ROM */
268 /* handle emulation mode */
269 if(DELTAT
->emulation_mode
== YM_DELTAT_EMULATION_MODE_YM2610
)
271 v
|= 0x01; /* YM2610 always uses ROM as an external memory and doesn't tave ROM/RAM memory flag bit. */
274 DELTAT
->pan
= &DELTAT
->output_pointer
[(v
>>6)&0x03];
275 if ((DELTAT
->control2
& 3) != (v
& 3))
277 /*0-DRAM x1, 1-ROM, 2-DRAM x8, 3-ROM (3 is bad setting - not allowed by the manual) */
278 if (DELTAT
->DRAMportshift
!= dram_rightshift
[v
&3])
280 DELTAT
->DRAMportshift
= dram_rightshift
[v
&3];
282 /* final shift value depends on chip type and memory type selected:
283 8 for YM2610 (ROM only),
284 5 for ROM for Y8950 and YM2608,
285 5 for x8bit DRAMs for Y8950 and YM2608,
286 2 for x1bit DRAMs for Y8950 and YM2608.
289 /* refresh addresses */
290 DELTAT
->start
= (DELTAT
->reg
[0x3]*0x0100 | DELTAT
->reg
[0x2]) << (DELTAT
->portshift
- DELTAT
->DRAMportshift
);
291 DELTAT
->end
= (DELTAT
->reg
[0x5]*0x0100 | DELTAT
->reg
[0x4]) << (DELTAT
->portshift
- DELTAT
->DRAMportshift
);
292 DELTAT
->end
+= (1 << (DELTAT
->portshift
-DELTAT
->DRAMportshift
) ) - 1;
293 DELTAT
->limit
= (DELTAT
->reg
[0xd]*0x0100 | DELTAT
->reg
[0xc]) << (DELTAT
->portshift
- DELTAT
->DRAMportshift
);
296 DELTAT
->control2
= v
;
298 case 0x02: /* Start Address L */
299 case 0x03: /* Start Address H */
300 DELTAT
->start
= (DELTAT
->reg
[0x3]*0x0100 | DELTAT
->reg
[0x2]) << (DELTAT
->portshift
- DELTAT
->DRAMportshift
);
301 /*logerror("DELTAT start: 02=%2x 03=%2x addr=%8x\n",DELTAT->reg[0x2], DELTAT->reg[0x3],DELTAT->start );*/
303 case 0x04: /* Stop Address L */
304 case 0x05: /* Stop Address H */
305 DELTAT
->end
= (DELTAT
->reg
[0x5]*0x0100 | DELTAT
->reg
[0x4]) << (DELTAT
->portshift
- DELTAT
->DRAMportshift
);
306 DELTAT
->end
+= (1 << (DELTAT
->portshift
-DELTAT
->DRAMportshift
) ) - 1;
307 /*logerror("DELTAT end : 04=%2x 05=%2x addr=%8x\n",DELTAT->reg[0x4], DELTAT->reg[0x5],DELTAT->end );*/
309 case 0x06: /* Prescale L (ADPCM and Record frq) */
310 case 0x07: /* Prescale H */
312 case 0x08: /* ADPCM data */
316 value: START, REC, MEMDAT, REPEAT, SPOFF, x,x,RESET meaning:
317 C8 1 1 0 0 1 0 0 0 Analysis (recording) from AUDIO to CPU (to reg $08), sample rate in PRESCALER register
318 E8 1 1 1 0 1 0 0 0 Analysis (recording) from AUDIO to EXT.MEMORY, sample rate in PRESCALER register
319 80 1 0 0 0 0 0 0 0 Synthesis (playing) from CPU (from reg $08) to AUDIO,sample rate in DELTA-N register
320 a0 1 0 1 0 0 0 0 0 Synthesis (playing) from EXT.MEMORY to AUDIO, sample rate in DELTA-N register
322 60 0 1 1 0 0 0 0 0 External memory write via ADPCM data register $08
323 20 0 0 1 0 0 0 0 0 External memory read via ADPCM data register $08
327 /* external memory write */
328 if ( (DELTAT
->portstate
& 0xe0)==0x60 )
332 DELTAT
->now_addr
= DELTAT
->start
<< 1;
336 /*logerror("YM Delta-T memory write $%08x, v=$%02x\n", DELTAT->now_addr >> 1, v);*/
338 if ( DELTAT
->now_addr
!= (DELTAT
->end
<<1) )
340 DELTAT
->memory
[DELTAT
->now_addr
>>1] = v
;
341 DELTAT
->now_addr
+=2; /* two nibbles at a time */
343 /* reset BRDY bit in status register, which means we are processing the write */
344 if(DELTAT
->status_reset_handler
)
345 if(DELTAT
->status_change_BRDY_bit
)
346 (DELTAT
->status_reset_handler
)(DELTAT
->status_change_which_chip
, DELTAT
->status_change_BRDY_bit
);
348 /* setup a timer that will callback us in 10 master clock cycles for Y8950
349 * in the callback set the BRDY flag to 1 , which means we have written the data.
350 * For now, we don't really do this; we simply reset and set the flag in zero time, so that the IRQ will work.
352 /* set BRDY bit in status register */
353 if(DELTAT
->status_set_handler
)
354 if(DELTAT
->status_change_BRDY_bit
)
355 (DELTAT
->status_set_handler
)(DELTAT
->status_change_which_chip
, DELTAT
->status_change_BRDY_bit
);
360 /* set EOS bit in status register */
361 if(DELTAT
->status_set_handler
)
362 if(DELTAT
->status_change_EOS_bit
)
363 (DELTAT
->status_set_handler
)(DELTAT
->status_change_which_chip
, DELTAT
->status_change_EOS_bit
);
369 /* ADPCM synthesis from CPU */
370 if ( (DELTAT
->portstate
& 0xe0)==0x80 )
372 DELTAT
->CPU_data
= v
;
374 /* Reset BRDY bit in status register, which means we are full of data */
375 if(DELTAT
->status_reset_handler
)
376 if(DELTAT
->status_change_BRDY_bit
)
377 (DELTAT
->status_reset_handler
)(DELTAT
->status_change_which_chip
, DELTAT
->status_change_BRDY_bit
);
382 case 0x09: /* DELTA-N L (ADPCM Playback Prescaler) */
383 case 0x0a: /* DELTA-N H */
384 DELTAT
->delta
= (DELTAT
->reg
[0xa]*0x0100 | DELTAT
->reg
[0x9]);
385 DELTAT
->step
= (UINT32
)( (double)(DELTAT
->delta
/* *(1<<(YM_DELTAT_SHIFT-16)) */ ) * (DELTAT
->freqbase
) );
386 /*logerror("DELTAT deltan:09=%2x 0a=%2x\n",DELTAT->reg[0x9], DELTAT->reg[0xa]);*/
388 case 0x0b: /* Output level control (volume, linear) */
390 INT32 oldvol
= DELTAT
->volume
;
391 DELTAT
->volume
= (v
&0xff) * (DELTAT
->output_range
/256) / YM_DELTAT_DECODE_RANGE
;
392 /* v * ((1<<16)>>8) >> 15;
393 * thus: v * (1<<8) >> 15;
394 * thus: output_range must be (1 << (15+8)) at least
395 * v * ((1<<23)>>8) >> 15;
398 /*logerror("DELTAT vol = %2x\n",v&0xff);*/
401 DELTAT
->adpcml
= (int)((double)DELTAT
->adpcml
/ (double)oldvol
* (double)DELTAT
->volume
);
405 case 0x0c: /* Limit Address L */
406 case 0x0d: /* Limit Address H */
407 DELTAT
->limit
= (DELTAT
->reg
[0xd]*0x0100 | DELTAT
->reg
[0xc]) << (DELTAT
->portshift
- DELTAT
->DRAMportshift
);
408 /*logerror("DELTAT limit: 0c=%2x 0d=%2x addr=%8x\n",DELTAT->reg[0xc], DELTAT->reg[0xd],DELTAT->limit );*/
413 void YM_DELTAT_ADPCM_Reset(YM_DELTAT
*DELTAT
,int pan
,int emulation_mode
)
415 DELTAT
->now_addr
= 0;
416 DELTAT
->now_step
= 0;
420 DELTAT
->limit
= ~0; /* this way YM2610 and Y8950 (both of which don't have limit address reg) will still work */
422 DELTAT
->pan
= &DELTAT
->output_pointer
[pan
];
424 DELTAT
->prev_acc
= 0;
425 DELTAT
->adpcmd
= 127;
427 DELTAT
->emulation_mode
= (UINT8
)emulation_mode
;
428 DELTAT
->portstate
= (emulation_mode
== YM_DELTAT_EMULATION_MODE_YM2610
) ? 0x20 : 0;
429 DELTAT
->control2
= (emulation_mode
== YM_DELTAT_EMULATION_MODE_YM2610
) ? 0x01 : 0; /* default setting depends on the emulation mode. MSX demo called "facdemo_4" doesn't setup control2 register at all and still works */
430 DELTAT
->DRAMportshift
= dram_rightshift
[DELTAT
->control2
& 3];
432 /* The flag mask register disables the BRDY after the reset, however
433 ** as soon as the mask is enabled the flag needs to be set. */
435 /* set BRDY bit in status register */
436 if(DELTAT
->status_set_handler
)
437 if(DELTAT
->status_change_BRDY_bit
)
438 (DELTAT
->status_set_handler
)(DELTAT
->status_change_which_chip
, DELTAT
->status_change_BRDY_bit
);
442 void YM_DELTAT_postload(YM_DELTAT
*DELTAT
,UINT8
*regs
)
450 YM_DELTAT_ADPCM_Write(DELTAT
,r
,regs
[r
]);
451 DELTAT
->reg
[0] = regs
[0];
453 /* current rom data */
455 DELTAT
->now_data
= *(DELTAT
->memory
+ (DELTAT
->now_addr
>>1) );
458 void YM_DELTAT_savestate(const device_config
*device
,YM_DELTAT
*DELTAT
)
461 state_save_register_device_item(device
, 0, DELTAT
->portstate
);
462 state_save_register_device_item(device
, 0, DELTAT
->now_addr
);
463 state_save_register_device_item(device
, 0, DELTAT
->now_step
);
464 state_save_register_device_item(device
, 0, DELTAT
->acc
);
465 state_save_register_device_item(device
, 0, DELTAT
->prev_acc
);
466 state_save_register_device_item(device
, 0, DELTAT
->adpcmd
);
467 state_save_register_device_item(device
, 0, DELTAT
->adpcml
);
473 #define YM_DELTAT_Limit(val,max,min) \
475 if ( val > max ) val = max; \
476 else if ( val < min ) val = min; \
479 static INLINE
void YM_DELTAT_synthesis_from_external_memory(YM_DELTAT
*DELTAT
)
484 DELTAT
->now_step
+= DELTAT
->step
;
485 if ( DELTAT
->now_step
>= (1<<YM_DELTAT_SHIFT
) )
487 step
= DELTAT
->now_step
>> YM_DELTAT_SHIFT
;
488 DELTAT
->now_step
&= (1<<YM_DELTAT_SHIFT
)-1;
491 if ( DELTAT
->now_addr
== (DELTAT
->limit
<<1) )
492 DELTAT
->now_addr
= 0;
494 if ( DELTAT
->now_addr
== (DELTAT
->end
<<1) ) { /* 12-06-2001 JB: corrected comparison. Was > instead of == */
495 if( DELTAT
->portstate
&0x10 ){
497 DELTAT
->now_addr
= DELTAT
->start
<<1;
499 DELTAT
->adpcmd
= YM_DELTAT_DELTA_DEF
;
500 DELTAT
->prev_acc
= 0;
502 /* set EOS bit in status register */
503 if(DELTAT
->status_set_handler
)
504 if(DELTAT
->status_change_EOS_bit
)
505 (DELTAT
->status_set_handler
)(DELTAT
->status_change_which_chip
, DELTAT
->status_change_EOS_bit
);
507 /* clear PCM BUSY bit (reflected in status register) */
510 DELTAT
->portstate
= 0;
512 DELTAT
->prev_acc
= 0;
517 if( DELTAT
->now_addr
&1 ) data
= DELTAT
->now_data
& 0x0f;
520 DELTAT
->now_data
= *(DELTAT
->memory
+ (DELTAT
->now_addr
>>1));
521 data
= DELTAT
->now_data
>> 4;
526 /* YM2610 address register is 24 bits wide.*/
527 /* The "+1" is there because we use 1 bit more for nibble calculations.*/
529 /* Side effect: we should take the size of the mapped ROM into account */
530 DELTAT
->now_addr
&= ( (1<<(24+1))-1);
532 /* store accumulator value */
533 DELTAT
->prev_acc
= DELTAT
->acc
;
535 /* Forecast to next Forecast */
536 DELTAT
->acc
+= (ym_deltat_decode_tableB1
[data
] * DELTAT
->adpcmd
/ 8);
537 YM_DELTAT_Limit(DELTAT
->acc
,YM_DELTAT_DECODE_MAX
, YM_DELTAT_DECODE_MIN
);
539 /* delta to next delta */
540 DELTAT
->adpcmd
= (DELTAT
->adpcmd
* ym_deltat_decode_tableB2
[data
] ) / 64;
541 YM_DELTAT_Limit(DELTAT
->adpcmd
,YM_DELTAT_DELTA_MAX
, YM_DELTAT_DELTA_MIN
);
543 /* ElSemi: Fix interpolator. */
544 /*DELTAT->prev_acc = prev_acc + ((DELTAT->acc - prev_acc) / 2 );*/
550 /* ElSemi: Fix interpolator. */
551 DELTAT
->adpcml
= DELTAT
->prev_acc
* (int)((1<<YM_DELTAT_SHIFT
)-DELTAT
->now_step
);
552 DELTAT
->adpcml
+= (DELTAT
->acc
* (int)DELTAT
->now_step
);
553 DELTAT
->adpcml
= (DELTAT
->adpcml
>>YM_DELTAT_SHIFT
) * (int)DELTAT
->volume
;
555 /* output for work of output channels (outd[OPNxxxx])*/
556 *(DELTAT
->pan
) += DELTAT
->adpcml
;
561 static INLINE
void YM_DELTAT_synthesis_from_CPU_memory(YM_DELTAT
*DELTAT
)
566 DELTAT
->now_step
+= DELTAT
->step
;
567 if ( DELTAT
->now_step
>= (1<<YM_DELTAT_SHIFT
) )
569 step
= DELTAT
->now_step
>> YM_DELTAT_SHIFT
;
570 DELTAT
->now_step
&= (1<<YM_DELTAT_SHIFT
)-1;
573 if( DELTAT
->now_addr
&1 )
575 data
= DELTAT
->now_data
& 0x0f;
577 DELTAT
->now_data
= DELTAT
->CPU_data
;
579 /* after we used CPU_data, we set BRDY bit in status register,
580 * which means we are ready to accept another byte of data */
581 if(DELTAT
->status_set_handler
)
582 if(DELTAT
->status_change_BRDY_bit
)
583 (DELTAT
->status_set_handler
)(DELTAT
->status_change_which_chip
, DELTAT
->status_change_BRDY_bit
);
587 data
= DELTAT
->now_data
>> 4;
592 /* store accumulator value */
593 DELTAT
->prev_acc
= DELTAT
->acc
;
595 /* Forecast to next Forecast */
596 DELTAT
->acc
+= (ym_deltat_decode_tableB1
[data
] * DELTAT
->adpcmd
/ 8);
597 YM_DELTAT_Limit(DELTAT
->acc
,YM_DELTAT_DECODE_MAX
, YM_DELTAT_DECODE_MIN
);
599 /* delta to next delta */
600 DELTAT
->adpcmd
= (DELTAT
->adpcmd
* ym_deltat_decode_tableB2
[data
] ) / 64;
601 YM_DELTAT_Limit(DELTAT
->adpcmd
,YM_DELTAT_DELTA_MAX
, YM_DELTAT_DELTA_MIN
);
608 /* ElSemi: Fix interpolator. */
609 DELTAT
->adpcml
= DELTAT
->prev_acc
* (int)((1<<YM_DELTAT_SHIFT
)-DELTAT
->now_step
);
610 DELTAT
->adpcml
+= (DELTAT
->acc
* (int)DELTAT
->now_step
);
611 DELTAT
->adpcml
= (DELTAT
->adpcml
>>YM_DELTAT_SHIFT
) * (int)DELTAT
->volume
;
613 /* output for work of output channels (outd[OPNxxxx])*/
614 *(DELTAT
->pan
) += DELTAT
->adpcml
;
619 /* ADPCM B (Delta-T control type) */
620 void YM_DELTAT_ADPCM_CALC(YM_DELTAT
*DELTAT
)
625 value: START, REC, MEMDAT, REPEAT, SPOFF, x,x,RESET meaning:
626 80 1 0 0 0 0 0 0 0 Synthesis (playing) from CPU (from reg $08) to AUDIO,sample rate in DELTA-N register
627 a0 1 0 1 0 0 0 0 0 Synthesis (playing) from EXT.MEMORY to AUDIO, sample rate in DELTA-N register
628 C8 1 1 0 0 1 0 0 0 Analysis (recording) from AUDIO to CPU (to reg $08), sample rate in PRESCALER register
629 E8 1 1 1 0 1 0 0 0 Analysis (recording) from AUDIO to EXT.MEMORY, sample rate in PRESCALER register
631 60 0 1 1 0 0 0 0 0 External memory write via ADPCM data register $08
632 20 0 0 1 0 0 0 0 0 External memory read via ADPCM data register $08
636 if ( (DELTAT
->portstate
& 0xe0)==0xa0 )
638 YM_DELTAT_synthesis_from_external_memory(DELTAT
);
642 if ( (DELTAT
->portstate
& 0xe0)==0x80 )
644 /* ADPCM synthesis from CPU-managed memory (from reg $08) */
645 YM_DELTAT_synthesis_from_CPU_memory(DELTAT
); /* change output based on data in ADPCM data reg ($08) */
649 //todo: ADPCM analysis
650 // if ( (DELTAT->portstate & 0xe0)==0xc0 )
651 // if ( (DELTAT->portstate & 0xe0)==0xe0 )