library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.numeric_std.all; use work.types.all; use work.disk.all; entity disk_ctrl is port ( clk : in std_logic; addr : inout byte; data : inout byte; DMA_req : out std_logic; DMA_ack : in std_logic ); end disk_ctrl; architecture Behavioral of disk_ctrl is constant param_1 : byte := x"FB"; constant param_2 : byte := x"FC"; constant param_3 : byte := x"FD"; constant param_4 : byte := x"FE"; constant read_cmnd : byte := x"FF"; constant sector_size : integer := 256; signal buff : disk_block; signal b_addr : byte; signal b_count : byte; signal b_offset : byte; signal b_length : byte; begin process (clk) type rd_state is ( idle, buff_sect, wait_DMA, transfer_byte, inc_byte_counter ); variable state : rd_state := idle; variable block_counter : integer := 0; variable byte_counter : integer := 0; variable block_size : integer := sector_size; begin if rising_edge (clk) then if addr = param_1 then b_addr <= data; end if; if addr = param_2 then b_count <= data; end if; if addr = param_3 then b_offset <= data; end if; if addr = param_4 then b_length <= data; end if; if addr = read_cmnd then byte_counter := to_integer(unsigned(b_offset)); block_counter := 0; state := buff_sect; end if; case state is when idle => when buff_sect => buff <= disk_data(to_integer(unsigned(b_addr))+block_counter); if block_counter = to_integer(unsigned(b_count)) then if to_integer(unsigned(b_length)) /= 0 then block_size := to_integer(unsigned(b_length)); end if; end if; DMA_req <= '1'; state := wait_DMA; when wait_DMA => if DMA_ack = '1' then state := transfer_byte; end if; when transfer_byte => if byte_counter < block_size then data <= buff(byte_counter); state := inc_byte_counter; else DMA_req <= '0'; if block_counter < to_integer(unsigned(b_count)) then block_counter := block_counter + 1; byte_counter := 0; state := buff_sect; else addr <= (others => 'Z'); data <= (others => 'Z'); block_size := sector_size; state := idle; end if; end if; when inc_byte_counter => byte_counter := byte_counter + 1; state := transfer_byte; end case; end if; end process; end Behavioral;