mirror of
https://github.com/mist-devel/mist-board.git
synced 2026-02-06 08:04:41 +00:00
204 lines
5.6 KiB
Verilog
204 lines
5.6 KiB
Verilog
//
|
|
// audio.v
|
|
//
|
|
// Atari audio subsystem implementation for the MiST board
|
|
// http://code.google.com/p/mist-board/
|
|
//
|
|
// Copyright (c) 2015 Till Harbaum <till@harbaum.org>
|
|
//
|
|
// 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/>.
|
|
|
|
module audio (
|
|
// system interface
|
|
input reset,
|
|
input clk_32, // 32 MHz
|
|
input clk_8,
|
|
input [1:0] bus_cycle, // bus-cycle for sync
|
|
|
|
|
|
// cpu interface
|
|
input [15:0] din,
|
|
input [15:0] addr,
|
|
output [15:0] dout,
|
|
input uds,
|
|
input lds,
|
|
input rw,
|
|
input psg_sel,
|
|
input ste_dma_snd_sel,
|
|
|
|
// ste dma interface
|
|
input hsync, // to synchronize with video
|
|
output dma_read,
|
|
output [22:0] dma_addr,
|
|
input [63:0] dma_data,
|
|
|
|
input psg_stereo,
|
|
|
|
// psg has gpios
|
|
output floppy_side,
|
|
output [1:0] floppy_sel,
|
|
// extra joystick map to parallel port
|
|
input [5:0] joy0,
|
|
input [5:0] joy1,
|
|
|
|
output [7:0] parallel_data_out,
|
|
input parallel_strobe_out,
|
|
output parallel_data_out_available,
|
|
|
|
output xsint,
|
|
output xsint_d,
|
|
|
|
output audio_r,
|
|
output audio_l
|
|
);
|
|
|
|
// 2Mhz clock for PSG and STE DMA audio delay buffer
|
|
reg [1:0] sclk;
|
|
always @ (posedge clk_8)
|
|
sclk <= sclk + 2'd1;
|
|
|
|
wire clk_2 = sclk[1];
|
|
|
|
wire [7:0] port_a_out;
|
|
wire [7:0] port_b_out;
|
|
assign floppy_side = port_a_out[0];
|
|
assign floppy_sel = port_a_out[2:1];
|
|
|
|
wire [9:0] ym_audio_out_l, ym_audio_out_r;
|
|
|
|
// extra joysticks are wired to the printer port
|
|
// using the "gauntlet2 interface", fire of
|
|
// joystick 0 is connected to the mfp I0 (busy)
|
|
wire [7:0] port_b_in = { ~joy0[0], ~joy0[1], ~joy0[2], ~joy0[3],
|
|
~joy1[0], ~joy1[1], ~joy1[2], ~joy1[3]};
|
|
wire [7:0] port_a_in = { 2'b11, ~joy1[4], 5'b11111 };
|
|
|
|
assign dout = psg_sel?{psg_dout,8'hff}:ste_dma_snd_sel?ste_dma_snd_data_out:16'h0000;
|
|
wire [15:0] ste_dma_snd_data_out;
|
|
wire [7:0] psg_dout;
|
|
|
|
YM2149 ym2149 (
|
|
.I_DA ( din[15:8] ),
|
|
.O_DA ( psg_dout ),
|
|
.O_DA_OE_L ( ),
|
|
|
|
// control
|
|
.I_A9_L ( 1'b0 ),
|
|
.I_A8 ( 1'b1 ),
|
|
.I_BDIR ( psg_sel && !rw ),
|
|
.I_BC2 ( 1'b1 ),
|
|
.I_BC1 ( psg_sel && !addr[1] ),
|
|
.I_SEL_L ( 1'b1 ),
|
|
|
|
.O_AUDIO_L (ym_audio_out_l ),
|
|
.O_AUDIO_R (ym_audio_out_r ),
|
|
|
|
.stereo (psg_stereo ),
|
|
|
|
// port a
|
|
.I_IOA ( port_a_in ),
|
|
.O_IOA ( port_a_out ),
|
|
.O_IOA_OE_L ( ),
|
|
|
|
// port b
|
|
.I_IOB ( port_b_in ),
|
|
.O_IOB ( port_b_out ),
|
|
.O_IOB_OE_L ( ),
|
|
|
|
//
|
|
.ENA ( 1'b1 ),
|
|
.RESET_L ( !reset ),
|
|
.CLK ( clk_2 ), // 2 MHz
|
|
.CLK8 ( clk_8 ) // 8 MHz CPU bus clock
|
|
);
|
|
|
|
wire parallel_fifo_full;
|
|
|
|
// ------ fifo to store printer data coming from psg ---------
|
|
io_fifo #(.DEPTH(4)) parallel_out_fifo (
|
|
.reset (reset),
|
|
|
|
.in_clk (clk_8),
|
|
.in (port_b_out),
|
|
.in_strobe (port_a_out[5]),
|
|
.in_enable (1'b0),
|
|
|
|
.out_clk (clk_8),
|
|
.out (parallel_data_out),
|
|
.out_strobe (parallel_strobe_out),
|
|
.out_enable (1'b0),
|
|
|
|
.full (parallel_fifo_full),
|
|
.data_available (parallel_data_out_available)
|
|
);
|
|
|
|
wire [7:0] ste_audio_out_r;
|
|
wire [7:0] ste_audio_out_l;
|
|
|
|
ste_dma_snd ste_dma_snd (
|
|
// cpu interface
|
|
.clk (clk_8 ),
|
|
.reset (reset ),
|
|
.din (din ),
|
|
.sel (ste_dma_snd_sel ),
|
|
.addr (addr[5:1] ),
|
|
.uds (uds ),
|
|
.lds (lds ),
|
|
.rw (rw ),
|
|
.dout (ste_dma_snd_data_out),
|
|
|
|
// memory interface
|
|
.clk32 (clk_32 ),
|
|
.bus_cycle (bus_cycle ),
|
|
.hsync (hsync ),
|
|
.saddr (dma_addr ),
|
|
.read (dma_read ),
|
|
.data (dma_data ),
|
|
|
|
.audio_l (ste_audio_out_l ),
|
|
.audio_r (ste_audio_out_r ),
|
|
|
|
.xsint ( xsint ),
|
|
.xsint_d ( xsint_d ) // 4 usec delayed
|
|
);
|
|
|
|
// audio output processing
|
|
|
|
// YM and STE audio channels are expanded to 14 bits and added resulting in 15 bits
|
|
// for the sigmadelta dac take from the minimig
|
|
|
|
// This should later be handled by the lmc1992
|
|
|
|
wire [9:0] ym_audio_out_l_signed = ym_audio_out_l - 10'h200;
|
|
wire [9:0] ym_audio_out_r_signed = ym_audio_out_r - 10'h200;
|
|
wire [7:0] ste_audio_out_l_signed = ste_audio_out_l - 8'h80;
|
|
wire [7:0] ste_audio_out_r_signed = ste_audio_out_r - 8'h80;
|
|
|
|
wire [14:0] audio_mix_l =
|
|
{ ym_audio_out_l_signed[9], ym_audio_out_l_signed, ym_audio_out_l_signed[9:6]} +
|
|
{ ste_audio_out_l_signed[7], ste_audio_out_l_signed, ste_audio_out_l_signed[7:2] };
|
|
wire [14:0] audio_mix_r =
|
|
{ ym_audio_out_r_signed[9], ym_audio_out_r_signed, ym_audio_out_r_signed[9:6]} +
|
|
{ ste_audio_out_r_signed[7], ste_audio_out_r_signed, ste_audio_out_r_signed[7:2] };
|
|
|
|
sigma_delta_dac sigma_delta_dac (
|
|
.clk ( clk_32 ), // bus clock
|
|
.ldatasum ( audio_mix_l ), // left channel data
|
|
.rdatasum ( audio_mix_r ), // right channel data
|
|
.left ( audio_l ), // left bitstream output
|
|
.right ( audio_r ) // right bitsteam output
|
|
);
|
|
|
|
endmodule
|