From 8755eecd28bd855a5466fbdc0697d3ef31e7e749 Mon Sep 17 00:00:00 2001 From: Marcel Date: Fri, 15 Mar 2019 21:10:24 +0100 Subject: [PATCH] new Core --- Arcade_MiST/Phoenix Hardware/Capitol.jpg | Bin 0 -> 8113 bytes .../Capitol_MIST/Capitol_mist.qpf | 30 + .../Capitol_MIST/Capitol_mist.qsf | 422 ++++ .../Capitol_MIST/Capitol_mist.sdc} | 0 .../Phoenix Hardware/Capitol_MIST/README.txt | 24 + .../Capitol_MIST/Release/Capitol_mist.rbf | Bin 0 -> 274224 bytes .../Capitol_MIST}/clean.bat | 0 .../Capitol_MIST/rtl/Capitol_MiST.sv | 184 ++ .../Capitol_MIST/rtl/ROM/23.hex | 129 ++ .../Capitol_MIST/rtl/ROM/24.hex | 129 ++ .../Capitol_MIST/rtl/ROM/39.hex | 129 ++ .../Capitol_MIST/rtl/ROM/40.hex | 129 ++ .../Capitol_MIST/rtl/ROM/ic40.hex | 17 + .../Capitol_MIST/rtl/ROM/ic41.hex | 17 + .../Capitol_MIST/rtl/ROM/prog.hex | 1025 +++++++++ .../Capitol_MIST}/rtl/T80/T80.vhd | 0 .../Capitol_MIST}/rtl/T80/T8080se.vhd | 0 .../Capitol_MIST}/rtl/T80/T80_ALU.vhd | 0 .../Capitol_MIST}/rtl/T80/T80_MCode.vhd | 0 .../Capitol_MIST}/rtl/T80/T80_Pack.vhd | 0 .../Capitol_MIST}/rtl/T80/T80_Reg.vhd | 0 .../Capitol_MIST}/rtl/build_id.tcl | 0 .../Capitol_MIST}/rtl/build_id.v | 0 .../Capitol_MIST}/rtl/dac.vhd | 0 .../Capitol_MIST}/rtl/gen_ram.vhd | 0 .../Capitol_MIST}/rtl/hq2x.sv | 0 .../Capitol_MIST}/rtl/mist_io.v | 0 .../Capitol_MIST}/rtl/osd.v | 0 .../Capitol_MIST/rtl/phoenix.vhd | 472 ++++ .../Capitol_MIST}/rtl/phoenix_effect1.vhd | 0 .../Capitol_MIST}/rtl/phoenix_effect2.vhd | 0 .../Capitol_MIST}/rtl/phoenix_effect3.vhd | 0 .../Capitol_MIST}/rtl/phoenix_mist.vhd | 0 .../Capitol_MIST}/rtl/phoenix_music.vhd | 0 .../Capitol_MIST}/rtl/phoenix_video.vhd | 0 .../Capitol_MIST}/rtl/pll.ppf | 0 .../Capitol_MIST}/rtl/pll.qip | 0 .../Phoenix Hardware/Capitol_MIST/rtl/pll.vhd | 387 ++++ .../Capitol_MIST}/rtl/scandoubler.v | 0 .../Capitol_MIST/rtl/spram.vhd | 55 + .../Capitol_MIST/rtl/sprom.vhd | 82 + .../Capitol_MIST}/rtl/video_mixer.sv | 0 .../Phoenix.jpg | Bin .../Phoenix_MIST/README.txt | 0 .../Phoenix_MIST/Release/phoenix_mist.rbf | Bin .../Phoenix Hardware/Phoenix_MIST/clean.bat | 15 + .../Phoenix_MIST/phoenix_mist.qpf | 0 .../Phoenix_MIST/phoenix_mist.qsf | 0 .../Phoenix_MIST/phoenix_mist.sdc | 33 + .../Phoenix_MIST/rtl/Phoenix_MiST.sv | 0 .../Phoenix_MIST/rtl/ROM/prom_ic23.vhd | 0 .../Phoenix_MIST/rtl/ROM/prom_ic24.vhd | 0 .../Phoenix_MIST/rtl/ROM/prom_ic39.vhd | 0 .../Phoenix_MIST/rtl/ROM/prom_ic40.vhd | 0 .../rtl/ROM/prom_palette_ic40.vhd | 0 .../rtl/ROM/prom_palette_ic41.vhd | 0 .../Phoenix_MIST/rtl/T80/T80.vhd | 1073 +++++++++ .../Phoenix_MIST/rtl/T80/T8080se.vhd | 185 ++ .../Phoenix_MIST/rtl/T80/T80_ALU.vhd | 351 +++ .../Phoenix_MIST/rtl/T80/T80_MCode.vhd | 1934 +++++++++++++++++ .../Phoenix_MIST/rtl/T80/T80_Pack.vhd | 208 ++ .../Phoenix_MIST/rtl/T80/T80_Reg.vhd | 105 + .../Phoenix_MIST/rtl/build_id.tcl | 35 + .../Phoenix_MIST/rtl/build_id.v | 2 + .../Phoenix Hardware/Phoenix_MIST/rtl/dac.vhd | 48 + .../Phoenix_MIST/rtl/gen_ram.vhd | 82 + .../Phoenix_MIST/rtl/greybox_tmp/cbx_args.txt | 0 .../Phoenix Hardware/Phoenix_MIST/rtl/hq2x.sv | 454 ++++ .../Phoenix_MIST/rtl/mist_io.v | 530 +++++ .../Phoenix Hardware/Phoenix_MIST/rtl/osd.v | 194 ++ .../Phoenix_MIST/rtl/phoenix.vhd | 0 .../Phoenix_MIST/rtl/phoenix_effect1.vhd | 230 ++ .../Phoenix_MIST/rtl/phoenix_effect2.vhd | 387 ++++ .../Phoenix_MIST/rtl/phoenix_effect3.vhd | 290 +++ .../Phoenix_MIST/rtl/phoenix_mist.vhd | 309 +++ .../Phoenix_MIST/rtl/phoenix_music.vhd | 241 ++ .../Phoenix_MIST/rtl/phoenix_prog.vhd | 0 .../Phoenix_MIST/rtl/phoenix_video.vhd | 160 ++ .../Phoenix Hardware/Phoenix_MIST/rtl/pll.ppf | 11 + .../Phoenix Hardware/Phoenix_MIST/rtl/pll.qip | 4 + .../Phoenix_MIST/rtl/pll.vhd | 0 .../Phoenix_MIST/rtl/scandoubler.v | 183 ++ .../Phoenix_MIST/rtl/video_mixer.sv | 243 +++ Arcade_MiST/README.txt | 8 +- 84 files changed, 10545 insertions(+), 1 deletion(-) create mode 100644 Arcade_MiST/Phoenix Hardware/Capitol.jpg create mode 100644 Arcade_MiST/Phoenix Hardware/Capitol_MIST/Capitol_mist.qpf create mode 100644 Arcade_MiST/Phoenix Hardware/Capitol_MIST/Capitol_mist.qsf rename Arcade_MiST/{Custom Hardware/Phoenix_MIST/phoenix_mist.sdc => Phoenix Hardware/Capitol_MIST/Capitol_mist.sdc} (100%) create mode 100644 Arcade_MiST/Phoenix Hardware/Capitol_MIST/README.txt create mode 100644 Arcade_MiST/Phoenix Hardware/Capitol_MIST/Release/Capitol_mist.rbf rename Arcade_MiST/{Custom Hardware/Phoenix_MIST => Phoenix Hardware/Capitol_MIST}/clean.bat (100%) create mode 100644 Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/Capitol_MiST.sv create mode 100644 Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/ROM/23.hex create mode 100644 Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/ROM/24.hex create mode 100644 Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/ROM/39.hex create mode 100644 Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/ROM/40.hex create mode 100644 Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/ROM/ic40.hex create mode 100644 Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/ROM/ic41.hex create mode 100644 Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/ROM/prog.hex rename Arcade_MiST/{Custom Hardware/Phoenix_MIST => Phoenix Hardware/Capitol_MIST}/rtl/T80/T80.vhd (100%) rename Arcade_MiST/{Custom Hardware/Phoenix_MIST => Phoenix Hardware/Capitol_MIST}/rtl/T80/T8080se.vhd (100%) rename Arcade_MiST/{Custom Hardware/Phoenix_MIST => Phoenix Hardware/Capitol_MIST}/rtl/T80/T80_ALU.vhd (100%) rename Arcade_MiST/{Custom Hardware/Phoenix_MIST => Phoenix Hardware/Capitol_MIST}/rtl/T80/T80_MCode.vhd (100%) rename Arcade_MiST/{Custom Hardware/Phoenix_MIST => Phoenix Hardware/Capitol_MIST}/rtl/T80/T80_Pack.vhd (100%) rename Arcade_MiST/{Custom Hardware/Phoenix_MIST => Phoenix Hardware/Capitol_MIST}/rtl/T80/T80_Reg.vhd (100%) rename Arcade_MiST/{Custom Hardware/Phoenix_MIST => Phoenix Hardware/Capitol_MIST}/rtl/build_id.tcl (100%) rename Arcade_MiST/{Custom Hardware/Phoenix_MIST => Phoenix Hardware/Capitol_MIST}/rtl/build_id.v (100%) rename Arcade_MiST/{Custom Hardware/Phoenix_MIST => Phoenix Hardware/Capitol_MIST}/rtl/dac.vhd (100%) rename Arcade_MiST/{Custom Hardware/Phoenix_MIST => Phoenix Hardware/Capitol_MIST}/rtl/gen_ram.vhd (100%) rename Arcade_MiST/{Custom Hardware/Phoenix_MIST => Phoenix Hardware/Capitol_MIST}/rtl/hq2x.sv (100%) rename Arcade_MiST/{Custom Hardware/Phoenix_MIST => Phoenix Hardware/Capitol_MIST}/rtl/mist_io.v (100%) rename Arcade_MiST/{Custom Hardware/Phoenix_MIST => Phoenix Hardware/Capitol_MIST}/rtl/osd.v (100%) create mode 100644 Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/phoenix.vhd rename Arcade_MiST/{Custom Hardware/Phoenix_MIST => Phoenix Hardware/Capitol_MIST}/rtl/phoenix_effect1.vhd (100%) rename Arcade_MiST/{Custom Hardware/Phoenix_MIST => Phoenix Hardware/Capitol_MIST}/rtl/phoenix_effect2.vhd (100%) rename Arcade_MiST/{Custom Hardware/Phoenix_MIST => Phoenix Hardware/Capitol_MIST}/rtl/phoenix_effect3.vhd (100%) rename Arcade_MiST/{Custom Hardware/Phoenix_MIST => Phoenix Hardware/Capitol_MIST}/rtl/phoenix_mist.vhd (100%) rename Arcade_MiST/{Custom Hardware/Phoenix_MIST => Phoenix Hardware/Capitol_MIST}/rtl/phoenix_music.vhd (100%) rename Arcade_MiST/{Custom Hardware/Phoenix_MIST => Phoenix Hardware/Capitol_MIST}/rtl/phoenix_video.vhd (100%) rename Arcade_MiST/{Custom Hardware/Phoenix_MIST => Phoenix Hardware/Capitol_MIST}/rtl/pll.ppf (100%) rename Arcade_MiST/{Custom Hardware/Phoenix_MIST => Phoenix Hardware/Capitol_MIST}/rtl/pll.qip (100%) create mode 100644 Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/pll.vhd rename Arcade_MiST/{Custom Hardware/Phoenix_MIST => Phoenix Hardware/Capitol_MIST}/rtl/scandoubler.v (100%) create mode 100644 Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/spram.vhd create mode 100644 Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/sprom.vhd rename Arcade_MiST/{Custom Hardware/Phoenix_MIST => Phoenix Hardware/Capitol_MIST}/rtl/video_mixer.sv (100%) rename Arcade_MiST/{Custom Hardware => Phoenix Hardware}/Phoenix.jpg (100%) rename Arcade_MiST/{Custom Hardware => Phoenix Hardware}/Phoenix_MIST/README.txt (100%) rename Arcade_MiST/{Custom Hardware => Phoenix Hardware}/Phoenix_MIST/Release/phoenix_mist.rbf (100%) create mode 100644 Arcade_MiST/Phoenix Hardware/Phoenix_MIST/clean.bat rename Arcade_MiST/{Custom Hardware => Phoenix Hardware}/Phoenix_MIST/phoenix_mist.qpf (100%) rename Arcade_MiST/{Custom Hardware => Phoenix Hardware}/Phoenix_MIST/phoenix_mist.qsf (100%) create mode 100644 Arcade_MiST/Phoenix Hardware/Phoenix_MIST/phoenix_mist.sdc rename Arcade_MiST/{Custom Hardware => Phoenix Hardware}/Phoenix_MIST/rtl/Phoenix_MiST.sv (100%) rename Arcade_MiST/{Custom Hardware => Phoenix Hardware}/Phoenix_MIST/rtl/ROM/prom_ic23.vhd (100%) rename Arcade_MiST/{Custom Hardware => Phoenix Hardware}/Phoenix_MIST/rtl/ROM/prom_ic24.vhd (100%) rename Arcade_MiST/{Custom Hardware => Phoenix Hardware}/Phoenix_MIST/rtl/ROM/prom_ic39.vhd (100%) rename Arcade_MiST/{Custom Hardware => Phoenix Hardware}/Phoenix_MIST/rtl/ROM/prom_ic40.vhd (100%) rename Arcade_MiST/{Custom Hardware => Phoenix Hardware}/Phoenix_MIST/rtl/ROM/prom_palette_ic40.vhd (100%) rename Arcade_MiST/{Custom Hardware => Phoenix Hardware}/Phoenix_MIST/rtl/ROM/prom_palette_ic41.vhd (100%) create mode 100644 Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/T80/T80.vhd create mode 100644 Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/T80/T8080se.vhd create mode 100644 Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/T80/T80_ALU.vhd create mode 100644 Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/T80/T80_MCode.vhd create mode 100644 Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/T80/T80_Pack.vhd create mode 100644 Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/T80/T80_Reg.vhd create mode 100644 Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/build_id.tcl create mode 100644 Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/build_id.v create mode 100644 Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/dac.vhd create mode 100644 Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/gen_ram.vhd rename Arcade_MiST/{Custom Hardware => Phoenix Hardware}/Phoenix_MIST/rtl/greybox_tmp/cbx_args.txt (100%) create mode 100644 Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/hq2x.sv create mode 100644 Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/mist_io.v create mode 100644 Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/osd.v rename Arcade_MiST/{Custom Hardware => Phoenix Hardware}/Phoenix_MIST/rtl/phoenix.vhd (100%) create mode 100644 Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/phoenix_effect1.vhd create mode 100644 Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/phoenix_effect2.vhd create mode 100644 Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/phoenix_effect3.vhd create mode 100644 Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/phoenix_mist.vhd create mode 100644 Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/phoenix_music.vhd rename Arcade_MiST/{Custom Hardware => Phoenix Hardware}/Phoenix_MIST/rtl/phoenix_prog.vhd (100%) create mode 100644 Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/phoenix_video.vhd create mode 100644 Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/pll.ppf create mode 100644 Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/pll.qip rename Arcade_MiST/{Custom Hardware => Phoenix Hardware}/Phoenix_MIST/rtl/pll.vhd (100%) create mode 100644 Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/scandoubler.v create mode 100644 Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/video_mixer.sv diff --git a/Arcade_MiST/Phoenix Hardware/Capitol.jpg b/Arcade_MiST/Phoenix Hardware/Capitol.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3943cc0b635ec6c1088bba03f0bb4a8606d25a2c GIT binary patch literal 8113 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 XneexQmX)E7`$k{f|8eQ)PDlO^kNR*^ literal 0 HcmV?d00001 diff --git a/Arcade_MiST/Phoenix Hardware/Capitol_MIST/Capitol_mist.qpf b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/Capitol_mist.qpf new file mode 100644 index 00000000..de19fb03 --- /dev/null +++ b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/Capitol_mist.qpf @@ -0,0 +1,30 @@ +# -------------------------------------------------------------------------- # +# +# Copyright (C) 1991-2013 Altera Corporation +# Your use of Altera Corporation's design tools, logic functions +# and other software and tools, and its AMPP partner logic +# functions, and any output files from any of the foregoing +# (including device programming or simulation files), and any +# associated documentation or information are expressly subject +# to the terms and conditions of the Altera Program License +# Subscription Agreement, Altera MegaCore Function License +# Agreement, or other applicable license agreement, including, +# without limitation, that your use is for the sole purpose of +# programming logic devices manufactured by Altera and sold by +# Altera or its authorized distributors. Please refer to the +# applicable agreement for further details. +# +# -------------------------------------------------------------------------- # +# +# Quartus II 64-Bit +# Version 13.1.0 Build 162 10/23/2013 SJ Web Edition +# Date created = 02:40:30 January 25, 2017 +# +# -------------------------------------------------------------------------- # + +QUARTUS_VERSION = "13.1" +DATE = "02:40:30 January 25, 2017" + +# Revisions + +PROJECT_REVISION = "Capitol_mist" \ No newline at end of file diff --git a/Arcade_MiST/Phoenix Hardware/Capitol_MIST/Capitol_mist.qsf b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/Capitol_mist.qsf new file mode 100644 index 00000000..f9e70867 --- /dev/null +++ b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/Capitol_mist.qsf @@ -0,0 +1,422 @@ +# -------------------------------------------------------------------------- # +# +# Copyright (C) 1991-2014 Altera Corporation +# Your use of Altera Corporation's design tools, logic functions +# and other software and tools, and its AMPP partner logic +# functions, and any output files from any of the foregoing +# (including device programming or simulation files), and any +# associated documentation or information are expressly subject +# to the terms and conditions of the Altera Program License +# Subscription Agreement, Altera MegaCore Function License +# Agreement, or other applicable license agreement, including, +# without limitation, that your use is for the sole purpose of +# programming logic devices manufactured by Altera and sold by +# Altera or its authorized distributors. Please refer to the +# applicable agreement for further details. +# +# -------------------------------------------------------------------------- # +# +# Quartus II 64-Bit +# Version 13.1.4 Build 182 03/12/2014 SJ Web Edition +# Date created = 20:38:53 March 15, 2019 +# +# -------------------------------------------------------------------------- # +# +# Notes: +# +# 1) The default values for assignments are stored in the file: +# Capitol_mist_assignment_defaults.qdf +# If this file doesn't exist, see file: +# assignment_defaults.qdf +# +# 2) Altera recommends that you do not modify this file. This +# file is updated automatically by the Quartus II software +# and any changes you make may be lost or overwritten. +# +# -------------------------------------------------------------------------- # + + + +# Project-Wide Assignments +# ======================== +set_global_assignment -name ORIGINAL_QUARTUS_VERSION 13.1 +set_global_assignment -name PROJECT_CREATION_TIME_DATE "21:40:24 MAY 17, 2014" +set_global_assignment -name LAST_QUARTUS_VERSION 13.1 +set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files +set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL +set_global_assignment -name SMART_RECOMPILE ON +set_global_assignment -name FLOW_ENABLE_IO_ASSIGNMENT_ANALYSIS ON +set_global_assignment -name SYSTEMVERILOG_FILE rtl/Capitol_MiST.sv +set_global_assignment -name VHDL_FILE rtl/phoenix.vhd +set_global_assignment -name VHDL_FILE rtl/phoenix_effect3.vhd +set_global_assignment -name VHDL_FILE rtl/phoenix_effect2.vhd +set_global_assignment -name VHDL_FILE rtl/phoenix_effect1.vhd +set_global_assignment -name VHDL_FILE rtl/phoenix_video.vhd +set_global_assignment -name VHDL_FILE rtl/phoenix_music.vhd +set_global_assignment -name VHDL_FILE rtl/pll.vhd +set_global_assignment -name VHDL_FILE rtl/T80/T8080se.vhd +set_global_assignment -name VHDL_FILE rtl/T80/T80_Reg.vhd +set_global_assignment -name VHDL_FILE rtl/T80/T80_Pack.vhd +set_global_assignment -name VHDL_FILE rtl/T80/T80_MCode.vhd +set_global_assignment -name VHDL_FILE rtl/T80/T80_ALU.vhd +set_global_assignment -name VHDL_FILE rtl/T80/T80.vhd +set_global_assignment -name VERILOG_FILE rtl/osd.v +set_global_assignment -name VERILOG_FILE rtl/mist_io.v +set_global_assignment -name SYSTEMVERILOG_FILE rtl/hq2x.sv +set_global_assignment -name VHDL_FILE rtl/gen_ram.vhd +set_global_assignment -name VHDL_FILE rtl/dac.vhd +set_global_assignment -name SYSTEMVERILOG_FILE rtl/video_mixer.sv +set_global_assignment -name VERILOG_FILE rtl/scandoubler.v +set_global_assignment -name VHDL_FILE rtl/sprom.vhd + +# 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 "pll27: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 CYCLONEII_OPTIMIZATION_TECHNIQUE SPEED +set_global_assignment -name FAMILY "Cyclone III" +set_global_assignment -name TOP_LEVEL_ENTITY Capitol_MiST +set_global_assignment -name DEVICE_FILTER_PACKAGE TQFP +set_global_assignment -name DEVICE_FILTER_PIN_COUNT 144 +set_global_assignment -name ALLOW_POWER_UP_DONT_CARE ON +set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS ON +set_global_assignment -name SAVE_DISK_SPACE OFF +set_global_assignment -name DEVICE_FILTER_SPEED_GRADE 8 + +# Fitter Assignments +# ================== +set_global_assignment -name FITTER_EARLY_TIMING_ESTIMATE_MODE OPTIMISTIC +set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC ON +set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_RETIMING ON +set_global_assignment -name PHYSICAL_SYNTHESIS_ASYNCHRONOUS_SIGNAL_PIPELINING ON +set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_DUPLICATION ON +set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC_FOR_AREA ON +set_global_assignment -name PHYSICAL_SYNTHESIS_MAP_LOGIC_TO_MEMORY_FOR_AREA ON +set_global_assignment -name PHYSICAL_SYNTHESIS_EFFORT EXTRA +set_global_assignment -name DEVICE EP3C25E144C8 +set_global_assignment -name CYCLONEIII_CONFIGURATION_SCHEME "PASSIVE SERIAL" +set_global_assignment -name FORCE_CONFIGURATION_VCCIO ON +set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "3.3-V LVTTL" +set_global_assignment -name CRC_ERROR_OPEN_DRAIN OFF +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" +set_global_assignment -name CYCLONEII_RESERVE_NCEO_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_global_assignment -name OPTIMIZE_HOLD_TIMING "ALL PATHS" +set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING ON +set_global_assignment -name FITTER_EFFORT "STANDARD FIT" + +# 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 stp1.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(Capitol_MiST) + + # Pin & Location Assignments + # ========================== + set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[0] + set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[1] + set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[2] + set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[3] + set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[4] + set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[5] + set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[6] + set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[7] + set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[8] + set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[9] + set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[10] + set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[11] + set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[12] + set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[13] + set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[14] + set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[15] + set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[0] + set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[1] + set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[2] + set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[3] + set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[4] + set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[5] + set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[6] + set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[7] + set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[8] + set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[9] + set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[10] + set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[11] + set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[12] + 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[0] + set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[1] + set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[2] + set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[3] + set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[4] + set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[5] + set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[6] + set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[7] + set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[8] + set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[9] + set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[10] + set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[11] + set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[12] + set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[13] + set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[14] + set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[15] + + # Fitter Assignments + # ================== + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SDRAM_A[0] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SDRAM_A[1] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SDRAM_A[2] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SDRAM_A[3] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SDRAM_A[4] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SDRAM_A[5] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SDRAM_A[6] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SDRAM_A[7] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SDRAM_A[8] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SDRAM_A[9] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SDRAM_A[10] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SDRAM_A[11] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SDRAM_A[12] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SDRAM_DQ[0] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SDRAM_DQ[1] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SDRAM_DQ[2] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SDRAM_DQ[3] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SDRAM_DQ[4] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SDRAM_DQ[5] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SDRAM_DQ[6] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SDRAM_DQ[7] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SDRAM_DQ[8] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SDRAM_DQ[9] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SDRAM_DQ[10] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SDRAM_DQ[11] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SDRAM_DQ[12] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SDRAM_DQ[13] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SDRAM_DQ[14] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SDRAM_DQ[15] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SDRAM_BA[0] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SDRAM_BA[1] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SDRAM_DQML + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SDRAM_DQMH + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SDRAM_nRAS + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SDRAM_nCAS + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SDRAM_nWE + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SDRAM_nCS + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SDRAM_CKE + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SDRAM_CLK + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to VGA_R[5] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to VGA_R[4] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to VGA_R[3] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to VGA_R[2] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to VGA_R[1] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to VGA_R[0] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to VGA_G[5] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to VGA_G[4] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to VGA_G[3] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to VGA_G[2] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to VGA_G[1] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to VGA_G[0] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to VGA_B[5] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to VGA_B[4] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to VGA_B[3] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to VGA_B[2] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to VGA_B[1] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to VGA_B[0] + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to VGA_HS + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to VGA_VS + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to LED + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to AUDIO_L + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to AUDIO_R + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SPI_DO + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to CONF_DATA0 + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to AUDIO_L + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to AUDIO_R + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to CLOCK_27 + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to CONF_DATA0 + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SPI_DI + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SPI_DO + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SPI_SCK + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SPI_SS2 + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SPI_SS3 + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to VGA_B[5] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to VGA_B[4] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to VGA_B[3] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to VGA_B[2] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to VGA_B[1] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to VGA_B[0] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to VGA_G[5] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to VGA_G[4] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to VGA_G[3] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to VGA_G[2] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to VGA_G[1] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to VGA_G[0] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to VGA_HS + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to VGA_R[5] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to VGA_R[4] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to VGA_R[3] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to VGA_R[2] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to VGA_R[1] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to VGA_R[0] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to VGA_VS + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM_A[0] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM_A[1] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM_A[2] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM_A[3] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM_A[4] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM_A[5] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM_A[6] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM_A[7] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM_A[8] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM_A[9] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM_A[10] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM_A[11] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM_A[12] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM_DQ[0] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM_DQ[1] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM_DQ[2] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM_DQ[3] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM_DQ[4] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM_DQ[5] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM_DQ[6] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM_DQ[7] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM_DQ[8] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM_DQ[9] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM_DQ[10] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM_DQ[11] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM_DQ[12] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM_DQ[13] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM_DQ[14] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM_DQ[15] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM_BA[0] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM_BA[1] + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM_DQMH + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM_DQML + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM_nRAS + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM_nCAS + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM_nWE + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM_nCS + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM_CKE + set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM_CLK + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to CLOCK_27 + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SPI_DI + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SPI_SCK + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SPI_SS2 + set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SPI_SS3 + + # 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(Capitol_MiST) +# ------------------------ +set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/Arcade_MiST/Custom Hardware/Phoenix_MIST/phoenix_mist.sdc b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/Capitol_mist.sdc similarity index 100% rename from Arcade_MiST/Custom Hardware/Phoenix_MIST/phoenix_mist.sdc rename to Arcade_MiST/Phoenix Hardware/Capitol_MIST/Capitol_mist.sdc diff --git a/Arcade_MiST/Phoenix Hardware/Capitol_MIST/README.txt b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/README.txt new file mode 100644 index 00000000..d8877bea --- /dev/null +++ b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/README.txt @@ -0,0 +1,24 @@ +--------------------------------------------------------------------------------- +-- +-- Arcade: Capitol for MiST by Gehstock +-- 15 Mar 2019 +-- +--------------------------------------------------------------------------------- +-- Copyright (c) DAR - Feb 2016 +-- https://sourceforge.net/projects/darfpga/files/Software%20VHDL/phoenix/ +--------------------------------------------------------------------------------- +-- +-- Only controls and OSD are rotated on VGA output. +-- +-- +-- Keyboard inputs : +-- +-- ESC : Coin +-- F1 : Start 1 player +-- F2 : Start 2 players +-- SPACE : Fire +-- ARROW KEYS : Movement/Shield +-- +-- Joystick support. +-- +--------------------------------------------------------------------------------- diff --git a/Arcade_MiST/Phoenix Hardware/Capitol_MIST/Release/Capitol_mist.rbf b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/Release/Capitol_mist.rbf new file mode 100644 index 0000000000000000000000000000000000000000..9fa072f9ba898ae7dcbbc4d8ef5ea3f7936df17a GIT binary patch literal 274224 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

!321UOn20b* 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 literal 0 HcmV?d00001 diff --git a/Arcade_MiST/Custom Hardware/Phoenix_MIST/clean.bat b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/clean.bat similarity index 100% rename from Arcade_MiST/Custom Hardware/Phoenix_MIST/clean.bat rename to Arcade_MiST/Phoenix Hardware/Capitol_MIST/clean.bat diff --git a/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/Capitol_MiST.sv b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/Capitol_MiST.sv new file mode 100644 index 00000000..c16018b6 --- /dev/null +++ b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/Capitol_MiST.sv @@ -0,0 +1,184 @@ +//============================================================================ +// Arcade: Capitol +// +//------------------------------------------------------------------------------- +// DE2-35 Top level for Phoenix by Dar (darfpga@aol.fr) (April 2016) +// http://darfpga.blogspot.fr +// +// +//------------------------------------------------------------------------------- + +module Capitol_MiST +( + output LED, + output [5:0] VGA_R, + output [5:0] VGA_G, + output [5:0] VGA_B, + output VGA_HS, + output VGA_VS, + output AUDIO_L, + output AUDIO_R, + input SPI_SCK, + output SPI_DO, + input SPI_DI, + input SPI_SS2, + input SPI_SS3, + input CONF_DATA0, + input CLOCK_27 +); + +`include "rtl\build_id.v" + +localparam CONF_STR = { + "Capitol;;", + "O2,Rotate Controls,Off,On;", + "O34,Scanlines,Off,25%,50%,75%;", + "T6,Reset;", + "V,v1.20.",`BUILD_DATE +}; + +assign LED = 1; +assign AUDIO_R = AUDIO_L; + +wire clk_sys, clk_mist; +wire pll_locked; +pll pll( + .inclk0(CLOCK_27), + .areset(0), + .c0(clk_mist),//44 + .c1(clk_sys)//11 + ); + +wire [31: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 [10:0] ps2_key; +reg [11:0] audio; +wire hb1, hb2, vb; +wire blankn = ~(hb1 | hb2 | vb); +wire ce_pix; +wire hs, vs; +wire [1:0] r,g,b; + +phoenix phoenix( + .clk(clk_sys), + .reset(status[0] | status[6] | buttons[1]), + .ce_pix(ce_pix), + .dip_switch(8'b00001111), + .btn_coin(btn_coin), + .btn_player_start({btn_two_players,btn_one_player}), + .btn_left(m_left), + .btn_right(m_right), + .btn_barrier(m_bomb), + .btn_fire(m_fire), + .video_r(r), + .video_g(g), + .video_b(b), + .video_hs(hs), + .video_vs(vs), + .video_vblank(vb), + .video_hblank_bg(hb1), + .video_hblank_fg(hb2), + .audio_select("000"), + .audio(audio) + ); + +video_mixer video_mixer( + .clk_sys(clk_mist), + .ce_pix(ce_pix), + .ce_pix_actual(ce_pix), + .SPI_SCK(SPI_SCK), + .SPI_SS3(SPI_SS3), + .SPI_DI(SPI_DI), + .R(blankn ? {r,r,r} : "000"), + .G(blankn ? {g,g,g} : "000"), + .B(blankn ? {b,b,b} : "000"), + .HSync(hs), + .VSync(vs), + .VGA_R(VGA_R), + .VGA_G(VGA_G), + .VGA_B(VGA_B), + .VGA_VS(VGA_VS), + .VGA_HS(VGA_HS), + .rotate({1'b1,status[2]}), + .scandoublerD(scandoublerD), + .scanlines(scandoublerD ? 2'b00 : status[4:3]), + .ypbpr(ypbpr), + .ypbpr_full(1), + .line_start(0), + .mono(0) + ); + +mist_io #( + .STRLEN(($size(CONF_STR)>>3))) +mist_io( + .clk_sys (clk_mist ), + .conf_str (CONF_STR ), + .SPI_SCK (SPI_SCK ), + .CONF_DATA0 (CONF_DATA0 ), + .SPI_SS2 (SPI_SS2 ), + .SPI_DO (SPI_DO ), + .SPI_DI (SPI_DI ), + .buttons (buttons ), + .switches (switches ), + .scandoublerD (scandoublerD ), + .ypbpr (ypbpr ), + .ps2_key (ps2_key ), + .joystick_0 (joystick_0 ), + .joystick_1 (joystick_1 ), + .status (status ) + ); + +dac #( + .C_bits(15)) +dac( + .clk_i(clk_mist), + .res_n_i(1), + .dac_i({audio, 4'b0000}), + .dac_o(AUDIO_L) + ); +// Rotated Normal +//wire m_up = ~status[2] ? btn_left | joystick_0[1] | joystick_1[1] : btn_up | joystick_0[3] | joystick_1[3]; +//wire m_down = ~status[2] ? btn_right | joystick_0[0] | joystick_1[0] : btn_down | joystick_0[2] | joystick_1[2]; +wire m_left = ~status[2] ? btn_down | joystick_0[2] | joystick_1[2] : btn_left | joystick_0[1] | joystick_1[1]; +wire m_right = ~status[2] ? btn_up | joystick_0[3] | joystick_1[3] : btn_right | joystick_0[0] | joystick_1[0]; +wire m_fire = btn_fire1 | joystick_0[4] | joystick_1[4]; +wire m_bomb = btn_fire2 | joystick_0[5] | joystick_1[5]; + +reg btn_one_player = 0; +reg btn_two_players = 0; +reg btn_left = 0; +reg btn_right = 0; +reg btn_down = 0; +reg btn_up = 0; +reg btn_fire1 = 0; +reg btn_fire2 = 0; +reg btn_fire3 = 0; +reg btn_coin = 0; +wire pressed = ps2_key[9]; +wire [7:0] code = ps2_key[7:0]; + +always @(posedge clk_mist) begin + reg old_state; + old_state <= ps2_key[10]; + if(old_state != ps2_key[10]) begin + case(code) + 'h75: btn_up <= pressed; // up + 'h72: btn_down <= pressed; // down + 'h6B: btn_left <= pressed; // left + 'h74: btn_right <= pressed; // right + 'h76: btn_coin <= pressed; // ESC + 'h05: btn_one_player <= pressed; // F1 + 'h06: btn_two_players <= pressed; // F2 + 'h14: btn_fire3 <= pressed; // ctrl + 'h11: btn_fire2 <= pressed; // alt + 'h29: btn_fire1 <= pressed; // Space + endcase + end +end + +endmodule \ No newline at end of file diff --git a/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/ROM/23.hex b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/ROM/23.hex new file mode 100644 index 00000000..340729c2 --- /dev/null +++ b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/ROM/23.hex @@ -0,0 +1,129 @@ +:1000000000000000000000000000000000000000F0 +:1000100000000000000000001010907000000000C0 +:10002000000000000F080804FFFFFF7E3F1C88E46B +:10003000E0F8FCFEFEFFFFFF0201000000000000F0 +:1000400000000000000000000000000000000000B0 +:1000500000000000000000000000000000000000A0 +:100060000000000000000000000000000000000090 +:100070000000000000000000000000000000000080 +:100080000000000000000000000000000000000070 +:100090000000000000000000000000000000000060 +:1000A0000000000000000000E3F1F87C7E3F1F0725 +:1000B000171FFF7F3F9F8FC7000000000080402078 +:1000C0000000000000000000000000000000000030 +:1000D0000000000000000000000000000000000020 +:1000E0000000000000000000000000000000000010 +:1000F0000000000000000000000000000000000000 +:10010000010204081020408040201008040201026F +:100110000408102040804020100804020102040856 +:100120001020408040201008040201020408102022 +:100130004080402010080402010204081020408082 +:1001400000183C7E3C180000000020707020000069 +:1001500010387CFE7C38100020A438FE38A4200023 +:1001600044AAAA0101AAAA4444AA82010182AA447B +:1001700044828201018282444080800000808000AD +:100180003C6EEFEFEFEF6E3C3C66E7E7E7E7663C7F +:100190003C66C3C3C3C3663CE8D0F05E7030301029 +:1001A000E8C8E4C3E3C4E8C8103030707ED0F0C8BB +:1001B0007306040C1E307CC01818700000701818EC +:1001C000C07C301E0C040673E0E0E0E0C0C0C0C09C +:1001D000C5ABAD9D9CB4B4F0F0B4B49C9DADABC5C3 +:1001E000C0C0C0C0E0E0E0E0808448301F304884F8 +:1001F00018242424242424180000000000000000F7 +:1002000090F0F83F0000000000023CCC1424488825 +:10021000FFFFC180800000000808080C8F8EC6FF19 +:100220000808D0E0781E0000C08080E01B0C34C4B9 +:10023000FFFFC38180000000000101038383C7FF2B +:10024000FF081020C0C06030003060C0C0A010089F +:10025000FFFFC78381000000000000008183C7FF0B +:10026000E0E0E0E0C0800000000080C0E0E0F8F8DE +:10027000F9FFFF1919FFFF0000FFFFF9F9FFFFF970 +:10028000C020F8FFF820C000302E3028302E302853 +:100290001038EC4EEC38100000E0F0A00000000038 +:1002A000A000400000000000F8F4E0400000000062 +:1002B00000006080100000000C0E5FFBB9C8E46015 +:1002C000000C0E2F7F7EF2FFD0A00800000000007F +:1002D000FBF0D04020000000307868C040000000F3 +:1002E0001E007FFF00F26AB0001C007F7F00FAF062 +:1002F000000000002A0000000000002A2A00000080 +:1003000000000000E800000000000008DC08000019 +:100310000000001CDC1C000000000000FF000000CA +:1003200057075707570756FC55005500550055FF0E +:100330000103FFFF570757070000FFFF5500550057 +:100340000000FC00FFFC000000FF00FF00FFFF00BA +:100350000000FF00AA00000000FF002A0054000077 +:10036000FF00FFFF00FF00FF0000002A0000000068 +:1003700000FF00FF00FF000004040606070700005E +:10038000FFFCE0C0800000000000000080C0E0FC36 +:10039000FF6FC7070F1F3E0000003E1F0F07C76F0C +:1003A000E00000000000000000000000000000006D +:1003B0007900F000000000F800F800000000F000F4 +:1003C000008080C0E0C08080008080C4EEC4808057 +:1003D000008080CEEECE808000808EDFFFDF8E80BA +:1003E000FE888890E080800000008080E09088880F +:1003F0003F08080403000000000000000304080890 +:1004000001020408102040800102040810204080EE +:10041000030C30C00000000000000000030C30C0DE +:100420000FF000000000000000000FF000000000CE +:10043000000000000FF000000000000000000FF0BE +:1004400080402010080402018040201008040201AE +:1004500000000000C0300C03C0300C03000000009E +:10046000000000000000F00F00000000F00F00008E +:100470000000F00F00000000F00F0000000000007E +:1004800080C0E0C080808000E0C0808080000000EC +:1004900000000000808080C00000808080C0E0C03C +:1004A000808080C0E0C08080A0F060C0808080003C +:1004B0000000808080C060F060C08080800000000C +:1004C000808080C060F0A0F080C060F0A0F060C0CC +:1004D00060F0A0F060C0808000000000808080C0DC +:1004E000E07078EEB8EE787078EEB8EE7870E0C034 +:1004F00080808080C0C0E070B8EE7870E0C0C080BE +:100500008080C0C0E07078EE7870E0C0C0808080ED +:10051000C0C0E07078EEB8EE705EE0E0C0C08080F1 +:10052000008080C0C0E0F05E030703010301030305 +:1005300003030301030103077F707FD0F8E0C0804D +:1005400000000080C0E0F8D01E0F1E0C07030F074C +:100550000E070F070F03070C180C180C07030F07E3 +:10056000F0FFD0F8E0C080800000000080F0A0FE26 +:100570003C1E3C1D0F070F03183C1C3E1F3F0F196C +:10058000F0FEA0F080000000808080C0E0F8D0FF86 +:100590003C190F3F1F3E1C3C07030F070F1D3C1E5D +:1005A000D0F8E0C080808080000080F0A0FEF0FFE6 +:1005B0003C1D0F070F0307031C3E1F3F0F193C1E76 +:1005C000A0F080000000000080C0E0F8D0FFF0FE46 +:1005D0000F3F1F3E1C3C18380F070F1D3C1E3C19D7 +:1005E00080F0A0FEF0FFD0F80F070F03070307030A +:1005F0001F3F0F193C1E3C1DE0F8D0FFF0FEA0F09D +:100600001F3E1C3C183830700F1D3C1E3C190F3F1C +:10061000A0FEF0FFD0F8E0C000000000000080F075 +:100620000F193C1E3C1D0F073038183C1C3E1F3F65 +:10063000D0FFF0FEA0F080008080808080C0E0F8D5 +:100640003C1E3C190F3F1F3E070307030F070F1DFA +:1006500030B0E0E0C0E0F8D090A0F0E0E0E0F8D00A +:10066000A4ECC890AC089850C48CA8143C645C9866 +:10067000000000000000000000000000000000007A +:10068000000206060A0A1234080A0F0F0E0E0E06A2 +:1006900003070D2A3A3A76D608090E0F0F0E0C06FC +:1006A000486C3C1C1E0E060200808060309890D87A +:1006B0008EC64456722A0B060080E0A0B81C1C08A7 +:1006C0000A010C040E0E0D0C0E070900080C0D0F8C +:1006D00003030302020202020202020202020303F5 +:1006E0000C080808080808080F070E060E0C0C0C6A +:1006F00008080C0C0C0C0E0680C0C0C06060607056 +:1007000003030301010101010703070303030303BB +:10071000C0C0606060703038C0C080808000000061 +:1007200018383070606060C00303030303030703DD +:1007300000010101010103030301010101010000A6 +:10074000606060703038183C3070606060C0C0C05D +:100750000303030307030703010101010303030369 +:10076000030303030301010160703038183C1C3E91 +:10077000808080C0C0C06060606060C0C0C0808099 +:100780000303070307030F07010103030303030325 +:1007900003030301010101010F030703070303031F +:1007A00000000008080808081C3C18383070606019 +:1007B0000000000101010101000000000000000034 +:1007C0008000000000000000808080000000000029 +:1007D0008080808080000000E0C0C0808080800039 +:1007E0000000000000008080000000008080808009 +:1007F000000080808080C0C0030303030303030361 +:00000001FF diff --git a/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/ROM/24.hex b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/ROM/24.hex new file mode 100644 index 00000000..8e51d82a --- /dev/null +++ b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/ROM/24.hex @@ -0,0 +1,129 @@ +:1000000000000000000000000000000000000000F0 +:100010000000000000000000181C9CFEFE7E1E0078 +:1000200000787E7F7F38381C201088C1E170381C32 +:1000300000002090482490480E07030100000000B3 +:1000400000000000000000000000000000000000B0 +:1000500000000000000000000000000000000000A0 +:100060000000000000000000000000000000000090 +:100070000000000000000000000000000000000080 +:100080000000000000000000000000000000000070 +:100090000000000000000000000000000000000060 +:1000A00000000000000000000E0713090402000019 +:1000B000100080C4E271381C0000000080C0603075 +:1000C0000000000000000000000000000000000030 +:1000D0000000000000000000000000000000000020 +:1000E0000000000000000000000000000000000010 +:1000F0000000000000000000000000000000000000 +:1001000000000000000000000000000000000000EF +:1001100000000000000000000000000000000000DF +:1001200000000000000000000000000000000000CF +:1001300000000000000000000000000000000000BF +:1001400000000000000000000000000000000000AF +:10015000000000000000000000000000000000009F +:10016000000000000000000000000000000000008F +:10017000000000000000000000000000000000007F +:10018000000000000000000000000000000000006F +:10019000000000000000000000000000000000005F +:1001A000000000000000000000000000000000004F +:1001B000000000000000000000000000000000003F +:1001C000000000000000000000000000000000002F +:1001D000000000000000000000000000000000001F +:1001E000000000000000000000000000000000000F +:1001F00000000000000000000000000000000000FF +:1002000000000000000000000000000000000000EE +:1002100007030100000000000C0E0F0F0C0F070772 +:10022000F0F4ECFE7E1E0000C0C0E000E0F0C83834 +:100230000707030100000000000101030303070793 +:1002400000F0E8D8B0F07030003070F0B8D8E8F0C6 +:100250000707070301000000000000000103070773 +:10026000E0E0E0E0C0800000000080C0E0E0E0E00E +:10027000000000000000000000000000000000007E +:10028000C00000F00000C0000000101810000000C6 +:10029000E07800F80078E0000E5E0C58F8F0B080CE +:1002A000FEF8FCFE7E3C30006FDFFEFEEECC000070 +:1002B000377F9E78FCFCB8900000000426379FFF33 +:1002C0000000000204290D12EF7EFEFC7C300000CD +:1002D0002E7FEFFEFA7830000207173EB8FCEC40A4 +:1002E0000018000C2A9D95EF0000140028050F3F10 +:1002F000000000FFFFFF000000FFFFFFFFFFFF0007 +:1003000000000000000000000000000000000000ED +:1003100000000000000000000000000000000000DD +:1003200000000000000000000000000000000000CD +:1003300000000000000000000000000000000000BD +:10034000000000505003FC0000000054540000FF67 +:10035000000000FFFFFFFF000000FFFFFFFFFFFFA7 +:100360000000545400545400FF00FFFFFF00000041 +:10037000FF0000002A0000FF040406060707FF0034 +:10038000F000003000C00000000000C0003000009D +:10039000000000010000003F003F000000010000DD +:1003A0001FF0C00000000000000000000000C0F0CE +:1003B0007E3FFF7F7C706000000060707C7FFF3FAD +:1003C00000000E1F1F1F0E0000000E1F1F1F0E003B +:1003D00000000E1F1F1F0E0000000E1F1F1F0E002B +:1003E000F78181820284A8E000E098840282818102 +:1003F0007740402020100C0300030C1020204040C8 +:10040000000000000000000080808080808080006C +:10041000000000000000000080808080808080005C +:10042000000000000000000080808000808080804C +:10043000000000000000000080808080808080003C +:10044000000000000000000000808080808080802C +:10045000000000000000000000808080808080801C +:10046000000000000000000080808080008080800C +:1004700000000000000000000080808080808080FC +:10048000000000200000000020000000000000002C +:10049000000000000000000000000000000020003C +:1004A00000000000200000000040100000000000DC +:1004B00000000000000080100000000000000000AC +:1004C000000000000010401000000010401000006C +:1004D00000104010000000000000000000000000BC +:1004E0000000001640160000001640160000000034 +:1004F00000000000000000004016000000000000A6 +:100500000000000080000096000080000000000055 +:10051000000080000096409680AE000000000000C1 +:1005200000000000000000AE000400000200020015 +:1005300000000200020000048F808F2018000000DD +:1005400000000000000018201900190300000C0032 +:100550000C000C000C0000031703170300000C0034 +:10056000000F201800000000000000000030401EB6 +:100570003301330200000C00003000300030000670 +:10058000001E403000000000000000000018200F96 +:10059000330600300030003006000C00000233014A +:1005A000201800000000000000000030401E000F76 +:1005B000330200000C00060000300030000633015A +:1005C000403000000000000000000018200F001E56 +:1005D00000300030003000000C0000023301330610 +:1005E0000030401E000F201800000C00060006001E +:1005F00000300006330133020018200F001E403087 +:1006000000300030000000000002330133060030EB +:10061000401E000F20180000000000000000003005 +:1006200000063301330200000000003000300030CB +:10063000200F001E403000000000000000000018E5 +:100640003301330600300030060006000C000002C3 +:10065000F0F0E0E000001820F0E0F060600018200A +:10066000BCFCF8F2ECF8F8F0FCFCFCF4FCFCFCF848 +:10067000000000000000000000000000000000007A +:10068000000216060E0E1E3C0002030303030101C6 +:1006900003074F2E3E3E7EFE0001030303030301CA +:1006A000787C3C1C1E0E2602008080E0F0F8F4F8F6 +:1006B000FEFE737E7EAF0F060080E4E0F8FCFCF8DF +:1006C00002070707030301000203070707070703E1 +:1006D000000000000000000000000000000000001A +:1006E00000000000000000000C000C0000000000F2 +:1006F00000000000000000000000000000000000FA +:1007000000000000000000000600060000000000DD +:1007100000000000000000000000000000000000D9 +:1007200000000000000000000000000000000600C3 +:1007300000000000000000000000000000000000B9 +:1007400000000000000000000000000000000000A9 +:10075000000000000600060000000000000000008D +:100760000000000000000000000000000030003029 +:100770000000000000000000000000000000000079 +:100780000000060006000C00000000000000000051 +:1007900000000000000000000C0006000600000041 +:1007A0000000000000000000003000000000000019 +:1007B0000000000000000000000000000000000039 +:1007C0000000000000000000000000000000000029 +:1007D0000000000000000000000000000000000019 +:1007E0000000000000000000000000000000000009 +:1007F00000000000000000000000000000000000F9 +:00000001FF diff --git a/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/ROM/39.hex b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/ROM/39.hex new file mode 100644 index 00000000..e23a3a26 --- /dev/null +++ b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/ROM/39.hex @@ -0,0 +1,129 @@ +:100000000000000000000000007C1212127E7C0044 +:1000100000344A4A4A7E7E0000244242427E3C002E +:10002000003C4242427E7E0000424A4A4A7E7E00B6 +:1000300000020A0A0A7E7E0000345252427E3C00D0 +:10004000007E0808087E7E000042427E7E4242001A +:10005000007E7E7E4040300000422418087E7E00F4 +:1000600000404040407E7E00007E027C027E7E009A +:10007000007E2018047E7E00003C4242427E3C000E +:10008000000C1212127E7E0000403C62427E3C0058 +:1000900000442A1A0A7E7E000034724A4A4E2C001E +:1000A0000002027E7E020200003E4040407E7E0052 +:1000B000001E2040203E1E00003E4038407E3E0094 +:1000C0000042261C3874620000060870080E060004 +:1000D0000042464E5A7262000000001818000000EC +:1000E0000000182424180000000042663C1800009C +:1000F000000000183C664200000024187E1824000E +:1001000000003C464A523C00000040407E42440011 +:100110000000644A526244000000344A4A4A4200E5 +:100120000000087E08080E000000304A4A4A4E00CF +:100130000000304A4A4A3C000000061A32620600BB +:100140000000344A4A4A340000003C5252520C002B +:10015000000060F8FFF860000000080808080800C8 +:10016000000000000000000000183C66663C18001B +:10017000003C425A5A423C0000000609510102006C +:10018000FCE070381C3E0000003E1C3870E0FC9F14 +:10019000E070387C00000000007C3870E0FC9FFCC0 +:1001A00070F800000000000000F870E0FC9FFCE028 +:1001B000F800000000000000F870E0FC9FFCE07018 +:1001C00070E0FC9FFCE070F800000000000000F808 +:1001D000E0FC9FFCE070F800000000000000F870F8 +:1001E000FC9FFCE070387C00000000007C3870E070 +:1001F0009FFCE070381C3E0000003E1C3870E0FCA4 +:100200007FC70E1C3870FC00FC70381C0EC77FE3E3 +:10021000CE1C3870FC000000FC70381CCE7FE37FE1 +:100220003C78FC0000000000FC783CDE7FE37FDED1 +:10023000FC00000000000000FC78FC7FE37FFC78FD +:1002400078FC7FE37FFC78FC00000000000000FCED +:10025000DE7FE37FDE3C78FC0000000000FC783CA1 +:100260007FE37FCE1C3870FC000000FC70381CCE91 +:10027000E37FC70E1C3870FC00FC70381C0EC77F73 +:10028000000000000000003F0000000000003F00F0 +:1002900000000000003F0000000000003F000000E0 +:1002A0000000003F0000000000003F0000000000D0 +:1002B000003F0000000000003F00000000000000C0 +:1002C0000000000000000E0000000000030E03000C +:1002D0000000000E00000000030E030000000000FC +:1002E000000000000000E0000000000030E03000EE +:1002F000000000E00000000030E0300000000000DE +:100300000303FFFF03030E0C0000000000000C0EAF +:10031000FFFF0303070C0000000000000C0E0303A6 +:1003200003030E0C0000000000000C0E0303FFFF8F +:100330000E0C0000000000000C0E0303FFFF03037F +:100340000C0CFCFC0C0C38300000000000003038B5 +:10035000FCFC0C0C383000000000000030380C0CA5 +:100360000C0C383000000000000030380C0CFCFC95 +:10037000383000000000000030380C0CFCFC0C0C85 +:10038000060F1F1F0F060000000000000000001CE9 +:100390001F1F0F0600000000000000000000060FF5 +:1003A0000F0600000000000000000000060F1F1FE5 +:1003B00007050202020700000000060F1F1F0F06BC +:1003C00000183F3F18000000000003030000030373 +:1003D0003F3F18000000000000000000000000186F +:1003E00018000000000000000000000000183F3F5F +:1003F000000000000000C0C0000000183F3F1800CF +:100400003030F0F03030E0C0000000000000C0E00C +:10041000F0F03030E0C0000000000000C0E03030FC +:100420003030E0C0000000000000C0E03030F0F0EC +:10043000E0C0000000000000C0E03030F0F03030DC +:10044000C0C0C0C0C0C0800000000000000000802C +:10045000C0C0C0C080000000000000000080C0C01C +:10046000C0C080000000000000000080C0C0C0C00C +:1004700080000000000000000080C0C0C0C0C0C0FC +:1004800000007F7F000000000000000000007B876C +:100490007F7F0000000000000E090101090E00002E +:1004A0002222030322221C000000000000007F7FA4 +:1004B00004080F0F0884877B000000007F7F000086 +:1004C0000000FFFF00000303000000000000030322 +:1004D000FFFF000003030000000000000303000012 +:1004E0000000030300000000000003030000FFFF02 +:1004F000030300000000000003030000FFFF0000F2 +:10050000787C7C7C7C7830000000000000000030AB +:100510007C7C7C7830000000000000000030787C9B +:100520007C7830000000000000000030787C7C7C8B +:1005300030000000000000000030787C7C7C7C787B +:10054000E0F0F0F0F0E0C00000000000000000C0AB +:10055000C0C0C0800000000000000000000080C09B +:10056000F0C0C00000000000000000C0E030F0F06B +:100570000000000000000000000080C0C0C0C0807B +:100580001E1F1F1F1F1E0C00000000000000000C9B +:10059000C0800000000000000000000080C0C0C05B +:1005A000070703000000000000000003070707071B +:1005B00000000804081408000000082610260C009B +:1005C000010101010101000000002C004D20140078 +:1005D00007070707030000000000000000030707EB +:1005E0000101000000000000000000000101010105 +:1005F00003000000000000000003070707070707CB +:100600000F0F0F0F0F0F0E0C0000000000000C0E5C +:100610000F0F0F0F0E0C0000000000000C0E0F0F4C +:100620001F1F1E0C0000000000000C1E1F1F1F1FBC +:100630000E0C0000000000000C0E0F0F0F0F0F0F2C +:1006400000000000000000000000000000000000AA +:10065000000000000000000000000000000000009A +:10066000000000000000000000000000000000008A +:10067000001420052A00320C0000000000000000D9 +:100680008CC2C0F03A380C460C80FCFFF082F03887 +:10069000051C78F2F0C498723F3D2D662643122067 +:1006A0003B3B75EEF53B7B9F20092C8444ED6D7F31 +:1006B000E2800C1E1E8C0000F878B060F3DBD830AE +:1006C0000C1E0C80C0C064B27727032000081C08F1 +:1006D000EFF977377CDFEB7D204104317B71336F9D +:1006E00000000400240E04000006160002000000B2 +:1006F00000004000006800000060F460002000007E +:10070000B8FC4CF8F0C8C080FC3ED6DBFBF7FEDC42 +:10071000C0E8E070F8F42CF89FBF77F7E6FCF0E251 +:10072000C0E2B89EE797D7DFE3F37E1E0C003030BF +:1007300000C2C0183C3E62C3EBFF5FDDC3B2BE1C0B +:100740001CBDE7E3D9FDFFCF30FCBE3E6EDC70E0A0 +:100750007E77B7B777EFBEBCB0E83C9EEEECE8FC26 +:100760007CCFF7FE6E0F0F061F7DFBB7F3D96F3FEF +:100770000F071C7D6B3F7F3F0000000210002E0F13 +:100780006F371F140F2F0703377EDFDBDB693C6FEA +:1007900003032B1E1E253F3BF3F3F9DF6F279F0F4B +:1007A0000F1F3F67EDD9DBFB036EF3E7F1FE1F037D +:1007B000B1590C240200000077CFBB80EF77FA3EDE +:1007C000010002047D59B7FECBF7FFFF6C9FF37C5D +:1007D0006E7F07FBFDBD9FDFFFFFFE63CB9DFFF339 +:1007E0003CFECFBDBDF37E18193C7E5E667E9C004C +:1007F0000600787C653C00020001183C3C18024071 +:00000001FF diff --git a/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/ROM/40.hex b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/ROM/40.hex new file mode 100644 index 00000000..170d4cf6 --- /dev/null +++ b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/ROM/40.hex @@ -0,0 +1,129 @@ +:1000000000000000000000000000000000000000F0 +:1000100000000000000000000000000000000000E0 +:1000200000000000000000000000000000000000D0 +:1000300000000000000000000000000000000000C0 +:1000400000000000000000000000000000000000B0 +:1000500000000000000000000000000000000000A0 +:100060000000000000000000000000000000000090 +:100070000000000000000000000000000000000080 +:100080000000000000000000000000000000000070 +:100090000000000000000000000000000000000060 +:1000A0000000000000000000000000000000000050 +:1000B0000000000000000000000000000000000040 +:1000C0000000000000000000000000000000000030 +:1000D0000000000000000000000000000000000020 +:1000E00000000018180000000000000000000000E0 +:1000F0000000000000000000000024187E1824000A +:1001000000000000000000000000000000000000EF +:1001100000000000000000000000000000000000DF +:1001200000000000000000000000000000000000CF +:1001300000000000000000000000000000000000BF +:1001400000000000000000000000000000000000AF +:1001500000F000001F0000F00000000000000000A0 +:10016000000000000000000000000018180000005F +:1001700000003C3C3C3C000000000000000000008F +:10018000000000000000000000000000000000FF70 +:10019000000026052AA45000000000000000FF0017 +:1001A0000040B419855200000000000000FF00006C +:1001B0008D1700440800000000000000FF00000050 +:1001C000000000FF000000000000100804400B06C3 +:1001D0000000FF000000000057A24C0410000000C7 +:1001E00000FF000000000000000010040C0252BDDF +:1001F000FF00000000000000000000000000000000 +:100200000000000000FF000000FF0000000000C32D +:10021000000000FF0000000000FF00000000C3001D +:100220000000FF0000000000FF00000000C300000D +:10023000FF00000000000000FF000000C3000000FD +:10024000000000C3000000FF00000000000000FFED +:100250000000C300000000FF0000000000FF0000DD +:1002600000C300000000FF0000000000FF000000CD +:10027000C30000000000FF000000FF0000000000BD +:1002800000000000000000FF000000000000FF0070 +:100290000000000000FF000000000000FF00000060 +:1002A000000000FF000000000000FF000000000050 +:1002B00000FF000000000000FF0000000000000040 +:1002C0000000000000030E0300000000000E00000C +:1002D0000000030E03000000000E000000000000FC +:1002E000000000000030E0300000000000E00000EE +:1002F000000030E03000000000E0000000000000DE +:100300000C0C80800C0C00000000000000000000BD +:1003100080800C0C000000000000000000000C0CAD +:100320000C0C000000000000000000000C0C80809D +:10033000000000000000000000000C0C80800C0C8D +:1003400030300000303000000000000000000000ED +:1003500000003030000000000000000000003030DD +:1003600030300000000000000000000030300000CD +:1003700000000000000000000000303000003030BD +:10038000060F1F1F0F060000000000000000001CE9 +:100390001F1F0F0600000000000000000000060FF5 +:1003A0000F0600000000000000000000060F1F1FE5 +:1003B00007050202050700000000060F1F1F0F06B9 +:1003C00000183C3C18000000030300000303000079 +:1003D0003C3C180000000000000000000000001875 +:1003E00018000000000000000000000000183C3C65 +:1003F000000000000000C0C0000000183C3C1800D5 +:10040000C0C00000C0C000000000000000000000EC +:100410000000C0C000000000000000000000C0C0DC +:10042000C0C000000000000000000000C0C00000CC +:1004300000000000000000000000C0C00000C0C0BC +:1004400000000000000000000000000000000000AC +:10045000000000000000000000000000000000009C +:10046000000000000000000000000000000000008C +:10047000000000000000000000000000000000007C +:1004800000006060000000000000000000007884B0 +:1004900060600000000000000E090101090E00006C +:1004A0002222020222221C000000000000006060E4 +:1004B000070B08080B8784780000000060600000CC +:1004C0000303000003030000000000000000000020 +:1004D0000000030300000000000000000000030310 +:1004E0000303000000000000000000000303000000 +:1004F00000000000000000000000030300000303F0 +:10050000003000003000000000000000000000008B +:100510008282B2844830000000000000304884B27B +:10052000B386CC7830000000003078CC86B383836B +:1005300048300000000000003048848282828284BB +:1005400000C00000C000000000000000000000002B +:10055000202020408000000000000000008040209B +:10056000CC1830E0C000000000C0E03018CC0C0C0B +:10057000800000000000000000804020202020407B +:10058000000C00000C000000000000000000000053 +:100590003060C08000000000000080C0603030305B +:1005A0000B080C07030000000003070C080B0808E9 +:1005B000000008102214000000001C222A0214006F +:1005C000000000000000000000100812692A040862 +:1005D00008080B0804030000000000000304080BD7 +:1005E00006060301000000000000010306060606DF +:1005F00004030000000000000304080B08080B08B7 +:100600008C6C10106C8C00000000000000000000DA +:1006100010102C4C800000000000000000008C6CCA +:100620004C8C000000000000000000008C4C2020DA +:10063000000000000000000000804C2C10106C8CAA +:10064000E300000000E31C00000000000000001CAC +:10065000E000101008070000000000000000031C6C +:10066000CC030000000000000000000003CC30308C +:1006700000100A55025522080708101000E01C035C +:100680000080402010084400040080EA8001A0108F +:1006900044001062C080082012092004804200201B +:1006A00097150A511B240E0B248028800404012A6C +:1006B0000010004C0C00002080C042802162E0C08D +:1006C000004C0100080084C0000000200240080027 +:1006D000060E1898032014020840040000091C307C +:1006E00000000400040E14000010000200000000CE +:1006F0000000401000686000040000088000000056 +:10070000481830000010400000C0E82C0C18000011 +:10071000002080C000DAD08020C088183830000067 +:1007200000004070186828200000000000003030F1 +:1007300000C040000000001814A0B03A3C1C0000AB +:100740000000183C36620000206060E0D02080008D +:10075000808C4C4C8C1840400080E06030301000A1 +:10076000333C0C01010020800002064C0E271000D3 +:10077000400083031624000000686002100000009F +:100780001C1E00030000100008002426261703008A +:1007900000020001011A10040C0E272030188040BE +:1007A000004000181A262C0C011E3F3E1F0F0201AC +:1007B00020100824004100000E39FCFF3B2898223D +:1007C00001000200084031CE763C080093600C0323 +:1007D000110038040240E0600018219C3462000CD3 +:1007E000000030464E1C0000000000301C0081005C +:1007F000200000301900400000010098180000009F +:00000001FF diff --git a/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/ROM/ic40.hex b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/ROM/ic40.hex new file mode 100644 index 00000000..041fbcb4 --- /dev/null +++ b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/ROM/ic40.hex @@ -0,0 +1,17 @@ +:1000000000000000000000000202040205020202DB +:1000100000010200020101010001010106040404C3 +:1000200000000000000000000401010303030100C0 +:10003000020505010101070006070705050503077D +:1000400000000000000000000202040201010101A2 +:100050000001020002020202000101010404040482 +:100060000000000000000000040101040404030477 +:100070000205050505050700050707030303050736 +:100080000000000000000000000000000000000070 +:100090000000000000000000000000000000000060 +:1000A0000000000000000000000000000000000050 +:1000B0000000000000000000000000000000000040 +:1000C0000000000000000000000000000000000030 +:1000D0000000000000000000000000000000000020 +:1000E0000000000000000000000000000000000010 +:1000F0000000000000000000000000000000000000 +:00000001FF diff --git a/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/ROM/ic41.hex b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/ROM/ic41.hex new file mode 100644 index 00000000..93f5edc8 --- /dev/null +++ b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/ROM/ic41.hex @@ -0,0 +1,17 @@ +:1000000000000000000000000206050305060606C9 +:10001000010303060203030307050503070505059E +:1000200000000000000000000601010303030104BA +:100030000605050707070703060707050505030764 +:100040000000000000000000020205030303030398 +:100050000103030606060606050505030505050555 +:100060000000000000000000060101040404030475 +:100070000605050505050703050707070707050723 +:100080000000000000000000000000000000000070 +:100090000000000000000000000000000000000060 +:1000A0000000000000000000000000000000000050 +:1000B0000000000000000000000000000000000040 +:1000C0000000000000000000000000000000000030 +:1000D0000000000000000000000000000000000020 +:1000E0000000000000000000000000000000000010 +:1000F0000000000000000000000000000000000000 +:00000001FF diff --git a/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/ROM/prog.hex b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/ROM/prog.hex new file mode 100644 index 00000000..45d919cd --- /dev/null +++ b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/ROM/prog.hex @@ -0,0 +1,1025 @@ +:100000000600210000C3100831FF4B26503600CDFA +:1000100050002100180E03CDD001CD80003AA2433C +:10002000A7CA2D00CD0004CD0027C31A003A0078DE +:10003000E640CAE003CD402700CD6017A7CA4600BE +:10004000CD8802C31A00CDE300C31A00BFE60087C3 +:10005000266836002660360026583600CD6B00260E +:10006000503601CD6B0026503600C921F84B3E3F7B +:1000700036002BBCC27000C9CD0008C3BC06FFFF10 +:1000800026787EE680CA80007EE680C288002670E0 +:100090007E21A04346772C702E9BCD00022E8F7EB2 +:1000A000FE09C8D200000601CDBB00C82E8F347EE9 +:1000B000C620324241C900C900C9FF21A0437E2F9A +:1000C000A02CA6C97EE60FF62012CD100205C87E30 +:1000D0000F0F0F0FE60FF62012CD10022B05C2C432 +:1000E00000C9FF219943CD0002010100CD5802CA89 +:1000F000E101010200111F01CD6002D29601012031 +:1001000001CD5802CA88060EB0CD5802CAE1010ED0 +:10011000C011E001CD6002D20C1B01000211C0032E +:10012000CD6002D2D01A01000411AF04CD6002D21A +:10013000C00301E60411FFFFCD6002D2B003C9FF86 +:10014000CDA003CD8000CD800321A34336022C3601 +:10015000000000002EB80608CDD8052EBA36102EA5 +:10016000BE3A0078E60C0707C6307726583600CD31 +:100170008000C97EE67F06CEFE1FD806FEC806AE0A +:10018000FE5FD806FEC806CEFE7FD806FE2D7EFE98 +:1001900009C0067EC9FF7EE61FFE06D85F7EE6E048 +:1001A0004F2D462EA8702C71016018CD06027E2DB1 +:1001B000666F7B562C5E2D4F856F79D6064FCAC869 +:1001C00001CD17020DC2C1017E12C34017C2C0018A +:1001D000562C5E7DC6056F061ACDED010DC2D0010D +:1001E000C9CD40012160190E03C3D001FF7E122347 +:1001F000CD170205C2ED01C9FFFFFFFFFFFFFFFFA3 +:1002000034C02D342CC97E81772D7E88772CC9FF90 +:100210007BC6205FD014C97BD6205FD015C9FFFFF5 +:10022000AF7E8127772D7E8827772D7ECE0027779A +:100230002C2CC9FFFFFF373E99CE00918627772DE2 +:100240003E99CE00908627772D3E99CE008627775F +:100250002C2CC9FFFFFFFFFF7EB9C02D7E2CB8C933 +:10026000CD7002D8CD7702C9FFFFFFFFFFFFFFFF70 +:100270007E912D7E982CC97B962D7A9E2CC9FFFFEE +:100280007DB9C07CB8C9FFFFCD400121C0190E0265 +:10029000CDD0010E02CD6017FE02DAA70221A01B0D +:1002A0000E01CDD0010E063A00702FA1C8CDCB02B1 +:1002B000CDF002CD2E03CD5003CD400126503601A6 +:1002C000CD400126503600C9FFFFFF0E01FE02CAD5 +:1002D000D4020E0221A243713A0078E610CAE3026A +:1002E00079074F2E8F7E9177C620324241C9FFFF9A +:1002F000118343218B43CD1403D420031E872EFF8B +:10030000CD1403D420032E8B1141410606CDC40029 +:10031000C9FFFFFF1A961D2D1A9E1D2D1A9EC9FF9B +:100320001A7713231A7713231A77C9FFFFFF218047 +:10033000433600237DFE88C231032E8311614206BD +:1003400006CDC4002E871121400606CDC400C9FF8A +:100350003A0078E603C60347219043702EA27EFE42 +:1003600001CA67032E91702E907EF62032A2422C95 +:100370007EF620326240C9218C43772C77C9FFFF7B +:10038000213F43111F00013F03722B722B7DA3B845 +:10039000C28903722B2B2B2B7CB9C28903C9FFFFA7 +:1003A000213F4B114700722B722B7CBBC2A603C9A5 +:1003B000CD730121A0437EE601B077C30004FFFFA7 +:1003C0007E0FE61CFE10DACC032FE60CF6206F261B +:1003D00014115242E5CDDC07E1113241C3DC07FFC5 +:1003E0003E0F218C43773200603E8F2C77320068BD +:1003F0003E7F30C338002EBA722C73C3800380FF57 +:10040000210E043AA44307856F7E2C6E67E9043001 +:1004100004AC051000780AEA0B60240005D0FFFF49 +:100420000404000006020400060602020204060498 +:1004300021A44336012C36802EA37E3600FE02C84E +:10044000772D7EFE01C82C7EA7CAA0042E907EA721 +:10045000C82EA33600010001CD6004C9FFFFFFFFD5 +:10046000210050112043701A71121C7BE603C266F2 +:10047000047BE6F0D6205FD26604157AFE3FC266A2 +:1004800004118043701A71121C7BFEB8C2840411DF +:10049000C04B701A71121C7BFE00C29204C9FFFF90 +:1004A0002EA33601010100CD6004C9FF21A543350B +:1004B0007E2D3602A7C83601FE7FCAF0072E9A3677 +:1004C000002C3600E608C2E604CD08050021A3434F +:1004D0007EA72E83116142CADF042E8711214006B8 +:1004E00006CDC400C9FF21A3437EA7116142CAF40F +:1004F000041121400606CDFB04C9FF3E0012CD10B9 +:100500000205C2FB04C9FFFF2100180E01C3D00180 +:1005100021A4433603CDEA05CD8005CDB8053ABB0D +:1005200043A7C8C3C432FFFFFFFF21380511C043F2 +:100530000604CDE005C3A0090C1064D8CD4205C364 +:10054000170621B043562C5E21401B010B04C3D675 +:100550000A05788E23477CFE40C2520578FE40CAC9 +:100560000800C300000000000000000000000020A0 +:1005700021A2437EA7C82EB53A8343E6708677C989 +:1005800021B8437EE6060707C6986F260511B043DB +:100590000608CDE005C370054B3F1DD8290020009B +:1005A000FFFFFFFFFFFF20004A461B4029800C0091 +:1005B0004B3F1C20FFFF200021704B060836042C07 +:1005C00036082C36802C36802C05C2BD05C9FFFFAD +:1005D000CDF431C3BC06FFFFAF772305C2D905C9EF +:1005E0007E12231305C2E005C9FF21C443063CCD9A +:1005F000D8052150430630CDD8052E920606CDD819 +:10060000052E9A0604CDD80521504B069CC3D8056B +:10061000FFFFFFFFCD5006AF32005832B94321B67D +:100620004335C02EA436022EB87E34E60FC0113BEF +:100630004A010A05C5D53E00121305C23606D1C1CE +:10064000CD17020DC23406C9AF2C77320058C9FF4E +:1006500021B043562C5E2C7E2C6E677E0601A7C20D +:1006600064062346FE3FC26B0623464F237912CD14 +:10067000170205C26D067AFE47C25B06EB21B14345 +:10068000352C722C73C9472001060211F04221B0AB +:1006900006CDD60A21B043364B23363A23361623ED +:1006A00036403E09F5CD5006F13DC2A406C9FFFF14 +:1006B00060706100C0C8C1C9A200A30021B8437E18 +:1006C00007E60C47FE0CCAEA062C2C7E2C863DFE63 +:1006D00003DAD6063E03B0C6206F2604463AA3438B +:1006E000E601B0320050C9FFCDF47EE6100F0F0FC7 +:1006F000B0472EA47EFE07C2FB060478C3D706FFD0 +:1007000001C04311E043CD180779C6044FC6205FEE +:1007100050FEECC20607C9C9CD2007C34007E6EF6B +:100720000A67E610C87CE6EF02070707E607C63847 +:100730006F26076EE96CFF8A6379FF9EBEFFFFFF9D +:100740000A67E608C87CE607670F0F0FB4F61802C1 +:10075000037CC65B6F26076EE95E0A6D88FFAAD22E +:10076000FFFFFFEB56235E2BAF12EBC9EBEB23230E +:1007700056235E0A120BC91223EB56235E2BAF12CF +:10078000CD1702AF12EBC923EB232356235E0A6F6A +:1007900026147E1223CD17027E120BC9FFEBEB56F7 +:1007A000235E2BAF121312EBC9FFEB232356235EFC +:1007B0000A6F26147E1223137E120BC92313EB56E5 +:1007C000235E2BAF121312CD1702AF121B12EBC90F +:1007D000CD4CEB232356235E0A6F26147E1223137F +:1007E0007E12231BCD17027E1223137E120BC9FF2C +:1007F0003AB943320058CD8003C32A05FFFFFFFFFB +:100800002114083AB84307E61E856F7E2C6E67E90F +:10081000C36014FF0614083422803400053C0834F9 +:1008200023602390FFFFFFFFFFFFFFFFFFFFFFFF9E +:10083000FFFFFFFFCD7608CDF00DCDAB2321924316 +:1008400046343ABA43A7CAF621FE02DC580D780FA7 +:10085000DA6408CD500ACD0030CD080FCD5025C345 +:10086000400CFFFFCD1C0DCD700DCD6C0ACD780F67 +:10087000C38020FFFFFFCD0007CD8608CDA008CDA7 +:10088000A009CD7A09C921EB430603562B5E2B72D2 +:100890002B732B05C28B08C9FFFFFFFFFFFFFFFF74 +:1008A000CDE00821C443CD300921C8433AB843E61E +:1008B0000FFE05CA30097EE608C26409C9FFFFFFC2 +:1008C000CD500ACD0030CD080FCD1C0DCD700DCD13 +:1008D0006C0A3A92430FDA5C08C36D08CDEA08CD82 +:1008E00021B8437EE60FFE06D2B0222EC2CDF80814 +:1008F000010016C32609FFFF3AA0432FE660C8E6B1 +:1009000040CA0A097EFE09D835C97EFEC0D034C966 +:10091000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +:10092000FFFFFFFFFFFF7EE607814F0A2D77C9FF1C +:100930007EE608C26409EB0610CDBB00C87EE6EF78 +:10094000771AF6081213133AC243C60412133AC3B5 +:1009500043D608121BEB012016CD26093E3032612A +:1009600043C9FFFF2C2C2C7ED60877FE1FD02D2DDF +:100970002D7EE6F777C9FFFF7EE63AC24347E607DA +:100980000721380B856F7896329E43237886329FF5 +:1009900043C9329F43C9C6001165410604C3C40060 +:1009A00001C24311E243CDBA090EC61EE6CDBA0913 +:1009B0000ECA1EEAC3BA09FFFFFF21000A0AE6F8C1 +:1009C0000F0F856F7E120313230AE6F80F0F0F86B1 +:1009D00012C9FFFF3AB8430F0F0F0FE6073C470E4F +:1009E0000016053ABC430F5FD2F009788127474FC4 +:1009F0007B15C2E60921DE4B712C3600C398090035 +:100A00004320430042E042C042A042804260424054 +:100A10004220420041E041C041A04180416041404C +:100A20004120410040E040C040A040804060404044 +:100A30004020400000000000000000000000000016 +:100A40002C2C2D2E2D2E2F2F3031323130312C33B6 +:100A500001704B11B04BC5CD1807C179C6044FC604 +:100A6000405F50FED0C2560AC9FFFFFF01704B1114 +:100A7000B34BC5D50AE618CA8A0AEB562B5E2B7211 +:100A80002B73EB13130303CDBA09D1C179C6044FFD +:100A90007BC6045FFED3C2720AC9FFFF21DB4B0194 +:100AA000D44B0AFE48C2E60E3604EB130BCDBA094E +:100AB0001B3E49123AD24B326243C9FF21DD4B5EE5 +:100AC0002D562D1AC614866F260A7E123ADB4BA7C6 +:100AD000C2900EC9FFFFD5C57E12231305C2D80AE6 +:100AE000C1D1CD17020DC2D60AC921E243562C5EF0 +:100AF0002EA5357ECA150BFE1FDA8003CAA00BD6C1 +:100B000020C3B80BFFFFFFFFFFFFFFFFFFFFFFFF4B +:100B1000FFFFFFFFFF2D36052D7EC6906F7EA7C815 +:100B200035E5CD6703E17EA7C82EA43600C9FFFFD7 +:100B3000FFF0E0B0C0D0C0B0000801090109020A0E +:100B4000020A0109010900082EBA3621B8437EFEC7 +:100B500010D8788727477EFE30D878872747C9FF87 +:100B600021A543347EFE40CAA00321001A0E01FED7 +:100B700080C2950B21A44336002E907E2CB6C0AFC8 +:100B80002E98772C772EA2772C7EA7C836000100EE +:100B900001CD6004C9CDD001CDE401C38816FFFFAB +:100BA00021B8437EE60EC8FE04DAAD0B352CAF77D4 +:100BB000320058C3A003FFFF0FDA780FE67EC6A00D +:100BC0006F262A7E236E67FE17CADC0B011F00EB1F +:100BD00009EB010403C3D60AFFFFFFFF015D00EB31 +:100BE00009EB010806CDEE0BCDEE0BC3D60A7AFE5B +:100BF00043C07BFE40D8D6205F7D806F0DC9FFFECD +:100C00007ED603BAD0C605BAD8237E2BD608BBD071 +:100C1000C610BBD82B7E23110839FE30DA2A0C11FE +:100C20000353FEC0DA2A0C11151F3ABA43FE02D252 +:100C3000A40E3AB843E670C610835F161AC3A40E1A +:100C400021FF430605CD8B08CD560CCD6B0CCDD8BE +:100C50000CC9FFFFFFFF21CC43E5CD840CE17DC62D +:100C6000046FFEE0C2590CC9FFFFFF01CE4311EE35 +:100C700043CDBA0903030313131379FEE2C2710CC7 +:100C8000C9FFFFFF7EE608C800002C7EEE04772C2B +:100C90002C7EC60477FEF9D26E092D47CDB40C78B0 +:100CA000FEB0D8C300204E0AEB2CFEE8D26E09C974 +:100CB000FFFFFFFFFEDCD8FEE9D03A9F43BED83AE3 +:100CC0009E43BED03E0432A4433E6032A5433EFF65 +:100CD000326343C9FFFFFFFF01CC4311EC43C5CD95 +:100CE0001807C179C6044FC6205F50A7C2DE0CC9E1 +:100CF00021DC4B36492C36A9219D433ADE4B772E19 +:100D0000A436062C36602E6336FF2EB834E1E1C9D6 +:100D1000CD8000CDA003E1E1C9FFFFFF01704B21B1 +:100D2000504BCD300D0C0C2C3E90B9C2220DC9FF9A +:100D300056230A0303E608C85EEB7E07C6006F264B +:100D4000170A860203230A8602EB570B0AB2E6074C +:100D5000C034C02D342CC9EB2E94780FDA610D36D7 +:100D6000017EA7C82EB87EE6F0C8E1C3C008FFFF29 +:100D700001704B21504BCD860D79C6044F3E90B982 +:100D8000C2760DC9FFFF56235E230AE608C8EB7E34 +:100D9000A7CAD80D07C6C06F26160303037E230F0C +:100DA000DAB40D0FDAC60D0A0FE603860BC3CC0DBD +:100DB0000FE603860A0FE60386670B0A07E60C8434 +:100DC000C3CC0DE604840B0A0FE603866F26167E5D +:100DD0000B020BEBC97E0B020AE6F702EBC91B1BE9 +:100DE0003A94431267133600C9126F137EC9FFFF8E +:100DF00001C44321E643CD040E01C84321EA43CD9B +:100E0000040EC9CC0AE608C87EC608572C5E1AD65E +:100E10002CFE12CA3C0EDA500E2D561AFE60D8FE79 +:100E2000D0D0E6070707C6C06F262A03030AE607E5 +:100E3000BED023BED8C3700EFFFFFFFFAF120AE67D +:100E4000F7022D563EFF3266430688C32D20233E0F +:100E5000FE03C23E0EE57BD6690707076F263E7E7E +:100E600021BC43B677E1FE1FCAF80CC33E0EFFFF5C +:100E7000230AE6F88657030AE6F85F21704B7E23C3 +:100E800023E608C4000C23233E90BDC27E0EC9FF9A +:100E90003A9243E60C0F0FC6486F260A7E32A649E7 +:100EA000C9020C002B2B0B0B0B0AE6F7027EE6F7B0 +:100EB000777DC6426F46234E2170437EE61FCAD51A +:100EC0000E2E747EE61FCAD50E2E787EE61FCAD57A +:100ED0000E2E7C0000722C732C702C71CDF00E0045 +:100EE0002EBA35E1E1E93600C9FFFFFFFFFFFFFF42 +:100EF0002E647BFE10DAFA0E2E6936FFC9FFFFFF63 +:100F0000FFFFFFFFFFFFFFFF21E243562C5E0102C0 +:100F100002CD560FC80000219E437ED60A472C4EB4 +:100F200021704B7E2C2CE608C4380F2C2C3E90BD33 +:100F3000C2230FC9FFFFFFFF2C7E2DFED4D8FEE792 +:100F4000D07EB9D0B8D8CDC40C1105392B2BC3AD88 +:100F50000EAD0EFFFFFFC5D51AFE60DA630FFED09F +:100F6000DA720F1305C2580FD1C1CD17020DC25648 +:100F70000FC9D1C1C9E2562C217043CDC02F2174B5 +:100F800043CDC02F217843CDC02F217C43C3C02F38 +:100F90007EE61FC8357EE6FE2C2C562C5E6F262A78 +:100FA0007E2C4E6F26150600EB09EB3EA0910F4FED +:100FB0000635C5010800C3BC0FC3AD0E7AFE43C29F +:100FC000E90F7BFE40DAE90FD6205F2C2C41FE4072 +:100FD000DAE90FD6205F2C2C7881477BFE40DAE9D6 +:100FE0000FD6205F2C2C788147E37D806FE301DFF3 +:100FF000FFEBC900C34035683E05329643C3A40EDB +:10100000051A1A1B1C1C1D1E1E1F10101112121374 +:101010001415161617171717160F0F121211111194 +:101020001100FFFF051D1E1F10101F1E1D1C1B1A87 +:101030001918181716151413121110101112121373 +:101040000F0F151616161717171700FF051C1C1C77 +:101050001D1D1E1E1E1E1F1F101010101112121318 +:101060000F0F0F1415151516161616171717171735 +:101070001700FFFF051C1C1C1C1D1E1E1F1010103E +:101080001010111212131414141415161617181820 +:101090001818191A1B1C1C1C1C1D1E1F10101011C7 +:1010A000121314140F0600FF051C1C1D1E1E1F101A +:1010B00010111213141414140402020202031C1C53 +:1010C0001C1C1D1E1F10101112121314140600FFF9 +:1010D000051F1F1E1E1E1D1C1C1C1C1B1A19181868 +:1010E000171615140F060808080808080808080845 +:1010F0000808090A0B0B0B0B0B0B00FF0E0E0E0E54 +:101100000E0E0E051C1B1A1A19181818171616158C +:101110000F0F0F13131212121211111111111111BD +:101120001100FFFF051C1C1B1A1A1918191A1B1C89 +:101130001D1E1F1011121314151617181716161549 +:1011400014141413131212121211111100FF051DA1 +:101150001D1D1D1C1C1B1A191818181817161514FC +:1011600014131313130F0402020202031C1B1B1B94 +:101170001B1C1C1D1E1F101010101112131414150F +:101180001515150600FF051C1C1C1C1C1C1B1B1A1E +:101190001A191818181716161515141414131312F3 +:1011A0001211101F1E1E1D1D1C1C1C1B1B1A1A19A0 +:1011B000181818171616151514140F0F0F0F060010 +:1011C000FFFF051C1C1C1C1C1C1B1A1A1A191818C2 +:1011D00018181817161616150F0F0F1413131212CE +:1011E000121111111111111100FF051C1C1C1C1BE7 +:1011F0001B1A1A19181818181716161514140F0F89 +:101200000F0F040101010101031C1C1D1E1F101101 +:10121000121314140600FFFF0519191A1A1A1B1BC2 +:101220001C1C1C1D1E1F101010111213140F060B76 +:101230000B0B0B0B0B0B0B0B0B0B0B0A090808080A +:101240000808080800FF0D0D0D0D0D0D0D051C1DE6 +:101250001E1E1F10101010111212130F0F0F141555 +:101260001616161717171717171717171700FFFF58 +:101270001717171717171717171615141414131213 +:1012800012111010101F1E1D1C1C1C1B1A191817E0 +:10129000160F0F13121111111111111010101F1F21 +:1012A00000FF17171717171717161616151414130C +:1012B00012121110101F1E1E1D1C1C1B1A1A1918A9 +:1012C00018181818171616150F0F0F1312121111E0 +:1012D0001111101010101F1F1F1F1F1F00FFFFFFF5 +:1012E00015151515151515161617181818191A1B92 +:1012F0001C1D1E1F101010111212130F0F0F0F15AF +:1013000016161718181819191919191900FF151593 +:1013100016161616171718181818191A1B1B0F0F60 +:101320000F0F0F1313121211101010101F1E1D0F8C +:101330000F0F0F151616171718181819191A19184C +:10134000171700FF16161616161616161616171865 +:10135000191A1B05070707070707070707070707E6 +:10136000070909090A0A0A0B0B0B0B0B0B0B0B0BDA +:101370000B0B00171700FFFF171717171616161578 +:1013800014131211101F1E1D1C1B191715131314F3 +:1013900014141404010101010101031C1D1E1F1F6F +:1013A00000FF151515151515161718191A1B1D1DF3 +:1013B0001D1E1F1011131414151515150F0F0402FF +:1013C00002020202020202031B1B1919191900FF73 +:1013D0001717171717161514141413121110101FBE +:1013E0001E1D1C1B1A1918181717161615150F0F86 +:1013F0000F04020202020202020202020200FFFFC6 +:1014000030403141004233430044354500463747C0 +:10141000384800493A4A004B3C4C004D3E4E3F4F45 +:10142000C0C8C1C9C2CAC3CBC4CCC5CDC600C7CF12 +:1014300060766100689369008094817188968991D3 +:101440006070610068706900807081008879899996 +:10145000A000A100A200A300A400A500A600A70070 +:10146000C3F120FFFFFFFFFFFFFFFFFFFFFFFFFFB5 +:10147000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +:10148000607061006878690080908100889889990F +:10149000627263736A7A6B7B829283008A9A8B9BF7 +:1014A000647465756C7C6D7D840085958C9C8D9DC8 +:1014B000660067776E006F7F860087978E9E8F9F8E +:1014C000B000B100A000A100A8B8A900FFFFFFFF75 +:1014D000FFFFFFFFA200A300FFFFFFFFAABAABBB05 +:1014E000FFFFFFFFA400A500ACBCADBDB2B4B3B517 +:1014F000FFFFFFFFA600A700FFFFFFFFAEBEAFBFCD +:10150000D6DDE9ECE3F3E1F1E4F4EBEED8EFDFDD77 +:10151000E0F0E1DAE9DAEAF1E2F2DEDC0000D6FF3F +:10152000E9ECEAEDEBEED8EF0000DFDDE0F0E1F111 +:10153000E2F2DEDC0000D6D9D7DAD8DB0000D0D367 +:10154000D1D4D2D5DFFFFEFCDEFEDCB6FFCE7EFFBF +:1015500000DDDFFF00DC00000000000000000000F4 +:10156000D6D9FFE9F9ECEBFBEED8DBEF00FEDD00AE +:10157000E0F0FFE2F200DC000000FF00D0D3DFD299 +:10158000D50000DC00000000D6D900D8DB00000048 +:1015900000000000DFDD00DEDC000000FFFFFFFFD9 +:1015A000D0F6DED1F7F5D2F8DF00D0D3FFD1D400EA +:1015B000D2D500D6D9DFD7DA00D8DB00DFDD00DEF8 +:1015C000FC00DDDC0000DE00DCFE0000DF00545526 +:1015D00056575800595A535C5D0054595B575C008C +:1015E000555A53585D0000540053570000560000F0 +:1015F00000000000000000000000000000000000EB +:101600001014181C0004080C2024282C3034383CFA +:101610008084888C9094989CA0A4A8ACB0B4B8BCEA +:1016200050515253545556574044484C5054585CAE +:10163000C0C4C8FFFFD4FFDCFFE4E8ECFFF4FFFC0C +:1016400000026F00027E7F001300057C7D001339CD +:101650003A2C2C2C2C2C3B3C001100023D36373808 +:101660003D00130002603334356000130004320083 +:10167000150003DCDDA9AADEF40011FB9CFE0002CC +:10168000A7A80013001A001AAF2186190606CDB0CC +:101690001621F81A0608CDB01621950B0609CDB013 +:1016A00016C66B4F11F137197E8177C9322341C9B4 +:1016B000862305C2B016C9FFFFFFFFFFFFFFFFFF34 +:1016C000FFFF02080208040C040C04280428022C62 +:1016D0000130013001300130022C013001300110A5 +:1016E0000110011001100110011001100110011072 +:1016F0000110011001100110011001100110011062 +:10170000FFFF0100FF0000FF000100FF00010200D9 +:1017100004020202FE02FC02FE00FCFE04FE0001C6 +:1017200002000201020201020002FF02FE02FE01AB +:10173000FE00FEFFFEFEFFFE00FE01FE02FE02FFB7 +:10174000473A0078E610C8EB7AFE18C07BFE953663 +:1017500022C8FE9C360EC8FEB53624C870C9FEFFEE +:101760003A0078E6103A8F43C80FE60FC9FFFFFF33 +:101770000000FEDC000000D6D9E5DD00DDE9F9E778 +:10178000ECDEFEE3FAEDF3DF00E4EAF9F4FFDDEB73 +:10179000FBE8EE0000D8DBE6EFDC0000FDDE000039 +:1017A0000000000000000000FDDD00000000E0E798 +:1017B000F0CE00FFE1F9DA000000EAFAF1DC00DD2A +:1017C000E2E8F2DF0000FFDF0000000000000000A0 +:1017D0000000000000000000D6D9FF000000E9F979 +:1017E000EC000000EBFBEE000000D8DBEF00000097 +:1017F00000000000000000000000000000000000E9 +:101800004320FFFFFFFF10150E0B14052100000001 +:1018100012050B0F120400000010150E0B14052208 +:101820004321FFFFFFFF0020202020202000000098 +:101830002020202020200000002020202020200028 +:101840004322FFFFFFFF0000002A200000000000ED +:1018500007050C04202000000000002A20000000E2 +:101860004325FFFFFFFF00000002091414050007D5 +:10187000050C040005090E17051206050E000000F0 +:101880004327FFFFFFFF0000001F00211310090581 +:101890000C05120000210D15050E1A0500001F0091 +:1018A0004329FFFFFFFF0000001F0022131009055E +:1018B0000C05120000220D15050E1A050E001F0062 +:1018C000432DFFFFFFFF00000010150E0B14051441 +:1018D00001020C0C050000000000000000000000E8 +:1018E0004330FFFFFFFF0000000000000000000089 +:1018F00023200028200021252000000000000000F7 +:101900004333FFFFFFFF0000000000000000000065 +:101910002520002120202B24202000000000000092 +:101920004337FFFFFFFF0000000000000000000041 +:10193000202020202B29262020000000000000006D +:10194000433AFFFFFFFF000000000000000000001E +:101950002120202B262020002520202B2420202081 +:10196000433C000000000000000000000000002CCC +:1019700000002129282100000000000000000000D4 +:10198000433D21002100160E0916051213010C001B +:10199000160904050F00131009050C00070D0208B5 +:1019A000433EFFFFFFFF00000000000000000000BA +:1019B0000000000000000000000000000000000027 +:1019C0004328FFFFFFFF00000000000000000000B0 +:1019D0000000000000000000000000000000000007 +:1019E000432CFFFFFFFF0000000000000E15120057 +:1019F000131009050C051200210000000000000072 +:101A00004328FFFFFFFF000000000000000013104C +:101A100009050C050E040500000000000000000090 +:101A200065656565656565650000000000656500C4 +:101A300000000000656565656565656565000065B4 +:101A40000000006565656565656565656565656575 +:101A5000656500006500000065656565000000655E +:101A60006565656565656500000000000065656584 +:101A70006565656565000000000000656565656574 +:101A800065656500000000006565656565656565FF +:101A9000656565656565650000000000006500001E +:101AA000000000006500000000000000FFFFFFFFD5 +:101AB000430A2003428A3503420A4A03418A5F01EE +:101AC000414A660340CA7B03404A9004FFFFFFFF80 +:101AD00021E84B35CAF81A7E2C6E261A562C5E2C3D +:101AE000462C4EFE20C2B80B211E0819EB261A68A0 +:101AF0000607C3D60A6C006C342C7EFEC8CA001CD4 +:101B0000C604772D3640C38003C3E401CD00042111 +:101B1000E84B36402C36B021A4437EFE03C8360283 +:101B20002EBA3601C9FF00CDBC06C32E0606CF0073 +:101B3000000000000000CACB000000000000000010 +:101B400000000000000000390000003A00603D2C59 +:101B50000033362C3034372C0035382C00603D2CC7 +:101B60000000003B0000003C00000000FFFFFFFF02 +:101B7000320036393639003234003B3D3B3D0034CB +:101B8000432C3232323200000000000E05150512DF +:101B900000010E0712090606000000000000000008 +:101BA000432CFFFFFFFF0000000000001310090599 +:101BB0000C05120021000F04051200220000000095 +:101BC0004329FFFFFFFF000001030814150E070063 +:101BD000000E05150512000115061412010700007C +:101BE000432CFFFFFFFF00001A09050C010E060C35 +:101BF0001507001A15120000020113091300000056 +:101C0000CD4601CD271BCDE401115D261911200021 +:101C10003EF4061A861905C2141C1E24198677C9BB +:101C20003F04873F108F3F0400048600108E00049D +:101C30003F04853F108D3F0400048400108C000495 +:101C40003F05873F0E8F3F05000586000E8E00057D +:101C50003F05853F0E8D3F05000584000E8C000575 +:101C60003F06873F0C8F3F06000686000C8E00065D +:101C7000833F05853F0C8D3F058B82000584000C5A +:101C80008C00058A3F01833F05873F0A8F3F058B04 +:101C90003F01000182000586000A8E00058A0001CE +:101CA0003F02833F04853F0A8D3F048B3F020002C1 +:101CB00082000484000A8C00048A00023F03833FF0 +:101CC00004873F088F3F048B3F0300038200048694 +:101CD00000088E00048A00033F04833F03853F0809 +:101CE0008D3F038B3F0400048200038400088C00B6 +:101CF000038A00043F05833F03873F068F3F038B22 +:101D00003F0500058200038600068E00038A000559 +:101D10003F06833F02853F068D3F028B3F068000D2 +:101D2000058200028400068C00028A000588788102 +:101D30003F05833F02873F048F3F028B3F05897831 +:101D40000001798000048200028600048E00028A6D +:101D500000048879000100027A813F04833F0185F5 +:101D60003F048D3F018B3F04897A000200037B8092 +:101D700000038200018400048C00018A0003887B38 +:101D80000003000478813F03833F01873F028F3FB8 +:101D9000018B3F03897800040005798000028200EE +:101DA000018600028E00018A000288790005000683 +:101DB0007A813F0283853F028D8B3F02897A00063C +:101DC00000077B800001828400028C8A0001887BEE +:101DD00000040001000100016E6C6B000578813F7A +:101DE0000183878F8B3F01897800055F65676E6C83 +:101DF0006B0006798082868E8A887900065F656727 +:101E00006E6C6B00077A81838B897A00075F656748 +:101E10006D6C6B00087B7E7F7B00085E65676D6C78 +:101E20006A00097C7D00095E65676D6C6A0002428C +:101E300043000B52525252000264666D6900014227 +:101E4000434041000B515151514E4F6363000169B2 +:101E500000014041000F4E4F4C4D60600001680092 +:101E60000350505050505000094C4D000400016385 +:101E70000018001800010001202122232425262714 +:101E80002625242322212021222324252627262516 +:101E90002423001A001A001A001A000C1919190735 +:101EA000040009000C1919151617190008000C195F +:101EB0000705061919190007000C19031719191934 +:101EC00019190006000D1919191919191919000500 +:101ED000000D1919191919191919190004000E19E9 +:101EE00019191919191919190003000F19191919B4 +:101EF00019070419190002001019191915161719D4 +:101F00001919000200040704000B1907050619003F +:101F100001191900010003151617000C03171919F0 +:101F200019191900010002070506000E19191919DF +:101F300019190001000203170010191919191900C5 +:101F400001001A001A001A001A104A2538104AA770 +:101F5000481048E9581049CB68104A4D7810494F4D +:101F60000000496010004A0220004904300049A6E0 +:101F7000400048A850004A4A6000496C7000486E12 +:101F800080004AF0900049D2A00048F4B0004A76A0 +:101F9000582048EB70204A2E8020495088204A91D2 +:101FA000C0204978D02048BA484049C9C8404A1999 +:101FB000001049A01010492220104A0430104A662F +:101FC000401048E8501049CA60104A4C7010494E01 +:101FD0008010487090104992A0104AB4B010493651 +:101FE000601048CC68104AED78104A0F901048D223 +:101FF0003030496698304A33B83049D7C0304AF853 +:102000007EE602C8547DC6205F1AC60847131A4FE1 +:102010000AFE40D8FE6FD078D60857592B2B7EE6A3 +:10202000F7770AFE50DA40203E0002068821904BE6 +:102030000E0FCD6820702C2C722C73C9FFFFFFFF90 +:10204000E603FE02C2582021A04B0EFFCD682036C9 +:10205000802C2C702C73C9FF3E0002066BC32D2010 +:10206000CD7608C3BC33FFFF7EA1C82C2C2C2C7E60 +:10207000A1C82C2C2C2C7EA1C82C2C2C2CC9FFFFE9 +:102080003A92430F0FDA9C2021904BE5CDB020E12E +:102090007DC6046FFEA0C28920C9FFFF21A04BE5C9 +:1020A000CDD420E17DC6046FFEB0C29F20C9FFFFE2 +:1020B0007EE60FC8357E2C2C562C5E6F262A6E26A7 +:1020C00015011E00EB09C3262121C5010C00C3BC6C +:1020D0000FFFFFFF7EA7C8357E2C2C562C5EE6072F +:1020E000C6F86F26206E26151B1BEB01DEFFC30C06 +:1020F00021C3982AFFFFFFFF56EBE5DFD9D3CDFFC1 +:102100001A7713231A7713231A7713091A771323CD +:102110001A7713231A7713091A7713231A771323BD +:102120001A771309C9D001DEFF7CFE43C200217D6E +:10213000FE40DA0021D6206F1C1C1CFE40DA0C2168 +:10214000D6206F1C1C1CC318219021C3A521F0F9B7 +:1021500021B8437EE604C000002E927E2192437E89 +:10216000FEC0D28421E604477E0F0F0F4FE618C64B +:1021700030806F262256235E2379E607866F26225B +:102180007E12C9FF0F0F0F4F7EE604C6486F26224E +:1021900056235E2379E607866F26226EEB7E23A602 +:1021A00001DFFF09A623A6E6F0FE40C0011F0009DB +:1021B000EB3E08326243E5CDC021E1C3DC0722CD0E +:1021C0007DFE70C021C2437EFE50D02EC87EE60840 +:1021D000C07EF608772336572301B81F7BFED8CA86 +:1021E000E52101C02F7023712EEA36002C3600C97C +:1021F0000F0FC63A5F16780FD20422CD400CCD786F +:102200000FCD8020219443347EFE60D82EA4360268 +:102210002E6036FF2EB8E5E57EE60EFE04CAF00C11 +:10222000E1E134FE00CA74222EBA3610C38003FFE7 +:102230004AA95000486E50004838580048185800C5 +:102240004944500049F250004AD860004A99600061 +:10225000292A2B2A2B2A2928616261606162616028 +:102260006C706C686C706C684042414344464547F2 +:10227000484A494B2EBB36082C3600C38003031551 +:1022800021B9437E0F0F0FE61FC6205F164B3E009D +:1022900012CD17027AFE47C28E22CD6020219B43C9 +:1022A0007E0FD82EB9357E320058C02D34C380033E +:1022B000CDC022CDE62201001621C243C32609FF6C +:1022C000219C433AA0432FE660CAD62234E640C898 +:1022D0003535C9FFFFFF3A9B430F00D07E35A7F08D +:1022E0003434C9FFFFFF219C437EA7F20B232F3C10 +:1022F000FE7CDAF9223E7C3684CD262321C2437E41 +:102300009177FE08D03608C32123FFFE7CDA132321 +:102310003E7C77CD262321C2437E8177FEC1D8360D +:10232000C02E9C3600C90F0F0F4FE607C6505F1630 +:10233000231A47790F0F0FE6014F3A9B43E607C672 +:10234000585F16231AA0C80CC9FFFFFFFFFFFFFF4D +:102350000102040810204080FEE0D0A9D4E0F880FB +:1023600021C01B0E02CDD001CD760821B9433EFF1E +:10237000773200582E94347EFE01C281232E6736B8 +:10238000FFFEC0C02EB834C3800336002D7EFE5E33 +:10239000CDF824CDA024CD6020CD780FCDF032CD66 +:1023A000A831C37632FFFFFFCD760821B8437EE621 +:1023B00004472E927EE603B007C6C46F26237E2C08 +:1023C0006E67E9FF215C2430243C24480A9C0ABC47 +:1023D00009D437D0FFFF21B8437EE60FFE01CA982B +:1023E0003AFE03CA983AFE05CAD03AFE07CAD03A66 +:1023F000FE09D8FE0BDA023BCD023BFF983FFFFF00 +:1024000000000021DC4B7ED608572C5E21BA4336F3 +:10241000102EA436022C357EC82D3606FE1ED8CAD4 +:102420008003FE1FCAA003D620CDB80BC3D4097EFB +:1024300021704BCD54242E74C35424FF21784BCDEE +:1024400054242E7CC35424FF21804BCD54242E844D +:10245000C35424FF7EE608C82C7EFE28D07DC641EA +:102460006F7EC608572C7EC6025F1AA7C03E3E127A +:10247000C9001CC3D60A7881CD95242ED37721BB01 +:10248000433E0896072E9A8607472E6F7EE61E80EB +:1024900032D14BC91F800DC8800DC8800DC887C9B7 +:1024A0002195437EA7C02EB97EA7C2B1242E9536B2 +:1024B000FF472EB87EE6F04F21601FE5CDCD24E129 +:1024C0007DC6046FFE00C2BB24C9FFFFFF7EB8C0FB +:1024D0002C7EA9E610C079BED82C562C5E7DE60471 +:1024E000C6EC6F2624CDDC0703C9FFFF7072717341 +:1024F00074767577FFFFFFFFCD1A2579A7C821B93C +:10250000437E9177320058E607C0CD500621B14393 +:102510007EFE1FC0363FC9FFFFFF2195437E2FE699 +:10252000044F2EB97EE6C0070781070707C326239D +:102530003A00702FE6100F0F0F00810707074FFEBC +:1025400040DA26230E40C326235E5F0604C3C40080 +:1025500021BA433E20960FE60F572E9F864F2D7EC1 +:10256000D60A92FEE0DA6925AF472E9A7E82FE40B7 +:10257000DA75253E40C688572E927EE60607C6705D +:102580006F264BE5CD9425E17DC6106FE5CD9425F2 +:10259000E1C9FFFF7EE608C82C2C7EB8D8B9D02D43 +:1025A0007EFE307AD2A925C6202C2CBED84E2D46D0 +:1025B000C3B725004F2D463AB8431603FE10DACABA +:1025C000251604FE20DACA25160521CC437EE6082E +:1025D000CAE0257DC6046F15C2CD25E1E1C9FFFF24 +:1025E00078C6044779C60C4F36082C780FE6035797 +:1025F00079E60482C658772C702C71E1E1C9FFFF9F +:1026000000000000003AB9432F0F0F0FE61F21D240 +:102610004B772C3AD14BBEDA50263AD54B57E603CE +:102620005F3A9B430707E60C83C6D06F263E7A0FBE +:102630000FE60786573AB9439232B9433200583A07 +:102640009B430FD2D026CD6826C3AA26C23A263A8B +:102650002C3A9B430707E60C86C6D06F263E3AB954 +:102660004386C33926D2AE263A6E43C602473A9A0B +:1026700043570F0FE60F804721BB433E08960FE6F6 +:102680000380475E003AD64BC6E06F263E78BEDA3E +:102690009326467AE6F880477BFE04D2A4262F00D4 +:1026A000E60380477832D54BC95821D34B7E35A7F6 +:1026B000C0342ED67EFE0CD0FE08D82C9607473AA2 +:1026C0006F43E6032ED4772FE6033C4FC37624C92D +:1026D00021A84B0100081100807EA7CAE5267A07D1 +:1026E000D2E42651590C7D906FFE68C2D9263AD2A9 +:1026F0004B8283E61F32D64B7B9232D74BC9FFFF0A +:1027000021A2437EA7C82C7EE6010707C6836F3E41 +:10271000FF329743117043CD48271C1C1C7BFE8061 +:10272000C217271E9D3AA443FE06DA39271A470E20 +:1027300000CD2002AF123297433A9743A7CC6827C7 +:10274000CDA827C3433BFFFF1A1CE61FFE01C01A9A +:10275000A7C80F0F0F0F47E6F04F78E60F47CD20C1 +:1027600002AF12329743C9FFE511614206063AA350 +:1027700043A7CA7827112140CDC400E111BD43EB26 +:102780007E2CB6C82CEBCD1403D03AA343C6906F71 +:1027900034CD67033EFF326A432EBE7E36000F0FF4 +:1027A0000F0F2D77C9FFFFFF218C437E3200602C75 +:1027B0007E320068360F2D360FC9C9FFFF216343F3 +:1027C0007EA7C8FE40DACA273640352E8C368FE108 +:1027D000C9FF216143067F7EA7CAE22706FF3DE6C7 +:1027E00002777830C9E9CD7C3DCD983D78A7C821E6 +:1027F0008D43362F79A7C80FE606F62077C9C9FFA3 +:10280000102410001024104C107410A8107410A87C +:1028100010D010FC10D010FC10D010FC10D010FC08 +:1028200011C2112411C21124114E1186114E11EA48 +:102830001186121812461218124612181246121851 +:102840002D122C002D122C002CD42D5C2CD42C36C7 +:102850002D322C642CA82D322CA82C642CA82D32BF +:10286000127013781270137812A212E013A2130ED2 +:1028700013A213D0130E1344130E13D01344130ECC +:102880002EAE2E742EAE2E562E742E8C2EEC2E8C3A +:102890002E742E8C2EEC2E8C2EEC2E8C2EEC2E8C60 +:1028A0002DE82D8A2DE82DAC2E282DC42E282DC4E0 +:1028B0002DAC2DC42E282DC42E282DC42E282DC479 +:1028C0002C002CD42C002F6A2F942CD42F6A2C3659 +:1028D0002F942C642CA82C642CA82F942C642CA846 +:1028E000127012A2127012A22F42130E12E02F1CAD +:1028F000130E2F1C2F42134413442F1C2F4213443A +:10290000413000183128C818514010A01320C8A029 +:102910004140C82861400028122060A0615040A0BA +:10292000613828285130C83813200018154000A0FD +:102930006150C8A0412028283120A0A01320C81829 +:1029400013040018513008181304C8183120B8189F +:10295000133080A05128C83861402828130800A0EF +:10296000514000A0130870A05140C8A03230C818D0 +:1029700022200018313000285140B8A0312028A072 +:102980001110504813300018414068481210C81800 +:10299000213070482120C83831306048111000289B +:1029A0002120584821300028313070482120C82883 +:1029B000312050481330C8182120684821400018A1 +:1029C0003130584831200038212060483130C83833 +:1029D000312050483130C828212058483130003843 +:1029E0004140704841380018111068484140C818EB +:1029F000213060484120C818313070481320001839 +:102A0000F22050204A20442034402A401C600E60AE +:102A100000601C6000600E602A403E2034403E2072 +:102A2000F22050204A20442034402A401C600E608E +:102A30001C602A403E2034403E2000000000000080 +:102A4000F22050204A20442034402A401C602A4072 +:102A500034403E20000000000000000000000000A4 +:102A6000F2C4BBB2A9A0B2A9A0B2A9A00000000004 +:102A7000F2C4BBB2BBB2A9A0A9A000000000000034 +:102A8000F2C4BBC4B2BBA9B2A000000000000000A9 +:102A900056EBE5D9D3CDE5EBC39830FFFFFFFFFF41 +:102AA00015901584156C17CA156C17CA17A01770E6 +:102AB00017A0177017CA177017A017CA156C1578CA +:102AC000080000FF0200F8FF080202FF0400FAFFFE +:102AD000080404FF0600FCFF080606FF0800FEFFCE +:102AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +:102AF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +:102B0000FFFF03030303FFFFFF030202020203FFB1 +:102B10000302020101020203030201000001020399 +:102B20000302010000010203030202010102020389 +:102B3000FF030202020203FFFFFF03030303FFFF81 +:102B4000FFFF01010101FFFFFF010303030301FF79 +:102B5000010303000003030101030002020003015B +:102B6000010300020200030101030300000303014B +:102B7000FF010303030301FFFFFF01010101FFFF49 +:102B8000A0420400AB428840B6418800A0420C40FD +:102B9000AB424600B641C640A0424A00A941CA40E5 +:102BA0001B1C2E2D2E2D1C1B000000CEB9CEB9B73C +:102BB000B6B7B6000000FCFDFEFFFCFDFEFF000006 +:102BC000381048E74820484968304A8DC0404A9844 +:102BD000B0504976906048725070496A280049E5C3 +:102BE0000810494155204A0B88304971A8404AF5E0 +:102BF000D05048777860486F2870488410004AFEAB +:102C0000121211101F1E1F1010111213141415167A +:102C1000171818191A1B1C1C1D1E1F101011121337 +:102C2000140F0F0F0F15161718171615151617185E +:102C30001819191900FF131313141415151414136C +:102C4000121111101F1E1E1D1C1C1B1A19181716FD +:102C5000150F0F1312121111111110101F1F1F1F2A +:102C60001F00FFFF13131312121211101010101F68 +:102C70001E1D1C1C1D1E1F101112131414151617D7 +:102C800018191A1B1C1C1B1A1918181818181716B3 +:102C9000150F0F0F0F131312121212111111111021 +:102CA00010101F1F1F00FFFF101010101010101029 +:102CB0001010101113141517181716150F06080801 +:102CC000080808080808080800131211111111114A +:102CD000111100FF0808080808080808080E0E056A +:102CE0001C1B1A1918181818181716161514131271 +:102CF000111010101010101112130F060A0A0B0BEE +:102D00000B0B0D0D0D0D0D0D0D0D0C00FFFFFFFF3D +:102D1000FFFF1111121213131414140F0F0F0F0FC2 +:102D20000F04020202020202031C1B1A1A191900E4 +:102D3000FFFF11111212131314151718191B1C1D64 +:102D40001F1011111212131314140F0F040101019B +:102D500001010101031C1D1E1F1F00FF131313138C +:102D600013131211101F1E1D1C1B1A1918171615EC +:102D700014141413130F04010101010101010101D5 +:102D8000031C1D1E1F1F1F1F00FF0F0F0F0F0F0F14 +:102D90000F0F0607070707070707070707090A0BAB +:102DA0000B0B0B0B0B0B0B0B0B00FFFF0B0B0B0B96 +:102DB0000B0A09080808080808090A0B0B0B0B0B7B +:102DC0000B00FFFF1C1C1D1E1F1010111212130FF1 +:102DD000060B0B0B0A090808090A0B0B0B0B0B0B54 +:102DE0000B0B0B0B0B00FFFF101112131415161712 +:102DF000181818191A1A1B1C1C1C1D1E1E1F101037 +:102E00001010111212131414141415151616171885 +:102E10001818191A1A0F0F0F13121110101F1E0F66 +:102E20000F161717171700FF101112131415161786 +:102E3000181818191A1B1C1C1C1D1E1E1F10101000 +:102E4000111212130F0F0F15151616161717171745 +:102E50001717171700FF0F0F0F0F0F0F0F0F0F068A +:102E60000C0C0C0C0C0C0A090808080808080808C7 +:102E70000800FFFF0808080808090A0B0B0B0B0BDA +:102E80000B0A0908080808080800FFFF1C1B1A198C +:102E900018181716150F06080808090A0B0B0A0957 +:102EA000080808080808080808080800FFFF1615A1 +:102EB0001414131211101F1E1E1D1C1C1C1B1A1A89 +:102EC00019181818171616151414141413121211B1 +:102ED000111010101F1E1D0F0F0F151617181818A0 +:102EE000191A0F0F0F131212111100FF16151414D7 +:102EF00013121110101F1E1D1C1C1C1C1B1A1A194A +:102F00001818181817161615141414131312121271 +:102F100011111111111111111100FFFF15151515C6 +:102F2000151515161718191A1B1D1E1F1011121230 +:102F3000130F0F0F060B0B0B0B0D0D0D0B0B0B0BCC +:102F400000FF0B0B0D0D0B0D0B0D0B0B0A0A0A09E5 +:102F500009090808080808080808090A0B0B0D0DDC +:102F60000B0B0D0D0B0B0D00FFFF1313131313139E +:102F700013131211101F1E1D1C1B1A1918171615DA +:102F8000140F0F0F0F0F060908080E0E0E08080E7B +:102F90000E00FFFF11101F1011101F1011101F1035 +:102FA0001111120F060B0B0B0B0B0B0B0B0B0B0A60 +:102FB000090808080E0E0E0E0808080E0E00FFFF86 +:102FC0007EE61FC8357ECAEC2FE6E7C2950F2C4679 +:102FD0002C562C5E7BE61FFE04D81D21E0FF19361F +:102FE0002021E24B700602C3C400FFFF2C2C2C7E74 +:102FF000E61FFE04D8352D2D2D7EC3960FFFFFFF53 +:103000002193437E3407E606C6166F26307E236E74 +:1030100067E9FFFFFFFF302030A031943140FFFF10 +:1030200021D04B7EA7C023237EA7CA3F30357EE642 +:1030300003C02D7EE6F0C87ED610772D3601C93E3E +:10304000FF32D94B11D14B21B4437E2C6E6706045D +:10305000CDE0057DE67FC25D307DC6806F7D32B5F7 +:1030600043CD78300FE63F4F21D24B7E913603D8C7 +:10307000FE04D877C9FFFFFF21B8437E0F0FE61C7F +:103080004F2C2C3E1096814F2E9A7E0FE67FFE200D +:10309000DA95303E1F814FC9C38B38FFFFFFFFFF1A +:1030A00021D04B7EFE01C021704B0108007EE60856 +:1030B000CAB430042C2C2C2C0DC2AD3021E44B7042 +:1030C00021D04B36003ABA4390C836022C477EE6F0 +:1030D0000F2ED777B8D870C94B7EFE02C0342ED3DE +:1030E0003AC243961600D2ED302F3C1620470F0F00 +:1030F0000FE61F5FCD78300F00E63F4F78E60F9167 +:10310000D205313E0083FE20DA0D313E1FE61EB2AD +:103110004721D44B7EFE403E00D21E313E40B04798 +:103120003AB843E60FFE013E00CA2E313E80B05F42 +:1031300016282ED51A772C1C1A77C9FFFFFFFFFF20 +:1031400021D04B7EFE03C0360011704B01504B3A2C +:10315000D34B32D84B1AE608CA6C3113131313033E +:103160000300007BFE90C25531C9FFFF1AE6F0F65E +:103170000C1213132ED87E12C61077132ED47E1283 +:10318000237E0223037E0213032335C26331C90069 +:10319000FFFFFFFF21D04B7EFE02C0342ED934C08A +:1031A000C3DE30FFFFFFFFFF21B9437EA7C02EB271 +:1031B0007EFE1FC02EC27EE607C6666F2632463AE6 +:1031C000B8430F0F0F0FE60F80FE08DAD0313E0034 +:1031D000470F0F0F21A543772D360778C66E6F2650 +:1031E000327E219D43772C36001179410604CDC4EF +:1031F00000C30007C3B43235CA30327EE61FCA802E +:1032000003FE1FC20B323E103263437E0F0FE607F0 +:103210004F7EE6E00F0F0FC6806F262B062B7E81B8 +:103220004F2356235E236E262BC34032FFFFFFFF42 +:103230002EA436022EB87EE6F0C61077C38003FFB8 +:10324000D53E00127EFEFFCA5032C5814F0A12C120 +:1032500013237DE607C24132D1CD17027DE63FC27E +:103260004032C9FFFFFF01020303030201014005D1 +:103270001015202530352195437EA7C02EB9462D47 +:103280007E2F0FE6304F7EE61007C6C06F262BE577 +:10329000CDA032E17DC6046FE61FC28F32C9FFFFA9 +:1032A0007EB8C02C3A8343AEA1C02C562C5E3E6F34 +:1032B00012C9FFFF219B437E0FD82EA5C3F7313AD9 +:1032C000BB43A7C80707074F21704B0680CDD80521 +:1032D000164B263F3E4091C6705FC6106F413AB80C +:1032E00043E610CAE0057DC6406FC3E005CDE005AA +:1032F00021E243562C5E2EB97EC6040F0F0F83E6E3 +:103300001F477BE6E0B05F7AC60857010202C5D5C9 +:10331000CD2A33D1C1CD9B3305C20E33CDF0330658 +:10332000020DC20E33C39037FFFF1AFE6FD816A8E6 +:10333000CA7033FE7CD0FE78D24233E6030707C65C +:10334000AC57CD4C33C8E1E1E1C3C40C78E601478A +:1033500079E60107B0473AB943E604B06F263E4626 +:103360003AC2430FE603826F26337EA0C9FFFFFFF8 +:10337000CD4C33C8E1E1C1AF771169432F12217001 +:1033800043361A2C1EB91A2F0FE670C610772C1E62 +:10339000E21A772C1C1A3D3D77C9E12E017B85E6A8 +:1033A0001F6F7BE6E0B55FC9FBFAEECC333B3AEA30 +:1033B000BBBBFEEF1A4ACCCCBBFAEECC21E24356A3 +:1033C0002C5E13132EC27EE606472E9B7E07E60870 +:1033D00080C6706F261BCDE6333AB843E60FFE0277 +:1033E000C02D1CCD10027E12CD17022C7E12C934C6 +:1033F0002EFECD9D33C317026032613462326134D8 +:10340000CD7608CD0038CD0026CD0038CD80393AB4 +:10341000BB43A7CA6234FE04D23834CD7434CD869F +:1034200034CD6035CD9834CDAA343A9B430FDA7849 +:103430000FCD3039C3400CFF3A9B430FDA5234CDE5 +:103440007434CD6035CD9834CD3039C3400CFFFF96 +:10345000FFFFCD8634CD6035CDAA34C3780FFFFF92 +:10346000FFFF3A9B430FD8CD400CCD780FC3042209 +:10347000FFFFFFFF21704BE5CDC034E17DC6086F33 +:10348000FE90C27734C921904BE5CDC034E17DC6B2 +:10349000086FFEB0C28934C921704BE5CDB035E16B +:1034A0007DC6086FFE90C29B34C921904BE5CDB01C +:1034B00035E17DC6086FFEB0C2AD34C9FFFFFFFF26 +:1034C0007EA7C847C6C05F163E1A4F2C562C5E2CEE +:1034D0007807070786E67E6F263E7E2C6E677AFEAB +:1034E0004BC20C357BFE50DA0C3506082C2CD6204E +:1034F0005FFE50DA093506102C2CD6205FFE50DA1C +:10350000093506182C2CD6205F79804F0635C50169 +:10351000DFFFEB360023360009C9FFFFFFFFFFFF87 +:103520001A7713231A7713091A7713231A771309B3 +:103530001A7713231A7713091A7713231A771309A3 +:103540001A7713231A7713091A7713231A77130993 +:103550001A7713231A7713093600233600C9FFFFA1 +:10356000CD58374707074F0707B0326F433AB84384 +:10357000FE40DA77353E30E6300F473ABB433DFE3A +:1035800004DA86353E0307B0473A9A430707E62038 +:10359000B0C6806F263E7E326E432C7E81E6F832C6 +:1035A0006D43C9FFFFFFFFFFFFFFFFFFFFFFFFFFAF +:1035B0007EA7C8472C2C2C2C7EA7CABE3535EBD550 +:1035C000780707076F263F46234EC52346234EC57F +:1035D0002346234EC52346234EC5EBC9FFFFFFFFFD +:1035E0002C2C7EFE10D22836472D86772D2D7886FE +:1035F00077FE08DA6A36E607772D7ED62077D20482 +:10360000362D352C2C2C2C4E2C2C7E2D361091CA80 +:1036100072363D0F0F0FE61FB83C77D83A6E4377EE +:10362000B8C80470C9FFFFFFE60FCA4437472D7EB4 +:1036300090772D2D7E9077D29536E607772D7EC632 +:103640002077D248362D342C2C2C2C7E2C2C960F07 +:103650000F0FE61FB83C2DDA63363A6E43B8CA63E3 +:1036600036783CF61077C977C9FF78A7C02C2C2C88 +:1036700034C92D462C2C3AC243E6F8B8D2803647DE +:103680003A6D434FC608326D4378913608D8FE082C +:10369000D877C9D8FE2C2C462C2C7EB8C02D3600ED +:1036A0002C3AC243E6F8B8DAAB36473A6D43C6085F +:1036B000326D438036C8D8FEC8D077C977C9FFFFBE +:1036C0007E0FD82D7E3CE60777C9FFFFD1C1E1C947 +:1036D000FFFFD1C1E17EA7C0702D2D2D2D723A685C +:1036E00043F601326843C9FFFFFFD1C1E17EA7C0A5 +:1036F0002C2C7EE60FC02D2D702D2D2D2D723A68AD +:1037000043F602326843C9FFFFFFD1C1E17EA7C083 +:103710002C2C7EE60FC02D2D702D2D2D2D723A688C +:1037200043F6043268433A6F43A3E6F0C07BE60FEA +:10373000772C2C2C2C713A6843F608326843C9FF69 +:10374000FFFFFFFF36112D352D2D36072D7EC620AC +:1037500077D02D34C9FFFFFF219B437E070707E683 +:10376000072EC286E60FC9E60E07D1C1E17EA7C0CB +:103770002C2C7EE610C283372D2D702D2D2D2D7211 +:10378000C9FFFF2D2D712D2D2D2D7BE60F77C9FF44 +:10379000219B437E0FD8E6030707C6C06F26375626 +:1037A000234E237E236E6706007EE6FCFE78C2B6BB +:1037B000377E3CE6FB770915C2A937C3BC33FFFF50 +:1037C000081F480708214A40041F491F042149DCFB +:1037D0003A9243E60C0FC6F86F26337E32E7493241 +:1037E00067492C56216A410120001E053ABC4370EE +:1037F0000FDAF53772091DC2EF37C934623261340E +:103800003AC443E608C83AE643C608573AD24B5F83 +:103810003AE743E6E0473AE7439300E61FB05F1A12 +:10382000D690D8473AC643E607C6006F263E4E7B81 +:10383000E60E07075F3EA8935F164B78FE40DC4418 +:1038400038C3BA38C6606F263B7EA1C8CDA138EB1D +:103850007E36002C2C2C2C56E121BB4335FE08DA99 +:1038600080385F3EFF32694301101F7BFE0DDAFA9C +:10387000380E20FE0FC2FA380E40C3FA380ECAFBCB +:103880000105393EFF326443C3FA38C35205FFFFD6 +:103890000D0D0D0D0D0D0F0F0E0E0E0E0E0F0E0F4A +:1038A000FFD50E20EB2356235E3A8719C6E26F261A +:1038B00017CDDE34D1C935D1C9FF78FE10D8C690F6 +:1038C0006F263B7EA1C8CDA1381AD608DAEA384760 +:1038D000627BC6056F3AC643BE17070707E608B006 +:1038E000C6906F263846EBCDE03C3EFF3266430182 +:1038F0000253C3FA3853C3FA38FFCD1439702C7110 +:103900002C3AE643772C3AE743773AC443E6F7325A +:10391000C443C9FF2170437EE61FC82C2C2C2C7E8B +:10392000E61FC82C2C2C2C7EE61FC82C2C2C2CC956 +:103930003AD24BE61EC6C06F263D5E2C6E264BCD9E +:10394000003A3A9F43824F3A9E439247E5CD5C3915 +:10395000E17DC6086F1DC24C39C9FFFF7EFE05D848 +:103960007DC6056F7EB8D8B9D0D604472D2D2D3A27 +:10397000D24B86E61F070707C6084FC3B725FFFFD0 +:103980003AD24BD60CD8FE10D021C44311C04B06FE +:1039900004CDE0052EE60602CDE0052EE211E64359 +:1039A0000602CDE0052EC43608119E433A9B430F14 +:1039B000DABF391C2EE77ED620772D7EDE00771AFF +:1039C00032C643CD003821C4437EE608CAF039210F +:1039D000E743347EE61FFE1DDAC33921C04B11C414 +:1039E000430604CDE0051EE60602C3E005FFFFFF27 +:1039F0002EA67EFEC0DAC40CD60177C3DB39FFFFEA +:103A00003ABB43D60C2F3C573A9B430F0FD8E1C922 +:103A100021B8118C43CD2A3ACD483A2166437EA77E +:103A2000C836001AF64012C9FFFF2169437EA7C8B5 +:103A3000E63F3D770F0F0F00E607477E0FE6038056 +:103A4000471AE6F0B012C9FF2164437EA7C8E61FFB +:103A50003D770F0F2FE607477E07E60680471AE6F9 +:103A6000F0B012C98C77C9FE10DA783A36103AB83D +:103A70003AA443FE03C2BD273AB843E60707C68A05 +:103A80006F263A7E2C6E67E9C9FF3A8827E63A9A94 +:103A90003AD03A8827E63AB43AE8218C4336AF3A2E +:103AA000B943FEFDD036BFE607C8367FE601C8360B +:103AB0003FC9212F3A9A43FE02D0E60F673A9B4353 +:103AC000E6FC6F7EE601C83E0D328C43C9FFFFFF66 +:103AD0003ABB43A7C8218C43363F3AB943FEF0D8DE +:103AE000E607C0362FC9C9F7CDB43A3A9543A7CAFD +:103AF000E03D3A9C43E67CC80F0F328D43C977C93D +:103B0000060021B8437EE60EFE00C80640FE06C849 +:103B10000680C90680C980B677C9782162437EA72E +:103B2000C83DE63F770700E60C472E8D7EE6F0B0F5 +:103B300077C9C9216A437EA7C835E608F6072E8DE6 +:103B400077C98DCD703ACD333BCD1B3BCD123ACDED +:103B5000D227CD003B2E8D7EE63FB077C93AFFFFDE +:103B6000FEF80F3FFFFE3FF8FFFFFF0FFFFFFFFFD5 +:103B70000FE03FF80FF80FFC07FC07FCF80FF80FF9 +:103B8000F80FF80FE03FE03FE03FE03FFF80FFFF2E +:103B900080FFFE03FE03FE03FE0307070000000094 +:103BA000F01FC007F007F003F803F80307F007F071 +:103BB00007F007F01FC01FC01FC01FC0007F00001C +:103BC0007F0001FC01FC01FC01FCF8F8FFFF000094 +:103BD0003FFF3FFFFCFFFEFFFFFFFE7FFEFFFFFFFB +:103BE000FFFFFFF8FFFF7FFCFFFFFFFFFFFFFFFF6F +:103BF000FFFFFFFF0FFF1F0080E0F8FE030F3FFFF6 +:103C000000E0F9E1ACAEADAF00E200FD000000E77E +:103C1000F8FFB4B6B5B700E800FE0000FA00FCEC0F +:103C2000FBBDBCBE00ED00EE0000F900FDF2FAF3B2 +:103C3000C2C4C3C500DF00FC00FB00F5C6C8C7C98D +:103C400000FF00F6000000E300E4B0B2B1B3FCE511 +:103C500000E6000000F900E9B8BAB9BBFDEA00EBE4 +:103C6000000000F800EFF8C0BFC1FEF0F8F1FC0062 +:103C700000DC00DDA7A9CAAACCD1D0F400DC00DDAD +:103C8000A7ABCBAACDD3D2F4D4DCD5D8A7A9A8AA08 +:103C900000DE00F4D6DCD7D9A7ABA8AA00DE00F47A +:103CA000D4DCD5D8A7A9CBAACDD3D2F4D6DCD7D92A +:103CB000A7ABCAAACCD1D0F400DC00DDA7A9A8AA82 +:103CC00000DE00F400E300E4B0B2ADAF00E200FDBE +:103CD00000E0F9E1ACAEB1B3FCE500E6B8BBB9BCBD +:103CE0007DC6056F7EE6F82C2CBEC82D7EE6F077EB +:103CF0002D7EE6F8772D36802D36002D2D2D70C9BE +:103D0000000000009000FC00000000009100920004 +:103D100000000000F900930000000000F80094008B +:103D200000000000950096000000000000009700D1 +:103D30009800000000000000F9009900FC0000005D +:103D40000000F8009A009B000000FB009C00FE00B1 +:103D500000000000FA009D009E0000000000F90035 +:103D60009F00A000FC000000F800A100A200FD00E0 +:103D7000000000DAA3A5A4A600DB000021D04B7E42 +:103D8000FE032EE3C2893D36107EA7C8352F00E61C +:103D90000FF610328D43E1C921704B01000011086C +:103DA000087E2CA2CAAF3D047EFE30D2AF3D4F2C20 +:103DB0002C2C1DC2A13DC9000C0C0EFF0D0E0DFFD9 +:103DC00006700770087007780680058804900398CD +:103DD00002A001A8017001700270037004700570E8 +:103DE000218D43363F3AB943FEFCD0362FE601C859 +:103DF0002D7EF64077C90504030202020202020288 +:103E000001020408102040803D003D083D103D188F +:103E10003D203D2A3D343D3E3D483D523D5C3D66A2 +:103E20003D483D523D5C3D703D703D703CB83CB8F6 +:103E30003D703D5C3D523D483CB83CB83D703D70E6 +:103E40003CB83CC43CB83CD03C463CB83CB83C00D8 +:103E50003C003CB83CB83C463C003C0E3C1C3C2A78 +:103E60003C383C463C543C623C703C703C7C3C7C66 +:103E70003C883C883C943C943CA03CA03CAC3CAC92 +:103E800004400320023002100548042803380218B9 +:103E9000065005300440032007580638054804281A +:103EA0000510042003300340061805280438034891 +:103EB00007200630054004500830074006500560D2 +:103EC000FF3830303028302828282820202828287B +:103ED00001010101000001010001010100000001D8 +:103EE0001415161008040000000101020203030467 +:103EF0000405060708090A0B0C0D0E0F101112130A +:103F0000FFFFFFFFFFFFFFFF20FF02FF36D235E07C +:103F100030FF03FF36D235E010FF04FF36EA35E00C +:103F200010FF05FF36EA36C010FF08FF36EA36C03C +:103F300030FF03FF36EA36C010FF06FF36EA36C010 +:103F40001010091A376A36C010100B38370A36C0FD +:103F500010100C38370A36C010100A77370A35E0CF +:103F600010100977370A35E010FF08FF36D236C047 +:103F700010FF08FF36D236C010FF08FF36D236C019 +:103F800001486E0010D01010014A8C00204800B883 +:103F9000014A2A003060102801496800409000B0B2 +:103FA000014AE60050300060014A8400604800A0E9 +:103FB0000148C20070B8108001494000809810404C +:103FC000014B2E001020004001486C0020D01070E2 +:103FD000014ACA00303800580148C80040B810589B +:103FE000014A6600505000700149240060A0104052 +:103FF000014A02007068008801498000808810280A +:00000001FF diff --git a/Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/T80/T80.vhd b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/T80/T80.vhd similarity index 100% rename from Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/T80/T80.vhd rename to Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/T80/T80.vhd diff --git a/Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/T80/T8080se.vhd b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/T80/T8080se.vhd similarity index 100% rename from Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/T80/T8080se.vhd rename to Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/T80/T8080se.vhd diff --git a/Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/T80/T80_ALU.vhd b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/T80/T80_ALU.vhd similarity index 100% rename from Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/T80/T80_ALU.vhd rename to Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/T80/T80_ALU.vhd diff --git a/Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/T80/T80_MCode.vhd b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/T80/T80_MCode.vhd similarity index 100% rename from Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/T80/T80_MCode.vhd rename to Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/T80/T80_MCode.vhd diff --git a/Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/T80/T80_Pack.vhd b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/T80/T80_Pack.vhd similarity index 100% rename from Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/T80/T80_Pack.vhd rename to Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/T80/T80_Pack.vhd diff --git a/Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/T80/T80_Reg.vhd b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/T80/T80_Reg.vhd similarity index 100% rename from Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/T80/T80_Reg.vhd rename to Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/T80/T80_Reg.vhd diff --git a/Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/build_id.tcl b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/build_id.tcl similarity index 100% rename from Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/build_id.tcl rename to Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/build_id.tcl diff --git a/Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/build_id.v b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/build_id.v similarity index 100% rename from Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/build_id.v rename to Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/build_id.v diff --git a/Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/dac.vhd b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/dac.vhd similarity index 100% rename from Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/dac.vhd rename to Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/dac.vhd diff --git a/Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/gen_ram.vhd b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/gen_ram.vhd similarity index 100% rename from Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/gen_ram.vhd rename to Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/gen_ram.vhd diff --git a/Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/hq2x.sv b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/hq2x.sv similarity index 100% rename from Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/hq2x.sv rename to Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/hq2x.sv diff --git a/Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/mist_io.v b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/mist_io.v similarity index 100% rename from Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/mist_io.v rename to Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/mist_io.v diff --git a/Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/osd.v b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/osd.v similarity index 100% rename from Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/osd.v rename to Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/osd.v diff --git a/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/phoenix.vhd b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/phoenix.vhd new file mode 100644 index 00000000..60285567 --- /dev/null +++ b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/phoenix.vhd @@ -0,0 +1,472 @@ +--------------------------------------------------------------------------------- +-- DE2-35 Top level for Phoenix by Dar (darfpga@aol.fr) +-- http://darfpga.blogspot.fr +--------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.ALL; +use ieee.numeric_std.all; + +entity phoenix is +generic ( + C_test_picture: boolean := false; + C_tile_rom: boolean := true; -- false: disable tile ROM to try game logic on small FPGA + -- reduce ROMs: 14 is normal game, 13 will draw initial screen, 12 will repeatedly blink 1 line of garbage + C_autofire: boolean := true; + -- C_audio: boolean := true; + C_prog_rom_addr_bits: integer range 12 to 14 := 14 +); +port( + clk : in std_logic; -- 11 MHz for TV, 25 MHz for VGA + reset : in std_logic; + ce_pix : out std_logic; + + dip_switch : in std_logic_vector(7 downto 0); + -- game controls, normal logic '1':pressed, '0':released + + btn_coin: in std_logic; + btn_player_start: in std_logic_vector(1 downto 0); + btn_fire, btn_left, btn_right, btn_barrier: in std_logic; + + video_r : out std_logic_vector(1 downto 0); + video_g : out std_logic_vector(1 downto 0); + video_b : out std_logic_vector(1 downto 0); + video_vblank, video_hblank_bg, video_hblank_fg: out std_logic; + video_hs : out std_logic; + video_vs : out std_logic; + + sound_fire : out std_logic; -- '1' when missile fires + sound_explode: out std_logic; -- '1' when ship explodes + sound_burn : out std_logic; -- bird burns + sound_fireball: out std_logic; -- bird explodes in 2 fireballs + sound_ab : out std_logic_vector(15 downto 0); + audio_select : in std_logic_vector(2 downto 0) := (others => '0'); + audio : out std_logic_vector(11 downto 0) +); +end phoenix; + +architecture struct of phoenix is + + signal reset_n: std_logic; + + signal hcnt : std_logic_vector(9 downto 1); + signal vcnt : std_logic_vector(8 downto 1); + signal sync : std_logic; + signal adrsel : std_logic; + signal rdy : std_logic := '1'; + signal vblank : std_logic; + signal hblank_bkgrd : std_logic; + signal hblank_frgrd : std_logic; + signal ce_pix1 : std_logic; + + signal cpu_adr : std_logic_vector(15 downto 0); + signal cpu_di : std_logic_vector( 7 downto 0); + signal cpu_do : std_logic_vector( 7 downto 0); + signal cpu_wr_n : std_logic; + signal prog_do : std_logic_vector( 7 downto 0); + signal S_prog_rom_addr : std_logic_vector(13 downto 0); + + signal frgnd_horz_cnt : std_logic_vector(7 downto 0) := (others =>'0'); + signal bkgnd_horz_cnt : std_logic_vector(7 downto 0) := (others =>'0'); + signal vert_cnt : std_logic_vector(7 downto 0) := (others =>'0'); + + signal frgnd_ram_adr: std_logic_vector(10 downto 0) := (others =>'0'); + signal bkgnd_ram_adr: std_logic_vector(10 downto 0) := (others =>'0'); + signal frgnd_ram_do : std_logic_vector( 7 downto 0) := (others =>'0'); + signal bkgnd_ram_do : std_logic_vector( 7 downto 0) := (others =>'0'); + signal frgnd_ram_we : std_logic := '0'; + signal bkgnd_ram_we : std_logic := '0'; + + signal frgnd_graph_adr : std_logic_vector(11 downto 0) := (others =>'0'); + signal bkgnd_graph_adr : std_logic_vector(11 downto 0) := (others =>'0'); + signal palette_adr : std_logic_vector( 7 downto 0) := (others =>'0'); + signal A11 : std_logic; + + signal frgnd_clk : std_logic; + signal bkgnd_clk : std_logic; + + signal frgnd_tile_id : std_logic_vector(7 downto 0) := (others =>'0'); + signal bkgnd_tile_id : std_logic_vector(7 downto 0) := (others =>'0'); + + signal frgnd_bit0_graph : std_logic_vector(7 downto 0) := (others =>'0'); + signal frgnd_bit1_graph : std_logic_vector(7 downto 0) := (others =>'0'); + signal bkgnd_bit0_graph : std_logic_vector(7 downto 0) := (others =>'0'); + signal bkgnd_bit1_graph : std_logic_vector(7 downto 0) := (others =>'0'); + + signal frgnd_bit0_graph_r : std_logic_vector(7 downto 0) := (others =>'0'); + signal frgnd_bit1_graph_r : std_logic_vector(7 downto 0) := (others =>'0'); + signal bkgnd_bit0_graph_r : std_logic_vector(7 downto 0) := (others =>'0'); + signal bkgnd_bit1_graph_r : std_logic_vector(7 downto 0) := (others =>'0'); + + signal fr_bit0 : std_logic; + signal fr_bit1 : std_logic; + signal bk_bit0 : std_logic; + signal bk_bit1 : std_logic; + signal fr_lin : std_logic_vector(2 downto 0); + signal bk_lin : std_logic_vector(2 downto 0); + + signal color_set : std_logic; + signal color_set2 : std_logic; + signal color_id : std_logic_vector(5 downto 0); + signal rgb_0 : std_logic_vector(2 downto 0); + signal rgb_1 : std_logic_vector(2 downto 0); + + signal player2 : std_logic := '0'; + signal pl2_cocktail : std_logic := '0'; + signal bkgnd_offset : std_logic_vector(7 downto 0) := (others =>'0'); + signal sound_a : std_logic_vector(7 downto 0) := (others =>'0'); + signal sound_b : std_logic_vector(7 downto 0) := (others =>'0'); + + signal clk10 : std_logic; + signal snd1 : std_logic_vector( 7 downto 0) := (others =>'0'); + signal snd2 : std_logic_vector( 1 downto 0) := (others =>'0'); + signal snd3 : std_logic_vector( 7 downto 0) := (others =>'0'); + signal song : std_logic_vector( 7 downto 0) := (others =>'0'); + signal mixed : std_logic_vector(11 downto 0) := (others =>'0'); + signal sound_string : std_logic_vector(31 downto 0); + + signal coin : std_logic; + signal player_start : std_logic_vector(1 downto 0); + signal buttons : std_logic_vector(3 downto 0); + signal R_autofire : std_logic_vector(21 downto 0); +begin + +-- game core uses inverted control logic +coin <= not btn_coin; -- insert coin +player_start <= not btn_player_start; -- select 1 or 2 players +buttons(1) <= not btn_right; -- Right +buttons(2) <= not btn_left; -- Left +buttons(3) <= not btn_barrier; -- Protection + +G_not_autofire: if not C_autofire generate + buttons(0) <= not btn_fire; -- Fire +end generate; + +G_yes_autofire: if C_autofire generate + process(clk) + begin + if rising_edge(clk) then + if btn_fire='1' then + R_autofire <= R_autofire-1; + else + R_autofire <= (others => '0'); + end if; + end if; + end process; + buttons(0) <= not R_autofire(R_autofire'high); +end generate; + + video: entity work.phoenix_video + port map + ( + clk11 => clk, + ce_pix => ce_pix1, + hcnt => hcnt, + vcnt => vcnt, + sync_hs => video_hs, + sync_vs => video_vs, + adrsel => adrsel, -- RAM address selector ('0')cpu / ('1')video_generator + rdy => rdy, -- Ready ('1')cpu can access RAMs read/write + vblank => vblank, + hblank_frgrd => hblank_frgrd, + hblank_bkgrd => hblank_bkgrd, + reset => reset + ); + reset_n <= not reset; + ce_pix <= ce_pix1; + +-- microprocessor 8085 +cpu8085 : entity work.T8080se +generic map +( + Mode => 2, + T2Write => 0 +) +port map( + RESET_n => reset_n, + CLK => clk, + CLKEN => '1', -- fixme: use it to make 5.5 MHz clock average + READY => rdy, + HOLD => '1', + INT => '1', + INTE => open, + DBIN => open, + SYNC => open, + VAIT => open, + HLDA => open, + WR_n => cpu_wr_n, + A => cpu_adr, + DI => cpu_di, + DO => cpu_do +); + +-- mux prog, ram, vblank, switch... to processor data bus in +cpu_di <= prog_do when cpu_adr(14) = '0' else + frgnd_ram_do when cpu_adr(13 downto 10) = 2#00_00# else + bkgnd_ram_do when cpu_adr(13 downto 10) = 2#00_10# else + buttons & '0' & player_start & coin when cpu_adr(13 downto 10) = 2#11_00# else--buttons & '1' + not vblank & dip_switch(6 downto 0) when cpu_adr(13 downto 10) = 2#11_10# else + prog_do; + +-- write enable to RAMs from cpu +frgnd_ram_we <= '1' when cpu_wr_n = '0' and cpu_adr(14 downto 10) = "10000" and adrsel = '0' else '0'; +bkgnd_ram_we <= '1' when cpu_wr_n = '0' and cpu_adr(14 downto 10) = "10010" and adrsel = '0' else '0'; + +-- RAMs address mux cpu/video_generator, bank0 for player1, bank1 for player2 +frgnd_ram_adr <= player2 & cpu_adr(9 downto 0) when adrsel ='0' else player2 & vert_cnt(7 downto 3) & frgnd_horz_cnt(7 downto 3); +bkgnd_ram_adr <= player2 & cpu_adr(9 downto 0) when adrsel ='0' else player2 & vert_cnt(7 downto 3) & bkgnd_horz_cnt(7 downto 3); + +-- demux cpu data to registers : background scrolling, sound control, +-- player id (1/2), palette color set. +process (clk) +begin + if rising_edge(clk) then + if cpu_wr_n = '0' then + case cpu_adr(14 downto 10) is + when "10110" => bkgnd_offset <= cpu_do; + when "11000" => sound_b <= cpu_do; + when "11010" => sound_a <= cpu_do; + when "10100" => player2 <= cpu_do(0); + color_set <= cpu_do(1); + color_set2 <= cpu_do(2); + A11 <= cpu_do(3); + when others => null; + end case; + end if; + end if; +end process; + +-- player2 and cocktail mode (flip horizontal/vertical) +pl2_cocktail <= player2 and dip_switch(7); + +-- horizontal scan video RAMs address background and foreground +-- with flip and scroll offset +frgnd_horz_cnt <= hcnt(8 downto 1) when pl2_cocktail = '0' else not hcnt(8 downto 1); +bkgnd_horz_cnt <= frgnd_horz_cnt + bkgnd_offset; + +-- vertical scan video RAMs address +vert_cnt <= vcnt(8 downto 1) when pl2_cocktail = '0' else not (vcnt(8 downto 1) + X"30"); + +-- get tile_ids from RAMs +frgnd_tile_id <= frgnd_ram_do; +bkgnd_tile_id <= bkgnd_ram_do; + +-- address graphix ROMs with tile_ids and line counter +frgnd_graph_adr <= A11 & frgnd_tile_id & vert_cnt(2 downto 0); +bkgnd_graph_adr <= A11 & bkgnd_tile_id & vert_cnt(2 downto 0); + +-- latch foreground/background next graphix byte, high bit and low bit +-- and palette_ids (fr_lin, bklin) +process (clk) +begin + if rising_edge(clk) then + if (pl2_cocktail = '0' and (frgnd_horz_cnt(2 downto 0) = "111")) or + (pl2_cocktail = '1' and (frgnd_horz_cnt(2 downto 0) = "000")) then + frgnd_bit0_graph_r <= frgnd_bit0_graph; + frgnd_bit1_graph_r <= frgnd_bit1_graph; + fr_lin <= frgnd_tile_id(7 downto 5); + end if; + if (pl2_cocktail = '0' and (bkgnd_horz_cnt(2 downto 0) = "111")) or + (pl2_cocktail = '1' and (bkgnd_horz_cnt(2 downto 0) = "000")) then + bkgnd_bit0_graph_r <= bkgnd_bit0_graph; + bkgnd_bit1_graph_r <= bkgnd_bit1_graph; + bk_lin <= bkgnd_tile_id(7 downto 5); + end if; + end if; +end process; + +-- demux background and foreground pixel bits (0/1) from graphix byte with horizontal counter +-- and apply horizontal and vertical blanking +fr_bit0 <= frgnd_bit0_graph_r(to_integer(unsigned(frgnd_horz_cnt(2 downto 0)))) when (vblank or hblank_frgrd)= '0' else '0'; +fr_bit1 <= frgnd_bit1_graph_r(to_integer(unsigned(frgnd_horz_cnt(2 downto 0)))) when (vblank or hblank_frgrd)= '0' else '0'; +bk_bit0 <= bkgnd_bit0_graph_r(to_integer(unsigned(bkgnd_horz_cnt(2 downto 0)))) when (vblank or hblank_bkgrd)= '0' else '0'; +bk_bit1 <= bkgnd_bit1_graph_r(to_integer(unsigned(bkgnd_horz_cnt(2 downto 0)))) when (vblank or hblank_bkgrd)= '0' else '0'; + +-- select pixel bits and palette_id with foreground priority +color_id <= (fr_bit0 or fr_bit1) & fr_bit1 & fr_bit0 & fr_lin when (fr_bit0 or fr_bit1) = '1' else + (fr_bit0 or fr_bit1) & bk_bit1 & bk_bit0 & bk_lin; + +-- address palette with pixel bits color and color set +palette_adr <= color_set2 & color_set & color_id; +-- output video to top level +video_vblank <= vblank; +video_hblank_fg <= hblank_frgrd; +video_hblank_bg <= hblank_bkgrd; +video_r <= rgb_1(0) & rgb_0(0) when (hcnt>=192) else "00"; +video_g <= rgb_1(2) & rgb_0(2) when (hcnt>=192) else "00"; +video_b <= rgb_1(1) & rgb_0(1) when (hcnt>=192) else "00"; + +frgnd_bit0 : entity work.sprom + generic map ( + init_file => "./ROM/39.hex", + widthad_a => 11, + width_a => 8) + port map ( + address => frgnd_graph_adr(10 downto 0), + clock => clk, + q => frgnd_bit0_graph + ); + +frgnd_bit1 : entity work.sprom + generic map ( + init_file => "./ROM/40.hex", + widthad_a => 11, + width_a => 8) + port map ( + address => frgnd_graph_adr(10 downto 0), + clock => clk, + q => frgnd_bit1_graph + ); + +bkgnd_bit0 : entity work.sprom + generic map ( + init_file => "./ROM/23.hex", + widthad_a => 11, + width_a => 8) + port map ( + address => bkgnd_graph_adr(10 downto 0), + clock => clk, + q => bkgnd_bit0_graph + ); + +bkgnd_bit1 : entity work.sprom + generic map ( + init_file => "./ROM/24.hex", + widthad_a => 11, + width_a => 8) + port map ( + address => bkgnd_graph_adr(10 downto 0), + clock => clk, + q => bkgnd_bit1_graph + ); + +palette_0 : entity work.sprom + generic map ( + init_file => "./ROM/ic40.hex", + widthad_a => 7, + width_a => 3) + port map ( + address => palette_adr(6 downto 0), + clock => clk, + q => rgb_0 + ); + +palette_1 : entity work.sprom + generic map ( + init_file => "./ROM/ic41.hex", + widthad_a => 7, + width_a => 3) + port map ( + address => palette_adr(6 downto 0), + clock => clk, + q => rgb_1 + ); + +-- Program PROM +S_prog_rom_addr(C_prog_rom_addr_bits-1 downto 0) <= cpu_adr(C_prog_rom_addr_bits-1 downto 0); + +prog : entity work.sprom + generic map ( + init_file => "./ROM/prog.hex", + widthad_a => 14, + width_a => 8) + port map ( + address => S_prog_rom_addr, + clock => clk, + q => prog_do + ); + +-- foreground RAM 0x4000-0x433F +-- cpu working area 0x4340-0x43FF +frgnd_ram : entity work.gen_ram +generic map( dWidth => 8, aWidth => 11) +port map( + clk => clk, + we => frgnd_ram_we, + addr => frgnd_ram_adr, + d => cpu_do, + q => frgnd_ram_do +); + +-- background RAM 0x4800-0x4B3F +-- cpu working area 0x4B40-0x4BFF +-- stack pointer downward from 0x4BFF +bkgnd_ram : entity work.gen_ram +generic map( dWidth => 8, aWidth => 11) +port map( + clk => clk, + we => bkgnd_ram_we, + addr => bkgnd_ram_adr, + d => cpu_do, + q => bkgnd_ram_do +); + + +effect1: entity work.phoenix_effect1 +port map +( + clk => clk, + reset => '0', + trigger => sound_a(4), + filter => sound_a(5), + divider => sound_a(3 downto 0), + snd => snd1 +); + +effect2 : entity work.phoenix_effect2 +port map +( + clk => clk, + reset => '0', + trigger1 => sound_b(4), + trigger2 => sound_b(5), + divider => sound_b(3 downto 0), + snd => snd2 +); + +effect3 : entity work.phoenix_effect3 +port map +( + clk => clk, + reset => '0', + trigger1 => sound_b(6), + trigger2 => sound_b(7), + snd => snd3 +); + +sound_burn <= sound_b(4); +sound_fire <= sound_b(6); -- '1' when fire sound +sound_explode <= sound_b(7); -- '1' when explode sound +sound_fireball <= sound_a(1) and not sound_a(0); -- ambiguity: mothership descend also triggers this +sound_ab <= sound_b & sound_a; + +music: entity work.phoenix_music +port map +( + clk => clk, + reset => '0', + trigger => sound_a(7), + sel_song => sound_a(6), + snd => song +); + +-- mix effects and music +mixed <= std_logic_vector + ( + unsigned("00" & snd1 & "00") + + unsigned("0" & snd2 & "000000000") + + unsigned("00" & snd3 & "00") + + unsigned("00" & song & "00" ) + ); + +-- select sound or/and effect +with audio_select select +audio <= "00" & snd1 & "00" when "100", + "0" & snd2 & "000000000" when "101", + "00" & snd3 & "00" when "110", + "00" & song & "00" when "111", + mixed when others; + + +end struct; diff --git a/Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/phoenix_effect1.vhd b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/phoenix_effect1.vhd similarity index 100% rename from Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/phoenix_effect1.vhd rename to Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/phoenix_effect1.vhd diff --git a/Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/phoenix_effect2.vhd b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/phoenix_effect2.vhd similarity index 100% rename from Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/phoenix_effect2.vhd rename to Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/phoenix_effect2.vhd diff --git a/Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/phoenix_effect3.vhd b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/phoenix_effect3.vhd similarity index 100% rename from Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/phoenix_effect3.vhd rename to Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/phoenix_effect3.vhd diff --git a/Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/phoenix_mist.vhd b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/phoenix_mist.vhd similarity index 100% rename from Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/phoenix_mist.vhd rename to Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/phoenix_mist.vhd diff --git a/Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/phoenix_music.vhd b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/phoenix_music.vhd similarity index 100% rename from Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/phoenix_music.vhd rename to Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/phoenix_music.vhd diff --git a/Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/phoenix_video.vhd b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/phoenix_video.vhd similarity index 100% rename from Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/phoenix_video.vhd rename to Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/phoenix_video.vhd diff --git a/Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/pll.ppf b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/pll.ppf similarity index 100% rename from Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/pll.ppf rename to Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/pll.ppf diff --git a/Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/pll.qip b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/pll.qip similarity index 100% rename from Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/pll.qip rename to Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/pll.qip diff --git a/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/pll.vhd b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/pll.vhd new file mode 100644 index 00000000..80c7787d --- /dev/null +++ b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/pll.vhd @@ -0,0 +1,387 @@ +-- megafunction wizard: %ALTPLL% +-- GENERATION: STANDARD +-- VERSION: WM1.0 +-- MODULE: altpll + +-- ============================================================ +-- File Name: pll.vhd +-- 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. + + +LIBRARY ieee; +USE ieee.std_logic_1164.all; + +LIBRARY altera_mf; +USE altera_mf.all; + +ENTITY pll IS + PORT + ( + areset : IN STD_LOGIC := '0'; + inclk0 : IN STD_LOGIC := '0'; + c0 : OUT STD_LOGIC ; + c1 : OUT STD_LOGIC + ); +END pll; + + +ARCHITECTURE SYN OF pll IS + + SIGNAL sub_wire0 : STD_LOGIC_VECTOR (4 DOWNTO 0); + SIGNAL sub_wire1 : STD_LOGIC ; + SIGNAL sub_wire2 : STD_LOGIC ; + SIGNAL sub_wire3 : STD_LOGIC ; + SIGNAL sub_wire4 : STD_LOGIC_VECTOR (1 DOWNTO 0); + SIGNAL sub_wire5_bv : BIT_VECTOR (0 DOWNTO 0); + SIGNAL sub_wire5 : STD_LOGIC_VECTOR (0 DOWNTO 0); + + + + COMPONENT altpll + GENERIC ( + bandwidth_type : STRING; + clk0_divide_by : NATURAL; + clk0_duty_cycle : NATURAL; + clk0_multiply_by : NATURAL; + clk0_phase_shift : STRING; + clk1_divide_by : NATURAL; + clk1_duty_cycle : NATURAL; + clk1_multiply_by : NATURAL; + clk1_phase_shift : STRING; + compensate_clock : STRING; + inclk0_input_frequency : NATURAL; + intended_device_family : STRING; + lpm_hint : STRING; + lpm_type : STRING; + operation_mode : STRING; + pll_type : STRING; + port_activeclock : STRING; + port_areset : STRING; + port_clkbad0 : STRING; + port_clkbad1 : STRING; + port_clkloss : STRING; + port_clkswitch : STRING; + port_configupdate : STRING; + port_fbin : STRING; + port_inclk0 : STRING; + port_inclk1 : STRING; + port_locked : STRING; + port_pfdena : STRING; + port_phasecounterselect : STRING; + port_phasedone : STRING; + port_phasestep : STRING; + port_phaseupdown : STRING; + port_pllena : STRING; + port_scanaclr : STRING; + port_scanclk : STRING; + port_scanclkena : STRING; + port_scandata : STRING; + port_scandataout : STRING; + port_scandone : STRING; + port_scanread : STRING; + port_scanwrite : STRING; + port_clk0 : STRING; + port_clk1 : STRING; + port_clk2 : STRING; + port_clk3 : STRING; + port_clk4 : STRING; + port_clk5 : STRING; + port_clkena0 : STRING; + port_clkena1 : STRING; + port_clkena2 : STRING; + port_clkena3 : STRING; + port_clkena4 : STRING; + port_clkena5 : STRING; + port_extclk0 : STRING; + port_extclk1 : STRING; + port_extclk2 : STRING; + port_extclk3 : STRING; + width_clock : NATURAL + ); + PORT ( + areset : IN STD_LOGIC ; + clk : OUT STD_LOGIC_VECTOR (4 DOWNTO 0); + inclk : IN STD_LOGIC_VECTOR (1 DOWNTO 0) + ); + END COMPONENT; + +BEGIN + sub_wire5_bv(0 DOWNTO 0) <= "0"; + sub_wire5 <= To_stdlogicvector(sub_wire5_bv); + sub_wire2 <= sub_wire0(0); + sub_wire1 <= sub_wire0(1); + c1 <= sub_wire1; + c0 <= sub_wire2; + sub_wire3 <= inclk0; + sub_wire4 <= sub_wire5(0 DOWNTO 0) & sub_wire3; + + altpll_component : altpll + GENERIC MAP ( + bandwidth_type => "AUTO", + clk0_divide_by => 27, + clk0_duty_cycle => 50, + clk0_multiply_by => 44, + clk0_phase_shift => "0", + clk1_divide_by => 27, + clk1_duty_cycle => 50, + clk1_multiply_by => 11, + clk1_phase_shift => "0", + compensate_clock => "CLK0", + inclk0_input_frequency => 37037, + intended_device_family => "Cyclone III", + lpm_hint => "CBX_MODULE_PREFIX=pll", + lpm_type => "altpll", + operation_mode => "NORMAL", + pll_type => "AUTO", + port_activeclock => "PORT_UNUSED", + port_areset => "PORT_USED", + port_clkbad0 => "PORT_UNUSED", + port_clkbad1 => "PORT_UNUSED", + port_clkloss => "PORT_UNUSED", + port_clkswitch => "PORT_UNUSED", + port_configupdate => "PORT_UNUSED", + port_fbin => "PORT_UNUSED", + port_inclk0 => "PORT_USED", + port_inclk1 => "PORT_UNUSED", + port_locked => "PORT_UNUSED", + port_pfdena => "PORT_UNUSED", + port_phasecounterselect => "PORT_UNUSED", + port_phasedone => "PORT_UNUSED", + port_phasestep => "PORT_UNUSED", + port_phaseupdown => "PORT_UNUSED", + port_pllena => "PORT_UNUSED", + port_scanaclr => "PORT_UNUSED", + port_scanclk => "PORT_UNUSED", + port_scanclkena => "PORT_UNUSED", + port_scandata => "PORT_UNUSED", + port_scandataout => "PORT_UNUSED", + port_scandone => "PORT_UNUSED", + port_scanread => "PORT_UNUSED", + port_scanwrite => "PORT_UNUSED", + port_clk0 => "PORT_USED", + port_clk1 => "PORT_USED", + port_clk2 => "PORT_UNUSED", + port_clk3 => "PORT_UNUSED", + port_clk4 => "PORT_UNUSED", + port_clk5 => "PORT_UNUSED", + port_clkena0 => "PORT_UNUSED", + port_clkena1 => "PORT_UNUSED", + port_clkena2 => "PORT_UNUSED", + port_clkena3 => "PORT_UNUSED", + port_clkena4 => "PORT_UNUSED", + port_clkena5 => "PORT_UNUSED", + port_extclk0 => "PORT_UNUSED", + port_extclk1 => "PORT_UNUSED", + port_extclk2 => "PORT_UNUSED", + port_extclk3 => "PORT_UNUSED", + width_clock => 5 + ) + PORT MAP ( + areset => areset, + inclk => sub_wire4, + clk => sub_wire0 + ); + + + +END SYN; + +-- ============================================================ +-- 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 "27" +-- Retrieval info: PRIVATE: DIV_FACTOR1 NUMERIC "27" +-- Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000" +-- Retrieval info: PRIVATE: DUTY_CYCLE1 STRING "50.00000000" +-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "44.000000" +-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "11.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 "0" +-- 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 "44" +-- Retrieval info: PRIVATE: MULT_FACTOR1 NUMERIC "11" +-- Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1" +-- Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "44.00000000" +-- Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "11.00000000" +-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "0" +-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE1 STRING "0" +-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz" +-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT1 STRING "MHz" +-- Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "1" +-- Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0" +-- Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000" +-- Retrieval info: PRIVATE: PHASE_SHIFT1 STRING "0.00000000" +-- Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0" +-- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg" +-- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT1 STRING "deg" +-- Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0" +-- Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "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 "27" +-- Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50" +-- Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "44" +-- 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 "11" +-- 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_UNUSED" +-- 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: WIDTH_CLOCK NUMERIC "5" +-- Retrieval info: USED_PORT: @clk 0 0 5 0 OUTPUT_CLK_EXT VCC "@clk[4..0]" +-- Retrieval info: USED_PORT: @inclk 0 0 2 0 INPUT_CLK_EXT VCC "@inclk[1..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: 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: GEN_FILE: TYPE_NORMAL pll.vhd TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL pll.ppf TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL pll.inc FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL pll.cmp FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL pll.bsf FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL pll_inst.vhd FALSE +-- Retrieval info: LIB_FILE: altera_mf +-- Retrieval info: CBX_MODULE_PREFIX: ON diff --git a/Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/scandoubler.v b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/scandoubler.v similarity index 100% rename from Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/scandoubler.v rename to Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/scandoubler.v diff --git a/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/spram.vhd b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/spram.vhd new file mode 100644 index 00000000..d8043481 --- /dev/null +++ b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/spram.vhd @@ -0,0 +1,55 @@ +LIBRARY ieee; +USE ieee.std_logic_1164.all; + +LIBRARY altera_mf; +USE altera_mf.altera_mf_components.all; + +ENTITY spram IS + generic ( + addr_width_g : integer := 8; + data_width_g : integer := 8 + ); + PORT + ( + address : IN STD_LOGIC_VECTOR (addr_width_g-1 DOWNTO 0); + clken : IN STD_LOGIC := '1'; + clock : IN STD_LOGIC := '1'; + data : IN STD_LOGIC_VECTOR (data_width_g-1 DOWNTO 0); + wren : IN STD_LOGIC ; + q : OUT STD_LOGIC_VECTOR (data_width_g-1 DOWNTO 0) + ); +END spram; + + +ARCHITECTURE SYN OF spram IS + +BEGIN + altsyncram_component : altsyncram + GENERIC MAP ( + clock_enable_input_a => "NORMAL", + clock_enable_output_a => "BYPASS", + intended_device_family => "Cyclone III", + lpm_hint => "ENABLE_RUNTIME_MOD=NO", + lpm_type => "altsyncram", + numwords_a => 2**addr_width_g, + operation_mode => "SINGLE_PORT", + outdata_aclr_a => "NONE", + outdata_reg_a => "UNREGISTERED", + power_up_uninitialized => "FALSE", + read_during_write_mode_port_a => "NEW_DATA_NO_NBE_READ", + widthad_a => addr_width_g, + width_a => data_width_g, + width_byteena_a => 1 + ) + PORT MAP ( + address_a => address, + clock0 => clock, + clocken0 => clken, + data_a => data, + wren_a => wren, + q_a => q + ); + + + +END SYN; diff --git a/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/sprom.vhd b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/sprom.vhd new file mode 100644 index 00000000..a81ac959 --- /dev/null +++ b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/sprom.vhd @@ -0,0 +1,82 @@ +LIBRARY ieee; +USE ieee.std_logic_1164.all; + +LIBRARY altera_mf; +USE altera_mf.all; + +ENTITY sprom IS + GENERIC + ( + init_file : string := ""; + widthad_a : natural; + width_a : natural := 8; + outdata_reg_a : string := "UNREGISTERED" + ); + PORT + ( + address : IN STD_LOGIC_VECTOR (widthad_a-1 DOWNTO 0); + clock : IN STD_LOGIC ; + q : OUT STD_LOGIC_VECTOR (width_a-1 DOWNTO 0) + ); +END sprom; + + +ARCHITECTURE SYN OF sprom IS + + SIGNAL sub_wire0 : STD_LOGIC_VECTOR (width_a-1 DOWNTO 0); + + + + COMPONENT altsyncram + GENERIC ( + address_aclr_a : STRING; + clock_enable_input_a : STRING; + clock_enable_output_a : STRING; + init_file : STRING; + intended_device_family : STRING; + lpm_hint : STRING; + lpm_type : STRING; + numwords_a : NATURAL; + operation_mode : STRING; + outdata_aclr_a : STRING; + outdata_reg_a : STRING; + widthad_a : NATURAL; + width_a : NATURAL; + width_byteena_a : NATURAL + ); + PORT ( + clock0 : IN STD_LOGIC ; + address_a : IN STD_LOGIC_VECTOR (widthad_a-1 DOWNTO 0); + q_a : OUT STD_LOGIC_VECTOR (width_a-1 DOWNTO 0) + ); + END COMPONENT; + +BEGIN + q <= sub_wire0(width_a-1 DOWNTO 0); + + altsyncram_component : altsyncram + GENERIC MAP ( + address_aclr_a => "NONE", + clock_enable_input_a => "BYPASS", + clock_enable_output_a => "BYPASS", + init_file => init_file, + intended_device_family => "Cyclone III", + lpm_hint => "ENABLE_RUNTIME_MOD=NO", + lpm_type => "altsyncram", + numwords_a => 2**widthad_a, + operation_mode => "ROM", + outdata_aclr_a => "NONE", + outdata_reg_a => outdata_reg_a, + widthad_a => widthad_a, + width_a => width_a, + width_byteena_a => 1 + ) + PORT MAP ( + clock0 => clock, + address_a => address, + q_a => sub_wire0 + ); + + + +END SYN; diff --git a/Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/video_mixer.sv b/Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/video_mixer.sv similarity index 100% rename from Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/video_mixer.sv rename to Arcade_MiST/Phoenix Hardware/Capitol_MIST/rtl/video_mixer.sv diff --git a/Arcade_MiST/Custom Hardware/Phoenix.jpg b/Arcade_MiST/Phoenix Hardware/Phoenix.jpg similarity index 100% rename from Arcade_MiST/Custom Hardware/Phoenix.jpg rename to Arcade_MiST/Phoenix Hardware/Phoenix.jpg diff --git a/Arcade_MiST/Custom Hardware/Phoenix_MIST/README.txt b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/README.txt similarity index 100% rename from Arcade_MiST/Custom Hardware/Phoenix_MIST/README.txt rename to Arcade_MiST/Phoenix Hardware/Phoenix_MIST/README.txt diff --git a/Arcade_MiST/Custom Hardware/Phoenix_MIST/Release/phoenix_mist.rbf b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/Release/phoenix_mist.rbf similarity index 100% rename from Arcade_MiST/Custom Hardware/Phoenix_MIST/Release/phoenix_mist.rbf rename to Arcade_MiST/Phoenix Hardware/Phoenix_MIST/Release/phoenix_mist.rbf diff --git a/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/clean.bat b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/clean.bat new file mode 100644 index 00000000..83fb0c47 --- /dev/null +++ b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/clean.bat @@ -0,0 +1,15 @@ +@echo off +del /s *.bak +del /s *.orig +del /s *.rej +rmdir /s /q db +rmdir /s /q incremental_db +rmdir /s /q output_files +rmdir /s /q simulation +rmdir /s /q greybox_tmp +del PLLJ_PLLSPE_INFO.txt +del *.qws +del *.ppf +del *.qip +del *.ddb +pause diff --git a/Arcade_MiST/Custom Hardware/Phoenix_MIST/phoenix_mist.qpf b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/phoenix_mist.qpf similarity index 100% rename from Arcade_MiST/Custom Hardware/Phoenix_MIST/phoenix_mist.qpf rename to Arcade_MiST/Phoenix Hardware/Phoenix_MIST/phoenix_mist.qpf diff --git a/Arcade_MiST/Custom Hardware/Phoenix_MIST/phoenix_mist.qsf b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/phoenix_mist.qsf similarity index 100% rename from Arcade_MiST/Custom Hardware/Phoenix_MIST/phoenix_mist.qsf rename to Arcade_MiST/Phoenix Hardware/Phoenix_MIST/phoenix_mist.qsf diff --git a/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/phoenix_mist.sdc b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/phoenix_mist.sdc new file mode 100644 index 00000000..3eba3b05 --- /dev/null +++ b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/phoenix_mist.sdc @@ -0,0 +1,33 @@ +#************************************************************ +# THIS IS A WIZARD-GENERATED FILE. +# +# Version 13.1.4 Build 182 03/12/2014 SJ Full Version +# +#************************************************************ + +# 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. + + + +# Clock constraints + +create_clock -name "CLOCK_27" -period 37.037 [get_ports {CLOCK_27}] +create_clock -name {SPI_SCK} -period 10.000 -waveform { 0.000 0.500 } [get_ports {SPI_SCK}] + +# 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 diff --git a/Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/Phoenix_MiST.sv b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/Phoenix_MiST.sv similarity index 100% rename from Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/Phoenix_MiST.sv rename to Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/Phoenix_MiST.sv diff --git a/Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/ROM/prom_ic23.vhd b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/ROM/prom_ic23.vhd similarity index 100% rename from Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/ROM/prom_ic23.vhd rename to Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/ROM/prom_ic23.vhd diff --git a/Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/ROM/prom_ic24.vhd b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/ROM/prom_ic24.vhd similarity index 100% rename from Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/ROM/prom_ic24.vhd rename to Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/ROM/prom_ic24.vhd diff --git a/Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/ROM/prom_ic39.vhd b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/ROM/prom_ic39.vhd similarity index 100% rename from Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/ROM/prom_ic39.vhd rename to Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/ROM/prom_ic39.vhd diff --git a/Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/ROM/prom_ic40.vhd b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/ROM/prom_ic40.vhd similarity index 100% rename from Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/ROM/prom_ic40.vhd rename to Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/ROM/prom_ic40.vhd diff --git a/Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/ROM/prom_palette_ic40.vhd b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/ROM/prom_palette_ic40.vhd similarity index 100% rename from Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/ROM/prom_palette_ic40.vhd rename to Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/ROM/prom_palette_ic40.vhd diff --git a/Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/ROM/prom_palette_ic41.vhd b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/ROM/prom_palette_ic41.vhd similarity index 100% rename from Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/ROM/prom_palette_ic41.vhd rename to Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/ROM/prom_palette_ic41.vhd diff --git a/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/T80/T80.vhd b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/T80/T80.vhd new file mode 100644 index 00000000..398fa0df --- /dev/null +++ b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/T80/T80.vhd @@ -0,0 +1,1073 @@ +-- +-- Z80 compatible microprocessor core +-- +-- Version : 0247 +-- +-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t80/ +-- +-- Limitations : +-- +-- File history : +-- +-- 0208 : First complete release +-- +-- 0210 : Fixed wait and halt +-- +-- 0211 : Fixed Refresh addition and IM 1 +-- +-- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test +-- +-- 0232 : Removed refresh address output for Mode > 1 and added DJNZ M1_n fix by Mike Johnson +-- +-- 0235 : Added clock enable and IM 2 fix by Mike Johnson +-- +-- 0237 : Changed 8080 I/O address output, added IntE output +-- +-- 0238 : Fixed (IX/IY+d) timing and 16 bit ADC and SBC zero flag +-- +-- 0240 : Added interrupt ack fix by Mike Johnson, changed (IX/IY+d) timing and changed flags in GB mode +-- +-- 0242 : Added I/O wait, fixed refresh address, moved some registers to RAM +-- +-- 0247 : Fixed bus req/ack cycle +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; +use work.T80_Pack.all; + +entity T80 is + generic( + Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB + IOWait : integer := 0; -- 1 => Single cycle I/O, 1 => Std I/O cycle + Flag_C : integer := 0; + Flag_N : integer := 1; + Flag_P : integer := 2; + Flag_X : integer := 3; + Flag_H : integer := 4; + Flag_Y : integer := 5; + Flag_Z : integer := 6; + Flag_S : integer := 7 + ); + port( + RESET_n : in std_logic; + CLK_n : in std_logic; + CEN : in std_logic; + WAIT_n : in std_logic; + INT_n : in std_logic; + NMI_n : in std_logic; + BUSRQ_n : in std_logic; + M1_n : out std_logic; + IORQ : out std_logic; + NoRead : out std_logic; + Write : out std_logic; + RFSH_n : out std_logic; + HALT_n : out std_logic; + BUSAK_n : out std_logic; + A : out std_logic_vector(15 downto 0); + DInst : in std_logic_vector(7 downto 0); + DI : in std_logic_vector(7 downto 0); + DO : out std_logic_vector(7 downto 0); + MC : out std_logic_vector(2 downto 0); + TS : out std_logic_vector(2 downto 0); + IntCycle_n : out std_logic; + IntE : out std_logic; + Stop : out std_logic + ); +end T80; + +architecture rtl of T80 is + + constant aNone : std_logic_vector(2 downto 0) := "111"; + constant aBC : std_logic_vector(2 downto 0) := "000"; + constant aDE : std_logic_vector(2 downto 0) := "001"; + constant aXY : std_logic_vector(2 downto 0) := "010"; + constant aIOA : std_logic_vector(2 downto 0) := "100"; + constant aSP : std_logic_vector(2 downto 0) := "101"; + constant aZI : std_logic_vector(2 downto 0) := "110"; + + -- Registers + signal ACC, F : std_logic_vector(7 downto 0); + signal Ap, Fp : std_logic_vector(7 downto 0); + signal I : std_logic_vector(7 downto 0); + signal R : unsigned(7 downto 0); + signal SP, PC : unsigned(15 downto 0); + signal RegDIH : std_logic_vector(7 downto 0); + signal RegDIL : std_logic_vector(7 downto 0); + signal RegBusA : std_logic_vector(15 downto 0); + signal RegBusB : std_logic_vector(15 downto 0); + signal RegBusC : std_logic_vector(15 downto 0); + signal RegAddrA_r : std_logic_vector(2 downto 0); + signal RegAddrA : std_logic_vector(2 downto 0); + signal RegAddrB_r : std_logic_vector(2 downto 0); + signal RegAddrB : std_logic_vector(2 downto 0); + signal RegAddrC : std_logic_vector(2 downto 0); + signal RegWEH : std_logic; + signal RegWEL : std_logic; + signal Alternate : std_logic; + + -- Help Registers + signal TmpAddr : std_logic_vector(15 downto 0); -- Temporary address register + signal IR : std_logic_vector(7 downto 0); -- Instruction register + signal ISet : std_logic_vector(1 downto 0); -- Instruction set selector + signal RegBusA_r : std_logic_vector(15 downto 0); + + signal ID16 : signed(15 downto 0); + signal Save_Mux : std_logic_vector(7 downto 0); + + signal TState : unsigned(2 downto 0); + signal MCycle : std_logic_vector(2 downto 0); + signal IntE_FF1 : std_logic; + signal IntE_FF2 : std_logic; + signal Halt_FF : std_logic; + signal BusReq_s : std_logic; + signal BusAck : std_logic; + signal ClkEn : std_logic; + signal NMI_s : std_logic; + signal INT_s : std_logic; + signal IStatus : std_logic_vector(1 downto 0); + + signal DI_Reg : std_logic_vector(7 downto 0); + signal T_Res : std_logic; + signal XY_State : std_logic_vector(1 downto 0); + signal Pre_XY_F_M : std_logic_vector(2 downto 0); + signal NextIs_XY_Fetch : std_logic; + signal XY_Ind : std_logic; + signal No_BTR : std_logic; + signal BTR_r : std_logic; + signal Auto_Wait : std_logic; + signal Auto_Wait_t1 : std_logic; + signal Auto_Wait_t2 : std_logic; + signal IncDecZ : std_logic; + + -- ALU signals + signal BusB : std_logic_vector(7 downto 0); + signal BusA : std_logic_vector(7 downto 0); + signal ALU_Q : std_logic_vector(7 downto 0); + signal F_Out : std_logic_vector(7 downto 0); + + -- Registered micro code outputs + signal Read_To_Reg_r : std_logic_vector(4 downto 0); + signal Arith16_r : std_logic; + signal Z16_r : std_logic; + signal ALU_Op_r : std_logic_vector(3 downto 0); + signal Save_ALU_r : std_logic; + signal PreserveC_r : std_logic; + signal MCycles : std_logic_vector(2 downto 0); + + -- Micro code outputs + signal MCycles_d : std_logic_vector(2 downto 0); + signal TStates : std_logic_vector(2 downto 0); + signal IntCycle : std_logic; + signal NMICycle : std_logic; + signal Inc_PC : std_logic; + signal Inc_WZ : std_logic; + signal IncDec_16 : std_logic_vector(3 downto 0); + signal Prefix : std_logic_vector(1 downto 0); + signal Read_To_Acc : std_logic; + signal Read_To_Reg : std_logic; + signal Set_BusB_To : std_logic_vector(3 downto 0); + signal Set_BusA_To : std_logic_vector(3 downto 0); + signal ALU_Op : std_logic_vector(3 downto 0); + signal Save_ALU : std_logic; + signal PreserveC : std_logic; + signal Arith16 : std_logic; + signal Set_Addr_To : std_logic_vector(2 downto 0); + signal Jump : std_logic; + signal JumpE : std_logic; + signal JumpXY : std_logic; + signal Call : std_logic; + signal RstP : std_logic; + signal LDZ : std_logic; + signal LDW : std_logic; + signal LDSPHL : std_logic; + signal IORQ_i : std_logic; + signal Special_LD : std_logic_vector(2 downto 0); + signal ExchangeDH : std_logic; + signal ExchangeRp : std_logic; + signal ExchangeAF : std_logic; + signal ExchangeRS : std_logic; + signal I_DJNZ : std_logic; + signal I_CPL : std_logic; + signal I_CCF : std_logic; + signal I_SCF : std_logic; + signal I_RETN : std_logic; + signal I_BT : std_logic; + signal I_BC : std_logic; + signal I_BTR : std_logic; + signal I_RLD : std_logic; + signal I_RRD : std_logic; + signal I_INRC : std_logic; + signal SetDI : std_logic; + signal SetEI : std_logic; + signal IMode : std_logic_vector(1 downto 0); + signal Halt : std_logic; + +begin + + mcode : T80_MCode + generic map( + Mode => Mode, + Flag_C => Flag_C, + Flag_N => Flag_N, + Flag_P => Flag_P, + Flag_X => Flag_X, + Flag_H => Flag_H, + Flag_Y => Flag_Y, + Flag_Z => Flag_Z, + Flag_S => Flag_S) + port map( + IR => IR, + ISet => ISet, + MCycle => MCycle, + F => F, + NMICycle => NMICycle, + IntCycle => IntCycle, + MCycles => MCycles_d, + TStates => TStates, + Prefix => Prefix, + Inc_PC => Inc_PC, + Inc_WZ => Inc_WZ, + IncDec_16 => IncDec_16, + Read_To_Acc => Read_To_Acc, + Read_To_Reg => Read_To_Reg, + Set_BusB_To => Set_BusB_To, + Set_BusA_To => Set_BusA_To, + ALU_Op => ALU_Op, + Save_ALU => Save_ALU, + PreserveC => PreserveC, + Arith16 => Arith16, + Set_Addr_To => Set_Addr_To, + IORQ => IORQ_i, + Jump => Jump, + JumpE => JumpE, + JumpXY => JumpXY, + Call => Call, + RstP => RstP, + LDZ => LDZ, + LDW => LDW, + LDSPHL => LDSPHL, + Special_LD => Special_LD, + ExchangeDH => ExchangeDH, + ExchangeRp => ExchangeRp, + ExchangeAF => ExchangeAF, + ExchangeRS => ExchangeRS, + I_DJNZ => I_DJNZ, + I_CPL => I_CPL, + I_CCF => I_CCF, + I_SCF => I_SCF, + I_RETN => I_RETN, + I_BT => I_BT, + I_BC => I_BC, + I_BTR => I_BTR, + I_RLD => I_RLD, + I_RRD => I_RRD, + I_INRC => I_INRC, + SetDI => SetDI, + SetEI => SetEI, + IMode => IMode, + Halt => Halt, + NoRead => NoRead, + Write => Write); + + alu : T80_ALU + generic map( + Mode => Mode, + Flag_C => Flag_C, + Flag_N => Flag_N, + Flag_P => Flag_P, + Flag_X => Flag_X, + Flag_H => Flag_H, + Flag_Y => Flag_Y, + Flag_Z => Flag_Z, + Flag_S => Flag_S) + port map( + Arith16 => Arith16_r, + Z16 => Z16_r, + ALU_Op => ALU_Op_r, + IR => IR(5 downto 0), + ISet => ISet, + BusA => BusA, + BusB => BusB, + F_In => F, + Q => ALU_Q, + F_Out => F_Out); + + ClkEn <= CEN and not BusAck; + + T_Res <= '1' when TState = unsigned(TStates) else '0'; + + NextIs_XY_Fetch <= '1' when XY_State /= "00" and XY_Ind = '0' and + ((Set_Addr_To = aXY) or + (MCycle = "001" and IR = "11001011") or + (MCycle = "001" and IR = "00110110")) else '0'; + + Save_Mux <= BusB when ExchangeRp = '1' else + DI_Reg when Save_ALU_r = '0' else + ALU_Q; + + process (RESET_n, CLK_n) + begin + if RESET_n = '0' then + PC <= (others => '0'); -- Program Counter + A <= (others => '0'); + TmpAddr <= (others => '0'); + IR <= "00000000"; + ISet <= "00"; + XY_State <= "00"; + IStatus <= "00"; + MCycles <= "000"; + DO <= "00000000"; + + ACC <= (others => '1'); + F <= (others => '1'); + Ap <= (others => '1'); + Fp <= (others => '1'); + I <= (others => '0'); + R <= (others => '0'); + SP <= (others => '1'); + Alternate <= '0'; + + Read_To_Reg_r <= "00000"; + F <= (others => '1'); + Arith16_r <= '0'; + BTR_r <= '0'; + Z16_r <= '0'; + ALU_Op_r <= "0000"; + Save_ALU_r <= '0'; + PreserveC_r <= '0'; + XY_Ind <= '0'; + + elsif CLK_n'event and CLK_n = '1' then + + if ClkEn = '1' then + + ALU_Op_r <= "0000"; + Save_ALU_r <= '0'; + Read_To_Reg_r <= "00000"; + + MCycles <= MCycles_d; + + if IMode /= "11" then + IStatus <= IMode; + end if; + + Arith16_r <= Arith16; + PreserveC_r <= PreserveC; + if ISet = "10" and ALU_OP(2) = '0' and ALU_OP(0) = '1' and MCycle = "011" then + Z16_r <= '1'; + else + Z16_r <= '0'; + end if; + + if MCycle = "001" and TState(2) = '0' then + -- MCycle = 1 and TState = 1, 2, or 3 + + if TState = 2 and Wait_n = '1' then + if Mode < 2 then + A(7 downto 0) <= std_logic_vector(R); + A(15 downto 8) <= I; + R(6 downto 0) <= R(6 downto 0) + 1; + end if; + + if Jump = '0' and Call = '0' and NMICycle = '0' and IntCycle = '0' and not (Halt_FF = '1' or Halt = '1') then + PC <= PC + 1; + end if; + + if IntCycle = '1' and IStatus = "01" then + IR <= "11111111"; + elsif Halt_FF = '1' or (IntCycle = '1' and IStatus = "10") or NMICycle = '1' then + IR <= "00000000"; + else + IR <= DInst; + end if; + + ISet <= "00"; + if Prefix /= "00" then + if Prefix = "11" then + if IR(5) = '1' then + XY_State <= "10"; + else + XY_State <= "01"; + end if; + else + if Prefix = "10" then + XY_State <= "00"; + XY_Ind <= '0'; + end if; + ISet <= Prefix; + end if; + else + XY_State <= "00"; + XY_Ind <= '0'; + end if; + end if; + + else + -- either (MCycle > 1) OR (MCycle = 1 AND TState > 3) + + if MCycle = "110" then + XY_Ind <= '1'; + if Prefix = "01" then + ISet <= "01"; + end if; + end if; + + if T_Res = '1' then + BTR_r <= (I_BT or I_BC or I_BTR) and not No_BTR; + if Jump = '1' then + A(15 downto 8) <= DI_Reg; + A(7 downto 0) <= TmpAddr(7 downto 0); + PC(15 downto 8) <= unsigned(DI_Reg); + PC(7 downto 0) <= unsigned(TmpAddr(7 downto 0)); + elsif JumpXY = '1' then + A <= RegBusC; + PC <= unsigned(RegBusC); + elsif Call = '1' or RstP = '1' then + A <= TmpAddr; + PC <= unsigned(TmpAddr); + elsif MCycle = MCycles and NMICycle = '1' then + A <= "0000000001100110"; + PC <= "0000000001100110"; + elsif MCycle = "011" and IntCycle = '1' and IStatus = "10" then + A(15 downto 8) <= I; + A(7 downto 0) <= TmpAddr(7 downto 0); + PC(15 downto 8) <= unsigned(I); + PC(7 downto 0) <= unsigned(TmpAddr(7 downto 0)); + else + case Set_Addr_To is + when aXY => + if XY_State = "00" then + A <= RegBusC; + else + if NextIs_XY_Fetch = '1' then + A <= std_logic_vector(PC); + else + A <= TmpAddr; + end if; + end if; + when aIOA => + if Mode = 3 then + -- Memory map I/O on GBZ80 + A(15 downto 8) <= (others => '1'); + elsif Mode = 2 then + -- Duplicate I/O address on 8080 + A(15 downto 8) <= DI_Reg; + else + A(15 downto 8) <= ACC; + end if; + A(7 downto 0) <= DI_Reg; + when aSP => + A <= std_logic_vector(SP); + when aBC => + if Mode = 3 and IORQ_i = '1' then + -- Memory map I/O on GBZ80 + A(15 downto 8) <= (others => '1'); + A(7 downto 0) <= RegBusC(7 downto 0); + else + A <= RegBusC; + end if; + when aDE => + A <= RegBusC; + when aZI => + if Inc_WZ = '1' then + A <= std_logic_vector(unsigned(TmpAddr) + 1); + else + A(15 downto 8) <= DI_Reg; + A(7 downto 0) <= TmpAddr(7 downto 0); + end if; + when others => + A <= std_logic_vector(PC); + end case; + end if; + + Save_ALU_r <= Save_ALU; + ALU_Op_r <= ALU_Op; + + if I_CPL = '1' then + -- CPL + ACC <= not ACC; + F(Flag_Y) <= not ACC(5); + F(Flag_H) <= '1'; + F(Flag_X) <= not ACC(3); + F(Flag_N) <= '1'; + end if; + if I_CCF = '1' then + -- CCF + F(Flag_C) <= not F(Flag_C); + F(Flag_Y) <= ACC(5); + F(Flag_H) <= F(Flag_C); + F(Flag_X) <= ACC(3); + F(Flag_N) <= '0'; + end if; + if I_SCF = '1' then + -- SCF + F(Flag_C) <= '1'; + F(Flag_Y) <= ACC(5); + F(Flag_H) <= '0'; + F(Flag_X) <= ACC(3); + F(Flag_N) <= '0'; + end if; + end if; + + if TState = 2 and Wait_n = '1' then + if ISet = "01" and MCycle = "111" then + IR <= DInst; + end if; + if JumpE = '1' then + PC <= unsigned(signed(PC) + signed(DI_Reg)); + elsif Inc_PC = '1' then + PC <= PC + 1; + end if; + if BTR_r = '1' then + PC <= PC - 2; + end if; + if RstP = '1' then + TmpAddr <= (others =>'0'); + TmpAddr(5 downto 3) <= IR(5 downto 3); + end if; + end if; + if TState = 3 and MCycle = "110" then + TmpAddr <= std_logic_vector(signed(RegBusC) + signed(DI_Reg)); + end if; + + if (TState = 2 and Wait_n = '1') or (TState = 4 and MCycle = "001") then + if IncDec_16(2 downto 0) = "111" then + if IncDec_16(3) = '1' then + SP <= SP - 1; + else + SP <= SP + 1; + end if; + end if; + end if; + + if LDSPHL = '1' then + SP <= unsigned(RegBusC); + end if; + if ExchangeAF = '1' then + Ap <= ACC; + ACC <= Ap; + Fp <= F; + F <= Fp; + end if; + if ExchangeRS = '1' then + Alternate <= not Alternate; + end if; + end if; + + if TState = 3 then + if LDZ = '1' then + TmpAddr(7 downto 0) <= DI_Reg; + end if; + if LDW = '1' then + TmpAddr(15 downto 8) <= DI_Reg; + end if; + + if Special_LD(2) = '1' then + case Special_LD(1 downto 0) is + when "00" => + ACC <= I; + F(Flag_P) <= IntE_FF2; + when "01" => + ACC <= std_logic_vector(R); + F(Flag_P) <= IntE_FF2; + when "10" => + I <= ACC; + when others => + R <= unsigned(ACC); + end case; + end if; + end if; + + if (I_DJNZ = '0' and Save_ALU_r = '1') or ALU_Op_r = "1001" then + if Mode = 3 then + F(6) <= F_Out(6); + F(5) <= F_Out(5); + F(7) <= F_Out(7); + if PreserveC_r = '0' then + F(4) <= F_Out(4); + end if; + else + F(7 downto 1) <= F_Out(7 downto 1); + if PreserveC_r = '0' then + F(Flag_C) <= F_Out(0); + end if; + end if; + end if; + if T_Res = '1' and I_INRC = '1' then + F(Flag_H) <= '0'; + F(Flag_N) <= '0'; + if DI_Reg(7 downto 0) = "00000000" then + F(Flag_Z) <= '1'; + else + F(Flag_Z) <= '0'; + end if; + F(Flag_S) <= DI_Reg(7); + F(Flag_P) <= not (DI_Reg(0) xor DI_Reg(1) xor DI_Reg(2) xor DI_Reg(3) xor + DI_Reg(4) xor DI_Reg(5) xor DI_Reg(6) xor DI_Reg(7)); + end if; + + if TState = 1 and Auto_Wait_t1 = '0' then + DO <= BusB; + if I_RLD = '1' then + DO(3 downto 0) <= BusA(3 downto 0); + DO(7 downto 4) <= BusB(3 downto 0); + end if; + if I_RRD = '1' then + DO(3 downto 0) <= BusB(7 downto 4); + DO(7 downto 4) <= BusA(3 downto 0); + end if; + end if; + + if T_Res = '1' then + Read_To_Reg_r(3 downto 0) <= Set_BusA_To; + Read_To_Reg_r(4) <= Read_To_Reg; + if Read_To_Acc = '1' then + Read_To_Reg_r(3 downto 0) <= "0111"; + Read_To_Reg_r(4) <= '1'; + end if; + end if; + + if TState = 1 and I_BT = '1' then + F(Flag_X) <= ALU_Q(3); + F(Flag_Y) <= ALU_Q(1); + F(Flag_H) <= '0'; + F(Flag_N) <= '0'; + end if; + if I_BC = '1' or I_BT = '1' then + F(Flag_P) <= IncDecZ; + end if; + + if (TState = 1 and Save_ALU_r = '0' and Auto_Wait_t1 = '0') or + (Save_ALU_r = '1' and ALU_OP_r /= "0111") then + case Read_To_Reg_r is + when "10111" => + ACC <= Save_Mux; + when "10110" => + DO <= Save_Mux; + when "11000" => + SP(7 downto 0) <= unsigned(Save_Mux); + when "11001" => + SP(15 downto 8) <= unsigned(Save_Mux); + when "11011" => + F <= Save_Mux; + when others => + end case; + end if; + + end if; + + end if; + + end process; + +--------------------------------------------------------------------------- +-- +-- BC('), DE('), HL('), IX and IY +-- +--------------------------------------------------------------------------- + process (CLK_n) + begin + if CLK_n'event and CLK_n = '1' then + if ClkEn = '1' then + -- Bus A / Write + RegAddrA_r <= Alternate & Set_BusA_To(2 downto 1); + if XY_Ind = '0' and XY_State /= "00" and Set_BusA_To(2 downto 1) = "10" then + RegAddrA_r <= XY_State(1) & "11"; + end if; + + -- Bus B + RegAddrB_r <= Alternate & Set_BusB_To(2 downto 1); + if XY_Ind = '0' and XY_State /= "00" and Set_BusB_To(2 downto 1) = "10" then + RegAddrB_r <= XY_State(1) & "11"; + end if; + + -- Address from register + RegAddrC <= Alternate & Set_Addr_To(1 downto 0); + -- Jump (HL), LD SP,HL + if (JumpXY = '1' or LDSPHL = '1') then + RegAddrC <= Alternate & "10"; + end if; + if ((JumpXY = '1' or LDSPHL = '1') and XY_State /= "00") or (MCycle = "110") then + RegAddrC <= XY_State(1) & "11"; + end if; + + if I_DJNZ = '1' and Save_ALU_r = '1' and Mode < 2 then + IncDecZ <= F_Out(Flag_Z); + end if; + if (TState = 2 or (TState = 3 and MCycle = "001")) and IncDec_16(2 downto 0) = "100" then + if ID16 = 0 then + IncDecZ <= '0'; + else + IncDecZ <= '1'; + end if; + end if; + + RegBusA_r <= RegBusA; + end if; + end if; + end process; + + RegAddrA <= + -- 16 bit increment/decrement + Alternate & IncDec_16(1 downto 0) when (TState = 2 or + (TState = 3 and MCycle = "001" and IncDec_16(2) = '1')) and XY_State = "00" else + XY_State(1) & "11" when (TState = 2 or + (TState = 3 and MCycle = "001" and IncDec_16(2) = '1')) and IncDec_16(1 downto 0) = "10" else + -- EX HL,DL + Alternate & "10" when ExchangeDH = '1' and TState = 3 else + Alternate & "01" when ExchangeDH = '1' and TState = 4 else + -- Bus A / Write + RegAddrA_r; + + RegAddrB <= + -- EX HL,DL + Alternate & "01" when ExchangeDH = '1' and TState = 3 else + -- Bus B + RegAddrB_r; + + ID16 <= signed(RegBusA) - 1 when IncDec_16(3) = '1' else + signed(RegBusA) + 1; + + process (Save_ALU_r, Auto_Wait_t1, ALU_OP_r, Read_To_Reg_r, + ExchangeDH, IncDec_16, MCycle, TState, Wait_n) + begin + RegWEH <= '0'; + RegWEL <= '0'; + if (TState = 1 and Save_ALU_r = '0' and Auto_Wait_t1 = '0') or + (Save_ALU_r = '1' and ALU_OP_r /= "0111") then + case Read_To_Reg_r is + when "10000" | "10001" | "10010" | "10011" | "10100" | "10101" => + RegWEH <= not Read_To_Reg_r(0); + RegWEL <= Read_To_Reg_r(0); + when others => + end case; + end if; + + if ExchangeDH = '1' and (TState = 3 or TState = 4) then + RegWEH <= '1'; + RegWEL <= '1'; + end if; + + if IncDec_16(2) = '1' and ((TState = 2 and Wait_n = '1' and MCycle /= "001") or (TState = 3 and MCycle = "001")) then + case IncDec_16(1 downto 0) is + when "00" | "01" | "10" => + RegWEH <= '1'; + RegWEL <= '1'; + when others => + end case; + end if; + end process; + + process (Save_Mux, RegBusB, RegBusA_r, ID16, + ExchangeDH, IncDec_16, MCycle, TState, Wait_n) + begin + RegDIH <= Save_Mux; + RegDIL <= Save_Mux; + + if ExchangeDH = '1' and TState = 3 then + RegDIH <= RegBusB(15 downto 8); + RegDIL <= RegBusB(7 downto 0); + end if; + if ExchangeDH = '1' and TState = 4 then + RegDIH <= RegBusA_r(15 downto 8); + RegDIL <= RegBusA_r(7 downto 0); + end if; + + if IncDec_16(2) = '1' and ((TState = 2 and MCycle /= "001") or (TState = 3 and MCycle = "001")) then + RegDIH <= std_logic_vector(ID16(15 downto 8)); + RegDIL <= std_logic_vector(ID16(7 downto 0)); + end if; + end process; + + Regs : T80_Reg + port map( + Clk => CLK_n, + CEN => ClkEn, + WEH => RegWEH, + WEL => RegWEL, + AddrA => RegAddrA, + AddrB => RegAddrB, + AddrC => RegAddrC, + DIH => RegDIH, + DIL => RegDIL, + DOAH => RegBusA(15 downto 8), + DOAL => RegBusA(7 downto 0), + DOBH => RegBusB(15 downto 8), + DOBL => RegBusB(7 downto 0), + DOCH => RegBusC(15 downto 8), + DOCL => RegBusC(7 downto 0)); + +--------------------------------------------------------------------------- +-- +-- Buses +-- +--------------------------------------------------------------------------- + process (CLK_n) + begin + if CLK_n'event and CLK_n = '1' then + if ClkEn = '1' then + case Set_BusB_To is + when "0111" => + BusB <= ACC; + when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" => + if Set_BusB_To(0) = '1' then + BusB <= RegBusB(7 downto 0); + else + BusB <= RegBusB(15 downto 8); + end if; + when "0110" => + BusB <= DI_Reg; + when "1000" => + BusB <= std_logic_vector(SP(7 downto 0)); + when "1001" => + BusB <= std_logic_vector(SP(15 downto 8)); + when "1010" => + BusB <= "00000001"; + when "1011" => + BusB <= F; + when "1100" => + BusB <= std_logic_vector(PC(7 downto 0)); + when "1101" => + BusB <= std_logic_vector(PC(15 downto 8)); + when "1110" => + BusB <= "00000000"; + when others => + BusB <= "--------"; + end case; + + case Set_BusA_To is + when "0111" => + BusA <= ACC; + when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" => + if Set_BusA_To(0) = '1' then + BusA <= RegBusA(7 downto 0); + else + BusA <= RegBusA(15 downto 8); + end if; + when "0110" => + BusA <= DI_Reg; + when "1000" => + BusA <= std_logic_vector(SP(7 downto 0)); + when "1001" => + BusA <= std_logic_vector(SP(15 downto 8)); + when "1010" => + BusA <= "00000000"; + when others => + BusB <= "--------"; + end case; + end if; + end if; + end process; + +--------------------------------------------------------------------------- +-- +-- Generate external control signals +-- +--------------------------------------------------------------------------- + process (RESET_n,CLK_n) + begin + if RESET_n = '0' then + RFSH_n <= '1'; + elsif CLK_n'event and CLK_n = '1' then + if CEN = '1' then + if MCycle = "001" and ((TState = 2 and Wait_n = '1') or TState = 3) then + RFSH_n <= '0'; + else + RFSH_n <= '1'; + end if; + end if; + end if; + end process; + + MC <= std_logic_vector(MCycle); + TS <= std_logic_vector(TState); + DI_Reg <= DI; + HALT_n <= not Halt_FF; + BUSAK_n <= not BusAck; + IntCycle_n <= not IntCycle; + IntE <= IntE_FF1; + IORQ <= IORQ_i; + Stop <= I_DJNZ; + +------------------------------------------------------------------------- +-- +-- Syncronise inputs +-- +------------------------------------------------------------------------- + process (RESET_n, CLK_n) + variable OldNMI_n : std_logic; + begin + if RESET_n = '0' then + BusReq_s <= '0'; + INT_s <= '0'; + NMI_s <= '0'; + OldNMI_n := '0'; + elsif CLK_n'event and CLK_n = '1' then + if CEN = '1' then + BusReq_s <= not BUSRQ_n; + INT_s <= not INT_n; + if NMICycle = '1' then + NMI_s <= '0'; + elsif NMI_n = '0' and OldNMI_n = '1' then + NMI_s <= '1'; + end if; + OldNMI_n := NMI_n; + end if; + end if; + end process; + +------------------------------------------------------------------------- +-- +-- Main state machine +-- +------------------------------------------------------------------------- + process (RESET_n, CLK_n) + begin + if RESET_n = '0' then + MCycle <= "001"; + TState <= "000"; + Pre_XY_F_M <= "000"; + Halt_FF <= '0'; + BusAck <= '0'; + NMICycle <= '0'; + IntCycle <= '0'; + IntE_FF1 <= '0'; + IntE_FF2 <= '0'; + No_BTR <= '0'; + Auto_Wait_t1 <= '0'; + Auto_Wait_t2 <= '0'; + M1_n <= '1'; + elsif CLK_n'event and CLK_n = '1' then + if CEN = '1' then + if T_Res = '1' then + Auto_Wait_t1 <= '0'; + else + Auto_Wait_t1 <= Auto_Wait or IORQ_i; + end if; + Auto_Wait_t2 <= Auto_Wait_t1; + No_BTR <= (I_BT and (not IR(4) or not F(Flag_P))) or + (I_BC and (not IR(4) or F(Flag_Z) or not F(Flag_P))) or + (I_BTR and (not IR(4) or F(Flag_Z))); + if TState = 2 then + if SetEI = '1' then + IntE_FF1 <= '1'; + IntE_FF2 <= '1'; + end if; + if I_RETN = '1' then + IntE_FF1 <= IntE_FF2; + end if; + end if; + if TState = 3 then + if SetDI = '1' then + IntE_FF1 <= '0'; + IntE_FF2 <= '0'; + end if; + end if; + if IntCycle = '1' or NMICycle = '1' then + Halt_FF <= '0'; + end if; + if MCycle = "001" and TState = 2 and Wait_n = '1' then + M1_n <= '1'; + end if; + if BusReq_s = '1' and BusAck = '1' then + else + BusAck <= '0'; + if TState = 2 and Wait_n = '0' then + elsif T_Res = '1' then + if Halt = '1' then + Halt_FF <= '1'; + end if; + if BusReq_s = '1' then + BusAck <= '1'; + else + TState <= "001"; + if NextIs_XY_Fetch = '1' then + MCycle <= "110"; + Pre_XY_F_M <= MCycle; + if IR = "00110110" and Mode = 0 then + Pre_XY_F_M <= "010"; + end if; + elsif (MCycle = "111") or + (MCycle = "110" and Mode = 1 and ISet /= "01") then + MCycle <= std_logic_vector(unsigned(Pre_XY_F_M) + 1); + elsif (MCycle = MCycles) or + No_BTR = '1' or + (MCycle = "010" and I_DJNZ = '1' and IncDecZ = '1') then + M1_n <= '0'; + MCycle <= "001"; + IntCycle <= '0'; + NMICycle <= '0'; + if NMI_s = '1' and Prefix = "00" then + NMICycle <= '1'; + IntE_FF1 <= '0'; + elsif (IntE_FF1 = '1' and INT_s = '1') and Prefix = "00" and SetEI = '0' then + IntCycle <= '1'; + IntE_FF1 <= '0'; + IntE_FF2 <= '0'; + end if; + else + MCycle <= std_logic_vector(unsigned(MCycle) + 1); + end if; + end if; + else + if (Auto_Wait = '1' and Auto_Wait_t2 = '0') nor + (IOWait = 1 and IORQ_i = '1' and Auto_Wait_t1 = '0') then + TState <= TState + 1; + end if; + end if; + end if; + if TState = 0 then + M1_n <= '0'; + end if; + end if; + end if; + end process; + + process (IntCycle, NMICycle, MCycle) + begin + Auto_Wait <= '0'; + if IntCycle = '1' or NMICycle = '1' then + if MCycle = "001" then + Auto_Wait <= '1'; + end if; + end if; + end process; + +end; diff --git a/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/T80/T8080se.vhd b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/T80/T8080se.vhd new file mode 100644 index 00000000..3fbf4ebd --- /dev/null +++ b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/T80/T8080se.vhd @@ -0,0 +1,185 @@ +-- +-- 8080 compatible microprocessor core, synchronous top level with clock enable +-- Different timing than the original 8080 +-- Inputs needs to be synchronous and outputs may glitch +-- +-- Version : 0242 +-- +-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t80/ +-- +-- Limitations : +-- STACK status output not supported +-- +-- File history : +-- +-- 0237 : First version +-- +-- 0238 : Updated for T80 interface change +-- +-- 0240 : Updated for T80 interface change +-- +-- 0242 : Updated for T80 interface change +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; +use work.T80_Pack.all; + +entity T8080se is + generic( + Mode : integer := 2; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB + T2Write : integer := 0 -- 0 => WR_n active in T3, /=0 => WR_n active in T2 + ); + port( + RESET_n : in std_logic; + CLK : in std_logic; + CLKEN : in std_logic; + READY : in std_logic; + HOLD : in std_logic; + INT : in std_logic; + INTE : out std_logic; + DBIN : out std_logic; + SYNC : out std_logic; + VAIT : out std_logic; + HLDA : out std_logic; + WR_n : out std_logic; + A : out std_logic_vector(15 downto 0); + DI : in std_logic_vector(7 downto 0); + DO : out std_logic_vector(7 downto 0) + ); +end T8080se; + +architecture rtl of T8080se is + + signal IntCycle_n : std_logic; + signal NoRead : std_logic; + signal Write : std_logic; + signal IORQ : std_logic; + signal INT_n : std_logic; + signal HALT_n : std_logic; + signal BUSRQ_n : std_logic; + signal BUSAK_n : std_logic; + signal DO_i : std_logic_vector(7 downto 0); + signal DI_Reg : std_logic_vector(7 downto 0); + signal MCycle : std_logic_vector(2 downto 0); + signal TState : std_logic_vector(2 downto 0); + signal One : std_logic; + +begin + + INT_n <= not INT; + BUSRQ_n <= HOLD; + HLDA <= not BUSAK_n; + SYNC <= '1' when TState = "001" else '0'; + VAIT <= '1' when TState = "010" else '0'; + One <= '1'; + + DO(0) <= not IntCycle_n when TState = "001" else DO_i(0); -- INTA + DO(1) <= Write when TState = "001" else DO_i(1); -- WO_n + DO(2) <= DO_i(2); -- STACK not supported !!!!!!!!!! + DO(3) <= not HALT_n when TState = "001" else DO_i(3); -- HLTA + DO(4) <= IORQ and Write when TState = "001" else DO_i(4); -- OUT + DO(5) <= DO_i(5) when TState /= "001" else '1' when MCycle = "001" else '0'; -- M1 + DO(6) <= IORQ and not Write when TState = "001" else DO_i(6); -- INP + DO(7) <= not IORQ and not Write and IntCycle_n when TState = "001" else DO_i(7); -- MEMR + + u0 : T80 + generic map( + Mode => Mode, + IOWait => 0) + port map( + CEN => CLKEN, + M1_n => open, + IORQ => IORQ, + NoRead => NoRead, + Write => Write, + RFSH_n => open, + HALT_n => HALT_n, + WAIT_n => READY, + INT_n => INT_n, + NMI_n => One, + RESET_n => RESET_n, + BUSRQ_n => BUSRQ_n, + BUSAK_n => BUSAK_n, + CLK_n => CLK, + A => A, + DInst => DI, + DI => DI_Reg, + DO => DO_i, + MC => MCycle, + TS => TState, + IntCycle_n => IntCycle_n, + IntE => INTE); + + process (RESET_n, CLK) + begin + if RESET_n = '0' then + DBIN <= '0'; + WR_n <= '1'; + DI_Reg <= "00000000"; + elsif CLK'event and CLK = '1' then + if CLKEN = '1' then + DBIN <= '0'; + WR_n <= '1'; + if MCycle = "001" then + if TState = "001" or (TState = "010" and READY = '0') then + DBIN <= IntCycle_n; + end if; + else + if (TState = "001" or (TState = "010" and READY = '0')) and NoRead = '0' and Write = '0' then + DBIN <= '1'; + end if; + if T2Write = 0 then + if TState = "010" and Write = '1' then + WR_n <= '0'; + end if; + else + if (TState = "001" or (TState = "010" and READY = '0')) and Write = '1' then + WR_n <= '0'; + end if; + end if; + end if; + if TState = "010" and READY = '1' then + DI_Reg <= DI; + end if; + end if; + end if; + end process; + +end; diff --git a/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/T80/T80_ALU.vhd b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/T80/T80_ALU.vhd new file mode 100644 index 00000000..86fddce7 --- /dev/null +++ b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/T80/T80_ALU.vhd @@ -0,0 +1,351 @@ +-- +-- Z80 compatible microprocessor core +-- +-- Version : 0247 +-- +-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t80/ +-- +-- Limitations : +-- +-- File history : +-- +-- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test +-- +-- 0238 : Fixed zero flag for 16 bit SBC and ADC +-- +-- 0240 : Added GB operations +-- +-- 0242 : Cleanup +-- +-- 0247 : Cleanup +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +entity T80_ALU is + generic( + Mode : integer := 0; + Flag_C : integer := 0; + Flag_N : integer := 1; + Flag_P : integer := 2; + Flag_X : integer := 3; + Flag_H : integer := 4; + Flag_Y : integer := 5; + Flag_Z : integer := 6; + Flag_S : integer := 7 + ); + port( + Arith16 : in std_logic; + Z16 : in std_logic; + ALU_Op : in std_logic_vector(3 downto 0); + IR : in std_logic_vector(5 downto 0); + ISet : in std_logic_vector(1 downto 0); + BusA : in std_logic_vector(7 downto 0); + BusB : in std_logic_vector(7 downto 0); + F_In : in std_logic_vector(7 downto 0); + Q : out std_logic_vector(7 downto 0); + F_Out : out std_logic_vector(7 downto 0) + ); +end T80_ALU; + +architecture rtl of T80_ALU is + + procedure AddSub(A : std_logic_vector; + B : std_logic_vector; + Sub : std_logic; + Carry_In : std_logic; + signal Res : out std_logic_vector; + signal Carry : out std_logic) is + variable B_i : unsigned(A'length - 1 downto 0); + variable Res_i : unsigned(A'length + 1 downto 0); + begin + if Sub = '1' then + B_i := not unsigned(B); + else + B_i := unsigned(B); + end if; + Res_i := unsigned("0" & A & Carry_In) + unsigned("0" & B_i & "1"); + Carry <= Res_i(A'length + 1); + Res <= std_logic_vector(Res_i(A'length downto 1)); + end; + + -- AddSub variables (temporary signals) + signal UseCarry : std_logic; + signal Carry7_v : std_logic; + signal Overflow_v : std_logic; + signal HalfCarry_v : std_logic; + signal Carry_v : std_logic; + signal Q_v : std_logic_vector(7 downto 0); + + signal BitMask : std_logic_vector(7 downto 0); + +begin + + with IR(5 downto 3) select BitMask <= "00000001" when "000", + "00000010" when "001", + "00000100" when "010", + "00001000" when "011", + "00010000" when "100", + "00100000" when "101", + "01000000" when "110", + "10000000" when others; + + UseCarry <= not ALU_Op(2) and ALU_Op(0); + AddSub(BusA(3 downto 0), BusB(3 downto 0), ALU_Op(1), ALU_Op(1) xor (UseCarry and F_In(Flag_C)), Q_v(3 downto 0), HalfCarry_v); + AddSub(BusA(6 downto 4), BusB(6 downto 4), ALU_Op(1), HalfCarry_v, Q_v(6 downto 4), Carry7_v); + AddSub(BusA(7 downto 7), BusB(7 downto 7), ALU_Op(1), Carry7_v, Q_v(7 downto 7), Carry_v); + OverFlow_v <= Carry_v xor Carry7_v; + + process (Arith16, ALU_OP, F_In, BusA, BusB, IR, Q_v, Carry_v, HalfCarry_v, OverFlow_v, BitMask, ISet, Z16) + variable Q_t : std_logic_vector(7 downto 0); + variable DAA_Q : unsigned(8 downto 0); + begin + Q_t := "--------"; + F_Out <= F_In; + DAA_Q := "---------"; + case ALU_Op is + when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" | "0110" | "0111" => + F_Out(Flag_N) <= '0'; + F_Out(Flag_C) <= '0'; + case ALU_OP(2 downto 0) is + when "000" | "001" => -- ADD, ADC + Q_t := Q_v; + F_Out(Flag_C) <= Carry_v; + F_Out(Flag_H) <= HalfCarry_v; + F_Out(Flag_P) <= OverFlow_v; + when "010" | "011" | "111" => -- SUB, SBC, CP + Q_t := Q_v; + F_Out(Flag_N) <= '1'; + F_Out(Flag_C) <= not Carry_v; + F_Out(Flag_H) <= not HalfCarry_v; + F_Out(Flag_P) <= OverFlow_v; + when "100" => -- AND + Q_t(7 downto 0) := BusA and BusB; + F_Out(Flag_H) <= '1'; + when "101" => -- XOR + Q_t(7 downto 0) := BusA xor BusB; + F_Out(Flag_H) <= '0'; + when others => -- OR "110" + Q_t(7 downto 0) := BusA or BusB; + F_Out(Flag_H) <= '0'; + end case; + if ALU_Op(2 downto 0) = "111" then -- CP + F_Out(Flag_X) <= BusB(3); + F_Out(Flag_Y) <= BusB(5); + else + F_Out(Flag_X) <= Q_t(3); + F_Out(Flag_Y) <= Q_t(5); + end if; + if Q_t(7 downto 0) = "00000000" then + F_Out(Flag_Z) <= '1'; + if Z16 = '1' then + F_Out(Flag_Z) <= F_In(Flag_Z); -- 16 bit ADC,SBC + end if; + else + F_Out(Flag_Z) <= '0'; + end if; + F_Out(Flag_S) <= Q_t(7); + case ALU_Op(2 downto 0) is + when "000" | "001" | "010" | "011" | "111" => -- ADD, ADC, SUB, SBC, CP + when others => + F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor + Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7)); + end case; + if Arith16 = '1' then + F_Out(Flag_S) <= F_In(Flag_S); + F_Out(Flag_Z) <= F_In(Flag_Z); + F_Out(Flag_P) <= F_In(Flag_P); + end if; + when "1100" => + -- DAA + F_Out(Flag_H) <= F_In(Flag_H); + F_Out(Flag_C) <= F_In(Flag_C); + DAA_Q(7 downto 0) := unsigned(BusA); + DAA_Q(8) := '0'; + if F_In(Flag_N) = '0' then + -- After addition + -- Alow > 9 or H = 1 + if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then + if (DAA_Q(3 downto 0) > 9) then + F_Out(Flag_H) <= '1'; + else + F_Out(Flag_H) <= '0'; + end if; + DAA_Q := DAA_Q + 6; + end if; + -- new Ahigh > 9 or C = 1 + if DAA_Q(8 downto 4) > 9 or F_In(Flag_C) = '1' then + DAA_Q := DAA_Q + 96; -- 0x60 + end if; + else + -- After subtraction + if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then + if DAA_Q(3 downto 0) > 5 then + F_Out(Flag_H) <= '0'; + end if; + DAA_Q(7 downto 0) := DAA_Q(7 downto 0) - 6; + end if; + if unsigned(BusA) > 153 or F_In(Flag_C) = '1' then + DAA_Q := DAA_Q - 352; -- 0x160 + end if; + end if; + F_Out(Flag_X) <= DAA_Q(3); + F_Out(Flag_Y) <= DAA_Q(5); + F_Out(Flag_C) <= F_In(Flag_C) or DAA_Q(8); + Q_t := std_logic_vector(DAA_Q(7 downto 0)); + if DAA_Q(7 downto 0) = "00000000" then + F_Out(Flag_Z) <= '1'; + else + F_Out(Flag_Z) <= '0'; + end if; + F_Out(Flag_S) <= DAA_Q(7); + F_Out(Flag_P) <= not (DAA_Q(0) xor DAA_Q(1) xor DAA_Q(2) xor DAA_Q(3) xor + DAA_Q(4) xor DAA_Q(5) xor DAA_Q(6) xor DAA_Q(7)); + when "1101" | "1110" => + -- RLD, RRD + Q_t(7 downto 4) := BusA(7 downto 4); + if ALU_Op(0) = '1' then + Q_t(3 downto 0) := BusB(7 downto 4); + else + Q_t(3 downto 0) := BusB(3 downto 0); + end if; + F_Out(Flag_H) <= '0'; + F_Out(Flag_N) <= '0'; + F_Out(Flag_X) <= Q_t(3); + F_Out(Flag_Y) <= Q_t(5); + if Q_t(7 downto 0) = "00000000" then + F_Out(Flag_Z) <= '1'; + else + F_Out(Flag_Z) <= '0'; + end if; + F_Out(Flag_S) <= Q_t(7); + F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor + Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7)); + when "1001" => + -- BIT + Q_t(7 downto 0) := BusB and BitMask; + F_Out(Flag_S) <= Q_t(7); + if Q_t(7 downto 0) = "00000000" then + F_Out(Flag_Z) <= '1'; + F_Out(Flag_P) <= '1'; + else + F_Out(Flag_Z) <= '0'; + F_Out(Flag_P) <= '0'; + end if; + F_Out(Flag_H) <= '1'; + F_Out(Flag_N) <= '0'; + F_Out(Flag_X) <= '0'; + F_Out(Flag_Y) <= '0'; + if IR(2 downto 0) /= "110" then + F_Out(Flag_X) <= BusB(3); + F_Out(Flag_Y) <= BusB(5); + end if; + when "1010" => + -- SET + Q_t(7 downto 0) := BusB or BitMask; + when "1011" => + -- RES + Q_t(7 downto 0) := BusB and not BitMask; + when "1000" => + -- ROT + case IR(5 downto 3) is + when "000" => -- RLC + Q_t(7 downto 1) := BusA(6 downto 0); + Q_t(0) := BusA(7); + F_Out(Flag_C) <= BusA(7); + when "010" => -- RL + Q_t(7 downto 1) := BusA(6 downto 0); + Q_t(0) := F_In(Flag_C); + F_Out(Flag_C) <= BusA(7); + when "001" => -- RRC + Q_t(6 downto 0) := BusA(7 downto 1); + Q_t(7) := BusA(0); + F_Out(Flag_C) <= BusA(0); + when "011" => -- RR + Q_t(6 downto 0) := BusA(7 downto 1); + Q_t(7) := F_In(Flag_C); + F_Out(Flag_C) <= BusA(0); + when "100" => -- SLA + Q_t(7 downto 1) := BusA(6 downto 0); + Q_t(0) := '0'; + F_Out(Flag_C) <= BusA(7); + when "110" => -- SLL (Undocumented) / SWAP + if Mode = 3 then + Q_t(7 downto 4) := BusA(3 downto 0); + Q_t(3 downto 0) := BusA(7 downto 4); + F_Out(Flag_C) <= '0'; + else + Q_t(7 downto 1) := BusA(6 downto 0); + Q_t(0) := '1'; + F_Out(Flag_C) <= BusA(7); + end if; + when "101" => -- SRA + Q_t(6 downto 0) := BusA(7 downto 1); + Q_t(7) := BusA(7); + F_Out(Flag_C) <= BusA(0); + when others => -- SRL + Q_t(6 downto 0) := BusA(7 downto 1); + Q_t(7) := '0'; + F_Out(Flag_C) <= BusA(0); + end case; + F_Out(Flag_H) <= '0'; + F_Out(Flag_N) <= '0'; + F_Out(Flag_X) <= Q_t(3); + F_Out(Flag_Y) <= Q_t(5); + F_Out(Flag_S) <= Q_t(7); + if Q_t(7 downto 0) = "00000000" then + F_Out(Flag_Z) <= '1'; + else + F_Out(Flag_Z) <= '0'; + end if; + F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor + Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7)); + if ISet = "00" then + F_Out(Flag_P) <= F_In(Flag_P); + F_Out(Flag_S) <= F_In(Flag_S); + F_Out(Flag_Z) <= F_In(Flag_Z); + end if; + when others => + null; + end case; + Q <= Q_t; + end process; + +end; diff --git a/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/T80/T80_MCode.vhd b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/T80/T80_MCode.vhd new file mode 100644 index 00000000..4cc30f35 --- /dev/null +++ b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/T80/T80_MCode.vhd @@ -0,0 +1,1934 @@ +-- +-- Z80 compatible microprocessor core +-- +-- Version : 0242 +-- +-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t80/ +-- +-- Limitations : +-- +-- File history : +-- +-- 0208 : First complete release +-- +-- 0211 : Fixed IM 1 +-- +-- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test +-- +-- 0235 : Added IM 2 fix by Mike Johnson +-- +-- 0238 : Added NoRead signal +-- +-- 0238b: Fixed instruction timing for POP and DJNZ +-- +-- 0240 : Added (IX/IY+d) states, removed op-codes from mode 2 and added all remaining mode 3 op-codes +-- +-- 0242 : Fixed I/O instruction timing, cleanup +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +entity T80_MCode is + generic( + Mode : integer := 0; + Flag_C : integer := 0; + Flag_N : integer := 1; + Flag_P : integer := 2; + Flag_X : integer := 3; + Flag_H : integer := 4; + Flag_Y : integer := 5; + Flag_Z : integer := 6; + Flag_S : integer := 7 + ); + port( + IR : in std_logic_vector(7 downto 0); + ISet : in std_logic_vector(1 downto 0); + MCycle : in std_logic_vector(2 downto 0); + F : in std_logic_vector(7 downto 0); + NMICycle : in std_logic; + IntCycle : in std_logic; + MCycles : out std_logic_vector(2 downto 0); + TStates : out std_logic_vector(2 downto 0); + Prefix : out std_logic_vector(1 downto 0); -- None,BC,ED,DD/FD + Inc_PC : out std_logic; + Inc_WZ : out std_logic; + IncDec_16 : out std_logic_vector(3 downto 0); -- BC,DE,HL,SP 0 is inc + Read_To_Reg : out std_logic; + Read_To_Acc : out std_logic; + Set_BusA_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F + Set_BusB_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0 + ALU_Op : out std_logic_vector(3 downto 0); + -- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None + Save_ALU : out std_logic; + PreserveC : out std_logic; + Arith16 : out std_logic; + Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI + IORQ : out std_logic; + Jump : out std_logic; + JumpE : out std_logic; + JumpXY : out std_logic; + Call : out std_logic; + RstP : out std_logic; + LDZ : out std_logic; + LDW : out std_logic; + LDSPHL : out std_logic; + Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None + ExchangeDH : out std_logic; + ExchangeRp : out std_logic; + ExchangeAF : out std_logic; + ExchangeRS : out std_logic; + I_DJNZ : out std_logic; + I_CPL : out std_logic; + I_CCF : out std_logic; + I_SCF : out std_logic; + I_RETN : out std_logic; + I_BT : out std_logic; + I_BC : out std_logic; + I_BTR : out std_logic; + I_RLD : out std_logic; + I_RRD : out std_logic; + I_INRC : out std_logic; + SetDI : out std_logic; + SetEI : out std_logic; + IMode : out std_logic_vector(1 downto 0); + Halt : out std_logic; + NoRead : out std_logic; + Write : out std_logic + ); +end T80_MCode; + +architecture rtl of T80_MCode is + + constant aNone : std_logic_vector(2 downto 0) := "111"; + constant aBC : std_logic_vector(2 downto 0) := "000"; + constant aDE : std_logic_vector(2 downto 0) := "001"; + constant aXY : std_logic_vector(2 downto 0) := "010"; + constant aIOA : std_logic_vector(2 downto 0) := "100"; + constant aSP : std_logic_vector(2 downto 0) := "101"; + constant aZI : std_logic_vector(2 downto 0) := "110"; +-- constant aNone : std_logic_vector(2 downto 0) := "000"; +-- constant aXY : std_logic_vector(2 downto 0) := "001"; +-- constant aIOA : std_logic_vector(2 downto 0) := "010"; +-- constant aSP : std_logic_vector(2 downto 0) := "011"; +-- constant aBC : std_logic_vector(2 downto 0) := "100"; +-- constant aDE : std_logic_vector(2 downto 0) := "101"; +-- constant aZI : std_logic_vector(2 downto 0) := "110"; + + function is_cc_true( + F : std_logic_vector(7 downto 0); + cc : bit_vector(2 downto 0) + ) return boolean is + begin + if Mode = 3 then + case cc is + when "000" => return F(7) = '0'; -- NZ + when "001" => return F(7) = '1'; -- Z + when "010" => return F(4) = '0'; -- NC + when "011" => return F(4) = '1'; -- C + when "100" => return false; + when "101" => return false; + when "110" => return false; + when "111" => return false; + end case; + else + case cc is + when "000" => return F(6) = '0'; -- NZ + when "001" => return F(6) = '1'; -- Z + when "010" => return F(0) = '0'; -- NC + when "011" => return F(0) = '1'; -- C + when "100" => return F(2) = '0'; -- PO + when "101" => return F(2) = '1'; -- PE + when "110" => return F(7) = '0'; -- P + when "111" => return F(7) = '1'; -- M + end case; + end if; + end; + +begin + + process (IR, ISet, MCycle, F, NMICycle, IntCycle) + variable DDD : std_logic_vector(2 downto 0); + variable SSS : std_logic_vector(2 downto 0); + variable DPair : std_logic_vector(1 downto 0); + variable IRB : bit_vector(7 downto 0); + begin + DDD := IR(5 downto 3); + SSS := IR(2 downto 0); + DPair := IR(5 downto 4); + IRB := to_bitvector(IR); + + MCycles <= "001"; + if MCycle = "001" then + TStates <= "100"; + else + TStates <= "011"; + end if; + Prefix <= "00"; + Inc_PC <= '0'; + Inc_WZ <= '0'; + IncDec_16 <= "0000"; + Read_To_Acc <= '0'; + Read_To_Reg <= '0'; + Set_BusB_To <= "0000"; + Set_BusA_To <= "0000"; + ALU_Op <= "0" & IR(5 downto 3); + Save_ALU <= '0'; + PreserveC <= '0'; + Arith16 <= '0'; + IORQ <= '0'; + Set_Addr_To <= aNone; + Jump <= '0'; + JumpE <= '0'; + JumpXY <= '0'; + Call <= '0'; + RstP <= '0'; + LDZ <= '0'; + LDW <= '0'; + LDSPHL <= '0'; + Special_LD <= "000"; + ExchangeDH <= '0'; + ExchangeRp <= '0'; + ExchangeAF <= '0'; + ExchangeRS <= '0'; + I_DJNZ <= '0'; + I_CPL <= '0'; + I_CCF <= '0'; + I_SCF <= '0'; + I_RETN <= '0'; + I_BT <= '0'; + I_BC <= '0'; + I_BTR <= '0'; + I_RLD <= '0'; + I_RRD <= '0'; + I_INRC <= '0'; + SetDI <= '0'; + SetEI <= '0'; + IMode <= "11"; + Halt <= '0'; + NoRead <= '0'; + Write <= '0'; + + case ISet is + when "00" => + +------------------------------------------------------------------------------ +-- +-- Unprefixed instructions +-- +------------------------------------------------------------------------------ + + case IRB is +-- 8 BIT LOAD GROUP + when "01000000"|"01000001"|"01000010"|"01000011"|"01000100"|"01000101"|"01000111" + |"01001000"|"01001001"|"01001010"|"01001011"|"01001100"|"01001101"|"01001111" + |"01010000"|"01010001"|"01010010"|"01010011"|"01010100"|"01010101"|"01010111" + |"01011000"|"01011001"|"01011010"|"01011011"|"01011100"|"01011101"|"01011111" + |"01100000"|"01100001"|"01100010"|"01100011"|"01100100"|"01100101"|"01100111" + |"01101000"|"01101001"|"01101010"|"01101011"|"01101100"|"01101101"|"01101111" + |"01111000"|"01111001"|"01111010"|"01111011"|"01111100"|"01111101"|"01111111" => + -- LD r,r' + Set_BusB_To(2 downto 0) <= SSS; + ExchangeRp <= '1'; + Set_BusA_To(2 downto 0) <= DDD; + Read_To_Reg <= '1'; + when "00000110"|"00001110"|"00010110"|"00011110"|"00100110"|"00101110"|"00111110" => + -- LD r,n + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + Set_BusA_To(2 downto 0) <= DDD; + Read_To_Reg <= '1'; + when others => null; + end case; + when "01000110"|"01001110"|"01010110"|"01011110"|"01100110"|"01101110"|"01111110" => + -- LD r,(HL) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + when 2 => + Set_BusA_To(2 downto 0) <= DDD; + Read_To_Reg <= '1'; + when others => null; + end case; + when "01110000"|"01110001"|"01110010"|"01110011"|"01110100"|"01110101"|"01110111" => + -- LD (HL),r + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + Set_BusB_To(2 downto 0) <= SSS; + Set_BusB_To(3) <= '0'; + when 2 => + Write <= '1'; + when others => null; + end case; + when "00110110" => + -- LD (HL),n + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + Set_Addr_To <= aXY; + Set_BusB_To(2 downto 0) <= SSS; + Set_BusB_To(3) <= '0'; + when 3 => + Write <= '1'; + when others => null; + end case; + when "00001010" => + -- LD A,(BC) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aBC; + when 2 => + Read_To_Acc <= '1'; + when others => null; + end case; + when "00011010" => + -- LD A,(DE) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aDE; + when 2 => + Read_To_Acc <= '1'; + when others => null; + end case; + when "00111010" => + if Mode = 3 then + -- LDD A,(HL) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + when 2 => + Read_To_Acc <= '1'; + IncDec_16 <= "1110"; + when others => null; + end case; + else + -- LD A,(nn) + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + when 4 => + Read_To_Acc <= '1'; + when others => null; + end case; + end if; + when "00000010" => + -- LD (BC),A + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aBC; + Set_BusB_To <= "0111"; + when 2 => + Write <= '1'; + when others => null; + end case; + when "00010010" => + -- LD (DE),A + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aDE; + Set_BusB_To <= "0111"; + when 2 => + Write <= '1'; + when others => null; + end case; + when "00110010" => + if Mode = 3 then + -- LDD (HL),A + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + Set_BusB_To <= "0111"; + when 2 => + Write <= '1'; + IncDec_16 <= "1110"; + when others => null; + end case; + else + -- LD (nn),A + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + Set_BusB_To <= "0111"; + when 4 => + Write <= '1'; + when others => null; + end case; + end if; + +-- 16 BIT LOAD GROUP + when "00000001"|"00010001"|"00100001"|"00110001" => + -- LD dd,nn + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + Read_To_Reg <= '1'; + if DPAIR = "11" then + Set_BusA_To(3 downto 0) <= "1000"; + else + Set_BusA_To(2 downto 1) <= DPAIR; + Set_BusA_To(0) <= '1'; + end if; + when 3 => + Inc_PC <= '1'; + Read_To_Reg <= '1'; + if DPAIR = "11" then + Set_BusA_To(3 downto 0) <= "1001"; + else + Set_BusA_To(2 downto 1) <= DPAIR; + Set_BusA_To(0) <= '0'; + end if; + when others => null; + end case; + when "00101010" => + if Mode = 3 then + -- LDI A,(HL) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + when 2 => + Read_To_Acc <= '1'; + IncDec_16 <= "0110"; + when others => null; + end case; + else + -- LD HL,(nn) + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + LDW <= '1'; + when 4 => + Set_BusA_To(2 downto 0) <= "101"; -- L + Read_To_Reg <= '1'; + Inc_WZ <= '1'; + Set_Addr_To <= aZI; + when 5 => + Set_BusA_To(2 downto 0) <= "100"; -- H + Read_To_Reg <= '1'; + when others => null; + end case; + end if; + when "00100010" => + if Mode = 3 then + -- LDI (HL),A + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + Set_BusB_To <= "0111"; + when 2 => + Write <= '1'; + IncDec_16 <= "0110"; + when others => null; + end case; + else + -- LD (nn),HL + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + LDW <= '1'; + Set_BusB_To <= "0101"; -- L + when 4 => + Inc_WZ <= '1'; + Set_Addr_To <= aZI; + Write <= '1'; + Set_BusB_To <= "0100"; -- H + when 5 => + Write <= '1'; + when others => null; + end case; + end if; + when "11111001" => + -- LD SP,HL + TStates <= "110"; + LDSPHL <= '1'; + when "11000101"|"11010101"|"11100101"|"11110101" => + -- PUSH qq + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + TStates <= "101"; + IncDec_16 <= "1111"; + Set_Addr_TO <= aSP; + if DPAIR = "11" then + Set_BusB_To <= "0111"; + else + Set_BusB_To(2 downto 1) <= DPAIR; + Set_BusB_To(0) <= '0'; + Set_BusB_To(3) <= '0'; + end if; + when 2 => + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + if DPAIR = "11" then + Set_BusB_To <= "1011"; + else + Set_BusB_To(2 downto 1) <= DPAIR; + Set_BusB_To(0) <= '1'; + Set_BusB_To(3) <= '0'; + end if; + Write <= '1'; + when 3 => + Write <= '1'; + when others => null; + end case; + when "11000001"|"11010001"|"11100001"|"11110001" => + -- POP qq + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aSP; + when 2 => + IncDec_16 <= "0111"; + Set_Addr_To <= aSP; + Read_To_Reg <= '1'; + if DPAIR = "11" then + Set_BusA_To(3 downto 0) <= "1011"; + else + Set_BusA_To(2 downto 1) <= DPAIR; + Set_BusA_To(0) <= '1'; + end if; + when 3 => + IncDec_16 <= "0111"; + Read_To_Reg <= '1'; + if DPAIR = "11" then + Set_BusA_To(3 downto 0) <= "0111"; + else + Set_BusA_To(2 downto 1) <= DPAIR; + Set_BusA_To(0) <= '0'; + end if; + when others => null; + end case; + +-- EXCHANGE, BLOCK TRANSFER AND SEARCH GROUP + when "11101011" => + if Mode /= 3 then + -- EX DE,HL + ExchangeDH <= '1'; + end if; + when "00001000" => + if Mode = 3 then + -- LD (nn),SP + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + LDW <= '1'; + Set_BusB_To <= "1000"; + when 4 => + Inc_WZ <= '1'; + Set_Addr_To <= aZI; + Write <= '1'; + Set_BusB_To <= "1001"; + when 5 => + Write <= '1'; + when others => null; + end case; + elsif Mode < 2 then + -- EX AF,AF' + ExchangeAF <= '1'; + end if; + when "11011001" => + if Mode = 3 then + -- RETI + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_TO <= aSP; + when 2 => + IncDec_16 <= "0111"; + Set_Addr_To <= aSP; + LDZ <= '1'; + when 3 => + Jump <= '1'; + IncDec_16 <= "0111"; + I_RETN <= '1'; + SetEI <= '1'; + when others => null; + end case; + elsif Mode < 2 then + -- EXX + ExchangeRS <= '1'; + end if; + when "11100011" => + if Mode /= 3 then + -- EX (SP),HL + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aSP; + when 2 => + Read_To_Reg <= '1'; + Set_BusA_To <= "0101"; + Set_BusB_To <= "0101"; + Set_Addr_To <= aSP; + when 3 => + IncDec_16 <= "0111"; + Set_Addr_To <= aSP; + TStates <= "100"; + Write <= '1'; + when 4 => + Read_To_Reg <= '1'; + Set_BusA_To <= "0100"; + Set_BusB_To <= "0100"; + Set_Addr_To <= aSP; + when 5 => + IncDec_16 <= "1111"; + TStates <= "101"; + Write <= '1'; + when others => null; + end case; + end if; + +-- 8 BIT ARITHMETIC AND LOGICAL GROUP + when "10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000111" + |"10001000"|"10001001"|"10001010"|"10001011"|"10001100"|"10001101"|"10001111" + |"10010000"|"10010001"|"10010010"|"10010011"|"10010100"|"10010101"|"10010111" + |"10011000"|"10011001"|"10011010"|"10011011"|"10011100"|"10011101"|"10011111" + |"10100000"|"10100001"|"10100010"|"10100011"|"10100100"|"10100101"|"10100111" + |"10101000"|"10101001"|"10101010"|"10101011"|"10101100"|"10101101"|"10101111" + |"10110000"|"10110001"|"10110010"|"10110011"|"10110100"|"10110101"|"10110111" + |"10111000"|"10111001"|"10111010"|"10111011"|"10111100"|"10111101"|"10111111" => + -- ADD A,r + -- ADC A,r + -- SUB A,r + -- SBC A,r + -- AND A,r + -- OR A,r + -- XOR A,r + -- CP A,r + Set_BusB_To(2 downto 0) <= SSS; + Set_BusA_To(2 downto 0) <= "111"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + when "10000110"|"10001110"|"10010110"|"10011110"|"10100110"|"10101110"|"10110110"|"10111110" => + -- ADD A,(HL) + -- ADC A,(HL) + -- SUB A,(HL) + -- SBC A,(HL) + -- AND A,(HL) + -- OR A,(HL) + -- XOR A,(HL) + -- CP A,(HL) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + when 2 => + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_BusB_To(2 downto 0) <= SSS; + Set_BusA_To(2 downto 0) <= "111"; + when others => null; + end case; + when "11000110"|"11001110"|"11010110"|"11011110"|"11100110"|"11101110"|"11110110"|"11111110" => + -- ADD A,n + -- ADC A,n + -- SUB A,n + -- SBC A,n + -- AND A,n + -- OR A,n + -- XOR A,n + -- CP A,n + MCycles <= "010"; + if MCycle = "010" then + Inc_PC <= '1'; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_BusB_To(2 downto 0) <= SSS; + Set_BusA_To(2 downto 0) <= "111"; + end if; + when "00000100"|"00001100"|"00010100"|"00011100"|"00100100"|"00101100"|"00111100" => + -- INC r + Set_BusB_To <= "1010"; + Set_BusA_To(2 downto 0) <= DDD; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + PreserveC <= '1'; + ALU_Op <= "0000"; + when "00110100" => + -- INC (HL) + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + when 2 => + TStates <= "100"; + Set_Addr_To <= aXY; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + PreserveC <= '1'; + ALU_Op <= "0000"; + Set_BusB_To <= "1010"; + Set_BusA_To(2 downto 0) <= DDD; + when 3 => + Write <= '1'; + when others => null; + end case; + when "00000101"|"00001101"|"00010101"|"00011101"|"00100101"|"00101101"|"00111101" => + -- DEC r + Set_BusB_To <= "1010"; + Set_BusA_To(2 downto 0) <= DDD; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + PreserveC <= '1'; + ALU_Op <= "0010"; + when "00110101" => + -- DEC (HL) + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + when 2 => + TStates <= "100"; + Set_Addr_To <= aXY; + ALU_Op <= "0010"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + PreserveC <= '1'; + Set_BusB_To <= "1010"; + Set_BusA_To(2 downto 0) <= DDD; + when 3 => + Write <= '1'; + when others => null; + end case; + +-- GENERAL PURPOSE ARITHMETIC AND CPU CONTROL GROUPS + when "00100111" => + -- DAA + Set_BusA_To(2 downto 0) <= "111"; + Read_To_Reg <= '1'; + ALU_Op <= "1100"; + Save_ALU <= '1'; + when "00101111" => + -- CPL + I_CPL <= '1'; + when "00111111" => + -- CCF + I_CCF <= '1'; + when "00110111" => + -- SCF + I_SCF <= '1'; + when "00000000" => + if NMICycle = '1' then + -- NMI + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + TStates <= "101"; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1101"; + when 2 => + TStates <= "100"; + Write <= '1'; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1100"; + when 3 => + TStates <= "100"; + Write <= '1'; + when others => null; + end case; + elsif IntCycle = '1' then + -- INT (IM 2) + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 1 => + LDZ <= '1'; + TStates <= "101"; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1101"; + when 2 => + TStates <= "100"; + Write <= '1'; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1100"; + when 3 => + TStates <= "100"; + Write <= '1'; + when 4 => + Inc_PC <= '1'; + LDZ <= '1'; + when 5 => + Jump <= '1'; + when others => null; + end case; + else + -- NOP + end if; + when "01110110" => + -- HALT + Halt <= '1'; + when "11110011" => + -- DI + SetDI <= '1'; + when "11111011" => + -- EI + SetEI <= '1'; + +-- 16 BIT ARITHMETIC GROUP + when "00001001"|"00011001"|"00101001"|"00111001" => + -- ADD HL,ss + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + NoRead <= '1'; + ALU_Op <= "0000"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_BusA_To(2 downto 0) <= "101"; + case to_integer(unsigned(IR(5 downto 4))) is + when 0|1|2 => + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + Set_BusB_To(0) <= '1'; + when others => + Set_BusB_To <= "1000"; + end case; + TStates <= "100"; + Arith16 <= '1'; + when 3 => + NoRead <= '1'; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + ALU_Op <= "0001"; + Set_BusA_To(2 downto 0) <= "100"; + case to_integer(unsigned(IR(5 downto 4))) is + when 0|1|2 => + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + when others => + Set_BusB_To <= "1001"; + end case; + Arith16 <= '1'; + when others => + end case; + when "00000011"|"00010011"|"00100011"|"00110011" => + -- INC ss + TStates <= "110"; + IncDec_16(3 downto 2) <= "01"; + IncDec_16(1 downto 0) <= DPair; + when "00001011"|"00011011"|"00101011"|"00111011" => + -- DEC ss + TStates <= "110"; + IncDec_16(3 downto 2) <= "11"; + IncDec_16(1 downto 0) <= DPair; + +-- ROTATE AND SHIFT GROUP + when "00000111" + -- RLCA + |"00010111" + -- RLA + |"00001111" + -- RRCA + |"00011111" => + -- RRA + Set_BusA_To(2 downto 0) <= "111"; + ALU_Op <= "1000"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + +-- JUMP GROUP + when "11000011" => + -- JP nn + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Inc_PC <= '1'; + Jump <= '1'; + when others => null; + end case; + when "11000010"|"11001010"|"11010010"|"11011010"|"11100010"|"11101010"|"11110010"|"11111010" => + if IR(5) = '1' and Mode = 3 then + case IRB(4 downto 3) is + when "00" => + -- LD ($FF00+C),A + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aBC; + Set_BusB_To <= "0111"; + when 2 => + Write <= '1'; + IORQ <= '1'; + when others => + end case; + when "01" => + -- LD (nn),A + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + Set_BusB_To <= "0111"; + when 4 => + Write <= '1'; + when others => null; + end case; + when "10" => + -- LD A,($FF00+C) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aBC; + when 2 => + Read_To_Acc <= '1'; + IORQ <= '1'; + when others => + end case; + when "11" => + -- LD A,(nn) + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + when 4 => + Read_To_Acc <= '1'; + when others => null; + end case; + end case; + else + -- JP cc,nn + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Inc_PC <= '1'; + if is_cc_true(F, to_bitvector(IR(5 downto 3))) then + Jump <= '1'; + end if; + when others => null; + end case; + end if; + when "00011000" => + if Mode /= 2 then + -- JR e + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + when 3 => + NoRead <= '1'; + JumpE <= '1'; + TStates <= "101"; + when others => null; + end case; + end if; + when "00111000" => + if Mode /= 2 then + -- JR C,e + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + if F(Flag_C) = '0' then + MCycles <= "010"; + end if; + when 3 => + NoRead <= '1'; + JumpE <= '1'; + TStates <= "101"; + when others => null; + end case; + end if; + when "00110000" => + if Mode /= 2 then + -- JR NC,e + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + if F(Flag_C) = '1' then + MCycles <= "010"; + end if; + when 3 => + NoRead <= '1'; + JumpE <= '1'; + TStates <= "101"; + when others => null; + end case; + end if; + when "00101000" => + if Mode /= 2 then + -- JR Z,e + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + if F(Flag_Z) = '0' then + MCycles <= "010"; + end if; + when 3 => + NoRead <= '1'; + JumpE <= '1'; + TStates <= "101"; + when others => null; + end case; + end if; + when "00100000" => + if Mode /= 2 then + -- JR NZ,e + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + if F(Flag_Z) = '1' then + MCycles <= "010"; + end if; + when 3 => + NoRead <= '1'; + JumpE <= '1'; + TStates <= "101"; + when others => null; + end case; + end if; + when "11101001" => + -- JP (HL) + JumpXY <= '1'; + when "00010000" => + if Mode = 3 then + I_DJNZ <= '1'; + elsif Mode < 2 then + -- DJNZ,e + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + TStates <= "101"; + I_DJNZ <= '1'; + Set_BusB_To <= "1010"; + Set_BusA_To(2 downto 0) <= "000"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + ALU_Op <= "0010"; + when 2 => + I_DJNZ <= '1'; + Inc_PC <= '1'; + when 3 => + NoRead <= '1'; + JumpE <= '1'; + TStates <= "101"; + when others => null; + end case; + end if; + +-- CALL AND RETURN GROUP + when "11001101" => + -- CALL nn + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + IncDec_16 <= "1111"; + Inc_PC <= '1'; + TStates <= "100"; + Set_Addr_To <= aSP; + LDW <= '1'; + Set_BusB_To <= "1101"; + when 4 => + Write <= '1'; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1100"; + when 5 => + Write <= '1'; + Call <= '1'; + when others => null; + end case; + when "11000100"|"11001100"|"11010100"|"11011100"|"11100100"|"11101100"|"11110100"|"11111100" => + if IR(5) = '0' or Mode /= 3 then + -- CALL cc,nn + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Inc_PC <= '1'; + LDW <= '1'; + if is_cc_true(F, to_bitvector(IR(5 downto 3))) then + IncDec_16 <= "1111"; + Set_Addr_TO <= aSP; + TStates <= "100"; + Set_BusB_To <= "1101"; + else + MCycles <= "011"; + end if; + when 4 => + Write <= '1'; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1100"; + when 5 => + Write <= '1'; + Call <= '1'; + when others => null; + end case; + end if; + when "11001001" => + -- RET + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + TStates <= "101"; + Set_Addr_TO <= aSP; + when 2 => + IncDec_16 <= "0111"; + Set_Addr_To <= aSP; + LDZ <= '1'; + when 3 => + Jump <= '1'; + IncDec_16 <= "0111"; + when others => null; + end case; + when "11000000"|"11001000"|"11010000"|"11011000"|"11100000"|"11101000"|"11110000"|"11111000" => + if IR(5) = '1' and Mode = 3 then + case IRB(4 downto 3) is + when "00" => + -- LD ($FF00+nn),A + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + Set_Addr_To <= aIOA; + Set_BusB_To <= "0111"; + when 3 => + Write <= '1'; + when others => null; + end case; + when "01" => + -- ADD SP,n + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + ALU_Op <= "0000"; + Inc_PC <= '1'; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_BusA_To <= "1000"; + Set_BusB_To <= "0110"; + when 3 => + NoRead <= '1'; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + ALU_Op <= "0001"; + Set_BusA_To <= "1001"; + Set_BusB_To <= "1110"; -- Incorrect unsigned !!!!!!!!!!!!!!!!!!!!! + when others => + end case; + when "10" => + -- LD A,($FF00+nn) + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + Set_Addr_To <= aIOA; + when 3 => + Read_To_Acc <= '1'; + when others => null; + end case; + when "11" => + -- LD HL,SP+n -- Not correct !!!!!!!!!!!!!!!!!!! + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + LDW <= '1'; + when 4 => + Set_BusA_To(2 downto 0) <= "101"; -- L + Read_To_Reg <= '1'; + Inc_WZ <= '1'; + Set_Addr_To <= aZI; + when 5 => + Set_BusA_To(2 downto 0) <= "100"; -- H + Read_To_Reg <= '1'; + when others => null; + end case; + end case; + else + -- RET cc + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + if is_cc_true(F, to_bitvector(IR(5 downto 3))) then + Set_Addr_TO <= aSP; + else + MCycles <= "001"; + end if; + TStates <= "101"; + when 2 => + IncDec_16 <= "0111"; + Set_Addr_To <= aSP; + LDZ <= '1'; + when 3 => + Jump <= '1'; + IncDec_16 <= "0111"; + when others => null; + end case; + end if; + when "11000111"|"11001111"|"11010111"|"11011111"|"11100111"|"11101111"|"11110111"|"11111111" => + -- RST p + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + TStates <= "101"; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1101"; + when 2 => + Write <= '1'; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1100"; + when 3 => + Write <= '1'; + RstP <= '1'; + when others => null; + end case; + +-- INPUT AND OUTPUT GROUP + when "11011011" => + if Mode /= 3 then + -- IN A,(n) + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + Set_Addr_To <= aIOA; + when 3 => + Read_To_Acc <= '1'; + IORQ <= '1'; + when others => null; + end case; + end if; + when "11010011" => + if Mode /= 3 then + -- OUT (n),A + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + Set_Addr_To <= aIOA; + Set_BusB_To <= "0111"; + when 3 => + Write <= '1'; + IORQ <= '1'; + when others => null; + end case; + end if; + +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +-- MULTIBYTE INSTRUCTIONS +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ + + when "11001011" => + if Mode /= 2 then + Prefix <= "01"; + end if; + + when "11101101" => + if Mode < 2 then + Prefix <= "10"; + end if; + + when "11011101"|"11111101" => + if Mode < 2 then + Prefix <= "11"; + end if; + + end case; + + when "01" => + +------------------------------------------------------------------------------ +-- +-- CB prefixed instructions +-- +------------------------------------------------------------------------------ + + Set_BusA_To(2 downto 0) <= IR(2 downto 0); + Set_BusB_To(2 downto 0) <= IR(2 downto 0); + + case IRB is + when "00000000"|"00000001"|"00000010"|"00000011"|"00000100"|"00000101"|"00000111" + |"00010000"|"00010001"|"00010010"|"00010011"|"00010100"|"00010101"|"00010111" + |"00001000"|"00001001"|"00001010"|"00001011"|"00001100"|"00001101"|"00001111" + |"00011000"|"00011001"|"00011010"|"00011011"|"00011100"|"00011101"|"00011111" + |"00100000"|"00100001"|"00100010"|"00100011"|"00100100"|"00100101"|"00100111" + |"00101000"|"00101001"|"00101010"|"00101011"|"00101100"|"00101101"|"00101111" + |"00110000"|"00110001"|"00110010"|"00110011"|"00110100"|"00110101"|"00110111" + |"00111000"|"00111001"|"00111010"|"00111011"|"00111100"|"00111101"|"00111111" => + -- RLC r + -- RL r + -- RRC r + -- RR r + -- SLA r + -- SRA r + -- SRL r + -- SLL r (Undocumented) / SWAP r + if MCycle = "001" then + ALU_Op <= "1000"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + end if; + when "00000110"|"00010110"|"00001110"|"00011110"|"00101110"|"00111110"|"00100110"|"00110110" => + -- RLC (HL) + -- RL (HL) + -- RRC (HL) + -- RR (HL) + -- SRA (HL) + -- SRL (HL) + -- SLA (HL) + -- SLL (HL) (Undocumented) / SWAP (HL) + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 | 7 => + Set_Addr_To <= aXY; + when 2 => + ALU_Op <= "1000"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_Addr_To <= aXY; + TStates <= "100"; + when 3 => + Write <= '1'; + when others => + end case; + when "01000000"|"01000001"|"01000010"|"01000011"|"01000100"|"01000101"|"01000111" + |"01001000"|"01001001"|"01001010"|"01001011"|"01001100"|"01001101"|"01001111" + |"01010000"|"01010001"|"01010010"|"01010011"|"01010100"|"01010101"|"01010111" + |"01011000"|"01011001"|"01011010"|"01011011"|"01011100"|"01011101"|"01011111" + |"01100000"|"01100001"|"01100010"|"01100011"|"01100100"|"01100101"|"01100111" + |"01101000"|"01101001"|"01101010"|"01101011"|"01101100"|"01101101"|"01101111" + |"01110000"|"01110001"|"01110010"|"01110011"|"01110100"|"01110101"|"01110111" + |"01111000"|"01111001"|"01111010"|"01111011"|"01111100"|"01111101"|"01111111" => + -- BIT b,r + if MCycle = "001" then + Set_BusB_To(2 downto 0) <= IR(2 downto 0); + ALU_Op <= "1001"; + end if; + when "01000110"|"01001110"|"01010110"|"01011110"|"01100110"|"01101110"|"01110110"|"01111110" => + -- BIT b,(HL) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 | 7 => + Set_Addr_To <= aXY; + when 2 => + ALU_Op <= "1001"; + TStates <= "100"; + when others => + end case; + when "11000000"|"11000001"|"11000010"|"11000011"|"11000100"|"11000101"|"11000111" + |"11001000"|"11001001"|"11001010"|"11001011"|"11001100"|"11001101"|"11001111" + |"11010000"|"11010001"|"11010010"|"11010011"|"11010100"|"11010101"|"11010111" + |"11011000"|"11011001"|"11011010"|"11011011"|"11011100"|"11011101"|"11011111" + |"11100000"|"11100001"|"11100010"|"11100011"|"11100100"|"11100101"|"11100111" + |"11101000"|"11101001"|"11101010"|"11101011"|"11101100"|"11101101"|"11101111" + |"11110000"|"11110001"|"11110010"|"11110011"|"11110100"|"11110101"|"11110111" + |"11111000"|"11111001"|"11111010"|"11111011"|"11111100"|"11111101"|"11111111" => + -- SET b,r + if MCycle = "001" then + ALU_Op <= "1010"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + end if; + when "11000110"|"11001110"|"11010110"|"11011110"|"11100110"|"11101110"|"11110110"|"11111110" => + -- SET b,(HL) + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 | 7 => + Set_Addr_To <= aXY; + when 2 => + ALU_Op <= "1010"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_Addr_To <= aXY; + TStates <= "100"; + when 3 => + Write <= '1'; + when others => + end case; + when "10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000111" + |"10001000"|"10001001"|"10001010"|"10001011"|"10001100"|"10001101"|"10001111" + |"10010000"|"10010001"|"10010010"|"10010011"|"10010100"|"10010101"|"10010111" + |"10011000"|"10011001"|"10011010"|"10011011"|"10011100"|"10011101"|"10011111" + |"10100000"|"10100001"|"10100010"|"10100011"|"10100100"|"10100101"|"10100111" + |"10101000"|"10101001"|"10101010"|"10101011"|"10101100"|"10101101"|"10101111" + |"10110000"|"10110001"|"10110010"|"10110011"|"10110100"|"10110101"|"10110111" + |"10111000"|"10111001"|"10111010"|"10111011"|"10111100"|"10111101"|"10111111" => + -- RES b,r + if MCycle = "001" then + ALU_Op <= "1011"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + end if; + when "10000110"|"10001110"|"10010110"|"10011110"|"10100110"|"10101110"|"10110110"|"10111110" => + -- RES b,(HL) + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 | 7 => + Set_Addr_To <= aXY; + when 2 => + ALU_Op <= "1011"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_Addr_To <= aXY; + TStates <= "100"; + when 3 => + Write <= '1'; + when others => + end case; + end case; + + when others => + +------------------------------------------------------------------------------ +-- +-- ED prefixed instructions +-- +------------------------------------------------------------------------------ + + case IRB is + when "00000000"|"00000001"|"00000010"|"00000011"|"00000100"|"00000101"|"00000110"|"00000111" + |"00001000"|"00001001"|"00001010"|"00001011"|"00001100"|"00001101"|"00001110"|"00001111" + |"00010000"|"00010001"|"00010010"|"00010011"|"00010100"|"00010101"|"00010110"|"00010111" + |"00011000"|"00011001"|"00011010"|"00011011"|"00011100"|"00011101"|"00011110"|"00011111" + |"00100000"|"00100001"|"00100010"|"00100011"|"00100100"|"00100101"|"00100110"|"00100111" + |"00101000"|"00101001"|"00101010"|"00101011"|"00101100"|"00101101"|"00101110"|"00101111" + |"00110000"|"00110001"|"00110010"|"00110011"|"00110100"|"00110101"|"00110110"|"00110111" + |"00111000"|"00111001"|"00111010"|"00111011"|"00111100"|"00111101"|"00111110"|"00111111" + + + |"10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000110"|"10000111" + |"10001000"|"10001001"|"10001010"|"10001011"|"10001100"|"10001101"|"10001110"|"10001111" + |"10010000"|"10010001"|"10010010"|"10010011"|"10010100"|"10010101"|"10010110"|"10010111" + |"10011000"|"10011001"|"10011010"|"10011011"|"10011100"|"10011101"|"10011110"|"10011111" + | "10100100"|"10100101"|"10100110"|"10100111" + | "10101100"|"10101101"|"10101110"|"10101111" + | "10110100"|"10110101"|"10110110"|"10110111" + | "10111100"|"10111101"|"10111110"|"10111111" + |"11000000"|"11000001"|"11000010"|"11000011"|"11000100"|"11000101"|"11000110"|"11000111" + |"11001000"|"11001001"|"11001010"|"11001011"|"11001100"|"11001101"|"11001110"|"11001111" + |"11010000"|"11010001"|"11010010"|"11010011"|"11010100"|"11010101"|"11010110"|"11010111" + |"11011000"|"11011001"|"11011010"|"11011011"|"11011100"|"11011101"|"11011110"|"11011111" + |"11100000"|"11100001"|"11100010"|"11100011"|"11100100"|"11100101"|"11100110"|"11100111" + |"11101000"|"11101001"|"11101010"|"11101011"|"11101100"|"11101101"|"11101110"|"11101111" + |"11110000"|"11110001"|"11110010"|"11110011"|"11110100"|"11110101"|"11110110"|"11110111" + |"11111000"|"11111001"|"11111010"|"11111011"|"11111100"|"11111101"|"11111110"|"11111111" => + null; -- NOP, undocumented + when "01111110"|"01111111" => + -- NOP, undocumented + null; +-- 8 BIT LOAD GROUP + when "01010111" => + -- LD A,I + Special_LD <= "100"; + TStates <= "101"; + when "01011111" => + -- LD A,R + Special_LD <= "101"; + TStates <= "101"; + when "01000111" => + -- LD I,A + Special_LD <= "110"; + TStates <= "101"; + when "01001111" => + -- LD R,A + Special_LD <= "111"; + TStates <= "101"; +-- 16 BIT LOAD GROUP + when "01001011"|"01011011"|"01101011"|"01111011" => + -- LD dd,(nn) + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + LDW <= '1'; + when 4 => + Read_To_Reg <= '1'; + if IR(5 downto 4) = "11" then + Set_BusA_To <= "1000"; + else + Set_BusA_To(2 downto 1) <= IR(5 downto 4); + Set_BusA_To(0) <= '1'; + end if; + Inc_WZ <= '1'; + Set_Addr_To <= aZI; + when 5 => + Read_To_Reg <= '1'; + if IR(5 downto 4) = "11" then + Set_BusA_To <= "1001"; + else + Set_BusA_To(2 downto 1) <= IR(5 downto 4); + Set_BusA_To(0) <= '0'; + end if; + when others => null; + end case; + when "01000011"|"01010011"|"01100011"|"01110011" => + -- LD (nn),dd + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + LDW <= '1'; + if IR(5 downto 4) = "11" then + Set_BusB_To <= "1000"; + else + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + Set_BusB_To(0) <= '1'; + Set_BusB_To(3) <= '0'; + end if; + when 4 => + Inc_WZ <= '1'; + Set_Addr_To <= aZI; + Write <= '1'; + if IR(5 downto 4) = "11" then + Set_BusB_To <= "1001"; + else + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + Set_BusB_To(0) <= '0'; + Set_BusB_To(3) <= '0'; + end if; + when 5 => + Write <= '1'; + when others => null; + end case; + when "10100000" | "10101000" | "10110000" | "10111000" => + -- LDI, LDD, LDIR, LDDR + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + IncDec_16 <= "1100"; -- BC + when 2 => + Set_BusB_To <= "0110"; + Set_BusA_To(2 downto 0) <= "111"; + ALU_Op <= "0000"; + Set_Addr_To <= aDE; + if IR(3) = '0' then + IncDec_16 <= "0110"; -- IX + else + IncDec_16 <= "1110"; + end if; + when 3 => + I_BT <= '1'; + TStates <= "101"; + Write <= '1'; + if IR(3) = '0' then + IncDec_16 <= "0101"; -- DE + else + IncDec_16 <= "1101"; + end if; + when 4 => + NoRead <= '1'; + TStates <= "101"; + when others => null; + end case; + when "10100001" | "10101001" | "10110001" | "10111001" => + -- CPI, CPD, CPIR, CPDR + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + IncDec_16 <= "1100"; -- BC + when 2 => + Set_BusB_To <= "0110"; + Set_BusA_To(2 downto 0) <= "111"; + ALU_Op <= "0111"; + Save_ALU <= '1'; + PreserveC <= '1'; + if IR(3) = '0' then + IncDec_16 <= "0110"; + else + IncDec_16 <= "1110"; + end if; + when 3 => + NoRead <= '1'; + I_BC <= '1'; + TStates <= "101"; + when 4 => + NoRead <= '1'; + TStates <= "101"; + when others => null; + end case; + when "01000100"|"01001100"|"01010100"|"01011100"|"01100100"|"01101100"|"01110100"|"01111100" => + -- NEG + Alu_OP <= "0010"; + Set_BusB_To <= "0111"; + Set_BusA_To <= "1010"; + Read_To_Acc <= '1'; + Save_ALU <= '1'; + when "01000110"|"01001110"|"01100110"|"01101110" => + -- IM 0 + IMode <= "00"; + when "01010110"|"01110110" => + -- IM 1 + IMode <= "01"; + when "01011110"|"01110111" => + -- IM 2 + IMode <= "10"; +-- 16 bit arithmetic + when "01001010"|"01011010"|"01101010"|"01111010" => + -- ADC HL,ss + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + NoRead <= '1'; + ALU_Op <= "0001"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_BusA_To(2 downto 0) <= "101"; + case to_integer(unsigned(IR(5 downto 4))) is + when 0|1|2 => + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + Set_BusB_To(0) <= '1'; + when others => + Set_BusB_To <= "1000"; + end case; + TStates <= "100"; + when 3 => + NoRead <= '1'; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + ALU_Op <= "0001"; + Set_BusA_To(2 downto 0) <= "100"; + case to_integer(unsigned(IR(5 downto 4))) is + when 0|1|2 => + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + Set_BusB_To(0) <= '0'; + when others => + Set_BusB_To <= "1001"; + end case; + when others => + end case; + when "01000010"|"01010010"|"01100010"|"01110010" => + -- SBC HL,ss + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + NoRead <= '1'; + ALU_Op <= "0011"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_BusA_To(2 downto 0) <= "101"; + case to_integer(unsigned(IR(5 downto 4))) is + when 0|1|2 => + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + Set_BusB_To(0) <= '1'; + when others => + Set_BusB_To <= "1000"; + end case; + TStates <= "100"; + when 3 => + NoRead <= '1'; + ALU_Op <= "0011"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_BusA_To(2 downto 0) <= "100"; + case to_integer(unsigned(IR(5 downto 4))) is + when 0|1|2 => + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + when others => + Set_BusB_To <= "1001"; + end case; + when others => + end case; + when "01101111" => + -- RLD + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 2 => + NoRead <= '1'; + Set_Addr_To <= aXY; + when 3 => + Read_To_Reg <= '1'; + Set_BusB_To(2 downto 0) <= "110"; + Set_BusA_To(2 downto 0) <= "111"; + ALU_Op <= "1101"; + TStates <= "100"; + Set_Addr_To <= aXY; + Save_ALU <= '1'; + when 4 => + I_RLD <= '1'; + Write <= '1'; + when others => + end case; + when "01100111" => + -- RRD + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 2 => + Set_Addr_To <= aXY; + when 3 => + Read_To_Reg <= '1'; + Set_BusB_To(2 downto 0) <= "110"; + Set_BusA_To(2 downto 0) <= "111"; + ALU_Op <= "1110"; + TStates <= "100"; + Set_Addr_To <= aXY; + Save_ALU <= '1'; + when 4 => + I_RRD <= '1'; + Write <= '1'; + when others => + end case; + when "01000101"|"01001101"|"01010101"|"01011101"|"01100101"|"01101101"|"01110101"|"01111101" => + -- RETI, RETN + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_TO <= aSP; + when 2 => + IncDec_16 <= "0111"; + Set_Addr_To <= aSP; + LDZ <= '1'; + when 3 => + Jump <= '1'; + IncDec_16 <= "0111"; + I_RETN <= '1'; + when others => null; + end case; + when "01000000"|"01001000"|"01010000"|"01011000"|"01100000"|"01101000"|"01110000"|"01111000" => + -- IN r,(C) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aBC; + when 2 => + IORQ <= '1'; + if IR(5 downto 3) /= "110" then + Read_To_Reg <= '1'; + Set_BusA_To(2 downto 0) <= IR(5 downto 3); + end if; + I_INRC <= '1'; + when others => + end case; + when "01000001"|"01001001"|"01010001"|"01011001"|"01100001"|"01101001"|"01110001"|"01111001" => + -- OUT (C),r + -- OUT (C),0 + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aBC; + Set_BusB_To(2 downto 0) <= IR(5 downto 3); + if IR(5 downto 3) = "110" then + Set_BusB_To(3) <= '1'; + end if; + when 2 => + Write <= '1'; + IORQ <= '1'; + when others => + end case; + when "10100010" | "10101010" | "10110010" | "10111010" => + -- INI, IND, INIR, INDR + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aBC; + Set_BusB_To <= "1010"; + Set_BusA_To <= "0000"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + ALU_Op <= "0010"; + when 2 => + IORQ <= '1'; + Set_BusB_To <= "0110"; + Set_Addr_To <= aXY; + when 3 => + if IR(3) = '0' then + IncDec_16 <= "0010"; + else + IncDec_16 <= "1010"; + end if; + TStates <= "100"; + Write <= '1'; + I_BTR <= '1'; + when 4 => + NoRead <= '1'; + TStates <= "101"; + when others => null; + end case; + when "10100011" | "10101011" | "10110011" | "10111011" => + -- OUTI, OUTD, OTIR, OTDR + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 1 => + TStates <= "101"; + Set_Addr_To <= aXY; + Set_BusB_To <= "1010"; + Set_BusA_To <= "0000"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + ALU_Op <= "0010"; + when 2 => + Set_BusB_To <= "0110"; + Set_Addr_To <= aBC; + when 3 => + if IR(3) = '0' then + IncDec_16 <= "0010"; + else + IncDec_16 <= "1010"; + end if; + IORQ <= '1'; + Write <= '1'; + I_BTR <= '1'; + when 4 => + NoRead <= '1'; + TStates <= "101"; + when others => null; + end case; + end case; + + end case; + + if Mode = 1 then + if MCycle = "001" then +-- TStates <= "100"; + else + TStates <= "011"; + end if; + end if; + + if Mode = 3 then + if MCycle = "001" then +-- TStates <= "100"; + else + TStates <= "100"; + end if; + end if; + + if Mode < 2 then + if MCycle = "110" then + Inc_PC <= '1'; + if Mode = 1 then + Set_Addr_To <= aXY; + TStates <= "100"; + Set_BusB_To(2 downto 0) <= SSS; + Set_BusB_To(3) <= '0'; + end if; + if IRB = "00110110" or IRB = "11001011" then + Set_Addr_To <= aNone; + end if; + end if; + if MCycle = "111" then + if Mode = 0 then + TStates <= "101"; + end if; + if ISet /= "01" then + Set_Addr_To <= aXY; + end if; + Set_BusB_To(2 downto 0) <= SSS; + Set_BusB_To(3) <= '0'; + if IRB = "00110110" or ISet = "01" then + -- LD (HL),n + Inc_PC <= '1'; + else + NoRead <= '1'; + end if; + end if; + end if; + + end process; + +end; diff --git a/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/T80/T80_Pack.vhd b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/T80/T80_Pack.vhd new file mode 100644 index 00000000..ac7d34da --- /dev/null +++ b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/T80/T80_Pack.vhd @@ -0,0 +1,208 @@ +-- +-- Z80 compatible microprocessor core +-- +-- Version : 0242 +-- +-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t80/ +-- +-- Limitations : +-- +-- File history : +-- + +library IEEE; +use IEEE.std_logic_1164.all; + +package T80_Pack is + + component T80 + generic( + Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB + IOWait : integer := 0; -- 1 => Single cycle I/O, 1 => Std I/O cycle + Flag_C : integer := 0; + Flag_N : integer := 1; + Flag_P : integer := 2; + Flag_X : integer := 3; + Flag_H : integer := 4; + Flag_Y : integer := 5; + Flag_Z : integer := 6; + Flag_S : integer := 7 + ); + port( + RESET_n : in std_logic; + CLK_n : in std_logic; + CEN : in std_logic; + WAIT_n : in std_logic; + INT_n : in std_logic; + NMI_n : in std_logic; + BUSRQ_n : in std_logic; + M1_n : out std_logic; + IORQ : out std_logic; + NoRead : out std_logic; + Write : out std_logic; + RFSH_n : out std_logic; + HALT_n : out std_logic; + BUSAK_n : out std_logic; + A : out std_logic_vector(15 downto 0); + DInst : in std_logic_vector(7 downto 0); + DI : in std_logic_vector(7 downto 0); + DO : out std_logic_vector(7 downto 0); + MC : out std_logic_vector(2 downto 0); + TS : out std_logic_vector(2 downto 0); + IntCycle_n : out std_logic; + IntE : out std_logic; + Stop : out std_logic + ); + end component; + + component T80_Reg + port( + Clk : in std_logic; + CEN : in std_logic; + WEH : in std_logic; + WEL : in std_logic; + AddrA : in std_logic_vector(2 downto 0); + AddrB : in std_logic_vector(2 downto 0); + AddrC : in std_logic_vector(2 downto 0); + DIH : in std_logic_vector(7 downto 0); + DIL : in std_logic_vector(7 downto 0); + DOAH : out std_logic_vector(7 downto 0); + DOAL : out std_logic_vector(7 downto 0); + DOBH : out std_logic_vector(7 downto 0); + DOBL : out std_logic_vector(7 downto 0); + DOCH : out std_logic_vector(7 downto 0); + DOCL : out std_logic_vector(7 downto 0) + ); + end component; + + component T80_MCode + generic( + Mode : integer := 0; + Flag_C : integer := 0; + Flag_N : integer := 1; + Flag_P : integer := 2; + Flag_X : integer := 3; + Flag_H : integer := 4; + Flag_Y : integer := 5; + Flag_Z : integer := 6; + Flag_S : integer := 7 + ); + port( + IR : in std_logic_vector(7 downto 0); + ISet : in std_logic_vector(1 downto 0); + MCycle : in std_logic_vector(2 downto 0); + F : in std_logic_vector(7 downto 0); + NMICycle : in std_logic; + IntCycle : in std_logic; + MCycles : out std_logic_vector(2 downto 0); + TStates : out std_logic_vector(2 downto 0); + Prefix : out std_logic_vector(1 downto 0); -- None,BC,ED,DD/FD + Inc_PC : out std_logic; + Inc_WZ : out std_logic; + IncDec_16 : out std_logic_vector(3 downto 0); -- BC,DE,HL,SP 0 is inc + Read_To_Reg : out std_logic; + Read_To_Acc : out std_logic; + Set_BusA_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F + Set_BusB_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0 + ALU_Op : out std_logic_vector(3 downto 0); + -- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None + Save_ALU : out std_logic; + PreserveC : out std_logic; + Arith16 : out std_logic; + Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI + IORQ : out std_logic; + Jump : out std_logic; + JumpE : out std_logic; + JumpXY : out std_logic; + Call : out std_logic; + RstP : out std_logic; + LDZ : out std_logic; + LDW : out std_logic; + LDSPHL : out std_logic; + Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None + ExchangeDH : out std_logic; + ExchangeRp : out std_logic; + ExchangeAF : out std_logic; + ExchangeRS : out std_logic; + I_DJNZ : out std_logic; + I_CPL : out std_logic; + I_CCF : out std_logic; + I_SCF : out std_logic; + I_RETN : out std_logic; + I_BT : out std_logic; + I_BC : out std_logic; + I_BTR : out std_logic; + I_RLD : out std_logic; + I_RRD : out std_logic; + I_INRC : out std_logic; + SetDI : out std_logic; + SetEI : out std_logic; + IMode : out std_logic_vector(1 downto 0); + Halt : out std_logic; + NoRead : out std_logic; + Write : out std_logic + ); + end component; + + component T80_ALU + generic( + Mode : integer := 0; + Flag_C : integer := 0; + Flag_N : integer := 1; + Flag_P : integer := 2; + Flag_X : integer := 3; + Flag_H : integer := 4; + Flag_Y : integer := 5; + Flag_Z : integer := 6; + Flag_S : integer := 7 + ); + port( + Arith16 : in std_logic; + Z16 : in std_logic; + ALU_Op : in std_logic_vector(3 downto 0); + IR : in std_logic_vector(5 downto 0); + ISet : in std_logic_vector(1 downto 0); + BusA : in std_logic_vector(7 downto 0); + BusB : in std_logic_vector(7 downto 0); + F_In : in std_logic_vector(7 downto 0); + Q : out std_logic_vector(7 downto 0); + F_Out : out std_logic_vector(7 downto 0) + ); + end component; + +end; diff --git a/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/T80/T80_Reg.vhd b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/T80/T80_Reg.vhd new file mode 100644 index 00000000..828485fb --- /dev/null +++ b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/T80/T80_Reg.vhd @@ -0,0 +1,105 @@ +-- +-- T80 Registers, technology independent +-- +-- Version : 0244 +-- +-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t51/ +-- +-- Limitations : +-- +-- File history : +-- +-- 0242 : Initial release +-- +-- 0244 : Changed to single register file +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +entity T80_Reg is + port( + Clk : in std_logic; + CEN : in std_logic; + WEH : in std_logic; + WEL : in std_logic; + AddrA : in std_logic_vector(2 downto 0); + AddrB : in std_logic_vector(2 downto 0); + AddrC : in std_logic_vector(2 downto 0); + DIH : in std_logic_vector(7 downto 0); + DIL : in std_logic_vector(7 downto 0); + DOAH : out std_logic_vector(7 downto 0); + DOAL : out std_logic_vector(7 downto 0); + DOBH : out std_logic_vector(7 downto 0); + DOBL : out std_logic_vector(7 downto 0); + DOCH : out std_logic_vector(7 downto 0); + DOCL : out std_logic_vector(7 downto 0) + ); +end T80_Reg; + +architecture rtl of T80_Reg is + + type Register_Image is array (natural range <>) of std_logic_vector(7 downto 0); + signal RegsH : Register_Image(0 to 7); + signal RegsL : Register_Image(0 to 7); + +begin + + process (Clk) + begin + if Clk'event and Clk = '1' then + if CEN = '1' then + if WEH = '1' then + RegsH(to_integer(unsigned(AddrA))) <= DIH; + end if; + if WEL = '1' then + RegsL(to_integer(unsigned(AddrA))) <= DIL; + end if; + end if; + end if; + end process; + + DOAH <= RegsH(to_integer(unsigned(AddrA))); + DOAL <= RegsL(to_integer(unsigned(AddrA))); + DOBH <= RegsH(to_integer(unsigned(AddrB))); + DOBL <= RegsL(to_integer(unsigned(AddrB))); + DOCH <= RegsH(to_integer(unsigned(AddrC))); + DOCL <= RegsL(to_integer(unsigned(AddrC))); + +end; diff --git a/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/build_id.tcl b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/build_id.tcl new file mode 100644 index 00000000..938515d8 --- /dev/null +++ b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/build_id.tcl @@ -0,0 +1,35 @@ +# ================================================================================ +# +# Build ID Verilog Module Script +# Jeff Wiencrot - 8/1/2011 +# +# Generates a Verilog module that contains a timestamp, +# from the current build. These values are available from the build_date, build_time, +# physical_address, and host_name output ports of the build_id module in the build_id.v +# Verilog source file. +# +# ================================================================================ + +proc generateBuildID_Verilog {} { + + # Get the timestamp (see: http://www.altera.com/support/examples/tcl/tcl-date-time-stamp.html) + set buildDate [ clock format [ clock seconds ] -format %y%m%d ] + set buildTime [ clock format [ clock seconds ] -format %H%M%S ] + + # Create a Verilog file for output + set outputFileName "rtl/build_id.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/Phoenix Hardware/Phoenix_MIST/rtl/build_id.v b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/build_id.v new file mode 100644 index 00000000..926fdbc9 --- /dev/null +++ b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/build_id.v @@ -0,0 +1,2 @@ +`define BUILD_DATE "190312" +`define BUILD_TIME "215035" diff --git a/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/dac.vhd b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/dac.vhd new file mode 100644 index 00000000..9685a6cc --- /dev/null +++ b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/dac.vhd @@ -0,0 +1,48 @@ +------------------------------------------------------------------------------- +-- +-- Delta-Sigma DAC +-- +-- Refer to Xilinx Application Note XAPP154. +-- +-- This DAC requires an external RC low-pass filter: +-- +-- dac_o 0---XXXXX---+---0 analog audio +-- 3k3 | +-- === 4n7 +-- | +-- GND +-- +------------------------------------------------------------------------------- + +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + +entity dac is + generic ( + C_bits : integer := 12 + ); + port ( + clk_i : in std_logic; + res_n_i : in std_logic; + dac_i : in std_logic_vector(C_bits-1 downto 0); + dac_o : out std_logic + ); +end dac; + +architecture rtl of dac is + signal sig_in: unsigned(C_bits downto 0); +begin + seq: process(clk_i, res_n_i) + begin + if res_n_i = '0' then + sig_in <= to_unsigned(2**C_bits, sig_in'length); + dac_o <= '0'; + elsif rising_edge(clk_i) then + -- not dac_i(C_bits-1) effectively adds 0x8..0 to dac_i + --sig_in <= sig_in + unsigned(sig_in(C_bits) & (not dac_i(C_bits-1)) & dac_i(C_bits-2 downto 0)); + sig_in <= sig_in + unsigned(sig_in(C_bits) & dac_i); + dac_o <= sig_in(C_bits); + end if; + end process seq; +end rtl; diff --git a/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/gen_ram.vhd b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/gen_ram.vhd new file mode 100644 index 00000000..0794fdc0 --- /dev/null +++ b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/gen_ram.vhd @@ -0,0 +1,82 @@ +-- ----------------------------------------------------------------------- +-- +-- Syntiac's generic VHDL support files. +-- +-- ----------------------------------------------------------------------- +-- Copyright 2005-2008 by Peter Wendrich (pwsoft@syntiac.com) +-- http://www.syntiac.com/fpga64.html +-- +-- Modified April 2016 by Dar (darfpga@aol.fr) +-- http://darfpga.blogspot.fr +-- Remove address register when writing +-- +-- ----------------------------------------------------------------------- +-- +-- gen_rwram.vhd +-- +-- ----------------------------------------------------------------------- +-- +-- generic ram. +-- +-- ----------------------------------------------------------------------- + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.numeric_std.ALL; + +-- ----------------------------------------------------------------------- + +entity gen_ram is + generic ( + dWidth : integer := 8; + aWidth : integer := 10 + ); + port ( + clk : in std_logic; + we : in std_logic; + addr : in std_logic_vector((aWidth-1) downto 0); + d : in std_logic_vector((dWidth-1) downto 0); + q : out std_logic_vector((dWidth-1) downto 0) + ); +end entity; + +-- ----------------------------------------------------------------------- + +architecture rtl of gen_ram is + subtype addressRange is integer range 0 to ((2**aWidth)-1); + type ramDef is array(addressRange) of std_logic_vector((dWidth-1) downto 0); + signal ram: ramDef; + + signal rAddrReg : std_logic_vector((aWidth-1) downto 0); + signal qReg : std_logic_vector((dWidth-1) downto 0); +begin +-- ----------------------------------------------------------------------- +-- Signals to entity interface +-- ----------------------------------------------------------------------- + q <= qReg; + +-- ----------------------------------------------------------------------- +-- Memory write +-- ----------------------------------------------------------------------- + process(clk) + begin + if rising_edge(clk) then + if we = '1' then + ram(to_integer(unsigned(addr))) <= d; + end if; + end if; + end process; + +-- ----------------------------------------------------------------------- +-- Memory read +-- ----------------------------------------------------------------------- + process(clk) + begin + if rising_edge(clk) then +-- qReg <= ram(to_integer(unsigned(rAddrReg))); +-- rAddrReg <= addr; + qReg <= ram(to_integer(unsigned(addr))); + end if; + end process; +end architecture; + diff --git a/Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/greybox_tmp/cbx_args.txt b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/greybox_tmp/cbx_args.txt similarity index 100% rename from Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/greybox_tmp/cbx_args.txt rename to Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/greybox_tmp/cbx_args.txt diff --git a/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/hq2x.sv b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/hq2x.sv new file mode 100644 index 00000000..f17732b6 --- /dev/null +++ b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/hq2x.sv @@ -0,0 +1,454 @@ +// +// +// Copyright (c) 2012-2013 Ludvig Strigeus +// Copyright (c) 2017 Sorgelig +// +// This program is GPL Licensed. See COPYING for the full license. +// +// +//////////////////////////////////////////////////////////////////////////////////////////////////////// + +// synopsys translate_off +`timescale 1 ps / 1 ps +// synopsys translate_on + +`define BITS_TO_FIT(N) ( \ + N <= 2 ? 0 : \ + N <= 4 ? 1 : \ + N <= 8 ? 2 : \ + N <= 16 ? 3 : \ + N <= 32 ? 4 : \ + N <= 64 ? 5 : \ + N <= 128 ? 6 : \ + N <= 256 ? 7 : \ + N <= 512 ? 8 : \ + N <=1024 ? 9 : 10 ) + +module hq2x_in #(parameter LENGTH, parameter DWIDTH) +( + input clk, + + input [AWIDTH:0] rdaddr, + input rdbuf, + output[DWIDTH:0] q, + + input [AWIDTH:0] wraddr, + input wrbuf, + input [DWIDTH:0] data, + input wren +); + + localparam AWIDTH = `BITS_TO_FIT(LENGTH); + wire [DWIDTH:0] out[2]; + assign q = out[rdbuf]; + + hq2x_buf #(.NUMWORDS(LENGTH), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf0(clk,data,rdaddr,wraddr,wren && (wrbuf == 0),out[0]); + hq2x_buf #(.NUMWORDS(LENGTH), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf1(clk,data,rdaddr,wraddr,wren && (wrbuf == 1),out[1]); +endmodule + + +module hq2x_out #(parameter LENGTH, parameter DWIDTH) +( + input clk, + + input [AWIDTH:0] rdaddr, + input [1:0] rdbuf, + output[DWIDTH:0] q, + + input [AWIDTH:0] wraddr, + input [1:0] wrbuf, + input [DWIDTH:0] data, + input wren +); + + localparam AWIDTH = `BITS_TO_FIT(LENGTH*2); + wire [DWIDTH:0] out[4]; + assign q = out[rdbuf]; + + hq2x_buf #(.NUMWORDS(LENGTH*2), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf0(clk,data,rdaddr,wraddr,wren && (wrbuf == 0),out[0]); + hq2x_buf #(.NUMWORDS(LENGTH*2), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf1(clk,data,rdaddr,wraddr,wren && (wrbuf == 1),out[1]); + hq2x_buf #(.NUMWORDS(LENGTH*2), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf2(clk,data,rdaddr,wraddr,wren && (wrbuf == 2),out[2]); + hq2x_buf #(.NUMWORDS(LENGTH*2), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf3(clk,data,rdaddr,wraddr,wren && (wrbuf == 3),out[3]); +endmodule + + +module hq2x_buf #(parameter NUMWORDS, parameter AWIDTH, parameter DWIDTH) +( + input clock, + input [DWIDTH:0] data, + input [AWIDTH:0] rdaddress, + input [AWIDTH:0] wraddress, + input wren, + output [DWIDTH:0] q +); + + altsyncram altsyncram_component ( + .address_a (wraddress), + .clock0 (clock), + .data_a (data), + .wren_a (wren), + .address_b (rdaddress), + .q_b(q), + .aclr0 (1'b0), + .aclr1 (1'b0), + .addressstall_a (1'b0), + .addressstall_b (1'b0), + .byteena_a (1'b1), + .byteena_b (1'b1), + .clock1 (1'b1), + .clocken0 (1'b1), + .clocken1 (1'b1), + .clocken2 (1'b1), + .clocken3 (1'b1), + .data_b ({(DWIDTH+1){1'b1}}), + .eccstatus (), + .q_a (), + .rden_a (1'b1), + .rden_b (1'b1), + .wren_b (1'b0)); + defparam + altsyncram_component.address_aclr_b = "NONE", + altsyncram_component.address_reg_b = "CLOCK0", + altsyncram_component.clock_enable_input_a = "BYPASS", + altsyncram_component.clock_enable_input_b = "BYPASS", + altsyncram_component.clock_enable_output_b = "BYPASS", + altsyncram_component.intended_device_family = "Cyclone III", + altsyncram_component.lpm_type = "altsyncram", + altsyncram_component.numwords_a = NUMWORDS, + altsyncram_component.numwords_b = NUMWORDS, + altsyncram_component.operation_mode = "DUAL_PORT", + altsyncram_component.outdata_aclr_b = "NONE", + altsyncram_component.outdata_reg_b = "UNREGISTERED", + altsyncram_component.power_up_uninitialized = "FALSE", + altsyncram_component.read_during_write_mode_mixed_ports = "DONT_CARE", + altsyncram_component.widthad_a = AWIDTH+1, + altsyncram_component.widthad_b = AWIDTH+1, + altsyncram_component.width_a = DWIDTH+1, + altsyncram_component.width_b = DWIDTH+1, + altsyncram_component.width_byteena_a = 1; + +endmodule + +//////////////////////////////////////////////////////////////////////////////////////////////////////// + +module DiffCheck +( + input [17:0] rgb1, + input [17:0] rgb2, + output result +); + + wire [5:0] r = rgb1[5:1] - rgb2[5:1]; + wire [5:0] g = rgb1[11:7] - rgb2[11:7]; + wire [5:0] b = rgb1[17:13] - rgb2[17:13]; + wire [6:0] t = $signed(r) + $signed(b); + wire [6:0] gx = {g[5], g}; + wire [7:0] y = $signed(t) + $signed(gx); + wire [6:0] u = $signed(r) - $signed(b); + wire [7:0] v = $signed({g, 1'b0}) - $signed(t); + + // if y is inside (-24..24) + wire y_inside = (y < 8'h18 || y >= 8'he8); + + // if u is inside (-4, 4) + wire u_inside = (u < 7'h4 || u >= 7'h7c); + + // if v is inside (-6, 6) + wire v_inside = (v < 8'h6 || v >= 8'hfA); + assign result = !(y_inside && u_inside && v_inside); +endmodule + +module InnerBlend +( + input [8:0] Op, + input [5:0] A, + input [5:0] B, + input [5:0] C, + output [5:0] O +); + + function [8:0] mul6x3; + input [5:0] op1; + input [2:0] op2; + begin + mul6x3 = 9'd0; + if(op2[0]) mul6x3 = mul6x3 + op1; + if(op2[1]) mul6x3 = mul6x3 + {op1, 1'b0}; + if(op2[2]) mul6x3 = mul6x3 + {op1, 2'b00}; + end + endfunction + + wire OpOnes = Op[4]; + wire [8:0] Amul = mul6x3(A, Op[7:5]); + wire [8:0] Bmul = mul6x3(B, {Op[3:2], 1'b0}); + wire [8:0] Cmul = mul6x3(C, {Op[1:0], 1'b0}); + wire [8:0] At = Amul; + wire [8:0] Bt = (OpOnes == 0) ? Bmul : {3'b0, B}; + wire [8:0] Ct = (OpOnes == 0) ? Cmul : {3'b0, C}; + wire [9:0] Res = {At, 1'b0} + Bt + Ct; + assign O = Op[8] ? A : Res[9:4]; +endmodule + +module Blend +( + input [5:0] rule, + input disable_hq2x, + input [17:0] E, + input [17:0] A, + input [17:0] B, + input [17:0] D, + input [17:0] F, + input [17:0] H, + output [17:0] Result +); + + reg [1:0] input_ctrl; + reg [8:0] op; + localparam BLEND0 = 9'b1_xxx_x_xx_xx; // 0: A + localparam BLEND1 = 9'b0_110_0_10_00; // 1: (A * 12 + B * 4) >> 4 + localparam BLEND2 = 9'b0_100_0_10_10; // 2: (A * 8 + B * 4 + C * 4) >> 4 + localparam BLEND3 = 9'b0_101_0_10_01; // 3: (A * 10 + B * 4 + C * 2) >> 4 + localparam BLEND4 = 9'b0_110_0_01_01; // 4: (A * 12 + B * 2 + C * 2) >> 4 + localparam BLEND5 = 9'b0_010_0_11_11; // 5: (A * 4 + (B + C) * 6) >> 4 + localparam BLEND6 = 9'b0_111_1_xx_xx; // 6: (A * 14 + B + C) >> 4 + localparam AB = 2'b00; + localparam AD = 2'b01; + localparam DB = 2'b10; + localparam BD = 2'b11; + wire is_diff; + DiffCheck diff_checker(rule[1] ? B : H, rule[0] ? D : F, is_diff); + + always @* begin + case({!is_diff, rule[5:2]}) + 1,17: {op, input_ctrl} = {BLEND1, AB}; + 2,18: {op, input_ctrl} = {BLEND1, DB}; + 3,19: {op, input_ctrl} = {BLEND1, BD}; + 4,20: {op, input_ctrl} = {BLEND2, DB}; + 5,21: {op, input_ctrl} = {BLEND2, AB}; + 6,22: {op, input_ctrl} = {BLEND2, AD}; + + 8: {op, input_ctrl} = {BLEND0, 2'bxx}; + 9: {op, input_ctrl} = {BLEND0, 2'bxx}; + 10: {op, input_ctrl} = {BLEND0, 2'bxx}; + 11: {op, input_ctrl} = {BLEND1, AB}; + 12: {op, input_ctrl} = {BLEND1, AB}; + 13: {op, input_ctrl} = {BLEND1, AB}; + 14: {op, input_ctrl} = {BLEND1, DB}; + 15: {op, input_ctrl} = {BLEND1, BD}; + + 24: {op, input_ctrl} = {BLEND2, DB}; + 25: {op, input_ctrl} = {BLEND5, DB}; + 26: {op, input_ctrl} = {BLEND6, DB}; + 27: {op, input_ctrl} = {BLEND2, DB}; + 28: {op, input_ctrl} = {BLEND4, DB}; + 29: {op, input_ctrl} = {BLEND5, DB}; + 30: {op, input_ctrl} = {BLEND3, BD}; + 31: {op, input_ctrl} = {BLEND3, DB}; + default: {op, input_ctrl} = 11'bx; + endcase + + // Setting op[8] effectively disables HQ2X because blend will always return E. + if (disable_hq2x) op[8] = 1; + end + + // Generate inputs to the inner blender. Valid combinations. + // 00: E A B + // 01: E A D + // 10: E D B + // 11: E B D + wire [17:0] Input1 = E; + wire [17:0] Input2 = !input_ctrl[1] ? A : + !input_ctrl[0] ? D : B; + + wire [17:0] Input3 = !input_ctrl[0] ? B : D; + InnerBlend inner_blend1(op, Input1[5:0], Input2[5:0], Input3[5:0], Result[5:0]); + InnerBlend inner_blend2(op, Input1[11:6], Input2[11:6], Input3[11:6], Result[11:6]); + InnerBlend inner_blend3(op, Input1[17:12], Input2[17:12], Input3[17:12], Result[17:12]); +endmodule + + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +module Hq2x #(parameter LENGTH, parameter HALF_DEPTH) +( + input clk, + input ce_x4, + input [DWIDTH:0] inputpixel, + input mono, + input disable_hq2x, + input reset_frame, + input reset_line, + input [1:0] read_y, + input [AWIDTH+1:0] read_x, + output [DWIDTH:0] outpixel +); + + +localparam AWIDTH = `BITS_TO_FIT(LENGTH); +localparam DWIDTH = HALF_DEPTH ? 8 : 17; + +wire [5:0] hqTable[256] = '{ + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 47, 35, 23, 15, 55, 39, + 19, 19, 26, 58, 19, 19, 26, 58, 23, 15, 35, 35, 23, 15, 7, 35, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 55, 39, 23, 15, 51, 43, + 19, 19, 26, 58, 19, 19, 26, 58, 23, 15, 51, 35, 23, 15, 7, 43, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 61, 35, 35, 23, 61, 51, 35, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 51, 35, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 61, 7, 35, 23, 61, 7, 43, + 19, 19, 26, 11, 19, 19, 26, 58, 23, 15, 51, 35, 23, 61, 7, 43, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 47, 35, 23, 15, 55, 39, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 51, 35, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 55, 39, 23, 15, 51, 43, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 39, 23, 15, 7, 43, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 51, 39, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 7, 35, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 7, 43, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 7, 35, 23, 15, 7, 43 +}; + +reg [17:0] Prev0, Prev1, Prev2, Curr0, Curr1, Next0, Next1, Next2; +reg [17:0] A, B, D, F, G, H; +reg [7:0] pattern, nextpatt; +reg [1:0] i; +reg [7:0] y; + +wire curbuf = y[0]; +reg prevbuf = 0; +wire iobuf = !curbuf; + +wire diff0, diff1; +DiffCheck diffcheck0(Curr1, (i == 0) ? Prev0 : (i == 1) ? Curr0 : (i == 2) ? Prev2 : Next1, diff0); +DiffCheck diffcheck1(Curr1, (i == 0) ? Prev1 : (i == 1) ? Next0 : (i == 2) ? Curr2 : Next2, diff1); + +wire [7:0] new_pattern = {diff1, diff0, pattern[7:2]}; + +wire [17:0] X = (i == 0) ? A : (i == 1) ? Prev1 : (i == 2) ? Next1 : G; +wire [17:0] blend_result; +Blend blender(hqTable[nextpatt], disable_hq2x, Curr0, X, B, D, F, H, blend_result); + +reg Curr2_addr1; +reg [AWIDTH:0] Curr2_addr2; +wire [17:0] Curr2 = HALF_DEPTH ? h2rgb(Curr2tmp) : Curr2tmp; +wire [DWIDTH:0] Curr2tmp; + +reg [AWIDTH:0] wrin_addr2; +reg [DWIDTH:0] wrpix; +reg wrin_en; + +function [17:0] h2rgb; + input [8:0] v; +begin + h2rgb = mono ? {v[5:3],v[2:0], v[5:3],v[2:0], v[5:3],v[2:0]} : {v[8:6],v[8:6],v[5:3],v[5:3],v[2:0],v[2:0]}; +end +endfunction + +function [8:0] rgb2h; + input [17:0] v; +begin + rgb2h = mono ? {3'b000, v[17:15], v[14:12]} : {v[17:15], v[11:9], v[5:3]}; +end +endfunction + +hq2x_in #(.LENGTH(LENGTH), .DWIDTH(DWIDTH)) hq2x_in +( + .clk(clk), + + .rdaddr(Curr2_addr2), + .rdbuf(Curr2_addr1), + .q(Curr2tmp), + + .wraddr(wrin_addr2), + .wrbuf(iobuf), + .data(wrpix), + .wren(wrin_en) +); + +reg [1:0] wrout_addr1; +reg [AWIDTH+1:0] wrout_addr2; +reg wrout_en; +reg [DWIDTH:0] wrdata; + +hq2x_out #(.LENGTH(LENGTH), .DWIDTH(DWIDTH)) hq2x_out +( + .clk(clk), + + .rdaddr(read_x), + .rdbuf(read_y), + .q(outpixel), + + .wraddr(wrout_addr2), + .wrbuf(wrout_addr1), + .data(wrdata), + .wren(wrout_en) +); + +always @(posedge clk) begin + reg [AWIDTH:0] offs; + reg old_reset_line; + reg old_reset_frame; + + wrout_en <= 0; + wrin_en <= 0; + + if(ce_x4) begin + + pattern <= new_pattern; + + if(~&offs) begin + if (i == 0) begin + Curr2_addr1 <= prevbuf; + Curr2_addr2 <= offs; + end + if (i == 1) begin + Prev2 <= Curr2; + Curr2_addr1 <= curbuf; + Curr2_addr2 <= offs; + end + if (i == 2) begin + Next2 <= HALF_DEPTH ? h2rgb(inputpixel) : inputpixel; + wrpix <= inputpixel; + wrin_addr2 <= offs; + wrin_en <= 1; + end + if (i == 3) begin + offs <= offs + 1'd1; + end + + if(HALF_DEPTH) wrdata <= rgb2h(blend_result); + else wrdata <= blend_result; + + wrout_addr1 <= {curbuf, i[1]}; + wrout_addr2 <= {offs, i[1]^i[0]}; + wrout_en <= 1; + end + + if(i==3) begin + nextpatt <= {new_pattern[7:6], new_pattern[3], new_pattern[5], new_pattern[2], new_pattern[4], new_pattern[1:0]}; + {A, G} <= {Prev0, Next0}; + {B, F, H, D} <= {Prev1, Curr2, Next1, Curr0}; + {Prev0, Prev1} <= {Prev1, Prev2}; + {Curr0, Curr1} <= {Curr1, Curr2}; + {Next0, Next1} <= {Next1, Next2}; + end else begin + nextpatt <= {nextpatt[5], nextpatt[3], nextpatt[0], nextpatt[6], nextpatt[1], nextpatt[7], nextpatt[4], nextpatt[2]}; + {B, F, H, D} <= {F, H, D, B}; + end + + i <= i + 1'b1; + if(old_reset_line && ~reset_line) begin + old_reset_frame <= reset_frame; + offs <= 0; + i <= 0; + y <= y + 1'd1; + prevbuf <= curbuf; + if(old_reset_frame & ~reset_frame) begin + y <= 0; + prevbuf <= 0; + end + end + + old_reset_line <= reset_line; + end +end + +endmodule // Hq2x diff --git a/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/mist_io.v b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/mist_io.v new file mode 100644 index 00000000..2f41221f --- /dev/null +++ b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/mist_io.v @@ -0,0 +1,530 @@ +// +// mist_io.v +// +// mist_io for the MiST board +// http://code.google.com/p/mist-board/ +// +// Copyright (c) 2014 Till Harbaum +// Copyright (c) 2015-2017 Sorgelig +// +// This source file is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This source file is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +/////////////////////////////////////////////////////////////////////// + +// +// Use buffer to access SD card. It's time-critical part. +// Made module synchroneous with 2 clock domains: clk_sys and SPI_SCK +// (Sorgelig) +// +// for synchronous projects default value for PS2DIV is fine for any frequency of system clock. +// clk_ps2 = clk_sys/(PS2DIV*2) +// + +module mist_io #(parameter STRLEN=0, parameter PS2DIV=100) +( + + // parameter STRLEN and the actual length of conf_str have to match + input [(8*STRLEN)-1:0] conf_str, + + // Global clock. It should be around 100MHz (higher is better). + input clk_sys, + + // Global SPI clock from ARM. 24MHz + input SPI_SCK, + + input CONF_DATA0, + input SPI_SS2, + output SPI_DO, + input SPI_DI, + + output reg [7:0] joystick_0, + output reg [7:0] joystick_1, +// output reg [31:0] joystick_2, +// output reg [31:0] joystick_3, +// output reg [31:0] joystick_4, + output reg [15:0] joystick_analog_0, + output reg [15:0] joystick_analog_1, + output [1:0] buttons, + output [1:0] switches, + output scandoublerD, + output ypbpr, + + output reg [31:0] status, + + // SD config + input sd_conf, + input sd_sdhc, + output [1:0] img_mounted, // signaling that new image has been mounted + output reg [31:0] img_size, // size of image in bytes + + // SD block level access + input [31:0] sd_lba, + input [1:0] sd_rd, + input [1:0] sd_wr, + output reg sd_ack, + output reg sd_ack_conf, + + // SD byte level access. Signals for 2-PORT altsyncram. + output reg [8:0] sd_buff_addr, + output reg [7:0] sd_buff_dout, + input [7:0] sd_buff_din, + output reg sd_buff_wr, + + // ps2 keyboard emulation + output ps2_kbd_clk, + output reg ps2_kbd_data, + output ps2_mouse_clk, + output reg ps2_mouse_data, + + // ps2 alternative interface. + + // [8] - extended, [9] - pressed, [10] - toggles with every press/release + output reg [10:0] ps2_key = 0, + + // [24] - toggles with every event + output reg [24:0] ps2_mouse = 0, + + // ARM -> FPGA download + input ioctl_ce, + output reg ioctl_download = 0, // signal indicating an active download + output reg [7:0] ioctl_index, // menu index used to upload the file + output reg ioctl_wr = 0, + output reg [24:0] ioctl_addr, + output reg [7:0] ioctl_dout +); + +reg [7:0] but_sw; +reg [2:0] stick_idx; + +reg [1:0] mount_strobe = 0; +assign img_mounted = mount_strobe; + +assign buttons = but_sw[1:0]; +assign switches = but_sw[3:2]; +assign scandoublerD = but_sw[4]; +assign ypbpr = but_sw[5]; + +// this variant of user_io is for 8 bit cores (type == a4) only +wire [7:0] core_type = 8'ha4; + +// command byte read by the io controller +wire drive_sel = sd_rd[1] | sd_wr[1]; +wire [7:0] sd_cmd = { 4'h6, sd_conf, sd_sdhc, sd_wr[drive_sel], sd_rd[drive_sel] }; + +reg [7:0] cmd; +reg [2:0] bit_cnt; // counts bits 0-7 0-7 ... +reg [9:0] byte_cnt; // counts bytes + +reg spi_do; +assign SPI_DO = CONF_DATA0 ? 1'bZ : spi_do; + +reg [7:0] spi_data_out; + +// SPI transmitter +always@(negedge SPI_SCK) spi_do <= spi_data_out[~bit_cnt]; + +reg [7:0] spi_data_in; +reg spi_data_ready = 0; + +// SPI receiver +always@(posedge SPI_SCK or posedge CONF_DATA0) begin + reg [6:0] sbuf; + reg [31:0] sd_lba_r; + reg drive_sel_r; + + if(CONF_DATA0) begin + bit_cnt <= 0; + byte_cnt <= 0; + spi_data_out <= core_type; + end + else + begin + bit_cnt <= bit_cnt + 1'd1; + sbuf <= {sbuf[5:0], SPI_DI}; + + // finished reading command byte + if(bit_cnt == 7) begin + if(!byte_cnt) cmd <= {sbuf, SPI_DI}; + + spi_data_in <= {sbuf, SPI_DI}; + spi_data_ready <= ~spi_data_ready; + if(~&byte_cnt) byte_cnt <= byte_cnt + 8'd1; + + spi_data_out <= 0; + case({(!byte_cnt) ? {sbuf, SPI_DI} : cmd}) + // reading config string + 8'h14: if(byte_cnt < STRLEN) spi_data_out <= conf_str[(STRLEN - byte_cnt - 1)<<3 +:8]; + + // reading sd card status + 8'h16: if(byte_cnt == 0) begin + spi_data_out <= sd_cmd; + sd_lba_r <= sd_lba; + drive_sel_r <= drive_sel; + end else if (byte_cnt == 1) begin + spi_data_out <= drive_sel_r; + end else if(byte_cnt < 6) spi_data_out <= sd_lba_r[(5-byte_cnt)<<3 +:8]; + + // reading sd card write data + 8'h18: spi_data_out <= sd_buff_din; + endcase + end + end +end + +reg [31:0] ps2_key_raw = 0; +wire pressed = (ps2_key_raw[15:8] != 8'hf0); +wire extended = (~pressed ? (ps2_key_raw[23:16] == 8'he0) : (ps2_key_raw[15:8] == 8'he0)); + +// transfer to clk_sys domain +always@(posedge clk_sys) begin + reg old_ss1, old_ss2; + reg old_ready1, old_ready2; + reg [2:0] b_wr; + reg got_ps2 = 0; + + old_ss1 <= CONF_DATA0; + old_ss2 <= old_ss1; + old_ready1 <= spi_data_ready; + old_ready2 <= old_ready1; + + sd_buff_wr <= b_wr[0]; + if(b_wr[2] && (~&sd_buff_addr)) sd_buff_addr <= sd_buff_addr + 1'b1; + b_wr <= (b_wr<<1); + + if(old_ss2) begin + got_ps2 <= 0; + sd_ack <= 0; + sd_ack_conf <= 0; + sd_buff_addr <= 0; + if(got_ps2) begin + if(cmd == 4) ps2_mouse[24] <= ~ps2_mouse[24]; + if(cmd == 5) begin + ps2_key <= {~ps2_key[10], pressed, extended, ps2_key_raw[7:0]}; + if(ps2_key_raw == 'hE012E07C) ps2_key[9:0] <= 'h37C; // prnscr pressed + if(ps2_key_raw == 'h7CE0F012) ps2_key[9:0] <= 'h17C; // prnscr released + if(ps2_key_raw == 'hF014F077) ps2_key[9:0] <= 'h377; // pause pressed + end + end + end + else + if(old_ready2 ^ old_ready1) begin + + if(cmd == 8'h18 && ~&sd_buff_addr) sd_buff_addr <= sd_buff_addr + 1'b1; + + if(byte_cnt < 2) begin + + if (cmd == 8'h19) sd_ack_conf <= 1; + if((cmd == 8'h17) || (cmd == 8'h18)) sd_ack <= 1; + mount_strobe <= 0; + + if(cmd == 5) ps2_key_raw <= 0; + end else begin + + case(cmd) + // buttons and switches + 8'h01: but_sw <= spi_data_in; + 8'h02: joystick_0 <= spi_data_in; + 8'h03: joystick_1 <= spi_data_in; +// 8'h60: if (byte_cnt < 5) joystick_0[(byte_cnt-1)<<3 +:8] <= spi_data_in; +// 8'h61: if (byte_cnt < 5) joystick_1[(byte_cnt-1)<<3 +:8] <= spi_data_in; +// 8'h62: if (byte_cnt < 5) joystick_2[(byte_cnt-1)<<3 +:8] <= spi_data_in; +// 8'h63: if (byte_cnt < 5) joystick_3[(byte_cnt-1)<<3 +:8] <= spi_data_in; +// 8'h64: if (byte_cnt < 5) joystick_4[(byte_cnt-1)<<3 +:8] <= spi_data_in; + // store incoming ps2 mouse bytes + 8'h04: begin + got_ps2 <= 1; + case(byte_cnt) + 2: ps2_mouse[7:0] <= spi_data_in; + 3: ps2_mouse[15:8] <= spi_data_in; + 4: ps2_mouse[23:16] <= spi_data_in; + endcase + ps2_mouse_fifo[ps2_mouse_wptr] <= spi_data_in; + ps2_mouse_wptr <= ps2_mouse_wptr + 1'd1; + end + + // store incoming ps2 keyboard bytes + 8'h05: begin + got_ps2 <= 1; + ps2_key_raw[31:0] <= {ps2_key_raw[23:0], spi_data_in}; + ps2_kbd_fifo[ps2_kbd_wptr] <= spi_data_in; + ps2_kbd_wptr <= ps2_kbd_wptr + 1'd1; + end + + 8'h15: status[7:0] <= spi_data_in; + + // send SD config IO -> FPGA + // flag that download begins + // sd card knows data is config if sd_dout_strobe is asserted + // with sd_ack still being inactive (low) + 8'h19, + // send sector IO -> FPGA + // flag that download begins + 8'h17: begin + sd_buff_dout <= spi_data_in; + b_wr <= 1; + end + + // joystick analog + 8'h1a: begin + // first byte is joystick index + if(byte_cnt == 2) stick_idx <= spi_data_in[2:0]; + else if(byte_cnt == 3) begin + // second byte is x axis + if(stick_idx == 0) joystick_analog_0[15:8] <= spi_data_in; + else if(stick_idx == 1) joystick_analog_1[15:8] <= spi_data_in; + end else if(byte_cnt == 4) begin + // third byte is y axis + if(stick_idx == 0) joystick_analog_0[7:0] <= spi_data_in; + else if(stick_idx == 1) joystick_analog_1[7:0] <= spi_data_in; + end + end + + // notify image selection + 8'h1c: mount_strobe[spi_data_in[0]] <= 1; + + // send image info + 8'h1d: if(byte_cnt<6) img_size[(byte_cnt-2)<<3 +:8] <= spi_data_in; + + // status, 32bit version + 8'h1e: if(byte_cnt<6) status[(byte_cnt-2)<<3 +:8] <= spi_data_in; + default: ; + endcase + end + end +end + + +/////////////////////////////// PS2 /////////////////////////////// +// 8 byte fifos to store ps2 bytes +localparam PS2_FIFO_BITS = 3; + +reg clk_ps2; +always @(negedge clk_sys) begin + integer cnt; + cnt <= cnt + 1'd1; + if(cnt == PS2DIV) begin + clk_ps2 <= ~clk_ps2; + cnt <= 0; + end +end + +// keyboard +reg [7:0] ps2_kbd_fifo[1<= 1)&&(ps2_kbd_tx_state < 9)) begin + ps2_kbd_data <= ps2_kbd_tx_byte[0]; // data bits + ps2_kbd_tx_byte[6:0] <= ps2_kbd_tx_byte[7:1]; // shift down + if(ps2_kbd_tx_byte[0]) + ps2_kbd_parity <= !ps2_kbd_parity; + end + + // transmission of parity + if(ps2_kbd_tx_state == 9) ps2_kbd_data <= ps2_kbd_parity; + + // transmission of stop bit + if(ps2_kbd_tx_state == 10) ps2_kbd_data <= 1; // stop bit is 1 + + // advance state machine + if(ps2_kbd_tx_state < 11) ps2_kbd_tx_state <= ps2_kbd_tx_state + 1'd1; + else ps2_kbd_tx_state <= 0; + end + end +end + +// mouse +reg [7:0] ps2_mouse_fifo[1<= 1)&&(ps2_mouse_tx_state < 9)) begin + ps2_mouse_data <= ps2_mouse_tx_byte[0]; // data bits + ps2_mouse_tx_byte[6:0] <= ps2_mouse_tx_byte[7:1]; // shift down + if(ps2_mouse_tx_byte[0]) + ps2_mouse_parity <= !ps2_mouse_parity; + end + + // transmission of parity + if(ps2_mouse_tx_state == 9) ps2_mouse_data <= ps2_mouse_parity; + + // transmission of stop bit + if(ps2_mouse_tx_state == 10) ps2_mouse_data <= 1; // stop bit is 1 + + // advance state machine + if(ps2_mouse_tx_state < 11) ps2_mouse_tx_state <= ps2_mouse_tx_state + 1'd1; + else ps2_mouse_tx_state <= 0; + end + end +end + + +/////////////////////////////// DOWNLOADING /////////////////////////////// + +reg [7:0] data_w; +reg [24:0] addr_w; +reg rclk = 0; + +localparam UIO_FILE_TX = 8'h53; +localparam UIO_FILE_TX_DAT = 8'h54; +localparam UIO_FILE_INDEX = 8'h55; + +reg rdownload = 0; + +// data_io has its own SPI interface to the io controller +always@(posedge SPI_SCK, posedge SPI_SS2) begin + reg [6:0] sbuf; + reg [7:0] cmd; + reg [4:0] cnt; + reg [24:0] addr; + + if(SPI_SS2) cnt <= 0; + else begin + // don't shift in last bit. It is evaluated directly + // when writing to ram + if(cnt != 15) sbuf <= { sbuf[5:0], SPI_DI}; + + // count 0-7 8-15 8-15 ... + if(cnt < 15) cnt <= cnt + 1'd1; + else cnt <= 8; + + // finished command byte + if(cnt == 7) cmd <= {sbuf, SPI_DI}; + + // prepare/end transmission + if((cmd == UIO_FILE_TX) && (cnt == 15)) begin + // prepare + if(SPI_DI) begin + case(ioctl_index[4:0]) + 1: addr <= 25'h200000; // TRD buffer at 2MB + 2: addr <= 25'h400000; // tape buffer at 4MB + default: addr <= 25'h150000; // boot rom + endcase + rdownload <= 1; + end else begin + addr_w <= addr; + rdownload <= 0; + end + end + + // command 0x54: UIO_FILE_TX + if((cmd == UIO_FILE_TX_DAT) && (cnt == 15)) begin + addr_w <= addr; + data_w <= {sbuf, SPI_DI}; + addr <= addr + 1'd1; + rclk <= ~rclk; + end + + // expose file (menu) index + if((cmd == UIO_FILE_INDEX) && (cnt == 15)) ioctl_index <= {sbuf, SPI_DI}; + end +end + +// transfer to ioctl_clk domain. +// ioctl_index is set before ioctl_download, so it's stable already +always@(posedge clk_sys) begin + reg rclkD, rclkD2; + + if(ioctl_ce) begin + ioctl_download <= rdownload; + + rclkD <= rclk; + rclkD2 <= rclkD; + ioctl_wr <= 0; + + if(rclkD != rclkD2) begin + ioctl_dout <= data_w; + ioctl_addr <= addr_w; + ioctl_wr <= 1; + end + end +end + +endmodule \ No newline at end of file diff --git a/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/osd.v b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/osd.v new file mode 100644 index 00000000..b9181763 --- /dev/null +++ b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/osd.v @@ -0,0 +1,194 @@ +// A simple OSD implementation. Can be hooked up between a cores +// VGA output and the physical VGA pins + +module osd ( + // OSDs pixel clock, should be synchronous to cores pixel clock to + // avoid jitter. + input clk_sys, + + // SPI interface + input SPI_SCK, + input SPI_SS3, + input SPI_DI, + + input [1:0] rotate, //[0] - rotate [1] - left or right + + // VGA signals coming from core + input [5:0] R_in, + input [5:0] G_in, + input [5:0] B_in, + input HSync, + input VSync, + + // VGA signals going to video connector + output [5:0] R_out, + output [5:0] G_out, + output [5:0] B_out +); + +parameter OSD_X_OFFSET = 10'd0; +parameter OSD_Y_OFFSET = 10'd0; +parameter OSD_COLOR = 3'd0; + +localparam OSD_WIDTH = 10'd256; +localparam OSD_HEIGHT = 10'd128; + +// ********************************************************************************* +// spi client +// ********************************************************************************* + +// this core supports only the display related OSD commands +// of the minimig +reg osd_enable; +(* ramstyle = "no_rw_check" *) reg [7:0] osd_buffer[2047:0]; // the OSD buffer itself + +// the OSD has its own SPI interface to the io controller +always@(posedge SPI_SCK, posedge SPI_SS3) begin + reg [4:0] cnt; + reg [10:0] bcnt; + reg [7:0] sbuf; + reg [7:0] cmd; + + if(SPI_SS3) begin + cnt <= 0; + bcnt <= 0; + end else begin + sbuf <= {sbuf[6:0], SPI_DI}; + + // 0:7 is command, rest payload + if(cnt < 15) cnt <= cnt + 1'd1; + else cnt <= 8; + + if(cnt == 7) begin + cmd <= {sbuf[6:0], SPI_DI}; + + // lower three command bits are line address + bcnt <= {sbuf[1:0], SPI_DI, 8'h00}; + + // command 0x40: OSDCMDENABLE, OSDCMDDISABLE + if(sbuf[6:3] == 4'b0100) osd_enable <= SPI_DI; + end + + // command 0x20: OSDCMDWRITE + if((cmd[7:3] == 5'b00100) && (cnt == 15)) begin + osd_buffer[bcnt] <= {sbuf[6:0], SPI_DI}; + bcnt <= bcnt + 1'd1; + end + end +end + +// ********************************************************************************* +// video timing and sync polarity anaylsis +// ********************************************************************************* + +// horizontal counter +reg [9:0] h_cnt; +reg [9:0] hs_low, hs_high; +wire hs_pol = hs_high < hs_low; +wire [9:0] dsp_width = hs_pol ? hs_low : hs_high; + +// vertical counter +reg [9:0] v_cnt; +reg [9:0] vs_low, vs_high; +wire vs_pol = vs_high < vs_low; +wire [9:0] dsp_height = vs_pol ? vs_low : vs_high; + +wire doublescan = (dsp_height>350); + +reg ce_pix; +always @(negedge clk_sys) begin + integer cnt = 0; + integer pixsz, pixcnt; + reg hs; + + cnt <= cnt + 1; + hs <= HSync; + + pixcnt <= pixcnt + 1; + if(pixcnt == pixsz) pixcnt <= 0; + ce_pix <= !pixcnt; + + if(hs && ~HSync) begin + cnt <= 0; + pixsz <= (cnt >> 9) - 1; + pixcnt <= 0; + ce_pix <= 1; + end +end + +always @(posedge clk_sys) begin + reg hsD, hsD2; + reg vsD, vsD2; + + if(ce_pix) begin + // bring hsync into local clock domain + hsD <= HSync; + hsD2 <= hsD; + + // falling edge of HSync + if(!hsD && hsD2) begin + h_cnt <= 0; + hs_high <= h_cnt; + end + + // rising edge of HSync + else if(hsD && !hsD2) begin + h_cnt <= 0; + hs_low <= h_cnt; + v_cnt <= v_cnt + 1'd1; + end else begin + h_cnt <= h_cnt + 1'd1; + end + + vsD <= VSync; + vsD2 <= vsD; + + // falling edge of VSync + if(!vsD && vsD2) begin + v_cnt <= 0; + vs_high <= v_cnt; + end + + // rising edge of VSync + else if(vsD && !vsD2) begin + v_cnt <= 0; + vs_low <= v_cnt; + end + end +end + +// area in which OSD is being displayed +wire [9:0] h_osd_start = ((dsp_width - OSD_WIDTH)>> 1) + OSD_X_OFFSET; +wire [9:0] h_osd_end = h_osd_start + OSD_WIDTH; +wire [9:0] v_osd_start = ((dsp_height- (OSD_HEIGHT<> 1) + OSD_Y_OFFSET; +wire [9:0] v_osd_end = v_osd_start + (OSD_HEIGHT<= h_osd_start) && (h_cnt < h_osd_end) && + (VSync != vs_pol) && (v_cnt >= v_osd_start) && (v_cnt < v_osd_end); + +reg [10:0] osd_buffer_addr; +wire [7:0] osd_byte = osd_buffer[osd_buffer_addr]; +reg osd_pixel; + +always @(posedge clk_sys) begin + if(ce_pix) begin + osd_buffer_addr <= rotate[0] ? {rotate[1] ? osd_hcnt_next2[7:5] : ~osd_hcnt_next2[7:5], + rotate[1] ? (doublescan ? ~osd_vcnt[7:0] : ~{osd_vcnt[6:0], 1'b0}) : + (doublescan ? osd_vcnt[7:0] : {osd_vcnt[6:0], 1'b0})} : + {doublescan ? osd_vcnt[7:5] : osd_vcnt[6:4], osd_hcnt_next2[7:0]}; + + osd_pixel <= rotate[0] ? osd_byte[rotate[1] ? osd_hcnt_next[4:2] : ~osd_hcnt_next[4:2]] : + osd_byte[doublescan ? osd_vcnt[4:2] : osd_vcnt[3:1]]; + end +end + +assign R_out = !osd_de ? R_in : {osd_pixel, osd_pixel, OSD_COLOR[2], R_in[5:3]}; +assign G_out = !osd_de ? G_in : {osd_pixel, osd_pixel, OSD_COLOR[1], G_in[5:3]}; +assign B_out = !osd_de ? B_in : {osd_pixel, osd_pixel, OSD_COLOR[0], B_in[5:3]}; + +endmodule diff --git a/Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/phoenix.vhd b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/phoenix.vhd similarity index 100% rename from Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/phoenix.vhd rename to Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/phoenix.vhd diff --git a/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/phoenix_effect1.vhd b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/phoenix_effect1.vhd new file mode 100644 index 00000000..43c9433b --- /dev/null +++ b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/phoenix_effect1.vhd @@ -0,0 +1,230 @@ +--------------------------------------------------------------------------------- +-- Phoenix sound effect1 by Dar (darfpga@aol.fr) (April 2016) +-- http://darfpga.blogspot.fr +--------------------------------------------------------------------------------- + +-- this module generates sound how the birds fly +-- how they burn and the ship's barrier activation sound +-- it is most often heard module througut all levels of the game + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.ALL; +use ieee.numeric_std.all; +use ieee.math_real.all; + +entity phoenix_effect1 is +generic( + -- Command + Cmd_Fs: real := 11.0; -- MHz + Cmd_V: real := 12.0; -- V + Cmd_Vd: real := 0.46; -- V + Cmd_Vce: real := 0.2; -- V + Cmd_R1: real := 100.0; -- k + Cmd_R2: real := 33.0; -- k + Cmd_R3: real := 0.47; -- k + Cmd_C: real := 6.8; -- uF + Cmd_Div2n: integer := 8; -- bits divisor + Cmd_bits: integer := 16; -- bits counter + -- Oscillator + Osc_Fs: real := 11.0; -- MHz + Osc_Vb: real := 5.0; -- V + Osc_Vce: real := 0.2; -- V + Osc_R1: real := 47.0; -- k + Osc_R2: real := 47.0; -- k + Osc_C: real := 0.001; -- uF + Osc_Div2n: integer := 7; -- bits divisor + Osc_bits: integer := 6; -- bits counter + -- Filter + Filt_Fs: real := 11.0; -- MHz + Filt_V1: real := 5.0; -- V + Filt_V2: real := 0.0; -- V + Filt_R1: real := 100.0; -- k + Filt_R2: real := 10.0; -- k + Filt_C: real := 0.047; -- uF + Filt_Div2n: integer := 7; -- bits divisor + Filt_bits: integer := 8; -- bits counter + + Vmax: real := 5.0; -- V + Vmax_bits: integer := 16 -- number of bits to represent vmax +); +port( + clk : in std_logic; + reset : in std_logic; + trigger : in std_logic; + filter : in std_logic; + divider : in std_logic_vector(3 downto 0); + snd : out std_logic_vector(7 downto 0) +); +end phoenix_effect1; + +architecture struct of phoenix_effect1 is + +-- integer representation of voltage, full range +constant IVmax: integer := integer(2**Vmax_bits)-1; +-- command -- +constant Cmd_div: integer := integer(2**Cmd_Div2n); +-- command charge +constant Cmd_VFc: real := (Cmd_V*Cmd_R2 + Cmd_Vd*Cmd_R1)/(Cmd_R1 + Cmd_R2); -- V +constant Cmd_RCc: real := Cmd_R1*Cmd_R2/(Cmd_R1 + Cmd_R2)*Cmd_C/1000.0; -- s +constant Cmd_ikc: integer := integer(Cmd_Fs * 1.0E6 * Cmd_RCc / 2.0**Cmd_Div2n); +constant Cmd_iVFc: integer := integer(Cmd_VFc * real(IVmax)/Vmax); +-- command discharge +constant Cmd_VFd: real := (Cmd_V/Cmd_R1+Cmd_Vd/Cmd_R2+(Cmd_Vd+Cmd_Vce)/Cmd_R3)/(1.0/Cmd_R1+1.0/Cmd_R2+1.0/Cmd_R3); -- V +constant Cmd_RCd: real := 1.0/(1.0/Cmd_R1+1.0/Cmd_R2+1.0/Cmd_R3)*Cmd_C/1000.0; -- s +constant Cmd_ikd: integer := integer(Cmd_Fs * 1.0E6 * Cmd_RCd / 2.0**Cmd_Div2n); +constant Cmd_iVFd: integer := integer(Cmd_VFd * real(IVmax)/Vmax); + +-- oscillator +constant Osc_div: integer := integer(2**Osc_Div2n); +-- oscillator charge +constant Osc_VFc: real := Osc_Vb; -- V +constant Osc_RCc: real := (Osc_R1+Osc_R2)*Osc_C/1000.0; -- s +constant Osc_ikc: integer := integer(Osc_Fs * 1.0E6 * Osc_RCc / 2.0**Osc_Div2n); +constant Osc_iVFc: integer := integer(Osc_VFc * real(IVmax)/Vmax); +-- oscillator discharge +constant Osc_VFd: real := Osc_Vce; -- V +constant Osc_RCd: real := Osc_R2*Osc_C/1000.0; -- s +constant Osc_ikd: integer := integer(Osc_Fs * 1.0E6 * Osc_RCd / 2.0**Osc_Div2n); +constant Osc_iVFd: integer := integer(Osc_VFd * real(IVmax)/Vmax); + +-- filter +constant Filt_div: integer := integer(2**Filt_Div2n); +-- filter charge +constant Filt_VFc: real := Filt_V1; -- V +constant Filt_RCc: real := 1.0/(1.0/Filt_R1+1.0/Filt_R2)*Filt_C/1000.0; -- s +constant Filt_ikc: integer := integer(Filt_Fs * 1.0E6 * Filt_RCc / 2.0**Filt_Div2n); +constant Filt_iVFc: integer := integer(Filt_VFc * real(IVmax)/Vmax); +-- filter discharge +constant Filt_VFd: real := Filt_V2; -- V +constant Filt_RCd: real := Filt_RCc; -- s +constant Filt_ikd: integer := integer(Filt_Fs * 1.0E6 * Filt_RCd / 2.0**Filt_Div2n); +constant Filt_iVFd: integer := integer(Filt_VFd * real(IVmax)/Vmax); + +function imax(x,y: integer) return integer is begin + if x > y then + return x; + else + return y; + end if; +end imax; + +signal u_c1 : unsigned(15 downto 0) := (others => '0'); +signal u_c2 : unsigned(15 downto 0) := (others => '0'); +signal flip : std_logic := '0'; + +signal u_cf : unsigned(15 downto 0) := (others => '0'); +signal sound : std_logic := '0'; + +begin + +-- Commande +-- R1 = 100k, R2 = 33k, R3 = 0.47k C=6.8e-6 SR=10MHz +-- Charge : VF1 = 43559, k1 = 6591 (R1//R2) +-- Decharge : VF2 = 9300, k2 = 123 (R1//R2//R3) +-- Div = 2^8 + +process (clk) + variable cnt: integer range 0 to imax(Cmd_ikc,Cmd_ikd) := 0; +begin + if rising_edge(clk) then + if reset = '1' then + cnt := 0; + u_c1 <= (others => '0'); + else + cnt := cnt + 1; + if trigger = '1' then + if cnt = Cmd_ikc then + cnt := 0; + u_c1 <= u_c1 + (Cmd_iVFc - u_c1)/Cmd_div; + end if; + else + if cnt = Cmd_ikd then + cnt := 0; + u_c1 <= u_c1 - (u_c1 - Cmd_iVFd)/Cmd_div; + end if; + end if; + end if; + end if; +end process; + +-- Oscillateur +-- R1 = 47k, R2 = 47k, C=0.001e-6 SR=50MHz +-- Charge : VF1 = 65535, k1 = 37 (R1+R2) +-- Decharge : VF2 = 2621, k2 = 18 (R2) +-- Div = 2^7 + +-- Diviseur +-- LS163 : Count up, Sync load when 0xF (no toggle sound if divider = 0xF) +-- LS74 : Divide by 2 + +process (clk) + variable cnt: integer range 0 to imax(Osc_ikc,Osc_ikd) := 0; + variable cnt2: unsigned(3 downto 0) := (others => '0'); +begin + if rising_edge(clk) then + if reset = '1' then + cnt := 0; + u_c2 <= (others => '0'); + flip <= '0'; + else + if u_c2 > u_c1 then flip <= '0'; end if; + if u_c2 < u_c1/2 then + flip <= '1'; + if flip = '0' then + cnt2 := cnt2 + 1; + if cnt2 = "0000" then + cnt2 := unsigned(divider); + if divider /= "1111" then sound <= not sound; end if; + end if; + end if; + end if; + cnt := cnt + 1; + if flip = '1' then + if cnt = Osc_ikc then + cnt := 0; + u_c2 <= u_c2 + (Osc_iVFc - u_c2)/Osc_div; + end if; + else + if cnt = Osc_ikd then + cnt := 0; + u_c2 <= u_c2 - (u_c2 - Osc_iVFd)/Osc_div; + end if; + end if; + end if; + end if; +end process; + +-- filter +-- R1 = 10k, R2 = 100k, C=0.047e-6, SR=10MHz +-- Charge : VF1= 65535, k1 = 33 (R1//R2) +-- Decharge : VF2= 0 , k2 = 33 (R1//R2) +-- Div = 2^7 + +process (clk) + variable cnt: integer range 0 to imax(Filt_ikc,Filt_ikd) := 0; +begin + if rising_edge(clk) then + if reset = '1' then + cnt := 0; + u_cf <= (others => '0'); + else + cnt := cnt + 1; + if sound = '1' then + if cnt = Filt_ikc then + cnt := 0; + u_cf <= u_cf + (Filt_iVFc - u_cf)/Filt_div; + end if; + else + if cnt = Filt_ikd then + cnt := 0; + u_cf <= u_cf - (u_cf - Filt_iVFd)/Filt_div; + end if; + end if; + end if; + end if; +end process; + +with filter select snd <= std_logic_vector(u_cf(15 downto 8)) when '1', sound&"0000000" when others; + +end struct; diff --git a/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/phoenix_effect2.vhd b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/phoenix_effect2.vhd new file mode 100644 index 00000000..097f4aa9 --- /dev/null +++ b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/phoenix_effect2.vhd @@ -0,0 +1,387 @@ +--------------------------------------------------------------------------------- +-- Phoenix sound effect2 by Dar (darfpga@aol.fr) (April 2016) +-- http://darfpga.blogspot.fr +--------------------------------------------------------------------------------- + +-- this module outputs sound of mothership's descend +-- it could be heard at beginning of level 5 +-- the prrrrr...vioooouuuuu sound +-- fixme: +-- the VCO control levels are too coarse (quantized) +-- frequency transitions are heard in large steps +-- instead of continous sweep + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.ALL; +use ieee.numeric_std.all; +use ieee.math_real.all; + +entity phoenix_effect2 is +generic( + -- Oscillator 1 + Osc1_Fs: real := 11.0; -- MHz + Osc1_Vb: real := 5.0; -- V + Osc1_Vce: real := 0.2; -- V + Osc1_R1: real := 47.0; -- k + Osc1_R2: real := 100.0; -- k + Osc1_C1: real := 0.01; -- uF + Osc1_C2: real := 0.47; -- uF + Osc1_C3: real := 1.0; -- uF + Osc1_Div2n: integer := 8; -- bits divisor + Osc1_bits: integer := 16; -- bits counter + -- Oscillator 2 + Osc2_Fs: real := 11.0; -- MHz + Osc2_Vb: real := 5.0; -- V + Osc2_Vce: real := 0.2; -- V + Osc2_R1: real := 510.0; -- k + Osc2_R2: real := 510.0; -- k + Osc2_C: real := 1.0; -- uF + Osc2_Div2n: integer := 8; -- bits divisor + Osc2_bits: integer := 17; -- bits counter + -- Filter 2 + Filt2_Fs: real := 11.0; -- MHz + Filt2_V: real := 5.0; -- V + Filt2_R1: real := 10.0; -- k + Filt2_R2: real := 5.1; -- k + Filt2_R3: real := 5.1; -- k + Filt2_R4: real := 5.0; -- k + Filt2_R5: real := 10.0; -- k + Filt2_C: real := 100.0; -- uF + Filt2_Div2n: integer := 8; -- bits divisor + Filt2_bits: integer := 16; -- bits counter + -- Oscillator 3 + Osc3_Fs: real := 11.0; -- MHz + Osc3_Vb: real := 5.0; -- V + Osc3_Vce: real := 0.2; -- V + Osc3_R1: real := 20.0; -- k + Osc3_R2: real := 20.0; -- k + Osc3_C: real := 0.001; -- uF + Osc3_Div2n: integer := 6; -- bits divisor + Osc3_bits: integer := 6; -- bits counter + + C_flip1_0: integer := 22020; + C_flip1_1: integer := 33063; + C_flip1_scale: integer := 84; -- ?? + + + Vmax: real := 5.0; -- V + Vmax_bits: integer := 16 -- number of bits to represent Vmax +); + +port( + clk : in std_logic; + reset : in std_logic; + trigger1 : in std_logic; + trigger2 : in std_logic; + divider : in std_logic_vector(3 downto 0); + snd : out std_logic_vector(1 downto 0) +); +end phoenix_effect2; + +architecture struct of phoenix_effect2 is + +function imax(x,y: integer) return integer is begin + if x > y then + return x; + else + return y; + end if; +end imax; + +-- integer representation of voltage, full range +constant IVmax: integer := integer(2**Vmax_bits)-1; +-- Oscillator1 -- +constant Osc1_div: integer := integer(2**Osc1_Div2n); +-- Oscillator1 charge/discharge voltages +constant Osc1_VFc: real := Osc1_Vb; -- V +constant Osc1_iVFc: integer := integer(Osc1_VFc * real(IVmax)/Vmax); +constant Osc1_VFd: real := Osc1_Vce; -- V +constant Osc1_iVFd: integer := integer(Osc1_VFd * real(IVmax)/Vmax); +-- Oscillator1 charge/discharge time constants +constant Osc1_T0_RCc: real := (Osc1_R1+Osc1_R2)*Osc1_C1/1000.0; -- s +constant Osc1_T0_ikc: integer := integer(Osc1_Fs * 1.0E6 * Osc1_T0_RCc / 2.0**Osc1_Div2n); +constant Osc1_T0_RCd: real := Osc1_R2*Osc1_C1/1000.0; -- s +constant Osc1_T0_ikd: integer := integer(Osc1_Fs * 1.0E6 * Osc1_T0_RCd / 2.0**Osc1_Div2n); + +constant Osc1_T1_RCc: real := (Osc1_R1+Osc1_R2)*(Osc1_C1+Osc1_C2)/1000.0; -- s +constant Osc1_T1_ikc: integer := integer(Osc1_Fs * 1.0E6 * Osc1_T1_RCc / 2.0**Osc1_Div2n); +constant Osc1_T1_RCd: real := Osc1_R2*(Osc1_C1+Osc1_C2)/1000.0; -- s +constant Osc1_T1_ikd: integer := integer(Osc1_Fs * 1.0E6 * Osc1_T1_RCd / 2.0**Osc1_Div2n); + +constant Osc1_T2_RCc: real := (Osc1_R1+Osc1_R2)*(Osc1_C1+Osc1_C3)/1000.0; -- s +constant Osc1_T2_ikc: integer := integer(Osc1_Fs * 1.0E6 * Osc1_T2_RCc / 2.0**Osc1_Div2n); +constant Osc1_T2_RCd: real := Osc1_R2*(Osc1_C1+Osc1_C3)/1000.0; -- s +constant Osc1_T2_ikd: integer := integer(Osc1_Fs * 1.0E6 * Osc1_T2_RCd / 2.0**Osc1_Div2n); + +constant Osc1_T3_RCc: real := (Osc1_R1+Osc1_R2)*(Osc1_C1+Osc1_C2+Osc1_C3)/1000.0; -- s +constant Osc1_T3_ikc: integer := integer(Osc1_Fs * 1.0E6 * Osc1_T3_RCc / 2.0**Osc1_Div2n); +constant Osc1_T3_RCd: real := Osc1_R2*(Osc1_C1+Osc1_C2+Osc1_C3)/1000.0; -- s +constant Osc1_T3_ikd: integer := integer(Osc1_Fs * 1.0E6 * Osc1_T3_RCd / 2.0**Osc1_Div2n); + +constant Osc1_ik_max: integer := imax( imax(Osc1_T1_ikc,Osc1_T1_ikd), imax(Osc1_T3_ikc,Osc1_T3_ikd)); + +-- Oscillator2 -- +constant Osc2_div: integer := integer(2**Osc2_Div2n); +-- Oscillator2 charge/discharge voltages +constant Osc2_VFc: real := Osc2_Vb; -- V +constant Osc2_iVFc: integer := integer(Osc2_VFc * real(IVmax)/Vmax); +constant Osc2_VFd: real := Osc2_Vce; -- V +constant Osc2_iVFd: integer := integer(Osc2_VFd * real(IVmax)/Vmax); +-- Oscillator2 charge/discharge time constants +constant Osc2_RCc: real := (Osc2_R1+Osc2_R2)*Osc2_C/1000.0; -- s +constant Osc2_ikc: integer := integer(Osc2_Fs * 1.0E6 * Osc2_RCc / 2.0**Osc2_Div2n); +constant Osc2_RCd: real := Osc2_R2*Osc2_C/1000.0; -- s +constant Osc2_ikd: integer := integer(Osc2_Fs * 1.0E6 * Osc2_RCd / 2.0**Osc2_Div2n); + +-- Filter2 -- +constant Filt2_div: integer := integer(2**Filt2_Div2n); +constant Filt2_R4p: real := 1.0/(1.0/Filt2_R1+1.0/Filt2_R4); -- k +constant Filt2_R5p: real := 1.0/(1.0/Filt2_R1+1.0/Filt2_R5); -- k +constant Filt2_Rp: real := 1.0/(1.0/Filt2_R3+1.0/Filt2_R4+1.0/Filt2_R5p); -- k +constant Filt2_Rs: real := 1.0/(1.0/Filt2_R2+1.0/Filt2_R3-Filt2_Rp/(Filt2_R3**2)); -- k +constant Filt2_RC: real := Filt2_Rs*Filt2_C/1000.0; -- s +constant Filt2_ik: integer := integer(Filt2_Fs*1.0E6*Filt2_RC / 2.0**Filt2_Div2n); +-- Filter2 voltages +constant Filt2_V0: real := Filt2_V*Filt2_Rp*Filt2_Rs/(Filt2_R3*Filt2_R4); -- V +constant Filt2_iV0: integer := integer(Filt2_V0 * real(IVmax)/Vmax); +constant Filt2_V1: real := Filt2_V*Filt2_Rp*Filt2_Rs/(Filt2_R4p*Filt2_R3); -- V +constant Filt2_iV1: integer := integer(Filt2_V1 * real(IVmax)/Vmax); +constant Filt2_V2: real := Filt2_V*Filt2_Rp*Filt2_Rs/(Filt2_R3*Filt2_R4)+Filt2_V*Filt2_Rs/Filt2_R2; -- V +constant Filt2_iV2: integer := integer(Filt2_V2 * real(IVmax)/Vmax); +constant Filt2_V3: real := Filt2_V*Filt2_Rp*Filt2_Rs/(Filt2_R3*Filt2_R4p)+Filt2_V*Filt2_Rs/Filt2_R2; -- V +constant Filt2_iV3: integer := integer(Filt2_V3 * real(IVmax)/Vmax); + +-- Oscillator3 -- +constant Osc3_div: integer := integer(2**Osc3_Div2n); +-- Oscillator3 charge/discharge voltages +constant Osc3_VFc: real := Osc3_Vb; -- V +constant Osc3_iVFc: integer := integer(Osc3_VFc * real(IVmax)/Vmax); +constant Osc3_VFd: real := Osc3_Vce; -- V +constant Osc3_iVFd: integer := integer(Osc3_VFd * real(IVmax)/Vmax); +-- Oscillator3 charge/discharge time constants +constant Osc3_RCc: real := (Osc3_R1+Osc3_R2)*Osc3_C/1000.0; -- s +constant Osc3_ikc: integer := integer(Osc3_Fs * 1.0E6 * Osc3_RCc / 2.0**Osc3_Div2n); +constant Osc3_RCd: real := Osc3_R2*Osc3_C/1000.0; -- s +constant Osc3_ikd: integer := integer(Osc3_Fs * 1.0E6 * Osc3_RCd / 2.0**Osc3_Div2n); + +signal u_c1 : unsigned(15 downto 0) := (others => '0'); +signal u_c2 : unsigned(15 downto 0) := (others => '0'); +signal u_c3 : unsigned(16 downto 0) := (others => '0'); +signal flip1 : std_logic := '0'; +signal flip2 : std_logic := '0'; +signal flip3 : std_logic := '0'; + +signal triggers : std_logic_vector(1 downto 0) := "00"; +--signal kc : unsigned(15 downto 0) := (others =>'0'); +--signal kd : unsigned(15 downto 0) := (others =>'0'); +signal kc : integer range 0 to Osc1_ik_max; +signal kd : integer range 0 to Osc1_ik_max; + +signal u_cf : unsigned(15 downto 0) := (others => '0'); +signal flips : std_logic_vector(1 downto 0) := "00"; +signal vf : unsigned(15 downto 0) := (others =>'0'); + +signal u_cf_scaled : unsigned(23 downto 0) := (others => '0'); +signal u_ctrl : unsigned(15 downto 0) := (others => '0'); + +signal sound: std_logic := '0'; + +begin + +-- Oscillateur1 +-- R1 = 47k, R2 = 100k, C1=0.01e-6, C2=0.047e-6, C3=1.000e-6 SR=10MHz +-- Div = 2^8 + +-- trigger = 00 +-- Charge : VF1 = 65535, k1 = 57 (R1+R2, C1) +-- Decharge : VF2 = 2621, k2 = 39 (R2, C1) +-- trigger = 01 +-- Charge : VF1 = 65535, k1 = 2756 (R1+R2, C1+C2) +-- Decharge : VF2 = 2621, k2 = 1875 (R2, C1+C2) +-- trigger = 10 +-- Charge : VF1 = 65535, k1 = 5800 (R1+R2, C1+C3) +-- Decharge : VF2 = 2621, k2 = 3945 (R2, C1+C3) +-- trigger = 11 +-- Charge : VF1 = 65535, k1 = 8498 (R1+R2, C1+C2+C3) +-- Decharge : VF2 = 2621, k2 = 5781 (R2, C1+C2+C3) + +triggers <= trigger2 & trigger1; + +with triggers select +kc <= Osc1_T0_ikc when "00", + Osc1_T1_ikc when "01", + Osc1_T2_ikc when "10", + Osc1_T3_ikc when others; + +with triggers select +kd <= Osc1_T0_ikd when "00", + Osc1_T1_ikd when "01", + Osc1_T2_ikd when "10", + Osc1_T3_ikd when others; + +process (clk) + variable cnt: integer range 0 to Osc1_ik_max := 0; +begin + if rising_edge(clk) then + if reset = '1' then + cnt := 0; + u_c1 <= (others => '0'); + else + if u_c1 > X"AAAA" then flip1 <= '0'; end if; + if u_c1 < X"5555" then flip1 <= '1'; end if; + cnt := cnt + 1; + if flip1 = '1' then + if cnt = kc then + cnt := 0; + u_c1 <= u_c1 + (Osc1_iVFc - u_c1)/Osc1_div; + end if; + else + if cnt = kd then + cnt := 0; + u_c1 <= u_c1 - (u_c1 - Osc1_iVFd)/Osc1_div; + end if; + end if; + end if; + end if; +end process; + +-- Oscillateur2 +-- R1 = 510k, R2 = 510k, C=1.000e-6, SR=10MHz +-- Charge : VF1 = 65535, k1 = 39844 (R1+R2, C) +-- Decharge : VF2 = 2621, k2 = 19922 (R2, C) +-- Div = 2^8 + +process (clk) + variable cnt: integer range 0 to imax(Osc2_ikc,Osc2_ikd) := 0; +begin + if rising_edge(clk) then + if reset = '1' then + cnt := 0; + u_c2 <= (others => '0'); + else + if u_c2 > X"AAAA" then flip2 <= '0'; end if; + if u_c2 < X"5555" then flip2 <= '1'; end if; + cnt := cnt + 1; + if flip2 = '1' then + if cnt = Osc2_ikc then + cnt := 0; + u_c2 <= u_c2 + (Osc2_iVFc - u_c2)/Osc2_div; + end if; + else + if cnt = Osc2_ikd then + cnt := 0; + u_c2 <= u_c2 - (u_c2 - Osc2_iVFd)/Osc2_div; + end if; + end if; + end if; + end if; +end process; + +-- Filtre +-- V1 = 5V +-- R1 = 10k, R2 = 5.1k, R3 = 5.1k, R4 = 5k, R5 = 10k, C=100.0e-6, SR=10MHz +-- Rp = R3//R4//R4//R1 = 1.68k +-- Rs = 1/(1/R2 + 1/R3 - Rp/(R3*R3)) = 3.05k +-- k = 11922 (Rs*C) +-- Div = 2^8 + +-- VF00 = 13159 (V*Rp*Rs)/(R4*R3) +-- VF01 = 19738 (V*Rp*Rs)/(R4p*R3) +-- VF10 = 52377 (V*Rp*Rs)/(R4*R3) + V*Rs/R2 +-- VF11 = 58957 (V*Rp*Rs)/(R4p*R3) + V*Rs/R2 + +flips <= flip2 & flip1; + +with flips select + +vf <= to_unsigned(Filt2_iV0,16) when "00", + to_unsigned(Filt2_iV1,16) when "01", + to_unsigned(Filt2_iV2,16) when "10", + to_unsigned(Filt2_iV3,16) when others; + +process (clk) + variable cnt: integer range 0 to Filt2_ik := 0; +begin + if rising_edge(clk) then + if reset = '1' then + cnt := 0; + u_cf <= (others => '0'); + else + cnt := cnt + 1; + if vf > u_cf then + if cnt = Filt2_ik then + cnt := 0; + u_cf <= u_cf + (vf - u_cf)/Filt2_div; + end if; + else + if cnt = Filt2_ik then + cnt := 0; + u_cf <= u_cf - (u_cf - vf)/Filt2_div; + end if; + end if; + end if; + end if; +end process; + +-- U_CTRL + +-- flip1 = 0 u_ctrl = 5V*Rp/R4 + u_cf*Rp/R3 # 22020 + u_cf*84/256 +-- flip1 = 1 u_ctrl = 5V*Rp/R4p + u_cf*Rp/R3 # 33063 + u_cf*84/256 + +u_cf_scaled <= u_cf*to_unsigned(C_flip1_scale,8); + +with flip1 select + u_ctrl <= to_unsigned(C_flip1_0,16)+u_cf_scaled(23 downto 8) when '0', + to_unsigned(C_flip1_1,16)+u_cf_scaled(23 downto 8) when others; + +-- Oscillateur3 +-- R1 = 20k, R2 = 20k, C=0.001e-6 SR=50MHz +-- Charge : VF1 = 65535, k1 = 31 (R1+R2) +-- Decharge : VF2 = 2621, k2 = 16 (R2) +-- Div = 2^6 + +-- Diviseur +-- LS163 : Count up, Sync load when 0xF (no toggle sound if divider = 0xF) +-- LS74 : Divide by 2 + +process (clk) + variable cnt: integer range 0 to imax(Osc3_ikc,Osc3_ikd) := 0; + variable cnt2: unsigned(3 downto 0) := (others => '0'); +begin + if rising_edge(clk) then + if reset = '1' then + cnt := 0; + u_c3 <= (others => '0'); + flip3 <= '0'; + else + if u_c3 > u_ctrl then flip3 <= '0'; end if; + if u_c3 < u_ctrl/2 then + flip3 <= '1'; + if flip3 = '0' then + cnt2 := cnt2 + 1; + if cnt2 = "0000" then + cnt2 := unsigned(divider); + if divider /= "1111" then sound <= not sound; end if; + end if; + end if; + end if; + cnt := cnt + 1; + if flip3 = '1' then + if cnt = Osc3_ikc then + cnt := 0; + u_c3 <= u_c3 + (Osc3_iVFc - u_c3)/Osc3_div; + end if; + else + if cnt = Osc3_ikd then + cnt := 0; + u_c3 <= u_c3 - (u_c3 - Osc3_iVFd)/Osc3_div; + end if; + end if; + end if; + end if; +end process; + +with trigger2 select snd <= '0'&sound when '1', sound&'0' when others; + +end struct; diff --git a/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/phoenix_effect3.vhd b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/phoenix_effect3.vhd new file mode 100644 index 00000000..c5bc2e77 --- /dev/null +++ b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/phoenix_effect3.vhd @@ -0,0 +1,290 @@ +--------------------------------------------------------------------------------- +-- Phoenix sound effect3 (noise) by Dar (darfpga@aol.fr) (April 2016) +-- http://darfpga.blogspot.fr +--------------------------------------------------------------------------------- + +-- this module generates noisy sound of ship missile shooting +-- ship explosions and enemy mothership explosion +-- it is often head throught all the levels of the game + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.ALL; +use ieee.numeric_std.all; + +entity phoenix_effect3 is +generic( + -- Command 1 + Cmd1_Fs: real := 11.0; -- MHz + Cmd1_V: real := 5.0; -- V + Cmd1_Vd: real := 0.46; -- V + Cmd1_Vce: real := 0.2; -- V + Cmd1_R1: real := 1.0; -- k + Cmd1_R2: real := 0.33; -- k + Cmd1_R3: real := 20.0; -- k + Cmd1_C: real := 6.8; -- uF + Cmd1_Div2n: integer := 8; -- bits divisor + --Cmd1_bits: integer := 16; -- bits counter + -- Command 2 + Cmd2_Fs: real := 11.0; -- MHz + Cmd2_V: real := 5.0; -- V + Cmd2_Vd: real := 0.46; -- V + Cmd2_Vce: real := 0.2; -- V + Cmd2_R1: real := 1.0; -- k + Cmd2_R2: real := 0.33; -- k + Cmd2_R3: real := 47.0; -- k + Cmd2_C: real := 6.8; -- uF + Cmd2_Div2n: integer := 8; -- bits divisor + --Cmd2_bits: integer := 16; -- bits counter + -- Oscillator + Osc_Fs: real := 11.0; -- MHz + Osc_Vb: real := 5.0; -- V + Osc_Vce: real := 0.2; -- V + Oscmin_R1a: real := 47.0; -- k + Oscmin_R2: real := 0.33; -- k + Oscmin_C: real := 0.05; -- uF + Oscmin_bits: integer := 16; -- bits counter + Oscmax_R1a: real := 2.553; -- k + Oscmax_R2: real := 1.0; -- k + Oscmax_C: real := 0.05; -- uF + Osc_Div2n: integer := 7; -- bits divisor + --Osc_bits: integer := 16; -- bits counter + + C_commande2_chop_k: integer := 62500; + + Vmax: real := 5.0; -- V + Vmax_bits: integer := 16 -- number of bits to represent Vmax +); +port( + clk : in std_logic; + reset : in std_logic; + trigger1 : in std_logic; + trigger2 : in std_logic; + snd : out std_logic_vector(7 downto 0) +); +end phoenix_effect3; + +architecture struct of phoenix_effect3 is + +-- integer representation of voltage, full range +constant IVmax: integer := integer(2**Vmax_bits)-1; +-- Command1 -- +constant Cmd1_div: integer := integer(2**Cmd1_Div2n); +-- Command1 charge/discharge voltages +constant Cmd1_VFc: real := Cmd1_V-Cmd1_Vd; -- V +constant Cmd1_iVFc: integer := integer(Cmd1_VFc * real(IVmax)/Vmax); +constant Cmd1_VFd: real := Cmd1_Vce+Cmd1_Vd; -- V +constant Cmd1_iVFd: integer := integer(Cmd1_VFd * real(IVmax)/Vmax); +-- Command1 charge/discharge time constants +constant Cmd1_RCc: real := (Cmd1_R1+Cmd1_R2+Cmd1_R3)*Cmd1_C/1000.0; -- s +constant Cmd1_ikc: integer := integer(Cmd1_Fs * 1.0E6 * Cmd1_RCc / 2.0**Cmd1_Div2n); +constant Cmd1_RCd: real := Cmd1_R2*Cmd1_C/1000.0; -- s +constant Cmd1_ikd: integer := integer(Cmd1_Fs * 1.0E6 * Cmd1_RCd / 2.0**Cmd1_Div2n); +-- Command2 -- +constant Cmd2_div: integer := integer(2**Cmd2_Div2n); +-- Command2 charge/discharge voltages +constant Cmd2_VFc: real := (Cmd2_V-Cmd2_Vd)*Cmd2_R3/(Cmd2_R1+Cmd2_R2+Cmd2_R3); -- V +constant Cmd2_iVFc: integer := integer(Cmd2_VFc * real(IVmax)/Vmax); +constant Cmd2_VFd: real := 0.0; -- V +constant Cmd2_iVFd: integer := integer(Cmd2_VFd * real(IVmax)/Vmax); +-- Command2 charge/discharge time constants +constant Cmd2_RCc: real := (Cmd2_R1+Cmd2_R2)*Cmd2_R3/(Cmd2_R1+Cmd2_R2+Cmd2_R3)*Cmd2_C/1000.0; -- s +constant Cmd2_ikc: integer := integer(Cmd2_Fs * 1.0E6 * Cmd2_RCc / 2.0**Cmd2_Div2n); +constant Cmd2_RCd: real := Cmd2_R3*Cmd2_C/1000.0; -- s +constant Cmd2_ikd: integer := integer(Cmd2_Fs * 1.0E6 * Cmd2_RCd / 2.0**Cmd2_Div2n); +-- Oscillator -- +constant Osc_div: integer := integer(2**Osc_Div2n); +-- Oscillator charge/discharge voltages +constant Osc_VFc: real := Osc_Vb; -- V +constant Osc_iVFc: integer := integer(Osc_VFc * real(IVmax)/Vmax); +constant Osc_VFd: real := Osc_Vce; -- V +constant Osc_iVFd: integer := integer(Osc_VFd * real(IVmax)/Vmax); +-- Oscillator min charge/discharge time constants +constant Oscmin_RCc: real := (Oscmin_R1a+Oscmin_R2)*Oscmin_C/1000.0; -- s +constant Oscmin_ikc: integer := integer(Osc_Fs * 1.0E6 * Oscmin_RCc / 2.0**Osc_Div2n); +constant Oscmin_RCd: real := Oscmin_R2*Oscmin_C/1000.0; -- s +constant Oscmin_ikd: integer := integer(Osc_Fs * 1.0E6 * Oscmin_RCd / 2.0**Osc_Div2n); +-- Oscillator max charge/discharge time constants +constant Oscmax_RCc: real := (Oscmax_R1a+Oscmax_R2)*Oscmax_C/1000.0; -- s +constant Oscmax_ikc: integer := integer(Osc_Fs * 1.0E6 * Oscmax_RCc / 2.0**Osc_Div2n); +constant Oscmax_RCd: real := Oscmax_R2*Oscmax_C/1000.0; -- s +constant Oscmax_ikd: integer := integer(Osc_Fs * 1.0E6 * Oscmax_RCd / 2.0**Osc_Div2n); + +function imax(x,y: integer) return integer is begin + if x > y then + return x; + else + return y; + end if; +end imax; + +signal u_c1 : unsigned(15 downto 0) := (others => '0'); +signal u_c2 : unsigned(15 downto 0) := (others => '0'); +signal u_c3 : unsigned(15 downto 0) := (others => '0'); +signal flip3 : std_logic := '0'; + +signal k_ch : unsigned(25 downto 0) := (others =>'0'); + +signal u_ctrl1 : unsigned(15 downto 0) := (others => '0'); +signal u_ctrl2 : unsigned(15 downto 0) := (others => '0'); +signal u_ctrl1_f : unsigned( 7 downto 0) := (others => '0'); +signal u_ctrl2_f : unsigned( 7 downto 0) := (others => '0'); +signal sound : unsigned( 7 downto 0) := (others => '0'); + +signal shift_reg : std_logic_vector(17 downto 0) := (others => '0'); + +begin + +-- Commande1 +-- R1 = 1k, R2 = 0.33k, R3 = 20k C=6.8e-6 SR=10MHz +-- Charge : VF1 = 59507, k1 = 5666 (R1+R2+R3) +-- Decharge : VF2 = 8651, k2 = 88 (R2) +-- Div = 2^8 + +process (clk) + -- variable cnt : unsigned(15 downto 0) := (others => '0'); + variable cnt: integer range 0 to imax(Cmd1_ikc,Cmd1_ikd)*2 := 0; +begin + if rising_edge(clk) then + if reset = '1' then + cnt := 0; + u_c1 <= (others => '0'); + else + cnt := cnt + 1; + if trigger1 = '1' then + -- if cnt > C_commande1_k1 then + if cnt > Cmd1_ikc then + cnt := 0; + -- u_c1 <= u_c1 + (C_commande1_VF1 - u_c1)/256; + u_c1 <= u_c1 + (Cmd1_iVFc - u_c1)/Cmd1_div; + end if; + else + -- if cnt > C_commande1_k2 then + if cnt > Cmd1_ikd then + cnt := 0; + -- u_c1 <= u_c1 - (u_c1 - C_commande1_VF2)/256; + u_c1 <= u_c1 - (u_c1 - Cmd1_iVFd)/Cmd1_div; + end if; + end if; + end if; + end if; +end process; + +-- Commande2 +-- R1 = 1k, R2 = 0.33k, R3 = 47k C=6.8e-6 SR=10MHz +-- Charge : VF1 = 57869, k1 = 344 (R1+R2)//R3 +-- Decharge : VF2 = 0, k2 = 12484 (R3) +-- Div = 2^8 + +process (clk) + -- variable cnt : unsigned(15 downto 0) := (others => '0'); + variable cnt: integer range 0 to imax(Cmd2_ikc,Cmd2_ikd)*2 := 0; +begin + if rising_edge(clk) then + if reset = '1' then + -- cnt := (others => '0'); + cnt := 0; + u_c2 <= (others => '0'); + else + cnt := cnt + 1; + if trigger2 = '1' then + -- if cnt > C_commande2_k1 then + if cnt > Cmd2_ikc then + -- cnt := (others => '0'); + cnt := 0; + -- u_c2 <= u_c2 + (C_commande2_VF1 - u_c2)/256; + u_c2 <= u_c2 + (Cmd2_iVFc - u_c2)/Cmd2_div; + end if; + else + -- if cnt > C_commande2_k2 then + if cnt > Cmd2_ikd then + -- cnt := (others => '0'); + cnt := 0; + -- u_c2 <= u_c2 - (u_c2 - C_commande2_VF2)/256; + u_c2 <= u_c2 - (u_c2 - Cmd2_iVFd)/Cmd2_div; + end if; + end if; + end if; + end if; +end process; + +-- control voltage from command1 is R3 voltage (not u_c1 voltage) +with trigger1 select +-- u_ctrl1 <= (to_unsigned(C_commande1_VF1,16) - u_c1) when '1', (others=>'0') when others; +u_ctrl1 <= (to_unsigned(Cmd1_iVFc,16) - u_c1) when '1', (others=>'0') when others; + +-- control voltage from command2 is u_c2 voltage +u_ctrl2 <= u_c2; + +-- sum up and scaled both control voltages to vary R1 resistor of oscillator +-- k_ch <= shift_right(((u_ctrl1/2 + u_ctrl2/2) * to_unsigned(C_oscillateur_min_k1-C_oscillateur_max_k1,10)),15) + C_oscillateur_max_k1; +k_ch <= shift_right(((u_ctrl1/2 + u_ctrl2/2) * to_unsigned(Oscmin_ikc-Oscmax_ikc,10)),15) + Oscmax_ikc; + +-- Oscillateur +-- R1 = 47k..2.533k, R2 = 1k, C=0.05e-6, SR=50MHz +-- Charge : VF1 = 65536, k_ch = 938..69 (R1+R2, C) +-- Decharge : VF2 = 2621, k2 = 20 (R2, C) +-- Div = 2^7 + +-- noise generator triggered by oscillator output + +process (clk) + variable cnt: integer range 0 to imax(imax(Oscmin_ikc,Oscmin_ikd), imax(Oscmax_ikc,Oscmax_ikd))+256 := 0; +begin + if rising_edge(clk) then + if reset = '1' then + cnt := 0; + u_c3 <= (others => '0'); + else + if u_c3 > X"AAAA" then flip3 <= '0'; end if; + if u_c3 < X"5555" then + flip3 <= '1'; + if flip3 = '0' then + shift_reg <= shift_reg(16 downto 0) & not(shift_reg(17) xor shift_reg(16)); + end if; + end if; + cnt := cnt + 1; + if flip3 = '1' then + if cnt > k_ch then + cnt := 0; + u_c3 <= u_c3 + (Osc_iVFc - u_c3)/Osc_div; + end if; + else + if cnt > Oscmax_ikd then + cnt := 0; + u_c3 <= u_c3 - (u_c3 - Osc_iVFd)/Osc_div; + end if; + end if; + end if; + end if; +end process; + +-- modulated (chop) command1 voltage with noise generator output +with shift_reg(17) xor shift_reg(16) select +u_ctrl1_f <= u_ctrl1(15 downto 8)/2 when '0', (others => '0') when others; + + +-- modulated (chop) command2 voltage with noise generator output +-- and add 400Hz filter (raw sub-sampling) +-- f=10 MHz, k = 25000 +process (clk) + variable cnt : unsigned(15 downto 0) := (others => '0'); +begin + if rising_edge(clk) then + cnt := cnt + 1; + if cnt > C_commande2_chop_k then + cnt := (others => '0'); + if (shift_reg(17) xor shift_reg(16)) = '0' then + u_ctrl2_f <= u_ctrl2(15 downto 8)/2; + else + u_ctrl2_f <= (others => '0'); + end if; + end if; + end if; +end process; + +-- mix modulated noises 1 and 2 +sound <= u_ctrl1_f + u_ctrl2_f; +snd <= std_logic_vector(sound); + +end struct; diff --git a/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/phoenix_mist.vhd b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/phoenix_mist.vhd new file mode 100644 index 00000000..f986972e --- /dev/null +++ b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/phoenix_mist.vhd @@ -0,0 +1,309 @@ +--------------------------------------------------------------------------------- +-- DE2-35 Top level for Phoenix by Dar (darfpga@aol.fr) (April 2016) +-- http://darfpga.blogspot.fr +-- +-- Main features +-- PS2 keyboard input +-- wm8731 sound output +-- NO board SRAM used +-- +-- sw 0: on/off hdmi-audio +-- +-- Board switch : ---- todo fixme switches note +-- 1 - 4 : dip switch +-- 0-1 : lives 3-6 +-- 3-2 : bonus life 30K-60K +-- 4 : coin 1-2 +-- 6-5 : unkonwn +-- 7 : upright-cocktail +-- 8 -10 : sound_select +-- 0XX : all mixed (normal) +-- 100 : sound1 only +-- 101 : sound2 only +-- 110 : sound3 only +-- 111 : melody only +-- Board key : +-- 0 : reset +-- +--------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.ALL; +use ieee.numeric_std.all; + +entity phoenix_mist is +port +( + CLOCK_27 : in std_logic; + LED : out std_logic; + VGA_R : out std_logic_vector(5 downto 0); + VGA_G : out std_logic_vector(5 downto 0); + VGA_B : out std_logic_vector(5 downto 0); + VGA_HS : out std_logic; + VGA_VS : out std_logic; + SPI_SCK : in std_logic; + SPI_DI : in std_logic; + SPI_DO : out std_logic; + SPI_SS2 : in std_logic; + SPI_SS3 : in std_logic; + CONF_DATA0 : in std_logic; + AUDIO_L : out std_logic; + AUDIO_R : out std_logic +); +end; + +architecture struct of phoenix_mist is + + signal clk : std_logic; + signal clk_88m : std_logic; + signal reset : std_logic; + signal clock_stable : std_logic; + + signal audio : std_logic_vector(11 downto 0); + signal video_r, video_g, video_b: std_logic_vector(1 downto 0); + signal vsync, hsync : std_logic; + + signal dip_switch : std_logic_vector(7 downto 0);-- := (others => '0'); + signal status : std_logic_vector(31 downto 0); + signal buttons : std_logic_vector(1 downto 0); + signal scandoubler_disable : std_logic; + signal ypbpr : std_logic; + signal ce_pix : std_logic; + + signal scanlines : std_logic_vector(1 downto 0); + signal hq2x : std_logic; + + signal coin : std_logic; + signal player_start : std_logic_vector(1 downto 0); + signal button_left, button_right, button_protect, button_fire: std_logic; + signal joy0 : std_logic_vector(7 downto 0); + signal joy1 : std_logic_vector(7 downto 0); + signal ps2Clk : std_logic; + signal ps2Data : std_logic; + signal kbd_joy : std_logic_vector(7 downto 0); + signal upjoyL : std_logic; + signal upjoyR : std_logic; + signal upjoyB : std_logic; +-- config string used by the io controller to fill the OSD + constant CONF_STR : string := "PHOENIX;;O4,Screen Direction,Upright,Normal;O67,Scandoubler Fx,None,HQ2x,CRT 25%,CRT 50%;T5,Reset;V,v1.1;"; + + function to_slv(s: string) return std_logic_vector is + constant ss: string(1 to s'length) := s; + variable rval: std_logic_vector(1 to 8 * s'length); + variable p: integer; + variable c: integer; + begin + for i in ss'range loop + p := 8 * i; + c := character'pos(ss(i)); + rval(p - 7 to p) := std_logic_vector(to_unsigned(c,8)); + end loop; + return rval; + end function; + + component mist_io + generic ( STRLEN : integer := 0 ); + port ( + clk_sys :in std_logic; + SPI_SCK, CONF_DATA0, SPI_DI :in std_logic; + SPI_DO : out std_logic; + conf_str : in std_logic_vector(8*STRLEN-1 downto 0); + buttons : out std_logic_vector(1 downto 0); + joystick_0 : out std_logic_vector(7 downto 0); + joystick_1 : out std_logic_vector(7 downto 0); + status : out std_logic_vector(31 downto 0); + scandoubler_disable, ypbpr : out std_logic; + ps2_kbd_clk : out std_logic; + ps2_kbd_data : out std_logic + ); + end component mist_io; + + component video_mixer + generic ( LINE_LENGTH : integer := 352; HALF_DEPTH : integer := 1 ); + port ( + clk_sys, ce_pix, ce_pix_actual : in std_logic; + SPI_SCK, SPI_SS3, SPI_DI : in std_logic; + scanlines : in std_logic_vector(1 downto 0); + scandoubler_disable, hq2x, ypbpr, ypbpr_full : in std_logic; + rotate : in std_logic_vector(1 downto 0); + R, G, B : in std_logic_vector(2 downto 0); + HSync, VSync, line_start, mono : in std_logic; + + VGA_R,VGA_G, VGA_B : out std_logic_vector(5 downto 0); + VGA_VS, VGA_HS : out std_logic + ); + end component video_mixer; + + component keyboard + PORT( + clk : in std_logic; + reset : in std_logic; + ps2_kbd_clk : in std_logic; + ps2_kbd_data : in std_logic; + joystick : out std_logic_vector (7 downto 0) + ); + end component; + + +begin + +-- SWITCH 1: SWITCH 2: NUMBER OF SPACESHIPS: +-- --------- --------- --------------------- +-- OFF OFF 6 +-- ON OFF 5 +-- OFF ON 4 +-- ON ON 3 +-- FIRST FREE SECOND FREE +-- SWITCH 3: SWITCH 4: SHIP SCORE: SHIP SCORE: +-- --------- --------- ----------- ----------- +-- OFF OFF 6,000 60,000 +-- ON OFF 5,000 50,000 +-- OFF ON 4,000 40,000 +-- ON ON 3,000 30,000 + + --Cocktail,Factory,Factory,Factory,Bonus2,Bonus1,Ships2,Ships1 + dip_switch <= "00001111"; + + mist_io_inst : mist_io + generic map (STRLEN => CONF_STR'length) + port map ( + clk_sys => clk, + SPI_SCK => SPI_SCK, + CONF_DATA0 => CONF_DATA0, + SPI_DI => SPI_DI, + SPI_DO => SPI_DO, + conf_str => to_slv(CONF_STR), + buttons => buttons, + scandoubler_disable => scandoubler_disable, + ypbpr => ypbpr, + joystick_1 => joy1, + joystick_0 => joy0, + status => status, + ps2_kbd_clk => ps2Clk, + ps2_kbd_data => ps2Data + ); + + -- + -- Audio + -- + u_dac1 : entity work.dac + port map( + clk_i => clk_88m, + res_n_i => not reset, + dac_i => audio, + dac_o => AUDIO_L + ); + + u_dac2 : entity work.dac + port map( + clk_i => clk_88m, + res_n_i => not reset, + dac_i => audio, + dac_o => AUDIO_R + ); + + + pll: entity work.pll27 + port map( + inclk0 => CLOCK_27, + c0 => clk_88m, + c1 => clk, + locked => clock_stable + ); + + reset <= status(0) or status(5) or buttons(1) or not clock_stable; + + u_keyboard : keyboard + port map( + clk => clk, + reset => reset, + ps2_kbd_clk => ps2Clk, + ps2_kbd_data => ps2Data, + joystick => kbd_joy + ); + + process(clk_88m) + variable cnt: integer range 0 to 6000000 := 0; + begin + if rising_edge(clk_88m) then + if status(3 downto 1) /= "000" then + cnt := 0; + coin <= status(1); + player_start <= status(3 downto 2); + else + if cnt < 6000000 then + cnt := cnt + 1; + else + coin <= '0'; + player_start <= "00"; + end if; + end if; + end if; + end process; + + upjoyB <= joy0(2) or joy1(2) when status(4) = '0' else joy0(0) or joy1(0); + upjoyL <= joy0(1) or joy1(1) or kbd_joy(6) when status(4) = '0' else joy0(2) or joy1(2) or kbd_joy(5); + upjoyR <= joy0(0) or joy1(0) or kbd_joy(7) when status(4) = '0' else joy0(3) or joy1(3) or kbd_joy(4); + + phoenix : entity work.phoenix + port map + ( + clk => clk, + reset => reset, + ce_pix => ce_pix, + dip_switch => dip_switch, + btn_coin => kbd_joy(3) or coin,--ESC + btn_player_start(0) => kbd_joy(1) or player_start(0),--1 + btn_player_start(1) => kbd_joy(2) or player_start(1),--2 + btn_left => upjoyL, + btn_right => upjoyR, + btn_barrier => upjoyB or kbd_joy(2),--TAB + btn_fire => joy0(4) or joy1(4) or kbd_joy(0),--space + video_r => video_r, + video_g => video_g, + video_b => video_b, + video_hs => hsync, + video_vs => vsync, + audio_select => "000", + audio => audio + ); + + scanlines(0) <= '1' when status(7 downto 6) = "10" else '0'; + scanlines(1) <= '1' when status(7 downto 6) = "11" else '0'; + hq2x <= '1' when status(7 downto 6) = "01" else '0'; + + vmixer : video_mixer + port map ( + clk_sys => clk_88m, + ce_pix => ce_pix, + ce_pix_actual => ce_pix, + + SPI_SCK => SPI_SCK, + SPI_SS3 => SPI_SS3, + SPI_DI => SPI_DI, + rotate => '1' & not status(4), + scanlines => scanlines, + scandoubler_disable => scandoubler_disable, + hq2x => hq2x, + ypbpr => ypbpr, + ypbpr_full => '1', + + R => video_r & video_r(1), + G => video_g & video_g(1), + B => video_b & video_b(1), + HSync => hsync, + VSync => vsync, + line_start => '0', + mono => '0', + + VGA_R => VGA_R, + VGA_G => VGA_G, + VGA_B => VGA_B, + VGA_VS => VGA_VS, + VGA_HS => VGA_HS + ); + + LED <= '1'; + +end struct; diff --git a/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/phoenix_music.vhd b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/phoenix_music.vhd new file mode 100644 index 00000000..56d6c594 --- /dev/null +++ b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/phoenix_music.vhd @@ -0,0 +1,241 @@ +--------------------------------------------------------------------------------- +-- Phoenix music by Dar (darfpga@aol.fr) (April 2016) +-- http://darfpga.blogspot.fr +--------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.ALL; +use ieee.numeric_std.all; +use ieee.math_real.all; + +entity phoenix_music is +generic( + C_clk_freq: real := 11.0 -- MHz +); +port( + clk : in std_logic; + reset : in std_logic; + trigger : in std_logic; + sel_song : in std_logic; + snd : out std_logic_vector(7 downto 0) +); +end phoenix_music; + +architecture struct of phoenix_music is + +constant C_voice_attack: integer := integer(230.0 * C_clk_freq); -- larger value is faster +constant C_song0_tempo: integer := integer(2200.0 * C_clk_freq); -- larger value is faster +constant C_song1_tempo: integer := integer(1700.0 * C_clk_freq); -- larger value is faster +constant C_voice_down_rate: integer := integer(4000.0 / C_clk_freq); -- larger value is slower + +type voice_array is array (0 to 94) of integer range 0 to 127; +-- main voice1 (Jeux Interdits) +constant voice1 : voice_array := ( +32,96,32,96,32,96,32,96,26,90,24,88,24,88,23,87,21,85,21,85,24,88,32,96,37,101,101,101,101,101,37,101,35,99,33,97,33,97,32,96,26,90,26,90,32,96,33,97,32,96,33,97,32,96,36,100,33,97,32,96,32,96,26,90,24,88,24,88,23,87,21,85,23,87,23,87,23,87,23,87,24,88,23,87,21,85,24,88,32,96,37,101,101,101,101); +-- accompagnement voice1 +constant voice2 : voice_array := ( +5,69,69,69,69,69,16,80,80,80,80,80,8,72,8,72,8,72,16,80,80,80,80,80,5,69,5,8,16,21,5,69,69,69,69,69,17,81,81,81,81,81,10,74,74,74,74,74,16,80,80,80,80,80,16,80,80,80,80,80,8,72,72,72,72,72,5,69,69,69,69,69,7,71,71,71,71,71,17,81,81,81,8,72,5,69,16,80,8,72,5,69,69,69,69); + +-- voice1, voice2 and voice3 value description +-- bit3-bit0 : tone from 0(La/A) to 11(Sol/G#) +-- bit5-bit4 : octave from 0(220Hz)to 2(880Hz) +-- bit6 : 0 = strike (restart) the tone, 1 = don't strike (hold) the tone + +type voice_array2 is array (0 to 45) of integer range 0 to 127; +-- main voice3 (La lettre a Elise) +constant voice3 : voice_array2 := ( +37,36,37,36,37,32,35,33,26,5,10,17,21,26,32,5,16,21,25,32,33,5,10,17,37,36,37,36,37,32,35,33,26,5,10,17,21,26,32,5,16,21,33,32,26,90); + +type period_array is array (0 to 11) of integer range 0 to 65535; +-- Octave 220Hz @ 10MHz +constant tone_period : period_array := ( + 45455, -- ton 0 La (A ) + 42903, -- ton 1 La# (A#) + 40495, -- ton 2 Si (B ) + 38223, -- ton 3 Do (C ) + 36077, -- ton 4 Do# (C#) + 34052, -- ton 5 Re (D ) + 32141, -- ton 6 Re# (D#) + 30337, -- ton 7 Mi (E ) + 28635, -- ton 8 Fa (F ) + 27027, -- ton 9 Fa# (F#) + 25511, -- ton 10 Sol (G ) + 24079 -- ton 11 Sol# (G#) +); + +signal tempo_period : integer range 0 to C_song0_tempo := C_song1_tempo; --0.19s @ 100kHz + +signal voice1_tone : integer range 0 to 65535 := 0; +signal voice1_tone_div : integer range 0 to 65535 := 0; +signal voice1_code : unsigned(6 downto 0) := "0000000"; +signal voice1_vol : unsigned(7 downto 0) := "00000000"; +signal voice1_snd : std_logic := '0'; + +signal voice2_tone : integer range 0 to 65535 := 0; +signal voice2_tone_div : integer range 0 to 65535 := 0; +signal voice2_code : unsigned(6 downto 0) := "0000000"; +signal voice2_vol : unsigned(7 downto 0) := "00000000"; +signal voice2_snd : std_logic := '0'; + +signal snd1 : unsigned(7 downto 0) := "00000000"; +signal snd2 : unsigned(7 downto 0) := "00000000"; + +signal trigger_r : std_logic := '0'; +signal max_step : integer range 0 to 94 := 94; +signal sel_song_r: std_logic := '1'; + +begin + +process (clk) + variable cnt : integer range 0 to 127 := 0; + variable step : integer range 0 to 94 := 94; + variable tempo : integer range 0 to C_song0_tempo := 0; + variable voice1_code_v : unsigned(6 downto 0) := "0000000"; + variable voice2_code_v : unsigned(6 downto 0) := "0000000"; + variable voice1_down_rate : integer range 0 to C_voice_down_rate := 0; + variable voice2_down_rate : integer range 0 to C_voice_down_rate := 0; +begin + if rising_edge(clk) then + trigger_r <= trigger; + + if reset = '1' then + cnt := 0; + step := 94; + voice1_vol <= X"00"; + voice2_vol <= X"00"; + elsif trigger ='1' and trigger_r ='0' and step = 94 then -- restart music on edge trigger if not already playing + cnt := 0; + step := 0; + voice1_vol <= X"00"; + voice2_vol <= X"00"; + sel_song_r <= sel_song; + if sel_song = '1' then + max_step <= 94; + tempo_period <= C_song1_tempo; + else + max_step <= 46; + tempo_period <= C_song0_tempo; + end if; + else + cnt := cnt +1; + if cnt >= 100 then + cnt := 0; + tempo := tempo +1; + if tempo >= tempo_period then -- next beat + tempo := 0; + if step < max_step then -- if not end of music get next note + if sel_song_r = '1' then + voice1_code_v := to_unsigned(voice1(step),7); + voice2_code_v := to_unsigned(voice2(step),7); + else + voice1_code_v := to_unsigned(voice3(step),7); + voice2_code_v := to_unsigned(voice3(step),7); + end if; + voice1_code <= voice1_code_v; + voice2_code <= voice2_code_v; + step := step + 1; + else -- if end cut-off volume + voice1_vol <= X"00"; + voice2_vol <= X"00"; + step := 94; + end if; + end if; + if (step < 94) then -- if not end of music + -- manage voice1 volume + -- ramp up fast to xF0 at begining of beat when new strike + if (tempo < C_voice_attack) and (voice1_code_v(6)='0') then + if voice1_vol < X"F0" then voice1_vol <= voice1_vol + X"01"; end if; + voice1_down_rate := 0; + -- ramp down slowly after a while, down to x80 + else + if voice1_vol > X"80" then + voice1_down_rate := voice1_down_rate+1; + if voice1_down_rate >= C_voice_down_rate then + voice1_down_rate := 0; + voice1_vol <= voice1_vol - X"01"; + end if; + end if; + end if; + -- manage voice2 volume + if (tempo < C_voice_attack) and (voice2_code_v(6)='0') then + if voice2_vol < X"F0" then voice2_vol <= voice2_vol + X"01"; end if; + voice2_down_rate := 0; + else + if voice2_vol > X"80" then + voice2_down_rate := voice2_down_rate+1; + if voice2_down_rate >= C_voice_down_rate then + voice2_down_rate := 0; + voice2_vol <= voice2_vol - X"01"; + end if; + end if; + end if; + end if; + end if; + end if; + end if; +end process; + +-- get voice1 raw tone +voice1_tone <= tone_period(to_integer(voice1_code(3 downto 0))); + +-- get voice1 tone w.r.t octave +with voice1_code(5 downto 4) select +voice1_tone_div <= voice1_tone when "00", + voice1_tone/2 when "01", + voice1_tone/4 when others; + +-- generate voice1 frequency +voice1_frequency: process (clk) + variable cnt : integer range 0 to 65535 := 0; +begin + if rising_edge(clk) then + if reset = '1' then + cnt := 0; + else + cnt := cnt+1; + if cnt >= voice1_tone_div then + cnt := 0; + voice1_snd <= not voice1_snd; + end if; + end if; + end if; +end process; + +-- get voice2 raw tone +voice2_tone <= tone_period(to_integer(voice2_code(3 downto 0))); + +-- get voice2 tone w.r.t octave +with voice2_code(5 downto 4) select +voice2_tone_div <= voice2_tone when "00", + voice2_tone/2 when "01", + voice2_tone/4 when others; + +-- generate voice2 frequency +voice2_frequency: process (clk) + variable cnt : integer range 0 to 65535 := 0; +begin + if rising_edge(clk) then + if reset = '1' then + cnt := 0; + else + cnt := cnt+1; + if cnt >= voice2_tone_div then + cnt := 0; + voice2_snd <= not voice2_snd; + end if; + end if; + end if; +end process; + +-- modulate voice1 volume with voice1 frequency +with voice1_snd select snd1 <= voice1_vol when '1', X"00" when others; + +-- modulate voice2 volume with voice2 frequency +with voice2_snd select snd2 <= voice2_vol when '1', X"00" when others; + +-- mix voice1 and voice 2 +snd <= std_logic_vector(('0'&snd1(7 downto 1)) + ('0'&snd2(7 downto 1))); + +end struct; + diff --git a/Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/phoenix_prog.vhd b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/phoenix_prog.vhd similarity index 100% rename from Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/phoenix_prog.vhd rename to Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/phoenix_prog.vhd diff --git a/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/phoenix_video.vhd b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/phoenix_video.vhd new file mode 100644 index 00000000..9f7ac60d --- /dev/null +++ b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/phoenix_video.vhd @@ -0,0 +1,160 @@ +--------------------------------------------------------------------------------- +-- Phoenix video generator by Dar (darfpga@aol.fr) +-- http://darfpga.blogspot.fr +--------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.ALL; +use ieee.numeric_std.all; + +entity phoenix_video is +port( + clk11 : in std_logic; + reset : in std_logic; + ce_pix : out std_logic; + hcnt : out std_logic_vector(9 downto 1); + vcnt : out std_logic_vector(8 downto 1); + sync_hs : out std_logic; + sync_vs : out std_logic; + adrsel : out std_logic; + rdy : out std_logic; + vblank : out std_logic; + hblank_frgrd : out std_logic; + hblank_bkgrd : out std_logic +); +end phoenix_video; + +architecture struct of phoenix_video is + signal hclk_i : std_logic := '0'; + signal hstb_i : std_logic := '0'; + signal hcnt_i : unsigned(9 downto 1) := (others=>'0'); + signal vcnt_i : unsigned(9 downto 1) := (others=>'0'); + signal vcnt2 : std_logic_vector(8 downto 1) := (others=>'0'); + signal vblank_n : std_logic := '0'; + + signal rdy1_i : std_logic; + signal rdy2_i : std_logic; + signal j1 : std_logic; + signal k1 : std_logic; + signal q1 : std_logic; + signal j2 : std_logic; + signal k2 : std_logic; + signal q2 : std_logic; + +begin + +-- horizontal counter clock (pixel clock) +process(clk11) begin + if falling_edge(clk11) then + hclk_i <= not hclk_i; + end if; +end process; + +-- horizontal counter from 0x0A0 to 0x1FF : 352 pixels +process(clk11) begin + if rising_edge(clk11) then + if hclk_i = '1' then + if reset = '1' then + hcnt_i <= (others=>'0'); + vcnt_i <= (others=>'0'); + else + hcnt_i <= hcnt_i +1; + if hcnt_i = 511 then + hcnt_i <= to_unsigned(160,9); + vcnt_i <= vcnt_i +1; + if vcnt_i = 261 then + vcnt_i <= to_unsigned(0,9); + end if; + end if; + end if; + end if; + end if; +end process; + +-- vertical counter clock (line clock) = hblank +process(clk11) begin + if rising_edge(clk11) then + if hclk_i = '1' then + if (hcnt_i(3) and hcnt_i(2) and hcnt_i(1)) = '1' then hstb_i <= not hcnt_i(9); end if; + end if; + end if; +end process; + +-- vertical blanking +vblank_n <= + not(vcnt2(8) and vcnt2(7)) + or + ( not + ( not (vcnt2(8) and vcnt2(7) and not vcnt2(6) and not vcnt2(5) and not vcnt2(4)) + and + not (vcnt2(8) and vcnt2(7) and not vcnt2(6) and not vcnt2(5) and vcnt2(4)) + ) +); + +-- ready signal for microprocessor +rdy1_i <= not( not(hcnt_i(9)) and not hcnt_i(7) and hcnt_i(6) and not hcnt_i(5)); +rdy2_i <= not( not(hcnt_i(9)) and hcnt_i(7) and hcnt_i(6) and hcnt_i(5)); + +-- background horizontal blanking +j1 <= hcnt_i(6) and hcnt_i(4); +k1 <= hstb_i; + +process(clk11) begin + if rising_edge(clk11) then + if hclk_i = '1' then + if (j1 xor k1) = '1' then + q1 <= j1; + elsif j1 = '1' then + q1 <= not q1; + else + q1 <= q1; + end if; + end if; + end if; +end process; + +j2 <= not hcnt_i(6) and hcnt_i(5); +k2 <= hcnt_i(8) and hcnt_i(7) and hcnt_i(6) and hcnt_i(4); + +process(clk11) begin + if rising_edge(clk11) then + if hclk_i = '1' then + if (j2 xor k2) = '1' then + q2 <= j2; + elsif j2 = '1' then + q2 <= not q2; + else + q2 <= q2; + end if; + end if; + end if; +end process; + +-- output +ce_pix <= hclk_i; +hcnt <= std_logic_vector(hcnt_i); +vcnt2 <= std_logic_vector(vcnt_i(8 downto 1)) when vcnt_i < 255 else "11111111"; +vcnt <= vcnt2; +--sync <= not(sync1_i xor sync2_i) ; original syncs +rdy <= not(vblank_n and (not (rdy1_i and rdy2_i and not hcnt_i(9)))); +adrsel <= vblank_n and hcnt_i(9); + +vblank <= not vblank_n; +hblank_frgrd <= hstb_i; +hblank_bkgrd <= not(hcnt_i(9) and q1) and not(hcnt_i(9) and (q2)); + +process(clk11) begin + if rising_edge(clk11) then + if hclk_i = '1' then + if hcnt_i = 191 then + sync_hs <= '1'; + if vcnt_i = 230 then sync_vs <= '1'; end if; + if vcnt_i = 237 then sync_vs <= '0'; end if; + end if; + if hcnt_i = 217 then sync_hs <= '0'; end if; + end if; + end if; +end process; + +end struct; diff --git a/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/pll.ppf b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/pll.ppf new file mode 100644 index 00000000..2dc9dced --- /dev/null +++ b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/pll.ppf @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/pll.qip b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/pll.qip new file mode 100644 index 00000000..48665362 --- /dev/null +++ b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/pll.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 VHDL_FILE [file join $::quartus(qip_path) "pll.vhd"] +set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll.ppf"] diff --git a/Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/pll.vhd b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/pll.vhd similarity index 100% rename from Arcade_MiST/Custom Hardware/Phoenix_MIST/rtl/pll.vhd rename to Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/pll.vhd diff --git a/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/scandoubler.v b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/scandoubler.v new file mode 100644 index 00000000..e85cba43 --- /dev/null +++ b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/scandoubler.v @@ -0,0 +1,183 @@ +// +// scandoubler.v +// +// Copyright (c) 2015 Till Harbaum +// Copyright (c) 2017 Sorgelig +// +// This source file is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This source file is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// TODO: Delay vsync one line + +module scandoubler #(parameter LENGTH, parameter HALF_DEPTH) +( + // system interface + input clk_sys, + input ce_pix, + input ce_pix_actual, + + input hq2x, + + // shifter video interface + input hs_in, + input vs_in, + input line_start, + + input [DWIDTH:0] r_in, + input [DWIDTH:0] g_in, + input [DWIDTH:0] b_in, + input mono, + + // output interface + output reg hs_out, + output vs_out, + output [DWIDTH:0] r_out, + output [DWIDTH:0] g_out, + output [DWIDTH:0] b_out +); + + +localparam DWIDTH = HALF_DEPTH ? 2 : 5; + +assign vs_out = vs_in; + +reg [2:0] phase; +reg [2:0] ce_div; +reg [7:0] pix_len = 0; +wire [7:0] pl = pix_len + 1'b1; + +reg ce_x1, ce_x4; +reg req_line_reset; +wire ls_in = hs_in | line_start; +always @(negedge clk_sys) begin + reg old_ce; + reg [2:0] ce_cnt; + + reg [7:0] pixsz2, pixsz4 = 0; + + old_ce <= ce_pix; + if(~&pix_len) pix_len <= pix_len + 1'd1; + + ce_x4 <= 0; + ce_x1 <= 0; + + // use such odd comparison to place c_x4 evenly if master clock isn't multiple 4. + if((pl == pixsz4) || (pl == pixsz2) || (pl == (pixsz2+pixsz4))) begin + phase <= phase + 1'd1; + ce_x4 <= 1; + end + + if(~old_ce & ce_pix) begin + pixsz2 <= {1'b0, pl[7:1]}; + pixsz4 <= {2'b00, pl[7:2]}; + ce_x1 <= 1; + ce_x4 <= 1; + pix_len <= 0; + phase <= phase + 1'd1; + + ce_cnt <= ce_cnt + 1'd1; + if(ce_pix_actual) begin + phase <= 0; + ce_div <= ce_cnt + 1'd1; + ce_cnt <= 0; + req_line_reset <= 0; + end + + if(ls_in) req_line_reset <= 1; + end +end + +reg ce_sd; +always @(*) begin + case(ce_div) + 2: ce_sd = !phase[0]; + 4: ce_sd = !phase[1:0]; + default: ce_sd <= 1; + endcase +end + +localparam AWIDTH = `BITS_TO_FIT(LENGTH); +Hq2x #(.LENGTH(LENGTH), .HALF_DEPTH(HALF_DEPTH)) Hq2x +( + .clk(clk_sys), + .ce_x4(ce_x4 & ce_sd), + .inputpixel({b_in,g_in,r_in}), + .mono(mono), + .disable_hq2x(~hq2x), + .reset_frame(vs_in), + .reset_line(req_line_reset), + .read_y(sd_line), + .read_x(sd_h_actual), + .outpixel({b_out,g_out,r_out}) +); + +reg [10:0] sd_h_actual; +always @(*) begin + case(ce_div) + 2: sd_h_actual = sd_h[10:1]; + 4: sd_h_actual = sd_h[10:2]; + default: sd_h_actual = sd_h; + endcase +end + +reg [10:0] sd_h; +reg [1:0] sd_line; +always @(posedge clk_sys) begin + + reg [11:0] hs_max,hs_rise,hs_ls; + reg [10:0] hcnt; + reg [11:0] sd_hcnt; + + reg hs, hs2, vs, ls; + + if(ce_x1) begin + hs <= hs_in; + ls <= ls_in; + + if(ls && !ls_in) hs_ls <= {hcnt,1'b1}; + + // falling edge of hsync indicates start of line + if(hs && !hs_in) begin + hs_max <= {hcnt,1'b1}; + hcnt <= 0; + if(ls && !ls_in) hs_ls <= {10'd0,1'b1}; + end else begin + hcnt <= hcnt + 1'd1; + end + + // save position of rising edge + if(!hs && hs_in) hs_rise <= {hcnt,1'b1}; + + vs <= vs_in; + if(vs && ~vs_in) sd_line <= 0; + end + + if(ce_x4) begin + hs2 <= hs_in; + + // output counter synchronous to input and at twice the rate + sd_hcnt <= sd_hcnt + 1'd1; + sd_h <= sd_h + 1'd1; + if(hs2 && !hs_in) sd_hcnt <= hs_max; + if(sd_hcnt == hs_max) sd_hcnt <= 0; + + // replicate horizontal sync at twice the speed + if(sd_hcnt == hs_max) hs_out <= 0; + if(sd_hcnt == hs_rise) hs_out <= 1; + + if(sd_hcnt == hs_ls) sd_h <= 0; + if(sd_hcnt == hs_ls) sd_line <= sd_line + 1'd1; + end +end + +endmodule diff --git a/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/video_mixer.sv b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/video_mixer.sv new file mode 100644 index 00000000..79d8ca03 --- /dev/null +++ b/Arcade_MiST/Phoenix Hardware/Phoenix_MIST/rtl/video_mixer.sv @@ -0,0 +1,243 @@ +// +// +// Copyright (c) 2017 Sorgelig +// +// This program is GPL Licensed. See COPYING for the full license. +// +// +//////////////////////////////////////////////////////////////////////////////////////////////////////// + +`timescale 1ns / 1ps + +// +// LINE_LENGTH: Length of display line in pixels +// Usually it's length from HSync to HSync. +// May be less if line_start is used. +// +// HALF_DEPTH: If =1 then color dept is 3 bits per component +// For half depth 6 bits monochrome is available with +// mono signal enabled and color = {G, R} + +module video_mixer +#( + parameter LINE_LENGTH = 480, + parameter HALF_DEPTH = 1, + + parameter OSD_COLOR = 3'd4, + parameter OSD_X_OFFSET = 10'd0, + parameter OSD_Y_OFFSET = 10'd0 +) +( + // master clock + // it should be multiple by (ce_pix*4). + input clk_sys, + + // Pixel clock or clock_enable (both are accepted). + input ce_pix, + + // Some systems have multiple resolutions. + // ce_pix_actual should match ce_pix where every second or fourth pulse is enabled, + // thus half or qurter resolutions can be used without brake video sync while switching resolutions. + // For fixed single resolution (or when video sync stability isn't required) ce_pix_actual = ce_pix. + input ce_pix_actual, + + // OSD SPI interface + input SPI_SCK, + input SPI_SS3, + input SPI_DI, + + // scanlines (00-none 01-25% 10-50% 11-75%) + input [1:0] scanlines, + + // 0 = HVSync 31KHz, 1 = CSync 15KHz + input scandoublerD, + + // High quality 2x scaling + input hq2x, + + // YPbPr always uses composite sync + input ypbpr, + + // 0 = 16-240 range. 1 = 0-255 range. (only for YPbPr color space) + input ypbpr_full, + input [1:0] rotate, //[0] - rotate [1] - left or right + // color + input [DWIDTH:0] R, + input [DWIDTH:0] G, + input [DWIDTH:0] B, + + // Monochrome mode (for HALF_DEPTH only) + input mono, + + // interlace sync. Positive pulses. + input HSync, + input VSync, + + // Falling of this signal means start of informative part of line. + // It can be horizontal blank signal. + // This signal can be used to reduce amount of required FPGA RAM for HQ2x scan doubler + // If FPGA RAM is not an issue, then simply set it to 0 for whole line processing. + // Keep in mind: due to algo first and last pixels of line should be black to avoid side artefacts. + // Thus, if blank signal is used to reduce the line, make sure to feed at least one black (or paper) pixel + // before first informative pixel. + input line_start, + + // MiST video output signals + output [5:0] VGA_R, + output [5:0] VGA_G, + output [5:0] VGA_B, + output VGA_VS, + output VGA_HS +); + +localparam DWIDTH = HALF_DEPTH ? 2 : 5; + +wire [DWIDTH:0] R_sd; +wire [DWIDTH:0] G_sd; +wire [DWIDTH:0] B_sd; +wire hs_sd, vs_sd; + +scandoubler #(.LENGTH(LINE_LENGTH), .HALF_DEPTH(HALF_DEPTH)) scandoubler +( + .*, + .hs_in(HSync), + .vs_in(VSync), + .r_in(R), + .g_in(G), + .b_in(B), + + .hs_out(hs_sd), + .vs_out(vs_sd), + .r_out(R_sd), + .g_out(G_sd), + .b_out(B_sd) +); + +wire [DWIDTH:0] rt = (scandoublerD ? R : R_sd); +wire [DWIDTH:0] gt = (scandoublerD ? G : G_sd); +wire [DWIDTH:0] bt = (scandoublerD ? B : B_sd); + +generate + if(HALF_DEPTH) begin + wire [5:0] r = mono ? {gt,rt} : {rt,rt}; + wire [5:0] g = mono ? {gt,rt} : {gt,gt}; + wire [5:0] b = mono ? {gt,rt} : {bt,bt}; + end else begin + wire [5:0] r = rt; + wire [5:0] g = gt; + wire [5:0] b = bt; + end +endgenerate + +wire hs = (scandoublerD ? HSync : hs_sd); +wire vs = (scandoublerD ? VSync : vs_sd); + +reg scanline = 0; +always @(posedge clk_sys) begin + reg old_hs, old_vs; + + old_hs <= hs; + old_vs <= vs; + + if(old_hs && ~hs) scanline <= ~scanline; + if(old_vs && ~vs) scanline <= 0; +end + +wire [5:0] r_out, g_out, b_out; +always @(*) begin + case(scanlines & {scanline, scanline}) + 1: begin // reduce 25% = 1/2 + 1/4 + r_out = {1'b0, r[5:1]} + {2'b00, r[5:2]}; + g_out = {1'b0, g[5:1]} + {2'b00, g[5:2]}; + b_out = {1'b0, b[5:1]} + {2'b00, b[5:2]}; + end + + 2: begin // reduce 50% = 1/2 + r_out = {1'b0, r[5:1]}; + g_out = {1'b0, g[5:1]}; + b_out = {1'b0, b[5:1]}; + end + + 3: begin // reduce 75% = 1/4 + r_out = {2'b00, r[5:2]}; + g_out = {2'b00, g[5:2]}; + b_out = {2'b00, b[5:2]}; + end + + default: begin + r_out = r; + g_out = g; + b_out = b; + end + endcase +end + +wire [5:0] red, green, blue; +osd #(OSD_X_OFFSET, OSD_Y_OFFSET, OSD_COLOR) osd +( + .*, + + .R_in(r_out), + .G_in(g_out), + .B_in(b_out), + .HSync(hs), + .VSync(vs), + .rotate(rotate), + + .R_out(red), + .G_out(green), + .B_out(blue) +); + +wire [5:0] yuv_full[225] = '{ + 6'd0, 6'd0, 6'd0, 6'd0, 6'd1, 6'd1, 6'd1, 6'd1, + 6'd2, 6'd2, 6'd2, 6'd3, 6'd3, 6'd3, 6'd3, 6'd4, + 6'd4, 6'd4, 6'd5, 6'd5, 6'd5, 6'd5, 6'd6, 6'd6, + 6'd6, 6'd7, 6'd7, 6'd7, 6'd7, 6'd8, 6'd8, 6'd8, + 6'd9, 6'd9, 6'd9, 6'd9, 6'd10, 6'd10, 6'd10, 6'd11, + 6'd11, 6'd11, 6'd11, 6'd12, 6'd12, 6'd12, 6'd13, 6'd13, + 6'd13, 6'd13, 6'd14, 6'd14, 6'd14, 6'd15, 6'd15, 6'd15, + 6'd15, 6'd16, 6'd16, 6'd16, 6'd17, 6'd17, 6'd17, 6'd17, + 6'd18, 6'd18, 6'd18, 6'd19, 6'd19, 6'd19, 6'd19, 6'd20, + 6'd20, 6'd20, 6'd21, 6'd21, 6'd21, 6'd21, 6'd22, 6'd22, + 6'd22, 6'd23, 6'd23, 6'd23, 6'd23, 6'd24, 6'd24, 6'd24, + 6'd25, 6'd25, 6'd25, 6'd25, 6'd26, 6'd26, 6'd26, 6'd27, + 6'd27, 6'd27, 6'd27, 6'd28, 6'd28, 6'd28, 6'd29, 6'd29, + 6'd29, 6'd29, 6'd30, 6'd30, 6'd30, 6'd31, 6'd31, 6'd31, + 6'd31, 6'd32, 6'd32, 6'd32, 6'd33, 6'd33, 6'd33, 6'd33, + 6'd34, 6'd34, 6'd34, 6'd35, 6'd35, 6'd35, 6'd35, 6'd36, + 6'd36, 6'd36, 6'd36, 6'd37, 6'd37, 6'd37, 6'd38, 6'd38, + 6'd38, 6'd38, 6'd39, 6'd39, 6'd39, 6'd40, 6'd40, 6'd40, + 6'd40, 6'd41, 6'd41, 6'd41, 6'd42, 6'd42, 6'd42, 6'd42, + 6'd43, 6'd43, 6'd43, 6'd44, 6'd44, 6'd44, 6'd44, 6'd45, + 6'd45, 6'd45, 6'd46, 6'd46, 6'd46, 6'd46, 6'd47, 6'd47, + 6'd47, 6'd48, 6'd48, 6'd48, 6'd48, 6'd49, 6'd49, 6'd49, + 6'd50, 6'd50, 6'd50, 6'd50, 6'd51, 6'd51, 6'd51, 6'd52, + 6'd52, 6'd52, 6'd52, 6'd53, 6'd53, 6'd53, 6'd54, 6'd54, + 6'd54, 6'd54, 6'd55, 6'd55, 6'd55, 6'd56, 6'd56, 6'd56, + 6'd56, 6'd57, 6'd57, 6'd57, 6'd58, 6'd58, 6'd58, 6'd58, + 6'd59, 6'd59, 6'd59, 6'd60, 6'd60, 6'd60, 6'd60, 6'd61, + 6'd61, 6'd61, 6'd62, 6'd62, 6'd62, 6'd62, 6'd63, 6'd63, + 6'd63 +}; + +// http://marsee101.blog19.fc2.com/blog-entry-2311.html +// Y = 16 + 0.257*R + 0.504*G + 0.098*B (Y = 0.299*R + 0.587*G + 0.114*B) +// Pb = 128 - 0.148*R - 0.291*G + 0.439*B (Pb = -0.169*R - 0.331*G + 0.500*B) +// Pr = 128 + 0.439*R - 0.368*G - 0.071*B (Pr = 0.500*R - 0.419*G - 0.081*B) + +wire [18:0] y_8 = 19'd04096 + ({red, 8'd0} + {red, 3'd0}) + ({green, 9'd0} + {green, 2'd0}) + ({blue, 6'd0} + {blue, 5'd0} + {blue, 2'd0}); +wire [18:0] pb_8 = 19'd32768 - ({red, 7'd0} + {red, 4'd0} + {red, 3'd0}) - ({green, 8'd0} + {green, 5'd0} + {green, 3'd0}) + ({blue, 8'd0} + {blue, 7'd0} + {blue, 6'd0}); +wire [18:0] pr_8 = 19'd32768 + ({red, 8'd0} + {red, 7'd0} + {red, 6'd0}) - ({green, 8'd0} + {green, 6'd0} + {green, 5'd0} + {green, 4'd0} + {green, 3'd0}) - ({blue, 6'd0} + {blue , 3'd0}); + +wire [7:0] y = ( y_8[17:8] < 16) ? 8'd16 : ( y_8[17:8] > 235) ? 8'd235 : y_8[15:8]; +wire [7:0] pb = (pb_8[17:8] < 16) ? 8'd16 : (pb_8[17:8] > 240) ? 8'd240 : pb_8[15:8]; +wire [7:0] pr = (pr_8[17:8] < 16) ? 8'd16 : (pr_8[17:8] > 240) ? 8'd240 : pr_8[15:8]; + +assign VGA_R = ypbpr ? (ypbpr_full ? yuv_full[pr-8'd16] : pr[7:2]) : red; +assign VGA_G = ypbpr ? (ypbpr_full ? yuv_full[y -8'd16] : y[7:2]) : green; +assign VGA_B = ypbpr ? (ypbpr_full ? yuv_full[pb-8'd16] : pb[7:2]) : blue; +assign VGA_VS = (scandoublerD | ypbpr) ? 1'b1 : ~vs_sd; +assign VGA_HS = scandoublerD ? ~(HSync ^ VSync) : ypbpr ? ~(hs_sd ^ vs_sd) : ~hs_sd; + +endmodule diff --git a/Arcade_MiST/README.txt b/Arcade_MiST/README.txt index ee55280f..49f66142 100644 --- a/Arcade_MiST/README.txt +++ b/Arcade_MiST/README.txt @@ -20,7 +20,6 @@ Aviable Arcade Cores Crazy Climber Crazy Kong Galaga - Phoenix #Data East Burger Time Hardware #Setup 1 @@ -36,12 +35,15 @@ Aviable Arcade Cores Black Hole Catacomb Galaxian + King & Balloon Moon Cresta Mr. Do´s Nightmare Omega Orbitron Pisces + Triple Draw Poker War of Bugs + Zig Zag #Irem M52 Hardware Moon Patrol @@ -91,6 +93,10 @@ Aviable Arcade Cores Van Van Car Woodpecker +#Phoenix Hardware + Capitol + Phoenix + #Scramble Hardware Amidar Frogger