Subversion Repositories KoE_projects

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

  1. --
  2. -- YM2149 vhdl core
  3.  
  4. -- Copyright (c) MikeJ - Jan 2005
  5. -- Copyleft :) koe - Sept 2oo9
  6.  
  7. library ieee;
  8.   use ieee.std_logic_1164.all;
  9.   use ieee.std_logic_arith.all;
  10.   use ieee.std_logic_unsigned.all;
  11.  
  12. entity YM2149 is
  13.   port (
  14.   -- data bus
  15.   I_DA                : in  std_logic_vector(7 downto 0);
  16.   O_DA                : out std_logic_vector(7 downto 0);
  17.  
  18.   output                  : out std_logic_vector(7 downto 0);
  19.  
  20.   strobe_a          : out std_logic;
  21.   strobe_b          : out std_logic;
  22.   strobe_c          : out std_logic;
  23.  
  24.   RESET_L             : in  std_logic;
  25.   CLK                 : in  std_logic;  -- note 6 Mhz
  26.   wr_addr                         : in std_logic;
  27.   wr_data                         : in std_logic;
  28.   rd_data                         : in std_logic;
  29.   state                         : out std_logic_vector(1 downto 0)
  30.  
  31. );
  32. end;
  33.  
  34. architecture RTL of YM2149 is
  35.   type  array_16x8   is array (0 to 15) of std_logic_vector(7 downto 0);
  36.   type  array_3x12   is array (1 to 3) of std_logic_vector(11 downto 0);
  37.  
  38.   signal cnt_div              : std_logic_vector(3 downto 0) := (others => '0');
  39.   signal noise_div            : std_logic := '0';
  40.   signal ena_div              : std_logic;
  41.   signal ena_div_noise        : std_logic;
  42.   signal poly17               : std_logic_vector(16 downto 0) := (others => '0');
  43.  
  44.   -- registers
  45.   signal addr                 : std_logic_vector(7 downto 0);
  46.   signal busctrl_addr         : std_logic;
  47.   signal busctrl_we           : std_logic;
  48.   signal busctrl_re           : std_logic;
  49.  
  50.   signal reg                  : array_16x8;
  51.   signal env_reset            : std_logic;
  52.   signal ioa_inreg            : std_logic_vector(7 downto 0);
  53.   signal iob_inreg            : std_logic_vector(7 downto 0);
  54.  
  55.   signal noise_gen_cnt        : std_logic_vector(4 downto 0);
  56.   signal noise_gen_op         : std_logic;
  57.   signal tone_gen_cnt         : array_3x12 := (others => (others => '0'));
  58.   signal tone_gen_op          : std_logic_vector(3 downto 1) := "000";
  59.  
  60.   signal env_gen_cnt          : std_logic_vector(15 downto 0);
  61.   signal env_ena              : std_logic;
  62.   signal env_hold             : std_logic;
  63.   signal env_inc              : std_logic;
  64.   signal env_vol              : std_logic_vector(4 downto 0);
  65.  
  66.   signal tone_ena_l           : std_logic;
  67.   signal tone_src             : std_logic;
  68.   signal noise_ena_l          : std_logic;
  69.   signal chan_vol             : std_logic_vector(4 downto 0);
  70.  
  71.   signal dac_amp              : std_logic_vector(7 downto 0);
  72.   signal audio_mix            : std_logic_vector(9 downto 0);
  73.  
  74.  
  75. begin
  76.  
  77.  
  78.   -- address latch
  79.   p_waddr                : process(wr_addr, RESET_L)
  80.   begin
  81.     if (RESET_L = '0') then
  82.       addr <= (others => '0');
  83.     elsif (falling_edge(wr_addr)) then
  84.       addr <= I_DA;
  85.     end if;
  86.   end process;
  87.  
  88.   -- data latch
  89.   p_wdata                : process(wr_data, RESET_L, addr)
  90.   begin
  91.     if (RESET_L = '0') then
  92.       reg <= (others => (others => '0'));
  93.     elsif (falling_edge(wr_data)) then
  94.         case addr(3 downto 0) is
  95.           when x"0" => reg(0)  <= I_DA;
  96.           when x"1" => reg(1)  <= I_DA;
  97.           when x"2" => reg(2)  <= I_DA;
  98.           when x"3" => reg(3)  <= I_DA;
  99.           when x"4" => reg(4)  <= I_DA;
  100.           when x"5" => reg(5)  <= I_DA;
  101.           when x"6" => reg(6)  <= I_DA;
  102.           when x"7" => reg(7)  <= I_DA;
  103.           when x"8" => reg(8)  <= I_DA;
  104.           when x"9" => reg(9)  <= I_DA;
  105.           when x"A" => reg(10) <= I_DA;
  106.           when x"B" => reg(11) <= I_DA;
  107.           when x"C" => reg(12) <= I_DA;
  108.           when x"D" => reg(13) <= I_DA;
  109.    
  110.           when others => null;
  111.         end case;
  112.     end if;
  113.  
  114. -- koe
  115.     env_reset <= '0';
  116.     if (wr_data = '0') and (addr(3 downto 0) = x"D") then
  117.       env_reset <= '1';
  118.     end if;
  119.   end process;
  120.  
  121.   p_rdata                : process(rd_data, busctrl_re, RESET_L, addr, reg)
  122.   begin
  123.    
  124. if (RESET_L = '0') then
  125. O_DA <= (others => '0');
  126.  
  127.     elsif (falling_edge(rd_data)) then
  128.       case addr(3 downto 0) is
  129.         when x"0" => O_DA <= reg(0) ;
  130.         when x"1" => O_DA <= "0000" & reg(1)(3 downto 0) ;
  131.         when x"2" => O_DA <= reg(2) ;
  132.         when x"3" => O_DA <= "0000" & reg(3)(3 downto 0) ;
  133.         when x"4" => O_DA <= reg(4) ;
  134.         when x"5" => O_DA <= "0000" & reg(5)(3 downto 0) ;
  135.         when x"6" => O_DA <= "000"  & reg(6)(4 downto 0) ;
  136.         when x"7" => O_DA <= reg(7) ;
  137.         when x"8" => O_DA <= "000"  & reg(8)(4 downto 0) ;
  138.         when x"9" => O_DA <= "000"  & reg(9)(4 downto 0) ;
  139.         when x"A" => O_DA <= "000"  & reg(10)(4 downto 0) ;
  140.         when x"B" => O_DA <= reg(11);
  141.         when x"C" => O_DA <= reg(12);
  142.         when x"D" => O_DA <= "0000" & reg(13)(3 downto 0);
  143.         when others => null;
  144.       end case;
  145.     end if;
  146.   end process;
  147.   --
  148.   p_divider              : process
  149.   begin
  150.     wait until rising_edge(CLK);
  151.     -- / 8 when SEL is high and /16 when SEL is low
  152.       ena_div <= '0';
  153.       ena_div_noise <= '0';
  154.       if (cnt_div = "0000") then
  155.        -- cnt_div <= (not I_SEL_L) & "111";
  156.         cnt_div <= "1111";
  157.         ena_div <= '1';
  158.  
  159.         noise_div <= not noise_div;
  160.         if (noise_div = '1') then
  161.           ena_div_noise <= '1';
  162.         end if;
  163.       else
  164.         cnt_div <= cnt_div - "1";
  165.       end if;
  166.   end process;
  167.  
  168.   p_noise_gen            : process
  169.     variable noise_gen_comp : std_logic_vector(4 downto 0);
  170.     variable poly17_zero : std_logic;
  171.   begin
  172.     wait until rising_edge(CLK);
  173.  
  174.     if (reg(6)(4 downto 0) = "00000") then
  175.       noise_gen_comp := "00000";
  176.     else
  177.       noise_gen_comp := (reg(6)(4 downto 0) - "1");
  178.     end if;
  179.  
  180.     poly17_zero := '0';
  181.     if (poly17 = "00000000000000000") then poly17_zero := '1'; end if;
  182.  
  183.       if (ena_div_noise = '1') then -- divider ena
  184.  
  185.         if (noise_gen_cnt >= noise_gen_comp) then
  186.           noise_gen_cnt <= "00000";
  187.           poly17 <= (poly17(0) xor poly17(2) xor poly17_zero) & poly17(16 downto 1);
  188.         else
  189.           noise_gen_cnt <= (noise_gen_cnt + "1");
  190.         end if;
  191.       end if;
  192.   end process;
  193.   noise_gen_op <= poly17(0);
  194.  
  195.   p_tone_gens            : process
  196.     variable tone_gen_freq : array_3x12;
  197.     variable tone_gen_comp : array_3x12;
  198.   begin
  199.     wait until rising_edge(CLK);
  200.  
  201.     -- looks like real chips count up - we need to get the Exact behaviour ..
  202.     tone_gen_freq(1) := reg(1)(3 downto 0) & reg(0);
  203.     tone_gen_freq(2) := reg(3)(3 downto 0) & reg(2);
  204.     tone_gen_freq(3) := reg(5)(3 downto 0) & reg(4);
  205.     -- period 0 = period 1
  206.     for i in 1 to 3 loop
  207.       if (tone_gen_freq(i) = x"000") then
  208.         tone_gen_comp(i) := x"000";
  209.       else
  210.         tone_gen_comp(i) := (tone_gen_freq(i) - "1");
  211.       end if;
  212.     end loop;
  213.  
  214.       for i in 1 to 3 loop
  215.         if (ena_div = '1') then -- divider ena
  216.  
  217.           if (tone_gen_cnt(i) >= tone_gen_comp(i)) then
  218.             tone_gen_cnt(i) <= x"000";
  219.             tone_gen_op(i) <= not tone_gen_op(i);
  220.           else
  221.             tone_gen_cnt(i) <= (tone_gen_cnt(i) + "1");
  222.           end if;
  223.         end if;
  224.       end loop;
  225.   end process;
  226.  
  227.   p_envelope_freq        : process
  228.     variable env_gen_freq : std_logic_vector(15 downto 0);
  229.     variable env_gen_comp : std_logic_vector(15 downto 0);
  230.   begin
  231.     wait until rising_edge(CLK);
  232.     env_gen_freq := reg(12) & reg(11);
  233.     -- envelope freqs 1 and 0 are the same.
  234.     if (env_gen_freq = x"0000") then
  235.       env_gen_comp := x"0000";
  236.     else
  237.       env_gen_comp := (env_gen_freq - "1");
  238.     end if;
  239.       env_ena <= '0';
  240.       if (ena_div = '1') then -- divider ena
  241.         if (env_gen_cnt >= env_gen_comp) then
  242.           env_gen_cnt <= x"0000";
  243.           env_ena <= '1';
  244.         else
  245.           env_gen_cnt <= (env_gen_cnt + "1");
  246.         end if;
  247.       end if;
  248.   end process;
  249.  
  250.   p_envelope_shape       : process(env_reset, reg, CLK)
  251.     variable is_bot    : boolean;
  252.     variable is_bot_p1 : boolean;
  253.     variable is_top_m1 : boolean;
  254.     variable is_top    : boolean;
  255.   begin
  256.         -- envelope shapes
  257.         -- C AtAlH
  258.         -- 0 0 x x  \___
  259.         --
  260.         -- 0 1 x x  /___
  261.         --
  262.         -- 1 0 0 0  \\\\
  263.         --
  264.         -- 1 0 0 1  \___
  265.         --
  266.         -- 1 0 1 0  \/\/
  267.         --           ___
  268.         -- 1 0 1 1  \
  269.         --
  270.         -- 1 1 0 0  ////
  271.         --           ___
  272.         -- 1 1 0 1  /
  273.         --
  274.         -- 1 1 1 0  /\/\
  275.         --
  276.         -- 1 1 1 1  /___
  277.     if (env_reset = '1') then
  278.       -- load initial state
  279.       if (reg(13)(2) = '0') then -- attack
  280.         env_vol <= "11111";
  281.         env_inc <= '0'; -- -1
  282.       else
  283.         env_vol <= "00000";
  284.         env_inc <= '1'; -- +1
  285.       end if;
  286.       env_hold <= '0';
  287.  
  288.     elsif rising_edge(CLK) then
  289.       is_bot    := (env_vol = "00000");
  290.       is_bot_p1 := (env_vol = "00001");
  291.       is_top_m1 := (env_vol = "11110");
  292.       is_top    := (env_vol = "11111");
  293.  
  294.         if (env_ena = '1') then
  295.           if (env_hold = '0') then
  296.             if (env_inc = '1') then
  297.               env_vol <= (env_vol + "00001");
  298.             else
  299.               env_vol <= (env_vol + "11111");
  300.             end if;
  301.           end if;
  302.  
  303.           -- envelope shape control.
  304.           if (reg(13)(3) = '0') then
  305.             if (env_inc = '0') then -- down
  306.               if is_bot_p1 then env_hold <= '1'; end if;
  307.             else
  308.               if is_top then env_hold <= '1'; end if;
  309.             end if;
  310.           else
  311.             if (reg(13)(0) = '1') then -- hold = 1
  312.               if (env_inc = '0') then -- down
  313.                 if (reg(13)(1) = '1') then -- alt
  314.                   if is_bot    then env_hold <= '1'; end if;
  315.                 else
  316.                   if is_bot_p1 then env_hold <= '1'; end if;
  317.                 end if;
  318.               else
  319.                 if (reg(13)(1) = '1') then -- alt
  320.                   if is_top    then env_hold <= '1'; end if;
  321.                 else
  322.                   if is_top_m1 then env_hold <= '1'; end if;
  323.                 end if;
  324.               end if;
  325.  
  326.             elsif (reg(13)(1) = '1') then -- alternate
  327.               if (env_inc = '0') then -- down
  328.                 if is_bot_p1 then env_hold <= '1'; end if;
  329.                 if is_bot    then env_hold <= '0'; env_inc <= '1'; end if;
  330.               else
  331.                 if is_top_m1 then env_hold <= '1'; end if;
  332.                 if is_top    then env_hold <= '0'; env_inc <= '0'; end if;
  333.               end if;
  334.             end if;
  335.  
  336.           end if;
  337.         end if;
  338.     end if;
  339.   end process;
  340.  
  341.   p_chan_mixer           : process(cnt_div, reg, tone_gen_op)
  342.   begin
  343.     tone_ena_l  <= '1'; tone_src <= '1';
  344.     noise_ena_l <= '1'; chan_vol <= "00000";
  345.     case cnt_div(1 downto 0) is
  346.       when "00" =>
  347.         tone_ena_l  <= reg(7)(0);
  348.                 tone_src    <= tone_gen_op(1);
  349.                 chan_vol    <= reg(8)(4 downto 0);
  350.         noise_ena_l <= reg(7)(3);
  351.       when "01" =>
  352.         tone_ena_l  <= reg(7)(1);
  353.         tone_src    <= tone_gen_op(2);
  354.         chan_vol    <= reg(9)(4 downto 0);
  355.         noise_ena_l <= reg(7)(4);
  356.       when "10" =>
  357.         tone_ena_l  <= reg(7)(2);
  358.         tone_src    <= tone_gen_op(3);
  359.         chan_vol    <= reg(10)(4 downto 0);
  360.         noise_ena_l <= reg(7)(5);
  361.       when "11" => null; -- tone gen outputs become valid on this clock
  362.       when others => null;
  363.     end case;
  364.   end process;
  365.  
  366.   p_op_mixer             : process
  367.     variable chan_mixed : std_logic;
  368.     variable chan_amp : std_logic_vector(4 downto 0);
  369.   begin
  370.     wait until rising_edge(CLK);
  371.    
  372.       chan_mixed := (tone_ena_l or tone_src) and (noise_ena_l or noise_gen_op);
  373.  
  374.       chan_amp := (others => '0');
  375.       if (chan_mixed = '1') then
  376.         if (chan_vol(4) = '0') then
  377.           if (chan_vol(3 downto 0) = "0000") then -- nothing is easy ! make sure quiet is quiet
  378.             chan_amp := "00000";
  379.           else
  380.             chan_amp := chan_vol(3 downto 0) & '1'; -- make sure level 31 (env) = level 15 (tone)
  381.           end if;
  382.         else
  383.           chan_amp := env_vol(4 downto 0);
  384.         end if;
  385.       end if;
  386.  
  387.       dac_amp <= x"00";
  388.       case chan_amp is
  389.     --    when "11111" => dac_amp <= x"FF";
  390.       --  when "11110" => dac_amp <= x"D9";
  391.       --  when "11101" => dac_amp <= x"BA";
  392.       --  when "11100" => dac_amp <= x"9F";
  393.       --  when "11011" => dac_amp <= x"88";
  394.       --  when "11010" => dac_amp <= x"74";
  395.       --  when "11001" => dac_amp <= x"63";
  396.       --  when "11000" => dac_amp <= x"54";
  397.       --  when "10111" => dac_amp <= x"48";
  398.       --  when "10110" => dac_amp <= x"3D";
  399.       --  when "10101" => dac_amp <= x"34";
  400.       --  when "10100" => dac_amp <= x"2C";
  401.       --  when "10011" => dac_amp <= x"25";
  402.       --  when "10010" => dac_amp <= x"1F";
  403.       --  when "10001" => dac_amp <= x"1A";
  404.       --  when "10000" => dac_amp <= x"16";
  405.       --  when "01111" => dac_amp <= x"13";
  406.       --  when "01110" => dac_amp <= x"10";
  407.       --  when "01101" => dac_amp <= x"0D";
  408.       --  when "01100" => dac_amp <= x"0B";
  409.       --  when "01011" => dac_amp <= x"09";
  410.       --  when "01010" => dac_amp <= x"08";
  411.       --  when "01001" => dac_amp <= x"07";
  412.        -- when "01000" => dac_amp <= x"06";
  413.       --  when "00111" => dac_amp <= x"05";
  414.       --  when "00110" => dac_amp <= x"04";
  415.      --   when "00101" => dac_amp <= x"03";
  416.      --   when "00100" => dac_amp <= x"03";
  417.      --   when "00011" => dac_amp <= x"02";
  418.      --   when "00010" => dac_amp <= x"02";
  419.      --   when "00001" => dac_amp <= x"01";
  420.      --   when "00000" => dac_amp <= x"00";
  421.      --   when others => null;
  422.  
  423.                 when "11111" => dac_amp <= x"3f";
  424.         when "11110" => dac_amp <= x"35";
  425.         when "11101" => dac_amp <= x"2c";
  426.         when "11100" => dac_amp <= x"25";
  427.         when "11011" => dac_amp <= x"1f";
  428.         when "11010" => dac_amp <= x"1a";
  429.         when "11001" => dac_amp <= x"16";
  430.         when "11000" => dac_amp <= x"12";
  431.         when "10111" => dac_amp <= x"0f";
  432.         when "10110" => dac_amp <= x"0d";
  433.         when "10101" => dac_amp <= x"0b";
  434.         when "10100" => dac_amp <= x"09";
  435.         when "10011" => dac_amp <= x"07";
  436.         when "10010" => dac_amp <= x"06";
  437.         when "10001" => dac_amp <= x"05";
  438.         when "10000" => dac_amp <= x"04";
  439.         when "01111" => dac_amp <= x"04";
  440.         when "01110" => dac_amp <= x"03";
  441.         when "01101" => dac_amp <= x"03";
  442.         when "01100" => dac_amp <= x"02";
  443.         when "01011" => dac_amp <= x"02";
  444.         when "01010" => dac_amp <= x"01";
  445.         when "01001" => dac_amp <= x"01";
  446.         when "01000" => dac_amp <= x"01";
  447.         when "00111" => dac_amp <= x"01";
  448.         when "00110" => dac_amp <= x"01";
  449.         when "00101" => dac_amp <= x"01";
  450.         when "00100" => dac_amp <= x"01";
  451.         when "00011" => dac_amp <= x"00";
  452.         when "00010" => dac_amp <= x"00";
  453.         when "00001" => dac_amp <= x"00";
  454.         when "00000" => dac_amp <= x"00";
  455.  
  456.       end case;
  457.  
  458.           if (cnt_div(1 downto 0) = "10") then
  459.         audio_mix   <= (others => '0');
  460.         --audio_final <= audio_mix;
  461.       else
  462.         audio_mix   <= audio_mix + ("00" & dac_amp);
  463.       end if;
  464.  
  465.   end process;
  466.  
  467. strobe: process
  468. begin
  469.     wait until rising_edge(CLK);
  470.     output(7 downto 0) <= dac_amp(7 downto 0);
  471. end process;
  472.  
  473. final_output: process
  474. begin
  475.     wait until falling_edge(CLK);
  476.                 case cnt_div(1 downto 0) is
  477.                 when "00" =>strobe_c <= '1';                                                             
  478.                         when "01" =>strobe_a <= '0';                                                             
  479.                         when "10" =>strobe_b<='0'; strobe_a <= '1';                                                            
  480.                         when "11" =>strobe_b <= '1';strobe_c <='0';                              
  481.                 end case;
  482. end process;
  483.  
  484. state(1 downto 0) <= cnt_div(1 downto 0);
  485.  
  486. end architecture RTL;
  487.