1
0
mirror of https://github.com/Gehstock/Mist_FPGA.git synced 2026-03-03 18:06:03 +00:00

Sync Midway8080

This commit is contained in:
Marcel
2020-08-19 16:40:39 +02:00
parent 8661efc57a
commit ae35cde8d4
20 changed files with 890 additions and 4380 deletions

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 SP4.26"
set_global_assignment -name LAST_QUARTUS_VERSION 13.1
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:rtl/build_id.tcl"

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 SP4.26"
set_global_assignment -name LAST_QUARTUS_VERSION 13.1
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:rtl/build_id.tcl"
# Pin & Location Assignments

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 SP4.26"
set_global_assignment -name LAST_QUARTUS_VERSION 13.1
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:rtl/build_id.tcl"

View File

@@ -167,10 +167,10 @@ set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -
set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
# end DESIGN_PARTITION(Top)
# -------------------------
# end ENTITY(SpaceWalk_mist)
# --------------------------
# --------------------------
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top

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 SP4.26"
set_global_assignment -name LAST_QUARTUS_VERSION 13.1
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:rtl/build_id.tcl"

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 SP4.26"
set_global_assignment -name LAST_QUARTUS_VERSION 13.1
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:rtl/build_id.tcl"
@@ -175,58 +175,4 @@ set_global_assignment -name SMART_RECOMPILE ON
set_global_assignment -name ENABLE_SIGNALTAP ON
set_global_assignment -name USE_SIGNALTAP_FILE output_files/stp3.stp
set_global_assignment -name SIGNALTAP_FILE output_files/stp3.stp
set_global_assignment -name SLD_NODE_CREATOR_ID 110 -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_ENTITY_NAME sld_signaltap -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_clk -to "invaderst:invaderst|Clk" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_RAM_BLOCK_TYPE=AUTO" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_NODE_INFO=805334528" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_POWER_UP_TRIGGER=0" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_STORAGE_QUALIFIER_INVERSION_MASK_LENGTH=0" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_SEGMENT_SIZE=128" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_ATTRIBUTE_MEM_MODE=OFF" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_STATE_FLOW_USE_GENERATED=0" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_STATE_BITS=11" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_BUFFER_FULL_STOP=1" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_CURRENT_RESOURCE_WIDTH=1" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_TRIGGER_LEVEL=1" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_SAMPLE_DEPTH=128" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_TRIGGER_IN_ENABLED=0" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_ADVANCED_TRIGGER_ENTITY=basic,1," -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_TRIGGER_LEVEL_PIPELINE=1" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_ENABLE_ADVANCED_TRIGGER=0" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[0] -to "invaderst:invaderst|Gun1[0]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[1] -to "invaderst:invaderst|Gun1[1]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[2] -to "invaderst:invaderst|Gun1[2]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[3] -to "invaderst:invaderst|Gun1[3]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[4] -to "invaderst:invaderst|Gun2[0]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[5] -to "invaderst:invaderst|Gun2[1]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[6] -to "invaderst:invaderst|Gun2[2]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[7] -to "invaderst:invaderst|Gun2[3]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[8] -to "invaderst:invaderst|state1[0]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[9] -to "invaderst:invaderst|state1[1]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[10] -to "invaderst:invaderst|state1[2]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[11] -to "invaderst:invaderst|state2[0]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[12] -to "invaderst:invaderst|state2[1]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[13] -to "invaderst:invaderst|state2[2]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[0] -to "invaderst:invaderst|Gun1[0]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[1] -to "invaderst:invaderst|Gun1[1]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[2] -to "invaderst:invaderst|Gun1[2]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[3] -to "invaderst:invaderst|Gun1[3]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[4] -to "invaderst:invaderst|Gun2[0]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[5] -to "invaderst:invaderst|Gun2[1]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[6] -to "invaderst:invaderst|Gun2[2]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[7] -to "invaderst:invaderst|Gun2[3]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[8] -to "invaderst:invaderst|state1[0]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[9] -to "invaderst:invaderst|state1[1]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[10] -to "invaderst:invaderst|state1[2]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[11] -to "invaderst:invaderst|state2[0]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[12] -to "invaderst:invaderst|state2[1]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[13] -to "invaderst:invaderst|state2[2]" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_DATA_BITS=14" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_TRIGGER_BITS=14" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_INVERSION_MASK=000000000000000000000000000000000000000000000000000000000000000" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_INVERSION_MASK_LENGTH=63" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_NODE_CRC_LOWORD=3917" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_NODE_CRC_HIWORD=53125" -section_id auto_signaltap_0
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
set_global_assignment -name SLD_FILE db/stp3_auto_stripped.stp
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top

View File

@@ -44,23 +44,6 @@ set_global_assignment -name PROJECT_CREATION_TIME_DATE "21:27:39 NOVEMBER 20, 2
set_global_assignment -name LAST_QUARTUS_VERSION 13.1
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:rtl/build_id.tcl"
set_global_assignment -name SYSTEMVERILOG_FILE rtl/Shuffleboard_mist.sv
set_global_assignment -name VHDL_FILE rtl/invaders.vhd
set_global_assignment -name VHDL_FILE rtl/mw8080.vhd
set_global_assignment -name VHDL_FILE rtl/invaders_audio.vhd
set_global_assignment -name SYSTEMVERILOG_FILE rtl/Shuffleboard_memory.sv
set_global_assignment -name VHDL_FILE rtl/dac.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/T80/T8080se.vhd
set_global_assignment -name VHDL_FILE rtl/T80/T80_Reg.vhd
set_global_assignment -name VHDL_FILE rtl/T80/T80_Pack.vhd
set_global_assignment -name VHDL_FILE rtl/T80/T80_MCode.vhd
set_global_assignment -name VHDL_FILE rtl/T80/T80_ALU.vhd
set_global_assignment -name VHDL_FILE rtl/T80/T80.vhd
set_global_assignment -name VHDL_FILE rtl/invaders_video.vhd
set_global_assignment -name VHDL_FILE rtl/pll.vhd
set_global_assignment -name QIP_FILE ../../../../common/mist/mist.qip
# Pin & Location Assignments
# ==========================
@@ -170,4 +153,15 @@ set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -
# end ENTITY(LunarRescue_mist)
# ----------------------------
set_global_assignment -name SYSTEMVERILOG_FILE rtl/Shuffleboard_mist.sv
set_global_assignment -name VHDL_FILE rtl/invaders.vhd
set_global_assignment -name VHDL_FILE rtl/mw8080.vhd
set_global_assignment -name VHDL_FILE rtl/invaders_audio.vhd
set_global_assignment -name SYSTEMVERILOG_FILE rtl/Shuffleboard_memory.sv
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/invaders_video.vhd
set_global_assignment -name VHDL_FILE rtl/pll.vhd
set_global_assignment -name QIP_FILE ../../../common/mist/mist.qip
set_global_assignment -name QIP_FILE ../../../common/CPU/T80/T80.qip
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top

View File

@@ -1,194 +0,0 @@
-- ****
-- T80(b) core. In an effort to merge and maintain bug fixes ....
--
--
-- Ver 300 started tidyup
-- MikeJ March 2005
-- Latest version from www.fpgaarcade.com (original www.opencores.org)
--
-- ****
--
-- 8080 compatible microprocessor core, synchronous top level with clock enable
-- Different timing than the original 8080
-- Inputs needs to be synchronous and outputs may glitch
--
-- Version : 0242
--
-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org)
--
-- 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 SOFTWARE 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.
--
-- Please report bugs to the author, but before you do so, please
-- make sure that this is not a derivative work and that
-- you have the latest version of this file.
--
-- The latest version of this file can be found at:
-- http://www.opencores.org/cvsweb.shtml/t80/
--
-- Limitations :
-- STACK status output not supported
--
-- File history :
--
-- 0237 : First version
--
-- 0238 : Updated for T80 interface change
--
-- 0240 : Updated for T80 interface change
--
-- 0242 : Updated for T80 interface change
--
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.T80_Pack.all;
entity T8080se is
generic(
Mode : integer := 2; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
T2Write : integer := 0 -- 0 => WR_n active in T3, /=0 => WR_n active in T2
);
port(
RESET_n : in std_logic;
CLK : in std_logic;
CLKEN : in std_logic;
READY : in std_logic;
HOLD : in std_logic;
INT : in std_logic;
INTE : out std_logic;
DBIN : out std_logic;
SYNC : out std_logic;
VAIT : out std_logic;
HLDA : out std_logic;
WR_n : out std_logic;
A : out std_logic_vector(15 downto 0);
DI : in std_logic_vector(7 downto 0);
DO : out std_logic_vector(7 downto 0)
);
end T8080se;
architecture rtl of T8080se is
signal IntCycle_n : std_logic;
signal NoRead : std_logic;
signal Write : std_logic;
signal IORQ : std_logic;
signal INT_n : std_logic;
signal HALT_n : std_logic;
signal BUSRQ_n : std_logic;
signal BUSAK_n : std_logic;
signal DO_i : std_logic_vector(7 downto 0);
signal DI_Reg : std_logic_vector(7 downto 0);
signal MCycle : std_logic_vector(2 downto 0);
signal TState : std_logic_vector(2 downto 0);
signal One : std_logic;
begin
INT_n <= not INT;
BUSRQ_n <= HOLD;
HLDA <= not BUSAK_n;
SYNC <= '1' when TState = "001" else '0';
VAIT <= '1' when TState = "010" else '0';
One <= '1';
DO(0) <= not IntCycle_n when TState = "001" else DO_i(0); -- INTA
DO(1) <= Write when TState = "001" else DO_i(1); -- WO_n
DO(2) <= DO_i(2); -- STACK not supported !!!!!!!!!!
DO(3) <= not HALT_n when TState = "001" else DO_i(3); -- HLTA
DO(4) <= IORQ and Write when TState = "001" else DO_i(4); -- OUT
DO(5) <= DO_i(5) when TState /= "001" else '1' when MCycle = "001" else '0'; -- M1
DO(6) <= IORQ and not Write when TState = "001" else DO_i(6); -- INP
DO(7) <= not IORQ and not Write and IntCycle_n when TState = "001" else DO_i(7); -- MEMR
u0 : T80
generic map(
Mode => Mode,
IOWait => 0)
port map(
CEN => CLKEN,
M1_n => open,
IORQ => IORQ,
NoRead => NoRead,
Write => Write,
RFSH_n => open,
HALT_n => HALT_n,
WAIT_n => READY,
INT_n => INT_n,
NMI_n => One,
RESET_n => RESET_n,
BUSRQ_n => One,
BUSAK_n => BUSAK_n,
CLK_n => CLK,
A => A,
DInst => DI,
DI => DI_Reg,
DO => DO_i,
MC => MCycle,
TS => TState,
IntCycle_n => IntCycle_n,
IntE => INTE);
process (RESET_n, CLK)
begin
if RESET_n = '0' then
DBIN <= '0';
WR_n <= '1';
DI_Reg <= "00000000";
elsif CLK'event and CLK = '1' then
if CLKEN = '1' then
DBIN <= '0';
WR_n <= '1';
if MCycle = "001" then
if TState = "001" or (TState = "010" and READY = '0') then
DBIN <= IntCycle_n;
end if;
else
if (TState = "001" or (TState = "010" and READY = '0')) and NoRead = '0' and Write = '0' then
DBIN <= '1';
end if;
if T2Write = 0 then
if TState = "010" and Write = '1' then
WR_n <= '0';
end if;
else
if (TState = "001" or (TState = "010" and READY = '0')) and Write = '1' then
WR_n <= '0';
end if;
end if;
end if;
if TState = "010" and READY = '1' then
DI_Reg <= DI;
end if;
end if;
end if;
end process;
end;

View File

@@ -1,361 +0,0 @@
-- ****
-- T80(b) core. In an effort to merge and maintain bug fixes ....
--
--
-- Ver 300 started tidyup
-- MikeJ March 2005
-- Latest version from www.fpgaarcade.com (original www.opencores.org)
--
-- ****
--
-- Z80 compatible microprocessor core
--
-- Version : 0247
--
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
--
-- 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 SOFTWARE 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.
--
-- Please report bugs to the author, but before you do so, please
-- make sure that this is not a derivative work and that
-- you have the latest version of this file.
--
-- The latest version of this file can be found at:
-- http://www.opencores.org/cvsweb.shtml/t80/
--
-- Limitations :
--
-- File history :
--
-- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test
--
-- 0238 : Fixed zero flag for 16 bit SBC and ADC
--
-- 0240 : Added GB operations
--
-- 0242 : Cleanup
--
-- 0247 : Cleanup
--
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity T80_ALU is
generic(
Mode : integer := 0;
Flag_C : integer := 0;
Flag_N : integer := 1;
Flag_P : integer := 2;
Flag_X : integer := 3;
Flag_H : integer := 4;
Flag_Y : integer := 5;
Flag_Z : integer := 6;
Flag_S : integer := 7
);
port(
Arith16 : in std_logic;
Z16 : in std_logic;
ALU_Op : in std_logic_vector(3 downto 0);
IR : in std_logic_vector(5 downto 0);
ISet : in std_logic_vector(1 downto 0);
BusA : in std_logic_vector(7 downto 0);
BusB : in std_logic_vector(7 downto 0);
F_In : in std_logic_vector(7 downto 0);
Q : out std_logic_vector(7 downto 0);
F_Out : out std_logic_vector(7 downto 0)
);
end T80_ALU;
architecture rtl of T80_ALU is
procedure AddSub(A : std_logic_vector;
B : std_logic_vector;
Sub : std_logic;
Carry_In : std_logic;
signal Res : out std_logic_vector;
signal Carry : out std_logic) is
variable B_i : unsigned(A'length - 1 downto 0);
variable Res_i : unsigned(A'length + 1 downto 0);
begin
if Sub = '1' then
B_i := not unsigned(B);
else
B_i := unsigned(B);
end if;
Res_i := unsigned("0" & A & Carry_In) + unsigned("0" & B_i & "1");
Carry <= Res_i(A'length + 1);
Res <= std_logic_vector(Res_i(A'length downto 1));
end;
-- AddSub variables (temporary signals)
signal UseCarry : std_logic;
signal Carry7_v : std_logic;
signal Overflow_v : std_logic;
signal HalfCarry_v : std_logic;
signal Carry_v : std_logic;
signal Q_v : std_logic_vector(7 downto 0);
signal BitMask : std_logic_vector(7 downto 0);
begin
with IR(5 downto 3) select BitMask <= "00000001" when "000",
"00000010" when "001",
"00000100" when "010",
"00001000" when "011",
"00010000" when "100",
"00100000" when "101",
"01000000" when "110",
"10000000" when others;
UseCarry <= not ALU_Op(2) and ALU_Op(0);
AddSub(BusA(3 downto 0), BusB(3 downto 0), ALU_Op(1), ALU_Op(1) xor (UseCarry and F_In(Flag_C)), Q_v(3 downto 0), HalfCarry_v);
AddSub(BusA(6 downto 4), BusB(6 downto 4), ALU_Op(1), HalfCarry_v, Q_v(6 downto 4), Carry7_v);
AddSub(BusA(7 downto 7), BusB(7 downto 7), ALU_Op(1), Carry7_v, Q_v(7 downto 7), Carry_v);
OverFlow_v <= Carry_v xor Carry7_v;
process (Arith16, ALU_OP, F_In, BusA, BusB, IR, Q_v, Carry_v, HalfCarry_v, OverFlow_v, BitMask, ISet, Z16)
variable Q_t : std_logic_vector(7 downto 0);
variable DAA_Q : unsigned(8 downto 0);
begin
Q_t := "--------";
F_Out <= F_In;
DAA_Q := "---------";
case ALU_Op is
when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" | "0110" | "0111" =>
F_Out(Flag_N) <= '0';
F_Out(Flag_C) <= '0';
case ALU_OP(2 downto 0) is
when "000" | "001" => -- ADD, ADC
Q_t := Q_v;
F_Out(Flag_C) <= Carry_v;
F_Out(Flag_H) <= HalfCarry_v;
F_Out(Flag_P) <= OverFlow_v;
when "010" | "011" | "111" => -- SUB, SBC, CP
Q_t := Q_v;
F_Out(Flag_N) <= '1';
F_Out(Flag_C) <= not Carry_v;
F_Out(Flag_H) <= not HalfCarry_v;
F_Out(Flag_P) <= OverFlow_v;
when "100" => -- AND
Q_t(7 downto 0) := BusA and BusB;
F_Out(Flag_H) <= '1';
when "101" => -- XOR
Q_t(7 downto 0) := BusA xor BusB;
F_Out(Flag_H) <= '0';
when others => -- OR "110"
Q_t(7 downto 0) := BusA or BusB;
F_Out(Flag_H) <= '0';
end case;
if ALU_Op(2 downto 0) = "111" then -- CP
F_Out(Flag_X) <= BusB(3);
F_Out(Flag_Y) <= BusB(5);
else
F_Out(Flag_X) <= Q_t(3);
F_Out(Flag_Y) <= Q_t(5);
end if;
if Q_t(7 downto 0) = "00000000" then
F_Out(Flag_Z) <= '1';
if Z16 = '1' then
F_Out(Flag_Z) <= F_In(Flag_Z); -- 16 bit ADC,SBC
end if;
else
F_Out(Flag_Z) <= '0';
end if;
F_Out(Flag_S) <= Q_t(7);
case ALU_Op(2 downto 0) is
when "000" | "001" | "010" | "011" | "111" => -- ADD, ADC, SUB, SBC, CP
when others =>
F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor
Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7));
end case;
if Arith16 = '1' then
F_Out(Flag_S) <= F_In(Flag_S);
F_Out(Flag_Z) <= F_In(Flag_Z);
F_Out(Flag_P) <= F_In(Flag_P);
end if;
when "1100" =>
-- DAA
F_Out(Flag_H) <= F_In(Flag_H);
F_Out(Flag_C) <= F_In(Flag_C);
DAA_Q(7 downto 0) := unsigned(BusA);
DAA_Q(8) := '0';
if F_In(Flag_N) = '0' then
-- After addition
-- Alow > 9 or H = 1
if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then
if (DAA_Q(3 downto 0) > 9) then
F_Out(Flag_H) <= '1';
else
F_Out(Flag_H) <= '0';
end if;
DAA_Q := DAA_Q + 6;
end if;
-- new Ahigh > 9 or C = 1
if DAA_Q(8 downto 4) > 9 or F_In(Flag_C) = '1' then
DAA_Q := DAA_Q + 96; -- 0x60
end if;
else
-- After subtraction
if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then
if DAA_Q(3 downto 0) > 5 then
F_Out(Flag_H) <= '0';
end if;
DAA_Q(7 downto 0) := DAA_Q(7 downto 0) - 6;
end if;
if unsigned(BusA) > 153 or F_In(Flag_C) = '1' then
DAA_Q := DAA_Q - 352; -- 0x160
end if;
end if;
F_Out(Flag_X) <= DAA_Q(3);
F_Out(Flag_Y) <= DAA_Q(5);
F_Out(Flag_C) <= F_In(Flag_C) or DAA_Q(8);
Q_t := std_logic_vector(DAA_Q(7 downto 0));
if DAA_Q(7 downto 0) = "00000000" then
F_Out(Flag_Z) <= '1';
else
F_Out(Flag_Z) <= '0';
end if;
F_Out(Flag_S) <= DAA_Q(7);
F_Out(Flag_P) <= not (DAA_Q(0) xor DAA_Q(1) xor DAA_Q(2) xor DAA_Q(3) xor
DAA_Q(4) xor DAA_Q(5) xor DAA_Q(6) xor DAA_Q(7));
when "1101" | "1110" =>
-- RLD, RRD
Q_t(7 downto 4) := BusA(7 downto 4);
if ALU_Op(0) = '1' then
Q_t(3 downto 0) := BusB(7 downto 4);
else
Q_t(3 downto 0) := BusB(3 downto 0);
end if;
F_Out(Flag_H) <= '0';
F_Out(Flag_N) <= '0';
F_Out(Flag_X) <= Q_t(3);
F_Out(Flag_Y) <= Q_t(5);
if Q_t(7 downto 0) = "00000000" then
F_Out(Flag_Z) <= '1';
else
F_Out(Flag_Z) <= '0';
end if;
F_Out(Flag_S) <= Q_t(7);
F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor
Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7));
when "1001" =>
-- BIT
Q_t(7 downto 0) := BusB and BitMask;
F_Out(Flag_S) <= Q_t(7);
if Q_t(7 downto 0) = "00000000" then
F_Out(Flag_Z) <= '1';
F_Out(Flag_P) <= '1';
else
F_Out(Flag_Z) <= '0';
F_Out(Flag_P) <= '0';
end if;
F_Out(Flag_H) <= '1';
F_Out(Flag_N) <= '0';
F_Out(Flag_X) <= '0';
F_Out(Flag_Y) <= '0';
if IR(2 downto 0) /= "110" then
F_Out(Flag_X) <= BusB(3);
F_Out(Flag_Y) <= BusB(5);
end if;
when "1010" =>
-- SET
Q_t(7 downto 0) := BusB or BitMask;
when "1011" =>
-- RES
Q_t(7 downto 0) := BusB and not BitMask;
when "1000" =>
-- ROT
case IR(5 downto 3) is
when "000" => -- RLC
Q_t(7 downto 1) := BusA(6 downto 0);
Q_t(0) := BusA(7);
F_Out(Flag_C) <= BusA(7);
when "010" => -- RL
Q_t(7 downto 1) := BusA(6 downto 0);
Q_t(0) := F_In(Flag_C);
F_Out(Flag_C) <= BusA(7);
when "001" => -- RRC
Q_t(6 downto 0) := BusA(7 downto 1);
Q_t(7) := BusA(0);
F_Out(Flag_C) <= BusA(0);
when "011" => -- RR
Q_t(6 downto 0) := BusA(7 downto 1);
Q_t(7) := F_In(Flag_C);
F_Out(Flag_C) <= BusA(0);
when "100" => -- SLA
Q_t(7 downto 1) := BusA(6 downto 0);
Q_t(0) := '0';
F_Out(Flag_C) <= BusA(7);
when "110" => -- SLL (Undocumented) / SWAP
if Mode = 3 then
Q_t(7 downto 4) := BusA(3 downto 0);
Q_t(3 downto 0) := BusA(7 downto 4);
F_Out(Flag_C) <= '0';
else
Q_t(7 downto 1) := BusA(6 downto 0);
Q_t(0) := '1';
F_Out(Flag_C) <= BusA(7);
end if;
when "101" => -- SRA
Q_t(6 downto 0) := BusA(7 downto 1);
Q_t(7) := BusA(7);
F_Out(Flag_C) <= BusA(0);
when others => -- SRL
Q_t(6 downto 0) := BusA(7 downto 1);
Q_t(7) := '0';
F_Out(Flag_C) <= BusA(0);
end case;
F_Out(Flag_H) <= '0';
F_Out(Flag_N) <= '0';
F_Out(Flag_X) <= Q_t(3);
F_Out(Flag_Y) <= Q_t(5);
F_Out(Flag_S) <= Q_t(7);
if Q_t(7 downto 0) = "00000000" then
F_Out(Flag_Z) <= '1';
else
F_Out(Flag_Z) <= '0';
end if;
F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor
Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7));
if ISet = "00" then
F_Out(Flag_P) <= F_In(Flag_P);
F_Out(Flag_S) <= F_In(Flag_S);
F_Out(Flag_Z) <= F_In(Flag_Z);
end if;
when others =>
null;
end case;
Q <= Q_t;
end process;
end;

View File

@@ -1,217 +0,0 @@
-- ****
-- T80(b) core. In an effort to merge and maintain bug fixes ....
--
--
-- Ver 300 started tidyup
-- MikeJ March 2005
-- Latest version from www.fpgaarcade.com (original www.opencores.org)
--
-- ****
--
-- Z80 compatible microprocessor core
--
-- Version : 0242
--
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
--
-- 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 SOFTWARE 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.
--
-- Please report bugs to the author, but before you do so, please
-- make sure that this is not a derivative work and that
-- you have the latest version of this file.
--
-- The latest version of this file can be found at:
-- http://www.opencores.org/cvsweb.shtml/t80/
--
-- Limitations :
--
-- File history :
--
library IEEE;
use IEEE.std_logic_1164.all;
package T80_Pack is
component T80
generic(
Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
IOWait : integer := 0; -- 1 => Single cycle I/O, 1 => Std I/O cycle
Flag_C : integer := 0;
Flag_N : integer := 1;
Flag_P : integer := 2;
Flag_X : integer := 3;
Flag_H : integer := 4;
Flag_Y : integer := 5;
Flag_Z : integer := 6;
Flag_S : integer := 7
);
port(
RESET_n : in std_logic;
CLK_n : in std_logic;
CEN : in std_logic;
WAIT_n : in std_logic;
INT_n : in std_logic;
NMI_n : in std_logic;
BUSRQ_n : in std_logic;
M1_n : out std_logic;
IORQ : out std_logic;
NoRead : out std_logic;
Write : out std_logic;
RFSH_n : out std_logic;
HALT_n : out std_logic;
BUSAK_n : out std_logic;
A : out std_logic_vector(15 downto 0);
DInst : in std_logic_vector(7 downto 0);
DI : in std_logic_vector(7 downto 0);
DO : out std_logic_vector(7 downto 0);
MC : out std_logic_vector(2 downto 0);
TS : out std_logic_vector(2 downto 0);
IntCycle_n : out std_logic;
IntE : out std_logic;
Stop : out std_logic
);
end component;
component T80_Reg
port(
Clk : in std_logic;
CEN : in std_logic;
WEH : in std_logic;
WEL : in std_logic;
AddrA : in std_logic_vector(2 downto 0);
AddrB : in std_logic_vector(2 downto 0);
AddrC : in std_logic_vector(2 downto 0);
DIH : in std_logic_vector(7 downto 0);
DIL : in std_logic_vector(7 downto 0);
DOAH : out std_logic_vector(7 downto 0);
DOAL : out std_logic_vector(7 downto 0);
DOBH : out std_logic_vector(7 downto 0);
DOBL : out std_logic_vector(7 downto 0);
DOCH : out std_logic_vector(7 downto 0);
DOCL : out std_logic_vector(7 downto 0)
);
end component;
component T80_MCode
generic(
Mode : integer := 0;
Flag_C : integer := 0;
Flag_N : integer := 1;
Flag_P : integer := 2;
Flag_X : integer := 3;
Flag_H : integer := 4;
Flag_Y : integer := 5;
Flag_Z : integer := 6;
Flag_S : integer := 7
);
port(
IR : in std_logic_vector(7 downto 0);
ISet : in std_logic_vector(1 downto 0);
MCycle : in std_logic_vector(2 downto 0);
F : in std_logic_vector(7 downto 0);
NMICycle : in std_logic;
IntCycle : in std_logic;
MCycles : out std_logic_vector(2 downto 0);
TStates : out std_logic_vector(2 downto 0);
Prefix : out std_logic_vector(1 downto 0); -- None,BC,ED,DD/FD
Inc_PC : out std_logic;
Inc_WZ : out std_logic;
IncDec_16 : out std_logic_vector(3 downto 0); -- BC,DE,HL,SP 0 is inc
Read_To_Reg : out std_logic;
Read_To_Acc : out std_logic;
Set_BusA_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F
Set_BusB_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0
ALU_Op : out std_logic_vector(3 downto 0);
-- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None
Save_ALU : out std_logic;
PreserveC : out std_logic;
Arith16 : out std_logic;
Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI
IORQ : out std_logic;
Jump : out std_logic;
JumpE : out std_logic;
JumpXY : out std_logic;
Call : out std_logic;
RstP : out std_logic;
LDZ : out std_logic;
LDW : out std_logic;
LDSPHL : out std_logic;
Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None
ExchangeDH : out std_logic;
ExchangeRp : out std_logic;
ExchangeAF : out std_logic;
ExchangeRS : out std_logic;
I_DJNZ : out std_logic;
I_CPL : out std_logic;
I_CCF : out std_logic;
I_SCF : out std_logic;
I_RETN : out std_logic;
I_BT : out std_logic;
I_BC : out std_logic;
I_BTR : out std_logic;
I_RLD : out std_logic;
I_RRD : out std_logic;
I_INRC : out std_logic;
SetDI : out std_logic;
SetEI : out std_logic;
IMode : out std_logic_vector(1 downto 0);
Halt : out std_logic;
NoRead : out std_logic;
Write : out std_logic
);
end component;
component T80_ALU
generic(
Mode : integer := 0;
Flag_C : integer := 0;
Flag_N : integer := 1;
Flag_P : integer := 2;
Flag_X : integer := 3;
Flag_H : integer := 4;
Flag_Y : integer := 5;
Flag_Z : integer := 6;
Flag_S : integer := 7
);
port(
Arith16 : in std_logic;
Z16 : in std_logic;
ALU_Op : in std_logic_vector(3 downto 0);
IR : in std_logic_vector(5 downto 0);
ISet : in std_logic_vector(1 downto 0);
BusA : in std_logic_vector(7 downto 0);
BusB : in std_logic_vector(7 downto 0);
F_In : in std_logic_vector(7 downto 0);
Q : out std_logic_vector(7 downto 0);
F_Out : out std_logic_vector(7 downto 0)
);
end component;
end;

View File

@@ -1,114 +0,0 @@
-- ****
-- T80(b) core. In an effort to merge and maintain bug fixes ....
--
--
-- Ver 300 started tidyup
-- MikeJ March 2005
-- Latest version from www.fpgaarcade.com (original www.opencores.org)
--
-- ****
--
-- T80 Registers, technology independent
--
-- Version : 0244
--
-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org)
--
-- 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 SOFTWARE 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.
--
-- Please report bugs to the author, but before you do so, please
-- make sure that this is not a derivative work and that
-- you have the latest version of this file.
--
-- The latest version of this file can be found at:
-- http://www.opencores.org/cvsweb.shtml/t51/
--
-- Limitations :
--
-- File history :
--
-- 0242 : Initial release
--
-- 0244 : Changed to single register file
--
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity T80_Reg is
port(
Clk : in std_logic;
CEN : in std_logic;
WEH : in std_logic;
WEL : in std_logic;
AddrA : in std_logic_vector(2 downto 0);
AddrB : in std_logic_vector(2 downto 0);
AddrC : in std_logic_vector(2 downto 0);
DIH : in std_logic_vector(7 downto 0);
DIL : in std_logic_vector(7 downto 0);
DOAH : out std_logic_vector(7 downto 0);
DOAL : out std_logic_vector(7 downto 0);
DOBH : out std_logic_vector(7 downto 0);
DOBL : out std_logic_vector(7 downto 0);
DOCH : out std_logic_vector(7 downto 0);
DOCL : out std_logic_vector(7 downto 0)
);
end T80_Reg;
architecture rtl of T80_Reg is
type Register_Image is array (natural range <>) of std_logic_vector(7 downto 0);
signal RegsH : Register_Image(0 to 7);
signal RegsL : Register_Image(0 to 7);
begin
process (Clk)
begin
if Clk'event and Clk = '1' then
if CEN = '1' then
if WEH = '1' then
RegsH(to_integer(unsigned(AddrA))) <= DIH;
end if;
if WEL = '1' then
RegsL(to_integer(unsigned(AddrA))) <= DIL;
end if;
end if;
end if;
end process;
DOAH <= RegsH(to_integer(unsigned(AddrA)));
DOAL <= RegsL(to_integer(unsigned(AddrA)));
DOBH <= RegsH(to_integer(unsigned(AddrB)));
DOBL <= RegsL(to_integer(unsigned(AddrB)));
DOCH <= RegsH(to_integer(unsigned(AddrC)));
DOCL <= RegsL(to_integer(unsigned(AddrC)));
end;

View File

@@ -1,48 +0,0 @@
-------------------------------------------------------------------------------
--
-- Delta-Sigma DAC
--
-- Refer to Xilinx Application Note XAPP154.
--
-- This DAC requires an external RC low-pass filter:
--
-- dac_o 0---XXXXX---+---0 analog audio
-- 3k3 |
-- === 4n7
-- |
-- GND
--
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity dac is
generic (
C_bits : integer := 8
);
port (
clk_i : in std_logic;
res_n_i : in std_logic;
dac_i : in std_logic_vector(C_bits-1 downto 0);
dac_o : out std_logic
);
end dac;
architecture rtl of dac is
signal sig_in: unsigned(C_bits downto 0);
begin
seq: process(clk_i, res_n_i)
begin
if res_n_i = '0' then
sig_in <= to_unsigned(2**C_bits, sig_in'length);
dac_o <= '0';
elsif rising_edge(clk_i) then
-- not dac_i(C_bits-1) effectively adds 0x8..0 to dac_i
--sig_in <= sig_in + unsigned(sig_in(C_bits) & (not dac_i(C_bits-1)) & dac_i(C_bits-2 downto 0));
sig_in <= sig_in + unsigned(sig_in(C_bits) & dac_i);
dac_o <= sig_in(C_bits);
end if;
end process seq;
end rtl;

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 SP4.26"
set_global_assignment -name LAST_QUARTUS_VERSION 13.1
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:rtl/build_id.tcl"

View File

@@ -44,22 +44,6 @@ set_global_assignment -name PROJECT_CREATION_TIME_DATE "21:27:39 NOVEMBER 20, 2
set_global_assignment -name LAST_QUARTUS_VERSION 13.1
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:rtl/build_id.tcl"
set_global_assignment -name SYSTEMVERILOG_FILE rtl/westerngun_mist.sv
set_global_assignment -name VHDL_FILE rtl/invaders.vhd
set_global_assignment -name VHDL_FILE rtl/mw8080.vhd
set_global_assignment -name VHDL_FILE rtl/invaders_audio.vhd
set_global_assignment -name SYSTEMVERILOG_FILE rtl/westerngun_memory.sv
set_global_assignment -name VHDL_FILE rtl/westerngun_overlay.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/T80/T8080se.vhd
set_global_assignment -name VHDL_FILE rtl/T80/T80_Reg.vhd
set_global_assignment -name VHDL_FILE rtl/T80/T80_Pack.vhd
set_global_assignment -name VHDL_FILE rtl/T80/T80_MCode.vhd
set_global_assignment -name VHDL_FILE rtl/T80/T80_ALU.vhd
set_global_assignment -name VHDL_FILE rtl/T80/T80.vhd
set_global_assignment -name VHDL_FILE rtl/pll.vhd
set_global_assignment -name QIP_FILE ../../../common/mist/mist.qip
# Pin & Location Assignments
# ==========================
@@ -169,4 +153,15 @@ set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -
set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
set_global_assignment -name SYSTEMVERILOG_FILE rtl/westerngun_mist.sv
set_global_assignment -name VHDL_FILE rtl/invaders.vhd
set_global_assignment -name VHDL_FILE rtl/mw8080.vhd
set_global_assignment -name VHDL_FILE rtl/invaders_audio.vhd
set_global_assignment -name SYSTEMVERILOG_FILE rtl/westerngun_memory.sv
set_global_assignment -name VHDL_FILE rtl/westerngun_overlay.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_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top

View File

@@ -274,4 +274,5 @@ set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_nCS
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_CKE
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_CLK
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to UART_RXD
set_global_assignment -name TEXT_FILE mister.txt
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top

View File

@@ -0,0 +1,424 @@
//============================================================================
// AY-3-8500 for MiSTer
//
// Copyright (C) 2019 Cole Johnson
//
// This program 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 2 of the License, or (at your option)
// any later version.
//
// This program 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, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//============================================================================
module emu
(
//Master input clock
input CLK_50M,
//Async reset from top-level module.
//Can be used as initial reset.
input RESET,
//Must be passed to hps_io module
inout [44:0] HPS_BUS,
//Base video clock. Usually equals to CLK_SYS.
output VGA_CLK,
//Multiple resolutions are supported using different VGA_CE rates.
//Must be based on CLK_VIDEO
output VGA_CE,
output [7:0] VGA_R,
output [7:0] VGA_G,
output [7:0] VGA_B,
output VGA_HS,
output VGA_VS,
output VGA_DE, // = ~(VBlank | HBlank)
//Base video clock. Usually equals to CLK_SYS.
output HDMI_CLK,
//Multiple resolutions are supported using different HDMI_CE rates.
//Must be based on CLK_VIDEO
output HDMI_CE,
output [7:0] HDMI_R,
output [7:0] HDMI_G,
output [7:0] HDMI_B,
output HDMI_HS,
output HDMI_VS,
output HDMI_DE, // = ~(VBlank | HBlank)
output [1:0] HDMI_SL, // scanlines fx
//Video aspect ratio for HDMI. Most retro systems have ratio 4:3.
output [7:0] HDMI_ARX,
output [7:0] HDMI_ARY,
output LED_USER, // 1 - ON, 0 - OFF.
// b[1]: 0 - LED status is system status OR'd with b[0]
// 1 - LED status is controled solely by b[0]
// hint: supply 2'b00 to let the system control the LED.
output [1:0] LED_POWER,
output [1:0] LED_DISK,
output [15:0] AUDIO_L,
output [15:0] AUDIO_R,
output AUDIO_S // 1 - signed audio samples, 0 - unsigned
);
assign LED_USER = 0;
assign LED_DISK = 0;
assign LED_POWER = 0;
assign HDMI_ARX = status[1] ? 8'd16 : 8'd4;
assign HDMI_ARY = status[1] ? 8'd9 : 8'd3;
`include "build_id.v"
localparam CONF_STR = {
"AY-3-8500;;",
"-;",
"O1,Aspect Ratio,Original,Wide;",
"O35,Scandoubler Fx,None,HQ2x,CRT 25%,CRT 50%,CRT 75%;",
"-;",
"O6,Invisiball,OFF,ON;",
"O7A,Color Pallette,Mono,Greyscale,RGB1,RGB2,Field,Ice,Christmas,Marksman,Las Vegas;",
"-;",
"R0,Reset;",
"V,v2",`BUILD_DATE
};
//////////////////// CLOCKS ///////////////////
wire clk_sys, clk_vid, clk_off;
wire pll_locked;
pll pll
(
.refclk(CLK_50M),
.rst(0),
.outclk_0(clk_sys), // 7.159mhz
.outclk_1(clk_vid), // 28.636mhz
.locked(pll_locked)
);
///////////////////////IN+OUT///////////////////////
wire [31:0] status;
wire [1:0] buttons;
wire forced_scandoubler;
wire ioctl_download;
wire ioctl_wr;
wire [24:0] ioctl_addr;
wire [7:0] ioctl_dout;
wire [10:0] ps2_key;
wire [15:0] joystick_0, joystick_1;
wire [15:0] joy = joystick_0;
wire [15:0] joy2 = joystick_1;
wire [15:0] joystick_analog_0;
wire [15:0] joystick_analog_1;
reg initReset_n = 0;
always @(posedge clk_sys) begin
reg old_download = 0;
old_download <= ioctl_download;
if(old_download & ~ioctl_download) initReset_n <= 1;
end
hps_io #(.STRLEN($size(CONF_STR)>>3)) hps_io
(
.clk_sys(clk_sys),
.HPS_BUS(HPS_BUS),
.conf_str(CONF_STR),
.buttons(buttons),
.status(status),
.forced_scandoubler(forced_scandoubler),
.ioctl_download(ioctl_download),
.ioctl_wr(ioctl_wr),
.ioctl_addr(ioctl_addr),
.ioctl_dout(ioctl_dout),
.joystick_0(joystick_0),
.joystick_1(joystick_1),
.joystick_analog_0(joystick_analog_0),
.joystick_analog_1(joystick_analog_1),
.ps2_key(ps2_key)
);
wire pressed = ps2_key[9];
wire [8:0] code = ps2_key[8:0];
always @(posedge clk_sys) begin
reg old_state;
old_state <= ps2_key[10];
if(old_state != ps2_key[10]) begin
casex(code)
'h01D: btnP1Up <= pressed; //W
'h01B: btnP1Down <= pressed; //S
'hX75: btnP2Up <= pressed; // up
'hX72: btnP2Down <= pressed; // down
'h029: btnServe <= pressed; // space
'h016: gameBtns[0:0] <= pressed; // 1
'h01E: gameBtns[1:1] <= pressed; // 2
'h026: gameBtns[2:2] <= pressed; // 3
'h025: gameBtns[3:3] <= pressed; // 4
'h02E: gameBtns[4:4] <= pressed; // 5
'h036: gameBtns[5:5] <= pressed; // 6
'h03D: gameBtns[6:6] <= pressed; // 7
'h01A: btnAngle <= pressed; // Z
'h022: btnSpeed <= pressed; // X
'h021: btnSize <= pressed; // C
'h02A: btnAutoserve <= pressed; // V
'h03A: btnMiss <= pressed; //M
'h033: btnHit <= pressed; //H
'h02D: btnReset <= pressed; //R
endcase
end
end
reg btnP1Up = 0;
reg btnP1Down = 0;
reg btnP2Up = 0;
reg btnP2Down = 0;
reg btnServe = 0;
reg btnReset = 0;
reg [7:0] gameBtns = 0;
reg [7:0] gameSelect = 7'b0000001;//Default to Tennis
reg btnAngle, btnAngleOld = 0;
reg btnSpeed, btnSpeedOld = 0;
reg btnSize, btnSizeOld = 0;
reg btnAutoserve, btnAutoserveOld = 0;
reg btnMiss = 0;
reg btnHit = 0;
reg [10:0] toggleInputs = 0;
reg angle = 0;
reg speed = 0;
reg size = 0;
reg autoserve = 0;
//Handle button toggling
always @(posedge clk_sys) begin
btnAngleOld <= btnAngle;
btnSpeedOld <= btnSpeed;
btnSizeOld <= btnSize;
btnAutoserveOld <= btnAutoserve;
if(gameBtns[0:0])
gameSelect = 7'b0000001;//Tennis
else if(gameBtns[1:1])
gameSelect = 7'b0000010;//Soccer
else if(gameBtns[2:2])
gameSelect = 7'b0000100;//Handicap (using a dummy bit)
else if(gameBtns[3:3])
gameSelect = 7'b0001000;//Squash
else if(gameBtns[4:4])
gameSelect = 7'b0010000;//Practice
else if(gameBtns[5:5])
gameSelect = 7'b0100000;//Rifle 1
else if(gameBtns[6:6])
gameSelect = 7'b1000000;//Rifle 2
if(btnAngle & !btnAngleOld)
angle <= !angle;
if(btnSpeed & !btnSpeedOld)
speed <= !speed;
if(btnSize & !btnSizeOld)
size <= !size;
if(btnAutoserve & !btnAutoserveOld)
autoserve <= !autoserve;
end
/////////////////Paddle Emulation//////////////////
wire [4:0] paddleMoveSpeed = speed ? 8 : 5;//Faster paddle movement when ball speed is high
reg [8:0] player1pos = 8'd128;
reg [8:0] player2pos = 8'd128;
reg [8:0] player1cap = 0;
reg [8:0] player2cap = 0;
reg hsOld = 0;
reg vsOld = 0;
always @(posedge clk_sys) begin
hsOld <= hs;
vsOld <= vs;
if(vs & !vsOld) begin
player1cap <= player1pos;
player2cap <= player2pos;
if(btnP1Up & player1pos>0)
player1pos <= player1pos - paddleMoveSpeed;
else if(btnP1Down & player1pos<8'hFF)
player1pos <= player1pos + paddleMoveSpeed;
if(btnP2Up & player2pos>0)
player2pos <= player2pos - paddleMoveSpeed;
else if(btnP2Down & player2pos < 8'hFF)
player2pos <= player2pos + paddleMoveSpeed;
end
else if(hs & !hsOld) begin
if(player1cap!=0)
player1cap <= player1cap - 1;
if(player2cap!=0)
player2cap <= player2cap - 1;
end
end
//Signal outputs (active-high except for sync)
wire audio;
wire rpOut;
wire lpOut;
wire ballOut;
wire scorefieldOut;
wire syncH;
wire syncV;
wire isBlanking;
//Misc pins
wire hitIn = (gameBtns[5:5] | gameBtns[6:6]) ? btnHit : audio;
//Still unknown why example schematic instructs connecting hitIn pin to audio during ball games
wire shotIn = (gameBtns[5:5] | gameBtns[6:6]) ? (btnHit | btnMiss) : 1;
wire lpIN = (player1cap == 0);
wire rpIN = (player2cap == 0);
wire lpIN_reset;//We don't use these signals, instead the VSYNC signal (identical) is directly accessed
wire rpIN_reset;
wire chipReset = btnReset | status[0];
ay38500NTSC the_chip
(
.clk(clk_sys),
.superclock(CLK_50M),
.reset(!chipReset),
.pinRPout(rpOut),
.pinLPout(lpOut),
.pinBallOut(ballOut),
.pinSFout(scorefieldOut),
.syncH(syncH),
.syncV(syncV),
.pinSound(audio),
.pinManualServe(!(autoserve | btnServe)),
.pinBallAngle(!angle),
.pinBatSize(!size),
.pinBallSpeed(!speed),
.pinPractice(!gameSelect[4:4]),
.pinSquash(!gameSelect[3:3]),
.pinSoccer(!gameSelect[1:1]),
.pinTennis(!gameSelect[0:0]),
.pinRifle1(!gameSelect[5:5]),
.pinRifle2(!gameSelect[6:6]),
.pinHitIn(hitIn),
.pinShotIn(shotIn),
.pinLPin(lpIN),
.pinRPin(rpIN)
);
/////////////////////VIDEO//////////////////////
wire hs = !syncH;
wire vs = !syncV;
wire hblank = !hs;
wire vblank = !vs;
wire [3:0] r,g,b;
wire showBall = !status[6:6] | (ballHide>0);
reg [5:0] ballHide = 0;
reg audioOld = 0;
always @(posedge clk_sys) begin
audioOld <= audio;
if(!audioOld & audio)
ballHide <= 5'h1F;
else if(vs & !vsOld & ballHide!=0)
ballHide <= ballHide - 1;
end
reg [12:0] colorOut = 0;
always @(posedge clk_sys) begin
if(ballOut & showBall) begin
case(status[11:7])
'h0: colorOut <= 12'hFFF;//Mono
'h1: colorOut <= 12'hFFF;//Greyscale
'h2: colorOut <= 12'hF00;//RGB1
'h3: colorOut <= 12'hFFF;//RGB2
'h4: colorOut <= 12'h000;//Field
'h5: colorOut <= 12'h000;//Ice
'h6: colorOut <= 12'hFFF;//Christmas
'h7: colorOut <= 12'hFFF;//Marksman
'h8: colorOut <= 12'hFF0;//Las Vegas
endcase
end
else if(lpOut) begin
case(status[11:7])
'h0: colorOut <= 12'hFFF;//Mono
'h1: colorOut <= 12'hFFF;//Greyscale
'h2: colorOut <= 12'h0F0;//RGB1
'h3: colorOut <= 12'h00F;//RGB2
'h4: colorOut <= 12'hF00;//Field
'h5: colorOut <= 12'hF00;//Ice
'h6: colorOut <= 12'hF00;//Christmas
'h7: colorOut <= 12'hFF0;//Marksman
'h8: colorOut <= 12'hFF0;//Las Vegas
endcase
end
else if(rpOut) begin
case(status[11:7])
'h0: colorOut <= 12'hFFF;//Mono
'h1: colorOut <= 12'h000;//Greyscale
'h2: colorOut <= 12'h0F0;//RGB1
'h3: colorOut <= 12'hF00;//RGB2
'h4: colorOut <= 12'h00F;//Field
'h5: colorOut <= 12'h030;//Ice
'h6: colorOut <= 12'h030;//Christmas
'h7: colorOut <= 12'h000;//Marksman
'h8: colorOut <= 12'hF0F;//Las Vegas
endcase
end
else if(scorefieldOut) begin
case(status[11:7])
'h0: colorOut <= 12'hFFF;//Mono
'h1: colorOut <= 12'hFFF;//Greyscale
'h2: colorOut <= 12'h00F;//RGB1
'h3: colorOut <= 12'h0F0;//RGB2
'h4: colorOut <= 12'hFFF;//Field
'h5: colorOut <= 12'h55F;//Ice
'h6: colorOut <= 12'hFFF;//Christmas
'h7: colorOut <= 12'hFFF;//Marksman
'h8: colorOut <= 12'hF90;//Las Vegas
endcase
end
else begin
case(status[11:7])
'h0: colorOut <= 12'h000;//Mono
'h1: colorOut <= 12'h999;//Greyscale
'h2: colorOut <= 12'h000;//RGB1
'h3: colorOut <= 12'h000;//RGB2
'h4: colorOut <= 12'h4F4;//Field
'h5: colorOut <= 12'hCCF;//Ice
'h6: colorOut <= 12'h000;//Christmas
'h7: colorOut <= 12'h0D0;//Marksman
'h8: colorOut <= 12'h000;//Las Vegas
endcase
end
end
arcade_fx #(375, 12) arcade_video
(
.*,
.clk_video(clk_vid),
.ce_pix(clk_sys),
.RGB_in(colorOut),
.HBlank(hblank),
.VBlank(vblank),
.HSync(hs),
.VSync(vs),
.fx(status[5:3])
//.no_rotate(status[2])
);
////////////////////AUDIO////////////////////////
assign AUDIO_L = {audio, 15'b0};
assign AUDIO_R = AUDIO_L;
assign AUDIO_S = 0;
endmodule

View File

@@ -14,25 +14,21 @@ module APF_TV_Fun_MiST
input SPI_DI,
input SPI_SS2,
input SPI_SS3,
input CONF_DATA0,
input UART_RXD,
output UART_TXD
input CONF_DATA0
);
`include "rtl\build_id.v"
localparam CONF_STR = {
"APF_TV_fun;;",
// "O1,Sound ,On,Off;",
"O23,Game ,Tennis,Soccer,Squash,Practice;",
// "O13,Game ,Hidden,Tennis,Soccer,Squash,Practice,gameRifle1,gameRifle2;",
"O4,Serve ,Auto,Manual;",
"O13,Game ,Tennis,Soccer,Handicap,Squash,Practice,Rifle1,Rifle2;",
"O4,Serve ,Manual,Auto;",
"O5,Ball Angle ,20deg,40deg;", //check
"O6,Bat Size ,Small,Big;", //check
"O7,Ball Speed ,Fast,Slow;",
"T8,Start;",
"T9,Reset;",
"O7,Ball Speed ,Fast,Slow;", //check
"O8,Invisiball,OFF,ON;",
"O9C,Color Pallette,Mono,Greyscale,RGB1,RGB2,Field,Ice,Christmas,Marksman,Las Vegas;",
"T0,Reset;",
"V,v1.00.",`BUILD_DATE
};
@@ -50,8 +46,6 @@ pll pll(
wire [31:0] status;
wire [1:0] buttons;
wire [1:0] switches;
wire [15:0] kbjoy;
wire [10:0] ps2_key;
wire [7:0] joystick_0;
wire [7:0] joystick_1;
wire scandoubler_disable;
@@ -60,81 +54,187 @@ wire ps2_kbd_clk, ps2_kbd_data;
wire audio;
wire hs, vs;
wire vid_play, vid_RP, vid_LP, vid_Ball;
wire video = vid_play | vid_RP | vid_LP | vid_Ball;
wire gameTennis;
wire gameSoccer;
wire gameSquash;
wire gamePractice;
wire gameRifle1;
wire gameRifle2;
wire m_left, m_right;
wire LPin, RPin, Rifle1, Rifle2;
reg [7:0] gameSelect = 7'b0000001;//Default to Tennis
always @(*) begin
case (status[3:2])
// 3'b001 : begin gameTennis <= 0; gameSoccer <= 1; gameSquash <= 1; gamePractice <= 1; gameRifle1 <= 1; gameRifle2 <= 1; end
// 3'b010 : begin gameTennis <= 1; gameSoccer <= 0; gameSquash <= 1; gamePractice <= 1; gameRifle1 <= 1; gameRifle2 <= 1; end
// 3'b011 : begin gameTennis <= 1; gameSoccer <= 1; gameSquash <= 0; gamePractice <= 1; gameRifle1 <= 1; gameRifle2 <= 1; end
// 3'b100 : begin gameTennis <= 1; gameSoccer <= 1; gameSquash <= 1; gamePractice <= 0; gameRifle1 <= 1; gameRifle2 <= 1; end
// 3'b101 : begin gameTennis <= 1; gameSoccer <= 1; gameSquash <= 1; gamePractice <= 1; gameRifle1 <= 0; gameRifle2 <= 1; end
// 3'b111 : begin gameTennis <= 1; gameSoccer <= 1; gameSquash <= 1; gamePractice <= 1; gameRifle1 <= 1; gameRifle2 <= 0; end
// default : begin gameTennis <= 1; gameSoccer <= 1; gameSquash <= 1; gamePractice <= 1; gameRifle1 <= 1; gameRifle2 <= 1; end
2'b01 : begin gameTennis <= 1; gameSoccer <= 0; gameSquash <= 1; gamePractice <= 1; gameRifle1 <= 1; gameRifle2 <= 1; end
2'b10 : begin gameTennis <= 1; gameSoccer <= 1; gameSquash <= 0; gamePractice <= 1; gameRifle1 <= 1; gameRifle2 <= 1; end
2'b11 : begin gameTennis <= 1; gameSoccer <= 1; gameSquash <= 1; gamePractice <= 0; gameRifle1 <= 1; gameRifle2 <= 1; end
default : begin gameTennis <= 0; gameSoccer <= 1; gameSquash <= 1; gamePractice <= 1; gameRifle1 <= 1; gameRifle2 <= 1; end
always @(clk_16) begin
case (status[3:1])
3'b000 : gameSelect = 7'b0000001;//Tennis
3'b001 : gameSelect = 7'b0000010;//Soccer
3'b010 : gameSelect = 7'b0000100;//Handicap (using a dummy bit)
3'b011 : gameSelect = 7'b0001000;//Squash
3'b100 : gameSelect = 7'b0010000;//Practice
3'b101 : gameSelect = 7'b0100000;//Rifle 1
3'b110 : gameSelect = 7'b1000000;//Rifle 1
default : gameSelect = 7'b0000001;//Tennis
endcase
end
/////////////////Paddle Emulation//////////////////
wire [4:0] paddleMoveSpeed = status[7] ? 8 : 5;//Faster paddle movement when ball speed is high
reg [8:0] player1pos = 8'd128;
reg [8:0] player2pos = 8'd128;
reg [8:0] player1cap = 0;
reg [8:0] player2cap = 0;
reg hsOld = 0;
reg vsOld = 0;
always @(posedge clk_16) begin
hsOld <= hs;
vsOld <= vs;
if(vs & !vsOld) begin
player1cap <= player1pos;
player2cap <= player2pos;
if(m_up & player1pos>0)
player1pos <= player1pos - paddleMoveSpeed;
else if(m_down & player1pos<8'hFF)
player1pos <= player1pos + paddleMoveSpeed;
if(m_up2 & player2pos>0)
player2pos <= player2pos - paddleMoveSpeed;
else if(m_down2 & player2pos < 8'hFF)
player2pos <= player2pos + paddleMoveSpeed;
end
else if(hs & !hsOld) begin
if(player1cap!=0)
player1cap <= player1cap - 1;
if(player2cap!=0)
player2cap <= player2cap - 1;
end
end
wire [3:0] r,g,b;
wire hb = !hs;
wire vb = !vs;
wire blankn = ~(hb | vb);
wire showBall = !status[8] | (ballHide>0);
reg [5:0] ballHide = 0;
reg audioOld = 0;
always @(clk_16) begin
audioOld <= audio;
if(!audioOld & audio)
ballHide <= 5'h1F;
else if(vs & !vsOld & ballHide!=0)
ballHide <= ballHide - 1;
end
reg [12:0] colorOut = 0;
always @(posedge clk_16) begin
if(vid_Ball & showBall) begin
case(status[13:9])
'h0: colorOut <= 12'hFFF;//Mono
'h1: colorOut <= 12'hFFF;//Greyscale
'h2: colorOut <= 12'hF00;//RGB1
'h3: colorOut <= 12'hFFF;//RGB2
'h4: colorOut <= 12'h000;//Field
'h5: colorOut <= 12'h000;//Ice
'h6: colorOut <= 12'hFFF;//Christmas
'h7: colorOut <= 12'hFFF;//Marksman
'h8: colorOut <= 12'hFF0;//Las Vegas
endcase
end
else if(vid_LP) begin
case(status[13:9])
'h0: colorOut <= 12'hFFF;//Mono
'h1: colorOut <= 12'hFFF;//Greyscale
'h2: colorOut <= 12'h0F0;//RGB1
'h3: colorOut <= 12'h00F;//RGB2
'h4: colorOut <= 12'hF00;//Field
'h5: colorOut <= 12'hF00;//Ice
'h6: colorOut <= 12'hF00;//Christmas
'h7: colorOut <= 12'hFF0;//Marksman
'h8: colorOut <= 12'hFF0;//Las Vegas
endcase
end
else if(vid_RP) begin
case(status[13:9])
'h0: colorOut <= 12'hFFF;//Mono
'h1: colorOut <= 12'h000;//Greyscale
'h2: colorOut <= 12'h0F0;//RGB1
'h3: colorOut <= 12'hF00;//RGB2
'h4: colorOut <= 12'h00F;//Field
'h5: colorOut <= 12'h030;//Ice
'h6: colorOut <= 12'h030;//Christmas
'h7: colorOut <= 12'h000;//Marksman
'h8: colorOut <= 12'hF0F;//Las Vegas
endcase
end
else if(vid_play) begin
case(status[13:9])
'h0: colorOut <= 12'hFFF;//Mono
'h1: colorOut <= 12'hFFF;//Greyscale
'h2: colorOut <= 12'h00F;//RGB1
'h3: colorOut <= 12'h0F0;//RGB2
'h4: colorOut <= 12'hFFF;//Field
'h5: colorOut <= 12'h55F;//Ice
'h6: colorOut <= 12'hFFF;//Christmas
'h7: colorOut <= 12'hFFF;//Marksman
'h8: colorOut <= 12'hF90;//Las Vegas
endcase
end
else begin
case(status[13:9])
'h0: colorOut <= 12'h000;//Mono
'h1: colorOut <= 12'h999;//Greyscale
'h2: colorOut <= 12'h000;//RGB1
'h3: colorOut <= 12'h000;//RGB2
'h4: colorOut <= 12'h4F4;//Field
'h5: colorOut <= 12'hCCF;//Ice
'h6: colorOut <= 12'h000;//Christmas
'h7: colorOut <= 12'h0D0;//Marksman
'h8: colorOut <= 12'h000;//Las Vegas
endcase
end
end
wire hitIn;// = (gameBtns[5:5] | gameBtns[6:6]) ? btnHit : audio;
//Still unknown why example schematic instructs connecting hitIn pin to audio during ball games
wire shotIn;// = (gameBtns[5:5] | gameBtns[6:6]) ? (btnHit | btnMiss) : 1;
wire LPin = (player1cap == 0);
wire RPin = (player2cap == 0);
wire ltest;
ay38500NTSC ay38500NTSC(
.clk(clk_2),
.reset(~(buttons[1] | status[0] | status[9])),
.superclock(CLOCK_27),
.reset(~(buttons[1] | status[0])),
.pinSound(audio),
//Video
.pinBallOut(vid_Ball),
.pinRPout(vid_RP),
.pinLPout(vid_LP),
.pinSFout(vid_play),
.vsync(vs),
.hsync(hs),
.pinSFout(vid_play),
.syncV(vs),
.syncH(hs),
//Menu Items
.pinManualServe(status[4] | joystick_0[4] | joystick_1[4]),
.pinManualServe(~(status[4] | m_fireA | m_fire2A)),
.pinBallAngle(status[5]),
.pinBatSize(status[6]),
.pinBallSpeed(status[7]),
//Game Select
.pinRifle1(1'b1),// ?
.pinRifle2(1'b1),// ?
.pinTennis(gameTennis),
.pinSoccer(gameSoccer),
.pinSquash(gameSquash),
.pinPractice(gamePractice),
.pinPractice(!gameSelect[4:4]),
.pinSquash(!gameSelect[3:3]),
.pinSoccer(!gameSelect[1:1]),
.pinTennis(!gameSelect[0:0]),
.pinRifle1(!gameSelect[5:5]),
.pinRifle2(!gameSelect[6:6]),
.pinShotIn(1),// todo
.pinHitIn(0),// todo
// .pinRifle1_DWN(Rifle1),// ?
// .pinTennis_DWN(Rifle2),// ?
// .pinRPin_DWN(1'b1),
.pinLPin_DWN(ltest),
.pinRPin(1'b1),// todo
.pinLPin(ltest ? UART_RXD : 1'b1)// todo
.pinHitIn(hitIn),
.pinShotIn(shotIn),
.pinLPin(LPin),
.pinRPin(RPin)
);
dac #(
.c_bits(8))
.c_bits(16))
dac (
.clk_i (clk_16 ),
.res_n_i (1 ),
.dac_i ({8{audio}} ),
.dac_i ({audio, 15'b0}),
.dac_o (AUDIO_L )
);
mist_video #(
.SD_HCNT_WIDTH(10),//wrong
.COLOR_DEPTH(1))
.SD_HCNT_WIDTH(12),//wrong
.COLOR_DEPTH(4))
mist_video(
.clk_sys(clk_16),
.SPI_DI(SPI_DI),
@@ -144,9 +244,9 @@ mist_video(
.ypbpr(ypbpr),
.HSync(~hs),
.VSync(~vs),
.R(video),
.G(video),
.B(video),
.R(colorOut[11:8]),
.G(colorOut[7:4]),
.B(colorOut[3:0]),
.VGA_HS(VGA_HS),
.VGA_VS(VGA_VS),
.VGA_R(VGA_R),
@@ -154,6 +254,11 @@ mist_video(
.VGA_B(VGA_B)
);
wire key_pressed;
wire key_extended;
wire [7:0] key_code;
wire key_strobe;
user_io #(.STRLEN(($size(CONF_STR)>>3))) user_io (
.clk_sys ( clk_16 ),
.conf_str ( CONF_STR ),
@@ -173,6 +278,24 @@ user_io #(.STRLEN(($size(CONF_STR)>>3))) user_io (
.status ( status )
);
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;
wire m_tilt, m_coin1, m_coin2, m_coin3, m_coin4, m_one_player, m_two_players, m_three_players, m_four_players;
arcade_inputs inputs (
.clk ( clk_16 ),
.key_strobe ( key_strobe ),
.key_pressed ( key_pressed ),
.key_code ( key_code ),
.joystick_0 ( joystick_0 ),
.joystick_1 ( joystick_1 ),
.rotate ( 1'b0 ),
.orientation ( 2'b10 ),
.joyswap ( 1'b0 ),
.oneplayer ( 1'b0 ),
.controls ( {m_tilt, m_coin4, m_coin3, m_coin2, m_coin1, m_four_players, m_three_players, m_two_players, m_one_player} ),
.player1 ( {m_fireF, m_fireE, m_fireD, m_fireC, m_fireB, m_fireA, m_up, m_down, m_left, m_right} ),
.player2 ( {m_fire2F, m_fire2E, m_fire2D, m_fire2C, m_fire2B, m_fire2A, m_up2, m_down2, m_left2, m_right2} )
);
endmodule

View File

@@ -1,15 +1,15 @@
/*
* Release 1 7/3/2019
* Release 2 12/23/2019 (2019/12/23 <- new year's resolution practice)
* Verilog description of the AY-3-8500 (NTSC varient)
* Generated from a transistor-level netlist by DLAET
* Some manual patches have been made (marked by comments)
*
* Thanks to Sean Riddle for decapping the speciman
* and to: Suverman, Erika, Ewen McNeill, and Dylan Lipsitz
* for supporting me on Patreon
* and to: Suverman, Erika, Ewen McNeill, Dylan Lipsitz, Ewen McNeill,
* Alan Steremberg, and JM Blandin for supporting me on Patreon
*/
`default_nettype none
/*verilator lint_off UNOPTFLAT */
module ay38500NTSC(
output pinRPout,
output pinLPout,
@@ -37,13 +37,15 @@ module ay38500NTSC(
input pinSquash,
input pinPractice,
input reset,
output vsync,
output hsync);
output syncH,//MC: split syncs were accessed
output syncV,
input superclock);
assign vsync = flop6;
assign hsync= !flop7;
assign pinRPout = !or28;
//wire pinLPin = counter3 > 50;
//wire pinRPin = counter3 > 70;
assign syncH = !flop7;
assign syncV = flop6;
assign pinRPout = !or28;//temp
assign pinLPout = !or38;
assign pinBallOut = !or2;
assign pinRPin_DWN = flop6;//MC: The ORs were bypassed
@@ -53,304 +55,249 @@ module ay38500NTSC(
assign pinRifle1_DWN = !or150;
assign pinTennis_DWN = !or211;
assign pinSFout = or212;
wire pulser0 = flop6;
wire pulser1 = (!or170 | pulser1_delay);
reg pulser0 = 0;//flop6;
reg pulser1 = 0;//(!or170 | pulser1_delay);
reg pulser0_delay = 0;
reg pulser1_delay = 0;
always @(negedge clk) begin
//MC: Pulsers always added manually
always @(posedge superclock) begin
pulser0_delay <= flop6;
pulser0 <= flop6 & !pulser0_delay;
pulser1_delay <= or170;
pulser1 <= or170 & !pulser1_delay;//was negedge
end
//MC: flop0 was tweaked
reg flop0 = 0;
always @(posedge clk) begin
always @(posedge superclock) begin
flop0 <= flop2;
end
reg flop1 = 0;
wire flop1_reset = !or213 | counter5_2268;
wire flop1_set = !or3 | !or6;
always @(posedge flop1_reset or posedge flop1_set) begin
if(flop1_reset)
always @(posedge superclock) begin
if(!or213 | counter5_2268)
flop1 <= 0;
else
else if(!or3 | !or6)
flop1 <= 1;
end
reg flop2 = 0;
wire flop2_reset = !or213 | counter4_2130;
wire flop2_set = !or18 | !or19;
always @(posedge flop2_reset or posedge flop2_set) begin
if(flop2_reset)
always @(posedge superclock) begin
if(!or213 | counter4_2130)
flop2 <= 0;
else
else if(!or18 | !or19)
flop2 <= 1;
end
reg flop3 = 0;
wire flop3_reset = !or4;
wire flop3_set = !pinManualServe & reset;//MC: set/reset priority have been reversed + reset added to flop3_set's OR
always @(posedge flop3_set or posedge flop3_reset) begin
if(flop3_set)
reg flop3 = 0;//MC: set/reset priority have been reversed + reset added to flop3_set's OR
always @(posedge superclock) begin
if(!pinManualServe)// | reset
flop3 <= 0;
else
else if(!or4)
flop3 <= 1;
end
reg flop4 = 0;
wire flop4_reset = !or16 | or24 | or27 | !or213;
wire flop4_set = !or15 | or23 | or22;
always @(posedge flop4_reset or posedge flop4_set) begin
if(flop4_reset)
always @(posedge superclock) begin
if(!or16 | or24 | or27 | !or213)
flop4 <= 0;
else
else if(!or15 | or23 | or22)
flop4 <= 1;
end
reg flop5 = 0;
wire flop5_reset = or27 | or22;
wire flop5_set = or24 | or23 | !or213;
always @(posedge flop5_reset or posedge flop5_set) begin
if(flop5_reset)
always @(posedge superclock) begin
if(or27 | or22)
flop5 <= 0;
else
else if(or24 | or23 | !or213)
flop5 <= 1;
end
reg flop6 = 0;
wire flop6_reset = !reset | !or88;
wire flop6_set = !or86;
always @(posedge flop6_reset or posedge flop6_set) begin
if(flop6_reset)
always @(posedge superclock) begin
if(!reset | !or88)
flop6 <= 0;
else
else if(!or86)
flop6 <= 1;
end
reg flop7 = 0;
wire flop7_reset = !reset | !or63;
wire flop7_set = !or74;
always @(posedge flop7_reset or posedge flop7_set) begin
if(flop7_reset)
always @(posedge superclock) begin
if(!reset | !or63)
flop7 <= 0;
else
else if(!or74)
flop7 <= 1;
end
reg flop8 = 0;
always @(negedge or8) begin
flop8 <= or55;
end
reg flop9 = 0;
always @(negedge or8) begin
flop9 <= !or49;
end
reg flop10 = 0;
always @(negedge or8) begin
flop10 <= or66;
end
reg flop11 = 0;
always @(negedge or8) begin
flop11 <= !or51;
reg or8_delay = 0;
always @(posedge superclock) begin
or8_delay <= or8;
if(!or8 & or8_delay) begin
flop8 <= or55;
flop9 <= !or49;
flop10 <= or66;
flop11 <= !or51;
end
end
reg flop12 = 0;
wire flop12_reset = !or92;
wire flop12_set = !or90;
always @(posedge flop12_reset or posedge flop12_set) begin
if(flop12_reset)
always @(posedge superclock) begin
if(!or92)
flop12 <= 0;
else
else if(!or90)
flop12 <= 1;
end
reg flop13 = 0;
wire flop13_reset = !or169;
wire flop13_set = !flop26 | !and18;
always @(posedge flop13_reset or posedge flop13_set) begin
if(flop13_reset)
always @(posedge superclock) begin
if(!or169)
flop13 <= 0;
else
else if(!flop26 | !and18)
flop13 <= 1;
end
reg flop14 = 0;
wire flop14_reset = !pulser1;
wire flop14_set = !and18;
always @(posedge flop14_reset or posedge flop14_set) begin
if(flop14_reset)
always @(posedge superclock) begin
if(pulser1)
flop14 <= 0;
else
else if(!and18)
flop14 <= 1;
end
reg flop15 = 0;
wire flop15_reset = !or135;
wire flop15_set = !or136;
always @(posedge flop15_reset or posedge flop15_set) begin
if(flop15_reset)
always @(posedge superclock) begin
if(!or135)
flop15 <= 0;
else
else if(!or136)
flop15 <= 1;
end
reg flop16 = 0;
wire flop16_reset = or144;
wire flop16_set = !and18;
always @(posedge flop16_reset or posedge flop16_set) begin
if(flop16_reset)
always @(posedge superclock) begin
if(or144)
flop16 <= 0;
else
else if(!and18)
flop16 <= 1;
end
reg flop17 = 0;
wire flop17_reset = or149;
wire flop17_set = or127 | !or153 | !or213;
always @(posedge flop17_reset or posedge flop17_set) begin
if(flop17_reset)
always @(posedge superclock) begin
if(or149)
flop17 <= 0;
else
else if(or127 | !or153 | !or213)
flop17 <= 1;
end
reg flop18 = 0;
wire flop18_reset = !reset;
wire flop18_set = !or193 | !or200;
always @(posedge flop18_reset or posedge flop18_set) begin
if(flop18_reset)
always @(posedge superclock) begin
if(!reset)
flop18 <= 0;
else
else if(!or193 | !or200)
flop18 <= 1;
end
reg flop19 = 0;
wire flop19_reset = !or155;
wire flop19_set = !and18;
always @(posedge flop19_reset or posedge flop19_set) begin
if(flop19_reset)
always @(posedge superclock) begin
if(!or155)
flop19 <= 0;
else
else if(!and18)
flop19 <= 1;
end
reg flop20 = 0;
wire flop20_reset = !or143;
wire flop20_set = !or142;
always @(posedge flop20_reset or posedge flop20_set) begin
if(flop20_reset)
always @(posedge superclock) begin
if(!or143)
flop20 <= 0;
else
else if(!or142)
flop20 <= 1;
end
reg flop21 = 0;
wire flop21_reset = or146;
wire flop21_set = !or138;
always @(posedge flop21_reset or posedge flop21_set) begin
if(flop21_reset)
always @(posedge superclock) begin
if(or146)
flop21 <= 0;
else
else if(!or138)
flop21 <= 1;
end
reg flop22 = 0;
always @(posedge or152) begin
flop22 <= flop21;
always @(posedge superclock) begin
if(or152)
flop22 <= flop21;
end
reg flop23 = 0;
wire flop23_reset = !or70;
wire flop23_set = !or68;
always @(posedge flop23_reset or posedge flop23_set) begin
if(flop23_reset)
always @(posedge superclock) begin
if(!or70)
flop23 <= 0;
else
else if(!or68)
flop23 <= 1;
end
reg flop24 = 0;
wire flop24_reset = !ripple_ctr9_2;
wire flop24_set = flop25;
always @(posedge flop24_reset or posedge flop24_set) begin
if(flop24_reset)
flop24 <= 0;
else
reg flop24 = 0;//MC: Set/Reset priority has been swapped
always @(posedge superclock) begin
if(flop25)
flop24 <= 1;
else if(!ripple_ctr9_2)
flop24 <= 0;
end
reg flop25 = 0;
wire flop25_reset = !ripple_ctr9_2 | flop24;
wire flop25_set = !or141;
always @(posedge flop25_reset or posedge flop25_set) begin
if(flop25_reset)
flop25 <= 0;
else
reg flop25 = 0;//MC: Set/Reset priority has been swapped
always @(posedge superclock) begin
if(!or141)
flop25 <= 1;
else if(!ripple_ctr9_2 | flop24)
flop25 <= 0;
end
reg flop26 = 0;
wire flop26_reset = !pinHitIn;
wire flop26_set = !and18;
always @(posedge flop26_reset or posedge flop26_set) begin
if(flop26_reset)
always @(posedge superclock) begin
if(!pinHitIn)
flop26 <= 0;
else
else if(!and18)
flop26 <= 1;
end
reg flop27 = 0;
wire flop27_reset = !or199;
wire flop27_set = !or166;
always @(posedge flop27_reset or posedge flop27_set) begin
if(flop27_reset)
always @(posedge superclock) begin
if(!or199)
flop27 <= 0;
else
else if(!or166)
flop27 <= 1;
end
reg flop28 = 0;
wire flop28_reset = !or124;
wire flop28_set = !or70;
always @(posedge flop28_reset or posedge flop28_set) begin
if(flop28_reset)
always @(posedge superclock) begin
if(!or124)
flop28 <= 0;
else
else if(!or70)
flop28 <= 1;
end
reg flop29 = 0;
wire flop29_reset = !or164;
wire flop29_set = !or199;
always @(posedge flop29_reset or posedge flop29_set) begin
if(flop29_reset)
always @(posedge superclock) begin
if(!or164)
flop29 <= 0;
else
else if(!or199)
flop29 <= 1;
end
reg flop30 = 0;
wire flop30_reset = !or199 | or205;
wire flop30_set = !reset;
always @(posedge flop30_reset or posedge flop30_set) begin
if(flop30_reset)
always @(posedge superclock) begin
if(!or199 | or205)
flop30 <= 0;
else
else if(!reset)
flop30 <= 1;
end
reg flop31 = 0;
wire flop31_reset = !or188;
wire flop31_set = !and18;
always @(posedge flop31_reset or posedge flop31_set) begin
if(flop31_reset)
always @(posedge superclock) begin
if(!or188)
flop31 <= 0;
else
else if(!and18)
flop31 <= 1;
end
reg flop32 = 0;
wire flop32_reset = !flop13 | !or155 | or144 | !pulser1;
wire flop32_set = !and18;
always @(posedge flop32_reset or posedge flop32_set) begin
if(flop32_reset)
always @(posedge superclock) begin
if(!flop13 | !or155 | or144 | pulser1)
flop32 <= 0;
else
else if(!and18)
flop32 <= 1;
end
reg flop33 = 0;
wire flop33_reset = !or193 | !or200 | !or205;
wire flop33_set = !or210;
always @(posedge flop33_reset or posedge flop33_set) begin
if(flop33_reset)
always @(posedge superclock) begin
if(!or193 | !or200 | !or205)
flop33 <= 0;
else
else if(!or210)
flop33 <= 1;
end
reg flop34 = 0;
wire flop34_reset = !or181;
wire flop34_set = !or177;
always @(posedge flop34_reset or posedge flop34_set) begin
if(flop34_reset)
always @(posedge superclock) begin
if(!or181)
flop34 <= 0;
else
else if(!or177)
flop34 <= 1;
end
reg flop35 = 0;
wire flop35_reset = !or168;
wire flop35_set = !or178;
always @(posedge flop35_reset or posedge flop35_set) begin
if(flop35_reset)
always @(posedge superclock) begin
if(!or168)
flop35 <= 0;
else
else if(!or178)
flop35 <= 1;
end
wire and0 = !or26 & !or147;
@@ -545,7 +492,7 @@ module ay38500NTSC(
wire or169 = flop26 | !pinHitIn;
wire or170 = !flop29 | flop27;
wire or171 = !or161 | !or158;
wire or172 = flop12 | !flop20 | ripple_ctr9_2;
wire or172 = flop12 | !flop20 | !ripple_ctr9_2;
wire or173 = !flop27 | or205 | flop18;
wire or174 = ripple_ctr10_2 | !or171 | flop34;
wire or175 = !or124 | !or70;
@@ -555,7 +502,7 @@ module ay38500NTSC(
wire or179 = !or205 | flop18 | !pinShotIn;
wire or180 = !flop7 | !counter3_2116;
wire or181 = !flop7 | !counter3_2021;
wire or182 = flop12 | !flop15 | ripple_ctr9_2;
wire or182 = flop12 | !flop15 | !ripple_ctr9_2;//172&182's Rin were not inverted
wire or183 = flop30 | !or179 | !or173;
wire or184 = !or160 | !or198 | !or174;
wire or185 = !or150 | !pinSoccer;
@@ -590,153 +537,179 @@ module ay38500NTSC(
wire or214 = pinSoccer | pinRifle2;
reg [5:0] shift_reg0 = 0;
reg [3:0] shift_reg0_spot = 0;
/* verilator lint_off WIDTH */
wire shift_reg0_104 = shift_reg0[shift_reg0_spot];
/* verilator lint_on WIDTH */
always @(negedge or145 or posedge flop24) begin
if(flop24) begin
reg sr0_delay = 0;
wire shift_reg0_104 = !shift_reg0[shift_reg0_spot] | !(counter2!=29 & counter2!=38);//Last two added as temporary patch to fix score width issue
always @(posedge superclock) begin
sr0_delay <= or145;
if(!flop24) begin
shift_reg0_spot <= 5;
shift_reg0[0:0] <= 0;
shift_reg0[1:1] <= !or115;
shift_reg0[2:2] <= !or116;
shift_reg0[3:3] <= !or114;
shift_reg0[4:4] <= 0;
shift_reg0[5:5] <= !or113;
end
else if(shift_reg0_spot!=0) begin
shift_reg0_spot <= shift_reg0_spot - 1;
else if(!or145 & sr0_delay) begin
if(shift_reg0_spot!=0) begin
shift_reg0_spot <= shift_reg0_spot - 1;
end
end
end
//MC: This block had to be manually changed
always @(posedge flop24) begin
shift_reg0[0:0] <= 1;
shift_reg0[1:1] <= or115;
shift_reg0[2:2] <= or116;
shift_reg0[3:3] <= or114;
shift_reg0[4:4] <= 1;
shift_reg0[5:5] <= or113;
end
//MC: All ripple counter outputs (except paddle ones) have inverted resets & outputs
reg [4:0] ripple_ctr0 = 0;
reg rc0_delay = 0;
wire ripple_ctr0_2 = !ripple_ctr0[0:0];
wire ripple_ctr0_3 = !ripple_ctr0[1:1];
wire ripple_ctr0_4 = !ripple_ctr0[2:2];
wire ripple_ctr0_5 = !ripple_ctr0[3:3];
always @(posedge or192 or negedge reset) begin
always @(posedge superclock) begin
rc0_delay <= or192;
if(!reset)
ripple_ctr0 <= 0;
else
else if(or192 & !rc0_delay)
ripple_ctr0 <= ripple_ctr0 + 1;
end
reg [4:0] ripple_ctr1 = 0;
reg rc1_delay = 0;
wire ripple_ctr1_2 = !ripple_ctr1[0:0];
wire ripple_ctr1_3 = !ripple_ctr1[1:1];
wire ripple_ctr1_4 = !ripple_ctr1[2:2];
wire ripple_ctr1_5 = !ripple_ctr1[3:3];
always @(posedge or183 or negedge reset) begin
always @(posedge superclock) begin
rc1_delay <= or183;
if(!reset)
ripple_ctr1 <= 0;
else
else if(or183 & !rc1_delay)
ripple_ctr1 <= ripple_ctr1 + 1;
end
reg [1:0] ripple_ctr2 = 0;
reg rc2_delay = 0;
wire ripple_ctr2_2 = !ripple_ctr2[0:0];
always @(negedge ripple_ctr10_2 or negedge or213) begin
always @(posedge superclock) begin
rc2_delay <= ripple_ctr10_2;
if(!or213)
ripple_ctr2 <= 0;
else
else if(!ripple_ctr10_2 & rc2_delay)
ripple_ctr2 <= ripple_ctr2 + 1;
end
reg [1:0] ripple_ctr3 = 0;
reg rc3_delay = 0;
wire ripple_ctr3_2 = !ripple_ctr3[0:0];
always @(negedge ripple_ctr2_2 or negedge or213) begin
always @(posedge superclock) begin
rc3_delay <= ripple_ctr2_2;
if(!or213)
ripple_ctr3 <= 0;
else
else if(!ripple_ctr2_2 & rc3_delay)
ripple_ctr3 <= ripple_ctr3 + 1;
end
reg [4:0] ripple_ctr4 = 0;
reg rc4_delay = 0;
wire ripple_ctr4_2 = !ripple_ctr4[0:0];
wire ripple_ctr4_3 = !ripple_ctr4[1:1];
wire ripple_ctr4_4 = !ripple_ctr4[2:2];
wire ripple_ctr4_5 = !ripple_ctr4[3:3];
always @(negedge or188 or posedge flop31) begin
always @(posedge superclock) begin
rc4_delay <= or188;
if(flop31)
ripple_ctr4 <= 0;
else
else if(!or188 & rc4_delay)
ripple_ctr4 <= ripple_ctr4 + 1;
end
reg [1:0] ripple_ctr5 = 0;
reg rc5_delay = 0;
wire ripple_ctr5_2 = !ripple_ctr5[0:0];
always @(negedge ripple_ctr3_2 or negedge reset) begin
always @(posedge superclock) begin
rc5_delay <= ripple_ctr3_2;
if(!reset)
ripple_ctr5 <= 0;
else
else if(!ripple_ctr3_2 & rc5_delay)
ripple_ctr5 <= ripple_ctr5 + 1;
end
reg [1:0] ripple_ctr6 = 0;
reg rc6_delay = 0;
wire ripple_ctr6_2 = !ripple_ctr6[0:0];
always @(negedge ripple_ctr5_2 or negedge reset) begin
always @(posedge superclock) begin
rc6_delay <= ripple_ctr5_2;
if(!reset)
ripple_ctr6 <= 0;
else
else if(!ripple_ctr5_2 & rc6_delay)
ripple_ctr6 <= ripple_ctr6 + 1;
end
reg [4:0] ripple_ctr7 = 0;
reg rc7_delay = 0;
wire ripple_ctr7_2 = ripple_ctr7[0:0];
wire ripple_ctr7_3 = ripple_ctr7[1:1];
wire ripple_ctr7_4 = ripple_ctr7[2:2];
wire ripple_ctr7_5 = ripple_ctr7[3:3];
always @(negedge or21 or posedge or14) begin
always @(posedge superclock) begin
rc7_delay <= or21;
if(or14)
ripple_ctr7 <= 0;
else
else if(!or21 & rc7_delay)
ripple_ctr7 <= ripple_ctr7 + 1;
end
reg [4:0] ripple_ctr8 = 0;
reg rc8_delay = 0;
wire ripple_ctr8_2 = ripple_ctr8[0:0];
wire ripple_ctr8_3 = ripple_ctr8[1:1];
wire ripple_ctr8_4 = ripple_ctr8[2:2];
wire ripple_ctr8_5 = ripple_ctr8[3:3];
always @(negedge or45 or posedge or48) begin
always @(posedge superclock) begin
rc8_delay <= or45;
if(or48)
ripple_ctr8 <= 0;
else
else if(!or45 & rc8_delay)
ripple_ctr8 <= ripple_ctr8 + 1;
end
reg [1:0] ripple_ctr9 = 0;
reg rc9_delay = 0;
wire ripple_ctr9_2 = !ripple_ctr9[0:0];
always @(negedge clk or negedge or213) begin
always @(posedge superclock) begin
rc9_delay <= clk;
if(!or213)
ripple_ctr9 <= 0;
else
else if(!clk & rc9_delay)
ripple_ctr9 <= ripple_ctr9 + 1;
end
reg [1:0] ripple_ctr10 = 0;
reg rc10_delay = 0;
wire ripple_ctr10_2 = !ripple_ctr10[0:0];
always @(posedge flop7 or negedge or213) begin
always @(posedge superclock) begin
rc10_delay <= flop7;
if(!or213)
ripple_ctr10 <= 0;
else
else if(flop7 & !rc10_delay)
ripple_ctr10 <= ripple_ctr10 + 1;
end
//MC: Add flop12 reset
reg [2:0] counter0 = 0;
reg c0_delay = 0;
wire counter0_2003 = (counter0==3);
always @(negedge flop7 or posedge flop12) begin
always @(posedge superclock) begin
c0_delay <= flop7;
if(flop12)
counter0 <= 0;
else if(counter0==3)
counter0 <= 0;
else
counter0 <= counter0 + 1;
else if(!flop7 & c0_delay) begin
if(counter0==3)//this was 6
counter0 <= 0;
else
counter0 <= counter0 + 1;
end
end
reg [3:0] counter1 = 0;
reg c1_delay = 0;
wire counter1_2005 = (counter1==5);
wire counter1_2003 = (counter1==3);
wire counter1_2006 = (counter1==6);
@@ -744,15 +717,19 @@ module ay38500NTSC(
wire counter1_2001 = (counter1==1);
wire counter1_2002 = (counter1==2);
wire counter1_2004 = (counter1==4);
always @(negedge counter0_2003 or posedge flop12) begin
always @(posedge superclock) begin
c1_delay <= counter0_2003;
if(flop12)
counter1 <= 0;
else if(counter1==6)
counter1 <= 0;
else
counter1 <= counter1 + 1;
else if(!counter0_2003 & c1_delay) begin
if(counter1==6)
counter1 <= 0;
else
counter1 <= counter1 + 1;
end
end
reg [7:0] counter2 = 0;
reg c2_delay = 0;
wire counter2_2038 = (counter2==38);
wire counter2_2033 = (counter2==33);
wire counter2_2029 = (counter2==29);
@@ -767,15 +744,19 @@ module ay38500NTSC(
wire counter2_2014 = (counter2==14);
wire counter2_2013 = (counter2==13);
wire counter2_2060 = (counter2==60);
always @(posedge ripple_ctr9_2 or posedge or57) begin
always @(posedge superclock) begin
c2_delay <= ripple_ctr9_2;
if(or57)
counter2 <= 0;
else if(counter2==126)
counter2 <= 0;
else
counter2 <= counter2 + 1;
else if(ripple_ctr9_2 & !c2_delay) begin
if(counter2==126)
counter2 <= 0;
else
counter2 <= counter2 + 1;
end
end
reg [8:0] counter3 = 0;
reg c3_delay = 0;
wire counter3_2129 = (counter3==129);
wire counter3_2131 = (counter3==131);
wire counter3_2117 = (counter3==117);
@@ -786,13 +767,16 @@ module ay38500NTSC(
wire counter3_2041 = (counter3==41);
wire counter3_2034 = (counter3==34);
wire counter3_2021 = (counter3==21);
always @(posedge ripple_ctr10_2 or posedge or58) begin
always @(posedge superclock) begin
c3_delay <= ripple_ctr10_2;
if(or58)
counter3 <= 0;
else if(counter3==216)
counter3 <= 0;
else
counter3 <= counter3 + 1;
else if(ripple_ctr10_2 & !c3_delay) begin
if(counter3==216)
counter3 <= 0;
else
counter3 <= counter3 + 1;
end
end
//MC: Multiple changes to jumping counters
reg [8:0] counter4 = 0;
@@ -801,23 +785,24 @@ module ay38500NTSC(
wire counter4_2130 = (counter4==129);
wire counter4_2125 = (counter4==125);
wire counter4_2128 = (counter4==128);
always @(posedge clk) begin
if(!reset | flop3) begin
always @(posedge superclock) begin
counter4_delay <= clk;
if(!reset) begin
counter4 <= 0;
counter4_jump <= 0;
end
else begin
else if(clk & !counter4_delay) begin
if(counter4==129) begin
counter4 <= !counter4_jump ? 2 : !or32 ? 0 : !or37 ? 1 : !or40 ? 4 : !or44 ? 3 : 0;//MC: 3 & 4 changed to 4 & 5
counter4 <= !counter4_jump ? 2 : !or32 ? 0 : !or37 ? 1 : !or40 ? 4 : !or44 ? 3 : 0;
counter4_jump <= 0;
end
else begin
counter4_delay <= pulser0;
if(!counter4_delay && pulser0)
counter4_jump <= 1;
else
counter4 <= counter4 + 1;
end
end
if(!reset | flop3)// | counter4==129)
counter4_jump <= 0;
else if(pulser0)
counter4_jump <= 1;
end
reg [9:0] counter5 = 0;
@@ -827,26 +812,26 @@ module ay38500NTSC(
wire counter5_2263 = (counter5==263);
wire counter5_2265 = (counter5==265);
wire counter5_2268 = (counter5==267);
always @(negedge flop7) begin
always @(posedge superclock) begin
counter5_delay <= flop7;
if(!reset) begin
counter5 <= 0;
counter5_jump <= 0;
end
else begin
if(counter5==267) begin//Values > non-jump must be increased by 4?
counter5 <= !counter5_jump ? 6 : !or59 ? 11 : !or9 ? 15 : !or10 ? 12 : !or62 ? 5 : !or61 ? 13 : !or11 ? 4 : !or12 ? 3 : !or60 ? 1 : 0;
else if(!flop7 & counter5_delay) begin//6-7-11-8-5-9-4-3-1-0
if(counter5==267) begin
counter5 <= !counter5_jump ? 6 : !or59 ? 7 : !or9 ? 11 : !or10 ? 8 : !or62 ? 5 : !or61 ? 9 : !or11 ? 4 : !or12 ? 3 : !or60 ? 1 : 0;
counter5_jump <= 0;
end
else begin
counter5_delay <= pulser0;
if(!counter5_delay && pulser0)
counter5_jump <= 1;
else
counter5 <= counter5 + 1;
end
end
if(!reset)// | counter5==267)
counter5_jump <= 0;
else if(pulser0)
counter5_jump <= 1;
end
wire mux0_100 = (!or78 & counter1_2001) | (!or77 & counter1_2002) | (!or76 & counter1_2004);
//MC: Some changes to this line
wire mux1_100 = (!or81 & counter1_2005) | (!or80 & counter1_2001) | (!or79 & counter1_2003) | counter1_2002 | counter1_2004;//constants had to be added manually
wire mux2_100 = (!or81 & counter1_2005) | (!or85 & counter1_2001) | (!or83 & counter1_2003) | (!or84 & counter1_2002) | (!or82 & counter1_2004);
endmodule
endmodule