----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    15:22:46 12/30/2008 
-- Design Name: 
-- Module Name:    memory - 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 memory is
    Port (
      -- interface to Z80 bus
      DATA_I : in  STD_LOGIC_VECTOR (7 downto 0);
      DATA_O : out  STD_LOGIC_VECTOR (7 downto 0);
      ADDR_I : in  STD_LOGIC_VECTOR (15 downto 0);
      RD_N : in  STD_LOGIC;
      WR_N : in  STD_LOGIC;
      MREQ_N : in  STD_LOGIC;
      CLK : in STD_LOGIC;
      CLKEN : in STD_LOGIC;
      -- interface to video generator
      VID_DATA_O : out STD_LOGIC_VECTOR(7 downto 0);
      VID_ADDR_I : in STD_LOGIC_VECTOR(9 downto 0);
      VID_CLK : in STD_LOGIC);
end memory;

architecture Behavioral of memory is
component monitorrom IS
	port ( clka: IN std_logic;
               addra: IN std_logic_VECTOR(10 downto 0);
               douta: OUT std_logic_VECTOR(7 downto 0);
               ena: in std_logic);
END component;

component basic_rom
  port (
    clka  : IN  std_logic;
    addra : IN  std_logic_VECTOR(12 downto 0);
    douta : OUT std_logic_VECTOR(7 downto 0);
    ena   : in  std_logic);
end component;

component ram2kx8 IS
	port ( clka: IN std_logic;
               dina: IN std_logic_VECTOR(7 downto 0);
               addra: IN std_logic_VECTOR(10 downto 0);
               wea: IN std_logic_VECTOR(0 downto 0);
               douta: OUT std_logic_VECTOR(7 downto 0);
               ena: in std_logic;
               clkb: IN std_logic;
               dinb: IN std_logic_VECTOR(7 downto 0);
               addrb: IN std_logic_VECTOR(10 downto 0);
               web: IN std_logic_VECTOR(0 downto 0);
               doutb: OUT std_logic_VECTOR(7 downto 0));
END component;

signal monitorrom_data, basicrom_data, ram2kx8_1_dout, ram2kx8_2_dout, ram2kx8_1_doutb: std_logic_vector(7 downto 0);
signal ram2kx8_1_addrb : std_logic_vector(10 downto 0);
signal ram2kx8_1_we, ram2kx8_2_we: std_logic_vector(0 downto 0);
begin
monitorrom_inst: monitorrom port map(	clka => CLK,
                                        addra => ADDR_I(10 downto 0),
                                        douta => monitorrom_data,
                                        ena => CLKEN);

basicrom_inst : basic_rom port map (
  clka  => CLK,
  addra => ADDR_I(12 downto 0),
  douta => basicrom_data,
  ena   => CLKEN);

ram2kx8_1_we(0) <= '1' when (WR_N = '0') and (ADDR_I(15 downto 11) = "00001") and (MREQ_N = '0') else '0';
ram2kx8_2_we(0) <= '1' when (WR_N = '0') and (ADDR_I(15 downto 11) = "00010") and (MREQ_N = '0') else '0';
ram2kx8_1_addrb <= '0' & VID_ADDR_I;

ram2kx8_inst_1: ram2kx8 port map(	clka => CLK,
                                dina => DATA_I,
                                addra => ADDR_I(10 downto 0),
                                wea => ram2kx8_1_we,
                                douta => ram2kx8_1_dout,
                                ena => CLKEN,
                                clkb => VID_CLK,
                                dinb => "00000000",
                                addrb => ram2kx8_1_addrb,
                                web => "0",
                                doutb => ram2kx8_1_doutb);

ram2kx8_inst_2: ram2kx8 port map(	clka => CLK,
                                dina => DATA_I,
                                addra => ADDR_I(10 downto 0),
                                wea => ram2kx8_2_we,
                                douta => ram2kx8_2_dout,
                                ena => CLKEN,
                                clkb => VID_CLK,
                                dinb => "00000000",
                                addrb => "00000000000",
                                web => "0",
                                doutb => open);
									
DATA_O <= monitorrom_data when ADDR_I(15 downto 11) = "00000" else
          ram2kx8_1_dout when ADDR_I(15 downto 11) = "00001" else
          ram2kx8_2_dout when ADDR_I(15 downto 11) = "00010" else
          basicrom_data when ADDR_I(15 downto 13) = "111" else
          "XXXXXXXX";

VID_DATA_O <= ram2kx8_1_doutb;
end Behavioral;

