--------------------------------------------------------------------------------
-- Company:        Jablotron s.r.o.
-- Engineer:       Hynek Sladky
--
-- Create Date:    10:29:19 02/04/07
-- Design Name:    expcard - Sharp MZ800 expansion card v1
-- Module Name:    expcard - top level
-- Project Name:   
-- Target Device:  Spartan3 - XC3S50TQ144-5
-- Tool versions:  
-- Description:
--
-- Dependencies:
-- 
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
-- 
--------------------------------------------------------------------------------
-- ToDo:
-- - memory card module ROM/RAM
--   cteni A8/F8: reset adresy
--   cteni A9/F9: cteni dat a postinkrementace
--   zapis A9/F9: zapis dat a postinkrementace; u ROM musi byt na prvni adrese 0xA5!
-- - memory card module RAM
--   cteni E8: reset adresy
--   zapis E9: zapis cisla stranky (asi je minena stranka 64KB?)
--   cteni EA: cteni dat + postinkrementace
--   zapis EA: zapis dat + postinkrementace
--   zapis EB: zapis adresy: low byte na D0-D7, high byte na A8-A15
-- - asi by bylo dobre spojit obe RAM dohromady???
-- - kazdopadne by asi bylo spravne mit dva citace?
--   ale pro zjednoduseni na zacatek bude jen jeden! Tj. spojene ROM/RAM/RAM do jednoho...
-- - stavajici ROM pack je na adrese A8/F8 (reset), A9/F9 (cteni ROM0), AA (cteni ROM1), AB (cteni ROM2), AC (cteni ROM3)
--   -> nemuzu tedy provozovat ROMpack i expcard!!!
-- - SD/MMC modul
--   - implementovat obsluhu signalu SDPWR a SDCS
--   - cteni stavu INS a LOCK, na stejnem portu muze byt i DIPSW...
--   - jeden port pro cteni/zapis 8bit dat (MSB first)
-- - pokud je zobrazena obrazovka standardniho monitoru (modra s cernym okrajem), tak po nahrati 'jen' do RAM se obraz neobjevi...
--   mrs nastartuje v rezimu cerne obrazovky a zeleneho okraje: ani zde se nerozbehne konfigurace do RAM...
--   jakmile se expcard zasekne, nenasel jsem zpusob, jak to rozbehnout (krome Power cycling...)
--   aha, ted se mi povedlo spustit naslepo AREM a znovu inicializovat RAM - uz to zas funguje
--   takze seznam funkcnich aplikaci:
--   - AREM (cela modra obrazovka)
--   - Tetris
--   seznam nefunkcnich aplikaci:
--   - MRS (zeleny okraj, cerne pozadi)
--   - TurboCopy (zeleny okraj, cerne pozadi)
--   - loader (cele cerne)
--   - Flappy (cele cerne)
--   - G nejde ani spustit! aha, protoze uz pristupuje na jiny port...
--     jednoduse to asi nepujde, nejlepsi by bylo pak napsat jiny bootovaci program...
--   po ruznych ladicich pokusech jsem zjistil, ze se nerozbehne DCM - vubec nenastartuje!!!
-- - ted dam zpet ROM/RAM podle typu
-- - po resetu se zavede jen obsah RAM disku (F8)
--   pokud je pozadovano zavedeni z ROM disku (A8) tak je nutne mit prazdnou RAM a zapsat prikaz EB
--   tj. jedina moznost je mit ROM disk jako RAM disk, jinak se automaticky nezavede!
-- - zrusit RAM block (pouzity pro simulaci RAM/ROM disku s inicializovanym obsahem)
--------------------------------------------------------------------------------
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 expcard is
  Port (
    -- Z80 bus
    PHI: in std_logic;
    -- VGA port
    Rout: out std_logic;
    Gout: out std_logic;
    Bout: out std_logic;
    Yout: out std_logic;
    HSout: out std_logic;
    VSout: out std_logic;
    -- CGA port
    Rin: in std_logic;
    Gin: in std_logic;
    Bin: in std_logic;
    Yin: in std_logic;
    HSin: in std_logic;
    VSin: in std_logic
  );
end expcard;

architecture Behavioral of expcard is
  -- deklarace prevodniku CGA2VGA
  component CGA2VGA
    port (
      CLOCK: in std_logic;
      Rin: in std_logic;
      Gin: in std_logic;
      Bin: in std_logic;
      Yin: in std_logic;
      HSin: in std_logic;
      VSin: in std_logic;
      Rout: out std_logic;
      Gout: out std_logic;
      Bout: out std_logic;
      Yout: out std_logic;
      HSout: out std_logic;
      VSout: out std_logic
    );
  end component;
  -- deklarace DCM modulu
  component DCM generic (
    CLK_FEEDBACK : string := "1X";
    CLKDV_DIVIDE : real:= 2.0; -- (1.5, 2.0, 2.5, 3.0, 4.0, 5.0, 8.0, 16.0)
    CLKFX_DIVIDE : integer := 1; -- (1 to 4096)
    CLKFX_MULTIPLY : integer := 2; -- (1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 5.0, 5.5,
      -- 6.0, 6.5, 7.0, 7.5, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0)
    CLKIN_DIVIDE_BY_2 : boolean := FALSE; -- (TRUE, FALSE)
    CLKOUT_PHASE_SHIFT : string := "NONE";
    DESKEW_ADJUST : string := "SYSTEM_SYNCHRONOUS";
    DFS_FREQUENCY_MODE : string := "LOW";
    DLL_FREQUENCY_MODE : string := "LOW";
    DSS_MODE : string := "NONE";
    DUTY_CYCLE_CORRECTION : Boolean := FALSE; -- (TRUE, FALSE)
    PHASE_SHIFT : real := 0.0;
    STARTUP_WAIT : boolean := FALSE; -- (TRUE, FALSE)
    CLKIN_PERIOD : real := 281.9 -- ns
  );
  port (
    CLK0 : out STD_ULOGIC;
    CLK180 : out STD_ULOGIC;
    CLK270 : out STD_ULOGIC;
    CLK2X : out STD_ULOGIC;
    CLK2X180 : out STD_ULOGIC;
    CLK90 : out STD_ULOGIC;
    CLKDV : out STD_ULOGIC;
    CLKFX : out STD_ULOGIC;
    CLKFX180 : out STD_ULOGIC;
    LOCKED : out STD_ULOGIC;
    PSDONE : out STD_ULOGIC;
    STATUS : out STD_LOGIC_VECTOR (7 downto 0);
    CLKFB : in STD_ULOGIC;
    CLKIN : in STD_ULOGIC;
    DSSEN : in STD_ULOGIC;
    PSCLK : in STD_ULOGIC;
    PSEN : in STD_ULOGIC;
    PSINCDEC : in STD_ULOGIC;
    RST : in STD_ULOGIC
  );
  end component;
  -- vnitrni signaly
  signal CLKFB2: std_logic;
  signal OSCF2: std_logic;
  -- signaly pro obsluhu sbernice
  --alias addr: std_logic_vector (7 downto 0) is A(7 downto 0);
  signal SDctrl: std_logic_vector (7 downto 0);
  signal SDstat: std_logic_vector (7 downto 0);
  -- signaly kvuli zpetne vazbe
  signal m_rd: std_logic;
  signal m_wr: std_logic;
  signal ma: std_logic_vector (18 downto 0);
  signal ROMen: std_logic;
  signal RAMen: std_logic;
  -- pamet pro nRD a nWR pri vzestupne hrane nIORQ
  signal Drd: std_logic;
  signal Dwr: std_logic;
  -- vestavena pamet pro loader
  signal ROMbus: std_logic_vector (7 downto 0);
begin
  -- pripojeni nasobice frekvence pro CGA modul
  -- DCM pracuje jen v rezimu DFS, kdy CLK_FEEDBACK="NONE" a nesmi byt pouzity jiny vystup nez CLKFX nebo CLKFX180
  -- nikde ale neni popsane pripojeni CLKFB v tomto rezimu, tak jsem ho zapojil na '0' a funguje to...
  VGA_clock_module : DCM generic map(
    CLK_FEEDBACK => "NONE",
    CLKDV_DIVIDE => 2.0, -- (1.5,2,2.5,3,4,5,8,16)
    CLKFX_DIVIDE => 1,
    CLKFX_MULTIPLY => 2,
    CLKIN_DIVIDE_BY_2 => FALSE, -- (TRUE, FALSE)
    CLKOUT_PHASE_SHIFT => "NONE",
    DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS",
    DFS_FREQUENCY_MODE => "LOW",
    DLL_FREQUENCY_MODE => "LOW",
    DSS_MODE => "NONE",
    DUTY_CYCLE_CORRECTION => FALSE, -- (TRUE, FALSE)
    PHASE_SHIFT => 0.0,
    STARTUP_WAIT => TRUE, -- (TRUE, FALSE)
    CLKIN_PERIOD => 281.9
  ) 
  port map (
    CLKIN => PHI,
    CLKFB => '0',
    CLKFX => OSCF2,
--    CLKFX180 => OSCF2,
    DSSEN => '0',
    PSCLK => '0',
    PSEN => '0',
    PSINCDEC => '0',
    RST => '0'
  );
  -- pripojeni CGA2VGA prevodniku
  CGA2VGA_module: CGA2VGA
  port map (
    CLOCK => OSCF2, -- PHI * 10
    Rin => Rin,
    Gin => Gin,
    Bin => Bin,
    Yin => Yin,
    HSin => HSin,
    VSin => VSin, -- '0', pokud je rezim generatoru
--    VSout => VSin, -- pokud je rezim generatoru
    Rout => Rout,
    Gout => Gout,
    Bout => Bout,
    Yout => Yout,
    HSout => HSout
  );

	VSout <= VSin;
	
end Behavioral;
