mirror of
https://github.com/UzixLS/TSConf_MiST.git
synced 2025-07-18 14:51:25 +03:00
Improve General Sound. Use up to 4MB of RAM.
This commit is contained in:
@ -374,7 +374,7 @@ set_global_assignment -name VHDL_FILE src/rtc/mc146818a.vhd
|
|||||||
set_global_assignment -name VHDL_FILE src/sound/soundrive.vhd
|
set_global_assignment -name VHDL_FILE src/sound/soundrive.vhd
|
||||||
set_global_assignment -name VHDL_FILE src/sound/turbosound.vhd
|
set_global_assignment -name VHDL_FILE src/sound/turbosound.vhd
|
||||||
set_global_assignment -name VHDL_FILE src/sound/ay8910.vhd
|
set_global_assignment -name VHDL_FILE src/sound/ay8910.vhd
|
||||||
set_global_assignment -name VHDL_FILE src/sound/gs.vhd
|
set_global_assignment -name VERILOG_FILE src/sound/gs.v
|
||||||
set_global_assignment -name SYSTEMVERILOG_FILE src/sound/saa1099.sv
|
set_global_assignment -name SYSTEMVERILOG_FILE src/sound/saa1099.sv
|
||||||
set_global_assignment -name VERILOG_FILE src/memory/dma.v
|
set_global_assignment -name VERILOG_FILE src/memory/dma.v
|
||||||
set_global_assignment -name VERILOG_FILE src/memory/arbiter.v
|
set_global_assignment -name VERILOG_FILE src/memory/arbiter.v
|
||||||
@ -394,12 +394,13 @@ set_global_assignment -name VERILOG_FILE src/video/mem/video_sfile.v
|
|||||||
set_global_assignment -name VERILOG_FILE src/video/mem/video_cram.v
|
set_global_assignment -name VERILOG_FILE src/video/mem/video_cram.v
|
||||||
set_global_assignment -name VERILOG_FILE src/video/video_top.v
|
set_global_assignment -name VERILOG_FILE src/video/video_top.v
|
||||||
set_global_assignment -name VHDL_FILE src/gen_rom.vhd
|
set_global_assignment -name VHDL_FILE src/gen_rom.vhd
|
||||||
set_global_assignment -name VHDL_FILE src/gen_ram.vhd
|
|
||||||
set_global_assignment -name VHDL_FILE src/keyboard.vhd
|
set_global_assignment -name VHDL_FILE src/keyboard.vhd
|
||||||
set_global_assignment -name VERILOG_FILE src/kempston_mouse.v
|
set_global_assignment -name VERILOG_FILE src/kempston_mouse.v
|
||||||
set_global_assignment -name VERILOG_FILE src/spi.v
|
set_global_assignment -name VERILOG_FILE src/spi.v
|
||||||
set_global_assignment -name VHDL_FILE src/sdram.vhd
|
set_global_assignment -name VHDL_FILE src/sdram.vhd
|
||||||
set_global_assignment -name VERILOG_FILE src/clock.v
|
set_global_assignment -name VERILOG_FILE src/clock.v
|
||||||
set_global_assignment -name VHDL_FILE src/tsconf.vhd
|
set_global_assignment -name VHDL_FILE src/tsconf.vhd
|
||||||
|
set_global_assignment -name SYSTEMVERILOG_FILE ddram.sv
|
||||||
|
set_global_assignment -name VERILOG_FILE dpram.v
|
||||||
set_global_assignment -name SYSTEMVERILOG_FILE TSConf.sv
|
set_global_assignment -name SYSTEMVERILOG_FILE TSConf.sv
|
||||||
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
@ -357,7 +357,6 @@ set_location_assignment PIN_W21 -to SW[2]
|
|||||||
set_location_assignment PIN_W20 -to SW[3]
|
set_location_assignment PIN_W20 -to SW[3]
|
||||||
|
|
||||||
set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:sys/build_id.tcl"
|
set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:sys/build_id.tcl"
|
||||||
|
|
||||||
set_global_assignment -name CDF_FILE jtag.cdf
|
set_global_assignment -name CDF_FILE jtag.cdf
|
||||||
set_global_assignment -name QIP_FILE sys/sys.qip
|
set_global_assignment -name QIP_FILE sys/sys.qip
|
||||||
set_global_assignment -name QSYS_FILE sys/vip.qsys
|
set_global_assignment -name QSYS_FILE sys/vip.qsys
|
||||||
@ -380,7 +379,7 @@ set_global_assignment -name VHDL_FILE src/rtc/mc146818a.vhd
|
|||||||
set_global_assignment -name VHDL_FILE src/sound/soundrive.vhd
|
set_global_assignment -name VHDL_FILE src/sound/soundrive.vhd
|
||||||
set_global_assignment -name VHDL_FILE src/sound/turbosound.vhd
|
set_global_assignment -name VHDL_FILE src/sound/turbosound.vhd
|
||||||
set_global_assignment -name VHDL_FILE src/sound/ay8910.vhd
|
set_global_assignment -name VHDL_FILE src/sound/ay8910.vhd
|
||||||
set_global_assignment -name VHDL_FILE src/sound/gs.vhd
|
set_global_assignment -name VERILOG_FILE src/sound/gs.v
|
||||||
set_global_assignment -name SYSTEMVERILOG_FILE src/sound/saa1099.sv
|
set_global_assignment -name SYSTEMVERILOG_FILE src/sound/saa1099.sv
|
||||||
set_global_assignment -name VERILOG_FILE src/memory/dma.v
|
set_global_assignment -name VERILOG_FILE src/memory/dma.v
|
||||||
set_global_assignment -name VERILOG_FILE src/memory/arbiter.v
|
set_global_assignment -name VERILOG_FILE src/memory/arbiter.v
|
||||||
@ -400,12 +399,12 @@ set_global_assignment -name VERILOG_FILE src/video/mem/video_sfile.v
|
|||||||
set_global_assignment -name VERILOG_FILE src/video/mem/video_cram.v
|
set_global_assignment -name VERILOG_FILE src/video/mem/video_cram.v
|
||||||
set_global_assignment -name VERILOG_FILE src/video/video_top.v
|
set_global_assignment -name VERILOG_FILE src/video/video_top.v
|
||||||
set_global_assignment -name VHDL_FILE src/gen_rom.vhd
|
set_global_assignment -name VHDL_FILE src/gen_rom.vhd
|
||||||
set_global_assignment -name VHDL_FILE src/gen_ram.vhd
|
|
||||||
set_global_assignment -name VHDL_FILE src/keyboard.vhd
|
set_global_assignment -name VHDL_FILE src/keyboard.vhd
|
||||||
set_global_assignment -name VERILOG_FILE src/kempston_mouse.v
|
set_global_assignment -name VERILOG_FILE src/kempston_mouse.v
|
||||||
set_global_assignment -name VERILOG_FILE src/spi.v
|
set_global_assignment -name VERILOG_FILE src/spi.v
|
||||||
set_global_assignment -name VHDL_FILE src/sdram.vhd
|
set_global_assignment -name VHDL_FILE src/sdram.vhd
|
||||||
set_global_assignment -name VERILOG_FILE src/clock.v
|
set_global_assignment -name VERILOG_FILE src/clock.v
|
||||||
set_global_assignment -name VHDL_FILE src/tsconf.vhd
|
set_global_assignment -name VHDL_FILE src/tsconf.vhd
|
||||||
set_global_assignment -name SYSTEMVERILOG_FILE TSConf.sv
|
set_global_assignment -name SYSTEMVERILOG_FILE ddram.sv
|
||||||
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
set_global_assignment -name VERILOG_FILE dpram.v
|
||||||
|
set_global_assignment -name SYSTEMVERILOG_FILE TSConf.svset_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
48
TSConf.sv
48
TSConf.sv
@ -97,8 +97,6 @@ module emu
|
|||||||
output SDRAM_nWE
|
output SDRAM_nWE
|
||||||
);
|
);
|
||||||
|
|
||||||
assign {DDRAM_CLK, DDRAM_BURSTCNT, DDRAM_ADDR, DDRAM_DIN, DDRAM_BE, DDRAM_RD, DDRAM_WE} = '0;
|
|
||||||
|
|
||||||
assign LED_USER = vsd_sel & sd_act;
|
assign LED_USER = vsd_sel & sd_act;
|
||||||
assign LED_DISK = {1'b1, ~vsd_sel & sd_act};
|
assign LED_DISK = {1'b1, ~vsd_sel & sd_act};
|
||||||
assign LED_POWER = 0;
|
assign LED_POWER = 0;
|
||||||
@ -112,7 +110,7 @@ localparam CONF_STR = {
|
|||||||
"O5,Aspect ratio,4:3,16:9;",
|
"O5,Aspect ratio,4:3,16:9;",
|
||||||
"O12,Scandoubler Fx,None,HQ2x,CRT 25%,CRT 50%;",
|
"O12,Scandoubler Fx,None,HQ2x,CRT 25%,CRT 50%;",
|
||||||
"O34,Stereo mix,None,25%,50%,100%;",
|
"O34,Stereo mix,None,25%,50%,100%;",
|
||||||
"OS,General Sound,Enabled,Disabled;",
|
"OST,General Sound,512KB,1MB,2MB,4MB;",
|
||||||
"-;",
|
"-;",
|
||||||
"O67,CPU Speed,3.5MHz,7MHz,14MHz;",
|
"O67,CPU Speed,3.5MHz,7MHz,14MHz;",
|
||||||
"O8,CPU Cache,On,Off;",
|
"O8,CPU Cache,On,Off;",
|
||||||
@ -264,10 +262,16 @@ tsconf tsconf
|
|||||||
.SD_CLK(sdclk),
|
.SD_CLK(sdclk),
|
||||||
.SD_CS_N(sdss),
|
.SD_CS_N(sdss),
|
||||||
|
|
||||||
.GS_ENA(~status[28]),
|
.GS_ENA(1),
|
||||||
|
.GS_ADDR(gs_mem_addr),
|
||||||
|
.GS_DI(gs_mem_din),
|
||||||
|
.GS_DO(gs_mem_dout | gs_mem_mask),
|
||||||
|
.GS_RD(gs_mem_rd),
|
||||||
|
.GS_WR(gs_mem_wr),
|
||||||
|
.GS_WAIT(~gs_mem_ready),
|
||||||
.SOUND_L(AUDIO_L),
|
.SOUND_L(AUDIO_L),
|
||||||
.SOUND_R(AUDIO_R),
|
.SOUND_R(AUDIO_R),
|
||||||
|
|
||||||
.COLD_RESET(RESET | status[0]),
|
.COLD_RESET(RESET | status[0]),
|
||||||
.WARM_RESET(buttons[1]),
|
.WARM_RESET(buttons[1]),
|
||||||
.RESET_OUT(reset),
|
.RESET_OUT(reset),
|
||||||
@ -280,7 +284,39 @@ tsconf tsconf
|
|||||||
.joystick(joy_0[5:0] | joy_1[5:0])
|
.joystick(joy_0[5:0] | joy_1[5:0])
|
||||||
);
|
);
|
||||||
|
|
||||||
assign AUDIO_S = 0;
|
assign DDRAM_CLK = clk_mem;
|
||||||
|
|
||||||
|
wire [21:0] gs_mem_addr;
|
||||||
|
wire [7:0] gs_mem_dout;
|
||||||
|
wire [7:0] gs_mem_din;
|
||||||
|
wire gs_mem_rd;
|
||||||
|
wire gs_mem_wr;
|
||||||
|
wire gs_mem_ready;
|
||||||
|
reg [7:0] gs_mem_mask;
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
gs_mem_mask = 0;
|
||||||
|
case(status[29:28])
|
||||||
|
0: if(gs_mem_addr[21:19]) gs_mem_mask = 8'hFF;
|
||||||
|
1: if(gs_mem_addr[21:20]) gs_mem_mask = 8'hFF;
|
||||||
|
2: if(gs_mem_addr[21] ) gs_mem_mask = 8'hFF;
|
||||||
|
3: gs_mem_mask = 0;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
ddram ddram
|
||||||
|
(
|
||||||
|
.*,
|
||||||
|
|
||||||
|
.addr(gs_mem_addr),
|
||||||
|
.dout(gs_mem_dout),
|
||||||
|
.din(gs_mem_din),
|
||||||
|
.we(gs_mem_wr),
|
||||||
|
.rd(gs_mem_rd),
|
||||||
|
.ready(gs_mem_ready)
|
||||||
|
);
|
||||||
|
|
||||||
|
assign AUDIO_S = 1;
|
||||||
assign AUDIO_MIX = status[4:3];
|
assign AUDIO_MIX = status[4:3];
|
||||||
|
|
||||||
reg ce_pix;
|
reg ce_pix;
|
||||||
|
124
ddram.sv
Normal file
124
ddram.sv
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
//
|
||||||
|
// ddram.v
|
||||||
|
//
|
||||||
|
// DE10-nano DDR3 memory interface
|
||||||
|
//
|
||||||
|
// Copyright (c) 2017 Sorgelig
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// 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/>.
|
||||||
|
//
|
||||||
|
// ------------------------------------------
|
||||||
|
//
|
||||||
|
|
||||||
|
// 8-bit version
|
||||||
|
|
||||||
|
module ddram
|
||||||
|
(
|
||||||
|
input reset,
|
||||||
|
input DDRAM_CLK,
|
||||||
|
|
||||||
|
input DDRAM_BUSY,
|
||||||
|
output [7:0] DDRAM_BURSTCNT,
|
||||||
|
output [28:0] DDRAM_ADDR,
|
||||||
|
input [63:0] DDRAM_DOUT,
|
||||||
|
input DDRAM_DOUT_READY,
|
||||||
|
output DDRAM_RD,
|
||||||
|
output [63:0] DDRAM_DIN,
|
||||||
|
output [7:0] DDRAM_BE,
|
||||||
|
output DDRAM_WE,
|
||||||
|
|
||||||
|
input [27:0] addr, // 256MB at the end of 1GB
|
||||||
|
output [7:0] dout, // data output to cpu
|
||||||
|
input [7:0] din, // data input from cpu
|
||||||
|
input we, // cpu requests write
|
||||||
|
input rd, // cpu requests read
|
||||||
|
output ready // dout is valid. Ready to accept new read/write.
|
||||||
|
);
|
||||||
|
|
||||||
|
assign DDRAM_BURSTCNT = 1;
|
||||||
|
assign DDRAM_BE = (8'd1<<ram_address[2:0]) | {8{ram_read}};
|
||||||
|
assign DDRAM_ADDR = {4'b0011, ram_address[27:3]}; // RAM at 0x30000000
|
||||||
|
assign DDRAM_RD = ram_read;
|
||||||
|
assign DDRAM_DIN = ram_cache;
|
||||||
|
assign DDRAM_WE = ram_write;
|
||||||
|
|
||||||
|
assign dout = ram_q;
|
||||||
|
assign ready = ~busy;
|
||||||
|
|
||||||
|
reg [7:0] ram_q;
|
||||||
|
reg [27:0] ram_address;
|
||||||
|
reg ram_read;
|
||||||
|
reg [63:0] ram_cache;
|
||||||
|
reg ram_write;
|
||||||
|
reg [7:0] cached;
|
||||||
|
reg busy;
|
||||||
|
|
||||||
|
|
||||||
|
always @(posedge DDRAM_CLK)
|
||||||
|
begin
|
||||||
|
reg old_rd, old_we;
|
||||||
|
reg old_reset;
|
||||||
|
reg state;
|
||||||
|
|
||||||
|
old_reset <= reset;
|
||||||
|
if(old_reset && ~reset) begin
|
||||||
|
busy <= 0;
|
||||||
|
state <= 0;
|
||||||
|
cached <= 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
if(!DDRAM_BUSY)
|
||||||
|
begin
|
||||||
|
ram_write <= 0;
|
||||||
|
ram_read <= 0;
|
||||||
|
if(state) begin
|
||||||
|
if(DDRAM_DOUT_READY) begin
|
||||||
|
ram_q <= DDRAM_DOUT[{ram_address[2:0], 3'b000} +:8];
|
||||||
|
ram_cache <= DDRAM_DOUT;
|
||||||
|
cached <= 8'hFF;
|
||||||
|
state <= 0;
|
||||||
|
busy <= 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
old_rd <= rd;
|
||||||
|
old_we <= we;
|
||||||
|
busy <= 0;
|
||||||
|
|
||||||
|
if(~old_we && we) begin
|
||||||
|
ram_cache[{addr[2:0], 3'b000} +:8] <= din;
|
||||||
|
ram_address <= addr;
|
||||||
|
busy <= 1;
|
||||||
|
ram_write <= 1;
|
||||||
|
cached <= ((ram_address[27:3] == addr[27:3]) ? cached : 8'h00) | (8'd1<<addr[2:0]);
|
||||||
|
end
|
||||||
|
|
||||||
|
if(~old_rd && rd) begin
|
||||||
|
if((ram_address[27:3] == addr[27:3]) && (cached & (8'd1<<addr[2:0]))) begin
|
||||||
|
ram_q <= ram_cache[{addr[2:0], 3'b000} +:8];
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
ram_address <= addr;
|
||||||
|
ram_read <= 1;
|
||||||
|
state <= 1;
|
||||||
|
cached <= 0;
|
||||||
|
busy <= 1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
72
dpram.v
Normal file
72
dpram.v
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
|
||||||
|
module dpram #(parameter DATAWIDTH=8, ADDRWIDTH=8, NUMWORDS=1<<ADDRWIDTH, MEM_INIT_FILE="")
|
||||||
|
(
|
||||||
|
input clock,
|
||||||
|
|
||||||
|
input [ADDRWIDTH-1:0] address_a,
|
||||||
|
input [DATAWIDTH-1:0] data_a,
|
||||||
|
input wren_a,
|
||||||
|
output [DATAWIDTH-1:0] q_a,
|
||||||
|
|
||||||
|
input [ADDRWIDTH-1:0] address_b,
|
||||||
|
input [DATAWIDTH-1:0] data_b,
|
||||||
|
input wren_b,
|
||||||
|
output [DATAWIDTH-1:0] q_b
|
||||||
|
);
|
||||||
|
|
||||||
|
altsyncram altsyncram_component (
|
||||||
|
.address_a (address_a),
|
||||||
|
.address_b (address_b),
|
||||||
|
.clock0 (clock),
|
||||||
|
.data_a (data_a),
|
||||||
|
.data_b (data_b),
|
||||||
|
.wren_a (wren_a),
|
||||||
|
.wren_b (wren_b),
|
||||||
|
.q_a (q_a),
|
||||||
|
.q_b (q_b),
|
||||||
|
.aclr0 (1'b0),
|
||||||
|
.aclr1 (1'b0),
|
||||||
|
.addressstall_a (1'b0),
|
||||||
|
.addressstall_b (1'b0),
|
||||||
|
.byteena_a (1'b1),
|
||||||
|
.byteena_b (1'b1),
|
||||||
|
.clock1 (1'b1),
|
||||||
|
.clocken0 (1'b1),
|
||||||
|
.clocken1 (1'b1),
|
||||||
|
.clocken2 (1'b1),
|
||||||
|
.clocken3 (1'b1),
|
||||||
|
.eccstatus (),
|
||||||
|
.rden_a (1'b1),
|
||||||
|
.rden_b (1'b1));
|
||||||
|
defparam
|
||||||
|
altsyncram_component.wrcontrol_wraddress_reg_b = "CLOCK0",
|
||||||
|
altsyncram_component.address_reg_b = "CLOCK0",
|
||||||
|
altsyncram_component.indata_reg_b = "CLOCK0",
|
||||||
|
altsyncram_component.numwords_a = NUMWORDS,
|
||||||
|
altsyncram_component.numwords_b = NUMWORDS,
|
||||||
|
altsyncram_component.widthad_a = ADDRWIDTH,
|
||||||
|
altsyncram_component.widthad_b = ADDRWIDTH,
|
||||||
|
altsyncram_component.width_a = DATAWIDTH,
|
||||||
|
altsyncram_component.width_b = DATAWIDTH,
|
||||||
|
altsyncram_component.width_byteena_a = 1,
|
||||||
|
altsyncram_component.width_byteena_b = 1,
|
||||||
|
|
||||||
|
altsyncram_component.init_file = MEM_INIT_FILE,
|
||||||
|
altsyncram_component.clock_enable_input_a = "BYPASS",
|
||||||
|
altsyncram_component.clock_enable_input_b = "BYPASS",
|
||||||
|
altsyncram_component.clock_enable_output_a = "BYPASS",
|
||||||
|
altsyncram_component.clock_enable_output_b = "BYPASS",
|
||||||
|
altsyncram_component.intended_device_family = "Cyclone V",
|
||||||
|
altsyncram_component.lpm_type = "altsyncram",
|
||||||
|
altsyncram_component.operation_mode = "BIDIR_DUAL_PORT",
|
||||||
|
altsyncram_component.outdata_aclr_a = "NONE",
|
||||||
|
altsyncram_component.outdata_aclr_b = "NONE",
|
||||||
|
altsyncram_component.outdata_reg_a = "UNREGISTERED",
|
||||||
|
altsyncram_component.outdata_reg_b = "UNREGISTERED",
|
||||||
|
altsyncram_component.power_up_uninitialized = "FALSE",
|
||||||
|
altsyncram_component.read_during_write_mode_mixed_ports = "DONT_CARE",
|
||||||
|
altsyncram_component.read_during_write_mode_port_a = "NEW_DATA_NO_NBE_READ",
|
||||||
|
altsyncram_component.read_during_write_mode_port_b = "NEW_DATA_NO_NBE_READ";
|
||||||
|
|
||||||
|
|
||||||
|
endmodule
|
@ -1,84 +0,0 @@
|
|||||||
-- -----------------------------------------------------------------------
|
|
||||||
--
|
|
||||||
-- Syntiac's generic VHDL support files.
|
|
||||||
--
|
|
||||||
-- -----------------------------------------------------------------------
|
|
||||||
-- Copyright 2005-2008 by Peter Wendrich (pwsoft@syntiac.com)
|
|
||||||
-- http://www.syntiac.com/fpga64.html
|
|
||||||
--
|
|
||||||
-- Modified April 2016 by Dar (darfpga@aol.fr)
|
|
||||||
-- http://darfpga.blogspot.fr
|
|
||||||
-- Remove address register when writing
|
|
||||||
--
|
|
||||||
-- -----------------------------------------------------------------------
|
|
||||||
--
|
|
||||||
-- gen_rwram.vhd
|
|
||||||
--
|
|
||||||
-- -----------------------------------------------------------------------
|
|
||||||
--
|
|
||||||
-- generic ram.
|
|
||||||
--
|
|
||||||
-- -----------------------------------------------------------------------
|
|
||||||
|
|
||||||
library IEEE;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
use IEEE.numeric_std.ALL;
|
|
||||||
|
|
||||||
-- -----------------------------------------------------------------------
|
|
||||||
|
|
||||||
entity gen_ram is
|
|
||||||
generic (
|
|
||||||
dWidth : integer := 8;
|
|
||||||
aWidth : integer := 10
|
|
||||||
);
|
|
||||||
port (
|
|
||||||
clk : in std_logic;
|
|
||||||
we : in std_logic;
|
|
||||||
addr : in std_logic_vector((aWidth-1) downto 0);
|
|
||||||
d : in std_logic_vector((dWidth-1) downto 0);
|
|
||||||
q : out std_logic_vector((dWidth-1) downto 0)
|
|
||||||
);
|
|
||||||
end entity;
|
|
||||||
|
|
||||||
-- -----------------------------------------------------------------------
|
|
||||||
|
|
||||||
architecture rtl of gen_ram is
|
|
||||||
subtype addressRange is integer range 0 to ((2**aWidth)-1);
|
|
||||||
type ramDef is array(addressRange) of std_logic_vector((dWidth-1) downto 0);
|
|
||||||
signal ram: ramDef;
|
|
||||||
|
|
||||||
signal rAddrReg : std_logic_vector((aWidth-1) downto 0);
|
|
||||||
signal qReg : std_logic_vector((dWidth-1) downto 0);
|
|
||||||
begin
|
|
||||||
-- -----------------------------------------------------------------------
|
|
||||||
-- Signals to entity interface
|
|
||||||
-- -----------------------------------------------------------------------
|
|
||||||
-- q <= qReg;
|
|
||||||
|
|
||||||
-- -----------------------------------------------------------------------
|
|
||||||
-- Memory write
|
|
||||||
-- -----------------------------------------------------------------------
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if we = '1' then
|
|
||||||
ram(to_integer(unsigned(addr))) <= d;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
-- -----------------------------------------------------------------------
|
|
||||||
-- Memory read
|
|
||||||
-- -----------------------------------------------------------------------
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
-- qReg <= ram(to_integer(unsigned(rAddrReg)));
|
|
||||||
-- rAddrReg <= addr;
|
|
||||||
---- qReg <= ram(to_integer(unsigned(addr)));
|
|
||||||
q <= ram(to_integer(unsigned(addr)));
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
--q <= ram(to_integer(unsigned(addr)));
|
|
||||||
end architecture;
|
|
||||||
|
|
255
src/sound/gs.v
Normal file
255
src/sound/gs.v
Normal file
@ -0,0 +1,255 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
General Sound
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
18.08.2018 Reworked first verilog version
|
||||||
|
19.08.2018 Produce proper signed output
|
||||||
|
|
||||||
|
CPU: Z80 @ 28MHz
|
||||||
|
ROM: 32K
|
||||||
|
RAM: 128KB+
|
||||||
|
INT: 37.5KHz
|
||||||
|
|
||||||
|
#xxBB Command register - регистр команд, доступный для записи
|
||||||
|
#xxBB Status register - регистр состояния, доступный для чтения
|
||||||
|
bit 7 флаг данных
|
||||||
|
bit <6:1> Не определен
|
||||||
|
bit 0 флаг команд. Этот регистр позволяет определить состояние GS, в частности можно ли прочитать или записать очередной байт данных, или подать очередную команду, и т.п.
|
||||||
|
#xxB3 Data register - регистр данных, доступный для записи. В этот регистр Спектрум записывает данные, например, это могут быть аргументы команд.
|
||||||
|
#xxB3 Output register - регистр вывода, доступный для чтения. Из этого регистра Спектрум читает данные, идущие от GS
|
||||||
|
|
||||||
|
Внутренние порта:
|
||||||
|
#xx00 "расширенная память" - регистр доступный для записи
|
||||||
|
bit <3:0> переключают страницы по 32Kb, страница 0 - ПЗУ
|
||||||
|
bit <7:0> не используются
|
||||||
|
|
||||||
|
порты 1 - 5 "обеспечивают связь с SPECTRUM'ом"
|
||||||
|
#xx01 чтение команды General Sound'ом
|
||||||
|
bit <7:0> код команды
|
||||||
|
#xx02 чтение данных General Sound'ом
|
||||||
|
bit <7:0> данные
|
||||||
|
#xx03 запись данных General Sound'ом для SPECTRUM'a
|
||||||
|
bit <7:0> данные
|
||||||
|
#xx04 чтение слова состояния General Sound'ом
|
||||||
|
bit 0 флаг команд
|
||||||
|
bit 7 флаг данных
|
||||||
|
#xx05 сбрасывает бит D0 (флаг команд) слова состояния
|
||||||
|
|
||||||
|
порты 6 - 9 "регулировка громкости" в каналах 1 - 4
|
||||||
|
#xx06 "регулировка громкости" в канале 1
|
||||||
|
bit <5:0> громкость
|
||||||
|
bit <7:6> не используются
|
||||||
|
#xx07 "регулировка громкости" в канале 2
|
||||||
|
bit <5:0> громкость
|
||||||
|
bit <7:6> не используются
|
||||||
|
#xx08 "регулировка громкости" в канале 3
|
||||||
|
bit <5:0> громкость
|
||||||
|
bit <7:6> не используются
|
||||||
|
#xx09 "регулировка громкости" в канале 4
|
||||||
|
bit <5:0> громкость
|
||||||
|
bit <7:6> не используются
|
||||||
|
|
||||||
|
#xx0A устанавливает бит 7 слова состояния не равным биту 0 порта #xx00
|
||||||
|
#xx0B устанавливает бит 0 слова состояния равным биту 5 порта #xx06
|
||||||
|
|
||||||
|
Распределение памяти
|
||||||
|
#0000 - #3FFF - первые 16Kb ПЗУ
|
||||||
|
#4000 - #7FFF - первые 16Kb первой страницы ОЗУ
|
||||||
|
#8000 - #FFFF - листаемые страницы по 32Kb
|
||||||
|
страница 0 - ПЗУ,
|
||||||
|
страница 1 - первая страница ОЗУ
|
||||||
|
страницы 2... ОЗУ
|
||||||
|
|
||||||
|
Данные в каналы заносятся при чтении процессором ОЗУ по адресам #6000 - #7FFF автоматически.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
module gs #(parameter PAGES=4, ROMFILE="gs105b.mif")
|
||||||
|
(
|
||||||
|
input RESET,
|
||||||
|
input CLK,
|
||||||
|
input CE,
|
||||||
|
|
||||||
|
input A,
|
||||||
|
input [7:0] DI,
|
||||||
|
output [7:0] DO,
|
||||||
|
input CS_n,
|
||||||
|
input WR_n,
|
||||||
|
input RD_n,
|
||||||
|
|
||||||
|
output [21:0] MEM_ADDR,
|
||||||
|
output [7:0] MEM_DI,
|
||||||
|
input [7:0] MEM_DO,
|
||||||
|
output MEM_RD,
|
||||||
|
output MEM_WR,
|
||||||
|
input MEM_WAIT,
|
||||||
|
|
||||||
|
output [14:0] OUTL,
|
||||||
|
output [14:0] OUTR
|
||||||
|
);
|
||||||
|
|
||||||
|
// port #xxBB : #xxB3
|
||||||
|
assign DO = A ? {bit7, 6'b111111, bit0} : port_03;
|
||||||
|
|
||||||
|
// CPU
|
||||||
|
reg int_n;
|
||||||
|
wire cpu_m1_n;
|
||||||
|
wire cpu_mreq_n;
|
||||||
|
wire cpu_iorq_n;
|
||||||
|
wire cpu_rd_n;
|
||||||
|
wire cpu_wr_n;
|
||||||
|
wire [15:0] cpu_a_bus;
|
||||||
|
wire [7:0] cpu_do_bus;
|
||||||
|
|
||||||
|
T80s cpu
|
||||||
|
(
|
||||||
|
.RESET_n(~RESET),
|
||||||
|
.CLK_n(CLK),
|
||||||
|
.CEN(CE & ~MEM_WAIT),
|
||||||
|
.WAIT_n(1),
|
||||||
|
.INT_n(int_n),
|
||||||
|
.NMI_n(1),
|
||||||
|
.BUSRQ_n(1),
|
||||||
|
.M1_n(cpu_m1_n),
|
||||||
|
.MREQ_n(cpu_mreq_n),
|
||||||
|
.IORQ_n(cpu_iorq_n),
|
||||||
|
.RD_n(cpu_rd_n),
|
||||||
|
.WR_n(cpu_wr_n),
|
||||||
|
.A(cpu_a_bus),
|
||||||
|
.DO(cpu_do_bus),
|
||||||
|
.DI(cpu_di_bus)
|
||||||
|
);
|
||||||
|
|
||||||
|
// INT#
|
||||||
|
always @(posedge CLK) begin
|
||||||
|
reg [9:0] cnt;
|
||||||
|
|
||||||
|
if(CE) begin
|
||||||
|
cnt <= cnt + 1'b1;
|
||||||
|
if (cnt == 746) begin // 37.48kHz
|
||||||
|
cnt <= 0;
|
||||||
|
int_n <= 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if (~cpu_iorq_n & ~cpu_m1_n) int_n <= 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
reg bit7;
|
||||||
|
reg bit0;
|
||||||
|
always @(posedge CLK) begin
|
||||||
|
if (~cpu_iorq_n & cpu_m1_n) begin
|
||||||
|
case(cpu_a_bus[3:0])
|
||||||
|
'h2: bit7 <= 0;
|
||||||
|
'h3: bit7 <= 1;
|
||||||
|
'h5: bit0 <= 0;
|
||||||
|
'hA: bit7 <= ~port_00[0];
|
||||||
|
'hB: bit0 <= port_09[5];
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
else if (~CS_n) begin
|
||||||
|
if (~A & ~RD_n) bit7 <= 0;
|
||||||
|
if (~A & ~WR_n) bit7 <= 1;
|
||||||
|
if ( A & ~WR_n) bit0 <= 1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
reg [7:0] port_BB;
|
||||||
|
reg [7:0] port_B3;
|
||||||
|
always @(posedge CLK) begin
|
||||||
|
if (RESET) begin
|
||||||
|
port_BB <= 0;
|
||||||
|
port_B3 <= 0;
|
||||||
|
end
|
||||||
|
else if (~CS_n && ~WR_n) begin
|
||||||
|
if(A) port_BB <= DI;
|
||||||
|
else port_B3 <= DI;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
reg [6:0] port_00;
|
||||||
|
reg [7:0] port_03;
|
||||||
|
reg signed [6:0] port_06, port_07, port_08, port_09;
|
||||||
|
reg signed [7:0] ch_a, ch_b, ch_c, ch_d;
|
||||||
|
|
||||||
|
always @(posedge CLK) begin
|
||||||
|
if (RESET) begin
|
||||||
|
port_00 <= 0;
|
||||||
|
port_03 <= 0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if (~cpu_iorq_n & ~cpu_wr_n) begin
|
||||||
|
case(cpu_a_bus[3:0])
|
||||||
|
0: port_00 <= cpu_do_bus[6:0];
|
||||||
|
3: port_03 <= cpu_do_bus;
|
||||||
|
6: port_06 <= cpu_do_bus[5:0];
|
||||||
|
7: port_07 <= cpu_do_bus[5:0];
|
||||||
|
8: port_08 <= cpu_do_bus[5:0];
|
||||||
|
9: port_09 <= cpu_do_bus[5:0];
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
if (~cpu_mreq_n && ~cpu_rd_n && cpu_a_bus[15:13] == 3) begin
|
||||||
|
case(cpu_a_bus[9:8])
|
||||||
|
0: ch_a <= {~mem_do[7],mem_do[6:0]};
|
||||||
|
1: ch_b <= {~mem_do[7],mem_do[6:0]};
|
||||||
|
2: ch_c <= {~mem_do[7],mem_do[6:0]};
|
||||||
|
3: ch_d <= {~mem_do[7],mem_do[6:0]};
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
wire [7:0] cpu_di_bus =
|
||||||
|
(~cpu_mreq_n && !page_addr[6:1]) ? mem_do :
|
||||||
|
(~cpu_mreq_n) ? MEM_DO :
|
||||||
|
(~cpu_iorq_n && cpu_a_bus[3:0] == 1) ? port_BB :
|
||||||
|
(~cpu_iorq_n && cpu_a_bus[3:0] == 2) ? port_B3 :
|
||||||
|
(~cpu_iorq_n && cpu_a_bus[3:0] == 4) ? {bit7, 6'b111111, bit0} :
|
||||||
|
8'hFF;
|
||||||
|
|
||||||
|
wire mem_wr = ~cpu_wr_n & ~cpu_mreq_n & |page_addr;
|
||||||
|
wire mem_rd = ~cpu_rd_n & ~cpu_mreq_n;
|
||||||
|
|
||||||
|
wire [6:0] page_addr = cpu_a_bus[15] ? port_00 : cpu_a_bus[14];
|
||||||
|
|
||||||
|
assign MEM_ADDR = {page_addr, &cpu_a_bus[15:14], cpu_a_bus[13:0]};
|
||||||
|
assign MEM_RD = mem_rd && |page_addr[6:1];
|
||||||
|
assign MEM_WR = mem_wr && |page_addr[6:1];
|
||||||
|
assign MEM_DI = cpu_do_bus;
|
||||||
|
|
||||||
|
wire [7:0] mem_do;
|
||||||
|
dpram #(.ADDRWIDTH(16), .NUMWORDS(2*32768), .MEM_INIT_FILE(ROMFILE)) mem
|
||||||
|
(
|
||||||
|
.clock(CLK),
|
||||||
|
.address_a(MEM_ADDR[15:0]),
|
||||||
|
.wren_a(mem_wr && !page_addr[6:1]),
|
||||||
|
.data_a(cpu_do_bus),
|
||||||
|
.q_a(mem_do)
|
||||||
|
);
|
||||||
|
|
||||||
|
reg signed [14:0] out_a,out_b,out_c,out_d;
|
||||||
|
always @(posedge CLK) begin
|
||||||
|
if(CE) begin
|
||||||
|
out_a <= ch_a * port_06;
|
||||||
|
out_b <= ch_b * port_07;
|
||||||
|
out_c <= ch_c * port_08;
|
||||||
|
out_d <= ch_d * port_09;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
reg signed [14:0] outl, outr;
|
||||||
|
always @(posedge CLK) begin
|
||||||
|
if(CE) begin
|
||||||
|
outl <= out_a + out_b;
|
||||||
|
outr <= out_c + out_d;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign OUTL = outl;
|
||||||
|
assign OUTR = outr;
|
||||||
|
|
||||||
|
endmodule
|
329
src/sound/gs.vhd
329
src/sound/gs.vhd
@ -1,329 +0,0 @@
|
|||||||
-------------------------------------------------------------------[04.10.2015]
|
|
||||||
-- General Sound
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
-- 01.11.2011 первая версия
|
|
||||||
-- 19.12.2011 CPU @ 84MHz, подтверждение INT#
|
|
||||||
-- 10.05.2013 исправлен bit7_flag, bit0_flag
|
|
||||||
-- 29.05.2013 добавлена громкость каналов, CPU @ 21MHz
|
|
||||||
-- 21.07.2013 исправлен int_n
|
|
||||||
|
|
||||||
-- CPU: Z80
|
|
||||||
-- ROM: 32K
|
|
||||||
-- RAM: 384K
|
|
||||||
-- INT: 37.5KHz
|
|
||||||
|
|
||||||
-- #xxBB Command register - регистр команд, доступный для записи
|
|
||||||
-- #xxBB Status register - регистр состояния, доступный для чтения
|
|
||||||
-- bit 7 флаг данных
|
|
||||||
-- bit <6:1> Не определен
|
|
||||||
-- bit 0 флаг команд. Этот регистр позволяет определить состояние GS, в частности можно ли прочитать или записать очередной байт данных, или подать очередную команду, и т.п.
|
|
||||||
-- #xxB3 Data register - регистр данных, доступный для записи. В этот регистр Спектрум записывает данные, например, это могут быть аргументы команд.
|
|
||||||
-- #xxB3 Output register - регистр вывода, доступный для чтения. Из этого регистра Спектрум читает данные, идущие от GS
|
|
||||||
|
|
||||||
-- Внутренние порта:
|
|
||||||
-- #xx00 "расширенная память" - регистр доступный для записи
|
|
||||||
-- bit <3:0> переключают страницы по 32Kb, страница 0 - ПЗУ
|
|
||||||
-- bit <7:0> не используются
|
|
||||||
|
|
||||||
-- порты 1 - 5 "обеспечивают связь с SPECTRUM'ом"
|
|
||||||
-- #xx01 чтение команды General Sound'ом
|
|
||||||
-- bit <7:0> код команды
|
|
||||||
-- #xx02 чтение данных General Sound'ом
|
|
||||||
-- bit <7:0> данные
|
|
||||||
-- #xx03 запись данных General Sound'ом для SPECTRUM'a
|
|
||||||
-- bit <7:0> данные
|
|
||||||
-- #xx04 чтение слова состояния General Sound'ом
|
|
||||||
-- bit 0 флаг команд
|
|
||||||
-- bit 7 флаг данных
|
|
||||||
-- #xx05 сбрасывает бит D0 (флаг команд) слова состояния
|
|
||||||
|
|
||||||
-- порты 6 - 9 "регулировка громкости" в каналах 1 - 4
|
|
||||||
-- #xx06 "регулировка громкости" в канале 1
|
|
||||||
-- bit <5:0> громкость
|
|
||||||
-- bit <7:6> не используются
|
|
||||||
-- #xx07 "регулировка громкости" в канале 2
|
|
||||||
-- bit <5:0> громкость
|
|
||||||
-- bit <7:6> не используются
|
|
||||||
-- #xx08 "регулировка громкости" в канале 3
|
|
||||||
-- bit <5:0> громкость
|
|
||||||
-- bit <7:6> не используются
|
|
||||||
-- #xx09 "регулировка громкости" в канале 4
|
|
||||||
-- bit <5:0> громкость
|
|
||||||
-- bit <7:6> не используются
|
|
||||||
|
|
||||||
-- #xx0A устанавливает бит 7 слова состояния не равным биту 0 порта #xx00
|
|
||||||
-- #xx0B устанавливает бит 0 слова состояния равным биту 5 порта #xx06
|
|
||||||
|
|
||||||
--Распределение памяти
|
|
||||||
--#0000 - #3FFF - первые 16Kb ПЗУ
|
|
||||||
--#4000 - #7FFF - первые 16Kb первой страницы ОЗУ
|
|
||||||
--#8000 - #FFFF - листаемые страницы по 32Kb
|
|
||||||
-- страница 0 - ПЗУ,
|
|
||||||
-- страница 1 - первая страница ОЗУ
|
|
||||||
-- страницы 2... ОЗУ
|
|
||||||
|
|
||||||
--Данные в каналы заносятся при чтении процессором ОЗУ по адресам #6000 - #7FFF автоматически.
|
|
||||||
|
|
||||||
library IEEE;
|
|
||||||
use IEEE.std_logic_1164.all;
|
|
||||||
use IEEE.std_logic_unsigned.all;
|
|
||||||
use IEEE.numeric_std.all;
|
|
||||||
use IEEE.STD_LOGIC_ARITH.all;
|
|
||||||
|
|
||||||
entity gs is
|
|
||||||
Port (
|
|
||||||
RESET : in std_logic;
|
|
||||||
CLK : in std_logic;
|
|
||||||
CE : in std_logic;
|
|
||||||
A : in std_logic_vector(15 downto 0);
|
|
||||||
DI : in std_logic_vector(7 downto 0);
|
|
||||||
DO : out std_logic_vector(7 downto 0);
|
|
||||||
WR_n : in std_logic;
|
|
||||||
RD_n : in std_logic;
|
|
||||||
IORQ_n : in std_logic;
|
|
||||||
M1_n : in std_logic;
|
|
||||||
OUTL : out std_logic_vector(14 downto 0);
|
|
||||||
OUTR : out std_logic_vector(14 downto 0)
|
|
||||||
);
|
|
||||||
end gs;
|
|
||||||
|
|
||||||
architecture gs_unit of gs is
|
|
||||||
signal port_xxbb_reg : std_logic_vector(7 downto 0);
|
|
||||||
signal port_xxb3_reg : std_logic_vector(7 downto 0);
|
|
||||||
signal port_xx00_reg : std_logic_vector(7 downto 0);
|
|
||||||
signal port_xx03_reg : std_logic_vector(7 downto 0);
|
|
||||||
signal port_xx06_reg : std_logic_vector(5 downto 0);
|
|
||||||
signal port_xx07_reg : std_logic_vector(5 downto 0);
|
|
||||||
signal port_xx08_reg : std_logic_vector(5 downto 0);
|
|
||||||
signal port_xx09_reg : std_logic_vector(5 downto 0);
|
|
||||||
signal ch_a_reg : std_logic_vector(7 downto 0);
|
|
||||||
signal ch_b_reg : std_logic_vector(7 downto 0);
|
|
||||||
signal ch_c_reg : std_logic_vector(7 downto 0);
|
|
||||||
signal ch_d_reg : std_logic_vector(7 downto 0);
|
|
||||||
signal bit7_flag : std_logic;
|
|
||||||
signal bit0_flag : std_logic;
|
|
||||||
signal cnt : std_logic_vector(9 downto 0);
|
|
||||||
signal int_n : std_logic;
|
|
||||||
signal out_a : std_logic_vector(13 downto 0);
|
|
||||||
signal out_b : std_logic_vector(13 downto 0);
|
|
||||||
signal out_c : std_logic_vector(13 downto 0);
|
|
||||||
signal out_d : std_logic_vector(13 downto 0);
|
|
||||||
|
|
||||||
-- CPU
|
|
||||||
signal cpu_m1_n : std_logic;
|
|
||||||
signal cpu_mreq_n : std_logic;
|
|
||||||
signal cpu_iorq_n : std_logic;
|
|
||||||
signal cpu_rd_n : std_logic;
|
|
||||||
signal cpu_wr_n : std_logic;
|
|
||||||
signal cpu_a_bus : std_logic_vector(15 downto 0);
|
|
||||||
signal cpu_di_bus : std_logic_vector(7 downto 0);
|
|
||||||
signal cpu_do_bus : std_logic_vector(7 downto 0);
|
|
||||||
|
|
||||||
signal ram_we : std_logic;
|
|
||||||
signal ram_en : std_logic;
|
|
||||||
signal rom_do : std_logic_vector(7 downto 0);
|
|
||||||
signal ram1_do : std_logic_vector(7 downto 0);
|
|
||||||
signal ram2_do : std_logic_vector(7 downto 0);
|
|
||||||
signal mem_do : std_logic_vector(7 downto 0);
|
|
||||||
signal ram_addr : std_logic_vector(18 downto 0);
|
|
||||||
begin
|
|
||||||
|
|
||||||
z80_unit: entity work.T80s
|
|
||||||
generic map (
|
|
||||||
Mode => 0, -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
|
|
||||||
T2Write => 1, -- 0 => WR_n active in T3, 1 => WR_n active in T2
|
|
||||||
IOWait => 1) -- 0 => Single cycle I/O, 1 => Std I/O cycle
|
|
||||||
port map (
|
|
||||||
RESET_n => not RESET,
|
|
||||||
CLK_n => CLK,
|
|
||||||
CEN => CE,
|
|
||||||
WAIT_n => '1',
|
|
||||||
INT_n => int_n,
|
|
||||||
NMI_n => '1',
|
|
||||||
BUSRQ_n => '1',
|
|
||||||
M1_n => cpu_m1_n,
|
|
||||||
MREQ_n => cpu_mreq_n,
|
|
||||||
IORQ_n => cpu_iorq_n,
|
|
||||||
RD_n => cpu_rd_n,
|
|
||||||
WR_n => cpu_wr_n,
|
|
||||||
A => cpu_a_bus,
|
|
||||||
DI => cpu_di_bus,
|
|
||||||
DO => cpu_do_bus);
|
|
||||||
|
|
||||||
|
|
||||||
-- INT#
|
|
||||||
process (CLK)
|
|
||||||
begin
|
|
||||||
if rising_edge(CLK) then
|
|
||||||
if CE = '1' then
|
|
||||||
cnt <= cnt + 1;
|
|
||||||
if cnt = "1011101010" then -- 28MHz / 747 = 0.03748MHz = 37.48kHz
|
|
||||||
cnt <= (others => '0');
|
|
||||||
int_n <= '0';
|
|
||||||
end if;
|
|
||||||
if cpu_iorq_n = '0' and cpu_m1_n = '0' then
|
|
||||||
int_n <= '1';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
process (CLK)
|
|
||||||
begin
|
|
||||||
if rising_edge(CLK) then
|
|
||||||
if (cpu_iorq_n = '0' and cpu_m1_n = '1' and cpu_a_bus(3 downto 0) = X"2") or (IORQ_n = '0' and RD_n = '0' and A(7 downto 0) = X"B3") then
|
|
||||||
bit7_flag <= '0';
|
|
||||||
elsif (cpu_iorq_n = '0' and cpu_m1_n = '1' and cpu_a_bus(3 downto 0) = X"3") or (IORQ_n = '0' and WR_n = '0' and A(7 downto 0) = X"B3") then
|
|
||||||
bit7_flag <= '1';
|
|
||||||
elsif (cpu_iorq_n = '0' and cpu_m1_n = '1' and cpu_a_bus(3 downto 0) = X"A") then
|
|
||||||
bit7_flag <= not port_xx00_reg(0);
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
process (CLK)
|
|
||||||
begin
|
|
||||||
if rising_edge(CLK) then
|
|
||||||
if cpu_iorq_n = '0' and cpu_m1_n = '1' and cpu_a_bus(3 downto 0) = X"5" then
|
|
||||||
bit0_flag <= '0';
|
|
||||||
elsif IORQ_n = '0' and WR_n = '0' and A(7 downto 0) = X"BB" then
|
|
||||||
bit0_flag <= '1';
|
|
||||||
elsif cpu_iorq_n = '0' and cpu_m1_n = '1' and cpu_a_bus(3 downto 0) = X"B" then
|
|
||||||
bit0_flag <= port_xx09_reg(5);
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
process (CLK)
|
|
||||||
begin
|
|
||||||
-- запись со стороны спектрума
|
|
||||||
if rising_edge(CLK) then
|
|
||||||
if RESET = '1' then
|
|
||||||
port_xxbb_reg <= (others => '0');
|
|
||||||
port_xxb3_reg <= (others => '0');
|
|
||||||
else
|
|
||||||
if IORQ_n = '0' and WR_n = '0' and A(7 downto 0) = X"BB" then port_xxbb_reg <= DI; end if;
|
|
||||||
if IORQ_n = '0' and WR_n = '0' and A(7 downto 0) = X"B3" then port_xxb3_reg <= DI; end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
-- port #xxBB / #xxB3
|
|
||||||
DO <= bit7_flag & "111111" & bit0_flag when A(3) = '1' else port_xx03_reg;
|
|
||||||
|
|
||||||
process (CLK)
|
|
||||||
begin
|
|
||||||
if rising_edge(CLK) then
|
|
||||||
if RESET = '1' then
|
|
||||||
port_xx00_reg <= (others => '0');
|
|
||||||
port_xx03_reg <= (others => '0');
|
|
||||||
port_xx06_reg <= (others => '0');
|
|
||||||
port_xx07_reg <= (others => '0');
|
|
||||||
port_xx08_reg <= (others => '0');
|
|
||||||
port_xx09_reg <= (others => '0');
|
|
||||||
ch_a_reg <= (others => '0');
|
|
||||||
ch_b_reg <= (others => '0');
|
|
||||||
ch_c_reg <= (others => '0');
|
|
||||||
ch_d_reg <= (others => '0');
|
|
||||||
elsif CE = '1' then
|
|
||||||
if cpu_iorq_n = '0' and cpu_wr_n = '0' and cpu_a_bus(3 downto 0) = X"0" then port_xx00_reg <= cpu_do_bus; end if;
|
|
||||||
if cpu_iorq_n = '0' and cpu_wr_n = '0' and cpu_a_bus(3 downto 0) = X"3" then port_xx03_reg <= cpu_do_bus; end if;
|
|
||||||
if cpu_iorq_n = '0' and cpu_wr_n = '0' and cpu_a_bus(3 downto 0) = X"6" then port_xx06_reg <= cpu_do_bus(5 downto 0); end if;
|
|
||||||
if cpu_iorq_n = '0' and cpu_wr_n = '0' and cpu_a_bus(3 downto 0) = X"7" then port_xx07_reg <= cpu_do_bus(5 downto 0); end if;
|
|
||||||
if cpu_iorq_n = '0' and cpu_wr_n = '0' and cpu_a_bus(3 downto 0) = X"8" then port_xx08_reg <= cpu_do_bus(5 downto 0); end if;
|
|
||||||
if cpu_iorq_n = '0' and cpu_wr_n = '0' and cpu_a_bus(3 downto 0) = X"9" then port_xx09_reg <= cpu_do_bus(5 downto 0); end if;
|
|
||||||
|
|
||||||
if cpu_mreq_n = '0' and cpu_rd_n = '0' and cpu_a_bus(15 downto 13) = "011" and cpu_a_bus(9 downto 8) = "00" then ch_a_reg <= ram1_do; end if;
|
|
||||||
if cpu_mreq_n = '0' and cpu_rd_n = '0' and cpu_a_bus(15 downto 13) = "011" and cpu_a_bus(9 downto 8) = "01" then ch_b_reg <= ram1_do; end if;
|
|
||||||
if cpu_mreq_n = '0' and cpu_rd_n = '0' and cpu_a_bus(15 downto 13) = "011" and cpu_a_bus(9 downto 8) = "10" then ch_c_reg <= ram1_do; end if;
|
|
||||||
if cpu_mreq_n = '0' and cpu_rd_n = '0' and cpu_a_bus(15 downto 13) = "011" and cpu_a_bus(9 downto 8) = "11" then ch_d_reg <= ram1_do; end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
-- Шина данных CPU
|
|
||||||
cpu_di_bus <=
|
|
||||||
mem_do when (cpu_mreq_n = '0' and cpu_rd_n = '0') else
|
|
||||||
bit7_flag & "111111" & bit0_flag when (cpu_iorq_n = '0' and cpu_rd_n = '0' and cpu_a_bus(3 downto 0) = X"4") else
|
|
||||||
port_xxbb_reg when (cpu_iorq_n = '0' and cpu_rd_n = '0' and cpu_a_bus(3 downto 0) = X"1") else
|
|
||||||
port_xxb3_reg when (cpu_iorq_n = '0' and cpu_rd_n = '0' and cpu_a_bus(3 downto 0) = X"2") else
|
|
||||||
"11111111";
|
|
||||||
|
|
||||||
ram_en <= '1' when cpu_a_bus(15 downto 14) = "01" or (cpu_a_bus(15) = '1' and port_xx00_reg(3 downto 0) /= "0000") else '0';
|
|
||||||
ram_we <= not cpu_wr_n and not cpu_mreq_n and ram_en;
|
|
||||||
|
|
||||||
ram_addr <=
|
|
||||||
"00000" & cpu_a_bus(13 downto 0) when cpu_a_bus(15) = '0' else
|
|
||||||
(port_xx00_reg(3 downto 0) - "0001") & cpu_a_bus(14 downto 0);
|
|
||||||
|
|
||||||
mem_do <=
|
|
||||||
rom_do when ram_en = '0' else
|
|
||||||
ram1_do when cpu_a_bus(15 downto 14) = "01" or (cpu_a_bus(15) = '1' and port_xx00_reg(3 downto 0) /= "0000" and ram_addr(18) = '0') else
|
|
||||||
ram2_do when cpu_a_bus(15) = '1' and port_xx00_reg(3 downto 0) /= "0000" and ram_addr(18 downto 17) = "10" else
|
|
||||||
x"FF";
|
|
||||||
|
|
||||||
ROM: entity work.gen_rom
|
|
||||||
generic map
|
|
||||||
(
|
|
||||||
INIT_FILE => "src/sound/gs105a.mif ",
|
|
||||||
ADDR_WIDTH => 15
|
|
||||||
)
|
|
||||||
port map
|
|
||||||
(
|
|
||||||
wrclock => CLK,
|
|
||||||
rdclock => CLK,
|
|
||||||
rdaddress => cpu_a_bus(14 downto 0),
|
|
||||||
q => rom_do
|
|
||||||
);
|
|
||||||
|
|
||||||
-- 256KB
|
|
||||||
RAM1: entity work.gen_ram
|
|
||||||
generic map (
|
|
||||||
aWidth => 18
|
|
||||||
)
|
|
||||||
port map
|
|
||||||
(
|
|
||||||
clk => CLK,
|
|
||||||
we => ram_we and not ram_addr(18),
|
|
||||||
addr => ram_addr(17 downto 0),
|
|
||||||
d => cpu_do_bus,
|
|
||||||
q => ram1_do
|
|
||||||
);
|
|
||||||
|
|
||||||
-- 128KB
|
|
||||||
RAM2: entity work.gen_ram
|
|
||||||
generic map (
|
|
||||||
aWidth => 17
|
|
||||||
)
|
|
||||||
port map
|
|
||||||
(
|
|
||||||
clk => CLK,
|
|
||||||
we => ram_we and ram_addr(18) and not ram_addr(17),
|
|
||||||
addr => ram_addr(16 downto 0),
|
|
||||||
d => cpu_do_bus,
|
|
||||||
q => ram2_do
|
|
||||||
);
|
|
||||||
|
|
||||||
process (CLK)
|
|
||||||
begin
|
|
||||||
if rising_edge(CLK) then
|
|
||||||
if CE = '1' then
|
|
||||||
out_a <= ch_a_reg * port_xx06_reg;
|
|
||||||
out_b <= ch_b_reg * port_xx07_reg;
|
|
||||||
out_c <= ch_c_reg * port_xx08_reg;
|
|
||||||
out_d <= ch_d_reg * port_xx09_reg;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
process (CLK)
|
|
||||||
begin
|
|
||||||
if rising_edge(CLK) then
|
|
||||||
if CE = '1' then
|
|
||||||
OUTL <= ('0'&out_a) + ('0'&out_b);
|
|
||||||
OUTR <= ('0'&out_c) + ('0'&out_d);
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
end gs_unit;
|
|
29029
src/sound/gs105a.mif
29029
src/sound/gs105a.mif
File diff suppressed because it is too large
Load Diff
Binary file not shown.
1382
src/sound/gs105b.mif
Normal file
1382
src/sound/gs105b.mif
Normal file
File diff suppressed because it is too large
Load Diff
@ -92,8 +92,16 @@ port
|
|||||||
SD_CLK : out std_logic;
|
SD_CLK : out std_logic;
|
||||||
SD_CS_N : out std_logic;
|
SD_CS_N : out std_logic;
|
||||||
|
|
||||||
-- Audio
|
-- General Sound
|
||||||
GS_ENA : in std_logic;
|
GS_ENA : in std_logic;
|
||||||
|
GS_ADDR : out std_logic_vector(21 downto 0);
|
||||||
|
GS_DI : out std_logic_vector(7 downto 0);
|
||||||
|
GS_DO : in std_logic_vector(7 downto 0);
|
||||||
|
GS_RD : out std_logic;
|
||||||
|
GS_WR : out std_logic;
|
||||||
|
GS_WAIT : in std_logic;
|
||||||
|
|
||||||
|
-- Audio
|
||||||
SOUND_L : out std_logic_vector(15 downto 0);
|
SOUND_L : out std_logic_vector(15 downto 0);
|
||||||
SOUND_R : out std_logic_vector(15 downto 0);
|
SOUND_R : out std_logic_vector(15 downto 0);
|
||||||
|
|
||||||
@ -349,6 +357,9 @@ signal mouse_do : std_logic_vector(7 downto 0);
|
|||||||
signal gs_l : std_logic_vector(14 downto 0);
|
signal gs_l : std_logic_vector(14 downto 0);
|
||||||
signal gs_r : std_logic_vector(14 downto 0);
|
signal gs_r : std_logic_vector(14 downto 0);
|
||||||
signal gs_do_bus : std_logic_vector(7 downto 0);
|
signal gs_do_bus : std_logic_vector(7 downto 0);
|
||||||
|
signal gs_sel : std_logic;
|
||||||
|
signal ce_gs : std_logic;
|
||||||
|
|
||||||
|
|
||||||
-- SAA1099
|
-- SAA1099
|
||||||
signal saa_wr_n : std_logic;
|
signal saa_wr_n : std_logic;
|
||||||
@ -818,6 +829,36 @@ port (
|
|||||||
out_r : out std_logic_vector(7 downto 0));
|
out_r : out std_logic_vector(7 downto 0));
|
||||||
end component;
|
end component;
|
||||||
|
|
||||||
|
component gs
|
||||||
|
generic (
|
||||||
|
PAGES : integer;
|
||||||
|
ROMFILE : string
|
||||||
|
);
|
||||||
|
port
|
||||||
|
(
|
||||||
|
RESET : in std_logic;
|
||||||
|
CLK : in std_logic;
|
||||||
|
CE : in std_logic;
|
||||||
|
|
||||||
|
A : in std_logic;
|
||||||
|
DI : in std_logic_vector(7 downto 0);
|
||||||
|
DO : out std_logic_vector(7 downto 0);
|
||||||
|
CS_n : in std_logic;
|
||||||
|
WR_n : in std_logic;
|
||||||
|
RD_n : in std_logic;
|
||||||
|
|
||||||
|
MEM_ADDR : out std_logic_vector(21 downto 0);
|
||||||
|
MEM_DI : out std_logic_vector(7 downto 0);
|
||||||
|
MEM_DO : in std_logic_vector(7 downto 0);
|
||||||
|
MEM_RD : out std_logic;
|
||||||
|
MEM_WR : out std_logic;
|
||||||
|
MEM_WAIT : in std_logic;
|
||||||
|
|
||||||
|
OUTL : out std_logic_vector(14 downto 0);
|
||||||
|
OUTR : out std_logic_vector(14 downto 0)
|
||||||
|
);
|
||||||
|
end component;
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
begin
|
begin
|
||||||
@ -1382,18 +1423,42 @@ port map (
|
|||||||
CN1_B => ssg_cn1_b,
|
CN1_B => ssg_cn1_b,
|
||||||
CN1_C => ssg_cn1_c);
|
CN1_C => ssg_cn1_c);
|
||||||
|
|
||||||
U15: entity work.gs
|
|
||||||
|
process (clk_84mhz)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk_84mhz) then
|
||||||
|
ce_gs <= clk_28mhz;
|
||||||
|
if ce_gs = '1' then
|
||||||
|
ce_gs <= '0';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
U15: gs
|
||||||
|
generic map
|
||||||
|
(
|
||||||
|
PAGES => 4,
|
||||||
|
ROMFILE => "src/sound/gs105b.mif"
|
||||||
|
)
|
||||||
port map (
|
port map (
|
||||||
RESET => reset or not GS_ENA,
|
RESET => reset,
|
||||||
CLK => clk_28mhz,
|
CLK => clk_84mhz,
|
||||||
CE => '1',
|
CE => ce_gs,
|
||||||
A => cpu_a_bus,
|
|
||||||
|
A => cpu_a_bus(3),
|
||||||
DI => cpu_do_bus,
|
DI => cpu_do_bus,
|
||||||
DO => gs_do_bus,
|
DO => gs_do_bus,
|
||||||
|
CS_n => cpu_iorq_n or not gs_sel,
|
||||||
WR_n => cpu_wr_n,
|
WR_n => cpu_wr_n,
|
||||||
RD_n => cpu_rd_n,
|
RD_n => cpu_rd_n,
|
||||||
IORQ_n => cpu_iorq_n,
|
|
||||||
M1_n => cpu_m1_n,
|
MEM_ADDR => GS_ADDR,
|
||||||
|
MEM_DI => GS_DI,
|
||||||
|
MEM_DO => GS_DO,
|
||||||
|
MEM_RD => GS_RD,
|
||||||
|
MEM_WR => GS_WR,
|
||||||
|
MEM_WAIT => GS_WAIT,
|
||||||
|
|
||||||
OUTL => gs_l,
|
OUTL => gs_l,
|
||||||
OUTR => gs_r);
|
OUTR => gs_r);
|
||||||
|
|
||||||
@ -1431,12 +1496,14 @@ cpu_addr_ext <= "100" when (loader = '1' and (cpu_a_bus(15 downto 14) = "10" or
|
|||||||
|
|
||||||
dram_rdata <= sdr_do_bus_16;
|
dram_rdata <= sdr_do_bus_16;
|
||||||
|
|
||||||
|
gs_sel <= '1' when GS_ENA = '1' and cpu_iorq_n = '0' and cpu_m1_n = '1' and cpu_a_bus(7 downto 4) = "1011" and cpu_a_bus(2 downto 0) = "011" else '0';
|
||||||
|
|
||||||
cpu_di_bus <=
|
cpu_di_bus <=
|
||||||
rom_do_bus when (loader = '1' and cpu_mreq_n = '0' and cpu_rd_n = '0' and cpu_a_bus(15 downto 13) = "000") else -- loader ROM
|
rom_do_bus when (loader = '1' and cpu_mreq_n = '0' and cpu_rd_n = '0' and cpu_a_bus(15 downto 13) = "000") else -- loader ROM
|
||||||
sdr_do_bus when (cpu_mreq_n = '0' and cpu_rd_n = '0') else -- SDRAM
|
sdr_do_bus when (cpu_mreq_n = '0' and cpu_rd_n = '0') else -- SDRAM
|
||||||
im2vect when intack = '1' else
|
im2vect when intack = '1' else
|
||||||
mc146818a_do_bus when (cpu_iorq_n = '0' and cpu_rd_n = '0' and port_bff7 = '1' and port_eff7_reg(7) = '1') else -- MC146818A
|
mc146818a_do_bus when (cpu_iorq_n = '0' and cpu_rd_n = '0' and port_bff7 = '1' and port_eff7_reg(7) = '1') else -- MC146818A
|
||||||
gs_do_bus when (GS_ENA = '1' and cpu_iorq_n = '0' and cpu_rd_n = '0' and cpu_a_bus(7 downto 4) = "1011" and cpu_a_bus(2 downto 0) = "011") else -- General Sound
|
gs_do_bus when gs_sel='1' and cpu_rd_n = '0' else -- General Sound
|
||||||
ssg_cn0_bus when (cpu_iorq_n = '0' and cpu_rd_n = '0' and cpu_a_bus = "1111111111111101" and ssg_sel = '0') else -- TurboSound
|
ssg_cn0_bus when (cpu_iorq_n = '0' and cpu_rd_n = '0' and cpu_a_bus = "1111111111111101" and ssg_sel = '0') else -- TurboSound
|
||||||
ssg_cn1_bus when (cpu_iorq_n = '0' and cpu_rd_n = '0' and cpu_a_bus = "1111111111111101" and ssg_sel = '1') else
|
ssg_cn1_bus when (cpu_iorq_n = '0' and cpu_rd_n = '0' and cpu_a_bus = "1111111111111101" and ssg_sel = '1') else
|
||||||
key_scancode when (cpu_iorq_n = '0' and cpu_rd_n = '0' and cpu_a_bus = X"0001") else
|
key_scancode when (cpu_iorq_n = '0' and cpu_rd_n = '0' and cpu_a_bus = X"0001") else
|
||||||
@ -1480,7 +1547,7 @@ SD_CS_N <= sdcs_n_TS;
|
|||||||
-- SAA1099
|
-- SAA1099
|
||||||
saa_wr_n <= '0' when (cpu_iorq_n = '0' and cpu_wr_n = '0' and cpu_a_bus(7 downto 0) = "11111111" and dos = '0') else '1';
|
saa_wr_n <= '0' when (cpu_iorq_n = '0' and cpu_wr_n = '0' and cpu_a_bus(7 downto 0) = "11111111" and dos = '0') else '1';
|
||||||
|
|
||||||
SOUND_L <= ("000" & port_xxfe_reg(4) & "000000000000") + ("000" & ssg_cn0_a & "00000") + ("0000" & ssg_cn0_b & "0000") + ("000" & ssg_cn1_a & "00000") + ("0000" & ssg_cn1_b & "0000") + ("00" & covox_a & "000000") + ("00" & covox_b & "000000") + ("0" & gs_l) + ("0" & saa_out_l & "0000000");
|
SOUND_L <= ("000" & port_xxfe_reg(4) & "000000000000") + ("000" & ssg_cn0_a & "00000") + ("0000" & ssg_cn0_b & "0000") + ("000" & ssg_cn1_a & "00000") + ("0000" & ssg_cn1_b & "0000") + ("00" & covox_a & "000000") + ("00" & covox_b & "000000") + (gs_l(14) & gs_l) + ("0" & saa_out_l & "0000000");
|
||||||
SOUND_R <= ("000" & port_xxfe_reg(4) & "000000000000") + ("000" & ssg_cn0_c & "00000") + ("0000" & ssg_cn0_b & "0000") + ("000" & ssg_cn1_c & "00000") + ("0000" & ssg_cn1_b & "0000") + ("00" & covox_c & "000000") + ("00" & covox_d & "000000") + ("0" & gs_r) + ("0" & saa_out_r & "0000000");
|
SOUND_R <= ("000" & port_xxfe_reg(4) & "000000000000") + ("000" & ssg_cn0_c & "00000") + ("0000" & ssg_cn0_b & "0000") + ("000" & ssg_cn1_c & "00000") + ("0000" & ssg_cn1_b & "0000") + ("00" & covox_c & "000000") + ("00" & covox_d & "000000") + (gs_r(14) & gs_r) + ("0" & saa_out_r & "0000000");
|
||||||
|
|
||||||
end rtl;
|
end rtl;
|
||||||
|
Reference in New Issue
Block a user