1 // Ported from NSFPlay to VGMPlay (including C++ -> C conversion)
2 // by Valley Bell on 25 September 2013
3 // Updated to NSFPlay 2.3 on 26 September 2013
4 // (Note: Encoding is UTF-8)
5 
6 #include <stdlib.h>	// for rand
7 #include <stdlib.h>
8 #include <string.h>	// for memset
9 #include <stddef.h>	// for NULL
10 #include "mamedef.h"
11 #include "../stdbool.h"
12 #include "np_nes_apu.h"	// for NES_APU_np_FrameSequence
13 #include "np_nes_dmc.h"
14 
15 
16 // Master Clock: 21477272 (NTSC)
17 // APU Clock = Master Clock / 12
18 #define DEFAULT_CLOCK	1789772.0
19 #define DEFAULT_CLK_PAL	1662607
20 #define DEFAULT_RATE	44100
21 
22 
23 /** Bottom Half of APU **/
24 enum
25 {
26 	OPT_UNMUTE_ON_RESET=0,
27 	OPT_NONLINEAR_MIXER,
28 	OPT_ENABLE_4011,
29 	OPT_ENABLE_PNOISE,
30 	OPT_DPCM_ANTI_CLICK,
31 	OPT_RANDOMIZE_NOISE,
32 	OPT_TRI_MUTE,
33 	OPT_TRI_NULL,
34 	OPT_END
35 };
36 
37 
38 // Note: For increased speed, I'll inline all of NSFPlay's Counter member functions.
39 #define COUNTER_SHIFT	24
40 
41 typedef struct _Counter Counter;
42 struct _Counter
43 {
44 	double ratio;
45 	UINT32 val, step;
46 };
47 #define COUNTER_setcycle(cntr, s)	(cntr).step = (UINT32)((cntr).ratio / (s + 1))
48 #define COUNTER_iup(cntr)			(cntr).val += (cntr).step
49 #define COUNTER_value(cntr)			((cntr).val >> COUNTER_SHIFT)
50 #define COUNTER_init(cntr, clk, rate)							\
51 {																\
52 	(cntr).ratio = (1 << COUNTER_SHIFT) * (1.0 * clk / rate);	\
53 	(cntr).step = (UINT32)((cntr).ratio + 0.5);					\
54 	(cntr).val = 0;												\
55 }
56 
57 
58 typedef struct _NES_DMC NES_DMC;
59 struct _NES_DMC
60 {
61 	//const int GETA_BITS;
62 	//static const UINT32 freq_table[2][16];
63 	//static const UINT32 wavlen_table[2][16];
64 	UINT32 tnd_table[2][16][16][128];
65 
66 	int option[OPT_END];
67 	int mask;
68 	INT32 sm[2][3];
69 	UINT8 reg[0x10];
70 	UINT32 len_reg;
71 	UINT32 adr_reg;
72 	//IDevice *memory;
73 	const UINT8* memory;
74 	UINT32 out[3];
75 	UINT32 daddress;
76 	UINT32 length;
77 	UINT32 data;
78 	INT16 damp;
79 	int dac_lsb;
80 	bool dmc_pop;
81 	INT32 dmc_pop_offset;
82 	INT32 dmc_pop_follow;
83 	UINT32 clock;
84 	UINT32 rate;
85 	int pal;
86 	int mode;
87 	bool irq;
88 	bool active;
89 
90 	UINT32 counter[3];	// frequency dividers
91 	int tphase;			// triangle phase
92 	UINT32 nfreq;		// noise frequency
93 	UINT32 dfreq;		// DPCM frequency
94 
95 	UINT32 tri_freq;
96 	int linear_counter;
97 	int linear_counter_reload;
98 	bool linear_counter_halt;
99 	bool linear_counter_control;
100 
101 	int noise_volume;
102 	UINT32 noise, noise_tap;
103 
104 	// noise envelope
105 	bool envelope_loop;
106 	bool envelope_disable;
107 	bool envelope_write;
108 	int envelope_div_period;
109 	int envelope_div;
110 	int envelope_counter;
111 
112 	bool enable[3];
113 	int length_counter[2];	// 0=tri, 1=noise
114 
115 	// frame sequencer
116 	void* apu;	// apu is clocked by DMC's frame sequencer
117 	int frame_sequence_count;	// current cycle count
118 	int frame_sequence_length;	// CPU cycles per FrameSequence
119 	int frame_sequence_step;	// current step of frame sequence
120 	int frame_sequence_steps;	// 4/5 steps per frame
121 	bool frame_irq;
122 	bool frame_irq_enable;
123 
124 	Counter tick_count;
125 	UINT32 tick_last;
126 };
127 
128 INLINE UINT32 calc_tri(NES_DMC* dmc, UINT32 clocks);
129 INLINE UINT32 calc_dmc(NES_DMC* dmc, UINT32 clocks);
130 INLINE UINT32 calc_noise(NES_DMC* dmc, UINT32 clocks);
131 static void FrameSequence(NES_DMC* dmc, int s);
132 static void TickFrameSequence(NES_DMC* dmc, UINT32 clocks);
133 static void Tick(NES_DMC* dmc, UINT32 clocks);
134 
135 #define GETA_BITS	20
136 static const UINT32 wavlen_table[2][16] = {
137 {	// NTSC
138 	4, 8, 16, 32, 64, 96, 128, 160, 202, 254, 380, 508, 762, 1016, 2034, 4068
139 },
140 {	// PAL
141 	4, 8, 14, 30, 60, 88, 118, 148, 188, 236, 354, 472, 708,  944, 1890, 3778
142 }};
143 
144 static const UINT32 freq_table[2][16] = {
145 {	// NTSC
146 	428, 380, 340, 320, 286, 254, 226, 214, 190, 160, 142, 128, 106,  84,  72,  54
147 },
148 {	// PAL
149 	398, 354, 316, 298, 276, 236, 210, 198, 176, 148, 132, 118,  98,  78,  66,  50
150 }};
151 
NES_DMC_np_Create(int clock,int rate)152 void* NES_DMC_np_Create(int clock, int rate)
153 {
154 	NES_DMC* dmc;
155 	int c, t;
156 
157 	dmc = (NES_DMC*)malloc(sizeof(NES_DMC));
158 	if (dmc == NULL)
159 		return NULL;
160 	memset(dmc, 0x00, sizeof(NES_DMC));
161 
162 	//NES_DMC_np_SetClock(dmc, DEFAULT_CLOCK);
163 	//NES_DMC_np_SetRate(dmc, DEFAULT_RATE);
164 	//NES_DMC_np_SetPal(dmc, false);
165 	NES_DMC_np_SetClock(dmc, clock);	// does SetPal, too
166 	NES_DMC_np_SetRate(dmc, rate);
167 	dmc->option[OPT_ENABLE_4011] = 1;
168 	dmc->option[OPT_ENABLE_PNOISE] = 1;
169 	dmc->option[OPT_UNMUTE_ON_RESET] = 1;
170 	dmc->option[OPT_DPCM_ANTI_CLICK] = 0;
171 	dmc->option[OPT_NONLINEAR_MIXER] = 1;
172 	dmc->option[OPT_RANDOMIZE_NOISE] = 1;
173 	dmc->option[OPT_TRI_MUTE] = 1;
174 	dmc->tnd_table[0][0][0][0] = 0;
175 	dmc->tnd_table[1][0][0][0] = 0;
176 
177 	dmc->apu = NULL;
178 	dmc->frame_sequence_count = 0;
179 	dmc->frame_sequence_length = 7458;
180 	dmc->frame_sequence_steps = 4;
181 
182 	for(c=0;c<2;++c)
183 		for(t=0;t<3;++t)
184 			dmc->sm[c][t] = 128;
185 
186 	return dmc;
187 }
188 
189 
NES_DMC_np_Destroy(void * chip)190 void NES_DMC_np_Destroy(void* chip)
191 {
192 	free(chip);
193 }
194 
NES_DMC_np_GetDamp(void * chip)195 int NES_DMC_np_GetDamp(void* chip)
196 {
197 	NES_DMC* dmc = (NES_DMC*)chip;
198 
199 	return (dmc->damp<<1)|dmc->dac_lsb;
200 }
201 
NES_DMC_np_SetMask(void * chip,int m)202 void NES_DMC_np_SetMask(void* chip, int m)
203 {
204 	NES_DMC* dmc = (NES_DMC*)chip;
205 
206 	dmc->mask = m;
207 }
208 
NES_DMC_np_SetStereoMix(void * chip,int trk,INT16 mixl,INT16 mixr)209 void NES_DMC_np_SetStereoMix(void* chip, int trk, INT16 mixl, INT16 mixr)
210 {
211 	NES_DMC* dmc = (NES_DMC*)chip;
212 
213 	if (trk < 0) return;
214 	if (trk > 2) return;
215 	dmc->sm[0][trk] = mixl;
216 	dmc->sm[1][trk] = mixr;
217 }
218 
FrameSequence(NES_DMC * dmc,int s)219 static void FrameSequence(NES_DMC* dmc, int s)
220 {
221 	//DEBUG_OUT("FrameSequence: %d\n",s);
222 
223 	if (s > 3) return;	// no operation in step 4
224 
225 	if (dmc->apu != NULL)
226 	{
227 		NES_APU_np_FrameSequence(dmc->apu, s);
228 	}
229 
230 	if (s == 0 && (dmc->frame_sequence_steps == 4))
231 	{
232 		dmc->frame_irq = true;
233 	}
234 
235 	// 240hz clock
236 	{
237 		bool divider = false;
238 
239 		// triangle linear counter
240 		if (dmc->linear_counter_halt)
241 		{
242 			dmc->linear_counter = dmc->linear_counter_reload;
243 		}
244 		else
245 		{
246 			if (dmc->linear_counter > 0) --dmc->linear_counter;
247 		}
248 		if (!dmc->linear_counter_control)
249 		{
250 			dmc->linear_counter_halt = false;
251 		}
252 
253 		// noise envelope
254 		//bool divider = false;
255 		if (dmc->envelope_write)
256 		{
257 			dmc->envelope_write = false;
258 			dmc->envelope_counter = 15;
259 			dmc->envelope_div = 0;
260 		}
261 		else
262 		{
263 			++dmc->envelope_div;
264 			if (dmc->envelope_div > dmc->envelope_div_period)
265 			{
266 				divider = true;
267 				dmc->envelope_div = 0;
268 			}
269 		}
270 		if (divider)
271 		{
272 			if (dmc->envelope_loop && dmc->envelope_counter == 0)
273 				dmc->envelope_counter = 15;
274 			else if (dmc->envelope_counter > 0)
275 				--dmc->envelope_counter;	// TODO: Make this work.
276 		}
277 	}
278 
279 	// 120hz clock
280 	if ((s&1) == 0)
281 	{
282 		// triangle length counter
283 		if (!dmc->linear_counter_control && (dmc->length_counter[0] > 0))
284 			--dmc->length_counter[0];
285 
286 		// noise length counter
287 		if (!dmc->envelope_loop && (dmc->length_counter[1] > 0))
288 			--dmc->length_counter[1];
289 	}
290 
291 }
292 
293 // 三角波チャンネルの計算 戻り値は0-15
calc_tri(NES_DMC * dmc,UINT32 clocks)294 UINT32 calc_tri(NES_DMC* dmc, UINT32 clocks)
295 {
296 	static UINT32 tritbl[32] =
297 	{
298 	  0, 1, 2, 3, 4, 5, 6, 7,
299 	  8, 9,10,11,12,13,14,15,
300 	 15,14,13,12,11,10, 9, 8,
301 	  7, 6, 5, 4, 3, 2, 1, 0
302 	};
303 
304 	if (dmc->linear_counter > 0 && dmc->length_counter[0] > 0
305 		&& (!dmc->option[OPT_TRI_MUTE] || dmc->tri_freq > 0))
306 	{
307 		dmc->counter[0] += clocks;
308 		while (dmc->counter[0] > dmc->tri_freq)
309 		{
310 			dmc->tphase = (dmc->tphase + 1) & 31;
311 			dmc->counter[0] -= (dmc->tri_freq + 1);
312 		}
313 	}
314 	// Note: else-block added by VB
315 	else if (dmc->option[OPT_TRI_NULL])
316 	{
317 		if (dmc->tphase && dmc->tphase < 31)
318 		{
319 			// Finish the Triangle wave to prevent clicks.
320 			dmc->counter[0] += clocks;
321 			while(dmc->counter[0] > dmc->tri_freq && dmc->tphase)
322 			{
323 				dmc->tphase = (dmc->tphase + 1) & 31;
324 				dmc->counter[0] -= (dmc->tri_freq + 1);
325 			}
326 		}
327 	}
328 
329 	//UINT32 ret = tritbl[tphase];
330 	//return ret;
331 	return tritbl[dmc->tphase];
332 }
333 
334 // ノイズチャンネルの計算 戻り値は0-127
335 // 低サンプリングレートで合成するとエイリアスノイズが激しいので
336 // ノイズだけはこの関数内で高クロック合成し、簡易なサンプリングレート
337 // 変換を行っている。
calc_noise(NES_DMC * dmc,UINT32 clocks)338 UINT32 calc_noise(NES_DMC* dmc, UINT32 clocks)
339 {
340 	UINT32 env, last, count, accum, clocks_accum;
341 
342 	env = dmc->envelope_disable ? dmc->noise_volume : dmc->envelope_counter;
343 	if (dmc->length_counter[1] < 1) env = 0;
344 
345 	last = (dmc->noise & 0x4000) ? env : 0;
346 	if (clocks < 1) return last;
347 
348 	// simple anti-aliasing (noise requires it, even when oversampling is off)
349 	count = 0;
350 	accum = 0;
351 
352 	dmc->counter[1] += clocks;
353 //	assert(dmc->nfreq > 0);	// prevent infinite loop
354 	if (dmc->nfreq <= 0)	// prevent infinite loop -VB
355 		return last;
356 	while (dmc->counter[1] >= dmc->nfreq)
357 	{
358 		// tick the noise generator
359 		UINT32 feedback = (dmc->noise&1) ^ ((dmc->noise&dmc->noise_tap)?1:0);
360 		dmc->noise = (dmc->noise>>1) | (feedback<<14);
361 
362 		++count;
363 		accum += last;
364 		last = (dmc->noise & 0x4000) ? env : 0;
365 
366 		dmc->counter[1] -= dmc->nfreq;
367 	}
368 
369 	if (count < 1) // no change over interval, don't anti-alias
370 	{
371 		return last;
372 	}
373 
374 	clocks_accum = clocks - dmc->counter[1];
375 	// count = number of samples in accum
376 	// counter[1] = number of clocks since last sample
377 
378 	accum = (accum * clocks_accum) + (last * dmc->counter[1] * count);
379 	// note accum as an average is already premultiplied by count
380 
381 	return accum / (clocks * count);
382 }
383 
384 // DMCチャンネルの計算 戻り値は0-127
calc_dmc(NES_DMC * dmc,UINT32 clocks)385 UINT32 calc_dmc(NES_DMC* dmc, UINT32 clocks)
386 {
387 	dmc->counter[2] += clocks;
388 //	assert(dmc->dfreq > 0);	// prevent infinite loop
389 	if (dmc->dfreq <= 0)	// prevent infinite loop -VB
390 		return (dmc->damp<<1) + dmc->dac_lsb;
391 	while (dmc->counter[2] >= dmc->dfreq)
392 	{
393 		if ( dmc->data != 0x100 )	// data = 0x100 は EMPTY を意味する。
394 		{
395 			if ((dmc->data & 1) && (dmc->damp < 63))
396 				dmc->damp++;
397 			else if (!(dmc->data & 1) && (0 < dmc->damp))
398 				dmc->damp--;
399 			dmc->data >>=1;
400 		}
401 
402 		if ( dmc->data == 0x100 && dmc->active )
403 		{
404 			//dmc->memory->Read(dmc->daddress, dmc->data);
405 			dmc->data = dmc->memory[dmc->daddress];
406 			dmc->data |= (dmc->data&0xFF)|0x10000;	// 8bitシフトで 0x100 になる
407 			if ( dmc->length > 0 )
408 			{
409 				dmc->daddress = ((dmc->daddress+1)&0xFFFF)|0x8000 ;
410 				dmc->length --;
411 			}
412 		}
413 
414 		if ( dmc->length == 0 )	// 最後のフェッチが終了したら(再生完了より前に)即座に終端処理
415 		{
416 			if (dmc->mode & 1)
417 			{
418 				dmc->daddress = ((dmc->adr_reg<<6)|0xC000);
419 				dmc->length = (dmc->len_reg<<4)+1;
420 			}
421 			else
422 			{
423 				dmc->irq = (dmc->mode==2&&dmc->active)?1:0;	// 直前がactiveだったときはIRQ発行
424 				dmc->active = false;
425 			}
426 		}
427 
428 		dmc->counter[2] -= dmc->dfreq;
429 	}
430 
431 	return (dmc->damp<<1) + dmc->dac_lsb;
432 }
433 
TickFrameSequence(NES_DMC * dmc,UINT32 clocks)434 static void TickFrameSequence(NES_DMC* dmc, UINT32 clocks)
435 {
436 	dmc->frame_sequence_count += clocks;
437 	while (dmc->frame_sequence_count > dmc->frame_sequence_length)
438 	{
439 		FrameSequence(dmc, dmc->frame_sequence_step);
440 		dmc->frame_sequence_count -= dmc->frame_sequence_length;
441 		++dmc->frame_sequence_step;
442 		if(dmc->frame_sequence_step >= dmc->frame_sequence_steps)
443 			dmc->frame_sequence_step = 0;
444 	}
445 }
446 
Tick(NES_DMC * dmc,UINT32 clocks)447 static void Tick(NES_DMC* dmc, UINT32 clocks)
448 {
449 	dmc->out[0] = calc_tri(dmc, clocks);
450 	dmc->out[1] = calc_noise(dmc, clocks);
451 	dmc->out[2] = calc_dmc(dmc, clocks);
452 }
453 
NES_DMC_np_Render(void * chip,INT32 b[2])454 UINT32 NES_DMC_np_Render(void* chip, INT32 b[2])
455 {
456 	NES_DMC* dmc = (NES_DMC*)chip;
457 	UINT32 clocks;
458 	INT32 m[3];
459 
460 	COUNTER_iup(dmc->tick_count);	// increase counter (overflows after 255)
461 	clocks = (COUNTER_value(dmc->tick_count) - dmc->tick_last) & 0xFF;
462 	TickFrameSequence(dmc, clocks);
463 	Tick(dmc, clocks);
464 	dmc->tick_last = COUNTER_value(dmc->tick_count);
465 
466 	dmc->out[0] = (dmc->mask & 1) ? 0 : dmc->out[0];
467 	dmc->out[1] = (dmc->mask & 2) ? 0 : dmc->out[1];
468 	dmc->out[2] = (dmc->mask & 4) ? 0 : dmc->out[2];
469 
470 	m[0] = dmc->tnd_table[0][dmc->out[0]][0][0];
471 	m[1] = dmc->tnd_table[0][0][dmc->out[1]][0];
472 	m[2] = dmc->tnd_table[0][0][0][dmc->out[2]];
473 
474 	if (dmc->option[OPT_NONLINEAR_MIXER])
475 	{
476 		INT32 ref = m[0] + m[1] + m[2];
477 		INT32 voltage = dmc->tnd_table[1][dmc->out[0]][dmc->out[1]][dmc->out[2]];
478 		int i;
479 		if (ref)
480 		{
481 			for (i=0; i < 3; ++i)
482 				m[i] = (m[i] * voltage) / ref;
483 		}
484 		else
485 		{
486 			for (i=0; i < 3; ++i)
487 				m[i] = voltage;
488 		}
489 	}
490 
491 	// anti-click nullifies any 4011 write but preserves nonlinearity
492 	if (dmc->option[OPT_DPCM_ANTI_CLICK])
493 	{
494 		if (dmc->dmc_pop) // $4011 will cause pop this frame
495 		{
496 			// adjust offset to counteract pop
497 			dmc->dmc_pop_offset += dmc->dmc_pop_follow - m[2];
498 			dmc->dmc_pop = false;
499 
500 			// prevent overflow, keep headspace at edges
501 			//const INT32 OFFSET_MAX = (1 << 30) - (4 << 16);
502 #define OFFSET_MAX	((1 << 30) - (4 << 16))
503 			if (dmc->dmc_pop_offset >  OFFSET_MAX) dmc->dmc_pop_offset =  OFFSET_MAX;
504 			if (dmc->dmc_pop_offset < -OFFSET_MAX) dmc->dmc_pop_offset = -OFFSET_MAX;
505 		}
506 		dmc->dmc_pop_follow = m[2]; // remember previous position
507 
508 		m[2] += dmc->dmc_pop_offset; // apply offset
509 
510 		// TODO implement this in a better way
511 		// roll off offset (not ideal, but prevents overflow)
512 		if (dmc->dmc_pop_offset > 0) --dmc->dmc_pop_offset;
513 		else if (dmc->dmc_pop_offset < 0) ++dmc->dmc_pop_offset;
514 	}
515 
516 	b[0]  = m[0] * dmc->sm[0][0];
517 	b[0] += m[1] * dmc->sm[0][1];
518 	b[0] +=-m[2] * dmc->sm[0][2];
519 	b[0] >>= 7-2;
520 
521 	b[1]  = m[0] * dmc->sm[1][0];
522 	b[1] += m[1] * dmc->sm[1][1];
523 	b[1] +=-m[2] * dmc->sm[1][2];
524 	b[1] >>= 7-2;
525 
526 	return 2;
527 }
528 
529 
NES_DMC_np_SetClock(void * chip,double c)530 void NES_DMC_np_SetClock(void* chip, double c)
531 {
532 	NES_DMC* dmc = (NES_DMC*)chip;
533 
534 	dmc->clock = (UINT32)(c);
535 
536 	if (abs(dmc->clock - DEFAULT_CLK_PAL) <= 1000)	// check for approximately DEFAULT_CLK_PAL
537 		NES_DMC_np_SetPal(dmc, true);
538 	else
539 		NES_DMC_np_SetPal(dmc, false);
540 }
541 
NES_DMC_np_SetRate(void * chip,double r)542 void NES_DMC_np_SetRate(void* chip, double r)
543 {
544 	NES_DMC* dmc = (NES_DMC*)chip;
545 
546 	dmc->rate = (UINT32)(r?r:DEFAULT_RATE);
547 
548 	COUNTER_init(dmc->tick_count, dmc->clock, dmc->rate);
549 	dmc->tick_last = 0;
550 }
551 
NES_DMC_np_SetPal(void * chip,bool is_pal)552 void NES_DMC_np_SetPal(void* chip, bool is_pal)
553 {
554 	NES_DMC* dmc = (NES_DMC*)chip;
555 
556 	dmc->pal = (is_pal ? 1 : 0);
557 	// set CPU cycles in frame_sequence
558 	dmc->frame_sequence_length = is_pal ? 8314 : 7458;
559 }
560 
NES_DMC_np_SetAPU(void * chip,void * apu_)561 void NES_DMC_np_SetAPU(void* chip, void* apu_)
562 {
563 	NES_DMC* dmc = (NES_DMC*)chip;
564 
565 	dmc->apu = apu_;
566 }
567 
568 // Initializing TRI, NOISE, DPCM mixing table
InitializeTNDTable(NES_DMC * dmc,double wt,double wn,double wd)569 static void InitializeTNDTable(NES_DMC* dmc, double wt, double wn, double wd)
570 {
571 	// volume adjusted by 0.75 based on empirical measurements
572 	const double MASTER = 8192.0 * 0.75;
573 	// truthfully, the nonlinear curve does not appear to match well
574 	// with my tests, triangle in particular seems too quiet relatively.
575 	// do more testing of the APU/DMC DAC later
576 
577 	int t, n, d;
578 
579 	{	// Linear Mixer
580 		for(t=0; t<16 ; t++) {
581 			for(n=0; n<16; n++) {
582 				for(d=0; d<128; d++) {
583 						dmc->tnd_table[0][t][n][d] = (UINT32)(MASTER*(3.0*t+2.0*n+d)/208.0);
584 				}
585 			}
586 		}
587 	}
588 	{	// Non-Linear Mixer
589 		dmc->tnd_table[1][0][0][0] = 0;
590 		for(t=0; t<16 ; t++) {
591 			for(n=0; n<16; n++) {
592 				for(d=0; d<128; d++) {
593 					if(t!=0||n!=0||d!=0)
594 						dmc->tnd_table[1][t][n][d] = (UINT32)((MASTER*159.79)/(100.0+1.0/((double)t/wt+(double)n/wn+(double)d/wd)));
595 				}
596 			}
597 		}
598 	}
599 
600 }
601 
NES_DMC_np_Reset(void * chip)602 void NES_DMC_np_Reset(void* chip)
603 {
604 	NES_DMC* dmc = (NES_DMC*)chip;
605 	int i;
606 	dmc->mask = 0;
607 
608 	InitializeTNDTable(dmc,8227,12241,22638);
609 
610 	dmc->counter[0] = 0;
611 	dmc->counter[1] = 0;
612 	dmc->counter[2] = 0;
613 	dmc->tphase = 0;
614 	dmc->nfreq = wavlen_table[0][0];
615 	dmc->dfreq = freq_table[0][0];
616 
617 	dmc->envelope_div = 0;
618 	dmc->length_counter[0] = 0;
619 	dmc->length_counter[1] = 0;
620 	dmc->linear_counter = 0;
621 	dmc->envelope_counter = 0;
622 
623 	dmc->frame_irq = false;
624 	dmc->frame_irq_enable = false;
625 	dmc->frame_sequence_count = 0;
626 	dmc->frame_sequence_steps = 4;
627 	dmc->frame_sequence_step = 0;
628 
629 	for (i = 0; i < 0x10; i++)
630 		NES_DMC_np_Write(dmc, 0x4008 + i, 0);
631 
632 	dmc->irq = false;
633 	NES_DMC_np_Write(dmc, 0x4015, 0x00);
634 	if (dmc->option[OPT_UNMUTE_ON_RESET])
635 		NES_DMC_np_Write(dmc, 0x4015, 0x0f);
636 
637 	dmc->out[0] = dmc->out[1] = dmc->out[2] = 0;
638 	dmc->tri_freq = 0;
639 	dmc->damp = 0;
640 	dmc->dmc_pop = false;
641 	dmc->dmc_pop_offset = 0;
642 	dmc->dmc_pop_follow = 0;
643 	dmc->dac_lsb = 0;
644 	dmc->data = 0x100;
645 	dmc->adr_reg = 0;
646 	dmc->active = false;
647 	dmc->length = 0;
648 	dmc->len_reg = 0;
649 	dmc->daddress = 0;
650 	dmc->noise = 1;
651 	dmc->noise_tap = (1<<1);
652 	if (dmc->option[OPT_RANDOMIZE_NOISE])
653 	{
654 		dmc->noise |= rand();
655 	}
656 
657 	NES_DMC_np_SetRate(dmc, dmc->rate);
658 }
659 
NES_DMC_np_SetMemory(void * chip,const UINT8 * r)660 void NES_DMC_np_SetMemory(void* chip, const UINT8* r)
661 {
662 	NES_DMC* dmc = (NES_DMC*)chip;
663 
664 	dmc->memory = r;
665 }
666 
NES_DMC_np_SetOption(void * chip,int id,int val)667 void NES_DMC_np_SetOption(void* chip, int id, int val)
668 {
669 	NES_DMC* dmc = (NES_DMC*)chip;
670 
671 	if(id<OPT_END)
672 	{
673 		dmc->option[id] = val;
674 		if(id==OPT_NONLINEAR_MIXER)
675 			InitializeTNDTable(dmc, 8227,12241,22638);
676 	}
677 }
678 
NES_DMC_np_Write(void * chip,UINT32 adr,UINT32 val)679 bool NES_DMC_np_Write(void* chip, UINT32 adr, UINT32 val)
680 {
681 	static const UINT8 length_table[32] = {
682 		0x0A, 0xFE,
683 		0x14, 0x02,
684 		0x28, 0x04,
685 		0x50, 0x06,
686 		0xA0, 0x08,
687 		0x3C, 0x0A,
688 		0x0E, 0x0C,
689 		0x1A, 0x0E,
690 		0x0C, 0x10,
691 		0x18, 0x12,
692 		0x30, 0x14,
693 		0x60, 0x16,
694 		0xC0, 0x18,
695 		0x48, 0x1A,
696 		0x10, 0x1C,
697 		0x20, 0x1E
698 	};
699 	NES_DMC* dmc = (NES_DMC*)chip;
700 
701 	if (adr == 0x4015)
702 	{
703 		dmc->enable[0] = (val & 4) ? true : false;
704 		dmc->enable[1] = (val & 8) ? true : false;
705 
706 		if (!dmc->enable[0])
707 		{
708 			dmc->length_counter[0] = 0;
709 		}
710 		if (!dmc->enable[1])
711 		{
712 			dmc->length_counter[1] = 0;
713 		}
714 
715 		if ((val & 16)&&!dmc->active)
716 		{
717 			dmc->enable[2] = dmc->active = true;
718 			dmc->daddress = (0xC000 | (dmc->adr_reg << 6));
719 			dmc->length = (dmc->len_reg << 4) + 1;
720 			dmc->irq = 0;
721 		}
722 		else if (!(val & 16))
723 		{
724 			dmc->enable[2] = dmc->active = false;
725 		}
726 
727 		dmc->reg[adr-0x4008] = val;
728 		return true;
729 	}
730 
731 	if (adr == 0x4017)
732 	{
733 		//DEBUG_OUT("4017 = %02X\n", val);
734 		dmc->frame_irq_enable = ((val & 0x40) == 0x40);
735 		dmc->frame_irq = (dmc->frame_irq_enable ? dmc->frame_irq : 0);
736 		dmc->frame_sequence_count = 0;
737 		if (val & 0x80)
738 		{
739 			dmc->frame_sequence_steps = 5;
740 			dmc->frame_sequence_step = 0;
741 			FrameSequence(dmc, dmc->frame_sequence_step);
742 			++dmc->frame_sequence_step;
743 		}
744 		else
745 		{
746 			dmc->frame_sequence_steps = 4;
747 			dmc->frame_sequence_step = 1;
748 		}
749 	}
750 
751 	if (adr<0x4008||0x4013<adr)
752 		return false;
753 
754 	dmc->reg[adr-0x4008] = val&0xff;
755 
756 	//DEBUG_OUT("$%04X %02X\n", adr, val);
757 
758 	switch (adr)
759 	{
760 
761 	// tri
762 
763 	case 0x4008:
764 		dmc->linear_counter_control = (val >> 7) & 1;
765 		dmc->linear_counter_reload = val & 0x7F;
766 		break;
767 
768 	case 0x4009:
769 		break;
770 
771 	case 0x400a:
772 		dmc->tri_freq = val | (dmc->tri_freq & 0x700) ;
773 		if (dmc->counter[0] > dmc->tri_freq) dmc->counter[0] = dmc->tri_freq;
774 		break;
775 
776 	case 0x400b:
777 		dmc->tri_freq = (dmc->tri_freq & 0xff) | ((val & 0x7) << 8) ;
778 		if (dmc->counter[0] > dmc->tri_freq) dmc->counter[0] = dmc->tri_freq;
779 		dmc->linear_counter_halt = true;
780 		if (dmc->enable[0])
781 		{
782 			dmc->length_counter[0] = length_table[(val >> 3) & 0x1f];
783 		}
784 		break;
785 
786 	// noise
787 
788 	case 0x400c:
789 		dmc->noise_volume = val & 15;
790 		dmc->envelope_div_period = val & 15;
791 		dmc->envelope_disable = (val >> 4) & 1;
792 		dmc->envelope_loop = (val >> 5) & 1;
793 		break;
794 
795 	case 0x400d:
796 		break;
797 
798 	case 0x400e:
799 		if (dmc->option[OPT_ENABLE_PNOISE])
800 			dmc->noise_tap = (val & 0x80) ? (1<<6) : (1<<1);
801 		else
802 			dmc->noise_tap = (1<<1);
803 		dmc->nfreq = wavlen_table[dmc->pal][val&15];
804 		if (dmc->counter[1] > dmc->nfreq) dmc->counter[1] = dmc->nfreq;
805 		break;
806 
807 	case 0x400f:
808 		if (dmc->enable[1])
809 		{
810 			dmc->length_counter[1] = length_table[(val >> 3) & 0x1f];
811 		}
812 		dmc->envelope_write = true;
813 		break;
814 
815 	// dmc
816 
817 	case 0x4010:
818 		dmc->mode = (val >> 6) & 3;
819 		dmc->dfreq = freq_table[dmc->pal][val&15];
820 		if (dmc->counter[2] > dmc->dfreq) dmc->counter[2] = dmc->dfreq;
821 		break;
822 
823 	case 0x4011:
824 		if (dmc->option[OPT_ENABLE_4011])
825 		{
826 			dmc->damp = (val >> 1) & 0x3f;
827 			dmc->dac_lsb = val & 1;
828 			dmc->dmc_pop = true;
829 		}
830 		break;
831 
832 	case 0x4012:
833 		dmc->adr_reg = val&0xff;
834 		// ここでdaddressは更新されない
835 		break;
836 
837 	case 0x4013:
838 		dmc->len_reg = val&0xff;
839 		// ここでlengthは更新されない
840 		break;
841 
842 	default:
843 		return false;
844 	}
845 
846 	return true;
847 }
848 
NES_DMC_np_Read(void * chip,UINT32 adr,UINT32 * val)849 bool NES_DMC_np_Read(void* chip, UINT32 adr, UINT32* val)
850 {
851 	NES_DMC* dmc = (NES_DMC*)chip;
852 
853 	if (adr == 0x4015)
854 	{
855 		*val |= (dmc->irq?128:0)
856 			 | (dmc->frame_irq ? 0x40 : 0)
857 			 | (dmc->active?16:0)
858 			 | (dmc->length_counter[1]?8:0)
859 			 | (dmc->length_counter[0]?4:0)
860 			 ;
861 
862 		dmc->frame_irq = false;
863 		return true;
864 	}
865 	else if (0x4008<=adr&&adr<=0x4014)
866 	{
867 		*val |= dmc->reg[adr-0x4008];
868 		return true;
869 	}
870 	else
871 		return false;
872 }
873