1
0
mirror of https://github.com/Gehstock/Mist_FPGA.git synced 2026-04-30 05:45:29 +00:00

Remove garbage

This commit is contained in:
Gyorgy Szombathelyi
2021-03-31 12:23:31 +02:00
parent b304707536
commit d55d98ed1e
57 changed files with 0 additions and 13801 deletions

View File

@@ -1,278 +0,0 @@
module AY8912
(
input CLK, // Global clock
input CE, // PSG Clock enable
input RESET, // Chip RESET (set all Registers to '0', active hi)
input BDIR, // Bus Direction (0 - read , 1 - write)
input BC, // Bus control
input [7:0] DI, // Data In
output [7:0] DO, // Data Out
output [7:0] CHANNEL_A, // PSG Output channel A
output [7:0] CHANNEL_B, // PSG Output channel B
output [7:0] CHANNEL_C, // PSG Output channel C
input SEL,
input [7:0] IO_in,
output [7:0] IO_out
);
assign IO_out = ymreg[14];
reg ena_div;
reg ena_div_noise;
reg [3:0] addr;
reg [7:0] ymreg[16];
reg env_ena;
reg [4:0] env_vol;
wire [7:0] volTableAy[16] =
'{8'h00, 8'h03, 8'h04, 8'h06,
8'h0a, 8'h0f, 8'h15, 8'h22,
8'h28, 8'h41, 8'h5b, 8'h72,
8'h90, 8'hb5, 8'hd7, 8'hff
};
// Read from AY
assign DO = dout;
reg [7:0] dout;
always_comb begin
case(addr)
0: dout = ymreg[0];
1: dout = {4'b0000, ymreg[1][3:0]};
2: dout = ymreg[2];
3: dout = {4'b0000, ymreg[3][3:0]};
4: dout = ymreg[4];
5: dout = {4'b0000, ymreg[5][3:0]};
6: dout = {3'b000, ymreg[6][4:0]};
7: dout = ymreg[7];
8: dout = {3'b000, ymreg[8][4:0]};
9: dout = {3'b000, ymreg[9][4:0]};
10: dout = {3'b000, ymreg[10][4:0]};
11: dout = ymreg[11];
12: dout = ymreg[12];
13: dout = {4'b0000, ymreg[13][3:0]};
14: dout = (ymreg[7][6] ? ymreg[14] : IO_in);
15: dout = (ymreg[7][7] ? ymreg[15] : IO_in);
endcase
end
// p_divider
always @(posedge CLK) begin
reg [3:0] cnt_div;
reg noise_div;
if(CE) begin
ena_div <= 0;
ena_div_noise <= 0;
if(!cnt_div) begin
cnt_div <= {SEL, 3'b111};
ena_div <= 1;
noise_div <= (~noise_div);
if (noise_div) ena_div_noise <= 1;
end else begin
cnt_div <= cnt_div - 1'b1;
end
end
end
reg [16:0] poly17;
wire [4:0] noise_gen_comp = ymreg[6][4:0] ? ymreg[6][4:0] - 1'd1 : 5'd0;
// p_noise_gen
always @(posedge CLK) begin
reg [4:0] noise_gen_cnt;
if(CE) begin
if (ena_div_noise) begin
if (noise_gen_cnt >= noise_gen_comp) begin
noise_gen_cnt <= 0;
poly17 <= {(poly17[0] ^ poly17[2] ^ !poly17), poly17[16:1]};
end else begin
noise_gen_cnt <= noise_gen_cnt + 1'd1;
end
end
end
end
wire [11:0] tone_gen_freq[1:3];
assign tone_gen_freq[1] = {ymreg[1][3:0], ymreg[0]};
assign tone_gen_freq[2] = {ymreg[3][3:0], ymreg[2]};
assign tone_gen_freq[3] = {ymreg[5][3:0], ymreg[4]};
wire [11:0] tone_gen_comp[1:3];
assign tone_gen_comp[1] = tone_gen_freq[1] ? tone_gen_freq[1] - 1'd1 : 12'd0;
assign tone_gen_comp[2] = tone_gen_freq[2] ? tone_gen_freq[2] - 1'd1 : 12'd0;
assign tone_gen_comp[3] = tone_gen_freq[3] ? tone_gen_freq[3] - 1'd1 : 12'd0;
reg [3:1] tone_gen_op;
//p_tone_gens
always @(posedge CLK) begin
integer i;
reg [11:0] tone_gen_cnt[1:3];
if(CE) begin
// looks like real chips count up - we need to get the Exact behaviour ..
for (i = 1; i <= 3; i = i + 1) begin
if(ena_div) begin
if (tone_gen_cnt[i] >= tone_gen_comp[i]) begin
tone_gen_cnt[i] <= 0;
tone_gen_op[i] <= (~tone_gen_op[i]);
end else begin
tone_gen_cnt[i] <= tone_gen_cnt[i] + 1'd1;
end
end
end
end
end
wire [15:0] env_gen_comp = {ymreg[12], ymreg[11]} ? {ymreg[12], ymreg[11]} - 1'd1 : 16'd0;
//p_envelope_freq
always @(posedge CLK) begin
reg [15:0] env_gen_cnt;
if(CE) begin
env_ena <= 0;
if(ena_div) begin
if (env_gen_cnt >= env_gen_comp) begin
env_gen_cnt <= 0;
env_ena <= 1;
end else begin
env_gen_cnt <= (env_gen_cnt + 1'd1);
end
end
end
end
wire is_bot = (env_vol == 5'b00000);
wire is_bot_p1 = (env_vol == 5'b00001);
wire is_top_m1 = (env_vol == 5'b11110);
wire is_top = (env_vol == 5'b11111);
always @(posedge CLK) begin
reg old_BDIR;
reg env_reset;
reg env_hold;
reg env_inc;
// envelope shapes
// C AtAlH
// 0 0 x x \___
//
// 0 1 x x /___
//
// 1 0 0 0 \\\\
//
// 1 0 0 1 \___
//
// 1 0 1 0 \/\/
// ___
// 1 0 1 1 \
//
// 1 1 0 0 ////
// ___
// 1 1 0 1 /
//
// 1 1 1 0 /\/\
//
// 1 1 1 1 /___
if(RESET) begin
ymreg[0] <= 0;
ymreg[1] <= 0;
ymreg[2] <= 0;
ymreg[3] <= 0;
ymreg[4] <= 0;
ymreg[5] <= 0;
ymreg[6] <= 0;
ymreg[7] <= 255;
ymreg[8] <= 0;
ymreg[9] <= 0;
ymreg[10] <= 0;
ymreg[11] <= 0;
ymreg[12] <= 0;
ymreg[13] <= 0;
ymreg[14] <= 0;
ymreg[15] <= 0;
addr <= 0;
env_vol <= 0;
end else begin
old_BDIR <= BDIR;
if(~old_BDIR & BDIR) begin
if(BC) addr <= DI[3:0];
else begin
ymreg[addr] <= DI;
env_reset <= (addr == 13);
end
end
end
if(CE) begin
if(env_reset) begin
env_reset <= 0;
// load initial state
if(!ymreg[13][2]) begin // attack
env_vol <= 5'b11111;
env_inc <= 0; // -1
end else begin
env_vol <= 5'b00000;
env_inc <= 1; // +1
end
env_hold <= 0;
end else begin
if (env_ena) begin
if (!env_hold) begin
if (env_inc) env_vol <= (env_vol + 5'b00001);
else env_vol <= (env_vol + 5'b11111);
end
// envelope shape control.
if(!ymreg[13][3]) begin
if(!env_inc) begin // down
if(is_bot_p1) env_hold <= 1;
end else if (is_top) env_hold <= 1;
end else if(ymreg[13][0]) begin // hold = 1
if(!env_inc) begin // down
if(ymreg[13][1]) begin // alt
if(is_bot) env_hold <= 1;
end else if(is_bot_p1) env_hold <= 1;
end else if(ymreg[13][1]) begin // alt
if(is_top) env_hold <= 1;
end else if(is_top_m1) env_hold <= 1;
end else if(ymreg[13][1]) begin // alternate
if(env_inc == 1'b0) begin // down
if(is_bot_p1) env_hold <= 1;
if(is_bot) begin
env_hold <= 0;
env_inc <= 1;
end
end else begin
if(is_top_m1) env_hold <= 1;
if(is_top) begin
env_hold <= 0;
env_inc <= 0;
end
end
end
end
end
end
end
wire [4:0] A = ~((ymreg[7][0] | tone_gen_op[1]) & (ymreg[7][3] | poly17[0])) ? 5'd0 : ymreg[8][4] ? env_vol[4:0] : { ymreg[8][3:0], ymreg[8][3]};
wire [4:0] B = ~((ymreg[7][1] | tone_gen_op[2]) & (ymreg[7][4] | poly17[0])) ? 5'd0 : ymreg[9][4] ? env_vol[4:0] : { ymreg[9][3:0], ymreg[9][3]};
wire [4:0] C = ~((ymreg[7][2] | tone_gen_op[3]) & (ymreg[7][5] | poly17[0])) ? 5'd0 : ymreg[10][4] ? env_vol[4:0] : {ymreg[10][3:0], ymreg[10][3]};
assign CHANNEL_A = volTableAy[A[4:1]];
assign CHANNEL_B = volTableAy[B[4:1]];
assign CHANNEL_C = volTableAy[C[4:1]];
endmodule

View File

@@ -1,308 +0,0 @@
// ports are not identical to the actual AY chip - no need for that.
// Also the parallel ports are not very useful, so they are not connected
module ay8910(rst_n,clk,clk_en,asel,wr_n,cs_n,din,dout,A,B,C,audio);
input rst_n;
input clk; // 28 MHz clock from the system
input clk_en; // 1.7 (?) clock to run the sound timing
input asel;
input wr_n;
input cs_n;
input [7:0] din;
output [7:0] dout;
output [7:0] A;
output [7:0] B;
output [7:0] C;
output [7:0] audio;
/////////////////////////////////////////////////////////////////////////////
// Write Register
/////////////////////////////////////////////////////////////////////////////
reg [3:0] addr;
// registers
reg [11:0] period_a,period_b,period_c;
reg [4:0] period_n;
reg [7:0] reg_en;
reg [4:0] vol_a,vol_b,vol_c;
reg [15:0] period_e;
reg [3:0] shape_e;
reg [7:0] pa_r,pb_r;
wire pb_od = reg_en[7];
wire pa_od = reg_en[6];
wire na = reg_en[5];
wire nb = reg_en[4];
wire nc = reg_en[3];
wire ena = reg_en[2];
wire enb = reg_en[1];
wire enc = reg_en[0];
always @(posedge clk)
if(~rst_n) begin
vol_a <= 0;
vol_b <= 0;
vol_c <= 0;
end else
if(~wr_n && ~cs_n) begin
if(asel)
begin
// address write
addr <= din[3:0];
end else begin
// register write
case(addr)
0:period_a[ 7:0] <= din;
1:period_a[11:8] <= din[3:0];
2:period_b[ 7:0] <= din;
3:period_b[11:8] <= din[3:0];
4:period_c[ 7:0] <= din;
5:period_c[11:8] <= din[3:0];
6:period_n[ 4:0] <= din[4:0];
7:reg_en <= din;
8:vol_a <= din[4:0];
9:vol_b <= din[4:0];
10:vol_c <= din[4:0];
11:period_e[7:0] <= din;
12:period_e[15:8] <= din;
13:shape_e <= din[3:0];
14:pa_r <= din;
15:pb_r <= din;
endcase
end
end
/////////////////////////////////////////////////////////////////////////////
// Read Register
/////////////////////////////////////////////////////////////////////////////
assign dout = addr==4'h0 ? period_a[7:0] :
addr==4'h1 ? {4'h0,period_a[11:0]} :
addr==4'h2 ? period_b[7:0] :
addr==4'h3 ? {4'h0,period_b[11:0]} :
addr==4'h4 ? period_c[7:0] :
addr==4'h5 ? {4'h0,period_c[11:0]} :
addr==4'h6 ? {3'h0,period_n} :
addr==4'h7 ? reg_en :
addr==4'h8 ? {3'h0,vol_a} :
addr==4'h9 ? {3'h0,vol_b} :
addr==4'ha ? {3'h0,vol_c} :
addr==4'hb ? period_e[7:0] :
addr==4'hc ? period_e[15:8] :
addr==4'hd ? {4'h0,shape_e} : 8'hff;
/////////////////////////////////////////////////////////////////////////////
// PSG
/////////////////////////////////////////////////////////////////////////////
//
// toneA 12bit | 12bit
// toneB 12bit | 12bit
// toneC 12bit | 12bit
// env 15bit | 15bit
//
reg [2:0] pris;
reg [11:0] cnt_a,cnt_b,cnt_c;
reg out_a,out_b,out_c;
always @(posedge clk)
if(clk_en) begin
pris <= pris + 1;
if(pris==0)
begin
// tone generator
cnt_a <= cnt_a + 1;
if(cnt_a==period_a)
begin
out_a <= ~out_a;
cnt_a <= 0;
end
cnt_b <= cnt_b + 1;
if(cnt_b==period_b)
begin
out_b <= ~out_b;
cnt_b <= 0;
end
cnt_c <= cnt_c + 1;
if(cnt_c==period_c)
begin
out_c <= ~out_c;
cnt_c <= 0;
end
end
end
/////////////////////////////////////////////////////////////////////////////
// envelope generator
/////////////////////////////////////////////////////////////////////////////
reg [15:0] env_cnt;
reg [3:0] env_phase;
reg env_start;
reg env_en;
reg env_inv;
// write eshape
wire env_clr = (addr==13) & ~cs_n & ~wr_n;
// bit3 = turn reset , 0=on , 1=off
// bit2 = start , 0=up , 1=down(inv)
// bit1 = turn invert, 0=tggle , 1=fix
// bit0 = turn repeat, 0=off, 1=on
wire next_no_reset = shape_e[3];
wire start_no_inv = shape_e[2];
wire next_toggle = shape_e[1];
wire next_repeat = shape_e[0];
// envelope volume output
wire [3:0] vol_e = env_phase ^ {4{env_inv}};
//
always @(posedge clk or posedge env_clr)
begin
if(env_clr) env_start <= 1'b1;
else if(clk_en) env_start <= 1'b0;
end
always @(posedge clk or negedge rst_n)
begin
if(~rst_n)
begin
env_en <= 1'b0;
end else
if(clk_en)begin
// start trigger
if(env_start)
begin
env_cnt <= 0;
env_phase <= 0;
env_inv <= ~start_no_inv;
env_en <= 1'b1;
end
// count
if(pris==0 && env_en)
begin
// phase up
env_cnt <= env_cnt + 1;
if(env_cnt==period_e)
begin
env_cnt <= 0;
env_phase <= env_phase+1;
// turn over
if(env_phase==15)
begin
if(~next_no_reset)
begin
env_inv <= (env_inv ^ next_toggle) & next_no_reset;
env_en <= next_repeat & next_no_reset;
end
end
end
end
end
end
/////////////////////////////////////////////////////////////////////////////
// noise generator
/////////////////////////////////////////////////////////////////////////////
reg [16:0] shift_n;
reg [4:0] cnt_n;
always @(posedge clk or negedge rst_n)
begin
if(~rst_n)
begin
shift_n <= 17'b00000000000000001;
end else if((pris==0) &&(clk_en))
begin
cnt_n <= cnt_n +1;
if(cnt_n == period_n)
begin
cnt_n <= 0;
shift_n <= {shift_n[0]^shift_n[3],shift_n[16:1]};
end
end
end
wire out_n = shift_n[0];
/////////////////////////////////////////////////////////////////////////////
// volume table 3db / step
/////////////////////////////////////////////////////////////////////////////
function [7:0] vol_tbl;
input [4:0] vol;
input [3:0] vole;
input out;
begin
if(~out)
vol_tbl = 0;
else case(vol[4]?vole:vol[3:0])
15:vol_tbl = 255;
14:vol_tbl = 180;
13:vol_tbl = 127;
12:vol_tbl = 90;
11:vol_tbl = 64;
10:vol_tbl = 45;
9:vol_tbl = 32;
8:vol_tbl = 22;
7:vol_tbl = 16;
6:vol_tbl = 11;
5:vol_tbl = 8;
4:vol_tbl = 5;
3:vol_tbl = 4;
2:vol_tbl = 3;
1:vol_tbl = 2;
0:vol_tbl = 0; //1;
endcase
end
endfunction
/////////////////////////////////////////////////////////////////////////////
// output
/////////////////////////////////////////////////////////////////////////////
assign A = vol_tbl(vol_a,vol_e,(out_a | ena) & (out_n | na) );
assign B = vol_tbl(vol_b,vol_e,(out_b | enb) & (out_n | nb) );
assign C = vol_tbl(vol_c,vol_e,(out_c | enc) & (out_n | nc) );
assign audio = {"00",A} + {"00",B} + {"00",C};//todo gehstock
endmodule

View File

@@ -1,380 +0,0 @@
------------------------------------------------------------------------------
------------------------------------------------------------------------------
-- --
-- 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;

View File

@@ -1,375 +0,0 @@
------------------------------------------------------------------------------
------------------------------------------------------------------------------
-- --
-- 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 ay8913 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);
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 ay8913;
architecture logic of ay8913 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" =>
t_Data <= PortA;
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;