1
0
mirror of https://github.com/Gehstock/Mist_FPGA.git synced 2026-02-05 07:44:46 +00:00

Vectrex Update

This commit is contained in:
Gehstock
2018-04-30 15:19:00 +02:00
parent e05de5842e
commit 966f2c5e32
16 changed files with 4815 additions and 732 deletions

4
.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
Robotron - Z1013_MiST/Z1013_Mist.pti_db_list.ddb
Robotron - Z1013_MiST/Z1013_Mist.tis_db_list.ddb
Sharp - MZ-80K_MiST/mz80k.qws

Binary file not shown.

View File

@@ -5,10 +5,20 @@ Max 16kb Roms supported
Controls:
Movement: Joystick, Keyboard(Arrow Keys)
Buttons: 1-2 on Joystick Fire Buttons
1-4 on Keyboard 1-4
Buttons: 1-4 on Joystick Fire Buttons
(Player 1) 1-4 on Keyboard 1-4 and WASD
(Player 2) NUM, /, *, - on Numpad and Arrow Keys
ToDo: Reset (hold Button longer for a Correct Reset)
ToDo: Fix Reset( hangs sometimes)

View File

@@ -1,574 +0,0 @@
-- changes for seperate audio outputs and enable now enables cpu access as well
--
-- A simulation model of YM2149 (AY-3-8910 with bells on)
-- Copyright (c) MikeJ - Jan 2005
--
-- All rights reserved
--
-- Redistribution and use in source and synthezised forms, with or without
-- modification, are permitted provided that the following conditions are met:
--
-- Redistributions of source code must retain the above copyright notice,
-- this list of conditions and the following disclaimer.
--
-- Redistributions in synthesized form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in the
-- documentation and/or other materials provided with the distribution.
--
-- Neither the name of the author nor the names of other contributors may
-- be used to endorse or promote products derived from this software without
-- specific prior written permission.
--
-- THIS CODE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-- POSSIBILITY OF SUCH DAMAGE.
--
-- You are responsible for any legal issues arising from your use of this code.
--
-- The latest version of this file can be found at: www.fpgaarcade.com
--
-- Email support@fpgaarcade.com
--
-- Revision list
--
-- version 001 initial release
--
-- Clues from MAME sound driver and Kazuhiro TSUJIKAWA
--
-- These are the measured outputs from a real chip for a single Isolated channel into a 1K load (V)
-- vol 15 .. 0
-- 3.27 2.995 2.741 2.588 2.452 2.372 2.301 2.258 2.220 2.198 2.178 2.166 2.155 2.148 2.141 2.132
-- As the envelope volume is 5 bit, I have fitted a curve to the not quite log shape in order
-- to produced all the required values.
-- (The first part of the curve is a bit steeper and the last bit is more linear than expected)
--
-- NOTE, this component uses LINEAR mixing of the three analogue channels, and is only
-- accurate for designs where the outputs are buffered and not simply wired together.
-- The ouput level is more complex in that case and requires a larger table.
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity YM2149 is
port (
-- data bus
I_DA : in std_logic_vector(7 downto 0);
O_DA : out std_logic_vector(7 downto 0);
O_DA_OE_L : out std_logic;
-- control
I_A9_L : in std_logic;
I_A8 : in std_logic;
I_BDIR : in std_logic;
I_BC2 : in std_logic;
I_BC1 : in std_logic;
I_SEL_L : in std_logic;
O_AUDIO : out std_logic_vector(7 downto 0);
O_CHAN : out std_logic_vector(1 downto 0);
-- port a
I_IOA : in std_logic_vector(7 downto 0);
O_IOA : out std_logic_vector(7 downto 0);
O_IOA_OE_L : out std_logic;
-- port b
I_IOB : in std_logic_vector(7 downto 0);
O_IOB : out std_logic_vector(7 downto 0);
O_IOB_OE_L : out std_logic;
ENA : in std_logic; -- clock enable for higher speed operation
RESET_L : in std_logic;
CLK : in std_logic -- note 6 Mhz
);
end;
architecture RTL of YM2149 is
type array_16x8 is array (0 to 15) of std_logic_vector( 7 downto 0);
type array_3x12 is array (1 to 3) of std_logic_vector(11 downto 0);
signal cnt_div : std_logic_vector(3 downto 0) := (others => '0');
signal cnt_div_t1 : std_logic_vector(3 downto 0);
signal noise_div : std_logic := '0';
signal ena_div : std_logic;
signal ena_div_noise : std_logic;
signal poly17 : std_logic_vector(16 downto 0) := (others => '0');
-- registers
signal addr : std_logic_vector(7 downto 0);
signal busctrl_addr : std_logic;
signal busctrl_we : std_logic;
signal busctrl_re : std_logic;
signal reg : array_16x8;
signal env_reset : std_logic;
signal ioa_inreg : std_logic_vector(7 downto 0);
signal iob_inreg : std_logic_vector(7 downto 0);
signal noise_gen_cnt : std_logic_vector(4 downto 0);
signal noise_gen_op : std_logic;
signal tone_gen_cnt : array_3x12 := (others => (others => '0'));
signal tone_gen_op : std_logic_vector(3 downto 1) := "000";
signal env_gen_cnt : std_logic_vector(15 downto 0);
signal env_ena : std_logic;
signal env_hold : std_logic;
signal env_inc : std_logic;
signal env_vol : std_logic_vector(4 downto 0);
signal tone_ena_l : std_logic;
signal tone_src : std_logic;
signal noise_ena_l : std_logic;
signal chan_vol : std_logic_vector(4 downto 0);
signal dac_amp : std_logic_vector(7 downto 0);
begin
-- cpu i/f
p_busdecode : process(I_BDIR, I_BC2, I_BC1, addr, I_A9_L, I_A8)
variable cs : std_logic;
variable sel : std_logic_vector(2 downto 0);
begin
-- BDIR BC2 BC1 MODE
-- 0 0 0 inactive
-- 0 0 1 address
-- 0 1 0 inactive
-- 0 1 1 read
-- 1 0 0 address
-- 1 0 1 inactive
-- 1 1 0 write
-- 1 1 1 read
busctrl_addr <= '0';
busctrl_we <= '0';
busctrl_re <= '0';
cs := '0';
if (I_A9_L = '0') and (I_A8 = '1') and (addr(7 downto 4) = "0000") then
cs := '1';
end if;
sel := (I_BDIR & I_BC2 & I_BC1);
case sel is
when "000" => null;
when "001" => busctrl_addr <= '1';
when "010" => null;
when "011" => busctrl_re <= cs;
when "100" => busctrl_addr <= '1';
when "101" => null;
when "110" => busctrl_we <= cs;
when "111" => busctrl_addr <= '1';
when others => null;
end case;
end process;
p_oe : process(busctrl_re)
begin
-- if we are emulating a real chip, maybe clock this to fake up the tristate typ delay of 100ns
O_DA_OE_L <= not (busctrl_re);
end process;
--
-- CLOCKED
--
p_waddr : process(RESET_L, CLK)
begin
-- looks like registers are latches in real chip, but the address is caught at the end of the address state.
if (RESET_L = '0') then
addr <= (others => '0');
elsif rising_edge(CLK) then
if (ENA = '1') then
if (busctrl_addr = '1') then
addr <= I_DA;
end if;
end if;
end if;
end process;
p_wdata : process(RESET_L, CLK)
begin
if (RESET_L = '0') then
reg <= (others => (others => '0'));
env_reset <= '1';
elsif rising_edge(CLK) then
if (ENA = '1') then
env_reset <= '0';
if (busctrl_we = '1') then
case addr(3 downto 0) is
when x"0" => reg(0) <= I_DA;
when x"1" => reg(1) <= I_DA;
when x"2" => reg(2) <= I_DA;
when x"3" => reg(3) <= I_DA;
when x"4" => reg(4) <= I_DA;
when x"5" => reg(5) <= I_DA;
when x"6" => reg(6) <= I_DA;
when x"7" => reg(7) <= I_DA;
when x"8" => reg(8) <= I_DA;
when x"9" => reg(9) <= I_DA;
when x"A" => reg(10) <= I_DA;
when x"B" => reg(11) <= I_DA;
when x"C" => reg(12) <= I_DA;
when x"D" => reg(13) <= I_DA; env_reset <= '1';
when x"E" => reg(14) <= I_DA;
when x"F" => reg(15) <= I_DA;
when others => null;
end case;
end if;
end if;
end if;
end process;
p_rdata : process(busctrl_re, addr, reg, ioa_inreg, iob_inreg)
begin
O_DA <= (others => '0'); -- 'X'
if (busctrl_re = '1') then -- not necessary, but useful for putting 'X's in the simulator
case addr(3 downto 0) is
when x"0" => O_DA <= reg(0) ;
when x"1" => O_DA <= "0000" & reg(1)(3 downto 0) ;
when x"2" => O_DA <= reg(2) ;
when x"3" => O_DA <= "0000" & reg(3)(3 downto 0) ;
when x"4" => O_DA <= reg(4) ;
when x"5" => O_DA <= "0000" & reg(5)(3 downto 0) ;
when x"6" => O_DA <= "000" & reg(6)(4 downto 0) ;
when x"7" => O_DA <= reg(7) ;
when x"8" => O_DA <= "000" & reg(8)(4 downto 0) ;
when x"9" => O_DA <= "000" & reg(9)(4 downto 0) ;
when x"A" => O_DA <= "000" & reg(10)(4 downto 0) ;
when x"B" => O_DA <= reg(11);
when x"C" => O_DA <= reg(12);
when x"D" => O_DA <= "0000" & reg(13)(3 downto 0);
when x"E" => if (reg(7)(6) = '0') then -- input
O_DA <= ioa_inreg;
else
O_DA <= reg(14); -- read output reg
end if;
when x"F" => if (Reg(7)(7) = '0') then
O_DA <= iob_inreg;
else
O_DA <= reg(15);
end if;
when others => null;
end case;
end if;
end process;
--
p_divider : process
begin
wait until rising_edge(CLK);
-- / 8 when SEL is high and /16 when SEL is low
if (ENA = '1') then
ena_div <= '0';
ena_div_noise <= '0';
if (cnt_div = "0000") then
cnt_div <= (not I_SEL_L) & "111";
ena_div <= '1';
noise_div <= not noise_div;
if (noise_div = '1') then
ena_div_noise <= '1';
end if;
else
cnt_div <= cnt_div - "1";
end if;
end if;
end process;
p_noise_gen : process
variable noise_gen_comp : std_logic_vector(4 downto 0);
variable poly17_zero : std_logic;
begin
wait until rising_edge(CLK);
if (reg(6)(4 downto 0) = "00000") then
noise_gen_comp := "00000";
else
noise_gen_comp := (reg(6)(4 downto 0) - "1");
end if;
poly17_zero := '0';
if (poly17 = "00000000000000000") then poly17_zero := '1'; end if;
if (ENA = '1') then
if (ena_div_noise = '1') then -- divider ena
if (noise_gen_cnt >= noise_gen_comp) then
noise_gen_cnt <= "00000";
poly17 <= (poly17(0) xor poly17(2) xor poly17_zero) & poly17(16 downto 1);
else
noise_gen_cnt <= (noise_gen_cnt + "1");
end if;
end if;
end if;
end process;
noise_gen_op <= poly17(0);
p_tone_gens : process
variable tone_gen_freq : array_3x12;
variable tone_gen_comp : array_3x12;
begin
wait until rising_edge(CLK);
-- looks like real chips count up - we need to get the Exact behaviour ..
tone_gen_freq(1) := reg(1)(3 downto 0) & reg(0);
tone_gen_freq(2) := reg(3)(3 downto 0) & reg(2);
tone_gen_freq(3) := reg(5)(3 downto 0) & reg(4);
-- period 0 = period 1
for i in 1 to 3 loop
if (tone_gen_freq(i) = x"000") then
tone_gen_comp(i) := x"000";
else
tone_gen_comp(i) := (tone_gen_freq(i) - "1");
end if;
end loop;
if (ENA = '1') then
for i in 1 to 3 loop
if (ena_div = '1') then -- divider ena
if (tone_gen_cnt(i) >= tone_gen_comp(i)) then
tone_gen_cnt(i) <= x"000";
tone_gen_op(i) <= not tone_gen_op(i);
else
tone_gen_cnt(i) <= (tone_gen_cnt(i) + "1");
end if;
end if;
end loop;
end if;
end process;
p_envelope_freq : process
variable env_gen_freq : std_logic_vector(15 downto 0);
variable env_gen_comp : std_logic_vector(15 downto 0);
begin
wait until rising_edge(CLK);
env_gen_freq := reg(12) & reg(11);
-- envelope freqs 1 and 0 are the same.
if (env_gen_freq = x"0000") then
env_gen_comp := x"0000";
else
env_gen_comp := (env_gen_freq - "1");
end if;
if (ENA = '1') then
env_ena <= '0';
if (ena_div = '1') then -- divider ena
if (env_gen_cnt >= env_gen_comp) then
env_gen_cnt <= x"0000";
env_ena <= '1';
else
env_gen_cnt <= (env_gen_cnt + "1");
end if;
end if;
end if;
end process;
p_envelope_shape : process(env_reset, reg, CLK)
variable is_bot : boolean;
variable is_bot_p1 : boolean;
variable is_top_m1 : boolean;
variable is_top : boolean;
begin
-- envelope shapes
-- C AtAlH
-- 0 0 x x \___
--
-- 0 1 x x /___
--
-- 1 0 0 0 \\\\
--
-- 1 0 0 1 \___
--
-- 1 0 1 0 \/\/
-- ___
-- 1 0 1 1 \
--
-- 1 1 0 0 ////
-- ___
-- 1 1 0 1 /
--
-- 1 1 1 0 /\/\
--
-- 1 1 1 1 /___
if (env_reset = '1') then
-- load initial state
if (reg(13)(2) = '0') then -- attack
env_vol <= "11111";
env_inc <= '0'; -- -1
else
env_vol <= "00000";
env_inc <= '1'; -- +1
end if;
env_hold <= '0';
elsif rising_edge(CLK) then
is_bot := (env_vol = "00000");
is_bot_p1 := (env_vol = "00001");
is_top_m1 := (env_vol = "11110");
is_top := (env_vol = "11111");
if (ENA = '1') then
if (env_ena = '1') then
if (env_hold = '0') then
if (env_inc = '1') then
env_vol <= (env_vol + "00001");
else
env_vol <= (env_vol + "11111");
end if;
end if;
-- envelope shape control.
if (reg(13)(3) = '0') then
if (env_inc = '0') then -- down
if is_bot_p1 then env_hold <= '1'; end if;
else
if is_top then env_hold <= '1'; end if;
end if;
else
if (reg(13)(0) = '1') then -- hold = 1
if (env_inc = '0') then -- down
if (reg(13)(1) = '1') then -- alt
if is_bot then env_hold <= '1'; end if;
else
if is_bot_p1 then env_hold <= '1'; end if;
end if;
else
if (reg(13)(1) = '1') then -- alt
if is_top then env_hold <= '1'; end if;
else
if is_top_m1 then env_hold <= '1'; end if;
end if;
end if;
elsif (reg(13)(1) = '1') then -- alternate
if (env_inc = '0') then -- down
if is_bot_p1 then env_hold <= '1'; end if;
if is_bot then env_hold <= '0'; env_inc <= '1'; end if;
else
if is_top_m1 then env_hold <= '1'; end if;
if is_top then env_hold <= '0'; env_inc <= '0'; end if;
end if;
end if;
end if;
end if;
end if;
end if;
end process;
p_chan_mixer : process(cnt_div, reg, tone_gen_op)
begin
tone_ena_l <= '1'; tone_src <= '1';
noise_ena_l <= '1'; chan_vol <= "00000";
case cnt_div(1 downto 0) is
when "00" =>
tone_ena_l <= reg(7)(0); tone_src <= tone_gen_op(1); chan_vol <= reg(8)(4 downto 0);
noise_ena_l <= reg(7)(3);
when "01" =>
tone_ena_l <= reg(7)(1); tone_src <= tone_gen_op(2); chan_vol <= reg(9)(4 downto 0);
noise_ena_l <= reg(7)(4);
when "10" =>
tone_ena_l <= reg(7)(2); tone_src <= tone_gen_op(3); chan_vol <= reg(10)(4 downto 0);
noise_ena_l <= reg(7)(5);
when "11" => null; -- tone gen outputs become valid on this clock
when others => null;
end case;
end process;
p_op_mixer : process
variable chan_mixed : std_logic;
variable chan_amp : std_logic_vector(4 downto 0);
begin
wait until rising_edge(CLK);
if (ENA = '1') then
chan_mixed := (tone_ena_l or tone_src) and (noise_ena_l or noise_gen_op);
chan_amp := (others => '0');
if (chan_mixed = '1') then
if (chan_vol(4) = '0') then
if (chan_vol(3 downto 0) = "0000") then -- nothing is easy ! make sure quiet is quiet
chan_amp := "00000";
else
chan_amp := chan_vol(3 downto 0) & '1'; -- make sure level 31 (env) = level 15 (tone)
end if;
else
chan_amp := env_vol(4 downto 0);
end if;
end if;
dac_amp <= x"00";
case chan_amp is
when "11111" => dac_amp <= x"FF";
when "11110" => dac_amp <= x"D9";
when "11101" => dac_amp <= x"BA";
when "11100" => dac_amp <= x"9F";
when "11011" => dac_amp <= x"88";
when "11010" => dac_amp <= x"74";
when "11001" => dac_amp <= x"63";
when "11000" => dac_amp <= x"54";
when "10111" => dac_amp <= x"48";
when "10110" => dac_amp <= x"3D";
when "10101" => dac_amp <= x"34";
when "10100" => dac_amp <= x"2C";
when "10011" => dac_amp <= x"25";
when "10010" => dac_amp <= x"1F";
when "10001" => dac_amp <= x"1A";
when "10000" => dac_amp <= x"16";
when "01111" => dac_amp <= x"13";
when "01110" => dac_amp <= x"10";
when "01101" => dac_amp <= x"0D";
when "01100" => dac_amp <= x"0B";
when "01011" => dac_amp <= x"09";
when "01010" => dac_amp <= x"08";
when "01001" => dac_amp <= x"07";
when "01000" => dac_amp <= x"06";
when "00111" => dac_amp <= x"05";
when "00110" => dac_amp <= x"04";
when "00101" => dac_amp <= x"03";
when "00100" => dac_amp <= x"03";
when "00011" => dac_amp <= x"02";
when "00010" => dac_amp <= x"02";
when "00001" => dac_amp <= x"01";
when "00000" => dac_amp <= x"00";
when others => null;
end case;
cnt_div_t1 <= cnt_div;
end if;
end process;
p_audio_output : process(RESET_L, CLK)
begin
if (RESET_L = '0') then
O_AUDIO <= (others => '0');
O_CHAN <= (others => '0');
elsif rising_edge(CLK) then
if (ENA = '1') then
O_AUDIO <= dac_amp(7 downto 0);
O_CHAN <= cnt_div_t1(1 downto 0);
end if;
end if;
end process;
p_io_ports : process(reg)
begin
O_IOA <= reg(14);
O_IOA_OE_L <= not reg(7)(6);
O_IOB <= reg(15);
O_IOB_OE_L <= not reg(7)(7);
end process;
p_io_ports_inreg : process
begin
wait until rising_edge(CLK);
if (ENA = '1') then -- resync
ioa_inreg <= I_IOA;
iob_inreg <= I_IOB;
end if;
end process;
end architecture RTL;

View File

@@ -1,2 +1,2 @@
`define BUILD_DATE "180402"
`define BUILD_TIME "195354"
`define BUILD_DATE "180429"
`define BUILD_TIME "150128"

View File

@@ -263,6 +263,7 @@ use ieee.std_logic_unsigned.all;
entity cpu09 is
port (
clk : in std_logic; -- E clock input (falling edge)
ce : in std_logic;
rst : in std_logic; -- reset input (active high)
vma : out std_logic; -- valid memory address (active high)
lic_out : out std_logic; -- last instruction cycle (active high)
@@ -277,8 +278,7 @@ entity cpu09 is
irq : in std_logic; -- interrupt request input (active high)
firq : in std_logic; -- fast interrupt request input (active high)
nmi : in std_logic; -- non maskable interrupt request input (active high)
halt : in std_logic; -- halt input (active high) grants DMA
hold_in : in std_logic -- hold input (active high) extend bus cycle
halt : in std_logic -- halt input (active high) grants DMA
);
end cpu09;
@@ -498,7 +498,7 @@ begin
wait_cycles: process(clk)
begin
if clk'event and clk = '0' then
if ce = '1' then
if lic = '1' then
case op_code is
when X"A6" => hold <= '1'; cnt_cycles <= X"1"; -- additional cycles for vectrex tuning
@@ -516,11 +516,11 @@ begin
if hold = '1' then
if cnt_cycles = X"1" then
hold <= '0';
hold <= '0';
end if;
cnt_cycles <= cnt_cycles - '1';
end if;
end if;
end if;
end process;
@@ -534,6 +534,7 @@ end process;
state_stack_proc: process( clk, st_ctrl, return_state )
begin
if clk'event and clk = '0' then
if ce = '1' then
if hold = '0' then
case st_ctrl is
when reset_st =>
@@ -544,6 +545,7 @@ begin
null;
end case;
end if;
end if;
end if;
end process;
@@ -556,6 +558,7 @@ end process;
int_vec_proc: process( clk, iv_ctrl )
begin
if clk'event and clk = '0' then
if ce = '1' then
if hold = '0' then
case iv_ctrl is
when reset_iv =>
@@ -576,6 +579,7 @@ begin
null;
end case;
end if; -- hold
end if;
end if; -- clk
end process;
@@ -589,6 +593,7 @@ end process;
pc_reg: process( clk )
begin
if clk'event and clk = '0' then
if ce = '1' then
if hold = '0' then
case pc_ctrl is
when reset_pc =>
@@ -605,6 +610,7 @@ begin
null;
end case;
end if;
end if;
end if;
end process;
@@ -619,6 +625,7 @@ ea_reg: process( clk )
begin
if clk'event and clk = '0' then
if ce = '1' then
if hold= '0' then
case ea_ctrl is
when reset_ea =>
@@ -635,6 +642,7 @@ begin
null;
end case;
end if;
end if;
end if;
end process;
@@ -647,6 +655,7 @@ end process;
acca_reg : process( clk )
begin
if clk'event and clk = '0' then
if ce = '1' then
if hold = '0' then
case acca_ctrl is
when reset_acca =>
@@ -661,6 +670,7 @@ begin
null;
end case;
end if;
end if;
end if;
end process;
@@ -673,6 +683,7 @@ end process;
accb_reg : process( clk )
begin
if clk'event and clk = '0' then
if ce = '1' then
if hold = '0' then
case accb_ctrl is
when reset_accb =>
@@ -685,6 +696,7 @@ begin
null;
end case;
end if;
end if;
end if;
end process;
@@ -697,6 +709,7 @@ end process;
ix_reg : process( clk )
begin
if clk'event and clk = '0' then
if ce = '1' then
if hold = '0' then
case ix_ctrl is
when reset_ix =>
@@ -711,6 +724,7 @@ begin
null;
end case;
end if;
end if;
end if;
end process;
@@ -723,6 +737,7 @@ end process;
iy_reg : process( clk )
begin
if clk'event and clk = '0' then
if ce = '1' then
if hold = '0' then
case iy_ctrl is
when reset_iy =>
@@ -737,6 +752,7 @@ begin
null;
end case;
end if;
end if;
end if;
end process;
@@ -749,6 +765,7 @@ end process;
sp_reg : process( clk )
begin
if clk'event and clk = '0' then
if ce = '1' then
if hold = '0' then
case sp_ctrl is
when reset_sp =>
@@ -766,6 +783,7 @@ begin
null;
end case;
end if;
end if;
end if;
end process;
@@ -778,6 +796,7 @@ end process;
up_reg : process( clk )
begin
if clk'event and clk = '0' then
if ce = '1' then
if hold = '0' then
case up_ctrl is
when reset_up =>
@@ -792,6 +811,7 @@ begin
null;
end case;
end if;
end if;
end if;
end process;
@@ -804,6 +824,7 @@ end process;
md_reg : process( clk )
begin
if clk'event and clk = '0' then
if ce = '1' then
if hold = '0' then
case md_ctrl is
when reset_md =>
@@ -824,6 +845,7 @@ begin
null;
end case;
end if;
end if;
end if;
end process;
@@ -838,6 +860,7 @@ end process;
cc_reg: process( clk )
begin
if clk'event and clk = '0' then
if ce = '1' then
if hold = '0' then
case cc_ctrl is
when reset_cc =>
@@ -850,6 +873,7 @@ begin
null;
end case;
end if;
end if;
end if;
end process;
@@ -863,6 +887,7 @@ end process;
dp_reg: process( clk )
begin
if clk'event and clk = '0' then
if ce = '1' then
if hold = '0' then
case dp_ctrl is
when reset_dp =>
@@ -875,6 +900,7 @@ begin
null;
end case;
end if;
end if;
end if;
end process;
@@ -889,6 +915,7 @@ end process;
op_reg: process( clk )
begin
if clk'event and clk = '0' then
if ce = '1' then
if hold = '0' then
case op_ctrl is
when reset_op =>
@@ -899,6 +926,7 @@ begin
null;
end case;
end if;
end if;
end if;
end process;
@@ -913,6 +941,7 @@ end process;
pre_reg: process( clk )
begin
if clk'event and clk = '0' then
if ce = '1' then
if hold = '0' then
case pre_ctrl is
when reset_pre =>
@@ -923,6 +952,7 @@ begin
null;
end case;
end if;
end if;
end if;
end process;
@@ -941,7 +971,7 @@ begin
fic <= '0';
nmi_ack <= '0';
state <= reset_state;
elsif hold = '0' then
elsif ce = '1' and hold = '0' then
fic <= lic;
--
@@ -1003,6 +1033,7 @@ begin
if rst='1' then
nmi_req <= '0';
elsif clk'event and clk='0' then
if ce = '1' then
if (nmi='1') and (nmi_ack='0') and (nmi_enable='1') then
nmi_req <= '1';
else
@@ -1010,6 +1041,7 @@ begin
nmi_req <= '0';
end if;
end if;
end if;
end if;
end process;

View File

@@ -7,7 +7,7 @@ module keyboard
input ps2_kbd_clk,
input ps2_kbd_data,
output reg[7:0] joystick
output reg[15:0] joystick
);
reg [11:0] shift_reg = 12'hFFF;
@@ -33,11 +33,24 @@ always @(negedge clk) begin
'h1E: joystick[5] <= ~release_btn; // 2
'h26: joystick[6] <= ~release_btn; // 3
'h25: joystick[7] <= ~release_btn; // 4
'h1D: joystick[11] <= ~release_btn; // W
'h1B: joystick[10] <= ~release_btn; // S
'h1C: joystick[9] <= ~release_btn; // A
'h23: joystick[8] <= ~release_btn; // D
'h77: joystick[12] <= ~release_btn; // NUM
'h4A: joystick[13] <= ~release_btn; // /
'h7C: joystick[14] <= ~release_btn; // *
'h7B: joystick[15] <= ~release_btn; // -
'h75: joystick[3] <= ~release_btn; // arrow up
'h72: joystick[2] <= ~release_btn; // arrow down
'h6B: joystick[1] <= ~release_btn; // arrow left
'h74: joystick[0] <= ~release_btn; // arrow right
endcase
end
end

View File

@@ -0,0 +1,89 @@
`timescale 1ns / 1ps
module mc6809
(
input CLK,
input CLKEN,
input nRESET,
input CPU,
output reg E,
output reg riseE,
output reg fallE, // everything except interrupts/dma registered/latched here
output reg Q,
output reg riseQ,
output reg fallQ, // NMI,IRQ,FIRQ,DMA,HALT registered here
input [7:0] Din,
output [7:0] Dout,
output [15:0] ADDR,
output RnW,
input nIRQ,
input nFIRQ,
input nNMI,
input nHALT
);
cpu09 cpu1
(
.clk(CLK),
.ce(fallE),
.rst(~nRESET | CPU),
.addr(ADDR1),
.rw(RnW1),
.data_out(Dout1),
.data_in(Din),
.irq(~nIRQ),
.firq(~nFIRQ),
.nmi(~nNMI),
.halt(~nHALT)
);
mc6809is cpu2
(
.CLK(CLK),
.D(Din),
.DOut(Dout2),
.ADDR(ADDR2),
.RnW(RnW2),
.fallE_en(fallE),
.fallQ_en(fallQ),
.nIRQ(nIRQ),
.nFIRQ(nFIRQ),
.nNMI(nNMI),
.nHALT(nHALT),
.nRESET(nRESET & CPU),
.nDMABREQ(1)
);
wire [7:0] Dout1,Dout2;
wire [15:0] ADDR1,ADDR2;
wire RnW1,RnW2;
assign Dout = CPU ? Dout2 : Dout1;
assign ADDR = CPU ? ADDR2 : ADDR1;
assign RnW = CPU ? RnW2 : RnW1;
always @(posedge CLK)
begin
reg [1:0] clk_phase =0;
fallE <= 0;
fallQ <= 0;
riseE <= 0;
riseQ <= 0;
if (CLKEN) begin
clk_phase <= clk_phase + 1'd1;
case (clk_phase)
2'b00: begin E <= 0; fallE <= 1; end
2'b01: begin Q <= 1; riseQ <= 1; end
2'b10: begin E <= 1; riseE <= 1; end
2'b11: begin Q <= 0; fallQ <= 1; end
endcase
end
end
endmodule

File diff suppressed because it is too large Load Diff

View File

@@ -111,17 +111,17 @@ module pll (
.vcounderrange ());
defparam
altpll_component.bandwidth_type = "AUTO",
altpll_component.clk0_divide_by = 44,
altpll_component.clk0_divide_by = 9,
altpll_component.clk0_duty_cycle = 50,
altpll_component.clk0_multiply_by = 41,
altpll_component.clk0_multiply_by = 8,
altpll_component.clk0_phase_shift = "0",
altpll_component.clk1_divide_by = 88,
altpll_component.clk1_divide_by = 9,
altpll_component.clk1_duty_cycle = 50,
altpll_component.clk1_multiply_by = 41,
altpll_component.clk1_multiply_by = 4,
altpll_component.clk1_phase_shift = "0",
altpll_component.clk2_divide_by = 176,
altpll_component.clk2_divide_by = 9,
altpll_component.clk2_duty_cycle = 50,
altpll_component.clk2_multiply_by = 41,
altpll_component.clk2_multiply_by = 2,
altpll_component.clk2_phase_shift = "0",
altpll_component.compensate_clock = "CLK0",
altpll_component.inclk0_input_frequency = 37037,
@@ -196,15 +196,15 @@ endmodule
// Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0"
// Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "c0"
// Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "8"
// Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "44"
// Retrieval info: PRIVATE: DIV_FACTOR1 NUMERIC "88"
// Retrieval info: PRIVATE: DIV_FACTOR2 NUMERIC "176"
// Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "9"
// Retrieval info: PRIVATE: DIV_FACTOR1 NUMERIC "9"
// Retrieval info: PRIVATE: DIV_FACTOR2 NUMERIC "9"
// 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 "25.159090"
// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "12.579545"
// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE2 STRING "6.289773"
// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "24.000000"
// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "12.000000"
// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE2 STRING "6.000000"
// 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"
@@ -231,13 +231,13 @@ endmodule
// 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 "41"
// Retrieval info: PRIVATE: MULT_FACTOR1 NUMERIC "41"
// Retrieval info: PRIVATE: MULT_FACTOR2 NUMERIC "41"
// Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "8"
// Retrieval info: PRIVATE: MULT_FACTOR1 NUMERIC "4"
// Retrieval info: PRIVATE: MULT_FACTOR2 NUMERIC "2"
// Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1"
// Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "25.17500000"
// Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "12.58750000"
// Retrieval info: PRIVATE: OUTPUT_FREQ2 STRING "6.29375000"
// Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "24.00000000"
// Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "12.00000000"
// Retrieval info: PRIVATE: OUTPUT_FREQ2 STRING "6.00000000"
// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "0"
// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE1 STRING "0"
// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE2 STRING "0"
@@ -290,17 +290,17 @@ endmodule
// Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0"
// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
// Retrieval info: CONSTANT: BANDWIDTH_TYPE STRING "AUTO"
// Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "44"
// Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "9"
// Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50"
// Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "41"
// Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "8"
// Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0"
// Retrieval info: CONSTANT: CLK1_DIVIDE_BY NUMERIC "88"
// Retrieval info: CONSTANT: CLK1_DIVIDE_BY NUMERIC "9"
// Retrieval info: CONSTANT: CLK1_DUTY_CYCLE NUMERIC "50"
// Retrieval info: CONSTANT: CLK1_MULTIPLY_BY NUMERIC "41"
// Retrieval info: CONSTANT: CLK1_MULTIPLY_BY NUMERIC "4"
// Retrieval info: CONSTANT: CLK1_PHASE_SHIFT STRING "0"
// Retrieval info: CONSTANT: CLK2_DIVIDE_BY NUMERIC "176"
// Retrieval info: CONSTANT: CLK2_DIVIDE_BY NUMERIC "9"
// Retrieval info: CONSTANT: CLK2_DUTY_CYCLE NUMERIC "50"
// Retrieval info: CONSTANT: CLK2_MULTIPLY_BY NUMERIC "41"
// Retrieval info: CONSTANT: CLK2_MULTIPLY_BY NUMERIC "2"
// Retrieval info: CONSTANT: CLK2_PHASE_SHIFT STRING "0"
// Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0"
// Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "37037"

View File

@@ -124,7 +124,7 @@ port
video_vs : out std_logic;
video_blankn : out std_logic;
video_csync : out std_logic;
frame : out std_logic;
audio_out : out std_logic_vector(9 downto 0);
cart_addr : out std_logic_vector(13 downto 0);
cart_do : in std_logic_vector( 7 downto 0);
@@ -301,6 +301,27 @@ architecture syn of vectrex is
signal compare : std_logic;
signal players_switches : std_logic_vector(7 downto 0);
component ym2149 is port
(
CLK : in std_logic;
CE : in std_logic;
RESET : in std_logic;
BDIR : in std_logic;
BC : in std_logic;
DI : in std_logic_vector(7 downto 0);
DO : out std_logic_vector(7 downto 0);
CHANNEL_A : out std_logic_vector(7 downto 0);
CHANNEL_B : out std_logic_vector(7 downto 0);
CHANNEL_C : out std_logic_vector(7 downto 0);
SEL : in std_logic;
MODE : in std_logic;
IOA_in : in std_logic_vector(7 downto 0);
IOA_out : out std_logic_vector(7 downto 0);
IOB_in : in std_logic_vector(7 downto 0);
IOB_out : out std_logic_vector(7 downto 0)
);
end component ym2149;
begin
-- debug
@@ -636,22 +657,8 @@ end process;
video_blankn <= not (hblank or vblank);
scan_video_addr <= vcnt_video * std_logic_vector(to_unsigned(max_h,10)) + hcnt_video;
-- sound
process (cpu_clock)
begin
if rising_edge(cpu_clock) then
if ay_audio_chan = "00" then ay_chan_a <= ay_audio_muxed; end if;
if ay_audio_chan = "01" then ay_chan_b <= ay_audio_muxed; end if;
if ay_audio_chan = "10" then ay_chan_c <= ay_audio_muxed; end if;
end if;
end process;
audio_out <= ("00"&ay_chan_a) +
("00"&ay_chan_b) +
("00"&ay_chan_c) +
("00"&dac_sound);
frame <= frame_line;
---------------------------
-- components
---------------------------
@@ -660,6 +667,7 @@ audio_out <= ("00"&ay_chan_a) +
main_cpu : entity work.cpu09
port map(
clk => cpu_clock,-- E clock input (falling edge)
ce => '1',
rst => reset, -- reset input (active high)
vma => open, -- valid memory address (active high)
lic_out => open, -- last instruction cycle (active high)
@@ -674,8 +682,8 @@ port map(
irq => cpu_irq, -- interrupt request input (active high)
firq => cpu_firq, -- fast interrupt request input (active high)
nmi => '0', -- non maskable interrupt request input (active high)
halt => '0', -- halt input (active high) grants DMA
hold_in => '0' -- hold input (active high) extend bus cycle
halt => '0'--, -- halt input (active high) grants DMA
-- hold_in => '0' -- hold input (active high) extend bus cycle
);
@@ -768,36 +776,31 @@ port map(
ENA_4 => via_en_4 -- 4x system clock (4HZ) _-_-_-_-_-
);
-- AY-3-8910
ay_3_8910_2 : entity work.YM2149
port map(
-- data bus
I_DA => via_pa_o, -- in std_logic_vector(7 downto 0);
O_DA => ay_do, -- out std_logic_vector(7 downto 0);
O_DA_OE_L => open, -- out std_logic;
-- control
I_A9_L => '0', -- in std_logic;
I_A8 => '1', -- in std_logic;
I_BDIR => via_pb_o(4), -- in std_logic;
I_BC2 => '1', -- in std_logic;
I_BC1 => via_pb_o(3), -- in std_logic;
I_SEL_L => '0', -- in std_logic;
O_AUDIO => ay_audio_muxed, -- out std_logic_vector(7 downto 0);
O_CHAN => ay_audio_chan, -- out std_logic_vector(1 downto 0);
-- port a
I_IOA => players_switches, -- in std_logic_vector(7 downto 0);
O_IOA => open, -- out std_logic_vector(7 downto 0);
O_IOA_OE_L => open, -- out std_logic;
-- port b
I_IOB => (others => '0'), -- in std_logic_vector(7 downto 0);
O_IOB => open, -- out std_logic_vector(7 downto 0);
O_IOB_OE_L => open, -- out std_logic;
ENA => '1', --cpu_ena, -- in std_logic; -- clock enable for higher speed operation
RESET_L => reset_n, -- in std_logic;
CLK => cpu_clock -- in std_logic -- note 6 Mhz
ym2149_inst : ym2149
port map
(
CLK => cpu_clock,
CE => '1',
RESET => reset,
BDIR => via_pb_o(4),
BC => via_pb_o(3),
DI => via_pa_o,
DO => ay_do,
CHANNEL_A => ay_chan_a,
CHANNEL_B => ay_chan_b,
CHANNEL_C => ay_chan_c,
SEL => '0',
MODE => '0',
IOA_in => players_switches,
IOB_in => (others => '0')
);
audio_out <= ("00"&ay_chan_a) +
("00"&ay_chan_b) +
("00"&ay_chan_c) +
("00"&dac_sound);
end SYN;

View File

@@ -13,24 +13,24 @@ architecture prom of vectrex_exec_prom is
type rom is array(0 to 8191) of std_logic_vector(7 downto 0);
signal rom_data: rom := (
X"ED",X"77",X"F8",X"50",X"30",X"E8",X"4D",X"49",X"4E",X"45",X"80",X"F8",X"50",X"00",X"DE",X"53",
X"54",X"4F",X"52",X"4D",X"80",X"00",X"8E",X"C8",X"83",X"6F",X"80",X"8C",X"CB",X"C5",X"26",X"F9",
X"54",X"4F",X"52",X"4D",X"80",X"00",X"8E",X"C8",X"83",X"6F",X"80",X"8C",X"CB",X"BB",X"26",X"F9",
X"BD",X"E8",X"E3",X"7C",X"C8",X"24",X"86",X"BB",X"B7",X"C8",X"80",X"8E",X"01",X"01",X"BF",X"C8",
X"81",X"8E",X"C8",X"83",X"6F",X"80",X"8C",X"CB",X"70",X"26",X"F9",X"20",X"00",X"BD",X"F1",X"AF",
X"CC",X"02",X"00",X"BD",X"F7",X"A9",X"0A",X"79",X"0F",X"56",X"0F",X"9B",X"8E",X"C8",X"A8",X"BD",
X"F8",X"4F",X"8E",X"C8",X"AF",X"BD",X"F8",X"4F",X"8E",X"C8",X"F9",X"BD",X"F8",X"4F",X"CC",X"00",
X"01",X"BD",X"F8",X"7C",X"8E",X"C9",X"00",X"BD",X"F8",X"4F",X"CC",X"00",X"01",X"BD",X"F8",X"7C",
X"8E",X"ED",X"AB",X"9F",X"C4",X"9F",X"C6",X"86",X"05",X"97",X"D9",X"97",X"DA",X"97",X"DB",X"20",
X"24",X"BD",X"E8",X"66",X"10",X"8E",X"C8",X"C4",X"96",X"9B",X"AE",X"A6",X"30",X"04",X"AF",X"A6",
X"8E",X"ED",X"A7",X"96",X"9B",X"AE",X"86",X"A6",X"05",X"84",X"03",X"26",X"02",X"0C",X"D9",X"CC",
X"00",X"01",X"BD",X"F8",X"7C",X"BD",X"E7",X"E4",X"8E",X"C8",X"C4",X"96",X"9B",X"AE",X"86",X"A6",
X"84",X"2B",X"05",X"BD",X"E1",X"29",X"20",X"41",X"DC",X"F0",X"83",X"00",X"01",X"DD",X"F0",X"27",
X"14",X"34",X"08",X"BD",X"F1",X"AA",X"BD",X"EA",X"CF",X"CE",X"EE",X"2F",X"BD",X"EA",X"9D",X"35",
X"08",X"96",X"0F",X"27",X"24",X"8E",X"C8",X"A8",X"CE",X"CB",X"EB",X"BD",X"F8",X"D8",X"8E",X"C8",
X"AF",X"CE",X"CB",X"EB",X"BD",X"F8",X"D8",X"DC",X"F0",X"10",X"26",X"FF",X"44",X"BD",X"F1",X"8B",
X"0F",X"3B",X"10",X"CE",X"CB",X"EA",X"7E",X"F0",X"1C",X"34",X"08",X"BD",X"EA",X"F0",X"BD",X"E5",
X"8E",X"CB",X"B3",X"9F",X"C4",X"8E",X"CB",X"B7",X"9F",X"C6",X"C6",X"08",X"8E",X"CB",X"B3",X"BD",
X"F5",X"3F",X"86",X"05",X"97",X"D9",X"97",X"DA",X"97",X"DB",X"20",X"23",X"BD",X"E8",X"66",X"10",
X"8E",X"C8",X"C4",X"96",X"9B",X"AE",X"A6",X"BD",X"ED",X"AB",X"8E",X"ED",X"A7",X"96",X"9B",X"AE",
X"86",X"A6",X"05",X"84",X"03",X"26",X"02",X"0C",X"D9",X"CC",X"00",X"01",X"BD",X"F8",X"7C",X"BD",
X"E7",X"E4",X"8E",X"C8",X"C4",X"96",X"9B",X"AE",X"86",X"BD",X"E1",X"29",X"20",X"3B",X"DC",X"F0",
X"83",X"00",X"01",X"DD",X"F0",X"27",X"26",X"34",X"08",X"BD",X"F1",X"AA",X"BD",X"EA",X"CF",X"CE",
X"EE",X"2F",X"BD",X"EA",X"9D",X"35",X"08",X"8E",X"C8",X"A8",X"CE",X"CB",X"EB",X"BD",X"F8",X"D8",
X"8E",X"C8",X"AF",X"CE",X"CB",X"EB",X"BD",X"F8",X"D8",X"96",X"0F",X"27",X"0C",X"DC",X"F0",X"10",
X"26",X"FF",X"3E",X"7E",X"EF",X"CC",X"12",X"12",X"12",X"34",X"08",X"BD",X"EA",X"F0",X"BD",X"E5",
X"1E",X"BD",X"E2",X"62",X"BD",X"E4",X"B8",X"BD",X"E3",X"53",X"35",X"08",X"BD",X"EB",X"43",X"BD",
X"EC",X"46",X"BD",X"EC",X"95",X"BD",X"E6",X"47",X"25",X"DF",X"96",X"BD",X"10",X"27",X"FF",X"61",
X"96",X"BE",X"10",X"26",X"FF",X"92",X"7E",X"E0",X"A5",X"9F",X"C2",X"CC",X"7F",X"00",X"DD",X"DC",
X"EC",X"46",X"BD",X"EC",X"95",X"BD",X"E6",X"47",X"25",X"DF",X"96",X"BD",X"10",X"27",X"FF",X"6C",
X"96",X"BE",X"10",X"26",X"FF",X"98",X"7E",X"E0",X"AF",X"9F",X"C2",X"CC",X"7F",X"00",X"DD",X"DC",
X"97",X"B7",X"86",X"20",X"97",X"9C",X"8E",X"E1",X"E7",X"9F",X"9D",X"8E",X"C9",X"33",X"9F",X"B9",
X"86",X"1D",X"97",X"B8",X"0F",X"56",X"CE",X"ED",X"77",X"BD",X"F6",X"8D",X"34",X"08",X"BD",X"E7",
X"11",X"BD",X"F6",X"87",X"96",X"26",X"85",X"01",X"26",X"02",X"0A",X"B7",X"BD",X"EA",X"F0",X"BD",
@@ -40,7 +40,7 @@ architecture prom of vectrex_exec_prom is
X"86",X"04",X"97",X"B7",X"86",X"7F",X"97",X"B8",X"96",X"B7",X"27",X"4A",X"D6",X"B8",X"27",X"04",
X"0A",X"B8",X"20",X"12",X"D6",X"26",X"C4",X"1F",X"26",X"0C",X"4A",X"97",X"B7",X"9E",X"C2",X"A6",
X"86",X"C6",X"03",X"BD",X"E9",X"A1",X"34",X"08",X"BD",X"EA",X"F0",X"BD",X"F2",X"A9",X"CE",X"EE",
X"20",X"BD",X"EA",X"9D",X"10",X"8E",X"E0",X"F8",X"CE",X"ED",X"A7",X"B6",X"C8",X"9B",X"EE",X"C6",
X"20",X"BD",X"EA",X"9D",X"10",X"8E",X"E0",X"00",X"CE",X"ED",X"A7",X"B6",X"C8",X"9B",X"EE",X"C6",
X"BD",X"EA",X"A8",X"BD",X"E5",X"1E",X"BD",X"E2",X"62",X"BD",X"E4",X"B8",X"35",X"08",X"BD",X"EB",
X"43",X"BD",X"E6",X"47",X"20",X"B2",X"39",X"0A",X"B8",X"27",X"4E",X"0C",X"ED",X"BD",X"F5",X"17",
X"84",X"07",X"8B",X"04",X"97",X"9C",X"DE",X"B9",X"86",X"80",X"A7",X"C4",X"DC",X"DC",X"8B",X"08",
@@ -65,8 +65,8 @@ architecture prom of vectrex_exec_prom is
X"EF",X"27",X"0D",X"BD",X"E9",X"8A",X"97",X"C8",X"0F",X"C9",X"D7",X"CA",X"0F",X"CB",X"35",X"88",
X"04",X"EE",X"86",X"1F",X"97",X"EF",X"35",X"88",X"D6",X"EF",X"C1",X"E0",X"2F",X"0C",X"96",X"EF",
X"80",X"04",X"97",X"EF",X"4F",X"BD",X"E9",X"4A",X"35",X"88",X"0F",X"EF",X"0F",X"EE",X"BD",X"E8",
X"37",X"35",X"88",X"B6",X"C8",X"E7",X"27",X"2B",X"34",X"08",X"86",X"C8",X"1F",X"8B",X"96",X"E7",
X"27",X"21",X"DC",X"DE",X"D3",X"E2",X"DD",X"DE",X"97",X"DC",X"DC",X"E0",X"D3",X"E4",X"DD",X"E0",
X"37",X"35",X"88",X"B6",X"C8",X"E7",X"27",X"2B",X"34",X"08",X"86",X"C8",X"1F",X"8B",X"12",X"12",
X"12",X"12",X"DC",X"DE",X"D3",X"E2",X"DD",X"DE",X"97",X"DC",X"DC",X"E0",X"D3",X"E4",X"DD",X"E0",
X"97",X"DD",X"35",X"08",X"BD",X"F2",X"A5",X"C6",X"08",X"10",X"BE",X"C8",X"DC",X"8E",X"EF",X"B3",
X"BD",X"EA",X"7F",X"39",X"8E",X"E3",X"A1",X"9F",X"A3",X"BD",X"F5",X"17",X"8E",X"E4",X"48",X"84",
X"06",X"AE",X"86",X"EC",X"81",X"DD",X"DC",X"97",X"DE",X"0F",X"DF",X"D7",X"E0",X"0F",X"E1",X"20",
@@ -104,7 +104,7 @@ architecture prom of vectrex_exec_prom is
X"EC",X"46",X"E3",X"4A",X"ED",X"46",X"BD",X"F2",X"A5",X"8E",X"E2",X"5A",X"A6",X"41",X"48",X"AE",
X"86",X"31",X"44",X"E6",X"42",X"BD",X"EA",X"8D",X"7E",X"E5",X"2A",X"EC",X"44",X"E3",X"48",X"29",
X"1A",X"ED",X"44",X"EC",X"46",X"E3",X"4A",X"29",X"12",X"ED",X"46",X"BD",X"F2",X"A9",X"31",X"44",
X"8E",X"CB",X"A7",X"C6",X"04",X"BD",X"EA",X"8D",X"7E",X"E5",X"2A",X"6F",X"C4",X"7A",X"C8",X"EB",
X"8E",X"CB",X"A4",X"C6",X"04",X"BD",X"EA",X"8D",X"7E",X"E5",X"2A",X"6F",X"C4",X"7A",X"C8",X"EB",
X"7E",X"E5",X"2A",X"A6",X"46",X"AB",X"C8",X"10",X"A7",X"46",X"A1",X"C8",X"11",X"26",X"02",X"64",
X"C4",X"BD",X"F2",X"A5",X"31",X"44",X"BD",X"EA",X"6D",X"7E",X"E5",X"2A",X"A6",X"43",X"81",X"03",
X"26",X"0D",X"A6",X"42",X"A1",X"C8",X"10",X"2C",X"06",X"8B",X"08",X"A7",X"42",X"20",X"1B",X"64",
@@ -125,12 +125,12 @@ architecture prom of vectrex_exec_prom is
X"9B",X"44",X"8E",X"C8",X"DA",X"E6",X"86",X"F7",X"C8",X"D9",X"27",X"EB",X"B6",X"C8",X"D9",X"26",
X"0D",X"86",X"01",X"B7",X"C8",X"BE",X"20",X"06",X"E6",X"44",X"E1",X"41",X"25",X"05",X"6F",X"C4",
X"7A",X"C8",X"EC",X"33",X"45",X"7A",X"C8",X"8F",X"10",X"26",X"FF",X"4B",X"BD",X"EC",X"C9",X"20",
X"05",X"34",X"08",X"BD",X"F1",X"AA",X"BD",X"F2",X"A5",X"8E",X"80",X"38",X"BF",X"C8",X"90",X"B6",
X"C8",X"D9",X"27",X"1E",X"B7",X"C8",X"8F",X"7A",X"C8",X"8F",X"27",X"16",X"B6",X"C8",X"91",X"8B",
X"05",X"34",X"08",X"BD",X"F1",X"AA",X"BD",X"F2",X"A5",X"8E",X"80",X"38",X"BF",X"C8",X"90",X"BD",
X"EF",X"D8",X"27",X"1E",X"12",X"12",X"12",X"7A",X"C8",X"8F",X"27",X"16",X"B6",X"C8",X"91",X"8B",
X"06",X"B7",X"C8",X"91",X"C6",X"04",X"10",X"BE",X"C8",X"90",X"8E",X"EE",X"EB",X"BD",X"EA",X"7F",
X"20",X"E5",X"35",X"08",X"96",X"26",X"84",X"01",X"48",X"48",X"48",X"8E",X"EE",X"AD",X"CE",X"CB",
X"A7",X"BD",X"F6",X"1F",X"D6",X"EC",X"26",X"0F",X"96",X"BD",X"26",X"08",X"D6",X"EB",X"26",X"07",
X"D6",X"ED",X"26",X"03",X"1C",X"FE",X"39",X"1A",X"01",X"39",X"34",X"32",X"8E",X"C8",X"C8",X"BD",
X"A4",X"BD",X"F6",X"1F",X"D6",X"EC",X"26",X"0F",X"96",X"BD",X"26",X"08",X"D6",X"EB",X"DA",X"ED",
X"DA",X"E7",X"26",X"03",X"1C",X"FE",X"39",X"1A",X"01",X"39",X"34",X"32",X"8E",X"C8",X"C8",X"BD",
X"F2",X"F2",X"A6",X"E4",X"97",X"04",X"1F",X"20",X"BD",X"F3",X"12",X"C6",X"0C",X"AE",X"61",X"BD",
X"F4",X"0E",X"35",X"B2",X"34",X"16",X"8E",X"CB",X"2B",X"86",X"0E",X"E6",X"84",X"27",X"07",X"30",
X"05",X"4A",X"26",X"F7",X"20",X"1D",X"A6",X"E4",X"84",X"80",X"4C",X"A7",X"84",X"2A",X"02",X"0C",
@@ -230,15 +230,15 @@ architecture prom of vectrex_exec_prom is
X"0B",X"00",X"0C",X"00",X"0D",X"00",X"FF",X"ED",X"8F",X"FE",X"B6",X"00",X"19",X"01",X"19",X"00",
X"19",X"01",X"32",X"00",X"19",X"01",X"19",X"00",X"19",X"06",X"19",X"05",X"19",X"00",X"80",X"FF",
X"EE",X"DD",X"CC",X"BB",X"AA",X"99",X"88",X"77",X"77",X"77",X"77",X"77",X"77",X"77",X"77",X"C8",
X"A8",X"C8",X"AF",X"7F",X"A0",X"7F",X"10",X"C8",X"F9",X"C9",X"00",X"00",X"00",X"00",X"00",X"02",
X"00",X"00",X"00",X"01",X"00",X"00",X"00",X"03",X"00",X"00",X"00",X"02",X"01",X"00",X"00",X"02",
X"03",X"00",X"00",X"01",X"03",X"00",X"00",X"02",X"02",X"00",X"00",X"01",X"01",X"00",X"00",X"03",
X"03",X"00",X"00",X"02",X"02",X"02",X"00",X"01",X"01",X"01",X"00",X"03",X"03",X"03",X"00",X"80",
X"A8",X"C8",X"AF",X"7F",X"A0",X"7F",X"10",X"C8",X"F9",X"C9",X"00",X"86",X"0C",X"A0",X"84",X"A0",
X"01",X"A0",X"02",X"A0",X"03",X"27",X"20",X"E6",X"84",X"CB",X"FD",X"C4",X"03",X"E7",X"84",X"C6",
X"FC",X"E9",X"01",X"C4",X"03",X"E7",X"01",X"C6",X"FC",X"E9",X"02",X"C4",X"03",X"E7",X"02",X"C6",
X"FC",X"E9",X"03",X"C4",X"03",X"E7",X"03",X"39",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"C8",X"40",X"3F",X"00",X"20",X"80",X"10",X"1F",X"3F",X"3F",X"00",X"BF",X"BF",X"BF",X"C0",X"20",
X"48",X"08",X"F8",X"30",X"A8",X"10",X"D0",X"A0",X"BF",X"BF",X"00",X"3F",X"3F",X"48",X"20",X"80",
X"00",X"B0",X"48",X"38",X"FB",X"38",X"80",X"28",X"30",X"48",X"80",X"80",X"45",X"F0",X"28",X"7F",
X"3F",X"BF",X"A5",X"00",X"D0",X"60",X"20",X"28",X"B8",X"40",X"15",X"80",X"40",X"F8",X"40",X"18",
X"FA",X"38",X"E0",X"C8",X"4D",X"49",X"4E",X"45",X"20",X"46",X"49",X"45",X"4C",X"44",X"80",X"FA",
X"FA",X"38",X"E0",X"C0",X"4D",X"49",X"4E",X"45",X"20",X"46",X"49",X"45",X"4C",X"44",X"80",X"FA",
X"38",X"E0",X"D8",X"47",X"41",X"4D",X"45",X"20",X"4F",X"56",X"45",X"52",X"80",X"00",X"10",X"00",
X"FF",X"20",X"A0",X"FF",X"C0",X"40",X"FF",X"90",X"20",X"FF",X"70",X"20",X"FF",X"50",X"50",X"FF",
X"D0",X"90",X"01",X"00",X"20",X"00",X"FF",X"30",X"B0",X"FF",X"B0",X"30",X"FF",X"B0",X"D0",X"FF",
@@ -264,10 +264,10 @@ architecture prom of vectrex_exec_prom is
X"FF",X"F0",X"F8",X"01",X"FF",X"00",X"D8",X"FF",X"E8",X"08",X"FF",X"00",X"40",X"FF",X"18",X"08",
X"FF",X"00",X"D8",X"00",X"08",X"E0",X"FF",X"10",X"00",X"FF",X"00",X"40",X"FF",X"F0",X"00",X"FF",
X"00",X"C0",X"01",X"00",X"18",X"00",X"FF",X"00",X"20",X"FF",X"C8",X"70",X"FF",X"10",X"A0",X"FF",
X"00",X"A0",X"FF",X"EC",X"A4",X"FF",X"39",X"6D",X"FF",X"00",X"20",X"01",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"A0",X"FF",X"EC",X"A4",X"FF",X"39",X"6D",X"FF",X"00",X"20",X"01",X"7F",X"C8",X"25",X"7F",
X"C8",X"26",X"7F",X"C8",X"3B",X"7E",X"F0",X"1C",X"B6",X"C8",X"D9",X"27",X"09",X"81",X"08",X"2F",
X"02",X"86",X"08",X"B7",X"C8",X"8F",X"39",X"BD",X"F1",X"BA",X"BD",X"F1",X"AF",X"96",X"0F",X"10",
X"26",X"00",X"79",X"7E",X"F0",X"1F",X"67",X"20",X"4D",X"42",X"20",X"80",X"00",X"00",X"00",X"00",
X"10",X"CE",X"CB",X"EA",X"BD",X"F1",X"8B",X"CC",X"73",X"21",X"10",X"B3",X"CB",X"FE",X"27",X"5C",
X"FD",X"CB",X"FE",X"7C",X"C8",X"3B",X"8E",X"CB",X"EB",X"BD",X"F8",X"4F",X"BD",X"F1",X"AF",X"DC",
X"25",X"10",X"83",X"01",X"01",X"26",X"02",X"D7",X"56",X"57",X"C4",X"03",X"8E",X"F0",X"FD",X"E6",

View File

@@ -20,7 +20,13 @@ module vectrex_mist
`include "rtl\build_id.v"
localparam CONF_STR = {
"Vectrex;BINVEC;",
"Vectrex;BINVECROM;",
"O2,Show Frame,No,Yes;",
"O3,Skip Logo,No,Yes;",
// "O23,Phosphor persistance,1,2,3,4;",
// "O8,Overburn,No,Yes;",
"T6,Reset;",
"V,v1.00.",`BUILD_DATE
};
@@ -28,13 +34,13 @@ localparam CONF_STR = {
wire [31:0] status;
wire [1:0] buttons;
wire [1:0] switches;
wire [7:0] kbjoy;
wire [15:0] kbjoy;
wire [7:0] joystick_0;
wire [7:0] joystick_1;
wire ypbpr;
wire ps2_kbd_clk, ps2_kbd_data;
wire [7:0] pot_x;
wire [7:0] pot_y;
wire [7:0] pot_x_1, pot_x_2;
wire [7:0] pot_y_1, pot_y_2;
wire [9:0] audio;
wire hs, vs, cs;
wire [3:0] r, g, b;
@@ -51,29 +57,39 @@ wire [7:0] ioctl_dout;
assign LED = !ioctl_downl;
wire clk_25, clk_12p5, clk_6p25, cpu_clock;
wire clk_24, clk_12, clk_6;
wire pll_locked;
always @(clk_6p25)begin
pot_x = 8'h00;
pot_y = 8'h00;
if (joystick_0[3] | joystick_1[3] | kbjoy[3]) pot_y = 8'h7F;
if (joystick_0[2] | joystick_1[2] | kbjoy[2]) pot_y = 8'h80;
if (joystick_0[1] | joystick_1[1] | kbjoy[1]) pot_x = 8'h80;
if (joystick_0[0] | joystick_1[0] | kbjoy[0]) pot_x = 8'h7F;
always @(clk_6)begin
pot_x_1 = 8'h00;
pot_y_1 = 8'h00;
pot_x_2 = 8'h00;
pot_y_2 = 8'h00;
//
if (joystick_0[1] | kbjoy[1]) pot_x_2 = 8'h80;
if (joystick_0[0] | kbjoy[0]) pot_x_2 = 8'h7F;
if (joystick_0[3] | kbjoy[3]) pot_y_2 = 8'h7F;
if (joystick_0[2] | kbjoy[2]) pot_y_2 = 8'h80;
//Player2
if (joystick_1[1] | kbjoy[9]) pot_x_1 = 8'h80;
if (joystick_1[0] | kbjoy[8]) pot_x_1 = 8'h7F;
if (joystick_1[3] | kbjoy[11]) pot_y_1 = 8'h7F;
if (joystick_1[2] | kbjoy[10]) pot_y_1 = 8'h80;
end
pll pll (
.inclk0 ( CLOCK_27 ),
.areset ( 0 ),
.c0 ( clk_25 ),
.c1 ( clk_12p5 ),
.c2 ( clk_6p25 ),
.c0 ( clk_24 ),
.c1 ( clk_12 ),
.c2 ( clk_6 ),
.locked ( pll_locked )
);
card card (
.clock ( clk_25 ),
.clock ( clk_24 ),
.address ( ioctl_downl ? ioctl_addr : cart_addr),
.data ( ioctl_dout ),
.rden ( !ioctl_downl && cart_rd),
@@ -81,56 +97,86 @@ card card (
.q ( cart_do )
);
wire reset = (status[0] | status[6] | buttons[1] | ioctl_downl | second_reset);
reg second_reset = 0;
always @(posedge clk_24) begin
integer timeout = 0;
if(ioctl_downl && status[3]) timeout <= 5000000;
else begin
if(!timeout) second_reset <= 0;
else begin
timeout <= timeout - 1;
if(timeout < 1000) second_reset <= 1;
end
end
end
vectrex vectrex (
.clock_24 ( clk_25 ),
.clock_12 ( clk_12p5 ),
.cpu_clock_o ( cpu_clock ),
.reset ( status[0] | status[6] | buttons[1] | ioctl_downl),
.video_r ( r ),
.video_g ( g ),
.video_b ( b ),
.clock_24 ( clk_24 ),
.clock_12 ( clk_12 ),
.reset ( reset ),
.video_r ( rr ),
.video_g ( gg ),
.video_b ( bb ),
.video_csync ( cs ),
.video_blankn ( blankn ),
.video_hs ( hs ),
.video_vs ( vs ),
.frame ( frame_line ),
.audio_out ( audio ),
.cart_addr ( cart_addr ),
.cart_do ( cart_do ),
.cart_rd ( cart_rd ),
.btn11 ( joystick_0[4] | joystick_1[4] | kbjoy[4]),
.btn12 ( joystick_0[5] | joystick_1[5] | kbjoy[5]),
.btn13 ( kbjoy[6] ),
.btn14 ( kbjoy[7] ),
.pot_x_1 ( pot_x ),
.pot_y_1 ( pot_y ),
.btn21 ( joystick_0[4] | joystick_1[4] | kbjoy[4]),
.btn22 ( joystick_0[5] | joystick_1[5] | kbjoy[5]),
.btn23 ( kbjoy[6] ),
.btn24 ( kbjoy[7] ),
.pot_x_2 ( pot_x ),
.pot_y_2 ( pot_y ),
.btn11 ( joystick_0[4] | kbjoy[4]),
.btn12 ( joystick_0[5] | kbjoy[5]),
.btn13 ( joystick_0[6] | kbjoy[6]),
.btn14 ( joystick_0[7] | kbjoy[7]),
.pot_x_1 ( pot_x_1 ),
.pot_y_1 ( pot_y_1 ),
.btn21 ( joystick_1[4] | kbjoy[12]),
.btn22 ( joystick_1[5] | kbjoy[13]),
.btn23 ( joystick_1[6] | kbjoy[14]),
.btn24 ( joystick_1[7] | kbjoy[15]),
.pot_x_2 ( pot_x_2 ),
.pot_y_2 ( pot_y_2 ),
.leds ( ),
.dbg_cpu_addr ( )
);
// .pot_x_1(joya_0[7:0] ? joya_0[7:0] : {joystick_0[1], {7{joystick_0[0]}}}),
//.pot_y_1(joya_0[15:8] ? ~joya_0[15:8] : {joystick_0[2], {7{joystick_0[3]}}}),
// .pot_x_2(joya_1[7:0] ? joya_1[7:0] : {joystick_1[1], {7{joystick_1[0]}}}),
//.pot_y_2(joya_1[15:8] ? ~joya_1[15:8] : {joystick_1[2], {7{joystick_1[3]}}})
dac dac (
.clk_i ( clk_25 ),
.clk_i ( clk_24 ),
.res_n_i ( 1 ),
.dac_i ( audio ),
.dac_o ( AUDIO_L )
);
assign AUDIO_R = AUDIO_L;
wire frame_line;
wire [3:0] rr,gg,bb;
assign r = status[2] & frame_line ? 4'h40 : rr;
assign g = status[2] & frame_line ? 4'h00 : gg;
assign b = status[2] & frame_line ? 4'h00 : bb;
video_mixer #(.LINE_LENGTH(640), .HALF_DEPTH(1)) video_mixer (
.clk_sys ( clk_25 ),
.ce_pix ( clk_6p25 ),
.ce_pix_actual ( clk_6p25 ),
.clk_sys ( clk_24 ),
.ce_pix ( clk_6 ),
.ce_pix_actual ( clk_6 ),
.SPI_SCK ( SPI_SCK ),
.SPI_SS3 ( SPI_SS3 ),
.SPI_DI ( SPI_DI ),
.R ( blankn ? r : "0000"),
.G ( blankn ? g : "0000"),
.B ( blankn ? b : "0000"),
.R ( blankn ? r : "0000"),
.G ( blankn ? g : "0000"),
.B ( blankn ? b : "0000"),
.HSync ( hs ),
.VSync ( vs ),
.VGA_R ( VGA_R ),
@@ -145,7 +191,7 @@ video_mixer #(.LINE_LENGTH(640), .HALF_DEPTH(1)) video_mixer (
);
mist_io #(.STRLEN(($size(CONF_STR)>>3))) mist_io (
.clk_sys ( clk_25 ),
.clk_sys ( clk_24 ),
.conf_str ( CONF_STR ),
.SPI_SCK ( SPI_SCK ),
.CONF_DATA0 ( CONF_DATA0 ),
@@ -168,7 +214,7 @@ mist_io #(.STRLEN(($size(CONF_STR)>>3))) mist_io (
);
keyboard keyboard (
.clk ( clk_25 ),
.clk ( clk_24 ),
.reset ( ),
.ps2_kbd_clk ( ps2_kbd_clk ),
.ps2_kbd_data ( ps2_kbd_data ),

View File

@@ -0,0 +1,304 @@
module ym2149
(
input CLK, // Global clock
input CE, // PSG Clock enable
input RESET, // Chip RESET (set all Registers to '0', active hi)
input BDIR, // Bus Direction (0 - read , 1 - write)
input BC, // Bus control
input [7:0] DI, // Data In
output [7:0] DO, // Data Out
output [7:0] CHANNEL_A, // PSG Output channel A
output [7:0] CHANNEL_B, // PSG Output channel B
output [7:0] CHANNEL_C, // PSG Output channel C
input SEL,
input MODE,
output [5:0] ACTIVE,
input [7:0] IOA_in,
output [7:0] IOA_out,
input [7:0] IOB_in,
output [7:0] IOB_out
);
assign ACTIVE = ~ymreg[7][5:0];
assign IOA_out = ymreg[14];
assign IOB_out = ymreg[15];
reg ena_div;
reg ena_div_noise;
reg [3:0] addr;
reg [7:0] ymreg[16];
reg env_ena;
reg [4:0] env_vol;
wire [7:0] volTableAy[16] =
'{8'h00, 8'h03, 8'h04, 8'h06,
8'h0a, 8'h0f, 8'h15, 8'h22,
8'h28, 8'h41, 8'h5b, 8'h72,
8'h90, 8'hb5, 8'hd7, 8'hff
};
wire [7:0] volTableYm[32] =
'{8'h00, 8'h01, 8'h01, 8'h02,
8'h02, 8'h03, 8'h03, 8'h04,
8'h06, 8'h07, 8'h09, 8'h0a,
8'h0c, 8'h0e, 8'h11, 8'h13,
8'h17, 8'h1b, 8'h20, 8'h25,
8'h2c, 8'h35, 8'h3e, 8'h47,
8'h54, 8'h66, 8'h77, 8'h88,
8'ha1, 8'hc0, 8'he0, 8'hff
};
// Read from AY
assign DO = dout;
reg [7:0] dout;
always_comb begin
case(addr)
0: dout = ymreg[0];
1: dout = {4'b0000, ymreg[1][3:0]};
2: dout = ymreg[2];
3: dout = {4'b0000, ymreg[3][3:0]};
4: dout = ymreg[4];
5: dout = {4'b0000, ymreg[5][3:0]};
6: dout = {3'b000, ymreg[6][4:0]};
7: dout = ymreg[7];
8: dout = {3'b000, ymreg[8][4:0]};
9: dout = {3'b000, ymreg[9][4:0]};
10: dout = {3'b000, ymreg[10][4:0]};
11: dout = ymreg[11];
12: dout = ymreg[12];
13: dout = {4'b0000, ymreg[13][3:0]};
14: dout = (ymreg[7][6] ? ymreg[14] : IOA_in);
15: dout = (ymreg[7][7] ? ymreg[15] : IOB_in);
endcase
end
// p_divider
always @(posedge CLK) begin
reg [3:0] cnt_div;
reg noise_div;
if(CE) begin
ena_div <= 0;
ena_div_noise <= 0;
if(!cnt_div) begin
cnt_div <= {SEL, 3'b111};
ena_div <= 1;
noise_div <= (~noise_div);
if (noise_div) ena_div_noise <= 1;
end else begin
cnt_div <= cnt_div - 1'b1;
end
end
end
reg noise_gen_op;
// p_noise_gen
always @(posedge CLK) begin
reg [16:0] poly17;
reg [4:0] noise_gen_cnt;
if(CE) begin
if (ena_div_noise) begin
if(ymreg[6][4:0]) begin
if (noise_gen_cnt >= ymreg[6][4:0] - 1'd1) begin
noise_gen_cnt <= 0;
poly17 <= {(poly17[0] ^ poly17[2] ^ !poly17), poly17[16:1]};
end else begin
noise_gen_cnt <= noise_gen_cnt + 1'd1;
end
noise_gen_op <= poly17[0];
end else begin
noise_gen_op <= 0;
noise_gen_cnt <= 0;
end
end
end
end
wire [11:0] tone_gen_freq[1:3];
assign tone_gen_freq[1] = {ymreg[1][3:0], ymreg[0]};
assign tone_gen_freq[2] = {ymreg[3][3:0], ymreg[2]};
assign tone_gen_freq[3] = {ymreg[5][3:0], ymreg[4]};
reg [3:1] tone_gen_op;
//p_tone_gens
always @(posedge CLK) begin
integer i;
reg [11:0] tone_gen_cnt[1:3];
if(CE) begin
// looks like real chips count up - we need to get the Exact behaviour ..
for (i = 1; i <= 3; i = i + 1) begin
if(ena_div) begin
if (tone_gen_freq[i]) begin
if (tone_gen_cnt[i] >= (tone_gen_freq[i] - 1'd1)) begin
tone_gen_cnt[i] <= 0;
tone_gen_op[i] <= ~tone_gen_op[i];
end else begin
tone_gen_cnt[i] <= tone_gen_cnt[i] + 1'd1;
end
end else begin
tone_gen_op[i] <= 0;
tone_gen_cnt[i] <= 0;
end
end
end
end
end
wire [15:0] env_gen_comp = {ymreg[12], ymreg[11]} ? {ymreg[12], ymreg[11]} - 1'd1 : 16'd0;
//p_envelope_freq
always @(posedge CLK) begin
reg [15:0] env_gen_cnt;
if(CE) begin
env_ena <= 0;
if(ena_div) begin
if (env_gen_cnt >= env_gen_comp) begin
env_gen_cnt <= 0;
env_ena <= 1;
end else begin
env_gen_cnt <= (env_gen_cnt + 1'd1);
end
end
end
end
wire is_bot = (env_vol == 5'b00000);
wire is_bot_p1 = (env_vol == 5'b00001);
wire is_top_m1 = (env_vol == 5'b11110);
wire is_top = (env_vol == 5'b11111);
always @(posedge CLK) begin
reg old_BDIR;
reg env_reset;
reg env_hold;
reg env_inc;
// envelope shapes
// C AtAlH
// 0 0 x x \___
//
// 0 1 x x /___
//
// 1 0 0 0 \\\\
//
// 1 0 0 1 \___
//
// 1 0 1 0 \/\/
// ___
// 1 0 1 1 \
//
// 1 1 0 0 ////
// ___
// 1 1 0 1 /
//
// 1 1 1 0 /\/\
//
// 1 1 1 1 /___
if(RESET) begin
ymreg[0] <= 0;
ymreg[1] <= 0;
ymreg[2] <= 0;
ymreg[3] <= 0;
ymreg[4] <= 0;
ymreg[5] <= 0;
ymreg[6] <= 0;
ymreg[7] <= 255;
ymreg[8] <= 0;
ymreg[9] <= 0;
ymreg[10] <= 0;
ymreg[11] <= 0;
ymreg[12] <= 0;
ymreg[13] <= 0;
ymreg[14] <= 0;
ymreg[15] <= 0;
addr <= 0;
env_vol <= 0;
end else begin
old_BDIR <= BDIR;
if(~old_BDIR & BDIR) begin
if(BC) addr <= DI[3:0];
else begin
ymreg[addr] <= DI;
env_reset <= (addr == 13);
end
end
end
if(CE) begin
if(env_reset) begin
env_reset <= 0;
// load initial state
if(!ymreg[13][2]) begin // attack
env_vol <= 5'b11111;
env_inc <= 0; // -1
end else begin
env_vol <= 5'b00000;
env_inc <= 1; // +1
end
env_hold <= 0;
end else begin
if (env_ena) begin
if (!env_hold) begin
if (env_inc) env_vol <= (env_vol + 5'b00001);
else env_vol <= (env_vol + 5'b11111);
end
// envelope shape control.
if(!ymreg[13][3]) begin
if(!env_inc) begin // down
if(is_bot_p1) env_hold <= 1;
end else if (is_top) env_hold <= 1;
end else if(ymreg[13][0]) begin // hold = 1
if(!env_inc) begin // down
if(ymreg[13][1]) begin // alt
if(is_bot) env_hold <= 1;
end else if(is_bot_p1) env_hold <= 1;
end else if(ymreg[13][1]) begin // alt
if(is_top) env_hold <= 1;
end else if(is_top_m1) env_hold <= 1;
end else if(ymreg[13][1]) begin // alternate
if(env_inc == 1'b0) begin // down
if(is_bot_p1) env_hold <= 1;
if(is_bot) begin
env_hold <= 0;
env_inc <= 1;
end
end else begin
if(is_top_m1) env_hold <= 1;
if(is_top) begin
env_hold <= 0;
env_inc <= 0;
end
end
end
end
end
end
end
wire [4:0] A = ~((ymreg[7][0] | tone_gen_op[1]) & (ymreg[7][3] | noise_gen_op)) ? 5'd0 : ymreg[8][4] ? env_vol[4:0] : { ymreg[8][3:0], ymreg[8][3]};
wire [4:0] B = ~((ymreg[7][1] | tone_gen_op[2]) & (ymreg[7][4] | noise_gen_op)) ? 5'd0 : ymreg[9][4] ? env_vol[4:0] : { ymreg[9][3:0], ymreg[9][3]};
wire [4:0] C = ~((ymreg[7][2] | tone_gen_op[3]) & (ymreg[7][5] | noise_gen_op)) ? 5'd0 : ymreg[10][4] ? env_vol[4:0] : {ymreg[10][3:0], ymreg[10][3]};
assign CHANNEL_A = MODE ? volTableAy[A[4:1]] : volTableYm[A];
assign CHANNEL_B = MODE ? volTableAy[B[4:1]] : volTableYm[B];
assign CHANNEL_C = MODE ? volTableAy[C[4:1]] : volTableYm[C];
endmodule

View File

@@ -43,7 +43,6 @@ set_global_assignment -name ORIGINAL_QUARTUS_VERSION 15.1.0
set_global_assignment -name PROJECT_CREATION_TIME_DATE "17:45:13 JUNE 17,2016"
set_global_assignment -name LAST_QUARTUS_VERSION 13.1
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
set_global_assignment -name VHDL_FILE rtl/YM2149_linmix_sep.vhd
set_global_assignment -name VHDL_FILE rtl/vectrex.vhd
set_global_assignment -name VHDL_FILE rtl/m6522a.vhd
set_global_assignment -name VHDL_FILE rtl/gen_ram.vhd
@@ -220,4 +219,7 @@ set_global_assignment -name PHYSICAL_SYNTHESIS_EFFORT EXTRA
set_global_assignment -name CYCLONEII_OPTIMIZATION_TECHNIQUE AREA
set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS ON
set_global_assignment -name ENABLE_SIGNALTAP OFF
set_global_assignment -name VERILOG_FILE rtl/mc6809is.v
set_global_assignment -name VERILOG_FILE rtl/mc6809.v
set_global_assignment -name SYSTEMVERILOG_FILE rtl/ym2149.sv
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top