1
0
mirror of https://github.com/Gehstock/Mist_FPGA.git synced 2026-01-18 09:02:08 +00:00

Merge pull request #97 from gyurco/master

Sounds for 280ZZZAP
This commit is contained in:
Marcel 2020-08-23 10:46:51 +02:00 committed by GitHub
commit e49f12efea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 542 additions and 29 deletions

View File

@ -99,7 +99,8 @@ begin
gas_timer <= (others => '0');
else
if vsync_r ='0' and vsync = '1' then
if (gas_timer >= 5 and (gas_minus_r = '1' or gas_plus_r = '1')) then --tune inc/dec rate
if (gas_timer >= 5 and gas_plus_r = '1') or
(gas_timer >= 3 and gas_minus_r = '1') then --tune inc/dec rate
gas_timer <= (others => '0');
else
gas_timer <= gas_timer + 1;

View File

@ -41,7 +41,7 @@
# ========================
set_global_assignment -name ORIGINAL_QUARTUS_VERSION 13.1
set_global_assignment -name PROJECT_CREATION_TIME_DATE "21:27:39 NOVEMBER 20, 2017"
set_global_assignment -name LAST_QUARTUS_VERSION 13.1
set_global_assignment -name LAST_QUARTUS_VERSION "13.1 SP4.26"
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:rtl/build_id.tcl"
@ -155,18 +155,21 @@ set_global_assignment -name EDA_OUTPUT_DATA_FORMAT NONE -section_id eda_simulati
# --------------------------
set_global_assignment -name ENABLE_SIGNALTAP OFF
set_global_assignment -name USE_SIGNALTAP_FILE output_files/stp1.stp
set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS ON
set_global_assignment -name SMART_RECOMPILE ON
set_global_assignment -name SYSTEMVERILOG_FILE rtl/D280ZZZAP_mist.sv
set_global_assignment -name VHDL_FILE rtl/spy_hunter_control.vhd
set_global_assignment -name VHDL_FILE rtl/invaders.vhd
set_global_assignment -name VHDL_FILE rtl/mw8080.vhd
set_global_assignment -name SYSTEMVERILOG_FILE rtl/D280ZZZAP_memory.sv
set_global_assignment -name VHDL_FILE rtl/D280ZZZAP_Overlay.vhd
set_global_assignment -name VHDL_FILE rtl/sound/sprint1_sound.vhd
set_global_assignment -name VHDL_FILE rtl/sound/screech.vhd
set_global_assignment -name VHDL_FILE rtl/sound/EngineSound.vhd
set_global_assignment -name VHDL_FILE rtl/sprom.vhd
set_global_assignment -name VHDL_FILE rtl/spram.vhd
set_global_assignment -name VHDL_FILE rtl/pll.vhd
set_global_assignment -name QIP_FILE ../../../common/CPU/T80/T80.qip
set_global_assignment -name QIP_FILE ../../../common/mist/mist.qip
set_global_assignment -name SIGNALTAP_FILE output_files/stp1.stp
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

View File

@ -84,8 +84,8 @@ set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [ge
#**************************************************************
set_output_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_DO}]
set_output_delay -add_delay -clock_fall -clock [get_clocks {pll|altpll_component|auto_generated|pll1|clk[0]}] 1.000 [get_ports {AUDIO_L}]
set_output_delay -add_delay -clock_fall -clock [get_clocks {pll|altpll_component|auto_generated|pll1|clk[0]}] 1.000 [get_ports {AUDIO_R}]
set_output_delay -add_delay -clock_fall -clock [get_clocks {pll|altpll_component|auto_generated|pll1|clk[2]}] 1.000 [get_ports {AUDIO_L}]
set_output_delay -add_delay -clock_fall -clock [get_clocks {pll|altpll_component|auto_generated|pll1|clk[2]}] 1.000 [get_ports {AUDIO_R}]
set_output_delay -add_delay -clock_fall -clock [get_clocks {pll|altpll_component|auto_generated|pll1|clk[0]}] 1.000 [get_ports {LED}]
set_output_delay -add_delay -clock_fall -clock [get_clocks {pll|altpll_component|auto_generated|pll1|clk[1]}] 1.000 [get_ports {VGA_*}]

View File

@ -32,14 +32,15 @@ wire overlay = status[5];
assign LED = 1;
wire clk_core, clk_vid;
wire clk_core, clk_vid, clk_aud;
wire pll_locked;
pll pll
(
.inclk0(CLOCK_27),
.areset(),
.c0(clk_core),
.c1(clk_vid)
.c1(clk_vid),
.c2(clk_aud)
);
wire reset = status[0] | buttons[1];
@ -219,17 +220,45 @@ mist_video #(.COLOR_DEPTH(1)) mist_video(
.ypbpr(ypbpr),
.no_csync(no_csync)
);
assign AUDIO_L = 0;
assign AUDIO_R = 0;
/*
--* Port 3:
--* bit 0= sound freq
--* bit 1= sound freq
--* bit 2= sound freq
--* bit 3= sound freq
--* bit 4= HI SHIFT MODIFIER
--* bit 5= LO SHIFT MODIFIER
--* bit 6= NC
--* bit 7= NC
--*
--* Port 5:
--* bit 0= BOOM sound
--* bit 1= ENGINE sound
--* bit 2= Screeching Sound
--* bit 3= after car blows up, before it appears again
--* bit 4= NC
--* bit 5= coin counter
--* bit 6= NC
--* bit 7= NC
*/
audio audio_inst (
.Clk_5(clk_aud),
.Motor1_n(SoundCtrl5[1]),
.Skid1(SoundCtrl5[2]),
.Crash_n(~SoundCtrl5[0]),
.NoiseReset_n(1'b1),
.motorspeed(SoundCtrl3[3:0]),
.Audio1(audio)
);
assign AUDIO_R = AUDIO_L;
dac dac (
.clk_i(clk_core),
.clk_i(clk_aud),
.res_n_i(1),
.dac_i(audio),
.dac_o(AUDIO_L)
);
*/
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;

View File

@ -44,7 +44,8 @@ ENTITY pll IS
(
inclk0 : IN STD_LOGIC := '0';
c0 : OUT STD_LOGIC ;
c1 : OUT STD_LOGIC
c1 : OUT STD_LOGIC ;
c2 : OUT STD_LOGIC
);
END pll;
@ -55,9 +56,10 @@ ARCHITECTURE SYN OF pll IS
SIGNAL sub_wire1 : STD_LOGIC ;
SIGNAL sub_wire2 : STD_LOGIC ;
SIGNAL sub_wire3 : STD_LOGIC ;
SIGNAL sub_wire4 : STD_LOGIC_VECTOR (1 DOWNTO 0);
SIGNAL sub_wire5_bv : BIT_VECTOR (0 DOWNTO 0);
SIGNAL sub_wire5 : STD_LOGIC_VECTOR (0 DOWNTO 0);
SIGNAL sub_wire4 : STD_LOGIC ;
SIGNAL sub_wire5 : STD_LOGIC_VECTOR (1 DOWNTO 0);
SIGNAL sub_wire6_bv : BIT_VECTOR (0 DOWNTO 0);
SIGNAL sub_wire6 : STD_LOGIC_VECTOR (0 DOWNTO 0);
@ -72,6 +74,10 @@ ARCHITECTURE SYN OF pll IS
clk1_duty_cycle : NATURAL;
clk1_multiply_by : NATURAL;
clk1_phase_shift : STRING;
clk2_divide_by : NATURAL;
clk2_duty_cycle : NATURAL;
clk2_multiply_by : NATURAL;
clk2_phase_shift : STRING;
compensate_clock : STRING;
inclk0_input_frequency : NATURAL;
intended_device_family : STRING;
@ -129,14 +135,16 @@ ARCHITECTURE SYN OF pll IS
END COMPONENT;
BEGIN
sub_wire5_bv(0 DOWNTO 0) <= "0";
sub_wire5 <= To_stdlogicvector(sub_wire5_bv);
sub_wire2 <= sub_wire0(1);
sub_wire1 <= sub_wire0(0);
c0 <= sub_wire1;
c1 <= sub_wire2;
sub_wire3 <= inclk0;
sub_wire4 <= sub_wire5(0 DOWNTO 0) & sub_wire3;
sub_wire6_bv(0 DOWNTO 0) <= "0";
sub_wire6 <= To_stdlogicvector(sub_wire6_bv);
sub_wire3 <= sub_wire0(2);
sub_wire2 <= sub_wire0(0);
sub_wire1 <= sub_wire0(1);
c1 <= sub_wire1;
c0 <= sub_wire2;
c2 <= sub_wire3;
sub_wire4 <= inclk0;
sub_wire5 <= sub_wire6(0 DOWNTO 0) & sub_wire4;
altpll_component : altpll
GENERIC MAP (
@ -149,6 +157,10 @@ BEGIN
clk1_duty_cycle => 50,
clk1_multiply_by => 832,
clk1_phase_shift => "0",
clk2_divide_by => 1125,
clk2_duty_cycle => 50,
clk2_multiply_by => 208,
clk2_phase_shift => "0",
compensate_clock => "CLK0",
inclk0_input_frequency => 37037,
intended_device_family => "Cyclone III",
@ -183,7 +195,7 @@ BEGIN
port_scanwrite => "PORT_UNUSED",
port_clk0 => "PORT_USED",
port_clk1 => "PORT_USED",
port_clk2 => "PORT_UNUSED",
port_clk2 => "PORT_USED",
port_clk3 => "PORT_UNUSED",
port_clk4 => "PORT_UNUSED",
port_clk5 => "PORT_UNUSED",
@ -200,7 +212,7 @@ BEGIN
width_clock => 5
)
PORT MAP (
inclk => sub_wire4,
inclk => sub_wire5,
clk => sub_wire0
);
@ -229,10 +241,13 @@ END SYN;
-- Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "8"
-- Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "27"
-- Retrieval info: PRIVATE: DIV_FACTOR1 NUMERIC "27"
-- Retrieval info: PRIVATE: DIV_FACTOR2 NUMERIC "1"
-- Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"
-- Retrieval info: PRIVATE: DUTY_CYCLE1 STRING "50.00000000"
-- Retrieval info: PRIVATE: DUTY_CYCLE2 STRING "50.00000000"
-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "9.984000"
-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "19.968000"
-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE2 STRING "4.992000"
-- Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0"
-- Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0"
-- Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1"
@ -254,25 +269,33 @@ END SYN;
-- Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0"
-- Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg"
-- Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT1 STRING "ps"
-- Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT2 STRING "ps"
-- Retrieval info: PRIVATE: MIG_DEVICE_SPEED_GRADE STRING "Any"
-- Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0"
-- Retrieval info: PRIVATE: MIRROR_CLK1 STRING "0"
-- Retrieval info: PRIVATE: MIRROR_CLK2 STRING "0"
-- Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "10"
-- Retrieval info: PRIVATE: MULT_FACTOR1 NUMERIC "20"
-- Retrieval info: PRIVATE: MULT_FACTOR2 NUMERIC "1"
-- Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1"
-- Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "9.98400000"
-- Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "19.96800000"
-- Retrieval info: PRIVATE: OUTPUT_FREQ2 STRING "4.99200000"
-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "1"
-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE1 STRING "1"
-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE2 STRING "1"
-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz"
-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT1 STRING "MHz"
-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT2 STRING "MHz"
-- Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "1"
-- Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0"
-- Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000"
-- Retrieval info: PRIVATE: PHASE_SHIFT1 STRING "0.00000000"
-- Retrieval info: PRIVATE: PHASE_SHIFT2 STRING "0.00000000"
-- Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0"
-- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg"
-- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT1 STRING "deg"
-- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT2 STRING "ps"
-- Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0"
-- Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "0"
-- Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1"
@ -296,13 +319,16 @@ END SYN;
-- Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "0"
-- Retrieval info: PRIVATE: STICKY_CLK0 STRING "1"
-- Retrieval info: PRIVATE: STICKY_CLK1 STRING "1"
-- Retrieval info: PRIVATE: STICKY_CLK2 STRING "1"
-- Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1"
-- Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "1"
-- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
-- Retrieval info: PRIVATE: USE_CLK0 STRING "1"
-- Retrieval info: PRIVATE: USE_CLK1 STRING "1"
-- Retrieval info: PRIVATE: USE_CLK2 STRING "1"
-- Retrieval info: PRIVATE: USE_CLKENA0 STRING "0"
-- Retrieval info: PRIVATE: USE_CLKENA1 STRING "0"
-- Retrieval info: PRIVATE: USE_CLKENA2 STRING "0"
-- Retrieval info: PRIVATE: USE_MIL_SPEED_GRADE NUMERIC "0"
-- Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0"
-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
@ -315,6 +341,10 @@ END SYN;
-- Retrieval info: CONSTANT: CLK1_DUTY_CYCLE NUMERIC "50"
-- Retrieval info: CONSTANT: CLK1_MULTIPLY_BY NUMERIC "832"
-- Retrieval info: CONSTANT: CLK1_PHASE_SHIFT STRING "0"
-- Retrieval info: CONSTANT: CLK2_DIVIDE_BY NUMERIC "1125"
-- Retrieval info: CONSTANT: CLK2_DUTY_CYCLE NUMERIC "50"
-- Retrieval info: CONSTANT: CLK2_MULTIPLY_BY NUMERIC "208"
-- Retrieval info: CONSTANT: CLK2_PHASE_SHIFT STRING "0"
-- Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0"
-- Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "37037"
-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III"
@ -348,7 +378,7 @@ END SYN;
-- Retrieval info: CONSTANT: PORT_SCANWRITE STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_clk0 STRING "PORT_USED"
-- Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_USED"
-- Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_USED"
-- Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_clk5 STRING "PORT_UNUSED"
@ -367,11 +397,13 @@ END SYN;
-- Retrieval info: USED_PORT: @inclk 0 0 2 0 INPUT_CLK_EXT VCC "@inclk[1..0]"
-- Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT_CLK_EXT VCC "c0"
-- Retrieval info: USED_PORT: c1 0 0 0 0 OUTPUT_CLK_EXT VCC "c1"
-- Retrieval info: USED_PORT: c2 0 0 0 0 OUTPUT_CLK_EXT VCC "c2"
-- Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0"
-- Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0
-- Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0
-- Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0
-- Retrieval info: CONNECT: c1 0 0 0 0 @clk 0 0 1 1
-- Retrieval info: CONNECT: c2 0 0 0 0 @clk 0 0 1 2
-- Retrieval info: GEN_FILE: TYPE_NORMAL pll.vhd TRUE
-- Retrieval info: GEN_FILE: TYPE_NORMAL pll.ppf TRUE
-- Retrieval info: GEN_FILE: TYPE_NORMAL pll.inc FALSE

View File

@ -0,0 +1,159 @@
-- Motor sound generator for Kee Games Sprint 1
-- Identical circuits are used in a number of other related games
-- (c) 2017 James Sweet
--
-- Original circuit used a 555 configured as an astable oscillator with the frequency controlled by
-- a four bit binary value. The output of this oscillator drives a counter configured to produce an
-- irregular thumping simulating the sound of an engine.
--
-- This 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 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.
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
entity EngineSound is
generic(
constant Freq_tune : integer := 50 -- Value from 0-100 used to tune the overall engine sound frequency
);
port(
Clk_5 : in std_logic;
Ena_3k : in std_logic;
EngineData : in std_logic_vector(3 downto 0);
Motor : out std_logic_vector(5 downto 0)
);
end EngineSound;
architecture rtl of EngineSound is
signal RPM_val : integer range 1 to 350;
signal Ramp_term_unfilt : integer range 1 to 80000;
signal Ramp_Count : integer range 0 to 80000;
signal Ramp_term : integer range 1 to 80000;
signal Freq_mod : integer range 0 to 400;
signal Motor_Clk : std_logic;
signal Counter_A : std_logic;
signal Counter_B : unsigned(2 downto 0);
signal Counter_A_clk : std_logic;
signal Motor_prefilter : unsigned(1 downto 0);
signal Motor_filter_t1 : unsigned(3 downto 0);
signal Motor_filter_t2 : unsigned(3 downto 0);
signal Motor_filter_t3 : unsigned(3 downto 0);
signal Motor_filtered : unsigned(5 downto 0);
begin
-- The frequency of the oscillator is set by a 4 bit binary value controlled by the game CPU
-- in the real hardware this is a 555 coupled to a 4 bit resistor DAC used to pull the frequency.
-- The output of this DAC has a capacitor to smooth out the frequency variation.
-- The constants assigned to RPM_val can be tweaked to adjust the frequency curve
Speed_select: process(Clk_5)
begin
if rising_edge(Clk_5) then
case EngineData is
when "0000" => RPM_val <= 280;
when "0001" => RPM_val <= 245;
when "0010" => RPM_val <= 230;
when "0011" => RPM_val <= 205;
when "0100" => RPM_val <= 190;
when "0101" => RPM_val <= 175;
when "0110" => RPM_val <= 160;
when "0111" => RPM_val <= 145;
when "1000" => RPM_val <= 130;
when "1001" => RPM_val <= 115;
when "1010" => RPM_val <= 100;
when "1011" => RPM_val <= 85;
when "1100" => RPM_val <= 70;
when "1101" => RPM_val <= 55;
when "1110" => RPM_val <= 40;
when "1111" => RPM_val <= 25;
end case;
end if;
end process;
-- There is a RC filter between the frequency control DAC and the 555 to smooth out the transitions between the
-- 16 possible states. We can simulate a reasonable approximation of that behavior using a linear slope which is
-- not truly accurate but should be close enough.
RC_filt: process(Clk_5, ena_3k, ramp_term_unfilt)
begin
if rising_edge(Clk_5) then
if ena_3k = '1' then
if ramp_term_unfilt > ramp_term then
ramp_term <= ramp_term + 5;
elsif ramp_term_unfilt = ramp_term then
ramp_term <= ramp_term;
else
ramp_term <= ramp_term - 3;
end if;
end if;
end if;
end process;
-- Ramp_term terminates the ramp count, the higher this value, the longer the ramp will count up and the lower
-- the frequency. RPM_val is multiplied by a constant which can be adjusted by changing the value of freq_tune
-- to simulate the function of the frequency adjustment pot in the original hardware.
ramp_term_unfilt <= ((200 - freq_tune) * RPM_val);
-- Variable frequency oscillator roughly approximating the function of a 555 astable oscillator
Ramp_osc: process(Clk_5)
begin
if rising_edge(Clk_5) then
motor_clk <= '1';
ramp_count <= ramp_count + 1;
if ramp_count > ramp_term then
ramp_count <= 0;
motor_clk <= '0';
end if;
end if;
end process;
-- 7492 counter with XOR on two of the outputs creates lumpy engine sound from smooth pulse train
-- 7492 has two sections, one div-by-2 and one div-by-6.
Engine_counter: process(motor_clk, Counter_A_clk, Counter_B)
begin
if rising_edge(motor_clk) then
Counter_B <= Counter_B + '1';
end if;
Counter_A_clk <= Counter_B(0) xor Counter_B(2);
if rising_edge(counter_A_clk) then
Counter_A <= (not Counter_A);
end if;
end process;
motor_prefilter <= ('0' & Counter_B(2)) + ('0' & Counter_B(1)) + ('0' & Counter_A);
-- Very simple low pass filter, borrowed from MikeJ's Asteroids code
Engine_filter: process(Clk_5)
begin
if rising_edge(Clk_5) then
if (ena_3k = '1') then
motor_filter_t1 <= ("00" & motor_prefilter) + ("00" & motor_prefilter);
motor_filter_t2 <= motor_filter_t1;
motor_filter_t3 <= motor_filter_t2;
end if;
motor_filtered <= ("00" & motor_filter_t1) +
('0' & motor_filter_t2 & '0') +
("00" & motor_filter_t3);
end if;
end process;
motor <= std_logic_vector(motor_filtered);
end rtl;

View File

@ -0,0 +1,73 @@
-- Tire screech sound generator for Kee Games Sprint 1
-- Identical circuit is used in a number of related Kee/Atari games
-- (c) 2017 James Sweet
--
-- Original circuit used a 7414 Schmitt trigger oscillator operating at approximately
-- 1.2kHz producing a sawtooth with the frequency modulated slightly by the pseudo-random
-- noise generator. This is an extension of work initially done in Verilog by Jonas Elofsson.
--
-- This 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 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.
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
entity tire_screech is
generic(
constant Inc1 : integer := 24; -- These constants can be adjusted to tune the frequency and modulation
constant Inc2 : integer := 34;
constant Dec1 : integer := 23;
constant Dec2 : integer := 12
);
port(
Clk : in std_logic; -- 750kHz from the horizontal line counter chain works well here
Noise : in std_logic; -- Output from LFSR pseudo-random noise generator
Screech_out : out std_logic -- Screech output - single bit
);
end tire_screech;
architecture rtl of tire_screech is
signal Screech_count : integer range 1000 to 11000;
signal Screech_state : std_logic;
begin
Screech: process(Clk, Screech_state)
begin
if rising_edge(Clk) then
if screech_state = '1' then -- screech_state is 1, counter is rising
if noise = '1' then -- Noise signal from LFSR, when high increases the slope of the rising ramp
screech_count <= screech_count + inc2;
else -- When Noise is low, decreas the slope of the ramp
screech_count <= screech_count + inc1;
end if;
if screech_count > 10000 then -- Reverse the ramp direction when boundary value of 10,000 is reached
screech_state <= '0';
end if;
elsif screech_state = '0' then -- screech_state is now low, decrement the counter (ramp down)
if noise = '1' then
screech_count <= screech_count - dec2; -- Slope is influenced by the Noise signal
else
screech_count <= screech_count - dec1;
end if;
if screech_count < 1000 then -- Reverse the ramp direction again when the lower boundary of 1,000 is crossed
screech_state <= '1';
end if;
end if;
end if;
screech_out <= screech_state;
end process;
end rtl;

View File

@ -0,0 +1,215 @@
-- Audio for Sprint 1
-- modified for 280zzap
-- First attempt at modeling the analog sound circuits used in Sprint 1, may be room for improvement as
-- I do not have a real board to compare.
-- (c) 2017 James Sweet
--
-- This 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 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.
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
entity audio is
port(
Clk_5 : in std_logic;
Motor1_n : in std_logic;
Skid1 : in std_logic;
Crash_n : in std_logic;
NoiseReset_n : in std_logic;
motorspeed : in std_logic_vector(3 downto 0);
Audio1 : out std_logic_vector(7 downto 0)
);
end audio;
architecture rtl of audio is
signal H4 : std_logic;
signal V2 : std_logic;
signal Noise : std_logic;
signal Noise_Shift : std_logic_vector(15 downto 0);
signal Shift_in : std_logic;
signal Screech_count : integer range 1000 to 11000;
signal Screech_state : std_logic;
signal Screech_snd1 : std_logic;
signal Screech1 : std_logic_vector(3 downto 0);
signal Crash : std_logic_vector(3 downto 0);
signal Bang : std_logic_vector(3 downto 0);
signal Mtr1_Freq : std_logic_vector(3 downto 0);
signal Motor1_speed : std_logic_vector(3 downto 0);
signal Motor1_snd_o : std_logic_vector(5 downto 0);
signal Motor1_snd : std_logic_vector(5 downto 0);
signal P1_audio : std_logic_vector(6 downto 0);
signal ena_count : std_logic_vector(11 downto 0);
signal ena_3k : std_logic;
signal bang_prefilter : std_logic_vector(3 downto 0);
signal bang_filter_t1 : std_logic_vector(3 downto 0);
signal bang_filter_t2 : std_logic_vector(3 downto 0);
signal bang_filter_t3 : std_logic_vector(3 downto 0);
signal bang_filtered : std_logic_vector(5 downto 0);
signal h_counter : std_logic_vector(9 downto 0) := (others => '0');
signal HCount : std_logic_vector(8 downto 0);
begin
hcount <= h_counter(9 downto 1);
H_count: process(Clk_5)
begin
if rising_edge(Clk_5) then
if h_counter = "1111111111" then
h_counter <= "0100000000";
else
h_counter <= h_counter + 1;
end if;
end if;
end process;
-- HCount
-- (0) 1H 3 MHz
-- (1) 2H 1.5MHz
-- (2) 4H 750 kHz
-- (3) 8H 375 kHz
-- (4) 16H 187 kHz
-- (5) 32H 93 kHz
-- (6) 64H 46 kHz
-- (7) 128H 23 kHz
-- (8) 256H 12 kHz
-- HCount
-- (0) 1H 2.5 MHz
-- (1) 2H 1.25MHz
-- (2) 4H 625 kHz
-- (3) 8H 312 kHz
-- (4) 16H 156 kHz
-- (5) 32H 78 kHz
-- (6) 64H 39 kHz
-- (7) 128H 19 kHz
-- (8) 256H 9 kHz
--H4 <= HCount(2);
--V2 <= HCount(3); -- not correct
H4 <= HCount(2); -- 750kHz??
V2 <= HCount(5); -- not correct
-- Generate the 3kHz clock enable used by the filter
Enable: process(Clk_5)
begin
if rising_edge(Clk_5) then
ena_count <= ena_count + "1";
ena_3k <= '0';
--if (ena_count(11 downto 0) = "000000000000") then
if (ena_count(11 downto 0) = "110101010101") then
ena_3k <= '1';
ena_count<="000000000000";
end if;
end if;
end process;
-- LFSR that generates pseudo-random noise
Noise_gen: process(NoiseReset_n, V2)
begin
if (noisereset_n = '0') then
noise_shift <= (others => '0');
noise <= '0';
elsif rising_edge(V2) then
shift_in <= not(noise_shift(6) xor noise_shift(8));
noise_shift <= shift_in & noise_shift(15 downto 1);
noise <= noise_shift(0);
end if;
end process;
-- Tire screech sound
Screech_gen1: entity work.tire_screech
generic map( -- These values can be tweaked to tune the screech sound
Inc1 => 24, -- Ramp increase rate when noise = 0
Inc2 => 33, -- Ramp increase rate when noise = 1
Dec1 => 29, -- Ramp decrease rate when noise = 0
Dec2 => 16 -- Ramp decrease rate when noise = 1
)
port map(
Clk => H4,
Noise => noise,
Screech_out => screech_snd1
);
-- Convert screech from 1 bit to 4 bits wide and enable via skid1 signal
Screech_ctrl: process(screech_snd1, Skid1)
begin
if (Skid1 and screech_snd1) = '1' then
screech1 <= "1111";
else
screech1 <= "0000";
end if;
end process;
--Crash_sound: process(crash_n, motorspeed, noise)
--begin
-- if crash_n = '0' then
-- crash <= not motorspeed(3 downto 0);
-- end if;
-- if noise = '1' then
-- bang_prefilter <= crash;
-- else
-- bang_prefilter <= "0000";
-- end if;
--end process;
---- Very simple low pass filter, borrowed from MikeJ's Asteroids code
Crash_filter: process(Clk_5)
begin
if rising_edge(Clk_5) then
if (ena_3k = '1') then
bang_filter_t1 <= bang_prefilter;
bang_filter_t2 <= bang_filter_t1;
bang_filter_t3 <= bang_filter_t2;
end if;
bang_filtered <= ("00" & bang_filter_t1) +
('0' & bang_filter_t2 & '0') +
("00" & bang_filter_t3);
end if;
end process;
Motor1: entity work.EngineSound
generic map(
Freq_tune => 40 -- Tuning pot for engine sound frequency
)
port map(
Clk_5 => clk_5,
Ena_3k => ena_3k,
EngineData => motorspeed,
Motor => Motor1_Snd_o
);
Motor1_Snd <= Motor1_Snd_o when Motor1_n = '0' else (others => '0');
-- Audio mixer, also mutes sound in attract mode
--Audio1 <= '0' & ('0' & motor1_snd) + ('0' & screech1 & '0') + ('0' & bang_filtered);
--Audio1 <= '0' & ('0' & motor1_snd) + ("00" & screech1) ;
Audio1 <= ('0' & motor1_snd & '0') + ('0' & screech1 & '0');
end rtl;

View File

@ -99,7 +99,8 @@ begin
gas_timer <= (others => '0');
else
if vsync_r ='0' and vsync = '1' then
if (gas_timer >= 5 and (gas_minus_r = '1' or gas_plus_r = '1')) then --tune inc/dec rate
if (gas_timer >= 5 and gas_plus_r = '1') or
(gas_timer >= 3 and gas_minus_r = '1') then --tune inc/dec rate
gas_timer <= (others => '0');
else
gas_timer <= gas_timer + 1;