1 /*
2 **
3 ** File: ymdeltat.c
4 **
5 ** YAMAHA DELTA-T adpcm sound emulation subroutine
6 ** used by fmopl.c (Y8950) and fm.c (YM2608 and YM2610/B)
7 **
8 ** Base program is YM2610 emulator by Hiromitsu Shioya.
9 ** Written by Tatsuyuki Satoh
10 ** Improvements by Jarek Burczynski (bujar at mame dot net)
11 **
12 **
13 ** History:
14 **
15 ** 03-08-2003 Jarek Burczynski:
16 **  - fixed BRDY flag implementation.
17 **
18 ** 24-07-2003 Jarek Burczynski, Frits Hilderink:
19 **  - fixed delault value for control2 in YM_DELTAT_ADPCM_Reset
20 **
21 ** 22-07-2003 Jarek Burczynski, Frits Hilderink:
22 **  - fixed external memory support
23 **
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.
30 **
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
34 **
35 ** 05-04-2003 Jarek Burczynski:
36 **  - implemented partial support for external/processor memory on sample replay
37 **
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
41 **
42 ** 28-12-2001 Acho A. Tang
43 **  - added EOS status report on ADPCM playback.
44 **
45 ** 05-08-2001 Jarek Burczynski:
46 **  - now_step is initialized with 0 at the start of play.
47 **
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.
52 **
53 ** TO DO:
54 **		Check size of the address register on the other chips....
55 **
56 ** Version 0.72
57 **
58 ** sound chips that have this unit:
59 ** YM2608   OPNA
60 ** YM2610/B OPNB
61 ** Y8950    MSX AUDIO
62 **
63 */
64 
65 #include "driver.h"
66 #include "state.h"
67 #include "ymdeltat.h"
68 
69 #define YM_DELTAT_DELTA_MAX (24576)
70 #define YM_DELTAT_DELTA_MIN (127)
71 #define YM_DELTAT_DELTA_DEF (127)
72 
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)
76 
77 extern INT32 FM_IS_POSTLOADING; // dink was here! jul31, 2021
78 
79 /* Forecast to next Forecast (rate = *8) */
80 /* 1/8 , 3/8 , 5/8 , 7/8 , 9/8 , 11/8 , 13/8 , 15/8 */
81 const INT32 ym_deltat_decode_tableB1[16] = {
82   1,   3,   5,   7,   9,  11,  13,  15,
83   -1,  -3,  -5,  -7,  -9, -11, -13, -15,
84 };
85 /* delta to next delta (rate= *64) */
86 /* 0.9 , 0.9 , 0.9 , 0.9 , 1.2 , 1.6 , 2.0 , 2.4 */
87 const INT32 ym_deltat_decode_tableB2[16] = {
88   57,  57,  57,  57, 77, 102, 128, 153,
89   57,  57,  57,  57, 77, 102, 128, 153
90 };
91 
92 #if 0
93 void YM_DELTAT_BRDY_callback(YM_DELTAT *DELTAT)
94 {
95 	logerror("BRDY_callback reached (flag set) !\n");
96 
97 	/* set BRDY bit in status register */
98 	if(DELTAT->status_set_handler)
99 		if(DELTAT->status_change_BRDY_bit)
100 			(DELTAT->status_set_handler)(DELTAT->status_change_which_chip, DELTAT->status_change_BRDY_bit);
101 }
102 #endif
103 
YM_DELTAT_ADPCM_Read(YM_DELTAT * DELTAT)104 UINT8 YM_DELTAT_ADPCM_Read(YM_DELTAT *DELTAT)
105 {
106 	UINT8 v = 0;
107 
108 	/* external memory read */
109 	if ( (DELTAT->portstate & 0xe0)==0x20 )
110 	{
111 		/* two dummy reads */
112 		if (DELTAT->memread)
113 		{
114 			DELTAT->now_addr = DELTAT->start << 1;
115 			DELTAT->memread--;
116 			return 0;
117 		}
118 
119 
120 		if ( DELTAT->now_addr != (DELTAT->end<<1) )
121 		{
122 			v = DELTAT->memory[DELTAT->now_addr>>1];
123 
124 			/*logerror("YM Delta-T memory read  $%08x, v=$%02x\n", DELTAT->now_addr >> 1, v);*/
125 
126 			DELTAT->now_addr+=2; /* two nibbles at a time */
127 
128 			/* reset BRDY bit in status register, which means we are reading the memory now */
129 			if(DELTAT->status_reset_handler)
130 				if(DELTAT->status_change_BRDY_bit)
131 					(DELTAT->status_reset_handler)(DELTAT->status_change_which_chip, DELTAT->status_change_BRDY_bit);
132 
133 	/* setup a timer that will callback us in 10 master clock cycles for Y8950
134 	* in the callback set the BRDY flag to 1 , which means we have another data ready.
135 	* 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 	*/
137 			/* set BRDY bit in status register */
138 			if(DELTAT->status_set_handler)
139 				if(DELTAT->status_change_BRDY_bit)
140 					(DELTAT->status_set_handler)(DELTAT->status_change_which_chip, DELTAT->status_change_BRDY_bit);
141 		}
142 		else
143 		{
144 			/* set EOS bit in status register */
145 			if(DELTAT->status_set_handler)
146 				if(DELTAT->status_change_EOS_bit)
147 					(DELTAT->status_set_handler)(DELTAT->status_change_which_chip, DELTAT->status_change_EOS_bit);
148 		}
149 	}
150 
151 	return v;
152 }
153 
154 
155 /* 0-DRAM x1, 1-ROM, 2-DRAM x8, 3-ROM (3 is bad setting - not allowed by the manual) */
156 static UINT8 dram_rightshift[4]={3,0,0,0};
157 
158 /* DELTA-T ADPCM write register */
YM_DELTAT_ADPCM_Write(YM_DELTAT * DELTAT,int r,int v)159 void YM_DELTAT_ADPCM_Write(YM_DELTAT *DELTAT,int r,int v)
160 {
161 	if(r>=0x10) return;
162 	DELTAT->reg[r] = v; /* stock data */
163 
164 	switch( r )
165 	{
166 	case 0x00:
167 /*
168 START:
169 	Accessing *external* memory is started when START bit (D7) is set to "1", so
170 	you must set all conditions needed for recording/playback before starting.
171 	If you access *CPU-managed* memory, recording/playback starts after
172 	read/write of ADPCM data register $08.
173 
174 REC:
175 	0 = ADPCM synthesis (playback)
176 	1 = ADPCM analysis (record)
177 
178 MEMDATA:
179 	0 = processor (*CPU-managed*) memory (means: using register $08)
180 	1 = external memory (using start/end/limit registers to access memory: RAM or ROM)
181 
182 
183 SPOFF:
184 	controls output pin that should disable the speaker while ADPCM analysis
185 
186 RESET and REPEAT only work with external memory.
187 
188 
189 some examples:
190 value:   START, REC, MEMDAT, REPEAT, SPOFF, x,x,RESET   meaning:
191   C8     1      1    0       0       1      0 0 0       Analysis (recording) from AUDIO to CPU (to reg $08), sample rate in PRESCALER register
192   E8     1      1    1       0       1      0 0 0       Analysis (recording) from AUDIO to EXT.MEMORY,       sample rate in PRESCALER register
193   80     1      0    0       0       0      0 0 0       Synthesis (playing) from CPU (from reg $08) to AUDIO,sample rate in DELTA-N register
194   a0     1      0    1       0       0      0 0 0       Synthesis (playing) from EXT.MEMORY to AUDIO,        sample rate in DELTA-N register
195 
196   60     0      1    1       0       0      0 0 0       External memory write via ADPCM data register $08
197   20     0      0    1       0       0      0 0 0       External memory read via ADPCM data register $08
198 
199 */
200 		/* handle emulation mode */
201 		if(DELTAT->emulation_mode == YM_DELTAT_EMULATION_MODE_YM2610)
202 		{
203 			v |= 0x20;		/*	YM2610 always uses external memory and doesn't even have memory flag bit. */
204 		}
205 
206 		DELTAT->portstate = v & (0x80|0x40|0x20|0x10|0x01); /* start, rec, memory mode, repeat flag copy, reset(bit0) */
207 
208 		if( DELTAT->portstate&0x80 )/* START,REC,MEMDATA,REPEAT,SPOFF,--,--,RESET */
209 		{
210 			/* set PCM BUSY bit */
211 			DELTAT->PCM_BSY = 1;
212 
213 			/* start ADPCM */
214 			DELTAT->now_step = 0;
215 			DELTAT->acc      = 0;
216 			DELTAT->prev_acc = 0;
217 			DELTAT->adpcml   = 0;
218 			DELTAT->adpcmd   = YM_DELTAT_DELTA_DEF;
219 			DELTAT->now_data = 0;
220 
221 		}
222 
223 		if( DELTAT->portstate&0x20 ) /* do we access external memory? */
224 		{
225 			DELTAT->now_addr = DELTAT->start << 1;
226 			DELTAT->memread = 2;	/* two dummy reads needed before accesing external memory via register $08*/
227 
228 			/* if yes, then let's check if ADPCM memory is mapped and big enough */
229 			if(DELTAT->memory == 0)
230 			{
231 				logerror("YM Delta-T ADPCM rom not mapped\n");
232 				DELTAT->portstate = 0x00;
233 				DELTAT->PCM_BSY = 0;
234 			}
235 			else
236 			{
237 				if( DELTAT->end >= DELTAT->memory_size )	/* Check End in Range */
238 				{
239 					logerror("YM Delta-T ADPCM end out of range: $%08x\n", DELTAT->end);
240 					DELTAT->end = DELTAT->memory_size - 1;
241 				}
242 				if( DELTAT->start >= DELTAT->memory_size )	/* Check Start in Range */
243 				{
244 					logerror("YM Delta-T ADPCM start out of range: $%08x\n", DELTAT->start);
245 					DELTAT->portstate = 0x00;
246 					DELTAT->PCM_BSY = 0;
247 				}
248 			}
249 		}
250 		else	/* we access CPU memory (ADPCM data register $08) so we only reset now_addr here */
251 		{
252 			DELTAT->now_addr = 0;
253 		}
254 
255 		if( DELTAT->portstate&0x01 )
256 		{
257 			DELTAT->portstate = 0x00;
258 
259 			/* clear PCM BUSY bit (in status register) */
260 			DELTAT->PCM_BSY = 0;
261 
262 			/* set BRDY flag */
263 			if(DELTAT->status_set_handler && !FM_IS_POSTLOADING)
264 				if(DELTAT->status_change_BRDY_bit)
265 					(DELTAT->status_set_handler)(DELTAT->status_change_which_chip, DELTAT->status_change_BRDY_bit);
266 		}
267 		break;
268 	case 0x01:	/* L,R,-,-,SAMPLE,DA/AD,RAMTYPE,ROM */
269 		/* handle emulation mode */
270 		if(DELTAT->emulation_mode == YM_DELTAT_EMULATION_MODE_YM2610)
271 		{
272 			v |= 0x01;		/*	YM2610 always uses ROM as an external memory and doesn't tave ROM/RAM memory flag bit. */
273 		}
274 
275 		DELTAT->pan = &DELTAT->output_pointer[(v>>6)&0x03];
276 		if ((DELTAT->control2 & 3) != (v & 3))
277 		{
278 			/*0-DRAM x1, 1-ROM, 2-DRAM x8, 3-ROM (3 is bad setting - not allowed by the manual) */
279 			if (DELTAT->DRAMportshift != dram_rightshift[v&3])
280 			{
281 				DELTAT->DRAMportshift = dram_rightshift[v&3];
282 
283 				/* final shift value depends on chip type and memory type selected:
284 						8 for YM2610 (ROM only),
285 						5 for ROM for Y8950 and YM2608,
286 						5 for x8bit DRAMs for Y8950 and YM2608,
287 						2 for x1bit DRAMs for Y8950 and YM2608.
288 				*/
289 
290 				/* refresh addresses */
291 				DELTAT->start  = (DELTAT->reg[0x3]*0x0100 | DELTAT->reg[0x2]) << (DELTAT->portshift - DELTAT->DRAMportshift);
292 				DELTAT->end    = (DELTAT->reg[0x5]*0x0100 | DELTAT->reg[0x4]) << (DELTAT->portshift - DELTAT->DRAMportshift);
293 				DELTAT->end   += (1 << (DELTAT->portshift-DELTAT->DRAMportshift) ) - 1;
294 				DELTAT->limit  = (DELTAT->reg[0xd]*0x0100 | DELTAT->reg[0xc]) << (DELTAT->portshift - DELTAT->DRAMportshift);
295 			}
296 		}
297 		DELTAT->control2 = v;
298 		break;
299 	case 0x02:	/* Start Address L */
300 	case 0x03:	/* Start Address H */
301 		DELTAT->start  = (DELTAT->reg[0x3]*0x0100 | DELTAT->reg[0x2]) << (DELTAT->portshift - DELTAT->DRAMportshift);
302 		/*logerror("DELTAT start: 02=%2x 03=%2x addr=%8x\n",DELTAT->reg[0x2], DELTAT->reg[0x3],DELTAT->start );*/
303 		break;
304 	case 0x04:	/* Stop Address L */
305 	case 0x05:	/* Stop Address H */
306 		DELTAT->end    = (DELTAT->reg[0x5]*0x0100 | DELTAT->reg[0x4]) << (DELTAT->portshift - DELTAT->DRAMportshift);
307 		DELTAT->end   += (1 << (DELTAT->portshift-DELTAT->DRAMportshift) ) - 1;
308 		/*logerror("DELTAT end  : 04=%2x 05=%2x addr=%8x\n",DELTAT->reg[0x4], DELTAT->reg[0x5],DELTAT->end   );*/
309 		break;
310 	case 0x06:	/* Prescale L (ADPCM and Record frq) */
311 	case 0x07:	/* Prescale H */
312 		break;
313 	case 0x08:	/* ADPCM data */
314 
315 /*
316 some examples:
317 value:   START, REC, MEMDAT, REPEAT, SPOFF, x,x,RESET   meaning:
318   C8     1      1    0       0       1      0 0 0       Analysis (recording) from AUDIO to CPU (to reg $08), sample rate in PRESCALER register
319   E8     1      1    1       0       1      0 0 0       Analysis (recording) from AUDIO to EXT.MEMORY,       sample rate in PRESCALER register
320   80     1      0    0       0       0      0 0 0       Synthesis (playing) from CPU (from reg $08) to AUDIO,sample rate in DELTA-N register
321   a0     1      0    1       0       0      0 0 0       Synthesis (playing) from EXT.MEMORY to AUDIO,        sample rate in DELTA-N register
322 
323   60     0      1    1       0       0      0 0 0       External memory write via ADPCM data register $08
324   20     0      0    1       0       0      0 0 0       External memory read via ADPCM data register $08
325 
326 */
327 
328 		/* external memory write */
329 		if ( (DELTAT->portstate & 0xe0)==0x60 )
330 		{
331 			if (DELTAT->memread)
332 			{
333 				DELTAT->now_addr = DELTAT->start << 1;
334 				DELTAT->memread = 0;
335 			}
336 
337 			/*logerror("YM Delta-T memory write $%08x, v=$%02x\n", DELTAT->now_addr >> 1, v);*/
338 
339 			if ( DELTAT->now_addr != (DELTAT->end<<1) )
340 			{
341 				DELTAT->memory[DELTAT->now_addr>>1] = v;
342 			 	DELTAT->now_addr+=2; /* two nibbles at a time */
343 
344 				/* reset BRDY bit in status register, which means we are processing the write */
345 				if(DELTAT->status_reset_handler && !FM_IS_POSTLOADING)
346 					if(DELTAT->status_change_BRDY_bit)
347 						(DELTAT->status_reset_handler)(DELTAT->status_change_which_chip, DELTAT->status_change_BRDY_bit);
348 
349 	/* setup a timer that will callback us in 10 master clock cycles for Y8950
350 	* in the callback set the BRDY flag to 1 , which means we have written the data.
351 	* 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 	*/
353 				/* set BRDY bit in status register */
354 				if(DELTAT->status_set_handler && !FM_IS_POSTLOADING)
355 					if(DELTAT->status_change_BRDY_bit)
356 						(DELTAT->status_set_handler)(DELTAT->status_change_which_chip, DELTAT->status_change_BRDY_bit);
357 
358 			}
359 			else
360 			{
361 				/* set EOS bit in status register */
362 				if(DELTAT->status_set_handler && !FM_IS_POSTLOADING)
363 					if(DELTAT->status_change_EOS_bit)
364 						(DELTAT->status_set_handler)(DELTAT->status_change_which_chip, DELTAT->status_change_EOS_bit);
365 			}
366 
367 			return;
368 		}
369 
370 		/* ADPCM synthesis from CPU */
371 		if ( (DELTAT->portstate & 0xe0)==0x80 )
372 		{
373 			DELTAT->CPU_data = v;
374 
375 			/* Reset BRDY bit in status register, which means we are full of data */
376 			if(DELTAT->status_reset_handler && !FM_IS_POSTLOADING)
377 				if(DELTAT->status_change_BRDY_bit)
378 					(DELTAT->status_reset_handler)(DELTAT->status_change_which_chip, DELTAT->status_change_BRDY_bit);
379 			return;
380 		}
381 
382 	  break;
383 	case 0x09:	/* DELTA-N L (ADPCM Playback Prescaler) */
384 	case 0x0a:	/* DELTA-N H */
385 		DELTAT->delta  = (DELTAT->reg[0xa]*0x0100 | DELTAT->reg[0x9]);
386 		DELTAT->step     = (UINT32)( (double)(DELTAT->delta /* *(1<<(YM_DELTAT_SHIFT-16)) */ ) * (DELTAT->freqbase) );
387 		/*logerror("DELTAT deltan:09=%2x 0a=%2x\n",DELTAT->reg[0x9], DELTAT->reg[0xa]);*/
388 		break;
389 	case 0x0b:	/* Output level control (volume, linear) */
390 		{
391 			INT32 oldvol = DELTAT->volume;
392 			DELTAT->volume = (v&0xff) * (DELTAT->output_range/256) / YM_DELTAT_DECODE_RANGE;
393 /*								v	  *		((1<<16)>>8)		>>	15;
394 *						thus:	v	  *		(1<<8)				>>	15;
395 *						thus: output_range must be (1 << (15+8)) at least
396 *								v     *		((1<<23)>>8)		>>	15;
397 *								v	  *		(1<<15)				>>	15;
398 */
399 			/*logerror("DELTAT vol = %2x\n",v&0xff);*/
400 			if( oldvol != 0 )
401 			{
402 				DELTAT->adpcml = (int)((double)DELTAT->adpcml / (double)oldvol * (double)DELTAT->volume);
403 			}
404 		}
405 		break;
406 	case 0x0c:	/* Limit Address L */
407 	case 0x0d:	/* Limit Address H */
408 		DELTAT->limit  = (DELTAT->reg[0xd]*0x0100 | DELTAT->reg[0xc]) << (DELTAT->portshift - DELTAT->DRAMportshift);
409 		/*logerror("DELTAT limit: 0c=%2x 0d=%2x addr=%8x\n",DELTAT->reg[0xc], DELTAT->reg[0xd],DELTAT->limit );*/
410 		break;
411 	}
412 }
413 
YM_DELTAT_ADPCM_Reset(YM_DELTAT * DELTAT,int pan,int emulation_mode)414 void YM_DELTAT_ADPCM_Reset(YM_DELTAT *DELTAT,int pan,int emulation_mode)
415 {
416 	DELTAT->now_addr  = 0;
417 	DELTAT->now_step  = 0;
418 	DELTAT->step      = 0;
419 	DELTAT->start     = 0;
420 	DELTAT->end       = 0;
421 	DELTAT->limit     = ~0; /* this way YM2610 and Y8950 (both of which don't have limit address reg) will still work */
422 	DELTAT->volume    = 0;
423 	DELTAT->pan       = &DELTAT->output_pointer[pan];
424 	DELTAT->acc       = 0;
425 	DELTAT->prev_acc  = 0;
426 	DELTAT->adpcmd    = 127;
427 	DELTAT->adpcml    = 0;
428 	DELTAT->emulation_mode = (UINT8)emulation_mode;
429 	DELTAT->portstate = (emulation_mode == YM_DELTAT_EMULATION_MODE_YM2610) ? 0x20 : 0;
430 	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 */
431 	DELTAT->DRAMportshift = dram_rightshift[DELTAT->control2 & 3];
432 
433 	/* The flag mask register disables the BRDY after the reset, however
434 	** as soon as the mask is enabled the flag needs to be set. */
435 
436 	/* set BRDY bit in status register */
437 	if(DELTAT->status_set_handler)
438 		if(DELTAT->status_change_BRDY_bit)
439 			(DELTAT->status_set_handler)(DELTAT->status_change_which_chip, DELTAT->status_change_BRDY_bit);
440 }
441 
YM_DELTAT_postload(YM_DELTAT * DELTAT,UINT8 * regszz)442 void YM_DELTAT_postload(YM_DELTAT *DELTAT,UINT8 *regszz)
443 {
444 
445 #if 0
446 	//	postload not needed for this -dink july31, 2021
447 	int r;
448 
449 	/* to keep adpcml */
450 	DELTAT->volume = 0;
451 	/* update */
452 	for(r=1;r<16;r++)
453 		YM_DELTAT_ADPCM_Write(DELTAT,r,DELTAT->reg[r]);
454 	DELTAT->reg[0] = regs[0];
455 #endif
456 	/* current rom data */
457 	if (DELTAT->memory)
458 		DELTAT->now_data = *(DELTAT->memory + (DELTAT->now_addr>>1) );
459 }
460 
YM_DELTAT_savestate(const char * statename,int num,YM_DELTAT * DELTAT)461 void YM_DELTAT_savestate(const char *statename,int num,YM_DELTAT *DELTAT)
462 {
463 #ifdef _STATE_H
464 	// hooked up proper deltaT states -dink july31, 2021
465 	// hint: mechatt now works with run-ahead! :)
466 	state_save_register_UINT8 (statename, num, "DeltaT.now_data" , &DELTAT->now_data, 1);
467 	state_save_register_UINT8 (statename, num, "DeltaT.CPU_data" , &DELTAT->CPU_data, 1);
468 	state_save_register_UINT8 (statename, num, "DeltaT.portstate", &DELTAT->portstate, 1);
469 	state_save_register_UINT8 (statename, num, "DeltaT.control2" , &DELTAT->control2, 1);
470 	state_save_register_UINT8 (statename, num, "DeltaT.portshift", &DELTAT->portshift, 1);
471 	state_save_register_UINT8 (statename, num, "DeltaT.DRAMportshift", &DELTAT->DRAMportshift, 1);
472 	state_save_register_UINT8 (statename, num, "DeltaT.memread"  , &DELTAT->memread, 1);
473 	state_save_register_UINT8 (statename, num, "DeltaT.PCM_BSY"  , &DELTAT->PCM_BSY, 1);
474 	state_save_register_UINT8 (statename, num, "DeltaT.reg"      , &DELTAT->reg[0], 16);
475 
476 	state_save_register_UINT32(statename, num, "DeltaT.now_addr" , &DELTAT->now_addr , 1);
477 	state_save_register_UINT32(statename, num, "DeltaT.now_step" , &DELTAT->now_step , 1);
478 	state_save_register_UINT32(statename, num, "DeltaT.step"     , &DELTAT->step , 1);
479 	state_save_register_UINT32(statename, num, "DeltaT.start"    , &DELTAT->start , 1);
480 	state_save_register_UINT32(statename, num, "DeltaT.limit"    , &DELTAT->limit , 1);
481 	state_save_register_UINT32(statename, num, "DeltaT.end"      , &DELTAT->end , 1);
482 	state_save_register_UINT32(statename, num, "DeltaT.delta"    , &DELTAT->delta , 1);
483 
484 	state_save_register_INT32 (statename, num, "DeltaT.volume"   , &DELTAT->volume   , 1);
485 	state_save_register_INT32 (statename, num, "DeltaT.acc"      , &DELTAT->acc      , 1);
486 	state_save_register_INT32 (statename, num, "DeltaT.prev_acc" , &DELTAT->prev_acc , 1);
487 	state_save_register_INT32 (statename, num, "DeltaT.adpcmd"   , &DELTAT->adpcmd   , 1);
488 	state_save_register_INT32 (statename, num, "DeltaT.adpcml"   , &DELTAT->adpcml   , 1);
489 #endif
490 }
491 
492 
493 #define YM_DELTAT_Limit(val,max,min)	\
494 {										\
495 	if ( val > max ) val = max;			\
496 	else if ( val < min ) val = min;	\
497 }
498 
YM_DELTAT_synthesis_from_external_memory(YM_DELTAT * DELTAT)499 INLINE void YM_DELTAT_synthesis_from_external_memory(YM_DELTAT *DELTAT)
500 {
501 	UINT32 step;
502 	int data;
503 
504 	DELTAT->now_step += DELTAT->step;
505 	if ( DELTAT->now_step >= (1<<YM_DELTAT_SHIFT) )
506 	{
507 		step = DELTAT->now_step >> YM_DELTAT_SHIFT;
508 		DELTAT->now_step &= (1<<YM_DELTAT_SHIFT)-1;
509 		do{
510 
511 			if ( DELTAT->now_addr == (DELTAT->limit<<1) )
512 				DELTAT->now_addr = 0;
513 
514 			if ( DELTAT->now_addr >= (DELTAT->memory_size<<1) ) {
515 				/* 2-26-2016 DINK@FBAlpha: solution for crash in gwar when loading a savestate as player death sample is playing. */
516 				/* set EOS bit in status register */
517 				if(DELTAT->status_set_handler)
518 					if(DELTAT->status_change_EOS_bit)
519 						(DELTAT->status_set_handler)(DELTAT->status_change_which_chip, DELTAT->status_change_EOS_bit);
520 
521 				/* clear PCM BUSY bit (reflected in status register) */
522 				DELTAT->PCM_BSY = 0;
523 
524 				DELTAT->portstate = 0;
525 				DELTAT->adpcml = 0;
526 				DELTAT->prev_acc = 0;
527 				return;
528 			}
529 
530 			if ( DELTAT->now_addr == (DELTAT->end<<1) ) {	/* 12-06-2001 JB: corrected comparison. Was > instead of == */
531 				if( DELTAT->portstate&0x10 ){
532 					/* repeat start */
533 					DELTAT->now_addr = DELTAT->start<<1;
534 					DELTAT->acc      = 0;
535 					DELTAT->adpcmd   = YM_DELTAT_DELTA_DEF;
536 					DELTAT->prev_acc = 0;
537 				}else{
538 					/* set EOS bit in status register */
539 					if(DELTAT->status_set_handler)
540 						if(DELTAT->status_change_EOS_bit)
541 							(DELTAT->status_set_handler)(DELTAT->status_change_which_chip, DELTAT->status_change_EOS_bit);
542 
543 					/* clear PCM BUSY bit (reflected in status register) */
544 					DELTAT->PCM_BSY = 0;
545 
546 					DELTAT->portstate = 0;
547 					DELTAT->adpcml = 0;
548 					DELTAT->prev_acc = 0;
549 					return;
550 				}
551 			}
552 
553 			if( DELTAT->now_addr&1 ) data = DELTAT->now_data & 0x0f;
554 			else
555 			{
556 				DELTAT->now_data = *(DELTAT->memory + (DELTAT->now_addr>>1));
557 				data = DELTAT->now_data >> 4;
558 			}
559 
560 			DELTAT->now_addr++;
561 			/* 12-06-2001 JB: */
562 			/* YM2610 address register is 24 bits wide.*/
563 			/* The "+1" is there because we use 1 bit more for nibble calculations.*/
564 			/* WARNING: */
565 			/* Side effect: we should take the size of the mapped ROM into account */
566 			DELTAT->now_addr &= ( (1<<(24+1))-1);
567 
568 			/* store accumulator value */
569 			DELTAT->prev_acc = DELTAT->acc;
570 
571 			/* Forecast to next Forecast */
572 			DELTAT->acc += (ym_deltat_decode_tableB1[data] * DELTAT->adpcmd / 8);
573 			YM_DELTAT_Limit(DELTAT->acc,YM_DELTAT_DECODE_MAX, YM_DELTAT_DECODE_MIN);
574 
575 			/* delta to next delta */
576 			DELTAT->adpcmd = (DELTAT->adpcmd * ym_deltat_decode_tableB2[data] ) / 64;
577 			YM_DELTAT_Limit(DELTAT->adpcmd,YM_DELTAT_DELTA_MAX, YM_DELTAT_DELTA_MIN );
578 
579 			/* ElSemi: Fix interpolator. */
580 			/*DELTAT->prev_acc = prev_acc + ((DELTAT->acc - prev_acc) / 2 );*/
581 
582 		}while(--step);
583 
584 	}
585 
586 	/* ElSemi: Fix interpolator. */
587 	DELTAT->adpcml = DELTAT->prev_acc * (int)((1<<YM_DELTAT_SHIFT)-DELTAT->now_step);
588 	DELTAT->adpcml += (DELTAT->acc * (int)DELTAT->now_step);
589 	DELTAT->adpcml = (DELTAT->adpcml>>YM_DELTAT_SHIFT) * (int)DELTAT->volume;
590 
591 	/* output for work of output channels (outd[OPNxxxx])*/
592 	*(DELTAT->pan) += DELTAT->adpcml;
593 }
594 
595 
596 
YM_DELTAT_synthesis_from_CPU_memory(YM_DELTAT * DELTAT)597 INLINE void YM_DELTAT_synthesis_from_CPU_memory(YM_DELTAT *DELTAT)
598 {
599 	UINT32 step;
600 	int data;
601 
602 	DELTAT->now_step += DELTAT->step;
603 	if ( DELTAT->now_step >= (1<<YM_DELTAT_SHIFT) )
604 	{
605 		step = DELTAT->now_step >> YM_DELTAT_SHIFT;
606 		DELTAT->now_step &= (1<<YM_DELTAT_SHIFT)-1;
607 		do{
608 
609 			if( DELTAT->now_addr&1 )
610 			{
611 				data = DELTAT->now_data & 0x0f;
612 
613 				DELTAT->now_data = DELTAT->CPU_data;
614 
615 				/* after we used CPU_data, we set BRDY bit in status register,
616 				* which means we are ready to accept another byte of data */
617 				if(DELTAT->status_set_handler)
618 					if(DELTAT->status_change_BRDY_bit)
619 						(DELTAT->status_set_handler)(DELTAT->status_change_which_chip, DELTAT->status_change_BRDY_bit);
620 			}
621 			else
622 			{
623 				data = DELTAT->now_data >> 4;
624 			}
625 
626 			DELTAT->now_addr++;
627 
628 			/* store accumulator value */
629 			DELTAT->prev_acc = DELTAT->acc;
630 
631 			/* Forecast to next Forecast */
632 			DELTAT->acc += (ym_deltat_decode_tableB1[data] * DELTAT->adpcmd / 8);
633 			YM_DELTAT_Limit(DELTAT->acc,YM_DELTAT_DECODE_MAX, YM_DELTAT_DECODE_MIN);
634 
635 			/* delta to next delta */
636 			DELTAT->adpcmd = (DELTAT->adpcmd * ym_deltat_decode_tableB2[data] ) / 64;
637 			YM_DELTAT_Limit(DELTAT->adpcmd,YM_DELTAT_DELTA_MAX, YM_DELTAT_DELTA_MIN );
638 
639 
640 		}while(--step);
641 
642 	}
643 
644 	/* ElSemi: Fix interpolator. */
645 	DELTAT->adpcml = DELTAT->prev_acc * (int)((1<<YM_DELTAT_SHIFT)-DELTAT->now_step);
646 	DELTAT->adpcml += (DELTAT->acc * (int)DELTAT->now_step);
647 	DELTAT->adpcml = (DELTAT->adpcml>>YM_DELTAT_SHIFT) * (int)DELTAT->volume;
648 
649 	/* output for work of output channels (outd[OPNxxxx])*/
650 	*(DELTAT->pan) += DELTAT->adpcml;
651 }
652 
653 
654 
655 /* ADPCM B (Delta-T control type) */
YM_DELTAT_ADPCM_CALC(YM_DELTAT * DELTAT)656 void YM_DELTAT_ADPCM_CALC(YM_DELTAT *DELTAT)
657 {
658 
659 /*
660 some examples:
661 value:   START, REC, MEMDAT, REPEAT, SPOFF, x,x,RESET   meaning:
662   80     1      0    0       0       0      0 0 0       Synthesis (playing) from CPU (from reg $08) to AUDIO,sample rate in DELTA-N register
663   a0     1      0    1       0       0      0 0 0       Synthesis (playing) from EXT.MEMORY to AUDIO,        sample rate in DELTA-N register
664   C8     1      1    0       0       1      0 0 0       Analysis (recording) from AUDIO to CPU (to reg $08), sample rate in PRESCALER register
665   E8     1      1    1       0       1      0 0 0       Analysis (recording) from AUDIO to EXT.MEMORY,       sample rate in PRESCALER register
666 
667   60     0      1    1       0       0      0 0 0       External memory write via ADPCM data register $08
668   20     0      0    1       0       0      0 0 0       External memory read via ADPCM data register $08
669 
670 */
671 
672 	if ( (DELTAT->portstate & 0xe0)==0xa0 )
673 	{
674 		YM_DELTAT_synthesis_from_external_memory(DELTAT);
675 		return;
676 	}
677 
678 	if ( (DELTAT->portstate & 0xe0)==0x80 )
679 	{
680 		/* ADPCM synthesis from CPU-managed memory (from reg $08) */
681 		YM_DELTAT_synthesis_from_CPU_memory(DELTAT);	/* change output based on data in ADPCM data reg ($08) */
682 		return;
683 	}
684 
685 //todo: ADPCM analysis
686 //	if ( (DELTAT->portstate & 0xe0)==0xc0 )
687 //	if ( (DELTAT->portstate & 0xe0)==0xe0 )
688 
689 	return;
690 }
691 
692