module MAINDEC
	(BCLK, RST_N, WRITE, READ, STATUS, SRAM_RDY, ADDR, BOOT_Q, SRAM_Q, UART_Q, BE, IO_DI,
	 UART_RD, UART_WR, CESRAM, NMI_N, DRD, READY, BRESET, ENDRAM, LEDR, LEDG, HEXL, HEXM, SSW );
	
	input 			BCLK;
	input			RST_N;
	input 			WRITE;
	input 			READ;
	input	 [3:0]	STATUS;
	input			SRAM_RDY;
	input	[31:2]	ADDR;
	input   [31:0]	BOOT_Q;
	input   [31:0]	SRAM_Q;
	input	 [3:0]	BE;
	input	[31:0]	IO_DI;
	
	output			UART_RD;
	output	 [1:0]	UART_WR;
	
	input   [31:0]	UART_Q;	
	output			CESRAM;
	
	output	reg		NMI_N;
	
	output  [31:0]	DRD;
	output	reg		READY;
	output	reg		BRESET;
	output	reg		ENDRAM;	
	
	input	 [9:0]	SSW;
	
	output	reg	 [6:0]	HEXL,HEXM;
	output	reg	 [9:0]	LEDR;
	output	reg	 [7:0]	LEDG;
	
	reg	    [31:0]	DRD;
	reg				rd_rdy;
	reg		 [3:0]	init_cou;
	reg		[25:0]	counter;
	reg		 [9:0]	ssw_reg;
	reg				nmie;

	wire			wr_leds,wr_coun;
	wire			access;
	
	assign access  = WRITE | READ;
	
	assign UART_WR = (WRITE & (ADDR[31:20] == 12'h202)) ? BE[1:0] : 2'd0;
	assign UART_RD = READ   & (ADDR[31:20] == 12'h202) & BE[0];	// Read Data Reg. -> Int to 0
	assign CESRAM  = access & (ADDR[31:20] == 12'h201);
	assign wr_coun = WRITE  & (ADDR[31:20] == 12'h205) & ADDR[2];
	
	assign wr_leds = WRITE  & (ADDR[31:20] == 12'h204);

	always @(posedge BCLK) if (wr_leds &&  ADDR[2] && BE[1]) HEXM <= IO_DI[14:8];
	always @(posedge BCLK) if (wr_leds &&  ADDR[2] && BE[0]) HEXL <= IO_DI[6:0];
	always @(posedge BCLK) if (wr_leds && !ADDR[2] && BE[2]) LEDG <= IO_DI[23:16];
	always @(posedge BCLK) if (wr_leds && !ADDR[2] && BE[1]) LEDR[9:8] <= IO_DI[9:8];
	always @(posedge BCLK) if (wr_leds && !ADDR[2] && BE[0]) LEDR[7:0] <= IO_DI[7:0];

	always @(posedge BCLK) ssw_reg <= SSW;
	
	always @(posedge BCLK) rd_rdy <= READ & ((ADDR[31:20] == 12'h200) | (ADDR[31:29] == 3'd0)) & ~rd_rdy;	
	
	always @(access or ADDR or WRITE or rd_rdy or SRAM_RDY)
	  casex({access,ADDR[31:20]})
		13'b1_000x_xxxx_xxxx : READY = rd_rdy;	// if DRAM not activ
		13'b1_0010_xxxx_0000 : READY = rd_rdy;	// Boot-ROM
		13'b1_0010_xxxx_0001 : READY = SRAM_RDY;
		default				 : READY = access;	// else only one clock !!!
	  endcase
	  
	always @(ADDR or BOOT_Q or SRAM_Q or UART_Q or ssw_reg or counter or nmie)
	  casex({ADDR[31:20]})
		12'h201 : DRD = SRAM_Q;	
		12'h202 : DRD = UART_Q;
		12'h203 : DRD = {22'd0,ssw_reg[9:0]};
		12'h205 : DRD = {(ADDR[2] ? nmie : 1'd0),5'd0,counter};
		default : DRD = BOOT_Q;	// Boot-ROM
	  endcase
	
	// Program access in higher ROM area switches DRAM on
	always @(posedge BCLK) ENDRAM <= (((ADDR[31:28] == 4'h2) & (STATUS == 4'h8) & READ) | ENDRAM) & BRESET;

	// ++++++++++++++++++++++++++ NMI Counter ++++++++++++++++++++++++++
	
	always @(posedge BCLK)
		if (!BRESET) counter <= 26'd0;
		  else counter <= (counter == 26'h2FA_F07F) ? 26'd0 : counter + 26'd1;	// 50.000.000 = 2FA_F080
		  
	always @(posedge BCLK) NMI_N <= ~((counter[25:4] == 22'h2FA_F07) & nmie);	// once per second

	always @(posedge BCLK or negedge BRESET)	// NMI Enable
		if (!BRESET) nmie <= 1'b0;
		  else if (wr_coun) nmie <= IO_DI[31];	// is SET able
		  
	// ++++++++++++++++++++++++++ RESET Signal ++++++++++++++++++++++++++
	
	always @(posedge BCLK or negedge RST_N)
		if (!RST_N) init_cou <= 4'h0;
		  else init_cou <= init_cou + 4'h1;
		  
	always @(posedge BCLK or negedge RST_N)
		if (!RST_N) BRESET <= 1'b0;
		  else
			if (init_cou == 4'hF) BRESET <= 1'b1;

endmodule