diff --git a/Arcade_MiST/Konami TimePilot84/TP84.qsf b/Arcade_MiST/Konami TimePilot84/TP84.qsf
index 43bbb948..28d79246 100644
--- a/Arcade_MiST/Konami TimePilot84/TP84.qsf
+++ b/Arcade_MiST/Konami TimePilot84/TP84.qsf
@@ -225,7 +225,6 @@ set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS ON
set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS ON
set_global_assignment -name SMART_RECOMPILE ON
-set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
set_global_assignment -name SYSTEMVERILOG_FILE rtl/TimePilot84_MiST.sv
set_global_assignment -name SYSTEMVERILOG_FILE rtl/TimePilot84.sv
set_global_assignment -name SYSTEMVERILOG_FILE rtl/TimePilot84_CPU.sv
@@ -244,4 +243,5 @@ set_global_assignment -name SIGNALTAP_FILE output_files/char.stp
set_global_assignment -name SIGNALTAP_FILE output_files/cpu.stp
set_global_assignment -name SIGNALTAP_FILE output_files/sdram.stp
set_global_assignment -name SIGNALTAP_FILE output_files/spr.stp
-set_global_assignment -name SIGNALTAP_FILE output_files/snd.stp
\ No newline at end of file
+set_global_assignment -name SIGNALTAP_FILE output_files/snd.stp
+set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
\ No newline at end of file
diff --git a/Console_MiST/Supervision_MiST/rtl/Supervision_MiST.sv b/Console_MiST/Supervision_MiST/rtl/Supervision_MiST.sv
index 23a02ec6..2c94f913 100644
--- a/Console_MiST/Supervision_MiST/rtl/Supervision_MiST.sv
+++ b/Console_MiST/Supervision_MiST/rtl/Supervision_MiST.sv
@@ -197,7 +197,7 @@ dac #(
dac_l(
.clk_i(clk_sys),
.res_n_i(1),
- .dac_i(audio_ch2),
+ .dac_i(audio_ch1),
.dac_o(AUDIO_L)
);
@@ -206,12 +206,11 @@ dac #(
dac_r(
.clk_i(clk_sys),
.res_n_i(1),
- .dac_i(audio_ch1),
+ .dac_i(audio_ch2),
.dac_o(AUDIO_R)
);
wire m_up, m_down, m_left, m_right, m_fireA, m_fireB, m_fireC, m_fireD, m_fireE, m_fireF;
-wire m_up2, m_down2, m_left2, m_right2, m_fire2A, m_fire2B, m_fire2C, m_fire2D, m_fire2E, m_fire2F;
wire m_tilt, m_coin1, m_coin2, m_coin3, m_coin4, m_one_player, m_two_players, m_three_players, m_four_players;
arcade_inputs inputs (
@@ -220,13 +219,10 @@ arcade_inputs inputs (
.key_pressed ( key_pressed ),
.key_code ( key_code ),
.joystick_0 ( joystick_0 ),
- //.rotate ( rotate ),
- //.orientation ( orientation ),
.joyswap ( status[6] ),
.oneplayer ( 1'b1 ),
.controls ( {m_tilt, m_coin4, m_coin3, m_coin2, m_coin1, m_four_players, m_three_players, m_two_players, m_one_player} ),
- .player1 ( {m_fireF, m_fireE, m_fireD, m_fireC, m_fireB, m_fireA, m_up, m_down, m_left, m_right} ),
- .player2 ( {m_fire2F, m_fire2E, m_fire2D, m_fire2C, m_fire2B, m_fire2A, m_up2, m_down2, m_left2, m_right2} )
+ .player1 ( {m_fireF, m_fireE, m_fireD, m_fireC, m_fireB, m_fireA, m_up, m_down, m_left, m_right} )
);
endmodule
\ No newline at end of file
diff --git a/Console_MiST/Supervision_MiST/rtl/Supervision_Top.sv b/Console_MiST/Supervision_MiST/rtl/Supervision_Top.sv
index b70b664a..bc2abce2 100644
--- a/Console_MiST/Supervision_MiST/rtl/Supervision_Top.sv
+++ b/Console_MiST/Supervision_MiST/rtl/Supervision_Top.sv
@@ -92,7 +92,7 @@ always @(posedge clk_cpu)
else
timer_div <= 14'hff;
- irq_timer
+// irq_timer
always @(posedge clk_cpu)
if (sys_cs && cpu_we && AB[2:0] == 3'h3)
irq_timer <= cpu_dout;
@@ -239,7 +239,7 @@ always @(posedge clk_sys)
//);
assign cpu_rom_addr = rom_addr;
-assign rom_dout = rom_cs ? cpu_rom_data : 8'hff;
+assign rom_dout = cpu_rom_data;
ram88 wram(
@@ -330,5 +330,4 @@ cpu_65c02 cpu(
.RDY(cpu_rdy)
);
-
endmodule
\ No newline at end of file
diff --git a/common/Sound/JT49/jt49.qip b/common/Sound/JT49/jt49.qip
new file mode 100644
index 00000000..ccc7d580
--- /dev/null
+++ b/common/Sound/JT49/jt49.qip
@@ -0,0 +1,8 @@
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt49.v]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt49_bus.v]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt49_cen.v]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt49_div.v]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt49_eg.v]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt49_exp.v]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt49_noise.v]
+
diff --git a/common/Sound/JT49/jt49.v b/common/Sound/JT49/jt49.v
new file mode 100644
index 00000000..e02eaeef
--- /dev/null
+++ b/common/Sound/JT49/jt49.v
@@ -0,0 +1,224 @@
+/* This file is part of JT49.
+
+ JT49 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.
+
+ JT49 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 JT49. If not, see .
+
+ Author: Jose Tejada Gomez. Twitter: @topapate
+ Version: 1.0
+ Date: 10-Nov-2018
+
+ Based on sqmusic, by the same author
+
+ */
+
+module jt49 ( // note that input ports are not multiplexed
+ input rst_n,
+ input clk, // signal on positive edge
+ input clk_en,
+ input [3:0] addr,
+ input cs_n,
+ input wr_n, // write
+ input [7:0] din,
+ input sel, // if sel is low, the clock is divided by 2
+ output reg [7:0] dout,
+ output reg [7:0] A, // linearised channel output
+ output reg [7:0] B,
+ output reg [7:0] C
+);
+
+parameter [1:0] COMP=2'b00;
+parameter CLKDIV=3;
+wire [1:0] comp = COMP;
+
+reg [7:0] regarray[15:0];
+
+wire [4:0] envelope;
+wire bitA, bitB, bitC;
+wire noise;
+reg Amix, Bmix, Cmix;
+
+wire cen16, cen256;
+
+jt49_cen #(.CLKDIV(CLKDIV)) u_cen(
+ .clk ( clk ),
+ .rst_n ( rst_n ),
+ .cen ( clk_en ),
+ .sel ( sel ),
+ .cen16 ( cen16 ),
+ .cen256 ( cen256 )
+);
+
+// internal modules operate at clk/16
+jt49_div #(12) u_chA(
+ .clk ( clk ),
+ .rst_n ( rst_n ),
+ .cen ( cen16 ),
+ .period ( {regarray[1][3:0], regarray[0][7:0] } ),
+ .div ( bitA )
+);
+
+jt49_div #(12) u_chB(
+ .clk ( clk ),
+ .rst_n ( rst_n ),
+ .cen ( cen16 ),
+ .period ( {regarray[3][3:0], regarray[2][7:0] } ),
+ .div ( bitB )
+);
+
+jt49_div #(12) u_chC(
+ .clk ( clk ),
+ .rst_n ( rst_n ),
+ .cen ( cen16 ),
+ .period ( {regarray[5][3:0], regarray[4][7:0] } ),
+ .div ( bitC )
+);
+
+jt49_noise u_ng(
+ .clk ( clk ),
+ .cen ( cen16 ),
+ .rst_n ( rst_n ),
+ .period ( regarray[6][4:0] ),
+ .noise ( noise )
+);
+
+// envelope generator
+wire eg_step;
+wire [15:0] eg_period = {regarray[4'hc],regarray[4'hb]};
+wire null_period = eg_period == 16'h0;
+
+jt49_div #(16) u_envdiv(
+ .clk ( clk ),
+ .cen ( cen256 ),
+ .rst_n ( rst_n ),
+ .period ( eg_period ),
+ .div ( eg_step )
+);
+
+reg eg_restart;
+
+jt49_eg u_env(
+ .clk ( clk ),
+ .cen ( cen256 ),
+ .step ( eg_step ),
+ .rst_n ( rst_n ),
+ .restart ( eg_restart ),
+ .null_period( null_period ),
+ .ctrl ( regarray[4'hD][3:0] ),
+ .env ( envelope )
+);
+
+reg [4:0] logA, logB, logC, log;
+wire [7:0] lin;
+
+jt49_exp u_exp(
+ .clk ( clk ),
+ .comp ( comp ),
+ .din ( log ),
+ .dout ( lin )
+);
+
+wire [4:0] volA = { regarray[ 8][3:0], regarray[ 8][3] };
+wire [4:0] volB = { regarray[ 9][3:0], regarray[ 9][3] };
+wire [4:0] volC = { regarray[10][3:0], regarray[10][3] };
+wire use_envA = regarray[ 8][4];
+wire use_envB = regarray[ 9][4];
+wire use_envC = regarray[10][4];
+wire use_noA = regarray[ 7][3];
+wire use_noB = regarray[ 7][4];
+wire use_noC = regarray[ 7][5];
+
+reg [3:0] acc_st;
+
+always @(posedge clk) if( clk_en ) begin
+ Amix <= (noise|use_noA) & (bitA|regarray[7][0]);
+ Bmix <= (noise|use_noB) & (bitB|regarray[7][1]);
+ Cmix <= (noise|use_noC) & (bitC|regarray[7][2]);
+
+ logA <= !Amix ? 5'd0 : (use_envA ? envelope : volA );
+ logB <= !Bmix ? 5'd0 : (use_envB ? envelope : volB );
+ logC <= !Cmix ? 5'd0 : (use_envC ? envelope : volC );
+end
+
+always @(posedge clk, negedge rst_n) begin
+ if( !rst_n ) begin
+ acc_st <= 4'b1;
+ A <= 8'd0;
+ B <= 8'd0;
+ C <= 8'd0;
+ end else if(clk_en) begin
+ acc_st <= { acc_st[2:0], acc_st[3] };
+ case( acc_st )
+ 4'b0001: begin
+ log <= logA;
+ end
+ 4'b0010: begin
+ A <= lin;
+ log <= logB;
+ end
+ 4'b0100: begin
+ B <= lin;
+ log <= logC;
+ end
+ 4'b1000: begin // last sum
+ C <= lin;
+ end
+ default:;
+ endcase
+ end
+end
+
+reg [7:0] read_mask;
+
+always @(*)
+ case(addr)
+ 4'h0,4'h2,4'h4,4'h7,4'hb,4'hc,4'he,4'hf:
+ read_mask = 8'hff;
+ 4'h1,4'h3,4'h5,4'hd:
+ read_mask = 8'h0f;
+ 4'h6,4'h8,4'h9,4'ha:
+ read_mask = 8'h1f;
+ endcase // addr
+
+// register array
+wire write;
+reg last_write;
+wire wr_edge = write & ~last_write;
+
+assign write = !wr_n && !cs_n;
+
+always @(posedge clk, negedge rst_n) begin
+ if( !rst_n ) begin
+ dout <= 8'd0;
+ last_write <= 0;
+ eg_restart <= 0;
+ regarray[0]<=8'd0; regarray[4]<=8'd0; regarray[ 8]<=8'd0; regarray[12]<=8'd0;
+ regarray[1]<=8'd0; regarray[5]<=8'd0; regarray[ 9]<=8'd0; regarray[13]<=8'd0;
+ regarray[2]<=8'd0; regarray[6]<=8'd0; regarray[10]<=8'd0; regarray[14]<=8'd0;
+ regarray[3]<=8'd0; regarray[7]<=8'd0; regarray[11]<=8'd0; regarray[15]<=8'd0;
+ end else begin
+ last_write <= write;
+ // Data read
+ case( addr )
+ default: dout <= regarray[ addr ] & read_mask;
+ endcase
+ // Data write
+ if( write ) begin
+ regarray[addr] <= din;
+ if ( addr == 4'hD && wr_edge ) eg_restart <= 1;
+ end else begin
+ eg_restart <= 0;
+ end
+ end
+end
+
+endmodule
diff --git a/common/Sound/JT49/jt49_bus.v b/common/Sound/JT49/jt49_bus.v
new file mode 100644
index 00000000..ee5f3f2a
--- /dev/null
+++ b/common/Sound/JT49/jt49_bus.v
@@ -0,0 +1,87 @@
+/* This file is part of JT49.
+
+ JT49 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.
+
+ JT49 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 JT49. If not, see .
+
+ Author: Jose Tejada Gomez. Twitter: @topapate
+ Version: 1.0
+ Date: 28-Jan-2019
+
+ Based on sqmusic, by the same author
+
+ */
+
+// This is a wrapper with the BDIR/BC1 pins
+
+module jt49_bus ( // note that input ports are not multiplexed
+ input rst_n,
+ input clk, // signal on positive edge
+ input clk_en,
+ // bus control pins of original chip
+ input bdir,
+ input bc1,
+ input [7:0] din,
+
+ input sel, // if sel is low, the clock is divided by 2
+ output [7:0] dout,
+ output [7:0] A, // linearised channel output
+ output [7:0] B,
+ output [7:0] C
+);
+
+parameter [1:0] COMP=2'b00;
+
+reg wr_n, cs_n;
+reg [3:0] addr;
+reg addr_ok;
+reg [7:0] din_latch;
+
+always @(posedge clk)
+ if( !rst_n ) begin
+ wr_n <= 1'b1;
+ cs_n <= 1'b1;
+ addr <= 4'd0;
+ addr_ok <= 1'b1;
+ end else begin // I/O cannot use clk_en
+ // addr must be
+ case( {bdir,bc1} )
+ 2'b00: { wr_n, cs_n } <= 2'b11;
+ 2'b01: { wr_n, cs_n } <= addr_ok ? 2'b10 : 2'b11;
+ 2'b10: begin
+ { wr_n, cs_n } <= addr_ok ? 2'b00 : 2'b11;
+ din_latch <= din;
+ end
+ 2'b11: begin
+ { wr_n, cs_n } <= 2'b11;
+ addr <= din[3:0];
+ addr_ok <= din[7:4] == 4'd0;
+ end
+ endcase // {bdir,bc1}
+ end
+
+jt49 #(.COMP(COMP)) u_jt49( // note that input ports are not multiplexed
+ .rst_n ( rst_n ),
+ .clk ( clk ), // signal on positive edge
+ .clk_en ( clk_en ), // clock enable on negative edge
+ .addr ( addr[3:0] ),
+ .cs_n ( cs_n ),
+ .wr_n ( wr_n ), // write
+ .din ( din_latch ),
+ .sel ( sel ), // if sel is low, the clock is divided by 2
+ .dout ( dout ),
+ .A ( A ), // linearised channel output
+ .B ( B ),
+ .C ( C )
+);
+
+endmodule // jt49_bus
\ No newline at end of file
diff --git a/common/Sound/JT49/jt49_cen.v b/common/Sound/JT49/jt49_cen.v
new file mode 100644
index 00000000..a3ca1d1a
--- /dev/null
+++ b/common/Sound/JT49/jt49_cen.v
@@ -0,0 +1,56 @@
+/* This file is part of JT49.
+
+ JT49 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.
+
+ JT49 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 JT49. If not, see .
+
+ Author: Jose Tejada Gomez. Twitter: @topapate
+ Version: 1.0
+ Date: 10-Nov-2018
+
+ Based on sqmusic, by the same author
+
+ */
+
+module jt49_cen(
+ input clk,
+ input rst_n,
+ input cen, // base clock enable signal
+ input sel, // when low, divide by 2 once more
+ output reg cen16,
+ output reg cen256
+);
+
+parameter CLKDIV = 3; // use 3 for standalone JT49 or 2
+
+reg [CLKDIV:0] cencnt;
+localparam eg = CLKDIV; //8;
+
+wire toggle16 = sel ? ~|cencnt[CLKDIV-1:0] : ~|cencnt[CLKDIV:0];
+wire toggle256= sel ? ~|cencnt[eg-2:0] : ~|cencnt[eg-1:0];
+
+
+always @(posedge clk, negedge rst_n) begin
+ if(!rst_n)
+ cencnt <= 1'd0;
+ else begin
+ if(cen) cencnt <= cencnt+1'd1;
+ end
+end
+
+always @(posedge clk) begin
+ cen16 <= cen & toggle16;
+ cen256 <= cen & toggle256;
+end
+
+
+endmodule // jt49_cen
diff --git a/common/Sound/JT49/jt49_div.v b/common/Sound/JT49/jt49_div.v
new file mode 100644
index 00000000..7a0e0b3e
--- /dev/null
+++ b/common/Sound/JT49/jt49_div.v
@@ -0,0 +1,53 @@
+/* This file is part of JT49.
+
+ JT49 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.
+
+ JT49 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 JT49. If not, see .
+
+ Author: Jose Tejada Gomez. Twitter: @topapate
+ Version: 1.0
+ Date: 10-Nov-2018
+
+ Based on sqmusic, by the same author
+
+ */
+
+
+module jt49_div #(parameter W=12 )
+(
+ input wire clk, // this is the divided down clock from the core
+ input wire cen,
+ input wire rst_n,
+ input wire[W-1:0] period,
+ output reg div
+);
+
+reg [W-1:0]count;
+
+wire [W-1:0] one = { {W-1{1'b0}}, 1'b1};
+
+always @(posedge clk, negedge rst_n ) begin
+ if( !rst_n) begin
+ count <= one;
+ div <= 1'b0;
+ end
+ else if(cen) begin
+ if( count>=period ) begin
+ count <= one;
+ div <= ~div;
+ end
+ else
+ /*if( period!={W{1'b0}} )*/ count <= count + one ;
+ end
+end
+
+endmodule
diff --git a/common/Sound/JT49/jt49_eg.v b/common/Sound/JT49/jt49_eg.v
new file mode 100644
index 00000000..eda17d32
--- /dev/null
+++ b/common/Sound/JT49/jt49_eg.v
@@ -0,0 +1,88 @@
+/* This file is part of JT49.
+
+ JT49 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.
+
+ JT49 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 JT49. If not, see .
+
+ Author: Jose Tejada Gomez. Twitter: @topapate
+ Version: 1.0
+ Date: 10-Nov-2018
+
+ Based on sqmusic, by the same author
+
+ */
+
+module jt49_eg(
+ input wire cen,
+ input wire clk, // this is the divided down clock from the core
+ input wire step,
+ input wire null_period,
+ input wire rst_n,
+ input wire restart,
+ input wire[3:0] ctrl,
+ output reg [4:0] env
+);
+
+reg inv, stop;
+reg [4:0] gain;
+
+wire CONT = ctrl[3];
+wire ATT = ctrl[2];
+wire ALT = ctrl[1];
+wire HOLD = ctrl[0];
+
+wire will_hold = !CONT || HOLD;
+
+always @(posedge clk)
+ if( cen ) env <= inv ? ~gain : gain;
+
+reg last_step;
+wire step_edge = (step && !last_step) || null_period;
+wire will_invert = (!CONT&&ATT) || (CONT&&ALT);
+reg rst_latch, rst_clr;
+
+always @(posedge clk) begin
+ if( restart ) rst_latch <= 1;
+ else if(rst_clr ) rst_latch <= 0;
+end
+
+always @( posedge clk, negedge rst_n )
+ if( !rst_n) begin
+ gain <= 5'h1F;
+ inv <= 0;
+ stop <= 0;
+ rst_clr <= 0;
+ end
+ else if( cen ) begin
+ last_step <= step;
+ if( rst_latch ) begin
+ gain <= 5'h1F;
+ inv <= ATT;
+ stop <= 1'b0;
+ rst_clr <= 1;
+ end
+ else begin
+ rst_clr <= 0;
+ if (step_edge && !stop) begin
+ if( gain==5'h00 ) begin
+ if( will_hold )
+ stop <= 1'b1;
+ else
+ gain <= gain-5'b1;
+ if( will_invert ) inv<=~inv;
+ end
+ else gain <= gain-5'b1;
+ end
+ end
+ end
+
+endmodule
diff --git a/common/Sound/JT49/jt49_exp.v b/common/Sound/JT49/jt49_exp.v
new file mode 100644
index 00000000..6eb3eb21
--- /dev/null
+++ b/common/Sound/JT49/jt49_exp.v
@@ -0,0 +1,174 @@
+/* This file is part of JT49.
+
+ JT49 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.
+
+ JT49 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 JT49. If not, see .
+
+ Author: Jose Tejada Gomez. Twitter: @topapate
+ Version: 1.0
+ Date: 10-Nov-2018
+
+ Based on sqmusic, by the same author
+
+ */
+
+`timescale 1ns / 1ps
+
+// Compression vs dynamic range
+// 0 -> 43.6dB
+// 1 -> 29.1
+// 2 -> 21.8
+// 3 -> 13.4
+
+module jt49_exp(
+ input wire clk,
+ input wire[1:0] comp, // compression
+ input wire[4:0] din,
+ output reg [7:0] dout
+);
+
+reg [7:0] lut[0:127];
+wire[6:0] addr = {comp,din};
+always @(posedge clk) dout <= lut[addr];
+
+initial begin
+ lut[0] = 8'd0;
+ lut[1] = 8'd1;
+ lut[2] = 8'd1;
+ lut[3] = 8'd1;
+ lut[4] = 8'd2;
+ lut[5] = 8'd2;
+ lut[6] = 8'd3;
+ lut[7] = 8'd3;
+ lut[8] = 8'd4;
+ lut[9] = 8'd5;
+ lut[10] = 8'd6;
+ lut[11] = 8'd7;
+ lut[12] = 8'd9;
+ lut[13] = 8'd11;
+ lut[14] = 8'd13;
+ lut[15] = 8'd15;
+ lut[16] = 8'd18;
+ lut[17] = 8'd22;
+ lut[18] = 8'd26;
+ lut[19] = 8'd31;
+ lut[20] = 8'd37;
+ lut[21] = 8'd45;
+ lut[22] = 8'd53;
+ lut[23] = 8'd63;
+ lut[24] = 8'd75;
+ lut[25] = 8'd90;
+ lut[26] = 8'd107;
+ lut[27] = 8'd127;
+ lut[28] = 8'd151;
+ lut[29] = 8'd180;
+ lut[30] = 8'd214;
+ lut[31] = 8'd255;
+ lut[32] = 8'd0;
+ lut[33] = 8'd7;
+ lut[34] = 8'd8;
+ lut[35] = 8'd10;
+ lut[36] = 8'd11;
+ lut[37] = 8'd12;
+ lut[38] = 8'd14;
+ lut[39] = 8'd15;
+ lut[40] = 8'd17;
+ lut[41] = 8'd20;
+ lut[42] = 8'd22;
+ lut[43] = 8'd25;
+ lut[44] = 8'd28;
+ lut[45] = 8'd31;
+ lut[46] = 8'd35;
+ lut[47] = 8'd40;
+ lut[48] = 8'd45;
+ lut[49] = 8'd50;
+ lut[50] = 8'd56;
+ lut[51] = 8'd63;
+ lut[52] = 8'd71;
+ lut[53] = 8'd80;
+ lut[54] = 8'd90;
+ lut[55] = 8'd101;
+ lut[56] = 8'd113;
+ lut[57] = 8'd127;
+ lut[58] = 8'd143;
+ lut[59] = 8'd160;
+ lut[60] = 8'd180;
+ lut[61] = 8'd202;
+ lut[62] = 8'd227;
+ lut[63] = 8'd255;
+ lut[64] = 8'd0;
+ lut[65] = 8'd18;
+ lut[66] = 8'd20;
+ lut[67] = 8'd22;
+ lut[68] = 8'd24;
+ lut[69] = 8'd26;
+ lut[70] = 8'd29;
+ lut[71] = 8'd31;
+ lut[72] = 8'd34;
+ lut[73] = 8'd37;
+ lut[74] = 8'd41;
+ lut[75] = 8'd45;
+ lut[76] = 8'd49;
+ lut[77] = 8'd53;
+ lut[78] = 8'd58;
+ lut[79] = 8'd63;
+ lut[80] = 8'd69;
+ lut[81] = 8'd75;
+ lut[82] = 8'd82;
+ lut[83] = 8'd90;
+ lut[84] = 8'd98;
+ lut[85] = 8'd107;
+ lut[86] = 8'd116;
+ lut[87] = 8'd127;
+ lut[88] = 8'd139;
+ lut[89] = 8'd151;
+ lut[90] = 8'd165;
+ lut[91] = 8'd180;
+ lut[92] = 8'd196;
+ lut[93] = 8'd214;
+ lut[94] = 8'd233;
+ lut[95] = 8'd255;
+ lut[96] = 8'd0;
+ lut[97] = 8'd51;
+ lut[98] = 8'd54;
+ lut[99] = 8'd57;
+ lut[100] = 8'd60;
+ lut[101] = 8'd63;
+ lut[102] = 8'd67;
+ lut[103] = 8'd70;
+ lut[104] = 8'd74;
+ lut[105] = 8'd78;
+ lut[106] = 8'd83;
+ lut[107] = 8'd87;
+ lut[108] = 8'd92;
+ lut[109] = 8'd97;
+ lut[110] = 8'd103;
+ lut[111] = 8'd108;
+ lut[112] = 8'd114;
+ lut[113] = 8'd120;
+ lut[114] = 8'd127;
+ lut[115] = 8'd134;
+ lut[116] = 8'd141;
+ lut[117] = 8'd149;
+ lut[118] = 8'd157;
+ lut[119] = 8'd166;
+ lut[120] = 8'd175;
+ lut[121] = 8'd185;
+ lut[122] = 8'd195;
+ lut[123] = 8'd206;
+ lut[124] = 8'd217;
+ lut[125] = 8'd229;
+ lut[126] = 8'd241;
+ lut[127] = 8'd255;
+
+end
+endmodule
diff --git a/common/Sound/JT49/jt49_noise.v b/common/Sound/JT49/jt49_noise.v
new file mode 100644
index 00000000..2c244f9e
--- /dev/null
+++ b/common/Sound/JT49/jt49_noise.v
@@ -0,0 +1,63 @@
+/* This file is part of JT49.
+
+ JT49 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.
+
+ JT49 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 JT49. If not, see .
+
+ Author: Jose Tejada Gomez. Twitter: @topapate
+ Version: 1.0
+ Date: 10-Nov-2018
+
+ Based on sqmusic, by the same author
+
+ */
+
+`timescale 1ns / 1ps
+
+module jt49_noise(
+ input wire cen,
+ input wire clk,
+ input wire rst_n,
+ input wire[4:0] period,
+ output reg noise
+);
+
+reg[5:0] count;
+reg[16:0] poly17;
+wire poly17_zero = poly17==17'b0;
+wire noise_en;
+reg last_en;
+
+wire noise_up = noise_en && !last_en;
+
+always @(posedge clk ) if(cen) begin
+ noise <= ~poly17[0];
+end
+
+always @( posedge clk, negedge rst_n )
+ if( !rst_n )
+ poly17 <= 17'd0;
+ else if( cen ) begin
+ last_en <= noise_en;
+ if( noise_up )
+ poly17 <= { poly17[0] ^ poly17[3] ^ poly17_zero, poly17[16:1] };
+ end
+
+jt49_div #(5) u_div(
+ .clk ( clk ),
+ .cen ( cen ),
+ .rst_n ( rst_n ),
+ .period ( period ),
+ .div ( noise_en )
+);
+
+endmodule
\ No newline at end of file
diff --git a/common/Sound/jt89/jt89.qip b/common/Sound/jt89/jt89.qip
new file mode 100644
index 00000000..c685868e
--- /dev/null
+++ b/common/Sound/jt89/jt89.qip
@@ -0,0 +1,6 @@
+set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) jt89.vhd ]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt89.v ]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt89_noise.v ]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt89_vol.v ]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt89_mixer.v ]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt89_tone.v ]
diff --git a/common/Sound/jt89/jt89.v b/common/Sound/jt89/jt89.v
new file mode 100644
index 00000000..27cf2272
--- /dev/null
+++ b/common/Sound/jt89/jt89.v
@@ -0,0 +1,159 @@
+/* This file is part of JT89.
+
+ JT89 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.
+
+ JT89 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 JT89. If not, see .
+
+ Author: Jose Tejada Gomez. Twitter: @topapate
+ Version: 1.0
+ Date: March, 8th 2017
+
+ This work was originally based in the implementation found on the
+ SMS core of MiST. Some of the changes, all according to data sheet:
+
+ -Fixed volume
+ -Fixed tone 2 rate option of noise generator
+ -Fixed rate of noise generator
+ -Fixed noise shift clear
+ -Fixed noise generator update bug by which it gets updated
+ multiple times if v='0'
+ -Added all 0's prevention circuit to noise generator
+
+ */
+
+module jt89(
+ input clk,
+(* direct_enable = 1 *) input clk_en,
+ input rst,
+ input wr_n,
+ input [7:0] din,
+ output signed [10:0] sound,
+ output ready
+);
+
+parameter interpol16=0;
+
+wire signed [ 8:0] ch0, ch1, ch2, noise;
+
+assign ready = 1'b1;
+(* direct_enable = 1 *) reg cen_16;
+(* direct_enable = 1 *) reg cen_4;
+
+jt89_mixer #(.interpol16(interpol16)) mix(
+ .clk ( clk ),
+ .clk_en ( clk_en), // uses main clock enable
+ .cen_16 ( cen_16),
+ .cen_4 ( cen_4 ),
+ .rst ( rst ),
+ .ch0 ( ch0 ),
+ .ch1 ( ch1 ),
+ .ch2 ( ch2 ),
+ .noise ( noise ),
+ .sound ( sound )
+);
+
+// configuration registers
+reg [9:0] tone0, tone1, tone2;
+reg [3:0] vol0, vol1, vol2, vol3;
+reg [2:0] ctrl3;
+reg [2:0] regn;
+
+reg [3:0] clk_div;
+
+always @(posedge clk )
+ if( rst ) begin
+ cen_16 <= 1'b1;
+ cen_4 <= 1'b1;
+ end else begin
+ cen_16 <= clk_en & (&clk_div);
+ cen_4 <= clk_en & (&clk_div[1:0]);
+ end
+
+always @(posedge clk )
+ if( rst )
+ clk_div <= 4'd0;
+ else if( clk_en )
+ clk_div <= clk_div + 1'b1;
+
+reg clr_noise, last_wr;
+wire [2:0] reg_sel = din[7] ? din[6:4] : regn;
+
+always @(posedge clk)
+ if( rst ) begin
+ { vol0, vol1, vol2, vol3 } <= {16{1'b1}};
+ { tone0, tone1, tone2 } <= 30'd0;
+ ctrl3 <= 3'b100;
+ end
+ else begin
+ last_wr <= wr_n;
+ if( !wr_n && last_wr ) begin
+ clr_noise <= din[7:4] == 4'b1110; // clear noise
+ // when there is an access to the control register
+ regn <= reg_sel;
+ case( reg_sel )
+ 3'b00_0: if( din[7] ) tone0[3:0]<=din[3:0]; else tone0[9:4]<=din[5:0];
+ 3'b01_0: if( din[7] ) tone1[3:0]<=din[3:0]; else tone1[9:4]<=din[5:0];
+ 3'b10_0: if( din[7] ) tone2[3:0]<=din[3:0]; else tone2[9:4]<=din[5:0];
+ 3'b11_0: ctrl3 <= din[2:0];
+ 3'b00_1: vol0 <= din[3:0];
+ 3'b01_1: vol1 <= din[3:0];
+ 3'b10_1: vol2 <= din[3:0];
+ 3'b11_1: vol3 <= din[3:0];
+ endcase
+ end
+ else clr_noise <= 1'b0;
+ end
+
+jt89_tone u_tone0(
+ .clk ( clk ),
+ .rst ( rst ),
+ .clk_en ( cen_16 ),
+ .vol ( vol0 ),
+ .tone ( tone0 ),
+ .snd ( ch0 ),
+ .out ( )
+);
+
+jt89_tone u_tone1(
+ .clk ( clk ),
+ .rst ( rst ),
+ .clk_en ( cen_16 ),
+ .vol ( vol1 ),
+ .tone ( tone1 ),
+ .snd ( ch1 ),
+ .out ( )
+);
+
+wire out2;
+
+jt89_tone u_tone2(
+ .clk ( clk ),
+ .rst ( rst ),
+ .clk_en ( cen_16 ),
+ .vol ( vol2 ),
+ .tone ( tone2 ),
+ .snd ( ch2 ),
+ .out ( out2 )
+);
+
+jt89_noise u_noise(
+ .clk ( clk ),
+ .rst ( rst ),
+ .clk_en ( cen_16 ),
+ .clr ( clr_noise ),
+ .vol ( vol3 ),
+ .ctrl3 ( ctrl3 ),
+ .tone2 ( tone2 ),
+ .snd ( noise )
+);
+
+endmodule
diff --git a/common/Sound/jt89/jt89.vhd b/common/Sound/jt89/jt89.vhd
new file mode 100644
index 00000000..0735b53a
--- /dev/null
+++ b/common/Sound/jt89/jt89.vhd
@@ -0,0 +1,19 @@
+library IEEE;
+use IEEE.std_logic_1164.all;
+
+package jt89 is
+
+component jt89
+port
+(
+ rst : in std_logic;
+ clk : in std_logic; -- CPU clock
+ clk_en : in std_logic := '1'; -- optional clock enable, if not needed leave as '1'
+ din : in std_logic_vector(7 downto 0);
+ wr_n : in std_logic;
+ ready : out std_logic;
+ sound : out std_logic_vector(10 downto 0) -- signed
+);
+end component;
+
+end;
diff --git a/common/Sound/jt89/jt89_mixer.v b/common/Sound/jt89/jt89_mixer.v
new file mode 100644
index 00000000..06a646c3
--- /dev/null
+++ b/common/Sound/jt89/jt89_mixer.v
@@ -0,0 +1,68 @@
+/* This file is part of JT89.
+
+ JT89 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.
+
+ JT89 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 JT89. If not, see .
+
+ Author: Jose Tejada Gomez. Twitter: @topapate
+ Version: 1.0
+ Date: December, 1st 2018
+
+ */
+
+module jt89_mixer #(parameter bw=9, interpol16=0)(
+ input rst,
+ input clk,
+ input clk_en,
+ input cen_16,
+ input cen_4,
+ input [bw-1:0] ch0,
+ input [bw-1:0] ch1,
+ input [bw-1:0] ch2,
+ input [bw-1:0] noise,
+ output signed [bw+1:0] sound
+);
+
+reg signed [bw+1:0] fresh;
+
+always @(posedge clk)
+ fresh <=
+ { {2{ch0[bw-1]}}, ch0 }+
+ { {2{ch1[bw-1]}}, ch1 }+
+ { {2{ch2[bw-1]}}, ch2 }+
+ { {2{noise[bw-1]}}, noise };
+
+generate
+ if( interpol16==1 ) begin
+ wire signed [bw+1:0] snd4;
+ localparam calcw=bw+8;
+ jt12_interpol #(.calcw(calcw),.inw(bw+2),.rate(4),.m(4),.n(2)) u_uprate1 (
+ .rst ( rst ),
+ .clk ( clk ),
+ .cen_in ( cen_16 ),
+ .cen_out( cen_4 ),
+ .snd_in ( fresh ),
+ .snd_out( snd4 )
+ );
+ jt12_interpol #(.calcw(calcw),.inw(bw+2),.rate(4),.m(4),.n(2)) u_uprate2 (
+ .rst ( rst ),
+ .clk ( clk ),
+ .cen_in ( cen_4 ),
+ .cen_out( clk_en ),
+ .snd_in ( snd4 ),
+ .snd_out( sound )
+ );
+ end else
+ assign sound = fresh;
+endgenerate
+
+endmodule
\ No newline at end of file
diff --git a/common/Sound/jt89/jt89_noise.v b/common/Sound/jt89/jt89_noise.v
new file mode 100644
index 00000000..3120c665
--- /dev/null
+++ b/common/Sound/jt89/jt89_noise.v
@@ -0,0 +1,76 @@
+/* This file is part of JT89.
+
+ JT89 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.
+
+ JT89 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 JT89. If not, see .
+
+ Author: Jose Tejada Gomez. Twitter: @topapate
+ Version: 1.0
+ Date: March, 8th 2017
+
+ This work was originally based in the implementation found on the
+ SMS core of MiST
+
+ */
+
+module jt89_noise(
+ input clk,
+(* direct_enable = 1 *) input clk_en,
+ input rst,
+ input clr,
+ input [2:0] ctrl3,
+ input [3:0] vol,
+ input [9:0] tone2,
+ output [8:0] snd
+);
+
+reg [15:0] shift;
+reg [10:0] cnt;
+reg update;
+
+jt89_vol u_vol(
+ .rst ( rst ),
+ .clk ( clk ),
+ .clk_en ( clk_en ),
+ .din ( shift[0] ),
+ .vol ( vol ),
+ .snd ( snd )
+);
+
+always @(posedge clk)
+ if( rst ) begin
+ cnt <= 'd0;
+ end else if( clk_en ) begin
+ if( cnt==11'd1 ) begin
+ case( ctrl3[1:0] )
+ 2'd0: cnt <= 11'h20; // clk_en already divides by 16
+ 2'd1: cnt <= 11'h40;
+ 2'd2: cnt <= 11'h80;
+ 2'd3: cnt <= (tone2 == 0) ? 11'h02 : {tone2, 1'b0};
+ endcase
+ end else begin
+ cnt <= cnt-11'b1;
+ end
+ end
+
+wire fb = ctrl3[2]?(shift[0]^shift[3]):shift[0];
+
+always @(posedge clk)
+ if( rst || clr )
+ shift <= { 1'b1, 15'd0 };
+ else if( clk_en ) begin
+ if( cnt==1 ) begin
+ shift <= (|shift == 1'b0) ? {1'b1, 15'd0 } : {fb, shift[15:1]};
+ end
+ end
+
+endmodule
diff --git a/common/Sound/jt89/jt89_sms.qip b/common/Sound/jt89/jt89_sms.qip
new file mode 100644
index 00000000..a4cec7bc
--- /dev/null
+++ b/common/Sound/jt89/jt89_sms.qip
@@ -0,0 +1,10 @@
+set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) jt89_sms.vhd ]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt89_sms.v ]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt89.v ]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt89_noise.v ]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt89_vol.v ]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt89_mixer.v ]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt89_tone.v ]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) mixer/jt12_interpol.v ]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) mixer/jt12_comb.v ]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) mixer/jt12_dac2.v ]
diff --git a/common/Sound/jt89/jt89_sms.v b/common/Sound/jt89/jt89_sms.v
new file mode 100644
index 00000000..f4cd3821
--- /dev/null
+++ b/common/Sound/jt89/jt89_sms.v
@@ -0,0 +1,43 @@
+/* This file is part of JT89.
+
+ JT89 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.
+
+ JT89 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 JT89. If not, see .
+
+ Author: Jose Tejada Gomez. Twitter: @topapate
+ Version: 1.0
+ Date: Dec, 22nd, 2018
+
+ JT89 with x16 interpolation filter. For use with SEGA MASTER SYSTEM cores.
+
+ */
+
+module jt89_sms(
+ input clk,
+ input rst,
+ input wr_n,
+ input [7:0] din,
+ output signed [10:0] sound,
+ output ready
+);
+
+jt89 #(.interpol16(1)) u_jt89(
+ .clk ( clk ),
+ .clk_en ( 1'b1 ),
+ .rst ( rst ),
+ .wr_n ( wr_n ),
+ .din ( din ),
+ .sound ( sound ), // output interpolated at clk data rate
+ .ready ( ready )
+);
+
+endmodule // jt89_sms
\ No newline at end of file
diff --git a/common/Sound/jt89/jt89_sms.vhd b/common/Sound/jt89/jt89_sms.vhd
new file mode 100644
index 00000000..a3aece82
--- /dev/null
+++ b/common/Sound/jt89/jt89_sms.vhd
@@ -0,0 +1,29 @@
+library IEEE;
+use IEEE.std_logic_1164.all;
+
+package jt89 is
+
+-- SMS wrapper. clk_en assumed to be 1. x16 LPF+interpolator enabled
+component jt89_sms
+port
+(
+ rst : in std_logic;
+ clk : in std_logic; -- CPU clock
+ din : in std_logic_vector(7 downto 0);
+ wr_n : in std_logic;
+ ready : out std_logic;
+ sound : out std_logic_vector(10 downto 0) -- signed
+);
+end component;
+
+component jt12_dac2
+port
+(
+ rst : in std_logic;
+ clk : in std_logic; -- CPU clock
+ din : in std_logic_vector(10 downto 0); -- signed
+ dout : out std_logic
+);
+end component;
+
+end;
diff --git a/common/Sound/jt89/jt89_tone.v b/common/Sound/jt89/jt89_tone.v
new file mode 100644
index 00000000..dd7b1bd2
--- /dev/null
+++ b/common/Sound/jt89/jt89_tone.v
@@ -0,0 +1,63 @@
+/* This file is part of JT89.
+
+ JT89 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.
+
+ JT89 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 JT89. If not, see .
+
+ Author: Jose Tejada Gomez. Twitter: @topapate
+ Version: 1.0
+ Date: March, 8th 2017
+
+ This work was originally based in the implementation found on the
+ SMS core of MiST
+
+ */
+
+module jt89_tone(
+ input clk,
+(* direct_enable = 1 *) input clk_en,
+ input rst,
+ input [9:0] tone,
+ input [3:0] vol,
+ output [8:0] snd,
+ output reg out
+);
+
+reg [9:0] cnt;
+reg last_out;
+
+jt89_vol u_vol(
+ .rst ( rst ),
+ .clk ( clk ),
+ .clk_en ( clk_en ),
+ .din ( out ),
+ .vol ( vol ),
+ .snd ( snd )
+);
+
+always @(posedge clk)
+ if( rst ) begin
+ cnt <= 10'd0;
+ out <= 1'b0;
+ end else if( clk_en ) begin
+ if( tone==10'd0 || tone==10'd1 ) // special case. This is used for sample playing.
+ out <= 1'b1;
+ else begin
+ if( cnt[9:0]==10'd1 ) begin
+ cnt[9:0] <= (tone==10'd0) ? 10'd1 : tone;
+ out <= ~out;
+ end
+ else cnt <= cnt-10'b1;
+ end
+ end
+
+endmodule
diff --git a/common/Sound/jt89/jt89_verilog.qip b/common/Sound/jt89/jt89_verilog.qip
new file mode 100644
index 00000000..f1c3ae79
--- /dev/null
+++ b/common/Sound/jt89/jt89_verilog.qip
@@ -0,0 +1,5 @@
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt89.v ]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt89_noise.v ]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt89_vol.v ]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt89_mixer.v ]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt89_tone.v ]
diff --git a/common/Sound/jt89/jt89_vol.v b/common/Sound/jt89/jt89_vol.v
new file mode 100644
index 00000000..d746bd36
--- /dev/null
+++ b/common/Sound/jt89/jt89_vol.v
@@ -0,0 +1,63 @@
+/* This file is part of JT89.
+
+ JT89 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.
+
+ JT89 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 JT89. If not, see .
+
+ Author: Jose Tejada Gomez. Twitter: @topapate
+ Version: 1.0
+ Date: December, 1st 2018
+
+ This work was originally based in the implementation found on the
+ SMS core of MiST
+
+ */
+
+module jt89_vol(
+ input clk,
+ input clk_en,
+ input rst,
+ input din,
+ input [3:0] vol,
+ output reg signed [8:0] snd
+);
+
+
+reg [7:0] max;
+
+always @(*)
+ case ( vol ) // 2dB per LSB (20*log10)
+ 4'd0: max = 8'd255;
+ 4'd1: max = 8'd203;
+ 4'd2: max = 8'd161;
+ 4'd3: max = 8'd128;
+ 4'd4: max = 8'd102;
+ 4'd5: max = 8'd81;
+ 4'd6: max = 8'd64;
+ 4'd7: max = 8'd51;
+ 4'd8: max = 8'd40;
+ 4'd9: max = 8'd32;
+ 4'd10: max = 8'd26;
+ 4'd11: max = 8'd20;
+ 4'd12: max = 8'd16;
+ 4'd13: max = 8'd13;
+ 4'd14: max = 8'd10;
+ 4'd15: max = 8'd0;
+ endcase
+
+always @(posedge clk)
+ if( rst )
+ snd <= 9'd0;
+ else if( clk_en )
+ snd <= din ? {1'b0,max} : -{1'b0,max};
+
+endmodule
\ No newline at end of file
diff --git a/common/Sound/jt89/mixer/jt12_comb.v b/common/Sound/jt89/mixer/jt12_comb.v
new file mode 100644
index 00000000..dfd390e6
--- /dev/null
+++ b/common/Sound/jt89/mixer/jt12_comb.v
@@ -0,0 +1,59 @@
+/* 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 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 .
+
+ Author: Jose Tejada Gomez. Twitter: @topapate
+ Version: 1.0
+ Date: 10-12-2018
+
+*/
+
+module jt12_comb #(parameter
+ w=16, // bit width
+ m=1 // depth of comb filter
+)(
+ input rst,
+ input clk,
+(* direct_enable *) input cen,
+ input signed [w-1:0] snd_in,
+ output reg signed [w-1:0] snd_out
+);
+
+wire signed [w-1:0] prev;
+
+// m-delay stage
+generate
+ genvar k;
+ reg signed [w-1:0] mem[0:m-1];
+ assign prev=mem[m-1];
+ for(k=0;k.
+
+ Author: Jose Tejada Gomez. Twitter: @topapate
+ Version: 1.0
+ Date: March, 9th 2017
+ */
+
+`timescale 1ns / 1ps
+
+/*
+
+ input sampling rate must be the same as clk frequency
+ interpolate input signal accordingly to get the
+ right sampling rate.
+
+ Refer to sigmadelta.ods to see how the internal width (int_w)
+ was determined.
+
+*/
+
+module jt12_dac2 #(parameter width=11)
+(
+ input clk,
+ input rst,
+ input signed [width-1:0] din,
+ output reg dout
+);
+
+localparam int_w = width+5;
+
+reg [int_w-1:0] y, error, error_1, error_2;
+
+wire [width-1:0] undin = { ~din[width-1], din[width-2:0] };
+
+always @(*) begin
+ y = undin + { error_1, 1'b0} - error_2;
+ dout = ~y[int_w-1];
+ error = y - {dout, {width{1'b0}}};
+end
+
+always @(posedge clk)
+ if( rst ) begin
+ error_1 <= {int_w{1'b0}};
+ error_2 <= {int_w{1'b0}};
+ end else begin
+ error_1 <= error;
+ error_2 <= error_1;
+ end
+
+endmodule
diff --git a/common/Sound/jt89/mixer/jt12_interpol.v b/common/Sound/jt89/mixer/jt12_interpol.v
new file mode 100644
index 00000000..e5ff23ba
--- /dev/null
+++ b/common/Sound/jt89/mixer/jt12_interpol.v
@@ -0,0 +1,92 @@
+/* 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 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 .
+
+ Author: Jose Tejada Gomez. Twitter: @topapate
+ Version: 1.0
+ Date: 10-12-2018
+
+*/
+
+module jt12_interpol #(parameter calcw=18, inw=16,
+ n=2, // number of stages
+ m=1, // depth of comb filter
+ rate=2 // it will stuff with as many as (rate-1) zeros
+)(
+ input rst,
+ input clk,
+(* direct_enable *) input cen_in,
+(* direct_enable *) input cen_out,
+ input signed [inw-1:0] snd_in,
+ output reg signed [inw-1:0] snd_out
+);
+
+reg signed [calcw-1:0] inter6;
+wire signed [calcw-1:0] comb_op, integ_op;
+localparam wdiff = calcw - inw;
+
+generate
+ genvar k;
+ wire [calcw-1:0] comb_data[0:n];
+ assign comb_data[0] = { {wdiff{snd_in[inw-1]}}, snd_in };
+ assign comb_op = comb_data[n];
+ for(k=0;k