1
0
mirror of https://github.com/Gehstock/Mist_FPGA.git synced 2026-01-25 11:35:58 +00:00

add Commen Units

This commit is contained in:
Marcel
2019-07-22 23:42:05 +02:00
parent fa65ff3c9f
commit 462f0490bd
512 changed files with 133512 additions and 5 deletions

View File

@@ -1,5 +0,0 @@
Acorn - Archimedes in FPGA
FPGA Board: Mist FPGA
Changed Clocks Source Code is the same like MiST Github Repo

View File

@@ -0,0 +1,380 @@
------------------------------------------------------------------------------
------------------------------------------------------------------------------
-- --
-- Copyright (c) 2005-2009 Tobias Gubener --
-- Subdesign CPC T-REX by TobiFlex --
-- --
-- This source file is free software: you can redistribute it and/or modify --
-- it under the terms of the GNU General Public License as published --
-- by the Free Software Foundation, either version 3 of the License, or --
-- (at your option) any later version. --
-- --
-- This source file is distributed in the hope that it will be useful, --
-- but WITHOUT ANY WARRANTY; without even the implied warranty of --
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --
-- GNU General Public License for more details. --
-- --
-- You should have received a copy of the GNU General Public License --
-- along with this program. If not, see <http://www.gnu.org/licenses/>. --
-- --
------------------------------------------------------------------------------
------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity ay8912 is
port (
cpuclk : in STD_LOGIC; --48MHz
reset : in STD_LOGIC;
cs : in STD_LOGIC; --H-aktiv
bc0 : in STD_LOGIC; --
bdir : in STD_LOGIC;
Data_in : in STD_LOGIC_VECTOR (7 downto 0);
Data_out : out STD_LOGIC_VECTOR (7 downto 0);
IO_A : in STD_LOGIC_VECTOR (7 downto 0);
chanA : buffer STD_LOGIC_VECTOR (10 downto 0);
chanB : buffer STD_LOGIC_VECTOR (10 downto 0);
chanC : buffer STD_LOGIC_VECTOR (10 downto 0);
Arechts : out STD_LOGIC_VECTOR (15 downto 0);
Alinks : out STD_LOGIC_VECTOR (15 downto 0);
Amono : out STD_LOGIC_VECTOR (15 downto 0)
);
end ay8912;
architecture logic of ay8912 is
signal t_Data : STD_LOGIC_VECTOR (7 downto 0);
signal PSGReg : STD_LOGIC_VECTOR (3 downto 0);
signal APeriode : STD_LOGIC_VECTOR (11 downto 0); --Reg 0,1
signal BPeriode : STD_LOGIC_VECTOR (11 downto 0); --Reg 2,3
signal CPeriode : STD_LOGIC_VECTOR (11 downto 0); --Reg 4,5
signal Noise : STD_LOGIC_VECTOR (4 downto 0); --Reg 6
signal enable : STD_LOGIC_VECTOR (7 downto 0); --Reg 7
signal AVol : STD_LOGIC_VECTOR (4 downto 0); --Reg 8
signal BVol : STD_LOGIC_VECTOR (4 downto 0); --Reg 9
signal CVol : STD_LOGIC_VECTOR (4 downto 0); --Reg 10
signal HPeriode : STD_LOGIC_VECTOR (15 downto 0); --Reg 11,12
signal HKurve : STD_LOGIC_VECTOR (3 downto 0); --Reg 13
signal PortA : STD_LOGIC_VECTOR (7 downto 0); --Reg 14
signal PortB : STD_LOGIC_VECTOR (7 downto 0); --Reg 15
signal AVollog : STD_LOGIC_VECTOR (9 downto 0); --Reg 8log
signal BVollog : STD_LOGIC_VECTOR (9 downto 0); --Reg 9log
signal CVollog : STD_LOGIC_VECTOR (9 downto 0); --Reg 10log
signal Alog : STD_LOGIC_VECTOR (9 downto 0);
signal Blog : STD_LOGIC_VECTOR (9 downto 0);
signal Clog : STD_LOGIC_VECTOR (9 downto 0);
signal HVollog : STD_LOGIC_VECTOR (11 downto 0);
signal ACount : STD_LOGIC_VECTOR (11 downto 0);
signal BCount : STD_LOGIC_VECTOR (11 downto 0);
signal CCount : STD_LOGIC_VECTOR (11 downto 0);
signal NCount : STD_LOGIC_VECTOR (4 downto 0);
signal HCount : STD_LOGIC_VECTOR (15 downto 0);
signal HVol : STD_LOGIC_VECTOR (4 downto 0);
signal nHVol : STD_LOGIC_VECTOR (3 downto 0);
signal HStart : STD_LOGIC;
signal Noisebit : STD_LOGIC;
signal RNG : STD_LOGIC_VECTOR (16 downto 0);
signal Anot, Bnot, Cnot : STD_LOGIC;
signal n_setreg : STD_LOGIC;
signal n_Pegel : STD_LOGIC_VECTOR (11 downto 0);
signal clockgen : STD_LOGIC_VECTOR (9 downto 0);
signal S_Tick : STD_LOGIC;
signal H_Tick : STD_LOGIC;
begin
-------------------------------------------------------------------------
--Clock gen
-------------------------------------------------------------------------
process (cpuclk, clockgen)
begin
S_Tick <= '0'; --sound
H_Tick <= '0'; --Hüllkurve
IF clockgen(9 downto 1)=0 THEN
S_Tick <= '1';
IF clockgen(0)='0' THEN
H_Tick <= '1';
END IF;
END IF;
IF rising_edge(cpuclk) THEN
Arechts <= (chanA&"00000")+('0'&chanB&"0000");
Alinks <= (chanC&"00000")+('0'&chanB&"0000");
Amono <= (chanC&"00000")+('0'&chanB&"0000")+(chanA&"00000");
IF H_Tick='1' THEN
-- clockgen <= ((48*16)-1); --48MHz
clockgen <= "1011111111"; --48MHz
ELSE
clockgen <= clockgen-1;
END IF;
END IF;
END process;
-------------------------------------------------------------------------
--IO Regs
-------------------------------------------------------------------------
process (cpuclk, reset, IO_A, PortA, PortB, Aperiode, Bperiode, Cperiode, Hperiode, AVol, BVol, CVol, Noise, HKurve, enable, Data_in, t_Data, PSGReg, bdir, bc0)
begin
IF reset='0' THEN
enable <= (others => '0');
PortA <= "11111111";
PortB <= "11111111";
ELSIF rising_edge(cpuclk) THEN
HStart <= '0';
IF bdir='1' AND bc0='1' THEN
IF Data_in(7 downto 4)="0000" THEN
PSGReg <= Data_in(3 downto 0);
END IF;
ELSE
IF bdir='1' AND bc0='0' THEN
CASE PSGReg IS
WHEN "0000" =>
APeriode(7 downto 0) <= Data_in;
WHEN "0001" =>
APeriode(11 downto 8) <= Data_in(3 downto 0);
WHEN "0010" =>
BPeriode(7 downto 0) <= Data_in;
WHEN "0011" =>
BPeriode(11 downto 8) <= Data_in(3 downto 0);
WHEN "0100" =>
CPeriode(7 downto 0) <= Data_in;
WHEN "0101" =>
CPeriode(11 downto 8) <= Data_in(3 downto 0);
WHEN "0110" =>
Noise(4 downto 0) <= Data_in(4 downto 0);
WHEN "0111" =>
enable <= Data_in XOR B"00111111";
WHEN "1000" =>
AVollog <= n_Pegel(9 downto 0);
AVol(4 downto 0) <= Data_in(4 downto 0);
WHEN "1001" =>
BVollog <= n_Pegel(9 downto 0);
BVol(4 downto 0) <= Data_in(4 downto 0);
WHEN "1010" =>
CVollog <= n_Pegel(9 downto 0);
CVol(4 downto 0) <= Data_in(4 downto 0);
WHEN "1011" =>
HPeriode(7 downto 0) <= Data_in;
WHEN "1100" =>
HPeriode(15 downto 8) <= Data_in;
WHEN "1101" =>
HStart <= '1';
HKurve(3 downto 0) <= Data_in(3 downto 0);
WHEN "1110" =>
PortA <= Data_in;
WHEN "1111" =>
PortB <= Data_in;
WHEN OTHERS => null;
END CASE;
END IF;
END IF;
END IF;
CASE Data_in(3 downto 0) IS
WHEN "1111" => n_Pegel <= X"2AA"; -- Umsetzung in logarithmische Werte in ca. 3dB Schritten
WHEN "1110" => n_Pegel <= X"1E2"; -- für Kanäle
WHEN "1101" => n_Pegel <= X"155";
WHEN "1100" => n_Pegel <= X"0F1";
WHEN "1011" => n_Pegel <= X"0AA";
WHEN "1010" => n_Pegel <= X"078";
WHEN "1001" => n_Pegel <= X"055";
WHEN "1000" => n_Pegel <= X"03C";
WHEN "0111" => n_Pegel <= X"02A";
WHEN "0110" => n_Pegel <= X"01E";
WHEN "0101" => n_Pegel <= X"015";
WHEN "0100" => n_Pegel <= X"00F";
WHEN "0011" => n_Pegel <= X"00A";
WHEN "0010" => n_Pegel <= X"007";
WHEN "0001" => n_Pegel <= X"005";
WHEN "0000" => n_Pegel <= X"000";
WHEN OTHERS => null;
END CASE;
-- read reg
IF bc0='1' AND bdir='0' THEN
Data_out <= t_Data;
ELSE
Data_out <= "11111111";
END IF;
t_Data <= "00000000";
CASE PSGReg IS
WHEN "0000" =>
t_Data <= Aperiode(7 downto 0);
WHEN "0001" =>
t_Data(3 downto 0) <= Aperiode(11 downto 8);
WHEN "0010" =>
t_Data <= Bperiode(7 downto 0);
WHEN "0011" =>
t_Data(3 downto 0) <= Bperiode(11 downto 8);
WHEN "0100" =>
t_Data <= Cperiode(7 downto 0);
WHEN "0101" =>
t_Data(3 downto 0) <= Cperiode(11 downto 8);
WHEN "0110" =>
t_Data(4 downto 0) <= Noise;
WHEN "0111" =>
t_Data <= enable XOR "00111111";
WHEN "1000" =>
t_Data(4 downto 0) <= AVol;
WHEN "1001" =>
t_Data(4 downto 0) <= BVol;
WHEN "1010" =>
t_Data(4 downto 0) <= CVol;
WHEN "1011" =>
t_Data <= Hperiode(7 downto 0);
WHEN "1100" =>
t_Data <= Hperiode(15 downto 8);
WHEN "1101" =>
t_Data(3 downto 0) <= HKurve;
WHEN "1110" =>
IF enable(6)='0' THEN
t_Data <= PortA AND IO_A;
ELSE
t_Data <= PortA;
END IF;
WHEN "1111" =>
t_Data <= PortB;
END CASE;
END process;
-------------------------------------------------------------------------
--Soundgen
-------------------------------------------------------------------------
process (cpuclk, reset, AVol, BVol, CVol, HVol, nHVol, AVollog, BVollog, CVollog, HVollog, HKurve)
begin
-- channel A
IF AVol(4)='1' THEN
Alog <= HVollog(9 downto 0);
ELSE
Alog <= AVollog;
END IF;
IF rising_edge(cpuclk) THEN
IF ((enable(3) AND Noisebit) XOR Anot)='1' THEN
chanA <= ('0'&Alog);
ELSE
chanA <= (others => '0');
END IF;
IF enable(0)='0' OR APeriode="000000000000" THEN
Anot <= '1';
ACount <= "000000000000";
ELSIF S_Tick='1' THEN
IF ACount(11 downto 0)>=APeriode THEN
ACount <= "000000000001";
Anot <= NOT Anot;
ELSE
ACount <= ACount+1;
END IF;
END IF;
END IF;
-- channel B
IF BVol(4)='1' THEN
Blog <= HVollog(9 downto 0);
ELSE
Blog <= BVollog;
END IF;
IF rising_edge(cpuclk) THEN
IF ((enable(4) AND Noisebit) XOR Bnot)='1' THEN
chanB <= ('0'&Blog);
ELSE
chanB <= (others => '0');
END IF;
IF enable(1)='0' OR BPeriode="000000000000" THEN
Bnot <= '1';
BCount <= "000000000000";
ELSIF S_Tick='1' THEN
IF BCount(11 downto 0)>=BPeriode THEN
BCount <= "000000000001";
Bnot <= NOT Bnot;
ELSE
BCount <= BCount+1;
END IF;
END IF;
END IF;
-- channel C
IF CVol(4)='1' THEN
Clog <= HVollog(9 downto 0);
ELSE
Clog <= CVollog;
END IF;
IF rising_edge(cpuclk) THEN
IF ((enable(5) AND Noisebit) XOR Cnot)='1' THEN
chanC <= ('0'&Clog);
ELSE
chanC <= (others => '0');
END IF;
IF enable(2)='0' OR CPeriode="000000000000" THEN
Cnot <= '1';
CCount <= "000000000000";
ELSIF S_Tick='1' THEN
IF CCount(11 downto 0)>=CPeriode THEN
CCount <= "000000000001";
Cnot <= NOT Cnot;
ELSE
CCount <= CCount+1;
END IF;
END IF;
END IF;
--noise
--Noise="00000" and Noise="00001" is the same
IF rising_edge(cpuclk) THEN
IF S_Tick='1' THEN
IF NCount(4 downto 1)="0000" THEN
NCount <= Noise ;
RNG <= (NOT (RNG(0) XOR RNG(2))& RNG(16 downto 1));
Noisebit <= RNG(0);
ELSE
NCount <= NCount-1;
END IF;
END IF;
END IF;
-- Huellkurve
nHVol <= HVol(3 downto 0);
IF ((HKurve(3) OR NOT HVol(4)) AND ( NOT HKurve(2) XOR ((HKurve(1) XOR HKurve(0)) AND HVol(4))))='1' THEN
nHVol <= HVol(3 downto 0) XOR "1111";
END IF;
IF rising_edge(cpuclk) THEN
IF HStart='1' THEN
HCount <= "0000000000000001";
HVol <= "00000";
ELSIF H_Tick='1' THEN
IF HCount>=HPeriode THEN
HCount <= "0000000000000001";
IF (NOT HVol(4) OR (NOT HKurve(0) AND HKurve(3)))='1' AND (HPeriode /= 0) THEN --HOLD
-- IF (NOT HVol(4) OR (NOT HKurve(0) AND HKurve(3)))='1' THEN --HOLD
HVol <= HVol+1;
END IF;
ELSE
HCount <= HCount+1;
END IF;
END IF;
END IF;
CASE nHVol(3 downto 0) IS
WHEN "1111" => HVollog <= X"2AA"; -- Umsetzung in logarithmische Werte in ca. 3dB Schritten
WHEN "1110" => HVollog <= X"1E2"; -- für Hüllkurve
WHEN "1101" => HVollog <= X"155";
WHEN "1100" => HVollog <= X"0F1";
WHEN "1011" => HVollog <= X"0AA";
WHEN "1010" => HVollog <= X"078";
WHEN "1001" => HVollog <= X"055";
WHEN "1000" => HVollog <= X"03C";
WHEN "0111" => HVollog <= X"02A";
WHEN "0110" => HVollog <= X"01E";
WHEN "0101" => HVollog <= X"015";
WHEN "0100" => HVollog <= X"00F";
WHEN "0011" => HVollog <= X"00A";
WHEN "0010" => HVollog <= X"007";
WHEN "0001" => HVollog <= X"005";
WHEN "0000" => HVollog <= X"000";
WHEN OTHERS => null;
END CASE;
END process;
end logic;