Update turbosound.

This commit is contained in:
sorgelig
2020-05-11 23:43:24 +08:00
parent 5a66d5ec1c
commit c08d8479be
51 changed files with 4523 additions and 3446 deletions

View File

@ -1,178 +1,109 @@
`timescale 1ns / 1ps
/* This file is part of JT12.
JT12 program 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.
JT12 program 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.
JT12 program 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.
JT12 program 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 JT12. If not, see <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU General Public License
along with JT12. If not, see <http://www.gnu.org/licenses/>.
Author: Jose Tejada Gomez. Twitter: @topapate
Version: 1.0
Date: 27-1-2017
Each channel can use the full range of the DAC as they do not
get summed in the real chip.
Operator data is summed up without adding extra bits. This is
the case of real YM3438, which was used on Megadrive 2 models.
Author: Jose Tejada Gomez. Twitter: @topapate
Version: 1.0
Date: 27-1-2017
Each channel can use the full range of the DAC as they do not
get summed in the real chip.
*/
/*
YM2612 had a limiter to prevent overflow
YM3438 did not
JT12 always has a limiter enabled
*/
`timescale 1ns / 1ps
module jt12_acc
(
input rst,
input clk,
input signed [8:0] op_result,
input [ 1:0] rl,
input limiter_en, // enables the limiter on
// the accumulator to prevent overfow.
// I reckon that:
// YM2612 had a limiter
// YM3438 did not
// note that the order changes to deal
// with the operator pipeline delay
input s1_enters,
input s2_enters,
input s3_enters,
input s4_enters,
input ch6op,
input [2:0] alg,
input pcm_en, // only enabled for channel 6
input [8:0] pcm,
// combined output
output reg signed [11:0] left,
output reg signed [11:0] right,
output sample,
// multiplexed output
output reg signed [8:0] mux_left,
output reg signed [8:0] mux_right,
output reg mux_sample
module jt12_acc(
input rst,
input clk,
input clk_en,
input signed [8:0] op_result,
input [ 1:0] rl,
input zero,
input s1_enters,
input s2_enters,
input s3_enters,
input s4_enters,
input ch6op,
input [2:0] alg,
input pcm_en, // only enabled for channel 6
input signed [8:0] pcm,
// combined output
output reg signed [11:0] left,
output reg signed [11:0] right
);
reg signed [11:0] pre_left, pre_right;
wire signed [8:0] total;
parameter num_ch=6;
reg sum_en;
always @(*) begin
case ( alg )
default: sum_en <= s4_enters;
3'd4: sum_en <= s2_enters | s4_enters;
3'd5,3'd6: sum_en <= ~s1_enters;
3'd7: sum_en <= 1'b1;
case ( alg )
default: sum_en = s4_enters;
3'd4: sum_en = s2_enters | s4_enters;
3'd5,3'd6: sum_en = ~s1_enters;
3'd7: sum_en = 1'b1;
endcase
end
reg sum_all;
assign sample = ~sum_all;
wire [8:0] buffer;
reg [8:0] buffer2;
reg [8:0] buf_mux;
reg [1:0] rl2,rl3;
reg last_s1;
reg [1:0] mux_cnt;
reg pcm_sum;
wire signed [11:0] total_signext = { {3{total[8]}}, total };
always @(posedge clk) if(clk_en)
if( zero ) pcm_sum <= 1'b1;
else if( ch6op ) pcm_sum <= 1'b0;
always @(posedge clk) begin : mux_dac_input
buffer2 <= buffer;
rl2 <= rl;
last_s1 <= s1_enters;
mux_cnt <= last_s1 && s3_enters ? 2'd01 : mux_cnt + 1'b1;
if( mux_cnt==2'b11 ) begin
if( s1_enters || s3_enters ) begin
buf_mux <= buffer2;
rl3 <= rl2;
end
else begin
buf_mux <= buffer;
rl3 <= rl;
end
end
if( mux_cnt==2'd0 ) begin
mux_left <= rl3[1] ? buf_mux : 9'd0;
mux_right<= rl3[0] ? buf_mux : 9'd0;
mux_sample <= 1'b1;
end
else
mux_sample <= 1'b0;
end
wire use_pcm = ch6op && pcm_en;
wire sum_or_pcm = sum_en | use_pcm;
wire left_en = rl[1];
wire right_en= rl[0];
wire signed [8:0] pcm_data = pcm_sum ? pcm : 9'd0;
wire [8:0] acc_input = use_pcm ? pcm_data : op_result;
always @(posedge clk) begin
if( rst ) begin
sum_all <= 1'b0;
end
else begin
if( s3_enters ) begin
sum_all <= 1'b1;
if( !sum_all ) begin
pre_right <= rl[0] ? total_signext : 12'd0;
pre_left <= rl[1] ? total_signext : 12'd0;
end
else begin
pre_right <= pre_right + (rl[0] ? total_signext : 12'd0);
pre_left <= pre_left + (rl[1] ? total_signext : 12'd0);
end
end
if( s2_enters ) begin
sum_all <= 1'b0;
left <= pre_left;
right <= pre_right;
`ifdef DUMPSOUND
$strobe("%d\t%d", left, right);
`endif
end
end
end
reg signed [8:0] next, opsum, prev;
wire signed [9:0] opsum10 = next+total;
always @(*) begin
next <= sum_en ? op_result : 9'd0;
if( s3_enters )
opsum <= (ch6op && pcm_en) ? { ~pcm[8], pcm[7:0] } : next;
else begin
if( sum_en && !(ch6op && pcm_en) )
if( limiter_en ) begin
if( opsum10[9]==opsum10[8] )
opsum <= opsum10[8:0];
else begin
opsum <= opsum10[9] ? 9'h100 : 9'h0ff;
end
end
else begin
// MSB is discarded according to
// YM3438 application notes
opsum <= opsum10[8:0];
end
else
opsum <= total;
end
end
jt12_sh #(.width(9),.stages(6)) u_acc(
.clk ( clk ),
.din ( opsum ),
.drop ( total )
// Continuous output
wire signed [11:0] pre_left, pre_right;
jt12_single_acc #(.win(9),.wout(12)) u_left(
.clk ( clk ),
.clk_en ( clk_en ),
.op_result ( acc_input ),
.sum_en ( sum_or_pcm & left_en ),
.zero ( zero ),
.snd ( pre_left )
);
jt12_sh #(.width(9),.stages(6)) u_buffer(
.clk ( clk ),
.din ( s3_enters ? total : buffer ),
.drop ( buffer )
jt12_single_acc #(.win(9),.wout(12)) u_right(
.clk ( clk ),
.clk_en ( clk_en ),
.op_result ( acc_input ),
.sum_en ( sum_or_pcm & right_en ),
.zero ( zero ),
.snd ( pre_right )
);
// Output can be amplied by 8/6=1.33 to use full range
// an easy alternative is to add 1/4th and get 1.25 amplification
always @(posedge clk) if(clk_en) begin
left <= pre_left + { {2{left [11]}}, left [11:2] };
right <= pre_right + { {2{right[11]}}, right[11:2] };
end
endmodule