library ieee;
use ieee.std_logic_1164.all;
use work.qsim_logic.all;	     -- package with to_integer() function
use std.textio.all;                  -- For file operations

entity memory16 is
 port (dbus: inout std_logic_vector(15 downto 0);
       abus: in bit_vector(15 downto 0);
       mrd:   in bit;			-- active high read enable
       mwr:   in bit);			-- active high write enable
end memory16;

architecture reglevel of memory16 is
begin
  
 process (mrd,mwr,abus,dbus)
    type mem is array(natural range <>) of std_logic_vector(15 downto 0);
    variable M: mem(0 to 65535);
    variable init:    boolean := true;          -- true 1st time through
    file P:  text is in "program";              -- program object code file
    variable L:       line;                     -- temp variable
    variable i:       natural := 0;		-- index for loading M
    variable tmp:     bit_vector(15 downto 0);  
  begin

     -- Do this only at initialization time to load a "program" into memory
    if init then
       while not endfile(P) loop    	-- Read program from data file
          readline(P,L);		-- Read one line of program
	  read(L,tmp);                  -- Must be 16-bit binary code
	  M(i) := to_stdlogicvector(tmp);	-- Put into array
	  i := i+1;                     -- Store in memory array
       end loop;
       init := false;                        -- Disable memory load
     end if;

   -- The actual memory read/write process
   if (mrd = '1') then   			-- read enabled
       dbus <= M(to_integer('0' & abus));	-- drive the bus
    elsif (mwr = '1') then   			-- write enabled
       dbus <= "ZZZZZZZZZZZZZZZZ";		-- disable drivers
       M(to_integer('0' & abus)) := dbus;	-- write value
    else
       dbus<="ZZZZZZZZZZZZZZZZ";		--disable drivers
    end if;

  end process;

end;
