diff --git a/Arcade_MiST/IremM92 Hardware/IremM92.qpf b/Arcade_MiST/IremM92 Hardware/IremM92.qpf new file mode 100644 index 00000000..e65af4b2 --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/IremM92.qpf @@ -0,0 +1,30 @@ +# -------------------------------------------------------------------------- # +# +# Copyright (C) 1991-2011 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 +# Version 10.1 Build 197 01/19/2011 Service Pack 1 SJ Full Version +# Date created = 23:49:02 July 13, 2012 +# +# -------------------------------------------------------------------------- # + +QUARTUS_VERSION = "10.1" +DATE = "23:49:02 July 13, 2012" + +# Revisions + +PROJECT_REVISION = "IremM92" diff --git a/Arcade_MiST/IremM92 Hardware/IremM92.qsf b/Arcade_MiST/IremM92 Hardware/IremM92.qsf new file mode 100644 index 00000000..0f46371e --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/IremM92.qsf @@ -0,0 +1,255 @@ +set_global_assignment -name FIT_ATTEMPTS_TO_SKIP 0 +# -------------------------------------------------------------------------- # +# +# 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 = 21:06:00 February 29, 2020 +# +# -------------------------------------------------------------------------- # +# +# Notes: +# +# 1) The default values for assignments are stored in the file: +# IremM92_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 PROJECT_OUTPUT_DIRECTORY output_files +set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL +set_global_assignment -name LAST_QUARTUS_VERSION 13.1 +set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:rtl/build_id.tcl" +set_global_assignment -name SMART_RECOMPILE ON + +# 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_90 -to SPI_SS4 +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 + +# Classic Timing Assignments +# ========================== +set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0 +set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85 +set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS ON + +# Analysis & Synthesis Assignments +# ================================ +set_global_assignment -name FAMILY "Cyclone III" +set_global_assignment -name TOP_LEVEL_ENTITY IremM92_MiST +set_global_assignment -name DEVICE_FILTER_PIN_COUNT 144 +set_global_assignment -name DEVICE_FILTER_SPEED_GRADE 8 +set_global_assignment -name DEVICE_FILTER_PACKAGE TQFP +set_global_assignment -name CYCLONEII_OPTIMIZATION_TECHNIQUE AREA +set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS ON +set_global_assignment -name ALLOW_SYNCH_CTRL_USAGE ON +set_global_assignment -name VHDL_INPUT_VERSION VHDL_2008 +set_global_assignment -name VHDL_SHOW_LMF_MAPPING_MESSAGES OFF + +# Fitter Assignments +# ================== +set_global_assignment -name DEVICE EP3C25E144C8 +set_global_assignment -name ENABLE_CONFIGURATION_PINS OFF +set_global_assignment -name ENABLE_NCE_PIN OFF +set_global_assignment -name ENABLE_BOOT_SEL_PIN OFF +set_global_assignment -name CYCLONEIII_CONFIGURATION_SCHEME "PASSIVE SERIAL" +set_global_assignment -name CRC_ERROR_OPEN_DRAIN OFF +set_global_assignment -name FORCE_CONFIGURATION_VCCIO ON +set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "3.3-V LVTTL" +set_global_assignment -name CYCLONEII_RESERVE_NCEO_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_global_assignment -name RESERVE_DATA0_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_global_assignment -name RESERVE_DATA1_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_global_assignment -name RESERVE_FLASH_NCE_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_global_assignment -name RESERVE_DCLK_AFTER_CONFIGURATION "USE AS REGULAR IO" +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 output_files/cpu.stp + +# Power Estimation Assignments +# ============================ +set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "NO HEAT SINK WITH STILL AIR" +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(IremM92_MiST) + + # Pin & Location Assignments + # ========================== +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[*] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[*] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_BA[0] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_BA[1] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQMH +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQML +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nRAS +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nCAS +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nWE +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nCS +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[*] +set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[*] + + # Fitter Assignments + # ================== +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[*] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[*] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_BA[*] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQML +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQMH +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nRAS +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nCAS +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nWE +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nCS +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_CKE +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_CLK +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_R[*] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_G[*] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_B[*] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_HS +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_VS +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to AUDIO_L +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to AUDIO_R +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SPI_DO + + # start DESIGN_PARTITION(Top) + # --------------------------- + + # Incremental Compilation Assignments + # =================================== +set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top +set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top +set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top + + # end DESIGN_PARTITION(Top) + # ------------------------- + +# end ENTITY(IremM92_MiST) +# --------------------------- +set_location_assignment PLL_1 -to pll|altpll_component|auto_generated|pll1 +set_global_assignment -name DSP_BLOCK_BALANCING "DSP BLOCKS" +set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_RETIMING OFF +set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_DUPLICATION OFF +set_global_assignment -name AUTO_SHIFT_REGISTER_RECOGNITION AUTO +set_global_assignment -name PHYSICAL_SYNTHESIS_EFFORT EXTRA +set_global_assignment -name VERILOG_SHOW_LMF_MAPPING_MESSAGES OFF +set_global_assignment -name SYSTEMVERILOG_FILE rtl/IremM92_MiST.sv +set_global_assignment -name QIP_FILE rtl/pll_mist.qip +set_global_assignment -name QIP_FILE rtl/m92.qip +set_global_assignment -name QIP_FILE ../../common/mist/mist.qip +set_global_assignment -name QIP_FILE ../../common/CPU/v30/V30.qip +set_global_assignment -name QIP_FILE ../../common/Sound/jt51/jt51.qip +set_global_assignment -name AUTO_RESOURCE_SHARING ON +set_global_assignment -name SIGNALTAP_FILE output_files/cpu.stp +set_global_assignment -name SIGNALTAP_FILE output_files/dio.stp +set_global_assignment -name SIGNALTAP_FILE output_files/spr.stp +set_global_assignment -name SIGNALTAP_FILE output_files/layer_a.stp +set_global_assignment -name SIGNALTAP_FILE output_files/cpu2.stp +set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/Arcade_MiST/IremM92 Hardware/IremM92.sdc b/Arcade_MiST/IremM92 Hardware/IremM92.sdc new file mode 100644 index 00000000..c8ae6146 --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/IremM92.sdc @@ -0,0 +1,153 @@ +## Generated SDC file "vectrex_MiST.out.sdc" + +## Copyright (C) 1991-2013 Altera Corporation +## Your use of Altera Corporation's design tools, logic functions +## and other software and tools, and its AMPP partner logic +## functions, and any output files from any of the foregoing +## (including device programming or simulation files), and any +## associated documentation or information are expressly subject +## to the terms and conditions of the Altera Program License +## Subscription Agreement, Altera MegaCore Function License +## Agreement, or other applicable license agreement, including, +## without limitation, that your use is for the sole purpose of +## programming logic devices manufactured by Altera and sold by +## Altera or its authorized distributors. Please refer to the +## applicable agreement for further details. + + +## VENDOR "Altera" +## PROGRAM "Quartus II" +## VERSION "Version 13.1.0 Build 162 10/23/2013 SJ Web Edition" + +## DATE "Sun Jun 24 12:53:00 2018" + +## +## DEVICE "EP3C25E144C8" +## + +# Clock constraints + +# Automatically constrain PLL and other generated clocks +derive_pll_clocks -create_base_clocks + +# Automatically calculate clock uncertainty to jitter and other effects. +derive_clock_uncertainty + +# tsu/th constraints + +# tco constraints + +# tpd constraints + +#************************************************************** +# Time Information +#************************************************************** + +set_time_format -unit ns -decimal_places 3 + + + +#************************************************************** +# Create Clock +#************************************************************** + +create_clock -name {SPI_SCK} -period 41.666 -waveform { 20.8 41.666 } [get_ports {SPI_SCK}] + +set sdram_clk "pll|altpll_component|auto_generated|pll1|clk[0]" +set mem_clk "pll|altpll_component|auto_generated|pll1|clk[1]" +set vid_clk "pll|altpll_component|auto_generated|pll1|clk[2]" +set game_clk "pll|altpll_component|auto_generated|pll1|clk[2]" + +#************************************************************** +# Create Generated Clock +#************************************************************** + + +#************************************************************** +# Set Clock Latency +#************************************************************** + + + +#************************************************************** +# Set Clock Uncertainty +#************************************************************** + +#************************************************************** +# Set Input Delay +#************************************************************** + +set_input_delay -add_delay -clock_fall -clock [get_clocks {CLOCK_27}] 1.000 [get_ports {CLOCK_27}] +set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {CONF_DATA0}] +set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_DI}] +set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_SCK}] +set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_SS2}] +set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_SS3}] + +set_input_delay -clock [get_clocks $sdram_clk] -reference_pin [get_ports {SDRAM_CLK}] -max 6.4 [get_ports SDRAM_DQ[*]] +set_input_delay -clock [get_clocks $sdram_clk] -reference_pin [get_ports {SDRAM_CLK}] -min 3.2 [get_ports SDRAM_DQ[*]] + +#************************************************************** +# Set Output Delay +#************************************************************** + +set_output_delay -add_delay -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_DO}] +set_output_delay -add_delay -clock [get_clocks $game_clk] 1.000 [get_ports {AUDIO_L}] +set_output_delay -add_delay -clock [get_clocks $game_clk] 1.000 [get_ports {AUDIO_R}] +set_output_delay -add_delay -clock [get_clocks $game_clk] 1.000 [get_ports {LED}] +set_output_delay -add_delay -clock [get_clocks $vid_clk] 1.000 [get_ports {VGA_*}] + +set_output_delay -clock [get_clocks $sdram_clk] -reference_pin [get_ports {SDRAM_CLK}] -max 1.5 [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}] +set_output_delay -clock [get_clocks $sdram_clk] -reference_pin [get_ports {SDRAM_CLK}] -min -0.8 [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}] + +#************************************************************** +# Set Clock Groups +#************************************************************** + +set_clock_groups -asynchronous -group [get_clocks {SPI_SCK}] -group [get_clocks {pll|altpll_component|auto_generated|pll1|clk[*]}] + +#************************************************************** +# Set False Path +#************************************************************** + + + +#************************************************************** +# Set Multicycle Path +#************************************************************** + +set_multicycle_path -to {VGA_*[*]} -setup 3 +set_multicycle_path -to {VGA_*[*]} -hold 2 + +set_multicycle_path -from [get_clocks $sdram_clk] -to [get_clocks $mem_clk] -setup 2 + +set_multicycle_path -from {m92:m92|v30:v30|*} -to {m92:m92|v30:v30|regs.*} -setup 2 +set_multicycle_path -from {m92:m92|v30:v30|*} -to {m92:m92|v30:v30|regs.*} -hold 1 +set_multicycle_path -from {m92:m92|v30:v30|*} -to {m92:m92|v30:v30|bus_datawrite[*]} -setup 2 +set_multicycle_path -from {m92:m92|v30:v30|*} -to {m92:m92|v30:v30|bus_datawrite[*]} -hold 1 +set_multicycle_path -from {m92:m92|v30:v30|*} -to {m92:m92|v30:v30|bus_addr[*]} -setup 2 +set_multicycle_path -from {m92:m92|v30:v30|*} -to {m92:m92|v30:v30|bus_addr[*]} -hold 1 + +set_multicycle_path -from {m92:m92|sound:sound|v35:v35|v30:core|*} -to {m92:m92|sound:sound|v35:v35|v30:core|regs.*} -setup 2 +set_multicycle_path -from {m92:m92|sound:sound|v35:v35|v30:core|*} -to {m92:m92|sound:sound|v35:v35|v30:core|regs.*} -hold 1 +set_multicycle_path -from {m92:m92|sound:sound|v35:v35|v30:core|*} -to {m92:m92|sound:sound|v35:v35|v30:core|bus_datawrite[*]} -setup 2 +set_multicycle_path -from {m92:m92|sound:sound|v35:v35|v30:core|*} -to {m92:m92|sound:sound|v35:v35|v30:core|bus_datawrite[*]} -hold 1 +set_multicycle_path -from {m92:m92|sound:sound|v35:v35|v30:core|*} -to {m92:m92|sound:sound|v35:v35|v30:core|bus_addr[*]} -setup 2 +set_multicycle_path -from {m92:m92|sound:sound|v35:v35|v30:core|*} -to {m92:m92|sound:sound|v35:v35|v30:core|bus_addr[*]} -hold 1 + +#************************************************************** +# Set Maximum Delay +#************************************************************** + + + +#************************************************************** +# Set Minimum Delay +#************************************************************** + + + +#************************************************************** +# Set Input Transition +#************************************************************** + diff --git a/Arcade_MiST/IremM92 Hardware/Readme.md b/Arcade_MiST/IremM92 Hardware/Readme.md new file mode 100644 index 00000000..6b82b99d --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/Readme.md @@ -0,0 +1,39 @@ +# Irem M92 Core + +![](docs/header-small.png) + +This is the port of the [MiSTer FPGA core for the Irem M92 arcade system](https://github.com/MiSTer-devel/Arcade-IremM92_MiSTer) (http://www.system16.com/hardware.php?id=747). The Irem M92 system is known for its high-quality graphics and sound, and this core brings these games to FPGA platforms for arcade enthusiasts to enjoy. + +New SDRAM controller, optimizations to fit into the MiST FPGA by Gyorgy Szombathelyi. Original core by [Martin Donlon](https://github.com/wickerwaka). + +The Irem M92 core includes numerous games that have not been ported elsewhere, providing a unique and authentic arcade experience. Some of the popular games available in this core are: + +- In the Hunt +- Gunforce +- R-Type Leo +- Hook +- Blade Master +- Mystic Riders +- Undercover Cops +- Ninja Baseball Batman + +## Controls +All of the games use standard 8-way input with two buttons with the exception of *Superior Soldiers* which uses six button input. Several of the games support 3 or 4 players but you will need to change a DIP switch in the DIP switch menu to enable that. By default the button buttons are mapped to the MiSTers SNES-like layout as `B,A,X,Y,L,R`. The `Coin` and `Start` buttons are mapped to Select and Start. There are two additional buttons that can be mapped that are not mapped by default. `P2 Start` maps the the second players start button. The only purpose this serves is for accessing the service menu with a single controller since most games require pressing P1 and P2 start to access it. The second unmapped button is `Pause` which pauses the core. + +Standard MAME keyboard controls are also supported for up to 4-players. + + +## Thanks +Many people, knowingly or not, contributed to this work. +- Mark, for his R-Type Leo PCB and his support through the years. +- @sorgelig, for developing and maintaining MiSTer. +- @RobertPeip, for the v30mz cpu I am using as the basis for the v33 & v35. +- @jotego, for the YM2151 implementation and analog adjustment module. +- @ArtemioUrbina, for their support building [MDfourier](https://junkerhq.net/MDFourier/) tests. +- @zakk4223, for hiscore support. +- @birdybro, @Toryalai1 & @wwark for MRA help. +- Sanborn, for help with the docs. +- The people from PLD Archive collecting and archiving PAL information https://wiki.pldarchive.co.uk/index.php?title=Category:Irem_M92 +- The MiSTer FPGA discord server for support, advice and testing. + + diff --git a/Arcade_MiST/IremM92 Hardware/clean.bat b/Arcade_MiST/IremM92 Hardware/clean.bat new file mode 100644 index 00000000..1e6a801a --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/clean.bat @@ -0,0 +1,36 @@ +@echo off +del /s *.bak +del /s *.orig +del /s *.rej +del /s *~ +rmdir /s /q db +rmdir /s /q incremental_db +rmdir /s /q output_files +rmdir /s /q simulation +rmdir /s /q greybox_tmp +rmdir /s /q hc_output +rmdir /s /q .qsys_edit +rmdir /s /q hps_isw_handoff +rmdir /s /q sys\.qsys_edit +rmdir /s /q sys\vip +for /d %%i in (sys\*_sim) do rmdir /s /q "%%i" +for /d %%i in (rtl\*_sim) do rmdir /s /q "%%i" +del build_id.v +del c5_pin_model_dump.txt +del PLLJ_PLLSPE_INFO.txt +del /s *.qws +del /s *.ppf +del /s *.ddb +del /s *.csv +del /s *.cmp +del /s *.sip +del /s *.spd +del /s *.bsf +del /s *.f +del /s *.sopcinfo +del /s *.xml +del *.cdf +del *.rpt +del /s new_rtl_netlist +del /s old_rtl_netlist +pause diff --git a/Arcade_MiST/IremM92 Hardware/meta/Blade Master (World).mra b/Arcade_MiST/IremM92 Hardware/meta/Blade Master (World).mra new file mode 100644 index 00000000..ff987ea1 --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/meta/Blade Master (World).mra @@ -0,0 +1,104 @@ + + Blade Master (World) + 0245 + bmaster + 1991 + Irem + Brawler + IremM92 + horizontal + + 8-way + 2 + + + + + + + + + + + + + + + + + 00 + + + 00 0a 00 00 + + + + + + + + + + + 01 10 00 00 + + + + + + + + + 02 20 00 00 + + + + + + + + + 03 02 00 00 + + + + + + + 04 00 01 00 + + 90 90 79 90 9d 48 90 90 90 90 2e 90 90 a5 72 90 + 46 5b b1 3a c3 90 35 90 90 23 90 99 90 05 90 3c + 3b 76 11 90 90 4b 90 92 90 32 5d 90 f7 5a 9c 90 + 26 40 89 90 90 90 90 57 90 90 90 90 90 ba 53 bb + 42 59 2f 90 77 90 90 4f bf 4a cb 86 62 7d 90 b8 + 90 34 90 5f 90 7f f8 80 a0 84 12 52 90 90 90 47 + 90 2b 88 f9 90 a3 83 90 75 87 90 ab eb 90 fe 90 + 90 af d0 2c d1 e6 90 43 a2 e7 85 e2 49 22 29 90 + 7c 90 90 9a 90 90 b9 90 14 cf 33 02 90 90 90 73 + 90 c5 90 90 90 f3 f6 24 90 56 d3 90 09 01 90 90 + 03 2d 1b 90 f5 be 90 90 fb 8e 21 8d 0b 90 90 b2 + fc fa c6 90 e8 d2 90 08 0a a8 78 ff 90 b5 90 90 + c7 06 18 90 90 1e 7e b0 0e 0f 90 90 0c aa 55 90 + 90 74 3d 90 90 38 27 50 90 b6 5e 8b 07 e5 39 ea + bd 90 81 b7 90 8a 0d 90 58 a1 a9 36 90 c4 90 8f + 8c 1f 51 04 f2 90 b3 b4 e9 2a 90 90 90 25 90 bc + + + + 05 08 00 00 + + + + + + + 00 00 00 F0 05 FF 00 01 00 0F 00 01 00 01 02 00 + 00 0e 75 0e 00 80 d3 00 + + + + diff --git a/Arcade_MiST/IremM92 Hardware/meta/Dream Soccer '94 (Japan, M92 hardware).mra b/Arcade_MiST/IremM92 Hardware/meta/Dream Soccer '94 (Japan, M92 hardware).mra new file mode 100644 index 00000000..64c266a8 --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/meta/Dream Soccer '94 (Japan, M92 hardware).mra @@ -0,0 +1,106 @@ + + Dream Soccer '94 (Japan, M92 hardware) + 0245 + dsoccr94 + dsoccr94j + 1994 + Irem + Sport + IremM92 + horizontal + + 8-way + 2 + + + + + + + + + + + + + + + + + + 86 + + + 00 10 00 00 + + + + + + + + + + + 01 40 00 00 + + + + + + + + + 06 40 00 00 + + + + + + + + + + + + + 03 02 00 00 + + + + + + + 04 00 01 00 + + 90 d1 90 90 90 79 2e 90 90 90 5a 0f 90 90 43 90 + 90 90 e8 50 90 90 90 a0 5d 22 90 90 b2 3a 90 90 + f6 8a 41 90 90 81 90 90 90 90 2b 58 90 90 90 c6 + 90 90 b9 90 90 2a 90 3c 90 80 26 90 b0 90 47 90 + 90 90 0a 55 90 90 90 88 90 90 87 90 90 b4 0c 90 + 73 53 90 90 3b 1f 90 90 90 90 90 90 90 90 90 90 + f7 90 90 90 90 1e 90 90 c3 90 a3 74 90 32 42 75 + fc 90 b8 90 33 90 5e 90 90 aa 90 90 04 90 9c ba + 90 90 24 89 90 90 ea 90 23 90 90 90 bb 90 90 c7 + 90 8e 90 52 90 18 90 72 90 90 90 90 b6 90 90 90 + fa 90 90 90 90 90 90 90 b1 90 90 90 90 57 78 a2 + 90 3d 51 90 90 bf 46 2c 90 90 fb 90 90 90 90 38 + 56 90 cf 90 08 90 90 90 5b 07 90 90 90 20 9d 90 + 03 90 90 90 90 90 bc 86 59 90 02 90 ff d2 8b 90 + 90 d0 90 90 90 90 90 e9 06 90 5f f3 90 b5 90 90 + eb 90 90 90 90 90 83 90 36 90 90 90 90 bd fe 90 + + + + 05 10 00 00 + + + + + + 00 00 00 F0 05 FF 00 01 00 0F 00 01 00 01 02 00 + 00 0e ad 6d 00 80 10 04 + + + + diff --git a/Arcade_MiST/IremM92 Hardware/meta/Gun Force II (US).mra b/Arcade_MiST/IremM92 Hardware/meta/Gun Force II (US).mra new file mode 100644 index 00000000..a8e70f2e --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/meta/Gun Force II (US).mra @@ -0,0 +1,99 @@ + + Gun Force II (US) + 0245 + gunforc2 + 1994 + Irem + Shooter + IremM92 + horizontal + + 8-way + 2 + + + + + + + + + + + + + + + + 06 + + + 00 10 00 00 + + + + + + + + + + + 01 20 00 00 + + + + + + + + + 02 40 00 00 + + + + + + + + + 03 02 00 00 + + + + + + + 04 00 01 00 + + 7f 26 5d 90 ba 90 1e 5e b8 49 bc e8 01 90 4a 25 + 90 bd 90 22 10 90 02 57 70 90 7c 90 e7 52 90 a9 + 90 90 c6 06 a0 fe cf 8e 43 8f 2d 8c d4 85 75 a2 + 3d 90 90 38 7e 89 d1 80 3b 72 07 90 42 37 0a 18 + 88 b4 98 8b b9 9c ad 0e 2b 90 bf 90 55 90 56 b0 + 93 91 90 eb 90 50 41 29 47 90 90 60 90 ab 90 90 + c3 e2 d0 b2 11 79 90 08 82 fb 90 2c 23 90 28 0d + 90 90 90 83 3c 90 1b 34 5b 90 40 90 90 04 fc cd + b1 f3 8a 90 90 87 90 90 90 90 90 90 be 84 1f e6 + ff 90 12 90 b5 36 90 b3 90 90 90 d2 4e 90 90 90 + a5 90 90 c7 90 27 0b 90 20 90 90 90 90 90 61 7d + 63 90 86 0f 90 b7 90 4f 13 90 c0 fd 90 39 90 77 + 05 3a 90 48 92 71 3e 03 90 f8 90 59 a8 5f f9 bb + 81 fa 9d e9 2e a1 c1 33 90 78 90 0c 90 24 aa ac + 90 b6 90 ea 90 73 e5 58 00 f7 90 74 90 76 90 a3 + 90 5a f6 32 46 2a 90 90 53 4b 90 35 51 68 99 13 + + + + 05 10 00 00 + + + + + + 00 00 00 0A 05 FF 00 01 00 0F 00 01 00 01 02 00 + 00 0e a5 ae 00 4b 00 a6 + + + + diff --git a/Arcade_MiST/IremM92 Hardware/meta/Gunforce - Battle Fire Engulfed Terror Island (World).mra b/Arcade_MiST/IremM92 Hardware/meta/Gunforce - Battle Fire Engulfed Terror Island (World).mra new file mode 100644 index 00000000..7c6fc192 --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/meta/Gunforce - Battle Fire Engulfed Terror Island (World).mra @@ -0,0 +1,101 @@ + + Gunforce - Battle Fire Engulfed Terror Island (World) + 0245 + gunforce + 1991 + Irem + Shooter + IremM92 + horizontal + + 2 + 8-way + 2 + + + + + + + + + + + + + + + + + 00 + + + 00 08 00 00 + + + + + + + + + + + 01 10 00 00 + + + + + + + + + 02 10 00 00 + + + + + + + + + 03 02 00 00 + + + + + + + 04 00 01 00 + + ff 90 90 2c 90 90 43 88 90 13 0a bd ba 60 ea 90 + 90 90 f2 29 b3 22 90 0c a9 5f 9d 07 90 90 0b bb + 8a 90 90 90 3a 3c 5a 38 99 90 f8 89 90 91 90 55 + ac 40 73 90 59 90 fc 90 50 fa 90 25 90 34 47 b7 + 90 90 90 49 90 0f 8b 05 c3 a5 bf 83 86 c5 90 90 + 08 77 24 b4 90 92 90 3b 5e b6 80 0d 2e ab e7 90 + 48 90 ad c0 90 1b c6 a3 04 90 90 90 16 b0 7d 98 + 87 46 8c 90 90 fe 90 cf 90 68 84 90 d2 90 18 51 + 76 a4 36 52 fb 90 b9 90 90 b1 1c 21 e6 b5 17 27 + 3d 45 be ae 90 4a 0e e5 90 58 1f 61 f3 02 90 e8 + 90 90 90 f7 56 96 aa bc 4f 90 90 79 d0 90 2a 12 + 4e b8 90 41 90 90 d3 90 2d 33 f6 90 90 14 90 32 + 5d a8 53 26 2b 20 81 75 7f 3e 90 90 00 93 90 b2 + 57 90 a0 90 39 90 90 72 90 01 42 74 9c 1e 90 5b + 90 f9 90 2f 85 90 eb a2 90 e2 11 90 4b 7e 90 78 + 90 90 09 a1 03 90 23 c1 8e e9 d1 7c 90 90 c7 06 + + + + 05 02 00 00 + + + + + + 00 00 00 F0 05 FF 00 01 00 0F 00 01 00 01 02 00 + 00 0e 66 33 00 40 44 20 + + + + diff --git a/Arcade_MiST/IremM92 Hardware/meta/Hook (World).mra b/Arcade_MiST/IremM92 Hardware/meta/Hook (World).mra new file mode 100644 index 00000000..2761b799 --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/meta/Hook (World).mra @@ -0,0 +1,102 @@ + + Hook (World) + 0245 + hook + 1992 + Irem + Brawler + IremM92 + horizontal + + 8-way + 2 + + + + + + + + + + + + + + + + + + + 00 + + + 00 0c 00 00 + + + + + + + + + + + 01 10 00 00 + + + + + + + + + 02 40 00 00 + + + + + + + + + 03 02 00 00 + + + + + + + 04 00 01 00 + + b6 20 22 90 0f 57 59 c6 eb 90 b0 bb 3b 90 90 90 + 36 90 90 90 90 90 90 90 90 fe 90 90 90 90 90 a0 + 2e 90 0b 90 90 58 90 90 90 90 90 90 90 80 90 90 + 33 90 90 bf 55 90 90 90 53 90 90 90 90 90 90 90 + 47 74 90 b1 b4 90 90 88 90 90 38 cf 90 8e 90 90 + 90 c7 90 32 90 52 3c 90 90 90 90 90 90 90 83 72 + 90 73 90 5a 90 43 90 90 90 90 41 e9 bd 90 b2 d2 + 90 aa a2 90 90 90 90 90 90 90 90 26 90 90 8a 90 + 90 90 90 90 90 90 90 18 90 9d 90 90 90 5d 90 46 + 90 90 90 f6 c3 a3 1e 07 5f 81 90 0c 90 b8 90 75 + 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 79 + 90 5e 90 90 06 90 ff 90 5b 24 90 2b 90 90 90 02 + 86 90 90 fb 90 90 50 fc 08 90 90 90 03 90 b9 90 + 90 bc e8 1f fa 42 90 90 89 90 23 87 90 2a 90 90 + 8b 90 f3 ea 04 2c b5 90 0a 90 51 90 90 3a 90 9c + 90 90 78 90 ba 90 90 90 90 90 90 90 d0 56 90 90 + + + + 05 08 00 00 + + + + + + 00 00 00 F0 05 FF 00 01 00 0F 00 01 00 01 02 00 + 00 0e a6 ad 00 ec 00 4f + + + + diff --git a/Arcade_MiST/IremM92 Hardware/meta/In The Hunt (World).mra b/Arcade_MiST/IremM92 Hardware/meta/In The Hunt (World).mra new file mode 100644 index 00000000..50370cab --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/meta/In The Hunt (World).mra @@ -0,0 +1,102 @@ + + In The Hunt (World) + 0245 + inthunt + 1993 + Irem + Shooter + IremM92 + horizontal + + 2 + 8-way + 2 + + + + + + + + + + + + + + + + + 00 + + + 00 0c 00 00 + + + + + + + + + + + 01 20 00 00 + + + + + + + + + 02 40 00 00 + + + + + + + + + 03 02 00 00 + + + + + + + 04 00 01 00 + + 1f 90 bb 50 90 58 42 57 90 90 e9 90 90 90 90 0b + 90 90 9d 9c 90 90 1e 90 90 b4 5b 90 90 90 90 90 + 90 90 78 c7 90 90 83 90 90 0c b0 04 90 90 90 90 + 90 90 90 90 3b c3 b5 47 90 90 90 90 59 90 90 90 + 90 90 90 38 90 90 90 90 5f a3 fa 90 e8 36 75 90 + 88 33 90 90 90 90 43 90 90 87 90 90 90 90 90 90 + 90 90 90 90 8e f3 56 90 90 90 90 26 ff 90 90 90 + 90 90 90 2a 90 8a 90 18 90 90 03 89 24 90 90 90 + 0a 90 eb 90 86 90 90 90 79 3a 90 90 90 90 a0 90 + ea 90 90 90 90 90 2c 90 c6 90 90 46 90 aa b6 5e + 90 90 90 90 8b 90 90 90 90 90 ba 90 b9 53 a2 90 + 90 07 90 90 90 3c 32 90 2b 90 b8 90 90 90 90 90 + bd 90 90 90 90 81 90 d0 08 90 55 06 cf 90 90 fc + 90 90 90 b1 bf 90 90 51 52 90 5d 90 5a 90 b2 90 + fe 90 90 22 20 72 f6 80 02 2e 90 74 0f 90 90 90 + 90 90 90 90 bc 41 90 fb 73 90 90 90 23 d2 90 90 + + + + 05 08 00 00 + + + + + + 00 00 00 F0 05 FF 00 01 00 0F 00 01 00 01 02 00 + 00 0e 01 80 00 d8 00 02 + + + + + diff --git a/Arcade_MiST/IremM92 Hardware/meta/Lethal Thunder (World).mra b/Arcade_MiST/IremM92 Hardware/meta/Lethal Thunder (World).mra new file mode 100644 index 00000000..f11507a9 --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/meta/Lethal Thunder (World).mra @@ -0,0 +1,101 @@ + + Lethal Thunder (World) + 0245 + lethalth + 1992 + Irem + Shooter + IremM92 + vertical + + 8-way + 2 + + + + + + + + + + + + + + + 01 + + + 10 + + + 00 08 00 00 + + + + + + + + + + + 01 10 00 00 + + + + + + + + + 02 10 00 00 + + + + + + + + + 03 02 00 00 + + + + + + + 04 00 01 00 + + 7f 26 5d 90 ba 90 1e 5e b8 49 bc e8 01 90 4a 25 + 90 bd 90 22 10 90 02 57 70 90 7c 90 e7 52 90 a9 + 90 90 c6 06 a0 fe cf 8e 43 8f 2d 8c d4 85 75 a2 + 3d 90 90 38 7e 89 d1 80 3b 72 07 90 42 37 0a 18 + 88 b4 98 8b b9 9c ad 0e 2b 90 bf 90 55 90 56 b0 + 93 91 90 eb 90 50 41 29 47 90 90 60 90 ab 90 90 + c3 e2 d0 b2 11 79 90 08 82 fb 90 2c 23 90 28 0d + 90 90 90 83 3c 90 1b 34 5b 90 40 90 90 04 fc cd + b1 f3 8a 90 90 87 90 90 90 90 90 90 be 84 1f e6 + ff 90 12 90 b5 36 90 b3 90 90 90 d2 4e 90 90 90 + a5 90 90 c7 90 27 0b 90 20 90 90 90 90 90 61 7d + 63 90 86 0f 90 b7 90 4f 13 90 c0 fd 90 39 90 77 + 05 3a 90 48 92 71 3e 03 90 f8 90 59 a8 5f f9 bb + 81 fa 9d e9 2e a1 c1 33 90 78 90 0c 90 24 aa ac + 90 b6 90 ea 90 73 e5 58 00 f7 90 74 90 76 90 a3 + 90 5a f6 32 46 2a 90 90 53 4b 90 35 51 68 99 13 + + + + 05 04 00 00 + + + + + + 00 00 00 F0 05 FF 00 01 00 0F 00 01 00 01 02 00 + 00 0e 00 86 00 b7 00 08 + + + + diff --git a/Arcade_MiST/IremM92 Hardware/meta/Major Title 2 (World, set 1).mra b/Arcade_MiST/IremM92 Hardware/meta/Major Title 2 (World, set 1).mra new file mode 100644 index 00000000..f8ef432d --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/meta/Major Title 2 (World, set 1).mra @@ -0,0 +1,101 @@ + + Major Title 2 (World, set 1) + 0245 + majtitl2 + 1992 + Irem + Sports + IremM92 + horizontal + + 4 + 8-way + 2 + + + + + + + + + + + + + + + + + + + 06 + + + 00 10 00 00 + + + + + + + + + + + 01 10 00 00 + + + + + + + + + 02 40 00 00 + + + + + + + + + 03 02 00 00 + + + + + + + 04 00 01 00 + + 87 90 78 aa 90 90 90 2c 32 0a 0f 90 5e 90 c6 8a + 33 90 90 90 90 ea 90 72 90 90 90 90 90 90 24 55 + 90 90 90 89 fb 90 59 02 90 90 5d 90 90 90 36 90 + 90 06 79 90 90 1e 07 90 90 90 83 90 90 90 90 90 + 9d 90 90 74 90 90 90 0c 58 90 90 90 90 90 90 90 + 3c 90 03 90 90 fa 43 90 bf 90 90 75 90 88 90 80 + 90 a3 90 fe 90 90 90 90 90 90 90 90 3a 90 90 90 + 2b 90 90 90 90 e9 5f 90 46 90 41 90 18 b8 90 90 + b4 5a b1 90 90 50 e8 20 90 b2 90 90 90 90 90 51 + 90 90 90 56 90 90 90 90 90 cf 90 90 90 c3 90 90 + 90 90 90 90 0b 90 90 b5 57 90 90 c7 3b 90 90 90 + 90 90 90 90 b6 90 eb 90 38 90 a0 08 90 86 b0 90 + 42 1f 73 90 f6 90 90 90 53 90 52 90 04 bd 90 90 + 26 ff 2e 90 81 90 47 90 90 90 90 d0 22 90 90 b9 + 23 90 f3 90 90 90 90 90 90 d2 8b ba 90 90 90 5b + 90 90 9c 90 90 90 90 fc bc a2 2a 90 90 8e bb 90 + + + + 05 08 00 00 + + + + 07 00 20 00 + + + + + diff --git a/Arcade_MiST/IremM92 Hardware/meta/Mystic Riders (World).mra b/Arcade_MiST/IremM92 Hardware/meta/Mystic Riders (World).mra new file mode 100644 index 00000000..14928ab2 --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/meta/Mystic Riders (World).mra @@ -0,0 +1,101 @@ + + Mystic Riders (World) + 0245 + mysticri + 1992 + Irem + Shooter + IremM92 + horizontal + + 8-way + 2 + + + + + + + + + + + + + + + + + 00 + + + 00 0a 00 00 + + + + + + + + + + + 01 10 00 00 + + + + + + + + + 02 20 00 00 + + + + + + + + + 03 02 00 00 + + + + + + + 04 00 01 00 + + 90 57 90 90 90 90 90 90 bf 43 90 90 b3 90 fc 90 + 90 90 90 90 90 52 a3 26 90 c7 90 0f 90 0c 90 90 + 90 90 ff 90 90 02 90 90 2e 90 5f 90 90 90 73 50 + b2 3a 90 90 bb 90 90 90 90 90 90 90 90 90 90 90 + 90 90 8e 3c 42 90 90 b9 90 90 2a 90 47 a0 2b 03 + b5 1f 90 aa 90 fb 90 90 90 90 90 90 38 90 90 90 + 2c 90 90 c6 90 90 b1 90 90 90 90 90 90 90 a2 90 + e9 e8 90 90 86 90 8b 90 90 90 90 90 5b 72 90 90 + 90 90 5d 0a 90 90 89 90 b0 88 90 b7 90 87 75 bd + 90 51 90 90 90 90 90 be 90 90 90 5a 58 90 90 56 + 90 8a 90 55 90 90 90 b4 08 90 f6 90 90 9d 90 bc + 0b 00 90 5e 90 90 90 22 36 4b 1e 90 b6 ba 23 90 + 20 90 90 90 59 53 90 04 81 90 90 f3 90 90 3b 06 + e2 79 83 9c 90 18 80 90 c3 90 90 90 32 90 cf 90 + eb 90 90 33 90 fa 90 90 d2 90 24 90 74 41 b8 90 + 34 90 d0 07 f8 90 90 90 90 46 90 ea fe 78 90 90 + + + + 05 04 00 00 + + + + + + 00 00 00 0F 05 FF 00 01 00 0F 00 01 00 01 02 00 + 00 0e 8a f8 00 38 00 4d + 00 0e 8b 30 00 94 2e 00 + + + + diff --git a/Arcade_MiST/IremM92 Hardware/meta/Ninja Baseball Bat Man (World).mra b/Arcade_MiST/IremM92 Hardware/meta/Ninja Baseball Bat Man (World).mra new file mode 100644 index 00000000..e1f95fe5 --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/meta/Ninja Baseball Bat Man (World).mra @@ -0,0 +1,103 @@ + + Ninja Baseball Bat Man (World) + 0245 + nbbatman + 1993 + Irem + Fighter + IremM92 + horizontal + + 4 + 8-way + 2 + + + + + + + + + + + + + + + + + + + 06 + + + 00 10 00 00 + + + + + + + + + + + 01 20 00 00 + + + + + + + + + 02 40 00 00 + + + + + + + + + 03 02 00 00 + + + + + + + 04 00 01 00 + + 90 90 90 55 bb 90 23 79 90 90 90 90 90 90 38 90 + f7 90 90 90 90 90 90 90 3d 90 90 90 ba 90 1e 90 + 2c 46 90 b5 90 4b 90 fe 90 90 fb 2e 90 90 36 04 + cf 90 f3 5a 8a 0c 9c 90 90 90 b2 50 90 90 90 5f + 90 90 24 90 90 41 2b 90 e9 90 08 3b 90 90 90 90 + 90 d2 51 90 90 90 22 90 eb 3a 5b a2 b1 80 90 90 + 90 90 90 90 59 b4 88 90 90 bf d1 90 b9 57 90 90 + 72 90 73 90 90 90 90 0f 90 90 90 90 56 90 90 c6 + 90 90 90 90 90 2a 8e 90 81 a3 58 90 aa 78 89 90 + 90 90 90 90 90 90 bd 90 90 90 ff 90 90 90 07 53 + a0 90 90 5e b0 90 83 f6 90 26 32 90 90 90 74 0a + 18 90 90 90 75 03 90 90 b6 02 90 90 43 90 b8 90 + e8 90 fc 90 20 c3 90 06 90 1f 86 00 90 90 90 d0 + 47 90 87 90 90 9d 3c c7 90 90 90 90 90 90 90 90 + 90 90 90 8b 90 90 33 90 90 90 90 90 fa 42 90 90 + 90 90 90 ea 90 52 90 5d 90 90 90 90 bc 90 90 90 + + + + 05 08 00 00 + + + + + + 00 00 00 0F 05 FF 00 01 00 0F 00 01 00 01 02 00 + 00 0e 25 d4 00 4f 00 03 + + + + diff --git a/Arcade_MiST/IremM92 Hardware/meta/R-Type Leo (World).mra b/Arcade_MiST/IremM92 Hardware/meta/R-Type Leo (World).mra new file mode 100644 index 00000000..5d72073f --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/meta/R-Type Leo (World).mra @@ -0,0 +1,101 @@ + + R-Type Leo (World) + 0245 + rtypeleo + 1992 + Irem + Shooter + IremM92 + horizontal + + 2 + 8-way + 2 + + + + + + + + + + + + + + + + 00 + + + 00 0c 00 00 + + + + + + + + + + + 01 20 00 00 + + + + + + + + + 02 40 00 00 + + + + + + + + + 03 02 00 00 + + + + + + + 04 00 01 00 + + 5d 90 c6 90 90 90 2a 3a 90 90 90 86 90 22 90 f3 + 90 90 90 90 90 38 f7 42 04 90 90 1f 4b 90 90 58 + 57 2e 90 90 53 90 b9 90 90 90 90 90 20 55 90 3d + a0 90 90 0c 03 90 83 90 90 90 8a 00 90 aa 90 90 + 90 90 90 90 90 90 90 90 90 41 0a 26 8b 56 5e 90 + 90 74 90 90 90 90 06 90 90 89 5b c7 43 90 90 90 + 90 b6 90 3b 90 90 90 90 90 36 ea 80 90 90 90 5f + 90 0f 90 90 90 46 90 90 3c 8e 90 a3 87 90 90 90 + 2b fb 47 0b 90 fc 02 90 90 90 90 90 90 90 72 2c + 33 90 90 90 90 90 9d bd 90 b2 90 78 75 b8 90 90 + 90 90 90 90 cf 5a 88 90 90 90 c3 90 eb fa 90 32 + 90 90 90 52 b4 90 90 90 90 bc 90 90 90 b1 59 50 + 90 90 b5 90 08 a2 bf bb 1e 9c 90 73 90 d0 90 90 + 90 90 90 90 81 90 79 90 90 24 23 90 90 b0 07 ff + 90 ba f6 51 90 90 90 fe 90 92 90 90 90 90 e9 90 + 90 90 90 90 90 90 e8 d2 90 18 90 90 90 d1 90 90 + + + + 05 08 00 00 + + + + + + 00 00 00 F0 05 FF 00 01 00 0F 00 01 00 01 02 00 + 00 0e 22 1e 00 38 40 20 + 00 0e 22 56 00 03 40 01 + + + + diff --git a/Arcade_MiST/IremM92 Hardware/meta/Superior Soldiers (US).mra b/Arcade_MiST/IremM92 Hardware/meta/Superior Soldiers (US).mra new file mode 100644 index 00000000..f1bbfc4c --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/meta/Superior Soldiers (US).mra @@ -0,0 +1,101 @@ + + Superior Soldiers (US) + 0245 + ssoldier + 1993 + Irem + Fighter + IremM92 + horizontal + + 8-way + 6 + + + + + + + + + + + + + + 40 + + + 00 0c 00 00 + + + + + + + + + + + 01 10 00 00 + + + + + + + + + 06 80 00 00 + + + + + + + + + + + + + 03 02 00 00 + + + + + + + 04 00 01 00 + + 90 90 90 8a 90 aa 90 90 90 20 23 55 90 b5 0a 90 + 90 46 90 b6 90 74 8b 90 90 ba f7 90 90 5a 86 fb + b2 90 b0 90 42 06 1e 08 22 9d 90 90 90 90 90 73 + 90 90 5f 90 90 d0 90 ff 90 90 bd 90 03 90 b9 90 + 90 90 90 51 5e 24 90 90 90 90 90 58 59 90 90 90 + 52 90 90 90 a0 90 90 02 d2 90 79 26 3a 0f cf b4 + f3 90 90 50 90 75 b1 90 d1 47 90 90 90 90 90 90 + c6 90 90 90 90 90 bc 90 90 90 90 90 53 41 90 90 + 90 90 90 90 90 90 04 90 90 90 90 2c 90 bf 90 90 + 90 90 e8 90 90 78 90 bb 90 90 1f 2b 87 90 4b 56 + 36 33 90 90 90 9c c3 90 90 81 90 e9 90 fa 90 90 + 90 72 90 a2 90 90 c7 90 90 92 90 90 88 90 90 90 + 3b 90 0c 90 80 90 90 90 90 2e 90 90 90 57 90 8e + 07 90 a3 90 90 90 3d 90 fe 90 90 fc ea 90 38 90 + 3c f6 90 90 90 18 90 90 b8 90 90 90 2a 5d 5b 90 + 90 43 32 90 90 90 eb 90 90 90 90 90 83 89 90 90 + + + + 05 08 00 00 + + + + + + 00 00 0F 00 05 FF 00 01 00 0F 00 01 00 01 02 00 + 00 0e 1b 0f 00 31 10 31 + + + + diff --git a/Arcade_MiST/IremM92 Hardware/meta/Undercover Cops (World).mra b/Arcade_MiST/IremM92 Hardware/meta/Undercover Cops (World).mra new file mode 100644 index 00000000..d62c6dbb --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/meta/Undercover Cops (World).mra @@ -0,0 +1,103 @@ + + Undercover Cops (World) + 0245 + uccops + 1992 + Irem + Fighter + IremM92 + horizontal + + 3 + 8-way + 2 + + + + + + + + + + + + + + + + + + + 00 + + + 00 0c 00 00 + + + + + + + + + + + 01 20 00 00 + + + + + + + + + 02 40 00 00 + + + + + + + + + 03 02 00 00 + + + + + + + 04 00 01 00 + + 1f 51 84 90 3d 09 0d 90 90 57 90 90 90 32 11 90 + 90 9c 90 90 4b 90 90 03 90 90 90 89 b0 90 90 90 + 90 bb 18 be 53 21 55 7c 90 90 47 58 f6 90 90 b2 + 06 90 2b 90 2f 0b fc 91 90 90 fa 81 83 40 38 90 + 90 90 49 85 d1 f5 07 e2 5e 1e 90 04 90 90 90 b1 + c7 90 96 f2 b6 d2 c3 90 87 ba cb 88 90 b9 d0 b5 + 9a 80 a2 72 90 b4 90 aa 26 7d 52 33 2e bc 08 79 + 48 90 76 36 02 90 5b 12 8b e7 90 90 90 ab 90 4f + 90 90 a8 e5 39 0e a9 90 90 14 90 ff 7f 90 90 27 + 90 01 90 90 e6 8a d3 90 90 8e 56 a5 92 90 90 f9 + 22 90 5f 90 90 a1 90 74 b8 90 46 05 eb cf bf 5d + 24 90 9d 90 90 90 90 90 59 8d 3c f8 c5 90 f3 4e + 90 90 50 c6 e9 fe 0a 90 99 86 90 90 af 8c 42 f7 + 90 41 90 a3 90 3a 2a 43 90 b3 e8 90 c4 35 78 25 + 75 90 b7 90 23 90 90 8f 90 90 2c 90 77 7e 90 0f + 0c a0 bd 90 90 2d 29 ea 90 3b 73 90 fb 20 90 5a + + + + 05 08 00 00 + + + + + + 00 00 00 0F 05 FF 00 01 00 0F 00 01 00 01 02 00 + 00 0e 3e 9a 00 49 30 01 + + + + diff --git a/Arcade_MiST/IremM92 Hardware/rtl/IremM92_MiST.sv b/Arcade_MiST/IremM92 Hardware/rtl/IremM92_MiST.sv new file mode 100644 index 00000000..1ea737f1 --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/rtl/IremM92_MiST.sv @@ -0,0 +1,492 @@ +import m92_pkg::*; + +module IremM92_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, + inout SPI_DO, + input SPI_DI, + input SPI_SS2, + input SPI_SS3, + input SPI_SS4, + input CONF_DATA0, + input CLOCK_27, + + output [12:0] SDRAM_A, + inout [15:0] SDRAM_DQ, + output SDRAM_DQML, + output SDRAM_DQMH, + output SDRAM_nWE, + output SDRAM_nCAS, + output SDRAM_nRAS, + output SDRAM_nCS, + output [1:0] SDRAM_BA, + output SDRAM_CLK, + output SDRAM_CKE +); + +`include "build_id.v" +//`define DEBUG 1 +`define CORE_NAME "BMASTER" + +wire [6:0] core_mod; + +localparam CONF_STR = { + `CORE_NAME,";;", + "O3,Rotate Controls,Off,On;", + "O45,Scanlines,Off,25%,50%,75%;", + "O6,Swap Joystick,Off,On;", + //"O7,Blending,Off,On;", + "O8,Pause,Off,On;", +`ifdef DEBUG + "O9,Layer A,On,Off;", + "OA,Layer B,On,Off;", + "OB,Layer C,On,Off;", + "OC,FM Enable,On,Off;", +`endif + //"OD,Audio Filters,On,Off;", + "DIP;", + "R8192,Save EEPROM;", + "T0,Reset;", + "V,v1.0.",`BUILD_DATE +}; + +wire rotate = status[3]; +wire [1:0] scanlines = status[5:4]; +wire joyswap = status[6]; +wire blend = 0;//status[7]; +wire system_pause = status[8]; +wire [2:0] dbg_en_layers = ~status[11:9]; +wire dbg_fm_en = ~status[12]; +wire dbg_sprite_freeze = 0; +wire filters = 0;//~status[13]; +wire [1:0] orientation = {1'b0, core_mod[0]}; +reg oneplayer = 0; +wire [15:0] dip_sw = status[31:16]; + +assign LED = ~ioctl_downl; +assign SDRAM_CKE = 1; + +wire CLK_120M, CLK_40M; +wire pll_locked; +pll_mist pll( + .inclk0(CLOCK_27), + .c0(SDRAM_CLK), + .c1(CLK_120M), + .c2(CLK_40M), + .locked(pll_locked) + ); + +wire [31:0] status; +wire [1:0] buttons; +wire [1:0] switches; +wire [15:0] joystick_0; +wire [15:0] joystick_1; +wire [15:0] joystick_2; +wire [15:0] joystick_3; +wire scandoublerD; +wire ypbpr; +wire no_csync; +wire key_pressed; +wire [7:0] key_code; +wire key_strobe; + +wire [9:0] conf_str_addr; +wire [7:0] conf_str_char; + +always @(posedge CLK_40M) + conf_str_char <= CONF_STR[(($size(CONF_STR)>>3) - conf_str_addr - 1)<<3 +:8]; + +user_io #( + //.STRLEN(($size(CONF_STR)>>3)), + .ROM_DIRECT_UPLOAD(1'b1)) +user_io( + .clk_sys (CLK_40M ), + .conf_str (CONF_STR ), + .SPI_CLK (SPI_SCK ), + .SPI_SS_IO (CONF_DATA0 ), + .SPI_MISO (SPI_DO ), + .SPI_MOSI (SPI_DI ), + .conf_addr (conf_str_addr ), + .conf_chr (conf_str_char ), + .buttons (buttons ), + .switches (switches ), + .scandoubler_disable (scandoublerD ), + .ypbpr (ypbpr ), + .no_csync (no_csync ), + .core_mod (core_mod ), + .key_strobe (key_strobe ), + .key_pressed (key_pressed ), + .key_code (key_code ), + .joystick_0 (joystick_0 ), + .joystick_1 (joystick_1 ), + .joystick_2 (joystick_2 ), + .joystick_3 (joystick_3 ), + .status (status ) + ); + +wire ioctl_downl; +wire ioctl_upl; +wire [7:0] ioctl_index; +wire ioctl_wr; +wire [24:0] ioctl_addr; +wire [7:0] ioctl_dout; +wire [7:0] ioctl_din; + +data_io #(.ROM_DIRECT_UPLOAD(1'b1)) data_io( + .clk_sys ( CLK_40M ), + .SPI_SCK ( SPI_SCK ), + .SPI_SS2 ( SPI_SS2 ), + .SPI_SS4 ( SPI_SS4 ), + .SPI_DI ( SPI_DI ), + .SPI_DO ( SPI_DO ), + .clkref_n ( 1'b0 ), + .ioctl_download( ioctl_downl ), + .ioctl_upload ( ioctl_upl ), + .ioctl_index ( ioctl_index ), + .ioctl_wr ( ioctl_wr ), + .ioctl_addr ( ioctl_addr ), + .ioctl_dout ( ioctl_dout ), + .ioctl_din ( ioctl_din ) +); + +// reset signal generation +reg reset = 1; +reg rom_loaded = 0; +always @(posedge CLK_40M) begin + reg ioctl_downlD; + ioctl_downlD <= ioctl_downl; + + reset <= 0; + if (status[0] | buttons[1] | ~rom_loaded) reset <= 1; + + if (ioctl_downlD & ~ioctl_downl) rom_loaded <= 1; +end + +wire sdr_vram_req; +wire [24:0] sdr_vram_addr; +wire [31:0] sdr_vram_data; + +wire [63:0] sdr_sprite_dout; +wire [24:0] sdr_sprite_addr; +wire sdr_sprite_req, sdr_sprite_ack; + +wire [31:0] sdr_bg_data_a; +wire [24:0] sdr_bg_addr_a; +wire sdr_bg_req_a, sdr_bg_ack_a; + +wire [31:0] sdr_bg_data_b; +wire [24:0] sdr_bg_addr_b; +wire sdr_bg_req_b, sdr_bg_ack_b; + +wire [31:0] sdr_bg_data_c; +wire [24:0] sdr_bg_addr_c; +wire sdr_bg_req_c, sdr_bg_ack_c; + +wire [15:0] sdr_cpu_dout, sdr_cpu_din; +wire [24:0] sdr_cpu_addr; +wire sdr_cpu_req, sdr_cpu_ack; +wire [1:0] sdr_cpu_wr_sel; + +wire [15:0] sdr_audio_cpu_dout, sdr_audio_cpu_din; +wire [24:0] sdr_audio_cpu_addr; +wire sdr_audio_cpu_req, sdr_audio_cpu_ack; +wire [1:0] sdr_audio_cpu_wr_sel; + +wire [24:0] sdr_rom_addr; +wire [15:0] sdr_rom_data; +wire [1:0] sdr_rom_be; +wire sdr_rom_req; +wire sdr_rom_ack; + +wire [24:0] sample_rom_addr; +wire [63:0] sample_rom_dout; +wire sample_rom_req; +wire sample_rom_ack; + +wire sdr_rom_write = ioctl_downl && (ioctl_index == 0); + +wire [19:0] bram_addr; +wire [7:0] bram_data; +wire [3:0] bram_cs; +wire bram_wr; + +board_cfg_t board_cfg; +sdram_4w_cl3 #(120) sdram +( + .*, + .init_n ( pll_locked ), + .clk ( CLK_120M ), + + // Bank 0-1 ops + .port1_a ( sdr_rom_addr[24:1] ), + .port1_req ( sdr_rom_req ), + .port1_ack ( sdr_rom_ack ), + .port1_we ( sdr_rom_write ), + .port1_ds ( sdr_rom_be ), + .port1_d ( sdr_rom_data ), + .port1_q ( sdr_rom_ack ), + + // Main CPU + .cpu1_rom_addr ( ), + .cpu1_rom_cs ( ), + .cpu1_rom_q ( ), + .cpu1_rom_valid( ), + + .cpu1_ram_req ( sdr_cpu_req ), + .cpu1_ram_ack ( sdr_cpu_ack ), + .cpu1_ram_addr ( sdr_cpu_addr[24:1] ), + .cpu1_ram_we ( |sdr_cpu_wr_sel ), + .cpu1_ram_d ( sdr_cpu_din ), + .cpu1_ram_q ( sdr_cpu_dout ), + .cpu1_ram_ds ( |sdr_cpu_wr_sel ? sdr_cpu_wr_sel : 2'b11 ), + + // Audio CPU + .cpu2_ram_req ( sdr_audio_cpu_req ), + .cpu2_ram_ack ( sdr_audio_cpu_ack ), + .cpu2_ram_addr ( sdr_audio_cpu_addr[24:1] ), + .cpu2_ram_we ( |sdr_audio_cpu_wr_sel ), + .cpu2_ram_d ( sdr_audio_cpu_din ), + .cpu2_ram_q ( sdr_audio_cpu_dout ), + .cpu2_ram_ds ( |sdr_audio_cpu_wr_sel ? sdr_audio_cpu_wr_sel : 2'b11 ), + + // VRAM + .vram_addr ( sdr_vram_addr[24:1] ), + .vram_req ( sdr_vram_req ), + .vram_q ( sdr_vram_data ), + .vram_ack ( ), + + // Bank 2-3 ops + .port2_a ( sdr_rom_addr[24:1] ), + .port2_req ( sdr_rom_req ), + .port2_ack ( sdr_rom_ack ), + .port2_we ( sdr_rom_write ), + .port2_ds ( sdr_rom_be ), + .port2_d ( sdr_rom_data ), + .port2_q ( sdr_rom_ack ), + + .gfx1_req ( sdr_bg_req_a ), + .gfx1_ack ( sdr_bg_ack_a ), + .gfx1_addr ( sdr_bg_addr_a[24:1] ), + .gfx1_q ( sdr_bg_data_a ), + + .gfx2_req ( sdr_bg_req_b ), + .gfx2_ack ( sdr_bg_ack_b ), + .gfx2_addr ( sdr_bg_addr_b[24:1] ), + .gfx2_q ( sdr_bg_data_b ), + + .gfx3_req ( sdr_bg_req_c ), + .gfx3_ack ( sdr_bg_ack_c ), + .gfx3_addr ( sdr_bg_addr_c[24:1] ), + .gfx3_q ( sdr_bg_data_c ), + + .sample_addr ( {sample_rom_addr[24:3], 2'b00} ), + .sample_q ( sample_rom_dout ), + .sample_req ( sample_rom_req ), + .sample_ack ( sample_rom_ack ), + + .sp_addr ( sdr_sprite_addr[24:1] ), + .sp_req ( sdr_sprite_req ), + .sp_ack ( sdr_sprite_ack ), + .sp_q ( sdr_sprite_dout ) +); + +rom_loader rom_loader( + .sys_clk(CLK_40M), + + .ioctl_downl(ioctl_downl), + .ioctl_wr(ioctl_wr && !ioctl_index), + .ioctl_data(ioctl_dout[7:0]), + + .ioctl_wait(), + + .sdr_addr(sdr_rom_addr), + .sdr_data(sdr_rom_data), + .sdr_be(sdr_rom_be), + .sdr_req(sdr_rom_req), + .sdr_ack(sdr_rom_ack), + + .bram_addr(bram_addr), + .bram_data(bram_data), + .bram_cs(bram_cs), + .bram_wr(bram_wr), + + .board_cfg(board_cfg) +); + +wire [15:0] ch_left, ch_right; +wire [7:0] R, G, B; +wire HBlank, VBlank, HSync, VSync; +wire blankn = !(HBlank | VBlank); +wire ce_pix; + + +m92 m92( + .clk_sys(CLK_40M), + .ce_pix(ce_pix), + .reset_n(~reset), + .HBlank(HBlank), + .VBlank(VBlank), + .HSync(HSync), + .VSync(VSync), + .R(R), + .G(G), + .B(B), + .AUDIO_L(ch_left), + .AUDIO_R(ch_right), + + .board_cfg(board_cfg), + + .coin({2'd0, m_coin2, m_coin1}), + + .start_buttons({m_four_players, m_three_players, m_two_players, m_one_player}), + + .p1_input({m_fire1[5:0], m_up1, m_down1, m_left1, m_right1}), + .p2_input({m_fire2[5:0], m_up2, m_down2, m_left2, m_right2}), + .p3_input({m_fire3[5:0], m_up3, m_down3, m_left3, m_right3}), + .p4_input({m_fire4[5:0], m_up4, m_down4, m_left4, m_right4}), + + .dip_sw(dip_sw), + + .sdr_sprite_addr(sdr_sprite_addr), + .sdr_sprite_dout(sdr_sprite_dout), + .sdr_sprite_req(sdr_sprite_req), + .sdr_sprite_ack(sdr_sprite_ack), + + .sdr_bg_data_a(sdr_bg_data_a), + .sdr_bg_addr_a(sdr_bg_addr_a), + .sdr_bg_req_a(sdr_bg_req_a), + .sdr_bg_ack_a(sdr_bg_ack_a), + + .sdr_bg_data_b(sdr_bg_data_b), + .sdr_bg_addr_b(sdr_bg_addr_b), + .sdr_bg_req_b(sdr_bg_req_b), + .sdr_bg_ack_b(sdr_bg_ack_b), + + .sdr_bg_data_c(sdr_bg_data_c), + .sdr_bg_addr_c(sdr_bg_addr_c), + .sdr_bg_req_c(sdr_bg_req_c), + .sdr_bg_ack_c(sdr_bg_ack_c), + + .sdr_cpu_dout(sdr_cpu_dout), + .sdr_cpu_din(sdr_cpu_din), + .sdr_cpu_addr(sdr_cpu_addr), + .sdr_cpu_req(sdr_cpu_req), + .sdr_cpu_ack(sdr_cpu_ack), + .sdr_cpu_wr_sel(sdr_cpu_wr_sel), + .sdr_vram_req(sdr_vram_req), + .sdr_vram_addr(sdr_vram_addr), + .sdr_vram_data(sdr_vram_data), + + .sdr_audio_cpu_dout(sdr_audio_cpu_dout), + .sdr_audio_cpu_din(sdr_audio_cpu_din), + .sdr_audio_cpu_addr(sdr_audio_cpu_addr), + .sdr_audio_cpu_req(sdr_audio_cpu_req), + .sdr_audio_cpu_ack(sdr_audio_cpu_ack), + .sdr_audio_cpu_wr_sel(sdr_audio_cpu_wr_sel), + + .sdr_audio_addr(sample_rom_addr), + .sdr_audio_dout(sample_rom_dout), + .sdr_audio_req(sample_rom_req), + .sdr_audio_ack(sample_rom_ack), + + .clk_bram(CLK_40M), + .bram_addr(bram_addr), + .bram_data(bram_data), + .bram_cs(bram_cs), + .bram_wr(bram_wr), + + .ioctl_download(ioctl_downl && ioctl_index == 8'hFF), + .ioctl_wr(ioctl_wr), + .ioctl_addr(ioctl_addr), + .ioctl_dout(ioctl_dout), + .ioctl_upload(ioctl_upl && ioctl_index == 8'hFF), + .ioctl_din(ioctl_din), +`ifdef M72_DEBUG + .pause_rq(system_pause | debug_stall), +`else + .pause_rq(system_pause), +`endif + .dbg_en_layers(dbg_en_layers), + .dbg_solid_sprites(), + .sprite_freeze(dbg_sprite_freeze), + .dbg_fm_en(dbg_fm_en), + .en_audio_filters(filters) +); + +mist_video #(.COLOR_DEPTH(6), .SD_HCNT_WIDTH(10)) mist_video( + .clk_sys ( CLK_40M ), + .SPI_SCK ( SPI_SCK ), + .SPI_SS3 ( SPI_SS3 ), + .SPI_DI ( SPI_DI ), + .R ( blankn ? R[7:2] : 0 ), + .G ( blankn ? G[7:2] : 0 ), + .B ( blankn ? B[7:2] : 0 ), + .HSync ( HSync ), + .VSync ( VSync ), + .VGA_R ( VGA_R ), + .VGA_G ( VGA_G ), + .VGA_B ( VGA_B ), + .VGA_VS ( VGA_VS ), + .VGA_HS ( VGA_HS ), + .rotate ( { orientation[1], rotate } ), + .ce_divider ( 3'd2 ), + .scandoubler_disable( scandoublerD ), + .scanlines ( scanlines ), + .blend ( blend ), + .ypbpr ( ypbpr ), + .no_csync ( no_csync ) + ); + +dac #( + .C_bits(16)) +dacl( + .clk_i(CLK_40M), + .res_n_i(1), + .dac_i({~ch_left[15], ch_left[14:0]}), + .dac_o(AUDIO_L) + ); + +dac #( + .C_bits(16)) +dacr( + .clk_i(CLK_40M), + .res_n_i(1), + .dac_i({~ch_right[15], ch_right[14:0]}), + .dac_o(AUDIO_R) + ); + +wire m_up1, m_down1, m_left1, m_right1, m_up1B, m_down1B, m_left1B, m_right1B; +wire m_up2, m_down2, m_left2, m_right2, m_up2B, m_down2B, m_left2B, m_right2B; +wire m_up3, m_down3, m_left3, m_right3, m_up3B, m_down3B, m_left3B, m_right3B; +wire m_up4, m_down4, m_left4, m_right4, m_up4B, m_down4B, m_left4B, m_right4B; +wire m_tilt, m_coin1, m_coin2, m_coin3, m_coin4, m_one_player, m_two_players, m_three_players, m_four_players; +wire [11:0] m_fire1, m_fire2, m_fire3, m_fire4; + +arcade_inputs inputs ( + .clk ( CLK_40M ), + .key_strobe ( key_strobe ), + .key_pressed ( key_pressed ), + .key_code ( key_code ), + .joystick_0 ( joystick_0 ), + .joystick_1 ( joystick_1 ), + .joystick_2 ( joystick_2 ), + .joystick_3 ( joystick_3 ), + .rotate ( rotate ), + .orientation ( orientation ), + .joyswap ( joyswap ), + .oneplayer ( oneplayer ), + .controls ( {m_tilt, m_coin4, m_coin3, m_coin2, m_coin1, m_four_players, m_three_players, m_two_players, m_one_player} ), + .player1 ( {m_up1B, m_down1B, m_left1B, m_right1B, m_fire1, m_up1, m_down1, m_left1, m_right1} ), + .player2 ( {m_up2B, m_down2B, m_left2B, m_right2B, m_fire2, m_up2, m_down2, m_left2, m_right2} ), + .player3 ( {m_up3B, m_down3B, m_left3B, m_right3B, m_fire3, m_up3, m_down3, m_left3, m_right3} ), + .player4 ( {m_up4B, m_down4B, m_left4B, m_right4B, m_fire4, m_up4, m_down4, m_left4, m_right4} ) +); + +endmodule diff --git a/Arcade_MiST/IremM92 Hardware/rtl/build_id.tcl b/Arcade_MiST/IremM92 Hardware/rtl/build_id.tcl new file mode 100644 index 00000000..73404976 --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/rtl/build_id.tcl @@ -0,0 +1,35 @@ +# ================================================================================ +# +# Build ID Verilog Module Script +# Jeff Wiencrot - 8/1/2011 +# +# Generates a Verilog module that contains a timestamp, +# from the current build. These values are available from the build_date, build_time, +# physical_address, and host_name output ports of the build_id module in the build_id.v +# Verilog source file. +# +# ================================================================================ + +proc generateBuildID_Verilog {} { + + # Get the timestamp (see: http://www.altera.com/support/examples/tcl/tcl-date-time-stamp.html) + set buildDate [ clock format [ clock seconds ] -format %y%m%d ] + set buildTime [ clock format [ clock seconds ] -format %H%M%S ] + + # Create a Verilog file for output + set outputFileName "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/IremM92 Hardware/rtl/dpramv.sv b/Arcade_MiST/IremM92 Hardware/rtl/dpramv.sv new file mode 100644 index 00000000..1dd3d2fc --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/rtl/dpramv.sv @@ -0,0 +1,175 @@ +//============================================================================ +// Copyright (C) 2023 Martin Donlon +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +//============================================================================ + +`timescale 1ns / 1ps + +module dualport_ram #( + parameter width = 8, + parameter widthad = 10 +) ( + // Port A + input wire clock_a, + input wire wren_a, + input wire [widthad-1:0] address_a, + input wire [width-1:0] data_a, + output reg [width-1:0] q_a, + + // Port B + input wire clock_b, + input wire wren_b, + input wire [widthad-1:0] address_b, + input wire [width-1:0] data_b, + output reg [width-1:0] q_b +); + +// Shared ramory +reg [width-1:0] ram[(2**widthad)-1:0]; + +// Port A +always @(posedge clock_a) begin + if (wren_a) begin + ram[address_a] <= data_a; + q_a <= data_a; + end else begin + q_a <= ram[address_a]; + end +end + +// Port B +always @(posedge clock_b) begin + if(wren_b) begin + q_b <= data_b; + ram[address_b] <= data_b; + end else begin + q_b <= ram[address_b]; + end +end + +endmodule + +module singleport_ram #( + parameter width = 8, + parameter widthad = 10, + parameter name = "NONE" +) ( + input wire clock, + input wire wren, + input wire [widthad-1:0] address, + input wire [width-1:0] data, + output reg [width-1:0] q + +); + +altsyncram altsyncram_component ( + .address_a (address), + .clock0 (clock), + .data_a (data), + .wren_a (wren), + .q_a (q), + .aclr0 (1'b0), + .aclr1 (1'b0), + .address_b (1'b1), + .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 (1'b1), + .eccstatus (), + .q_b (), + .rden_a (1'b1), + .rden_b (1'b1), + .wren_b (1'b0)); +defparam + altsyncram_component.clock_enable_input_a = "BYPASS", + altsyncram_component.clock_enable_output_a = "BYPASS", + altsyncram_component.intended_device_family = "Cyclone V", + altsyncram_component.lpm_hint = "ENABLE_RUNTIME_MOD=NO", + altsyncram_component.lpm_type = "altsyncram", + altsyncram_component.numwords_a = 2**widthad, + altsyncram_component.operation_mode = "SINGLE_PORT", + altsyncram_component.outdata_aclr_a = "NONE", + altsyncram_component.outdata_reg_a = "CLOCK0", + altsyncram_component.power_up_uninitialized = "FALSE", + altsyncram_component.ram_block_type = "M10K", + altsyncram_component.read_during_write_mode_port_a = "DONT_CARE", + altsyncram_component.widthad_a = widthad, + altsyncram_component.width_a = width, + altsyncram_component.width_byteena_a = 1; + + +endmodule + +module singleport_unreg_ram #( + parameter width = 8, + parameter widthad = 10, + parameter name = "NONE" +) ( + input wire clock, + input wire wren, + input wire [widthad-1:0] address, + input wire [width-1:0] data, + output wire [width-1:0] q +); + +altsyncram altsyncram_component ( + .address_a (address), + .clock0 (clock), + .data_a (data), + .wren_a (wren), + .q_a (q), + .aclr0 (1'b0), + .aclr1 (1'b0), + .address_b (1'b1), + .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 (1'b1), + .eccstatus (), + .q_b (), + .rden_a (1'b1), + .rden_b (1'b1), + .wren_b (1'b0)); +defparam + altsyncram_component.clock_enable_input_a = "BYPASS", + altsyncram_component.clock_enable_output_a = "BYPASS", + altsyncram_component.intended_device_family = "Cyclone V", + altsyncram_component.lpm_hint = "ENABLE_RUNTIME_MOD=NO", + altsyncram_component.lpm_type = "altsyncram", + altsyncram_component.numwords_a = 2**widthad, + altsyncram_component.operation_mode = "SINGLE_PORT", + altsyncram_component.outdata_aclr_a = "NONE", + altsyncram_component.outdata_reg_a = "UNREGISTERED", + altsyncram_component.power_up_uninitialized = "FALSE", + altsyncram_component.ram_block_type = "M10K", + altsyncram_component.read_during_write_mode_port_a = "DONT_CARE", + altsyncram_component.widthad_a = widthad, + altsyncram_component.width_a = width, + altsyncram_component.width_byteena_a = 1; + +endmodule \ No newline at end of file diff --git a/Arcade_MiST/IremM92 Hardware/rtl/eeprom.sv b/Arcade_MiST/IremM92 Hardware/rtl/eeprom.sv new file mode 100644 index 00000000..bd86fd8c --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/rtl/eeprom.sv @@ -0,0 +1,169 @@ +//============================================================================ +// Copyright (C) 2023 Martin Donlon +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +//============================================================================ + +module eeprom_28C64 #(parameter WRITE_CYCLES=0) ( + // Hardware ports + input clk, + input reset, + + input ce, + input wr, + input rd, + + input [12:0] addr, + input [7:0] data, + output [7:0] q, + + output ready, + + + // MiSTer support + output reg modified, + input ioctl_download, + input ioctl_wr, + input [12:0] ioctl_addr, + input [7:0] ioctl_dout, + + input ioctl_upload, + output [7:0] ioctl_din, + input ioctl_rd +); + +wire [7:0] q0; + +dualport_ram #(8, 13) mem( + .clock_a(clk), + .wren_a(wr), + .address_a(addr), + .data_a(data), + .q_a(q0), + + .clock_b(clk), + .wren_b(ioctl_download & ioctl_wr), + .address_b(ioctl_addr), + .data_b(ioctl_dout), + .q_b(ioctl_din) +); + +wire busy; +reg [31:0] write_timer; +reg prev_upload; + +assign ready = write_timer == 32'd0; +assign busy = ~ready; +assign q = ready ? q0 : ( ~q0 ); + +always_ff @(posedge clk) begin + if (reset) begin + write_timer <= 32'd0; + modified <= 0; + end else if (ce) begin + if (ioctl_upload & ~prev_upload) modified <= 0; + prev_upload <= ioctl_upload; + + if (wr) modified <= 1; + if (busy) begin + write_timer <= write_timer - 32'd1; + end else if (wr) begin + write_timer <= WRITE_CYCLES; + end + end +end + +endmodule + + +// This is completely untested. I wrote it and then realized it was not the eeprom that the M92 uses. +// Keeping it here in case it comes in useful at some point. It is an Atmel 28 series eeprom with 64 +// byte pages. +module eeprom_28xx_paged( + input clk, + + input reset, + + input ce, + input wr, + input rd, + + input [13:0] addr, + input [7:0] data, + output reg [7:0] q +); + +reg [7:0] mem[16384]; + +reg [7:0] write_page; +reg [5:0] write_addrs[64]; +reg [7:0] write_bytes[64]; +reg [6:0] write_index; +reg [6:0] store_index; +reg write_queuing; +reg store_pending; +reg [31:0] write_timer; +reg [7:0] last_byte; + +always @(posedge clk) begin + if (reset) begin + store_pending <= 0; + write_queuing <= 0; + write_index <= 7'd0; + store_index <= 7'd0; + + end else if (ce) begin + if (store_pending) begin + if (store_index == write_index) begin + store_pending <= 0; + end else begin + mem[{write_page, write_addrs[store_index]}] <= write_bytes[store_index]; + store_index <= store_index + 7'd1; + end + end else if (wr) begin + write_timer <= 32'd0; + write_queuing <= 1; + write_addrs[write_index] <= addr[5:0]; + write_bytes[write_index] <= data; + write_index <= write_index + 7'd1; + write_page <= addr[13:6]; + last_byte <= data; + + if (write_index == 7'd63) begin + store_pending <= 1; + store_index <= 7'd0; + write_queuing <= 0; + end + end else if (write_queuing) begin + write_timer <= write_timer + 32'd1; + if (write_timer == 32'd100_000) begin + store_pending <= 1; + store_index <= 7'd0; + write_queuing <= 0; + end + end + + if (rd) begin + if (write_queuing | store_pending) begin + q <= { ~last_byte[7], last_byte[6:0] }; + last_byte[6] <= ~last_byte[6]; + end else begin + q <= mem[addr]; + end + end + end +end + +endmodule diff --git a/Arcade_MiST/IremM92 Hardware/rtl/ga20.sv b/Arcade_MiST/IremM92 Hardware/rtl/ga20.sv new file mode 100644 index 00000000..440d5f71 --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/rtl/ga20.sv @@ -0,0 +1,306 @@ +//============================================================================ +// Copyright (C) 2023 Martin Donlon +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +//============================================================================ + +module ga20_channel( + input clk, + input reset, + + input ce, + + input cs, + input rd, + input wr, + input [2:0] addr, + input [7:0] din, + output reg [7:0] dout, + + output [19:0] sample_addr, + output reg sample_req, + input sample_ack, + input [63:0] sample_din, + + output [15:0] sample_out +); + +reg step; +reg [5:0] volume; +reg [7:0] rate; +reg [19:0] start_addr, end_addr, cur_addr; +reg [1:0] play; +reg [8:0] rate_cnt; + +reg [7:0] sample_s8; + +reg play_set; +wire [7:0] sample_data; + +assign sample_addr = cur_addr; + +always @(*) begin + case(cur_addr[2:0]) + 3'd0: sample_data = sample_din[ 7: 0]; + 3'd1: sample_data = sample_din[15: 8]; + 3'd2: sample_data = sample_din[23:16]; + 3'd3: sample_data = sample_din[31:24]; + 3'd4: sample_data = sample_din[39:32]; + 3'd5: sample_data = sample_din[47:40]; + 3'd6: sample_data = sample_din[55:48]; + default: sample_data = sample_din[63:56]; + endcase; +end +always_ff @(posedge clk, posedge reset) begin + if (reset) begin + volume <= 6'd00; + play <= 2'd0; + step <= 0; + play_set <= 0; + sample_s8 <= 8'h00; + end else begin + if (cs & rd) begin + if (addr == 3'd7) dout <= { 7'd0, play[1] }; + end else if (cs & wr) begin + case (addr) + 3'd0: start_addr[11:0] <= { din, 4'b0000 }; + 3'd1: start_addr[19:12] <= din; + 3'd2: end_addr[11:0] <= { din, 4'b0000 }; + 3'd3: end_addr[19:12] <= din; + 3'd4: rate <= din; + 3'd5: volume <= din[5:0]; + 3'd6: begin + play <= din[1:0]; + play_set <= din[1]; + end + endcase + end + + if (ce && sample_req == sample_ack) begin + step <= ~step; + + if (~step) begin + // first cycle + + if (play_set) begin + cur_addr <= start_addr; + sample_req <= ~sample_req; + play_set <= 0; + rate_cnt <= rate + 9'd2; + end else begin + rate_cnt <= rate_cnt + 9'd2; + end + end else begin + // second cycle + if (~play_set & play[1]) begin + if (sample_data == 8'd0) begin + play[1] <= 0; + sample_s8 <= 8'h00; + end else begin + sample_s8 <= { ~sample_data[7], sample_data[6:0] }; + + if (rate_cnt[8]) begin + cur_addr <= cur_addr + 20'd1; + if (cur_addr[2:0] == 3'b111) begin + sample_req <= ~sample_req; + end + rate_cnt <= rate_cnt + { 1'b1, rate }; + + if (cur_addr == end_addr) begin + if (play[0]) begin + cur_addr <= start_addr; + sample_req <= ~sample_req; + end else begin + sample_s8 <= 8'h00; + play[1] <= 0; + end + end + end + end + end + end + end + end +end + +// apply attenuation after filtering +always_ff @(posedge clk) begin + bit [7:0] vol_one; + + vol_one = { 2'd0, volume } + 8'd1; + + sample_out <= $signed(sample_s8) * $signed(vol_one); +end + + +endmodule + + +module ga20( + input clk, + input reset, + input filter_en, + + input ce, + + input cs, + input rd, + input wr, + input [4:0] addr, + input [7:0] din, + output [7:0] dout, + + + output reg sample_rom_req, + output reg [19:0] sample_rom_addr, + input sample_rom_ack, + input [63:0] sample_rom_din, + + output [15:0] sample_out +); + +reg [2:0] step; + +wire ce0 = step[2:1] == 2'd0; +wire ce1 = step[2:1] == 2'd1; +wire ce2 = step[2:1] == 2'd2; +wire ce3 = step[2:1] == 2'd3; + +wire cs0 = cs && addr[4:3] == 2'd0; +wire cs1 = cs && addr[4:3] == 2'd1; +wire cs2 = cs && addr[4:3] == 2'd2; +wire cs3 = cs && addr[4:3] == 2'd3; + +wire [7:0] dout0, dout1, dout2, dout3; + +assign dout = cs0 ? dout0 : cs1 ? dout1 : cs2 ? dout2 : dout3; + +wire [19:0] sample_addr[4]; +wire [15:0] sample_out0, sample_out1, sample_out2, sample_out3; +wire [3:0] sample_req; +reg [3:0] sample_ack; +reg [63:0] sample_data[4]; +reg [3:0] req_pending; + +ga20_channel ch0( .clk(clk), .reset(reset), .ce(ce & ce0), .cs(cs0), .rd(rd), .wr(wr), .addr(addr[2:0]), .din(din), .dout(dout0), .sample_addr(sample_addr[0]), .sample_req(sample_req[0]), .sample_ack(sample_ack[0]), .sample_din(sample_data[0]), .sample_out(sample_out0)); +ga20_channel ch1( .clk(clk), .reset(reset), .ce(ce & ce1), .cs(cs1), .rd(rd), .wr(wr), .addr(addr[2:0]), .din(din), .dout(dout1), .sample_addr(sample_addr[1]), .sample_req(sample_req[1]), .sample_ack(sample_ack[1]), .sample_din(sample_data[1]), .sample_out(sample_out1)); +ga20_channel ch2( .clk(clk), .reset(reset), .ce(ce & ce2), .cs(cs2), .rd(rd), .wr(wr), .addr(addr[2:0]), .din(din), .dout(dout2), .sample_addr(sample_addr[2]), .sample_req(sample_req[2]), .sample_ack(sample_ack[2]), .sample_din(sample_data[2]), .sample_out(sample_out2)); +ga20_channel ch3( .clk(clk), .reset(reset), .ce(ce & ce3), .cs(cs3), .rd(rd), .wr(wr), .addr(addr[2:0]), .din(din), .dout(dout3), .sample_addr(sample_addr[3]), .sample_req(sample_req[3]), .sample_ack(sample_ack[3]), .sample_din(sample_data[3]), .sample_out(sample_out3)); + +always_ff @(posedge clk, posedge reset) begin + if (reset) begin + sample_data[0] <= 0; + sample_data[1] <= 0; + sample_data[2] <= 0; + sample_data[3] <= 0; + req_pending <= 0; + end else begin + if (req_pending[0]) begin + if (sample_rom_req == sample_rom_ack) begin + req_pending[0] <= 0; + sample_ack[0] <= sample_req[0]; + sample_data[0] <= sample_rom_din; + end + end else if (req_pending[1]) begin + if (sample_rom_req == sample_rom_ack) begin + req_pending[1] <= 0; + sample_ack[1] <= sample_req[1]; + sample_data[1] <= sample_rom_din; + end + end else if (req_pending[2]) begin + if (sample_rom_req == sample_rom_ack) begin + req_pending[2] <= 0; + sample_ack[2] <= sample_req[2]; + sample_data[2] <= sample_rom_din; + end + end else if (req_pending[3]) begin + if (sample_rom_req == sample_rom_ack) begin + req_pending[3] <= 0; + sample_ack[3] <= sample_req[3]; + sample_data[3] <= sample_rom_din; + end + end else if (sample_req[0] != sample_ack[0]) begin + sample_rom_addr <= sample_addr[0]; + sample_rom_req <= ~sample_rom_req; + req_pending[0] <= 1; + end else if (sample_req[1] != sample_ack[1]) begin + sample_rom_addr <= sample_addr[1]; + sample_rom_req <= ~sample_rom_req; + req_pending[1] <= 1; + end else if (sample_req[2] != sample_ack[2]) begin + sample_rom_addr <= sample_addr[2]; + sample_rom_req <= ~sample_rom_req; + req_pending[2] <= 1; + end else if (sample_req[3] != sample_ack[3]) begin + sample_rom_addr <= sample_addr[3]; + sample_rom_req <= ~sample_rom_req; + req_pending[3] <= 1; + end + end +end + +always_ff @(posedge clk, posedge reset) begin + if (reset) begin + step <= 3'd0; + end else begin + reg prev_ce = 0; + prev_ce <= ce; + if (~ce & prev_ce) begin + step <= step + 3'd1; + end + end +end + +reg [15:0] sample_combined; + +// 9685hz 2nd order 10749hz 1st order +localparam CX = 0.00000741947949554119; +localparam CY0 = -2.95726738834813529522; +localparam CY1 = 2.91526970775390958934; +localparam CY2 = -0.95799698165074131939; +reg [15:0] sample_filtered; + +IIR_filter #( + .use_params(1), + .stereo(0), + .coeff_x(CX), + .coeff_x0(3), + .coeff_x1(3), + .coeff_x2(1), + .coeff_y0(CY0), + .coeff_y1(CY1), + .coeff_y2(CY2)) lpf_sample ( + .clk(clk), + .reset(reset), + + .ce(ce), + .sample_ce(ce), + + .cx(), .cx0(), .cx1(), .cx2(), .cy0(), .cy1(), .cy2(), + + .input_l(sample_combined), + .output_l(sample_filtered), + + .input_r(), + .output_r() +); + +always_ff @(posedge clk) begin + sample_combined <= sample_out0 + sample_out1 + sample_out2 + sample_out3; +end + +assign sample_out = filter_en ? sample_filtered : sample_combined; + +endmodule diff --git a/Arcade_MiST/IremM92 Hardware/rtl/ga21.sv b/Arcade_MiST/IremM92 Hardware/rtl/ga21.sv new file mode 100644 index 00000000..9f51d38f --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/rtl/ga21.sv @@ -0,0 +1,238 @@ +//============================================================================ +// Copyright (C) 2023 Martin Donlon +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +//============================================================================ + +module GA21( + input clk, + input ce, + + input reset, + + input [15:0] din, + output [15:0] dout, + + input [10:0] addr, + + input reg_cs, + input buf_cs, + input wr, + + output busy, + + output [15:0] obj_dout, + input [15:0] obj_din, + output [10:0] obj_addr, + output obj_we, + + output buffer_we, + output [10:0] buffer_addr, + output [15:0] buffer_dout, + input [15:0] buffer_din, + + input [9:0] count, + + output [12:0] pal_addr, + output [15:0] pal_dout, + input [15:0] pal_din, + output pal_we, + output pal_cs + + // TODO pal latching and OE signals? + +); + +reg [7:0] reg_direct_access; +reg [7:0] reg_obj_ptr; +reg [15:0] reg_copy_mode; + +wire [2:0] pal_addr_high = reg_copy_mode[10:8]; +wire layer_ordered_copy = reg_copy_mode[0]; +wire full_copy = reg_copy_mode[7] & ~reg_copy_mode[0]; + +reg obj_addr_high = 0; + +enum { + IDLE, + IDLE_DELAY, + INIT_COPY_PAL, + COPY_PAL, + INIT_CLEAR_OBJ, + CLEAR_OBJ, + INIT_COPY_OBJ, + COPY_OBJ +} copy_state = IDLE; + + +reg [10:0] copy_counter; +reg [15:0] copy_dout; +reg [10:0] copy_obj_addr; +reg [9:0] copy_pal_addr; +reg [2:0] copy_obj_word; +reg [8:0] copy_obj_idx; +reg [10:0] buffer_src_addr; +reg [10:0] next_buffer_src_addr; +reg [2:0] copy_layer; +reg copy_this_obj; + +reg copy_obj_we, copy_pal_we; + +wire direct_access_pal = reg_direct_access[1]; +wire direct_access_obj = reg_direct_access[0]; + +always_ff @(posedge clk or posedge reset) begin + bit [8:0] obj_y; + bit [1:0] obj_height; + bit [1:0] obj_log2_cols; + bit [2:0] obj_layer; + bit [3:0] obj_cols; + bit [8:0] next_obj_idx; + + if (reset) begin + copy_state <= IDLE; + reg_direct_access <= 0; + reg_obj_ptr <= 0; + reg_copy_mode <= 0; + + copy_obj_we <= 0; + copy_pal_we <= 0; + end else begin + if (reg_cs & wr) begin + if (addr == 11'h0) reg_obj_ptr <= din[7:0]; + if (addr == 11'h1) reg_direct_access <= din[7:0]; + if (addr == 11'h2) reg_copy_mode <= din[15:0]; + if (addr == 11'h4) begin + copy_state <= INIT_COPY_PAL; + end + end + + if (ce) begin + copy_obj_we <= 0; + copy_pal_we <= 0; + + case(copy_state) + IDLE_DELAY: copy_state <= IDLE; + IDLE: begin + end + INIT_COPY_PAL: begin + buffer_src_addr <= 11'h400; + copy_pal_addr <= ~10'd0; + copy_state <= COPY_PAL; + end + COPY_PAL: begin + if (buffer_src_addr == 11'h000) begin + copy_state <= INIT_CLEAR_OBJ; + end else begin + buffer_src_addr <= buffer_src_addr + 11'd1; + copy_pal_addr <= copy_pal_addr + 10'd1; + copy_dout <= buffer_din; + copy_pal_we <= 1; + end + end + INIT_CLEAR_OBJ: begin + copy_dout <= 16'd0; + copy_obj_addr <= 11'd0; + copy_obj_we <= 1; + copy_state <= CLEAR_OBJ; + end + CLEAR_OBJ: begin + copy_obj_addr <= copy_obj_addr + 11'd1; + copy_obj_we <= 1; + if (©_obj_addr) begin + copy_state <= INIT_COPY_OBJ; + end + end + INIT_COPY_OBJ: begin + copy_state <= COPY_OBJ; + copy_this_obj <= 0; + buffer_src_addr <= 11'd0; + copy_obj_word <= 2'd0; + copy_layer <= 3'd0; + copy_obj_idx <= 9'h100 - {1'b0, reg_obj_ptr}; + end + COPY_OBJ: begin + copy_dout <= buffer_din; + buffer_src_addr <= buffer_src_addr + 11'd1; + copy_obj_word <= copy_obj_word + 2'd1; + copy_obj_addr <= {1'b0, copy_obj_idx[7:0], copy_obj_word[1:0]}; + copy_obj_we <= copy_this_obj; + + if (buffer_src_addr[1:0] == 2'b00) begin + if (copy_obj_idx == 9'd0) begin + copy_state <= IDLE; + copy_obj_we <= 0; + end else begin + obj_y = buffer_din[8:0]; + obj_height = buffer_din[10:9]; + obj_log2_cols = buffer_din[12:11]; + obj_layer = buffer_din[15:13]; + obj_cols = 4'd1 << obj_log2_cols; + + if (full_copy || (layer_ordered_copy == 0 && obj_layer != 3'd7) || (obj_layer == copy_layer)) begin + copy_this_obj <= 1; + copy_obj_we <= 1; + + next_obj_idx = copy_obj_idx - obj_cols; + if (next_obj_idx[8]) begin // wrapped around + copy_state <= IDLE; + copy_obj_we <= 0; + end else begin + copy_obj_addr <= {1'b0, next_obj_idx, copy_obj_word[1:0]}; + copy_obj_idx <= next_obj_idx; + end + end else begin + copy_this_obj <= 0; + copy_obj_we <= 0; + end + + next_buffer_src_addr <= buffer_src_addr + { obj_cols, 2'b00 }; + end + end else if (buffer_src_addr[1:0] == 2'b11) begin + if (next_buffer_src_addr[10]) begin // end of input + if (layer_ordered_copy && (copy_layer != 3'd6)) begin + copy_layer <= copy_layer + 3'd1; + buffer_src_addr <= 11'd0; + end else begin + copy_state <= IDLE_DELAY; // delay for one cycle so final write can complete + end + end else begin + buffer_src_addr <= next_buffer_src_addr; + end + end + end + endcase + end + end +end + +assign dout = buf_cs ? (direct_access_obj ? obj_din : (direct_access_pal ? pal_din : buffer_din)) : 16'd0; +assign busy = copy_state != IDLE; + +assign buffer_we = ~busy & buf_cs & wr & ~direct_access_obj & ~direct_access_pal; +assign buffer_addr = busy ? buffer_src_addr : addr; + +assign buffer_dout = din; + +assign obj_dout = direct_access_obj ? din : copy_dout; +assign obj_addr = direct_access_obj ? addr : (busy ? copy_obj_addr : {obj_addr_high, count}); +assign obj_we = direct_access_obj ? (buf_cs & wr) : (busy ? copy_obj_we : 1'b0); + +assign pal_dout = direct_access_pal ? din : copy_dout; +assign pal_addr = {pal_addr_high, direct_access_pal ? addr[9:0] : (busy ? copy_pal_addr : 10'd0)}; +assign pal_we = direct_access_pal ? (buf_cs & wr) : (busy ? copy_pal_we : 1'b0); +assign pal_cs = direct_access_pal ? buf_cs : 1'b0; + +endmodule \ No newline at end of file diff --git a/Arcade_MiST/IremM92 Hardware/rtl/ga21_tb.sv b/Arcade_MiST/IremM92 Hardware/rtl/ga21_tb.sv new file mode 100644 index 00000000..f75494a3 --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/rtl/ga21_tb.sv @@ -0,0 +1,39 @@ +module ga21_tb; + +reg clk; +reg buf_cs; +reg [10:0] addr; +reg reg_cs; +reg reset; +reg wr; + +GA21 ga21( .clk(clk), .ce(1), .reset(reset), .buf_cs(0), .wr(wr), .reg_cs(reg_cs), .addr(addr)); + +always begin + clk = 1'b1; + #1; + clk = 1'b0; + #1; +end + +initial begin + reset = 1; + buf_cs = 0; + reg_cs = 0; + wr = 0; + #5; + reset = 0; + #5; + + addr = 'h9008 >> 1; + reg_cs = 1; + wr = 1; + #2; + + reg_cs = 0; + wr = 0; + #1000000; + $stop; +end + +endmodule \ No newline at end of file diff --git a/Arcade_MiST/IremM92 Hardware/rtl/ga22.sv b/Arcade_MiST/IremM92 Hardware/rtl/ga22.sv new file mode 100644 index 00000000..4a7a0ed1 --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/rtl/ga22.sv @@ -0,0 +1,171 @@ +//============================================================================ +// Copyright (C) 2023 Martin Donlon +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +//============================================================================ + +import m92_pkg::*; + +module GA22 ( + input clk, + + input ce, // 13.33Mhz + + input ce_pix, // 6.66Mhz + + input reset, + + output reg [11:0] color, + + input NL, + input hpulse, + input vpulse, + + output reg [9:0] count, + + input [63:0] obj_in, + + input [63:0] sdr_data, + output reg [24:0] sdr_addr, + output reg sdr_req, + input sdr_ack, + output reg sdr_refresh, + + input dbg_solid_sprites +); + +reg [6:0] linebuf_color; +reg linebuf_prio; +reg [9:0] linebuf_x; +reg linebuf_write; +reg linebuf_flip; +reg scan_toggle = 0; +reg [9:0] scan_pos = 0; +wire [9:0] scan_pos_nl = scan_pos ^ {10{NL}}; +wire [11:0] scan_out; + +double_linebuf line_buffer( + .clk(clk), + .ce_pix(ce_pix), + + .scan_pos(scan_pos_nl), + .scan_toggle(scan_toggle), + .scan_out(scan_out), + + .bitplanes(dbg_solid_sprites ? 64'hffff_ffff_ffff_ffff : sdr_data), + .flip(linebuf_flip), + .color(linebuf_color), + .prio(linebuf_prio), + .pos(linebuf_x), + .we(linebuf_write), + + .idle() +); + +reg [63:0] obj_data; + +wire [8:0] obj_org_y = obj_data[8:0]; +wire [1:0] obj_height = obj_data[10:9]; +wire [1:0] obj_width = obj_data[12:11]; +wire [2:0] obj_layer = obj_data[15:13]; +wire [15:0] obj_code = obj_data[31:16]; +wire [6:0] obj_color = obj_data[38:32]; +wire obj_pri = obj_data[39]; +wire obj_flipx = obj_data[40]; +wire obj_flipy = obj_data[41]; +wire [9:0] obj_org_x = obj_data[57:48]; + +always_ff @(posedge clk) begin + reg visible; + reg [3:0] span; + reg [3:0] end_span; + reg [8:0] V; + + reg [15:0] code; + reg [8:0] height_px; + reg [3:0] width; + reg [8:0] rel_y; + reg [8:0] row_y; + + linebuf_write <= 0; + + if (reset) begin + V <= 9'd0; + end else if (ce) begin + count <= count + 10'd1; + + sdr_refresh <= 0; + + if (ce_pix) begin + color <= scan_out[11:0]; + scan_pos <= scan_pos + 10'd1; + if (hpulse) begin + count <= 10'd0; + V <= V + 9'd1; + scan_pos <= 10'd44; + scan_toggle <= ~scan_toggle; + span <= 0; + end_span <= 0; + visible <= 0; + sdr_refresh <= 1; + end + end + + if (vpulse) begin + V <= 9'd126; + end + case(count[1:0]) + 0: begin + linebuf_flip <= obj_flipx; + linebuf_color <= obj_color; + linebuf_prio <= obj_pri; + linebuf_x <= obj_org_x + ( 10'd16 * span ); + linebuf_write <= visible; + if (span == end_span) begin + span <= 4'd0; + obj_data <= obj_in; + end else begin + span <= span + 4'd1; + end + end + 1: begin + end_span <= ( 4'd1 << obj_width ) - 1'd1; + height_px = 9'd16 << obj_height; + width = 4'd1 << obj_width; + rel_y = V + obj_org_y + ( 9'd16 << obj_height ); + row_y = obj_flipy ? (height_px - rel_y - 9'd1) : rel_y; + + if (rel_y < height_px) begin + code = obj_code + row_y[8:4] + ( ( obj_flipx ? ( width - span - 16'd1 ) : span ) * 16'd8 ); + sdr_addr <= REGION_SPRITE.base_addr[24:0] + { code[15:0], row_y[3:0], 3'b000 }; + sdr_req <= ~sdr_req; + visible <= 1; + end else begin + visible <= 0; + sdr_refresh <= 1; + end + end + 2: begin + sdr_refresh <= 1; + end + 3: begin + sdr_refresh <= 0; + end + endcase + end + +end + +endmodule \ No newline at end of file diff --git a/Arcade_MiST/IremM92 Hardware/rtl/ga22_linebuffer.sv b/Arcade_MiST/IremM92 Hardware/rtl/ga22_linebuffer.sv new file mode 100644 index 00000000..7917db75 --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/rtl/ga22_linebuffer.sv @@ -0,0 +1,191 @@ +//============================================================================ +// Copyright (C) 2023 Martin Donlon +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +//============================================================================ + +module linebuf( + input clk, + + input ce_pix, + + input [9:0] scan_pos, + input scan_active, + output [11:0] scan_out, + + input [11:0] color0, + input [11:0] color1, + input [9:0] draw_pos, + input draw_we +); + +wire [11:0] scan_odd, scan_even; +assign scan_out = scan_pos[0] ? scan_odd : scan_even; + +wire [11:0] odd_color = draw_pos[0] ? color0 : color1; +wire [11:0] even_color = draw_pos[0] ? color1 : color0; +wire [8:0] odd_addr = draw_pos[9:1]; +wire [8:0] even_addr = draw_pos[0] ? draw_pos[9:1] + 9'd1 : draw_pos[9:1]; + +dualport_ram #(.widthad(9), .width(12)) buffer_odd +( + .clock_a(clk), + .address_a(scan_pos[9:1]), + .q_a(scan_odd), + .wren_a(scan_active & ce_pix & scan_pos[0]), + .data_a(12'd0), + + .clock_b(clk), + .address_b(odd_addr), + .data_b(odd_color), + .wren_b((~scan_active) & draw_we & |odd_color[3:0]), + .q_b() +); + +dualport_ram #(.widthad(9), .width(12)) buffer_even +( + .clock_a(clk), + .address_a(scan_pos[9:1]), + .q_a(scan_even), + .wren_a(scan_active & ce_pix & ~scan_pos[0]), + .data_a(12'd0), + + .clock_b(clk), + .address_b(even_addr), + .data_b(even_color), + .wren_b((~scan_active) & draw_we & |even_color[3:0]), + .q_b() +); + +endmodule + + +module double_linebuf( + input clk, + + input ce_pix, + + input [9:0] scan_pos, + input scan_toggle, + output [11:0] scan_out, + + input [63:0] bitplanes, + input flip, + input [6:0] color, + input prio, + input [9:0] pos, + input we, + + output idle +); + +wire [11:0] scan_out_0, scan_out_1; +assign scan_out = scan_toggle ? scan_out_0 : scan_out_1; + +reg [11:0] color0; +reg [11:0] color1; +reg [9:0] draw_pos; +reg draw_we = 0; + +linebuf buf_0( + .clk(clk), + .ce_pix(ce_pix), + + .scan_active(scan_toggle), + .scan_out(scan_out_0), + .scan_pos(scan_pos), + + .color0(color0), + .color1(color1), + .draw_pos(draw_pos), + .draw_we(draw_we) +); + +linebuf buf_1( + .clk(clk), + .ce_pix(ce_pix), + + .scan_active(~scan_toggle), + .scan_out(scan_out_1), + .scan_pos(scan_pos), + + .color0(color0), + .color1(color1), + .draw_pos(draw_pos), + .draw_we(draw_we) +); + +// d is 16 pixels stored as 2 sets of 4 bitplanes +// d[31:0] is 8 pixels, made up from planes d[7:0], d[15:8], etc +// d[63:32] is 8 pixels made up from planes d[39:32], d[47:40], etc +// Returns 16 pixels stored as 4 bit planes d[15:0], d[31:16], etc +function [63:0] deswizzle(input [63:0] d, input rev); + begin + integer i; + bit [7:0] plane[8]; + bit [7:0] t; + for( i = 0; i < 8; i = i + 1 ) begin + t = d[(i*8) +: 8]; + plane[i] = rev ? { t[0], t[1], t[2], t[3], t[4], t[5], t[6], t[7] } : t; + end + + deswizzle[15:0] = rev ? { plane[4], plane[0] } : { plane[0], plane[4] }; + deswizzle[31:16] = rev ? { plane[5], plane[1] } : { plane[1], plane[5] }; + deswizzle[47:32] = rev ? { plane[6], plane[2] } : { plane[2], plane[6] }; + deswizzle[63:48] = rev ? { plane[7], plane[3] } : { plane[3], plane[7] }; + end +endfunction + +reg [3:0] count = 0; +assign idle = count == 4'd0; + +always_ff @(posedge clk) begin + reg [63:0] bits_r; + bit [63:0] bits; + reg [6:0] color_r; + reg prio_r; + + draw_we <= 0; + + if (count != 4'd0) begin + color0 <= { prio_r, color_r, bits_r[63], bits_r[47], bits_r[31], bits_r[15] }; + color1 <= { prio_r, color_r, bits_r[62], bits_r[46], bits_r[30], bits_r[14] }; + draw_pos <= draw_pos + 10'd2; + draw_we <= 1; + + bits_r <= { bits_r[61:0], 2'b00 }; + + count <= count - 4'd1; + end + + if (we) begin + bits = deswizzle(bitplanes, flip); + + color0 <= { prio, color, bits[63], bits[47], bits[31], bits[15] }; + color1 <= { prio, color, bits[62], bits[46], bits[30], bits[14] }; + draw_we <= 1; + draw_pos <= pos; + + bits_r <= { bits[61:0], 2'b00 }; + color_r <= color; + prio_r <= prio; + + count <= 4'd7; + end +end + +endmodule + + diff --git a/Arcade_MiST/IremM92 Hardware/rtl/ga23.sv b/Arcade_MiST/IremM92 Hardware/rtl/ga23.sv new file mode 100644 index 00000000..b45754b3 --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/rtl/ga23.sv @@ -0,0 +1,312 @@ +//============================================================================ +// Copyright (C) 2023 Martin Donlon +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +//============================================================================ + +module GA23( + input clk, + + input ce, + + input paused, + + input reset, + + input io_wr, + input [15:0] addr, + input [15:0] cpu_din, + + output reg [14:0] vram_addr, + output reg vram_req, + input [31:0] vram_din, + + input large_tileset, + + input [31:0] sdr_data_a, + output [24:0] sdr_addr_a, + output sdr_req_a, + input sdr_ack_a, + + input [31:0] sdr_data_b, + output [24:0] sdr_addr_b, + output sdr_req_b, + input sdr_ack_b, + + input [31:0] sdr_data_c, + output [24:0] sdr_addr_c, + output sdr_req_c, + input sdr_ack_c, + + output vblank, + output vsync, + output hblank, + output hsync, + + output hpulse, + output vpulse, + + output hint, + + output reg [10:0] color_out, + output reg prio_out, + + input [2:0] dbg_en_layers +); + + +//// VIDEO TIMING +reg [9:0] hcnt, vcnt; +reg [9:0] hint_line; + +assign hsync = hcnt < 10'd65 || hcnt > 10'd448; +assign hblank = hcnt < 10'd104 || hcnt > 10'd422; +assign vblank = vcnt > 10'd113 && vcnt < 10'd136; +assign vsync = vcnt > 10'd119 && vcnt < 10'd125; +assign hpulse = hcnt == 10'd48; +assign vpulse = (vcnt == 10'd124 && hcnt > 10'd260) || (vcnt == 10'd125 && hcnt < 10'd260); +assign hint = vcnt == hint_line && hcnt > 10'd422 && ~paused; + +always_ff @(posedge clk) begin + if (ce) begin + hcnt <= hcnt + 10'd1; + if (hcnt == 10'd471) begin + hcnt <= 10'd48; + vcnt <= vcnt + 10'd1; + if (vcnt == 10'd375) begin + vcnt <= 10'd114; + end + end + end +end + +wire [21:0] rom_addr[3]; +wire [31:0] rom_data[3]; +wire rom_req[3]; +wire rom_ack[3]; + +//// MEMORY ACCESS +reg [2:0] mem_cyc; +reg [3:0] rs_cyc; + +reg [9:0] x_ofs[3], y_ofs[3]; +reg [7:0] control[3]; +reg [9:0] rowscroll[3]; + +wire [14:0] layer_vram_addr[3]; +reg layer_load[3]; +wire layer_prio[3]; +wire [10:0] layer_color[3]; +reg [15:0] vram_latch; + +reg [37:0] control_save_0[512]; +reg [37:0] control_save_1[512]; +reg [37:0] control_save_2[512]; + +reg [37:0] control_restore[3]; + +reg rowscroll_active, rowscroll_pending; + +always_ff @(posedge clk, posedge reset) begin + bit [9:0] rs_y; + if (reset) begin + mem_cyc <= 0; + + // layer regs + x_ofs[0] <= 10'd0; x_ofs[1] <= 10'd0; x_ofs[2] <= 10'd0; + y_ofs[0] <= 10'd0; y_ofs[1] <= 10'd0; y_ofs[2] <= 10'd0; + control[0] <= 8'd0; control[1] <= 8'd0; control[2] <= 8'd0; + hint_line <= 10'd0; + + rowscroll_pending <= 0; + rowscroll_active <= 0; + + end else begin + + if (ce) begin + layer_load[0] <= 0; layer_load[1] <= 0; layer_load[2] <= 0; + mem_cyc <= mem_cyc + 3'd1; + + if (hpulse) begin + mem_cyc <= 3'd7; + rowscroll_pending <= 1; + end + + if (rowscroll_active) begin + rs_cyc <= rs_cyc + 4'd1; + case(rs_cyc) + 0: vram_addr <= 'h7800; + 4: begin + rs_y = y_ofs[0] + vcnt; + vram_addr <= 'h7a00 + rs_y[8:0]; + vram_req <= ~vram_req; + end + 7: rowscroll[0] <= vram_din[9:0]; + 8: begin + rs_y = y_ofs[1] + vcnt; + vram_addr <= 'h7c00 + rs_y[8:0]; + vram_req <= ~vram_req; + end + 10: rowscroll[1] <= vram_din[9:0]; + 12: begin + rs_y = y_ofs[2] + vcnt; + vram_addr <= 'h7e00 + rs_y[8:0]; + vram_req <= ~vram_req; + end + 14: rowscroll[2] <= vram_din[9:0]; + 15: rowscroll_active <= 0; + endcase + + end else begin + + case(mem_cyc) + 3'd0: begin + vram_addr <= layer_vram_addr[0]; + vram_req <= ~vram_req; + end + 3'd1: begin + layer_load[0] <= 1; // would be better a bit later + end + 3'd2: begin + vram_addr <= layer_vram_addr[1]; + vram_req <= ~vram_req; + end + 3'd4: begin + layer_load[1] <= 1; + end + 3'd5: begin + vram_addr <= layer_vram_addr[2]; + vram_req <= ~vram_req; + end + 3'd7: begin + layer_load[2] <= 1; + + if (rowscroll_pending) begin + rowscroll_pending <= 0; + rowscroll_active <= 1; + rs_cyc <= 4'd0; + end + end + endcase + end + + prio_out <= layer_prio[0] | layer_prio[1] | layer_prio[2]; + if (|layer_color[0][3:0]) begin + color_out <= layer_color[0]; + end else if (|layer_color[1][3:0]) begin + color_out <= layer_color[1]; + end else begin + color_out <= layer_color[2]; + end + end + + if (io_wr) begin + case(addr[7:0]) + 'h80: y_ofs[0][7:0] <= cpu_din[7:0]; + 'h81: y_ofs[0][9:8] <= cpu_din[1:0]; + 'h84: x_ofs[0][7:0] <= cpu_din[7:0]; + 'h85: x_ofs[0][9:8] <= cpu_din[1:0]; + + 'h88: y_ofs[1][7:0] <= cpu_din[7:0]; + 'h89: y_ofs[1][9:8] <= cpu_din[1:0]; + 'h8c: x_ofs[1][7:0] <= cpu_din[7:0]; + 'h8d: x_ofs[1][9:8] <= cpu_din[1:0]; + + 'h90: y_ofs[2][7:0] <= cpu_din[7:0]; + 'h91: y_ofs[2][9:8] <= cpu_din[1:0]; + 'h94: x_ofs[2][7:0] <= cpu_din[7:0]; + 'h95: x_ofs[2][9:8] <= cpu_din[1:0]; + + 'h98: control[0] <= cpu_din[7:0]; + 'h9a: control[1] <= cpu_din[7:0]; + 'h9c: control[2] <= cpu_din[7:0]; + + 'h9e: hint_line[7:0] <= cpu_din[7:0]; + 'h9f: hint_line[9:8] <= cpu_din[1:0]; + endcase + end +`ifdef CTRL_SAVE + if (hcnt == 10'd104 && ~paused) begin // end of hblank + control_save_0[vcnt] <= { y_ofs[0], x_ofs[0], control[0], rowscroll[0] }; + control_save_1[vcnt] <= { y_ofs[1], x_ofs[1], control[1], rowscroll[1] }; + control_save_2[vcnt] <= { y_ofs[2], x_ofs[2], control[2], rowscroll[2] }; + end else if (paused) begin + control_restore[0] <= control_save_0[vcnt]; + control_restore[1] <= control_save_1[vcnt]; + control_restore[2] <= control_save_2[vcnt]; + end +`endif + end +end + + +assign rom_data[0] = sdr_data_a; +assign sdr_addr_a = REGION_TILE.base_addr[24:0] | rom_addr[0]; +assign sdr_req_a = rom_req[0]; +assign rom_ack[0] = sdr_ack_a; + +assign rom_data[1] = sdr_data_b; +assign sdr_addr_b = REGION_TILE.base_addr[24:0] | rom_addr[1]; +assign sdr_req_b = rom_req[1]; +assign rom_ack[1] = sdr_ack_b; + +assign rom_data[2] = sdr_data_c; +assign sdr_addr_c = REGION_TILE.base_addr[24:0] | rom_addr[2]; +assign sdr_req_c = rom_req[2]; +assign rom_ack[2] = sdr_ack_c; + +//// LAYERS +generate + genvar i; + for(i = 0; i < 3; i = i + 1 ) begin : generate_layer + wire [9:0] _y_ofs = paused ? control_restore[i][37:28] : y_ofs[i]; + wire [9:0] _x_ofs = paused ? control_restore[i][27:18] : x_ofs[i]; + wire [7:0] _control = paused ? control_restore[i][17:10] : control[i]; + wire [9:0] _rowscroll = paused ? control_restore[i][9:0] : rowscroll[i]; + + ga23_layer layer( + .clk(clk), + .ce_pix(ce), + + .NL(0), + .large_tileset(large_tileset), + + .x_ofs(_x_ofs), + .y_ofs(_y_ofs), + .control(_control), + + .x_base({hcnt[9:3], 3'd0}), + .y(_y_ofs + vcnt), + .rowscroll(_rowscroll), + + .vram_addr(layer_vram_addr[i]), + + .load(layer_load[i]), + .attrib(vram_din[31:16]), + .index(vram_din[15:0]), + + .color_out(layer_color[i]), + .prio_out(layer_prio[i]), + + .sdr_addr(rom_addr[i]), + .sdr_data(rom_data[i]), + .sdr_req(rom_req[i]), + .sdr_ack(rom_ack[i]), + + .dbg_enabled(dbg_en_layers[i]) + ); + end +endgenerate +endmodule diff --git a/Arcade_MiST/IremM92 Hardware/rtl/ga23_layer.sv b/Arcade_MiST/IremM92 Hardware/rtl/ga23_layer.sv new file mode 100644 index 00000000..ea11c3b1 --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/rtl/ga23_layer.sv @@ -0,0 +1,112 @@ +//============================================================================ +// Copyright (C) 2023 Martin Donlon +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +//============================================================================ + +module ga23_layer( + input clk, + input ce_pix, + + input NL, + + input large_tileset, + + // io registers + input [9:0] x_ofs, + input [9:0] y_ofs, + input [7:0] control, + + // position + input [9:0] x_base, + input [9:0] y, + input [9:0] rowscroll, + + // vram address for current tile + output [14:0] vram_addr, + + // + input load, + input [15:0] attrib, + input [15:0] index, + + output prio_out, + output [10:0] color_out, + + input [31:0] sdr_data, + output reg [21:0] sdr_addr, + output reg sdr_req, + input sdr_ack, + + input dbg_enabled +); + +wire [14:0] vram_base = { control[1:0], 13'd0 }; +wire wide = control[2]; +wire enabled = ~control[4] & dbg_enabled; +wire en_rowscroll = control[6]; +wire [9:0] x = x_base + ( en_rowscroll ? rowscroll : x_ofs ); +wire [6:0] tile_x = x[9:3] + ( wide ? 7'd32 : 7'd0); +wire [5:0] tile_y = y[8:3]; + +assign vram_addr = vram_base + (wide ? {1'b0, tile_y, tile_x[6:0], 1'b0} : {2'b00, tile_y, tile_x[5:0], 1'b0}); + +reg [3:0] cnt; + +reg [1:0] prio; +reg [6:0] palette; +reg flip_x; +wire flip_y = attrib[10]; +reg [2:0] offset; + +always_ff @(posedge clk) begin + + if (ce_pix) begin + cnt <= cnt + 4'd1; + if (load & dbg_enabled) begin + cnt <= 4'd0; + sdr_addr <= { (large_tileset ? attrib[15] : 1'b0), index, flip_y ? ~y[2:0] : y[2:0], 2'b00 }; + sdr_req <= ~sdr_req; + palette <= attrib[6:0]; + prio <= attrib[8:7]; + flip_x <= attrib[9]; + offset <= x[2:0]; + end + end +end + +wire [1:0] shift_prio_out; +wire [10:0] shift_color_out; + +ga23_shifter shifter( + .clk(clk), + .ce_pix(ce_pix), + + .offset(offset), + + .load(load), + .reverse(flip_x), + .row(sdr_data), + .palette(palette), + .prio(prio), + + .color_out(shift_color_out), + .prio_out(shift_prio_out) +); + +assign color_out = enabled ? shift_color_out : 11'd0; +assign prio_out = enabled ? ( ( shift_prio_out[0] & shift_color_out[3] ) | ( shift_prio_out[1] & |shift_color_out[3:0] ) ) : 1'b0; + +endmodule \ No newline at end of file diff --git a/Arcade_MiST/IremM92 Hardware/rtl/ga23_shifter.sv b/Arcade_MiST/IremM92 Hardware/rtl/ga23_shifter.sv new file mode 100644 index 00000000..b5910e58 --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/rtl/ga23_shifter.sv @@ -0,0 +1,70 @@ +//============================================================================ +// Copyright (C) 2023 Martin Donlon +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +//============================================================================ + +module ga23_shifter( + input clk, + input ce_pix, + + input [2:0] offset, + + input load, + input reverse, + input [31:0] row, + input [6:0] palette, + input [1:0] prio, + + output [10:0] color_out, + output [1:0] prio_out +); + +reg [2:0] cnt; +reg [31:0] pix_next, pix_cur; +reg [6:0] pal_next, pal_cur; +reg [1:0] prio_next, prio_cur; +wire [2:0] flip_cnt = cnt + offset; + +always_ff @(posedge clk) begin + if (ce_pix) begin + pix_cur[27:0] <= pix_cur[31:4]; + cnt <= cnt + 3'd1; + + if (&flip_cnt) begin + pix_cur <= pix_next; + prio_cur <= prio_next; + pal_cur <= pal_next; + end + + if (load) begin + integer i; + for( i = 0; i < 8; i = i + 1 ) begin + pix_next[(i * 4) + 3] = reverse ? row[24 + i] : row[31 - i]; + pix_next[(i * 4) + 2] = reverse ? row[16 + i] : row[23 - i]; + pix_next[(i * 4) + 1] = reverse ? row[ 8 + i] : row[15 - i]; + pix_next[(i * 4) + 0] = reverse ? row[ 0 + i] : row[ 7 - i]; + end + pal_next <= palette; + prio_next <= prio; + cnt <= 0; + end + end +end + +assign prio_out = prio_cur; +assign color_out = { pal_cur, pix_cur[3:0] }; + +endmodule \ No newline at end of file diff --git a/Arcade_MiST/IremM92 Hardware/rtl/iir_filter.v b/Arcade_MiST/IremM92 Hardware/rtl/iir_filter.v new file mode 100644 index 00000000..a5336e98 --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/rtl/iir_filter.v @@ -0,0 +1,213 @@ + +// 3-tap IIR filter for 2 channels. +// Copyright (C) 2020 Sorgelig +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +// +// Can be converted to 2-tap (coeff_x2 = 0, coeff_y2 = 0) or 1-tap (coeff_x1,2 = 0, coeff_y1,2 = 0) +// +module IIR_filter +#( + parameter use_params = 1, // set to 1 to use following parameters, 0 for input port variables. + parameter stereo = 1, // 0 for mono (input_l) + + parameter coeff_x = 0.00000774701983513660, // Base gain value for X. Float. Range: 0.0 ... 0.999(9) + parameter coeff_x0 = 3, // Gain scale factor for X0. Integer. Range -7 ... +7 + parameter coeff_x1 = 3, // Gain scale factor for X1. Integer. Range -7 ... +7 + parameter coeff_x2 = 1, // Gain scale factor for X2. Integer. Range -7 ... +7 + parameter coeff_y0 = -2.96438150626551080000, // Coefficient for Y0. Float. Range -3.999(9) ... 3.999(9) + parameter coeff_y1 = 2.92939452735121100000, // Coefficient for Y1. Float. Range -3.999(9) ... 3.999(9) + parameter coeff_y2 = -0.96500747158831091000 // Coefficient for Y2. Float. Range -3.999(9) ... 3.999(9) +) +( + input clk, + input reset, + + input ce, // must be double of calculated rate for stereo! + input sample_ce, // desired output sample rate + + input [39:0] cx, + input [7:0] cx0, + input [7:0] cx1, + input [7:0] cx2, + input [23:0] cy0, + input [23:0] cy1, + input [23:0] cy2, + + input [15:0] input_l, input_r, // signed samples + output [15:0] output_l, output_r // signed samples +); + +localparam [39:0] pcoeff_x = coeff_x * 40'h8000000000; +localparam [31:0] pcoeff_y0 = coeff_y0 * 24'h200000; +localparam [31:0] pcoeff_y1 = coeff_y1 * 24'h200000; +localparam [31:0] pcoeff_y2 = coeff_y2 * 24'h200000; + +wire [39:0] vcoeff = use_params ? pcoeff_x : cx; +wire [23:0] vcoeff_y0 = use_params ? pcoeff_y0[23:0] : cy0; +wire [23:0] vcoeff_y1 = use_params ? pcoeff_y1[23:0] : cy1; +wire [23:0] vcoeff_y2 = use_params ? pcoeff_y2[23:0] : cy2; + +wire [59:0] inp_mul = $signed(inp) * $signed(vcoeff); + +wire [39:0] x = inp_mul[59:20]; +wire [39:0] y = x + tap0; + +wire [39:0] tap0; +iir_filter_tap iir_tap_0 +( + .clk(clk), + .reset(reset), + .ce(ce), + .ch(ch), + .cx(use_params ? coeff_x0[7:0] : cx0), + .cy(vcoeff_y0), + .x(x), + .y(y), + .z(tap1), + .tap(tap0) +); + +wire [39:0] tap1; +iir_filter_tap iir_tap_1 +( + .clk(clk), + .reset(reset), + .ce(ce), + .ch(ch), + .cx(use_params ? coeff_x1[7:0] : cx1), + .cy(vcoeff_y1), + .x(x), + .y(y), + .z(tap2), + .tap(tap1) +); + +wire [39:0] tap2; +iir_filter_tap iir_tap_2 +( + .clk(clk), + .reset(reset), + .ce(ce), + .ch(ch), + .cx(use_params ? coeff_x2[7:0] : cx2), + .cy(vcoeff_y2), + .x(x), + .y(y), + .z(0), + .tap(tap2) +); + +wire [15:0] y_clamp = (~y[39] & |y[38:35]) ? 16'h7FFF : (y[39] & ~&y[38:35]) ? 16'h8000 : y[35:20]; + +reg ch = 0; +reg [15:0] out_l, out_r, out_m; +reg [15:0] inp, inp_m; +always @(posedge clk) if (ce) begin + if(!stereo) begin + ch <= 0; + inp <= input_l; + out_l <= y_clamp; + out_r <= y_clamp; + end + else begin + ch <= ~ch; + if(ch) begin + out_m <= y_clamp; + inp <= inp_m; + end + else begin + out_l <= out_m; + out_r <= y_clamp; + inp <= input_l; + inp_m <= input_r; + end + end +end + +reg [31:0] out; +always @(posedge clk) if (sample_ce) out <= {out_l, out_r}; + +assign {output_l, output_r} = out; + +endmodule + +module iir_filter_tap +( + input clk, + input reset, + + input ce, + input ch, + + input [7:0] cx, + input [23:0] cy, + + input [39:0] x, + input [39:0] y, + input [39:0] z, + output [39:0] tap +); + +wire signed [60:0] y_mul = $signed(y[36:0]) * $signed(cy); + +function [39:0] x_mul; + input [39:0] x; +begin + x_mul = 0; + if(cx[0]) x_mul = x_mul + {{4{x[39]}}, x[39:4]}; + if(cx[1]) x_mul = x_mul + {{3{x[39]}}, x[39:3]}; + if(cx[2]) x_mul = x_mul + {{2{x[39]}}, x[39:2]}; + if(cx[7]) x_mul = ~x_mul; //cheap NEG +end +endfunction + +(* ramstyle = "logic" *) reg [39:0] intreg[2]; +always @(posedge clk, posedge reset) begin + if(reset) {intreg[0],intreg[1]} <= 80'd0; + else if(ce) intreg[ch] <= x_mul(x) - y_mul[60:21] + z; +end + +assign tap = intreg[ch]; + +endmodule + +// simplified IIR 1-tap. +module DC_blocker +( + input clk, + input ce, // 48/96 KHz + input mute, + + input sample_rate, + input [15:0] din, + output [15:0] dout +); + +wire [39:0] x = {din[15], din, 23'd0}; +wire [39:0] x0 = x - (sample_rate ? {{11{x[39]}}, x[39:11]} : {{10{x[39]}}, x[39:10]}); +wire [39:0] y1 = y - (sample_rate ? {{10{y[39]}}, y[39:10]} : {{09{y[39]}}, y[39:09]}); +wire [39:0] y0 = x0 - x1 + y1; + +reg [39:0] x1, y; +always @(posedge clk) if(ce) begin + x1 <= x0; + y <= ^y0[39:38] ? {{2{y0[39]}},{38{y0[38]}}} : y0; +end + +assign dout = mute ? 16'd0 : y[38:23]; + +endmodule diff --git a/Arcade_MiST/IremM92 Hardware/rtl/jtframe_frac_cen.v b/Arcade_MiST/IremM92 Hardware/rtl/jtframe_frac_cen.v new file mode 100644 index 00000000..37b2780a --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/rtl/jtframe_frac_cen.v @@ -0,0 +1,62 @@ +/////////////////////////////////////////////////////////////////////////// +// Fractional clock enable signal +// W refers to the number of divided down cen signals available +// each one is divided by 2 + +module jtframe_frac_cen #(parameter W=2)( + input clk, + input cen_in, + + input [9:0] n, // numerator + input [9:0] m, // denominator + output reg [W-1:0] cen, + output reg [W-1:0] cenb // 180 shifted +); + +wire [10:0] step={1'b0,n}; +wire [10:0] lim ={1'b0,m}; +wire [10:0] absmax = lim+step; + +reg [10:0] cencnt=11'd0; +reg [10:0] next; +reg [10:0] next2; + +always @(*) begin + next = cencnt+step; + next2 = next-lim; +end + +reg half = 1'b0; +wire over = next>=lim; +wire halfway = next >= (lim>>1) && !half; + +reg [W-1:0] edgecnt = {W{1'b0}}; +wire [W-1:0] next_edgecnt = edgecnt + 1'b1; +wire [W-1:0] toggle = next_edgecnt & ~edgecnt; + +always @(posedge clk) begin + cen <= {W{1'b0}}; + cenb <= {W{1'b0}}; + + if (cen_in) begin + if( cencnt >= absmax ) begin + // something went wrong: restart + cencnt <= 11'd0; + end else + if( halfway ) begin + half <= 1'b1; + cenb[0] <= 1'b1; + end + if( over ) begin + cencnt <= next2; + half <= 1'b0; + edgecnt <= next_edgecnt; + cen <= { toggle[W-2:0], 1'b1 }; + end else begin + cencnt <= next; + end + end +end + + +endmodule \ No newline at end of file diff --git a/Arcade_MiST/IremM92 Hardware/rtl/m92.qip b/Arcade_MiST/IremM92 Hardware/rtl/m92.qip new file mode 100644 index 00000000..154d55a8 --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/rtl/m92.qip @@ -0,0 +1,21 @@ +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ./rom.sv ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ./pal.sv ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ./ga22.sv ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ./sound.sv ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ./ga23_layer.sv ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ./eeprom.sv ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ./m92_pkg.sv ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ./m92.sv ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ./palram.sv ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ./ga22_linebuffer.sv ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ./ga21.sv ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ./m92_pic.sv ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ./ga20.sv ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ./dpramv.sv ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ./objram.sv ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ./ga23_shifter.sv ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ./sdram_4w_cl3.sv ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ./ga23.sv ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ./v35.sv ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ./jtframe_frac_cen.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ./iir_filter.v ] diff --git a/Arcade_MiST/IremM92 Hardware/rtl/m92.sv b/Arcade_MiST/IremM92 Hardware/rtl/m92.sv new file mode 100644 index 00000000..cf359497 --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/rtl/m92.sv @@ -0,0 +1,724 @@ +//============================================================================ +// Irem M92 for MiSTer FPGA - Main module +// +// Copyright (C) 2023 Martin Donlon +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +//============================================================================ + +import m92_pkg::*; + +module m92 ( + input clk_sys, + + input reset_n, + output reg ce_pix, + + input board_cfg_t board_cfg, + + + output [7:0] R, + output [7:0] G, + output [7:0] B, + + output HSync, + output VSync, + output HBlank, + output VBlank, + + output [15:0] AUDIO_L, + output [15:0] AUDIO_R, + + input [3:0] coin, + input [3:0] start_buttons, + + input [9:0] p1_input, + input [9:0] p2_input, + input [9:0] p3_input, + input [9:0] p4_input, + + input [23:0] dip_sw, + + input pause_rq, + output cpu_paused, + + output [24:0] sdr_vram_addr, + input [31:0] sdr_vram_data, + output sdr_vram_req, + + output [24:0] sdr_sprite_addr, + input [63:0] sdr_sprite_dout, + output sdr_sprite_req, + input sdr_sprite_ack, + output sdr_sprite_refresh, + + output [24:0] sdr_bg_addr_a, + input [31:0] sdr_bg_data_a, + output sdr_bg_req_a, + input sdr_bg_ack_a, + + output [24:0] sdr_bg_addr_b, + input [31:0] sdr_bg_data_b, + output sdr_bg_req_b, + input sdr_bg_ack_b, + + output [24:0] sdr_bg_addr_c, + input [31:0] sdr_bg_data_c, + output sdr_bg_req_c, + input sdr_bg_ack_c, + + output reg [24:0] sdr_cpu_addr, + input [15:0] sdr_cpu_dout, + output reg [15:0] sdr_cpu_din, + output reg sdr_cpu_req, + input sdr_cpu_ack, + output reg [1:0] sdr_cpu_wr_sel, + + output reg [24:0] sdr_audio_cpu_addr, + input [15:0] sdr_audio_cpu_dout, + output reg [15:0] sdr_audio_cpu_din, + output reg sdr_audio_cpu_req, + input sdr_audio_cpu_ack, + output reg [1:0] sdr_audio_cpu_wr_sel, + + output [24:0] sdr_audio_addr, + input [63:0] sdr_audio_dout, + output sdr_audio_req, + input sdr_audio_ack, + + input clk_bram, + input bram_wr, + input [7:0] bram_data, + input [19:0] bram_addr, + input [4:0] bram_cs, + + input ioctl_download, + input ioctl_wr, + input [26:0] ioctl_addr, + input [7:0] ioctl_dout, + + input ioctl_upload, + output [7:0] ioctl_upload_index, + output [7:0] ioctl_din, + input ioctl_rd, + output ioctl_upload_req, + + input [2:0] dbg_en_layers, + input dbg_solid_sprites, + input en_audio_filters, + input dbg_fm_en, + + input sprite_freeze, + + input dbg_io_write, + input [7:0] dbg_io_data, + output reg dbg_io_wait +); + +assign ioctl_upload_index = 8'd1; + +wire [15:0] rgb_color; +assign R = { rgb_color[4:0], rgb_color[4:2] }; +assign G = { rgb_color[9:5], rgb_color[9:7] }; +assign B = { rgb_color[14:10], rgb_color[14:12] }; + +reg paused = 0; +assign cpu_paused = paused; + +always @(posedge clk_sys) begin + if (pause_rq & ~paused) begin + if (~cpu_mem_read & ~cpu_mem_write & ~mem_rq_active & vpulse) begin + paused <= 1; + end + end else if (~pause_rq & paused) begin + paused <= ~vpulse; + end +end + + +wire ce_13m; +jtframe_frac_cen #(2) pixel_cen +( + .clk(clk_sys), + .cen_in(1), + .n(10'd1), + .m(10'd3), + .cen({ce_pix, ce_13m}) +); + +wire ce_9m, ce_18m; +jtframe_frac_cen #(2) cpu_cen +( + .clk(clk_sys), + .cen_in(1), + .n(10'd9), + .m(10'd20), + .cen({ce_9m, ce_18m}) +); + +wire dma_busy; + +wire [15:0] cpu_mem_out; +wire [19:0] cpu_mem_addr; +wire [1:0] cpu_mem_sel; + +// v30 bus read/write signals are only asserted for a single clock cycle, so latch them for an additional one +reg cpu_mem_read_lat, cpu_mem_write_lat; +wire cpu_mem_read_w, cpu_mem_write_w; +wire cpu_mem_read = cpu_mem_read_w | cpu_mem_read_lat; +wire cpu_mem_write = cpu_mem_write_w | cpu_mem_write_lat; + +wire cpu_io_read, cpu_io_write; +wire [7:0] cpu_io_in; +wire [7:0] cpu_io_out; +wire [7:0] cpu_io_addr; + +wire [15:0] cpu_mem_in; + +/* Global signals from schematics */ +wire IOWR = cpu_io_write; // IO Write +wire IORD = cpu_io_read; // IO Read +wire MWR = cpu_mem_write; // Mem Write +wire MRD = cpu_mem_read; // Mem Read + + +wire [15:0] cpu_word_out = cpu_mem_addr[0] ? { cpu_mem_out[7:0], 8'h00 } : cpu_mem_out; +wire [1:0] cpu_word_byte_sel = cpu_mem_addr[0] ? { cpu_mem_sel[0], 1'b0 } : cpu_mem_sel; +reg [15:0] cpu_ram_rom_data; +wire [24:0] cpu_region_addr; +wire cpu_region_writable; + +wire ram_rom_memrq; +wire buffer_memrq; +wire sprite_control_memrq; +wire video_control_memrq; +wire eeprom_memrq; +wire banked_memrq; + +wire [7:0] snd_latch_dout; +wire snd_latch_rdy; + +reg [1:0] ce_counter_cpu; +reg ce_cpu, ce_4x_cpu; +reg mem_rq_active = 0; + +always @(posedge clk_sys, negedge reset_n) begin + if (!reset_n) begin + ce_cpu <= 0; + ce_4x_cpu <= 0; + ce_counter_cpu <= 0; + end else begin + ce_cpu <= 0; + ce_4x_cpu <= 0; + + if (~paused) begin + if (~((ram_rom_memrq) & (cpu_mem_read | cpu_mem_write)) & ~mem_rq_active) begin // stall main cpu while fetching from sdram + ce_counter_cpu <= ce_counter_cpu + 2'd1; + ce_4x_cpu <= 1; + ce_cpu <= &ce_counter_cpu; + end + end + end +end + +function [15:0] word_shuffle(input [19:0] addr, input [15:0] data); + begin + word_shuffle = addr[0] ? { 8'h00, data[15:8] } : data; + end +endfunction + +always_ff @(posedge clk_sys or negedge reset_n) begin + if (!reset_n) begin + mem_rq_active <= 0; + end else begin + cpu_mem_read_lat <= cpu_mem_read_w; + cpu_mem_write_lat <= cpu_mem_write_w; + if (!mem_rq_active) begin + if (ram_rom_memrq & ((cpu_mem_read_w & ~cpu_mem_read_lat) | (cpu_mem_write_w & ~cpu_mem_write_lat))) begin // sdram request + sdr_cpu_wr_sel <= 2'b00; + sdr_cpu_addr <= cpu_region_addr; + if (cpu_mem_write & cpu_region_writable ) begin + sdr_cpu_wr_sel <= cpu_word_byte_sel; + sdr_cpu_din <= cpu_word_out; + end + sdr_cpu_req <= ~sdr_cpu_req; + mem_rq_active <= 1; + end + end else if (sdr_cpu_req == sdr_cpu_ack) begin + mem_rq_active <= 0; + cpu_ram_rom_data <= sdr_cpu_dout; + end + end +end + +wire rom0_ce, rom1_ce, ram_cs2; + +reg [7:0] dbg_io_latch; + +reg [3:0] bank_select = 4'd0; + + +wire [7:0] switches_p1 = board_cfg.kick_harness ? { p1_input[4], p1_input[5], p1_input[6], 1'b0, p1_input[3], p1_input[2], p1_input[1], p1_input[0] } + : { p1_input[4], p1_input[5], 1'b0, 1'b0, p1_input[3], p1_input[2], p1_input[1], p1_input[0] }; +wire [7:0] switches_p2 = board_cfg.kick_harness ? { p2_input[4], p2_input[5], p2_input[6], 1'b0, p2_input[3], p2_input[2], p2_input[1], p2_input[0] } + : { p2_input[4], p2_input[5], 1'b0, 1'b0, p2_input[3], p2_input[2], p2_input[1], p2_input[0] }; +wire [7:0] switches_p3 = board_cfg.kick_harness ? { 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0 } + : { p3_input[4], p3_input[5], coin[2], start_buttons[2], p3_input[3], p3_input[2], p3_input[1], p3_input[0] }; +wire [7:0] switches_p4 = board_cfg.kick_harness ? { p2_input[9], p2_input[8], p2_input[7], 1'b0, p1_input[9], p1_input[8], p1_input[7], 1'b0 } + : { p4_input[4], p4_input[5], coin[3], start_buttons[3], p4_input[3], p4_input[2], p4_input[1], p4_input[0] }; + +wire [15:0] switches_p1_p2 = { ~switches_p2, ~switches_p1 }; + +`ifdef M92_DEBUG_IO +wire [15:0] switches_p3_p4 = { dbg_io_latch, dbg_io_latch }; +`else +wire [15:0] switches_p3_p4 = { ~switches_p4, ~switches_p3 }; +`endif + +wire [15:0] flags = { ~dip_sw[23:16], ~dma_busy, 1'b1, 1'b1 /*TEST*/, 1'b1 /*R*/, ~coin[1:0], ~start_buttons[1:0] }; + +reg [7:0] sys_flags = 0; +wire COIN0 = sys_flags[0]; +wire COIN1 = sys_flags[1]; +wire SOFT_NL = ~sys_flags[2]; +wire CBLK = sys_flags[3]; +wire BRQ = ~sys_flags[4]; +wire BANK = sys_flags[5]; +wire NL = SOFT_NL ^ ~dip_sw[8]; + +// TODO BANK, CBLK, NL +always @(posedge clk_sys) begin + if (IOWR && cpu_io_addr == 8'h02) sys_flags <= cpu_io_out[7:0]; + if (IOWR && cpu_io_addr == 8'h20) bank_select <= cpu_io_out[3:0]; +end + +reg [15:0] vid_ctrl; +always @(posedge clk_sys or negedge reset_n) begin + if (~reset_n) begin + vid_ctrl <= 0; + end else if (video_control_memrq & MWR) begin + vid_ctrl <= cpu_word_out; + end +end + +`ifdef M92_DEBUG_IO +always @(posedge clk_sys or negedge reset_n) begin + if (~reset_n) begin + dbg_io_wait <= 0; + dbg_io_latch <= 8'hff; + end else begin + if (IORD && cpu_io_addr == 8'h06) begin + dbg_io_wait <= 0; + end + + if (dbg_io_write) begin + dbg_io_wait <= 1; + dbg_io_latch <= dbg_io_data; + end + end +end +`endif + +wire [15:0] ga21_dout; +wire [7:0] eeprom_dout; + +// mux io and memory reads +always_comb begin + bit [15:0] d16; + bit [15:0] io16; + + if (buffer_memrq) d16 = ga21_dout; + else if(eeprom_memrq) d16 = { eeprom_dout, eeprom_dout }; + else d16 = cpu_ram_rom_data; + cpu_mem_in = word_shuffle(cpu_mem_addr, d16); + + case ({cpu_io_addr[7:1], 1'b0}) + 8'h00: io16 = switches_p1_p2; + 8'h02: io16 = flags; + 8'h04: io16 = ~dip_sw[15:0]; + 8'h06: io16 = switches_p3_p4; + 8'h08: io16 = { snd_latch_dout, snd_latch_dout }; + default: io16 = 16'hffff; + endcase + + cpu_io_in = cpu_io_addr[0] ? io16[15:8] : io16[7:0]; +end + +wire int_req, int_ack; +wire [8:0] int_vector; + +v30 v30( + .clk(clk_sys), + .ce(ce_cpu), + .ce_4x(ce_4x_cpu), + .reset(~reset_n), + .turbo(1), + .SLOWTIMING(0), + + .cpu_idle(), + .cpu_halt(), + .cpu_irqrequest(), + .cpu_prefix(), + + .bus_read(cpu_mem_read_w), + .bus_write(cpu_mem_write_w), + .bus_be(cpu_mem_sel), + .bus_addr(cpu_mem_addr), + .bus_datawrite(cpu_mem_out), + .bus_dataread(cpu_mem_in), + + .irqrequest_in(int_req), + .irqvector_in(int_vector), + .irqrequest_ack(int_ack), + + // TODO + .cpu_done(), + + .RegBus_Din(cpu_io_out), + .RegBus_Adr(cpu_io_addr), + .RegBus_wren(cpu_io_write), + .RegBus_rden(cpu_io_read), + .RegBus_Dout(cpu_io_in) +); + +address_translator address_translator( + .A(cpu_mem_addr), + .board_cfg(board_cfg), + .ram_rom_memrq(ram_rom_memrq), + .sdr_addr(cpu_region_addr), + .writable(cpu_region_writable), + + .buffer_memrq(buffer_memrq), + .sprite_control_memrq(sprite_control_memrq), + .video_control_memrq(video_control_memrq), + .eeprom_memrq(eeprom_memrq), + + .bank_select(bank_select) +); + +wire vblank, hblank, vsync, hsync, vpulse, hpulse, hint; + +m92_pic m92_pic( + .clk(clk_sys), + .ce(ce_cpu), + .reset(~reset_n), + + .cs((IORD | IOWR) & ~cpu_io_addr[7] & cpu_io_addr[6] & ~cpu_io_addr[0]), // 0x40-0x43 + .wr(IOWR), + .rd(0), + .a0(cpu_io_addr[1]), + + .din(cpu_io_out), + + .int_req(int_req), + .int_vector(int_vector), + .int_ack(int_ack), + + .intp({4'd0, snd_latch_rdy, hint, ~dma_busy, vblank}) +); + +assign HSync = hsync; +assign HBlank = hblank; +assign VSync = vsync; +assign VBlank = vblank; + +wire objram_we; +wire [15:0] objram_data, objram_q; +wire [63:0] objram_q64; +wire [10:0] objram_addr; + +wire [11:0] ga22_color, ga23_color; +wire ga23_prio; + +objram objram( + .clk(clk_sys), + + .addr(objram_addr), + .we(objram_we), + + .data(objram_data), + + .q(objram_q), + .q64(objram_q64) +); + +wire bufram_we; +wire [15:0] bufram_data; +wire [15:0] bufram_q00, bufram_q01, bufram_q10, bufram_q11; +wire [10:0] bufram_addr; + +wire [1:0] bufram_cs = ( ~bufram_addr[10] & ~dma_busy ) ? { 1'b0, vid_ctrl[0] } : + ( bufram_addr[10] & ~dma_busy ) ? { vid_ctrl[2], vid_ctrl[1] } : + ( ~bufram_addr[10] & dma_busy ) ? { 1'b0, vid_ctrl[3] } : + ( bufram_addr[10] & dma_busy ) ? { vid_ctrl[5], vid_ctrl[4] } : 2'b00; + +wire [15:0] bufram_q; + +wire [12:0] ga21_palram_addr; +wire ga21_palram_we, ga21_palram_cs; +wire [15:0] ga21_palram_dout; +wire [15:0] palram_q; +wire [10:0] ga22_count; + + + +singleport_unreg_ram #(.widthad(13), .width(16), .name("BUFRAM")) bufram( + .clock(clk_sys), + .address({bufram_cs, bufram_addr}), + .q(bufram_q), + .wren(bufram_we), + .data(bufram_data) +); + +palram palram( + .clk(clk_sys), + + .ce_pix(ce_pix), + + .vid_ctrl(vid_ctrl), + .dma_busy(dma_busy), + + .cpu_addr(cpu_mem_addr[10:1]), + + .ga21_addr(ga21_palram_addr), + .ga21_we(ga21_palram_we), + .ga21_req(ga21_palram_cs), + + .obj_color(ga22_color[10:0]), + .obj_prio(ga22_color[11]), + .obj_active(|ga22_color[3:0]), + + .pf_color(ga23_color), + .pf_prio(~ga23_prio), + + .din(ga21_palram_dout), + .dout(palram_q), + + .rgb_out(rgb_color) +); + +GA21 ga21( + .clk(clk_sys), + .ce(ce_9m), + + .reset(), + + .din(cpu_word_out), + .dout(ga21_dout), + + .addr(cpu_mem_addr[11:1]), + + .reg_cs(sprite_control_memrq), + .buf_cs(buffer_memrq), + .wr(MWR), + + .busy(dma_busy), + + .obj_dout(objram_data), + .obj_din(objram_q), + .obj_addr(objram_addr), + .obj_we(objram_we), + + .buffer_dout(bufram_data), + .buffer_din(bufram_q), + .buffer_addr(bufram_addr), + .buffer_we(bufram_we), + + .count(ga22_count), + + .pal_addr(ga21_palram_addr), + .pal_dout(ga21_palram_dout), + .pal_din(palram_q), + .pal_we(ga21_palram_we), + .pal_cs(ga21_palram_cs) +); + +GA22 ga22( + .clk(clk_sys), + + .ce(ce_13m), // 13.33Mhz + + .ce_pix(ce_pix), // 6.66Mhz + + .reset(~reset_n), + + .color(ga22_color), + + .NL(NL), + .hpulse(hpulse), + .vpulse(vpulse), + + .count(ga22_count), + + .obj_in(objram_q64), + + .sdr_data(sdr_sprite_dout), + .sdr_addr(sdr_sprite_addr), + .sdr_req(sdr_sprite_req), + .sdr_ack(sdr_sprite_ack), + .sdr_refresh(sdr_sprite_refresh), + + .dbg_solid_sprites(dbg_solid_sprites) +); + +wire [14:0] vram_addr; +assign sdr_vram_addr = {REGION_VRAM.base_addr[24:16], vram_addr, 1'b0}; + +GA23 ga23( + .clk(clk_sys), + + .ce(ce_pix), + + .reset(~reset_n), + + .paused(paused), + + .io_wr(IOWR), + .addr(IOWR ? {8'd0, cpu_io_addr} : cpu_mem_addr), + .cpu_din(IOWR ? {8'd0, cpu_io_out} : cpu_mem_out), + + .vram_addr(vram_addr), + .vram_din(sdr_vram_data), + .vram_req(sdr_vram_req), + + .large_tileset(board_cfg.large_tileset), + + .sdr_data_a(sdr_bg_data_a), + .sdr_addr_a(sdr_bg_addr_a), + .sdr_req_a(sdr_bg_req_a), + .sdr_ack_a(sdr_bg_ack_a), + + .sdr_data_b(sdr_bg_data_b), + .sdr_addr_b(sdr_bg_addr_b), + .sdr_req_b(sdr_bg_req_b), + .sdr_ack_b(sdr_bg_ack_b), + + .sdr_data_c(sdr_bg_data_c), + .sdr_addr_c(sdr_bg_addr_c), + .sdr_req_c(sdr_bg_req_c), + .sdr_ack_c(sdr_bg_ack_c), + + .vblank(vblank), + .hblank(hblank), + .vsync(vsync), + .hsync(hsync), + .hpulse(hpulse), + .vpulse(vpulse), + + .hint(hint), + + .color_out(ga23_color), + .prio_out(ga23_prio), + + .dbg_en_layers(dbg_en_layers) +); + +/* +// Sound board test (select sound with P1 left/right) +reg [7:0] snd_id; +reg snd_wr; +reg left_last, right_last; +wire left = p1_input[1]; +wire right = p1_input[0]; + +always @(posedge clk_sys) begin + if (!reset_n) begin + snd_wr <= 0; + snd_id <= 0; + end else begin + snd_wr <= 0; + left_last <= left; + right_last <= right; + if (!left_last & left) begin + snd_id <= snd_id - 1'd1; + snd_wr <= 1; + end + if (!right_last & right) begin + snd_id <= snd_id + 1'd1; + snd_wr <= 1; + end + end + +end +*/ +wire [15:0] sound_sample; + +sound sound( + .clk_sys(clk_sys), + .reset(~reset_n), + .filter_en(en_audio_filters), + .dbg_fm_en(dbg_fm_en), + .paused(paused), + + .latch_wr(IOWR & cpu_io_addr == 8'h00), + //.latch_wr(snd_wr), + .latch_rd(IORD & cpu_io_addr == 8'h08), + .latch_din(cpu_io_out), + //.latch_din(snd_id), + .latch_dout(snd_latch_dout), + .latch_rdy(snd_latch_rdy), + + .rom_addr(bram_addr), + .rom_data(bram_data), + .rom_wr(bram_wr & bram_cs[1]), + + .secure_addr(bram_addr[7:0]), + .secure_data(bram_data), + .secure_wr(bram_wr & bram_cs[0]), + + .sample(sound_sample), + + .sdr_cpu_addr(sdr_audio_cpu_addr), + .sdr_cpu_dout(sdr_audio_cpu_dout), + .sdr_cpu_din(sdr_audio_cpu_din), + .sdr_cpu_req(sdr_audio_cpu_req), + .sdr_cpu_ack(sdr_audio_cpu_ack), + .sdr_cpu_wr_sel(sdr_audio_cpu_wr_sel), + + .sdr_addr(sdr_audio_addr), + .sdr_data(sdr_audio_dout), + .sdr_req(sdr_audio_req), + .sdr_ack(sdr_audio_ack) +); + +assign AUDIO_L = sound_sample; +assign AUDIO_R = sound_sample; + +eeprom_28C64 eeprom( + .clk(clk_sys), + .reset(~reset_n), + .ce(1), + + .rd(MRD & eeprom_memrq), + .wr(MWR & eeprom_memrq), + + .addr(cpu_mem_addr[13:1]), + .q(eeprom_dout), + .data(cpu_mem_out[7:0]), + + .ready(), + + .modified(ioctl_upload_req), + .ioctl_download(ioctl_download | bram_cs[2]), + .ioctl_wr(bram_cs[2] ? bram_wr : ioctl_wr), + .ioctl_addr(bram_cs[2] ? bram_addr[12:0] : ioctl_addr[12:0]), + .ioctl_dout(ioctl_dout), + + .ioctl_upload(ioctl_upload), + .ioctl_din(ioctl_din), + .ioctl_rd(ioctl_rd) +); + +endmodule diff --git a/Arcade_MiST/IremM92 Hardware/rtl/m92_pic.sv b/Arcade_MiST/IremM92 Hardware/rtl/m92_pic.sv new file mode 100644 index 00000000..c0f2c89f --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/rtl/m92_pic.sv @@ -0,0 +1,153 @@ +//============================================================================ +// Irem M92 for MiSTer FPGA - Programmable interrupt controller +// +// Copyright (C) 2023 Martin Donlon +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +//============================================================================ + +module m92_pic( + input clk, + input ce, + input reset, + + input cs, + input wr, + input rd, + input a0, + + input [7:0] din, + + output int_req, + output reg [8:0] int_vector, + input int_ack, + + input [7:0] intp +); + +enum { + UNINIT, + INIT_IW2, + INIT_IW3, + INIT_IW4, + INIT_DONE +} init_state = UNINIT; + +reg [7:0] IW1, IW2, IW3, IW4; +reg [7:0] IMW; +reg [7:0] PFCW; +reg [7:0] MCW; + +reg [7:0] IRR; +int ISR; + +wire [7:0] IRQ = ( IRR & ~IMW ); +assign int_req = IRQ != 8'd0; + +wire iw4_write = IW1[0]; +wire iw4_not_written = ~IW1[0]; +wire single_mode = IW1[1]; +wire extended_mode = ~IW1[1]; +wire address_gap_4 = IW1[2]; +wire address_gap_8 = ~IW1[2]; +wire level_triggered = IW1[3]; +wire edge_triggered = ~IW1[3]; + +reg [7:0] intp_latch = 0; + +always_ff @(posedge clk or posedge reset) begin + if (reset) begin + init_state <= UNINIT; + intp_latch <= 0; + IRR <= 8'd0; + ISR <= 8; + end else if (ce) begin + if (cs & wr) begin + if (~a0) begin + if (din[4]) begin + init_state <= INIT_IW2; + IW1 <= din; + PFCW <= 0; + MCW <= 0; + IMW <= 0; + IRR <= 0; + ISR <= 8; + end else if (~din[4] & ~din[3]) begin + PFCW <= din; + end else if (~din[4] & din[3]) begin + MCW <= din; + end + end + + if (a0) begin + case (init_state) + INIT_IW2: begin + IW2 <= din; + if (extended_mode) init_state <= INIT_IW3; + else if (iw4_write) init_state <= INIT_IW4; + else init_state <= INIT_DONE; + end + INIT_IW3: begin + IW3 <= din; + if (iw4_write) init_state <= INIT_IW4; + else init_state <= INIT_DONE; + end + INIT_IW4: begin + IW4 <= din; + init_state <= INIT_DONE; + end + INIT_DONE: begin + IMW <= din; + end + endcase + end + end + + if (init_state == INIT_DONE) begin + bit [7:0] trig; + int p; + + intp_latch <= intp; + + if (int_req) begin + if (int_ack) begin + if ( IRQ[0] ) begin int_vector <= {IW2[6:3], 3'd0, 2'b00}; IRR[0] <= 0; end + else if ( IRQ[1] ) begin int_vector <= {IW2[6:3], 3'd1, 2'b00}; IRR[1] <= 0; end + else if ( IRQ[2] ) begin int_vector <= {IW2[6:3], 3'd2, 2'b00}; IRR[2] <= 0; end + else if ( IRQ[3] ) begin int_vector <= {IW2[6:3], 3'd3, 2'b00}; IRR[3] <= 0; end + else if ( IRQ[4] ) begin int_vector <= {IW2[6:3], 3'd4, 2'b00}; IRR[4] <= 0; end + else if ( IRQ[5] ) begin int_vector <= {IW2[6:3], 3'd5, 2'b00}; IRR[5] <= 0; end + else if ( IRQ[6] ) begin int_vector <= {IW2[6:3], 3'd6, 2'b00}; IRR[6] <= 0; end + else if ( IRQ[7] ) begin int_vector <= {IW2[6:3], 3'd7, 2'b00}; IRR[7] <= 0; end + end + end + + if (edge_triggered) + trig = intp & ~intp_latch; + else + trig = intp; + + for( p = 0; p < 8; p = p + 1 ) begin + if (intp[p]) begin + if (trig[p]) begin + IRR[p] <= 1'b1; + end + end + end + end + end +end + +endmodule \ No newline at end of file diff --git a/Arcade_MiST/IremM92 Hardware/rtl/m92_pkg.sv b/Arcade_MiST/IremM92 Hardware/rtl/m92_pkg.sv new file mode 100644 index 00000000..79c8fb04 --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/rtl/m92_pkg.sv @@ -0,0 +1,61 @@ +//============================================================================ +// Irem M92 for MiSTer FPGA - Common definitions +// +// Copyright (C) 2023 Martin Donlon +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +//============================================================================ + +package m92_pkg; + + typedef struct packed { + bit [27:0] base_addr; + bit reorder_64; + bit [4:0] bram_cs; + } region_t; + + parameter region_t REGION_CPU_ROM = '{ 28'h000_0000, 0, 5'b00000 }; + parameter region_t REGION_CPU_RAM = '{ 28'h010_0000, 0, 5'b00000 }; + parameter region_t REGION_SOUND = '{ 28'h020_0000, 0, 5'b00000 }; + parameter region_t REGION_GA20 = '{ 28'h030_0000, 0, 5'b00000 }; + parameter region_t REGION_SPRITE = '{ 28'h040_0000, 1, 5'b00000 }; + parameter region_t REGION_TILE = '{ 28'h0c0_0000, 0, 5'b00000 }; + parameter region_t REGION_CRYPT = '{ 28'h000_0000, 0, 5'b00001 }; + parameter region_t REGION_WIDE_SPRITE = '{ 28'h040_0000, 0, 5'b00000 }; + parameter region_t REGION_EEPROM = '{ 28'h000_0000, 0, 5'b00100 }; + + parameter region_t REGION_VRAM = '{ 28'h070_0000, 0, 5'b00000 }; + parameter region_t REGION_SOUND_RAM = '{ 28'h078_0000, 0, 5'b00000 }; + + parameter region_t LOAD_REGIONS[8] = '{ + REGION_CPU_ROM, + REGION_TILE, + REGION_SPRITE, + REGION_SOUND, + REGION_CRYPT, + REGION_GA20, + REGION_WIDE_SPRITE, + REGION_EEPROM + }; + + + typedef struct packed { + bit large_tileset; + bit kick_harness; + bit wide_sprites; + bit alt_map; + bit [3:0] bank_mask; + } board_cfg_t; +endpackage \ No newline at end of file diff --git a/Arcade_MiST/IremM92 Hardware/rtl/objram.sv b/Arcade_MiST/IremM92 Hardware/rtl/objram.sv new file mode 100644 index 00000000..ddfd5d98 --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/rtl/objram.sv @@ -0,0 +1,77 @@ +//============================================================================ +// Copyright (C) 2023 Martin Donlon +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +//============================================================================ + +module objram( + input clk, + + input [10:0] addr, + input we, + + input [15:0] data, + + output [15:0] q, + output [63:0] q64 +); + +wire [1:0] col = addr[1:0]; +wire [63:0] data64 = { col == 2'd3 ? data : 16'd0, col == 2'd2 ? data : 16'd0, col == 2'd1 ? data : 16'd0, col == 2'd0 ? data : 16'd0 }; +wire [7:0] byte_en = { col == 2'd3 ? 2'b11 : 2'b00, col == 2'd2 ? 2'b11 : 2'b00, col == 2'd1 ? 2'b11 : 2'b00, col == 2'd0 ? 2'b11 : 2'b00 }; +assign q = col == 2'd0 ? q64[15:0] : col == 2'd1 ? q64[31:16] : col == 2'd2 ? q64[47:32] : q64[63:48]; + +altsyncram altsyncram_component ( + .address_a (addr[10:2]), + .byteena_a (byte_en), + .clock0 (clk), + .data_a (data64), + .wren_a (we), + .q_a (q64), + .aclr0 (1'b0), + .aclr1 (1'b0), + .address_b (1'b1), + .addressstall_a (1'b0), + .addressstall_b (1'b0), + .byteena_b (1'b1), + .clock1 (1'b1), + .clocken0 (1'b1), + .clocken1 (1'b1), + .clocken2 (1'b1), + .clocken3 (1'b1), + .data_b (1'b1), + .eccstatus (), + .q_b (), + .rden_a (1'b1), + .rden_b (1'b1), + .wren_b (1'b0)); +defparam + altsyncram_component.byte_size = 8, + altsyncram_component.clock_enable_input_a = "BYPASS", + altsyncram_component.clock_enable_output_a = "BYPASS", + altsyncram_component.intended_device_family = "Cyclone V", + altsyncram_component.lpm_hint = "ENABLE_RUNTIME_MOD=NO", + altsyncram_component.lpm_type = "altsyncram", + altsyncram_component.numwords_a = 512, + altsyncram_component.operation_mode = "SINGLE_PORT", + altsyncram_component.outdata_aclr_a = "NONE", + altsyncram_component.outdata_reg_a = "UNREGISTERED", + altsyncram_component.power_up_uninitialized = "FALSE", + altsyncram_component.read_during_write_mode_port_a = "DONT_CARE", + altsyncram_component.widthad_a = 9, + altsyncram_component.width_a = 64, + altsyncram_component.width_byteena_a = 8; + +endmodule \ No newline at end of file diff --git a/Arcade_MiST/IremM92 Hardware/rtl/pal.sv b/Arcade_MiST/IremM92 Hardware/rtl/pal.sv new file mode 100644 index 00000000..2b9a8bd8 --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/rtl/pal.sv @@ -0,0 +1,85 @@ +//============================================================================ +// Irem M92 for MiSTer FPGA - PAL address decoders +// +// Copyright (C) 2023 Martin Donlon +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +//============================================================================ + + +import m92_pkg::*; + +module address_translator +( + input logic [19:0] A, + + input logic [3:0] bank_select, + + input board_cfg_t board_cfg, + + output [24:0] sdr_addr, + output writable, + output ram_rom_memrq, + + output buffer_memrq, + output sprite_control_memrq, + output video_control_memrq, + output eeprom_memrq +); + +wire [3:0] bank_a19_16 = ( bank_select & board_cfg.bank_mask ) | ( A[19:16] & ~board_cfg.bank_mask ); + +always_comb begin + ram_rom_memrq = 0; + writable = 0; + sdr_addr = 0; + + buffer_memrq = 0; + sprite_control_memrq = 0; + video_control_memrq = 0; + eeprom_memrq = 0; + + casex (A[19:0]) + // 0xc0000-0xcffff + 20'b1100_xxxx_xxxx_xxxx_xxxx: begin ram_rom_memrq = 1; writable = 0; sdr_addr = { REGION_CPU_ROM.base_addr[24:16], A[15:0] }; end + // 0xd0000-0xdffff + 20'b1101_xxxx_xxxx_xxxx_xxxx: begin ram_rom_memrq = 1; writable = 1; sdr_addr = { REGION_VRAM.base_addr[24:16], A[15:0] }; end + // 0xe0000-0xeffff + 20'b1110_xxxx_xxxx_xxxx_xxxx: begin ram_rom_memrq = 1; writable = 1; sdr_addr = { REGION_CPU_RAM.base_addr[24:16], A[15:0] }; end + // 0xf0000-0xf3fff + 20'b1111_00xx_xxxx_xxxx_xxxx: eeprom_memrq = 1; + // 0xf8000-0xf87ff + 20'b1111_1000_xxxx_xxxx_xxxx: buffer_memrq = 1; + // 0xf9000-0xf900f + 20'b1111_1001_0000_0000_xxxx: sprite_control_memrq = 1; + // 0xf9800-0xf9801 + 20'b1111_1001_1000_0000_000x: video_control_memrq = 1; + // 0xffff0-0xfffff + 20'b1111_1111_1111_1111_xxxx: begin ram_rom_memrq = 1; writable = 0; sdr_addr = { REGION_CPU_ROM.base_addr[24:20], 16'h7fff, A[3:0] }; end + // 0x00000-0xbffff + default: begin + if (board_cfg.alt_map && A[19:16] == 4'h8) begin + ram_rom_memrq = 1; + writable = 1; + sdr_addr = { REGION_VRAM.base_addr[24:16], A[15:0] }; + end else begin + ram_rom_memrq = 1; + writable = 0; + sdr_addr = { REGION_CPU_ROM.base_addr[24:20], A[19:17] == 3'b101 ? bank_a19_16 : A[19:16], A[15:0] }; + end + end + endcase +end +endmodule diff --git a/Arcade_MiST/IremM92 Hardware/rtl/palram.sv b/Arcade_MiST/IremM92 Hardware/rtl/palram.sv new file mode 100644 index 00000000..0c722707 --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/rtl/palram.sv @@ -0,0 +1,84 @@ +//============================================================================ +// Copyright (C) 2023 Martin Donlon +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +//============================================================================ + +module palram( + input clk, + + input ce_pix, + + input [15:0] vid_ctrl, + input dma_busy, + + input [9:0] cpu_addr, + + input [12:0] ga21_addr, + input ga21_we, + input ga21_req, + + input [10:0] obj_color, + input obj_prio, + input obj_active, + + input [10:0] pf_color, + input pf_prio, + + input [15:0] din, + output [15:0] dout, + + output reg [15:0] rgb_out +); + +wire obj_pal_bank = ~vid_ctrl[13] & obj_prio; +wire obj_avail = ~vid_ctrl[7] & obj_active; + +wire n_sela = ~dma_busy & ( + ( vid_ctrl[13] & obj_prio & obj_avail ) | + ( ~obj_prio & pf_prio & obj_avail ) | + ( ~vid_ctrl[13] & obj_prio & pf_prio & obj_avail ) | + ( vid_ctrl[12] ) | + ga21_req +); + +wire selb = ~dma_busy & ~ga21_req & ~vid_ctrl[12]; + +wire [1:0] sel = { selb, ~n_sela }; + +wire [12:0] full_cpu_addr = { vid_ctrl[10:8], cpu_addr[9:0] }; +wire [12:0] obj_addr = { vid_ctrl[15], obj_pal_bank, obj_color }; +wire [12:0] pf_addr = { vid_ctrl[15], vid_ctrl[14], pf_color }; + +wire we = sel == 0 ? ga21_we : sel == 1 ? ga21_we : 1'b0; +wire [12:0] selected_addr = sel == 0 ? full_cpu_addr : + sel == 1 ? ga21_addr : + sel == 2 ? obj_addr : + pf_addr; + +singleport_unreg_ram #(.widthad(13), .width(16), .name("PALRAM")) ram +( + .clock(clk), + .address(selected_addr), + .q(dout), + .wren(we), + .data(din) +); + +always_ff @(posedge clk) begin + if (ce_pix) rgb_out <= dout; +end + +endmodule \ No newline at end of file diff --git a/Arcade_MiST/IremM92 Hardware/rtl/pll_mist.qip b/Arcade_MiST/IremM92 Hardware/rtl/pll_mist.qip new file mode 100644 index 00000000..6182871f --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/rtl/pll_mist.qip @@ -0,0 +1,4 @@ +set_global_assignment -name IP_TOOL_NAME "ALTPLL" +set_global_assignment -name IP_TOOL_VERSION "13.1" +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "pll_mist.v"] +set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll_mist.ppf"] diff --git a/Arcade_MiST/IremM92 Hardware/rtl/pll_mist.v b/Arcade_MiST/IremM92 Hardware/rtl/pll_mist.v new file mode 100644 index 00000000..59ee6382 --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/rtl/pll_mist.v @@ -0,0 +1,365 @@ +// megafunction wizard: %ALTPLL% +// GENERATION: STANDARD +// VERSION: WM1.0 +// MODULE: altpll + +// ============================================================ +// File Name: pll_mist.v +// Megafunction Name(s): +// altpll +// +// Simulation Library Files(s): +// altera_mf +// ============================================================ +// ************************************************************ +// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! +// +// 13.1.4 Build 182 03/12/2014 SJ Web Edition +// ************************************************************ + + +//Copyright (C) 1991-2014 Altera Corporation +//Your use of Altera Corporation's design tools, logic functions +//and other software and tools, and its AMPP partner logic +//functions, and any output files from any of the foregoing +//(including device programming or simulation files), and any +//associated documentation or information are expressly subject +//to the terms and conditions of the Altera Program License +//Subscription Agreement, Altera MegaCore Function License +//Agreement, or other applicable license agreement, including, +//without limitation, that your use is for the sole purpose of +//programming logic devices manufactured by Altera and sold by +//Altera or its authorized distributors. Please refer to the +//applicable agreement for further details. + + +// synopsys translate_off +`timescale 1 ps / 1 ps +// synopsys translate_on +module pll_mist ( + inclk0, + c0, + c1, + c2, + locked); + + input inclk0; + output c0; + output c1; + output c2; + output locked; + + wire [4:0] sub_wire0; + wire sub_wire2; + wire [0:0] sub_wire7 = 1'h0; + wire [2:2] sub_wire4 = sub_wire0[2:2]; + wire [0:0] sub_wire3 = sub_wire0[0:0]; + wire [1:1] sub_wire1 = sub_wire0[1:1]; + wire c1 = sub_wire1; + wire locked = sub_wire2; + wire c0 = sub_wire3; + wire c2 = sub_wire4; + wire sub_wire5 = inclk0; + wire [1:0] sub_wire6 = {sub_wire7, sub_wire5}; + + altpll altpll_component ( + .inclk (sub_wire6), + .clk (sub_wire0), + .locked (sub_wire2), + .activeclock (), + .areset (1'b0), + .clkbad (), + .clkena ({6{1'b1}}), + .clkloss (), + .clkswitch (1'b0), + .configupdate (1'b0), + .enable0 (), + .enable1 (), + .extclk (), + .extclkena ({4{1'b1}}), + .fbin (1'b1), + .fbmimicbidir (), + .fbout (), + .fref (), + .icdrclk (), + .pfdena (1'b1), + .phasecounterselect ({4{1'b1}}), + .phasedone (), + .phasestep (1'b1), + .phaseupdown (1'b1), + .pllena (1'b1), + .scanaclr (1'b0), + .scanclk (1'b0), + .scanclkena (1'b1), + .scandata (1'b0), + .scandataout (), + .scandone (), + .scanread (1'b0), + .scanwrite (1'b0), + .sclkout0 (), + .sclkout1 (), + .vcooverrange (), + .vcounderrange ()); + defparam + altpll_component.bandwidth_type = "AUTO", + altpll_component.clk0_divide_by = 9, + altpll_component.clk0_duty_cycle = 50, + altpll_component.clk0_multiply_by = 40, + altpll_component.clk0_phase_shift = "-694", + altpll_component.clk1_divide_by = 9, + altpll_component.clk1_duty_cycle = 50, + altpll_component.clk1_multiply_by = 40, + altpll_component.clk1_phase_shift = "0", + altpll_component.clk2_divide_by = 27, + altpll_component.clk2_duty_cycle = 50, + altpll_component.clk2_multiply_by = 40, + altpll_component.clk2_phase_shift = "0", + altpll_component.compensate_clock = "CLK0", + altpll_component.inclk0_input_frequency = 37037, + altpll_component.intended_device_family = "Cyclone III", + altpll_component.lpm_hint = "CBX_MODULE_PREFIX=pll_mist", + altpll_component.lpm_type = "altpll", + altpll_component.operation_mode = "NORMAL", + altpll_component.pll_type = "AUTO", + altpll_component.port_activeclock = "PORT_UNUSED", + altpll_component.port_areset = "PORT_UNUSED", + altpll_component.port_clkbad0 = "PORT_UNUSED", + altpll_component.port_clkbad1 = "PORT_UNUSED", + altpll_component.port_clkloss = "PORT_UNUSED", + altpll_component.port_clkswitch = "PORT_UNUSED", + altpll_component.port_configupdate = "PORT_UNUSED", + altpll_component.port_fbin = "PORT_UNUSED", + altpll_component.port_inclk0 = "PORT_USED", + altpll_component.port_inclk1 = "PORT_UNUSED", + altpll_component.port_locked = "PORT_USED", + altpll_component.port_pfdena = "PORT_UNUSED", + altpll_component.port_phasecounterselect = "PORT_UNUSED", + altpll_component.port_phasedone = "PORT_UNUSED", + altpll_component.port_phasestep = "PORT_UNUSED", + altpll_component.port_phaseupdown = "PORT_UNUSED", + altpll_component.port_pllena = "PORT_UNUSED", + altpll_component.port_scanaclr = "PORT_UNUSED", + altpll_component.port_scanclk = "PORT_UNUSED", + altpll_component.port_scanclkena = "PORT_UNUSED", + altpll_component.port_scandata = "PORT_UNUSED", + altpll_component.port_scandataout = "PORT_UNUSED", + altpll_component.port_scandone = "PORT_UNUSED", + altpll_component.port_scanread = "PORT_UNUSED", + altpll_component.port_scanwrite = "PORT_UNUSED", + altpll_component.port_clk0 = "PORT_USED", + altpll_component.port_clk1 = "PORT_USED", + altpll_component.port_clk2 = "PORT_USED", + altpll_component.port_clk3 = "PORT_UNUSED", + altpll_component.port_clk4 = "PORT_UNUSED", + altpll_component.port_clk5 = "PORT_UNUSED", + altpll_component.port_clkena0 = "PORT_UNUSED", + altpll_component.port_clkena1 = "PORT_UNUSED", + altpll_component.port_clkena2 = "PORT_UNUSED", + altpll_component.port_clkena3 = "PORT_UNUSED", + altpll_component.port_clkena4 = "PORT_UNUSED", + altpll_component.port_clkena5 = "PORT_UNUSED", + altpll_component.port_extclk0 = "PORT_UNUSED", + altpll_component.port_extclk1 = "PORT_UNUSED", + altpll_component.port_extclk2 = "PORT_UNUSED", + altpll_component.port_extclk3 = "PORT_UNUSED", + altpll_component.self_reset_on_loss_lock = "OFF", + altpll_component.width_clock = 5; + + +endmodule + +// ============================================================ +// CNX file retrieval info +// ============================================================ +// Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0" +// Retrieval info: PRIVATE: BANDWIDTH STRING "1.000" +// Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "1" +// Retrieval info: PRIVATE: BANDWIDTH_FREQ_UNIT STRING "MHz" +// Retrieval info: PRIVATE: BANDWIDTH_PRESET STRING "Low" +// Retrieval info: PRIVATE: BANDWIDTH_USE_AUTO STRING "1" +// Retrieval info: PRIVATE: BANDWIDTH_USE_PRESET STRING "0" +// Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0" +// Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0" +// Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "0" +// Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "0" +// Retrieval info: PRIVATE: CREATE_CLKBAD_CHECK STRING "0" +// Retrieval info: PRIVATE: CREATE_INCLK1_CHECK STRING "0" +// Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0" +// Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "c0" +// Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "8" +// Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "1" +// Retrieval info: PRIVATE: DIV_FACTOR1 NUMERIC "1" +// Retrieval info: PRIVATE: DIV_FACTOR2 NUMERIC "1" +// Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000" +// Retrieval info: PRIVATE: DUTY_CYCLE1 STRING "50.00000000" +// Retrieval info: PRIVATE: DUTY_CYCLE2 STRING "50.00000000" +// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "120.000000" +// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "120.000000" +// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE2 STRING "40.000000" +// Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0" +// Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0" +// Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1" +// Retrieval info: PRIVATE: GLOCKED_FEATURE_ENABLED STRING "0" +// Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0" +// Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575" +// Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1" +// Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "27.000" +// Retrieval info: PRIVATE: INCLK0_FREQ_UNIT_COMBO STRING "MHz" +// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT STRING "100.000" +// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT_CHANGED STRING "1" +// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_CHANGED STRING "1" +// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_COMBO STRING "MHz" +// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone III" +// Retrieval info: PRIVATE: INT_FEEDBACK__MODE_RADIO STRING "1" +// Retrieval info: PRIVATE: LOCKED_OUTPUT_CHECK STRING "1" +// Retrieval info: PRIVATE: LONG_SCAN_RADIO STRING "1" +// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "Not Available" +// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0" +// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg" +// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT1 STRING "deg" +// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT2 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: MIRROR_CLK2 STRING "0" +// Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "1" +// Retrieval info: PRIVATE: MULT_FACTOR1 NUMERIC "1" +// Retrieval info: PRIVATE: MULT_FACTOR2 NUMERIC "1" +// Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1" +// Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "120.00000000" +// Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "120.00000000" +// Retrieval info: PRIVATE: OUTPUT_FREQ2 STRING "40.00000000" +// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "1" +// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE1 STRING "1" +// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE2 STRING "1" +// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz" +// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT1 STRING "MHz" +// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT2 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.69444400" +// Retrieval info: PRIVATE: PHASE_SHIFT1 STRING "0.00000000" +// Retrieval info: PRIVATE: PHASE_SHIFT2 STRING "0.00000000" +// Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0" +// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "ns" +// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT1 STRING "deg" +// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT2 STRING "ps" +// Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0" +// Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "0" +// Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1" +// Retrieval info: PRIVATE: PLL_ENHPLL_CHECK NUMERIC "0" +// Retrieval info: PRIVATE: PLL_FASTPLL_CHECK NUMERIC "0" +// Retrieval info: PRIVATE: PLL_FBMIMIC_CHECK STRING "0" +// Retrieval info: PRIVATE: PLL_LVDS_PLL_CHECK NUMERIC "0" +// Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0" +// Retrieval info: PRIVATE: PLL_TARGET_HARCOPY_CHECK NUMERIC "0" +// Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0" +// Retrieval info: PRIVATE: RECONFIG_FILE STRING "pll_mist.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: STICKY_CLK2 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_CLK2 STRING "1" +// Retrieval info: PRIVATE: USE_CLKENA0 STRING "0" +// Retrieval info: PRIVATE: USE_CLKENA1 STRING "0" +// Retrieval info: PRIVATE: USE_CLKENA2 STRING "0" +// Retrieval info: PRIVATE: USE_MIL_SPEED_GRADE NUMERIC "0" +// Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0" +// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all +// Retrieval info: CONSTANT: BANDWIDTH_TYPE STRING "AUTO" +// Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "9" +// Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50" +// Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "40" +// Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "-694" +// Retrieval info: CONSTANT: CLK1_DIVIDE_BY NUMERIC "9" +// Retrieval info: CONSTANT: CLK1_DUTY_CYCLE NUMERIC "50" +// Retrieval info: CONSTANT: CLK1_MULTIPLY_BY NUMERIC "40" +// Retrieval info: CONSTANT: CLK1_PHASE_SHIFT STRING "0" +// Retrieval info: CONSTANT: CLK2_DIVIDE_BY NUMERIC "27" +// Retrieval info: CONSTANT: CLK2_DUTY_CYCLE NUMERIC "50" +// Retrieval info: CONSTANT: CLK2_MULTIPLY_BY NUMERIC "40" +// Retrieval info: CONSTANT: CLK2_PHASE_SHIFT STRING "0" +// Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0" +// Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "37037" +// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III" +// Retrieval info: CONSTANT: LPM_TYPE STRING "altpll" +// Retrieval info: CONSTANT: OPERATION_MODE STRING "NORMAL" +// Retrieval info: CONSTANT: PLL_TYPE STRING "AUTO" +// Retrieval info: CONSTANT: PORT_ACTIVECLOCK STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_ARESET STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_CLKBAD0 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_CLKBAD1 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_CLKLOSS STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_CLKSWITCH STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_CONFIGUPDATE STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_FBIN STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_INCLK0 STRING "PORT_USED" +// Retrieval info: CONSTANT: PORT_INCLK1 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_LOCKED STRING "PORT_USED" +// Retrieval info: CONSTANT: PORT_PFDENA STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_PHASECOUNTERSELECT STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_PHASEDONE STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_PHASESTEP STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_PHASEUPDOWN STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_PLLENA STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANACLR STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANCLK STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANCLKENA STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANDATA STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANDATAOUT STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANDONE STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANREAD STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANWRITE STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clk0 STRING "PORT_USED" +// Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_USED" +// Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_USED" +// Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clk5 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena0 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena1 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena2 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena3 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena4 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena5 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_extclk0 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_extclk1 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_extclk2 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_extclk3 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: SELF_RESET_ON_LOSS_LOCK STRING "OFF" +// Retrieval info: CONSTANT: WIDTH_CLOCK NUMERIC "5" +// Retrieval info: USED_PORT: @clk 0 0 5 0 OUTPUT_CLK_EXT VCC "@clk[4..0]" +// Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT_CLK_EXT VCC "c0" +// Retrieval info: USED_PORT: c1 0 0 0 0 OUTPUT_CLK_EXT VCC "c1" +// Retrieval info: USED_PORT: c2 0 0 0 0 OUTPUT_CLK_EXT VCC "c2" +// Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0" +// Retrieval info: USED_PORT: locked 0 0 0 0 OUTPUT GND "locked" +// Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0 +// Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0 +// Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0 +// Retrieval info: CONNECT: c1 0 0 0 0 @clk 0 0 1 1 +// Retrieval info: CONNECT: c2 0 0 0 0 @clk 0 0 1 2 +// Retrieval info: CONNECT: locked 0 0 0 0 @locked 0 0 0 0 +// Retrieval info: GEN_FILE: TYPE_NORMAL pll_mist.v TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll_mist.ppf TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll_mist.inc FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll_mist.cmp FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll_mist.bsf FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll_mist_inst.v FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll_mist_bb.v FALSE +// Retrieval info: LIB_FILE: altera_mf +// Retrieval info: CBX_MODULE_PREFIX: ON diff --git a/Arcade_MiST/IremM92 Hardware/rtl/rom.sv b/Arcade_MiST/IremM92 Hardware/rtl/rom.sv new file mode 100644 index 00000000..f2a7c368 --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/rtl/rom.sv @@ -0,0 +1,124 @@ +//============================================================================ +// Irem M72 for MiSTer FPGA - ROM loading +// +// Copyright (C) 2022 Martin Donlon +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +//============================================================================ + +import m92_pkg::*; + +module rom_loader +( + input sys_clk, + + input ioctl_downl, + input ioctl_wr, + input [7:0] ioctl_data, + + output ioctl_wait, + + output [24:0] sdr_addr, + output [15:0] sdr_data, + output [1:0] sdr_be, + output reg sdr_req, + input sdr_ack, + + output [19:0] bram_addr, + output [7:0] bram_data, + output reg [4:0] bram_cs, + output bram_wr, + + output board_cfg_t board_cfg +); + +reg [27:0] base_addr; +reg reorder_64; +reg [24:0] offset; +reg [23:0] size; + +enum { + BOARD_CFG, + REGION_IDX, + SIZE_0, + SIZE_1, + SIZE_2, + SDR_DATA, + BRAM_DATA +} stage = BOARD_CFG; + +integer region = 0; + +always @(posedge sys_clk) begin + if (!ioctl_downl) begin + stage <= BOARD_CFG; + region <= 0; + bram_cs <= 0; + end + if (sdr_ack == sdr_req) begin + ioctl_wait <= 0; + end + bram_wr <= 0; + + if (ioctl_wr) begin + case (stage) + BOARD_CFG: begin board_cfg <= board_cfg_t'(ioctl_data); stage <= REGION_IDX; end + REGION_IDX: begin + if (ioctl_data == 8'hff) region <= region + 4'd1; + else region <= ioctl_data[3:0]; + stage <= SIZE_0; + end + SIZE_0: begin size[23:16] <= ioctl_data; stage <= SIZE_1; end + SIZE_1: begin size[15:8] <= ioctl_data; stage <= SIZE_2; end + SIZE_2: begin + size[7:0] <= ioctl_data; + base_addr <= LOAD_REGIONS[region].base_addr; + reorder_64 <= LOAD_REGIONS[region].reorder_64; + bram_cs <= LOAD_REGIONS[region].bram_cs; + offset <= 25'd0; + + if ({size[23:8], ioctl_data} == 24'd0) + stage <= REGION_IDX; + else if (LOAD_REGIONS[region].bram_cs != 0) + stage <= BRAM_DATA; + else + stage <= SDR_DATA; + end + SDR_DATA: begin + if (reorder_64) + sdr_addr <= base_addr[24:0] + {offset[24:7], offset[5:2], offset[6], offset[1:0]}; + else + sdr_addr <= base_addr[24:0] + offset[24:0]; + sdr_data = {ioctl_data, ioctl_data}; + sdr_be <= { offset[0], ~offset[0] }; + offset <= offset + 25'd1; + sdr_req <= ~sdr_req; + ioctl_wait <= 1; + + if (offset == ( size - 1)) stage <= REGION_IDX; + end + BRAM_DATA: begin + bram_addr <= offset[19:0]; + bram_data <= ioctl_data; + bram_wr <= 1; + offset <= offset + 25'd1; + + if (offset == ( size - 1)) stage <= REGION_IDX; + end + endcase + end +end + +endmodule diff --git a/Arcade_MiST/IremM92 Hardware/rtl/sdram_4w_cl3.sv b/Arcade_MiST/IremM92 Hardware/rtl/sdram_4w_cl3.sv new file mode 100644 index 00000000..f1e5f189 --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/rtl/sdram_4w_cl3.sv @@ -0,0 +1,499 @@ +// +// sdram.v +// +// sdram controller implementation for the MiST board +// https://github.com/mist-devel/mist-board +// +// Copyright (c) 2013 Till Harbaum +// Copyright (c) 2019-2022 Gyorgy Szombathelyi +// +// This source file is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This source file is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +module sdram_4w_cl3 ( + + // interface to the MT48LC16M16 chip + inout reg [15:0] SDRAM_DQ, // 16 bit bidirectional data bus + output reg [12:0] SDRAM_A, // 13 bit multiplexed address bus + output reg SDRAM_DQML, // two byte masks + output reg SDRAM_DQMH, // two byte masks + output reg [1:0] SDRAM_BA, // two banks + output SDRAM_nCS, // a single chip select + output SDRAM_nWE, // write enable + output SDRAM_nRAS, // row address select + output SDRAM_nCAS, // columns address select + + // cpu/chipset interface + input init_n, // init signal after FPGA config to initialize RAM + input clk, // sdram clock + + // 1st bank + input port1_req, + output reg port1_ack = 0, + input port1_we, + input [23:1] port1_a, + input [1:0] port1_ds, + input [15:0] port1_d, + output reg [15:0] port1_q, + + // cpu1 rom/ram + input [20:1] cpu1_rom_addr, + input cpu1_rom_cs, + output reg [15:0] cpu1_rom_q, + output reg cpu1_rom_valid, + + input cpu1_ram_req, + output reg cpu1_ram_ack = 0, + input [22:1] cpu1_ram_addr, + input cpu1_ram_we, + input [1:0] cpu1_ram_ds, + input [15:0] cpu1_ram_d, + output reg [15:0] cpu1_ram_q, + + // cpu2 rom/ram + input cpu2_ram_req, + output reg cpu2_ram_ack = 0, + input [22:1] cpu2_ram_addr, + input cpu2_ram_we, + input [1:0] cpu2_ram_ds, + input [15:0] cpu2_ram_d, + output reg [15:0] cpu2_ram_q, + + // cpu3 rom + input vram_req, + output reg vram_ack = 0, + input [22:1] vram_addr, + output reg [31:0] vram_q, + + // 2nd bank + input port2_req, + output reg port2_ack = 0, + input port2_we, + input [23:1] port2_a, + input [1:0] port2_ds, + input [15:0] port2_d, + output reg [31:0] port2_q, + + input gfx1_req, + output reg gfx1_ack = 0, + input [23:1] gfx1_addr, + output reg [31:0] gfx1_q, + + input gfx2_req, + output reg gfx2_ack = 0, + input [23:1] gfx2_addr, + output reg [31:0] gfx2_q, + + input gfx3_req, + output reg gfx3_ack = 0, + input [23:1] gfx3_addr, + output reg [31:0] gfx3_q, + + input sample_req, + output reg sample_ack = 0, + input [23:1] sample_addr, + output reg [63:0] sample_q, + + input sp_req, + output reg sp_ack = 0, + input [23:1] sp_addr, + output reg [63:0] sp_q +); + +parameter MHZ = 16'd80; // 80 MHz default clock, set it to proper value to calculate refresh rate + +localparam RASCAS_DELAY = 3'd3; // tRCD=20ns -> 2 cycles@<100MHz +localparam BURST_LENGTH = 3'b010; // 000=1, 001=2, 010=4, 011=8 +localparam ACCESS_TYPE = 1'b0; // 0=sequential, 1=interleaved +localparam CAS_LATENCY = 3'd3; // 2/3 allowed +localparam OP_MODE = 2'b00; // only 00 (standard operation) allowed +localparam NO_WRITE_BURST = 1'b1; // 0= write burst enabled, 1=only single access write + +localparam MODE = { 3'b000, NO_WRITE_BURST, OP_MODE, CAS_LATENCY, ACCESS_TYPE, BURST_LENGTH}; + +// 64ms/8192 rows = 7.8us +localparam RFRSH_CYCLES = 16'd78*MHZ/4'd10; + +// --------------------------------------------------------------------- +// ------------------------ cycle state machine ------------------------ +// --------------------------------------------------------------------- + +/* + SDRAM state machine for 2 bank interleaved access + 4 words burst, CL3 +cmd issued registered + 0 RAS0 data1 returned + 1 ras0, data1 returned + 2 data1 returned + 3 CAS0 + 4 RAS1 cas0 + 5 ras1 + 6 + 7 CAS1 data0 returned + 8 cas1 - data0 masked if cas1 write + 9 data0 returned (but masked via DQM) + 10 data0 returned (but masked via DQM) + 11 data1 returned +*/ + +localparam STATE_RAS0 = 4'd0; // first state in cycle +localparam STATE_CAS0 = 4'd3; +localparam STATE_READ0 = 4'd8; // STATE_CAS0 + CAS_LATENCY + 2'd2; +localparam STATE_READ0b = 4'd9; +localparam STATE_DS0 = 4'd4; +localparam STATE_DS0b = 4'd5; +localparam STATE_RAS1 = 4'd4; // Second ACTIVE command after RAS0 + tRRD (15ns) +localparam STATE_CAS1 = 4'd7; // CAS phase +localparam STATE_READ1 = 4'd0; +localparam STATE_READ1b = 4'd1; +localparam STATE_READ1c = 4'd2; +localparam STATE_READ1d = 4'd3; +localparam STATE_DS1a = 4'd8; +localparam STATE_DS1b = 4'd9; +localparam STATE_DS1c = 4'd10; +localparam STATE_DS1d = 4'd11; +localparam STATE_LAST = 4'd11; + +reg [3:0] t; + +always @(posedge clk) begin + t <= t + 1'd1; + if (t == STATE_LAST) t <= STATE_RAS0; +end + +// --------------------------------------------------------------------- +// --------------------------- startup/reset --------------------------- +// --------------------------------------------------------------------- + +// wait 1ms (32 8Mhz cycles) after FPGA config is done before going +// into normal operation. Initialize the ram in the last 16 reset cycles (cycles 15-0) +reg [4:0] reset; +reg init = 1'b1; +always @(posedge clk, negedge init_n) begin + if(!init_n) begin + reset <= 5'h1f; + init <= 1'b1; + end else begin + if((t == STATE_LAST) && (reset != 0)) reset <= reset - 5'd1; + init <= !(reset == 0); + end +end + +// --------------------------------------------------------------------- +// ------------------ generate ram control signals --------------------- +// --------------------------------------------------------------------- + +// all possible commands +localparam CMD_INHIBIT = 4'b1111; +localparam CMD_NOP = 4'b0111; +localparam CMD_ACTIVE = 4'b0011; +localparam CMD_READ = 4'b0101; +localparam CMD_WRITE = 4'b0100; +localparam CMD_BURST_TERMINATE = 4'b0110; +localparam CMD_PRECHARGE = 4'b0010; +localparam CMD_AUTO_REFRESH = 4'b0001; +localparam CMD_LOAD_MODE = 4'b0000; + +reg [3:0] sd_cmd; // current command sent to sd ram +reg [15:0] sd_din; +// drive control signals according to current command +assign SDRAM_nCS = sd_cmd[3]; +assign SDRAM_nRAS = sd_cmd[2]; +assign SDRAM_nCAS = sd_cmd[1]; +assign SDRAM_nWE = sd_cmd[0]; + +reg [24:1] addr_latch[3]; +reg [24:1] addr_latch_next[2]; +reg [15:0] din_next; +reg [15:0] din_latch[2]; +reg oe_next; +reg [1:0] oe_latch; +reg we_next; +reg [1:0] we_latch; +reg [1:0] ds_next; +reg [1:0] ds[2]; + +reg port1_state; +reg port2_state; +reg cpu1_ram_req_state; +reg cpu2_ram_req_state; +reg vram_req_state; +reg sp_req_state; +reg sample_req_state; + +localparam PORT_NONE = 3'd0; +localparam PORT_CPU1_ROM = 3'd1; +localparam PORT_CPU1_RAM = 3'd2; +localparam PORT_CPU2_RAM = 3'd3; +localparam PORT_VRAM = 3'd4; +localparam PORT_GFX1 = 3'd1; +localparam PORT_GFX2 = 3'd2; +localparam PORT_GFX3 = 3'd3; +localparam PORT_SAMPLE = 3'd4; +localparam PORT_SP = 3'd5; +localparam PORT_REQ = 3'd6; + +reg [2:0] next_port[2]; +reg [2:0] port[2]; + +reg refresh; +reg [10:0] refresh_cnt; +wire need_refresh = (refresh_cnt >= RFRSH_CYCLES); + +// PORT1: bank 0,1 +always @(*) begin + next_port[0] = PORT_NONE; + addr_latch_next[0] = addr_latch[0]; + ds_next = 2'b00; + { oe_next, we_next } = 2'b00; + din_next = 0; + + if (refresh) begin + // nothing + end else if (port1_req ^ port1_state) begin + next_port[0] = PORT_REQ; + addr_latch_next[0] = { 1'b0, port1_a }; + ds_next = port1_ds; + { oe_next, we_next } = { ~port1_we, port1_we }; + din_next = port1_d; + end else if (vram_req ^ vram_req_state) begin + next_port[0] = PORT_VRAM; + addr_latch_next[0] = { 2'b00, vram_addr }; + ds_next = 2'b11; + { oe_next, we_next } = 2'b10; + end else if (/*cpu1_rom_addr != addr_last[PORT_CPU1_ROM] &&*/ cpu1_rom_cs && !cpu1_rom_valid) begin + next_port[0] = PORT_CPU1_ROM; + addr_latch_next[0] = { 4'd0, cpu1_rom_addr }; + ds_next = 2'b11; + { oe_next, we_next } = 2'b10; + end else if (cpu1_ram_req ^ cpu1_ram_req_state) begin + next_port[0] = PORT_CPU1_RAM; + addr_latch_next[0] = { 2'b00, cpu1_ram_addr }; + ds_next = cpu1_ram_ds; + { oe_next, we_next } = { ~cpu1_ram_we, cpu1_ram_we }; + din_next = cpu1_ram_d; + end else if (cpu2_ram_req ^ cpu2_ram_req_state) begin + next_port[0] = PORT_CPU2_RAM; + addr_latch_next[0] = { 2'b00, cpu2_ram_addr }; + ds_next = cpu2_ram_ds; + { oe_next, we_next } = { ~cpu2_ram_we, cpu2_ram_we }; + din_next = cpu2_ram_d; + end +end + +// PORT1: bank 2,3 +always @(*) begin + if (port2_req ^ port2_state) begin + next_port[1] = PORT_REQ; + addr_latch_next[1] = { 1'b1, port2_a }; + end else if (sp_req ^ sp_req_state) begin + next_port[1] = PORT_SP; + addr_latch_next[1] = { 1'b1, sp_addr }; + end else if (gfx1_req ^ gfx1_ack) begin + next_port[1] = PORT_GFX1; + addr_latch_next[1] = { 1'b1, gfx1_addr }; + end else if (gfx2_req ^ gfx2_ack) begin + next_port[1] = PORT_GFX2; + addr_latch_next[1] = { 1'b1, gfx2_addr }; + end else if (gfx3_req ^ gfx3_ack) begin + next_port[1] = PORT_GFX3; + addr_latch_next[1] = { 1'b1, gfx3_addr }; + end else if (sample_req ^ sample_req_state) begin + next_port[1] = PORT_SAMPLE; + addr_latch_next[1] = { 1'b1, sample_addr }; + end else begin + next_port[1] = PORT_NONE; + addr_latch_next[1] = addr_latch[1]; + end +end + +always @(posedge clk) begin + + // permanently latch ram data to reduce delays + sd_din <= SDRAM_DQ; + SDRAM_DQ <= 16'bZZZZZZZZZZZZZZZZ; + { SDRAM_DQMH, SDRAM_DQML } <= 2'b11; + sd_cmd <= CMD_NOP; // default: idle + refresh_cnt <= refresh_cnt + 1'd1; + + if(init) begin + cpu1_rom_valid <= 0; + // initialization takes place at the end of the reset phase + if(t == STATE_RAS0) begin + + if(reset == 15) begin + sd_cmd <= CMD_PRECHARGE; + SDRAM_A[10] <= 1'b1; // precharge all banks + end + + if(reset == 10 || reset == 8) begin + sd_cmd <= CMD_AUTO_REFRESH; + end + + if(reset == 2) begin + sd_cmd <= CMD_LOAD_MODE; + SDRAM_A <= MODE; + SDRAM_BA <= 2'b00; + end + end + end else begin + if (!cpu1_rom_cs) cpu1_rom_valid <= 0; + + // RAS phase + // bank 0,1 + if(t == STATE_RAS0) begin + addr_latch[0] <= addr_latch_next[0]; + port[0] <= next_port[0]; + ds[0] <= ds_next; + { oe_latch[0], we_latch[0] } <= { oe_next, we_next }; + din_latch[0] <= din_next; + + if (next_port[0] != PORT_NONE) begin + sd_cmd <= CMD_ACTIVE; + SDRAM_A <= addr_latch_next[0][22:10]; + SDRAM_BA <= addr_latch_next[0][24:23]; + end + + if (next_port[0] == PORT_REQ) port1_state <= port1_req; + if (next_port[0] == PORT_CPU1_RAM) cpu1_ram_req_state <= cpu1_ram_req; + if (next_port[0] == PORT_CPU2_RAM) cpu2_ram_req_state <= cpu2_ram_req; + if (next_port[0] == PORT_VRAM) vram_req_state <= vram_req; + end + + // bank 2,3 + if(t == STATE_RAS1) begin + refresh <= 1'b0; + addr_latch[1] <= addr_latch_next[1]; + { oe_latch[1], we_latch[1] } <= 2'b00; + port[1] <= next_port[1]; + + if (next_port[1] != PORT_NONE) begin + sd_cmd <= CMD_ACTIVE; + SDRAM_A <= addr_latch_next[1][22:10]; + SDRAM_BA <= addr_latch_next[1][24:23]; + if (next_port[1] == PORT_REQ) begin + { oe_latch[1], we_latch[1] } <= { ~port1_we, port1_we }; + ds[1] <= port2_ds; + din_latch[1] <= port2_d; + port2_state <= port2_req; + end else begin + { oe_latch[1], we_latch[1] } <= 2'b10; + ds[1] <= 2'b11; + end + end + if (next_port[1] == PORT_SP) sp_req_state <= sp_req; + if (next_port[1] == PORT_SAMPLE) sample_req_state <= sample_req; + + if (next_port[1] == PORT_NONE && need_refresh && !we_latch[0] && !oe_latch[0]) begin + refresh <= 1'b1; + refresh_cnt <= 0; + sd_cmd <= CMD_AUTO_REFRESH; + end + end + + // CAS phase + if(t == STATE_CAS0 && (we_latch[0] || oe_latch[0])) begin + sd_cmd <= we_latch[0]?CMD_WRITE:CMD_READ; + if (we_latch[0]) begin + { SDRAM_DQMH, SDRAM_DQML } <= ~ds[0]; + SDRAM_DQ <= din_latch[0]; + case(port[0]) + PORT_REQ: port1_ack <= port1_req; + PORT_CPU1_RAM: cpu1_ram_ack <= cpu1_ram_req; + PORT_CPU2_RAM: cpu2_ram_ack <= cpu2_ram_req; + default: ; + endcase; + end + SDRAM_A <= { 4'b0010, addr_latch[0][9:1] }; // auto precharge + SDRAM_BA <= addr_latch[0][24:23]; + end + + if(t == STATE_CAS1 && (we_latch[1] || oe_latch[1])) begin + sd_cmd <= we_latch[1]?CMD_WRITE:CMD_READ; + if (we_latch[1]) begin + { SDRAM_DQMH, SDRAM_DQML } <= ~ds[1]; + SDRAM_DQ <= din_latch[1]; + port2_ack <= port2_req; + end + SDRAM_A <= { 4'b0010, addr_latch[1][9:1] }; // auto precharge + SDRAM_BA <= addr_latch[1][24:23]; + end + + if(t == STATE_DS0 && oe_latch[0]) { SDRAM_DQMH, SDRAM_DQML } <= 0; + if(t == STATE_DS0b && oe_latch[0] && !we_latch[1]) { SDRAM_DQMH, SDRAM_DQML } <= 0; + + // Data returned + if(t == STATE_READ0 && oe_latch[0]) begin + case(port[0]) + PORT_REQ: begin port1_q <= sd_din; port1_ack <= port1_req; end + PORT_CPU1_ROM: begin cpu1_rom_q <= sd_din; cpu1_rom_valid <= 1; end + PORT_CPU1_RAM: begin cpu1_ram_q <= sd_din; cpu1_ram_ack <= cpu1_ram_req; end + PORT_CPU2_RAM: begin cpu2_ram_q <= sd_din; cpu2_ram_ack <= cpu2_ram_req; end + PORT_VRAM: vram_q[15:0] <= sd_din; + default: ; + endcase; + end + if(t == STATE_READ0b && oe_latch[0]) begin + case(port[0]) + PORT_VRAM: begin vram_q[31:16] <= sd_din; vram_ack <= vram_req; end + default: ; + endcase; + end + + if(t == STATE_DS1a && oe_latch[1]) { SDRAM_DQMH, SDRAM_DQML } <= 0; + if(t == STATE_DS1b && oe_latch[1]) { SDRAM_DQMH, SDRAM_DQML } <= 0; + if(t == STATE_DS1c && oe_latch[1]) { SDRAM_DQMH, SDRAM_DQML } <= 0; + if(t == STATE_DS1d && oe_latch[1]) { SDRAM_DQMH, SDRAM_DQML } <= 0; + + if(t == STATE_READ1 && oe_latch[1]) begin + case(port[1]) + PORT_REQ : port2_q[15:0] <= sd_din; + PORT_GFX1 : gfx1_q[15:0] <= sd_din; + PORT_GFX2 : gfx2_q[15:0] <= sd_din; + PORT_GFX3 : gfx3_q[15:0] <= sd_din; + PORT_SAMPLE: sample_q[15:0] <= sd_din; + PORT_SP : sp_q[15:0] <= sd_din; + default: ; + endcase; + end + + if(t == STATE_READ1b && oe_latch[1]) begin + case(port[1]) + PORT_REQ : begin port2_q[31:16] <= sd_din; port2_ack <= port2_req; end + PORT_GFX1 : begin gfx1_q[31:16] <= sd_din; gfx1_ack <= gfx1_req; end + PORT_GFX2 : begin gfx2_q[31:16] <= sd_din; gfx2_ack <= gfx2_req; end + PORT_GFX3 : begin gfx3_q[31:16] <= sd_din; gfx3_ack <= gfx3_req; end + PORT_SAMPLE: sample_q[31:16] <= sd_din; + PORT_SP : sp_q[31:16] <= sd_din; + default: ; + endcase; + end + if(t == STATE_READ1c && oe_latch[1]) begin + case(port[1]) + PORT_SAMPLE: sample_q[47:32] <= sd_din; + PORT_SP: sp_q[47:32] <= sd_din; + default: ; + endcase; + end + if(t == STATE_READ1d && oe_latch[1]) begin + case(port[1]) + PORT_SAMPLE: begin sample_q[63:48] <= sd_din; sample_ack <= sample_req; end + PORT_SP: begin sp_q[63:48] <= sd_din; sp_ack <= sp_req; end + default: ; + endcase; + end + end +end + +endmodule diff --git a/Arcade_MiST/IremM92 Hardware/rtl/sound.sv b/Arcade_MiST/IremM92 Hardware/rtl/sound.sv new file mode 100644 index 00000000..c2214fb3 --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/rtl/sound.sv @@ -0,0 +1,266 @@ +//============================================================================ +// Copyright (C) 2023 Martin Donlon +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +//============================================================================ + +module sound( + input clk_sys, // 40M + input reset, + + input paused, + input filter_en, + input dbg_fm_en, + + input latch_wr, + input latch_rd, + + input [7:0] latch_din, + output [7:0] latch_dout, + output latch_rdy, + + // ioctl load + input [19:0] rom_addr, + input [7:0] rom_data, + input rom_wr, + + input [7:0] secure_addr, + input [7:0] secure_data, + input secure_wr, + + output reg [15:0] sample, + + // sdr + output [24:0] sdr_addr, + input [63:0] sdr_data, + output sdr_req, + input sdr_ack, + + output reg [24:0] sdr_cpu_addr, + input [15:0] sdr_cpu_dout, + output reg [15:0] sdr_cpu_din, + output reg sdr_cpu_req, + input sdr_cpu_ack, + output reg [1:0] sdr_cpu_wr_sel +); + + +wire [15:0] sample_out, fm_sample, fm_sample_flt; + +localparam OVERALL_GAIN = 0.9; +wire [11:0] fm_scale = int'(1.3 * OVERALL_GAIN * 128); +wire [11:0] pcm_scale = int'(3.1 * OVERALL_GAIN * 128); + +always_ff @(posedge clk_sys) begin + reg [27:0] sum; + reg [27:0] fm; + reg [27:0] pcm; + + fm <= $signed(filter_en ? fm_sample_flt : fm_sample) * fm_scale; + pcm <= $signed(sample_out) * pcm_scale; + if (!dbg_fm_en) fm <= 0; + + sum <= fm + pcm; + if (&sum[27:22] || &(~sum[27:22])) sample <= sum[22:7]; + else if (sum[27]) sample <= 16'h8000; + else sample <= 16'h7fff; +end + +wire ce_28m, ce_14m, ce_7m, ce_3_5m, ce_1_7m; +jtframe_frac_cen #(6) pixel_cen +( + .clk(clk_sys), + .cen_in(~paused), + .n(10'd63), + .m(10'd88), + .cen({ce_1_7m, ce_3_5m, ce_7m, ce_14m, ce_28m}) +); + +wire ram_cs, rom_cs, io_cs; +wire ym2151_cs, ga20_cs, snd_latch_cs, main_latch_cs; +wire [1:0] cpu_be; +wire [15:0] cpu_dout, cpu_din; +wire [19:0] cpu_addr; +reg [15:0] ramrom_dout; +wire cpu_rd, cpu_wr; + +wire [7:0] ym2151_dout; +wire ym2151_irq_n; + +wire [7:0] ga20_dout; + +reg [7:0] main_latch, snd_latch; +reg main_latch_rdy, snd_latch_rdy; + +assign latch_rdy = main_latch_rdy; +assign latch_dout = main_latch; + +wire [15:0] cpu_word_dout = cpu_addr[0] ? { cpu_dout[7:0], 8'h00 } : cpu_dout; +wire [1:0] cpu_word_be = cpu_addr[0] ? { cpu_be[0], 1'b0 } : cpu_be; + +assign ram_cs = cpu_addr[19:14] == {4'ha, 2'b00};// cpu_addr[13:12]>= 8'ha0 && cpu_addr[19:12] < 8'ha4; +assign io_cs = cpu_addr[19:12] == 8'ha8; +assign rom_cs = ~ram_cs & ~io_cs; + +assign ga20_cs = io_cs & cpu_addr[7:6] == 2'b00; // 0xa8000 - 0xa803f +assign ym2151_cs = io_cs & cpu_addr[7:2] == 6'b010000; // 0xa8040 - 0xa8043 +assign snd_latch_cs = io_cs & cpu_addr[7:0] == 8'h44; +assign main_latch_cs = io_cs & cpu_addr[7:0] == 8'h46; + +assign cpu_din = rom_cs ? ( cpu_addr[0] ? { ramrom_dout[7:0], ramrom_dout[15:8] } : ramrom_dout ) : + ram_cs ? ( cpu_addr[0] ? { 8'd0, ramrom_dout[15:8] } : ramrom_dout ) : + ym2151_cs ? { 8'd0, ym2151_dout } : + snd_latch_cs ? { 8'd0, snd_latch } : + ga20_cs ? { 8'd0, ga20_dout } : + 16'hffff; + +wire ram_rom_memrq = rom_cs | ram_cs; +wire cpu_region_writable = !rom_cs; +reg mem_rq_active; +reg cpu_rd_lat, cpu_wr_lat; +wire cpu_mem_read = cpu_rd | cpu_rd_lat; +wire cpu_mem_write = cpu_wr | cpu_wr_lat; +wire ramrom_busy = ((ram_rom_memrq) & (cpu_mem_read | cpu_mem_write)) | mem_rq_active; + +always_ff @(posedge clk_sys, posedge reset) begin + if (reset) begin + mem_rq_active <= 0; + end else begin + cpu_rd_lat <= cpu_rd; + cpu_wr_lat <= cpu_wr; + if (!mem_rq_active) begin + if (ram_rom_memrq & ((cpu_rd & ~cpu_rd_lat) | (cpu_wr & ~cpu_wr_lat))) begin // sdram request + sdr_cpu_wr_sel <= 2'b00; + sdr_cpu_addr <= rom_cs ? {REGION_SOUND.base_addr[24:17], cpu_addr[16:0]} : {REGION_SOUND_RAM.base_addr[24:14], cpu_addr[13:0]}; + if (cpu_wr & cpu_region_writable) begin + sdr_cpu_wr_sel <= cpu_word_be; + sdr_cpu_din <= cpu_word_dout; + end + sdr_cpu_req <= ~sdr_cpu_req; + mem_rq_active <= 1; + end + end else if (sdr_cpu_req == sdr_cpu_ack) begin + mem_rq_active <= 0; + ramrom_dout <= sdr_cpu_dout; + end + end +end + +v35 v35( + .clk(clk_sys), + .ce(ce_28m & !ramrom_busy), + .ce_cycle(ce_7m & !ramrom_busy), + .reset(reset), + + .mem_rd(cpu_rd), + .mem_wr(cpu_wr), + .mem_be(cpu_be), + .mem_addr(cpu_addr), + .mem_dout(cpu_dout), + .mem_din(cpu_din), + + .intp0(ym2151_irq_n), + .intp1(~snd_latch_rdy), + .intp2(0), + + .secure(1), + .secure_wr(secure_wr), + .secure_addr(secure_addr), + .secure_data(secure_data) +); + + +jt51 ym2151( + .rst(reset), + .clk(clk_sys), + .cen(ce_3_5m), + .cen_p1(ce_1_7m), + .cs_n(~ym2151_cs), + .wr_n(~cpu_wr), + .a0(cpu_addr[1]), + .din(cpu_dout[7:0]), + .dout(ym2151_dout), + .irq_n(ym2151_irq_n), + .xright(fm_sample), + .xleft() +); + +// fc1 = 19020hz +// fc2 = 8707hz +IIR_filter #( .use_params(1), .stereo(0), .coeff_x(0.000001054852861174913), .coeff_x0(3), .coeff_x1(3), .coeff_x2(1), .coeff_y0(-2.94554610428990093496), .coeff_y1(2.89203308225615352001), .coeff_y2(-0.94647938909674766972)) lpf_ym ( + .clk(clk_sys), + .reset(reset), + + .ce(ce_3_5m), + .sample_ce(ce_3_5m), + + .cx(), .cx0(), .cx1(), .cx2(), .cy0(), .cy1(), .cy2(), + + .input_l(fm_sample), + .output_l(fm_sample_flt), + + .input_r(), + .output_r() +); + +wire [19:0] sample_rom_addr; +assign sdr_addr = { REGION_GA20.base_addr[24:20], sample_rom_addr }; + +ga20 ga20( + .clk(clk_sys), + .reset(reset), + .filter_en(filter_en), + .ce(ce_3_5m), + + .cs(ga20_cs), + .rd(cpu_rd), + .wr(cpu_wr), + .addr(cpu_addr[5:1]), + .din(cpu_dout[7:0]), + .dout(ga20_dout), + + .sample_rom_req(sdr_req), + .sample_rom_addr(sample_rom_addr), + .sample_rom_ack(sdr_ack), + .sample_rom_din(sdr_data), + + .sample_out(sample_out) +); + +always_ff @(posedge clk_sys, posedge reset) begin + if (reset) begin + main_latch_rdy <= 0; + snd_latch_rdy <= 0; + end else begin + if (latch_rd) begin + main_latch_rdy <= 0; + end + + if (latch_wr) begin + snd_latch <= latch_din; + snd_latch_rdy <= 1; + end + + if (snd_latch_cs & cpu_wr) begin + snd_latch_rdy <= 0; + end + + if (main_latch_cs & cpu_wr) begin + main_latch <= cpu_dout[7:0]; + main_latch_rdy <= 1; + end + end +end +endmodule \ No newline at end of file diff --git a/Arcade_MiST/IremM92 Hardware/rtl/v35.sv b/Arcade_MiST/IremM92 Hardware/rtl/v35.sv new file mode 100644 index 00000000..2e6b060a --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/rtl/v35.sv @@ -0,0 +1,395 @@ +module v35( + input clk, + input ce, // 4x internal clock + input ce_cycle, // real internal clock + + input reset, + + output mem_rd, + output mem_wr, + output [1:0] mem_be, + output [19:0] mem_addr, + output [15:0] mem_dout, + input [15:0] mem_din, + + input intp0, + input intp1, + input intp2, + + input secure, + + input secure_wr, + input [7:0] secure_addr, + input [7:0] secure_data +); + +wire rd, wr; +wire prefetching; +wire [1:0] be; +wire [19:0] addr; +wire [15:0] dout, din; + +reg [2:0] irq_pending = 0; +reg [7:0] irq_vec; +wire irq_ack; +wire irq_fini; + +reg [15:0] TM0, MD0, TM1, MD1, WTC; +reg [7:0] P0, PM0, PMC0, P1, PM1, PMC1, P2, PM2; +reg [7:0] PMC2, PT, PMT, INTM, EMS0, EMS1, EMS2, EXIC0; +reg [7:0] EXIC1, EXIC2, ISPR, RXB0, TXB0, SRMS0, STMS0, SCM0; +reg [7:0] SCC0, BRG0, SCE0, SEIC0, SRIC0, STIC0, RXB1, TXB1; +reg [7:0] SRMS1, STMS1, SCM1, SCC1, BRG1, SCE1, SEIC1, SRIC1; +reg [7:0] STIC1, TMC0, TMC1, TMMS0, TMMS1, TMMS2, TMIC0, TMIC1; +reg [7:0] TMIC2, DMAC0, DMAM0, DMAC1, DMAM1, DIC0, DIC1, STBC; +reg [7:0] RFM, FLAG, PRC, TBIC, IDB; + +wire RAMEN = PRC[6]; +wire [1:0] TB = PRC[3:2]; +wire [1:0] PCK = PRC[1:0]; +wire ESNMI = INTM[0]; +wire ES0 = INTM[2]; +wire ES1 = INTM[4]; +wire ES2 = INTM[6]; + + +reg [7:0] exi_prio_bit; + +reg [15:0] internal_din; +reg [7:0] iram[256]; +reg [1:0] wait_cycles = 0; + +reg intp0_prev, intp1_prev, intp2_prev; + +wire internal_rq = ~prefetching && ( addr[19:9] == { IDB, 3'b111 } || addr[19:0] == 20'hfffff ); +wire internal_ram_rq = RAMEN & internal_rq & ~addr[8]; +wire sfr_area_rq = internal_rq & addr[8]; + +reg internal_rq_latch; + +assign mem_rd = rd & ~internal_rq; +assign mem_wr = wr & ~internal_rq; +assign mem_be = be; +assign mem_addr = addr; +assign mem_dout = dout; +assign din = internal_rq_latch ? internal_din : mem_din; + +always_ff @(posedge clk) begin + if (reset) begin + PM0 <= 8'hff; + PMC0 <= 8'h00; + PM1 <= 8'hff; + PMC1 <= 8'h00; + PM2 <= 8'hff; + PMC2 <= 8'h00; + PMT <= 8'h00; + INTM <= 8'h00; + EXIC0 <= 8'h47; + EXIC1 <= 8'h47; + EXIC2 <= 8'h47; + ISPR <= 8'h00; + SCM0 <= 8'h00; + SCC0 <= 8'h00; + BRG0 <= 8'h00; + SCE0 <= 8'h00; + SEIC0 <= 8'h47; + SRIC0 <= 8'h47; + STIC0 <= 8'h47; + SCM1 <= 8'h00; + SCC1 <= 8'h00; + BRG1 <= 8'h00; + SCE1 <= 8'h00; + SEIC1 <= 8'h47; + SRIC1 <= 8'h47; + STIC1 <= 8'h47; + TMC0 <= 8'h00; + TMC1 <= 8'h00; + TMIC0 <= 8'h47; + TMIC1 <= 8'h47; + TMIC2 <= 8'h47; + DMAM0 <= 8'h00; + DMAM1 <= 8'h00; + DIC0 <= 8'h47; + DIC1 <= 8'h47; + STBC <= 8'h00; + RFM <= 8'hfc; + WTC <= 16'hffff; + FLAG <= 8'h00; + PRC <= 8'h4e; + TBIC <= 8'h47; + IDB <= 8'hff; + + irq_pending <= 0; + wait_cycles <= 2'd0; + end else begin + if (sfr_area_rq) begin + if (wr) begin + case(addr[7:0]) + 8'h00: P0 <= dout[7:0]; + 8'h01: PM0 <= dout[7:0]; + 8'h02: PMC0 <= dout[7:0]; + 8'h08: P1 <= dout[7:0]; + 8'h09: PM1 <= dout[7:0]; + 8'h0a: PMC1 <= dout[7:0]; + 8'h10: P2 <= dout[7:0]; + 8'h11: PM2 <= dout[7:0]; + 8'h12: PMC2 <= dout[7:0]; + 8'h3b: PMT <= dout[7:0]; + 8'h40: INTM <= dout[7:0]; + 8'h44: EMS0 <= dout[7:0]; + 8'h45: EMS1 <= dout[7:0]; + 8'h46: EMS2 <= dout[7:0]; + 8'h4c: EXIC0 <= dout[7:0]; + 8'h4d: EXIC1 <= dout[7:0]; + 8'h4e: EXIC2 <= dout[7:0]; + 8'h62: TXB0 <= dout[7:0]; + 8'h65: SRMS0 <= dout[7:0]; + 8'h66: STMS0 <= dout[7:0]; + 8'h68: SCM0 <= dout[7:0]; + 8'h69: SCC0 <= dout[7:0]; + 8'h6a: BRG0 <= dout[7:0]; + 8'h6c: SEIC0 <= dout[7:0]; + 8'h6d: SRIC0 <= dout[7:0]; + 8'h6e: STIC0 <= dout[7:0]; + 8'h72: TXB1 <= dout[7:0]; + 8'h75: SRMS1 <= dout[7:0]; + 8'h76: STMS1 <= dout[7:0]; + 8'h78: SCM1 <= dout[7:0]; + 8'h79: SCC1 <= dout[7:0]; + 8'h7a: BRG1 <= dout[7:0]; + 8'h7c: SEIC1 <= dout[7:0]; + 8'h7d: SRIC1 <= dout[7:0]; + 8'h7e: STIC1 <= dout[7:0]; + 8'h80: begin + if (be[0]) TM0[7:0] <= dout[7:0]; + if (be[1]) TM0[15:8] <= dout[15:8]; + end + 8'h81: TM0[15:8] <= dout[7:0]; + 8'h82: begin + if (be[0]) MD0[7:0] <= dout[7:0]; + if (be[1]) MD0[15:8] <= dout[15:8]; + end + 8'h83: MD0[15:8] <= dout[7:0]; + 8'h88: begin + if (be[0]) TM1[7:0] <= dout[7:0]; + if (be[1]) TM1[15:8] <= dout[15:8]; + end + 8'h89: TM1[15:8] <= dout[7:0]; + 8'h8a: begin + if (be[0]) MD1[7:0] <= dout[7:0]; + if (be[1]) MD1[15:8] <= dout[15:8]; + end + 8'h8b: MD1[15:8] <= dout[7:0]; + 8'h90: TMC0 <= dout[7:0]; + 8'h91: TMC1 <= dout[7:0]; + 8'h94: TMMS0 <= dout[7:0]; + 8'h95: TMMS1 <= dout[7:0]; + 8'h96: TMMS2 <= dout[7:0]; + 8'h9c: TMIC0 <= dout[7:0]; + 8'h9d: TMIC1 <= dout[7:0]; + 8'h9e: TMIC2 <= dout[7:0]; + 8'ha0: DMAC0 <= dout[7:0]; + 8'ha1: DMAM0 <= dout[7:0]; + 8'ha2: DMAC1 <= dout[7:0]; + 8'ha3: DMAM1 <= dout[7:0]; + 8'hac: DIC0 <= dout[7:0]; + 8'had: DIC1 <= dout[7:0]; + 8'he0: STBC <= dout[7:0]; + 8'he1: RFM <= dout[7:0]; + 8'he8: begin + if (be[0]) WTC[7:0] <= dout[7:0]; + if (be[1]) WTC[15:8] <= dout[15:8]; + end + 8'he9: WTC[15:8] <= dout[7:0]; + 8'hea: FLAG <= dout[7:0]; + 8'heb: PRC <= dout[7:0]; + 8'hec: TBIC <= dout[7:0]; + 8'hff: IDB <= dout[7:0]; + endcase + end else if (rd) begin + case(addr[7:0]) + 8'h00: internal_din <= { 8'd0, P0 }; + 8'h08: internal_din <= { 8'd0, P1 }; + 8'h10: internal_din <= { 8'd0, P2 }; + 8'h38: internal_din <= { 8'd0, PT }; + 8'h3b: internal_din <= { 8'd0, PMT }; + 8'h40: internal_din <= { 8'd0, INTM }; + 8'h44: internal_din <= { 8'd0, EMS0 }; + 8'h45: internal_din <= { 8'd0, EMS1 }; + 8'h46: internal_din <= { 8'd0, EMS2 }; + 8'h4c: internal_din <= { 8'd0, EXIC0 }; + 8'h4d: internal_din <= { 8'd0, EXIC1 }; + 8'h4e: internal_din <= { 8'd0, EXIC2 }; + 8'hfc: internal_din <= { 8'd0, ISPR }; + 8'h60: internal_din <= { 8'd0, RXB0 }; + 8'h65: internal_din <= { 8'd0, SRMS0 }; + 8'h66: internal_din <= { 8'd0, STMS0 }; + 8'h68: internal_din <= { 8'd0, SCM0 }; + 8'h69: internal_din <= { 8'd0, SCC0 }; + 8'h6a: internal_din <= { 8'd0, BRG0 }; + 8'h6b: internal_din <= { 8'd0, SCE0 }; + 8'h6c: internal_din <= { 8'd0, SEIC0 }; + 8'h6d: internal_din <= { 8'd0, SRIC0 }; + 8'h6e: internal_din <= { 8'd0, STIC0 }; + 8'h70: internal_din <= { 8'd0, RXB1 }; + 8'h75: internal_din <= { 8'd0, SRMS1 }; + 8'h76: internal_din <= { 8'd0, STMS1 }; + 8'h78: internal_din <= { 8'd0, SCM1 }; + 8'h79: internal_din <= { 8'd0, SCC1 }; + 8'h7a: internal_din <= { 8'd0, BRG1 }; + 8'h7b: internal_din <= { 8'd0, SCE1 }; + 8'h7c: internal_din <= { 8'd0, SEIC1 }; + 8'h7d: internal_din <= { 8'd0, SRIC1 }; + 8'h7e: internal_din <= { 8'd0, STIC1 }; + 8'h80: internal_din <= TM0; + 8'h81: internal_din <= { 8'd0, TM0[15:8] }; + 8'h82: internal_din <= MD0; + 8'h83: internal_din <= { 8'd0, MD0[15:8] }; + 8'h88: internal_din <= TM1; + 8'h89: internal_din <= { 8'd0, TM1[15:8] }; + 8'h8a: internal_din <= MD1; + 8'h8b: internal_din <= { 8'd0, MD1[15:8] }; + 8'h90: internal_din <= { 8'd0, TMC0 }; + 8'h91: internal_din <= { 8'd0, TMC1 }; + 8'h94: internal_din <= { 8'd0, TMMS0 }; + 8'h95: internal_din <= { 8'd0, TMMS1 }; + 8'h96: internal_din <= { 8'd0, TMMS2 }; + 8'h9c: internal_din <= { 8'd0, TMIC0 }; + 8'h9d: internal_din <= { 8'd0, TMIC1 }; + 8'h9e: internal_din <= { 8'd0, TMIC2 }; + 8'ha0: internal_din <= { 8'd0, DMAC0 }; + 8'ha1: internal_din <= { 8'd0, DMAM0 }; + 8'ha2: internal_din <= { 8'd0, DMAC1 }; + 8'ha3: internal_din <= { 8'd0, DMAM1 }; + 8'hac: internal_din <= { 8'd0, DIC0 }; + 8'had: internal_din <= { 8'd0, DIC1 }; + 8'he0: internal_din <= { 8'd0, STBC }; + 8'he1: internal_din <= { 8'd0, RFM }; + 8'he8: internal_din <= WTC; + 8'he9: internal_din <= { 8'd0, WTC[15:8] }; + 8'hea: internal_din <= { 8'd0, FLAG }; + 8'heb: internal_din <= { 8'd0, PRC }; + 8'hec: internal_din <= { 8'd0, TBIC }; + 8'hff: internal_din <= { 8'd0, IDB }; + endcase + end + end else if (internal_ram_rq) begin +/* + if (wr) begin + if (be[0]) iram[addr[7:0]] <= dout[7:0]; + if (be[1]) iram[addr[7:0] + 8'd1] <= dout[15:8]; + end else if (rd) begin + internal_din <= { iram[addr[7:0] + 8'd1], iram[addr[7:0]] }; + end +*/ + end + + if (rd) internal_rq_latch <= internal_rq; + + if (rd | wr) begin + case(addr[19:16]) + 4'h0, 4'h1: wait_cycles <= WTC[1:0]; + 4'h2, 4'h3: wait_cycles <= WTC[3:2]; + 4'h4, 4'h5: wait_cycles <= WTC[5:4]; + 4'h6, 4'h7: wait_cycles <= WTC[7:6]; + 4'h8, 4'h9: wait_cycles <= WTC[9:8]; + 4'ha, 4'hb: wait_cycles <= WTC[11:10]; + 4'hc, 4'hf: wait_cycles <= WTC[13:12]; + endcase + end + + if (ce_cycle) begin + if (wait_cycles != 2'd0) wait_cycles <= wait_cycles - 2'd1; + + ///////////////////////////////////////////// + //// General CE processing + if (irq_ack) begin + ISPR <= ISPR | exi_prio_bit; + case(irq_pending) + 1: EXIC0[7] <= 0; + 2: EXIC1[7] <= 0; + 3: EXIC2[7] <= 0; + endcase + irq_pending <= 0; + end + + if (irq_fini) begin + casex(ISPR) + 8'bxxxxxxx1: ISPR <= ISPR & 8'b11111110; + 8'bxxxxxx10: ISPR <= ISPR & 8'b11111100; + 8'bxxxxx100: ISPR <= ISPR & 8'b11111000; + 8'bxxxx1000: ISPR <= ISPR & 8'b11110000; + 8'bxxx10000: ISPR <= ISPR & 8'b11100000; + 8'bxx100000: ISPR <= ISPR & 8'b11000000; + 8'bx1000000: ISPR <= ISPR & 8'b10000000; + 8'b10000000: ISPR <= ISPR & 8'b00000000; + endcase + end + + intp0_prev <= intp0; + intp1_prev <= intp1; + intp2_prev <= intp2; + + if (intp0 != intp0_prev && intp0 == ES0) EXIC0[7] <= 1; + if (intp1 != intp1_prev && intp1 == ES1) EXIC1[7] <= 1; + if (intp2 != intp2_prev && intp2 == ES2) EXIC2[7] <= 1; + + if (irq_pending == 0 && (ISPR & exi_prio_bit) == 8'd0) begin + if (EXIC0[7] & ~EXIC0[6]) begin + irq_pending <= 2'd1; + irq_vec <= 8'd24; + end else if (EXIC1[7] & ~EXIC1[6]) begin + irq_pending <= 2'd2; + irq_vec <= 8'd25; + end else if (EXIC2[7] & ~EXIC2[6]) begin + irq_pending <= 2'd3; + irq_vec <= 8'd26; + end + end + end + end + + exi_prio_bit <= 8'd1 << EXIC0[2:0]; +end + +v30 core( + .clk(clk), + .ce(ce_cycle & (wait_cycles == 2'd0)), + .ce_4x(ce & (wait_cycles == 2'd0)), + .reset(reset), + .turbo(1), + .SLOWTIMING(), + + .cpu_idle(), + .cpu_halt(), + .cpu_irqrequest(), + .cpu_prefix(), + .cpu_done(), + + .bus_read(rd), + .bus_write(wr), + .bus_prefetch(prefetching), + .bus_be(be), + .bus_addr(addr), + .bus_datawrite(dout), + .bus_dataread(din), + + .irqrequest_in(irq_pending != 0), + .irqvector_in({irq_vec, 2'b00}), + .irqrequest_ack(irq_ack), + .irqrequest_fini(irq_fini), + + .secure(secure), + .secure_wr(secure_wr), + .secure_addr(secure_addr), + .secure_data(secure_data), + + // TODO - m92 doesn't use IO ports, but we want to merge these with data anyway + .RegBus_Din(), + .RegBus_Adr(), + .RegBus_wren(), + .RegBus_rden(), + .RegBus_Dout(0) +); + +endmodule \ No newline at end of file diff --git a/Arcade_MiST/IremM92 Hardware/sidi/IremM92.qpf b/Arcade_MiST/IremM92 Hardware/sidi/IremM92.qpf new file mode 100644 index 00000000..e65af4b2 --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/sidi/IremM92.qpf @@ -0,0 +1,30 @@ +# -------------------------------------------------------------------------- # +# +# Copyright (C) 1991-2011 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 +# Version 10.1 Build 197 01/19/2011 Service Pack 1 SJ Full Version +# Date created = 23:49:02 July 13, 2012 +# +# -------------------------------------------------------------------------- # + +QUARTUS_VERSION = "10.1" +DATE = "23:49:02 July 13, 2012" + +# Revisions + +PROJECT_REVISION = "IremM92" diff --git a/Arcade_MiST/IremM92 Hardware/sidi/IremM92.qsf b/Arcade_MiST/IremM92 Hardware/sidi/IremM92.qsf new file mode 100644 index 00000000..4cf3964e --- /dev/null +++ b/Arcade_MiST/IremM92 Hardware/sidi/IremM92.qsf @@ -0,0 +1,252 @@ +set_global_assignment -name FIT_ATTEMPTS_TO_SKIP 0 +# -------------------------------------------------------------------------- # +# +# 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 = 21:06:00 February 29, 2020 +# +# -------------------------------------------------------------------------- # +# +# Notes: +# +# 1) The default values for assignments are stored in the file: +# IremM92_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 PROJECT_OUTPUT_DIRECTORY output_files +set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL +set_global_assignment -name LAST_QUARTUS_VERSION 13.1 +set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:../rtl/build_id.tcl" +set_global_assignment -name SMART_RECOMPILE ON + +# Pin & Location Assignments +# ========================== +set_location_assignment PIN_G1 -to LED +set_location_assignment PIN_E1 -to CLOCK_27 +set_location_assignment PIN_P16 -to VGA_R[5] +set_location_assignment PIN_P15 -to VGA_R[4] +set_location_assignment PIN_R16 -to VGA_R[3] +set_location_assignment PIN_R14 -to VGA_R[2] +set_location_assignment PIN_T15 -to VGA_R[1] +set_location_assignment PIN_T14 -to VGA_R[0] +set_location_assignment PIN_J16 -to VGA_B[5] +set_location_assignment PIN_J15 -to VGA_B[4] +set_location_assignment PIN_J14 -to VGA_B[3] +set_location_assignment PIN_K16 -to VGA_B[2] +set_location_assignment PIN_K15 -to VGA_B[1] +set_location_assignment PIN_J13 -to VGA_B[0] +set_location_assignment PIN_F16 -to VGA_G[5] +set_location_assignment PIN_F15 -to VGA_G[4] +set_location_assignment PIN_L16 -to VGA_G[3] +set_location_assignment PIN_L15 -to VGA_G[2] +set_location_assignment PIN_N15 -to VGA_G[1] +set_location_assignment PIN_N16 -to VGA_G[0] +set_location_assignment PIN_T10 -to VGA_VS +set_location_assignment PIN_T11 -to VGA_HS +set_location_assignment PIN_T12 -to AUDIO_L +set_location_assignment PIN_T13 -to AUDIO_R +set_location_assignment PIN_T2 -to SPI_DO +set_location_assignment PIN_R1 -to SPI_DI +set_location_assignment PIN_T3 -to SPI_SCK +set_location_assignment PIN_T4 -to SPI_SS2 +set_location_assignment PIN_G15 -to SPI_SS3 +set_location_assignment PIN_G16 -to SPI_SS4 +set_location_assignment PIN_H2 -to CONF_DATA0 +set_location_assignment PIN_B14 -to SDRAM_A[0] +set_location_assignment PIN_C14 -to SDRAM_A[1] +set_location_assignment PIN_C15 -to SDRAM_A[2] +set_location_assignment PIN_C16 -to SDRAM_A[3] +set_location_assignment PIN_B16 -to SDRAM_A[4] +set_location_assignment PIN_A15 -to SDRAM_A[5] +set_location_assignment PIN_A14 -to SDRAM_A[6] +set_location_assignment PIN_A13 -to SDRAM_A[7] +set_location_assignment PIN_A12 -to SDRAM_A[8] +set_location_assignment PIN_D16 -to SDRAM_A[9] +set_location_assignment PIN_B13 -to SDRAM_A[10] +set_location_assignment PIN_D15 -to SDRAM_A[11] +set_location_assignment PIN_D14 -to SDRAM_A[12] +set_location_assignment PIN_C3 -to SDRAM_DQ[0] +set_location_assignment PIN_C2 -to SDRAM_DQ[1] +set_location_assignment PIN_A4 -to SDRAM_DQ[2] +set_location_assignment PIN_B4 -to SDRAM_DQ[3] +set_location_assignment PIN_A6 -to SDRAM_DQ[4] +set_location_assignment PIN_D6 -to SDRAM_DQ[5] +set_location_assignment PIN_A7 -to SDRAM_DQ[6] +set_location_assignment PIN_B7 -to SDRAM_DQ[7] +set_location_assignment PIN_E6 -to SDRAM_DQ[8] +set_location_assignment PIN_C6 -to SDRAM_DQ[9] +set_location_assignment PIN_B6 -to SDRAM_DQ[10] +set_location_assignment PIN_B5 -to SDRAM_DQ[11] +set_location_assignment PIN_A5 -to SDRAM_DQ[12] +set_location_assignment PIN_B3 -to SDRAM_DQ[13] +set_location_assignment PIN_A3 -to SDRAM_DQ[14] +set_location_assignment PIN_A2 -to SDRAM_DQ[15] +set_location_assignment PIN_A11 -to SDRAM_BA[0] +set_location_assignment PIN_B12 -to SDRAM_BA[1] +set_location_assignment PIN_C9 -to SDRAM_DQMH +set_location_assignment PIN_C8 -to SDRAM_DQML +set_location_assignment PIN_A10 -to SDRAM_nRAS +set_location_assignment PIN_B10 -to SDRAM_nCAS +set_location_assignment PIN_D8 -to SDRAM_nWE +set_location_assignment PIN_B11 -to SDRAM_nCS +set_location_assignment PIN_C11 -to SDRAM_CKE +set_location_assignment PIN_R4 -to SDRAM_CLK + +# Classic Timing Assignments +# ========================== +set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0 +set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85 +set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS ON + +# Analysis & Synthesis Assignments +# ================================ +set_global_assignment -name TOP_LEVEL_ENTITY IremM92_MiST +set_global_assignment -name DEVICE_FILTER_PIN_COUNT 144 +set_global_assignment -name DEVICE_FILTER_SPEED_GRADE 8 +set_global_assignment -name DEVICE_FILTER_PACKAGE TQFP +set_global_assignment -name CYCLONEII_OPTIMIZATION_TECHNIQUE AREA +set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS ON +set_global_assignment -name ALLOW_SYNCH_CTRL_USAGE ON +set_global_assignment -name VHDL_INPUT_VERSION VHDL_2008 +set_global_assignment -name VHDL_SHOW_LMF_MAPPING_MESSAGES OFF + +# Fitter Assignments +# ================== +set_global_assignment -name DEVICE EP4CE22F17C8 +set_global_assignment -name FAMILY "Cyclone IV E" +set_global_assignment -name ENABLE_CONFIGURATION_PINS OFF +set_global_assignment -name ENABLE_NCE_PIN OFF +set_global_assignment -name ENABLE_BOOT_SEL_PIN OFF +set_global_assignment -name CYCLONEIII_CONFIGURATION_SCHEME "PASSIVE SERIAL" +set_global_assignment -name CRC_ERROR_OPEN_DRAIN OFF +set_global_assignment -name FORCE_CONFIGURATION_VCCIO ON +set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "3.3-V LVTTL" +set_global_assignment -name CYCLONEII_RESERVE_NCEO_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_global_assignment -name RESERVE_DATA0_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_global_assignment -name RESERVE_DATA1_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_global_assignment -name RESERVE_FLASH_NCE_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_global_assignment -name RESERVE_DCLK_AFTER_CONFIGURATION "USE AS REGULAR IO" +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 output_files/cpu.stp + +# Power Estimation Assignments +# ============================ +set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "NO HEAT SINK WITH STILL AIR" +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(IremM92_MiST) + + # Pin & Location Assignments + # ========================== +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[*] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[*] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_BA[0] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_BA[1] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQMH +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQML +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nRAS +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nCAS +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nWE +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nCS +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[*] +set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[*] + + # Fitter Assignments + # ================== +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[*] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[*] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_BA[*] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQML +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQMH +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nRAS +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nCAS +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nWE +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nCS +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_CKE +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_CLK +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_R[*] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_G[*] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_B[*] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_HS +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_VS +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to AUDIO_L +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to AUDIO_R +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SPI_DO + + # start DESIGN_PARTITION(Top) + # --------------------------- + + # Incremental Compilation Assignments + # =================================== +set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top +set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top +set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top + + # end DESIGN_PARTITION(Top) + # ------------------------- + +# end ENTITY(IremM92_MiST) +# --------------------------- +set_location_assignment PLL_1 -to pll|altpll_component|auto_generated|pll1 +set_global_assignment -name DSP_BLOCK_BALANCING "DSP BLOCKS" +set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_RETIMING OFF +set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_DUPLICATION OFF +set_global_assignment -name AUTO_SHIFT_REGISTER_RECOGNITION AUTO +set_global_assignment -name PHYSICAL_SYNTHESIS_EFFORT EXTRA +set_global_assignment -name VERILOG_SHOW_LMF_MAPPING_MESSAGES OFF +set_global_assignment -name AUTO_RESOURCE_SHARING ON +set_global_assignment -name SDC_FILE ../IremM92.sdc +set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/IremM92_MiST.sv +set_global_assignment -name QIP_FILE ../rtl/pll_mist.qip +set_global_assignment -name QIP_FILE ../rtl/m92.qip +set_global_assignment -name QIP_FILE ../../../common/mist/mist.qip +set_global_assignment -name QIP_FILE ../../../common/CPU/v30/V30.qip +set_global_assignment -name QIP_FILE ../../../common/Sound/jt51/jt51.qip +set_global_assignment -name VERILOG_MACRO "JT51_ONLYTIMERS=1" +set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/common/CPU/v30/cpu.vhd b/common/CPU/v30/cpu.vhd index b8036401..e269aa70 100644 --- a/common/CPU/v30/cpu.vhd +++ b/common/CPU/v30/cpu.vhd @@ -319,7 +319,7 @@ architecture arch of v30 is signal irqBlocked : std_logic; signal reqModRM : std_logic; signal repeatZero : std_logic; - signal opsize : integer range 1 to 2; + signal opsize : std_logic; signal instantFetch : std_logic; signal fetch1Val : unsigned(15 downto 0); signal fetch2Val : unsigned(15 downto 0); @@ -429,7 +429,9 @@ architecture arch of v30 is type arr_opcode IS ARRAY (0 to 255) OF std_logic_vector(7 downto 0); signal decryption_table : arr_opcode; attribute ramstyle : string; - attribute ramstyle OF decryption_table : signal is "logic"; + --attribute ramstyle OF decryption_table : signal is "logic"; + signal decryption_addr : unsigned(7 downto 0); + signal decryption_q : std_logic_vector(7 downto 0); -- savestates signal SS_CPU1 : std_logic_vector(REG_SAVESTATE_CPU1.upper downto REG_SAVESTATE_CPU1.lower); @@ -509,7 +511,15 @@ begin SS_CPU_BACK3(63 downto 48) <= std_logic_vector(regs.reg_ss); SS_CPU_BACK4(15 downto 0) <= std_logic_vector(regs.reg_ds); SS_CPU_BACK4(31 downto 16) <= std_logic_vector(Reg_f); - + + decryption_addr <= secure_addr when secure_wr = '1' else + unsigned(prefetchBuffer(15 downto 8)) when consumePrefetch = 1 else unsigned(prefetchBuffer(7 downto 0)); + process (clk) begin + if falling_edge(clk) then + decryption_q <= decryption_table(to_integer(decryption_addr)); + end if; + end process; + process (clk) variable varPrefetchCount : integer range 0 to 15; variable varprefetchBuffer : std_logic_vector(127 downto 0); @@ -570,7 +580,7 @@ begin bus_read <= '0'; bus_write <= '0'; - + if (ce_4x = '1') then clearPrefetch <= '0'; consumePrefetch <= 0; @@ -585,9 +595,8 @@ begin end if; if (secure_wr = '1') then - decryption_table(to_integer(secure_addr)) <= secure_data; + decryption_table(to_integer(decryption_addr)) <= secure_data; end if; - --if (testpcsum(63) = '1' and testcmd(31) = '1') then -- DIVstart <= '1'; --end if; @@ -598,30 +607,30 @@ begin if (reset = '1') then - regs.reg_ip <= unsigned(SS_CPU1(15 downto 0)); -- x"0000"; - regs.reg_ax <= unsigned(SS_CPU1(31 downto 16)); -- x"0000"; - regs.reg_cx <= unsigned(SS_CPU1(47 downto 32)); -- x"0000"; - regs.reg_dx <= unsigned(SS_CPU1(63 downto 48)); -- x"0000"; - regs.reg_bx <= unsigned(SS_CPU2(15 downto 0)); -- x"0000"; - regs.reg_sp <= unsigned(SS_CPU2(31 downto 16)); -- x"2000"; - regs.reg_bp <= unsigned(SS_CPU2(47 downto 32)); -- x"0000"; - regs.reg_si <= unsigned(SS_CPU2(63 downto 48)); -- x"0000"; - regs.reg_di <= unsigned(SS_CPU3(15 downto 0)); -- x"0000"; - regs.reg_es <= unsigned(SS_CPU3(31 downto 16)); -- x"0000"; - regs.reg_cs <= unsigned(SS_CPU3(47 downto 32)); -- x"FFFF"; - regs.reg_ss <= unsigned(SS_CPU3(63 downto 48)); -- x"0000"; - regs.reg_ds <= unsigned(SS_CPU4(15 downto 0)); -- x"0000"; + regs.reg_ip <= x"0000"; + regs.reg_ax <= x"0000"; + regs.reg_cx <= x"0000"; + regs.reg_dx <= x"0000"; + regs.reg_bx <= x"0000"; + regs.reg_sp <= x"2000"; + regs.reg_bp <= x"0000"; + regs.reg_si <= x"0000"; + regs.reg_di <= x"0000"; + regs.reg_es <= x"0000"; + regs.reg_cs <= x"FFFF"; + regs.reg_ss <= x"0000"; + regs.reg_ds <= x"0000"; - regs.FlagCar <= SS_CPU4(16); --'0'; - regs.FlagPar <= SS_CPU4(18); --'0'; - regs.FlagHaC <= SS_CPU4(20); --'0'; - regs.FlagZer <= SS_CPU4(22); --'0'; - regs.FlagSgn <= SS_CPU4(23); --'0'; - regs.FlagBrk <= SS_CPU4(24); --'0'; - regs.FlagIrq <= SS_CPU4(25); --'0'; - regs.FlagDir <= SS_CPU4(26); --'0'; - regs.FlagOvf <= SS_CPU4(27); --'0'; - regs.FlagMod <= SS_CPU4(31); --'1'; + regs.FlagCar <= '0'; + regs.FlagPar <= '0'; + regs.FlagHaC <= '0'; + regs.FlagZer <= '0'; + regs.FlagSgn <= '0'; + regs.FlagBrk <= '0'; + regs.FlagIrq <= '0'; + regs.FlagDir <= '0'; + regs.FlagOvf <= '0'; + regs.FlagMod <= '1'; halt <= '0'; cpustage <= CPUSTAGE_IDLE; @@ -719,13 +728,13 @@ begin exOpcodebyte <= x"00"; if (consumePrefetch = 1) then if (secure) then - opcodebyte <= decryption_table(to_integer(unsigned(prefetchBuffer(15 downto 8)))); + opcodebyte <= decryption_q; else opcodebyte <= prefetchBuffer(15 downto 8); end if; else if (secure) then - opcodebyte <= decryption_table(to_integer(unsigned(prefetchBuffer(7 downto 0)))); + opcodebyte <= decryption_q; else opcodebyte <= prefetchBuffer(7 downto 0); end if; @@ -799,22 +808,22 @@ begin case (opcodebyte) is - when x"00" => opcode <= OP_MOVMEM; aluop <= ALU_OP_ADD; useAluResult <= '1'; opsize <= 1; newDelay := 1; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_MODRM_REG; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MEM; - when x"01" => opcode <= OP_MOVMEM; aluop <= ALU_OP_ADD; useAluResult <= '1'; opsize <= 2; newDelay := 1; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_MODRM_REG; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MEM; - when x"02" => opcode <= OP_MOVREG; aluop <= ALU_OP_ADD; useAluResult <= '1'; opsize <= 1; source1 <= OPSOURCE_MODRM_REG; source2 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MODRM_REG; - when x"03" => opcode <= OP_MOVREG; aluop <= ALU_OP_ADD; useAluResult <= '1'; opsize <= 2; source1 <= OPSOURCE_MODRM_REG; source2 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MODRM_REG; - when x"04" => opcode <= OP_MOVREG; aluop <= ALU_OP_ADD; useAluResult <= '1'; opsize <= 1; instantFetch <= '1'; source1 <= OPSOURCE_ACC; source2 <= OPSOURCE_FETCHVALUE8; cpustage <= CPUSTAGE_FETCHDATA2_8 ; optarget <= OPTARGET_DECODE; target_decode <= CPU_REG_al; - when x"05" => opcode <= OP_MOVREG; aluop <= ALU_OP_ADD; useAluResult <= '1'; opsize <= 2; instantFetch <= '1'; source1 <= OPSOURCE_ACC; source2 <= OPSOURCE_FETCHVALUE16; cpustage <= CPUSTAGE_FETCHDATA2_16; optarget <= OPTARGET_DECODE; target_decode <= CPU_REG_ax; + when x"00" => opcode <= OP_MOVMEM; aluop <= ALU_OP_ADD; useAluResult <= '1'; opsize <= '0'; newDelay := 1; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_MODRM_REG; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MEM; + when x"01" => opcode <= OP_MOVMEM; aluop <= ALU_OP_ADD; useAluResult <= '1'; opsize <= '1'; newDelay := 1; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_MODRM_REG; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MEM; + when x"02" => opcode <= OP_MOVREG; aluop <= ALU_OP_ADD; useAluResult <= '1'; opsize <= '0'; source1 <= OPSOURCE_MODRM_REG; source2 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MODRM_REG; + when x"03" => opcode <= OP_MOVREG; aluop <= ALU_OP_ADD; useAluResult <= '1'; opsize <= '1'; source1 <= OPSOURCE_MODRM_REG; source2 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MODRM_REG; + when x"04" => opcode <= OP_MOVREG; aluop <= ALU_OP_ADD; useAluResult <= '1'; opsize <= '0'; instantFetch <= '1'; source1 <= OPSOURCE_ACC; source2 <= OPSOURCE_FETCHVALUE8; cpustage <= CPUSTAGE_FETCHDATA2_8 ; optarget <= OPTARGET_DECODE; target_decode <= CPU_REG_al; + when x"05" => opcode <= OP_MOVREG; aluop <= ALU_OP_ADD; useAluResult <= '1'; opsize <= '1'; instantFetch <= '1'; source1 <= OPSOURCE_ACC; source2 <= OPSOURCE_FETCHVALUE16; cpustage <= CPUSTAGE_FETCHDATA2_16; optarget <= OPTARGET_DECODE; target_decode <= CPU_REG_ax; when x"06" => pushlist <= REGPOS_es; cpustage <= CPUSTAGE_CHECKDATAREADY; when x"07" => poplist <= REGPOS_es; cpustage <= CPUSTAGE_CHECKDATAREADY; newDelay := 1; - when x"08" => opcode <= OP_MOVMEM; aluop <= ALU_OP_OR ; useAluResult <= '1'; opsize <= 1; newDelay := 1; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_MODRM_REG; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MEM; - when x"09" => opcode <= OP_MOVMEM; aluop <= ALU_OP_OR ; useAluResult <= '1'; opsize <= 2; newDelay := 1; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_MODRM_REG; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MEM; - when x"0A" => opcode <= OP_MOVREG; aluop <= ALU_OP_OR ; useAluResult <= '1'; opsize <= 1; source1 <= OPSOURCE_MODRM_REG; source2 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MODRM_REG; - when x"0B" => opcode <= OP_MOVREG; aluop <= ALU_OP_OR ; useAluResult <= '1'; opsize <= 2; source1 <= OPSOURCE_MODRM_REG; source2 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MODRM_REG; - when x"0C" => opcode <= OP_MOVREG; aluop <= ALU_OP_OR ; useAluResult <= '1'; opsize <= 1; instantFetch <= '1'; source1 <= OPSOURCE_ACC; source2 <= OPSOURCE_FETCHVALUE8; cpustage <= CPUSTAGE_FETCHDATA2_8 ; optarget <= OPTARGET_DECODE; target_decode <= CPU_REG_al; - when x"0D" => opcode <= OP_MOVREG; aluop <= ALU_OP_OR ; useAluResult <= '1'; opsize <= 2; instantFetch <= '1'; source1 <= OPSOURCE_ACC; source2 <= OPSOURCE_FETCHVALUE16; cpustage <= CPUSTAGE_FETCHDATA2_16; optarget <= OPTARGET_DECODE; target_decode <= CPU_REG_ax; + when x"08" => opcode <= OP_MOVMEM; aluop <= ALU_OP_OR ; useAluResult <= '1'; opsize <= '0'; newDelay := 1; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_MODRM_REG; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MEM; + when x"09" => opcode <= OP_MOVMEM; aluop <= ALU_OP_OR ; useAluResult <= '1'; opsize <= '1'; newDelay := 1; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_MODRM_REG; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MEM; + when x"0A" => opcode <= OP_MOVREG; aluop <= ALU_OP_OR ; useAluResult <= '1'; opsize <= '0'; source1 <= OPSOURCE_MODRM_REG; source2 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MODRM_REG; + when x"0B" => opcode <= OP_MOVREG; aluop <= ALU_OP_OR ; useAluResult <= '1'; opsize <= '1'; source1 <= OPSOURCE_MODRM_REG; source2 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MODRM_REG; + when x"0C" => opcode <= OP_MOVREG; aluop <= ALU_OP_OR ; useAluResult <= '1'; opsize <= '0'; instantFetch <= '1'; source1 <= OPSOURCE_ACC; source2 <= OPSOURCE_FETCHVALUE8; cpustage <= CPUSTAGE_FETCHDATA2_8 ; optarget <= OPTARGET_DECODE; target_decode <= CPU_REG_al; + when x"0D" => opcode <= OP_MOVREG; aluop <= ALU_OP_OR ; useAluResult <= '1'; opsize <= '1'; instantFetch <= '1'; source1 <= OPSOURCE_ACC; source2 <= OPSOURCE_FETCHVALUE16; cpustage <= CPUSTAGE_FETCHDATA2_16; optarget <= OPTARGET_DECODE; target_decode <= CPU_REG_ax; when x"0E" => pushlist <= REGPOS_cs; cpustage <= CPUSTAGE_CHECKDATAREADY; when x"0F" => @@ -823,25 +832,25 @@ begin consumePrefetch <= 1; case (prefetchBuffer(15 downto 8)) is -- TEST1 - when x"10" => cpustage <= CPUSTAGE_MODRM; opcode <= OP_NOP; aluop <= ALU_OP_TEST1; opsize <= 1; source2 <= OPSOURCE_REG_cx; source1 <= OPSOURCE_MEM; - when x"11" => cpustage <= CPUSTAGE_MODRM; opcode <= OP_NOP; aluop <= ALU_OP_TEST1; opsize <= 2; source2 <= OPSOURCE_REG_cx; source1 <= OPSOURCE_MEM; - when x"18" => cpustage <= CPUSTAGE_MODRM; opcode <= OP_NOP; aluop <= ALU_OP_TEST1; opsize <= 1; source2 <= OPSOURCE_FETCHVALUE8; source1 <= OPSOURCE_MEM; - when x"19" => cpustage <= CPUSTAGE_MODRM; opcode <= OP_NOP; aluop <= ALU_OP_TEST1; opsize <= 2; source2 <= OPSOURCE_FETCHVALUE8; source1 <= OPSOURCE_MEM; + when x"10" => cpustage <= CPUSTAGE_MODRM; opcode <= OP_NOP; aluop <= ALU_OP_TEST1; opsize <= '0'; source2 <= OPSOURCE_REG_cx; source1 <= OPSOURCE_MEM; + when x"11" => cpustage <= CPUSTAGE_MODRM; opcode <= OP_NOP; aluop <= ALU_OP_TEST1; opsize <= '1'; source2 <= OPSOURCE_REG_cx; source1 <= OPSOURCE_MEM; + when x"18" => cpustage <= CPUSTAGE_MODRM; opcode <= OP_NOP; aluop <= ALU_OP_TEST1; opsize <= '0'; source2 <= OPSOURCE_FETCHVALUE8; source1 <= OPSOURCE_MEM; + when x"19" => cpustage <= CPUSTAGE_MODRM; opcode <= OP_NOP; aluop <= ALU_OP_TEST1; opsize <= '1'; source2 <= OPSOURCE_FETCHVALUE8; source1 <= OPSOURCE_MEM; -- CLR1 - when x"12" => cpustage <= CPUSTAGE_MODRM; opcode <= OP_MOVMEM; aluop <= ALU_OP_CLR1; opsize <= 1; useAluResult <= '1'; source2 <= OPSOURCE_REG_cx; source1 <= OPSOURCE_MEM; optarget <= OPTARGET_MEM; - when x"13" => cpustage <= CPUSTAGE_MODRM; opcode <= OP_MOVMEM; aluop <= ALU_OP_CLR1; opsize <= 2; useAluResult <= '1'; source2 <= OPSOURCE_REG_cx; source1 <= OPSOURCE_MEM; optarget <= OPTARGET_MEM; - when x"1a" => cpustage <= CPUSTAGE_MODRM; opcode <= OP_MOVMEM; aluop <= ALU_OP_CLR1; opsize <= 1; useAluResult <= '1'; source2 <= OPSOURCE_FETCHVALUE8; source1 <= OPSOURCE_MEM; optarget <= OPTARGET_MEM; - when x"1b" => cpustage <= CPUSTAGE_MODRM; opcode <= OP_MOVMEM; aluop <= ALU_OP_CLR1; opsize <= 2; useAluResult <= '1'; source2 <= OPSOURCE_FETCHVALUE8; source1 <= OPSOURCE_MEM; optarget <= OPTARGET_MEM; + when x"12" => cpustage <= CPUSTAGE_MODRM; opcode <= OP_MOVMEM; aluop <= ALU_OP_CLR1; opsize <= '0'; useAluResult <= '1'; source2 <= OPSOURCE_REG_cx; source1 <= OPSOURCE_MEM; optarget <= OPTARGET_MEM; + when x"13" => cpustage <= CPUSTAGE_MODRM; opcode <= OP_MOVMEM; aluop <= ALU_OP_CLR1; opsize <= '1'; useAluResult <= '1'; source2 <= OPSOURCE_REG_cx; source1 <= OPSOURCE_MEM; optarget <= OPTARGET_MEM; + when x"1a" => cpustage <= CPUSTAGE_MODRM; opcode <= OP_MOVMEM; aluop <= ALU_OP_CLR1; opsize <= '0'; useAluResult <= '1'; source2 <= OPSOURCE_FETCHVALUE8; source1 <= OPSOURCE_MEM; optarget <= OPTARGET_MEM; + when x"1b" => cpustage <= CPUSTAGE_MODRM; opcode <= OP_MOVMEM; aluop <= ALU_OP_CLR1; opsize <= '1'; useAluResult <= '1'; source2 <= OPSOURCE_FETCHVALUE8; source1 <= OPSOURCE_MEM; optarget <= OPTARGET_MEM; -- SET1 - when x"14" => cpustage <= CPUSTAGE_MODRM; opcode <= OP_MOVMEM; aluop <= ALU_OP_SET1; opsize <= 1; useAluResult <= '1'; source2 <= OPSOURCE_REG_cx; source1 <= OPSOURCE_MEM; optarget <= OPTARGET_MEM; - when x"15" => cpustage <= CPUSTAGE_MODRM; opcode <= OP_MOVMEM; aluop <= ALU_OP_SET1; opsize <= 2; useAluResult <= '1'; source2 <= OPSOURCE_REG_cx; source1 <= OPSOURCE_MEM; optarget <= OPTARGET_MEM; - when x"1c" => cpustage <= CPUSTAGE_MODRM; opcode <= OP_MOVMEM; aluop <= ALU_OP_SET1; opsize <= 1; useAluResult <= '1'; source2 <= OPSOURCE_FETCHVALUE8; source1 <= OPSOURCE_MEM; optarget <= OPTARGET_MEM; - when x"1d" => cpustage <= CPUSTAGE_MODRM; opcode <= OP_MOVMEM; aluop <= ALU_OP_SET1; opsize <= 2; useAluResult <= '1'; source2 <= OPSOURCE_FETCHVALUE8; source1 <= OPSOURCE_MEM; optarget <= OPTARGET_MEM; + when x"14" => cpustage <= CPUSTAGE_MODRM; opcode <= OP_MOVMEM; aluop <= ALU_OP_SET1; opsize <= '0'; useAluResult <= '1'; source2 <= OPSOURCE_REG_cx; source1 <= OPSOURCE_MEM; optarget <= OPTARGET_MEM; + when x"15" => cpustage <= CPUSTAGE_MODRM; opcode <= OP_MOVMEM; aluop <= ALU_OP_SET1; opsize <= '1'; useAluResult <= '1'; source2 <= OPSOURCE_REG_cx; source1 <= OPSOURCE_MEM; optarget <= OPTARGET_MEM; + when x"1c" => cpustage <= CPUSTAGE_MODRM; opcode <= OP_MOVMEM; aluop <= ALU_OP_SET1; opsize <= '0'; useAluResult <= '1'; source2 <= OPSOURCE_FETCHVALUE8; source1 <= OPSOURCE_MEM; optarget <= OPTARGET_MEM; + when x"1d" => cpustage <= CPUSTAGE_MODRM; opcode <= OP_MOVMEM; aluop <= ALU_OP_SET1; opsize <= '1'; useAluResult <= '1'; source2 <= OPSOURCE_FETCHVALUE8; source1 <= OPSOURCE_MEM; optarget <= OPTARGET_MEM; -- NOT1 - when x"16" => cpustage <= CPUSTAGE_MODRM; opcode <= OP_MOVMEM; aluop <= ALU_OP_NOT1; opsize <= 1; useAluResult <= '1'; source2 <= OPSOURCE_REG_cx; source1 <= OPSOURCE_MEM; optarget <= OPTARGET_MEM; - when x"17" => cpustage <= CPUSTAGE_MODRM; opcode <= OP_MOVMEM; aluop <= ALU_OP_NOT1; opsize <= 2; useAluResult <= '1'; source2 <= OPSOURCE_REG_cx; source1 <= OPSOURCE_MEM; optarget <= OPTARGET_MEM; - when x"1e" => cpustage <= CPUSTAGE_MODRM; opcode <= OP_MOVMEM; aluop <= ALU_OP_NOT1; opsize <= 1; useAluResult <= '1'; source2 <= OPSOURCE_FETCHVALUE8; source1 <= OPSOURCE_MEM; optarget <= OPTARGET_MEM; - when x"1f" => cpustage <= CPUSTAGE_MODRM; opcode <= OP_MOVMEM; aluop <= ALU_OP_NOT1; opsize <= 2; useAluResult <= '1'; source2 <= OPSOURCE_FETCHVALUE8; source1 <= OPSOURCE_MEM; optarget <= OPTARGET_MEM; + when x"16" => cpustage <= CPUSTAGE_MODRM; opcode <= OP_MOVMEM; aluop <= ALU_OP_NOT1; opsize <= '0'; useAluResult <= '1'; source2 <= OPSOURCE_REG_cx; source1 <= OPSOURCE_MEM; optarget <= OPTARGET_MEM; + when x"17" => cpustage <= CPUSTAGE_MODRM; opcode <= OP_MOVMEM; aluop <= ALU_OP_NOT1; opsize <= '1'; useAluResult <= '1'; source2 <= OPSOURCE_REG_cx; source1 <= OPSOURCE_MEM; optarget <= OPTARGET_MEM; + when x"1e" => cpustage <= CPUSTAGE_MODRM; opcode <= OP_MOVMEM; aluop <= ALU_OP_NOT1; opsize <= '0'; useAluResult <= '1'; source2 <= OPSOURCE_FETCHVALUE8; source1 <= OPSOURCE_MEM; optarget <= OPTARGET_MEM; + when x"1f" => cpustage <= CPUSTAGE_MODRM; opcode <= OP_MOVMEM; aluop <= ALU_OP_NOT1; opsize <= '1'; useAluResult <= '1'; source2 <= OPSOURCE_FETCHVALUE8; source1 <= OPSOURCE_MEM; optarget <= OPTARGET_MEM; -- ADD4S when x"20" => cpustage <= CPUSTAGE_EXECUTE; opcode <= OP_BCDSTRING; bcdOp <= BCD_OP_ADD; bcdOffset <= (others => '0'); regs.FlagCar <= '0'; regs.FlagZer <= '1'; -- SUB4S @@ -849,9 +858,9 @@ begin -- CMP4S when x"26" => cpustage <= CPUSTAGE_EXECUTE; opcode <= OP_BCDSTRING; bcdOp <= BCD_OP_CMP; bcdOffset <= (others => '0'); regs.FlagCar <= '0'; regs.FlagZer <= '1'; -- ROL4 - when x"28" => cpustage <= CPUSTAGE_MODRM; opcode <= OP_MOVMEM; aluop <= ALU_OP_ROL4; opsize <= 1; useAluResult <= '1'; source1 <= OPSOURCE_MEM; optarget <= OPTARGET_MEM; + when x"28" => cpustage <= CPUSTAGE_MODRM; opcode <= OP_MOVMEM; aluop <= ALU_OP_ROL4; opsize <= '0'; useAluResult <= '1'; source1 <= OPSOURCE_MEM; optarget <= OPTARGET_MEM; -- ROR4 - when x"2a" => cpustage <= CPUSTAGE_MODRM; opcode <= OP_MOVMEM; aluop <= ALU_OP_ROR4; opsize <= 1; useAluResult <= '1'; source1 <= OPSOURCE_MEM; optarget <= OPTARGET_MEM; + when x"2a" => cpustage <= CPUSTAGE_MODRM; opcode <= OP_MOVMEM; aluop <= ALU_OP_ROR4; opsize <= '0'; useAluResult <= '1'; source1 <= OPSOURCE_MEM; optarget <= OPTARGET_MEM; -- INS when x"31" => cpustage <= CPUSTAGE_IDLE; cpu_done <= '1'; halt <= '1'; -- EXT @@ -867,86 +876,86 @@ begin end case; - when x"10" => opcode <= OP_MOVMEM; aluop <= ALU_OP_ADC; useAluResult <= '1'; opsize <= 1; newDelay := 1; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_MODRM_REG; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MEM; - when x"11" => opcode <= OP_MOVMEM; aluop <= ALU_OP_ADC; useAluResult <= '1'; opsize <= 2; newDelay := 1; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_MODRM_REG; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MEM; - when x"12" => opcode <= OP_MOVREG; aluop <= ALU_OP_ADC; useAluResult <= '1'; opsize <= 1; source1 <= OPSOURCE_MODRM_REG; source2 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MODRM_REG; - when x"13" => opcode <= OP_MOVREG; aluop <= ALU_OP_ADC; useAluResult <= '1'; opsize <= 2; source1 <= OPSOURCE_MODRM_REG; source2 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MODRM_REG; - when x"14" => opcode <= OP_MOVREG; aluop <= ALU_OP_ADC; useAluResult <= '1'; opsize <= 1; instantFetch <= '1'; source1 <= OPSOURCE_ACC; source2 <= OPSOURCE_FETCHVALUE8; cpustage <= CPUSTAGE_FETCHDATA2_8 ; optarget <= OPTARGET_DECODE; target_decode <= CPU_REG_al; - when x"15" => opcode <= OP_MOVREG; aluop <= ALU_OP_ADC; useAluResult <= '1'; opsize <= 2; instantFetch <= '1'; source1 <= OPSOURCE_ACC; source2 <= OPSOURCE_FETCHVALUE16; cpustage <= CPUSTAGE_FETCHDATA2_16; optarget <= OPTARGET_DECODE; target_decode <= CPU_REG_ax; + when x"10" => opcode <= OP_MOVMEM; aluop <= ALU_OP_ADC; useAluResult <= '1'; opsize <= '0'; newDelay := 1; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_MODRM_REG; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MEM; + when x"11" => opcode <= OP_MOVMEM; aluop <= ALU_OP_ADC; useAluResult <= '1'; opsize <= '1'; newDelay := 1; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_MODRM_REG; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MEM; + when x"12" => opcode <= OP_MOVREG; aluop <= ALU_OP_ADC; useAluResult <= '1'; opsize <= '0'; source1 <= OPSOURCE_MODRM_REG; source2 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MODRM_REG; + when x"13" => opcode <= OP_MOVREG; aluop <= ALU_OP_ADC; useAluResult <= '1'; opsize <= '1'; source1 <= OPSOURCE_MODRM_REG; source2 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MODRM_REG; + when x"14" => opcode <= OP_MOVREG; aluop <= ALU_OP_ADC; useAluResult <= '1'; opsize <= '0'; instantFetch <= '1'; source1 <= OPSOURCE_ACC; source2 <= OPSOURCE_FETCHVALUE8; cpustage <= CPUSTAGE_FETCHDATA2_8 ; optarget <= OPTARGET_DECODE; target_decode <= CPU_REG_al; + when x"15" => opcode <= OP_MOVREG; aluop <= ALU_OP_ADC; useAluResult <= '1'; opsize <= '1'; instantFetch <= '1'; source1 <= OPSOURCE_ACC; source2 <= OPSOURCE_FETCHVALUE16; cpustage <= CPUSTAGE_FETCHDATA2_16; optarget <= OPTARGET_DECODE; target_decode <= CPU_REG_ax; when x"16" => pushlist <= REGPOS_ss; cpustage <= CPUSTAGE_CHECKDATAREADY; when x"17" => poplist <= REGPOS_ss; cpustage <= CPUSTAGE_CHECKDATAREADY; newDelay := 1; irqBlocked <= '1'; - when x"18" => opcode <= OP_MOVMEM; aluop <= ALU_OP_SBB; useAluResult <= '1'; opsize <= 1; newDelay := 1; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_MODRM_REG; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MEM; - when x"19" => opcode <= OP_MOVMEM; aluop <= ALU_OP_SBB; useAluResult <= '1'; opsize <= 2; newDelay := 1; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_MODRM_REG; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MEM; - when x"1A" => opcode <= OP_MOVREG; aluop <= ALU_OP_SBB; useAluResult <= '1'; opsize <= 1; source1 <= OPSOURCE_MODRM_REG; source2 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MODRM_REG; - when x"1B" => opcode <= OP_MOVREG; aluop <= ALU_OP_SBB; useAluResult <= '1'; opsize <= 2; source1 <= OPSOURCE_MODRM_REG; source2 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MODRM_REG; - when x"1C" => opcode <= OP_MOVREG; aluop <= ALU_OP_SBB; useAluResult <= '1'; opsize <= 1; instantFetch <= '1'; source1 <= OPSOURCE_ACC; source2 <= OPSOURCE_FETCHVALUE8; cpustage <= CPUSTAGE_FETCHDATA2_8 ; optarget <= OPTARGET_DECODE; target_decode <= CPU_REG_al; - when x"1D" => opcode <= OP_MOVREG; aluop <= ALU_OP_SBB; useAluResult <= '1'; opsize <= 2; instantFetch <= '1'; source1 <= OPSOURCE_ACC; source2 <= OPSOURCE_FETCHVALUE16; cpustage <= CPUSTAGE_FETCHDATA2_16; optarget <= OPTARGET_DECODE; target_decode <= CPU_REG_ax; + when x"18" => opcode <= OP_MOVMEM; aluop <= ALU_OP_SBB; useAluResult <= '1'; opsize <= '0'; newDelay := 1; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_MODRM_REG; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MEM; + when x"19" => opcode <= OP_MOVMEM; aluop <= ALU_OP_SBB; useAluResult <= '1'; opsize <= '1'; newDelay := 1; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_MODRM_REG; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MEM; + when x"1A" => opcode <= OP_MOVREG; aluop <= ALU_OP_SBB; useAluResult <= '1'; opsize <= '0'; source1 <= OPSOURCE_MODRM_REG; source2 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MODRM_REG; + when x"1B" => opcode <= OP_MOVREG; aluop <= ALU_OP_SBB; useAluResult <= '1'; opsize <= '1'; source1 <= OPSOURCE_MODRM_REG; source2 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MODRM_REG; + when x"1C" => opcode <= OP_MOVREG; aluop <= ALU_OP_SBB; useAluResult <= '1'; opsize <= '0'; instantFetch <= '1'; source1 <= OPSOURCE_ACC; source2 <= OPSOURCE_FETCHVALUE8; cpustage <= CPUSTAGE_FETCHDATA2_8 ; optarget <= OPTARGET_DECODE; target_decode <= CPU_REG_al; + when x"1D" => opcode <= OP_MOVREG; aluop <= ALU_OP_SBB; useAluResult <= '1'; opsize <= '1'; instantFetch <= '1'; source1 <= OPSOURCE_ACC; source2 <= OPSOURCE_FETCHVALUE16; cpustage <= CPUSTAGE_FETCHDATA2_16; optarget <= OPTARGET_DECODE; target_decode <= CPU_REG_ax; when x"1E" => pushlist <= REGPOS_ds; cpustage <= CPUSTAGE_CHECKDATAREADY; when x"1F" => poplist <= REGPOS_ds; cpustage <= CPUSTAGE_CHECKDATAREADY; newDelay := 1; - when x"20" => opcode <= OP_MOVMEM; aluop <= ALU_OP_AND; useAluResult <= '1'; opsize <= 1; newDelay := 1; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_MODRM_REG; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MEM; - when x"21" => opcode <= OP_MOVMEM; aluop <= ALU_OP_AND; useAluResult <= '1'; opsize <= 2; newDelay := 1; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_MODRM_REG; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MEM; - when x"22" => opcode <= OP_MOVREG; aluop <= ALU_OP_AND; useAluResult <= '1'; opsize <= 1; source1 <= OPSOURCE_MODRM_REG; source2 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MODRM_REG; - when x"23" => opcode <= OP_MOVREG; aluop <= ALU_OP_AND; useAluResult <= '1'; opsize <= 2; source1 <= OPSOURCE_MODRM_REG; source2 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MODRM_REG; - when x"24" => opcode <= OP_MOVREG; aluop <= ALU_OP_AND; useAluResult <= '1'; opsize <= 1; instantFetch <= '1'; source1 <= OPSOURCE_ACC; source2 <= OPSOURCE_FETCHVALUE8; cpustage <= CPUSTAGE_FETCHDATA2_8 ; optarget <= OPTARGET_DECODE; target_decode <= CPU_REG_al; - when x"25" => opcode <= OP_MOVREG; aluop <= ALU_OP_AND; useAluResult <= '1'; opsize <= 2; instantFetch <= '1'; source1 <= OPSOURCE_ACC; source2 <= OPSOURCE_FETCHVALUE16; cpustage <= CPUSTAGE_FETCHDATA2_16; optarget <= OPTARGET_DECODE; target_decode <= CPU_REG_ax; + when x"20" => opcode <= OP_MOVMEM; aluop <= ALU_OP_AND; useAluResult <= '1'; opsize <= '0'; newDelay := 1; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_MODRM_REG; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MEM; + when x"21" => opcode <= OP_MOVMEM; aluop <= ALU_OP_AND; useAluResult <= '1'; opsize <= '1'; newDelay := 1; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_MODRM_REG; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MEM; + when x"22" => opcode <= OP_MOVREG; aluop <= ALU_OP_AND; useAluResult <= '1'; opsize <= '0'; source1 <= OPSOURCE_MODRM_REG; source2 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MODRM_REG; + when x"23" => opcode <= OP_MOVREG; aluop <= ALU_OP_AND; useAluResult <= '1'; opsize <= '1'; source1 <= OPSOURCE_MODRM_REG; source2 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MODRM_REG; + when x"24" => opcode <= OP_MOVREG; aluop <= ALU_OP_AND; useAluResult <= '1'; opsize <= '0'; instantFetch <= '1'; source1 <= OPSOURCE_ACC; source2 <= OPSOURCE_FETCHVALUE8; cpustage <= CPUSTAGE_FETCHDATA2_8 ; optarget <= OPTARGET_DECODE; target_decode <= CPU_REG_al; + when x"25" => opcode <= OP_MOVREG; aluop <= ALU_OP_AND; useAluResult <= '1'; opsize <= '1'; instantFetch <= '1'; source1 <= OPSOURCE_ACC; source2 <= OPSOURCE_FETCHVALUE16; cpustage <= CPUSTAGE_FETCHDATA2_16; optarget <= OPTARGET_DECODE; target_decode <= CPU_REG_ax; when x"26" => prefixSegmentES <= '1'; isPrefix := '1'; irqBlocked <= '1'; usePrefix := '1'; cpu_done <= '1'; newBuf := dbuf + 1; cpustage <= CPUSTAGE_IDLE; - when x"27" => opcode <= OP_MOVREG; aluop <= ALU_OP_DECADJUST; useAluResult <= '1'; newDelay := 9; opsize <= 1; cpustage <= CPUSTAGE_EXECUTE; target_decode <= CPU_REG_al; optarget <= OPTARGET_DECODE; adjustNegate <= '0'; + when x"27" => opcode <= OP_MOVREG; aluop <= ALU_OP_DECADJUST; useAluResult <= '1'; newDelay := 9; opsize <= '0'; cpustage <= CPUSTAGE_EXECUTE; target_decode <= CPU_REG_al; optarget <= OPTARGET_DECODE; adjustNegate <= '0'; - when x"28" => opcode <= OP_MOVMEM; aluop <= ALU_OP_SUB; useAluResult <= '1'; opsize <= 1; newDelay := 1; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_MODRM_REG; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MEM; - when x"29" => opcode <= OP_MOVMEM; aluop <= ALU_OP_SUB; useAluResult <= '1'; opsize <= 2; newDelay := 1; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_MODRM_REG; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MEM; - when x"2A" => opcode <= OP_MOVREG; aluop <= ALU_OP_SUB; useAluResult <= '1'; opsize <= 1; source1 <= OPSOURCE_MODRM_REG; source2 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MODRM_REG; - when x"2B" => opcode <= OP_MOVREG; aluop <= ALU_OP_SUB; useAluResult <= '1'; opsize <= 2; source1 <= OPSOURCE_MODRM_REG; source2 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MODRM_REG; - when x"2C" => opcode <= OP_MOVREG; aluop <= ALU_OP_SUB; useAluResult <= '1'; opsize <= 1; instantFetch <= '1'; source1 <= OPSOURCE_ACC; source2 <= OPSOURCE_FETCHVALUE8; cpustage <= CPUSTAGE_FETCHDATA2_8 ; optarget <= OPTARGET_DECODE; target_decode <= CPU_REG_al; - when x"2D" => opcode <= OP_MOVREG; aluop <= ALU_OP_SUB; useAluResult <= '1'; opsize <= 2; instantFetch <= '1'; source1 <= OPSOURCE_ACC; source2 <= OPSOURCE_FETCHVALUE16; cpustage <= CPUSTAGE_FETCHDATA2_16; optarget <= OPTARGET_DECODE; target_decode <= CPU_REG_ax; + when x"28" => opcode <= OP_MOVMEM; aluop <= ALU_OP_SUB; useAluResult <= '1'; opsize <= '0'; newDelay := 1; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_MODRM_REG; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MEM; + when x"29" => opcode <= OP_MOVMEM; aluop <= ALU_OP_SUB; useAluResult <= '1'; opsize <= '1'; newDelay := 1; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_MODRM_REG; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MEM; + when x"2A" => opcode <= OP_MOVREG; aluop <= ALU_OP_SUB; useAluResult <= '1'; opsize <= '0'; source1 <= OPSOURCE_MODRM_REG; source2 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MODRM_REG; + when x"2B" => opcode <= OP_MOVREG; aluop <= ALU_OP_SUB; useAluResult <= '1'; opsize <= '1'; source1 <= OPSOURCE_MODRM_REG; source2 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MODRM_REG; + when x"2C" => opcode <= OP_MOVREG; aluop <= ALU_OP_SUB; useAluResult <= '1'; opsize <= '0'; instantFetch <= '1'; source1 <= OPSOURCE_ACC; source2 <= OPSOURCE_FETCHVALUE8; cpustage <= CPUSTAGE_FETCHDATA2_8 ; optarget <= OPTARGET_DECODE; target_decode <= CPU_REG_al; + when x"2D" => opcode <= OP_MOVREG; aluop <= ALU_OP_SUB; useAluResult <= '1'; opsize <= '1'; instantFetch <= '1'; source1 <= OPSOURCE_ACC; source2 <= OPSOURCE_FETCHVALUE16; cpustage <= CPUSTAGE_FETCHDATA2_16; optarget <= OPTARGET_DECODE; target_decode <= CPU_REG_ax; when x"2E" => prefixSegmentCS <= '1'; isPrefix := '1'; irqBlocked <= '1'; usePrefix := '1'; cpu_done <= '1'; newBuf := dbuf + 1; cpustage <= CPUSTAGE_IDLE; - when x"2F" => opcode <= OP_MOVREG; aluop <= ALU_OP_DECADJUST; useAluResult <= '1'; newDelay := 10; opsize <= 1; cpustage <= CPUSTAGE_EXECUTE; target_decode <= CPU_REG_al; optarget <= OPTARGET_DECODE; adjustNegate <= '1'; + when x"2F" => opcode <= OP_MOVREG; aluop <= ALU_OP_DECADJUST; useAluResult <= '1'; newDelay := 10; opsize <= '0'; cpustage <= CPUSTAGE_EXECUTE; target_decode <= CPU_REG_al; optarget <= OPTARGET_DECODE; adjustNegate <= '1'; - when x"30" => opcode <= OP_MOVMEM; aluop <= ALU_OP_XOR; useAluResult <= '1'; opsize <= 1; newDelay := 1; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_MODRM_REG; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MEM; - when x"31" => opcode <= OP_MOVMEM; aluop <= ALU_OP_XOR; useAluResult <= '1'; opsize <= 2; newDelay := 1; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_MODRM_REG; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MEM; - when x"32" => opcode <= OP_MOVREG; aluop <= ALU_OP_XOR; useAluResult <= '1'; opsize <= 1; source1 <= OPSOURCE_MODRM_REG; source2 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MODRM_REG; - when x"33" => opcode <= OP_MOVREG; aluop <= ALU_OP_XOR; useAluResult <= '1'; opsize <= 2; source1 <= OPSOURCE_MODRM_REG; source2 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MODRM_REG; - when x"34" => opcode <= OP_MOVREG; aluop <= ALU_OP_XOR; useAluResult <= '1'; opsize <= 1; instantFetch <= '1'; source1 <= OPSOURCE_ACC; source2 <= OPSOURCE_FETCHVALUE8; cpustage <= CPUSTAGE_FETCHDATA2_8 ; optarget <= OPTARGET_DECODE; target_decode <= CPU_REG_al; - when x"35" => opcode <= OP_MOVREG; aluop <= ALU_OP_XOR; useAluResult <= '1'; opsize <= 2; instantFetch <= '1'; source1 <= OPSOURCE_ACC; source2 <= OPSOURCE_FETCHVALUE16; cpustage <= CPUSTAGE_FETCHDATA2_16; optarget <= OPTARGET_DECODE; target_decode <= CPU_REG_ax; + when x"30" => opcode <= OP_MOVMEM; aluop <= ALU_OP_XOR; useAluResult <= '1'; opsize <= '0'; newDelay := 1; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_MODRM_REG; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MEM; + when x"31" => opcode <= OP_MOVMEM; aluop <= ALU_OP_XOR; useAluResult <= '1'; opsize <= '1'; newDelay := 1; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_MODRM_REG; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MEM; + when x"32" => opcode <= OP_MOVREG; aluop <= ALU_OP_XOR; useAluResult <= '1'; opsize <= '0'; source1 <= OPSOURCE_MODRM_REG; source2 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MODRM_REG; + when x"33" => opcode <= OP_MOVREG; aluop <= ALU_OP_XOR; useAluResult <= '1'; opsize <= '1'; source1 <= OPSOURCE_MODRM_REG; source2 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MODRM_REG; + when x"34" => opcode <= OP_MOVREG; aluop <= ALU_OP_XOR; useAluResult <= '1'; opsize <= '0'; instantFetch <= '1'; source1 <= OPSOURCE_ACC; source2 <= OPSOURCE_FETCHVALUE8; cpustage <= CPUSTAGE_FETCHDATA2_8 ; optarget <= OPTARGET_DECODE; target_decode <= CPU_REG_al; + when x"35" => opcode <= OP_MOVREG; aluop <= ALU_OP_XOR; useAluResult <= '1'; opsize <= '1'; instantFetch <= '1'; source1 <= OPSOURCE_ACC; source2 <= OPSOURCE_FETCHVALUE16; cpustage <= CPUSTAGE_FETCHDATA2_16; optarget <= OPTARGET_DECODE; target_decode <= CPU_REG_ax; when x"36" => prefixSegmentSS <= '1'; isPrefix := '1'; irqBlocked <= '1'; usePrefix := '1'; cpu_done <= '1'; newBuf := dbuf + 1; cpustage <= CPUSTAGE_IDLE; - when x"37" => opcode <= OP_MOVREG; aluop <= ALU_OP_ASCIIADJUST; useAluResult <= '1'; newDelay := 8; opsize <= 2; cpustage <= CPUSTAGE_EXECUTE; target_decode <= CPU_REG_ax; optarget <= OPTARGET_DECODE; adjustNegate <= '0'; + when x"37" => opcode <= OP_MOVREG; aluop <= ALU_OP_ASCIIADJUST; useAluResult <= '1'; newDelay := 8; opsize <= '1'; cpustage <= CPUSTAGE_EXECUTE; target_decode <= CPU_REG_ax; optarget <= OPTARGET_DECODE; adjustNegate <= '0'; - when x"38" => opcode <= OP_NOP; aluop <= ALU_OP_CMP; opsize <= 1; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_MODRM_REG; cpustage <= CPUSTAGE_MODRM; - when x"39" => opcode <= OP_NOP; aluop <= ALU_OP_CMP; opsize <= 2; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_MODRM_REG; cpustage <= CPUSTAGE_MODRM; - when x"3A" => opcode <= OP_NOP; aluop <= ALU_OP_CMP; opsize <= 1; source1 <= OPSOURCE_MODRM_REG; source2 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; - when x"3B" => opcode <= OP_NOP; aluop <= ALU_OP_CMP; opsize <= 2; source1 <= OPSOURCE_MODRM_REG; source2 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; - when x"3C" => opcode <= OP_NOP; aluop <= ALU_OP_CMP; opsize <= 1; instantFetch <= '1'; source1 <= OPSOURCE_ACC; source2 <= OPSOURCE_FETCHVALUE8; cpustage <= CPUSTAGE_FETCHDATA2_8 ; - when x"3D" => opcode <= OP_NOP; aluop <= ALU_OP_CMP; opsize <= 2; instantFetch <= '1'; source1 <= OPSOURCE_ACC; source2 <= OPSOURCE_FETCHVALUE16; cpustage <= CPUSTAGE_FETCHDATA2_16; + when x"38" => opcode <= OP_NOP; aluop <= ALU_OP_CMP; opsize <= '0'; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_MODRM_REG; cpustage <= CPUSTAGE_MODRM; + when x"39" => opcode <= OP_NOP; aluop <= ALU_OP_CMP; opsize <= '1'; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_MODRM_REG; cpustage <= CPUSTAGE_MODRM; + when x"3A" => opcode <= OP_NOP; aluop <= ALU_OP_CMP; opsize <= '0'; source1 <= OPSOURCE_MODRM_REG; source2 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; + when x"3B" => opcode <= OP_NOP; aluop <= ALU_OP_CMP; opsize <= '1'; source1 <= OPSOURCE_MODRM_REG; source2 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; + when x"3C" => opcode <= OP_NOP; aluop <= ALU_OP_CMP; opsize <= '0'; instantFetch <= '1'; source1 <= OPSOURCE_ACC; source2 <= OPSOURCE_FETCHVALUE8; cpustage <= CPUSTAGE_FETCHDATA2_8 ; + when x"3D" => opcode <= OP_NOP; aluop <= ALU_OP_CMP; opsize <= '1'; instantFetch <= '1'; source1 <= OPSOURCE_ACC; source2 <= OPSOURCE_FETCHVALUE16; cpustage <= CPUSTAGE_FETCHDATA2_16; when x"3E" => prefixSegmentDS <= '1'; isPrefix := '1'; irqBlocked <= '1'; usePrefix := '1'; cpu_done <= '1'; newBuf := dbuf + 1; cpustage <= CPUSTAGE_IDLE; - when x"3F" => opcode <= OP_MOVREG; aluop <= ALU_OP_ASCIIADJUST; useAluResult <= '1'; newDelay := 8; opsize <= 2; cpustage <= CPUSTAGE_EXECUTE; target_decode <= CPU_REG_ax; optarget <= OPTARGET_DECODE; adjustNegate <= '1'; + when x"3F" => opcode <= OP_MOVREG; aluop <= ALU_OP_ASCIIADJUST; useAluResult <= '1'; newDelay := 8; opsize <= '1'; cpustage <= CPUSTAGE_EXECUTE; target_decode <= CPU_REG_ax; optarget <= OPTARGET_DECODE; adjustNegate <= '1'; - when x"40" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_EXECUTE; aluop <= ALU_OP_INC; source1 <= OPSOURCE_REG_ax; source2 <= OPSOURCE_IMMIDIATE; immidiate8 <= x"01"; target_decode <= CPU_REG_ax; optarget <= OPTARGET_DECODE; opsize <= 2; useAluResult <= '1'; - when x"41" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_EXECUTE; aluop <= ALU_OP_INC; source1 <= OPSOURCE_REG_cx; source2 <= OPSOURCE_IMMIDIATE; immidiate8 <= x"01"; target_decode <= CPU_REG_cx; optarget <= OPTARGET_DECODE; opsize <= 2; useAluResult <= '1'; - when x"42" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_EXECUTE; aluop <= ALU_OP_INC; source1 <= OPSOURCE_REG_dx; source2 <= OPSOURCE_IMMIDIATE; immidiate8 <= x"01"; target_decode <= CPU_REG_dx; optarget <= OPTARGET_DECODE; opsize <= 2; useAluResult <= '1'; - when x"43" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_EXECUTE; aluop <= ALU_OP_INC; source1 <= OPSOURCE_REG_bx; source2 <= OPSOURCE_IMMIDIATE; immidiate8 <= x"01"; target_decode <= CPU_REG_bx; optarget <= OPTARGET_DECODE; opsize <= 2; useAluResult <= '1'; - when x"44" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_EXECUTE; aluop <= ALU_OP_INC; source1 <= OPSOURCE_REG_sp; source2 <= OPSOURCE_IMMIDIATE; immidiate8 <= x"01"; target_decode <= CPU_REG_sp; optarget <= OPTARGET_DECODE; opsize <= 2; useAluResult <= '1'; - when x"45" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_EXECUTE; aluop <= ALU_OP_INC; source1 <= OPSOURCE_REG_bp; source2 <= OPSOURCE_IMMIDIATE; immidiate8 <= x"01"; target_decode <= CPU_REG_bp; optarget <= OPTARGET_DECODE; opsize <= 2; useAluResult <= '1'; - when x"46" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_EXECUTE; aluop <= ALU_OP_INC; source1 <= OPSOURCE_REG_si; source2 <= OPSOURCE_IMMIDIATE; immidiate8 <= x"01"; target_decode <= CPU_REG_si; optarget <= OPTARGET_DECODE; opsize <= 2; useAluResult <= '1'; - when x"47" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_EXECUTE; aluop <= ALU_OP_INC; source1 <= OPSOURCE_REG_di; source2 <= OPSOURCE_IMMIDIATE; immidiate8 <= x"01"; target_decode <= CPU_REG_di; optarget <= OPTARGET_DECODE; opsize <= 2; useAluResult <= '1'; - when x"48" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_EXECUTE; aluop <= ALU_OP_DEC; source1 <= OPSOURCE_REG_ax; source2 <= OPSOURCE_IMMIDIATE; immidiate8 <= x"01"; target_decode <= CPU_REG_ax; optarget <= OPTARGET_DECODE; opsize <= 2; useAluResult <= '1'; - when x"49" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_EXECUTE; aluop <= ALU_OP_DEC; source1 <= OPSOURCE_REG_cx; source2 <= OPSOURCE_IMMIDIATE; immidiate8 <= x"01"; target_decode <= CPU_REG_cx; optarget <= OPTARGET_DECODE; opsize <= 2; useAluResult <= '1'; - when x"4A" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_EXECUTE; aluop <= ALU_OP_DEC; source1 <= OPSOURCE_REG_dx; source2 <= OPSOURCE_IMMIDIATE; immidiate8 <= x"01"; target_decode <= CPU_REG_dx; optarget <= OPTARGET_DECODE; opsize <= 2; useAluResult <= '1'; - when x"4B" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_EXECUTE; aluop <= ALU_OP_DEC; source1 <= OPSOURCE_REG_bx; source2 <= OPSOURCE_IMMIDIATE; immidiate8 <= x"01"; target_decode <= CPU_REG_bx; optarget <= OPTARGET_DECODE; opsize <= 2; useAluResult <= '1'; - when x"4C" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_EXECUTE; aluop <= ALU_OP_DEC; source1 <= OPSOURCE_REG_sp; source2 <= OPSOURCE_IMMIDIATE; immidiate8 <= x"01"; target_decode <= CPU_REG_sp; optarget <= OPTARGET_DECODE; opsize <= 2; useAluResult <= '1'; - when x"4D" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_EXECUTE; aluop <= ALU_OP_DEC; source1 <= OPSOURCE_REG_bp; source2 <= OPSOURCE_IMMIDIATE; immidiate8 <= x"01"; target_decode <= CPU_REG_bp; optarget <= OPTARGET_DECODE; opsize <= 2; useAluResult <= '1'; - when x"4E" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_EXECUTE; aluop <= ALU_OP_DEC; source1 <= OPSOURCE_REG_si; source2 <= OPSOURCE_IMMIDIATE; immidiate8 <= x"01"; target_decode <= CPU_REG_si; optarget <= OPTARGET_DECODE; opsize <= 2; useAluResult <= '1'; - when x"4F" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_EXECUTE; aluop <= ALU_OP_DEC; source1 <= OPSOURCE_REG_di; source2 <= OPSOURCE_IMMIDIATE; immidiate8 <= x"01"; target_decode <= CPU_REG_di; optarget <= OPTARGET_DECODE; opsize <= 2; useAluResult <= '1'; + when x"40" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_EXECUTE; aluop <= ALU_OP_INC; source1 <= OPSOURCE_REG_ax; source2 <= OPSOURCE_IMMIDIATE; immidiate8 <= x"01"; target_decode <= CPU_REG_ax; optarget <= OPTARGET_DECODE; opsize <= '1'; useAluResult <= '1'; + when x"41" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_EXECUTE; aluop <= ALU_OP_INC; source1 <= OPSOURCE_REG_cx; source2 <= OPSOURCE_IMMIDIATE; immidiate8 <= x"01"; target_decode <= CPU_REG_cx; optarget <= OPTARGET_DECODE; opsize <= '1'; useAluResult <= '1'; + when x"42" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_EXECUTE; aluop <= ALU_OP_INC; source1 <= OPSOURCE_REG_dx; source2 <= OPSOURCE_IMMIDIATE; immidiate8 <= x"01"; target_decode <= CPU_REG_dx; optarget <= OPTARGET_DECODE; opsize <= '1'; useAluResult <= '1'; + when x"43" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_EXECUTE; aluop <= ALU_OP_INC; source1 <= OPSOURCE_REG_bx; source2 <= OPSOURCE_IMMIDIATE; immidiate8 <= x"01"; target_decode <= CPU_REG_bx; optarget <= OPTARGET_DECODE; opsize <= '1'; useAluResult <= '1'; + when x"44" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_EXECUTE; aluop <= ALU_OP_INC; source1 <= OPSOURCE_REG_sp; source2 <= OPSOURCE_IMMIDIATE; immidiate8 <= x"01"; target_decode <= CPU_REG_sp; optarget <= OPTARGET_DECODE; opsize <= '1'; useAluResult <= '1'; + when x"45" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_EXECUTE; aluop <= ALU_OP_INC; source1 <= OPSOURCE_REG_bp; source2 <= OPSOURCE_IMMIDIATE; immidiate8 <= x"01"; target_decode <= CPU_REG_bp; optarget <= OPTARGET_DECODE; opsize <= '1'; useAluResult <= '1'; + when x"46" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_EXECUTE; aluop <= ALU_OP_INC; source1 <= OPSOURCE_REG_si; source2 <= OPSOURCE_IMMIDIATE; immidiate8 <= x"01"; target_decode <= CPU_REG_si; optarget <= OPTARGET_DECODE; opsize <= '1'; useAluResult <= '1'; + when x"47" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_EXECUTE; aluop <= ALU_OP_INC; source1 <= OPSOURCE_REG_di; source2 <= OPSOURCE_IMMIDIATE; immidiate8 <= x"01"; target_decode <= CPU_REG_di; optarget <= OPTARGET_DECODE; opsize <= '1'; useAluResult <= '1'; + when x"48" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_EXECUTE; aluop <= ALU_OP_DEC; source1 <= OPSOURCE_REG_ax; source2 <= OPSOURCE_IMMIDIATE; immidiate8 <= x"01"; target_decode <= CPU_REG_ax; optarget <= OPTARGET_DECODE; opsize <= '1'; useAluResult <= '1'; + when x"49" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_EXECUTE; aluop <= ALU_OP_DEC; source1 <= OPSOURCE_REG_cx; source2 <= OPSOURCE_IMMIDIATE; immidiate8 <= x"01"; target_decode <= CPU_REG_cx; optarget <= OPTARGET_DECODE; opsize <= '1'; useAluResult <= '1'; + when x"4A" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_EXECUTE; aluop <= ALU_OP_DEC; source1 <= OPSOURCE_REG_dx; source2 <= OPSOURCE_IMMIDIATE; immidiate8 <= x"01"; target_decode <= CPU_REG_dx; optarget <= OPTARGET_DECODE; opsize <= '1'; useAluResult <= '1'; + when x"4B" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_EXECUTE; aluop <= ALU_OP_DEC; source1 <= OPSOURCE_REG_bx; source2 <= OPSOURCE_IMMIDIATE; immidiate8 <= x"01"; target_decode <= CPU_REG_bx; optarget <= OPTARGET_DECODE; opsize <= '1'; useAluResult <= '1'; + when x"4C" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_EXECUTE; aluop <= ALU_OP_DEC; source1 <= OPSOURCE_REG_sp; source2 <= OPSOURCE_IMMIDIATE; immidiate8 <= x"01"; target_decode <= CPU_REG_sp; optarget <= OPTARGET_DECODE; opsize <= '1'; useAluResult <= '1'; + when x"4D" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_EXECUTE; aluop <= ALU_OP_DEC; source1 <= OPSOURCE_REG_bp; source2 <= OPSOURCE_IMMIDIATE; immidiate8 <= x"01"; target_decode <= CPU_REG_bp; optarget <= OPTARGET_DECODE; opsize <= '1'; useAluResult <= '1'; + when x"4E" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_EXECUTE; aluop <= ALU_OP_DEC; source1 <= OPSOURCE_REG_si; source2 <= OPSOURCE_IMMIDIATE; immidiate8 <= x"01"; target_decode <= CPU_REG_si; optarget <= OPTARGET_DECODE; opsize <= '1'; useAluResult <= '1'; + when x"4F" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_EXECUTE; aluop <= ALU_OP_DEC; source1 <= OPSOURCE_REG_di; source2 <= OPSOURCE_IMMIDIATE; immidiate8 <= x"01"; target_decode <= CPU_REG_di; optarget <= OPTARGET_DECODE; opsize <= '1'; useAluResult <= '1'; when x"50" => pushlist <= REGPOS_ax; cpustage <= CPUSTAGE_CHECKDATAREADY; newBuf := dbuf + 1; when x"51" => pushlist <= REGPOS_cx; cpustage <= CPUSTAGE_CHECKDATAREADY; newBuf := dbuf + 1; @@ -968,7 +977,7 @@ begin when x"60" => pushlist <= REGPOS_ax or REGPOS_cx or REGPOS_dx or REGPOS_bx or REGPOS_sp or REGPOS_bp or REGPOS_si or REGPOS_di; cpustage <= CPUSTAGE_CHECKDATAREADY; when x"61" => poplist <= REGPOS_ax or REGPOS_cx or REGPOS_dx or REGPOS_bx or REGPOS_bp or REGPOS_si or REGPOS_di; cpustage <= CPUSTAGE_CHECKDATAREADY; newDelay := 1; - when x"62" => opcode <= OP_BOUND; newDelay := 4; opsize <= 2; cpustage <= CPUSTAGE_MODRM; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_MEM; + when x"62" => opcode <= OP_BOUND; newDelay := 4; opsize <= '1'; cpustage <= CPUSTAGE_MODRM; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_MEM; -- when x"63" => ? -- when x"64" => repnc @@ -976,42 +985,42 @@ begin -- when x"66" => fpo2 -- when x"67" => fpo2 - when x"68" => pushlist <= REGPOS_imm; cpustage <= CPUSTAGE_PUSH; opsize <= 2; newBuf := dbuf + 1; fetch1Val <= unsigned(prefetchBuffer(23 downto 8)); regs.reg_ip <= regs.reg_ip + 2; consumePrefetch <= 2; - when x"69" => opcode <= OP_MOVREG; aluop <= ALU_OP_MULI; newDelay := 3; useAluResult <= '1'; opsize <= 2; source1 <= OPSOURCE_FETCHVALUE16; source2 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MODRM_REG; - when x"6A" => pushlist <= REGPOS_imm; cpustage <= CPUSTAGE_PUSH; opsize <= 1; newBuf := dbuf + 1; fetch1Val <= x"00" & unsigned(prefetchBuffer(15 downto 8)); regs.reg_ip <= regs.reg_ip + 1; consumePrefetch <= 1; - when x"6B" => opcode <= OP_MOVREG; aluop <= ALU_OP_MULI; newDelay := 3; useAluResult <= '1'; opsize <= 2; source1 <= OPSOURCE_FETCHVALUE8; source2 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MODRM_REG; + when x"68" => pushlist <= REGPOS_imm; cpustage <= CPUSTAGE_PUSH; opsize <= '1'; newBuf := dbuf + 1; fetch1Val <= unsigned(prefetchBuffer(23 downto 8)); regs.reg_ip <= regs.reg_ip + 2; consumePrefetch <= 2; + when x"69" => opcode <= OP_MOVREG; aluop <= ALU_OP_MULI; newDelay := 3; useAluResult <= '1'; opsize <= '1'; source1 <= OPSOURCE_FETCHVALUE16; source2 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MODRM_REG; + when x"6A" => pushlist <= REGPOS_imm; cpustage <= CPUSTAGE_PUSH; opsize <= '0'; newBuf := dbuf + 1; fetch1Val <= x"00" & unsigned(prefetchBuffer(15 downto 8)); regs.reg_ip <= regs.reg_ip + 1; consumePrefetch <= 1; + when x"6B" => opcode <= OP_MOVREG; aluop <= ALU_OP_MULI; newDelay := 3; useAluResult <= '1'; opsize <= '1'; source1 <= OPSOURCE_FETCHVALUE8; source2 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; optarget <= OPTARGET_MODRM_REG; - when x"6C" => opcode <= OP_OPIN; newDelay := 5; opcodeNext <= OP_STRINGSTORE; opsize <= 1; cpustage <= CPUSTAGE_FETCHDATA1_8; source1 <= OPSOURCE_FETCHVALUE8; source2 <= OPSOURCE_MEM; - when x"6D" => opcode <= OP_OPIN; newDelay := 4; opcodeNext <= OP_STRINGSTORE; opsize <= 2; cpustage <= CPUSTAGE_FETCHDATA1_8; source1 <= OPSOURCE_FETCHVALUE8; source2 <= OPSOURCE_MEM; - when x"6E" => opcode <= OP_STRINGLOAD; newDelay := 5; opcodeNext <= OP_OPOUT; opsize <= 1; cpustage <= CPUSTAGE_EXECUTE; source1 <= OPSOURCE_REG_dx; source2 <= OPSOURCE_STRINGLOAD1; - when x"6F" => opcode <= OP_STRINGLOAD; newDelay := 1; opcodeNext <= OP_OPOUT; opsize <= 2; cpustage <= CPUSTAGE_EXECUTE; source1 <= OPSOURCE_REG_dx; source2 <= OPSOURCE_STRINGLOAD1; + when x"6C" => opcode <= OP_OPIN; newDelay := 5; opcodeNext <= OP_STRINGSTORE; opsize <= '0'; cpustage <= CPUSTAGE_FETCHDATA1_8; source1 <= OPSOURCE_FETCHVALUE8; source2 <= OPSOURCE_MEM; + when x"6D" => opcode <= OP_OPIN; newDelay := 4; opcodeNext <= OP_STRINGSTORE; opsize <= '1'; cpustage <= CPUSTAGE_FETCHDATA1_8; source1 <= OPSOURCE_FETCHVALUE8; source2 <= OPSOURCE_MEM; + when x"6E" => opcode <= OP_STRINGLOAD; newDelay := 5; opcodeNext <= OP_OPOUT; opsize <= '0'; cpustage <= CPUSTAGE_EXECUTE; source1 <= OPSOURCE_REG_dx; source2 <= OPSOURCE_STRINGLOAD1; + when x"6F" => opcode <= OP_STRINGLOAD; newDelay := 1; opcodeNext <= OP_OPOUT; opsize <= '1'; cpustage <= CPUSTAGE_EXECUTE; source1 <= OPSOURCE_REG_dx; source2 <= OPSOURCE_STRINGLOAD1; when x"70" | x"71" | x"72" | x"73" | x"74" | x"75" | x"76" | x"77" | x"78" | x"79" | x"7a" | x"7b" | x"7c" | x"7d" | x"7e" | x"7f" => opcode <= OP_JUMPIF; source1 <= OPSOURCE_FETCHVALUE8; cpustage <= CPUSTAGE_FETCHDATA1_8; - when x"80" => opcode <= OP_MEMIMM1; cpustage <= CPUSTAGE_MODRM; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_FETCHVALUE8; optarget <= OPTARGET_MEM; useAluResult <= '1'; opsize <= 1; opsign <= '0'; - when x"81" => opcode <= OP_MEMIMM1; cpustage <= CPUSTAGE_MODRM; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_FETCHVALUE16; optarget <= OPTARGET_MEM; useAluResult <= '1'; opsize <= 2; opsign <= '0'; - when x"82" => opcode <= OP_MEMIMM1; cpustage <= CPUSTAGE_MODRM; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_FETCHVALUE8; optarget <= OPTARGET_MEM; useAluResult <= '1'; opsize <= 1; opsign <= '1'; - when x"83" => opcode <= OP_MEMIMM1; cpustage <= CPUSTAGE_MODRM; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_FETCHVALUE8; optarget <= OPTARGET_MEM; useAluResult <= '1'; opsize <= 2; opsign <= '1'; + when x"80" => opcode <= OP_MEMIMM1; cpustage <= CPUSTAGE_MODRM; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_FETCHVALUE8; optarget <= OPTARGET_MEM; useAluResult <= '1'; opsize <= '0'; opsign <= '0'; + when x"81" => opcode <= OP_MEMIMM1; cpustage <= CPUSTAGE_MODRM; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_FETCHVALUE16; optarget <= OPTARGET_MEM; useAluResult <= '1'; opsize <= '1'; opsign <= '0'; + when x"82" => opcode <= OP_MEMIMM1; cpustage <= CPUSTAGE_MODRM; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_FETCHVALUE8; optarget <= OPTARGET_MEM; useAluResult <= '1'; opsize <= '0'; opsign <= '1'; + when x"83" => opcode <= OP_MEMIMM1; cpustage <= CPUSTAGE_MODRM; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_FETCHVALUE8; optarget <= OPTARGET_MEM; useAluResult <= '1'; opsize <= '1'; opsign <= '1'; - when x"84" => opcode <= OP_NOP; cpustage <= CPUSTAGE_MODRM; opsize <= 1; aluop <= ALU_OP_TST; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_MODRM_REG; - when x"85" => opcode <= OP_NOP; cpustage <= CPUSTAGE_MODRM; opsize <= 2; aluop <= ALU_OP_TST; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_MODRM_REG; + when x"84" => opcode <= OP_NOP; cpustage <= CPUSTAGE_MODRM; opsize <= '0'; aluop <= ALU_OP_TST; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_MODRM_REG; + when x"85" => opcode <= OP_NOP; cpustage <= CPUSTAGE_MODRM; opsize <= '1'; aluop <= ALU_OP_TST; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_MODRM_REG; - when x"86" => opcode <= OP_MOVMEM; newDelay := 2; opcodeNext <= OP_MOVREG; opsize <= 1; cpustage <= CPUSTAGE_MODRM; source1 <= OPSOURCE_MODRM_REG; source2 <= OPSOURCE_MEM; optarget <= OPTARGET_MEM; optarget2 <= OPTARGET_MODRM_REG; - when x"87" => opcode <= OP_MOVMEM; newDelay := 2; opcodeNext <= OP_MOVREG; opsize <= 2; cpustage <= CPUSTAGE_MODRM; source1 <= OPSOURCE_MODRM_REG; source2 <= OPSOURCE_MEM; optarget <= OPTARGET_MEM; optarget2 <= OPTARGET_MODRM_REG; + when x"86" => opcode <= OP_MOVMEM; newDelay := 2; opcodeNext <= OP_MOVREG; opsize <= '0'; cpustage <= CPUSTAGE_MODRM; source1 <= OPSOURCE_MODRM_REG; source2 <= OPSOURCE_MEM; optarget <= OPTARGET_MEM; optarget2 <= OPTARGET_MODRM_REG; + when x"87" => opcode <= OP_MOVMEM; newDelay := 2; opcodeNext <= OP_MOVREG; opsize <= '1'; cpustage <= CPUSTAGE_MODRM; source1 <= OPSOURCE_MODRM_REG; source2 <= OPSOURCE_MEM; optarget <= OPTARGET_MEM; optarget2 <= OPTARGET_MODRM_REG; - when x"88" => opcode <= OP_MOVMEM; cpustage <= CPUSTAGE_MODRM; opsize <= 1; source1 <= OPSOURCE_MODRM_REG; optarget <= OPTARGET_MEM; - when x"89" => opcode <= OP_MOVMEM; cpustage <= CPUSTAGE_MODRM; opsize <= 2; source1 <= OPSOURCE_MODRM_REG; optarget <= OPTARGET_MEM; - when x"8A" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_MODRM; opsize <= 1; source1 <= OPSOURCE_MEM; optarget <= OPTARGET_MODRM_REG; newBuf := dbuf + 1; - when x"8B" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_MODRM; opsize <= 2; source1 <= OPSOURCE_MEM; optarget <= OPTARGET_MODRM_REG; newBuf := dbuf + 1; + when x"88" => opcode <= OP_MOVMEM; cpustage <= CPUSTAGE_MODRM; opsize <= '0'; source1 <= OPSOURCE_MODRM_REG; optarget <= OPTARGET_MEM; + when x"89" => opcode <= OP_MOVMEM; cpustage <= CPUSTAGE_MODRM; opsize <= '1'; source1 <= OPSOURCE_MODRM_REG; optarget <= OPTARGET_MEM; + when x"8A" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_MODRM; opsize <= '0'; source1 <= OPSOURCE_MEM; optarget <= OPTARGET_MODRM_REG; newBuf := dbuf + 1; + when x"8B" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_MODRM; opsize <= '1'; source1 <= OPSOURCE_MEM; optarget <= OPTARGET_MODRM_REG; newBuf := dbuf + 1; - when x"8C" => opcode <= OP_MOVMEM; cpustage <= CPUSTAGE_MODRM; opsize <= 2; source1 <= OPSOURCE_MODRM_REG; segmentaccess <= '1'; optarget <= OPTARGET_MEM; irqBlocked <= '1'; + when x"8C" => opcode <= OP_MOVMEM; cpustage <= CPUSTAGE_MODRM; opsize <= '1'; source1 <= OPSOURCE_MODRM_REG; segmentaccess <= '1'; optarget <= OPTARGET_MEM; irqBlocked <= '1'; - when x"8D" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_MODRM; opsize <= 2; source1 <= OPSOURCE_MODRM_ADDR; optarget <= OPTARGET_MODRM_REG; + when x"8D" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_MODRM; opsize <= '1'; source1 <= OPSOURCE_MODRM_ADDR; optarget <= OPTARGET_MODRM_REG; - when x"8E" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_MODRM; opsize <= 2; source1 <= OPSOURCE_MEM; optarget <= OPTARGET_MODRM_REG; segmentaccess <= '1'; newDelay := 1; + when x"8E" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_MODRM; opsize <= '1'; source1 <= OPSOURCE_MEM; optarget <= OPTARGET_MODRM_REG; segmentaccess <= '1'; newDelay := 1; - when x"8F" => opcode <= OP_MOVMEM; poplist <= REGPOS_mem; cpustage <= CPUSTAGE_MODRM; source1 <= OPSOURCE_POPVALUE; optarget <= OPTARGET_MEM; opsize <= 2; newDelay := 1; + when x"8F" => opcode <= OP_MOVMEM; poplist <= REGPOS_mem; cpustage <= CPUSTAGE_MODRM; source1 <= OPSOURCE_POPVALUE; optarget <= OPTARGET_MEM; opsize <= '1'; newDelay := 1; -- when x"90" => NOP @@ -1023,8 +1032,8 @@ begin when x"96" => opcode <= OP_EXCHANGE; cpustage <= CPUSTAGE_EXECUTE; newDelay := 2; when x"97" => opcode <= OP_EXCHANGE; cpustage <= CPUSTAGE_EXECUTE; newDelay := 2; - when x"98" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_EXECUTE; aluop <= ALU_OP_SXT; source1 <= OPSOURCE_ACC; opsize <= 2; useAluResult <= '1'; optarget <= OPTARGET_DECODE; target_decode <= CPU_REG_ax; - when x"99" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_EXECUTE; aluop <= ALU_OP_SXT; source1 <= OPSOURCE_ACC; opsize <= 2; useAluResult <= '1'; optarget <= OPTARGET_DECODE; target_decode <= CPU_REG_dx; + when x"98" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_EXECUTE; aluop <= ALU_OP_SXT; source1 <= OPSOURCE_ACC; opsize <= '1'; useAluResult <= '1'; optarget <= OPTARGET_DECODE; target_decode <= CPU_REG_ax; + when x"99" => opcode <= OP_MOVREG; cpustage <= CPUSTAGE_EXECUTE; aluop <= ALU_OP_SXT; source1 <= OPSOURCE_ACC; opsize <= '1'; useAluResult <= '1'; optarget <= OPTARGET_DECODE; target_decode <= CPU_REG_dx; when x"9A" => opcode <= OP_JUMPFAR; newDelay := 4; cpustage <= CPUSTAGE_FETCHDATA1_16; pushlist <= REGPOS_cs or REGPOS_ip; source1 <= OPSOURCE_FETCHVALUE16; source2 <= OPSOURCE_FETCHVALUE16; @@ -1036,63 +1045,63 @@ begin when x"9E" => opcode <= OP_FLAGSFROMACC; newDelay := 3; cpustage <= CPUSTAGE_EXECUTE; when x"9F" => opcode <= OP_FLAGSTOACC; newDelay := 1; cpustage <= CPUSTAGE_EXECUTE; - when x"A0" => opcode <= OP_MOVREG; newBuf := dbuf + 1; memAddr <= unsigned(prefetchBuffer(23 downto 8)); regs.reg_ip <= regs.reg_ip + 2; consumePrefetch <= 2; cpustage <= CPUSTAGE_CHECKDATAREADY; opsize <= 1; source1 <= OPSOURCE_MEM; target_decode <= CPU_REG_al; optarget <= OPTARGET_DECODE; - when x"A1" => opcode <= OP_MOVREG; newBuf := dbuf + 1; memAddr <= unsigned(prefetchBuffer(23 downto 8)); regs.reg_ip <= regs.reg_ip + 2; consumePrefetch <= 2; cpustage <= CPUSTAGE_CHECKDATAREADY; opsize <= 2; source1 <= OPSOURCE_MEM; target_decode <= CPU_REG_ax; optarget <= OPTARGET_DECODE; - when x"A2" => opcode <= OP_MOVMEM; memAddr <= unsigned(prefetchBuffer(23 downto 8)); regs.reg_ip <= regs.reg_ip + 2; consumePrefetch <= 2; cpustage <= CPUSTAGE_CHECKDATAREADY; opsize <= 1; source1 <= OPSOURCE_ACC; optarget <= OPTARGET_MEM; - when x"A3" => opcode <= OP_MOVMEM; memAddr <= unsigned(prefetchBuffer(23 downto 8)); regs.reg_ip <= regs.reg_ip + 2; consumePrefetch <= 2; cpustage <= CPUSTAGE_CHECKDATAREADY; opsize <= 2; source1 <= OPSOURCE_ACC; optarget <= OPTARGET_MEM; + when x"A0" => opcode <= OP_MOVREG; newBuf := dbuf + 1; memAddr <= unsigned(prefetchBuffer(23 downto 8)); regs.reg_ip <= regs.reg_ip + 2; consumePrefetch <= 2; cpustage <= CPUSTAGE_CHECKDATAREADY; opsize <= '0'; source1 <= OPSOURCE_MEM; target_decode <= CPU_REG_al; optarget <= OPTARGET_DECODE; + when x"A1" => opcode <= OP_MOVREG; newBuf := dbuf + 1; memAddr <= unsigned(prefetchBuffer(23 downto 8)); regs.reg_ip <= regs.reg_ip + 2; consumePrefetch <= 2; cpustage <= CPUSTAGE_CHECKDATAREADY; opsize <= '1'; source1 <= OPSOURCE_MEM; target_decode <= CPU_REG_ax; optarget <= OPTARGET_DECODE; + when x"A2" => opcode <= OP_MOVMEM; memAddr <= unsigned(prefetchBuffer(23 downto 8)); regs.reg_ip <= regs.reg_ip + 2; consumePrefetch <= 2; cpustage <= CPUSTAGE_CHECKDATAREADY; opsize <= '0'; source1 <= OPSOURCE_ACC; optarget <= OPTARGET_MEM; + when x"A3" => opcode <= OP_MOVMEM; memAddr <= unsigned(prefetchBuffer(23 downto 8)); regs.reg_ip <= regs.reg_ip + 2; consumePrefetch <= 2; cpustage <= CPUSTAGE_CHECKDATAREADY; opsize <= '1'; source1 <= OPSOURCE_ACC; optarget <= OPTARGET_MEM; - when x"A4" => opcode <= OP_STRINGLOAD; newDelay := 3; opcodeNext <= OP_STRINGSTORE; opsize <= 1; cpustage <= CPUSTAGE_EXECUTE; source1 <= OPSOURCE_STRINGLOAD1; usePrefix := '1'; - when x"A5" => opcode <= OP_STRINGLOAD; newDelay := 1; opcodeNext <= OP_STRINGSTORE; opsize <= 2; cpustage <= CPUSTAGE_EXECUTE; source1 <= OPSOURCE_STRINGLOAD1; usePrefix := '1'; + when x"A4" => opcode <= OP_STRINGLOAD; newDelay := 3; opcodeNext <= OP_STRINGSTORE; opsize <= '0'; cpustage <= CPUSTAGE_EXECUTE; source1 <= OPSOURCE_STRINGLOAD1; usePrefix := '1'; + when x"A5" => opcode <= OP_STRINGLOAD; newDelay := 1; opcodeNext <= OP_STRINGSTORE; opsize <= '1'; cpustage <= CPUSTAGE_EXECUTE; source1 <= OPSOURCE_STRINGLOAD1; usePrefix := '1'; - when x"A6" => opcode <= OP_STRINGLOAD; newDelay := 2; opcodeNext <= OP_STRINGCOMPARE; opsize <= 1; cpustage <= CPUSTAGE_EXECUTE; source1 <= OPSOURCE_STRINGLOAD1; source2 <= OPSOURCE_STRINGLOAD2; usePrefix := '1'; - when x"A7" => opcode <= OP_STRINGLOAD; opcodeNext <= OP_STRINGCOMPARE; opsize <= 2; cpustage <= CPUSTAGE_EXECUTE; source1 <= OPSOURCE_STRINGLOAD1; source2 <= OPSOURCE_STRINGLOAD2; usePrefix := '1'; + when x"A6" => opcode <= OP_STRINGLOAD; newDelay := 2; opcodeNext <= OP_STRINGCOMPARE; opsize <= '0'; cpustage <= CPUSTAGE_EXECUTE; source1 <= OPSOURCE_STRINGLOAD1; source2 <= OPSOURCE_STRINGLOAD2; usePrefix := '1'; + when x"A7" => opcode <= OP_STRINGLOAD; opcodeNext <= OP_STRINGCOMPARE; opsize <= '1'; cpustage <= CPUSTAGE_EXECUTE; source1 <= OPSOURCE_STRINGLOAD1; source2 <= OPSOURCE_STRINGLOAD2; usePrefix := '1'; - when x"A8" => opcode <= OP_NOP; opsize <= 1; cpustage <= CPUSTAGE_FETCHDATA1_8 ; aluop <= ALU_OP_TST; source1 <= OPSOURCE_FETCHVALUE8; source2 <= OPSOURCE_ACC; instantFetch <= '1'; - when x"A9" => opcode <= OP_NOP; opsize <= 2; cpustage <= CPUSTAGE_FETCHDATA1_16; aluop <= ALU_OP_TST; source1 <= OPSOURCE_FETCHVALUE16; source2 <= OPSOURCE_ACC; instantFetch <= '1'; + when x"A8" => opcode <= OP_NOP; opsize <= '0'; cpustage <= CPUSTAGE_FETCHDATA1_8 ; aluop <= ALU_OP_TST; source1 <= OPSOURCE_FETCHVALUE8; source2 <= OPSOURCE_ACC; instantFetch <= '1'; + when x"A9" => opcode <= OP_NOP; opsize <= '1'; cpustage <= CPUSTAGE_FETCHDATA1_16; aluop <= ALU_OP_TST; source1 <= OPSOURCE_FETCHVALUE16; source2 <= OPSOURCE_ACC; instantFetch <= '1'; - when x"AA" => opcode <= OP_STRINGSTORE; newDelay := 2; opsize <= 1; cpustage <= CPUSTAGE_EXECUTE; source1 <= OPSOURCE_ACC; usePrefix := '1'; - when x"AB" => opcode <= OP_STRINGSTORE; newDelay := 1; opsize <= 2; cpustage <= CPUSTAGE_EXECUTE; source1 <= OPSOURCE_ACC; usePrefix := '1'; + when x"AA" => opcode <= OP_STRINGSTORE; newDelay := 2; opsize <= '0'; cpustage <= CPUSTAGE_EXECUTE; source1 <= OPSOURCE_ACC; usePrefix := '1'; + when x"AB" => opcode <= OP_STRINGSTORE; newDelay := 1; opsize <= '1'; cpustage <= CPUSTAGE_EXECUTE; source1 <= OPSOURCE_ACC; usePrefix := '1'; - when x"AC" => opcode <= OP_STRINGLOAD; newDelay := 1; opcodeNext <= OP_MOVREG; opsize <= 1; source1 <= OPSOURCE_STRINGLOAD1; cpustage <= CPUSTAGE_EXECUTE; usePrefix := '1'; target_decode <= CPU_REG_al; optarget <= OPTARGET_DECODE; - when x"AD" => opcode <= OP_STRINGLOAD; opcodeNext <= OP_MOVREG; opsize <= 2; source1 <= OPSOURCE_STRINGLOAD1; cpustage <= CPUSTAGE_EXECUTE; usePrefix := '1'; target_decode <= CPU_REG_ax; optarget <= OPTARGET_DECODE; + when x"AC" => opcode <= OP_STRINGLOAD; newDelay := 1; opcodeNext <= OP_MOVREG; opsize <= '0'; source1 <= OPSOURCE_STRINGLOAD1; cpustage <= CPUSTAGE_EXECUTE; usePrefix := '1'; target_decode <= CPU_REG_al; optarget <= OPTARGET_DECODE; + when x"AD" => opcode <= OP_STRINGLOAD; opcodeNext <= OP_MOVREG; opsize <= '1'; source1 <= OPSOURCE_STRINGLOAD1; cpustage <= CPUSTAGE_EXECUTE; usePrefix := '1'; target_decode <= CPU_REG_ax; optarget <= OPTARGET_DECODE; - when x"AE" => opcode <= OP_STRINGCOMPARE; newDelay := 1; opsize <= 1; cpustage <= CPUSTAGE_EXECUTE; source1 <= OPSOURCE_ACC; source2 <= OPSOURCE_STRINGLOAD2; usePrefix := '1'; - when x"AF" => opcode <= OP_STRINGCOMPARE; opsize <= 2; cpustage <= CPUSTAGE_EXECUTE; source1 <= OPSOURCE_ACC; source2 <= OPSOURCE_STRINGLOAD2; usePrefix := '1'; + when x"AE" => opcode <= OP_STRINGCOMPARE; newDelay := 1; opsize <= '0'; cpustage <= CPUSTAGE_EXECUTE; source1 <= OPSOURCE_ACC; source2 <= OPSOURCE_STRINGLOAD2; usePrefix := '1'; + when x"AF" => opcode <= OP_STRINGCOMPARE; opsize <= '1'; cpustage <= CPUSTAGE_EXECUTE; source1 <= OPSOURCE_ACC; source2 <= OPSOURCE_STRINGLOAD2; usePrefix := '1'; - when x"B0" => opcode <= OP_MOVREG; target_decode <= CPU_REG_al; cpustage <= CPUSTAGE_FETCHDATA1_8 ; source1 <= OPSOURCE_FETCHVALUE8; opsize <= 1; optarget <= OPTARGET_DECODE; instantFetch <= '1'; - when x"B1" => opcode <= OP_MOVREG; target_decode <= CPU_REG_cl; cpustage <= CPUSTAGE_FETCHDATA1_8 ; source1 <= OPSOURCE_FETCHVALUE8; opsize <= 1; optarget <= OPTARGET_DECODE; instantFetch <= '1'; - when x"B2" => opcode <= OP_MOVREG; target_decode <= CPU_REG_dl; cpustage <= CPUSTAGE_FETCHDATA1_8 ; source1 <= OPSOURCE_FETCHVALUE8; opsize <= 1; optarget <= OPTARGET_DECODE; instantFetch <= '1'; - when x"B3" => opcode <= OP_MOVREG; target_decode <= CPU_REG_bl; cpustage <= CPUSTAGE_FETCHDATA1_8 ; source1 <= OPSOURCE_FETCHVALUE8; opsize <= 1; optarget <= OPTARGET_DECODE; instantFetch <= '1'; - when x"B4" => opcode <= OP_MOVREG; target_decode <= CPU_REG_ah; cpustage <= CPUSTAGE_FETCHDATA1_8 ; source1 <= OPSOURCE_FETCHVALUE8; opsize <= 1; optarget <= OPTARGET_DECODE; instantFetch <= '1'; - when x"B5" => opcode <= OP_MOVREG; target_decode <= CPU_REG_ch; cpustage <= CPUSTAGE_FETCHDATA1_8 ; source1 <= OPSOURCE_FETCHVALUE8; opsize <= 1; optarget <= OPTARGET_DECODE; instantFetch <= '1'; - when x"B6" => opcode <= OP_MOVREG; target_decode <= CPU_REG_dh; cpustage <= CPUSTAGE_FETCHDATA1_8 ; source1 <= OPSOURCE_FETCHVALUE8; opsize <= 1; optarget <= OPTARGET_DECODE; instantFetch <= '1'; - when x"B7" => opcode <= OP_MOVREG; target_decode <= CPU_REG_bh; cpustage <= CPUSTAGE_FETCHDATA1_8 ; source1 <= OPSOURCE_FETCHVALUE8; opsize <= 1; optarget <= OPTARGET_DECODE; instantFetch <= '1'; - when x"B8" => opcode <= OP_MOVREG; target_decode <= CPU_REG_ax; cpustage <= CPUSTAGE_FETCHDATA1_16; source1 <= OPSOURCE_FETCHVALUE16; opsize <= 2; optarget <= OPTARGET_DECODE; instantFetch <= '1'; - when x"B9" => opcode <= OP_MOVREG; target_decode <= CPU_REG_cx; cpustage <= CPUSTAGE_FETCHDATA1_16; source1 <= OPSOURCE_FETCHVALUE16; opsize <= 2; optarget <= OPTARGET_DECODE; instantFetch <= '1'; - when x"BA" => opcode <= OP_MOVREG; target_decode <= CPU_REG_dx; cpustage <= CPUSTAGE_FETCHDATA1_16; source1 <= OPSOURCE_FETCHVALUE16; opsize <= 2; optarget <= OPTARGET_DECODE; instantFetch <= '1'; - when x"BB" => opcode <= OP_MOVREG; target_decode <= CPU_REG_bx; cpustage <= CPUSTAGE_FETCHDATA1_16; source1 <= OPSOURCE_FETCHVALUE16; opsize <= 2; optarget <= OPTARGET_DECODE; instantFetch <= '1'; - when x"BC" => opcode <= OP_MOVREG; target_decode <= CPU_REG_sp; cpustage <= CPUSTAGE_FETCHDATA1_16; source1 <= OPSOURCE_FETCHVALUE16; opsize <= 2; optarget <= OPTARGET_DECODE; instantFetch <= '1'; - when x"BD" => opcode <= OP_MOVREG; target_decode <= CPU_REG_bp; cpustage <= CPUSTAGE_FETCHDATA1_16; source1 <= OPSOURCE_FETCHVALUE16; opsize <= 2; optarget <= OPTARGET_DECODE; instantFetch <= '1'; - when x"BE" => opcode <= OP_MOVREG; target_decode <= CPU_REG_si; cpustage <= CPUSTAGE_FETCHDATA1_16; source1 <= OPSOURCE_FETCHVALUE16; opsize <= 2; optarget <= OPTARGET_DECODE; instantFetch <= '1'; - when x"BF" => opcode <= OP_MOVREG; target_decode <= CPU_REG_di; cpustage <= CPUSTAGE_FETCHDATA1_16; source1 <= OPSOURCE_FETCHVALUE16; opsize <= 2; optarget <= OPTARGET_DECODE; instantFetch <= '1'; + when x"B0" => opcode <= OP_MOVREG; target_decode <= CPU_REG_al; cpustage <= CPUSTAGE_FETCHDATA1_8 ; source1 <= OPSOURCE_FETCHVALUE8; opsize <= '0'; optarget <= OPTARGET_DECODE; instantFetch <= '1'; + when x"B1" => opcode <= OP_MOVREG; target_decode <= CPU_REG_cl; cpustage <= CPUSTAGE_FETCHDATA1_8 ; source1 <= OPSOURCE_FETCHVALUE8; opsize <= '0'; optarget <= OPTARGET_DECODE; instantFetch <= '1'; + when x"B2" => opcode <= OP_MOVREG; target_decode <= CPU_REG_dl; cpustage <= CPUSTAGE_FETCHDATA1_8 ; source1 <= OPSOURCE_FETCHVALUE8; opsize <= '0'; optarget <= OPTARGET_DECODE; instantFetch <= '1'; + when x"B3" => opcode <= OP_MOVREG; target_decode <= CPU_REG_bl; cpustage <= CPUSTAGE_FETCHDATA1_8 ; source1 <= OPSOURCE_FETCHVALUE8; opsize <= '0'; optarget <= OPTARGET_DECODE; instantFetch <= '1'; + when x"B4" => opcode <= OP_MOVREG; target_decode <= CPU_REG_ah; cpustage <= CPUSTAGE_FETCHDATA1_8 ; source1 <= OPSOURCE_FETCHVALUE8; opsize <= '0'; optarget <= OPTARGET_DECODE; instantFetch <= '1'; + when x"B5" => opcode <= OP_MOVREG; target_decode <= CPU_REG_ch; cpustage <= CPUSTAGE_FETCHDATA1_8 ; source1 <= OPSOURCE_FETCHVALUE8; opsize <= '0'; optarget <= OPTARGET_DECODE; instantFetch <= '1'; + when x"B6" => opcode <= OP_MOVREG; target_decode <= CPU_REG_dh; cpustage <= CPUSTAGE_FETCHDATA1_8 ; source1 <= OPSOURCE_FETCHVALUE8; opsize <= '0'; optarget <= OPTARGET_DECODE; instantFetch <= '1'; + when x"B7" => opcode <= OP_MOVREG; target_decode <= CPU_REG_bh; cpustage <= CPUSTAGE_FETCHDATA1_8 ; source1 <= OPSOURCE_FETCHVALUE8; opsize <= '0'; optarget <= OPTARGET_DECODE; instantFetch <= '1'; + when x"B8" => opcode <= OP_MOVREG; target_decode <= CPU_REG_ax; cpustage <= CPUSTAGE_FETCHDATA1_16; source1 <= OPSOURCE_FETCHVALUE16; opsize <= '1'; optarget <= OPTARGET_DECODE; instantFetch <= '1'; + when x"B9" => opcode <= OP_MOVREG; target_decode <= CPU_REG_cx; cpustage <= CPUSTAGE_FETCHDATA1_16; source1 <= OPSOURCE_FETCHVALUE16; opsize <= '1'; optarget <= OPTARGET_DECODE; instantFetch <= '1'; + when x"BA" => opcode <= OP_MOVREG; target_decode <= CPU_REG_dx; cpustage <= CPUSTAGE_FETCHDATA1_16; source1 <= OPSOURCE_FETCHVALUE16; opsize <= '1'; optarget <= OPTARGET_DECODE; instantFetch <= '1'; + when x"BB" => opcode <= OP_MOVREG; target_decode <= CPU_REG_bx; cpustage <= CPUSTAGE_FETCHDATA1_16; source1 <= OPSOURCE_FETCHVALUE16; opsize <= '1'; optarget <= OPTARGET_DECODE; instantFetch <= '1'; + when x"BC" => opcode <= OP_MOVREG; target_decode <= CPU_REG_sp; cpustage <= CPUSTAGE_FETCHDATA1_16; source1 <= OPSOURCE_FETCHVALUE16; opsize <= '1'; optarget <= OPTARGET_DECODE; instantFetch <= '1'; + when x"BD" => opcode <= OP_MOVREG; target_decode <= CPU_REG_bp; cpustage <= CPUSTAGE_FETCHDATA1_16; source1 <= OPSOURCE_FETCHVALUE16; opsize <= '1'; optarget <= OPTARGET_DECODE; instantFetch <= '1'; + when x"BE" => opcode <= OP_MOVREG; target_decode <= CPU_REG_si; cpustage <= CPUSTAGE_FETCHDATA1_16; source1 <= OPSOURCE_FETCHVALUE16; opsize <= '1'; optarget <= OPTARGET_DECODE; instantFetch <= '1'; + when x"BF" => opcode <= OP_MOVREG; target_decode <= CPU_REG_di; cpustage <= CPUSTAGE_FETCHDATA1_16; source1 <= OPSOURCE_FETCHVALUE16; opsize <= '1'; optarget <= OPTARGET_DECODE; instantFetch <= '1'; - when x"C0" => opcode <= OP_MEMIMM2; newDelay := 2; cpustage <= CPUSTAGE_MODRM; opsize <= 1; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_FETCHVALUE8; useAluResult <= '1'; optarget <= OPTARGET_MEM; - when x"C1" => opcode <= OP_MEMIMM2; newDelay := 2; cpustage <= CPUSTAGE_MODRM; opsize <= 2; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_FETCHVALUE8; useAluResult <= '1'; optarget <= OPTARGET_MEM; + when x"C0" => opcode <= OP_MEMIMM2; newDelay := 2; cpustage <= CPUSTAGE_MODRM; opsize <= '0'; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_FETCHVALUE8; useAluResult <= '1'; optarget <= OPTARGET_MEM; + when x"C1" => opcode <= OP_MEMIMM2; newDelay := 2; cpustage <= CPUSTAGE_MODRM; opsize <= '1'; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_FETCHVALUE8; useAluResult <= '1'; optarget <= OPTARGET_MEM; - when x"C2" => opcode <= OP_RETURNFAR; opsize <= 2; source1 <= OPSOURCE_FETCHVALUE16; cpustage <= CPUSTAGE_FETCHDATA1_16; newDelay := 1; poplist <= REGPOS_ip; + when x"C2" => opcode <= OP_RETURNFAR; opsize <= '1'; source1 <= OPSOURCE_FETCHVALUE16; cpustage <= CPUSTAGE_FETCHDATA1_16; newDelay := 1; poplist <= REGPOS_ip; when x"C3" => newDelay := 1; poplist <= REGPOS_ip; cpustage <= CPUSTAGE_CHECKDATAREADY; - when x"C4" => opcode <= OP_MOVREG; newDelay := 3; cpustage <= CPUSTAGE_MODRM; opsize <= 2; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_MEM; optarget <= OPTARGET_MODRM_REG; - when x"C5" => opcode <= OP_MOVREG; newDelay := 3; cpustage <= CPUSTAGE_MODRM; opsize <= 2; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_MEM; optarget <= OPTARGET_MODRM_REG; + when x"C4" => opcode <= OP_MOVREG; newDelay := 3; cpustage <= CPUSTAGE_MODRM; opsize <= '1'; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_MEM; optarget <= OPTARGET_MODRM_REG; + when x"C5" => opcode <= OP_MOVREG; newDelay := 3; cpustage <= CPUSTAGE_MODRM; opsize <= '1'; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_MEM; optarget <= OPTARGET_MODRM_REG; - when x"C6" => opcode <= OP_MOVMEM; cpustage <= CPUSTAGE_MODRM; opsize <= 1; source1 <= OPSOURCE_FETCHVALUE8; optarget <= OPTARGET_MEM; newBuf := dbuf + 1; - when x"C7" => opcode <= OP_MOVMEM; cpustage <= CPUSTAGE_MODRM; opsize <= 2; source1 <= OPSOURCE_FETCHVALUE16; optarget <= OPTARGET_MEM; newBuf := dbuf + 1; + when x"C6" => opcode <= OP_MOVMEM; cpustage <= CPUSTAGE_MODRM; opsize <= '0'; source1 <= OPSOURCE_FETCHVALUE8; optarget <= OPTARGET_MEM; newBuf := dbuf + 1; + when x"C7" => opcode <= OP_MOVMEM; cpustage <= CPUSTAGE_MODRM; opsize <= '1'; source1 <= OPSOURCE_FETCHVALUE16; optarget <= OPTARGET_MEM; newBuf := dbuf + 1; - when x"C8" => opcode <= OP_ENTER; cpustage <= CPUSTAGE_FETCHDATA1_16; newDelay := 6; pushlist <= REGPOS_bp; opsize <= 1; source1 <= OPSOURCE_FETCHVALUE16; source2 <= OPSOURCE_FETCHVALUE8; + when x"C8" => opcode <= OP_ENTER; cpustage <= CPUSTAGE_FETCHDATA1_16; newDelay := 6; pushlist <= REGPOS_bp; opsize <= '0'; source1 <= OPSOURCE_FETCHVALUE16; source2 <= OPSOURCE_FETCHVALUE8; when x"C9" => opcode <= OP_MOVREG; regs.reg_sp <= regs.reg_bp; poplist <= REGPOS_MEM; cpustage <= CPUSTAGE_POP_REQ; source1 <= OPSOURCE_POPVALUE; target_decode <= CPU_REG_bp; optarget <= OPTARGET_DECODE; - when x"CA" => opcode <= OP_RETURNFAR; opsize <= 2; source1 <= OPSOURCE_FETCHVALUE16; cpustage <= CPUSTAGE_FETCHDATA1_16; poplist <= REGPOS_cs or REGPOS_ip; + when x"CA" => opcode <= OP_RETURNFAR; opsize <= '1'; source1 <= OPSOURCE_FETCHVALUE16; cpustage <= CPUSTAGE_FETCHDATA1_16; poplist <= REGPOS_cs or REGPOS_ip; when x"CB" => newDelay := 2; poplist <= REGPOS_cs or REGPOS_ip; cpustage <= CPUSTAGE_CHECKDATAREADY; @@ -1102,16 +1111,16 @@ begin when x"CF" => newDelay := 3; poplist <= REGPOS_cs or REGPOS_ip or REGPOS_f; cpustage <= CPUSTAGE_CHECKDATAREADY; irqBlocked <= '1'; - when x"D0" => opcode <= OP_MEMIMM2; cpustage <= CPUSTAGE_MODRM; opsize <= 1; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_IMMIDIATE; useAluResult <= '1'; optarget <= OPTARGET_MEM; newDelay := 1; immidiate8 <= x"01"; - when x"D1" => opcode <= OP_MEMIMM2; cpustage <= CPUSTAGE_MODRM; opsize <= 2; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_IMMIDIATE; useAluResult <= '1'; optarget <= OPTARGET_MEM; newDelay := 1; immidiate8 <= x"01"; - when x"D2" => opcode <= OP_MEMIMM2; cpustage <= CPUSTAGE_MODRM; opsize <= 1; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_IMMIDIATE; useAluResult <= '1'; optarget <= OPTARGET_MEM; newDelay := 3; immidiate8 <= regs.reg_cx(7 downto 0); - when x"D3" => opcode <= OP_MEMIMM2; cpustage <= CPUSTAGE_MODRM; opsize <= 2; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_IMMIDIATE; useAluResult <= '1'; optarget <= OPTARGET_MEM; newDelay := 3; immidiate8 <= regs.reg_cx(7 downto 0); + when x"D0" => opcode <= OP_MEMIMM2; cpustage <= CPUSTAGE_MODRM; opsize <= '0'; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_IMMIDIATE; useAluResult <= '1'; optarget <= OPTARGET_MEM; newDelay := 1; immidiate8 <= x"01"; + when x"D1" => opcode <= OP_MEMIMM2; cpustage <= CPUSTAGE_MODRM; opsize <= '1'; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_IMMIDIATE; useAluResult <= '1'; optarget <= OPTARGET_MEM; newDelay := 1; immidiate8 <= x"01"; + when x"D2" => opcode <= OP_MEMIMM2; cpustage <= CPUSTAGE_MODRM; opsize <= '0'; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_IMMIDIATE; useAluResult <= '1'; optarget <= OPTARGET_MEM; newDelay := 3; immidiate8 <= regs.reg_cx(7 downto 0); + when x"D3" => opcode <= OP_MEMIMM2; cpustage <= CPUSTAGE_MODRM; opsize <= '1'; source1 <= OPSOURCE_MEM; source2 <= OPSOURCE_IMMIDIATE; useAluResult <= '1'; optarget <= OPTARGET_MEM; newDelay := 3; immidiate8 <= regs.reg_cx(7 downto 0); - when x"D4" => opcode <= OP_MULADJUST; cpustage <= CPUSTAGE_FETCHDATA1_8; source1 <= OPSOURCE_FETCHVALUE8; newDelay := 2; opsize <= 2; - when x"D5" => opcode <= OP_DIVADJUST; cpustage <= CPUSTAGE_FETCHDATA1_8; source1 <= OPSOURCE_FETCHVALUE8; newDelay := 4; opsize <= 2; + when x"D4" => opcode <= OP_MULADJUST; cpustage <= CPUSTAGE_FETCHDATA1_8; source1 <= OPSOURCE_FETCHVALUE8; newDelay := 2; opsize <= '1'; + when x"D5" => opcode <= OP_DIVADJUST; cpustage <= CPUSTAGE_FETCHDATA1_8; source1 <= OPSOURCE_FETCHVALUE8; newDelay := 4; opsize <= '1'; when x"D6" | x"D7" => - opcode <= OP_MOVREG; cpustage <= CPUSTAGE_CHECKDATAREADY; source1 <= OPSOURCE_MEM; opsize <= 1; optarget <= OPTARGET_DECODE; target_decode <= CPU_REG_al; newDelay := 3; + opcode <= OP_MOVREG; cpustage <= CPUSTAGE_CHECKDATAREADY; source1 <= OPSOURCE_MEM; opsize <= '0'; optarget <= OPTARGET_DECODE; target_decode <= CPU_REG_al; newDelay := 3; memSegment <= regs.reg_ds; if (prefixSegmentES = '1') then memSegment <= regs.reg_es; end if; if (prefixSegmentCS = '1') then memSegment <= regs.reg_cs; end if; @@ -1134,20 +1143,20 @@ begin when x"E2" => opcode <= OP_JUMPIF; newDelay := 1; cpustage <= CPUSTAGE_FETCHDATA1_8; source1 <= OPSOURCE_FETCHVALUE8; when x"E3" => opcode <= OP_JUMPIF; cpustage <= CPUSTAGE_FETCHDATA1_8; source1 <= OPSOURCE_FETCHVALUE8; - when x"E4" => opcode <= OP_OPIN; newDelay := 5; cpustage <= CPUSTAGE_FETCHDATA1_8; opsize <= 1; source1 <= OPSOURCE_FETCHVALUE8; - when x"E5" => opcode <= OP_OPIN; newDelay := 4; cpustage <= CPUSTAGE_FETCHDATA1_8; opsize <= 2; source1 <= OPSOURCE_FETCHVALUE8; - when x"E6" => opcode <= OP_OPOUT; newDelay := 4; cpustage <= CPUSTAGE_FETCHDATA1_8; opsize <= 1; source1 <= OPSOURCE_FETCHVALUE8; source2 <= OPSOURCE_ACC; - when x"E7" => opcode <= OP_OPOUT; newDelay := 3; cpustage <= CPUSTAGE_FETCHDATA1_8; opsize <= 2; source1 <= OPSOURCE_FETCHVALUE8; source2 <= OPSOURCE_ACC; + when x"E4" => opcode <= OP_OPIN; newDelay := 5; cpustage <= CPUSTAGE_FETCHDATA1_8; opsize <= '0'; source1 <= OPSOURCE_FETCHVALUE8; + when x"E5" => opcode <= OP_OPIN; newDelay := 4; cpustage <= CPUSTAGE_FETCHDATA1_8; opsize <= '1'; source1 <= OPSOURCE_FETCHVALUE8; + when x"E6" => opcode <= OP_OPOUT; newDelay := 4; cpustage <= CPUSTAGE_FETCHDATA1_8; opsize <= '0'; source1 <= OPSOURCE_FETCHVALUE8; source2 <= OPSOURCE_ACC; + when x"E7" => opcode <= OP_OPOUT; newDelay := 3; cpustage <= CPUSTAGE_FETCHDATA1_8; opsize <= '1'; source1 <= OPSOURCE_FETCHVALUE8; source2 <= OPSOURCE_ACC; when x"E8" => opcode <= OP_JUMP; cpustage <= CPUSTAGE_FETCHDATA1_16; source1 <= OPSOURCE_FETCHVALUE16; pushlist <= REGPOS_ip; when x"E9" => opcode <= OP_JUMP; cpustage <= CPUSTAGE_FETCHDATA1_16; source1 <= OPSOURCE_FETCHVALUE16; - when x"EA" => opcode <= OP_JUMPFAR; newDelay := 3; opsize <= 2; cpustage <= CPUSTAGE_FETCHDATA1_16; source1 <= OPSOURCE_FETCHVALUE16; source2 <= OPSOURCE_FETCHVALUE16; + when x"EA" => opcode <= OP_JUMPFAR; newDelay := 3; opsize <= '1'; cpustage <= CPUSTAGE_FETCHDATA1_16; source1 <= OPSOURCE_FETCHVALUE16; source2 <= OPSOURCE_FETCHVALUE16; when x"EB" => opcode <= OP_JUMPIF; cpustage <= CPUSTAGE_FETCHDATA1_8; source1 <= OPSOURCE_FETCHVALUE8; - when x"EC" => opcode <= OP_OPIN; newDelay := 4; cpustage <= CPUSTAGE_EXECUTE; opsize <= 1; source1 <= OPSOURCE_REG_dx; - when x"ED" => opcode <= OP_OPIN; newDelay := 4; cpustage <= CPUSTAGE_EXECUTE; opsize <= 2; source1 <= OPSOURCE_REG_dx; - when x"EE" => opcode <= OP_OPOUT; newDelay := 3; cpustage <= CPUSTAGE_EXECUTE; opsize <= 1; source1 <= OPSOURCE_REG_dx; source2 <= OPSOURCE_ACC; - when x"EF" => opcode <= OP_OPOUT; newDelay := 2; cpustage <= CPUSTAGE_EXECUTE; opsize <= 2; source1 <= OPSOURCE_REG_dx; source2 <= OPSOURCE_ACC; + when x"EC" => opcode <= OP_OPIN; newDelay := 4; cpustage <= CPUSTAGE_EXECUTE; opsize <= '0'; source1 <= OPSOURCE_REG_dx; + when x"ED" => opcode <= OP_OPIN; newDelay := 4; cpustage <= CPUSTAGE_EXECUTE; opsize <= '1'; source1 <= OPSOURCE_REG_dx; + when x"EE" => opcode <= OP_OPOUT; newDelay := 3; cpustage <= CPUSTAGE_EXECUTE; opsize <= '0'; source1 <= OPSOURCE_REG_dx; source2 <= OPSOURCE_ACC; + when x"EF" => opcode <= OP_OPOUT; newDelay := 2; cpustage <= CPUSTAGE_EXECUTE; opsize <= '1'; source1 <= OPSOURCE_REG_dx; source2 <= OPSOURCE_ACC; when x"F0" => isPrefix := '1'; irqBlocked <= '1'; usePrefix := '1'; -- lock @@ -1160,8 +1169,8 @@ begin when x"F5" => opcode <= OP_NOP; newDelay := 3; regs.FlagCar <= not regs.FlagCar; cpustage <= CPUSTAGE_EXECUTE; - when x"F6" => opcode <= OP_MEMIMM3; source1 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; opsize <= 1; - when x"F7" => opcode <= OP_MEMIMM3; source1 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; opsize <= 2; + when x"F6" => opcode <= OP_MEMIMM3; source1 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; opsize <= '0'; + when x"F7" => opcode <= OP_MEMIMM3; source1 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; opsize <= '1'; when x"F8" => newDelay := 3; cpustage <= CPUSTAGE_IDLE; cpu_finished <= '1'; regs.FlagCar <= '0'; when x"F9" => newDelay := 3; cpustage <= CPUSTAGE_IDLE; cpu_finished <= '1'; regs.FlagCar <= '1'; @@ -1170,8 +1179,8 @@ begin when x"FC" => newDelay := 3; cpustage <= CPUSTAGE_IDLE; cpu_finished <= '1'; regs.FlagDir <= '0'; when x"FD" => newDelay := 3; cpustage <= CPUSTAGE_IDLE; cpu_finished <= '1'; regs.FlagDir <= '1'; - when x"FE" => opcode <= OP_MEMIMM4; source1 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; opsize <= 1; - when x"FF" => opcode <= OP_MEMIMM4; source1 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; opsize <= 2; + when x"FE" => opcode <= OP_MEMIMM4; source1 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; opsize <= '0'; + when x"FF" => opcode <= OP_MEMIMM4; source1 <= OPSOURCE_MEM; cpustage <= CPUSTAGE_MODRM; opsize <= '1'; when others => cpustage <= CPUSTAGE_IDLE; cpu_done <= '1'; @@ -1265,7 +1274,7 @@ begin when others => null; end case; else - if (opsize = 1) then + if (opsize = '0') then case (to_integer(MODRM_reg)) is when 0 => vartarget_reg := CPU_REG_al; when 1 => vartarget_reg := CPU_REG_cl; @@ -1277,7 +1286,7 @@ begin when 7 => vartarget_reg := CPU_REG_bh; when others => null; end case; - elsif (opsize = 2) then + elsif (opsize = '1') then case (to_integer(MODRM_reg)) is when 0 => vartarget_reg := CPU_REG_ax; when 1 => vartarget_reg := CPU_REG_cx; @@ -1303,7 +1312,7 @@ begin when others => null; end case; else - if (opsize = 1) then + if (opsize = '0') then case (to_integer(MODRM_reg)) is when 0 => MODRM_value_reg <= x"00" & regs.reg_ax( 7 downto 0); when 1 => MODRM_value_reg <= x"00" & regs.reg_cx( 7 downto 0); @@ -1315,7 +1324,7 @@ begin when 7 => MODRM_value_reg <= x"00" & regs.reg_bx(15 downto 8); when others => null; end case; - elsif (opsize = 2) then + elsif (opsize = '1') then case (to_integer(MODRM_reg)) is when 0 => MODRM_value_reg <= regs.reg_ax; when 1 => MODRM_value_reg <= regs.reg_cx; @@ -1364,16 +1373,16 @@ begin case (to_integer(MODRM_reg)) is when 0 | 1 => opcode <= OP_NOP; aluop <= ALU_OP_TST; - if (opsize = 2) then varsource2 := OPSOURCE_FETCHVALUE16; else varsource2 := OPSOURCE_FETCHVALUE8; end if; + if (opsize = '1') then varsource2 := OPSOURCE_FETCHVALUE16; else varsource2 := OPSOURCE_FETCHVALUE8; end if; dbuf <= dbuf + 1; when 2 => opcode <= OP_MOVMEM; varoptarget := OPTARGET_MEM; aluop <= ALU_OP_NOT; useAluResult <= '1'; if (MODRM_mod /= 3) then newModDelay := newModDelay + 1; end if; when 3 => opcode <= OP_MOVMEM; varoptarget := OPTARGET_MEM; aluop <= ALU_OP_NEG; useAluResult <= '1'; if (MODRM_mod /= 3) then newModDelay := newModDelay + 1; end if; when 4 => opcode <= OP_NOP; varsource1 := OPSOURCE_ACC; varsource2 := OPSOURCE_MEM; aluop <= ALU_OP_MUL; useAluResult <= '1'; newModDelay := newModDelay + 2; when 5 => opcode <= OP_NOP; varsource1 := OPSOURCE_ACC; varsource2 := OPSOURCE_MEM; aluop <= ALU_OP_MULI; useAluResult <= '1'; newModDelay := newModDelay + 2; when 6 => opcode <= OP_DIV; varsource1 := OPSOURCE_ACC; varsource2 := OPSOURCE_MEM; - if (opsize = 1) then newModDelay := newModDelay + 2; else newModDelay := newModDelay + 11; end if; + if (opsize = '0') then newModDelay := newModDelay + 2; else newModDelay := newModDelay + 11; end if; when 7 => opcode <= OP_DIVI; varsource1 := OPSOURCE_ACC; varsource2 := OPSOURCE_MEM; - if (opsize = 1) then newModDelay := newModDelay + 4; else newModDelay := newModDelay + 12; end if; + if (opsize = '0') then newModDelay := newModDelay + 4; else newModDelay := newModDelay + 12; end if; when others => null; end case; @@ -1407,7 +1416,7 @@ begin if (opcode = OP_MEMIMM1 and to_integer(MODRM_reg) = 7) then -- special case: CMP opcode <= OP_NOP; end if; - if (opsize = 1) then + if (opsize = '0') then case (to_integer(MODRM_mem)) is when 0 => target_reg <= CPU_REG_al; when 1 => target_reg <= CPU_REG_cl; @@ -1419,7 +1428,7 @@ begin when 7 => target_reg <= CPU_REG_bh; when others => null; end case; - elsif (opsize = 2) then + elsif (opsize = '1') then case (to_integer(MODRM_mem)) is when 0 => target_reg <= CPU_REG_ax; when 1 => target_reg <= CPU_REG_cx; @@ -1457,7 +1466,7 @@ begin -- instant fetching if memory access degrades to register access fetchedRMMODData := x"0000"; - if (opsize = 1) then + if (opsize = '0') then case (to_integer(MODRM_mem)) is when 0 => fetchedRMMODData := x"00" & regs.reg_ax( 7 downto 0); when 1 => fetchedRMMODData := x"00" & regs.reg_cx( 7 downto 0); @@ -1469,7 +1478,7 @@ begin when 7 => fetchedRMMODData := x"00" & regs.reg_bx(15 downto 8); when others => null; end case; - elsif (opsize = 2) then + elsif (opsize = '1') then case (to_integer(MODRM_mem)) is when 0 => fetchedRMMODData := regs.reg_ax; when 1 => fetchedRMMODData := regs.reg_cx; @@ -1633,7 +1642,7 @@ begin when CPUSTAGE_FETCHMEM_REC => if (source1 = OPSOURCE_MEM and fetchedSource1 = '0') then - if (opsize = 1) then + if (opsize = '0') then memFetchValue1 <= x"00" & unsigned(bus_dataread(7 downto 0)); if (source2 = OPSOURCE_MEM) then memAddr <= memAddr + 1; end if; fetchedSource1 <= '1'; @@ -1671,7 +1680,7 @@ begin end if; end if; elsif (source2 = OPSOURCE_MEM and fetchedSource2 = '0') then - if (opsize = 1) then + if (opsize = '0') then memFetchValue2 <= x"00" & unsigned(bus_dataread(7 downto 0)); fetchedSource2 <= '1'; if (pushlist /= x"0000") then @@ -1776,7 +1785,7 @@ begin when 13 => pushValue := std_logic_vector(regs.reg_ip - prefixIP); when 14 => pushValue := std_logic_vector(memFetchValue1); when 15 => - if (opsize = 1) then + if (opsize = '0') then pushValue := std_logic_vector(resize(signed(fetch1Val(7 downto 0)), 16)); else pushValue := std_logic_vector(fetch1Val); @@ -1934,7 +1943,7 @@ begin when OPSOURCE_MEM => source1Val := memFetchValue1; when OPSOURCE_MODRM_REG => source1Val := MODRM_value_reg; when OPSOURCE_MODRM_ADDR => source1Val := memAddr; - when OPSOURCE_ACC => if (opsize = 1) then source1Val := x"00" & regs.reg_ax(7 downto 0); else source1Val := regs.reg_ax; end if; + when OPSOURCE_ACC => if (opsize = '0') then source1Val := x"00" & regs.reg_ax(7 downto 0); else source1Val := regs.reg_ax; end if; when OPSOURCE_STRINGLOAD1 => source1Val := stringLoad; when OPSOURCE_STRINGLOAD2 => source1Val := stringLoad2; when OPSOURCE_IMMIDIATE => source1Val := x"00" & immidiate8; @@ -1957,7 +1966,7 @@ begin when OPSOURCE_IRQVECTOR => source2Val := fetch2Val; when OPSOURCE_MEM => source2Val := memFetchValue2; when OPSOURCE_MODRM_REG => source2Val := MODRM_value_reg; - when OPSOURCE_ACC => if (opsize = 1) then source2Val := x"00" & regs.reg_ax(7 downto 0); else source2Val := regs.reg_ax; end if; + when OPSOURCE_ACC => if (opsize = '0') then source2Val := x"00" & regs.reg_ax(7 downto 0); else source2Val := regs.reg_ax; end if; when OPSOURCE_STRINGLOAD1 => source2Val := stringLoad; when OPSOURCE_STRINGLOAD2 => source2Val := stringLoad2; when OPSOURCE_IMMIDIATE => source2Val := x"00" & immidiate8; @@ -1985,7 +1994,7 @@ begin if (aluop /= ALU_OP_NOTHING) then case (aluop) is when ALU_OP_SET1 => - if (opsize = 1) then + if (opsize = '0') then op2value := shift_left(to_unsigned(1, 16), to_integer(source2Val(2 downto 0))); else op2value := shift_left(to_unsigned(1, 16), to_integer(source2Val(3 downto 0))); @@ -1993,7 +2002,7 @@ begin result := source1Val or op2value; when ALU_OP_CLR1 => - if (opsize = 1) then + if (opsize = '0') then op2value := shift_left(to_unsigned(1, 16), to_integer(source2Val(2 downto 0))); else op2value := shift_left(to_unsigned(1, 16), to_integer(source2Val(3 downto 0))); @@ -2001,7 +2010,7 @@ begin result := source1Val and (not op2value); when ALU_OP_TEST1 => - if (opsize = 1) then + if (opsize = '0') then op2value := shift_left(to_unsigned(1, 16), to_integer(source2Val(2 downto 0))); else op2value := shift_left(to_unsigned(1, 16), to_integer(source2Val(3 downto 0))); @@ -2011,7 +2020,7 @@ begin newZero := '1'; newParity := '1'; newSign := '1'; when ALU_OP_NOT1 => - if (opsize = 1) then + if (opsize = '0') then op2value := shift_left(to_unsigned(1, 16), to_integer(source2Val(2 downto 0))); else op2value := shift_left(to_unsigned(1, 16), to_integer(source2Val(3 downto 0))); @@ -2049,8 +2058,8 @@ begin if (source1Val > 0) then regs.FlagCar <= '1'; else regs.FlagCar <= '0'; end if; if (source1Val(3 downto 0) > 0) then regs.FlagHaC <= '1'; else regs.FlagHaC <= '0'; end if; regs.FlagOvf <= '0'; - if (opsize = 1 and source1Val(7 downto 0) = x"80") then regs.FlagOvf <= '1'; end if; - if (opsize = 2 and source1Val = x"8000") then regs.FlagOvf <= '1'; end if; + if (opsize = '0' and source1Val(7 downto 0) = x"80") then regs.FlagOvf <= '1'; end if; + if (opsize = '1' and source1Val = x"8000") then regs.FlagOvf <= '1'; end if; newZero := '1'; newParity := '1'; newSign := '1'; when ALU_OP_ADD | ALU_OP_INC | ALU_OP_ADC => @@ -2062,11 +2071,11 @@ begin result := source1Val + op2value; if (aluop /= ALU_OP_INC) then regs.FlagCar <= '0'; - if (opsize = 1 and to_integer(source1Val) + to_integer(op2value) > 16#FF#) then regs.FlagCar <= '1'; end if; - if (opsize = 2 and to_integer(source1Val) + to_integer(op2value) > 16#FFFF#) then regs.FlagCar <= '1'; end if; + if (opsize = '0' and to_integer(source1Val) + to_integer(op2value) > 16#FF#) then regs.FlagCar <= '1'; end if; + if (opsize = '1' and to_integer(source1Val) + to_integer(op2value) > 16#FFFF#) then regs.FlagCar <= '1'; end if; end if; if (to_integer(source1Val(3 downto 0)) + to_integer(op2value(3 downto 0)) >= 16) then regs.FlagHaC <= '1'; else regs.FlagHaC <= '0'; end if; - if (opsize = 1) then + if (opsize = '0') then regs.FlagOvf <= (source1Val(7) xor result(7)) and (op2value(7) xor result(7)); else regs.FlagOvf <= (source1Val(15) xor result(15)) and (op2value(15) xor result(15)); @@ -2083,7 +2092,7 @@ begin if (op2value > source1Val) then regs.FlagCar <= '1'; else regs.FlagCar <= '0'; end if; end if; if (op2value(3 downto 0) > source1Val(3 downto 0)) then regs.FlagHaC <= '1'; else regs.FlagHaC <= '0'; end if; - if (opsize = 1) then + if (opsize = '0') then regs.FlagOvf <= (source1Val(7) xor op2value(7)) and (source1Val(7) xor result(7)); else regs.FlagOvf <= (source1Val(15) xor op2value(15)) and (source1Val(15) xor result(15)); @@ -2091,7 +2100,7 @@ begin when ALU_OP_ROL => result17 := resize(source1Val, 17) sll to_integer(source2Val(4 downto 0)); - if (opsize = 1) then + if (opsize = '0') then result(7 downto 0) := source1Val(7 downto 0) rol to_integer(source2Val(4 downto 0)); regs.FlagCar <= result17(8); regs.FlagOvf <= source1Val(7) xor result(7); @@ -2106,7 +2115,7 @@ begin result17 := (source1Val & '0') srl to_integer(source2Val(4 downto 0)); result := result17(16 downto 1); regs.FlagCar <= result17(0); - if (opsize = 1) then + if (opsize = '0') then result(7 downto 0) := source1Val(7 downto 0) ror to_integer(source2Val(4 downto 0)); regs.FlagOvf <= source1Val(7) xor result(7); else @@ -2119,7 +2128,7 @@ begin result := source1Val; for i in 0 to 31 loop if (i < source2Val(4 downto 0)) then - if (opsize = 1) then + if (opsize = '0') then carryWork2 := result(7); else carryWork2 := result(15); @@ -2129,7 +2138,7 @@ begin end if; end loop; regs.FlagCar <= carryWork1; - if (opsize = 1) then + if (opsize = '0') then regs.FlagOvf <= (source1Val(7) xor result(7)); else regs.FlagOvf <= (source1Val(15) xor result(15)); @@ -2142,7 +2151,7 @@ begin if (i < source2Val(4 downto 0)) then carryWork2 := result(0); result := '0' & result(15 downto 1); - if (opsize = 1) then + if (opsize = '0') then result(7) := carryWork1; else result(15) := carryWork1; @@ -2151,7 +2160,7 @@ begin end if; end loop; regs.FlagCar <= carryWork1; - if (opsize = 1) then + if (opsize = '0') then regs.FlagOvf <= (source1Val(7) xor result(7)); else regs.FlagOvf <= (source1Val(15) xor result(15)); @@ -2159,12 +2168,12 @@ begin when ALU_OP_SHL | ALU_OP_SAL => result17 := resize(source1Val, 17) sll to_integer(source2Val(4 downto 0)); - if (opsize = 1) then regs.FlagCar <= result17(8); end if; - if (opsize = 2) then regs.FlagCar <= result17(16); end if; + if (opsize = '0') then regs.FlagCar <= result17(8); end if; + if (opsize = '1') then regs.FlagCar <= result17(16); end if; if (aluop = ALU_OP_SAL) then regs.FlagOvf <= '0'; else - if (opsize = 1) then + if (opsize = '0') then regs.FlagOvf <= source1Val(7) xor result17(7); else regs.FlagOvf <= source1Val(15) xor result17(15); @@ -2177,7 +2186,7 @@ begin result17 := (source1Val & '0') srl to_integer(source2Val(4 downto 0)); result := result17(16 downto 1); regs.FlagCar <= result17(0); - if (opsize = 1) then + if (opsize = '0') then regs.FlagOvf <= source1Val(7) xor result(7); else regs.FlagOvf <= source1Val(15) xor result(15); @@ -2186,7 +2195,7 @@ begin when ALU_OP_SAR => if (source2Val(4) = '1') then - if ((opsize = 1 and source1Val(7) = '1') or (opsize = 2 and source1Val(15) = '1')) then + if ((opsize = '0' and source1Val(7) = '1') or (opsize = '1' and source1Val(15) = '1')) then result := x"FFFF"; regs.FlagCar <= '1'; else @@ -2196,7 +2205,7 @@ begin else result17 := (source1Val & '0') srl to_integer(source2Val(4 downto 0)); regs.FlagCar <= result17(0); - if (opsize = 1) then + if (opsize = '0') then result := x"00" & unsigned(shift_right(signed(source1Val(7 downto 0)),to_integer(source2Val(4 downto 0)))); else result := unsigned(shift_right(signed(source1Val),to_integer(source2Val(4 downto 0)))); @@ -2208,7 +2217,7 @@ begin when ALU_OP_MUL => regs.FlagCar <= '0'; regs.FlagOvf <= '0'; - if (opsize = 1) then + if (opsize = '0') then result32 := resize(source1Val(7 downto 0) * memFetchValue2, 32); regs.reg_ax <= result32(15 downto 0); if (result32(31 downto 8) /= x"000000") then @@ -2225,7 +2234,7 @@ begin when ALU_OP_MULI => regs.FlagCar <= '0'; regs.FlagOvf <= '0'; - if (opsize = 1) then + if (opsize = '0') then result32 := unsigned(to_signed(to_integer(signed(source1Val(7 downto 0))) * to_integer(signed(memFetchValue2(7 downto 0))), 32)); if (opcode = OP_NOP) then regs.reg_ax <= result32(15 downto 0); end if; if (result32(31 downto 8) /= x"000000") then @@ -2310,7 +2319,7 @@ begin end if; -- flags - if (opsize = 1) then + if (opsize = '0') then result(15 downto 8) := x"00"; end if; @@ -2319,7 +2328,7 @@ begin end if; if (newSign = '1') then - if (opsize = 1) then regs.FlagSgn <= result(7); else regs.FlagSgn <= result(15); end if; + if (opsize = '0') then regs.FlagSgn <= result(7); else regs.FlagSgn <= result(15); end if; end if; if (newParity = '1') then @@ -2364,7 +2373,7 @@ begin bus_addr <= resize(varmemSegment * 16 + memAddr + 1, 20); bus_datawrite <= x"00" & std_logic_vector(resultval(15 downto 8)); bus_be <= "01"; - elsif (opsize = 2 and memAddr(0) = '0') then + elsif (opsize = '1' and memAddr(0) = '0') then bus_addr <= resize(varmemSegment * 16 + memAddr, 20); bus_datawrite <= std_logic_vector(resultval); bus_be <= "11"; @@ -2374,7 +2383,7 @@ begin bus_be <= "01"; end if; - if (opsize = 1 or memFirst = '0' or memAddr(0) = '0') then + if (opsize = '0' or memFirst = '0' or memAddr(0) = '0') then if (SLOWTIMING = '1') then newExeDelay := newExeDelay + 1; end if; if (opcodeNext /= OP_INVALID) then if (target_reg2 /= CPU_REG_NONE) then @@ -2472,7 +2481,7 @@ begin if (opcodeNext = OP_INVALID) then regs.reg_ax(7 downto 0) <= unsigned(RegBus_Dout); end if; - if (opsize = 1) then + if (opsize = '0') then if (opcodeNext /= OP_INVALID) then if (ce = '1') then source1 <= source2; @@ -2509,7 +2518,7 @@ begin when OP_OPOUT => memFirst <= '0'; - if (opsize = 1 or memFirst = '1') then + if (opsize = '0' or memFirst = '1') then RegBus_Din <= std_logic_vector(source2Val(7 downto 0)); RegBus_Adr <= std_logic_vector(source1Val(7 downto 0)); RegBus_wren <= '1'; @@ -2518,7 +2527,7 @@ begin RegBus_Adr <= std_logic_vector(source1Val(7 downto 0) + 1); RegBus_wren <= '1'; end if; - if (opsize = 1 or (memFirst = '0' and ce = '1')) then + if (opsize = '0' or (memFirst = '0' and ce = '1')) then exeDone := '1'; newExeDelay := newExeDelay + 1; end if; @@ -2629,7 +2638,7 @@ begin end if; when OP_STRINGLOAD => - if (opsize = 2) then + if (opsize = '1') then wordAligned := (not regs.reg_si(0)); else wordAligned := '0'; @@ -2642,7 +2651,7 @@ begin consumePrefetch <= 1; newExeDelay := newExeDelay + 1; exeDone := '1'; - if (opcodeNext /= OP_INVALID) then newExeDelay := newExeDelay + 1 + opsize; end if; + if (opcodeNext /= OP_INVALID) then newExeDelay := newExeDelay + 2 + to_integer('0'&opsize); end if; else case (opstep) is @@ -2671,17 +2680,17 @@ begin memFirst <= '0'; if (wordAligned = '1') then stringLoad(15 downto 0) <= unsigned(bus_dataread(15 downto 0)); - elsif (opsize = 1 or memFirst = '1') then + elsif (opsize = '0' or memFirst = '1') then stringLoad(7 downto 0) <= unsigned(bus_dataread(7 downto 0)); - if (opsize = 1) then stringLoad(15 downto 8) <= x"00"; end if; + if (opsize = '0') then stringLoad(15 downto 8) <= x"00"; end if; else stringLoad(15 downto 8) <= unsigned(bus_dataread(7 downto 0)); end if; - if (opsize = 1 or memFirst = '0' or wordAligned = '1') then + if (opsize = '0' or memFirst = '0' or wordAligned = '1') then if (regs.FlagDir) then - regs.reg_si <= regs.reg_si - opsize; + regs.reg_si <= regs.reg_si - 1 - to_integer('0'&opsize); else - regs.reg_si <= regs.reg_si + opsize; + regs.reg_si <= regs.reg_si + 1 + to_integer('0'&opsize); end if; if (opcodeNext /= OP_INVALID) then @@ -2709,7 +2718,7 @@ begin end if; when OP_STRINGCOMPARE => - if (opsize = 2) then + if (opsize = '1') then wordAligned := (not regs.reg_di(0)); else wordAligned := '0'; @@ -2744,13 +2753,13 @@ begin memFirst <= '0'; if (wordAligned = '1') then stringLoad2(15 downto 0) <= unsigned(bus_dataread(15 downto 0)); - elsif (opsize = 1 or memFirst = '1') then + elsif (opsize = '0' or memFirst = '1') then stringLoad2(7 downto 0) <= unsigned(bus_dataread(7 downto 0)); - if (opsize = 1) then stringLoad2(15 downto 8) <= x"00"; end if; + if (opsize = '0') then stringLoad2(15 downto 8) <= x"00"; end if; else stringLoad2(15 downto 8) <= unsigned(bus_dataread(7 downto 0)); end if; - if (opsize = 1 or memFirst = '0' or wordAligned = '1') then + if (opsize = '0' or memFirst = '0' or wordAligned = '1') then opstep <= 3; aluop <= ALU_OP_CMP; else @@ -2761,9 +2770,9 @@ begin if (ce = '1') then exeDone := '1'; if (regs.FlagDir) then - regs.reg_di <= regs.reg_di - opsize; + regs.reg_di <= regs.reg_di - 1 - to_integer('0'&opsize); else - regs.reg_di <= regs.reg_di + opsize; + regs.reg_di <= regs.reg_di + 1 + to_integer('0'&opsize); end if; if (repeat = '1') then regs.reg_cx <= regs.reg_cx - 1; @@ -2784,7 +2793,7 @@ begin end if; when OP_STRINGSTORE => - if (opsize = 2) then + if (opsize = '1') then wordAligned := (not regs.reg_di(0)); else wordAligned := '0'; @@ -2818,12 +2827,12 @@ begin bus_addr <= resize(regs.reg_es * 16 + regs.reg_di, 20); end if; - if (opsize = 1 or memFirst = '0' or wordAligned = '1') then + if (opsize = '0' or memFirst = '0' or wordAligned = '1') then exeDone := '1'; if (regs.FlagDir) then - regs.reg_di <= regs.reg_di - opsize; + regs.reg_di <= regs.reg_di - 1 - to_integer('0'&opsize); else - regs.reg_di <= regs.reg_di + opsize; + regs.reg_di <= regs.reg_di + 1 + to_integer('0'&opsize); end if; if (repeat = '1') then regs.reg_cx <= regs.reg_cx - 1; @@ -2986,7 +2995,7 @@ begin opstep <= 1; DIVstart <= '1'; DIVdivisor <= '0' & x"0000" & signed(memFetchValue2); - if (opsize = 1) then + if (opsize = '0') then DIVdividend <= '0' & x"0000" & signed(regs.reg_ax); else DIVdividend <= '0' & signed(regs.reg_dx) & signed(regs.reg_ax); @@ -2997,7 +3006,7 @@ begin irqrequest <= '1'; irqvector <= (others => '0'); else - if (opsize = 1) then + if (opsize = '0') then regs.reg_ax <= unsigned(DIVremainder(7 downto 0)) & unsigned(DIVquotient(7 downto 0)); else regs.reg_ax <= unsigned(DIVquotient(15 downto 0)); @@ -3011,7 +3020,7 @@ begin delay <= 10; opstep <= 1; DIVstart <= '1'; - if (opsize = 1) then + if (opsize = '0') then DIVdividend <= resize(signed(regs.reg_ax), 33); DIVdivisor <= resize(signed(memFetchValue2(7 downto 0)), 33); else @@ -3024,7 +3033,7 @@ begin irqrequest <= '1'; irqvector <= (others => '0'); else - if (opsize = 1) then + if (opsize = '0') then regs.reg_ax <= unsigned(DIVremainder(7 downto 0)) & unsigned(DIVquotient(7 downto 0)); else regs.reg_ax <= unsigned(DIVquotient(15 downto 0));