----------------------------------------------------------------------------------
-- Company:
-- Engineer:       Gerald Ebert
--
-- Create Date:    20:06:31 05/02/2007
-- Design Name:
-- Module Name:    BOOTRAM68k - Behavioral
-- Project Name:   BOOTRAM68k
-- Target Devices: XC9536-xxPC44
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:       1.20
-- 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 BOOTRAM68Main IS
  PORT ( busdata6_7    : IN  STD_LOGIC_VECTOR (1 DOWNTO 0);
         busadr0_7     : IN  STD_LOGIC_VECTOR (7 DOWNTO 0);
         busadr15_19   : IN  STD_LOGIC_VECTOR (4 DOWNTO 0);
         busiorq0      : IN  STD_LOGIC;
         busmreq0      : IN  STD_LOGIC;
         buswr0        : IN  STD_LOGIC;
         busreset0     : IN  STD_LOGIC;
         busbanken     : IN  STD_LOGIC;          -- BANKEN from NDR/ECB-Bus

         banken_en0    : IN  STD_LOGIC;          -- Bootoption if jumper is set
         ramsel_switch : IN  STD_LOGIC_VECTOR (3 DOWNTO 0);
         ramsel_mode   : IN  STD_LOGIC;          -- Lower Memory if jumper is set

         banken_out    : OUT  STD_LOGIC;         -- Simulates open collector gate
         banken_led    : OUT  STD_LOGIC;         -- Drives Boot Indicator LED
         ram0_cs0      : OUT  STD_LOGIC;         -- Chip Select RAM0
         ram1_cs0      : OUT  STD_LOGIC;         -- Chip Select RAM1
         booteprom_cs0 : OUT  STD_LOGIC;         -- Chip Select BootEPROM
         gpeprom_cs0   : OUT  STD_LOGIC;         -- Chip Select GP-EPROM
			databus_en0   : OUT  STD_LOGIC);	       -- Enables '645 bus driver

END BOOTRAM68Main;

ARCHITECTURE Behavioral OF BOOTRAM68Main IS

  CONSTANT lowsignal   : STD_LOGIC := '0';
  CONSTANT adrbankboot : STD_LOGIC_VECTOR (7 DOWNTO 0) := "11001000"; -- Port $C8
  CONSTANT adrgpeprom  : STD_LOGIC_VECTOR (3 DOWNTO 0) := "1000";     -- Adr $8xxxxxxxx

  SIGNAL   bankreg : STD_LOGIC_VECTOR (1 DOWNTO 0) := "00";           -- Registerbits
  
  SIGNAL   regmatch, iocsen0 : STD_LOGIC;
  SIGNAL   komp_ram, komp_adrgp : STD_LOGIC;
  SIGNAL   ibanken_out : STD_LOGIC;
  SIGNAL   ichipselcode : STD_LOGIC_VECTOR (4 DOWNTO 0);
  SIGNAL   chipsel0 : STD_LOGIC_VECTOR (3 DOWNTO 0);

BEGIN
--===================================================================================
  -- Calc enable signal for registers
  regmatch <= '0' WHEN busadr0_7 = adrbankboot ELSE '1';
  iocsen0 <= buswr0 OR busiorq0 OR regmatch;
  
-- Handle BankBoot registers (d6/d7)
  bankregister : PROCESS ( busreset0, iocsen0, busdata6_7 )
  BEGIN
    IF ( busreset0 = '0' ) THEN
      bankreg <= "00";   -- Default states like original BANKBOOT
    ELSIF ( iocsen0 = '1' AND iocsen0'event ) THEN
      bankreg <= busdata6_7;  -- Enable GP-EPROM if '1'; Disable BootEPROM if '1'
    END IF;
  END PROCESS bankregister;

--===================================================================================
  -- Handle bankboot logic and transfer signals
  ibanken_out <= NOT(bankreg(1) OR banken_en0) WHEN busadr15_19(0) = '0'
                                               ELSE '0';           -- high active
  banken_led  <= NOT bankreg(1);                                   -- high active
  -- Simulate open collector gate to pull down BANKEN signal
  bankendrv : OBUFE PORT MAP ( i => lowsignal, o => banken_out, e => ibanken_out);

--===================================================================================
  -- Compare bankaddresses for work modes
  komp_ram   <= NOT ramsel_mode WHEN busadr15_19(4 DOWNTO 1) < ramsel_switch ELSE ramsel_mode;
  komp_adrgp <= bankreg(0) WHEN busadr15_19(4 DOWNTO 1) = adrgpeprom ELSE '0';
  
  -- Get memory selection
  ichipselcode <= busmreq0 & busbanken & komp_ram & busadr15_19(4) & komp_adrgp;
  WITH ichipselcode SELECT
    chipsel0 <= "1110" WHEN "01100",                         -- ram0_cs0
                "1101" WHEN "01110",                         -- ram1_cs0
                "1011" WHEN "01001"|"01011"|"01101"|"01111", -- gpep_cs0
                "0111" WHEN "00000"|"00001"|"00010"|"00011", -- bbep_cs0
                "0111" WHEN "00100"|"00101"|"00110"|"00111",
	             "1111" WHEN OTHERS;

  -- Transport signals
	 ram0_cs0      <= chipsel0(0);
	 ram1_cs0      <= chipsel0(1);
	 gpeprom_cs0   <= chipsel0(2);
	 booteprom_cs0 <= chipsel0(3) OR bankreg(1);
	 
	 databus_en0   <= '0' WHEN chipsel0(2 DOWNTO 0) /= "111" ELSE chipsel0(3) OR bankreg(1);
	 
END Behavioral;

