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