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:
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
Reference in New Issue
Block a user