Added DSS/Covox support

This commit is contained in:
Aitor Gómez
2022-07-13 09:32:05 +02:00
parent baacf39ee1
commit 98254b6135
6 changed files with 358 additions and 28 deletions

34
PCXT.sv
View File

@@ -186,7 +186,6 @@ assign VGA_SCALER = 0;
assign HDMI_FREEZE = 0;
assign AUDIO_S = 1;
assign AUDIO_L = AUDIO_R;
assign AUDIO_MIX = 0;
assign LED_DISK = 0;
@@ -209,6 +208,7 @@ localparam CONF_STR = {
"O3,Model,IBM PCXT,Tandy 1000;",
"-;",
"OA,Adlib,On,Invisible;",
"OE,DSS/Covox,Unplugged,Plugged;",
//"O4,CPU Speed,4.77Mhz,7.16Mhz;",
"OB,Lo-tech 2MB EMS, Enabled, Disabled;",
"OCD,EMS Frame,A000,C000,D000;",
@@ -354,6 +354,18 @@ wire ce_pix;
assign CLK_VIDEO = clk_28_636;
assign CE_PIXEL = 1'b1;
reg cen_44100;
reg [31:0] cen_44100_cnt;
wire [31:0] cen_44100_cnt_next = cen_44100_cnt + 16'd44100;
always @(posedge CLK_50M) begin
cen_44100 <= 0;
cen_44100_cnt <= cen_44100_cnt_next;
if (cen_44100_cnt_next >= (50000000)) begin
cen_44100 <= 1;
cen_44100_cnt <= cen_44100_cnt_next - (50000000);
end
end
always @(posedge clk_28_636)
clk_14_318 <= ~clk_14_318; // 14.318Mhz
@@ -622,17 +634,18 @@ end
.ps2_data (device_data),
.ps2_clock_out (ps2_kbd_clk_out),
.ps2_data_out (ps2_kbd_data_out),
.clk_en_44100 (cen_44100),
.dss_covox_en (status[14]),
.lclamp (AUDIO_L),
.rclamp (AUDIO_R),
.clk_en_opl2 (cen_opl2), // clk_en_opl2
.jtopl2_snd_e (jtopl2_snd_e),
.adlibhide (adlibhide),
.tandy_video (tandy_mode),
.tandy_snd_e (tandy_snd_e),
.ioctl_download (ioctl_download),
.ioctl_index (ioctl_index),
.ioctl_wr (ioctl_wr),
.ioctl_addr (ioctl_addr),
.ioctl_data (ioctl_data),
.ioctl_data (ioctl_data),
.clk_uart (clk_uart),
.uart_rx (uart_rx),
.uart_tx (uart_tx),
@@ -659,23 +672,14 @@ end
.ems_address (status[13:12]),
.tandy_mode (tandy_mode)
);
wire speaker_out;
wire [7:0] tandy_snd_e;
wire tandy_snd_rdy;
wire [15:0] jtopl2_snd_e;
wire [16:0]sndmix = (({jtopl2_snd_e[15], jtopl2_snd_e}) << 2) + (speaker_out << 15) + {tandy_snd_e, 6'd0}; // signed mixer
wire [15:0] SDRAM_DQ_IN;
wire [15:0] SDRAM_DQ_OUT;
wire SDRAM_DQ_IO;
assign SDRAM_DQ_IN = SDRAM_DQ;
assign SDRAM_DQ = ~SDRAM_DQ_IO ? SDRAM_DQ_OUT : 16'hZZZZ;
assign AUDIO_R = sndmix >> 1;
wire s6_3_mux;
wire [2:0] SEGMENT;

View File

@@ -74,14 +74,16 @@ module CHIPSET (
input logic ps2_data,
output logic ps2_clock_out,
output logic ps2_data_out,
// SOUND
input logic clk_en_44100, // COVOX/DSS clock enable
input logic dss_covox_en,
output logic [15:0] lclamp,
output logic [15:0] rclamp,
// JTOPL
input logic clk_en_opl2,
output logic [15:0] jtopl2_snd_e,
input logic adlibhide,
// TANDY
input logic tandy_video,
output logic [7:0] tandy_snd_e,
// IOCTL
input logic ioctl_download,
input logic [7:0] ioctl_index,
@@ -265,10 +267,12 @@ module CHIPSET (
.ps2_data (ps2_data),
.ps2_clock_out (ps2_clock_out),
.ps2_data_out (ps2_data_out),
.clk_en_44100 (clk_en_44100),
.dss_covox_en (dss_covox_en),
.lclamp (lclamp),
.rclamp (rclamp),
.clk_en_opl2 (clk_en_opl2),
.jtopl2_snd_e (jtopl2_snd_e),
.adlibhide (adlibhide),
.tandy_snd_e (tandy_snd_e),
.tandy_video (tandy_video),
.tandy_snd_rdy (tandy_snd_rdy),
.ioctl_download (ioctl_download),

View File

@@ -7,7 +7,7 @@ module PERIPHERALS #(
) (
input logic clock,
input logic clk_sys,
input logic peripheral_clock,
input logic peripheral_clock,
input logic reset,
// CPU
output logic interrupt_to_cpu,
@@ -56,13 +56,16 @@ module PERIPHERALS #(
input logic ps2_data,
output logic ps2_clock_out,
output logic ps2_data_out,
// SOUND
input logic clk_en_44100, // COVOX/DSS clock enable
input logic dss_covox_en,
output logic [15:0] lclamp,
output logic [15:0] rclamp,
// JTOPL
input logic clk_en_opl2,
output logic [15:0] jtopl2_snd_e,
input logic clk_en_opl2,
input logic adlibhide,
// TANDY
input logic tandy_video,
output logic [7:0] tandy_snd_e,
input logic tandy_video,
output logic tandy_snd_rdy,
// IOCTL
input logic ioctl_download,
@@ -131,6 +134,7 @@ module PERIPHERALS #(
wire xtide_select_n = ~(~iorq && ~address_enable_n && address[19:14] == 6'b111011); // EC000 - EFFFF (16 KB)
wire uart_cs = (~address_enable_n && {address[15:3], 3'd0} == 16'h03F8);
wire lpt_cs = (iorq && ~address_enable_n && {address[15:3], 3'd0} == 16'h0378);
wire lpt_ctl_cs = (iorq && ~address_enable_n && {address[15:3], 3'd0} == 16'h0379);
wire [3:0] ems_page_address = (ems_address == 2'b00) ? 4'b1010 : (ems_address == 2'b01) ? 4'b1100 : 4'b1101;
@@ -330,8 +334,9 @@ module PERIPHERALS #(
end
wire [15:0] jtopl2_snd_e;
wire [7:0] jtopl2_dout;
wire [7:0]opl32_data;
wire [7:0] opl32_data;
assign opl32_data = adlibhide ? 8'hFF : jtopl2_dout;
jtopl2 jtopl2_inst
@@ -351,6 +356,7 @@ module PERIPHERALS #(
// Tandy sound
wire [7:0] tandy_snd_e;
sn76489_top sn76489
(
.clock_i(clock),
@@ -361,7 +367,26 @@ module PERIPHERALS #(
.ready_o(tandy_snd_rdy),
.d_i(internal_data_bus),
.aout_o(tandy_snd_e)
);
);
wire dss_full;
soundwave sound_gen
(
.CLK(clock),
.clk_en(clk_en_44100),
.data(internal_data_bus),
.we(dss_covox_en && lpt_cs && ~io_write_n),
// .word(WORD),
.speaker(speaker_out),
.tandy_snd(tandy_snd_e),
.opl2left(jtopl2_snd_e),
.opl2right(jtopl2_snd_e),
// .full(sq_full), // when not full, write max 2x1152 16bit samples
.dss_full(dss_full),
.lclamp(lclamp),
.rclamp(rclamp)
);
logic keybord_interrupt_ff;
always_ff @(posedge clock, posedge reset) begin
@@ -724,6 +749,10 @@ module PERIPHERALS #(
data_bus_out_from_chipset = 1'b1;
data_bus_out = lpt_data;
end
else if ((lpt_ctl_cs) && (~io_read_n)) begin
data_bus_out_from_chipset = 1'b1;
data_bus_out = {1'bx, dss_full, 6'bxxxxxx};
end
else begin
data_bus_out_from_chipset = 1'b0;
data_bus_out = 8'b00000000;

View File

@@ -1,3 +1,5 @@
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ram.v ]
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) clk_div3.v ]
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) bios.v ]
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) bios.v ]
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) soundwave.v ]
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) sndfifo.v ]

172
rtl/common/sndfifo.v Normal file
View File

@@ -0,0 +1,172 @@
// megafunction wizard: %FIFO%
// GENERATION: STANDARD
// VERSION: WM1.0
// MODULE: dcfifo
// ============================================================
// File Name: sndfifo.v
// Megafunction Name(s):
// dcfifo
//
// Simulation Library Files(s):
// altera_mf
// ============================================================
// ************************************************************
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
//
// 15.1.0 Build 185 10/21/2015 SJ Lite Edition
// ************************************************************
//Copyright (C) 1991-2015 Altera Corporation. All rights reserved.
//Your use of Altera Corporation's design tools, logic functions
//and other software and tools, and its AMPP partner logic
//functions, and any output files from any of the foregoing
//(including device programming or simulation files), and any
//associated documentation or information are expressly subject
//to the terms and conditions of the Altera Program License
//Subscription Agreement, the Altera Quartus Prime License Agreement,
//the Altera MegaCore Function License Agreement, or other
//applicable license agreement, including, without limitation,
//that your use is for the sole purpose of programming logic
//devices manufactured by Altera and sold by Altera or its
//authorized distributors. Please refer to the applicable
//agreement for further details.
// synopsys translate_off
`timescale 1 ps / 1 ps
// synopsys translate_on
module sndfifo (
data,
rdclk,
rdreq,
wrclk,
wrreq,
q,
rdempty,
rdusedw,
wrusedw);
input [31:0] data;
input rdclk;
input rdreq;
input wrclk;
input wrreq;
output [31:0] q;
output rdempty;
output [11:0] rdusedw;
output [11:0] wrusedw;
wire [31:0] sub_wire0;
wire sub_wire1;
wire [11:0] sub_wire2;
wire [11:0] sub_wire3;
wire [31:0] q = sub_wire0[31:0];
wire rdempty = sub_wire1;
wire [11:0] rdusedw = sub_wire2[11:0];
wire [11:0] wrusedw = sub_wire3[11:0];
dcfifo dcfifo_component (
.data (data),
.rdclk (rdclk),
.rdreq (rdreq),
.wrclk (wrclk),
.wrreq (wrreq),
.q (sub_wire0),
.rdempty (sub_wire1),
.rdusedw (sub_wire2),
.wrusedw (sub_wire3),
.aclr (),
.eccstatus (),
.rdfull (),
.wrempty (),
.wrfull ());
defparam
dcfifo_component.intended_device_family = "Cyclone IV E",
dcfifo_component.lpm_numwords = 4096,
dcfifo_component.lpm_showahead = "OFF",
dcfifo_component.lpm_type = "dcfifo",
dcfifo_component.lpm_width = 32,
dcfifo_component.lpm_widthu = 12,
dcfifo_component.overflow_checking = "ON",
dcfifo_component.rdsync_delaypipe = 4,
dcfifo_component.underflow_checking = "ON",
dcfifo_component.use_eab = "ON",
dcfifo_component.wrsync_delaypipe = 4;
endmodule
// ============================================================
// CNX file retrieval info
// ============================================================
// Retrieval info: PRIVATE: AlmostEmpty NUMERIC "0"
// Retrieval info: PRIVATE: AlmostEmptyThr NUMERIC "-1"
// Retrieval info: PRIVATE: AlmostFull NUMERIC "0"
// Retrieval info: PRIVATE: AlmostFullThr NUMERIC "-1"
// Retrieval info: PRIVATE: CLOCKS_ARE_SYNCHRONIZED NUMERIC "0"
// Retrieval info: PRIVATE: Clock NUMERIC "4"
// Retrieval info: PRIVATE: Depth NUMERIC "4096"
// Retrieval info: PRIVATE: Empty NUMERIC "1"
// Retrieval info: PRIVATE: Full NUMERIC "1"
// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
// Retrieval info: PRIVATE: LE_BasedFIFO NUMERIC "0"
// Retrieval info: PRIVATE: LegacyRREQ NUMERIC "1"
// Retrieval info: PRIVATE: MAX_DEPTH_BY_9 NUMERIC "0"
// Retrieval info: PRIVATE: OVERFLOW_CHECKING NUMERIC "0"
// Retrieval info: PRIVATE: Optimize NUMERIC "0"
// Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
// Retrieval info: PRIVATE: UNDERFLOW_CHECKING NUMERIC "0"
// Retrieval info: PRIVATE: UsedW NUMERIC "1"
// Retrieval info: PRIVATE: Width NUMERIC "32"
// Retrieval info: PRIVATE: dc_aclr NUMERIC "0"
// Retrieval info: PRIVATE: diff_widths NUMERIC "0"
// Retrieval info: PRIVATE: msb_usedw NUMERIC "0"
// Retrieval info: PRIVATE: output_width NUMERIC "32"
// Retrieval info: PRIVATE: rsEmpty NUMERIC "1"
// Retrieval info: PRIVATE: rsFull NUMERIC "0"
// Retrieval info: PRIVATE: rsUsedW NUMERIC "1"
// Retrieval info: PRIVATE: sc_aclr NUMERIC "0"
// Retrieval info: PRIVATE: sc_sclr NUMERIC "0"
// Retrieval info: PRIVATE: wsEmpty NUMERIC "0"
// Retrieval info: PRIVATE: wsFull NUMERIC "0"
// Retrieval info: PRIVATE: wsUsedW NUMERIC "1"
// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
// Retrieval info: CONSTANT: LPM_NUMWORDS NUMERIC "4096"
// Retrieval info: CONSTANT: LPM_SHOWAHEAD STRING "OFF"
// Retrieval info: CONSTANT: LPM_TYPE STRING "dcfifo"
// Retrieval info: CONSTANT: LPM_WIDTH NUMERIC "32"
// Retrieval info: CONSTANT: LPM_WIDTHU NUMERIC "12"
// Retrieval info: CONSTANT: OVERFLOW_CHECKING STRING "ON"
// Retrieval info: CONSTANT: RDSYNC_DELAYPIPE NUMERIC "4"
// Retrieval info: CONSTANT: UNDERFLOW_CHECKING STRING "ON"
// Retrieval info: CONSTANT: USE_EAB STRING "ON"
// Retrieval info: CONSTANT: WRSYNC_DELAYPIPE NUMERIC "4"
// Retrieval info: USED_PORT: data 0 0 32 0 INPUT NODEFVAL "data[31..0]"
// Retrieval info: USED_PORT: q 0 0 32 0 OUTPUT NODEFVAL "q[31..0]"
// Retrieval info: USED_PORT: rdclk 0 0 0 0 INPUT NODEFVAL "rdclk"
// Retrieval info: USED_PORT: rdempty 0 0 0 0 OUTPUT NODEFVAL "rdempty"
// Retrieval info: USED_PORT: rdreq 0 0 0 0 INPUT NODEFVAL "rdreq"
// Retrieval info: USED_PORT: rdusedw 0 0 12 0 OUTPUT NODEFVAL "rdusedw[11..0]"
// Retrieval info: USED_PORT: wrclk 0 0 0 0 INPUT NODEFVAL "wrclk"
// Retrieval info: USED_PORT: wrreq 0 0 0 0 INPUT NODEFVAL "wrreq"
// Retrieval info: USED_PORT: wrusedw 0 0 12 0 OUTPUT NODEFVAL "wrusedw[11..0]"
// Retrieval info: CONNECT: @data 0 0 32 0 data 0 0 32 0
// Retrieval info: CONNECT: @rdclk 0 0 0 0 rdclk 0 0 0 0
// Retrieval info: CONNECT: @rdreq 0 0 0 0 rdreq 0 0 0 0
// Retrieval info: CONNECT: @wrclk 0 0 0 0 wrclk 0 0 0 0
// Retrieval info: CONNECT: @wrreq 0 0 0 0 wrreq 0 0 0 0
// Retrieval info: CONNECT: q 0 0 32 0 @q 0 0 32 0
// Retrieval info: CONNECT: rdempty 0 0 0 0 @rdempty 0 0 0 0
// Retrieval info: CONNECT: rdusedw 0 0 12 0 @rdusedw 0 0 12 0
// Retrieval info: CONNECT: wrusedw 0 0 12 0 @wrusedw 0 0 12 0
// Retrieval info: GEN_FILE: TYPE_NORMAL sndfifo.v TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL sndfifo.inc FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL sndfifo.cmp FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL sndfifo.bsf FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL sndfifo_inst.v FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL sndfifo_bb.v TRUE
// Retrieval info: LIB_FILE: altera_mf

119
rtl/common/soundwave.v Normal file
View File

@@ -0,0 +1,119 @@
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
//
// This file is part of the Next186 Soc PC project
// http://opencores.org/project,next186
//
// Filename: sound_gen.v
// Description: Part of the Next186 SoC PC project,
// stereo 2x16bit pulse density modulated sound generator
// 44100 samples/sec
// Disney Sound Source and Covox Speech compatible
// Version 1.0
// Creation date: Jan2015
//
// Author: Nicolae Dumitrache
// e-mail: ndumitrache@opencores.org
//
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015 Nicolae Dumitrache
//
// This source file may be used and distributed without
// restriction provided that this copyright statement is not
// removed from the file and that any derivative work contains
// the original copyright notice and the associated disclaimer.
//
// This source file is free software; you can redistribute it
// and/or modify it under the terms of the GNU Lesser General
// Public License as published by the Free Software Foundation;
// either version 2.1 of the License, or (at your option) any
// later version.
//
// This source 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 Lesser General Public License for more
// details.
//
// You should have received a copy of the GNU Lesser General
// Public License along with this source; if not, download it
// from http://www.opencores.org/lgpl.shtml
//
//////////////////////////////////////////////////////////////////////////////////
// Additional Comments:
//
// byte write: both channels are the same (Covox emulation), the 8bit sample value is shifted by 8, the channel selector is reset to LEFT
// word write: LEFT first, the queue is updated only after RIGHT value is written
// sample rate: 44100Hz
//////////////////////////////////////////////////////////////////////////////////
`define SPKVOL 11
module soundwave(
input CLK,
input clk_en,
// input [15:0]data,
input [7:0]data,
input we,
// input word,
input speaker,
input [15:0]opl2left,
input [15:0]opl2right,
input [7:0]tandy_snd,
output full, // when not full, write max 2x1152 16bit samples
output dss_full,
output [15:0] lclamp,
output [15:0] rclamp
);
reg [31:0]wdata;
reg lr = 1'b0;
reg [2:0]write = 3'b000;
wire qempty;
wire [31:0]sample;
wire [31:0]sample1 = qempty ? 32'hc000c000 : sample;
reg [15:0]r_opl2left = 0;
reg [15:0]r_opl2right = 0;
wire [16:0]lmix = {sample1[15], sample1[15:0]} + {r_opl2left[15], r_opl2left} + {tandy_snd, 6'd0} + (speaker << `SPKVOL); // signed mixer left
wire [16:0]rmix = {sample1[31], sample1[31:16]} + {r_opl2right[15], r_opl2right} + {tandy_snd, 6'd0} + (speaker << `SPKVOL); // signed mixer right
assign lclamp = (~|lmix[16:15] | &lmix[16:15]) ? {!lmix[15], lmix[14:0]} : {16{!lmix[16]}}; // clamp to [-32768..32767] and add 32878
assign rclamp = (~|rmix[16:15] | &rmix[16:15]) ? {!rmix[15], rmix[14:0]} : {16{!rmix[16]}};
wire [11:0]wrusedw;
wire [11:0]rdusedw;
assign full = wrusedw >= 12'd2940;
assign dss_full = rdusedw > 12'd90; // Disney sound source queue full
sndfifo sndfifo_inst
(
.wrclk(CLK), // input wr_clk
.rdclk(CLK), // input rd_clk
.data(wdata), // input [31 : 0] din
.wrreq(|write), // input wr_en
.rdreq(clk_en), // input rd_en
.q(sample), // output [31 : 0] dout
.wrusedw(wrusedw),
.rdusedw(rdusedw),
.rdempty(qempty) // output empty
);
always @(posedge CLK) begin
r_opl2left <= opl2left;
r_opl2right <= opl2right;
if(we) begin
/*
if(word) begin
lr <= !lr;
write <= {2'b00, lr};
if(lr) wdata[31:16] <= data;
else wdata[15:0] <= data;
end else begin
*/
lr <= 1'b0; // left
write <= 3'b110;
wdata <= {1'b1, data[7:0], 8'b00000001, data[7:0], 7'b0000000};
end
else write <= write - |write;
end
endmodule