diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/clean.bat b/Arcade_MiST/Custom Hardware/UltraTank_MiST/clean.bat new file mode 100644 index 00000000..b3b7c3b5 --- /dev/null +++ b/Arcade_MiST/Custom Hardware/UltraTank_MiST/clean.bat @@ -0,0 +1,37 @@ +@echo off +del /s *.bak +del /s *.orig +del /s *.rej +del /s *~ +rmdir /s /q db +rmdir /s /q incremental_db +rmdir /s /q output_files +rmdir /s /q simulation +rmdir /s /q greybox_tmp +rmdir /s /q hc_output +rmdir /s /q .qsys_edit +rmdir /s /q hps_isw_handoff +rmdir /s /q sys\.qsys_edit +rmdir /s /q sys\vip +cd sys +for /d %%i in (*_sim) do rmdir /s /q "%%~nxi" +cd .. +for /d %%i in (*_sim) do rmdir /s /q "%%~nxi" +del build_id.v +del c5_pin_model_dump.txt +del PLLJ_PLLSPE_INFO.txt +del /s *.qws +del /s *.ppf +del /s *.ddb +del /s *.csv +del /s *.cmp +del /s *.sip +del /s *.spd +del /s *.bsf +del /s *.f +del /s *.sopcinfo +del /s *.xml +del /s new_rtl_netlist +del /s old_rtl_netlist + +pause diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/EngineSound.vhd b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/EngineSound.vhd new file mode 100644 index 00000000..51056dcc --- /dev/null +++ b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/EngineSound.vhd @@ -0,0 +1,165 @@ +-- Motor sound generator for Kee Games Ultra Tank +-- This was originally created for Sprint 2 - Identical circuit +-- Similar circuits are used in a number of other games +-- (c) 2017 James Sweet +-- +-- Original circuit used a 555 configured as an astable oscillator with the frequency controlled by +-- a four bit binary value. The output of this oscillator drives a counter configured to produce an +-- irregular thumping simulating the sound of an engine. +-- +-- This is free software: you can redistribute +-- it and/or modify it under the terms of the GNU General +-- Public License as published by the Free Software +-- Foundation, either version 3 of the License, or (at your +-- option) any later version. +-- +-- This is distributed in the hope that it will +-- be useful, but WITHOUT ANY WARRANTY; without even the +-- implied warranty of MERCHANTABILITY or FITNESS FOR A +-- PARTICULAR PURPOSE. See the GNU General Public License +-- for more details. + +library IEEE; +use IEEE.STD_LOGIC_1164.all; +use IEEE.STD_LOGIC_ARITH.all; +use IEEE.STD_LOGIC_UNSIGNED.all; + +entity EngineSound is +generic( + constant Freq_tune : integer := 50 -- Value from 0-100 used to tune the overall engine sound frequency + ); +port( + Clk_6 : in std_logic; + Reset : in std_logic; + Ena_3k : in std_logic; + EngineData : in std_logic_vector(3 downto 0); + Motor : out std_logic_vector(5 downto 0) + ); +end EngineSound; + +architecture rtl of EngineSound is + +signal RPM_val : integer range 1 to 350; +signal Ramp_term_unfilt : integer range 1 to 80000; +signal Ramp_Count : integer range 0 to 80000; +signal Ramp_term : integer range 1 to 80000; +signal Freq_mod : integer range 0 to 400; +signal Motor_Clk : std_logic; + +signal Counter_A : std_logic; +signal Counter_B : unsigned(2 downto 0); +signal Counter_A_clk : std_logic; + +signal Motor_prefilter : unsigned(1 downto 0); +signal Motor_filter_t1 : unsigned(3 downto 0); +signal Motor_filter_t2 : unsigned(3 downto 0); +signal Motor_filter_t3 : unsigned(3 downto 0); +signal Motor_filtered : unsigned(5 downto 0); + + +begin + +-- The frequency of the oscillator is set by a 4 bit binary value controlled by the game CPU +-- in the real hardware this is a 555 coupled to a 4 bit resistor DAC used to pull the frequency. +-- The output of this DAC has a capacitor to smooth out the frequency variation. +-- The constants assigned to RPM_val can be tweaked to adjust the frequency curve + +Speed_select: process(Clk_6) +begin + if rising_edge(Clk_6) then + case EngineData is + when "0000" => RPM_val <= 280; + when "0001" => RPM_val <= 245; + when "0010" => RPM_val <= 230; + when "0011" => RPM_val <= 205; + when "0100" => RPM_val <= 190; + when "0101" => RPM_val <= 175; + when "0110" => RPM_val <= 160; + when "0111" => RPM_val <= 145; + when "1000" => RPM_val <= 130; + when "1001" => RPM_val <= 115; + when "1010" => RPM_val <= 100; + when "1011" => RPM_val <= 85; + when "1100" => RPM_val <= 70; + when "1101" => RPM_val <= 55; + when "1110" => RPM_val <= 40; + when "1111" => RPM_val <= 25; + end case; + end if; +end process; + + +-- There is a RC filter between the frequency control DAC and the 555 to smooth out the transitions between the +-- 16 possible states. We can simulate a reasonable approximation of that behavior using a linear slope which is +-- not truly accurate but should be close enough. +RC_filt: process(clk_6, ena_3k, ramp_term_unfilt) +begin + if rising_edge(clk_6) then + if ena_3k = '1' then + if ramp_term_unfilt > ramp_term then + ramp_term <= ramp_term + 10; + elsif ramp_term_unfilt = ramp_term then + ramp_term <= ramp_term; + else + ramp_term <= ramp_term - 8; + end if; + end if; + end if; +end process; + + +-- Ramp_term terminates the ramp count, the higher this value, the longer the ramp will count up and the lower +-- the frequency. RPM_val is multiplied by a constant which can be adjusted by changing the value of freq_tune +-- to simulate the function of the frequency adjustment pot in the original hardware. +ramp_term_unfilt <= ((200 - freq_tune) * RPM_val); + +-- Variable frequency oscillator roughly approximating the function of a 555 astable oscillator +Ramp_osc: process(clk_6) +begin + if rising_edge(clk_6) then + motor_clk <= '1'; + ramp_count <= ramp_count + 1; + if ramp_count > ramp_term then + ramp_count <= 0; + motor_clk <= '0'; + end if; + end if; +end process; + + +-- 7492 counter with XOR on two of the outputs creates lumpy engine sound from smooth pulse train +-- 7492 has two sections, one div-by-2 and one div-by-6. +Engine_counter: process(motor_clk, counter_A_clk, counter_B, reset) +begin + if reset = '1' then + Counter_B <= (others => '0'); + elsif rising_edge(motor_clk) then + Counter_B <= Counter_B + '1'; + end if; + Counter_A_clk <= Counter_B(0) xor Counter_B(2); + if reset = '1' then + Counter_A <= '0'; + elsif rising_edge(counter_A_clk) then + Counter_A <= (not Counter_A); + end if; +end process; +motor_prefilter <= ('0' & Counter_B(2)) + ('0' & Counter_B(1)) + ('0' & Counter_A); + +-- Very simple low pass filter, borrowed from MikeJ's Asteroids code +Engine_filter: process(clk_6) +begin + if rising_edge(clk_6) then + if (ena_3k = '1') then + motor_filter_t1 <= ("00" & motor_prefilter) + ("00" & motor_prefilter); + motor_filter_t2 <= motor_filter_t1; + motor_filter_t3 <= motor_filter_t2; + end if; + motor_filtered <= ("00" & motor_filter_t1) + + ('0' & motor_filter_t2 & '0') + + ("00" & motor_filter_t3); + end if; +end process; + +motor <= std_logic_vector(motor_filtered); + +end rtl; \ No newline at end of file diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/T65/T65.vhd b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/T65/T65.vhd new file mode 100644 index 00000000..161debea --- /dev/null +++ b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/T65/T65.vhd @@ -0,0 +1,551 @@ +-- **** +-- T65(b) core. In an effort to merge and maintain bug fixes .... +-- +-- +-- Ver 301 more merging +-- Ver 300 Bugfixes by ehenciak added, started tidyup *bust* +-- MikeJ March 2005 +-- Latest version from www.fpgaarcade.com (original www.opencores.org) +-- +-- **** +-- +-- 65xx compatible microprocessor core +-- +-- Version : 0246 +-- +-- 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/t65/ +-- +-- Limitations : +-- +-- 65C02 and 65C816 modes are incomplete +-- Undocumented instructions are not supported +-- Some interface signals behaves incorrect +-- +-- File history : +-- +-- 0246 : First release +-- + +library IEEE; + use IEEE.std_logic_1164.all; + use IEEE.numeric_std.all; + use work.T65_Pack.all; + +-- ehenciak 2-23-2005 : Added the enable signal so that one doesn't have to use +-- the ready signal to limit the CPU. +entity T65 is + port( + Mode : in std_logic_vector(1 downto 0); -- "00" => 6502, "01" => 65C02, "10" => 65C816 + Res_n : in std_logic; + Enable : in std_logic; + Clk : in std_logic; + Rdy : in std_logic; + Abort_n : in std_logic; + IRQ_n : in std_logic; + NMI_n : in std_logic; + SO_n : in std_logic; + R_W_n : out std_logic; + Sync : out std_logic; + EF : out std_logic; + MF : out std_logic; + XF : out std_logic; + ML_n : out std_logic; + VP_n : out std_logic; + VDA : out std_logic; + VPA : out std_logic; + A : out std_logic_vector(23 downto 0); + DI : in std_logic_vector(7 downto 0); + DO : out std_logic_vector(7 downto 0) + ); +end T65; + +architecture rtl of T65 is + + -- Registers + signal ABC, X, Y, D : std_logic_vector(15 downto 0); + signal P, AD, DL : std_logic_vector(7 downto 0) := x"00"; + signal BAH : std_logic_vector(7 downto 0); + signal BAL : std_logic_vector(8 downto 0); + signal PBR : std_logic_vector(7 downto 0); + signal DBR : std_logic_vector(7 downto 0); + signal PC : unsigned(15 downto 0); + signal S : unsigned(15 downto 0); + signal EF_i : std_logic; + signal MF_i : std_logic; + signal XF_i : std_logic; + + signal IR : std_logic_vector(7 downto 0); + signal MCycle : std_logic_vector(2 downto 0); + + signal Mode_r : std_logic_vector(1 downto 0); + signal ALU_Op_r : std_logic_vector(3 downto 0); + signal Write_Data_r : std_logic_vector(2 downto 0); + signal Set_Addr_To_r : std_logic_vector(1 downto 0); + signal PCAdder : unsigned(8 downto 0); + + signal RstCycle : std_logic; + signal IRQCycle : std_logic; + signal NMICycle : std_logic; + + signal B_o : std_logic; + signal SO_n_o : std_logic; + signal IRQ_n_o : std_logic; + signal NMI_n_o : std_logic; + signal NMIAct : std_logic; + + signal Break : std_logic; + + -- ALU signals + signal BusA : std_logic_vector(7 downto 0); + signal BusA_r : std_logic_vector(7 downto 0); + signal BusB : std_logic_vector(7 downto 0); + signal ALU_Q : std_logic_vector(7 downto 0); + signal P_Out : std_logic_vector(7 downto 0); + + -- Micro code outputs + signal LCycle : std_logic_vector(2 downto 0); + signal ALU_Op : std_logic_vector(3 downto 0); + signal Set_BusA_To : std_logic_vector(2 downto 0); + signal Set_Addr_To : std_logic_vector(1 downto 0); + signal Write_Data : std_logic_vector(2 downto 0); + signal Jump : std_logic_vector(1 downto 0); + signal BAAdd : std_logic_vector(1 downto 0); + signal BreakAtNA : std_logic; + signal ADAdd : std_logic; + signal AddY : std_logic; + signal PCAdd : std_logic; + signal Inc_S : std_logic; + signal Dec_S : std_logic; + signal LDA : std_logic; + signal LDP : std_logic; + signal LDX : std_logic; + signal LDY : std_logic; + signal LDS : std_logic; + signal LDDI : std_logic; + signal LDALU : std_logic; + signal LDAD : std_logic; + signal LDBAL : std_logic; + signal LDBAH : std_logic; + signal SaveP : std_logic; + signal Write : std_logic; + + signal really_rdy : std_logic; + signal R_W_n_i : std_logic; + +begin + -- ehenciak : gate Rdy with read/write to make an "OK, it's + -- really OK to stop the processor now if Rdy is + -- deasserted" signal + really_rdy <= Rdy or not(R_W_n_i); + + -- ehenciak : Drive R_W_n_i off chip. + R_W_n <= R_W_n_i; + + Sync <= '1' when MCycle = "000" else '0'; + EF <= EF_i; + MF <= MF_i; + XF <= XF_i; + ML_n <= '0' when IR(7 downto 6) /= "10" and IR(2 downto 1) = "11" and MCycle(2 downto 1) /= "00" else '1'; + VP_n <= '0' when IRQCycle = '1' and (MCycle = "101" or MCycle = "110") else '1'; + VDA <= '1' when Set_Addr_To_r /= "000" else '0'; -- Incorrect !!!!!!!!!!!! + VPA <= '1' when Jump(1) = '0' else '0'; -- Incorrect !!!!!!!!!!!! + + mcode : T65_MCode + port map( + Mode => Mode_r, + IR => IR, + MCycle => MCycle, + P => P, + LCycle => LCycle, + ALU_Op => ALU_Op, + Set_BusA_To => Set_BusA_To, + Set_Addr_To => Set_Addr_To, + Write_Data => Write_Data, + Jump => Jump, + BAAdd => BAAdd, + BreakAtNA => BreakAtNA, + ADAdd => ADAdd, + AddY => AddY, + PCAdd => PCAdd, + Inc_S => Inc_S, + Dec_S => Dec_S, + LDA => LDA, + LDP => LDP, + LDX => LDX, + LDY => LDY, + LDS => LDS, + LDDI => LDDI, + LDALU => LDALU, + LDAD => LDAD, + LDBAL => LDBAL, + LDBAH => LDBAH, + SaveP => SaveP, + Write => Write + ); + + alu : T65_ALU + port map( + Mode => Mode_r, + Op => ALU_Op_r, + BusA => BusA_r, + BusB => BusB, + P_In => P, + P_Out => P_Out, + Q => ALU_Q + ); + + process (Res_n, Clk) + begin + if Res_n = '0' then + PC <= (others => '0'); -- Program Counter + IR <= "00000000"; + S <= (others => '0'); -- Dummy !!!!!!!!!!!!!!!!!!!!! + D <= (others => '0'); + PBR <= (others => '0'); + DBR <= (others => '0'); + + Mode_r <= (others => '0'); + ALU_Op_r <= "1100"; + Write_Data_r <= "000"; + Set_Addr_To_r <= "00"; + + R_W_n_i <= '1'; + EF_i <= '1'; + MF_i <= '1'; + XF_i <= '1'; + + elsif Clk'event and Clk = '1' then + if (Enable = '1') then + if (really_rdy = '1') then + R_W_n_i <= not Write or RstCycle; + + D <= (others => '1'); -- Dummy + PBR <= (others => '1'); -- Dummy + DBR <= (others => '1'); -- Dummy + EF_i <= '0'; -- Dummy + MF_i <= '0'; -- Dummy + XF_i <= '0'; -- Dummy + + if MCycle = "000" then + Mode_r <= Mode; + + if IRQCycle = '0' and NMICycle = '0' then + PC <= PC + 1; + end if; + + if IRQCycle = '1' or NMICycle = '1' then + IR <= "00000000"; + else + IR <= DI; + end if; + end if; + + ALU_Op_r <= ALU_Op; + Write_Data_r <= Write_Data; + if Break = '1' then + Set_Addr_To_r <= "00"; + else + Set_Addr_To_r <= Set_Addr_To; + end if; + + if Inc_S = '1' then + S <= S + 1; + end if; + if Dec_S = '1' and RstCycle = '0' then + S <= S - 1; + end if; + if LDS = '1' then + S(7 downto 0) <= unsigned(ALU_Q); + end if; + + if IR = "00000000" and MCycle = "001" and IRQCycle = '0' and NMICycle = '0' then + PC <= PC + 1; + end if; + -- + -- jump control logic + -- + case Jump is + when "01" => + PC <= PC + 1; + + when "10" => + PC <= unsigned(DI & DL); + + when "11" => + if PCAdder(8) = '1' then + if DL(7) = '0' then + PC(15 downto 8) <= PC(15 downto 8) + 1; + else + PC(15 downto 8) <= PC(15 downto 8) - 1; + end if; + end if; + PC(7 downto 0) <= PCAdder(7 downto 0); + + when others => null; + end case; + end if; + end if; + end if; + end process; + + PCAdder <= resize(PC(7 downto 0),9) + resize(unsigned(DL(7) & DL),9) when PCAdd = '1' + else "0" & PC(7 downto 0); + + process (Clk) + begin + if Clk'event and Clk = '1' then + if (Enable = '1') then + if (really_rdy = '1') then + if MCycle = "000" then + if LDA = '1' then + ABC(7 downto 0) <= ALU_Q; + end if; + if LDX = '1' then + X(7 downto 0) <= ALU_Q; + end if; + if LDY = '1' then + Y(7 downto 0) <= ALU_Q; + end if; + if (LDA or LDX or LDY) = '1' then + P <= P_Out; + end if; + end if; + if SaveP = '1' then + P <= P_Out; + end if; + if LDP = '1' then + P <= ALU_Q; + end if; + if IR(4 downto 0) = "11000" then + case IR(7 downto 5) is + when "000" => + P(Flag_C) <= '0'; + when "001" => + P(Flag_C) <= '1'; + when "010" => + P(Flag_I) <= '0'; + when "011" => + P(Flag_I) <= '1'; + when "101" => + P(Flag_V) <= '0'; + when "110" => + P(Flag_D) <= '0'; + when "111" => + P(Flag_D) <= '1'; + when others => + end case; + end if; + if IR = "00000000" and MCycle = "011" and RstCycle = '0' and NMICycle = '0' and IRQCycle = '0' then + P(Flag_B) <= '1'; + end if; + if IR = "00000000" and MCycle = "100" and RstCycle = '0' and (NMICycle = '1' or IRQCycle = '1') then + P(Flag_I) <= '1'; + P(Flag_B) <= B_o; + end if; + if SO_n_o = '1' and SO_n = '0' then + P(Flag_V) <= '1'; + end if; + if RstCycle = '1' and Mode_r /= "00" then + P(Flag_1) <= '1'; + P(Flag_D) <= '0'; + P(Flag_I) <= '1'; + end if; + P(Flag_1) <= '1'; + + B_o <= P(Flag_B); + SO_n_o <= SO_n; + IRQ_n_o <= IRQ_n; + NMI_n_o <= NMI_n; + end if; + end if; + end if; + end process; + +--------------------------------------------------------------------------- +-- +-- Buses +-- +--------------------------------------------------------------------------- + + process (Res_n, Clk) + begin + if Res_n = '0' then + BusA_r <= (others => '0'); + BusB <= (others => '0'); + AD <= (others => '0'); + BAL <= (others => '0'); + BAH <= (others => '0'); + DL <= (others => '0'); + elsif Clk'event and Clk = '1' then + if (Enable = '1') then + if (Rdy = '1') then + BusA_r <= BusA; + BusB <= DI; + + case BAAdd is + when "01" => + -- BA Inc + AD <= std_logic_vector(unsigned(AD) + 1); + BAL <= std_logic_vector(unsigned(BAL) + 1); + when "10" => + -- BA Add + BAL <= std_logic_vector(resize(unsigned(BAL(7 downto 0)),9) + resize(unsigned(BusA),9)); + when "11" => + -- BA Adj + if BAL(8) = '1' then + BAH <= std_logic_vector(unsigned(BAH) + 1); + end if; + when others => + end case; + + -- ehenciak : modified to use Y register as well (bugfix) + if ADAdd = '1' then + if (AddY = '1') then + AD <= std_logic_vector(unsigned(AD) + unsigned(Y(7 downto 0))); + else + AD <= std_logic_vector(unsigned(AD) + unsigned(X(7 downto 0))); + end if; + end if; + + if IR = "00000000" then + BAL <= (others => '1'); + BAH <= (others => '1'); + if RstCycle = '1' then + BAL(2 downto 0) <= "100"; + elsif NMICycle = '1' then + BAL(2 downto 0) <= "010"; + else + BAL(2 downto 0) <= "110"; + end if; + if Set_addr_To_r = "11" then + BAL(0) <= '1'; + end if; + end if; + + + if LDDI = '1' then + DL <= DI; + end if; + if LDALU = '1' then + DL <= ALU_Q; + end if; + if LDAD = '1' then + AD <= DI; + end if; + if LDBAL = '1' then + BAL(7 downto 0) <= DI; + end if; + if LDBAH = '1' then + BAH <= DI; + end if; + end if; + end if; + end if; + end process; + + Break <= (BreakAtNA and not BAL(8)) or (PCAdd and not PCAdder(8)); + + + with Set_BusA_To select + BusA <= DI when "000", + ABC(7 downto 0) when "001", + X(7 downto 0) when "010", + Y(7 downto 0) when "011", + std_logic_vector(S(7 downto 0)) when "100", + P when "101", + (others => '-') when others; + + with Set_Addr_To_r select + A <= "0000000000000001" & std_logic_vector(S(7 downto 0)) when "01", + DBR & "00000000" & AD when "10", + "00000000" & BAH & BAL(7 downto 0) when "11", + PBR & std_logic_vector(PC(15 downto 8)) & std_logic_vector(PCAdder(7 downto 0)) when others; + + with Write_Data_r select + DO <= DL when "000", + ABC(7 downto 0) when "001", + X(7 downto 0) when "010", + Y(7 downto 0) when "011", + std_logic_vector(S(7 downto 0)) when "100", + P when "101", + std_logic_vector(PC(7 downto 0)) when "110", + std_logic_vector(PC(15 downto 8)) when others; + +------------------------------------------------------------------------- +-- +-- Main state machine +-- +------------------------------------------------------------------------- + + process (Res_n, Clk) + begin + if Res_n = '0' then + MCycle <= "001"; + RstCycle <= '1'; + IRQCycle <= '0'; + NMICycle <= '0'; + NMIAct <= '0'; + elsif Clk'event and Clk = '1' then + if (Enable = '1') then + if (really_rdy = '1') then + if MCycle = LCycle or Break = '1' then + MCycle <= "000"; + RstCycle <= '0'; + IRQCycle <= '0'; + NMICycle <= '0'; + if NMIAct = '1' then + NMICycle <= '1'; + elsif IRQ_n_o = '0' and P(Flag_I) = '0' then + IRQCycle <= '1'; + end if; + else + MCycle <= std_logic_vector(unsigned(MCycle) + 1); + end if; + + if NMICycle = '1' then + NMIAct <= '0'; + end if; + if NMI_n_o = '1' and NMI_n = '0' then + NMIAct <= '1'; + end if; + end if; + end if; + end if; + end process; + +end; diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/T65/T65_ALU.vhd b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/T65/T65_ALU.vhd new file mode 100644 index 00000000..b1f6d632 --- /dev/null +++ b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/T65/T65_ALU.vhd @@ -0,0 +1,260 @@ +-- **** +-- T65(b) core. In an effort to merge and maintain bug fixes .... +-- +-- +-- Ver 300 Bugfixes by ehenciak added +-- MikeJ March 2005 +-- Latest version from www.fpgaarcade.com (original www.opencores.org) +-- +-- **** +-- +-- 6502 compatible microprocessor core +-- +-- Version : 0245 +-- +-- 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/t65/ +-- +-- Limitations : +-- +-- File history : +-- +-- 0245 : First version +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; +use work.T65_Pack.all; + +entity T65_ALU is + port( + Mode : in std_logic_vector(1 downto 0); -- "00" => 6502, "01" => 65C02, "10" => 65816 + Op : in std_logic_vector(3 downto 0); + BusA : in std_logic_vector(7 downto 0); + BusB : in std_logic_vector(7 downto 0); + P_In : in std_logic_vector(7 downto 0); + P_Out : out std_logic_vector(7 downto 0); + Q : out std_logic_vector(7 downto 0) + ); +end T65_ALU; + +architecture rtl of T65_ALU is + + -- AddSub variables (temporary signals) + signal ADC_Z : std_logic; + signal ADC_C : std_logic; + signal ADC_V : std_logic; + signal ADC_N : std_logic; + signal ADC_Q : std_logic_vector(7 downto 0); + signal SBC_Z : std_logic; + signal SBC_C : std_logic; + signal SBC_V : std_logic; + signal SBC_N : std_logic; + signal SBC_Q : std_logic_vector(7 downto 0); + +begin + + process (P_In, BusA, BusB) + variable AL : unsigned(6 downto 0); + variable AH : unsigned(6 downto 0); + variable C : std_logic; + begin + AL := resize(unsigned(BusA(3 downto 0) & P_In(Flag_C)), 7) + resize(unsigned(BusB(3 downto 0) & "1"), 7); + AH := resize(unsigned(BusA(7 downto 4) & AL(5)), 7) + resize(unsigned(BusB(7 downto 4) & "1"), 7); + +-- pragma translate_off + if is_x(std_logic_vector(AL)) then AL := "0000000"; end if; + if is_x(std_logic_vector(AH)) then AH := "0000000"; end if; +-- pragma translate_on + + if AL(4 downto 1) = 0 and AH(4 downto 1) = 0 then + ADC_Z <= '1'; + else + ADC_Z <= '0'; + end if; + + if AL(5 downto 1) > 9 and P_In(Flag_D) = '1' then + AL(6 downto 1) := AL(6 downto 1) + 6; + end if; + + C := AL(6) or AL(5); + AH := resize(unsigned(BusA(7 downto 4) & C), 7) + resize(unsigned(BusB(7 downto 4) & "1"), 7); + + ADC_N <= AH(4); + ADC_V <= (AH(4) xor BusA(7)) and not (BusA(7) xor BusB(7)); + +-- pragma translate_off + if is_x(std_logic_vector(AH)) then AH := "0000000"; end if; +-- pragma translate_on + + if AH(5 downto 1) > 9 and P_In(Flag_D) = '1' then + AH(6 downto 1) := AH(6 downto 1) + 6; + end if; + + ADC_C <= AH(6) or AH(5); + + ADC_Q <= std_logic_vector(AH(4 downto 1) & AL(4 downto 1)); + end process; + + process (Op, P_In, BusA, BusB) + variable AL : unsigned(6 downto 0); + variable AH : unsigned(5 downto 0); + variable C : std_logic; + begin + C := P_In(Flag_C) or not Op(0); + AL := resize(unsigned(BusA(3 downto 0) & C), 7) - resize(unsigned(BusB(3 downto 0) & "1"), 6); + AH := resize(unsigned(BusA(7 downto 4) & "0"), 6) - resize(unsigned(BusB(7 downto 4) & AL(5)), 6); + +-- pragma translate_off + if is_x(std_logic_vector(AL)) then AL := "0000000"; end if; + if is_x(std_logic_vector(AH)) then AH := "000000"; end if; +-- pragma translate_on + + if AL(4 downto 1) = 0 and AH(4 downto 1) = 0 then + SBC_Z <= '1'; + else + SBC_Z <= '0'; + end if; + + SBC_C <= not AH(5); + SBC_V <= (AH(4) xor BusA(7)) and (BusA(7) xor BusB(7)); + SBC_N <= AH(4); + + if P_In(Flag_D) = '1' then + if AL(5) = '1' then + AL(5 downto 1) := AL(5 downto 1) - 6; + end if; + AH := resize(unsigned(BusA(7 downto 4) & "0"), 6) - resize(unsigned(BusB(7 downto 4) & AL(6)), 6); + if AH(5) = '1' then + AH(5 downto 1) := AH(5 downto 1) - 6; + end if; + end if; + + SBC_Q <= std_logic_vector(AH(4 downto 1) & AL(4 downto 1)); + end process; + + process (Op, P_In, BusA, BusB, + ADC_Z, ADC_C, ADC_V, ADC_N, ADC_Q, + SBC_Z, SBC_C, SBC_V, SBC_N, SBC_Q) + variable Q_t : std_logic_vector(7 downto 0); + begin + -- ORA, AND, EOR, ADC, NOP, LD, CMP, SBC + -- ASL, ROL, LSR, ROR, BIT, LD, DEC, INC + P_Out <= P_In; + Q_t := BusA; + case Op(3 downto 0) is + when "0000" => + -- ORA + Q_t := BusA or BusB; + when "0001" => + -- AND + Q_t := BusA and BusB; + when "0010" => + -- EOR + Q_t := BusA xor BusB; + when "0011" => + -- ADC + P_Out(Flag_V) <= ADC_V; + P_Out(Flag_C) <= ADC_C; + Q_t := ADC_Q; + when "0101" | "1101" => + -- LDA + when "0110" => + -- CMP + P_Out(Flag_C) <= SBC_C; + when "0111" => + -- SBC + P_Out(Flag_V) <= SBC_V; + P_Out(Flag_C) <= SBC_C; + Q_t := SBC_Q; + when "1000" => + -- ASL + Q_t := BusA(6 downto 0) & "0"; + P_Out(Flag_C) <= BusA(7); + when "1001" => + -- ROL + Q_t := BusA(6 downto 0) & P_In(Flag_C); + P_Out(Flag_C) <= BusA(7); + when "1010" => + -- LSR + Q_t := "0" & BusA(7 downto 1); + P_Out(Flag_C) <= BusA(0); + when "1011" => + -- ROR + Q_t := P_In(Flag_C) & BusA(7 downto 1); + P_Out(Flag_C) <= BusA(0); + when "1100" => + -- BIT + P_Out(Flag_V) <= BusB(6); + when "1110" => + -- DEC + Q_t := std_logic_vector(unsigned(BusA) - 1); + when "1111" => + -- INC + Q_t := std_logic_vector(unsigned(BusA) + 1); + when others => + end case; + + case Op(3 downto 0) is + when "0011" => + P_Out(Flag_N) <= ADC_N; + P_Out(Flag_Z) <= ADC_Z; + when "0110" | "0111" => + P_Out(Flag_N) <= SBC_N; + P_Out(Flag_Z) <= SBC_Z; + when "0100" => + when "1100" => + P_Out(Flag_N) <= BusB(7); + if (BusA and BusB) = "00000000" then + P_Out(Flag_Z) <= '1'; + else + P_Out(Flag_Z) <= '0'; + end if; + when others => + P_Out(Flag_N) <= Q_t(7); + if Q_t = "00000000" then + P_Out(Flag_Z) <= '1'; + else + P_Out(Flag_Z) <= '0'; + end if; + end case; + + Q <= Q_t; + end process; + +end; diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/T65/T65_MCode.vhd b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/T65/T65_MCode.vhd new file mode 100644 index 00000000..06229751 --- /dev/null +++ b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/T65/T65_MCode.vhd @@ -0,0 +1,1050 @@ +-- **** +-- T65(b) core. In an effort to merge and maintain bug fixes .... +-- +-- +-- Ver 301 Jump timing fixed +-- Ver 300 Bugfixes by ehenciak added +-- MikeJ March 2005 +-- Latest version from www.fpgaarcade.com (original www.opencores.org) +-- +-- **** +-- +-- 65xx compatible microprocessor core +-- +-- Version : 0246 + fix +-- +-- 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/t65/ +-- +-- Limitations : +-- +-- 65C02 +-- supported : inc, dec, phx, plx, phy, ply +-- missing : bra, ora, lda, cmp, sbc, tsb*2, trb*2, stz*2, bit*2, wai, stp, jmp, bbr*8, bbs*8 +-- +-- File history : +-- +-- 0246 : First release +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; +use work.T65_Pack.all; + +entity T65_MCode is + port( + Mode : in std_logic_vector(1 downto 0); -- "00" => 6502, "01" => 65C02, "10" => 65816 + IR : in std_logic_vector(7 downto 0); + MCycle : in std_logic_vector(2 downto 0); + P : in std_logic_vector(7 downto 0); + LCycle : out std_logic_vector(2 downto 0); + ALU_Op : out std_logic_vector(3 downto 0); + Set_BusA_To : out std_logic_vector(2 downto 0); -- DI,A,X,Y,S,P + Set_Addr_To : out std_logic_vector(1 downto 0); -- PC Adder,S,AD,BA + Write_Data : out std_logic_vector(2 downto 0); -- DL,A,X,Y,S,P,PCL,PCH + Jump : out std_logic_vector(1 downto 0); -- PC,++,DIDL,Rel + BAAdd : out std_logic_vector(1 downto 0); -- None,DB Inc,BA Add,BA Adj + BreakAtNA : out std_logic; + ADAdd : out std_logic; + AddY : out std_logic; + PCAdd : out std_logic; + Inc_S : out std_logic; + Dec_S : out std_logic; + LDA : out std_logic; + LDP : out std_logic; + LDX : out std_logic; + LDY : out std_logic; + LDS : out std_logic; + LDDI : out std_logic; + LDALU : out std_logic; + LDAD : out std_logic; + LDBAL : out std_logic; + LDBAH : out std_logic; + SaveP : out std_logic; + Write : out std_logic + ); +end T65_MCode; + +architecture rtl of T65_MCode is + + signal Branch : std_logic; + +begin + + with IR(7 downto 5) select + Branch <= not P(Flag_N) when "000", + P(Flag_N) when "001", + not P(Flag_V) when "010", + P(Flag_V) when "011", + not P(Flag_C) when "100", + P(Flag_C) when "101", + not P(Flag_Z) when "110", + P(Flag_Z) when others; + + process (IR, MCycle, P, Branch, Mode) + begin + LCycle <= "001"; + Set_BusA_To <= "001"; -- A + Set_Addr_To <= (others => '0'); + Write_Data <= (others => '0'); + Jump <= (others => '0'); + BAAdd <= "00"; + BreakAtNA <= '0'; + ADAdd <= '0'; + PCAdd <= '0'; + Inc_S <= '0'; + Dec_S <= '0'; + LDA <= '0'; + LDP <= '0'; + LDX <= '0'; + LDY <= '0'; + LDS <= '0'; + LDDI <= '0'; + LDALU <= '0'; + LDAD <= '0'; + LDBAL <= '0'; + LDBAH <= '0'; + SaveP <= '0'; + Write <= '0'; + AddY <= '0'; + + case IR(7 downto 5) is + when "100" => + --{{{ + case IR(1 downto 0) is + when "00" => + Set_BusA_To <= "011"; -- Y + Write_Data <= "011"; -- Y + when "10" => + Set_BusA_To <= "010"; -- X + Write_Data <= "010"; -- X + when others => + Write_Data <= "001"; -- A + end case; + --}}} + when "101" => + --{{{ + case IR(1 downto 0) is + when "00" => + if IR(4) /= '1' or IR(2) /= '0' then + LDY <= '1'; + end if; + when "10" => + LDX <= '1'; + when others => + LDA <= '1'; + end case; + Set_BusA_To <= "000"; -- DI + --}}} + when "110" => + --{{{ + case IR(1 downto 0) is + when "00" => + if IR(4) = '0' then + LDY <= '1'; + end if; + Set_BusA_To <= "011"; -- Y + when others => + Set_BusA_To <= "001"; -- A + end case; + --}}} + when "111" => + --{{{ + case IR(1 downto 0) is + when "00" => + if IR(4) = '0' then + LDX <= '1'; + end if; + Set_BusA_To <= "010"; -- X + when others => + Set_BusA_To <= "001"; -- A + end case; + --}}} + when others => + end case; + + if IR(7 downto 6) /= "10" and IR(1 downto 0) = "10" then + Set_BusA_To <= "000"; -- DI + end if; + + case IR(4 downto 0) is + when "00000" | "01000" | "01010" | "11000" | "11010" => + --{{{ + -- Implied + case IR is + when "00000000" => + -- BRK + LCycle <= "110"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= "01"; -- S + Write_Data <= "111"; -- PCH + Write <= '1'; + when 2 => + Dec_S <= '1'; + Set_Addr_To <= "01"; -- S + Write_Data <= "110"; -- PCL + Write <= '1'; + when 3 => + Dec_S <= '1'; + Set_Addr_To <= "01"; -- S + Write_Data <= "101"; -- P + Write <= '1'; + when 4 => + Dec_S <= '1'; + Set_Addr_To <= "11"; -- BA + when 5 => + LDDI <= '1'; + Set_Addr_To <= "11"; -- BA + when 6 => + Jump <= "10"; -- DIDL + when others => + end case; + when "00100000" => + -- JSR + LCycle <= "101"; + case to_integer(unsigned(MCycle)) is + when 1 => + Jump <= "01"; + LDDI <= '1'; + Set_Addr_To <= "01"; -- S + when 2 => + Set_Addr_To <= "01"; -- S + Write_Data <= "111"; -- PCH + Write <= '1'; + when 3 => + Dec_S <= '1'; + Set_Addr_To <= "01"; -- S + Write_Data <= "110"; -- PCL + Write <= '1'; + when 4 => + Dec_S <= '1'; + when 5 => + Jump <= "10"; -- DIDL + when others => + end case; + when "01000000" => + -- RTI + LCycle <= "101"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= "01"; -- S + when 2 => + Inc_S <= '1'; + Set_Addr_To <= "01"; -- S + when 3 => + Inc_S <= '1'; + Set_Addr_To <= "01"; -- S + Set_BusA_To <= "000"; -- DI + when 4 => + LDP <= '1'; + Inc_S <= '1'; + LDDI <= '1'; + Set_Addr_To <= "01"; -- S + when 5 => + Jump <= "10"; -- DIDL + when others => + end case; + when "01100000" => + -- RTS + LCycle <= "101"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= "01"; -- S + when 2 => + Inc_S <= '1'; + Set_Addr_To <= "01"; -- S + when 3 => + Inc_S <= '1'; + LDDI <= '1'; + Set_Addr_To <= "01"; -- S + when 4 => + Jump <= "10"; -- DIDL + when 5 => + Jump <= "01"; + when others => + end case; + when "00001000" | "01001000" | "01011010" | "11011010" => + -- PHP, PHA, PHY*, PHX* + LCycle <= "010"; + if Mode = "00" and IR(1) = '1' then + LCycle <= "001"; + end if; + case to_integer(unsigned(MCycle)) is + when 1 => + case IR(7 downto 4) is + when "0000" => + Write_Data <= "101"; -- P + when "0100" => + Write_Data <= "001"; -- A + when "0101" => + Write_Data <= "011"; -- Y + when "1101" => + Write_Data <= "010"; -- X + when others => + end case; + Write <= '1'; + Set_Addr_To <= "01"; -- S + when 2 => + Dec_S <= '1'; + when others => + end case; + when "00101000" | "01101000" | "01111010" | "11111010" => + -- PLP, PLA, PLY*, PLX* + LCycle <= "011"; + if Mode = "00" and IR(1) = '1' then + LCycle <= "001"; + end if; + case IR(7 downto 4) is + when "0010" => + LDP <= '1'; + when "0110" => + LDA <= '1'; + when "0111" => + if Mode /= "00" then + LDY <= '1'; + end if; + when "1111" => + if Mode /= "00" then + LDX <= '1'; + end if; + when others => + end case; + case to_integer(unsigned(MCycle)) is + when 0 => + SaveP <= '1'; + when 1 => + Set_Addr_To <= "01"; -- S + when 2 => + Inc_S <= '1'; + Set_Addr_To <= "01"; -- S + when 3 => + Set_BusA_To <= "000"; -- DI + when others => + end case; + when "10100000" | "11000000" | "11100000" => + -- LDY, CPY, CPX + -- Immediate + case to_integer(unsigned(MCycle)) is + when 0 => + when 1 => + Jump <= "01"; + when others => + end case; + when "10001000" => + -- DEY + LDY <= '1'; + case to_integer(unsigned(MCycle)) is + when 0 => + when 1 => + Set_BusA_To <= "011"; -- Y + when others => + end case; + when "11001010" => + -- DEX + LDX <= '1'; + case to_integer(unsigned(MCycle)) is + when 0 => + when 1 => + Set_BusA_To <= "010"; -- X + when others => + end case; + when "00011010" | "00111010" => + -- INC*, DEC* + if Mode /= "00" then + LDA <= '1'; -- A + end if; + case to_integer(unsigned(MCycle)) is + when 0 => + when 1 => + Set_BusA_To <= "100"; -- S + when others => + end case; + when "00001010" | "00101010" | "01001010" | "01101010" => + -- ASL, ROL, LSR, ROR + LDA <= '1'; -- A + Set_BusA_To <= "001"; -- A + case to_integer(unsigned(MCycle)) is + when 0 => + when 1 => + when others => + end case; + when "10001010" | "10011000" => + -- TYA, TXA + LDA <= '1'; -- A + case to_integer(unsigned(MCycle)) is + when 0 => + when 1 => + when others => + end case; + when "10101010" | "10101000" => + -- TAX, TAY + case to_integer(unsigned(MCycle)) is + when 0 => + when 1 => + Set_BusA_To <= "001"; -- A + when others => + end case; + when "10011010" => + -- TXS + case to_integer(unsigned(MCycle)) is + when 0 => + LDS <= '1'; + when 1 => + when others => + end case; + when "10111010" => + -- TSX + LDX <= '1'; + case to_integer(unsigned(MCycle)) is + when 0 => + when 1 => + Set_BusA_To <= "100"; -- S + when others => + end case; + + -- when "00011000" | "00111000" | "01011000" | "01111000" | "10111000" | "11011000" | "11111000" | "11001000" | "11101000" => + -- -- CLC, SEC, CLI, SEI, CLV, CLD, SED, INY, INX + -- case to_integer(unsigned(MCycle)) is + -- when 1 => + -- when others => + -- end case; + when others => + case to_integer(unsigned(MCycle)) is + when 0 => + when others => + end case; + end case; + --}}} + + when "00001" | "00011" => + --{{{ + -- Zero Page Indexed Indirect (d,x) + LCycle <= "101"; + if IR(7 downto 6) /= "10" then + LDA <= '1'; + end if; + case to_integer(unsigned(MCycle)) is + when 0 => + when 1 => + Jump <= "01"; + LDAD <= '1'; + Set_Addr_To <= "10"; -- AD + when 2 => + ADAdd <= '1'; + Set_Addr_To <= "10"; -- AD + when 3 => + BAAdd <= "01"; -- DB Inc + LDBAL <= '1'; + Set_Addr_To <= "10"; -- AD + when 4 => + LDBAH <= '1'; + if IR(7 downto 5) = "100" then + Write <= '1'; + end if; + Set_Addr_To <= "11"; -- BA + when 5 => + when others => + end case; + --}}} + + when "01001" | "01011" => + --{{{ + -- Immediate + LDA <= '1'; + case to_integer(unsigned(MCycle)) is + when 0 => + when 1 => + Jump <= "01"; + when others => + end case; + + --}}} + + when "00010" | "10010" => + --{{{ + -- Immediate, KIL + LDX <= '1'; + case to_integer(unsigned(MCycle)) is + when 0 => + when 1 => + if IR = "10100010" then + -- LDX + Jump <= "01"; + else + -- KIL !!!!!!!!!!!!!!!!!!!!!!!!!!!!! + end if; + when others => + end case; + --}}} + + when "00100" => + --{{{ + -- Zero Page + LCycle <= "010"; + case to_integer(unsigned(MCycle)) is + when 0 => + if IR(7 downto 5) = "001" then + SaveP <= '1'; + end if; + when 1 => + Jump <= "01"; + LDAD <= '1'; + if IR(7 downto 5) = "100" then + Write <= '1'; + end if; + Set_Addr_To <= "10"; -- AD + when 2 => + when others => + end case; + --}}} + + when "00101" | "00110" | "00111" => + --{{{ + -- Zero Page + if IR(7 downto 6) /= "10" and IR(1 downto 0) = "10" then + -- Read-Modify-Write + LCycle <= "100"; + case to_integer(unsigned(MCycle)) is + when 1 => + Jump <= "01"; + LDAD <= '1'; + Set_Addr_To <= "10"; -- AD + when 2 => + LDDI <= '1'; + Write <= '1'; + Set_Addr_To <= "10"; -- AD + when 3 => + LDALU <= '1'; + SaveP <= '1'; + Write <= '1'; + Set_Addr_To <= "10"; -- AD + when 4 => + when others => + end case; + else + LCycle <= "010"; + if IR(7 downto 6) /= "10" then + LDA <= '1'; + end if; + case to_integer(unsigned(MCycle)) is + when 0 => + when 1 => + Jump <= "01"; + LDAD <= '1'; + if IR(7 downto 5) = "100" then + Write <= '1'; + end if; + Set_Addr_To <= "10"; -- AD + when 2 => + when others => + end case; + end if; + --}}} + + when "01100" => + --{{{ + -- Absolute + if IR(7 downto 6) = "01" and IR(4 downto 0) = "01100" then + -- JMP + if IR(5) = '0' then + --LCycle <= "011"; + LCycle <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Jump <= "01"; + LDDI <= '1'; + when 2 => + Jump <= "10"; -- DIDL + when others => + end case; + else + LCycle <= "101"; + case to_integer(unsigned(MCycle)) is + when 2 => + Jump <= "01"; + LDDI <= '1'; + LDBAL <= '1'; + when 3 => + LDBAH <= '1'; + if Mode /= "00" then + Jump <= "10"; -- DIDL + end if; + if Mode = "00" then + Set_Addr_To <= "11"; -- BA + end if; + when 4 => + LDDI <= '1'; + if Mode = "00" then + Set_Addr_To <= "11"; -- BA + BAAdd <= "01"; -- DB Inc + else + Jump <= "01"; + end if; + when 5 => + Jump <= "10"; -- DIDL + when others => + end case; + end if; + else + LCycle <= "011"; + case to_integer(unsigned(MCycle)) is + when 0 => + if IR(7 downto 5) = "001" then + SaveP <= '1'; + end if; + when 1 => + Jump <= "01"; + LDBAL <= '1'; + when 2 => + Jump <= "01"; + LDBAH <= '1'; + if IR(7 downto 5) = "100" then + Write <= '1'; + end if; + Set_Addr_To <= "11"; -- BA + when 3 => + when others => + end case; + end if; + --}}} + + when "01101" | "01110" | "01111" => + --{{{ + -- Absolute + if IR(7 downto 6) /= "10" and IR(1 downto 0) = "10" then + -- Read-Modify-Write + LCycle <= "101"; + case to_integer(unsigned(MCycle)) is + when 1 => + Jump <= "01"; + LDBAL <= '1'; + when 2 => + Jump <= "01"; + LDBAH <= '1'; + Set_Addr_To <= "11"; -- BA + when 3 => + LDDI <= '1'; + Write <= '1'; + Set_Addr_To <= "11"; -- BA + when 4 => + Write <= '1'; + LDALU <= '1'; + SaveP <= '1'; + Set_Addr_To <= "11"; -- BA + when 5 => + SaveP <= '0'; -- MIKEJ was 1 + when others => + end case; + else + LCycle <= "011"; + if IR(7 downto 6) /= "10" then + LDA <= '1'; + end if; + case to_integer(unsigned(MCycle)) is + when 0 => + when 1 => + Jump <= "01"; + LDBAL <= '1'; + when 2 => + Jump <= "01"; + LDBAH <= '1'; + if IR(7 downto 5) = "100" then + Write <= '1'; + end if; + Set_Addr_To <= "11"; -- BA + when 3 => + when others => + end case; + end if; + --}}} + + when "10000" => + --{{{ + -- Relative + + -- This circuit dictates when the last + -- microcycle occurs for the branch depending on + -- whether or not the branch is taken and if a page + -- is crossed... + if (Branch = '1') then + + LCycle <= "011"; -- We're done @ T3 if branching...upper + -- level logic will stop at T2 if no page cross + -- (See the Break signal) + else + + LCycle <= "001"; + + end if; + + -- This decodes the current microcycle and takes the + -- proper course of action... + case to_integer(unsigned(MCycle)) is + + -- On the T1 microcycle, increment the program counter + -- and instruct the upper level logic to fetch the offset + -- from the Din bus and store it in the data latches. This + -- will be the last microcycle if the branch isn't taken. + when 1 => + + Jump <= "01"; -- Increments the PC by one (PC will now be PC+2) + -- from microcycle T0. + + LDDI <= '1'; -- Tells logic in top level (T65.vhd) to route + -- the Din bus to the memory data latch (DL) + -- so that the branch offset is fetched. + + -- In microcycle T2, tell the logic in the top level to + -- add the offset. If the most significant byte of the + -- program counter (i.e. the current "page") does not need + -- updating, we are done here...the Break signal at the + -- T65.vhd level takes care of that... + when 2 => + + Jump <= "11"; -- Tell the PC Jump logic to use relative mode. + + PCAdd <= '1'; -- This tells the PC adder to update itself with + -- the current offset recently fetched from + -- memory. + + -- The following is microcycle T3 : + -- The program counter should be completely updated + -- on this cycle after the page cross is detected. + -- We don't need to do anything here... + when 3 => + + + when others => null; -- Do nothing. + + end case; + --}}} + + when "10001" | "10011" => + --{{{ + -- Zero Page Indirect Indexed (d),y + LCycle <= "101"; + if IR(7 downto 6) /= "10" then + LDA <= '1'; + end if; + case to_integer(unsigned(MCycle)) is + when 0 => + when 1 => + Jump <= "01"; + LDAD <= '1'; + Set_Addr_To <= "10"; -- AD + when 2 => + LDBAL <= '1'; + BAAdd <= "01"; -- DB Inc + Set_Addr_To <= "10"; -- AD + when 3 => + Set_BusA_To <= "011"; -- Y + BAAdd <= "10"; -- BA Add + LDBAH <= '1'; + Set_Addr_To <= "11"; -- BA + when 4 => + BAAdd <= "11"; -- BA Adj + if IR(7 downto 5) = "100" then + Write <= '1'; + else + BreakAtNA <= '1'; + end if; + Set_Addr_To <= "11"; -- BA + when 5 => + when others => + end case; + --}}} + + when "10100" | "10101" | "10110" | "10111" => + --{{{ + -- Zero Page, X + if IR(7 downto 6) /= "10" and IR(1 downto 0) = "10" then + -- Read-Modify-Write + LCycle <= "101"; + case to_integer(unsigned(MCycle)) is + when 1 => + Jump <= "01"; + LDAD <= '1'; + Set_Addr_To <= "10"; -- AD + when 2 => + ADAdd <= '1'; + Set_Addr_To <= "10"; -- AD + when 3 => + LDDI <= '1'; + Write <= '1'; + Set_Addr_To <= "10"; -- AD + when 4 => + LDALU <= '1'; + SaveP <= '1'; + Write <= '1'; + Set_Addr_To <= "10"; -- AD + when 5 => + when others => + end case; + else + LCycle <= "011"; + if IR(7 downto 6) /= "10" then + LDA <= '1'; + end if; + case to_integer(unsigned(MCycle)) is + when 0 => + when 1 => + Jump <= "01"; + LDAD <= '1'; + Set_Addr_To <= "10"; -- AD + when 2 => + ADAdd <= '1'; + -- Added this check for Y reg. use... + if (IR(3 downto 0) = "0110") then + AddY <= '1'; + end if; + + if IR(7 downto 5) = "100" then + Write <= '1'; + end if; + Set_Addr_To <= "10"; -- AD + when 3 => null; + when others => + end case; + end if; + --}}} + + when "11001" | "11011" => + --{{{ + -- Absolute Y + LCycle <= "100"; + if IR(7 downto 6) /= "10" then + LDA <= '1'; + end if; + case to_integer(unsigned(MCycle)) is + when 0 => + when 1 => + Jump <= "01"; + LDBAL <= '1'; + when 2 => + Jump <= "01"; + Set_BusA_To <= "011"; -- Y + BAAdd <= "10"; -- BA Add + LDBAH <= '1'; + Set_Addr_To <= "11"; -- BA + when 3 => + BAAdd <= "11"; -- BA adj + if IR(7 downto 5) = "100" then + Write <= '1'; + else + BreakAtNA <= '1'; + end if; + Set_Addr_To <= "11"; -- BA + when 4 => + when others => + end case; + --}}} + + when "11100" | "11101" | "11110" | "11111" => + --{{{ + -- Absolute X + + if IR(7 downto 6) /= "10" and IR(1 downto 0) = "10" then + -- Read-Modify-Write + LCycle <= "110"; + case to_integer(unsigned(MCycle)) is + when 1 => + Jump <= "01"; + LDBAL <= '1'; + when 2 => + Jump <= "01"; + Set_BusA_To <= "010"; -- X + BAAdd <= "10"; -- BA Add + LDBAH <= '1'; + Set_Addr_To <= "11"; -- BA + when 3 => + BAAdd <= "11"; -- BA adj + Set_Addr_To <= "11"; -- BA + when 4 => + LDDI <= '1'; + Write <= '1'; + Set_Addr_To <= "11"; -- BA + when 5 => + LDALU <= '1'; + SaveP <= '1'; + Write <= '1'; + Set_Addr_To <= "11"; -- BA + when 6 => + when others => + end case; + else + LCycle <= "100"; + if IR(7 downto 6) /= "10" then + LDA <= '1'; + end if; + case to_integer(unsigned(MCycle)) is + when 0 => + when 1 => + Jump <= "01"; + LDBAL <= '1'; + when 2 => + Jump <= "01"; + -- mikej + -- special case 0xBE which uses Y reg as index!! + if (IR = "10111110") then + Set_BusA_To <= "011"; -- Y + else + Set_BusA_To <= "010"; -- X + end if; + BAAdd <= "10"; -- BA Add + LDBAH <= '1'; + Set_Addr_To <= "11"; -- BA + when 3 => + BAAdd <= "11"; -- BA adj + if IR(7 downto 5) = "100" then + Write <= '1'; + else + BreakAtNA <= '1'; + end if; + Set_Addr_To <= "11"; -- BA + when 4 => + when others => + end case; + end if; + --}}} + when others => + end case; + end process; + + process (IR, MCycle) + begin + -- ORA, AND, EOR, ADC, NOP, LD, CMP, SBC + -- ASL, ROL, LSR, ROR, BIT, LD, DEC, INC + case IR(1 downto 0) is + when "00" => + --{{{ + case IR(4 downto 2) is + when "000" | "001" | "011" => + case IR(7 downto 5) is + when "110" | "111" => + -- CP + ALU_Op <= "0110"; + when "101" => + -- LD + ALU_Op <= "0101"; + when "001" => + -- BIT + ALU_Op <= "1100"; + when others => + -- NOP/ST + ALU_Op <= "0100"; + end case; + when "010" => + case IR(7 downto 5) is + when "111" | "110" => + -- IN + ALU_Op <= "1111"; + when "100" => + -- DEY + ALU_Op <= "1110"; + when others => + -- LD + ALU_Op <= "1101"; + end case; + when "110" => + case IR(7 downto 5) is + when "100" => + -- TYA + ALU_Op <= "1101"; + when others => + ALU_Op <= "----"; + end case; + when others => + case IR(7 downto 5) is + when "101" => + -- LD + ALU_Op <= "1101"; + when others => + ALU_Op <= "0100"; + end case; + end case; + --}}} + when "01" => -- OR + --{{{ + ALU_Op(3) <= '0'; + ALU_Op(2 downto 0) <= IR(7 downto 5); + --}}} + when "10" => + --{{{ + ALU_Op(3) <= '1'; + ALU_Op(2 downto 0) <= IR(7 downto 5); + case IR(7 downto 5) is + when "000" => + if IR(4 downto 2) = "110" then + -- INC + ALU_Op <= "1111"; + end if; + when "001" => + if IR(4 downto 2) = "110" then + -- DEC + ALU_Op <= "1110"; + end if; + when "100" => + if IR(4 downto 2) = "010" then + -- TXA + ALU_Op <= "0101"; + else + ALU_Op <= "0100"; + end if; + when others => + end case; + --}}} + when others => + --{{{ + case IR(7 downto 5) is + when "100" => + ALU_Op <= "0100"; + when others => + if MCycle = "000" then + ALU_Op(3) <= '0'; + ALU_Op(2 downto 0) <= IR(7 downto 5); + else + ALU_Op(3) <= '1'; + ALU_Op(2 downto 0) <= IR(7 downto 5); + end if; + end case; + --}}} + end case; + end process; + +end; diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/T65/T65_Pack.vhd b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/T65/T65_Pack.vhd new file mode 100644 index 00000000..e025e1bf --- /dev/null +++ b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/T65/T65_Pack.vhd @@ -0,0 +1,117 @@ +-- **** +-- T65(b) core. In an effort to merge and maintain bug fixes .... +-- +-- +-- Ver 300 Bugfixes by ehenciak added +-- MikeJ March 2005 +-- Latest version from www.fpgaarcade.com (original www.opencores.org) +-- +-- **** +-- +-- 65xx compatible microprocessor core +-- +-- Version : 0246 +-- +-- 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/t65/ +-- +-- Limitations : +-- +-- File history : +-- + +library IEEE; +use IEEE.std_logic_1164.all; + +package T65_Pack is + + constant Flag_C : integer := 0; + constant Flag_Z : integer := 1; + constant Flag_I : integer := 2; + constant Flag_D : integer := 3; + constant Flag_B : integer := 4; + constant Flag_1 : integer := 5; + constant Flag_V : integer := 6; + constant Flag_N : integer := 7; + + component T65_MCode + port( + Mode : in std_logic_vector(1 downto 0); -- "00" => 6502, "01" => 65C02, "10" => 65816 + IR : in std_logic_vector(7 downto 0); + MCycle : in std_logic_vector(2 downto 0); + P : in std_logic_vector(7 downto 0); + LCycle : out std_logic_vector(2 downto 0); + ALU_Op : out std_logic_vector(3 downto 0); + Set_BusA_To : out std_logic_vector(2 downto 0); -- DI,A,X,Y,S,P + Set_Addr_To : out std_logic_vector(1 downto 0); -- PC Adder,S,AD,BA + Write_Data : out std_logic_vector(2 downto 0); -- DL,A,X,Y,S,P,PCL,PCH + Jump : out std_logic_vector(1 downto 0); -- PC,++,DIDL,Rel + BAAdd : out std_logic_vector(1 downto 0); -- None,DB Inc,BA Add,BA Adj + BreakAtNA : out std_logic; + ADAdd : out std_logic; + AddY : out std_logic; + PCAdd : out std_logic; + Inc_S : out std_logic; + Dec_S : out std_logic; + LDA : out std_logic; + LDP : out std_logic; + LDX : out std_logic; + LDY : out std_logic; + LDS : out std_logic; + LDDI : out std_logic; + LDALU : out std_logic; + LDAD : out std_logic; + LDBAL : out std_logic; + LDBAH : out std_logic; + SaveP : out std_logic; + Write : out std_logic + ); + end component; + + component T65_ALU + port( + Mode : in std_logic_vector(1 downto 0); -- "00" => 6502, "01" => 65C02, "10" => 65C816 + Op : in std_logic_vector(3 downto 0); + BusA : in std_logic_vector(7 downto 0); + BusB : in std_logic_vector(7 downto 0); + P_In : in std_logic_vector(7 downto 0); + P_Out : out std_logic_vector(7 downto 0); + Q : out std_logic_vector(7 downto 0) + ); + end component; + +end; diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/build_id.sv b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/build_id.sv new file mode 100644 index 00000000..1d53a3f2 --- /dev/null +++ b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/build_id.sv @@ -0,0 +1,2 @@ +`define BUILD_DATE "171221" +`define BUILD_TIME "172231" diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/build_id.tcl b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/build_id.tcl new file mode 100644 index 00000000..be673dac --- /dev/null +++ b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/build_id.tcl @@ -0,0 +1,35 @@ +# ================================================================================ +# +# Build ID Verilog Module Script +# Jeff Wiencrot - 8/1/2011 +# +# Generates a Verilog module that contains a timestamp, +# from the current build. These values are available from the build_date, build_time, +# physical_address, and host_name output ports of the build_id module in the build_id.v +# Verilog source file. +# +# ================================================================================ + +proc generateBuildID_Verilog {} { + + # Get the timestamp (see: http://www.altera.com/support/examples/tcl/tcl-date-time-stamp.html) + set buildDate [ clock format [ clock seconds ] -format %y%m%d ] + set buildTime [ clock format [ clock seconds ] -format %H%M%S ] + + # Create a Verilog file for output + set outputFileName "rtl/build_id.sv" + set outputFile [open $outputFileName "w"] + + # Output the Verilog source + puts $outputFile "`define BUILD_DATE \"$buildDate\"" + puts $outputFile "`define BUILD_TIME \"$buildTime\"" + close $outputFile + + # Send confirmation message to the Messages window + post_message "Generated build identification Verilog module: [pwd]/$outputFileName" + post_message "Date: $buildDate" + post_message "Time: $buildTime" +} + +# Comment out this line to prevent the process from automatically executing when the file is sourced: +generateBuildID_Verilog \ No newline at end of file diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/collision.vhd b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/collision.vhd new file mode 100644 index 00000000..1425281a --- /dev/null +++ b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/collision.vhd @@ -0,0 +1,105 @@ +-- Collision detection logic for for Kee Games Ultra Tank +-- This is called the "Tank/Shell Comparator" in the manual and works by comparing the +-- video signals representing tanks, shells and playfield objects generating +-- collision signals when multiple objects appear at the same time (location) in the video. +-- +-- (c) 2017 James Sweet +-- +-- This is free software: you can redistribute +-- it and/or modify it under the terms of the GNU General +-- Public License as published by the Free Software +-- Foundation, either version 3 of the License, or (at your +-- option) any later version. +-- +-- This is distributed in the hope that it will +-- be useful, but WITHOUT ANY WARRANTY; without even the +-- implied warranty of MERCHANTABILITY or FITNESS FOR A +-- PARTICULAR PURPOSE. See the GNU General Public License +-- for more details. + +library IEEE; +use IEEE.STD_LOGIC_1164.all; + +entity collision_detect is +port( + Clk6 : in std_logic; + Adr : in std_logic_vector(2 downto 0); + Object_n : in std_logic_vector(4 downto 1); + Playfield_n : in std_logic; + CollisionReset_n : in std_logic_vector(4 downto 1); + Slam_n : in std_logic; -- Slam switch is read by collision detection mux + Collision_n : out std_logic + ); +end collision_detect; + +architecture rtl of collision_detect is + +signal Col_latch_Q : std_logic_vector(4 downto 1) := (others => '0'); +signal S1_n : std_logic_vector(4 downto 1); +signal R_n : std_logic_vector(4 downto 1); + + +begin + +-- Glue logic - This can be re-written to incorporate into the latch process +R_n <= CollisionReset_n; +S1_n(1) <= Object_n(1) or Playfield_n; +S1_n(2) <= Object_n(2) or Playfield_n; +S1_n(3) <= Object_n(3) or Playfield_n; +S1_n(4) <= Object_n(4) or Playfield_n; + + +-- 74LS279 quad SR latch at L11, all inputs are active low +H6: process(Clk6, S1_n, R_n, Col_latch_Q) +begin + if rising_edge(Clk6) then +-- Units 1 and 3 each have an extra Set element but these are not used in this game +-- Ordered from top to bottom as drawn in the schematic + if R_n(1) = '0' then + Col_latch_Q(1) <= '0'; + elsif S1_n(1) = '0' then + Col_latch_Q(1) <= '1'; + else + Col_latch_Q(1) <= Col_latch_Q(1); + end if; + if R_n(2) = '0' then + Col_latch_Q(2) <= '0'; + elsif S1_n(2) = '0' then + Col_latch_Q(2) <= '1'; + else + Col_latch_Q(2) <= Col_latch_Q(2); + end if; + if R_n(4) = '0' then + Col_latch_Q(4) <= '0'; + elsif S1_n(4) = '0' then + Col_latch_Q(4) <= '1'; + else + Col_latch_Q(4) <= Col_latch_Q(4); + end if; + if R_n(3) = '0' then + Col_latch_Q(3) <= '0'; + elsif S1_n(3) = '0' then + Col_latch_Q(3) <= '1'; + else + Col_latch_Q(3) <= Col_latch_Q(3); + end if; + end if; +end process; + +-- 9312 Data Selector/Multiplexer at L12 +L12: process(Adr, Slam_n, Col_latch_Q) +begin + case Adr(2 downto 0) is + when "000" => Collision_n <= '1'; + when "001" => Collision_n <= Col_latch_Q(1); + when "010" => Collision_n <= '1'; + when "011" => Collision_n <= Col_latch_Q(2); + when "100" => Collision_n <= '1'; + when "101" => Collision_n <= Col_latch_Q(3); + when "110" => Collision_n <= Slam_n; + when "111" => Collision_n <= Col_latch_Q(4); + when others => Collision_n <= '1'; + end case; +end process; + +end rtl; \ No newline at end of file diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/cpu_mem.vhd b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/cpu_mem.vhd new file mode 100644 index 00000000..2683463a --- /dev/null +++ b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/cpu_mem.vhd @@ -0,0 +1,460 @@ +-- CPU, RAM, ROM and address decoder for Kee Games Ultra Tank +-- (c) 2017 James Sweet +-- +-- This is free software: you can redistribute +-- it and/or modify it under the terms of the GNU General +-- Public License as published by the Free Software +-- Foundation, either version 3 of the License, or (at your +-- option) any later version. +-- +-- This is distributed in the hope that it will +-- be useful, but WITHOUT ANY WARRANTY; without even the +-- implied warranty of MERCHANTABILITY or FITNESS FOR A +-- PARTICULAR PURPOSE. See the GNU General Public License +-- for more details. + +library IEEE; +use IEEE.STD_LOGIC_1164.all; +use IEEE.STD_LOGIC_ARITH.all; +use IEEE.STD_LOGIC_UNSIGNED.all; + +entity CPU_mem is +port( + CLK12 : in std_logic; + CLK6 : in std_logic; -- 6MHz on schematic + Reset_n : in std_logic; + VCount : in std_logic_vector(7 downto 0); + HCount : in std_logic_vector(8 downto 0); + Vblank_n_s : in std_logic; -- Vblank* on schematic + Test_n : in std_logic; + Collision_n : in std_logic; + DB_in : in std_logic_vector(7 downto 0); -- CPU data bus + DBus : buffer std_logic_vector(7 downto 0); + DBuS_n : buffer std_logic_vector(7 downto 0); + PRAM : buffer std_logic_vector(7 downto 0); + ABus : out std_logic_vector(15 downto 0); + Attract : buffer std_logic; + Attract_n : out std_logic; + CollReset_n : out std_logic_vector(4 downto 1); + Barrier_Read_n : out std_logic; + Throttle_Read_n : out std_logic; + Coin_Read_n : out std_logic; + Options_Read_n : out std_logic; + Wr_DA_Latch_n : out std_logic; + Wr_Explosion_n : out std_logic; + Fire1 : out std_logic; + Fire2 : out std_logic; + LED1 : out std_logic; + LED2 : out std_logic; + Lockout_n : out std_logic; + PHI1_O : out std_logic; + PHI2_O : out std_logic; + DMA : out std_logic_vector(7 downto 0); + DMA_n : out std_logic_vector(7 downto 0) + ); +end CPU_mem; + +architecture rtl of CPU_mem is +-- Clock signals +signal cpu_clk : std_logic; +signal PHI1 : std_logic; +signal PHI2 : std_logic; + +-- Video scan signals +signal H256 : std_logic; +signal H256_n : std_logic; +signal H128 : std_logic; +signal H64 : std_logic; +signal H32 : std_logic; +signal H16 : std_logic; +signal H8 : std_logic; +signal H4 : std_logic; +signal H2 : std_logic; +signal H1 : std_logic; +signal V128 : std_logic; +signal V64 : std_logic; +signal V32 : std_logic; +signal V16 : std_logic; +signal V8 : std_logic; + +-- CPU signals +signal NMI_n : std_logic := '1'; +signal RW_n : std_logic; +signal RnW : std_logic; +signal A : std_logic_vector(15 downto 0); +signal ADR : std_logic_vector(15 downto 0); +signal cpuDin : std_logic_vector(7 downto 0); +signal cpuDout : std_logic_vector(7 downto 0); + +-- Address decoder signals +signal N10_in : std_logic_vector(3 downto 0) := (others => '0'); +signal N10_out : std_logic_vector(9 downto 0) := (others => '1'); +signal M10_out_A : std_logic_vector(3 downto 0) := (others => '1'); +signal M10_out_B : std_logic_vector(3 downto 0) := (others => '1'); +signal B2_in : std_logic_vector(3 downto 0) := (others => '0'); +signal B2_out : std_logic_vector(9 downto 0) := (others => '1'); +signal R10_Q : std_logic := '0'; +signal D4_8 : std_logic := '1'; + +-- Buses and chip enables +signal cpuRAM_dout : std_logic_vector(7 downto 0) := (others => '0'); +signal AddRAM_dout : std_logic_vector(7 downto 0) := (others => '0'); +signal Vram_dout : std_logic_vector(7 downto 0) := (others => '0'); +signal RAM_din : std_logic_vector(7 downto 0) := (others => '0'); +signal RAM_addr : std_logic_vector(9 downto 0) := (others => '0'); +signal Vram_addr : std_logic_vector(9 downto 0) := (others => '0'); +signal RAM_dout : std_logic_vector(7 downto 0) := (others => '0'); +signal RAM_we : std_logic; +signal RAM_n : std_logic := '1'; +signal WRAM : std_logic; +signal WRITE_n : std_logic := '1'; +signal ROM_mux_in : std_logic_vector(1 downto 0) := (others => '0'); +signal ROM3_dout : std_logic_vector(7 downto 0) := (others => '0'); +signal ROM4_dout : std_logic_vector(7 downto 0) := (others => '0'); +signal ROM_dout : std_logic_vector(7 downto 0) := (others => '0'); +signal ROM3_n : std_logic := '1'; +signal ROM4_n : std_logic := '1'; +signal ROMCE_n : std_logic := '1'; +signal ADDRAM_n : std_logic := '1'; +signal Display_n : std_logic := '1'; +signal VBlank_Read_n : std_logic := '1'; +signal Timer_Reset_n : std_logic := '1'; +signal Collision_Read_n : std_logic := '1'; +signal Inputs_n : std_logic := '1'; +signal Test : std_logic := '0'; + +begin + +Test <= (not Test_n); + +H1 <= HCount(0); +H2 <= HCount(1); +H4 <= HCount(2); +H8 <= HCount(3); +H16 <= HCount(4); +H32 <= HCount(5); +H64 <= HCount(6); +H128 <= HCount(7); +H256 <= HCount(8); +H256_n <= (not HCount(8)); + +V8 <= VCount(3); +V16 <= VCount(4); +V32 <= VCount(5); +V64 <= VCount(6); +V128 <= VCount(7); + + +CPU: entity work.T65 +port map( + Enable => '1', + Mode => "00", + Res_n => reset_n, + Clk => phi1, + Rdy => '1', + Abort_n => '1', + IRQ_n => '1', + NMI_n => NMI_n, + SO_n => '1', + R_W_n => RW_n, + A(15 downto 0) => A, + DI => cpuDin, + DO => cpuDout + ); + +DBus_n <= (not cpuDout); -- Data bus to video RAM is inverted +DBus <= cpuDout; +ABus <= ADR; +ADR(15 downto 10) <= A(15 downto 10); +ADR(9 downto 8) <= (A(9) or WRAM) & (A(8) or WRAM); +ADR(7 downto 0) <= A(7 downto 0); +RnW <= (not RW_n); + +NMI_n <= ((not V32) or Test); + +-- DFF and logic used to generate the Write_n signal +R10: process(H1, H2) +begin + if rising_edge(H1) then + R10_Q <= (not H2); + end if; +end process; +Write_n <= (phi2 and R10_Q) nand RnW; + + +-- CPU clock and phase 2 clock output +Phi2 <= H4; +Phi1 <= (not PHI2); +Phi1_O <= PHI1; +Phi2_O <= PHI2; + + +-- Program ROMs +N1: entity work.sprom +generic map( + init_file => "rtl/roms/030180n1.hex", + widthad_a => 11, + width_a => 4) +port map( + clock => clk6, + address => ADR(10 downto 0), + q => rom3_dout(3 downto 0) + ); + +K1: entity work.sprom +generic map( + init_file => "rtl/roms/030181k1.hex", + widthad_a => 11, + width_a => 4) +port map( + clock => clk6, + address => ADR(10 downto 0), + q => rom3_dout(7 downto 4) + ); + +M1: entity work.sprom +generic map( + init_file => "rtl/roms/030182m1.hex", + widthad_a => 11, + width_a => 4) +port map( + clock => clk6, + address => ADR(10 downto 0), + q => rom4_dout(3 downto 0) + ); + +L1: entity work.sprom +generic map( + init_file => "rtl/roms/030183l1.hex", + widthad_a => 11, + width_a => 4) +port map( + clock => clk6, + address => ADR(10 downto 0), + q => rom4_dout(7 downto 4) + ); + +-- ROM data mux +ROM_mux_in <= (ROM4_n & ROM3_n); +ROM_mux: process(ROM_mux_in, rom3_dout, rom4_dout) + begin + ROM_dout <= (others => '0'); + case ROM_mux_in is + when "10" => rom_dout <= rom3_dout; + when "01" => rom_dout <= rom4_dout; + when others => null; + end case; +end process; +ROMCE_n <= (ROM3_n and ROM4_n); + + +-- Additional CPU RAM - Many earlier games use only a single RAM as both CPU and video RAM. This hardware has a separate 128 byte RAM +A1: entity work.spram +generic map( + widthad_a => 7, + width_a => 8) +port map( + clock => clk6, + address => Adr(6 downto 0), + wren => (not Write_n) and (not ADDRAM_n) and (not Adr(7)), + data => cpuDout, + q => AddRAM_dout + ); + +--A1: entity work.ram128 +--port map( +-- clock => clk6, +-- address => Adr(6 downto 0), +-- wren => (not Write_n) and (not ADDRAM_n) and (not Adr(7)), +-- data => cpuDout, +-- q => AddRAM_dout +-- ); + + +-- Video RAM +RAM: entity work.spram +generic map( + widthad_a => 10, + width_a => 8) +port map( + clock => clk6, + address => RAM_addr, + wren => RAM_we, + data => DBus_n, + q => RAM_dout + ); + +--RAM: entity work.ram1k +--port map( +-- clock => clk6, +-- address => RAM_addr, +-- wren => RAM_we, +-- data => DBus_n, +-- q => RAM_dout +-- ); + + +-- Altera block RAM has active high WE, original RAM had active low WE +ram_we <= (not Write_n) and (not Display_n); + +Vram_addr <= (V128 or H256_n) & (V64 or H256_n) & (V32 or H256_n) & (V16 and H256) & (V8 and H256) & H128 & H64 & H32 & H16 & H8; + +RAM_addr <= Vram_addr when phi2 = '0' else Adr(9 downto 0); + +PRAM <= (not RAM_dout); + + +-- Rising edge of phi2 clock latches inverted and non-inverted output of VRAM data bus into DMA and DMA_n complementary buses +F5: process(phi2, PRAM) +begin + if rising_edge(phi2) then + DMA <= PRAM; + DMA_n <= (not PRAM); + end if; +end process; + + +-- Address decoder +B2_in <= '0' & Adr(13 downto 11); -- AND gate C4 is involved with Adr(15), function unknown +B2: process(B2_in) +begin + case B2_in is + when "0000" => + B2_out <= "1111111110"; + when "0001" => + B2_out <= "1111111101"; + when "0010" => + B2_out <= "1111111011"; + when "0011" => + B2_out <= "1111110111"; + when "0100" => + B2_out <= "1111101111"; + when "0110" => + B2_out <= "1110111111"; + when "0111" => + B2_out <= "1101111111"; + when others => + B2_out <= "1111111111"; + end case; +end process; +ADDRAM_n <= B2_out(0); +VBlank_Read_n <= B2_out(2); +Barrier_Read_n <= B2_out(3); +ROM3_n <= B2_out(6); +ROM4_n <= B2_out(7); +WRAM <= not ((not Adr(7)) or B2_out(0)); +Display_n <= (not WRAM) and B2_out(1); +RAM_n <= (Display_n or RnW); + + +D4_8 <= not ( (not B2_out(4)) and (not Adr(7)) and (Write_n nand (Phi2 nand RW_n))); + +N10_in <= D4_8 & RnW & Adr(6 downto 5); +N10: process(N10_in) +begin + case N10_in is + when "0000" => + N10_out <= "1111111110"; + when "0001" => + N10_out <= "1111111101"; + when "0010" => + N10_out <= "1111111011"; + when "0011" => + N10_out <= "1111110111"; + when "0100" => + N10_out <= "1111101111"; + when "0101" => + N10_out <= "1111011111"; + when "0110" => + N10_out <= "1110111111"; + when "0111" => + N10_out <= "1101111111"; + when "1000" => + N10_out <= "1011111111"; + when "1001" => + N10_out <= "0111111111"; + when others => + N10_out <= "1111111111"; + end case; +end process; +Throttle_Read_n <= N10_out(0); +Coin_Read_n <= N10_out(1); +Collision_Read_n <= N10_out(2); +Options_Read_n <= N10_out(3); + +-- Used for CPU data-in mux, asserts to read inputs +Inputs_n <= B2_out(3) and N10_out(0) and N10_out(1) and N10_out(2) and N10_out(3) and B2_out(3); + +-- DFF that creates the Attract and Attract_n signals +R_10: process(N10_out, DBus_n, Attract) +begin + if rising_edge(N10_out(4)) then + Attract <= DBus_n(0); + end if; + Attract_n <= (not Attract); +end process; + +-- 9321 dual decoder at M10 creates collision reset, watchdog reset, explosion sound and input DA latch signals +M10: process(N10_out, Adr) +begin + if N10_out(5) = '1' then + M10_out_A <= "1111"; + else + case Adr(2 downto 1) is + when "00" => M10_out_A <= "1110"; + when "01" => M10_out_A <= "1101"; + when "10" => M10_out_A <= "1011"; + when "11" => M10_out_A <= "0111"; + when others => M10_out_A <= "1111"; + end case; + end if; + if N10_out(6) = '1' then + M10_out_B <= "1111"; + else + case Adr(2 downto 1) is + when "00" => M10_out_B <= "1110"; + when "01" => M10_out_B <= "1101"; + when "10" => M10_out_B <= "1011"; + when "11" => M10_out_B <= "0111"; + when others => M10_out_B <= "1111"; + end case; + end if; +end process; +CollReset_n <= M10_out_A; +Timer_Reset_n <= M10_out_B(2); +Wr_Explosion_n <= M10_out_B(1); +Wr_DA_Latch_n <= M10_out_B(0); + + +-- E11 9334 addressable latch drives shell fire sound triggers, player start button LEDs and coin mech lockout coil +E11: process(clk6, N10_out, Adr) +begin +if rising_edge(clk6) then + if (N10_out(7) = '0') then + case Adr(3 downto 1) is + when "000" => null; + when "001" => null; + when "010" => null; + when "011" => Lockout_n <= Adr(0); + when "100" => LED1 <= Adr(0); + when "101" => LED2 <= Adr(0); + when "110" => Fire2 <= Adr(0); + when "111" => Fire1 <= Adr(0); + when others => null; + end case; + end if; + end if; +end process; + + +-- CPU Din mux, no tristate logic in modern FPGAs so this mux is used to select the source to the CPU data-in bus +cpuDin <= + PRAM when (RAM_n = '0') and (Display_n = '0') else -- Video RAM + AddRAM_dout when (ADDRAM_n or Adr(7)) = '0' else -- Additional RAM + ROM_dout when ROMCE_n = '0' else -- Program ROM + VBlank_n_s & Test_n & "111111" when Vblank_Read_n = '0' else -- VBlank and Self Test switch + Collision_n & "1111111" when Collision_Read_n = '0' else -- Collision Detection + DB_in when Inputs_n = '0' else -- Inputs + x"FF"; +end rtl; + diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/dac.sv b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/dac.sv new file mode 100644 index 00000000..22ae8f07 --- /dev/null +++ b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/dac.sv @@ -0,0 +1,33 @@ +// +// PWM DAC +// +// MSBI is the highest bit number. NOT amount of bits! +// +module dac #(parameter MSBI=6, parameter INV=1'b1) +( + output reg DACout, //Average Output feeding analog lowpass + input [MSBI:0] DACin, //DAC input (excess 2**MSBI) + input CLK, + input RESET +); + +reg [MSBI+2:0] DeltaAdder; //Output of Delta Adder +reg [MSBI+2:0] SigmaAdder; //Output of Sigma Adder +reg [MSBI+2:0] SigmaLatch; //Latches output of Sigma Adder +reg [MSBI+2:0] DeltaB; //B input of Delta Adder + +always @(*) DeltaB = {SigmaLatch[MSBI+2], SigmaLatch[MSBI+2]} << (MSBI+1); +always @(*) DeltaAdder = DACin + DeltaB; +always @(*) SigmaAdder = DeltaAdder + SigmaLatch; + +always @(posedge CLK or posedge RESET) begin + if(RESET) begin + SigmaLatch <= 1'b1 << (MSBI+1); + DACout <= INV; + end else begin + SigmaLatch <= SigmaAdder; + DACout <= SigmaLatch[MSBI+2] ^ INV; + end +end + +endmodule diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/hq2x.sv b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/hq2x.sv new file mode 100644 index 00000000..f17732b6 --- /dev/null +++ b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/hq2x.sv @@ -0,0 +1,454 @@ +// +// +// Copyright (c) 2012-2013 Ludvig Strigeus +// Copyright (c) 2017 Sorgelig +// +// This program is GPL Licensed. See COPYING for the full license. +// +// +//////////////////////////////////////////////////////////////////////////////////////////////////////// + +// synopsys translate_off +`timescale 1 ps / 1 ps +// synopsys translate_on + +`define BITS_TO_FIT(N) ( \ + N <= 2 ? 0 : \ + N <= 4 ? 1 : \ + N <= 8 ? 2 : \ + N <= 16 ? 3 : \ + N <= 32 ? 4 : \ + N <= 64 ? 5 : \ + N <= 128 ? 6 : \ + N <= 256 ? 7 : \ + N <= 512 ? 8 : \ + N <=1024 ? 9 : 10 ) + +module hq2x_in #(parameter LENGTH, parameter DWIDTH) +( + input clk, + + input [AWIDTH:0] rdaddr, + input rdbuf, + output[DWIDTH:0] q, + + input [AWIDTH:0] wraddr, + input wrbuf, + input [DWIDTH:0] data, + input wren +); + + localparam AWIDTH = `BITS_TO_FIT(LENGTH); + wire [DWIDTH:0] out[2]; + assign q = out[rdbuf]; + + hq2x_buf #(.NUMWORDS(LENGTH), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf0(clk,data,rdaddr,wraddr,wren && (wrbuf == 0),out[0]); + hq2x_buf #(.NUMWORDS(LENGTH), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf1(clk,data,rdaddr,wraddr,wren && (wrbuf == 1),out[1]); +endmodule + + +module hq2x_out #(parameter LENGTH, parameter DWIDTH) +( + input clk, + + input [AWIDTH:0] rdaddr, + input [1:0] rdbuf, + output[DWIDTH:0] q, + + input [AWIDTH:0] wraddr, + input [1:0] wrbuf, + input [DWIDTH:0] data, + input wren +); + + localparam AWIDTH = `BITS_TO_FIT(LENGTH*2); + wire [DWIDTH:0] out[4]; + assign q = out[rdbuf]; + + hq2x_buf #(.NUMWORDS(LENGTH*2), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf0(clk,data,rdaddr,wraddr,wren && (wrbuf == 0),out[0]); + hq2x_buf #(.NUMWORDS(LENGTH*2), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf1(clk,data,rdaddr,wraddr,wren && (wrbuf == 1),out[1]); + hq2x_buf #(.NUMWORDS(LENGTH*2), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf2(clk,data,rdaddr,wraddr,wren && (wrbuf == 2),out[2]); + hq2x_buf #(.NUMWORDS(LENGTH*2), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf3(clk,data,rdaddr,wraddr,wren && (wrbuf == 3),out[3]); +endmodule + + +module hq2x_buf #(parameter NUMWORDS, parameter AWIDTH, parameter DWIDTH) +( + input clock, + input [DWIDTH:0] data, + input [AWIDTH:0] rdaddress, + input [AWIDTH:0] wraddress, + input wren, + output [DWIDTH:0] q +); + + altsyncram altsyncram_component ( + .address_a (wraddress), + .clock0 (clock), + .data_a (data), + .wren_a (wren), + .address_b (rdaddress), + .q_b(q), + .aclr0 (1'b0), + .aclr1 (1'b0), + .addressstall_a (1'b0), + .addressstall_b (1'b0), + .byteena_a (1'b1), + .byteena_b (1'b1), + .clock1 (1'b1), + .clocken0 (1'b1), + .clocken1 (1'b1), + .clocken2 (1'b1), + .clocken3 (1'b1), + .data_b ({(DWIDTH+1){1'b1}}), + .eccstatus (), + .q_a (), + .rden_a (1'b1), + .rden_b (1'b1), + .wren_b (1'b0)); + defparam + altsyncram_component.address_aclr_b = "NONE", + altsyncram_component.address_reg_b = "CLOCK0", + altsyncram_component.clock_enable_input_a = "BYPASS", + altsyncram_component.clock_enable_input_b = "BYPASS", + altsyncram_component.clock_enable_output_b = "BYPASS", + altsyncram_component.intended_device_family = "Cyclone III", + altsyncram_component.lpm_type = "altsyncram", + altsyncram_component.numwords_a = NUMWORDS, + altsyncram_component.numwords_b = NUMWORDS, + altsyncram_component.operation_mode = "DUAL_PORT", + altsyncram_component.outdata_aclr_b = "NONE", + altsyncram_component.outdata_reg_b = "UNREGISTERED", + altsyncram_component.power_up_uninitialized = "FALSE", + altsyncram_component.read_during_write_mode_mixed_ports = "DONT_CARE", + altsyncram_component.widthad_a = AWIDTH+1, + altsyncram_component.widthad_b = AWIDTH+1, + altsyncram_component.width_a = DWIDTH+1, + altsyncram_component.width_b = DWIDTH+1, + altsyncram_component.width_byteena_a = 1; + +endmodule + +//////////////////////////////////////////////////////////////////////////////////////////////////////// + +module DiffCheck +( + input [17:0] rgb1, + input [17:0] rgb2, + output result +); + + wire [5:0] r = rgb1[5:1] - rgb2[5:1]; + wire [5:0] g = rgb1[11:7] - rgb2[11:7]; + wire [5:0] b = rgb1[17:13] - rgb2[17:13]; + wire [6:0] t = $signed(r) + $signed(b); + wire [6:0] gx = {g[5], g}; + wire [7:0] y = $signed(t) + $signed(gx); + wire [6:0] u = $signed(r) - $signed(b); + wire [7:0] v = $signed({g, 1'b0}) - $signed(t); + + // if y is inside (-24..24) + wire y_inside = (y < 8'h18 || y >= 8'he8); + + // if u is inside (-4, 4) + wire u_inside = (u < 7'h4 || u >= 7'h7c); + + // if v is inside (-6, 6) + wire v_inside = (v < 8'h6 || v >= 8'hfA); + assign result = !(y_inside && u_inside && v_inside); +endmodule + +module InnerBlend +( + input [8:0] Op, + input [5:0] A, + input [5:0] B, + input [5:0] C, + output [5:0] O +); + + function [8:0] mul6x3; + input [5:0] op1; + input [2:0] op2; + begin + mul6x3 = 9'd0; + if(op2[0]) mul6x3 = mul6x3 + op1; + if(op2[1]) mul6x3 = mul6x3 + {op1, 1'b0}; + if(op2[2]) mul6x3 = mul6x3 + {op1, 2'b00}; + end + endfunction + + wire OpOnes = Op[4]; + wire [8:0] Amul = mul6x3(A, Op[7:5]); + wire [8:0] Bmul = mul6x3(B, {Op[3:2], 1'b0}); + wire [8:0] Cmul = mul6x3(C, {Op[1:0], 1'b0}); + wire [8:0] At = Amul; + wire [8:0] Bt = (OpOnes == 0) ? Bmul : {3'b0, B}; + wire [8:0] Ct = (OpOnes == 0) ? Cmul : {3'b0, C}; + wire [9:0] Res = {At, 1'b0} + Bt + Ct; + assign O = Op[8] ? A : Res[9:4]; +endmodule + +module Blend +( + input [5:0] rule, + input disable_hq2x, + input [17:0] E, + input [17:0] A, + input [17:0] B, + input [17:0] D, + input [17:0] F, + input [17:0] H, + output [17:0] Result +); + + reg [1:0] input_ctrl; + reg [8:0] op; + localparam BLEND0 = 9'b1_xxx_x_xx_xx; // 0: A + localparam BLEND1 = 9'b0_110_0_10_00; // 1: (A * 12 + B * 4) >> 4 + localparam BLEND2 = 9'b0_100_0_10_10; // 2: (A * 8 + B * 4 + C * 4) >> 4 + localparam BLEND3 = 9'b0_101_0_10_01; // 3: (A * 10 + B * 4 + C * 2) >> 4 + localparam BLEND4 = 9'b0_110_0_01_01; // 4: (A * 12 + B * 2 + C * 2) >> 4 + localparam BLEND5 = 9'b0_010_0_11_11; // 5: (A * 4 + (B + C) * 6) >> 4 + localparam BLEND6 = 9'b0_111_1_xx_xx; // 6: (A * 14 + B + C) >> 4 + localparam AB = 2'b00; + localparam AD = 2'b01; + localparam DB = 2'b10; + localparam BD = 2'b11; + wire is_diff; + DiffCheck diff_checker(rule[1] ? B : H, rule[0] ? D : F, is_diff); + + always @* begin + case({!is_diff, rule[5:2]}) + 1,17: {op, input_ctrl} = {BLEND1, AB}; + 2,18: {op, input_ctrl} = {BLEND1, DB}; + 3,19: {op, input_ctrl} = {BLEND1, BD}; + 4,20: {op, input_ctrl} = {BLEND2, DB}; + 5,21: {op, input_ctrl} = {BLEND2, AB}; + 6,22: {op, input_ctrl} = {BLEND2, AD}; + + 8: {op, input_ctrl} = {BLEND0, 2'bxx}; + 9: {op, input_ctrl} = {BLEND0, 2'bxx}; + 10: {op, input_ctrl} = {BLEND0, 2'bxx}; + 11: {op, input_ctrl} = {BLEND1, AB}; + 12: {op, input_ctrl} = {BLEND1, AB}; + 13: {op, input_ctrl} = {BLEND1, AB}; + 14: {op, input_ctrl} = {BLEND1, DB}; + 15: {op, input_ctrl} = {BLEND1, BD}; + + 24: {op, input_ctrl} = {BLEND2, DB}; + 25: {op, input_ctrl} = {BLEND5, DB}; + 26: {op, input_ctrl} = {BLEND6, DB}; + 27: {op, input_ctrl} = {BLEND2, DB}; + 28: {op, input_ctrl} = {BLEND4, DB}; + 29: {op, input_ctrl} = {BLEND5, DB}; + 30: {op, input_ctrl} = {BLEND3, BD}; + 31: {op, input_ctrl} = {BLEND3, DB}; + default: {op, input_ctrl} = 11'bx; + endcase + + // Setting op[8] effectively disables HQ2X because blend will always return E. + if (disable_hq2x) op[8] = 1; + end + + // Generate inputs to the inner blender. Valid combinations. + // 00: E A B + // 01: E A D + // 10: E D B + // 11: E B D + wire [17:0] Input1 = E; + wire [17:0] Input2 = !input_ctrl[1] ? A : + !input_ctrl[0] ? D : B; + + wire [17:0] Input3 = !input_ctrl[0] ? B : D; + InnerBlend inner_blend1(op, Input1[5:0], Input2[5:0], Input3[5:0], Result[5:0]); + InnerBlend inner_blend2(op, Input1[11:6], Input2[11:6], Input3[11:6], Result[11:6]); + InnerBlend inner_blend3(op, Input1[17:12], Input2[17:12], Input3[17:12], Result[17:12]); +endmodule + + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +module Hq2x #(parameter LENGTH, parameter HALF_DEPTH) +( + input clk, + input ce_x4, + input [DWIDTH:0] inputpixel, + input mono, + input disable_hq2x, + input reset_frame, + input reset_line, + input [1:0] read_y, + input [AWIDTH+1:0] read_x, + output [DWIDTH:0] outpixel +); + + +localparam AWIDTH = `BITS_TO_FIT(LENGTH); +localparam DWIDTH = HALF_DEPTH ? 8 : 17; + +wire [5:0] hqTable[256] = '{ + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 47, 35, 23, 15, 55, 39, + 19, 19, 26, 58, 19, 19, 26, 58, 23, 15, 35, 35, 23, 15, 7, 35, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 55, 39, 23, 15, 51, 43, + 19, 19, 26, 58, 19, 19, 26, 58, 23, 15, 51, 35, 23, 15, 7, 43, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 61, 35, 35, 23, 61, 51, 35, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 51, 35, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 61, 7, 35, 23, 61, 7, 43, + 19, 19, 26, 11, 19, 19, 26, 58, 23, 15, 51, 35, 23, 61, 7, 43, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 47, 35, 23, 15, 55, 39, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 51, 35, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 55, 39, 23, 15, 51, 43, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 39, 23, 15, 7, 43, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 51, 39, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 7, 35, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 7, 43, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 7, 35, 23, 15, 7, 43 +}; + +reg [17:0] Prev0, Prev1, Prev2, Curr0, Curr1, Next0, Next1, Next2; +reg [17:0] A, B, D, F, G, H; +reg [7:0] pattern, nextpatt; +reg [1:0] i; +reg [7:0] y; + +wire curbuf = y[0]; +reg prevbuf = 0; +wire iobuf = !curbuf; + +wire diff0, diff1; +DiffCheck diffcheck0(Curr1, (i == 0) ? Prev0 : (i == 1) ? Curr0 : (i == 2) ? Prev2 : Next1, diff0); +DiffCheck diffcheck1(Curr1, (i == 0) ? Prev1 : (i == 1) ? Next0 : (i == 2) ? Curr2 : Next2, diff1); + +wire [7:0] new_pattern = {diff1, diff0, pattern[7:2]}; + +wire [17:0] X = (i == 0) ? A : (i == 1) ? Prev1 : (i == 2) ? Next1 : G; +wire [17:0] blend_result; +Blend blender(hqTable[nextpatt], disable_hq2x, Curr0, X, B, D, F, H, blend_result); + +reg Curr2_addr1; +reg [AWIDTH:0] Curr2_addr2; +wire [17:0] Curr2 = HALF_DEPTH ? h2rgb(Curr2tmp) : Curr2tmp; +wire [DWIDTH:0] Curr2tmp; + +reg [AWIDTH:0] wrin_addr2; +reg [DWIDTH:0] wrpix; +reg wrin_en; + +function [17:0] h2rgb; + input [8:0] v; +begin + h2rgb = mono ? {v[5:3],v[2:0], v[5:3],v[2:0], v[5:3],v[2:0]} : {v[8:6],v[8:6],v[5:3],v[5:3],v[2:0],v[2:0]}; +end +endfunction + +function [8:0] rgb2h; + input [17:0] v; +begin + rgb2h = mono ? {3'b000, v[17:15], v[14:12]} : {v[17:15], v[11:9], v[5:3]}; +end +endfunction + +hq2x_in #(.LENGTH(LENGTH), .DWIDTH(DWIDTH)) hq2x_in +( + .clk(clk), + + .rdaddr(Curr2_addr2), + .rdbuf(Curr2_addr1), + .q(Curr2tmp), + + .wraddr(wrin_addr2), + .wrbuf(iobuf), + .data(wrpix), + .wren(wrin_en) +); + +reg [1:0] wrout_addr1; +reg [AWIDTH+1:0] wrout_addr2; +reg wrout_en; +reg [DWIDTH:0] wrdata; + +hq2x_out #(.LENGTH(LENGTH), .DWIDTH(DWIDTH)) hq2x_out +( + .clk(clk), + + .rdaddr(read_x), + .rdbuf(read_y), + .q(outpixel), + + .wraddr(wrout_addr2), + .wrbuf(wrout_addr1), + .data(wrdata), + .wren(wrout_en) +); + +always @(posedge clk) begin + reg [AWIDTH:0] offs; + reg old_reset_line; + reg old_reset_frame; + + wrout_en <= 0; + wrin_en <= 0; + + if(ce_x4) begin + + pattern <= new_pattern; + + if(~&offs) begin + if (i == 0) begin + Curr2_addr1 <= prevbuf; + Curr2_addr2 <= offs; + end + if (i == 1) begin + Prev2 <= Curr2; + Curr2_addr1 <= curbuf; + Curr2_addr2 <= offs; + end + if (i == 2) begin + Next2 <= HALF_DEPTH ? h2rgb(inputpixel) : inputpixel; + wrpix <= inputpixel; + wrin_addr2 <= offs; + wrin_en <= 1; + end + if (i == 3) begin + offs <= offs + 1'd1; + end + + if(HALF_DEPTH) wrdata <= rgb2h(blend_result); + else wrdata <= blend_result; + + wrout_addr1 <= {curbuf, i[1]}; + wrout_addr2 <= {offs, i[1]^i[0]}; + wrout_en <= 1; + end + + if(i==3) begin + nextpatt <= {new_pattern[7:6], new_pattern[3], new_pattern[5], new_pattern[2], new_pattern[4], new_pattern[1:0]}; + {A, G} <= {Prev0, Next0}; + {B, F, H, D} <= {Prev1, Curr2, Next1, Curr0}; + {Prev0, Prev1} <= {Prev1, Prev2}; + {Curr0, Curr1} <= {Curr1, Curr2}; + {Next0, Next1} <= {Next1, Next2}; + end else begin + nextpatt <= {nextpatt[5], nextpatt[3], nextpatt[0], nextpatt[6], nextpatt[1], nextpatt[7], nextpatt[4], nextpatt[2]}; + {B, F, H, D} <= {F, H, D, B}; + end + + i <= i + 1'b1; + if(old_reset_line && ~reset_line) begin + old_reset_frame <= reset_frame; + offs <= 0; + i <= 0; + y <= y + 1'd1; + prevbuf <= curbuf; + if(old_reset_frame & ~reset_frame) begin + y <= 0; + prevbuf <= 0; + end + end + + old_reset_line <= reset_line; + end +end + +endmodule // Hq2x diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/inputs.vhd b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/inputs.vhd new file mode 100644 index 00000000..98aefa4e --- /dev/null +++ b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/inputs.vhd @@ -0,0 +1,140 @@ +-- Input module for Kee Games Ultra Tank +-- 2017 James Sweet +-- +-- This is free software: you can redistribute +-- it and/or modify it under the terms of the GNU General +-- Public License as published by the Free Software +-- Foundation, either version 3 of the License, or (at your +-- option) any later version. +-- +-- This is distributed in the hope that it will +-- be useful, but WITHOUT ANY WARRANTY; without even the +-- implied warranty of MERCHANTABILITY or FITNESS FOR A +-- PARTICULAR PURPOSE. See the GNU General Public License +-- for more details. + +library IEEE; +use IEEE.STD_LOGIC_1164.all; + +entity control_inputs is +port( + clk6 : in std_logic; + DipSw : in std_logic_vector(7 downto 0); + Coin1_n : in std_logic; + Coin2_n : in std_logic; + Start1_n : in std_logic; + Start2_n : in std_logic; + Invisible_n : in std_logic; + Rebound_n : in std_logic; + Barrier_n : in std_logic; + JoyW_Fw : in std_logic; + JoyW_Bk : in std_logic; + JoyY_Fw : in std_logic; + JoyY_Bk : in std_logic; + JoyX_Fw : in std_logic; + JoyX_Bk : in std_logic; + JoyZ_Fw : in std_logic; + JoyZ_Bk : in std_logic; + FireA_n : in std_logic; + FireB_n : in std_logic; + Throttle_Read_n : in std_logic; + Coin_Read_n : in std_logic; + Options_Read_n : in std_logic; + Barrier_Read_n : in std_logic; + Wr_DA_Latch_n : in std_logic; + Adr : in std_logic_vector(2 downto 0); + DBus : in std_logic_vector(3 downto 0); + Dout : out std_logic_vector(7 downto 0) + ); +end control_inputs; + +architecture rtl of control_inputs is + + +signal Coin : std_logic := '1'; +signal Coin1 : std_logic := '0'; +signal Coin2 : std_logic := '0'; +signal Options : std_logic_vector(1 downto 0) := "11"; +signal Throttle : std_logic := '1'; +signal DA_latch : std_logic_vector(3 downto 0) := (others => '0'); +signal JoyW : std_logic; +signal JoyX : std_logic; +signal JoyY : std_logic; +signal JoyZ : std_logic; + + +begin + +-- Joysticks use a clever analog multiplexing in the real hardware in order to reduce the pins required +-- in the wiring harness to the board. For an FPGA this would require additional hardware and complexity +-- so this has been re-worked to provide individual active-low inputs + +--- E6 is a quad synchronous latch driving a 4 bit resistor DAC +E6: process(Clk6, Wr_DA_Latch_n, DBus) +begin + if falling_edge(Wr_DA_Latch_n) then + DA_latch <= (not DBus); + end if; +end process; + +-- Each joystick input goes to a comparator that compares it with a reference voltage coming from the DAC +-- Here we dispense with the DAC and use separate inputs for each of the two switches in each joystick +JoyW <= JoyW_Fw and (JoyW_Bk or DA_latch(0)); +JoyY <= JoyY_Fw and (JoyY_Bk or DA_latch(0)); +JoyX <= JoyX_Fw and (JoyX_Bk or DA_latch(1)); +JoyZ <= JoyZ_Fw and (JoyZ_Bk or DA_latch(1)); + +-- 9312 Data Selector/Multiplexer at K11 +K11: process(Adr, Start1_n, Start2_n, FireA_n, FireB_n, JoyW, JoyY, JoyX, JoyZ) +begin + case Adr(2 downto 0) is + when "000" => Throttle <= Start1_n; + when "001" => Throttle <= JoyW; + when "010" => Throttle <= Start2_n; + when "011" => Throttle <= JoyY; + when "100" => Throttle <= FireA_n; + when "101" => Throttle <= JoyX; + when "110" => Throttle <= FireB_n; + when "111" => Throttle <= JoyZ; + when others => Throttle <= '0'; + end case; +end process; + +-- 9312 Data Selector/Multiplexer at F10 +F10: process(Adr, Coin1_n, Coin2_n, Invisible_n, Rebound_n) +begin + case Adr(2 downto 0) is + when "000" => Coin <= (not Coin1_n); + when "001" => Coin <= '1'; + when "010" => Coin <= (not Coin2_n); + when "011" => Coin <= '1'; + when "100" => Coin <= (not Invisible_n); + when "101" => Coin <= '1'; + when "110" => Coin <= (not Rebound_n); + when "111" => Coin <= '1'; + when others => Coin <= '0'; + end case; +end process; + + +-- Configuration DIP switches +N9: process(Adr(1 downto 0), DipSw) +begin + case Adr(1 downto 0) is + when "00" => Options <= DipSw(0) & DipSw(1); + when "01" => Options <= DipSw(2) & DipSw(3); + when "10" => Options <= DipSw(4) & DipSw(5); + when "11" => Options <= DipSw(6) & DipSw(7); + when others => Options <= "11"; + end case; +end process; + + +-- Inputs data mux +Dout <= Throttle & "1111111" when Throttle_Read_n = '0' else + Coin & "1111111" when Coin_Read_n = '0' else + Barrier_n & "1111111" when Barrier_Read_n = '0' else + "111111" & Options when Options_Read_n = '0' else + x"FF"; + +end rtl; \ No newline at end of file diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/keyboard.sv b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/keyboard.sv new file mode 100644 index 00000000..ce182b0a --- /dev/null +++ b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/keyboard.sv @@ -0,0 +1,84 @@ + + +module keyboard +( + input clk, + input reset, + input ps2_kbd_clk, + input ps2_kbd_data, + + output reg[11:0] joystick +); + +reg [11:0] shift_reg = 12'hFFF; +wire[11:0] kdata = {ps2_kbd_data,shift_reg[11:1]}; +wire [7:0] kcode = kdata[9:2]; +reg release_btn = 0; + +reg [7:0] code; +reg input_strobe = 0; + +always @(negedge clk) begin + reg old_reset = 0; + + old_reset <= reset; + + if(~old_reset & reset)begin + joystick <= 0; + end + + if(input_strobe) begin + case(code) + '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 + + 'h29: joystick[4] <= ~release_btn; // Space + 'h05: joystick[5] <= ~release_btn; // F1 + 'h06: joystick[6] <= ~release_btn; // F2 + 'h76: joystick[7] <= ~release_btn; // Escape + + 'h69: joystick[8] <= ~release_btn; // 1 + 'h72: joystick[9] <= ~release_btn; // 2 + 'h7A: joystick[10] <= ~release_btn; // 3 + 'h6B: joystick[11] <= ~release_btn; // 4 + endcase + end +end + +always @(posedge clk) begin + reg [3:0] prev_clk = 0; + reg old_reset = 0; + reg action = 0; + + old_reset <= reset; + input_strobe <= 0; + + if(~old_reset & reset)begin + prev_clk <= 0; + shift_reg <= 12'hFFF; + end else begin + prev_clk <= {ps2_kbd_clk,prev_clk[3:1]}; + if(prev_clk == 1) begin + if (kdata[11] & ^kdata[10:2] & ~kdata[1] & kdata[0]) begin + shift_reg <= 12'hFFF; + if (kcode == 8'he0) ; + // Extended key code follows + else if (kcode == 8'hf0) + // Release code follows + action <= 1; + else begin + // Cancel extended/release flags for next time + action <= 0; + release_btn <= action; + code <= kcode; + input_strobe <= 1; + end + end else begin + shift_reg <= kdata; + end + end + end +end +endmodule diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/mist_io.sv b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/mist_io.sv new file mode 100644 index 00000000..dcc7ecde --- /dev/null +++ b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/mist_io.sv @@ -0,0 +1,491 @@ +// +// mist_io.v +// +// mist_io for the MiST board +// http://code.google.com/p/mist-board/ +// +// Copyright (c) 2014 Till Harbaum +// +// This source file is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This source file is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +/////////////////////////////////////////////////////////////////////// + +// +// Use buffer to access SD card. It's time-critical part. +// Made module synchroneous with 2 clock domains: clk_sys and SPI_SCK +// (Sorgelig) +// +// for synchronous projects default value for PS2DIV is fine for any frequency of system clock. +// clk_ps2 = clk_sys/(PS2DIV*2) +// + +module mist_io #(parameter STRLEN=0, parameter PS2DIV=100) +( + + // parameter STRLEN and the actual length of conf_str have to match + input [(8*STRLEN)-1:0] conf_str, + + // Global clock. It should be around 100MHz (higher is better). + input clk_sys, + + // Global SPI clock from ARM. 24MHz + input SPI_SCK, + + input CONF_DATA0, + input SPI_SS2, + output SPI_DO, + input SPI_DI, + + output reg [7:0] joystick_0, + output reg [7:0] joystick_1, + output reg [15:0] joystick_analog_0, + output reg [15:0] joystick_analog_1, + output [1:0] buttons, + output [1:0] switches, + output scandoubler_disable, + output ypbpr, + + output reg [31:0] status, + + // SD config + input sd_conf, + input sd_sdhc, + output img_mounted, // signaling that new image has been mounted + output reg [31:0] img_size, // size of image in bytes + + // SD block level access + input [31:0] sd_lba, + input sd_rd, + input sd_wr, + output reg sd_ack, + output reg sd_ack_conf, + + // SD byte level access. Signals for 2-PORT altsyncram. + output reg [8:0] sd_buff_addr, + output reg [7:0] sd_buff_dout, + input [7:0] sd_buff_din, + output reg sd_buff_wr, + + // ps2 keyboard emulation + output ps2_kbd_clk, + output reg ps2_kbd_data, + output ps2_mouse_clk, + output reg ps2_mouse_data, + input ps2_caps_led, + + // ARM -> FPGA download + output reg ioctl_download = 0, // signal indicating an active download + output reg [7:0] ioctl_index, // menu index used to upload the file + output ioctl_wr, + output reg [23:0] ioctl_addr, + output reg [7:0] ioctl_dout +); + +reg [7:0] b_data; +reg [6:0] sbuf; +reg [7:0] cmd; +reg [2:0] bit_cnt; // counts bits 0-7 0-7 ... +reg [9:0] byte_cnt; // counts bytes +reg [7:0] but_sw; +reg [2:0] stick_idx; + +reg mount_strobe = 0; +assign img_mounted = mount_strobe; + +assign buttons = but_sw[1:0]; +assign switches = but_sw[3:2]; +assign scandoubler_disable = but_sw[4]; +assign ypbpr = but_sw[5]; + +wire [7:0] spi_dout = { sbuf, SPI_DI}; + +// this variant of user_io is for 8 bit cores (type == a4) only +wire [7:0] core_type = 8'ha4; + +// command byte read by the io controller +wire [7:0] sd_cmd = { 4'h5, sd_conf, sd_sdhc, sd_wr, sd_rd }; + +reg spi_do; +assign SPI_DO = CONF_DATA0 ? 1'bZ : spi_do; + +wire [7:0] kbd_led = { 2'b01, 4'b0000, ps2_caps_led, 1'b1}; + +// drive MISO only when transmitting core id +always@(negedge SPI_SCK) begin + if(!CONF_DATA0) begin + // first byte returned is always core type, further bytes are + // command dependent + if(byte_cnt == 0) begin + spi_do <= core_type[~bit_cnt]; + + end else begin + case(cmd) + // reading config string + 8'h14: begin + // returning a byte from string + if(byte_cnt < STRLEN + 1) spi_do <= conf_str[{STRLEN - byte_cnt,~bit_cnt}]; + else spi_do <= 0; + end + + // reading sd card status + 8'h16: begin + if(byte_cnt == 1) spi_do <= sd_cmd[~bit_cnt]; + else if((byte_cnt >= 2) && (byte_cnt < 6)) spi_do <= sd_lba[{5-byte_cnt, ~bit_cnt}]; + else spi_do <= 0; + end + + // reading sd card write data + 8'h18: + spi_do <= b_data[~bit_cnt]; + + // reading keyboard LED status + 8'h1f: + spi_do <= kbd_led[~bit_cnt]; + + default: + spi_do <= 0; + endcase + end + end +end + +reg b_wr2,b_wr3; +always @(negedge clk_sys) begin + b_wr3 <= b_wr2; + sd_buff_wr <= b_wr3; +end + +// SPI receiver +always@(posedge SPI_SCK or posedge CONF_DATA0) begin + + if(CONF_DATA0) begin + b_wr2 <= 0; + bit_cnt <= 0; + byte_cnt <= 0; + sd_ack <= 0; + sd_ack_conf <= 0; + end else begin + b_wr2 <= 0; + + sbuf <= spi_dout[6:0]; + bit_cnt <= bit_cnt + 1'd1; + if(bit_cnt == 5) begin + if (byte_cnt == 0) sd_buff_addr <= 0; + if((byte_cnt != 0) & (sd_buff_addr != 511)) sd_buff_addr <= sd_buff_addr + 1'b1; + if((byte_cnt == 1) & ((cmd == 8'h17) | (cmd == 8'h19))) sd_buff_addr <= 0; + end + + // finished reading command byte + if(bit_cnt == 7) begin + if(~&byte_cnt) byte_cnt <= byte_cnt + 8'd1; + if(byte_cnt == 0) begin + cmd <= spi_dout; + + if(spi_dout == 8'h19) begin + sd_ack_conf <= 1; + sd_buff_addr <= 0; + end + if((spi_dout == 8'h17) || (spi_dout == 8'h18)) begin + sd_ack <= 1; + sd_buff_addr <= 0; + end + if(spi_dout == 8'h18) b_data <= sd_buff_din; + + mount_strobe <= 0; + + end else begin + + case(cmd) + // buttons and switches + 8'h01: but_sw <= spi_dout; + 8'h02: joystick_0 <= spi_dout; + 8'h03: joystick_1 <= spi_dout; + + // store incoming ps2 mouse bytes + 8'h04: begin + ps2_mouse_fifo[ps2_mouse_wptr] <= spi_dout; + ps2_mouse_wptr <= ps2_mouse_wptr + 1'd1; + end + + // store incoming ps2 keyboard bytes + 8'h05: begin + ps2_kbd_fifo[ps2_kbd_wptr] <= spi_dout; + ps2_kbd_wptr <= ps2_kbd_wptr + 1'd1; + end + + 8'h15: status[7:0] <= spi_dout; + + // send SD config IO -> FPGA + // flag that download begins + // sd card knows data is config if sd_dout_strobe is asserted + // with sd_ack still being inactive (low) + 8'h19, + // send sector IO -> FPGA + // flag that download begins + 8'h17: begin + sd_buff_dout <= spi_dout; + b_wr2 <= 1; + end + + 8'h18: b_data <= sd_buff_din; + + // joystick analog + 8'h1a: begin + // first byte is joystick index + if(byte_cnt == 1) stick_idx <= spi_dout[2:0]; + else if(byte_cnt == 2) begin + // second byte is x axis + if(stick_idx == 0) joystick_analog_0[15:8] <= spi_dout; + else if(stick_idx == 1) joystick_analog_1[15:8] <= spi_dout; + end else if(byte_cnt == 3) begin + // third byte is y axis + if(stick_idx == 0) joystick_analog_0[7:0] <= spi_dout; + else if(stick_idx == 1) joystick_analog_1[7:0] <= spi_dout; + end + end + + // notify image selection + 8'h1c: mount_strobe <= 1; + + // send image info + 8'h1d: if(byte_cnt<5) img_size[(byte_cnt-1)<<3 +:8] <= spi_dout; + + // status, 32bit version + 8'h1e: if(byte_cnt<5) status[(byte_cnt-1)<<3 +:8] <= spi_dout; + default: ; + endcase + end + end + end +end + + +/////////////////////////////// PS2 /////////////////////////////// +// 8 byte fifos to store ps2 bytes +localparam PS2_FIFO_BITS = 3; + +reg clk_ps2; +always @(negedge clk_sys) begin + integer cnt; + cnt <= cnt + 1'd1; + if(cnt == PS2DIV) begin + clk_ps2 <= ~clk_ps2; + cnt <= 0; + end +end + +// keyboard +reg [7:0] ps2_kbd_fifo[1<= 1)&&(ps2_kbd_tx_state < 9)) begin + ps2_kbd_data <= ps2_kbd_tx_byte[0]; // data bits + ps2_kbd_tx_byte[6:0] <= ps2_kbd_tx_byte[7:1]; // shift down + if(ps2_kbd_tx_byte[0]) + ps2_kbd_parity <= !ps2_kbd_parity; + end + + // transmission of parity + if(ps2_kbd_tx_state == 9) ps2_kbd_data <= ps2_kbd_parity; + + // transmission of stop bit + if(ps2_kbd_tx_state == 10) ps2_kbd_data <= 1; // stop bit is 1 + + // advance state machine + if(ps2_kbd_tx_state < 11) ps2_kbd_tx_state <= ps2_kbd_tx_state + 1'd1; + else ps2_kbd_tx_state <= 0; + end + end +end + +// mouse +reg [7:0] ps2_mouse_fifo[1<= 1)&&(ps2_mouse_tx_state < 9)) begin + ps2_mouse_data <= ps2_mouse_tx_byte[0]; // data bits + ps2_mouse_tx_byte[6:0] <= ps2_mouse_tx_byte[7:1]; // shift down + if(ps2_mouse_tx_byte[0]) + ps2_mouse_parity <= !ps2_mouse_parity; + end + + // transmission of parity + if(ps2_mouse_tx_state == 9) ps2_mouse_data <= ps2_mouse_parity; + + // transmission of stop bit + if(ps2_mouse_tx_state == 10) ps2_mouse_data <= 1; // stop bit is 1 + + // advance state machine + if(ps2_mouse_tx_state < 11) ps2_mouse_tx_state <= ps2_mouse_tx_state + 1'd1; + else ps2_mouse_tx_state <= 0; + end + end +end + + +/////////////////////////////// DOWNLOADING /////////////////////////////// + +reg [7:0] data_w; +reg [23:0] addr_w; +reg rclk = 0; + +localparam UIO_FILE_TX = 8'h53; +localparam UIO_FILE_TX_DAT = 8'h54; +localparam UIO_FILE_INDEX = 8'h55; + +// data_io has its own SPI interface to the io controller +always@(posedge SPI_SCK, posedge SPI_SS2) begin + reg [6:0] sbuf; + reg [7:0] cmd; + reg [4:0] cnt; + reg [23:0] addr; + + if(SPI_SS2) cnt <= 0; + else begin + rclk <= 0; + + // don't shift in last bit. It is evaluated directly + // when writing to ram + if(cnt != 15) sbuf <= { sbuf[5:0], SPI_DI}; + + // increase target address after write + if(rclk) addr <= addr + 1'd1; + + // count 0-7 8-15 8-15 ... + if(cnt < 15) cnt <= cnt + 1'd1; + else cnt <= 8; + + // finished command byte + if(cnt == 7) cmd <= {sbuf, SPI_DI}; + + // prepare/end transmission + if((cmd == UIO_FILE_TX) && (cnt == 15)) begin + // prepare + if(SPI_DI) begin + addr <= 0; + ioctl_download <= 1; + end else begin + addr_w <= addr; + ioctl_download <= 0; + end + end + + // command 0x54: UIO_FILE_TX + if((cmd == UIO_FILE_TX_DAT) && (cnt == 15)) begin + addr_w <= addr; + data_w <= {sbuf, SPI_DI}; + rclk <= 1; + end + + // expose file (menu) index + if((cmd == UIO_FILE_INDEX) && (cnt == 15)) ioctl_index <= {sbuf, SPI_DI}; + end +end + +assign ioctl_wr = |ioctl_wrd; +reg [1:0] ioctl_wrd; + +always@(negedge clk_sys) begin + reg rclkD, rclkD2; + + rclkD <= rclk; + rclkD2 <= rclkD; + ioctl_wrd<= {ioctl_wrd[0],1'b0}; + + if(rclkD & ~rclkD2) begin + ioctl_dout <= data_w; + ioctl_addr <= addr_w; + ioctl_wrd <= 2'b11; + end +end + +endmodule diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/motion.vhd b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/motion.vhd new file mode 100644 index 00000000..80ceb836 --- /dev/null +++ b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/motion.vhd @@ -0,0 +1,330 @@ +-- Motion object generation circuitry for Kee Games Ultra Tank +-- This generates the four motion objects in the game consisting +-- of two tanks and two shells +-- (c) 2017 James Sweet +-- +-- This is free software: you can redistribute +-- it and/or modify it under the terms of the GNU General +-- Public License as published by the Free Software +-- Foundation, either version 3 of the License, or (at your +-- option) any later version. +-- +-- This is distributed in the hope that it will +-- be useful, but WITHOUT ANY WARRANTY; without even the +-- implied warranty of MERCHANTABILITY or FITNESS FOR A +-- PARTICULAR PURPOSE. See the GNU General Public License +-- for more details. + +library IEEE; +use IEEE.STD_LOGIC_1164.all; +use IEEE.STD_LOGIC_UNSIGNED.all; + +entity motion is +port( + CLK6 : in std_logic; -- 6MHz* on schematic + PHI2 : in std_logic; + DMA_n : in std_logic_vector(7 downto 0); + PRAM : in std_logic_vector(7 downto 0); + H256_s : in std_logic; -- 256H* on schematic + VCount : in std_logic_vector(7 downto 0); + HCount : in std_logic_vector(8 downto 0); + Load_n : buffer std_logic_vector(8 downto 1); + Object : out std_logic_vector(4 downto 1); + Object_n : out std_logic_vector(4 downto 1) + ); +end motion; + +architecture rtl of motion is + +signal phi1 : std_logic; + +signal H256_n : std_logic; +signal H64 : std_logic; +signal H32 : std_logic; +signal H16 : std_logic; +signal H8 : std_logic; + +signal P6_R5sum : std_logic_vector(7 downto 0); +signal Match_n : std_logic := '1'; +signal R6_8 : std_logic := '1'; + +signal P7_in : std_logic_vector(3 downto 0) := (others => '0'); +signal P7_out : std_logic_vector(9 downto 0) := (others => '1'); +signal R4_in : std_logic_vector(3 downto 0) := (others => '0'); +signal R4_out : std_logic_vector(9 downto 0) := (others => '1'); + +signal Object1_Hpos : std_logic_vector(7 downto 0) := (others => '0'); +signal Object2_Hpos : std_logic_vector(7 downto 0) := (others => '0'); +signal Object3_Hpos : std_logic_vector(7 downto 0) := (others => '0'); +signal Object4_Hpos : std_logic_vector(7 downto 0) := (others => '0'); + +signal Object1_reg : std_logic_vector(15 downto 0) := (others => '0'); +signal Object2_reg : std_logic_vector(15 downto 0) := (others => '0'); +signal Object3_reg : std_logic_vector(15 downto 0) := (others => '0'); +signal Object4_reg : std_logic_vector(15 downto 0) := (others => '0'); + +signal Object1_Inh : std_logic := '1'; +signal Object2_Inh : std_logic := '1'; +signal Object3_Inh : std_logic := '1'; +signal Object4_Inh : std_logic := '1'; + +signal Vid : std_logic_vector(15 downto 1) := (others => '0'); + + +begin +phi1 <= (not phi2); + +H8 <= Hcount(3); +H16 <= Hcount(4); +H32 <= Hcount(5); +H64 <= Hcount(6); +H256_n <= not(Hcount(8)); + +-- Vertical line comparator +P6_R5sum <= DMA_n + VCount; + +-- Motion object PROMs +N6: entity work.sprom +generic map( + init_file => "rtl/roms/30174-01n6.hex", + widthad_a => 10, + width_a => 4) +port map( + clock => clk6, + address => PRAM(2) & PRAM(7 downto 3) & P6_R5sum(3 downto 0), + q => Vid(4 downto 1) + ); + +--N6: entity work.n6_prom +--port map( +-- clock => clk6, +-- address => PRAM(2) & PRAM(7 downto 3) & P6_R5sum(3 downto 0), +-- q => Vid(4 downto 1) +-- ); + +M6: entity work.sprom +generic map( + init_file => "rtl/roms/30175-01m6.hex", + widthad_a => 10, + width_a => 4) +port map( + clock => clk6, + address => PRAM(2) & PRAM(7 downto 3) & P6_R5sum(3 downto 0), + q => Vid(8 downto 5) + ); + +--M6: entity work.m6_prom +--port map( +-- clock => clk6, +-- address => PRAM(2) & PRAM(7 downto 3) & P6_R5sum(3 downto 0), +-- q => Vid(8 downto 5) +-- ); + +L6: entity work.sprom +generic map( + init_file => "rtl/roms/30176-01l6.hex", + widthad_a => 10, + width_a => 4) +port map( + clock => clk6, + address => PRAM(2) & PRAM(7 downto 3) & P6_R5sum(3 downto 0), + q => Vid(12 downto 9) + ); + +--L6: entity work.l6_prom +--port map( +-- clock => clk6, +-- address => PRAM(2) & PRAM(7 downto 3) & P6_R5sum(3 downto 0), +-- q => Vid(12 downto 9) +-- ); + +K6: entity work.sprom +generic map( + init_file => "rtl/roms/30177-01k6.hex", + widthad_a => 10, + width_a => 4) +port map( + clock => clk6, + address => PRAM(2) & PRAM(7 downto 3) & P6_R5sum(3 downto 0), + q(2 downto 0) => Vid(15 downto 13) + ); + +--K6: entity work.k6_prom +--port map( +-- clock => clk6, +-- address => PRAM(2) & PRAM(7 downto 3) & P6_R5sum(3 downto 0), +-- q(2 downto 0) => Vid(15 downto 13) +-- ); + +-- Some glue logic +Match_n <= not(P6_R5sum(7) and P6_R5sum(6) and P6_R5sum(5) and P6_R5sum(4)); +R6_8 <= not(H256_n and H8 and Phi1 and (H64 nand Match_n)); + + +R4_in <= R6_8 & H64 & H32 & H16; +R4: process(R4_in) +begin + case R4_in is + when "0000" => + R4_out <= "1111111110"; + when "0001" => + R4_out <= "1111111101"; + when "0010" => + R4_out <= "1111111011"; + when "0011" => + R4_out <= "1111110111"; + when "0100" => + R4_out <= "1111101111"; + when "0101" => + R4_out <= "1111011111"; + when "0110" => + R4_out <= "1110111111"; + when "0111" => + R4_out <= "1101111111"; + when others => + R4_out <= "1111111111"; + end case; +end process; +Load_n(8) <= R4_out(7); +Load_n(7) <= R4_out(6); +Load_n(6) <= R4_out(5); +Load_n(5) <= R4_out(4); +Load_n(4) <= R4_out(3); +Load_n(3) <= R4_out(2); +Load_n(2) <= R4_out(1); +Load_n(1) <= R4_out(0); + + +-- Object 1 Horizontal position counter +-- This combines two 74163s at locations P5 and P6 on the PCB +P5_4: process(clk6, H256_s, Load_n, DMA_n) +begin + if rising_edge(clk6) then + if Load_n(1) = '0' then -- preload the counter + Object1_Hpos <= DMA_n; + elsif H256_s = '1' then -- increment the counter + Object1_Hpos <= Object1_Hpos + '1'; + end if; + if Object1_Hpos(7 downto 4) = "1111" then + Object1_Inh <= '0'; + else + Object1_Inh <= '1'; + end if; + end if; +end process; + +-- Object 1 video shift register +-- This combines two 74165s at locations N7 and N8 on the PCB +N7_8: process(clk6, Object1_Inh, Load_n, Vid) +begin + if Load_n(5) = '0' then + Object1_reg <= Vid & '0'; -- Preload the register + elsif rising_edge(clk6) then + if Object1_Inh = '0' then + Object1_reg <= '0' & Object1_reg(15 downto 1); + end if; + end if; +end process; +Object(1) <= Object1_reg(0); +Object_n(1) <= (not Object1_reg(0)); + + +-- Object 2 Horizontal position counter +-- This combines two 74LS163s at locations P5 and P6 on the PCB +P5_6: process(clk6, H256_s, Load_n, DMA_n) +begin + if rising_edge(clk6) then + if Load_n(2) = '0' then -- preload the counter + Object2_Hpos <= DMA_n; + elsif H256_s = '1' then -- increment the counter + Object2_Hpos <= Object2_Hpos + '1'; + end if; + if Object2_Hpos(7 downto 4) = "1111" then + Object2_Inh <= '0'; + else + Object2_Inh <= '1'; + end if; + end if; +end process; + +-- Object 2 video shift register +M7_8: process(clk6, Load_n, Vid) +begin + if Load_n(6) = '0' then + Object2_reg <= Vid & '0'; -- Preload the register + elsif rising_edge(clk6) then + if Object2_Inh = '0' then + Object2_reg <= '0' & Object2_reg(15 downto 1); + end if; + end if; +end process; +Object(2) <= Object2_reg(0); +Object_n(2) <= (not Object2_reg(0)); + + +-- Object 3 Horizontal position counter +-- This combines two 74LS163s at locations M5 and M4 on the PCB +M5_4: process(clk6, H256_s, Load_n, DMA_n) +begin + if rising_edge(clk6) then + if Load_n(3) = '0' then -- preload the counter + Object3_Hpos <= DMA_n; + elsif H256_s = '1' then -- increment the counter + Object3_Hpos <= Object3_Hpos + '1'; + end if; + if Object3_Hpos(7 downto 4) = "1111" then + Object3_Inh <= '0'; + else + Object3_Inh <= '1'; + end if; + end if; +end process; + +-- Object 3 video shift register +L7_8: process(clk6, Object3_Inh, Load_n, Vid) +begin + if Load_n(7) = '0' then + Object3_reg <= Vid & '0'; -- Preload the register + elsif rising_edge(clk6) then + if Object3_Inh = '0' then + Object3_reg <= '0' & Object3_reg(15 downto 1); + end if; + end if; +end process; +Object(3) <= Object3_reg(0); +Object_n(3) <= (not Object3_reg(0)); + + +-- Object 4 Horizontal position counter +-- This combines two 74LS163s at locations L5 and L4on the PCB +L5_4: process(clk6, H256_s, Load_n, DMA_n) +begin + if rising_edge(clk6) then + if Load_n(4) = '0' then -- preload the counter + Object4_Hpos <= DMA_n; + elsif H256_s = '1' then -- increment the counter + Object4_Hpos <= Object4_Hpos + '1'; + end if; + if Object4_Hpos(7 downto 4) = "1111" then + Object4_Inh <= '0'; + else + Object4_Inh <= '1'; + end if; + end if; +end process; + +-- Object 4 video shift register +K7_8: process(clk6, Object4_Inh, Load_n, Vid) +begin + if Load_n(8) = '0' then + Object4_reg <= Vid & '0'; -- Preload the register + elsif rising_edge(clk6) then + if Object4_Inh = '0' then + Object4_reg <= '0' & Object4_reg(15 downto 1); + end if; + end if; +end process; +Object(4) <= Object4_reg(0); +Object_n(4) <= (not Object4_reg(0)); + +end rtl; diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/osd.sv b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/osd.sv new file mode 100644 index 00000000..c62c10af --- /dev/null +++ b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/osd.sv @@ -0,0 +1,179 @@ +// A simple OSD implementation. Can be hooked up between a cores +// VGA output and the physical VGA pins + +module osd ( + // OSDs pixel clock, should be synchronous to cores pixel clock to + // avoid jitter. + input clk_sys, + + // SPI interface + input SPI_SCK, + input SPI_SS3, + input SPI_DI, + + // VGA signals coming from core + input [5:0] R_in, + input [5:0] G_in, + input [5:0] B_in, + input HSync, + input VSync, + + // VGA signals going to video connector + output [5:0] R_out, + output [5:0] G_out, + output [5:0] B_out +); + +parameter OSD_X_OFFSET = 10'd0; +parameter OSD_Y_OFFSET = 10'd0; +parameter OSD_COLOR = 3'd0; + +localparam OSD_WIDTH = 10'd256; +localparam OSD_HEIGHT = 10'd128; + +// ********************************************************************************* +// spi client +// ********************************************************************************* + +// this core supports only the display related OSD commands +// of the minimig +reg osd_enable; +(* ramstyle = "no_rw_check" *) reg [7:0] osd_buffer[2047:0]; // the OSD buffer itself + +// the OSD has its own SPI interface to the io controller +always@(posedge SPI_SCK, posedge SPI_SS3) begin + reg [4:0] cnt; + reg [10:0] bcnt; + reg [7:0] sbuf; + reg [7:0] cmd; + + if(SPI_SS3) begin + cnt <= 0; + bcnt <= 0; + end else begin + sbuf <= {sbuf[6:0], SPI_DI}; + + // 0:7 is command, rest payload + if(cnt < 15) cnt <= cnt + 1'd1; + else cnt <= 8; + + if(cnt == 7) begin + cmd <= {sbuf[6:0], SPI_DI}; + + // lower three command bits are line address + bcnt <= {sbuf[1:0], SPI_DI, 8'h00}; + + // command 0x40: OSDCMDENABLE, OSDCMDDISABLE + if(sbuf[6:3] == 4'b0100) osd_enable <= SPI_DI; + end + + // command 0x20: OSDCMDWRITE + if((cmd[7:3] == 5'b00100) && (cnt == 15)) begin + osd_buffer[bcnt] <= {sbuf[6:0], SPI_DI}; + bcnt <= bcnt + 1'd1; + end + end +end + +// ********************************************************************************* +// video timing and sync polarity anaylsis +// ********************************************************************************* + +// horizontal counter +reg [9:0] h_cnt; +reg [9:0] hs_low, hs_high; +wire hs_pol = hs_high < hs_low; +wire [9:0] dsp_width = hs_pol ? hs_low : hs_high; + +// vertical counter +reg [9:0] v_cnt; +reg [9:0] vs_low, vs_high; +wire vs_pol = vs_high < vs_low; +wire [9:0] dsp_height = vs_pol ? vs_low : vs_high; + +wire doublescan = (dsp_height>350); + +reg ce_pix; +always @(negedge clk_sys) begin + integer cnt = 0; + integer pixsz, pixcnt; + reg hs; + + cnt <= cnt + 1; + hs <= HSync; + + pixcnt <= pixcnt + 1; + if(pixcnt == pixsz) pixcnt <= 0; + ce_pix <= !pixcnt; + + if(hs && ~HSync) begin + cnt <= 0; + pixsz <= (cnt >> 9) - 1; + pixcnt <= 0; + ce_pix <= 1; + end +end + +always @(posedge clk_sys) begin + reg hsD, hsD2; + reg vsD, vsD2; + + if(ce_pix) begin + // bring hsync into local clock domain + hsD <= HSync; + hsD2 <= hsD; + + // falling edge of HSync + if(!hsD && hsD2) begin + h_cnt <= 0; + hs_high <= h_cnt; + end + + // rising edge of HSync + else if(hsD && !hsD2) begin + h_cnt <= 0; + hs_low <= h_cnt; + v_cnt <= v_cnt + 1'd1; + end else begin + h_cnt <= h_cnt + 1'd1; + end + + vsD <= VSync; + vsD2 <= vsD; + + // falling edge of VSync + if(!vsD && vsD2) begin + v_cnt <= 0; + vs_high <= v_cnt; + end + + // rising edge of VSync + else if(vsD && !vsD2) begin + v_cnt <= 0; + vs_low <= v_cnt; + end + end +end + +// area in which OSD is being displayed +wire [9:0] h_osd_start = ((dsp_width - OSD_WIDTH)>> 1) + OSD_X_OFFSET; +wire [9:0] h_osd_end = h_osd_start + OSD_WIDTH; +wire [9:0] v_osd_start = ((dsp_height- (OSD_HEIGHT<> 1) + OSD_Y_OFFSET; +wire [9:0] v_osd_end = v_osd_start + (OSD_HEIGHT<= h_osd_start) && (h_cnt < h_osd_end) && + (VSync != vs_pol) && (v_cnt >= v_osd_start) && (v_cnt < v_osd_end); + +reg [7:0] osd_byte; +always @(posedge clk_sys) if(ce_pix) osd_byte <= osd_buffer[{doublescan ? osd_vcnt[7:5] : osd_vcnt[6:4], osd_hcnt[7:0]}]; + +wire osd_pixel = osd_byte[doublescan ? osd_vcnt[4:2] : osd_vcnt[3:1]]; + +assign R_out = !osd_de ? R_in : {osd_pixel, osd_pixel, OSD_COLOR[2], R_in[5:3]}; +assign G_out = !osd_de ? G_in : {osd_pixel, osd_pixel, OSD_COLOR[1], G_in[5:3]}; +assign B_out = !osd_de ? B_in : {osd_pixel, osd_pixel, OSD_COLOR[0], B_in[5:3]}; + +endmodule diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/playfield.vhd b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/playfield.vhd new file mode 100644 index 00000000..8fbfff26 --- /dev/null +++ b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/playfield.vhd @@ -0,0 +1,265 @@ +-- Playfield generation and video mixing circuitry for Kee Games Ultra Tank +-- (c) 2017 James Sweet +-- +-- This is free software: you can redistribute +-- it and/or modify it under the terms of the GNU General +-- Public License as published by the Free Software +-- Foundation, either version 3 of the License, or (at your +-- option) any later version. +-- +-- This is distributed in the hope that it will +-- be useful, but WITHOUT ANY WARRANTY; without even the +-- implied warranty of MERCHANTABILITY or FITNESS FOR A +-- PARTICULAR PURPOSE. See the GNU General Public License +-- for more details. + +library IEEE; +use IEEE.STD_LOGIC_1164.all; +use IEEE.STD_LOGIC_ARITH.all; +use IEEE.STD_LOGIC_UNSIGNED.all; + +entity playfield is +port( + Clk6 : in std_logic; + DMA : in std_logic_vector(7 downto 0); + PRAM : in std_logic_vector(7 downto 0); + Load_n : in std_logic_vector(8 downto 1); + Object : in std_logic_vector(4 downto 1); + HCount : in std_logic_vector(8 downto 0); + VCount : in std_logic_vector(7 downto 0); + HBlank : in std_logic; + VBlank : in std_logic; + VBlank_n_s : in std_logic; -- VBLANK* on the schematic + HSync : in std_logic; + VSync : in std_logic; + H256_s : out std_logic; + CC3_n : out std_logic; + CC2 : out std_logic; + CC1 : out std_logic; + CC0 : out std_logic; + CompBlank : buffer std_logic; + CompSync_n : out std_logic; + Playfield_n : out std_logic; + White : out std_logic; + PF_Vid1 : out std_logic; + PF_Vid2 : out std_logic + ); +end playfield; + +architecture rtl of playfield is + +signal H1 : std_logic; +signal H2 : std_logic; +signal H4 : std_logic; +signal H256 : std_logic; +signal H256_n : std_logic; + +signal V1 : std_logic; +signal V2 : std_logic; +signal V4 : std_logic; + +signal char_addr : std_logic_vector(8 downto 0) := (others => '0'); +signal char_data : std_logic_vector(7 downto 0) := (others => '0'); +signal shift_data : std_logic_vector(7 downto 0) := (others => '0'); +signal QH : std_logic := '0'; +signal H8_reg : std_logic_vector(3 downto 0) := (others => '0'); +signal H9_in : std_logic_vector(3 downto 0) := (others => '0'); +signal H9_out : std_logic_vector(9 downto 0) := (others => '0'); +signal H10_Q : std_logic_vector(7 downto 0) := (others => '0'); +signal Numeral_n : std_logic; +signal Color0 : std_logic; +signal Color1 : std_logic; +signal J10_addr : std_logic_vector(4 downto 0) := (others => '0'); +signal J10_Q : std_logic_vector(7 downto 0) := (others => '0'); +signal Obj_bus : std_logic_vector(4 downto 1) := (others => '0'); +signal CharLoad_n : std_logic := '1'; +signal K9 : std_logic_vector(4 downto 1) := (others => '0'); + +-- These signals are based off the schematic and are formatted as Designator_PinNumber +-- they really ought to have more descriptive names +signal R3_3 : std_logic; +signal P2_13 : std_logic; +signal P3_6 : std_logic; +signal A6_6 : std_logic; +signal A6_3 : std_logic; + + +begin + +-- Video synchronization signals +H1 <= Hcount(0); +H2 <= Hcount(1); +H4 <= Hcount(2); +H256 <= Hcount(8); +H256_n <= not(Hcount(8)); + +V1 <= Vcount(0); +V2 <= Vcount(1); +V4 <= Vcount(2); + +-- Some glue logic, may be re-written later to be cleaner and easier to follow without referring to schematic +CharLoad_n <= not(H1 and H2 and H4); +R3_3 <= (H256_n or CharLoad_n); +Char_Addr <= DMA(5 downto 0) & V4 & V2 & V1; + + +-- Background character ROMs +H6: entity work.sprom +generic map( + init_file => "rtl/roms/30173-01h6.hex", + widthad_a => 9, + width_a => 4) +port map( + clock => clk6, + Address => char_addr, + q => char_data(3 downto 0) + ); + +--H6: entity work.Char_MSB +--port map( +-- clock => clk6, +-- Address => char_addr, +-- q => char_data(3 downto 0) +-- ); + +J6: entity work.sprom +generic map( + init_file => "rtl/roms/30172-01j6.hex", + widthad_a => 9, + width_a => 4) +port map( + clock => clk6, + Address => char_addr, + q => char_data(7 downto 4) + ); + +--J6: entity work.Char_LSB +--port map( +-- clock => clk6, +-- Address => char_addr, +-- q => char_data(7 downto 4) +-- ); + + +-- 74LS166 video shift register +R3: process(clk6, R3_3, VBlank_n_s, char_data, shift_data) +begin + if VBlank_n_s = '0' then -- Connected Clear input + shift_data <= (others => '0'); + elsif rising_edge(clk6) then + if R3_3 = '0' then -- Parallel load + shift_data <= char_data(7 downto 0); + else + shift_data <= shift_data(6 downto 0) & '0'; + end if; + end if; + QH <= shift_data(7); +end process; + + +-- 9316 counter at H8 +-- CEP and CET tied to ground, counter is used only as a synchronous latch +H8: process(clk6, CharLoad_n, DMA, H256) +begin + if rising_edge(clk6) then + if CharLoad_n = '0' then + H8_reg <= (((not DMA(5)) or (not DMA(7))) & ((not DMA(5)) or (not DMA(6))) & (not DMA(5)) & H256); -- A bit hard to follow, see schematic + end if; + end if; +end process; + +Color0 <= H8_reg(3); +Color1 <= H8_reg(2); +Numeral_n <= H8_reg(1); +H256_s <= H8_reg(0); + +Playfield_n <= (not QH); + +H9_in <= (not QH) & Numeral_n & Color1 & Color0; + +H9: process(H9_in) +begin + case H9_in is + when "0000" => + H9_out <= "1111111110"; + when "0001" => + H9_out <= "1111111101"; + when "0010" => + H9_out <= "1111111011"; + when "0011" => + H9_out <= "1111110111"; + when "0111" => + H9_out <= "1101111111"; + when others => + H9_out <= "1111111111"; + end case; +end process; + + +LK9_10: process(Load_n, PRAM) +begin + if rising_edge(Load_n(1)) then + Obj_bus(1) <= (not PRAM(7)); + end if; + + if rising_edge(Load_n(2)) then + Obj_bus(2) <= (not PRAM(7)); + end if; + + if rising_edge(Load_n(3)) then + Obj_bus(3) <= (not PRAM(7)); + end if; + + if rising_edge(Load_n(4)) then + Obj_bus(4) <= (not PRAM(7)); + end if; +end process; + +K9(4) <= Obj_bus(4) nand Object(4); +K9(3) <= Obj_bus(3) nand Object(3); +K9(2) <= Obj_bus(2) nand Object(2); +K9(1) <= Obj_bus(1) nand Object(1); + +J10_addr <= (not H9_out(7)) & (K9(1) nand H9_out(0)) & (K9(2) nand H9_out(1)) & (K9(3) nand H9_out(2)) & (K9(4) nand H9_out(3)); + +J10: entity work.sprom +generic map( + init_file => "rtl/roms/30218-01j10.hex", + widthad_a => 5, + width_a => 8) +port map( + clock => clk6, + address => J10_addr, + q => J10_Q + ); + +--J10: entity work.J10_PROM +--port map( +-- clock => clk6, +-- address => J10_addr, +-- q => J10_Q +-- ); + +-- 74LS273 octal flip-flop with asynchronous clear at H10 +H10: process(clk6, J10_Q, CompBlank) +begin + if CompBlank = '0' then + H10_Q <= (others => '0'); + elsif rising_edge(clk6) then + H10_Q <= J10_Q; + end if; +end process; + +CompBlank <= HBlank nor VBlank; +CompSync_n <= HSync nor VSync; + +White <= H10_Q(1); +CC3_n <= (not CompBlank); +CC2 <= H10_Q(4); +CC1 <= H10_Q(3); +CC0 <= H10_Q(2); + +PF_Vid1 <= H10_Q(1); +PF_Vid2 <= H10_Q(0); + +end rtl; \ No newline at end of file diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/pll.v b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/pll.v new file mode 100644 index 00000000..6a352243 --- /dev/null +++ b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/pll.v @@ -0,0 +1,337 @@ +// megafunction wizard: %ALTPLL% +// GENERATION: STANDARD +// VERSION: WM1.0 +// MODULE: altpll + +// ============================================================ +// File Name: pll.v +// Megafunction Name(s): +// altpll +// +// Simulation Library Files(s): +// altera_mf +// ============================================================ +// ************************************************************ +// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! +// +// 13.1.4 Build 182 03/12/2014 SJ Web Edition +// ************************************************************ + + +//Copyright (C) 1991-2014 Altera Corporation +//Your use of Altera Corporation's design tools, logic functions +//and other software and tools, and its AMPP partner logic +//functions, and any output files from any of the foregoing +//(including device programming or simulation files), and any +//associated documentation or information are expressly subject +//to the terms and conditions of the Altera Program License +//Subscription Agreement, Altera MegaCore Function License +//Agreement, or other applicable license agreement, including, +//without limitation, that your use is for the sole purpose of +//programming logic devices manufactured by Altera and sold by +//Altera or its authorized distributors. Please refer to the +//applicable agreement for further details. + + +// synopsys translate_off +`timescale 1 ps / 1 ps +// synopsys translate_on +module pll ( + inclk0, + c0, + c1, + locked); + + input inclk0; + output c0; + output c1; + output locked; + + wire [4:0] sub_wire0; + wire sub_wire2; + wire [0:0] sub_wire6 = 1'h0; + wire [0:0] sub_wire3 = sub_wire0[0:0]; + wire [1:1] sub_wire1 = sub_wire0[1:1]; + wire c1 = sub_wire1; + wire locked = sub_wire2; + wire c0 = sub_wire3; + wire sub_wire4 = inclk0; + wire [1:0] sub_wire5 = {sub_wire6, sub_wire4}; + + altpll altpll_component ( + .inclk (sub_wire5), + .clk (sub_wire0), + .locked (sub_wire2), + .activeclock (), + .areset (1'b0), + .clkbad (), + .clkena ({6{1'b1}}), + .clkloss (), + .clkswitch (1'b0), + .configupdate (1'b0), + .enable0 (), + .enable1 (), + .extclk (), + .extclkena ({4{1'b1}}), + .fbin (1'b1), + .fbmimicbidir (), + .fbout (), + .fref (), + .icdrclk (), + .pfdena (1'b1), + .phasecounterselect ({4{1'b1}}), + .phasedone (), + .phasestep (1'b1), + .phaseupdown (1'b1), + .pllena (1'b1), + .scanaclr (1'b0), + .scanclk (1'b0), + .scanclkena (1'b1), + .scandata (1'b0), + .scandataout (), + .scandone (), + .scanread (1'b0), + .scanwrite (1'b0), + .sclkout0 (), + .sclkout1 (), + .vcooverrange (), + .vcounderrange ()); + defparam + altpll_component.bandwidth_type = "AUTO", + altpll_component.clk0_divide_by = 125, + altpll_component.clk0_duty_cycle = 50, + altpll_component.clk0_multiply_by = 224, + altpll_component.clk0_phase_shift = "0", + altpll_component.clk1_divide_by = 125, + altpll_component.clk1_duty_cycle = 50, + altpll_component.clk1_multiply_by = 56, + altpll_component.clk1_phase_shift = "0", + altpll_component.compensate_clock = "CLK0", + altpll_component.inclk0_input_frequency = 37037, + altpll_component.intended_device_family = "Cyclone III", + altpll_component.lpm_hint = "CBX_MODULE_PREFIX=pll", + altpll_component.lpm_type = "altpll", + altpll_component.operation_mode = "NORMAL", + altpll_component.pll_type = "AUTO", + altpll_component.port_activeclock = "PORT_UNUSED", + altpll_component.port_areset = "PORT_UNUSED", + altpll_component.port_clkbad0 = "PORT_UNUSED", + altpll_component.port_clkbad1 = "PORT_UNUSED", + altpll_component.port_clkloss = "PORT_UNUSED", + altpll_component.port_clkswitch = "PORT_UNUSED", + altpll_component.port_configupdate = "PORT_UNUSED", + altpll_component.port_fbin = "PORT_UNUSED", + altpll_component.port_inclk0 = "PORT_USED", + altpll_component.port_inclk1 = "PORT_UNUSED", + altpll_component.port_locked = "PORT_USED", + altpll_component.port_pfdena = "PORT_UNUSED", + altpll_component.port_phasecounterselect = "PORT_UNUSED", + altpll_component.port_phasedone = "PORT_UNUSED", + altpll_component.port_phasestep = "PORT_UNUSED", + altpll_component.port_phaseupdown = "PORT_UNUSED", + altpll_component.port_pllena = "PORT_UNUSED", + altpll_component.port_scanaclr = "PORT_UNUSED", + altpll_component.port_scanclk = "PORT_UNUSED", + altpll_component.port_scanclkena = "PORT_UNUSED", + altpll_component.port_scandata = "PORT_UNUSED", + altpll_component.port_scandataout = "PORT_UNUSED", + altpll_component.port_scandone = "PORT_UNUSED", + altpll_component.port_scanread = "PORT_UNUSED", + altpll_component.port_scanwrite = "PORT_UNUSED", + altpll_component.port_clk0 = "PORT_USED", + altpll_component.port_clk1 = "PORT_USED", + altpll_component.port_clk2 = "PORT_UNUSED", + altpll_component.port_clk3 = "PORT_UNUSED", + altpll_component.port_clk4 = "PORT_UNUSED", + altpll_component.port_clk5 = "PORT_UNUSED", + altpll_component.port_clkena0 = "PORT_UNUSED", + altpll_component.port_clkena1 = "PORT_UNUSED", + altpll_component.port_clkena2 = "PORT_UNUSED", + altpll_component.port_clkena3 = "PORT_UNUSED", + altpll_component.port_clkena4 = "PORT_UNUSED", + altpll_component.port_clkena5 = "PORT_UNUSED", + altpll_component.port_extclk0 = "PORT_UNUSED", + altpll_component.port_extclk1 = "PORT_UNUSED", + altpll_component.port_extclk2 = "PORT_UNUSED", + altpll_component.port_extclk3 = "PORT_UNUSED", + altpll_component.self_reset_on_loss_lock = "OFF", + altpll_component.width_clock = 5; + + +endmodule + +// ============================================================ +// CNX file retrieval info +// ============================================================ +// Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0" +// Retrieval info: PRIVATE: BANDWIDTH STRING "1.000" +// Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "1" +// Retrieval info: PRIVATE: BANDWIDTH_FREQ_UNIT STRING "MHz" +// Retrieval info: PRIVATE: BANDWIDTH_PRESET STRING "Low" +// Retrieval info: PRIVATE: BANDWIDTH_USE_AUTO STRING "1" +// Retrieval info: PRIVATE: BANDWIDTH_USE_PRESET STRING "0" +// Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0" +// Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0" +// Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "0" +// Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "0" +// Retrieval info: PRIVATE: CREATE_CLKBAD_CHECK STRING "0" +// Retrieval info: PRIVATE: CREATE_INCLK1_CHECK STRING "0" +// 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 "125" +// Retrieval info: PRIVATE: DIV_FACTOR1 NUMERIC "125" +// Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000" +// Retrieval info: PRIVATE: DUTY_CYCLE1 STRING "50.00000000" +// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "48.383999" +// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "12.096000" +// 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" +// Retrieval info: PRIVATE: GLOCKED_FEATURE_ENABLED STRING "0" +// Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0" +// Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575" +// Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1" +// Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "27.000" +// Retrieval info: PRIVATE: INCLK0_FREQ_UNIT_COMBO STRING "MHz" +// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT STRING "100.000" +// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT_CHANGED STRING "1" +// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_CHANGED STRING "1" +// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_COMBO STRING "MHz" +// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone III" +// Retrieval info: PRIVATE: INT_FEEDBACK__MODE_RADIO STRING "1" +// Retrieval info: PRIVATE: LOCKED_OUTPUT_CHECK STRING "1" +// Retrieval info: PRIVATE: LONG_SCAN_RADIO STRING "1" +// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "Not Available" +// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0" +// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg" +// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT1 STRING "ps" +// Retrieval info: PRIVATE: MIG_DEVICE_SPEED_GRADE STRING "Any" +// Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0" +// Retrieval info: PRIVATE: MIRROR_CLK1 STRING "0" +// Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "224" +// Retrieval info: PRIVATE: MULT_FACTOR1 NUMERIC "56" +// Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1" +// Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "48.38400000" +// Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "12.09600000" +// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "0" +// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE1 STRING "0" +// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz" +// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT1 STRING "MHz" +// Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "1" +// Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0" +// Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000" +// Retrieval info: PRIVATE: PHASE_SHIFT1 STRING "0.00000000" +// Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0" +// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg" +// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT1 STRING "deg" +// Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0" +// Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "0" +// Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1" +// Retrieval info: PRIVATE: PLL_ENHPLL_CHECK NUMERIC "0" +// Retrieval info: PRIVATE: PLL_FASTPLL_CHECK NUMERIC "0" +// Retrieval info: PRIVATE: PLL_FBMIMIC_CHECK STRING "0" +// Retrieval info: PRIVATE: PLL_LVDS_PLL_CHECK NUMERIC "0" +// Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0" +// Retrieval info: PRIVATE: PLL_TARGET_HARCOPY_CHECK NUMERIC "0" +// Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0" +// Retrieval info: PRIVATE: RECONFIG_FILE STRING "pll.mif" +// Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0" +// Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "1" +// Retrieval info: PRIVATE: SELF_RESET_LOCK_LOSS STRING "0" +// Retrieval info: PRIVATE: SHORT_SCAN_RADIO STRING "0" +// Retrieval info: PRIVATE: SPREAD_FEATURE_ENABLED STRING "0" +// Retrieval info: PRIVATE: SPREAD_FREQ STRING "50.000" +// Retrieval info: PRIVATE: SPREAD_FREQ_UNIT STRING "KHz" +// Retrieval info: PRIVATE: SPREAD_PERCENT STRING "0.500" +// Retrieval info: PRIVATE: SPREAD_USE STRING "0" +// Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "0" +// Retrieval info: PRIVATE: STICKY_CLK0 STRING "1" +// Retrieval info: PRIVATE: STICKY_CLK1 STRING "1" +// Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1" +// Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "1" +// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0" +// Retrieval info: PRIVATE: USE_CLK0 STRING "1" +// Retrieval info: PRIVATE: USE_CLK1 STRING "1" +// Retrieval info: PRIVATE: USE_CLKENA0 STRING "0" +// Retrieval info: PRIVATE: USE_CLKENA1 STRING "0" +// Retrieval info: PRIVATE: USE_MIL_SPEED_GRADE NUMERIC "0" +// Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0" +// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all +// Retrieval info: CONSTANT: BANDWIDTH_TYPE STRING "AUTO" +// Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "125" +// Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50" +// Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "224" +// Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0" +// Retrieval info: CONSTANT: CLK1_DIVIDE_BY NUMERIC "125" +// Retrieval info: CONSTANT: CLK1_DUTY_CYCLE NUMERIC "50" +// Retrieval info: CONSTANT: CLK1_MULTIPLY_BY NUMERIC "56" +// Retrieval info: CONSTANT: CLK1_PHASE_SHIFT STRING "0" +// Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0" +// Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "37037" +// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III" +// Retrieval info: CONSTANT: LPM_TYPE STRING "altpll" +// Retrieval info: CONSTANT: OPERATION_MODE STRING "NORMAL" +// Retrieval info: CONSTANT: PLL_TYPE STRING "AUTO" +// Retrieval info: CONSTANT: PORT_ACTIVECLOCK STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_ARESET STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_CLKBAD0 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_CLKBAD1 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_CLKLOSS STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_CLKSWITCH STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_CONFIGUPDATE STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_FBIN STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_INCLK0 STRING "PORT_USED" +// Retrieval info: CONSTANT: PORT_INCLK1 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_LOCKED STRING "PORT_USED" +// Retrieval info: CONSTANT: PORT_PFDENA STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_PHASECOUNTERSELECT STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_PHASEDONE STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_PHASESTEP STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_PHASEUPDOWN STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_PLLENA STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANACLR STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANCLK STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANCLKENA STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANDATA STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANDATAOUT STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANDONE STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANREAD STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANWRITE STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clk0 STRING "PORT_USED" +// Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_USED" +// Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clk5 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena0 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena1 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena2 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena3 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena4 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena5 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_extclk0 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_extclk1 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_extclk2 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_extclk3 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: SELF_RESET_ON_LOSS_LOCK STRING "OFF" +// Retrieval info: CONSTANT: WIDTH_CLOCK NUMERIC "5" +// Retrieval info: USED_PORT: @clk 0 0 5 0 OUTPUT_CLK_EXT VCC "@clk[4..0]" +// Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT_CLK_EXT VCC "c0" +// Retrieval info: USED_PORT: c1 0 0 0 0 OUTPUT_CLK_EXT VCC "c1" +// Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0" +// Retrieval info: USED_PORT: locked 0 0 0 0 OUTPUT GND "locked" +// Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0 +// Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0 +// Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0 +// Retrieval info: CONNECT: c1 0 0 0 0 @clk 0 0 1 1 +// Retrieval info: CONNECT: locked 0 0 0 0 @locked 0 0 0 0 +// Retrieval info: GEN_FILE: TYPE_NORMAL pll.v TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll.ppf TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll.inc FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll.cmp FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll.bsf FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll_inst.v FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll_bb.v FALSE +// Retrieval info: LIB_FILE: altera_mf +// Retrieval info: CBX_MODULE_PREFIX: ON diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/roms/030180n1.hex b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/roms/030180n1.hex new file mode 100644 index 00000000..c3e443e6 --- /dev/null +++ b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/roms/030180n1.hex @@ -0,0 +1,129 @@ +:10000000030C000000030C030E06090004050C009D +:1000100006000000000501000503050E05010003B0 +:10002000000F000506000A000F0109010506000186 +:1000300005080A00030D03000903000C080207006D +:1000400003010208000301080A0900050F0A050759 +:100050000D0B0000010C08010206040A000B060A41 +:100060000004050E000F0C03010602050E05020038 +:100070000D0000000608000F0000060A000C0B002F +:10008000030005010004050005020802040901003F +:1000900002020000030102050003010C0F000D0124 +:1000A0000009030A000D0003010508000E06030005 +:1000B0000A0900050300060A0C0C0B0009020B05D7 +:1000C000000805010401000A080A0A0A09000900DB +:1000D00008050504050A000300060A050C00030CC8 +:1000E000030000020E05050002020D000301020BD1 +:1000F00004050002020C000301020905050A0002C2 +:10010000020A0C03010401000A05000A05020A0A9A +:10011000090308000D0C000405000A05020A0A097B +:100120000309030809000002090105000900050E82 +:100130000D01000903000108050809000001080875 +:100140000002090305040500000405080A000D0665 +:1001500000000904040900050D0C080A05000A093D +:10016000000A0A0A09010D0708020F0C0301000228 +:10017000020D0401050F0C0501090F05070502001A +:1001800008010900000B010A0A0006020005000030 +:100190000C00030102010502000F0C030102050916 +:1001A000000D01080A000A000B020509000D0908EC +:1001B0000A000A0000090002050009000507040200 +:1001C00000060B0800060B0804020500000E0108DB +:1001D000080C0901080A0A0A0A000E010808090F9A +:1001E0000004040700050809000607090F050F09A8 +:1001F0000008000D00080906000A0D0108090200A8 +:10020000030C02080C0A020D0C020A090E02090076 +:10021000090F0D00080808000200030B0D0F010074 +:100220000507040701010101010102020707070791 +:10023000070A070A0D08080808080808020900024A +:1002400005030300030401020404070F00000C016E +:1002500009030000050200030F090E0100030F0946 +:100260000E0000050200000C010905020002000357 +:100270000F090E030000050200000C010905020031 +:10028000000003020504090400060F02000100003B +:1002900000000003050C050304000F0004090F0E05 +:1002A000030000000000000007010D05000F060517 +:1002B0000200000000050804050E04050400000CFF +:1002C0000109060F020F00050E000609050C0407C0 +:1002D000010C0C0300010E04000D090E05030006BD +:1002E000090309020C050004010E0B0300000009BC +:1002F0000E06090309020C050004010E0B0300039E +:100300000405050201020C05000308050C0C03029C +:100310000F050E03090E07000308050C0C0300006F +:100320000305030F0E040300040F00000C01090075 +:10033000020F020F04000A030202000803000E036A +:1003400000080405030A0A0001000201050F050860 +:1003500008050A0004090F09010A000008050F003A +:1003600002090F0901050F000002050C00060A0929 +:1003700002080502080902000002090000030A0041 +:100380000308000A090A03050E0000010307000024 +:10039000040F0509080508080A0809020A050908E2 +:1003A00005080A0805030006090F090108080503E6 +:1003B000080805040005090F0901080404050300E5 +:1003C000040008000F0805000503000A0501000AE3 +:1003D0000B0A04000000000E000B000400050600DC +:1003E0000A000405010003050108080001060004D5 +:1003F0000006010501080900000C000009030400C3 +:1004000003080008040308040400090003000509A8 +:1004100000080503080904040A0A0504080A080874 +:100420000805070001090C0004090C000404080079 +:10043000050A060F060F0902050E00010A050A0546 +:100440000E080A0A0A0A040C00020501040100024F +:100450000601000002030507090B0D0003080E0743 +:100460000500020F0000000005030402000406025C +:10047000000B050E0508000C0A05030000090F0813 +:1004800009060500050F050E0A0805070A0A0A0AEB +:100490000A090009070805090509050805080208F1 +:1004A000000D0B0808090109070A000E04000E04DC +:1004B000000E04080A040E090E0400030C0F0508C0 +:1004C000090808050B000209000A0A0A0A050F08B4 +:1004D00000090908040F0003080901040D000E04B7 +:1004E00001000A08050B050A080002090F000C0CA0 +:1004F000070A0002020701000A0A0A060E000001AC +:1005000000010300030002010101060103010601CD +:10051000030103030303000800080404000408099E +:1005200000050205080A0A0A090209010005010876 +:10053000050008050208050308060A000305000B6C +:100540000802020000070008050A0A000602060069 +:1005500007080A0A0009080503080502080500083B +:10056000050100060B000C0D020009030A0D04052D +:10057000050B050C0009050D000608080901080512 +:100580000D0900000A000D0C000509030504000F09 +:10059000050D00000D0300090300090A0C0B0008FB +:1005A00008020204000009080A09020808090200FA +:1005B000000E0903050D050D02070003010C0F05D0 +:1005C0000A0A000F020F060C0908050A08060105B1 +:1005D0000D0000040F00000407000F0004010900D3 +:1005E0000900080003050709050C0002050E050AAD +:1005F0000500000D050C040C0004040000020503B6 +:100600000A08050D00090808050D0003000D08087B +:10061000090F0901000B08090F060500090006056E +:1006200001090105090A000C060C02060C00000D68 +:100630000609060A0601060B0602060C0608060154 +:10064000060004060506080900050600020607095B +:100650000700080509090F05090501090005090535 +:10066000010507050A0004050A0405000209080837 +:1006700000070C050F08000A0C050E000004060C0C +:100680000D060004060C0B06000C06090008050EFA +:1006900008090008050F0C0206000C0605060809EB +:1006A00000050600020607090700000C06050E08F3 +:1006B000050F0805030908000408090000080800E0 +:1006C00000080800010808050A050A08050C050CC1 +:1006D0000809000A08050A050A08050C050C0000AF +:1006E000080800010808050B050B08050D050D0895 +:1006F00009000A08050B050B08050D050D09040086 +:100700000000050400050002070001050E000108B5 +:1007100005030009080603090C050300070507097E +:10072000080C09070A0908090C050908000804054E +:100730000004050B000209000A0501090F00020967 +:10074000000501000C05030008050C0508050D0552 +:1007500009000A080809040A000D0B0208090F081D +:100760000C0C0701000900000A080005000707003B +:10077000010A080A000A08000D0A0C0C070100090A +:100780000A000608080A040C000406020606090FFF +:10079000050309000100080A00000F0502080D0EFC +:1007A00007000108000200010808000F0503080DFA +:1007B0000507000108000200010A05020A080805F1 +:1007C0000C050C0808050D050D08000001020202C9 +:1007D00001000000010008080800080808000808D7 +:1007E00000080808000800080A080D0E070805029E +:1007F000080900080D050708050308090008090095 +:00000001FF diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/roms/030181k1.hex b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/roms/030181k1.hex new file mode 100644 index 00000000..777c7929 --- /dev/null +++ b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/roms/030181k1.hex @@ -0,0 +1,129 @@ +:100000000E0200010700040E0B0400090F0A000194 +:100010000002030B02000B02030B0A07000A0F0089 +:10002000020B0B0A050D0D02060B0A0008050D0D4B +:100030000A000409020A060202000F01040A000273 +:100040000F0B0A00020F0B060A0A0408000008053D +:100050000B0B0B0A07040B0B0A000A060F000C0619 +:100060000D000A070D00040F0B0A0A0A07080A0F01 +:10007000020E000D0104020B0B020F0B02070B0214 +:100080000E0B0A0A0D0008080808060A000C000FEB +:10009000000A00020F0B0A00020F0B040B0B0A06EA +:1000A0000202000A0F0E020F0B0A000D00040A0DD7 +:1000B000000A08080A020F0B04070B060103040AD2 +:1000C000070A040708070F0109040606020C0600C8 +:1000D0000A04080808040900020F0B0A00010004C2 +:1000E0000E0B060A000A0801000A00020F0B0A00A4 +:1000F000020807000A00020F0B0A000A08040900A0 +:100100000A00040F0B0A0A0F000A08000A0802027C +:1001100002000A02020B09010A08000A0802020290 +:10012000000C000A0A0F09000A00080A0A000C075E +:100130000A060202000D00010A0002010D00030977 +:100140000B00000008080A0A0F020A00040B000C4A +:100150000A0D0008080A0A080804030B0A0A02022A +:100160000C0202020603080A000A00040F0B060A2A +:10017000000B0B0B08000B0B0B0A0F08050B0502FD +:100180000B0B0003020E0B0C0C010E0A010A0803F4 +:1001900000020F0B0A010A080300040F0B0A000AF1 +:1001A000000904000C010F030E0A000A00090500F3 +:1001B0000C010F0608030C0208010A0808050800D4 +:1001C000020D0B04020D0B040A000A01020D0B06BE +:1001D0000C040D0B0404040404020D0B060C0200B5 +:1001E0000D000205030001060304050203000009D7 +:1001F0000000060A00020C040D000A00020C050DA6 +:10020000000400020B010B0B020B0A0B030B0C0882 +:1002100002030904000C0E090F0605000102040088 +:1002200006070808090A0B0D0C0E0F0F040404043E +:1002300004060400020A0A0C0C0E0E060001050555 +:1002400004050504050504050D050504040504045D +:10025000050504050405040404040C030404040453 +:100260000404050405040504040504050C03040442 +:1002700004040405040504050405040405040D0430 +:10028000040404050404040504040405040304042C +:100290000C04040504040404050404050504040412 +:1002A00005040C0404040404040404040404050404 +:1002B000050404040C0405050404040404040504F2 +:1002C000040D04040D0405040404040404040C05D2 +:1002D00004040405040404040404040404050C05D3 +:1002E00004050404040404050404040504040C04C3 +:1002F00004050405040404040405040404050C05B1 +:1003000005040405040404040405040404040D04A1 +:1003100004050404040404040504040404050C0492 +:100320000504040404040504050404050404050C80 +:10033000050404040D02040B0A0002060B02080B5C +:1003400002060B09070C0C010F060A0008080B0334 +:10035000030F030B00040F06000C010F0106080930 +:10036000000A0F00000808060A000A00030108043A +:10037000000A0B05030F05000B000A000A00040F1A +:1003800000080D0F0B080B090406000000000A000E +:1003900009040B03040B0304080404000A0B030400 +:1003A0000B030B030F000B00040F06000C0C0900DD +:1003B00006030F000B00040F06000C09000D000DD2 +:1003C000000A000D030308010B000F000801020DD5 +:1003D0000B020A010C010A0F0B010A000D000201B9 +:1003E000020B000C0109000E0103080D0F02010AA7 +:1003F0000104010C010906000B0D0A010D050B0B90 +:100400000008010F0900090B000F000C000F000A83 +:1004100001030F000107060B00000900060A06068B +:10042000030F010F01020F0F000C0F09000A000D4E +:10043000000003040F040A000D040B000409040B60 +:100440000403020000000B050F0009080B080F0051 +:100450000D0806000000000000000001010101027B +:1004600003050A0F010002030B070B010F000D012A +:100470000D070B0402000F00040B070B0702000A14 +:100480000B010B060B04080808040B010404040408 +:100490000406000200040B0308040B0308040A000E +:1004A000020E0B0601060002000A020E0B020E0BE2 +:1004B000020E0B060A0A080B0F0B010004010B04C5 +:1004C0000A00030F040B000A00000000000C0806DD +:1004D00009000A040B040F000900040B0601000BBD +:1004E000080D00040B010D04060B000200060B0CA6 +:1004F0000B0C01000A000B000000000208060404B7 +:100500000C04040C040C0404040404040404040493 +:100510000404040404040404040404040404040A95 +:100520000309010A0000020202000004060A000496 +:100530000A00040A00040A00040E0002060B020767 +:100540000B0A0002000B020E0B0C0C010F0A00023A +:100550000F0B0C0C010F0608000608000608000629 +:100560000800040C0001070A060202000A0B0E0B29 +:1005700008000A0003050A080F010F030E000D080A +:10058000080C08090402020B09040A0008080D03FC +:100590000A000D030A060202000F020A0B0B0B08E9 +:1005A000090A000B080101040804000A060D0500F1 +:1005B0000B000A03080808000A00020F0B040C0BCA +:1005C0000C0C010D0A0F08000A0708060E080A0A9B +:1005D000080A0408000A0808050A00020D0B0003B7 +:1005E00009000006020304050A000F000A070006BE +:1005F000000A0D050B060A0003000B0803000B0799 +:10060000000405060100060409060300020A0B06A1 +:1006100002010C010B030A0B020B08000B030B0871 +:10062000000A0008060402020B04050B0600000A7B +:100630000B090B0A0B040B080B080B070B080B0527 +:100640000B02040B0B01030E0C09010B000D010A38 +:100650000006010606020708060B09020800060943 +:10066000090B010D010F01090102080100020F042D +:1006700002050B09010602050B09010602040B0421 +:100680000A0B02040B04080B02090B0A00030F01FA +:100690000A0A00030F01040B0B02090B0B010106F0 +:1006A0000C090109000F010A000602090B0B010ADF +:1006B0000B01040B010C020900060A000609040ADA +:1006C00000060401000801070209020907030903E3 +:1006D000060C0806010702090209070309030A00BC +:1006E00006040100080107020902090703090306BD +:1006F0000C0806010702090209070309030A00069C +:100700000A000B07010002050B0A000A0001000C99 +:100710000B010F000C0D0102030D010D000B010276 +:100720000F04020B00020304030909090D0002086B +:1007300007000B010F000A08000B0902070B00005D +:1007400008090903000B0503000B0309030B030948 +:1007500003060804030E000A020E0B0A000A0F0427 +:100760000B0C0B0B0002020F00060300020E0B091C +:100770000008040C010E0603010A0B0C0B0B000C05 +:10078000070D0106040A020003000F0504050A0311 +:1007900009010A000900060A060A0F0A0001070DEE +:1007A0000B0D000A01000A0009040A0F0A000107E4 +:1007B0000D0B0D000A01000A000B0B000A090107CE +:1007C00003090306010703090306060200000204E9 +:1007D000040402000200000000000F0F0F000F0FC2 +:1007E00000000000000F000408040B0D0B010600C0 +:1007F000010602040B0D0B010600010602040A02A9 +:00000001FF diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/roms/030182m1.hex b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/roms/030182m1.hex new file mode 100644 index 00000000..74bfef88 --- /dev/null +++ b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/roms/030182m1.hex @@ -0,0 +1,129 @@ +:1000000008000F080A05020805040A0D0E07080576 +:1000100002080900080D050708050308090008097A +:100020000008000F080A0503080808080A08000865 +:100030000A0808080A05010805060004090F090155 +:100040000900000D08090B08050105030805070054 +:1000500004090F09010900000808090B080501003F +:1000600002090F05030808080A0800000104090036 +:100070000904010001040900090401050C08050D2B +:1000800008050E040F000F08090408080900000AFB +:100090000200050C050E0A000309020A060C0902FB +:1000A0000A060C02010A000A0900050E000A0809E6 +:1000B0000208090300000D050E08050F0005050FD5 +:1000C0000800070C080A09020A05010008050500D6 +:1000D00000080808080401080500080503080502CF +:1000E000040500040900050F080A000F040C060BA4 +:1000F00000080808080A00050100010005000003C7 +:100100000C01090502040500000A09020902080998 +:100110000F0008090E000C0E09050308050205036F +:100120000A000206020A0602040500010805030887 +:10013000090004030002090F050205020808050E64 +:10014000050E0502050005000A0A0008090005025F +:100150000808000A0A000D0B0100090A000C0C0B2C +:10016000070007060F000A0C0B090A0809020A001B +:10017000070C0808080A05030A05000401000F0817 +:1001800009010808080A0001000809020A040C0015 +:100190000406020606090F05030A09020A05080AF1 +:1001A00009080002090808050705070900050B08EA +:1001B0000A05000004090F050006000002000309FB +:1001C0000005010A08090209020A060B060B080AC3 +:1001D000000A0E0B0F05050D070E0B090F0809018C +:1001E00009040200040A0A0A0A040300020A0A09AE +:1001F00000000905020503000D05030502000705BF +:10020000080A090000020900000209000A000E089D +:10021000050305020006090005030503080A000C92 +:100220000502050300060900050205020A08090285 +:100230000A090E050B080A00000C0B00060A000C48 +:100240000B090F050608080002000A00030D000B49 +:100250000D00080D00090D000A0A000F0606020035 +:100260000C030B060A060A08000008000C08000F21 +:1002700000000F0F0F0F0F0F0505050505050506FB +:100280000A0A0A0A0A0800080508000C010D000302 +:100290000C0A0E0D0A0309030105000A0C0A0102EB +:1002A0000B070F0C0B0506050A0D04000C030306D3 +:1002B0000F0005070A0A00070900080002060605E4 +:1002C00007050201050602060200040A0A000600EC +:1002D00000020A08090805080901050700020A06C4 +:1002E000070607050705070003090F0007050809AA +:1002F0000B000100080000080A050509010A0001B9 +:100300000002020D030A05050D040A05060000049B +:100310000700000A000800020A050408090102009B +:10032000010700010B00020A050400070902090089 +:100330000002090502000107000100010700010B8E +:100340000C050B0A05040A000B0A0809010200014A +:10035000070C010B0A0A0A050406040A0D0D0B001E +:10036000030E03080200010700010B0C050B00003F +:100370000A0008090A0200010700030005050A092E +:100380000808000409080008050D040F0904050EFB +:10039000090005090908050C090005070000000708 +:1003A00008000006090908000006070000010F0008 +:1003B000000604090005040D0D0B000206040805E3 +:1003C0000705070504050805080604000900020CD6 +:1003D00005000A000B00090A0501000809000600D3 +:1003E0000A050100020501080004060000090205D3 +:1003F000010900080501080A06010A0601090005AD +:100400000008090708090405020900080500080A90 +:100410000A0A050005000809070809040503000188 +:1004200000040D080C0A0C040D08050C000202085B +:100430000D010009030004050E000B050100020573 +:10044000000900050C000B0601090F0500060E0649 +:1004500006080A0A000A00080900080A080A050234 +:100460000A0A0A0D0D0C0A0502080A0800000D0907 +:1004700005010C07010B030A01060A0E0F0F0F0EF0 +:100480000A06010A030B01070C0105090D00030709 +:100490000B0F04090F050D060F0A060201010102E8 +:1004A000060A0F060D050F09040F0B07030D0400C4 +:1004B0000406000100080A080A08080805050900E2 +:1004C000090000030C030E0D0000000C05080A02D1 +:1004D00002050C0500050D050805000401000405D2 +:1004E0000404050809080002090F090000020900B8 +:1004F00008050408050C00090400000204040904AE +:100500000D0904050D0D010005040D00000A0A0087 +:1005100000000A02020800000E0A0A000806080984 +:1005200000050A0609000F0E00040D000A0D000563 +:100530000E050A00090A050309040002000A08085A +:10054000080A080000080808080000000808080059 +:10055000000008080900080E00080001080A0E063D +:10056000000001080A0E04000001080A0204000E3F +:100570000D020200080D000E0D020000080D080516 +:10058000070407040805080409050705020507050F +:100590000805090502050C0009050D000000000D05 +:1005A0000100000108090A0D00000D01000001080A +:1005B00009070D080D050000020808080C040000DA +:1005C0000209000C0000000209000009050D0000EE +:1005D0000D0500000600030003060202000A0E0AD1 +:1005E0000A000909060508000205080A0D01000AAB +:1005F000080900050F00050508050E000508050F90 +:100600000007050F0508080002060E060E0904057E +:100610000E0002050E0508000A000D000009000A80 +:10062000060705070008090E00020908090005076A +:100630000D0600090000060507050A050B00000E5F +:10064000060A060B000E0608090E050B050000043D +:100650000900050000050C0A09010D00000A090047 +:100660000004050D050B050C050E060B0900080915 +:100670000C00090E00000202080A08060B0001081F +:10068000090C0005030A0A080808090F0E040C08E3 +:100690000005040C090F0E0400090F0E0404090FD5 +:1006A0000E0A0A0003090F0002090F0D02000000E4 +:1006B0000101020202030304050607080A0B0D02EA +:1006C000020D0100090300060901050E0A0A0D04C6 +:1006D00000050402030D08000A0A00030D08000AC1 +:1006E000000300060608020F0A0802000A05000AB5 +:1006F000000B0C0000000A00080A090F050C0C0191 +:100700000002000A05000D0008080008000F05009F +:10071000000904000A000702090002020600060D93 +:10072000030F0908080A0800060200090005000D69 +:1007300000090A0D000A0D000B0A000F090005014F +:100740000900050002050601080A010008000B0A5D +:1007500006010907040100010A090F00050D040044 +:10076000060106010A090000050D04000601050145 +:100770000900000C020000050501090F0004020930 +:1007800000050D0908020600060D0D0F0901080AF3 +:10079000080006090305040505050E000F0E0C00F0 +:1007A00000000B0C0000000B00040D00050E0C00F7 +:1007B0000000030C030E0D00000A0D02000D0600E0 +:1007C0000900050C08050E0500000E050A000204CC +:1007D0000B040C050A0D020009030809010D0008AD +:1007E0000C0E0F0201040002010D000F0B020104A8 +:1007F00000020F0D000F0B0000000D0C060E0D0582 +:00000001FF diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/roms/030183l1.hex b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/roms/030183l1.hex new file mode 100644 index 00000000..75ae0064 --- /dev/null +++ b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/roms/030183l1.hex @@ -0,0 +1,129 @@ +:100000000A02020B0B0900060B000A0B0D0B01067E +:1000100000010602040B0D0B010600010602040A92 +:10002000020A02020B0B0D00060606060A0606046B +:10003000080409040B0B00030F000B00040F06005B +:100040000C010B010A0B060B09000B00030F000B40 +:1000500000040F06000C010B000A0B060B07000939 +:10006000000A0F0900060A060A0606000000000141 +:1000700001020304050607090A0C0E0A03040A0319 +:10008000040A030A0302020B0C0C06060A000B0109 +:100090000A000B030D0308090004000A0D03040005 +:1000A0000A0F030A0004090E0A08080006080404DF +:1000B000000A0B01000D030B010401010F030B01EA +:1000C0000402020B040804000A0B040F000B040DC9 +:1000D000020E0E0E0E0904060904060902060902A4 +:1000E000020801000A010905060A0A0009050F01B4 +:1000F00006060606060A060B040D00060B060F0090 +:10010000040B0B08000208030108020004000A0B9C +:100110000100040B010004010B0B02040B02080098 +:100120000009000C0000020002080301030E000495 +:100130000A00020003000A0F060008000601070279 +:1001400009020A000704090408040B000A00080059 +:10015000060E0D0C0C020E0B0B000C070F00020C10 +:100160000B0F0005050F04040D0B080402000A0222 +:10017000020B0409040B0B000A0B040B0402020B14 +:100180000C050606060A0900060402000A0200031E +:10019000000F0504050A0309010804000A0A00000B +:1001A0000A0109000A0E01070109010A00090406F3 +:1001B0000A0B060D000A0009060D060F0006090AC3 +:1001C0000009040804020004000A0F040501060ADD +:1001D000060A0E0B050F050B0E070D02000A0B0D8C +:1001E0000B02000300000000000200030000000CEE +:1001F0000C09010A00050201000A00050201000ABB +:1002000000040A0803000A0C0B00040C0009000497 +:100210000B02040001000A000F0209020600090097 +:100220000B02040001000A000F0209020804020088 +:100230000A0A0F0905060A06020C0B020F0B020739 +:100240000B0A0F08080D05060A0008030009000044 +:100250000900000900000900000C0D0E04050A0049 +:1002600004000B060B080B0100000A000000000050 +:100270000C000F0F0F0F0F0F0505050505050505F0 +:100280000A0A0A0A0A0A00030C0008040F03000EF7 +:100290000E0508060F08010A000A000B06060F0CDF +:1002A00003010E0F0802010D0C00080B0403010CE2 +:1002B0000F0F0A0004040D000A0C0C0D000E0008BC +:1002C0000008000300040004000F000404010F06EE +:1002D000020B0B01060008060A000806020B0B00C1 +:1002E00006000600060806090F0C0F0D000A060C92 +:1002F000000D0006010602040B0A08020C040B00A4 +:10030000060A000B060B08000B060B08000A000883 +:1003100000020D0B0B05020B0B08000106020A0080 +:100320000806020B0B020B0B0C000D010C000A025D +:1003300009000A020A000C060D00060806020B0B53 +:1003400004020B0A0400040D00080106020A00085A +:100350000604010B080000000008000A0B090B0D41 +:10036000000800000A000806020B0B04020B020D35 +:100370000B0B000A070A0008060F0F060A08040AFA +:10038000070A0B000A040A0A080308030A0D0803F7 +:100390000A0C08010A0308030A0408010600000207 +:1003A00002000002020202000002020000000F0E22 +:1003B000020A000A0008000B0A0B01000C000106EB +:1003C0000608060A00060608060800060A000A06CD +:1003D00009000C0D0F060A0008010A000A000201BC +:1003E000020C0109000E01080D0F0201060A0008A7 +:1003F000000A0F01070404000200000200020E08B8 +:1004000000060200030E0008000A0F01070404049E +:10041000040400000800060200030E0008000A029F +:10042000060B030C04020B0B03080B03060A000166 +:100430000A060202000F000A070F010A0A0F000B4A +:10044000080408030601000E0A0A0F09080C070435 +:1004500005030C0C010D06030E040408040B0B002D +:1004600004040A0B060B0B0900060A06060000012D +:100470000203030405050606070707070707070722 +:1004800007070706060505040303020100000F0E17 +:100490000D0C0C0B0A0A09090808080808080808C6 +:1004A00008080809090A0A0B0C0C0D0E0F080402B3 +:1004B00002080300040408040B09040D0B00020FDA +:1004C0000C0B0F00040E0B0A000103050A00040ABE +:1004D000000B0309090B0309090B040B040B000BA8 +:1004E000040B04000C000B000A0F0C010B000A01A6 +:1004F0000209090909090F000B060B000B060B0482 +:100500000B040809090B040209070902020C0C017B +:100510000C0B000A000102040B0C0C010F0E000A68 +:100520000008000E00020B0B02050B020D0B02056A +:100530000B0A000D000B0B0002000D00000E060A56 +:10054000060A06040808080808090909090909092A +:10055000090908080A00010A0001010003020A0251 +:1005600002010003020A0202030003020A0002075A +:100570000B0A0002090B02070B0A0002090B0A0B07 +:100580000809080B0809080805030808070B0801F3 +:1005900008020500070906060A000804020A000B03 +:1005A000000201000C0A000804020B000201000C0A +:1005B0000B0D0B0A0B000201010C0C090B000201D0 +:1005C0000000040B000203000008060A00080402F1 +:1005D0000B0002010E030E0000000A0002010B0CCA +:1005E0000C010F0A000C070B0008070402060204A6 +:1005F0000A060008070D0008070807060A070C0787 +:1006000009010E070807090D000E070E070A000C66 +:10061000070B0008070A070D0C060B02020408006E +:1006200007070B070F01020F0B000C0F060009074D +:100630000A040202080D0009070907090706090E46 +:100640000307030709000E070A0F08060A0A0F002E +:100650000A0F080A060A00000600080002040A0041 +:100660000B010805080508050805040606000A0927 +:100670000602090602060A0004080A050509000C1C +:100680000906020B0104040A0601070A0B0B050800 +:1006900003000905070A0B0B06070A0B0B06070ADE +:1006A0000B0C0C010D0C0009000A000804020600E6 +:1006B0000000000000000000000000000000000A30 +:1006C000000A060202000F000A000C07020A0906CF +:1006D000020A080A000906020C040B000906020CB3 +:1006E000010F060408070A0F090D0A000809000C8B +:1006F0000D0F020001050002030B0A0F08000400A1 +:100700000B0A000A09000900000E0D0F0A0F0D0068 +:100710000D0009000C0D0F0A000D000A000A000B65 +:100720000E0B0902000C08010F0A000A000900095B +:100730000000080900000900000C0D0E0A0B08005B +:100740000A0008000A05000A0A0805000C0D0F0A35 +:100750000E000A0002000D0F0802000F000804023C +:100760000E0A000A08020F0F000804020E0A0A000F +:100770000C0C090C0A000A030A0A02000D000A0008 +:100780000D000803000A000A000B0E0B0903000C01 +:1007900008010F0A08080808080807020B0B0200E6 +:1007A00001010F020001030F02050B02050B0200FD +:1007B000010500040E0B0A0202000A0202040402F0 +:1007C0000208060601060606070A0F0C050F0008B8 +:1007D00006080008050A06020200010607080500CF +:1007E00004090B00000000010000000000000000F0 +:1007F000000100000000000000000A0B0E0B020BBD +:00000001FF diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/roms/30024-01p8.hex b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/roms/30024-01p8.hex new file mode 100644 index 00000000..43303fd0 --- /dev/null +++ b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/roms/30024-01p8.hex @@ -0,0 +1,33 @@ +:1000000000000000000000000000000000000000F0 +:1000100000000000000000000000000000000000E0 +:1000200000000000000000000000000000000000D0 +:1000300000000000000000000000000000000000C0 +:1000400000000000000000000000000000000000B0 +:1000500000000000000000000000000000000000A0 +:100060000000000000000000000000000000000090 +:100070000800000000000000000000000000000078 +:100080000A0A0A0A0A0A0A0A0B0B0A0A0A0A0A0ACE +:100090000A0A0A0A0A0A0A0A0A0A0A0A0A060000D8 +:1000A0000000000000000000000000000000000050 +:1000B0000000000000000000000000000000000040 +:1000C0000000000000000000000000000000000030 +:1000D0000000000000000000000000000000000020 +:1000E0000000000000000000000000000000000010 +:1000F00008080808080808080A0A0A0A0A0A0A0A70 +:1001000000000000000000000000000000000000EF +:1001100000000000000000000000000000000000DF +:1001200000000000000000000000000000000000CF +:1001300000000000000000000000000000000000BF +:1001400000000000000000000000000000000000AF +:10015000000000000000000000000000000000009F +:10016000000000000000000000000000000000008F +:100170000800000000000000000000000000000077 +:100180000A0A0A060000000000000000000000004B +:10019000000000000000000000000000000000005F +:1001A000000000000000000000000000000000004F +:1001B000000000000000000000000000000000003F +:1001C000000000000000000000000000000000002F +:1001D000000000000000000000000000000000001F +:1001E000000000000000000000000000000000000F +:1001F00008080808080808080A0A0B0B0A0A0A0A6D +:00000001FF diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/roms/30172-01j6.hex b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/roms/30172-01j6.hex new file mode 100644 index 00000000..5d788741 --- /dev/null +++ b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/roms/30172-01j6.hex @@ -0,0 +1,33 @@ +:1000000000000000000000000003060C0C0F0C0CA8 +:10001000000F0C0C0F0C0C0F0003060C0C0C06034D +:10002000000F0C0C0C0C0C0F000F0C0C0F0C0C0F19 +:10003000000F0C0C0F0C0C0C0003060C0C0C060330 +:10004000000C0C0C0F0C0C0C000F03030303030F2C +:100050000000000000000C07000C0C0D0F0F0D0C31 +:10006000000C0C0C0C0C0C0F000C0E0F0F0D0C0CDC +:10007000000C0E0F0F0D0C0C00070C0C0C0C0C07D9 +:10008000000F0C0C0C0F0C0C00070C0C0C0D0C07CB +:10009000000F0C0C0C0F0D0C00070C0C07000C07CC +:1000A000000F030303030303000C0C0C0C0C0C07E0 +:1000B000000C0C0C0E070301000C0C0D0F0F0E0CA6 +:1000C000000C0E0703070E0C000C0C0C07030303B7 +:1000D000000F000103070E0F0000000000000000E9 +:1000E0000000000000000000000000000000000010 +:1000F0000000000000000000000000000000000000 +:100100000F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0FFF +:100110000F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0FEF +:100120000F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0FDF +:100130000F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0FCF +:100140000F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0FBF +:10015000000000000000000000000000000000009F +:10016000000000000000000000000000000000008F +:10017000000000000000000000000000000000007F +:100180000003040C0C0C0603000307030303030F16 +:1001900000070C0003070E0F0007000103000C0707 +:1001A000000103060C0F0000000F0C0F00000C07ED +:1001B0000003060C0F0C0C07000F0C0001030303D7 +:1001C00000070C0E0709080700070C0C07000007C2 +:1001D000000002010102000000020103030102000D +:1001E00000000103070301000000010306030100F2 +:1001F00000010E0602060E010000030207020300C2 +:00000001FF diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/roms/30173-01h6.hex b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/roms/30173-01h6.hex new file mode 100644 index 00000000..f5a78ae4 --- /dev/null +++ b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/roms/30173-01h6.hex @@ -0,0 +1,33 @@ +:10000000000000000000000000080C06060E0606B6 +:10001000000C06060C06060C000C06000000060C80 +:1000200000080C0606060C08000C00000800000E74 +:10003000000E00000C000000000E00000E06060E70 +:10004000000606060E060606000C00000000000C66 +:10005000000606060606060C00060C0800080C0E34 +:10006000000000000000000C00060E0E0E06060642 +:10007000000606060E0E0E06000C06060606060C08 +:10008000000C0606060C0000000C0606060E0C0A04 +:10009000000C06060E080C0E00080C000C06060CE0 +:1000A000000C000000000000000606060606060C14 +:1000B000000606060E0C0800000606060E0E0E06CA +:1000C00000060E0C080C0E06000C0C0C08000000BC +:1000D000000E0E0C0800000E0000000000000000E2 +:1000E0000000000000000000000000000000000010 +:1000F0000000000000000000000000000000000000 +:100100000F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0FFF +:100110000F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0FEF +:100120000F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0FDF +:100130000F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0FCF +:100140000F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0FBF +:10015000000000000000000000000000000000009F +:10016000000000000000000000000000000000008F +:10017000000000000000000000000000000000007F +:1001800000080C0606060408000000000000000C31 +:10019000000C060E0C08000E000E0C080C06060CD7 +:1001A000000C0C0C0C0E0C0C000C000C0606060CC3 +:1001B000000C00000C06060C000E060C08000000E7 +:1001C00000080404080E060C000C06060E060C08B7 +:1001D00000000408080400000004080C0C080400D7 +:1001E00000080C0E0F0E0C0800080C060B060C087D +:1001F00000000E0C080C0E0000080E0A0F0A0E0874 +:00000001FF diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/roms/30174-01n6.hex b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/roms/30174-01n6.hex new file mode 100644 index 00000000..849c86ac --- /dev/null +++ b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/roms/30174-01n6.hex @@ -0,0 +1,65 @@ +:100000000000000000000E0E0E0E0E0E0E0000008E +:1000100000000000000C0C0C0E0E0E0E0000000084 +:1000200000000008080C0C0E0E0E0C000000000072 +:100030000000000008080C0C0E0E0C000000000070 +:100040000000080C0E0F0F0600000000000000006A +:1000500000080C0E0F0F0E08080000000000000042 +:1000600000080E0E0E080808000000000000000046 +:1000700000000E0E0E08080808000008080800001E +:10008000000C0C0C0000080800000C0C0C00000018 +:10009000000808080000080808080E0E0E000000FE +:1000A000000000000000000808080E0E0F08000005 +:1000B00000000000000008080E0F0F0E0C080000E2 +:1000C00000000000000000060F0F0E0C08000000EA +:1000D000000000000C0E0E0C0C08080000000000D0 +:1000E000000000000C0E0E0E0C0C080800000000B2 +:1000F0000000000E0E0E0E0C0C0C000000000000A4 +:1001000000000E0E0E0E0E0E0E000000000000008D +:10011000000C0C0C0E0E0E0E000000000000000083 +:10012000000C0C0E0E0F0F06000008080C0C080047 +:1001300000080C0E0F0F06000008080E0E0C000041 +:100140000000080C0E0F0C000000080E0E0C000042 +:1001500000000000080800000000080E0E0C00005F +:10016000000000080800000000080F0F0600000053 +:1001700000000000000000060F0F06000000000055 +:100180000000000000060E0E060000000000000047 +:1001900000000000060E0E06000000000000000037 +:1001A0000000060F0F080000000008080000000013 +:1001B000000C0E0E080000000008080000000000FF +:1001C000000C0E0E080000000C0E0E0C08000000C3 +:1001D000000C0E0E08080000060F0F0E0C080000A1 +:1001E000080C0C08080000060F0F0E0E0C0C000087 +:1001F000000000000000000E0E0E0E0C0C0C0000A3 +:1002000000000000000000000000000000000000EE +:1002100000000000000000000000000000000000DE +:1002200000000000000000000000000000000000CE +:1002300000000000000000040000000000000000BA +:1002400000000000000000040400000000000000A6 +:10025000000200080800000606000008080002006E +:10026000000606000000000606000000000606006A +:10027000000200060600020000020006060002005E +:10028000000000000E0202020200000A0A020A0038 +:10029000000000080C0A0A0A0408000A0507050005 +:1002A00000000008040A0A0A040800040A0E0A00F2 +:1002B000000000000000000000000000000000003E +:1002C000000000000000000000000000000000002E +:1002D000000000000000000000000000000000001E +:1002E000000000000000000000000000000000000E +:1002F00000000000000000000000000000000000FE +:1003000000000000000000000000000000000000ED +:1003100000000000000000000000000000000000DD +:1003200000000000000000000000000000000000CD +:1003300000000000000000000000000000000000BD +:1003400000000000000000000000000000000000AD +:10035000000000000000000000000000000000009D +:10036000000000000000000000000000000000008D +:10037000000000000000000000000000000000007D +:10038000000000000000000000000000000000006D +:10039000000000000000000000000000000000005D +:1003A000000000000000000000000000000000004D +:1003B000000000000000000000000000000000003D +:1003C000000000000000000000000000000000002D +:1003D000000000000000000000000000000000001D +:1003E000000000000000000000000000000000000D +:1003F00000000000000000000000000000000000FD +:00000001FF diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/roms/30175-01m6.hex b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/roms/30175-01m6.hex new file mode 100644 index 00000000..92150794 --- /dev/null +++ b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/roms/30175-01m6.hex @@ -0,0 +1,65 @@ +:10000000000E0E0C0C0E0E0F0F0F0F0C0000000058 +:100010000008080008090D0F0F0F0F0C000000006A +:1000200000000001030D0F0F0F0F0C08000000006F +:100030000000000307070F0F0F0E0E0C000000005A +:1000400000030707070F0F0E0E0C00000808000042 +:10005000030707030F0F0F0F0F0F0E0F0F06000000 +:10006000060F0F070F0F0F0F0F0E0E0F0F0E0000D2 +:10007000000F0F0F070F0F0F0F0F0F0F0F070000CD +:10008000000F0F0F0F0F0F0F0F0F0F0F0F000000BC +:1000900000070F0F0F0F0F0F0F0F070F0F0F0000AD +:1000A000000E0F0F0E0E0F0F0F0F0F070F0F060092 +:1000B00000060F0F0C0F0F0F0F0F0F0307070300A2 +:1000C00000080800000C0E0E0F0F070707030000C2 +:1000D0000000000C0E0F0F0F0F07070300000000B9 +:1000E000000000080C0F0F0F0F0B030100000000B1 +:1000F0000000000C0F0F0F0F0D090800080800008A +:100100000000000C0F0F0F0F0E0E0C0C0E0E000057 +:100110000001010F0F0F0F0E0E0E0E060F0F000045 +:100120000001010F0F0F0F0F0F0F07030101010057 +:100130000307070F0F0F0F0F0F0703010000000049 +:10014000060F0F0707070F0E0F0F07010000000033 +:1001500000000C0F0F0F0F0C0E0F0F03000000001C +:1001600000080E0F0F0F0C0E0F0F0F0108080000F4 +:1001700000000E0E0E080C0F0F0F000808080000FC +:10018000000C0C0C080E0F0F0E080C0C0C000000DD +:1001900000080808000F0F0F0C080E0E0E000000DC +:1001A000000808010F0F0F0E0C0F0F0F0E080000B4 +:1001B000000000030F0F0E0C0F0F0F0F0C000000BC +:1001C00000000001070F0F0E0F0F07070F0F0600AB +:1001D0000000000103070F0F0F0F0F0F07070300A9 +:1001E00001010103070F0F0F0F0F0F0F0101000097 +:1001F000000F0F060E0E0E0E0F0F0F0F0101000065 +:1002000000000000000000080800000000000000DE +:1002100000000000000004000004000000000000D6 +:1002200000000000000200040400020000000000C2 +:1002300000000000040002000002000400000000B2 +:100240000008080003030008080003030008080072 +:100250000000080101000400000400010108000082 +:100260000008080003030008080003030008080052 +:1002700000080B030008000303000800030B08003C +:10028000000000000E0202020200000B060F060032 +:1002900000000001020504050201000B050D050028 +:1002A0000000000102050405020100070A0A0A0015 +:1002B000000000000000000000000000000000003E +:1002C000000000000000000000000000000000002E +:1002D000000000000000000000000000000000001E +:1002E000000000000000000000000000000000000E +:1002F00000000000000000000000000000000000FE +:1003000000000000000000000000000000000000ED +:1003100000000000000000000000000000000000DD +:1003200000000000000000000000000000000000CD +:1003300000000000000000000000000000000000BD +:1003400000000000000000000000000000000000AD +:10035000000000000000000000000000000000009D +:10036000000000000000000000000000000000008D +:10037000000000000000000000000000000000007D +:10038000000000000000000000000000000000006D +:10039000000000000000000000000000000000005D +:1003A000000000000000000000000000000000004D +:1003B000000000000000000000000000000000003D +:1003C000000000000000000000000000000000002D +:1003D000000000000000000000000000000000001D +:1003E000000000000000000000000000000000000D +:1003F00000000000000000000000000000000000FD +:00000001FF diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/roms/30176-01l6.hex b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/roms/30176-01l6.hex new file mode 100644 index 00000000..eef8d817 --- /dev/null +++ b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/roms/30176-01l6.hex @@ -0,0 +1,65 @@ +:100000000001010000010D0F0F0F0F0C0C0000008C +:10001000000707030303030B0F0F0F0F0C0C000067 +:100020000C0C0C0E0F0707070F0F0F0F0C0C000026 +:100030000008080C0E0F0707070F0F0F0F0F060021 +:100040000008080C0F0707030F0F0F0F0F0703001F +:100050000008080E0F070301070F0F07010000003B +:100060000000000C0F0F070301070F0F0300000033 +:1000700000000000000F0F07010003030300000051 +:100080000001010100030F0F030001010100000046 +:1000900000000303030001070F0F00000000000031 +:1000A0000000030F0F070103070F0F0C00000000F3 +:1000B000000001070F0F070103070F0E08080000DB +:1000C00003070F0F0F0F0F0307070F0C080800009F +:1000D000060F0F0F0F0F0707070F0E0C0808000081 +:1000E000000C0C0F0F0F0F0707070F0E0C0C0C0066 +:1000F000000C0C0F0F0F0F0B030303030707000087 +:1001000000000C0C0F0F0F0F0D010000010100008B +:10011000000000090F0F0F0F0D0C00000000000081 +:1001200000000000090F0F0F0F0E0E0C0000000062 +:10013000000000010B0B0F0F0F0F0F060000000057 +:1001400000000000000103030F0F0F0F0F06000057 +:100150000003070703070F0F0F0F0F0E0F0F060007 +:10016000000307070303070F0F0F0F0F0F0F030005 +:10017000000F0F0F07070F0F0F0F0F0F0F070000D4 +:10018000000F0F0F07070F0F07070F0F0F000000DB +:1001900000070F0F0F0F0F0F0F07070F0F0F0000B4 +:1001A000030F0F0F0F0F0F0F0703030707030000C5 +:1001B000060F0F0E0F0F0F0F0F07010707030000A9 +:1001C00000060F0F0F0F0F030301000000000000D7 +:1001D000000000060F0F0F0F0F0F0B0100000000B3 +:1001E0000000000C0E0E0F0F0F0F090000000000A2 +:1001F00000000000000C0D0F0F0F0F0900000000A1 +:1002000000000000000000010100000000000000EC +:1002100000000000000002000002000000000000DA +:1002200000000000000400020200040000000000C2 +:1002300000000000020004000004000200000000B2 +:10024000000101000C0C000101000C0C0001010078 +:100250000000010808000200000200080801000078 +:10026000000101000C0C000101000C0C0001010058 +:1002700000010D0C0001000C0C0001000C0D010030 +:1002800000000008040A020A0408000E0505050023 +:1002900000000000070404040400000C050D050024 +:1002A00000000000070404040400000D060F06000F +:1002B000000000000000000000000000000000003E +:1002C000000000000000000000000000000000002E +:1002D000000000000000000000000000000000001E +:1002E000000000000000000000000000000000000E +:1002F00000000000000000000000000000000000FE +:1003000000000000000000000000000000000000ED +:1003100000000000000000000000000000000000DD +:1003200000000000000000000000000000000000CD +:1003300000000000000000000000000000000000BD +:1003400000000000000000000000000000000000AD +:10035000000000000000000000000000000000009D +:10036000000000000000000000000000000000008D +:10037000000000000000000000000000000000007D +:10038000000000000000000000000000000000006D +:10039000000000000000000000000000000000005D +:1003A000000000000000000000000000000000004D +:1003B000000000000000000000000000000000003D +:1003C000000000000000000000000000000000002D +:1003D000000000000000000000000000000000001D +:1003E000000000000000000000000000000000000D +:1003F00000000000000000000000000000000000FD +:00000001FF diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/roms/30177-01k6.hex b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/roms/30177-01k6.hex new file mode 100644 index 00000000..559365c5 --- /dev/null +++ b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/roms/30177-01k6.hex @@ -0,0 +1,65 @@ +:1000000000000000000001010101010101000000E9 +:1000100000000000000000030303030101010000D1 +:1000200000010100000000030707030301010000B5 +:1000300000010303000000000307070301000000A4 +:1000400000010303000000000103030100000000A1 +:100050000001030300000000000000000000000099 +:10006000000003070700000000000000000000007F +:100070000000000003030303000000000000000074 +:100080000000000000030303030000000000000064 +:100090000000000000000003030303000000000054 +:1000A000000000000000000000000707030000003F +:1000B0000000000000000000000000030301000039 +:1000C0000000000103030100000000030301000021 +:1000D0000000010307070300000000030301000004 +:1000E00000010103030707030000000001010000F5 +:1000F00000010101030303030000000000000000F1 +:1001000000000101010101010100000000000000E8 +:1001100000000003030303010101000000000000D0 +:1001200000000000010303030101000000000000C3 +:1001300000000000010303010100000000000000B6 +:10014000000000000000000307070301000000009A +:10015000000000000000000003070703010000008A +:100160000000000000000000000003030300000086 +:100170000000000000000000000003030300000076 +:100180000001010100000000000001010100000069 +:100190000000030303000000000000000000000056 +:1001A0000000030303000000000000000000000046 +:1001B000000001030707030000000000000000002A +:1001C000000000010307070300000000000000001A +:1001D0000000000000000101030301000000000016 +:1001E0000000000000010103030301000000000003 +:1001F00000000000000101010303030300000000F0 +:1002000000000000000000000000000000000000EE +:1002100000000000000000000000000000000000DE +:1002200000000000000000000000000000000000CE +:1002300000000000000000020000000000000000BC +:1002400000000000000000020200000000000000AA +:100250000004000101000006060000010100040086 +:10026000000606000000000606000000000606006A +:100270000004000606000400000400060600040056 +:100280000000000102050505020100020507050046 +:100290000000000007040404040000050504050034 +:1002A0000000000007040404040000050504050024 +:1002B000000000000000000000000000000000003E +:1002C000000000000000000000000000000000002E +:1002D000000000000000000000000000000000001E +:1002E000000000000000000000000000000000000E +:1002F00000000000000000000000000000000000FE +:1003000000000000000000000000000000000000ED +:1003100000000000000000000000000000000000DD +:1003200000000000000000000000000000000000CD +:1003300000000000000000000000000000000000BD +:1003400000000000000000000000000000000000AD +:10035000000000000000000000000000000000009D +:10036000000000000000000000000000000000008D +:10037000000000000000000000000000000000007D +:10038000000000000000000000000000000000006D +:10039000000000000000000000000000000000005D +:1003A000000000000000000000000000000000004D +:1003B000000000000000000000000000000000003D +:1003C000000000000000000000000000000000002D +:1003D000000000000000000000000000000000001D +:1003E000000000000000000000000000000000000D +:1003F00000000000000000000000000000000000FD +:00000001FF diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/roms/30218-01j10.hex b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/roms/30218-01j10.hex new file mode 100644 index 00000000..29a92430 --- /dev/null +++ b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/roms/30218-01j10.hex @@ -0,0 +1,3 @@ +:100000000A07000114151415131311111111111100 +:1000100001010101010101010101010101010101D0 +:00000001FF diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/scandoubler.sv b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/scandoubler.sv new file mode 100644 index 00000000..0213d20c --- /dev/null +++ b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/scandoubler.sv @@ -0,0 +1,195 @@ +// +// scandoubler.v +// +// Copyright (c) 2015 Till Harbaum +// Copyright (c) 2017 Sorgelig +// +// This source file is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This source file is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// TODO: Delay vsync one line + +module scandoubler #(parameter LENGTH, parameter HALF_DEPTH) +( + // system interface + input clk_sys, + input ce_pix, + input ce_pix_actual, + + input hq2x, + + // shifter video interface + input hs_in, + input vs_in, + input line_start, + + input [DWIDTH:0] r_in, + input [DWIDTH:0] g_in, + input [DWIDTH:0] b_in, + input mono, + + // output interface + output reg hs_out, + output vs_out, + output [DWIDTH:0] r_out, + output [DWIDTH:0] g_out, + output [DWIDTH:0] b_out +); + + +localparam DWIDTH = HALF_DEPTH ? 2 : 5; + +assign vs_out = vs_in; + +reg [2:0] phase; +reg [2:0] ce_div; +reg [7:0] pix_len = 0; +wire [7:0] pl = pix_len + 1'b1; + +reg ce_x1, ce_x4; +reg req_line_reset; +wire ls_in = hs_in | line_start; +always @(negedge clk_sys) begin + reg old_ce; + reg [2:0] ce_cnt; + + reg [7:0] pixsz2, pixsz4 = 0; + + old_ce <= ce_pix; + if(~&pix_len) pix_len <= pix_len + 1'd1; + + ce_x4 <= 0; + ce_x1 <= 0; + + // use such odd comparison to place c_x4 evenly if master clock isn't multiple 4. + if((pl == pixsz4) || (pl == pixsz2) || (pl == (pixsz2+pixsz4))) begin + phase <= phase + 1'd1; + ce_x4 <= 1; + end + + if(~old_ce & ce_pix) begin + pixsz2 <= {1'b0, pl[7:1]}; + pixsz4 <= {2'b00, pl[7:2]}; + ce_x1 <= 1; + ce_x4 <= 1; + pix_len <= 0; + phase <= phase + 1'd1; + + ce_cnt <= ce_cnt + 1'd1; + if(ce_pix_actual) begin + phase <= 0; + ce_div <= ce_cnt + 1'd1; + ce_cnt <= 0; + req_line_reset <= 0; + end + + if(ls_in) req_line_reset <= 1; + end +end + +reg ce_sd; +always @(*) begin + case(ce_div) + 2: ce_sd = !phase[0]; + 4: ce_sd = !phase[1:0]; + default: ce_sd <= 1; + endcase +end + +`define BITS_TO_FIT(N) ( \ + N <= 2 ? 0 : \ + N <= 4 ? 1 : \ + N <= 8 ? 2 : \ + N <= 16 ? 3 : \ + N <= 32 ? 4 : \ + N <= 64 ? 5 : \ + N <= 128 ? 6 : \ + N <= 256 ? 7 : \ + N <= 512 ? 8 : \ + N <=1024 ? 9 : 10 ) + +localparam AWIDTH = `BITS_TO_FIT(LENGTH); +Hq2x #(.LENGTH(LENGTH), .HALF_DEPTH(HALF_DEPTH)) Hq2x +( + .clk(clk_sys), + .ce_x4(ce_x4 & ce_sd), + .inputpixel({b_in,g_in,r_in}), + .mono(mono), + .disable_hq2x(~hq2x), + .reset_frame(vs_in), + .reset_line(req_line_reset), + .read_y(sd_line), + .read_x(sd_h_actual), + .outpixel({b_out,g_out,r_out}) +); + +reg [10:0] sd_h_actual; +always @(*) begin + case(ce_div) + 2: sd_h_actual = sd_h[10:1]; + 4: sd_h_actual = sd_h[10:2]; + default: sd_h_actual = sd_h; + endcase +end + +reg [10:0] sd_h; +reg [1:0] sd_line; +always @(posedge clk_sys) begin + + reg [11:0] hs_max,hs_rise,hs_ls; + reg [10:0] hcnt; + reg [11:0] sd_hcnt; + + reg hs, hs2, vs, ls; + + if(ce_x1) begin + hs <= hs_in; + ls <= ls_in; + + if(ls && !ls_in) hs_ls <= {hcnt,1'b1}; + + // falling edge of hsync indicates start of line + if(hs && !hs_in) begin + hs_max <= {hcnt,1'b1}; + hcnt <= 0; + if(ls && !ls_in) hs_ls <= {10'd0,1'b1}; + end else begin + hcnt <= hcnt + 1'd1; + end + + // save position of rising edge + if(!hs && hs_in) hs_rise <= {hcnt,1'b1}; + + vs <= vs_in; + if(vs && ~vs_in) sd_line <= 0; + end + + if(ce_x4) begin + hs2 <= hs_in; + + // output counter synchronous to input and at twice the rate + sd_hcnt <= sd_hcnt + 1'd1; + sd_h <= sd_h + 1'd1; + if(hs2 && !hs_in) sd_hcnt <= hs_max; + if(sd_hcnt == hs_max) sd_hcnt <= 0; + + // replicate horizontal sync at twice the speed + if(sd_hcnt == hs_max) hs_out <= 0; + if(sd_hcnt == hs_rise) hs_out <= 1; + + if(sd_hcnt == hs_ls) sd_h <= 0; + if(sd_hcnt == hs_ls) sd_line <= sd_line + 1'd1; + end +end + +endmodule diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/screech.vhd b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/screech.vhd new file mode 100644 index 00000000..35380721 --- /dev/null +++ b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/screech.vhd @@ -0,0 +1,73 @@ +-- Shell fire sound generator for Kee Games Ultra Tank +-- This was originally created as tire screech sound for Sprint 2 - Identical circuit +-- (c) 2017 James Sweet +-- +-- Original circuit used a 7414 Schmitt trigger oscillator operating at approximately +-- 1.2kHz producing a sawtooth with the frequency modulated slightly by the pseudo-random +-- noise generator. This is an extension of work initially done in Verilog by Jonas Elofsson. +-- +-- This is free software: you can redistribute +-- it and/or modify it under the terms of the GNU General +-- Public License as published by the Free Software +-- Foundation, either version 3 of the License, or (at your +-- option) any later version. +-- +-- This is distributed in the hope that it will +-- be useful, but WITHOUT ANY WARRANTY; without even the +-- implied warranty of MERCHANTABILITY or FITNESS FOR A +-- PARTICULAR PURPOSE. See the GNU General Public License +-- for more details. + +library IEEE; +use IEEE.STD_LOGIC_1164.all; +use IEEE.STD_LOGIC_ARITH.all; +use IEEE.STD_LOGIC_UNSIGNED.all; + +entity screech is +generic( + constant Inc1 : integer := 24; -- These constants can be adjusted to tune the frequency and modulation + constant Inc2 : integer := 34; + constant Dec1 : integer := 23; + constant Dec2 : integer := 12 + ); +port( + Clk : in std_logic; -- 750kHz from the horizontal line counter chain works well here + Noise : in std_logic; -- Output from LFSR pseudo-random noise generator + Screech_out : out std_logic -- Screech output - single bit + ); +end screech; + +architecture rtl of screech is + +signal Screech_count : integer range 1000 to 11000; +signal Screech_state : std_logic; + +begin + +Screech: process(Clk, Screech_state) +begin + if rising_edge(Clk) then + if screech_state = '1' then -- screech_state is 1, counter is rising + if noise = '1' then -- Noise signal from LFSR, when high increases the slope of the rising ramp + screech_count <= screech_count + inc2; + else -- When Noise is low, decreas the slope of the ramp + screech_count <= screech_count + inc1; + end if; + if screech_count > 10000 then -- Reverse the ramp direction when boundary value of 10,000 is reached + screech_state <= '0'; + end if; + elsif screech_state = '0' then -- screech_state is now low, decrement the counter (ramp down) + if noise = '1' then + screech_count <= screech_count - dec2; -- Slope is influenced by the Noise signal + else + screech_count <= screech_count - dec1; + end if; + if screech_count < 1000 then -- Reverse the ramp direction again when the lower boundary of 1,000 is crossed + screech_state <= '1'; + end if; + end if; + end if; +screech_out <= screech_state; +end process; + +end rtl; \ No newline at end of file diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/sound.vhd b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/sound.vhd new file mode 100644 index 00000000..2b576900 --- /dev/null +++ b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/sound.vhd @@ -0,0 +1,244 @@ +-- Audio for Kee Games Ultra Tank +-- First attempt at modeling the analog sound circuits used in Ultra Tank, may be room for improvement as +-- I do not have a real board to compare. +-- (c) 2017 James Sweet +-- +-- This is free software: you can redistribute +-- it and/or modify it under the terms of the GNU General +-- Public License as published by the Free Software +-- Foundation, either version 3 of the License, or (at your +-- option) any later version. +-- +-- This is distributed in the hope that it will +-- be useful, but WITHOUT ANY WARRANTY; without even the +-- implied warranty of MERCHANTABILITY or FITNESS FOR A +-- PARTICULAR PURPOSE. See the GNU General Public License +-- for more details. + +library IEEE; +use IEEE.STD_LOGIC_1164.all; +use IEEE.STD_LOGIC_UNSIGNED.all; + +entity audio is +port( + Clk_6 : in std_logic; + Reset_n : in std_logic; + Load_n : in std_logic_vector(8 downto 1); + Fire1 : in std_logic; + Fire2 : in std_logic; + Write_Explosion_n : in std_logic; + Attract : in std_logic; + Attract_n : in std_logic; + PRAM : in std_logic_vector(7 downto 0); + DBus_n : in std_logic_vector(7 downto 0); + HCount : in std_logic_vector(8 downto 0); + VCount : in std_logic_vector(7 downto 0); + Audio1 : out std_logic_vector(6 downto 0); + Audio2 : out std_logic_vector(6 downto 0)); +end audio; + +architecture rtl of audio is + +signal reset : std_logic; + +signal H4 : std_logic; +signal V2 : std_logic; + +signal Noise : std_logic; +signal Noise_Shift : std_logic_vector(15 downto 0); +signal Shift_in : std_logic; + +signal Crash : std_logic_vector(3 downto 0); +signal Explosion : std_logic_vector(3 downto 0); + +signal Mtr1_Freq : std_logic_vector(3 downto 0); +signal Mtr2_Freq : std_logic_vector(3 downto 0); +signal Motor1_speed : std_logic_vector(3 downto 0); +signal Motor1_snd : std_logic_vector(5 downto 0); +signal Motor2_speed : std_logic_vector(3 downto 0); +signal Motor2_snd : std_logic_vector(5 downto 0); + +signal Screech1 : std_logic := '0'; +signal Screech2 : std_logic := '0'; +signal Shell_fire1 : std_logic_vector(3 downto 0) := (others => '0'); +signal Shell_fire2 : std_logic_vector(3 downto 0) := (others => '0'); + +signal ena_count : std_logic_vector(10 downto 0) := (others => '0'); +signal ena_3k : std_logic := '0'; + +signal explosion_prefilter : std_logic_vector(3 downto 0); +signal explosion_filter_t1 : std_logic_vector(3 downto 0); +signal explosion_filter_t2 : std_logic_vector(3 downto 0); +signal explosion_filter_t3 : std_logic_vector(3 downto 0); +signal explosion_filtered : std_logic_vector(5 downto 0); + + +begin + +-- HCount +-- (0) 1H 3 MHz +-- (1) 2H 1.5MHz +-- (2) 4H 750 kHz +-- (3) 8H 375 kHz +-- (4) 16H 187 kHz +-- (5) 32H 93 kHz +-- (6) 64H 46 kHz +-- (7) 128H 23 kHz +-- (8) 256H 12 kHz + +reset <= (not reset_n); + +H4 <= HCount(2); +V2 <= VCount(1); + +-- Generate the 3kHz clock enable used by the filter +Enable: process(clk_6) +begin + if rising_edge(CLK_6) then + ena_count <= ena_count + "1"; + ena_3k <= '0'; + if (ena_count(10 downto 0) = "00000000000") then + ena_3k <= '1'; + end if; + end if; +end process; + + +-- LFSR that generates pseudo-random noise +Noise_gen: process(Attract_n, V2) +begin + if (attract_n = '0') then + noise_shift <= (others => '0'); + noise <= '0'; + elsif rising_edge(V2) then + shift_in <= not(noise_shift(6) xor noise_shift(8)); + noise_shift <= shift_in & noise_shift(15 downto 1); + noise <= noise_shift(0); + end if; +end process; + + +-- Screech sound used for shell fire. These can be tuned slightly differently to model variations in analog sound hardware. +ShellFire1: entity work.screech +generic map( -- These values can be tweaked to tune the screech sound + Inc1 => 24, -- Ramp increase rate when noise = 0 + Inc2 => 33, -- Ramp increase rate when noise = 1 + Dec1 => 29, -- Ramp decrease rate when noise = 0 + Dec2 => 16 -- Ramp decrease rate when noise = 1 + ) +port map( + Clk => H4, + Noise => noise, + Screech_out => screech1 + ); + + +ShellFire2: entity work.screech +generic map( -- These values can be tweaked to tune the screech sound + Inc1 => 24, -- Ramp increase rate when noise = 0 + Inc2 => 34, -- Ramp increase rate when noise = 1 + Dec1 => 23, -- Ramp decrease rate when noise = 0 + Dec2 => 12 -- Ramp decrease rate when noise = 1 + ) +port map( + Clk => H4, + Noise => noise, + Screech_out => screech2 + ); + +-- Convert shell fire screech sound from 1 bit to 4 bits wide and enable via fire1 and fire2 signals +Fire_ctrl: process(fire1, fire2, screech1, screech2) +begin + if (fire1 and screech1) = '1' then + shell_fire1 <= "1111"; + else + shell_fire1 <= "0000"; + end if; + + if (fire2 and screech2) = '1' then + shell_fire2 <= "1111"; + else + shell_fire2 <= "0000"; + end if; +end process; + + +Explosion_sound: process(Clk_6, DBus_n, Write_Explosion_n, Explosion, noise) +begin + if rising_edge(clk_6) then + if Write_Explosion_n = '0' then + explosion <= not DBus_n(3 downto 0); + end if; + if noise = '1' then + explosion_prefilter <= explosion; + else + explosion_prefilter <= "0000"; + end if; + end if; +end process; + +---- Very simple low pass filter, borrowed from MikeJ's Asteroids code +Crash_filter: process(clk_6) +begin + if rising_edge(clk_6) then + if (ena_3k = '1') then + explosion_filter_t1 <= explosion_prefilter; + explosion_filter_t2 <= explosion_filter_t1; + explosion_filter_t3 <= explosion_filter_t2; + end if; + explosion_filtered <= ("00" & explosion_filter_t1) + + ('0' & explosion_filter_t2 & '0') + + ("00" & explosion_filter_t3); + end if; +end process; + + +Motor1_latch: process(Load_n, PRAM) +begin + if Load_n(1) = '0' then + Motor1_speed <= PRAM(3 downto 0); + end if; +end process; + +Motor1: entity work.EngineSound +generic map( + Freq_tune => 50 -- Tuning pot for engine sound frequency + ) +port map( + Clk_6 => clk_6, + Reset => Attract, + Ena_3k => ena_3k, + EngineData => motor1_speed, + Motor => motor1_snd + ); + + +Motor2_latch: process(Load_n, PRAM) +begin + if Load_n(2) = '0' then + Motor2_speed <= PRAM(3 downto 0); + end if; +end process; + +Motor2: entity work.EngineSound +generic map( + Freq_tune => 48 -- Tuning pot for engine sound frequency + ) +port map( + Clk_6 => clk_6, + Reset => Attract, + Ena_3k => ena_3k, + EngineData => motor2_speed, + Motor => motor2_snd + ); + + +-- Audio mixer, also mutes sound in attract mode +Audio1 <= ('0' & motor1_snd) + ("00" & shell_fire1) + ('0' & explosion_filtered); -- when attract = '0' + --else "0000000"; + +Audio2 <= ('0' & motor2_snd) + ("00" & shell_fire2) + ('0' & explosion_filtered); -- when attract = '0' + --else "0000000"; + + +end rtl; \ No newline at end of file diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/spram.vhd b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/spram.vhd new file mode 100644 index 00000000..d4e8dd90 --- /dev/null +++ b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/spram.vhd @@ -0,0 +1,90 @@ +LIBRARY ieee; +USE ieee.std_logic_1164.all; + +LIBRARY altera_mf; +USE altera_mf.all; + +ENTITY spram IS + GENERIC + ( + init_file : string := ""; + widthad_a : natural; + width_a : natural := 8; + outdata_reg_a : string := "UNREGISTERED" + ); + PORT + ( + address : IN STD_LOGIC_VECTOR (widthad_a-1 DOWNTO 0); + clock : IN STD_LOGIC ; + data : IN STD_LOGIC_VECTOR (width_a-1 DOWNTO 0); + wren : IN STD_LOGIC ; + q : OUT STD_LOGIC_VECTOR (width_a-1 DOWNTO 0) + ); +END spram; + + +ARCHITECTURE SYN OF spram IS + + SIGNAL sub_wire0 : STD_LOGIC_VECTOR (width_a-1 DOWNTO 0); + + + + COMPONENT altsyncram + GENERIC ( + clock_enable_input_a : STRING; + clock_enable_output_a : STRING; + init_file : STRING; + intended_device_family : STRING; + lpm_hint : STRING; + lpm_type : STRING; + numwords_a : NATURAL; + operation_mode : STRING; + outdata_aclr_a : STRING; + outdata_reg_a : STRING; + power_up_uninitialized : STRING; + read_during_write_mode_port_a : STRING; + widthad_a : NATURAL; + width_a : NATURAL; + width_byteena_a : NATURAL + ); + PORT ( + wren_a : IN STD_LOGIC ; + clock0 : IN STD_LOGIC ; + address_a : IN STD_LOGIC_VECTOR (widthad_a-1 DOWNTO 0); + q_a : OUT STD_LOGIC_VECTOR (width_a-1 DOWNTO 0); + data_a : IN STD_LOGIC_VECTOR (width_a-1 DOWNTO 0) + ); + END COMPONENT; + +BEGIN + q <= sub_wire0(width_a-1 DOWNTO 0); + + altsyncram_component : altsyncram + GENERIC MAP ( + clock_enable_input_a => "BYPASS", + clock_enable_output_a => "BYPASS", + init_file => init_file, + intended_device_family => "Cyclone III", + lpm_hint => "ENABLE_RUNTIME_MOD=NO", + lpm_type => "altsyncram", + numwords_a => 2**widthad_a, + operation_mode => "SINGLE_PORT", + outdata_aclr_a => "NONE", + outdata_reg_a => outdata_reg_a, + power_up_uninitialized => "FALSE", + read_during_write_mode_port_a => "NEW_DATA_NO_NBE_READ", + widthad_a => widthad_a, + width_a => width_a, + width_byteena_a => 1 + ) + PORT MAP ( + wren_a => wren, + clock0 => clock, + address_a => address, + data_a => data, + q_a => sub_wire0 + ); + + + +END SYN; diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/sprom.vhd b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/sprom.vhd new file mode 100644 index 00000000..a81ac959 --- /dev/null +++ b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/sprom.vhd @@ -0,0 +1,82 @@ +LIBRARY ieee; +USE ieee.std_logic_1164.all; + +LIBRARY altera_mf; +USE altera_mf.all; + +ENTITY sprom IS + GENERIC + ( + init_file : string := ""; + widthad_a : natural; + width_a : natural := 8; + outdata_reg_a : string := "UNREGISTERED" + ); + PORT + ( + address : IN STD_LOGIC_VECTOR (widthad_a-1 DOWNTO 0); + clock : IN STD_LOGIC ; + q : OUT STD_LOGIC_VECTOR (width_a-1 DOWNTO 0) + ); +END sprom; + + +ARCHITECTURE SYN OF sprom IS + + SIGNAL sub_wire0 : STD_LOGIC_VECTOR (width_a-1 DOWNTO 0); + + + + COMPONENT altsyncram + GENERIC ( + address_aclr_a : STRING; + clock_enable_input_a : STRING; + clock_enable_output_a : STRING; + init_file : STRING; + intended_device_family : STRING; + lpm_hint : STRING; + lpm_type : STRING; + numwords_a : NATURAL; + operation_mode : STRING; + outdata_aclr_a : STRING; + outdata_reg_a : STRING; + widthad_a : NATURAL; + width_a : NATURAL; + width_byteena_a : NATURAL + ); + PORT ( + clock0 : IN STD_LOGIC ; + address_a : IN STD_LOGIC_VECTOR (widthad_a-1 DOWNTO 0); + q_a : OUT STD_LOGIC_VECTOR (width_a-1 DOWNTO 0) + ); + END COMPONENT; + +BEGIN + q <= sub_wire0(width_a-1 DOWNTO 0); + + altsyncram_component : altsyncram + GENERIC MAP ( + address_aclr_a => "NONE", + clock_enable_input_a => "BYPASS", + clock_enable_output_a => "BYPASS", + init_file => init_file, + intended_device_family => "Cyclone III", + lpm_hint => "ENABLE_RUNTIME_MOD=NO", + lpm_type => "altsyncram", + numwords_a => 2**widthad_a, + operation_mode => "ROM", + outdata_aclr_a => "NONE", + outdata_reg_a => outdata_reg_a, + widthad_a => widthad_a, + width_a => width_a, + width_byteena_a => 1 + ) + PORT MAP ( + clock0 => clock, + address_a => address, + q_a => sub_wire0 + ); + + + +END SYN; diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/sync.vhd b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/sync.vhd new file mode 100644 index 00000000..eddf924a --- /dev/null +++ b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/sync.vhd @@ -0,0 +1,197 @@ +-- Video synchronizer circuit for Ultra Tank +-- Similar circuit used in many other Atari and Kee Games arcade games +-- (c) 2017 James Sweet +-- +-- This is free software: you can redistribute +-- it and/or modify it under the terms of the GNU General +-- Public License as published by the Free Software +-- Foundation, either version 3 of the License, or (at your +-- option) any later version. +-- +-- This is distributed in the hope that it will +-- be useful, but WITHOUT ANY WARRANTY; without even the +-- implied warranty of MERCHANTABILITY or FITNESS FOR A +-- PARTICULAR PURPOSE. See the GNU General Public License +-- for more details. + +library IEEE; +use IEEE.STD_LOGIC_1164.all; +use IEEE.STD_LOGIC_UNSIGNED.all; + +entity synchronizer is +port( + clk_12 : in std_logic; + clk_6 : buffer std_logic; + hcount : out std_logic_vector(8 downto 0); + vcount : out std_logic_vector(7 downto 0); + hsync : out std_logic; + hblank : out std_logic; + vblank_s : out std_logic; + vblank_n_s : out std_logic; + vblank : out std_logic; + vsync : out std_logic; + vreset : out std_logic); +end synchronizer; + +architecture rtl of synchronizer is + +signal h_counter : std_logic_vector(8 downto 0) := (others => '0'); +signal H256 : std_logic; +signal H256_n : std_logic; +signal H128 : std_logic; +signal H64 : std_logic; +signal H32 : std_logic; +signal H16 : std_logic; +signal H8 : std_logic; +signal H8_n : std_logic; +signal H4 : std_logic; +signal H4_n : std_logic; +signal H2 : std_logic; +signal H1 : std_logic; + +signal v_counter : std_logic_vector(7 downto 0) := (others => '0'); +signal V128 : std_logic; +signal V64 : std_logic; +signal V32 : std_logic; +signal V16 : std_logic; +signal V8 : std_logic; +signal V4 : std_logic; +signal V2 : std_logic; +signal V1 : std_logic; + +signal sync_bus : std_logic_vector(3 downto 0) := (others => '0'); +signal sync_reg : std_logic_vector(3 downto 0) := (others => '0'); +signal vblank_int : std_logic := '0'; +signal vreset_n : std_logic := '0'; + +signal hblank_int : std_logic := '0'; +signal hsync_int : std_logic := '0'; +signal hsync_n : std_logic := '1'; +signal hsync_reset : std_logic := '0'; + + +begin + +Divider: process(clk_12) +begin + if rising_edge(clk_12) then + Clk_6 <= (not Clk_6); + end if; +end process; + + +-- Horizontal counter is 8 bits long plus additional flip flop. The last 4 bit IC in the chain resets to 0010 so total count resets to 128 +-- using only the last three count states +H_count: process(clk_6) +begin + if rising_edge(clk_6) then + if h_counter = "111111111" then + h_counter <= "010000000"; + else + h_counter <= h_counter + 1; + end if; + end if; +end process; + +-- Vertical counter is 8 bits, clocked by the rising edge of HSync at the end of each horizontal line +V_count: process(hsync_int) +begin + if rising_edge(Hsync_int) then + if vreset_n = '0' then + v_counter <= (others => '0'); + else + v_counter <= v_counter + '1'; + end if; + end if; +end process; + +-- Many Atari raster games use a prom to decode vertical sync signals +-- This could be replaced by combinatorial logic +P8: entity work.sprom +generic map( + init_file => "rtl/roms/30024-01p8.hex", + widthad_a => 9, + width_a => 4) +port map( + clock => clk_12, + address => '1' & sync_reg(3) & V128 & V64 & V32 & V16 & V8 & V4 & V2, + q => sync_bus + ); + +--P8: entity work.sync_prom +--port map( +-- clock => clk_12, +-- address => '1' & sync_reg(3) & V128 & V64 & V32 & V16 & V8 & V4 & V2, +-- q => sync_bus +-- ); + +-- Register fed by the sync PROM, in the original hardware this also creates the complements of these signals +sync_register: process(hsync_n) +begin + if rising_edge(hsync_n) then + sync_reg <= sync_bus; + end if; +end process; + +-- Outputs of sync PROM +vblank_s <= sync_reg(3); +vblank_n_s <= not sync_reg(3); +vreset <= sync_reg(2); +vreset_n <= not sync_reg(2); +vblank <= sync_reg(1); +vsync <= sync_reg(0); + +-- A pair of D type flip-flops that generate the HBlank and HSync signals +HBlank_gen: process(H256_n, H32) +begin + if H256_n = '0' then + hblank_int <= '0'; + else + if rising_edge(H32) then + hblank_int <= not H64; + end if; + end if; +end process; + +HSync_gen: process(hblank_int, H8) +begin + if hblank_int = '0' then + hsync_int <= '0'; + hsync_n <= '1'; + else + if rising_edge(H8) then + hsync_int <= H32; + hsync_n <= (not H32); + end if; + end if; +end process; + +-- Assign various signals +H1 <= h_counter(0); +H2 <= h_counter(1); +H4 <= h_counter(2); +H8 <= h_counter(3); +H16 <= h_counter(4); +H32 <= h_counter(5); +H64 <= h_counter(6); +H128 <= h_counter(7); +H256 <= h_counter(8); +H4_n <= not H4; +H8_n <= not H8; +H256_n <= not H256; + +V1 <= v_counter(0); +V2 <= v_counter(1); +V4 <= v_counter(2); +V8 <= v_counter(3); +V16 <= v_counter(4); +V32 <= v_counter(5); +V64 <= v_counter(6); +V128 <= v_counter(7); + +hcount <= h_counter; +vcount <= v_counter; +hsync <= hsync_int; +hblank <= hblank_int; + +end rtl; \ No newline at end of file diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/ultra_tank.vhd b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/ultra_tank.vhd new file mode 100644 index 00000000..11a82e92 --- /dev/null +++ b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/ultra_tank.vhd @@ -0,0 +1,288 @@ +-- Top level file for Kee Games Ultra Tank +-- (c) 2017 James Sweet +-- +-- This is free software: you can redistribute +-- it and/or modify it under the terms of the GNU General +-- Public License as published by the Free Software +-- Foundation, either version 3 of the License, or (at your +-- option) any later version. +-- +-- This is distributed in the hope that it will +-- be useful, but WITHOUT ANY WARRANTY; without even the +-- implied warranty of MERCHANTABILITY or FITNESS FOR A +-- PARTICULAR PURPOSE. See the GNU General Public License +-- for more details. + +-- Targeted to EP2C5T144C8 mini board but porting to nearly any FPGA should be fairly simple +-- See Ultra Tank manual for video output details. Resistor values listed here have been scaled +-- for 3.3V logic. + + +library IEEE; +use IEEE.STD_LOGIC_1164.all; + + +entity ultra_tank is +port( + clk_12 : in std_logic; -- 50MHz input clock + Reset_n : in std_logic; -- Reset button (Active low) + Video1_O : out std_logic; -- White video output (680 Ohm) + Video2_O : out std_logic; -- Black video output (1.2k) + Sync_O : out std_logic; -- Composite sync output (1.2k) + Blank_O : out std_logic; -- Composite blank output + HS : out std_logic; + VS : out std_logic; + HB : out std_logic; + VB : out std_logic; + CC3_n_O : out std_logic; -- Not sure what these are, color monitor? (not connected in real game) + CC2_O : out std_logic; + CC1_O : out std_logic; + CC0_O : out std_logic; + White_O : out std_logic; + Audio1_O : out std_logic_vector(6 downto 0); -- Ideally these should have a simple low pass filter + Audio2_O : out std_logic_vector(6 downto 0); + Coin1_I : in std_logic; -- Coin switches (Active low) + Coin2_I : in std_logic; + Start1_I : in std_logic; -- Start buttons + Start2_I : in std_logic; + Invisible_I : in std_logic; -- Invisible tanks switch + Rebound_I : in std_logic; -- Rebounding shells switch + Barrier_I : in std_logic; -- Barriers switch + JoyW_Fw_I : in std_logic; -- Joysticks, these are all active low + JoyW_Bk_I : in std_logic; + JoyY_Fw_I : in std_logic; + JoyY_Bk_I : in std_logic; + JoyX_Fw_I : in std_logic; + JoyX_Bk_I : in std_logic; + JoyZ_Fw_I : in std_logic; + JoyZ_Bk_I : in std_logic; + FireA_I : in std_logic; -- Fire buttons + FireB_I : in std_logic; + Test_I : in std_logic; -- Self-test switch + Slam_I : in std_logic; -- Slam switch + LED1_O : out std_logic; -- Player 1 and 2 start button LEDs + LED2_O : out std_logic; + Lockout_O : out std_logic -- Coin mech lockout coil + ); +end ultra_tank; + +architecture rtl of ultra_tank is + +signal Clk_6 : std_logic; +signal Phi1 : std_logic; +signal Phi2 : std_logic; + +signal Hcount : std_logic_vector(8 downto 0); +signal Vcount : std_logic_vector(7 downto 0) := (others => '0'); +signal H256_s : std_logic; +signal Hsync : std_logic; +signal Vsync : std_logic; +signal Vblank : std_logic; +signal Vblank_n_s : std_logic; +signal HBlank : std_logic; +signal CompBlank_s : std_logic; +signal CompSync_n_s : std_logic; + +signal DMA : std_logic_vector(7 downto 0); +signal DMA_n : std_logic_vector(7 downto 0); +signal PRAM : std_logic_vector(7 downto 0); +signal Load_n : std_logic_vector(8 downto 1); +signal Object : std_logic_vector(4 downto 1); +signal Object_n : std_logic_vector(4 downto 1); +signal Playfield_n : std_logic; + +signal CPU_Din : std_logic_vector(7 downto 0); +signal CPU_Dout : std_logic_vector(7 downto 0); +signal DBus_n : std_logic_vector(7 downto 0); +signal BA : std_logic_vector(15 downto 0); + +signal Barrier_Read_n : std_logic; +signal Throttle_Read_n : std_logic; +signal Coin_Read_n : std_logic; +signal Collision_Read_n : std_logic; +signal Collision_n : std_logic; +signal CollisionReset_n : std_logic_vector(4 downto 1); +signal Options_Read_n : std_logic; +signal Wr_DA_Latch_n : std_logic; +signal Wr_Explosion_n : std_logic; +signal Fire1 : std_logic; +signal Fire2 : std_logic; +signal Attract : std_logic; +signal Attract_n : std_logic; + +signal SW1 : std_logic_vector(7 downto 0); + + +begin +-- Configuration DIP switches, these can be brought out to external switches if desired +-- See Ultra Tank manual page 6 for complete information. Active low (0 = On, 1 = Off) +-- 1 2 Extended Play (11 - 75pts, 01 - 50pts, 10 - 25pts, 00 - None) +-- 3 4 Game Length (11 - 60sec, 10 - 90sec, 01 - 120sec, 00 - 150sec) +-- 5 6 Game Cost (10 - 1 Coin, 1 Play, 01 - 2 Plays, 1 Coin, 11 - 2 Coins, 1 Play) +-- 7 8 Unused? +SW1 <= "10010100"; -- Config dip switches + + + +Vid_sync: entity work.synchronizer +port map( + Clk_12 => Clk_12, + Clk_6 => Clk_6, + HCount => HCount, + VCount => VCount, + HSync => HSync, + HBlank => HBlank, + VBlank_n_s => VBlank_n_s, + VBlank => VBlank, + VSync => VSync + ); + + +Background: entity work.playfield +port map( + Clk6 => Clk_6, + DMA => DMA, + PRAM => PRAM, + Load_n => Load_n, + Object => Object, + HCount => HCount, + VCount => VCount, + HBlank => HBlank, + VBlank => VBlank, + VBlank_n_s => VBlank_n_s, + HSync => Hsync, + VSync => VSync, + H256_s => H256_s, + Playfield_n => Playfield_n, + CC3_n => CC3_n_O, + CC2 => CC2_O, + CC1 => CC1_O, + CC0 => CC0_O, + White => White_O, + PF_Vid1 => Video1_O, + PF_Vid2 => Video2_O + ); + + +Tank_Shells: entity work.motion +port map( + CLK6 => Clk_6, + PHI2 => Phi2, + DMA_n => DMA_n, + PRAM => PRAM, + H256_s => H256_s, + VCount => VCount, + HCount => HCount, + Load_n => Load_n, + Object => Object, + Object_n => Object_n + ); + + +Tank_Shell_Comparator: entity work.collision_detect +port map( + Clk6 => Clk_6, + Adr => BA(2 downto 0), + Object_n => Object_n, + Playfield_n => Playfield_n, + CollisionReset_n => CollisionReset_n, + Slam_n => Slam_I, + Collision_n => Collision_n + ); + + +CPU: entity work.cpu_mem +port map( + Clk12 => clk_12, + Clk6 => clk_6, + Reset_n => reset_n, + VCount => VCount, + HCount => HCount, + Vblank_n_s => Vblank_n_s, + Test_n => Test_I, + Collision_n => Collision_n, + DB_in => CPU_Din, + DBus => CPU_Dout, + DBus_n => DBus_n, + PRAM => PRAM, + ABus => BA, + Attract => Attract, + Attract_n => Attract_n, + CollReset_n => CollisionReset_n, + Barrier_Read_n => Barrier_Read_n, + Throttle_Read_n => Throttle_Read_n, + Coin_Read_n => Coin_Read_n, + Options_Read_n => Options_Read_n, + Wr_DA_Latch_n => Wr_DA_Latch_n, + Wr_Explosion_n => Wr_Explosion_n, + Fire1 => Fire1, + Fire2 => Fire2, + LED1 => LED1_O, + LED2 => LED2_O, + Lockout_n => Lockout_O, + Phi1_o => Phi1, + Phi2_o => Phi2, + DMA => DMA, + DMA_n => DMA_n + ); + + +Input: entity work.Control_Inputs +port map( + Clk6 => Clk_6, + DipSw => SW1, -- DIP switches + Coin1_n => Coin1_I, + Coin2_n => Coin2_I, + Start1_n => Start1_I, + Start2_n => Start2_I, + Invisible_n => Invisible_I, + Rebound_n => Rebound_I, + Barrier_n => Barrier_I, + JoyW_Fw => JoyW_Fw_I, + JoyW_Bk => JoyW_Bk_I, + JoyY_Fw => JoyY_Fw_I, + JoyY_Bk => JoyY_Bk_I, + JoyX_Fw => JoyX_Fw_I, + JoyX_Bk => JoyX_Bk_I, + JoyZ_Fw => JoyZ_Fw_I, + JoyZ_Bk => JoyZ_Bk_I, + FireA_n => FireA_I, + FireB_n => FireB_I, + Throttle_Read_n => Throttle_Read_n, + Coin_Read_n => Coin_Read_n, + Options_Read_n => Options_Read_n, + Barrier_Read_n => Barrier_Read_n, + Wr_DA_Latch_n => Wr_DA_Latch_n, + Adr => BA(2 downto 0), + DBus => CPU_Dout(3 downto 0), + Dout => CPU_Din + ); + + +Sound: entity work.audio +port map( + Clk_6 => Clk_6, + Reset_n => Reset_n, + Load_n => Load_n, + Fire1 => Fire1, + Fire2 => Fire2, + Write_Explosion_n => Wr_Explosion_n, + Attract => Attract, + Attract_n => Attract_n, + PRAM => PRAM, + DBus_n => not CPU_Dout, + HCount => HCount, + VCount => VCount, + Audio1 => Audio1_O, + Audio2 => Audio2_O + ); + +Sync_O <= HSync nor VSync; +Blank_O <= HBlank nor VBlank; + +HS <= HSync; +VS <= VSync; +HB <= HBlank; +VB <= VBlank; + +end rtl; \ No newline at end of file diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/ultratank_mist.sv b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/ultratank_mist.sv new file mode 100644 index 00000000..1b8a482d --- /dev/null +++ b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/ultratank_mist.sv @@ -0,0 +1,165 @@ +module ultratank_mist( + output LED, + output [5:0] VGA_R, + output [5:0] VGA_G, + output [5:0] VGA_B, + output VGA_HS, + output VGA_VS, + output AUDIO_L, + output AUDIO_R, + input SPI_SCK, + output SPI_DO, + input SPI_DI, + input SPI_SS2, + input SPI_SS3, + input CONF_DATA0, + input CLOCK_27 +); + +`include "rtl\build_id.sv" + +localparam CONF_STR = { + "Ultra Tank;;", + "O1,Test Mode,Off,On;", + "O34,Scandoubler Fx,None,HQ2x,CRT 25%,CRT 50%;", + "T6,Reset;", + "V,v1.00.",`BUILD_DATE +}; + +wire [31:0] status; +wire [1:0] buttons; +wire [1:0] switches; +wire [11:0] kbjoy; +wire [7:0] joystick_0; +wire [7:0] joystick_1; +wire scandoubler_disable; +wire ypbpr; +wire ps2_kbd_clk, ps2_kbd_data; +wire [6:0] audio1, audio2; +wire video1, video2; + +wire clk_48, clk_12; +wire locked; +pll pll +( + .inclk0(CLOCK_27), + .c0(clk_48),//48.384 + .c1(clk_12),//12.096 + .locked(locked) +); + +ultra_tank ultra_tank ( + .clk_12(clk_12), + .Reset_n(~(status[0] | status[6] | buttons[1])), + .Video1_O(video1),// White video output (680 Ohm) + .Video2_O(video2),// Black video output (1.2k) + .Sync_O(), + .Blank_O(), + .HS(hs), + .VS(vs), + .HB(vb), + .VB(hb), + .CC3_n_O(),// Not sure what these are, color monitor? (not connected in real game) + .CC2_O(), + .CC1_O(), + .CC0_O(), + .White_O(), + .Audio1_O(audio1), + .Audio2_O(audio2), + .Coin1_I(~kbjoy[7]), + .Coin2_I(~kbjoy[7]), + .Start1_I(~kbjoy[5]), + .Start2_I(~kbjoy[6]), + .Invisible_I(),// Invisible tanks switch + .Rebound_I(),// Rebounding shells switch + .Barrier_I(),// Barriers switch + .JoyW_Fw_I(~kbjoy[3]), + .JoyW_Bk_I(~kbjoy[2]), + .JoyY_Fw_I(~kbjoy[1]), + .JoyY_Bk_I(~kbjoy[0]), + .JoyX_Fw_I(), + .JoyX_Bk_I(), + .JoyZ_Fw_I(), + .JoyZ_Bk_I(), + .FireA_I(~kbjoy[4]), + .FireB_I(), + .Test_I(~status[1]), + .Slam_I(), + .LED1_O(), + .LED2_O(), + .Lockout_O() +); + +dac dac1 ( + .CLK(clk_48), + .RESET(1'b0), + .DACin(audio1), + .DACout(AUDIO_L) + ); + +dac dac2 ( + .CLK(clk_48), + .RESET(1'b0), + .DACin(audio2), + .DACout(AUDIO_R) + ); + +wire hs, vs; +wire hb, vb; +wire blankn = ~(hb | vb); +video_mixer #(.LINE_LENGTH(480), .HALF_DEPTH(1)) video_mixer +( + .clk_sys(clk_48), + .ce_pix(clk_12), + .ce_pix_actual(clk_12), + .SPI_SCK(SPI_SCK), + .SPI_SS3(SPI_SS3), + .SPI_DI(SPI_DI), + .R(blankn ? {video1&video2,video1&video2,video1&video2} : "000"), + .G(blankn ? {video1&video2,video1&video2,video1&video2} : "000"), + .B(blankn ? {video1&video2,video1&video2,video1&video2} : "000"), + .HSync(hs), + .VSync(vs), + .VGA_R(VGA_R), + .VGA_G(VGA_G), + .VGA_B(VGA_B), + .VGA_VS(VGA_VS), + .VGA_HS(VGA_HS), + .scandoubler_disable(scandoubler_disable), + .scanlines(scandoubler_disable ? 2'b00 : {status[4:3] == 3, status[4:3] == 2}), + .hq2x(status[4:3]==1), + .ypbpr_full(1), + .line_start(0), + .mono(0) +); + +mist_io #(.STRLEN(($size(CONF_STR)>>3))) mist_io +( + .clk_sys (clk_48 ), + .conf_str (CONF_STR ), + .SPI_SCK (SPI_SCK ), + .CONF_DATA0 (CONF_DATA0 ), + .SPI_SS2 (SPI_SS2 ), + .SPI_DO (SPI_DO ), + .SPI_DI (SPI_DI ), + .buttons (buttons ), + .switches (switches ), + .scandoubler_disable(scandoubler_disable), + .ypbpr (ypbpr ), + .ps2_kbd_clk (ps2_kbd_clk ), + .ps2_kbd_data (ps2_kbd_data ), + .joystick_0 (joystick_0 ), + .joystick_1 (joystick_1 ), + .status (status ) +); + +keyboard keyboard( + .clk(clk_48), + .reset(), + .ps2_kbd_clk(ps2_kbd_clk), + .ps2_kbd_data(ps2_kbd_data), + .joystick(kbjoy) + ); + + +endmodule diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/video_mixer.sv b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/video_mixer.sv new file mode 100644 index 00000000..04cfd4ba --- /dev/null +++ b/Arcade_MiST/Custom Hardware/UltraTank_MiST/rtl/video_mixer.sv @@ -0,0 +1,242 @@ +// +// +// Copyright (c) 2017 Sorgelig +// +// This program is GPL Licensed. See COPYING for the full license. +// +// +//////////////////////////////////////////////////////////////////////////////////////////////////////// + +`timescale 1ns / 1ps + +// +// LINE_LENGTH: Length of display line in pixels +// Usually it's length from HSync to HSync. +// May be less if line_start is used. +// +// HALF_DEPTH: If =1 then color dept is 3 bits per component +// For half depth 6 bits monochrome is available with +// mono signal enabled and color = {G, R} + +module video_mixer +#( + parameter LINE_LENGTH = 768, + parameter HALF_DEPTH = 0, + + parameter OSD_COLOR = 3'd4, + parameter OSD_X_OFFSET = 10'd0, + parameter OSD_Y_OFFSET = 10'd0 +) +( + // master clock + // it should be multiple by (ce_pix*4). + input clk_sys, + + // Pixel clock or clock_enable (both are accepted). + input ce_pix, + + // Some systems have multiple resolutions. + // ce_pix_actual should match ce_pix where every second or fourth pulse is enabled, + // thus half or qurter resolutions can be used without brake video sync while switching resolutions. + // For fixed single resolution (or when video sync stability isn't required) ce_pix_actual = ce_pix. + input ce_pix_actual, + + // OSD SPI interface + input SPI_SCK, + input SPI_SS3, + input SPI_DI, + + // scanlines (00-none 01-25% 10-50% 11-75%) + input [1:0] scanlines, + + // 0 = HVSync 31KHz, 1 = CSync 15KHz + input scandoubler_disable, + + // High quality 2x scaling + input hq2x, + + // YPbPr always uses composite sync + input ypbpr, + + // 0 = 16-240 range. 1 = 0-255 range. (only for YPbPr color space) + input ypbpr_full, + + // color + input [DWIDTH:0] R, + input [DWIDTH:0] G, + input [DWIDTH:0] B, + + // Monochrome mode (for HALF_DEPTH only) + input mono, + + // interlace sync. Positive pulses. + input HSync, + input VSync, + + // Falling of this signal means start of informative part of line. + // It can be horizontal blank signal. + // This signal can be used to reduce amount of required FPGA RAM for HQ2x scan doubler + // If FPGA RAM is not an issue, then simply set it to 0 for whole line processing. + // Keep in mind: due to algo first and last pixels of line should be black to avoid side artefacts. + // Thus, if blank signal is used to reduce the line, make sure to feed at least one black (or paper) pixel + // before first informative pixel. + input line_start, + + // MiST video output signals + output [5:0] VGA_R, + output [5:0] VGA_G, + output [5:0] VGA_B, + output VGA_VS, + output VGA_HS +); + +localparam DWIDTH = HALF_DEPTH ? 2 : 5; + +wire [DWIDTH:0] R_sd; +wire [DWIDTH:0] G_sd; +wire [DWIDTH:0] B_sd; +wire hs_sd, vs_sd; + +scandoubler #(.LENGTH(LINE_LENGTH), .HALF_DEPTH(HALF_DEPTH)) scandoubler +( + .*, + .hs_in(HSync), + .vs_in(VSync), + .r_in(R), + .g_in(G), + .b_in(B), + + .hs_out(hs_sd), + .vs_out(vs_sd), + .r_out(R_sd), + .g_out(G_sd), + .b_out(B_sd) +); + +wire [DWIDTH:0] rt = (scandoubler_disable ? R : R_sd); +wire [DWIDTH:0] gt = (scandoubler_disable ? G : G_sd); +wire [DWIDTH:0] bt = (scandoubler_disable ? B : B_sd); + +generate + if(HALF_DEPTH) begin + wire [5:0] r = mono ? {gt,rt} : {rt,rt}; + wire [5:0] g = mono ? {gt,rt} : {gt,gt}; + wire [5:0] b = mono ? {gt,rt} : {bt,bt}; + end else begin + wire [5:0] r = rt; + wire [5:0] g = gt; + wire [5:0] b = bt; + end +endgenerate + +wire hs = (scandoubler_disable ? HSync : hs_sd); +wire vs = (scandoubler_disable ? VSync : vs_sd); + +reg scanline = 0; +always @(posedge clk_sys) begin + reg old_hs, old_vs; + + old_hs <= hs; + old_vs <= vs; + + if(old_hs && ~hs) scanline <= ~scanline; + if(old_vs && ~vs) scanline <= 0; +end + +wire [5:0] r_out, g_out, b_out; +always @(*) begin + case(scanlines & {scanline, scanline}) + 1: begin // reduce 25% = 1/2 + 1/4 + r_out = {1'b0, r[5:1]} + {2'b00, r[5:2]}; + g_out = {1'b0, g[5:1]} + {2'b00, g[5:2]}; + b_out = {1'b0, b[5:1]} + {2'b00, b[5:2]}; + end + + 2: begin // reduce 50% = 1/2 + r_out = {1'b0, r[5:1]}; + g_out = {1'b0, g[5:1]}; + b_out = {1'b0, b[5:1]}; + end + + 3: begin // reduce 75% = 1/4 + r_out = {2'b00, r[5:2]}; + g_out = {2'b00, g[5:2]}; + b_out = {2'b00, b[5:2]}; + end + + default: begin + r_out = r; + g_out = g; + b_out = b; + end + endcase +end + +wire [5:0] red, green, blue; +osd #(OSD_X_OFFSET, OSD_Y_OFFSET, OSD_COLOR) osd +( + .*, + + .R_in(r_out), + .G_in(g_out), + .B_in(b_out), + .HSync(hs), + .VSync(vs), + + .R_out(red), + .G_out(green), + .B_out(blue) +); + +wire [5:0] yuv_full[225] = '{ + 6'd0, 6'd0, 6'd0, 6'd0, 6'd1, 6'd1, 6'd1, 6'd1, + 6'd2, 6'd2, 6'd2, 6'd3, 6'd3, 6'd3, 6'd3, 6'd4, + 6'd4, 6'd4, 6'd5, 6'd5, 6'd5, 6'd5, 6'd6, 6'd6, + 6'd6, 6'd7, 6'd7, 6'd7, 6'd7, 6'd8, 6'd8, 6'd8, + 6'd9, 6'd9, 6'd9, 6'd9, 6'd10, 6'd10, 6'd10, 6'd11, + 6'd11, 6'd11, 6'd11, 6'd12, 6'd12, 6'd12, 6'd13, 6'd13, + 6'd13, 6'd13, 6'd14, 6'd14, 6'd14, 6'd15, 6'd15, 6'd15, + 6'd15, 6'd16, 6'd16, 6'd16, 6'd17, 6'd17, 6'd17, 6'd17, + 6'd18, 6'd18, 6'd18, 6'd19, 6'd19, 6'd19, 6'd19, 6'd20, + 6'd20, 6'd20, 6'd21, 6'd21, 6'd21, 6'd21, 6'd22, 6'd22, + 6'd22, 6'd23, 6'd23, 6'd23, 6'd23, 6'd24, 6'd24, 6'd24, + 6'd25, 6'd25, 6'd25, 6'd25, 6'd26, 6'd26, 6'd26, 6'd27, + 6'd27, 6'd27, 6'd27, 6'd28, 6'd28, 6'd28, 6'd29, 6'd29, + 6'd29, 6'd29, 6'd30, 6'd30, 6'd30, 6'd31, 6'd31, 6'd31, + 6'd31, 6'd32, 6'd32, 6'd32, 6'd33, 6'd33, 6'd33, 6'd33, + 6'd34, 6'd34, 6'd34, 6'd35, 6'd35, 6'd35, 6'd35, 6'd36, + 6'd36, 6'd36, 6'd36, 6'd37, 6'd37, 6'd37, 6'd38, 6'd38, + 6'd38, 6'd38, 6'd39, 6'd39, 6'd39, 6'd40, 6'd40, 6'd40, + 6'd40, 6'd41, 6'd41, 6'd41, 6'd42, 6'd42, 6'd42, 6'd42, + 6'd43, 6'd43, 6'd43, 6'd44, 6'd44, 6'd44, 6'd44, 6'd45, + 6'd45, 6'd45, 6'd46, 6'd46, 6'd46, 6'd46, 6'd47, 6'd47, + 6'd47, 6'd48, 6'd48, 6'd48, 6'd48, 6'd49, 6'd49, 6'd49, + 6'd50, 6'd50, 6'd50, 6'd50, 6'd51, 6'd51, 6'd51, 6'd52, + 6'd52, 6'd52, 6'd52, 6'd53, 6'd53, 6'd53, 6'd54, 6'd54, + 6'd54, 6'd54, 6'd55, 6'd55, 6'd55, 6'd56, 6'd56, 6'd56, + 6'd56, 6'd57, 6'd57, 6'd57, 6'd58, 6'd58, 6'd58, 6'd58, + 6'd59, 6'd59, 6'd59, 6'd60, 6'd60, 6'd60, 6'd60, 6'd61, + 6'd61, 6'd61, 6'd62, 6'd62, 6'd62, 6'd62, 6'd63, 6'd63, + 6'd63 +}; + +// http://marsee101.blog19.fc2.com/blog-entry-2311.html +// Y = 16 + 0.257*R + 0.504*G + 0.098*B (Y = 0.299*R + 0.587*G + 0.114*B) +// Pb = 128 - 0.148*R - 0.291*G + 0.439*B (Pb = -0.169*R - 0.331*G + 0.500*B) +// Pr = 128 + 0.439*R - 0.368*G - 0.071*B (Pr = 0.500*R - 0.419*G - 0.081*B) + +wire [18:0] y_8 = 19'd04096 + ({red, 8'd0} + {red, 3'd0}) + ({green, 9'd0} + {green, 2'd0}) + ({blue, 6'd0} + {blue, 5'd0} + {blue, 2'd0}); +wire [18:0] pb_8 = 19'd32768 - ({red, 7'd0} + {red, 4'd0} + {red, 3'd0}) - ({green, 8'd0} + {green, 5'd0} + {green, 3'd0}) + ({blue, 8'd0} + {blue, 7'd0} + {blue, 6'd0}); +wire [18:0] pr_8 = 19'd32768 + ({red, 8'd0} + {red, 7'd0} + {red, 6'd0}) - ({green, 8'd0} + {green, 6'd0} + {green, 5'd0} + {green, 4'd0} + {green, 3'd0}) - ({blue, 6'd0} + {blue , 3'd0}); + +wire [7:0] y = ( y_8[17:8] < 16) ? 8'd16 : ( y_8[17:8] > 235) ? 8'd235 : y_8[15:8]; +wire [7:0] pb = (pb_8[17:8] < 16) ? 8'd16 : (pb_8[17:8] > 240) ? 8'd240 : pb_8[15:8]; +wire [7:0] pr = (pr_8[17:8] < 16) ? 8'd16 : (pr_8[17:8] > 240) ? 8'd240 : pr_8[15:8]; + +assign VGA_R = ypbpr ? (ypbpr_full ? yuv_full[pr-8'd16] : pr[7:2]) : red; +assign VGA_G = ypbpr ? (ypbpr_full ? yuv_full[y -8'd16] : y[7:2]) : green; +assign VGA_B = ypbpr ? (ypbpr_full ? yuv_full[pb-8'd16] : pb[7:2]) : blue; +assign VGA_VS = (scandoubler_disable | ypbpr) ? 1'b1 : ~vs_sd; +assign VGA_HS = scandoubler_disable ? ~(HSync ^ VSync) : ypbpr ? ~(hs_sd ^ vs_sd) : ~hs_sd; + +endmodule diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/snapshot/ultratank.rbf b/Arcade_MiST/Custom Hardware/UltraTank_MiST/snapshot/ultratank.rbf new file mode 100644 index 00000000..1dbe331a Binary files /dev/null and b/Arcade_MiST/Custom Hardware/UltraTank_MiST/snapshot/ultratank.rbf differ diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/ultratank.qpf b/Arcade_MiST/Custom Hardware/UltraTank_MiST/ultratank.qpf new file mode 100644 index 00000000..d63a5af5 --- /dev/null +++ b/Arcade_MiST/Custom Hardware/UltraTank_MiST/ultratank.qpf @@ -0,0 +1,30 @@ +# -------------------------------------------------------------------------- # +# +# Copyright (C) 1991-2013 Altera Corporation +# Your use of Altera Corporation's design tools, logic functions +# and other software and tools, and its AMPP partner logic +# functions, and any output files from any of the foregoing +# (including device programming or simulation files), and any +# associated documentation or information are expressly subject +# to the terms and conditions of the Altera Program License +# Subscription Agreement, Altera MegaCore Function License +# Agreement, or other applicable license agreement, including, +# without limitation, that your use is for the sole purpose of +# programming logic devices manufactured by Altera and sold by +# Altera or its authorized distributors. Please refer to the +# applicable agreement for further details. +# +# -------------------------------------------------------------------------- # +# +# Quartus II 64-Bit +# Version 13.0.1 Build 232 06/12/2013 Service Pack 1 SJ Web Edition +# Date created = 19:51:47 November 12, 2017 +# +# -------------------------------------------------------------------------- # + +QUARTUS_VERSION = "13.0" +DATE = "19:51:47 November 12, 2017" + +# Revisions + +PROJECT_REVISION = "ultratank" diff --git a/Arcade_MiST/Custom Hardware/UltraTank_MiST/ultratank.qsf b/Arcade_MiST/Custom Hardware/UltraTank_MiST/ultratank.qsf new file mode 100644 index 00000000..f175df88 --- /dev/null +++ b/Arcade_MiST/Custom Hardware/UltraTank_MiST/ultratank.qsf @@ -0,0 +1,174 @@ +# -------------------------------------------------------------------------- # +# +# Copyright (C) 1991-2014 Altera Corporation +# Your use of Altera Corporation's design tools, logic functions +# and other software and tools, and its AMPP partner logic +# functions, and any output files from any of the foregoing +# (including device programming or simulation files), and any +# associated documentation or information are expressly subject +# to the terms and conditions of the Altera Program License +# Subscription Agreement, Altera MegaCore Function License +# Agreement, or other applicable license agreement, including, +# without limitation, that your use is for the sole purpose of +# programming logic devices manufactured by Altera and sold by +# Altera or its authorized distributors. Please refer to the +# applicable agreement for further details. +# +# -------------------------------------------------------------------------- # +# +# Quartus II 64-Bit +# Version 13.1.4 Build 182 03/12/2014 SJ Web Edition +# Date created = 15:18:38 May 31, 2018 +# +# -------------------------------------------------------------------------- # +# +# Notes: +# +# 1) The default values for assignments are stored in the file: +# sprint1_assignment_defaults.qdf +# If this file doesn't exist, see file: +# assignment_defaults.qdf +# +# 2) Altera recommends that you do not modify this file. This +# file is updated automatically by the Quartus II software +# and any changes you make may be lost or overwritten. +# +# -------------------------------------------------------------------------- # + + + +# Project-Wide Assignments +# ======================== +set_global_assignment -name ORIGINAL_QUARTUS_VERSION "13.0 SP1" +set_global_assignment -name PROJECT_CREATION_TIME_DATE "19:52:16 OCTOBER 10, 2017" +set_global_assignment -name LAST_QUARTUS_VERSION 13.1 +set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files + +# Analysis & Synthesis Assignments +# ================================ +set_global_assignment -name FAMILY "Cyclone III" +set_global_assignment -name ALLOW_POWER_UP_DONT_CARE OFF +set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS OFF +set_global_assignment -name DEVICE_FILTER_PIN_COUNT 144 +set_global_assignment -name DEVICE_FILTER_SPEED_GRADE 8 +set_global_assignment -name TOP_LEVEL_ENTITY ultratank_mist + +# Fitter Assignments +# ================== +set_global_assignment -name DEVICE EP3C25E144C8 +set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "3.3-V LVTTL" +set_global_assignment -name ENABLE_CONFIGURATION_PINS OFF +set_global_assignment -name ENABLE_NCE_PIN OFF +set_global_assignment -name ENABLE_BOOT_SEL_PIN OFF +set_global_assignment -name CYCLONEIII_CONFIGURATION_SCHEME "PASSIVE SERIAL" +set_global_assignment -name CRC_ERROR_OPEN_DRAIN OFF +set_global_assignment -name FORCE_CONFIGURATION_VCCIO ON +set_global_assignment -name CYCLONEII_RESERVE_NCEO_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_global_assignment -name RESERVE_DATA0_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_global_assignment -name RESERVE_DATA1_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_global_assignment -name RESERVE_FLASH_NCE_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_global_assignment -name RESERVE_DCLK_AFTER_CONFIGURATION "USE AS REGULAR IO" + +# Assembler Assignments +# ===================== +set_global_assignment -name USE_CONFIGURATION_DEVICE OFF +set_global_assignment -name GENERATE_RBF_FILE ON + +# SignalTap II Assignments +# ======================== +set_global_assignment -name ENABLE_SIGNALTAP OFF +set_global_assignment -name USE_SIGNALTAP_FILE output_files/stp3.stp + +# Advanced I/O Timing Assignments +# =============================== +set_global_assignment -name OUTPUT_IO_TIMING_NEAR_END_VMEAS "HALF VCCIO" -rise +set_global_assignment -name OUTPUT_IO_TIMING_NEAR_END_VMEAS "HALF VCCIO" -fall +set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -rise +set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -fall + +# --------------------- +# start ENTITY(sprint1) +set_location_assignment PIN_7 -to LED +set_location_assignment PIN_54 -to CLOCK_27 +set_location_assignment PIN_144 -to VGA_R[5] +set_location_assignment PIN_143 -to VGA_R[4] +set_location_assignment PIN_142 -to VGA_R[3] +set_location_assignment PIN_141 -to VGA_R[2] +set_location_assignment PIN_137 -to VGA_R[1] +set_location_assignment PIN_135 -to VGA_R[0] +set_location_assignment PIN_133 -to VGA_B[5] +set_location_assignment PIN_132 -to VGA_B[4] +set_location_assignment PIN_125 -to VGA_B[3] +set_location_assignment PIN_121 -to VGA_B[2] +set_location_assignment PIN_120 -to VGA_B[1] +set_location_assignment PIN_115 -to VGA_B[0] +set_location_assignment PIN_114 -to VGA_G[5] +set_location_assignment PIN_113 -to VGA_G[4] +set_location_assignment PIN_112 -to VGA_G[3] +set_location_assignment PIN_111 -to VGA_G[2] +set_location_assignment PIN_110 -to VGA_G[1] +set_location_assignment PIN_106 -to VGA_G[0] +set_location_assignment PIN_136 -to VGA_VS +set_location_assignment PIN_119 -to VGA_HS +set_location_assignment PIN_65 -to AUDIO_L +set_location_assignment PIN_80 -to AUDIO_R +set_location_assignment PIN_46 -to UART_TX +set_location_assignment PIN_31 -to UART_RX +set_location_assignment PIN_105 -to SPI_DO +set_location_assignment PIN_88 -to SPI_DI +set_location_assignment PIN_126 -to SPI_SCK +set_location_assignment PIN_127 -to SPI_SS2 +set_location_assignment PIN_91 -to SPI_SS3 +set_location_assignment PIN_90 -to SPI_SS4 +set_location_assignment PIN_13 -to CONF_DATA0 +# end ENTITY(sprint1) +# ------------------- + +# -------------------------- +# start ENTITY(sprint1_mist) + + # start DESIGN_PARTITION(Top) + # --------------------------- + + # Incremental Compilation Assignments + # =================================== + + # end DESIGN_PARTITION(Top) + # ------------------------- + +# end ENTITY(sprint1_mist) +# ------------------------ +set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0 +set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85 +set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW" +set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)" +set_global_assignment -name SYSTEMVERILOG_FILE rtl/ultratank_mist.sv +set_global_assignment -name VHDL_FILE rtl/ultra_tank.vhd +set_global_assignment -name VERILOG_FILE rtl/pll.v +set_global_assignment -name VHDL_FILE rtl/sync.vhd +set_global_assignment -name VHDL_FILE rtl/collision.vhd +set_global_assignment -name VHDL_FILE rtl/screech.vhd +set_global_assignment -name VHDL_FILE rtl/cpu_mem.vhd +set_global_assignment -name VHDL_FILE rtl/playfield.vhd +set_global_assignment -name VHDL_FILE rtl/EngineSound.vhd +set_global_assignment -name VHDL_FILE rtl/Inputs.vhd +set_global_assignment -name VHDL_FILE rtl/motion.vhd +set_global_assignment -name SYSTEMVERILOG_FILE rtl/video_mixer.sv +set_global_assignment -name SYSTEMVERILOG_FILE rtl/scandoubler.sv +set_global_assignment -name SYSTEMVERILOG_FILE rtl/osd.sv +set_global_assignment -name VHDL_FILE rtl/sprom.vhd +set_global_assignment -name SYSTEMVERILOG_FILE rtl/mist_io.sv +set_global_assignment -name SYSTEMVERILOG_FILE rtl/keyboard.sv +set_global_assignment -name SYSTEMVERILOG_FILE rtl/hq2x.sv +set_global_assignment -name SYSTEMVERILOG_FILE rtl/dac.sv +set_global_assignment -name SYSTEMVERILOG_FILE rtl/build_id.sv +set_global_assignment -name VHDL_FILE rtl/T65/T65_Pack.vhd +set_global_assignment -name VHDL_FILE rtl/T65/T65_MCode.vhd +set_global_assignment -name VHDL_FILE rtl/T65/T65_ALU.vhd +set_global_assignment -name VHDL_FILE rtl/T65/T65.vhd +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 VHDL_FILE rtl/spram.vhd +set_global_assignment -name VHDL_FILE rtl/sound.vhd +set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file