
module DE1_TOP
	(
		////////////////////	Clock Input	 	////////////////////	 
		CLOCK_24,						//	24 MHz
		CLOCK_27,						//	27 MHz
		CLOCK_50,						//	50 MHz
		EXT_CLOCK,						//	External Clock
		////////////////////	Push Button		////////////////////
		KEY,							//	Pushbutton[3:0]
		////////////////////	DPDT Switch		////////////////////
		SW,								//	Toggle Switch[9:0]
		////////////////////	7-SEG Dispaly	////////////////////
		HEX0,							//	Seven Segment Digit 0
		HEX1,							//	Seven Segment Digit 1
		HEX2,							//	Seven Segment Digit 2
		HEX3,							//	Seven Segment Digit 3
		////////////////////////	LED		////////////////////////
		LEDG,							//	LED Green[7:0]
		LEDR,							//	LED Red[9:0]
		////////////////////////	UART	////////////////////////
		UART_TXD,						//	UART Transmitter
		UART_RXD,						//	UART Receiver
		/////////////////////	SDRAM Interface		////////////////
		DRAM_DQ,						//	SDRAM Data bus 16 Bits
		DRAM_ADDR,						//	SDRAM Address bus 12 Bits
		DRAM_LDQM,						//	SDRAM Low-byte Data Mask 
		DRAM_UDQM,						//	SDRAM High-byte Data Mask
		DRAM_WE_N,						//	SDRAM Write Enable
		DRAM_CAS_N,						//	SDRAM Column Address Strobe
		DRAM_RAS_N,						//	SDRAM Row Address Strobe
		DRAM_CS_N,						//	SDRAM Chip Select
		DRAM_BA_0,						//	SDRAM Bank Address 0
		DRAM_BA_1,						//	SDRAM Bank Address 0
		DRAM_CLK,						//	SDRAM Clock
		DRAM_CKE,						//	SDRAM Clock Enable
		////////////////////	Flash Interface		////////////////
		FL_DQ,							//	FLASH Data bus 8 Bits
		FL_ADDR,						//	FLASH Address bus 22 Bits
		FL_WE_N,						//	FLASH Write Enable
		FL_RST_N,						//	FLASH Reset
		FL_OE_N,						//	FLASH Output Enable
		FL_CE_N,						//	FLASH Chip Enable
		////////////////////	SRAM Interface		////////////////
		SRAM_DQ,						//	SRAM Data bus 16 Bits
		SRAM_ADDR,						//	SRAM Address bus 18 Bits
		SRAM_UB_N,						//	SRAM High-byte Data Mask 
		SRAM_LB_N,						//	SRAM Low-byte Data Mask 
		SRAM_WE_N,						//	SRAM Write Enable
		SRAM_CE_N,						//	SRAM Chip Enable
		SRAM_OE_N,						//	SRAM Output Enable
		////////////////////	SD_Card Interface	////////////////
		SD_DAT,							//	SD Card Data
		SD_DAT3,						//	SD Card Data 3
		SD_CMD,							//	SD Card Command Signal
		SD_CLK,							//	SD Card Clock
		////////////////////	USB JTAG link	////////////////////
		TDI,  							// CPLD -> FPGA (data in)
		TCK,  							// CPLD -> FPGA (clk)
		TCS,  							// CPLD -> FPGA (CS)
	    TDO,  							// FPGA -> CPLD (data out)
		////////////////////	I2C		////////////////////////////
		I2C_SDAT,						//	I2C Data
		I2C_SCLK,						//	I2C Clock
		////////////////////	PS2		////////////////////////////
		PS2_DAT,						//	PS2 Data
		PS2_CLK,						//	PS2 Clock
		////////////////////	VGA		////////////////////////////
		VGA_HS,							//	VGA H_SYNC
		VGA_VS,							//	VGA V_SYNC
		VGA_R,   						//	VGA Red[3:0]
		VGA_G,	 						//	VGA Green[3:0]
		VGA_B,  						//	VGA Blue[3:0]
		////////////////	Audio CODEC		////////////////////////
		AUD_ADCLRCK,					//	Audio CODEC ADC LR Clock
		AUD_ADCDAT,						//	Audio CODEC ADC Data
		AUD_DACLRCK,					//	Audio CODEC DAC LR Clock
		AUD_DACDAT,						//	Audio CODEC DAC Data
		AUD_BCLK,						//	Audio CODEC Bit-Stream Clock
		AUD_XCK,						//	Audio CODEC Chip Clock
		////////////////////	GPIO	////////////////////////////
		GPIO_0,							//	GPIO Connection 0
		GPIO_1							//	GPIO Connection 1
	);

////////////////////////	Clock Input	 	////////////////////////
input	[1:0]	CLOCK_24;				//	24 MHz
input	[1:0]	CLOCK_27;				//	27 MHz
input			CLOCK_50;				//	50 MHz
input			EXT_CLOCK;				//	External Clock
////////////////////////	Push Button		////////////////////////
input	[3:0]	KEY;					//	Pushbutton[3:0]
////////////////////////	DPDT Switch		////////////////////////
input	[9:0]	SW;						//	Toggle Switch[9:0]
////////////////////////	7-SEG Dispaly	////////////////////////
output	[6:0]	HEX0;					//	Seven Segment Digit 0
output	[6:0]	HEX1;					//	Seven Segment Digit 1
output	[6:0]	HEX2;					//	Seven Segment Digit 2
output	[6:0]	HEX3;					//	Seven Segment Digit 3
////////////////////////////	LED		////////////////////////////
output	[7:0]	LEDG;					//	LED Green[7:0]
output	[9:0]	LEDR;					//	LED Red[9:0]
////////////////////////////	UART	////////////////////////////
output			UART_TXD;				//	UART Transmitter
input			UART_RXD;				//	UART Receiver
///////////////////////		SDRAM Interface	////////////////////////
inout	[15:0]	DRAM_DQ;				//	SDRAM Data bus 16 Bits
output	[11:0]	DRAM_ADDR;				//	SDRAM Address bus 12 Bits
output			DRAM_LDQM;				//	SDRAM Low-byte Data Mask 
output			DRAM_UDQM;				//	SDRAM High-byte Data Mask
output			DRAM_WE_N;				//	SDRAM Write Enable
output			DRAM_CAS_N;				//	SDRAM Column Address Strobe
output			DRAM_RAS_N;				//	SDRAM Row Address Strobe
output			DRAM_CS_N;				//	SDRAM Chip Select
output			DRAM_BA_0;				//	SDRAM Bank Address 0
output			DRAM_BA_1;				//	SDRAM Bank Address 0
output			DRAM_CLK;				//	SDRAM Clock
output			DRAM_CKE;				//	SDRAM Clock Enable
////////////////////////	Flash Interface	////////////////////////
inout	[7:0]	FL_DQ;					//	FLASH Data bus 8 Bits
output	[21:0]	FL_ADDR;				//	FLASH Address bus 22 Bits
output			FL_WE_N;				//	FLASH Write Enable
output			FL_RST_N;				//	FLASH Reset
output			FL_OE_N;				//	FLASH Output Enable
output			FL_CE_N;				//	FLASH Chip Enable
////////////////////////	SRAM Interface	////////////////////////
inout	[15:0]	SRAM_DQ;				//	SRAM Data bus 16 Bits
output	[17:0]	SRAM_ADDR;				//	SRAM Address bus 18 Bits
output			SRAM_UB_N;				//	SRAM High-byte Data Mask 
output			SRAM_LB_N;				//	SRAM Low-byte Data Mask 
output			SRAM_WE_N;				//	SRAM Write Enable
output			SRAM_CE_N;				//	SRAM Chip Enable
output			SRAM_OE_N;				//	SRAM Output Enable
////////////////////	SD Card Interface	////////////////////////
inout			SD_DAT;					//	SD Card Data
inout			SD_DAT3;				//	SD Card Data 3
inout			SD_CMD;					//	SD Card Command Signal
output			SD_CLK;					//	SD Card Clock
////////////////////////	I2C		////////////////////////////////
inout			I2C_SDAT;				//	I2C Data
output			I2C_SCLK;				//	I2C Clock
////////////////////////	PS2		////////////////////////////////
input		 	PS2_DAT;				//	PS2 Data
input			PS2_CLK;				//	PS2 Clock
////////////////////	USB JTAG link	////////////////////////////
input  			TDI;					// CPLD -> FPGA (data in)
input  			TCK;					// CPLD -> FPGA (clk)
input  			TCS;					// CPLD -> FPGA (CS)
output 			TDO;					// FPGA -> CPLD (data out)
////////////////////////	VGA			////////////////////////////
output			VGA_HS;					//	VGA H_SYNC
output			VGA_VS;					//	VGA V_SYNC
output	[3:0]	VGA_R;   				//	VGA Red[3:0]
output	[3:0]	VGA_G;	 				//	VGA Green[3:0]
output	[3:0]	VGA_B;   				//	VGA Blue[3:0]
////////////////////	Audio CODEC		////////////////////////////
inout			AUD_ADCLRCK;			//	Audio CODEC ADC LR Clock
input			AUD_ADCDAT;				//	Audio CODEC ADC Data
inout			AUD_DACLRCK;			//	Audio CODEC DAC LR Clock
output			AUD_DACDAT;				//	Audio CODEC DAC Data
inout			AUD_BCLK;				//	Audio CODEC Bit-Stream Clock
output			AUD_XCK;				//	Audio CODEC Chip Clock
////////////////////////	GPIO	////////////////////////////////
inout	[35:0]	GPIO_0;					//	GPIO Connection 0
inout	[35:0]	GPIO_1;					//	GPIO Connection 1

assign	LEDR		=	{1'h0, Scan_DAV, MMC_data};

//	All inout port turn to tri-state
assign	DRAM_DQ		=	16'hzzzz;
assign	FL_DQ		=	8'hzz;
assign	SRAM_DQ		=	16'hzzzz;
assign	SD_DAT		=	1'bz;
assign	I2C_SDAT	=	1'bz;
assign	AUD_ADCLRCK	=	1'bz;
assign	AUD_DACLRCK	=	1'bz;
assign	AUD_BCLK	=	1'bz;
assign	GPIO_0		=	36'hzzzzzzzzz; //{28'hzzzzzzz, sample_high8};
assign	GPIO_1		=	{8'hzz, 

							ram_addr,  // 18 bits
							1'bz,		// first 10
							cen,
							cpu_oe,
							cpu_we_n,
							mmc_ram_we,
							MMC_is_idle,	
							SD_DAT,						
							SD_DAT3,					
							SD_CMD,						
							SD_CLK,	
						};

//	Audio
assign	AUD_ADCLRCK	=	AUD_DACLRCK;
assign	AUD_XCK		=	AUD_CTRL_CLK;


assign FL_WE_N = 1;
assign FL_RST_N = 1;

// end of generic setup

wire tape_in;
assign tape_in = 1'b1; //GPIO_0[0];
assign LEDG = {1'b0, A16ram, DL};

wire mclk28;
wire [7:0] mem_data;
wire [7:0] io_data;
wire [7:0] data_for_cpu;
wire m1_n;
wire [15:0] mSEG7_DIG;
wire reset_in;
wire mreq_n, iorq_n; 
wire cpu_wt;
wire [12:0] video_addr;
wire [3:0] high_cpu_addr;
wire ROM_address_space;

wire [15:0] cpu_addr;
wire [7:0] cpu_di;
wire [7:0] cpu_do;
wire cpu_rom_access;
wire cpu_ram_access;
wire video_has_bus;
wire io_access, cen;
wire [17:0] ram_addr;
wire	turbo;
assign	turbo = 0;
wire [5:0] DL;
wire vga_oe, cpu_oe; 
wire cpu_clock_en;
wire [7:0] romdata;
wire [7:0] disk_buff_do;
wire [7:0] low16k_data;
wire top_16k = cpu_addr[15] & cpu_addr[14];
wire low_8k_access = (cpu_addr[15:13] == 3'b0);
wire  A15VID ;
wire [4:0] scan_res; //from keyboard
reg  text_mode;
reg	 mmc_load_mode;

assign A15VID = DL[3]; 
assign ROM_address_space = ~(cpu_addr[15] | cpu_addr[14]);

assign cpu_oe = mreq_n | cpu_rd | ~rfsh_n | ~cen; // all low -> low
assign vga_oe = ~video_has_bus; 

`define HAS_CPU
`define HAS_SOUND

reg [3:0] clk_div = 0;
reg A14ram;
reg A15ram;
reg A16ram;


assign SRAM_UB_N = 1'b1;
assign SRAM_LB_N = 1'b0;

assign SRAM_OE_N =  vga_oe & cpu_oe ;
assign SRAM_CE_N = 0; //always on


  always @(*) begin
	 if(top_16k)	begin // top 1/4 0xCxxx
	 	 A14ram <= DL[0];
		 A15ram <= DL[1];
		 A16ram <= DL[2];
	 end else begin
	 	A14ram <= cpu_addr[14];
		A15ram <= cpu_addr[15];
		A16ram <= cpu_addr[14];
	 end
  end //always


  wire SPI_active;
  assign SRAM_DQ[7:0] = mmc_writes_to_SRAM ? MMC_data :
	 (((mreq_n | cpu_wt) == 0) && cen) ? cpu_do: 8'bz; //may be redundant

  assign SRAM_DQ[15:8] = 8'bz; 

   assign cen = turbo ? 1 : (clk_div[2:0] == 7) & cpu_clock_en;

	assign	CPU_reset_n = locked_sig && KEY[0];
	assign reset_in = ~CPU_reset_n;

	pll pll_50_to_28 (.inclk0(CLOCK_50),	.c0(mclk28),.locked(locked_sig));
	SEG7_LUT_4 			u0	(	HEX0,HEX1,HEX2,HEX3,mSEG7_DIG );

	assign io_data = cpu_addr[7:0] == 8'haa ? MMC_data : 
		cpu_addr[7:0] == 8'hab ? {7'h0, SPI_active} : 
		cpu_addr[7:0] == 8'h00 ? {1'b0, ASCII_Code} : 
		cs_8910 == 0 ?  do_8910 :
		{1'b1, tape_in, 1'b1, scan_res};
	
	reg [7:0] di_r1;
	assign data_for_cpu = (mreq_n == 0) ? mem_data : io_data; 


	reg force_flash_mode;
	wire use_flash_for_ROM = SW[0] || force_flash_mode;
	
	// SW 0 up means use Flash for ROM (from 1 MB up)
	assign mem_data = (cpu_addr[15] | cpu_addr[14]) ? SRAM_DQ[7:0] : 
	 	use_flash_for_ROM ?  FL_DQ : low16k_data;
	
	assign FL_CE_N = ~(use_flash_for_ROM && ROM_address_space);
	assign FL_OE_N = cpu_oe || ~use_flash_for_ROM;
	
	assign cpu_clock_en = SW[9];
	
    assign ram_addr =  mmc_writes_to_SRAM ? {1'b0, DMA_addr_high[5],  DMA_addr_high[6:0], MMC_addr} :
		video_has_bus ?  {2'b01,  A15VID, 2'b10, video_addr} : 
		{high_cpu_addr, cpu_addr[13:0]};
	
	assign SRAM_ADDR = ram_addr;

	always @(posedge mclk28) begin
	 	if(cen) begin
			if(mreq_n == 0)
	 			di_r1 <=   mem_data;
			if(iorq_n == 0)
				di_r1 <= io_data;
		end
	 end

  //  assign di = mreq_n ? io_data : mem_data ;
   // assign di = mem_data ;
	 assign cpu_di = turbo ? mem_data : di_r1 ;

	wire cpu_we_n;
	
	assign	cpu_we_n = 	mreq_n | cpu_wt | ~cen ; // all low -> low
	
	assign SRAM_WE_N = 	mmc_writes_to_SRAM ? ~mmc_ram_we : 
		cpu_we_n | ROM_address_space;
					

	always @(posedge mclk28) begin
		clk_div <= clk_div +1;
	end

// VIDEO section
	wire  bright;
	wire R,G,B;
	
	assign VGA_R = ~R ? 4'b0 : 
		bright ? 4'b1111 : 4'b1000;
	
	assign VGA_G = ~G ? 4'b0 : 
		bright ? 4'b1111 : 4'b1000;

	assign VGA_B = ~B ? 4'b0 : 
		bright ? 4'b1111 : 4'b1000;
	
	zx2_sram zx_video (
	    .clk28(mclk28), 
	    .reset(reset_in), 
	    .R(R), 
	    .G(G), 
	    .B(B), 
	    .bright(bright), 
	    .HSync(VGA_HS), 
	    .VSync(VGA_VS), 
	    .ioreq(iorq_n), 
	    .memreq(mreq_n), 
	    .refr(rfsh_n), 
	    .wr_n(cpu_wt), 
	    .rd_n(cpu_rd), 
	    .M1(m1_n), 
	    .ram_addr(video_addr), 
	    .ram_data(SRAM_DQ[7:0]), 
	    .cpu_data(cpu_do), 
	    .cpu_addr(cpu_addr), 
	    .A14_rom(A14_rom), 
	    .clk_div(clk_div),
	    .video_access(video_has_bus),
	    .interrupt(interrupt),
	    .turbo(turbo),
	    .DL(DL),
	    .speaker(speaker),
		.text_mode(text_mode)
	    );

	
	
	// flash contains rom data starting at 1 MB, 0x100000
	assign FL_ADDR = { 7'b0100000, A14_rom, cpu_addr[13:0]};
	
	

	wire wait_n;			
	assign wait_n = 1;
	wire int_n, nmi_n, busrq_n;
	assign int_n = ~interrupt;
	assign nmi_n = 1;
	assign busrq_n = 1;
	
	
`ifdef HAS_CPU

tv80s cpu (
    .m1_n(m1_n), 
    .mreq_n(mreq_n), 
    .iorq_n(iorq_n), 
    .rd_n(cpu_rd), 
    .wr_n(cpu_wt), 
    .rfsh_n(rfsh_n), 
    .halt_n(halt_n), 
    .busak_n(busak_n), 
    .A(cpu_addr), 
    .do(cpu_do), 
    .reset_n(CPU_reset_n), 
    .clk(mclk28), 
    .wait_n(wait_n), 
    .int_n(int_n), 
    .nmi_n(nmi_n), 
    .busrq_n(busrq_n), 
    .di(cpu_di), 
    .cen(cen)
    );

wire [6:0] ASCII_Code;

   kbd_intf kbd_intf (
    .mclk25(mclk28), 
    .reset_in(reset_in), 
    .PS2_Clk(PS2_CLK), 
    .PS2_Data(PS2_DAT), 
  //  .shift(shift), 
   .scan_addr(cpu_addr[15:8]),
   .scan_res(scan_res),
   .debug_res0(debug_res0),
   .ASCII_Code(ASCII_Code),
   .Scan_DAV(Scan_DAV)
   );

	assign mSEG7_DIG[6:0] = ASCII_Code;

  assign high_cpu_addr[3] = 0; 
  assign high_cpu_addr[2] = A16ram;
  assign high_cpu_addr[1] = ROM_address_space ? 0 : A15ram;
  assign high_cpu_addr[0] = ROM_address_space ? A14_rom : A14ram;
`endif

	
wire [7:0] MMC_data;
wire [7:0] disk_buff_di;
wire [8:0] MMC_addr;	
wire [8:0] disk_buff_addr;	
//assign SD_DAT3 = ~SPI_control;

wire disk_buff_space;
assign disk_buff_space = (cpu_addr[15:9] == 7'b0010000) && mmc_access_mode;

wire mmc_access_mode;
wire mmc_writes_to_SRAM;

assign mmc_access_mode = SW[1];
assign mmc_writes_to_SRAM = DMA_enable && ~MMC_is_idle && mmc_access_mode;

assign disk_buff_di = MMC_is_idle ? cpu_do : MMC_data;
assign disk_buff_addr = MMC_is_idle ? cpu_addr : MMC_addr;
assign membuff_ram_we = MMC_is_idle ? cpu_write_to_buff : mmc_ram_we;
assign cpu_write_to_buff = (((mreq_n | cpu_wt) == 0) && cen && disk_buff_space ); // mapped at 0x2000

assign low16k_data = disk_buff_space ? disk_buff_do : romdata;

reg [7:0] SPI_write_data;
reg  SPI_control;
reg  SPI_start;
reg  SPI_block;
reg  DMA_enable;

// the block address for the MMC controller
reg [7:0] block_addr_lo; // i/o at 0xf0
reg [7:0] block_addr_mid; // i/o at 0xf1
reg [7:0] block_addr_high; // i/o at 0xf2

reg [7:0] DMA_addr_lo; // i/o at 0xf3
reg [7:0] DMA_addr_high; // i/o at 0xf4

always @ (posedge mclk28)
	if(reset_in) begin
		SPI_control <= 0;
		SPI_start <= 0;
		block_addr_lo <= 0;
		block_addr_mid <= 0;
		block_addr_high <= 0;
		text_mode <= SW[1];		
		force_flash_mode <= 0;
		mmc_load_mode <= 1;
	end	
		
	else begin
		if(~m1_n && ~mreq_n && (cpu_addr == 16'h0052) && cen ) begin // fetch instruction "ret" from RAM
				mmc_load_mode <= 0;
		end		
		
		if(cen && ~mmc_load_mode)		//delay by one clock so that we fetch "ret" from special RAM
				force_flash_mode <= 1;		
				
	 if(~iorq_n) begin
		if((cpu_addr[7:0] == 8'haa) && ~cpu_wt)
			SPI_write_data <= cpu_do;
			
		if((cpu_addr[7:0] == 8'hab) && ~cpu_wt)	begin 
			SPI_start <= cpu_do[0];
			SPI_block <= cpu_do[1];
			DMA_enable <= cpu_do[3];
			text_mode <= cpu_do[7];
		end	
			
		if((cpu_addr[7:0] == 8'hac) && ~cpu_wt)
			SPI_control <= cpu_do[0];

		if((cpu_addr[7:0] == 8'hf0) && ~cpu_wt)	
			block_addr_lo <= cpu_do;

		if((cpu_addr[7:0] == 8'hf1) && ~cpu_wt)	
			block_addr_mid <= cpu_do;

		if((cpu_addr[7:0] == 8'hf2) && ~cpu_wt)	
			block_addr_high <= cpu_do;
			
		if((cpu_addr[7:0] == 8'hf3) && ~cpu_wt)	
			DMA_addr_lo <= cpu_do;
			
		if((cpu_addr[7:0] == 8'hf4) && ~cpu_wt)	
			DMA_addr_high <= cpu_do;

			
	  end		
	end 
	
	
`ifdef SIMPLE_SPI
spi_mmc spi_mmc (.clock(mclk28),.reset(reset_in),
	.SDO(SD_DAT),
	.SDI(SD_CMD),
	.SCL(SD_CLK),
	.write_data(SPI_write_data),
	.start(SPI_start),
	.block(SPI_block),
	.SPI_active(SPI_active),
	.read_data(MMC_data),
	.write_strobe(mmc_write_strobe), 
	.ram_addr(MMC_addr)
	);
	
`else
	
 spi_controller spi_controller1(
	.CS_N (SD_DAT3),          //: out std_logic;     -- MMC chip select
    .MOSI(SD_CMD),           //: out std_logic;     -- Data to card (master out slave in)
    .MISO(SD_DAT),           //: in  std_logic;     -- Data from card (master in slave out)
    .SCLK(SD_CLK),           //: out std_logic;     -- Card clock
    
    .ram_write_addr(MMC_addr), //: out unsigned(13 downto 0);
    .ram_di(MMC_data),         //: out unsigned(7 downto 0);
    .ram_we(mmc_ram_we),         //: out std_logic;
    
    .track(5'h0),          //: in  unsigned(5 downto 0);  -- 0 - 34
    .block_to_read({block_addr_high,block_addr_mid,block_addr_lo}),
    .block_read_cmd(SPI_start),		      
    
    .CLK_14M(mclk28),        //: in  std_logic;    -- System clock
    .reset(reset_in),          //: in  std_logic);
	.is_idle(MMC_is_idle)
	);

 assign SPI_active = ~MMC_is_idle;

`endif // SIMPLE_SPI	

 buff_ram	buff_ram (
	.address(disk_buff_addr),
	.clock(mclk28),
	.data(disk_buff_di),
	.wren(membuff_ram_we),
	.q(disk_buff_do)
 );

wire protected_low_4k = (cpu_addr[12:10] == 3'b0);

 mmc_ram  mmc_prog_ram (
	.address(cpu_addr[12:0]),
	.clock(mclk28),
	.data(cpu_do),
	.wren(~cpu_we_n && low_8k_access && ~protected_low_4k),
	.q(romdata));


VGA_Audio_PLL 		u3	(	.inclk0(CLOCK_27[0]),.c0(VGA_CTRL_CLK),.c1(AUD_CTRL_CLK)	);

`ifdef HAS_SOUND


wire [7:0] sample_high8;
wire [9:0] iLeft;
wire [9:0] iRight;

I2C_AV_Config 		u7	(	//	Host Side
							.iCLK(CLOCK_50),
							.iRST_N(KEY[0]),
							//	I2C Side
							.I2C_SCLK(I2C_SCLK),
							.I2C_SDAT(I2C_SDAT)	);

AUDIO_DAC 			u8	(	//	Audio Side
							.oAUD_BCK(AUD_BCLK),
							.oAUD_DATA(AUD_DACDAT),
							.oAUD_LRCK(AUD_DACLRCK),
							
							.iLeft(iLeft), // 10 bits each
							.iRight(iRight),
							
							//	Control Signals
							.iSrc_Select(SW[8]),
				            .iCLK_18_4(AUD_CTRL_CLK),
							.iRST_N(KEY[0]),
							.sample_high8(sample_high8)
							);

	wire clk_en_ay8910 = (clk_div == 0); // 28/16=1.75 MHz

	wire asel_ay8910 = cpu_addr[14];
	wire cs_8910 = ~(cen && ~iorq_n && ~cpu_addr[1]  && cpu_addr[15] && m1_n);	//A1=0, A14=A15=1
	wire [7:0] do_8910;
	wire [7:0] A_8910;
	wire [7:0] B_8910;
	wire [7:0] C_8910;
	wire [7:0] beeper = {speaker, 7'b0}; 

	ay8910 ay8910 (
    .rst_n(~reset_in), 
    .clk(mclk28), 
    .clk_en(clk_en_ay8910), 
    .asel(asel_ay8910), 
    .wr_n(cpu_wt), 
    .cs_n(cs_8910), 
    .di(cpu_do), 
    .do(do_8910), 
    .A(A_8910), 
    .B(B_8910), 
    .C(C_8910)
    );

	assign iLeft = beeper + A_8910 + {1'b0, B_8910[7:1]};
	assign iRight= beeper + C_8910 + {1'b0, B_8910[7:1]};


`endif



//rom16k rom48(.address(cpu_addr[13:0]), .clock(mclk28), .q(romdata));

/*
 rambuff1  rambuff1 (
	.address(MMC_addr),
//	.clken(1'b1),
	.clock(mclk28),
	.data(MMC_data),
	.wren(mmc_write_strobe),
	.q());
*/

endmodule