diff --git a/Arcade_MiST/Sega Bank Panic Hardware/BankPanic.qpf b/Arcade_MiST/Sega Bank Panic Hardware/BankPanic.qpf
new file mode 100644
index 00000000..7e76628f
--- /dev/null
+++ b/Arcade_MiST/Sega Bank Panic Hardware/BankPanic.qpf
@@ -0,0 +1,31 @@
+# -------------------------------------------------------------------------- #
+#
+# 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.1.0 Build 162 10/23/2013 SJ Web Edition
+# Date created = 00:21:03 December 03, 2019
+#
+# -------------------------------------------------------------------------- #
+
+QUARTUS_VERSION = "13.1"
+DATE = "00:21:03 December 03, 2019"
+
+# Revisions
+
+PROJECT_REVISION = "BankPanic"
+
diff --git a/Arcade_MiST/Sega Bank Panic Hardware/BankPanic.qsf b/Arcade_MiST/Sega Bank Panic Hardware/BankPanic.qsf
new file mode 100644
index 00000000..c1b58567
--- /dev/null
+++ b/Arcade_MiST/Sega Bank Panic Hardware/BankPanic.qsf
@@ -0,0 +1,241 @@
+# -------------------------------------------------------------------------- #
+#
+# 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 Full Version
+# Date created = 15:08:12 December 26, 2022
+#
+# -------------------------------------------------------------------------- #
+#
+# Notes:
+#
+# 1) The default values for assignments are stored in the file:
+# BankPanic_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 PROJECT_OUTPUT_DIRECTORY output_files
+set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL
+set_global_assignment -name LAST_QUARTUS_VERSION 13.1
+set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:rtl/build_id.tcl"
+
+# Pin & Location Assignments
+# ==========================
+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_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_13 -to CONF_DATA0
+set_location_assignment PIN_49 -to SDRAM_A[0]
+set_location_assignment PIN_44 -to SDRAM_A[1]
+set_location_assignment PIN_42 -to SDRAM_A[2]
+set_location_assignment PIN_39 -to SDRAM_A[3]
+set_location_assignment PIN_4 -to SDRAM_A[4]
+set_location_assignment PIN_6 -to SDRAM_A[5]
+set_location_assignment PIN_8 -to SDRAM_A[6]
+set_location_assignment PIN_10 -to SDRAM_A[7]
+set_location_assignment PIN_11 -to SDRAM_A[8]
+set_location_assignment PIN_28 -to SDRAM_A[9]
+set_location_assignment PIN_50 -to SDRAM_A[10]
+set_location_assignment PIN_30 -to SDRAM_A[11]
+set_location_assignment PIN_32 -to SDRAM_A[12]
+set_location_assignment PIN_83 -to SDRAM_DQ[0]
+set_location_assignment PIN_79 -to SDRAM_DQ[1]
+set_location_assignment PIN_77 -to SDRAM_DQ[2]
+set_location_assignment PIN_76 -to SDRAM_DQ[3]
+set_location_assignment PIN_72 -to SDRAM_DQ[4]
+set_location_assignment PIN_71 -to SDRAM_DQ[5]
+set_location_assignment PIN_69 -to SDRAM_DQ[6]
+set_location_assignment PIN_68 -to SDRAM_DQ[7]
+set_location_assignment PIN_86 -to SDRAM_DQ[8]
+set_location_assignment PIN_87 -to SDRAM_DQ[9]
+set_location_assignment PIN_98 -to SDRAM_DQ[10]
+set_location_assignment PIN_99 -to SDRAM_DQ[11]
+set_location_assignment PIN_100 -to SDRAM_DQ[12]
+set_location_assignment PIN_101 -to SDRAM_DQ[13]
+set_location_assignment PIN_103 -to SDRAM_DQ[14]
+set_location_assignment PIN_104 -to SDRAM_DQ[15]
+set_location_assignment PIN_58 -to SDRAM_BA[0]
+set_location_assignment PIN_51 -to SDRAM_BA[1]
+set_location_assignment PIN_85 -to SDRAM_DQMH
+set_location_assignment PIN_67 -to SDRAM_DQML
+set_location_assignment PIN_60 -to SDRAM_nRAS
+set_location_assignment PIN_64 -to SDRAM_nCAS
+set_location_assignment PIN_66 -to SDRAM_nWE
+set_location_assignment PIN_59 -to SDRAM_nCS
+set_location_assignment PIN_33 -to SDRAM_CKE
+set_location_assignment PIN_43 -to SDRAM_CLK
+set_location_assignment PLL_1 -to "pll:pll|altpll:altpll_component"
+
+# Classic Timing Assignments
+# ==========================
+set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0
+set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85
+
+# Analysis & Synthesis Assignments
+# ================================
+set_global_assignment -name FAMILY "Cyclone III"
+set_global_assignment -name DEVICE_FILTER_PIN_COUNT 144
+set_global_assignment -name DEVICE_FILTER_SPEED_GRADE 8
+set_global_assignment -name DEVICE_FILTER_PACKAGE TQFP
+set_global_assignment -name TOP_LEVEL_ENTITY BankPanic_MiST
+
+# Fitter Assignments
+# ==================
+set_global_assignment -name DEVICE EP3C25E144C8
+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 STRATIX_DEVICE_IO_STANDARD "3.3-V LVTTL"
+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 GENERATE_RBF_FILE ON
+set_global_assignment -name USE_CONFIGURATION_DEVICE OFF
+
+# SignalTap II Assignments
+# ========================
+set_global_assignment -name ENABLE_SIGNALTAP OFF
+set_global_assignment -name USE_SIGNALTAP_FILE output_files/bankp.stp
+
+# Power Estimation Assignments
+# ============================
+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)"
+
+# 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(BankPanic)
+
+ # Pin & Location Assignments
+ # ==========================
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[*]
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[*]
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_BA[0]
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_BA[1]
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQMH
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQML
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nRAS
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nCAS
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nWE
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nCS
+set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[*]
+set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[*]
+
+ # Fitter Assignments
+ # ==================
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[*]
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[*]
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_BA[*]
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQML
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQMH
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nRAS
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nCAS
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nWE
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nCS
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_CKE
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_CLK
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_R[*]
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_G[*]
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_B[*]
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_HS
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_VS
+set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to AUDIO_L
+set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to AUDIO_R
+set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SPI_DO
+
+ # start DESIGN_PARTITION(Top)
+ # ---------------------------
+
+ # Incremental Compilation Assignments
+ # ===================================
+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
+
+ # end DESIGN_PARTITION(Top)
+ # -------------------------
+
+# end ENTITY(BankPanic)
+# ------------------
+set_global_assignment -name VERILOG_SHOW_LMF_MAPPING_MESSAGES OFF
+set_global_assignment -name VERILOG_MACRO "EXT_ROM=1"
+set_global_assignment -name SYSTEMVERILOG_FILE rtl/BankPanic_MiST.sv
+set_global_assignment -name SYSTEMVERILOG_FILE rtl/sdram.sv
+set_global_assignment -name VERILOG_FILE rtl/x74139.v
+set_global_assignment -name VERILOG_FILE rtl/x74138.v
+set_global_assignment -name VHDL_FILE rtl/sn76489_audio.vhd
+set_global_assignment -name VERILOG_FILE rtl/pll_mist.v
+set_global_assignment -name QIP_FILE rtl/pll_mist.qip
+set_global_assignment -name VERILOG_FILE rtl/dpram.v
+set_global_assignment -name VERILOG_FILE rtl/core.v
+set_global_assignment -name VERILOG_FILE rtl/clk_en.v
+set_global_assignment -name QIP_FILE ../../common/CPU/T80/T80.qip
+set_global_assignment -name QIP_FILE ../../common/mist/mist.qip
+set_global_assignment -name SIGNALTAP_FILE output_files/bankp.stp
+set_global_assignment -name SIGNALTAP_FILE output_files/cpu.stp
+set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
\ No newline at end of file
diff --git a/Arcade_MiST/Sega Bank Panic Hardware/BankPanic.sdc b/Arcade_MiST/Sega Bank Panic Hardware/BankPanic.sdc
new file mode 100644
index 00000000..59bf935d
--- /dev/null
+++ b/Arcade_MiST/Sega Bank Panic Hardware/BankPanic.sdc
@@ -0,0 +1,135 @@
+## Generated SDC file "vectrex_MiST.out.sdc"
+
+## 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.
+
+
+## VENDOR "Altera"
+## PROGRAM "Quartus II"
+## VERSION "Version 13.1.0 Build 162 10/23/2013 SJ Web Edition"
+
+## DATE "Sun Jun 24 12:53:00 2018"
+
+##
+## DEVICE "EP3C25E144C8"
+##
+
+# Clock constraints
+
+# Automatically constrain PLL and other generated clocks
+derive_pll_clocks -create_base_clocks
+
+# Automatically calculate clock uncertainty to jitter and other effects.
+derive_clock_uncertainty
+
+# tsu/th constraints
+
+# tco constraints
+
+# tpd constraints
+
+#**************************************************************
+# Time Information
+#**************************************************************
+
+set_time_format -unit ns -decimal_places 3
+
+
+
+#**************************************************************
+# Create Clock
+#**************************************************************
+
+create_clock -name {SPI_SCK} -period 41.666 -waveform { 20.8 41.666 } [get_ports {SPI_SCK}]
+
+set sys_clk "pll|altpll_component|auto_generated|pll1|clk[1]"
+set sdram_clk "pll|altpll_component|auto_generated|pll1|clk[0]"
+set aud_clk "pll|altpll_component|auto_generated|pll1|clk[1]"
+#**************************************************************
+# Create Generated Clock
+#**************************************************************
+
+
+#**************************************************************
+# Set Clock Latency
+#**************************************************************
+
+
+
+#**************************************************************
+# Set Clock Uncertainty
+#**************************************************************
+
+#**************************************************************
+# Set Input Delay
+#**************************************************************
+
+set_input_delay -add_delay -clock_fall -clock [get_clocks {CLOCK_27}] 1.000 [get_ports {CLOCK_27}]
+set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {CONF_DATA0}]
+set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_DI}]
+set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_SCK}]
+set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_SS2}]
+set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_SS3}]
+
+set_input_delay -clock [get_clocks $sdram_clk] -reference_pin [get_ports {SDRAM_CLK}] -max 6.6 [get_ports SDRAM_DQ[*]]
+set_input_delay -clock [get_clocks $sdram_clk] -reference_pin [get_ports {SDRAM_CLK}] -min 3.5 [get_ports SDRAM_DQ[*]]
+
+#**************************************************************
+# Set Output Delay
+#**************************************************************
+
+set_output_delay -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_DO}]
+set_output_delay -clock [get_clocks $aud_clk] 1.000 [get_ports {AUDIO_L}]
+set_output_delay -clock [get_clocks $aud_clk] 1.000 [get_ports {AUDIO_R}]
+set_output_delay -clock [get_clocks $sys_clk] 1.000 [get_ports {LED}]
+set_output_delay -clock [get_clocks $sys_clk] 1.000 [get_ports {VGA_*}]
+
+set_output_delay -clock [get_clocks $sdram_clk] -reference_pin [get_ports {SDRAM_CLK}] -max 1.5 [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}]
+set_output_delay -clock [get_clocks $sdram_clk] -reference_pin [get_ports {SDRAM_CLK}] -min -0.8 [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}]
+
+#**************************************************************
+# Set Clock Groups
+#**************************************************************
+
+set_clock_groups -asynchronous -group [get_clocks {SPI_SCK}] -group [get_clocks {pll|altpll_component|auto_generated|pll1|clk[*]}]
+
+#**************************************************************
+# Set False Path
+#**************************************************************
+
+
+
+#**************************************************************
+# Set Multicycle Path
+#**************************************************************
+
+set_multicycle_path -to {VGA_*[*]} -setup 2
+set_multicycle_path -to {VGA_*[*]} -hold 1
+
+#**************************************************************
+# Set Maximum Delay
+#**************************************************************
+
+
+
+#**************************************************************
+# Set Minimum Delay
+#**************************************************************
+
+
+
+#**************************************************************
+# Set Input Transition
+#**************************************************************
+
diff --git a/Arcade_MiST/Sega Bank Panic Hardware/Readme.md b/Arcade_MiST/Sega Bank Panic Hardware/Readme.md
new file mode 100644
index 00000000..cc52344a
--- /dev/null
+++ b/Arcade_MiST/Sega Bank Panic Hardware/Readme.md
@@ -0,0 +1,10 @@
+# BankPanic for MiSTerFPGA
+
+## General description
+This is the port of Bank Panic for MiSTerFPGA by Pierco (Pierre Cornier). I tried to reproduce the PCB as much as possible so it should be very close to the original hardware.
+
+I would like to give special thanks to Mark Haysman from RetroClinic for sharing the equations of the PAL 315-5075, and to David Shadoff, Alan Steremberg & Chockichoc for their support and friendship!
+
+MiST port, SDRAM controller and convert to fully synchronous logic by Gyorgy Szombathelyi.
+
+Original core: https://github.com/MiSTer-devel/Arcade-BankPanic_MiSTer
\ No newline at end of file
diff --git a/Arcade_MiST/Sega Bank Panic Hardware/meta/BankPanic.mra b/Arcade_MiST/Sega Bank Panic Hardware/meta/BankPanic.mra
new file mode 100644
index 00000000..6799bb8c
--- /dev/null
+++ b/Arcade_MiST/Sega Bank Panic Hardware/meta/BankPanic.mra
@@ -0,0 +1,89 @@
+
+ BankPanic
+
+ no
+ no
+
+
+
+
+ 1984
+ Sanritsu/Sega
+ Shooter/1stPerson
+
+ bankp
+ 0247
+ bankpanic
+
+
+ 15kHz
+ horizontal
+
+
+ 2
+ 2-way
+
+ 3
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 202108231828
+
diff --git a/Arcade_MiST/Sega Bank Panic Hardware/meta/Combat Hawk.mra b/Arcade_MiST/Sega Bank Panic Hardware/meta/Combat Hawk.mra
new file mode 100644
index 00000000..c6ca2d2a
--- /dev/null
+++ b/Arcade_MiST/Sega Bank Panic Hardware/meta/Combat Hawk.mra
@@ -0,0 +1,57 @@
+
+ Combat Hawk
+ no
+ no
+ 1987
+ Sanritsu/Sega
+ Shooter/1stPerson
+ combh
+ 0247
+ bankpanic
+ 15kHz
+ horizontal
+ 2
+ 2-way
+ 3
+
+
+
+
+
+
+
+
+
+
+
+ 01
+
+
+
+
+
+
+
+ 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Arcade_MiST/Sega Bank Panic Hardware/rtl/BankPanic_MiST.sv b/Arcade_MiST/Sega Bank Panic Hardware/rtl/BankPanic_MiST.sv
new file mode 100644
index 00000000..0fa2fce5
--- /dev/null
+++ b/Arcade_MiST/Sega Bank Panic Hardware/rtl/BankPanic_MiST.sv
@@ -0,0 +1,284 @@
+
+module BankPanic_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,
+
+ output [12:0] SDRAM_A,
+ inout [15:0] SDRAM_DQ,
+ output SDRAM_DQML,
+ output SDRAM_DQMH,
+ output SDRAM_nWE,
+ output SDRAM_nCAS,
+ output SDRAM_nRAS,
+ output SDRAM_nCS,
+ output [1:0] SDRAM_BA,
+ output SDRAM_CLK,
+ output SDRAM_CKE
+);
+
+`include "rtl/build_id.v"
+
+localparam CONF_STR = {
+ "BANKP;;",
+ "O2,Rotate Controls,Off,On;",
+ "O34,Scanlines,Off,25%,50%,75%;",
+ "O5,Blend,Off,On;",
+ "O6,Joystick Swap,Off,On;",
+ "DIP;",
+ "T0,Reset;",
+ "V,v1.0.",`BUILD_DATE
+};
+
+wire rotate = status[2];
+wire [1:0] scanlines = status[4:3];
+wire blend = status[5];
+wire joyswap = status[6];
+wire [7:0] dsw = status[15:8];
+wire [1:0] orientation = {core_mod[0] & dsw[0], core_mod[0]};
+
+assign LED = ~ioctl_downl;
+assign AUDIO_R = AUDIO_L;
+
+wire clk_sys, clk_mem, pll_locked;
+pll_mist pll(
+ .inclk0(CLOCK_27),
+ .c0(clk_mem),//93
+ .c1(clk_sys),//31
+ .locked(pll_locked)
+ );
+assign SDRAM_CLK = clk_mem;
+assign SDRAM_CKE = 1;
+
+wire [63:0] status;
+wire [1:0] buttons;
+wire [1:0] switches;
+wire [7:0] joystick_0;
+wire [7:0] joystick_1;
+wire scandoublerD;
+wire ypbpr;
+wire no_csync;
+wire [6:0] core_mod;
+
+wire ioctl_downl;
+wire [7:0] ioctl_index;
+wire ioctl_wr;
+wire [24:0] ioctl_addr;
+wire [7:0] ioctl_dout;
+wire key_strobe;
+wire key_pressed;
+wire [7:0] key_code;
+
+user_io #(
+ .STRLEN(($size(CONF_STR)>>3)))
+user_io(
+ .clk_sys (clk_sys ),
+ .conf_str (CONF_STR ),
+ .SPI_CLK (SPI_SCK ),
+ .SPI_SS_IO (CONF_DATA0 ),
+ .SPI_MISO (SPI_DO ),
+ .SPI_MOSI (SPI_DI ),
+ .buttons (buttons ),
+ .switches (switches ),
+ .scandoubler_disable (scandoublerD ),
+ .ypbpr (ypbpr ),
+ .no_csync (no_csync ),
+ .core_mod (core_mod ),
+ .key_strobe (key_strobe ),
+ .key_pressed (key_pressed ),
+ .key_code (key_code ),
+ .joystick_0 (joystick_0 ),
+ .joystick_1 (joystick_1 ),
+ .status (status )
+ );
+
+data_io data_io(
+ .clk_sys ( clk_sys ),
+ .SPI_SCK ( SPI_SCK ),
+ .SPI_SS2 ( SPI_SS2 ),
+ .SPI_DI ( SPI_DI ),
+ .ioctl_download( ioctl_downl ),
+ .ioctl_index ( ioctl_index ),
+ .ioctl_wr ( ioctl_wr ),
+ .ioctl_addr ( ioctl_addr ),
+ .ioctl_dout ( ioctl_dout )
+);
+
+reg reset = 1;
+reg rom_loaded = 0;
+always @(posedge clk_sys) begin
+ reg ioctl_downlD;
+ ioctl_downlD <= ioctl_downl;
+
+ if (ioctl_downlD & ~ioctl_downl) rom_loaded <= 1;
+ reset <= status[0] | buttons[1] | ~rom_loaded;
+end
+
+wire [15:0] cpu_rom_addr;
+wire cpu_rom_cs;
+wire [15:0] cpu_rom_data;
+wire [13:0] bg_rom_addr;
+wire [15:0] bg_rom_data;
+wire [13:0] sp_rom_addr;
+wire [31:0] sp_rom_data;
+reg port1_req, port2_req;
+
+// ROM download controller
+always @(posedge clk_sys) begin
+ reg ioctl_wr_last = 0;
+
+ ioctl_wr_last <= ioctl_wr;
+ if (ioctl_downl) begin
+ if (~ioctl_wr_last && ioctl_wr) begin
+ port1_req <= ~port1_req;
+ port2_req <= ~port2_req;
+ end
+ end
+end
+
+sdram #(93) sdram
+(
+ .*,
+ .init_n ( pll_locked ),
+ .clk ( clk_mem ),
+
+ // Bank 0-1 ops
+ .port1_req ( port1_req ),
+ .port1_ack ( ),
+ .port1_a ( ioctl_addr[23:1] ),
+ .port1_ds ( {ioctl_addr[0], ~ioctl_addr[0]} ),
+ .port1_we ( ioctl_downl ),
+ .port1_d ( {ioctl_dout, ioctl_dout} ),
+ .port1_q ( ),
+
+ // Main CPU
+ .cpu1_addr ( cpu_rom_addr[15:1] ),
+ .cpu1_cs ( cpu_rom_cs ),
+ .cpu1_q ( cpu_rom_data ),
+
+ .cpu2_addr ( bg_rom_addr[13:1] + 19'h8000 ),
+ .cpu2_q ( bg_rom_data ),
+
+ // Bank 2-3 ops
+ .port2_req ( port2_req ),
+ .port2_ack ( ),
+ .port2_a ( ioctl_addr[23:1] ),
+ .port2_ds ( {ioctl_addr[0], ~ioctl_addr[0]} ),
+ .port2_we ( ioctl_downl ),
+ .port2_d ( {ioctl_dout, ioctl_dout} ),
+ .port2_q ( ),
+
+ .sp_addr ( sp_rom_addr + 17'h5000 ),
+ .sp_q ( sp_rom_data )
+);
+
+wire [15:0] audio;
+wire hs, vs, cs;
+wire hb, vb;
+wire blankn = ~(hb | vb);
+wire [2:0] g, r;
+wire [1:0] b;
+
+wire [7:0] p1 = { m_fireB, m_fireD, m_coin1, m_fireA, core_mod[0] ? {1'b0, m_down, 1'b0, m_up} : {m_left, 1'b0, m_right, 1'b0} };
+wire [7:0] p2 = { m_fire2B, m_two_players, m_one_player, m_fire2A, core_mod[0] ? {1'b0, m_down2, 1'b0, m_up2} : {m_left2, 1'b0, m_right2, 1'b0} };
+wire [7:0] p3 = { 4'd0, m_fireE, m_coin2, m_fire2C, m_fireC };
+
+core u_core(
+ .reset ( reset ),
+ .clk_sys ( clk_sys ),
+ .p1 ( p1 ),
+ .p2 ( p2 ),
+ .p3 ( p3 ),
+ .dsw ( dsw ),
+ .ioctl_index ( ioctl_index ),
+ .ioctl_download ( ioctl_downl ),
+ .ioctl_addr ( ioctl_addr ),
+ .ioctl_dout ( ioctl_dout ),
+ .ioctl_wr ( ioctl_wr ),
+ .red ( r ),
+ .green ( g ),
+ .blue ( b ),
+ .vs ( vs ),
+ .vb ( vb ),
+ .hs ( hs ),
+ .hb ( hb ),
+ .ce_pix ( ),
+ .sound ( audio ),
+ .hoffs ( 0 ),
+ .cpu_rom_addr ( cpu_rom_addr ),
+ .cpu_rom_cs ( cpu_rom_cs ),
+ .cpu_rom_data ( cpu_rom_addr[0] ? cpu_rom_data[15:8] : cpu_rom_data[7:0] ),
+ .bg_rom_addr ( bg_rom_addr ),
+ .bg_rom_data ( bg_rom_addr[0] ? bg_rom_data[15:8] : bg_rom_data[7:0] ),
+ .sp_rom_addr ( sp_rom_addr ),
+ .sp_rom_data ( sp_rom_data )
+);
+
+mist_video #(.COLOR_DEPTH(3), .SD_HCNT_WIDTH(10)) mist_video(
+ .clk_sys ( clk_sys ),
+ .SPI_SCK ( SPI_SCK ),
+ .SPI_SS3 ( SPI_SS3 ),
+ .SPI_DI ( SPI_DI ),
+ .R ( blankn ? r : 0 ),
+ .G ( blankn ? g : 0 ),
+ .B ( blankn ? {b,b[1]} : 0 ),
+ .HSync ( hs ),
+ .VSync ( vs ),
+ .VGA_R ( VGA_R ),
+ .VGA_G ( VGA_G ),
+ .VGA_B ( VGA_B ),
+ .VGA_VS ( VGA_VS ),
+ .VGA_HS ( VGA_HS ),
+ .ce_divider ( 0 ),
+ .rotate ( { orientation[1], rotate } ),
+ .blend ( blend ),
+ .scandoubler_disable( scandoublerD ),
+ .scanlines ( scanlines ),
+ .ypbpr ( ypbpr ),
+ .no_csync ( no_csync )
+ );
+
+dac #(
+ .C_bits(16))
+dac_l(
+ .clk_i(clk_sys),
+ .res_n_i(1),
+ .dac_i(audio),
+ .dac_o(AUDIO_L)
+ );
+
+
+// General controls
+wire m_up, m_down, m_left, m_right, m_fireA, m_fireB, m_fireC, m_fireD, m_fireE, m_fireF;
+wire m_up2, m_down2, m_left2, m_right2, m_fire2A, m_fire2B, m_fire2C, m_fire2D, m_fire2E, m_fire2F;
+wire m_tilt, m_coin1, m_coin2, m_coin3, m_coin4, m_one_player, m_two_players, m_three_players, m_four_players;
+
+arcade_inputs inputs (
+ .clk ( clk_sys ),
+ .key_strobe ( key_strobe ),
+ .key_pressed ( key_pressed ),
+ .key_code ( key_code ),
+ .joystick_0 ( joystick_0 ),
+ .joystick_1 ( joystick_1 ),
+ .rotate ( rotate ),
+ .orientation ( orientation ),
+ .joyswap ( joyswap ),
+ .oneplayer ( 1'b0 ),
+ .controls ( {m_tilt, m_coin4, m_coin3, m_coin2, m_coin1, m_four_players, m_three_players, m_two_players, m_one_player} ),
+ .player1 ( {m_fireF, m_fireE, m_fireD, m_fireC, m_fireB, m_fireA, m_up, m_down, m_left, m_right} ),
+ .player2 ( {m_fire2F, m_fire2E, m_fire2D, m_fire2C, m_fire2B, m_fire2A, m_up2, m_down2, m_left2, m_right2} )
+);
+
+endmodule
diff --git a/Arcade_MiST/Sega Bank Panic Hardware/rtl/build_id.tcl b/Arcade_MiST/Sega Bank Panic Hardware/rtl/build_id.tcl
new file mode 100644
index 00000000..938515d8
--- /dev/null
+++ b/Arcade_MiST/Sega Bank Panic Hardware/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.v"
+ 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/Sega Bank Panic Hardware/rtl/clk_en.v b/Arcade_MiST/Sega Bank Panic Hardware/rtl/clk_en.v
new file mode 100644
index 00000000..f0192c91
--- /dev/null
+++ b/Arcade_MiST/Sega Bank Panic Hardware/rtl/clk_en.v
@@ -0,0 +1,23 @@
+
+module clk_en #(
+ parameter DIV=12,
+ parameter OFFSET=0
+)
+(
+ input ref_clk,
+ output reg cen
+);
+
+reg [15:0] cnt = OFFSET;
+always @(posedge ref_clk) begin
+ if (cnt == DIV) begin
+ cnt <= 16'd0;
+ cen <= 1'b1;
+ end
+ else begin
+ cen <= 1'b0;
+ cnt <= cnt + 16'd1;
+ end
+end
+
+endmodule
diff --git a/Arcade_MiST/Sega Bank Panic Hardware/rtl/core.v b/Arcade_MiST/Sega Bank Panic Hardware/rtl/core.v
new file mode 100644
index 00000000..ce2bc010
--- /dev/null
+++ b/Arcade_MiST/Sega Bank Panic Hardware/rtl/core.v
@@ -0,0 +1,752 @@
+
+module core(
+ input reset,
+ input clk_sys,
+
+ input [7:0] p1,
+ input [7:0] p2,
+ input [7:0] p3,
+ input [7:0] dsw,
+
+ input [7:0] ioctl_index,
+ input ioctl_download,
+ input [26:0] ioctl_addr,
+ input [15:0] ioctl_dout,
+ input ioctl_wr,
+
+ output [2:0] red,
+ output [2:0] green,
+ output [1:0] blue,
+ output reg vb,
+ output hb,
+ output vs,
+ output reg hs,
+ output ce_pix,
+ input [4:0] hoffs,
+
+ output [15:0] sound,
+
+ output [15:0] cpu_rom_addr,
+ output cpu_rom_cs,
+ input [7:0] cpu_rom_data,
+ output [13:0] bg_rom_addr,
+ input [7:0] bg_rom_data,
+ output [13:0] sp_rom_addr,
+ input [23:0] sp_rom_data
+
+);
+
+/******** LOAD ROMs ********/
+
+wire [7:0] col_data = ioctl_dout;
+wire [7:0] fg_color_addr = ioctl_download ? ioctl_addr - 27'h24020 : rc_addr;
+wire fg_color_wren = ioctl_download && ioctl_addr >= 27'h24020 && ioctl_addr < 27'h24120 ? ioctl_wr : 1'b0;
+wire [7:0] bg_color_addr = ioctl_download ? ioctl_addr - 27'h24120 : sc_addr;
+wire bg_color_wren = ioctl_download && ioctl_addr >= 27'h24120 && ioctl_addr < 27'h24220 ? ioctl_wr : 1'b0;
+wire [4:0] pal_addr = ioctl_download ? ioctl_addr - 27'h24000 : { back, col };
+wire pal_wren = ioctl_download && ioctl_addr >= 27'h24000 && ioctl_addr < 27'h24020 ? ioctl_wr : 1'b0;
+
+/******** RGB ********/
+
+reg [7:0] color;
+always @(posedge clk_sys)
+ if (clk_en_514) color <= u8H[2] ? pal_data : 8'd0;
+
+assign ce_pix = clk_en_514;
+assign { blue, green, red } = color;
+
+/******** CLOCKS ********/
+
+// 31/12 =2.5833
+// 31/6 =5.1666
+
+wire clk_en_257, clk_en_514;
+clk_en #(11) mcpu_clk_en(clk_sys, clk_en_257);
+clk_en #(5) pxl_clk_en(clk_sys, clk_en_514);
+
+
+/******** PAL 315-5074 ********/
+
+wire rld_n = ~(&sh[1:0] & hcount[8]) /* synthesis keep */;
+wire rch_set_n = ~(sh[0] & ~sh[1] & sh[2] & hcount[8]) /* synthesis keep */;
+wire rcol_set_n = ~(sh[0] & sh[1] & ~sh[2] & hcount[8]) /* synthesis keep */;
+wire rad_sel_n = hcount[8] & ~vb /* synthesis keep */;
+wire sld_n = ~(&hcount[2:0] & hcount[8]) /* synthesis keep */;
+wire sch_set_n = ~(hcount[0] & ~hcount[1] & ~hcount[2] & hcount[8]) /* synthesis keep */;
+wire scol_set_n = ~(hcount[0] & hcount[1] & ~hcount[2] & hcount[8]) /* synthesis keep */;
+wire sad_sel_n = ~hcount[2] & ~vb /* synthesis keep */;
+
+/******** PAL 315-5075 ********/
+
+reg cpusel_n;
+reg o13; // cpu wait
+reg rf16, rf15, rf14, rf13;
+
+wire pre = ~hcount[8];
+reg oldh2;
+always @(posedge clk_sys) begin
+ oldh2 <= hcount[2];
+ if (~pre) cpusel_n <= 1'b1;
+ if (pre & ~oldh2 & hcount[2]) begin
+ cpusel_n <= hcount[5] & hs;
+ end
+end
+
+wire srwr_n = ~((vb & ~sram_cs_n & ~mcpu_wr_n)
+ | (~sram_cs_n & ~mcpu_wr_n & rf16));
+wire rrwr_n = ~((vb & ~rram_cs_n & ~mcpu_wr_n)
+ | (~rram_cs_n & sram_cs_n & ~mcpu_wr_n & ~hcount[8] & ~cpusel_n)
+ | (~rram_cs_n & ~mcpu_wr_n & ~hcount[8] & ~cpusel_n & rf15));
+
+
+//always @(posedge clk_en_514) begin
+always @(posedge clk_sys) begin
+ if (clk_en_514) begin
+ o13 <= ~((~vb & ~sram_cs_n & ~rf15)
+ | (~vb & ~rram_cs_n & cpusel_n));
+ rf14 <= ~vb & ~sram_cs_n & ~rf15;
+ rf15 <= (rf15 & ~sram_cs_n)
+ | (hcount[0] & hcount[1] & ~hcount[2] & rf14);
+ rf16 <= (rf16 & ~sram_cs_n)
+ | (~sram_cs_n & rf15);
+ end
+end
+
+
+/******** VIDEO ********/
+
+reg [8:0] hcount /* synthesis keep */;
+reg [8:0] vcount /* synthesis keep */;
+wire u1D_co;
+wire u1E_co;
+wire u1G_co;
+wire u1H_co;
+
+always @(posedge clk_sys) begin
+ if (clk_en_514) begin
+ hcount <= hcount + 1'd1;
+ if (hcount == 9'h1ff) hcount <= 9'h0c0;
+ end
+end
+assign hb = hcount[8:0] > 192 && hcount[8:0] <= 256 + 32;
+
+assign vs = vcount[8];
+
+always @(posedge clk_sys) begin
+ if (clk_en_514) begin
+ if (hcount == 9'h0c4) begin
+ vcount <= vcount + 1'd1;
+ if (vcount == 9'h1ff) vcount <= 9'h0f8;
+ if (vcount == 9'h10f) vb <= 0;
+ if (vcount == 9'h1ef) vb <= 1;
+ end
+ end
+end
+
+// 1C
+wire [8:0] hc2 = hcount - hoffs;
+always @(posedge clk_sys) begin
+ if (hc2[8]) hs <= 1'b0;
+ else if (clk_en_514) begin
+ if (hc2[2:0] == 3'b011) hs <= |hc2[5:4]; // hc2[2] rising edge
+ end
+end
+
+
+/******** MCPU ********/
+
+wire wait_n = o13 & rdy_n;
+
+wire [7:0] mcpu_din;
+wire [15:0] mcpu_addr;
+wire [7:0] mcpu_dout;
+wire mcpu_rd_n;
+wire mcpu_wr_n;
+wire mcpu_m1_n;
+wire mcpu_mreq_n;
+wire mcpu_iorq_n;
+wire mcpu_rfsh_n;
+reg mcpu_nmi_n;
+wire mcpu_wait_n = wait_n;
+
+// u8H is used by the CPU to reset NMI state
+
+reg oldvb;
+always @(posedge clk_sys) begin
+ oldvb <= vb;
+ if (~oldvb & vb & u8H[4]) begin
+ mcpu_nmi_n <= 1'b0;
+ end
+ if (~u8H[4]) mcpu_nmi_n <= 1'b1;
+end
+
+t80s mcpu(
+ .reset_n ( ~reset ),
+ .clk ( clk_sys ),
+ .cen ( clk_en_257 ),
+ .wait_n ( mcpu_wait_n ),
+ .int_n ( 1'b1 ),
+ .nmi_n ( mcpu_nmi_n ),
+ .busrq_n ( 1'b1 ),
+ .m1_n ( mcpu_m1_n ),
+ .mreq_n ( mcpu_mreq_n ),
+ .iorq_n ( mcpu_iorq_n ),
+ .rd_n ( mcpu_rd_n ),
+ .wr_n ( mcpu_wr_n ),
+ .rfsh_n ( mcpu_rfsh_n ),
+ .halt_n ( ),
+ .busak_n ( ),
+ .A ( mcpu_addr ),
+ .DI ( mcpu_din ),
+ .DO ( mcpu_dout )
+);
+
+/******** MCPU MEMORY CS ********/
+
+wire [3:0] u7A_Y1;
+wire [3:0] u7A_Y2;
+wire [3:0] u7B_Y1;
+wire [3:0] u7B_Y2;
+
+x74139 u7A(
+ .E1 ( u7B_Y2[3] ),
+ .A1 ( { mcpu_addr[13], 1'b0 } ),
+ .O1 ( u7A_Y1 ),
+ .E2 ( u7A_Y1[2] ),
+ .A2 ( mcpu_addr[12:11] ),
+ .O2 ( u7A_Y2 )
+);
+
+x74139 u7B(
+ .E1 ( mcpu_mreq_n ),
+ .A1 ( { mcpu_rfsh_n, 1'b0 } ),
+ .O1 ( u7B_Y1 ),
+ .E2 ( u7B_Y1[2] ),
+ .A2 ( mcpu_addr[15:14] ),
+ .O2 ( u7B_Y2 )
+);
+
+wire mcpu_rom_cs_n_0 = u7B_Y2[0]; // $0000-$3fff
+wire mcpu_rom_cs_n_1 = u7B_Y2[1]; // $4000-$7fff
+wire mcpu_rom_cs_n_2 = u7B_Y2[2]; // $8000-$bfff
+wire mcpu_rom_cs_n_3 = u7A_Y1[0]; // $c000-$ffff
+
+wire wram_cs_n = u7A_Y2[0]; // wram $e000-$e7ff
+wire rram_cs_n = u7A_Y2[2]; // rram $f000-$f7ff
+wire sram_cs_n = u7A_Y2[3]; // sram $f800-$ffff
+
+/******** MCPU MEMORIES ********/
+
+wire [7:0] mcpu_rom0_q;
+wire [7:0] mcpu_rom1_q;
+wire [7:0] mcpu_rom2_q;
+wire [7:0] mcpu_rom3_q;
+wire [7:0] mcpu_wram_q;
+wire [7:0] sram_q;
+wire [7:0] rram_q;
+
+// 3E 3F 3H 3I 3J muxes for RRAM/SRAM address, (r|s)ad_sel_n is active (low) on blank
+wire [10:0] avr = ~rad_sel_n ? mcpu_addr[10:0] : { sh[1], xv[7:3], xsh[7:3] };
+wire [10:0] avs = ~sad_sel_n ? mcpu_addr[10:0] : { hcount[1], xv[7:3], xh[7:3] };
+
+`ifdef EXT_ROM
+assign cpu_rom_addr = mcpu_addr[15:0];
+assign mcpu_rom0_q = cpu_rom_data;
+assign mcpu_rom1_q = cpu_rom_data;
+assign mcpu_rom2_q = cpu_rom_data;
+assign mcpu_rom3_q = cpu_rom_data;
+assign cpu_rom_cs = ~(mcpu_rom_cs_n_0 & mcpu_rom_cs_n_1 & mcpu_rom_cs_n_2 & mcpu_rom_cs_n_3);
+
+`else
+wire [7:0] mcpu_rom_data = ioctl_dout[7:0];
+wire [13:0] mcpu_rom0_addr = ioctl_download ? ioctl_addr : mcpu_addr[13:0];
+wire mcpu_rom0_wren_a = ioctl_download && ioctl_addr < 27'h4000 ? ioctl_wr : 1'b0;
+wire [13:0] mcpu_rom1_addr = ioctl_download ? ioctl_addr : mcpu_addr[13:0];
+wire mcpu_rom1_wren_a = ioctl_download && ioctl_addr < 27'h8000 ? ioctl_wr : 1'b0;
+wire [13:0] mcpu_rom2_addr = ioctl_download ? ioctl_addr : mcpu_addr[13:0];
+wire mcpu_rom2_wren_a = ioctl_download && ioctl_addr < 27'hc000 ? ioctl_wr : 1'b0;
+wire [13:0] mcpu_rom3_addr = ioctl_download ? ioctl_addr : mcpu_addr[13:0];
+wire mcpu_rom3_wren_a = ioctl_download && ioctl_addr < 27'hf000 ? ioctl_wr : 1'b0;
+
+dpram #(14,8) mcpu_rom0(
+ .clock ( clk_sys ),
+ .address_a ( mcpu_rom0_addr ),
+ .data_a ( mcpu_rom_data ),
+ .q_a ( mcpu_rom0_q ),
+ .rden_a ( 1'b1 ),
+ .wren_a ( mcpu_rom0_wren_a )
+);
+
+dpram #(14,8) mcpu_rom1(
+ .clock ( clk_sys ),
+ .address_a ( mcpu_rom1_addr ),
+ .data_a ( mcpu_rom_data ),
+ .q_a ( mcpu_rom1_q ),
+ .rden_a ( 1'b1 ),
+ .wren_a ( mcpu_rom1_wren_a )
+);
+
+dpram #(14,8) mcpu_rom2(
+ .clock ( clk_sys ),
+ .address_a ( mcpu_rom2_addr ),
+ .data_a ( mcpu_rom_data ),
+ .q_a ( mcpu_rom2_q ),
+ .rden_a ( 1'b1 ),
+ .wren_a ( mcpu_rom2_wren_a )
+);
+
+dpram #(14,8) mcpu_rom3(
+ .clock ( clk_sys ),
+ .address_a ( mcpu_rom3_addr ),
+ .data_a ( mcpu_rom_data ),
+ .q_a ( mcpu_rom3_q ),
+ .rden_a ( 1'b1 ),
+ .wren_a ( mcpu_rom3_wren_a )
+);
+`endif
+
+dpram #(11,8) mcpu_wram(
+ .clock ( clk_sys ),
+ .address_a ( mcpu_addr[10:0] ),
+ .data_a ( mcpu_dout ),
+ .q_a ( mcpu_wram_q ),
+ .rden_a ( 1'b1 ),
+ .wren_a ( ~wram_cs_n & ~mcpu_wr_n )
+);
+
+// vram bg
+
+dpram #(11,8) sram(
+ .clock ( clk_sys ),
+ .address_a ( avs ),
+ .data_a ( mcpu_dout ),
+ .q_a ( sram_q ),
+ .rden_a ( 1'b1 ),
+ .wren_a ( ~srwr_n )
+);
+
+// vram fg
+
+dpram #(11,8) rram(
+ .clock ( clk_sys ),
+ .address_a ( avr ),
+ .data_a ( mcpu_dout ),
+ .q_a ( rram_q ),
+ .rden_a ( 1'b1 ),
+ .wren_a ( ~rrwr_n )
+);
+
+/******** MCPU I/O & DATA BUS ********/
+
+wire [7:0] u6E_Y, u6D_Y;
+
+wire IN1 = ~u6D_Y[0];
+wire IN2 = ~u6D_Y[1];
+wire IN3 = ~u6D_Y[2];
+wire DSW = ~u6D_Y[4];
+wire SN1 = u6E_Y[0];
+wire SN2 = u6E_Y[1];
+wire SN3 = u6E_Y[2];
+wire SCR = ~u6E_Y[5];
+wire IOW = ~u6E_Y[7];
+
+x74138 u6E(
+ .G1 ( 1'b1 ),
+ .G2A ( mcpu_iorq_n ),
+ .G2B ( mcpu_wr_n ),
+ .A ( mcpu_addr[2:0] ),
+ .Y ( u6E_Y )
+);
+
+x74138 u6D(
+ .G1 ( 1'b1 ),
+ .G2A ( mcpu_iorq_n ),
+ .G2B ( mcpu_rd_n ),
+ .A ( mcpu_addr[2:0] ),
+ .Y ( u6D_Y )
+);
+
+reg [7:0] u2J;
+reg [7:0] u8H;
+
+always @(posedge clk_sys) begin
+ if (~mcpu_wr_n) begin
+ if (SCR) u2J <= mcpu_dout;
+ if (IOW) u8H <= mcpu_dout;
+ end
+end
+
+assign mcpu_din =
+ ~wram_cs_n ? mcpu_wram_q :
+ ~sram_cs_n ? sram_q :
+ ~rram_cs_n ? rram_q :
+ ~mcpu_rom_cs_n_0 ? mcpu_rom0_q :
+ ~mcpu_rom_cs_n_1 ? mcpu_rom1_q :
+ ~mcpu_rom_cs_n_2 ? mcpu_rom2_q :
+ ~mcpu_rom_cs_n_3 ? mcpu_rom3_q :
+ IN1 ? p1 :
+ IN2 ? p2 :
+ IN3 ? p3 :
+ DSW ? dsw :
+ 8'h0;
+
+
+/******** SCROLL COUNT ********/
+
+reg [7:0] sh;
+always @(posedge clk_sys) begin : U2HU2I
+ if (clk_en_514) begin
+ if (!hcount[8]) sh <= u2J;
+ else sh <= sh + 1'd1;
+ end
+end
+
+// flip
+wire bflip = u8H[5];
+wire [7:0] xv = vcount[7:0] ^ {8{bflip}};
+wire [7:3] xh = hcount[7:3] ^ {5{bflip}};
+wire [7:2] xsh = sh[7:2] ^ {{5{bflip}}, rhinv};
+
+/******** COL/CH registers ********/
+
+// COLors & CHaracters
+// It captures VRAM data to build tile & color addresses
+// timing signals are generated by the PAL 315-5074
+
+reg [7:0] r3l;
+reg [7:0] r2l;
+reg [7:0] r4l;
+reg [7:0] r3b;
+reg [7:0] r3c;
+
+always @(posedge clk_sys) begin
+
+ if (clk_en_514) begin
+ if (!rcol_set_n) r3l <= rram_q; // rcol_set_n rising edge
+ if (!rch_set_n) begin // rch_set_n rising edge
+ r2l <= rram_q;
+ r4l <= r3l;
+ end
+ end
+ if (oldvb & ~vb) begin
+ r2l <= 8'd0;
+ r4l <= 8'd0;
+ end
+end
+
+always @(posedge clk_sys) begin
+
+ if (clk_en_514) begin
+ if (!scol_set_n) r3b <= sram_q;
+ if (!sch_set_n) r3c <= sram_q;
+ end
+ if (oldvb & ~vb) begin
+ r3b <= 8'd0;
+ r3c <= 8'd0;
+ end
+end
+
+/******** BG/FG shift registers ********/
+
+// shift & select high or low bits of ROM data
+// translated to verilog to avoid a lot of 74LS194 instances
+
+reg [3:0] r4a;
+reg [4:0] r4k;
+reg sinv;
+reg rinv;
+
+// tile flip code
+wire shinv = r3b[3] ^ bflip;
+wire rhinv = r4l[2] ^ bflip;
+
+// 4K & 4A for stable address/inv signals
+always @(posedge clk_sys) begin
+
+ if (clk_en_514) begin
+ if (!sld_n) begin
+ r4a <= r3b[7:4];
+ sinv <= shinv;
+ end
+ if (!rld_n) begin
+ r4k <= r4l[7:3];
+ rinv <= rhinv;
+ end
+ end
+
+end
+
+// bit select
+wire ss0 = sinv ? 1'b1 : ~sld_n;
+wire ss1 = sinv ? ~sld_n : 1'b1;
+wire rs0 = rinv ? 1'b1 : ~rld_n;
+wire rs1 = rinv ? ~rld_n : 1'b1;
+
+// extract bits from ROM data
+wire [2:0] sex = sinv ? { sra[7], srb[7], src[7] } : { sra[0], srb[0], src[0] };
+wire [1:0] rex = rinv ? { rra[3], rrb[3] } : { rra[0], rrb[0] };
+
+
+// shift registers
+reg [7:0] sra, srb, src;
+reg [3:0] rra, rrb;
+always @(posedge clk_sys) begin
+ if (clk_en_514) begin
+
+ if (ss0 & ss1) begin
+ sra <= srom_dout_a;
+ srb <= srom_dout_b;
+ src <= srom_dout_c;
+ end
+ else if (~ss0 & ss1) begin
+ sra <= { 1'b0, sra[7:1] };
+ srb <= { 1'b0, srb[7:1] };
+ src <= { 1'b0, src[7:1] };
+ end
+ else if (ss0 & ~ss1) begin
+ sra <= { sra[6:0], 1'b0 };
+ srb <= { srb[6:0], 1'b0 };
+ src <= { src[6:0], 1'b0 };
+ end
+
+ if (rs0 & rs1) begin
+ rra <= rrom_dout[7:4];
+ rrb <= rrom_dout[3:0];
+ end
+ else if (~rs0 & rs1) begin
+ rra <= { 1'b0, rra[3:1] };
+ rrb <= { 1'b0, rrb[3:1] };
+ end
+ else if (rs0 & ~rs1) begin
+ rra <= { rra[2:0], 1'b0 };
+ rrb <= { rrb[2:0], 1'b0 };
+ end
+
+ end
+end
+
+/******** BG/FG color palette ********/
+
+wire [7:0] rc_addr = { 1'b0, r4k, rex };
+wire [7:0] sc_addr = { 1'b0, r4a, sex };
+
+wire [3:0] scol;
+wire [3:0] rcol;
+wire [7:0] pal_data;
+
+// priority & transparency
+wire rex_n = ~|rcol;
+wire sex_n = ~|scol;
+wire sel_n = (rex_n | ~sex_n | u8H[0]) & (rex_n | u8H[1]);
+wire [3:0] col = sel_n ? scol : rcol;
+
+dpram #(8,4) fg_color_lut(
+ .clock ( clk_sys ),
+ .address_a ( fg_color_addr ),
+ .data_a ( col_data[3:0] ),
+ .q_a ( rcol ),
+ .rden_a ( 1'b1 ),
+ .wren_a ( fg_color_wren )
+);
+
+dpram #(8,4) bg_color_lut(
+ .clock ( clk_sys ),
+ .address_a ( bg_color_addr ),
+ .data_a ( col_data[3:0] ),
+ .q_a ( scol ),
+ .rden_a ( 1'b1 ),
+ .wren_a ( bg_color_wren )
+);
+
+// back is a palette switch
+// the only difference between the two palettes is color 7 (2F/40)
+wire back = u8H[3];
+dpram #(5,8) palette(
+ .clock ( clk_sys ),
+ .address_a ( pal_addr ),
+ .data_a ( col_data ),
+ .q_a ( pal_data ),
+ .rden_a ( 1'b1 ),
+ .wren_a ( pal_wren )
+);
+
+/******** GFX ROMs ********/
+
+wire [13:0] rca = { r4l[1:0], r2l, xsh[2], xv[2:0] };
+wire [13:0] sca = { r3b[2:0], r3c, xv[2:0] };
+
+wire [7:0] gfx_rom1_q;
+wire [7:0] gfx_rom2_q;
+wire [7:0] gfx_rom3_q;
+wire [7:0] gfx_rom4_q;
+wire [7:0] gfx_rom5_q;
+wire [7:0] gfx_rom6_q;
+wire [7:0] gfx_rom7_q;
+wire [7:0] gfx_rom8_q;
+
+wire [7:0] rrom_dout = ~rca[13] ? gfx_rom1_q : gfx_rom2_q;
+wire [7:0] srom_dout_a = ~sca[13] ? gfx_rom3_q : gfx_rom4_q;
+wire [7:0] srom_dout_b = ~sca[13] ? gfx_rom5_q : gfx_rom6_q;
+wire [7:0] srom_dout_c = ~sca[13] ? gfx_rom7_q : gfx_rom8_q;
+
+`ifdef EXT_ROM
+reg [13:0] rca_reg, sca_reg; // register for stability
+always @(posedge clk_sys) begin
+ rca_reg <= rca;
+ sca_reg <= sca;
+end
+assign bg_rom_addr = rca_reg;
+assign sp_rom_addr = sca_reg;
+assign gfx_rom1_q = bg_rom_data;
+assign gfx_rom2_q = bg_rom_data;
+
+assign gfx_rom3_q = sp_rom_data[ 7: 0];
+assign gfx_rom4_q = sp_rom_data[ 7: 0];
+assign gfx_rom5_q = sp_rom_data[15: 8];
+assign gfx_rom6_q = sp_rom_data[15: 8];
+assign gfx_rom7_q = sp_rom_data[23:16];
+assign gfx_rom8_q = sp_rom_data[23:16];
+
+`else
+wire [7:0] gfx_rom_data = ioctl_dout;
+wire [12:0] gfx_rom1_addr = ioctl_download ? ioctl_addr - 27'h10000 : rca[12:0];
+wire gfx_rom1_wren_a = ioctl_download && ioctl_addr >= 27'h10000 && ioctl_addr < 27'h12000 ? ioctl_wr : 1'b0;
+wire [12:0] gfx_rom2_addr = ioctl_download ? ioctl_addr - 27'h12000 : rca[12:0];
+wire gfx_rom2_wren_a = ioctl_download && ioctl_addr >= 27'h12000 && ioctl_addr < 27'h14000 ? ioctl_wr : 1'b0;
+wire [12:0] gfx_rom3_addr = ioctl_download ? ioctl_addr - 27'h14000 : sca[12:0];
+wire gfx_rom3_wren_a = ioctl_download && ioctl_addr >= 27'h14000 && ioctl_addr < 27'h16000 ? ioctl_wr : 1'b0;
+wire [12:0] gfx_rom4_addr = ioctl_download ? ioctl_addr - 27'h16000 : sca[12:0];
+wire gfx_rom4_wren_a = ioctl_download && ioctl_addr >= 27'h16000 && ioctl_addr < 27'h18000 ? ioctl_wr : 1'b0;
+wire [12:0] gfx_rom5_addr = ioctl_download ? ioctl_addr - 27'h18000 : sca[12:0];
+wire gfx_rom5_wren_a = ioctl_download && ioctl_addr >= 27'h18000 && ioctl_addr < 27'h1a000 ? ioctl_wr : 1'b0;
+wire [12:0] gfx_rom6_addr = ioctl_download ? ioctl_addr - 27'h1a000 : sca[12:0];
+wire gfx_rom6_wren_a = ioctl_download && ioctl_addr >= 27'h1a000 && ioctl_addr < 27'h1c000 ? ioctl_wr : 1'b0;
+wire [12:0] gfx_rom7_addr = ioctl_download ? ioctl_addr - 27'h1c000 : sca[12:0];
+wire gfx_rom7_wren_a = ioctl_download && ioctl_addr >= 27'h1c000 && ioctl_addr < 27'h1e000 ? ioctl_wr : 1'b0;
+wire [12:0] gfx_rom8_addr = ioctl_download ? ioctl_addr - 27'h1e000 : sca[12:0];
+wire gfx_rom8_wren_a = ioctl_download && ioctl_addr >= 27'h1e000 && ioctl_addr < 27'h20000 ? ioctl_wr : 1'b0;
+
+// fg
+
+dpram #(13,8) gfx_rom1(
+ .clock ( clk_sys ),
+ .address_a ( gfx_rom1_addr ),
+ .data_a ( gfx_rom_data ),
+ .q_a ( gfx_rom1_q ),
+ .rden_a ( 1'b1 ),
+ .wren_a ( gfx_rom1_wren_a )
+);
+
+dpram #(13,8) gfx_rom2(
+ .clock ( clk_sys ),
+ .address_a ( gfx_rom2_addr ),
+ .data_a ( gfx_rom_data ),
+ .q_a ( gfx_rom2_q ),
+ .rden_a ( 1'b1 ),
+ .wren_a ( gfx_rom2_wren_a )
+);
+
+// bg
+
+dpram #(13,8) gfx_rom3(
+ .clock ( clk_sys ),
+ .address_a ( gfx_rom3_addr ),
+ .data_a ( gfx_rom_data ),
+ .q_a ( gfx_rom3_q ),
+ .rden_a ( 1'b1 ),
+ .wren_a ( gfx_rom3_wren_a )
+);
+
+dpram #(13,8) gfx_rom4(
+ .clock ( clk_sys ),
+ .address_a ( gfx_rom4_addr ),
+ .data_a ( gfx_rom_data ),
+ .q_a ( gfx_rom4_q ),
+ .rden_a ( 1'b1 ),
+ .wren_a ( gfx_rom4_wren_a )
+);
+
+dpram #(13,8) gfx_rom5(
+ .clock ( clk_sys ),
+ .address_a ( gfx_rom5_addr ),
+ .data_a ( gfx_rom_data ),
+ .q_a ( gfx_rom5_q ),
+ .rden_a ( 1'b1 ),
+ .wren_a ( gfx_rom5_wren_a )
+);
+
+dpram #(13,8) gfx_rom6(
+ .clock ( clk_sys ),
+ .address_a ( gfx_rom6_addr ),
+ .data_a ( gfx_rom_data ),
+ .q_a ( gfx_rom6_q ),
+ .rden_a ( 1'b1 ),
+ .wren_a ( gfx_rom6_wren_a )
+);
+
+dpram #(13,8) gfx_rom7(
+ .clock ( clk_sys ),
+ .address_a ( gfx_rom7_addr ),
+ .data_a ( gfx_rom_data ),
+ .q_a ( gfx_rom7_q ),
+ .rden_a ( 1'b1 ),
+ .wren_a ( gfx_rom7_wren_a )
+);
+
+dpram #(13,8) gfx_rom8(
+ .clock ( clk_sys ),
+ .address_a ( gfx_rom8_addr ),
+ .data_a ( gfx_rom_data ),
+ .q_a ( gfx_rom8_q ),
+ .rden_a ( 1'b1 ),
+ .wren_a ( gfx_rom8_wren_a )
+);
+`endif
+
+/******** AUDIO ********/
+
+// /RDY are open-collector outputs on original schematic
+
+wire rdy1;
+wire rdy2;
+wire rdy3;
+wire rdy_n = rdy1 & rdy2 & rdy3;
+
+wire [13:0] mix_audio1;
+wire [13:0] mix_audio2;
+wire [13:0] mix_audio3;
+
+assign sound = mix_audio1 + mix_audio2 + mix_audio3;
+
+sn76489_audio usnd1(
+ .clk_i ( clk_sys ),
+ .en_clk_psg_i ( clk_en_257 ),
+ .ce_n_i ( SN1 ),
+ .wr_n_i ( mcpu_wr_n | SN1 ),
+ .ready_o ( rdy1 ),
+ .data_i ( mcpu_dout ),
+ .mix_audio_o ( mix_audio1 )
+);
+
+sn76489_audio usnd2(
+ .clk_i ( clk_sys ),
+ .en_clk_psg_i ( clk_en_257 ),
+ .ce_n_i ( SN2 ),
+ .wr_n_i ( mcpu_wr_n | SN2 ),
+ .ready_o ( rdy2 ),
+ .data_i ( mcpu_dout ),
+ .mix_audio_o ( mix_audio2 )
+);
+
+sn76489_audio usnd3(
+ .clk_i ( clk_sys ),
+ .en_clk_psg_i ( clk_en_257 ),
+ .ce_n_i ( SN3 ),
+ .wr_n_i ( mcpu_wr_n | SN3 ),
+ .ready_o ( rdy3 ),
+ .data_i ( mcpu_dout ),
+ .mix_audio_o ( mix_audio3 )
+);
+
+
+endmodule
diff --git a/Arcade_MiST/Sega Bank Panic Hardware/rtl/dpram.v b/Arcade_MiST/Sega Bank Panic Hardware/rtl/dpram.v
new file mode 100644
index 00000000..e5e87fbc
--- /dev/null
+++ b/Arcade_MiST/Sega Bank Panic Hardware/rtl/dpram.v
@@ -0,0 +1,137 @@
+// megafunction wizard: %RAM: 2-PORT%
+// GENERATION: STANDARD
+// VERSION: WM1.0
+// MODULE: altsyncram
+
+// ============================================================
+// File Name: dpram.v
+// Megafunction Name(s):
+// altsyncram
+//
+// Simulation Library Files(s):
+// altera_mf
+// ============================================================
+// ************************************************************
+// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
+//
+// 17.0.0 Build 595 04/25/2017 SJ Lite Edition
+// ************************************************************
+
+
+//Copyright (C) 2017 Intel Corporation. All rights reserved.
+//Your use of Intel 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 Intel Program License
+//Subscription Agreement, the Intel Quartus Prime License Agreement,
+//the Intel 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 Intel and sold by Intel 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 dpram
+#(
+ parameter ADDRWIDTH=12,
+ parameter DATAWIDTH=8
+)
+(
+ address_a,
+ address_b,
+ clock,
+ data_a,
+ data_b,
+ wren_a,
+ wren_b,
+ rden_a,
+ rden_b,
+ q_a,
+ q_b);
+
+ input [ADDRWIDTH-1:0] address_a;
+ input [ADDRWIDTH-1:0] address_b;
+ input clock;
+ input [DATAWIDTH-1:0] data_a;
+ input [DATAWIDTH-1:0] data_b;
+ input wren_a;
+ input wren_b;
+ input rden_a;
+ input rden_b;
+ output [DATAWIDTH-1:0] q_a;
+ output [DATAWIDTH-1:0] q_b;
+`ifndef ALTERA_RESERVED_QIS
+// synopsys translate_off
+`endif
+ tri1 clock;
+ tri0 wren_a;
+ tri0 wren_b;
+`ifndef ALTERA_RESERVED_QIS
+// synopsys translate_on
+`endif
+
+ wire [DATAWIDTH-1:0] sub_wire0;
+ wire [DATAWIDTH-1:0] sub_wire1;
+ wire [DATAWIDTH-1:0] q_a = rden_a ? sub_wire0[DATAWIDTH-1:0] : {DATAWIDTH{1'b0}};
+ wire [DATAWIDTH-1:0] q_b = rden_b ? sub_wire1[DATAWIDTH-1:0] : {DATAWIDTH{1'b0}};
+
+ altsyncram altsyncram_component (
+ .address_a (address_a),
+ .address_b (address_b),
+ .clock0 (clock),
+ .data_a (data_a),
+ .data_b (data_b),
+ .wren_a (wren_a),
+ .wren_b (wren_b),
+ .q_a (sub_wire0),
+ .q_b (sub_wire1),
+ .aclr0 (1'b0),
+ .aclr1 (1'b0),
+ .addressstall_a (1'b0),
+ .addressstall_b (1'b0),
+ .byteena_a (1'b1),
+ .byteena_b (1'b1),
+ .clock1 (1'b1),
+ .clocken0 (1'b1),
+ .clocken1 (1'b1),
+ .clocken2 (1'b1),
+ .clocken3 (1'b1),
+ .eccstatus (),
+ .rden_a (1'b1),
+ .rden_b (1'b1));
+ defparam
+ altsyncram_component.address_reg_b = "CLOCK0",
+ altsyncram_component.clock_enable_input_a = "BYPASS",
+ altsyncram_component.clock_enable_input_b = "BYPASS",
+ altsyncram_component.clock_enable_output_a = "BYPASS",
+ altsyncram_component.clock_enable_output_b = "BYPASS",
+ altsyncram_component.indata_reg_b = "CLOCK0",
+ altsyncram_component.intended_device_family = "Cyclone V",
+ altsyncram_component.lpm_type = "altsyncram",
+ altsyncram_component.numwords_a = 2**ADDRWIDTH,
+ altsyncram_component.numwords_b = 2**ADDRWIDTH,
+ altsyncram_component.operation_mode = "BIDIR_DUAL_PORT",
+ altsyncram_component.outdata_aclr_a = "NONE",
+ altsyncram_component.outdata_aclr_b = "NONE",
+ altsyncram_component.outdata_reg_a = "CLOCK0",
+ altsyncram_component.outdata_reg_b = "CLOCK0",
+ altsyncram_component.power_up_uninitialized = "FALSE",
+ altsyncram_component.read_during_write_mode_mixed_ports = "DONT_CARE",
+ altsyncram_component.read_during_write_mode_port_a = "NEW_DATA_NO_NBE_READ",
+ altsyncram_component.read_during_write_mode_port_b = "NEW_DATA_NO_NBE_READ",
+ altsyncram_component.widthad_a = ADDRWIDTH,
+ altsyncram_component.widthad_b = ADDRWIDTH,
+ altsyncram_component.width_a = DATAWIDTH,
+ altsyncram_component.width_b = DATAWIDTH,
+ altsyncram_component.width_byteena_a = 1,
+ altsyncram_component.width_byteena_b = 1,
+ altsyncram_component.wrcontrol_wraddress_reg_b = "CLOCK0";
+
+
+endmodule
diff --git a/Arcade_MiST/Sega Bank Panic Hardware/rtl/pll_mist.qip b/Arcade_MiST/Sega Bank Panic Hardware/rtl/pll_mist.qip
new file mode 100644
index 00000000..6182871f
--- /dev/null
+++ b/Arcade_MiST/Sega Bank Panic Hardware/rtl/pll_mist.qip
@@ -0,0 +1,4 @@
+set_global_assignment -name IP_TOOL_NAME "ALTPLL"
+set_global_assignment -name IP_TOOL_VERSION "13.1"
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "pll_mist.v"]
+set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll_mist.ppf"]
diff --git a/Arcade_MiST/Sega Bank Panic Hardware/rtl/pll_mist.v b/Arcade_MiST/Sega Bank Panic Hardware/rtl/pll_mist.v
new file mode 100644
index 00000000..8d5a964e
--- /dev/null
+++ b/Arcade_MiST/Sega Bank Panic Hardware/rtl/pll_mist.v
@@ -0,0 +1,348 @@
+// megafunction wizard: %ALTPLL%
+// GENERATION: STANDARD
+// VERSION: WM1.0
+// MODULE: altpll
+
+// ============================================================
+// File Name: pll_mist.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_mist (
+ areset,
+ inclk0,
+ c0,
+ c1,
+ locked);
+
+ input areset;
+ input inclk0;
+ output c0;
+ output c1;
+ output locked;
+`ifndef ALTERA_RESERVED_QIS
+// synopsys translate_off
+`endif
+ tri0 areset;
+`ifndef ALTERA_RESERVED_QIS
+// synopsys translate_on
+`endif
+
+ 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 (
+ .areset (areset),
+ .inclk (sub_wire5),
+ .clk (sub_wire0),
+ .locked (sub_wire2),
+ .activeclock (),
+ .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 = 9,
+ altpll_component.clk0_duty_cycle = 50,
+ altpll_component.clk0_multiply_by = 31,
+ altpll_component.clk0_phase_shift = "0",
+ altpll_component.clk1_divide_by = 27,
+ altpll_component.clk1_duty_cycle = 50,
+ altpll_component.clk1_multiply_by = 31,
+ 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_mist",
+ 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_USED",
+ 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 "9"
+// Retrieval info: PRIVATE: DIV_FACTOR1 NUMERIC "1"
+// Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"
+// Retrieval info: PRIVATE: DUTY_CYCLE1 STRING "50.00000000"
+// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "93.000000"
+// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "31.000000"
+// Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0"
+// Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0"
+// Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1"
+// 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 "16"
+// Retrieval info: PRIVATE: MULT_FACTOR1 NUMERIC "1"
+// Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1"
+// Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "93.00000000"
+// Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "31.00000000"
+// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "1"
+// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE1 STRING "1"
+// 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 "ps"
+// Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0"
+// Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "1"
+// 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 "9"
+// Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50"
+// Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "31"
+// Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0"
+// Retrieval info: CONSTANT: CLK1_DIVIDE_BY NUMERIC "27"
+// Retrieval info: CONSTANT: CLK1_DUTY_CYCLE NUMERIC "50"
+// Retrieval info: CONSTANT: CLK1_MULTIPLY_BY NUMERIC "31"
+// 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_USED"
+// 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: areset 0 0 0 0 INPUT GND "areset"
+// 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: @areset 0 0 0 0 areset 0 0 0 0
+// 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_mist.v TRUE
+// Retrieval info: GEN_FILE: TYPE_NORMAL pll_mist.ppf TRUE
+// Retrieval info: GEN_FILE: TYPE_NORMAL pll_mist.inc FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL pll_mist.cmp FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL pll_mist.bsf FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL pll_mist_inst.v FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL pll_mist_bb.v FALSE
+// Retrieval info: LIB_FILE: altera_mf
+// Retrieval info: CBX_MODULE_PREFIX: ON
diff --git a/Arcade_MiST/Sega Bank Panic Hardware/rtl/sdram.sv b/Arcade_MiST/Sega Bank Panic Hardware/rtl/sdram.sv
new file mode 100644
index 00000000..9b1b8d1b
--- /dev/null
+++ b/Arcade_MiST/Sega Bank Panic Hardware/rtl/sdram.sv
@@ -0,0 +1,352 @@
+//
+// sdram.v
+//
+// sdram controller implementation for the MiST board
+// https://github.com/mist-devel/mist-board
+//
+// Copyright (c) 2013 Till Harbaum
+// Copyright (c) 2019 Gyorgy Szombathelyi
+//
+// 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 .
+//
+
+module sdram (
+
+ // interface to the MT48LC16M16 chip
+ inout reg [15:0] SDRAM_DQ, // 16 bit bidirectional data bus
+ output reg [12:0] SDRAM_A, // 13 bit multiplexed address bus
+ output reg SDRAM_DQML, // two byte masks
+ output reg SDRAM_DQMH, // two byte masks
+ output reg [1:0] SDRAM_BA, // two banks
+ output SDRAM_nCS, // a single chip select
+ output SDRAM_nWE, // write enable
+ output SDRAM_nRAS, // row address select
+ output SDRAM_nCAS, // columns address select
+
+ // cpu/chipset interface
+ input init_n, // init signal after FPGA config to initialize RAM
+ input clk, // sdram clock
+
+ input port1_req,
+ output reg port1_ack,
+ input port1_we,
+ input [23:1] port1_a,
+ input [1:0] port1_ds,
+ input [15:0] port1_d,
+ output reg [15:0] port1_q,
+
+ input [19:1] cpu1_addr,
+ input cpu1_cs,
+ output reg [15:0] cpu1_q,
+ input [19:1] cpu2_addr,
+ output reg [15:0] cpu2_q,
+
+ input port2_req,
+ output reg port2_ack,
+ input port2_we,
+ input [23:1] port2_a,
+ input [1:0] port2_ds,
+ input [15:0] port2_d,
+ output reg [31:0] port2_q,
+
+ input [17:2] sp_addr,
+ output reg [31:0] sp_q
+);
+
+parameter MHZ = 16'd80; // 80 MHz default clock, set it to proper value to calculate refresh rate
+
+localparam RASCAS_DELAY = 3'd2; // tRCD=20ns -> 2 cycles@<100MHz
+localparam BURST_LENGTH = 3'b001; // 000=1, 001=2, 010=4, 011=8
+localparam ACCESS_TYPE = 1'b0; // 0=sequential, 1=interleaved
+localparam CAS_LATENCY = 3'd2; // 2/3 allowed
+localparam OP_MODE = 2'b00; // only 00 (standard operation) allowed
+localparam NO_WRITE_BURST = 1'b1; // 0= write burst enabled, 1=only single access write
+
+localparam MODE = { 3'b000, NO_WRITE_BURST, OP_MODE, CAS_LATENCY, ACCESS_TYPE, BURST_LENGTH};
+
+// 64ms/8192 rows = 7.8us
+localparam RFRSH_CYCLES = 16'd78*MHZ/4'd10;
+
+// ---------------------------------------------------------------------
+// ------------------------ cycle state machine ------------------------
+// ---------------------------------------------------------------------
+
+/*
+ SDRAM state machine for 2 bank interleaved access
+ 1 word burst, CL2
+cmd issued registered
+ 0 RAS0 cas1 - data0 read burst terminated
+ 1 ras0
+ 2 data1 returned
+ 3 CAS0 data1 returned
+ 4 RAS1 cas0
+ 5 ras1
+ 6 CAS1 data0 returned
+*/
+
+localparam STATE_RAS0 = 3'd0; // first state in cycle
+localparam STATE_RAS1 = 3'd4; // Second ACTIVE command after RAS0 + tRRD (15ns)
+localparam STATE_CAS0 = STATE_RAS0 + RASCAS_DELAY + 1'd1; // CAS phase - 3
+localparam STATE_CAS1 = STATE_RAS1 + RASCAS_DELAY; // CAS phase - 6
+localparam STATE_READ0 = 3'd0;// STATE_CAS0 + CAS_LATENCY + 2'd2; // 7
+localparam STATE_READ1 = 3'd3;
+localparam STATE_DS1b = 3'd0;
+localparam STATE_READ1b = 3'd4;
+localparam STATE_LAST = 3'd6;
+
+reg [2:0] t;
+
+always @(posedge clk) begin
+ t <= t + 1'd1;
+ if (t == STATE_LAST) t <= STATE_RAS0;
+end
+
+// ---------------------------------------------------------------------
+// --------------------------- startup/reset ---------------------------
+// ---------------------------------------------------------------------
+
+// wait 1ms (32 8Mhz cycles) after FPGA config is done before going
+// into normal operation. Initialize the ram in the last 16 reset cycles (cycles 15-0)
+reg [4:0] reset;
+reg init = 1'b1;
+always @(posedge clk, negedge init_n) begin
+ if(!init_n) begin
+ reset <= 5'h1f;
+ init <= 1'b1;
+ end else begin
+ if((t == STATE_LAST) && (reset != 0)) reset <= reset - 5'd1;
+ init <= !(reset == 0);
+ end
+end
+
+// ---------------------------------------------------------------------
+// ------------------ generate ram control signals ---------------------
+// ---------------------------------------------------------------------
+
+// all possible commands
+localparam CMD_INHIBIT = 4'b1111;
+localparam CMD_NOP = 4'b0111;
+localparam CMD_ACTIVE = 4'b0011;
+localparam CMD_READ = 4'b0101;
+localparam CMD_WRITE = 4'b0100;
+localparam CMD_BURST_TERMINATE = 4'b0110;
+localparam CMD_PRECHARGE = 4'b0010;
+localparam CMD_AUTO_REFRESH = 4'b0001;
+localparam CMD_LOAD_MODE = 4'b0000;
+
+reg [3:0] sd_cmd; // current command sent to sd ram
+reg [15:0] sd_din; // Fast Input register latching incoming SDRAM data
+
+// drive control signals according to current command
+assign SDRAM_nCS = sd_cmd[3];
+assign SDRAM_nRAS = sd_cmd[2];
+assign SDRAM_nCAS = sd_cmd[1];
+assign SDRAM_nWE = sd_cmd[0];
+
+reg [24:1] addr_latch[2];
+reg [24:1] addr_latch_next[2];
+reg [19:1] addr_last[2];
+reg [17:2] addr_last2[2];
+reg [15:0] din_latch[2];
+reg [1:0] oe_latch;
+reg [1:0] we_latch;
+reg [1:0] ds[2];
+
+reg port1_state;
+reg port2_state;
+
+localparam PORT_NONE = 2'd0;
+localparam PORT_CPU1 = 2'd1;
+localparam PORT_CPU2 = 2'd2;
+localparam PORT_SP = 2'd1;
+localparam PORT_REQ = 2'd3;
+
+reg [1:0] next_port[2];
+reg [1:0] port[2];
+
+reg refresh;
+reg [11:0] refresh_cnt;
+reg need_refresh;
+
+// PORT1: bank 0,1
+always @(*) begin
+ if (refresh) begin
+ next_port[0] = PORT_NONE;
+ addr_latch_next[0] = addr_latch[1];
+ end else if (port1_req ^ port1_state) begin
+ next_port[0] = PORT_REQ;
+ addr_latch_next[0] = { 1'b0, port1_a };
+ end else if (cpu2_addr != addr_last[PORT_CPU2]) begin
+ next_port[0] = PORT_CPU2;
+ addr_latch_next[0] = { 5'd0, cpu2_addr };
+ end else if (cpu1_cs && cpu1_addr != addr_last[PORT_CPU1]) begin
+ next_port[0] = PORT_CPU1;
+ addr_latch_next[0] = { 5'd0, cpu1_addr };
+ end else begin
+ next_port[0] = PORT_NONE;
+ addr_latch_next[0] = addr_latch[0];
+ end
+end
+
+// PORT1: bank 2,3
+always @(*) begin
+ if (port2_req ^ port2_state) begin
+ next_port[1] = PORT_REQ;
+ addr_latch_next[1] = { 1'b1, port2_a };
+ end else if (sp_addr != addr_last2[PORT_SP]) begin
+ next_port[1] = PORT_SP;
+ addr_latch_next[1] = { 1'b1, 6'd0, sp_addr, 1'b0 };
+ end else begin
+ next_port[1] = PORT_NONE;
+ addr_latch_next[1] = addr_latch[1];
+ end
+end
+
+always @(posedge clk) begin
+
+ // permanently latch ram data to reduce delays
+ sd_din <= SDRAM_DQ;
+ SDRAM_DQ <= 16'bZZZZZZZZZZZZZZZZ;
+ { SDRAM_DQMH, SDRAM_DQML } <= 2'b11;
+ sd_cmd <= CMD_NOP; // default: idle
+ refresh_cnt <= refresh_cnt + 1'd1;
+ need_refresh <= (refresh_cnt >= RFRSH_CYCLES);
+
+ if(init) begin
+ // initialization takes place at the end of the reset phase
+ if(t == STATE_RAS0) begin
+
+ if(reset == 15) begin
+ sd_cmd <= CMD_PRECHARGE;
+ SDRAM_A[10] <= 1'b1; // precharge all banks
+ end
+
+ if(reset == 10 || reset == 8) begin
+ sd_cmd <= CMD_AUTO_REFRESH;
+ end
+
+ if(reset == 2) begin
+ sd_cmd <= CMD_LOAD_MODE;
+ SDRAM_A <= MODE;
+ SDRAM_BA <= 2'b00;
+ end
+ end
+ end else begin
+ // RAS phase
+ // bank 0,1
+ if(t == STATE_RAS0) begin
+ addr_latch[0] <= addr_latch_next[0];
+ port[0] <= next_port[0];
+ { oe_latch[0], we_latch[0] } <= 2'b00;
+
+ if (next_port[0] != PORT_NONE) begin
+ sd_cmd <= CMD_ACTIVE;
+ SDRAM_A <= addr_latch_next[0][22:10];
+ SDRAM_BA <= addr_latch_next[0][24:23];
+ addr_last[next_port[0]] <= addr_latch_next[0][19:1];
+ if (next_port[0] == PORT_REQ) begin
+ { oe_latch[0], we_latch[0] } <= { ~port1_we, port1_we };
+ ds[0] <= port1_ds;
+ din_latch[0] <= port1_d;
+ port1_state <= port1_req;
+ end else begin
+ { oe_latch[0], we_latch[0] } <= 2'b10;
+ ds[0] <= 2'b11;
+ end
+ end
+ end
+
+ // bank 2,3
+ if(t == STATE_RAS1) begin
+ refresh <= 0;
+ addr_latch[1] <= addr_latch_next[1];
+ { oe_latch[1], we_latch[1] } <= 2'b00;
+ port[1] <= next_port[1];
+
+ if (next_port[1] != PORT_NONE) begin
+ sd_cmd <= CMD_ACTIVE;
+ SDRAM_A <= addr_latch_next[1][22:10];
+ SDRAM_BA <= addr_latch_next[1][24:23];
+ addr_last2[next_port[1]] <= addr_latch_next[1][16:2];
+ if (next_port[1] == PORT_REQ) begin
+ { oe_latch[1], we_latch[1] } <= { ~port1_we, port1_we };
+ ds[1] <= port2_ds;
+ din_latch[1] <= port2_d;
+ port2_state <= port2_req;
+ end else begin
+ { oe_latch[1], we_latch[1] } <= 2'b10;
+ ds[1] <= 2'b11;
+ end
+ end else if (need_refresh && !oe_latch[0] & !we_latch[0]) begin
+ refresh <= 1;
+ refresh_cnt <= 0;
+ sd_cmd <= CMD_AUTO_REFRESH;
+ end
+ end
+
+ // CAS phase
+ if(t == STATE_CAS0 && (we_latch[0] || oe_latch[0])) begin
+ sd_cmd <= we_latch[0]?CMD_WRITE:CMD_READ;
+ { SDRAM_DQMH, SDRAM_DQML } <= ~ds[0];
+ if (we_latch[0]) begin
+ SDRAM_DQ <= din_latch[0];
+ port1_ack <= port1_req;
+ end
+ SDRAM_A <= { 4'b0010, addr_latch[0][9:1] }; // auto precharge
+ SDRAM_BA <= addr_latch[0][24:23];
+ end
+
+ if(t == STATE_CAS1 && (we_latch[1] || oe_latch[1])) begin
+ sd_cmd <= we_latch[1]?CMD_WRITE:CMD_READ;
+ { SDRAM_DQMH, SDRAM_DQML } <= ~ds[1];
+ if (we_latch[1]) begin
+ SDRAM_DQ <= din_latch[1];
+ port2_ack <= port2_req;
+ end
+ SDRAM_A <= { 4'b0010, addr_latch[1][9:1] }; // auto precharge
+ SDRAM_BA <= addr_latch[1][24:23];
+ end
+
+ // Data returned
+ if(t == STATE_READ0 && oe_latch[0]) begin
+ case(port[0])
+ PORT_REQ: begin port1_q <= sd_din; port1_ack <= port1_req; end
+ PORT_CPU1: begin cpu1_q <= sd_din; end
+ PORT_CPU2: begin cpu2_q <= sd_din; end
+ default: ;
+ endcase;
+ end
+
+ if(t == STATE_READ1 && oe_latch[1]) begin
+ case(port[1])
+ PORT_REQ: port2_q[15:0] <= sd_din;
+ PORT_SP : sp_q[15:0] <= sd_din;
+ default: ;
+ endcase;
+ end
+
+ //set DQM two cycles before the 2nd word in the burst
+ if(t == STATE_DS1b && oe_latch[1]) { SDRAM_DQMH, SDRAM_DQML } <= ~ds[1];
+
+ if(t == STATE_READ1b && oe_latch[1]) begin
+ case(port[1])
+ PORT_REQ: begin port2_q[31:16] <= sd_din; port2_ack <= port2_req; end
+ PORT_SP : begin sp_q[31:16] <= sd_din; end
+ default: ;
+ endcase;
+ end
+ end
+end
+
+endmodule
diff --git a/Arcade_MiST/Sega Bank Panic Hardware/rtl/sn76489_audio.vhd b/Arcade_MiST/Sega Bank Panic Hardware/rtl/sn76489_audio.vhd
new file mode 100644
index 00000000..218f6d62
--- /dev/null
+++ b/Arcade_MiST/Sega Bank Panic Hardware/rtl/sn76489_audio.vhd
@@ -0,0 +1,908 @@
+--
+-- SN76489 Complex Sound Generator
+-- Matthew Hagerty
+-- July 2020
+-- https://dnotq.io
+--
+
+-- Released under the 3-Clause BSD License:
+--
+-- Copyright 2020 Matthew Hagerty (matthew dnotq io)
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions are met:
+--
+-- 1. Redistributions of source code must retain the above copyright notice,
+-- this list of conditions and the following disclaimer.
+--
+-- 2. Redistributions in binary 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.
+--
+-- 3. Neither the name of the copyright holder nor the names of its
+-- 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 COPYRIGHT HOLDER 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.
+
+--
+-- A huge amount of effort has gone into making this core as accurate as
+-- possible to the real IC, while at the same time making it usable in all
+-- digital SoC designs, i.e. retro-computer and game systems, etc. Design
+-- elements from the real IC were used and implemented when possible, with any
+-- work-around or changes noted along with the reasons.
+--
+-- Synthesized and FPGA proven:
+--
+-- * Xilinx Spartan-6 LX16, SoC 21.477MHz system clock, 3.58MHz clock-enable.
+--
+--
+-- References:
+--
+-- * The SN76489 datasheet
+-- * Insight gained from the AY-3-8910/YM-2149 die-shot and reverse-engineered
+-- schematics (similar audio chips from the same era).
+-- * Real hardware (SN76489 in a ColecoVision game console).
+-- * Chip quirks, use, and abuse details from friends and retro enthusiasts.
+--
+--
+-- Generates:
+--
+-- * Unsigned 12-bit output for each channel.
+-- * Unsigned 14-bit summation of the four channels.
+-- * Signed 14-bit PCM summation of the four channels, with each channel
+-- converted to -/+ zero-centered level or -/+ full-range level.
+--
+-- The tone counters are period-limited to prevent the very high frequency
+-- outputs that the original IC is capable of producing. Frequencies above
+-- 20KHz cause problems in all-digital systems with sampling rates around
+-- 44.1KHz to 48KHz. The primary use of these high frequencies was as a
+-- carrier for amplitude modulated (AM) audio. The high frequency would be
+-- filtered out by external electronics, leaving only the low frequency audio.
+--
+-- When the tone counters are limited, the output square-wave is disabled, but
+-- the amplitude can still be changed, which allows the A.M. technique to still
+-- work in a digital Soc.
+--
+-- I/O requires at least two clock-enable cycles. This could be modified to
+-- operate faster, i.e. based on the input-clock directly. All inputs are
+-- registered at the system-clock rate.
+--
+-- Optionally simulates the original 32-clock (clock-enable) I/O cycle.
+--
+-- The SN76489 does not have an external reset and the original IC "wakes up"
+-- generating a tone. This implementation sets the default output level to
+-- full attenuation (silent output). If the original functionality is desired,
+-- modify the channel period and level register initial values.
+
+--
+-- Basic I/O interface use:
+--
+-- Set-up data on data_i.
+-- Set ce_n_i and wr_n_i low.
+-- Observe ready_o and wait for it to become high.
+-- Set wr_n_i high, if done writing to the chip set ce_n_i high.
+
+--
+-- Version history:
+--
+-- July 21 2020
+-- V1.0. Release. SoC tested.
+--
+
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity sn76489_audio is
+generic -- 0 = normal I/O, 32 clocks per write
+ -- 1 = fast I/O, around 2 clocks per write
+ ( FAST_IO_G : std_logic := '0'
+
+ -- Minimum allowable period count (see comments further
+ -- down for more information), recommended:
+ -- 6 18643.46Hz First audible count.
+ -- 17 6580.04Hz Counts at 16 are known to be used for
+ -- amplitude-modulation.
+ ; MIN_PERIOD_CNT_G : integer := 6
+);
+port
+ ( clk_i : in std_logic -- System clock
+ ; en_clk_psg_i : in std_logic -- PSG clock enable
+ ; ce_n_i : in std_logic -- chip enable, active low
+ ; wr_n_i : in std_logic -- write enable, active low
+ ; ready_o : out std_logic -- low during I/O operations
+ ; data_i : in std_logic_vector(7 downto 0)
+ ; ch_a_o : out unsigned(11 downto 0)
+ ; ch_b_o : out unsigned(11 downto 0)
+ ; ch_c_o : out unsigned(11 downto 0)
+ ; noise_o : out unsigned(11 downto 0)
+ ; mix_audio_o : out unsigned(13 downto 0)
+ ; pcm14s_o : out unsigned(13 downto 0)
+);
+end sn76489_audio;
+
+architecture rtl of sn76489_audio is
+
+ -- Registered I/O.
+ signal ce_n_r : std_logic := '1';
+ signal wr_n_r : std_logic := '1';
+ signal din_r : unsigned(7 downto 0) := x"00";
+ signal ready_r : std_logic := '1';
+ signal ready_x : std_logic;
+
+ -- I/O FSM.
+ type io_state_t is (IO_IDLE, IO_OP, IO_WAIT);
+ signal io_state_r : io_state_t := IO_IDLE;
+ signal io_state_x : io_state_t;
+ signal io_cnt_r : unsigned(4 downto 0) := (others => '0');
+ signal io_cnt_x : unsigned(4 downto 0);
+ signal en_reg_wr_s : std_logic;
+
+ -- Register file.
+ signal reg_addr_r : unsigned(2 downto 0) := (others => '0');
+ signal reg_sel_s : unsigned(2 downto 0);
+
+ signal ch_a_period_r : unsigned(9 downto 0) := (others => '0');
+ signal ch_a_period_x : unsigned(9 downto 0);
+ signal ch_a_level_r : unsigned(11 downto 0) := (others => '0');
+ signal ch_a_level_x : unsigned(11 downto 0);
+
+ signal ch_b_period_r : unsigned(9 downto 0) := (others => '0');
+ signal ch_b_period_x : unsigned(9 downto 0);
+ signal ch_b_level_r : unsigned(11 downto 0) := (others => '0');
+ signal ch_b_level_x : unsigned(11 downto 0);
+
+ signal ch_c_period_r : unsigned(9 downto 0) := (others => '0');
+ signal ch_c_period_x : unsigned(9 downto 0);
+ signal ch_c_level_r : unsigned(11 downto 0) := (others => '0');
+ signal ch_c_level_x : unsigned(11 downto 0);
+
+ signal noise_ctrl_r : std_logic := '0';
+ signal noise_ctrl_x : std_logic;
+ signal noise_shift_r : unsigned(1 downto 0) := (others => '0');
+ signal noise_shift_x : unsigned(1 downto 0);
+ signal noise_level_r : unsigned(11 downto 0) := (others => '0');
+ signal noise_level_x : unsigned(11 downto 0);
+ signal noise_rst_r : std_logic := '0';
+ signal noise_rst_x : std_logic;
+
+ -- Clock conditioning counters and enables.
+ signal clk_div16_r : unsigned(3 downto 0) := (others => '0');
+ signal clk_div16_x : unsigned(3 downto 0);
+ signal en_cnt_r : std_logic := '0';
+ signal en_cnt_x : std_logic;
+
+ -- Channel tone counters.
+ signal ch_a_cnt_r : unsigned(9 downto 0) := (others => '0');
+ signal ch_a_cnt_x : unsigned(9 downto 0);
+ signal flatline_a_s : std_logic;
+ signal tone_a_r : std_logic := '1';
+ signal tone_a_x : std_logic;
+
+ signal ch_b_cnt_r : unsigned(9 downto 0) := (others => '0');
+ signal ch_b_cnt_x : unsigned(9 downto 0);
+ signal flatline_b_s : std_logic;
+ signal tone_b_r : std_logic := '1';
+ signal tone_b_x : std_logic;
+
+ signal ch_c_cnt_r : unsigned(9 downto 0) := (others => '0');
+ signal ch_c_cnt_x : unsigned(9 downto 0);
+ signal flatline_c_s : std_logic;
+ signal tone_c_r : std_logic := '1';
+ signal tone_c_x : std_logic;
+ signal c_ff_r : std_logic := '1';
+ signal c_ff_x : std_logic;
+
+ -- Noise counter.
+ signal noise_cnt_r : unsigned(6 downto 0) := (others => '0');
+ signal noise_cnt_x : unsigned(6 downto 0);
+ signal noise_ff_r : std_logic := '1';
+ signal noise_ff_x : std_logic;
+
+ -- 15-bit Noise LFSR.
+ signal noise_lfsr_r : std_logic_vector(14 downto 0) := b"100_0000_0000_0000";
+ signal noise_lfsr_x : std_logic_vector(14 downto 0);
+ signal noise_fb_s : std_logic;
+ signal noise_s : std_logic;
+
+ -- Amplitude / Attenuation control.
+ signal level_a_s : unsigned(11 downto 0);
+ signal level_b_s : unsigned(11 downto 0);
+ signal level_c_s : unsigned(11 downto 0);
+ signal level_n_s : unsigned(11 downto 0);
+
+ -- DAC.
+ signal dac_a_r : unsigned(11 downto 0) := (others => '0');
+ signal dac_b_r : unsigned(11 downto 0) := (others => '0');
+ signal dac_c_r : unsigned(11 downto 0) := (others => '0');
+ signal dac_n_r : unsigned(11 downto 0) := (others => '0');
+ signal sum_audio_r : unsigned(13 downto 0) := (others => '0');
+
+ -- Digital to Analogue Output-level lookup table ROM.
+ --
+ -- The 4-bit level from the channel register is used as an index into a
+ -- calculated table of values that represent the equivalent voltage.
+ --
+ -- The output scale is amplitude logarithmic.
+ --
+ -- ln10 = Natural logarithm of 10, ~= 2.302585
+ -- amp = Amplitude in voltage, 0.2, 1.45, etc.
+ -- dB = decibel value in dB, -1.5, -3, etc.
+ --
+ -- dB = 20 * log(amp) / ln10
+ -- amp = 10 ^ (dB / 20)
+ --
+ -- -1.5dB = 0.8413951416
+ -- -2.0dB = 0.7943282347
+ -- -3.0dB = 0.7079457843
+ --
+ -- The datasheet defines 16 attenuation steps that are -2.0dB apart.
+ --
+ -- 1V reference values based on sixteen 2.0dB steps:
+ --
+ -- 1.0000, 0.7943, 0.6310, 0.5012, 0.3981, 0.3162, 0.2512, 0.1995,
+ -- 0.1585, 0.1259, 0.1000, 0.0794, 0.0631, 0.0501, 0.0398, 0.0316
+ --
+ -- A 7-bit number (0..128) can support a scaled version of the reference
+ -- list without having any duplicate values, but the difference is small at
+ -- the bottom-end. Duplicate values means several volume levels produce the
+ -- same output level, and is not accurate.
+ --
+ -- Using using a 12-bit output value means the four channels can be summed
+ -- into a 14-bit value without overflow, and leaves room for adjustments if
+ -- converting to something like 16-bit PCM. The 12-bit values also provide
+ -- a nicer curve, and are easier to initialize in VHDL.
+ --
+ -- The lowest volume level needs to go to 0 in a digital SoC to prevent
+ -- noise that would be filtered in a real system with external electronics.
+
+ signal dac_level_s : unsigned(11 downto 0);
+
+ type dacrom_type is array (0 to 15) of unsigned(11 downto 0);
+ signal dacrom_ar : dacrom_type := (
+ -- 4095,3253,2584,2052,1630,1295,1029, 817,
+ -- 649, 516, 409, 325, 258, 205, 163, 129 (forced to 0)
+ x"FFF",x"CB5",x"A18",x"804",x"65E",x"50F",x"405",x"331",
+ x"289",x"204",x"199",x"145",x"102",x"0CD",x"0A3",x"000");
+
+ -- PCM signed 14-bit.
+ signal sign_a_r : unsigned(11 downto 0) := (others => '0');
+ signal sign_a_x : unsigned(11 downto 0);
+ signal sign_b_r : unsigned(11 downto 0) := (others => '0');
+ signal sign_b_x : unsigned(11 downto 0);
+ signal sign_c_r : unsigned(11 downto 0) := (others => '0');
+ signal sign_c_x : unsigned(11 downto 0);
+ signal sign_n_r : unsigned(11 downto 0) := (others => '0');
+ signal sign_n_x : unsigned(11 downto 0);
+ signal pcm14s_r : unsigned(13 downto 0) := (others => '0');
+
+begin
+
+ -- Register the input data at the full clock rate.
+ process ( clk_i ) begin
+ if rising_edge(clk_i) then
+ ce_n_r <= ce_n_i;
+ wr_n_r <= wr_n_i;
+ din_r <= unsigned(data_i);
+ -- Ready is very fast so the external CPU will see the signal
+ -- in time to extend the I/O operation.
+ ready_r <= ready_x;
+ end if;
+ end process;
+
+ -- Registered output.
+ ready_o <= ready_r;
+
+
+ -- -----------------------------------------------------------------------
+ --
+ -- External bus cycle FSM.
+ --
+ -- The SN76489 can only be written (registers cannot be read back), and
+ -- only when the chip is selected.
+ --
+ -- A write operation takes 32 clock cycles. A fast-IO mode is available
+ -- if legacy timing is not important.
+
+ bus_io : process
+ ( ce_n_r, wr_n_r
+ , io_state_r, io_cnt_r, ready_r
+ ) begin
+
+ io_state_x <= io_state_r;
+ io_cnt_x <= io_cnt_r;
+ ready_x <= ready_r;
+ en_reg_wr_s <= '0';
+
+ case io_state_r is
+
+ when IO_IDLE =>
+ -- Wait for CE_n and WR_n.
+ if ce_n_r = '0' and wr_n_r = '0' then
+ io_state_x <= IO_OP;
+ ready_x <= '0';
+
+ if FAST_IO_G = '1' then
+ -- No delay.
+ io_cnt_x <= (others => '0');
+ else
+ -- The real IC takes 32 cycles for an I/O operation.
+ io_cnt_x <= to_unsigned(31, io_cnt_x'length);
+ end if;
+ end if;
+
+ when IO_OP =>
+ if io_cnt_r = 0 then
+ io_state_x <= IO_WAIT;
+ en_reg_wr_s <= '1';
+ ready_x <= '1';
+ else
+ io_cnt_x <= io_cnt_r - 1;
+ end if;
+
+ when IO_WAIT =>
+ -- The CPU must end the write-cycle; fine if CE_n is still asserted.
+ if wr_n_r = '1' then
+ io_state_x <= IO_IDLE;
+ end if;
+
+ end case;
+ end process;
+
+
+ process
+ ( clk_i, en_clk_psg_i
+ ) begin
+ if rising_edge(clk_i) then
+ if en_clk_psg_i = '1' then
+ io_state_r <= io_state_x;
+ io_cnt_r <= io_cnt_x;
+ end if;
+ end if;
+ end process;
+
+
+ -- -----------------------------------------------------------------------
+ --
+ -- Registers. Setting the channel tone period requires two writes to set
+ -- the full 10-bit value. Bit numbering is n..0, which is *BACKWARDS* from
+ -- TI's bit numbering during this era.
+ --
+ -- 7654 3210
+ -- R0 1000 PPPP Channel A tone period 3..0.
+ -- 0-PP PPPP Channel A tone period 9..4.
+ -- R1 1001 AAAA Channel A attenuation.
+ -- R2 1010 PPPP Channel B tone period 3..0.
+ -- 0-PP PPPP Channel B tone period 9..4.
+ -- R3 1011 AAAA Channel B attenuation.
+ -- R4 1100 PPPP Channel C tone period 3..0.
+ -- 0-PP PPPP Channel C tone period 9..4.
+ -- R5 1101 AAAA Channel C attenuation.
+ -- R6 1110 -F-- Noise feedback, 0=periodic, 1=white noise
+ -- 1110 --SS Noise shift rate, 00=N/512, 01=N/1024, 10=N/2048, 11=Channel C
+ -- R7 1111 AAAA Noise attenuation.
+
+ -- The register last written is latched, so any bytes written with a '0' in
+ -- the MS-bit will go to the same register.
+
+ -- The output-level is converted to the equivalent DAC value and stored as
+ -- as the look-up result, rather than the 4-bit level index. This allows
+ -- sharing of the ROM lookup table, and uses less FPGA resources.
+
+ dac_level_s <= dacrom_ar(to_integer(unsigned(din_r(3 downto 0))));
+
+ register_file : process
+ ( din_r, reg_addr_r, reg_sel_s, dac_level_s, en_reg_wr_s
+ , ch_a_period_r, ch_a_level_r
+ , ch_b_period_r, ch_b_level_r
+ , ch_c_period_r, ch_c_level_r
+ , noise_ctrl_r, noise_level_r, noise_shift_r
+ ) begin
+
+ -- Register writes go to the specified register, data writes go to the
+ -- previously written register.
+ if din_r(7) = '0' then
+ reg_sel_s <= reg_addr_r;
+ else
+ reg_sel_s <= din_r(6 downto 4);
+ end if;
+
+ ch_a_period_x <= ch_a_period_r;
+ ch_a_level_x <= ch_a_level_r;
+ ch_b_period_x <= ch_b_period_r;
+ ch_b_level_x <= ch_b_level_r;
+ ch_c_period_x <= ch_c_period_r;
+ ch_c_level_x <= ch_c_level_r;
+
+ noise_ctrl_x <= noise_ctrl_r;
+ noise_shift_x <= noise_shift_r;
+ noise_level_x <= noise_level_r;
+ noise_rst_x <= '0';
+
+
+ case reg_sel_s is
+
+ when "000" =>
+ if din_r(7) = '0' then
+ ch_a_period_x <= din_r(5 downto 0) & ch_a_period_r(3 downto 0);
+ else
+ ch_a_period_x <= ch_a_period_r(9 downto 4) & din_r(3 downto 0);
+ end if;
+
+ when "001" =>
+ ch_a_level_x <= dac_level_s;
+
+ when "010" =>
+ if din_r(7) = '0' then
+ ch_b_period_x <= din_r(5 downto 0) & ch_b_period_r(3 downto 0);
+ else
+ ch_b_period_x <= ch_b_period_r(9 downto 4) & din_r(3 downto 0);
+ end if;
+
+ when "011" =>
+ ch_b_level_x <= dac_level_s;
+
+ when "100" =>
+ if din_r(7) = '0' then
+ ch_c_period_x <= din_r(5 downto 0) & ch_c_period_r(3 downto 0);
+ else
+ ch_c_period_x <= ch_c_period_r(9 downto 4) & din_r(3 downto 0);
+ end if;
+
+ when "101" =>
+ ch_c_level_x <= dac_level_s;
+
+ when "110" =>
+ noise_ctrl_x <= din_r(2);
+ noise_shift_x <= din_r(1 downto 0);
+ -- Writing to the noise control register resets the LFSR to its
+ -- initialization value.
+ noise_rst_x <= en_reg_wr_s;
+
+ -- "111"
+ when others =>
+ noise_level_x <= dac_level_s;
+
+ null;
+ end case;
+ end process;
+
+
+ process
+ ( clk_i, en_clk_psg_i
+ ) begin
+ if rising_edge(clk_i) then
+ if en_clk_psg_i = '1' then
+
+ noise_rst_r <= noise_rst_x;
+
+ if en_reg_wr_s = '1' then
+ -- Latch the register when the write specifies a register.
+ reg_addr_r <= reg_sel_s;
+
+ ch_a_period_r <= ch_a_period_x;
+ ch_a_level_r <= ch_a_level_x;
+ ch_b_period_r <= ch_b_period_x;
+ ch_b_level_r <= ch_b_level_x;
+ ch_c_period_r <= ch_c_period_x;
+ ch_c_level_r <= ch_c_level_x;
+
+ noise_ctrl_r <= noise_ctrl_x;
+ noise_shift_r <= noise_shift_x;
+ noise_level_r <= noise_level_x;
+ end if;
+
+ end if;
+ end if;
+ end process;
+
+
+ -- -----------------------------------------------------------------------
+ --
+ -- Clock conditioning. Reduce the input clock to provide the divide by
+ -- sixteen clock-phases.
+ --
+
+ clk_div16_x <= clk_div16_r + 1;
+ en_cnt_x <= '1' when clk_div16_r = 0 else '0';
+
+ process
+ ( clk_i, en_clk_psg_i
+ ) begin
+ if rising_edge(clk_i) then
+ if en_clk_psg_i = '1' then
+ clk_div16_r <= clk_div16_x;
+ en_cnt_r <= en_cnt_x;
+ end if;
+ end if;
+ end process;
+
+
+ -- -----------------------------------------------------------------------
+ --
+ -- Channel tone counters. The counters *always* count.
+ --
+ -- The counters count *down* and load the period when they reach zero. The
+ -- zero-check-and-load are all part of the same cycle. An implementation in
+ -- C might look like this:
+ --
+ -- {
+ -- if ( counter == 0 ) {
+ -- tone = !tone;
+ -- counter = period;
+ -- }
+ --
+ -- counter--;
+ -- }
+ --
+ -- With the period work-around described below:
+ --
+ -- {
+ -- if ( counter == 0 )
+ -- {
+ -- if ( period > 0 and period < 6 ) {
+ -- tone = 1;
+ -- } else {
+ -- tone = !tone;
+ -- }
+ --
+ -- counter = period;
+ -- }
+ --
+ -- counter--;
+ -- }
+ --
+ -- This also demonstrates why changing the tone period will not take effect
+ -- until the next cycle of the counter. Interestingly, the same counter is
+ -- used in the AY-3-8910 and YM-2149, only slightly modified to count up
+ -- (actually, in silicon both up and down counters are present
+ -- simultaneously) and reset on a >= period condition.
+ --
+
+ -- Amplitude Modulation.
+ --
+ -- With a typical 3.5MHz to 4.0MHz (max) input clock, the main-clock divide
+ -- by sixteen produces a 223.72KHz clock into the tone counters. With small
+ -- period counts, frequencies *well over* the human hearing range can be
+ -- produced.
+ --
+ -- The problem with the frequencies over 20KHz is, in a digital SoC the high
+ -- frequencies do not filter out like they do when the output is connected
+ -- to an external low-pass filter and inductive load (speaker), like they
+ -- are with the real IC.
+ --
+ -- In an all digital system with digital audio, the generated frequencies
+ -- should never be more than the Nyquist frequency (twice the sample rate).
+ -- Typical sample rates are 44.1KHz or 48KHz, so any frequency over 20KHz
+ -- should not be output (and is not audible to a human anyway).
+ --
+ -- The work-around here is to flat-line the toggle flip-flop for any tone
+ -- counter with a period that produces a frequency over the Nyquist rate.
+ -- This change still allows the technique of modulating the output with
+ -- rapid volume level changes.
+ --
+ -- Based on a typical PSG clock of 3.58MHz for a Z80-based system, the
+ -- period counts that cause frequencies above 20KHz are:
+ --
+ -- f = CLK / (32 * Count)
+ --
+ -- Clk 3,579,545Hz 2.793651ns
+ --
+ -- Cnt Frequency Period
+ -- 1 111860.78Hz 8.9396us
+ -- 2 55930.39Hz 17.8793us
+ -- 3 37286.92Hz 26.8190us
+ -- 4 27965.19Hz 35.7587us
+ -- 5 22372.15Hz 44.6984us
+ -- ---------------------------
+ -- 6 18643.46Hz 53.6381us First audible count.
+ -- 7 15980.11Hz 62.5777us
+ -- 8 13982.59Hz 71.5174us
+ -- 9 12428.97Hz 80.4571us
+ -- 10 11186.07Hz 89.3968us
+ -- 11 10169.16Hz 98.3365us
+ -- 12 9321.73Hz 107.2762us
+ -- 13 8604.67Hz 116.2158us
+ -- 14 7990.05Hz 125.1555us
+ -- 15 7457.38Hz 134.0952us
+ -- 16 6991.29Hz 143.0349us Used by some software for level-modulation.
+ -- ---------------------------
+ -- 17 6580.04Hz 151.9746us
+ -- ...
+ -- 0 109.23Hz 9.1542ms A count of zero is the maximum period.
+ --
+ -- While a count of 6 is technically the Nyquist cut-off, some game software
+ -- is known to use a period of 16 as the base frequency for the amplitude
+ -- modulation hack. While audible, the 7KHz tone is not very musical, and
+ -- causes a harsh (if not painful) undertone to the sound being created with
+ -- the amplitude modulation.
+ --
+ -- Suffice to say, setting the flat-line cut-off to 16 should not affect the
+ -- audio for most software in any negative way, but can help some software
+ -- sound better.
+
+
+ -- A channel counter and tone flip-flop.
+ ch_a_cnt_x <=
+ -- Load uses count-enable next-state look-ahead when counter is 0.
+ ch_a_period_r when (en_cnt_x = '1' and ch_a_cnt_r = 0) else
+ -- Counting uses the current-state.
+ ch_a_cnt_r - 1 when en_cnt_r = '1' else
+ ch_a_cnt_r;
+
+ flatline_a_s <=
+ '1' when ch_a_period_r > 0 and ch_a_period_r < MIN_PERIOD_CNT_G else
+ '0';
+
+ tone_a_x <=
+ -- Flat-line the output for counts that produce frequencies > 20KHz.
+ '1' when flatline_a_s = '1' else
+ -- Toggle channel tone flip-flop when the counter reaches 0.
+ -- Same look-ahead condition as the counter-load.
+ not tone_a_r when (en_cnt_x = '1' and ch_a_cnt_r = 0) else
+ tone_a_r;
+
+ -- B channel counter and tone flip-flop.
+ ch_b_cnt_x <=
+ ch_b_period_r when (en_cnt_x = '1' and ch_b_cnt_r = 0) else
+ ch_b_cnt_r - 1 when en_cnt_r = '1' else
+ ch_b_cnt_r;
+
+ flatline_b_s <=
+ '1' when ch_b_period_r > 0 and ch_b_period_r < MIN_PERIOD_CNT_G else
+ '0';
+
+ tone_b_x <=
+ '1' when flatline_b_s = '1' else
+ not tone_b_r when (en_cnt_x = '1' and ch_b_cnt_r = 0) else
+ tone_b_r;
+
+ -- C channel counter and tone flip-flop.
+ ch_c_cnt_x <=
+ ch_c_period_r when (en_cnt_x = '1' and ch_c_cnt_r = 0) else
+ ch_c_cnt_r - 1 when en_cnt_r = '1' else
+ ch_c_cnt_r;
+
+ flatline_c_s <=
+ '1' when ch_c_period_r > 0 and ch_c_period_r < MIN_PERIOD_CNT_G else
+ '0';
+
+ tone_c_x <= flatline_c_s or c_ff_r;
+
+ -- The work-around to limit high frequency outputs interferes with Channel-C
+ -- being able to clock the noise shift register. This is a work-around to
+ -- that work-around, to always have an output from Channel-C that can be
+ -- used to clock the noise shift register.
+ c_ff_x <=
+ not c_ff_r when (en_cnt_x = '1' and ch_c_cnt_r = 0) else
+ c_ff_r;
+
+
+ process
+ ( clk_i, en_clk_psg_i
+ ) begin
+ if rising_edge(clk_i) then
+
+ if en_clk_psg_i = '1' then
+ ch_a_cnt_r <= ch_a_cnt_x;
+ tone_a_r <= tone_a_x;
+
+ ch_b_cnt_r <= ch_b_cnt_x;
+ tone_b_r <= tone_b_x;
+
+ ch_c_cnt_r <= ch_c_cnt_x;
+ tone_c_r <= tone_c_x;
+ c_ff_r <= c_ff_x;
+ end if;
+
+ end if;
+ end process;
+
+
+ -- -----------------------------------------------------------------------
+ --
+ -- Noise period counter. A continuous counter to further divide the input
+ -- clock by 32, 64, or 128. The output goes to a selector, controlled by the
+ -- noise register, to choose one of the three rates, or the output flip-flop
+ -- of channel C, to drive the LFSR.
+
+ noise_cnt_x <=
+ noise_cnt_r + 1 when en_cnt_r = '1' else
+ noise_cnt_r;
+
+ with noise_shift_r select
+ noise_ff_x <= -- N = PSG input clock, typical 3.58MHz.
+ noise_cnt_r(4) when "00", -- N / 512 = approx 6991.2988Hz 143.034us
+ noise_cnt_r(5) when "01", -- N / 1024 = approx 3495.6494Hz 286.069us
+ noise_cnt_r(6) when "10", -- N / 2048 = approx 1747.8247Hz 572.139us
+ c_ff_r when others; -- "11" -- Channel C tone as the clock.
+
+
+ -- The noise can be periodic or white depending on the feedback-bit in the
+ -- noise control register. 0 = periodic, which just disables the XOR of the
+ -- LFSR and loops the single initialization bit through the shift register.
+ --
+ -- Noise 15-bit right-shift LFSR with taps at 0 and 1, LS-bit is the output.
+ -- Reset loads the LFSR with 0x4000 to prevent lock-up. The same pattern
+ -- can be obtained with a left-shift, taps at 13 and 14, MS-bit output.
+ --
+ -- Accurate implementation in C, no branching:
+ --
+ -- uint32_t lfsr;
+ -- uint8_t noise_bit;
+ --
+ -- // A 15-input NOR gate ensures init with 100_0000_0000_0000
+ -- lfsr = (1 << 14);
+ --
+ -- // Taps at 0 and 1, mask result.
+ -- int32_t fb = ((lfsr >> 0) ^ (lfsr >> 1)) & 1;
+ --
+ -- // Right-shift, feedback bit to the most-significant bit.
+ -- lfsr = (lfsr >> 1) | (fb << 14);
+ --
+ -- noise_bit = (lfsr & 1);
+ --
+
+ noise_fb_s <=
+ (noise_ctrl_r and noise_lfsr_r(1)) xor noise_lfsr_r(0);
+ noise_lfsr_x <= noise_fb_s & noise_lfsr_r(14 downto 1);
+ noise_s <= noise_lfsr_r(0);
+
+
+ process
+ ( clk_i, en_clk_psg_i, noise_rst_r
+ ) begin
+ if rising_edge(clk_i) then
+
+ -- ** NOTE: This reset is active high.
+ if noise_rst_r = '1' then
+ noise_cnt_r <= (others => '0');
+ noise_ff_r <= '1';
+ noise_lfsr_r <= b"100_0000_0000_0000";
+
+ elsif en_clk_psg_i = '1' then
+ noise_cnt_r <= noise_cnt_x;
+ noise_ff_r <= noise_ff_x;
+ -- Look-ahead rising-edge detect the noise flip-flop.
+ if noise_ff_r = '0' and noise_ff_x = '1' then
+ noise_lfsr_r <= noise_lfsr_x;
+ end if;
+ end if;
+
+ end if;
+ end process;
+
+
+ -- -----------------------------------------------------------------------
+ --
+ -- Amplitude / Attenuation control. The amplitude of each channel is
+ -- controlled by the channel's 4-bit attenuation register.
+ --
+ -- The "level" in the SN76489 is an amount of attenuation, and the channel's
+ -- level has already been converted into its DAC level. When the tone
+ -- flip-flop is '0', the most attenuation (minimum DAC level) is output.
+
+ level_a_s <=
+ (others => '0') when tone_a_r = '0' else
+ ch_a_level_r;
+
+ level_b_s <=
+ (others => '0') when tone_b_r = '0' else
+ ch_b_level_r;
+
+ level_c_s <=
+ (others => '0') when tone_c_r = '0' else
+ ch_c_level_r;
+
+ level_n_s <=
+ (others => '0') when noise_s = '0' else
+ noise_level_r;
+
+
+ -- -----------------------------------------------------------------------
+ --
+ -- Output registers and unsigned summation. If the level had not already
+ -- been converted to the output level, this would also be the DAC section.
+ --
+
+ ch_a_o <= dac_a_r;
+ ch_b_o <= dac_b_r;
+ ch_c_o <= dac_c_r;
+ noise_o <= dac_n_r;
+ mix_audio_o <= sum_audio_r;
+
+ process
+ ( clk_i, en_clk_psg_i
+ ) begin
+ if rising_edge(clk_i) then
+ if en_clk_psg_i = '1' then
+
+ dac_a_r <= level_a_s;
+ dac_b_r <= level_b_s;
+ dac_c_r <= level_c_s;
+ dac_n_r <= level_n_s;
+
+ -- Sum the audio channels.
+ sum_audio_r <= ("00" & level_a_s) + ("00" & level_b_s) +
+ ("00" & level_c_s) + ("00" & level_n_s);
+ end if;
+ end if;
+ end process;
+
+
+ -- -----------------------------------------------------------------------
+ --
+ -- Signed zero-centered 14-bit PCM.
+ --
+
+ -- Make a -/+ level value depending on the tone state. When the flat-line
+ -- work-around for frequencies over the Nyquist rate is in effect, adjust
+ -- the unsigned level-range to a signed-level range.
+ --
+ -- signed_level =
+ -- level - (range / 2) when flat-line
+ --
+ -- otherwise, -/+ zero-centered square-wave:
+ --
+ -- signed_level =
+ -- -(level / 2) when tone == 0
+ -- (level / 2) when tone == 1
+
+ sign_a_x <=
+ ch_a_level_r - x"800" when flatline_a_s = '1' else
+ ("1" & (not ch_a_level_r(11 downto 1))) + 1 when tone_a_r = '0' else
+ ("0" & ch_a_level_r(11 downto 1));
+
+ sign_b_x <=
+ ch_b_level_r - x"800" when flatline_b_s = '1' else
+ ("1" & (not ch_b_level_r(11 downto 1))) + 1 when tone_b_r = '0' else
+ ("0" & ch_b_level_r(11 downto 1));
+
+ sign_c_x <=
+ ch_c_level_r - x"800" when flatline_c_s = '1' else
+ ("1" & (not ch_c_level_r(11 downto 1))) + 1 when tone_c_r = '0' else
+ ("0" & ch_c_level_r(11 downto 1));
+
+ sign_n_x <=
+ ("1" & (not noise_level_r(11 downto 1))) + 1 when noise_s = '0' else
+ ("0" & noise_level_r(11 downto 1));
+
+
+ pcm14s_o <= pcm14s_r;
+
+
+ process
+ ( clk_i, en_clk_psg_i
+ ) begin
+ if rising_edge(clk_i) then
+ if en_clk_psg_i = '1' then
+
+ sign_a_r <= sign_a_x;
+ sign_b_r <= sign_b_x;
+ sign_c_r <= sign_c_x;
+ sign_n_r <= sign_n_x;
+
+ -- Sum to signed 14-bit and left-align to signed 16-bit.
+ pcm14s_r <=
+ (sign_a_r(11) & sign_a_r(11) & sign_a_r) +
+ (sign_b_r(11) & sign_b_r(11) & sign_b_r) +
+ (sign_c_r(11) & sign_c_r(11) & sign_c_r) +
+ (sign_n_r(11) & sign_n_r(11) & sign_n_r);
+
+ end if;
+ end if;
+ end process;
+
+end rtl;
diff --git a/Arcade_MiST/Sega Bank Panic Hardware/rtl/x74138.v b/Arcade_MiST/Sega Bank Panic Hardware/rtl/x74138.v
new file mode 100644
index 00000000..a3afed51
--- /dev/null
+++ b/Arcade_MiST/Sega Bank Panic Hardware/rtl/x74138.v
@@ -0,0 +1,14 @@
+
+module x74138(
+ input G1,
+ input G2A,
+ input G2B,
+ input [2:0] A,
+ output reg [7:0] Y
+);
+
+always @*
+ if (~G2B & ~G2A & G1) Y = ~(1<