module DPCMChan (
	PHI1, ACLK1, nACLK2, 
	RES, DB, RnW, LOCK,
	W4010, W4011, W4012, W4013, W4015, n_R4015, 
	n_DMCAB, RUNDMC, DMCRDY, DMCINT,
	DMC_Addr, DMC_Out);

	input PHI1; 			// PHI1 is used together with the R/W core signal to determine the 6502 read cycle, because the RDY setting is ignored by the 6502 core during the write cycle (see datasheet)
	input ACLK1;
	input nACLK2;

	input RES;
	inout [7:0] DB;	
	input RnW;			// CPU data bus mode (1: Read, 0: Write)
	input LOCK;			// The LOCK signal is used to temporarily suspend the sound generators so that their values can be fixed in the debug registers  (2A03 only)

	input W4010;
	input W4011;
	input W4012;
	input W4013;
	input W4015;
	input n_R4015;

	output n_DMCAB;			// 0: Gain control of the address bus to read the DPCM sample
	output RUNDMC;			// 1: DMC is minding its own business and hijacks DMA control
	output DMCRDY;			// 1: DMC Ready. Used to control processor readiness (RDY)
	output DMCINT;			// 1: DMC interrupt is active

	output [15:0] DMC_Addr;		// Address for reading the DPCM sample
	output [6:0] DMC_Out;		// Output value for DAC

	// Internal wires

	wire ACLK2;				// Other ACLK
	wire LOOPMode;			// 1: DPCM looped playback
	wire n_IRQEN;			// 0: Enable interrupt from DPCM
	wire DSLOAD;			// Load value into Sample Counter
	wire DSSTEP;			// Perform Sample Counter decrement
	wire BLOAD;				// Load value into Sample Buffer
	wire BSTEP;				// Perform a Sample Buffer bit shift
	wire NSTEP;				// Perform Sample Bit Counter increment
	wire DSTEP;				// Increment/decrement the DPCM Output counter
	wire PCM;				// Load new sample value into Sample Buffer
	wire DOUT;				// DPCM Out counter has finished counting
	wire n_NOUT;			// 0: Sample Bit Counter has finished counting
	wire SOUT;				// Sample Counter has finished counting
	wire DFLOAD;			// Frequency LFSR finished counting and reloaded itself
	wire n_BOUT; 			// The next bit value pushed out of the Sample Buffer shift register (inverted value)
	wire [7:0] DPA; 		// Register $4012 value
	wire [7:0] DSC; 		// Register $4013 value
	wire [3:0] Fx;			// Decoder in
	wire [8:0] FR;			// Decoder out

	// Instantiate

	// Control

	assign ACLK2 = ~nACLK2;

	DPCM_ControlReg ctrl_reg (.ACLK1(ACLK1), .W4010(W4010), .DB(DB), .Fx(Fx), .n_IRQEN(n_IRQEN), .LOOPMode(LOOPMode) );

	DPCM_Control dpcm_ctrl (
		.nACLK2(nACLK2),
		.ACLK1(ACLK1),
		.ACLK2(ACLK2),
		.PHI1(PHI1),
		.RES(RES),
		.RnW(RnW),
		.LOCK(LOCK),
		.W4015(W4015),
		.n_R4015(n_R4015),
		.LOOPMode(LOOPMode),
		.n_IRQEN(n_IRQEN),
		.DOUT(DOUT),
		.n_NOUT(n_NOUT),
		.SOUT(SOUT),
		.DFLOAD(DFLOAD),
		.DB(DB),
		.n_DMCAB(n_DMCAB),
		.RUNDMC(RUNDMC),
		.DMCRDY(DMCRDY),
		.DMCINT(DMCINT),
		.DSLOAD(DSLOAD),
		.DSSTEP(DSSTEP),
		.BLOAD(BLOAD),
		.BSTEP(BSTEP),
		.NSTEP(NSTEP),
		.DSTEP(DSTEP),
		.PCM(PCM) );

	// Sampling

	DPCM_Decoder decoder (.Fx(Fx), .FR(FR) );

	DPCM_FreqLFSR lfsr (.nACLK2(nACLK2), .ACLK1(ACLK1), .ACLK2(ACLK2), .RES(RES), .FR(FR), .DFLOAD(DFLOAD) );

	DPCM_SampleCounterReg scnt_reg (.ACLK1(ACLK1), .W4013(W4013), .DB(DB), .DSC(DSC) );

	DPCM_SampleCounter scnt (.ACLK1(ACLK1), .RES(RES), .DSLOAD(DSLOAD), .DSSTEP(DSSTEP), .DSC(DSC), .SOUT(SOUT) );

	DPCM_SampleBitCounter sbcnt (.ACLK1(ACLK1), .RES(RES), .NSTEP(NSTEP), .n_NOUT(n_NOUT) );

	DPCM_SampleBuffer sbuf (.ACLK1(ACLK1), .RES(RES), .BLOAD(BLOAD), .BSTEP(BSTEP), .PCM(PCM), .DB(DB), .n_BOUT(n_BOUT) );

	// Addressing & Output

	DPCM_AddressReg addr_reg (.ACLK1(ACLK1), .W4012(W4012), .DB(DB), .DPA(DPA) );

	DPCM_AddressCounter addr_cnt (.ACLK1(ACLK1), .RES(RES), .DSLOAD(DSLOAD), .DSSTEP(DSSTEP), .DPA(DPA), .DMC_Addr(DMC_Addr) );

	DPCM_Output dpcm_out (.ACLK1(ACLK1), .RES(RES), .W4011(W4011), .CountDown(n_BOUT), .DSTEP(DSTEP), .DB(DB), .DMC_Out(DMC_Out), .DOUT(DOUT) );

endmodule // DPCMChan