From 925ba715be5114f38c2f9cafd869fca2fc4dfddc Mon Sep 17 00:00:00 2001
From: Gyorgy Szombathelyi <8644936+gyurco@users.noreply.github.com>
Date: Sat, 15 Apr 2023 16:45:57 +0200
Subject: [PATCH] IremM92
---
Arcade_MiST/IremM92 Hardware/IremM92.qpf | 30 +
Arcade_MiST/IremM92 Hardware/IremM92.qsf | 255 ++++++
Arcade_MiST/IremM92 Hardware/IremM92.sdc | 153 ++++
Arcade_MiST/IremM92 Hardware/Readme.md | 39 +
Arcade_MiST/IremM92 Hardware/clean.bat | 36 +
.../meta/Blade Master (World).mra | 104 +++
...Dream Soccer '94 (Japan, M92 hardware).mra | 106 +++
.../meta/Gun Force II (US).mra | 99 +++
...le Fire Engulfed Terror Island (World).mra | 101 +++
.../IremM92 Hardware/meta/Hook (World).mra | 102 +++
.../meta/In The Hunt (World).mra | 102 +++
.../meta/Lethal Thunder (World).mra | 101 +++
.../meta/Major Title 2 (World, set 1).mra | 101 +++
.../meta/Mystic Riders (World).mra | 101 +++
.../meta/Ninja Baseball Bat Man (World).mra | 103 +++
.../meta/R-Type Leo (World).mra | 101 +++
.../meta/Superior Soldiers (US).mra | 101 +++
.../meta/Undercover Cops (World).mra | 103 +++
.../IremM92 Hardware/rtl/IremM92_MiST.sv | 492 ++++++++++++
Arcade_MiST/IremM92 Hardware/rtl/build_id.tcl | 35 +
Arcade_MiST/IremM92 Hardware/rtl/dpramv.sv | 175 +++++
Arcade_MiST/IremM92 Hardware/rtl/eeprom.sv | 169 ++++
Arcade_MiST/IremM92 Hardware/rtl/ga20.sv | 306 ++++++++
Arcade_MiST/IremM92 Hardware/rtl/ga21.sv | 238 ++++++
Arcade_MiST/IremM92 Hardware/rtl/ga21_tb.sv | 39 +
Arcade_MiST/IremM92 Hardware/rtl/ga22.sv | 171 +++++
.../IremM92 Hardware/rtl/ga22_linebuffer.sv | 191 +++++
Arcade_MiST/IremM92 Hardware/rtl/ga23.sv | 312 ++++++++
.../IremM92 Hardware/rtl/ga23_layer.sv | 112 +++
.../IremM92 Hardware/rtl/ga23_shifter.sv | 70 ++
Arcade_MiST/IremM92 Hardware/rtl/iir_filter.v | 213 ++++++
.../IremM92 Hardware/rtl/jtframe_frac_cen.v | 62 ++
Arcade_MiST/IremM92 Hardware/rtl/m92.qip | 21 +
Arcade_MiST/IremM92 Hardware/rtl/m92.sv | 724 ++++++++++++++++++
Arcade_MiST/IremM92 Hardware/rtl/m92_pic.sv | 153 ++++
Arcade_MiST/IremM92 Hardware/rtl/m92_pkg.sv | 61 ++
Arcade_MiST/IremM92 Hardware/rtl/objram.sv | 77 ++
Arcade_MiST/IremM92 Hardware/rtl/pal.sv | 85 ++
Arcade_MiST/IremM92 Hardware/rtl/palram.sv | 84 ++
Arcade_MiST/IremM92 Hardware/rtl/pll_mist.qip | 4 +
Arcade_MiST/IremM92 Hardware/rtl/pll_mist.v | 365 +++++++++
Arcade_MiST/IremM92 Hardware/rtl/rom.sv | 124 +++
.../IremM92 Hardware/rtl/sdram_4w_cl3.sv | 499 ++++++++++++
Arcade_MiST/IremM92 Hardware/rtl/sound.sv | 266 +++++++
Arcade_MiST/IremM92 Hardware/rtl/v35.sv | 395 ++++++++++
Arcade_MiST/IremM92 Hardware/sidi/IremM92.qpf | 30 +
Arcade_MiST/IremM92 Hardware/sidi/IremM92.qsf | 252 ++++++
common/CPU/v30/cpu.vhd | 555 +++++++-------
48 files changed, 7845 insertions(+), 273 deletions(-)
create mode 100644 Arcade_MiST/IremM92 Hardware/IremM92.qpf
create mode 100644 Arcade_MiST/IremM92 Hardware/IremM92.qsf
create mode 100644 Arcade_MiST/IremM92 Hardware/IremM92.sdc
create mode 100644 Arcade_MiST/IremM92 Hardware/Readme.md
create mode 100644 Arcade_MiST/IremM92 Hardware/clean.bat
create mode 100644 Arcade_MiST/IremM92 Hardware/meta/Blade Master (World).mra
create mode 100644 Arcade_MiST/IremM92 Hardware/meta/Dream Soccer '94 (Japan, M92 hardware).mra
create mode 100644 Arcade_MiST/IremM92 Hardware/meta/Gun Force II (US).mra
create mode 100644 Arcade_MiST/IremM92 Hardware/meta/Gunforce - Battle Fire Engulfed Terror Island (World).mra
create mode 100644 Arcade_MiST/IremM92 Hardware/meta/Hook (World).mra
create mode 100644 Arcade_MiST/IremM92 Hardware/meta/In The Hunt (World).mra
create mode 100644 Arcade_MiST/IremM92 Hardware/meta/Lethal Thunder (World).mra
create mode 100644 Arcade_MiST/IremM92 Hardware/meta/Major Title 2 (World, set 1).mra
create mode 100644 Arcade_MiST/IremM92 Hardware/meta/Mystic Riders (World).mra
create mode 100644 Arcade_MiST/IremM92 Hardware/meta/Ninja Baseball Bat Man (World).mra
create mode 100644 Arcade_MiST/IremM92 Hardware/meta/R-Type Leo (World).mra
create mode 100644 Arcade_MiST/IremM92 Hardware/meta/Superior Soldiers (US).mra
create mode 100644 Arcade_MiST/IremM92 Hardware/meta/Undercover Cops (World).mra
create mode 100644 Arcade_MiST/IremM92 Hardware/rtl/IremM92_MiST.sv
create mode 100644 Arcade_MiST/IremM92 Hardware/rtl/build_id.tcl
create mode 100644 Arcade_MiST/IremM92 Hardware/rtl/dpramv.sv
create mode 100644 Arcade_MiST/IremM92 Hardware/rtl/eeprom.sv
create mode 100644 Arcade_MiST/IremM92 Hardware/rtl/ga20.sv
create mode 100644 Arcade_MiST/IremM92 Hardware/rtl/ga21.sv
create mode 100644 Arcade_MiST/IremM92 Hardware/rtl/ga21_tb.sv
create mode 100644 Arcade_MiST/IremM92 Hardware/rtl/ga22.sv
create mode 100644 Arcade_MiST/IremM92 Hardware/rtl/ga22_linebuffer.sv
create mode 100644 Arcade_MiST/IremM92 Hardware/rtl/ga23.sv
create mode 100644 Arcade_MiST/IremM92 Hardware/rtl/ga23_layer.sv
create mode 100644 Arcade_MiST/IremM92 Hardware/rtl/ga23_shifter.sv
create mode 100644 Arcade_MiST/IremM92 Hardware/rtl/iir_filter.v
create mode 100644 Arcade_MiST/IremM92 Hardware/rtl/jtframe_frac_cen.v
create mode 100644 Arcade_MiST/IremM92 Hardware/rtl/m92.qip
create mode 100644 Arcade_MiST/IremM92 Hardware/rtl/m92.sv
create mode 100644 Arcade_MiST/IremM92 Hardware/rtl/m92_pic.sv
create mode 100644 Arcade_MiST/IremM92 Hardware/rtl/m92_pkg.sv
create mode 100644 Arcade_MiST/IremM92 Hardware/rtl/objram.sv
create mode 100644 Arcade_MiST/IremM92 Hardware/rtl/pal.sv
create mode 100644 Arcade_MiST/IremM92 Hardware/rtl/palram.sv
create mode 100644 Arcade_MiST/IremM92 Hardware/rtl/pll_mist.qip
create mode 100644 Arcade_MiST/IremM92 Hardware/rtl/pll_mist.v
create mode 100644 Arcade_MiST/IremM92 Hardware/rtl/rom.sv
create mode 100644 Arcade_MiST/IremM92 Hardware/rtl/sdram_4w_cl3.sv
create mode 100644 Arcade_MiST/IremM92 Hardware/rtl/sound.sv
create mode 100644 Arcade_MiST/IremM92 Hardware/rtl/v35.sv
create mode 100644 Arcade_MiST/IremM92 Hardware/sidi/IremM92.qpf
create mode 100644 Arcade_MiST/IremM92 Hardware/sidi/IremM92.qsf
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
+
+
+
+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));