summaryrefslogtreecommitdiffstats
path: root/de1/fpga-bbc-pq/master/sn76489-fixes.patch
diff options
context:
space:
mode:
Diffstat (limited to 'de1/fpga-bbc-pq/master/sn76489-fixes.patch')
-rw-r--r--de1/fpga-bbc-pq/master/sn76489-fixes.patch634
1 files changed, 634 insertions, 0 deletions
diff --git a/de1/fpga-bbc-pq/master/sn76489-fixes.patch b/de1/fpga-bbc-pq/master/sn76489-fixes.patch
new file mode 100644
index 0000000..6566582
--- /dev/null
+++ b/de1/fpga-bbc-pq/master/sn76489-fixes.patch
@@ -0,0 +1,634 @@
+diff --git a/sn76489-1.0/sn76489_comp_pack-p.vhd b/sn76489-1.0/sn76489_comp_pack-p.vhd
+index 06b12c8..c5fcc90 100644
+--- a/sn76489-1.0/sn76489_comp_pack-p.vhd
++++ b/sn76489-1.0/sn76489_comp_pack-p.vhd
+@@ -27,9 +27,11 @@ package sn76489_comp_pack is
+ clock_i : in std_logic;
+ clk_en_i : in boolean;
+ res_n_i : in std_logic;
+- we_i : in boolean;
++ we_i : in std_logic;
+ d_i : in std_logic_vector(0 to 7);
+- r2_i : in std_logic;
++ addr_i : in std_logic_vector(0 to 1);
++ rst_a_i : in std_logic_vector(0 to 3);
++ rst_cnt_i: in std_logic_vector(0 to 9);
+ ff_o : out std_logic;
+ tone_o : out signed(0 to 7)
+ );
+@@ -40,31 +42,14 @@ package sn76489_comp_pack is
+ clock_i : in std_logic;
+ clk_en_i : in boolean;
+ res_n_i : in std_logic;
+- we_i : in boolean;
++ we_i : in std_logic;
+ d_i : in std_logic_vector(0 to 7);
+- r2_i : in std_logic;
++ addr_i : in std_logic_vector(0 to 1);
+ tone3_ff_i : in std_logic;
+ noise_o : out signed(0 to 7)
+ );
+ end component;
+
+- component sn76489_latch_ctrl
+- port (
+- clock_i : in std_logic;
+- clk_en_i : in boolean;
+- res_n_i : in std_logic;
+- ce_n_i : in std_logic;
+- we_n_i : in std_logic;
+- d_i : in std_logic_vector(0 to 7);
+- ready_o : out std_logic;
+- tone1_we_o : out boolean;
+- tone2_we_o : out boolean;
+- tone3_we_o : out boolean;
+- noise_we_o : out boolean;
+- r2_o : out std_logic
+- );
+- end component;
+-
+ component sn76489_clock_div
+ generic (
+ clock_div_16_g : integer := 1
+diff --git a/sn76489-1.0/sn76489_latch_ctrl-c.vhd b/sn76489-1.0/sn76489_latch_ctrl-c.vhd
+deleted file mode 100644
+index abc09e0..0000000
+--- a/sn76489-1.0/sn76489_latch_ctrl-c.vhd
++++ /dev/null
+@@ -1,14 +0,0 @@
+--------------------------------------------------------------------------------
+---
+--- Synthesizable model of TI's SN76489AN.
+---
+--- $Id: sn76489_latch_ctrl-c.vhd,v 1.2 2005/10/10 22:12:38 arnim Exp $
+---
+--------------------------------------------------------------------------------
+-
+-configuration sn76489_latch_ctrl_rtl_c0 of sn76489_latch_ctrl is
+-
+- for rtl
+- end for;
+-
+-end sn76489_latch_ctrl_rtl_c0;
+diff --git a/sn76489-1.0/sn76489_latch_ctrl.vhd b/sn76489-1.0/sn76489_latch_ctrl.vhd
+deleted file mode 100644
+index 789720c..0000000
+--- a/sn76489-1.0/sn76489_latch_ctrl.vhd
++++ /dev/null
+@@ -1,138 +0,0 @@
+--------------------------------------------------------------------------------
+---
+--- Synthesizable model of TI's SN76489AN.
+---
+--- $Id: sn76489_latch_ctrl.vhd,v 1.6 2006/02/27 20:30:10 arnim Exp $
+---
+--- Latch Control Unit
+---
+--------------------------------------------------------------------------------
+---
+--- Copyright (c) 2005, 2006, Arnim Laeuger (arnim.laeuger@gmx.net)
+---
+--- All rights reserved
+---
+--- Redistribution and use in source and synthezised forms, with or without
+--- modification, are permitted provided that the following conditions are met:
+---
+--- Redistributions of source code must retain the above copyright notice,
+--- this list of conditions and the following disclaimer.
+---
+--- Redistributions in synthesized form must reproduce the above copyright
+--- notice, this list of conditions and the following disclaimer in the
+--- documentation and/or other materials provided with the distribution.
+---
+--- Neither the name of the author nor the names of other contributors may
+--- be used to endorse or promote products derived from this software without
+--- specific prior written permission.
+---
+--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
+--- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+--- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+--- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+--- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+--- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+--- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+--- POSSIBILITY OF SUCH DAMAGE.
+---
+--- Please report bugs to the author, but before you do so, please
+--- make sure that this is not a derivative work and that
+--- you have the latest version of this file.
+---
+--------------------------------------------------------------------------------
+-
+-library ieee;
+-use ieee.std_logic_1164.all;
+-
+-entity sn76489_latch_ctrl is
+-
+- port (
+- clock_i : in std_logic;
+- clk_en_i : in boolean;
+- res_n_i : in std_logic;
+- ce_n_i : in std_logic;
+- we_n_i : in std_logic;
+- d_i : in std_logic_vector(0 to 7);
+- ready_o : out std_logic;
+- tone1_we_o : out boolean;
+- tone2_we_o : out boolean;
+- tone3_we_o : out boolean;
+- noise_we_o : out boolean;
+- r2_o : out std_logic
+- );
+-
+-end sn76489_latch_ctrl;
+-
+-
+-library ieee;
+-use ieee.numeric_std.all;
+-
+-architecture rtl of sn76489_latch_ctrl is
+-
+- signal reg_q : std_logic_vector(0 to 2);
+- signal we_q : boolean;
+- signal ready_q : std_logic;
+-
+-begin
+-
+- -----------------------------------------------------------------------------
+- -- Process seq
+- --
+- -- Purpose:
+- -- Implements the sequential elements.
+- --
+- seq: process (clock_i, res_n_i)
+- begin
+- if res_n_i = '0' then
+- reg_q <= (others => '0');
+- we_q <= false;
+- ready_q <= '0';
+-
+- elsif clock_i'event and clock_i = '1' then
+- -- READY Flag Output ----------------------------------------------------
+- if ready_q = '0' and we_q then
+- if clk_en_i then
+- -- assert READY when write access happened
+- ready_q <= '1';
+- end if;
+- elsif ce_n_i = '1' then
+- -- deassert READY when access has finished
+- ready_q <= '0';
+- end if;
+-
+- -- Register Selection ---------------------------------------------------
+- if ce_n_i = '0' and we_n_i = '0' then
+- if clk_en_i then
+- if d_i(0) = '1' then
+- reg_q <= d_i(1 to 3);
+- end if;
+- we_q <= true;
+- end if;
+- else
+- we_q <= false;
+- end if;
+-
+- end if;
+- end process seq;
+- --
+- -----------------------------------------------------------------------------
+-
+-
+- -----------------------------------------------------------------------------
+- -- Output mapping
+- -----------------------------------------------------------------------------
+- tone1_we_o <= reg_q(0 to 1) = "00" and we_q;
+- tone2_we_o <= reg_q(0 to 1) = "01" and we_q;
+- tone3_we_o <= reg_q(0 to 1) = "10" and we_q;
+- noise_we_o <= reg_q(0 to 1) = "11" and we_q;
+-
+- r2_o <= reg_q(2);
+-
+- ready_o <= ready_q
+- when ce_n_i = '0' else
+- '1';
+-
+-end rtl;
+diff --git a/sn76489-1.0/sn76489_noise.vhd b/sn76489-1.0/sn76489_noise.vhd
+index 8b2ee0e..035adab 100644
+--- a/sn76489-1.0/sn76489_noise.vhd
++++ b/sn76489-1.0/sn76489_noise.vhd
+@@ -54,9 +54,9 @@ entity sn76489_noise is
+ clock_i : in std_logic;
+ clk_en_i : in boolean;
+ res_n_i : in std_logic;
+- we_i : in boolean;
++ we_i : in std_logic;
+ d_i : in std_logic_vector(0 to 7);
+- r2_i : in std_logic;
++ addr_i : in std_logic_vector(0 to 1);
+ tone3_ff_i : in std_logic;
+ noise_o : out signed(0 to 7)
+ );
+@@ -68,6 +68,9 @@ use work.sn76489_comp_pack.sn76489_attenuator;
+
+ architecture rtl of sn76489_noise is
+
++ signal selected : std_logic;
++ signal write_cr : std_logic;
++
+ signal nf_q : std_logic_vector(0 to 1);
+ signal fb_q : std_logic;
+ signal a_q : std_logic_vector(0 to 3);
+@@ -78,12 +81,13 @@ architecture rtl of sn76489_noise is
+ shift_source_q : std_logic;
+ signal shift_rise_edge_s : boolean;
+
+- signal lfsr_q : std_logic_vector(0 to 15);
++ signal lfsr_q : std_logic_vector(0 to 7);
+
+ signal freq_s : signed(0 to 1);
+
+ begin
+
++
+ -----------------------------------------------------------------------------
+ -- Process cpu_regs
+ --
+@@ -96,22 +100,25 @@ begin
+ nf_q <= (others => '0');
+ fb_q <= '0';
+ a_q <= (others => '1');
+-
+- elsif clock_i'event and clock_i = '1' then
+- if clk_en_i and we_i then
+- if r2_i = '0' then
+- -- access to control register
+- -- both access types can write to the control register!
+- nf_q <= d_i(6 to 7);
+- fb_q <= d_i(5);
+-
+- else
+- -- access to attenuator register
+- -- both access types can write to the attenuator register!
+- a_q <= d_i(4 to 7);
+-
++ elsif rising_edge(clock_i) and we_i = '1' then
++ if d_i(0) = '1' then
++ if d_i(1 to 2) = addr_i then
++ if d_i(3) = '0' then
++ selected<='1';
++ nf_q <= d_i(6 to 7);
++ fb_q <= d_i(5);
++ else
++ selected <='0';
++ a_q <= d_i(4 to 7);
++ end if;
++ else
++ selected <='0';
++ end if;
++ elsif selected = '1' then
++ selected<='0';
++ nf_q <= d_i(6 to 7);
++ fb_q <= d_i(5);
+ end if;
+- end if;
+ end if;
+ end process cpu_regs;
+ --
+@@ -130,8 +137,7 @@ begin
+ freq_cnt_q <= (others => '0');
+ freq_ff_q <= '0';
+
+- elsif clock_i'event and clock_i = '1' then
+- if clk_en_i then
++ elsif rising_edge(clock_i) and clk_en_i then
+ if freq_cnt_q = 0 then
+ -- reload frequency counter according to NF setting
+ case nf_q is
+@@ -152,8 +158,6 @@ begin
+ freq_cnt_q <= freq_cnt_q - 1;
+
+ end if;
+-
+- end if;
+ end if;
+ end process freq_gen;
+ --
+@@ -191,6 +195,8 @@ begin
+ shift_rise_edge_s <= shift_source_q = '0' and shift_source_s = '1';
+
+
++ write_cr <= '1' when ((we_i='1') and (((d_i(0) = '1') and (d_i(1 to 2) = addr_i) and (d_i(3) = '0')) or (selected='1'))) else '0';
++
+ -----------------------------------------------------------------------------
+ -- Process lfsr
+ --
+@@ -219,15 +225,15 @@ begin
+ return parity_v;
+ end;
+
++
+ begin
+ if res_n_i = '0' then
+ -- reset LFSR to "0000000000000001"
+ lfsr_q <= (others => '0');
+ lfsr_q(lfsr_q'right) <= '1';
+
+- elsif clock_i'event and clock_i = '1' then
+- if clk_en_i then
+- if we_i and r2_i = '0' then
++ elsif rising_edge(clock_i) and clk_en_i then
++ if write_cr='1' then
+ -- write to noise register
+ -- -> reset LFSR
+ lfsr_q <= (others => '0');
+@@ -253,7 +259,6 @@ begin
+
+ end if;
+
+- end if;
+ end if;
+ end process lfsr;
+ --
+diff --git a/sn76489-1.0/sn76489_tone.vhd b/sn76489-1.0/sn76489_tone.vhd
+index b71af8b..f1b6885 100644
+--- a/sn76489-1.0/sn76489_tone.vhd
++++ b/sn76489-1.0/sn76489_tone.vhd
+@@ -54,9 +54,11 @@ entity sn76489_tone is
+ clock_i : in std_logic;
+ clk_en_i : in boolean;
+ res_n_i : in std_logic;
+- we_i : in boolean;
++ we_i : in std_logic;
+ d_i : in std_logic_vector(0 to 7);
+- r2_i : in std_logic;
++ addr_i : in std_logic_vector(0 to 1);
++ rst_a_i : in std_logic_vector(0 to 3);
++ rst_cnt_i: in std_logic_vector(0 to 9);
+ ff_o : out std_logic;
+ tone_o : out signed(0 to 7)
+ );
+@@ -68,6 +70,7 @@ use work.sn76489_comp_pack.sn76489_attenuator;
+
+ architecture rtl of sn76489_tone is
+
++ signal selected : std_logic;
+ signal f_q : std_logic_vector(0 to 9);
+ signal a_q : std_logic_vector(0 to 3);
+ signal freq_cnt_q : unsigned(0 to 9);
+@@ -75,6 +78,7 @@ architecture rtl of sn76489_tone is
+
+ signal freq_s : signed(0 to 1);
+
++
+ function all_zero(a : in std_logic_vector) return boolean is
+ variable result_v : boolean;
+ begin
+@@ -91,6 +95,8 @@ architecture rtl of sn76489_tone is
+
+ begin
+
++
++
+ -----------------------------------------------------------------------------
+ -- Process cpu_regs
+ --
+@@ -99,27 +105,28 @@ begin
+ --
+ cpu_regs: process (clock_i, res_n_i)
+ begin
+- if res_n_i = '0' then
+- f_q <= (others => '0');
+- a_q <= (others => '1');
+-
+- elsif clock_i'event and clock_i = '1' then
+- if clk_en_i and we_i then
+- if r2_i = '0' then
+- -- access to frequency register
+- if d_i(0) = '0' then
+- f_q(0 to 5) <= d_i(2 to 7);
+- else
+- f_q(6 to 9) <= d_i(4 to 7);
+- end if;
+-
+- else
+- -- access to attenuator register
+- -- both access types can write to the attenuator register!
+- a_q <= d_i(4 to 7);
+
++ if res_n_i = '0' then
++ f_q <= (others => '1');
++ a_q <= rst_a_i;
++ selected <='0';
++ elsif rising_edge(clock_i) and we_i = '1' then
++ if d_i(0) = '1' then
++ if d_i(1 to 2) = addr_i then
++ if d_i(3) = '0' then
++ selected<='1';
++ f_q(6 to 9) <= d_i(4 to 7);
++ else
++ selected <='0';
++ a_q <= d_i(4 to 7);
++ end if;
++ else
++ selected <='0';
++ end if;
++ elsif selected = '1' then
++ selected<='0';
++ f_q(0 to 5) <= d_i(2 to 7);
+ end if;
+- end if;
+ end if;
+ end process cpu_regs;
+ --
+@@ -135,17 +142,19 @@ begin
+ freq_gen: process (clock_i, res_n_i)
+ begin
+ if res_n_i = '0' then
+- freq_cnt_q <= (others => '0');
++ freq_cnt_q <= unsigned(rst_cnt_i);
+ freq_ff_q <= '0';
+
+- elsif clock_i'event and clock_i = '1' then
+- if clk_en_i then
+- if freq_cnt_q = 0 then
++ elsif rising_edge(clock_i) and clk_en_i then
++ if we_i='1' and selected = '1' then
++ freq_cnt_q <= (others => '0');
++ freq_ff_q <= '1';
++ elsif freq_cnt_q = 0 then
+ -- update counter from frequency register
+- freq_cnt_q <= unsigned(f_q);
++ freq_cnt_q <= unsigned(f_q)-to_unsigned(1,10);
+
+ -- and toggle the frequency flip-flop if enabled
+- if not all_zero(f_q) then
++ if unsigned(f_q) > to_unsigned(1,10) then
+ freq_ff_q <= not freq_ff_q;
+ else
+ -- if frequency setting is 0, then keep flip-flop at +1
+@@ -157,7 +166,6 @@ begin
+ freq_cnt_q <= freq_cnt_q - 1;
+
+ end if;
+- end if;
+ end if;
+ end process freq_gen;
+ --
+diff --git a/sn76489-1.0/sn76489_top-c.vhd b/sn76489-1.0/sn76489_top-c.vhd
+index 8f709b9..55f3dfb 100644
+--- a/sn76489-1.0/sn76489_top-c.vhd
++++ b/sn76489-1.0/sn76489_top-c.vhd
+@@ -14,10 +14,6 @@ configuration sn76489_top_struct_c0 of sn76489_top is
+ use configuration work.sn76489_clock_div_rtl_c0;
+ end for;
+
+- for latch_ctrl_b : sn76489_latch_ctrl
+- use configuration work.sn76489_latch_ctrl_rtl_c0;
+- end for;
+-
+ for all : sn76489_tone
+ use configuration work.sn76489_tone_rtl_c0;
+ end for;
+diff --git a/sn76489-1.0/sn76489_top.vhd b/sn76489-1.0/sn76489_top.vhd
+index deb8170..2f6a01c 100644
+--- a/sn76489-1.0/sn76489_top.vhd
++++ b/sn76489-1.0/sn76489_top.vhd
+@@ -86,19 +86,17 @@ architecture struct of sn76489_top is
+
+ signal clk_en_s : boolean;
+
+- signal tone1_we_s,
+- tone2_we_s,
+- tone3_we_s,
+- noise_we_s : boolean;
+- signal r2_s : std_logic;
+-
+ signal tone1_s,
+ tone2_s,
+ tone3_s,
+- noise_s : signed(0 to 7);
++ noise_s : signed(0 to 15);
+
+ signal tone3_ff_s : std_logic;
+
++ signal dl : std_logic_vector(0 to 9);
++
++ signal we : std_logic;
++
+ begin
+
+ -----------------------------------------------------------------------------
+@@ -116,26 +114,6 @@ begin
+ );
+
+
+- -----------------------------------------------------------------------------
+- -- Latch Control = CPU Interface
+- -----------------------------------------------------------------------------
+- latch_ctrl_b : sn76489_latch_ctrl
+- port map (
+- clock_i => clock_i,
+- clk_en_i => clk_en_s,
+- res_n_i => res_n_i,
+- ce_n_i => ce_n_i,
+- we_n_i => we_n_i,
+- d_i => d_i,
+- ready_o => ready_o,
+- tone1_we_o => tone1_we_s,
+- tone2_we_o => tone2_we_s,
+- tone3_we_o => tone3_we_s,
+- noise_we_o => noise_we_s,
+- r2_o => r2_s
+- );
+-
+-
+ -----------------------------------------------------------------------------
+ -- Tone Channel 1
+ -----------------------------------------------------------------------------
+@@ -144,9 +122,11 @@ begin
+ clock_i => clock_i,
+ clk_en_i => clk_en_s,
+ res_n_i => res_n_i,
+- we_i => tone1_we_s,
++ we_i => we,
+ d_i => d_i,
+- r2_i => r2_s,
++ addr_i => "00",
++ rst_a_i => "0000",
++ rst_cnt_i=> "0000000000",
+ ff_o => open,
+ tone_o => tone1_s
+ );
+@@ -159,9 +139,11 @@ begin
+ clock_i => clock_i,
+ clk_en_i => clk_en_s,
+ res_n_i => res_n_i,
+- we_i => tone2_we_s,
++ we_i => we,
+ d_i => d_i,
+- r2_i => r2_s,
++ addr_i => "01",
++ rst_a_i => "1000",
++ rst_cnt_i=> "0000110100",
+ ff_o => open,
+ tone_o => tone2_s
+ );
+@@ -174,9 +156,11 @@ begin
+ clock_i => clock_i,
+ clk_en_i => clk_en_s,
+ res_n_i => res_n_i,
+- we_i => tone3_we_s,
++ we_i => we,
+ d_i => d_i,
+- r2_i => r2_s,
++ addr_i => "10",
++ rst_a_i => "1000",
++ rst_cnt_i=> "1100110100",
+ ff_o => tone3_ff_s,
+ tone_o => tone3_s
+ );
+@@ -189,14 +173,16 @@ begin
+ clock_i => clock_i,
+ clk_en_i => clk_en_s,
+ res_n_i => res_n_i,
+- we_i => noise_we_s,
++ we_i => we,
+ d_i => d_i,
+- r2_i => r2_s,
++ addr_i => "11",
+ tone3_ff_i => tone3_ff_s,
+ noise_o => noise_s
+ );
+
+
++ we<= not(ce_n_i or we_n_i) when clk_en_s else '0';
++
+ -- Register output
+ process(clock_i)
+ begin
+@@ -207,4 +193,23 @@ begin
+ end if;
+ end process;
+
++ process(clock_i)
++ begin
++ if res_n_i = '0' then
++ dl<=(others => '0');
++ elsif rising_edge(clock_i) then
++ if ce_n_i = '0' and we_n_i = '0' then
++ if d_i(0)='1' then
++ if d_i(3)='0' then
++ dl(6 to 9) <= d_i(4 to 7);
++ end if;
++ else
++ dl(0 to 5) <= d_i(2 to 7);
++ end if;
++ end if;
++ end if;
++ end process;
++
++
++ ready_o <= '1';
+ end struct;