----------------------------------------------------------------------------------
-- Company: 		 NetBurner Inc.
-- Engineer: 
-- 
-- Create Date:    23:53:34 09/02/2008 
-- Design Name: 
-- Module Name:    NBPKBD - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

ENTITY NBPKBD IS

	 PORT ( DataBus		 			: INOUT  STD_LOGIC_VECTOR (7 DOWNTO 0);
           AddrBus 					: IN  	STD_LOGIC_VECTOR (2 DOWNTO 0);
			  ExternalEnable 			: OUT  STD_LOGIC_VECTOR (36 DOWNTO 1);
			  ExternalDataOut			: OUT  STD_LOGIC_VECTOR (36 DOWNTO 1);
			  ExternalDataIn			: IN		STD_LOGIC_VECTOR (36 DOWNTO 1);
           nCS2 						: IN  	STD_LOGIC;
           RnW 						: IN  	STD_LOGIC;
           UTX2 						: INOUT 	STD_LOGIC;
			  URX2 						: INOUT 	STD_LOGIC;
			  TIN1 						: INOUT  STD_LOGIC;  
			  TOUT3 						: INOUT	STD_LOGIC;  
			  CPU_CLK	 				: IN	   STD_LOGIC;  
           nRSTO 						: IN  	STD_LOGIC;
			  nRSTI 						: INOUT  STD_LOGIC;  
			  nIRQ3 						: INOUT 	STD_LOGIC );		 
	
END NBPKBD;

ARCHITECTURE Behavioral OF NBPKBD IS
	
	SIGNAL DataBus_Out			: STD_LOGIC_VECTOR (7 DOWNTO 0);
	SIGNAL EnableRegister		: STD_LOGIC_VECTOR (36 DOWNTO 1) := x"FFFFFFFFF";
	SIGNAL DriveRegister			: STD_LOGIC_VECTOR (36 DOWNTO 1) := x"000000000";		
	
	BEGIN

	nRSTI <= 'Z';
	nIRQ3 <= 'Z';
	TOUT3 <= 'Z';
	TIN1 <= 'Z';
	URX2 <= 'Z';
	UTX2 <= 'Z';
	
	ExternalEnable <= EnableRegister;
	ExternalDataOut <= DriveRegister;


-- ADDRESSES FOR BUS READS ARE AS FOLLOWS: 
-- 0x0 - ExternalDataIn pins 9 down to 2
-- 0x1 - ExternalDataIn pins 18 down to 11
-- 0x2 - ExternalDataIn pins 27 down to 20
-- 0x3 - ExternalDataIn pins 36 down to 29
-- All other addresses output 0xFF


	DataBus <= DataBus_Out when (RnW = '1' and nCS2 = '0'  ) 
		else (others => 'Z');

	with AddrBus select DataBus_Out <= 
		ExternalDataIn (9 DOWNTO 2)	 	when "000",
		ExternalDataIn (18 DOWNTO 11)	 	when "001",
		ExternalDataIn (27 DOWNTO 20)	 	when "010",
		ExternalDataIn (36 DOWNTO 29)	 	when "011",
		x"FF" 									when others;
		
	
	 	
-- ADDRESSES FOR BUS WRITES ARE AS FOLLOWS: 
-- 0x0 - ExternalDriveEnable pins 9 down to 2
-- 0x1 - ExternalDriveEnable pins 18 down to 11
-- 0x2 - ExternalDriveEnable pins 27 down to 20
-- 0x3 - ExternalDriveEnable pins 36 down to 29
-- 0x4 - ExternalDataOut pins 9 down to 2
-- 0x5 - ExternalDataOut pins 18 down to 11
-- 0x6 - ExternalDataOut pins 27 down to 20
-- 0x7 - ExternalDataOut pins 36 down to 29
-- All other addresses do nothing

BusWrite : PROCESS ( nCS2 )
	
	BEGIN
		
	IF ( RnW = '0' AND RISING_EDGE(nCS2) ) THEN
		CASE AddrBus IS
			WHEN "000" => EnableRegister (9 DOWNTO 2)   <=  not DataBus(7 DOWNTO 0);
			WHEN "001" => EnableRegister (18 DOWNTO 11) <=  not DataBus(7 DOWNTO 0);
			WHEN "010" => EnableRegister (27 DOWNTO 20) <=  not DataBus(7 DOWNTO 0);
			WHEN "011" => EnableRegister (36 DOWNTO 29) <=  not DataBus(7 DOWNTO 0);
			WHEN "100" => DriveRegister  (9 DOWNTO 2)   <=  DataBus(7 DOWNTO 0);
			WHEN "101" => DriveRegister  (18 DOWNTO 11) <=  DataBus(7 DOWNTO 0);
			WHEN "110" => DriveRegister  (27 DOWNTO 20) <=  DataBus(7 DOWNTO 0);
			WHEN "111" => DriveRegister  (36 DOWNTO 29) <=  DataBus(7 DOWNTO 0);
			WHEN others => null;
		END CASE;
	END IF;
	
END PROCESS BusWrite;
	
END Behavioral;