From f47f302c20de115b9567be250e0a63b2d8ab3738 Mon Sep 17 00:00:00 2001 From: Gyorgy Szombathelyi Date: Wed, 18 Dec 2019 23:24:25 +0100 Subject: [PATCH] MappyHardware: port works 1 core for all: Mappy, Motos, Tower Of Druaga, Dig Dug II --- .../DigDugII_MiST/Release/DIGDUG2.ROM | Bin 32768 -> 0 bytes .../Mappy_MiST/Release/MAPPY.ROM | Bin 24576 -> 0 bytes .../Motos_MiST/Release/MOTOS.ROM | Bin 32768 -> 0 bytes Arcade_MiST/Mappy Hardware/README.txt | 77 + .../Mappy Hardware/TheTowerofDruaga.qpf | 6 + .../Mappy Hardware/TheTowerofDruaga.qsf | 236 + .../Mappy Hardware/TheTowerofDruaga.sdc | 134 + .../TheTowerofDruaga_MiST/Release/DRUAGA.ROM | Bin 32768 -> 0 bytes .../rtl/TheTowerofDruaga_mist.sv | 299 ++ Arcade_MiST/Mappy Hardware/rtl/build_id.tcl | 35 + Arcade_MiST/Mappy Hardware/rtl/dpram.vhd | 81 + .../Mappy Hardware/rtl/druaga_sprite.v | 181 + Arcade_MiST/Mappy Hardware/rtl/druaga_video.v | 127 + Arcade_MiST/Mappy Hardware/rtl/fpga_druaga.v | 442 ++ Arcade_MiST/Mappy Hardware/rtl/hvgen.v | 40 + Arcade_MiST/Mappy Hardware/rtl/ioctrl.v | 142 + Arcade_MiST/Mappy Hardware/rtl/ioctrl_0.v | 119 + Arcade_MiST/Mappy Hardware/rtl/ioctrl_1.v | 48 + .../Mappy Hardware/rtl/mc6809/cpucore.v | 36 + .../Mappy Hardware/rtl/mc6809/mc6809.v | 80 + .../Mappy Hardware/rtl/mc6809/mc6809i.v | 4156 +++++++++++++++++ Arcade_MiST/Mappy Hardware/rtl/mems.v | 102 + Arcade_MiST/Mappy Hardware/rtl/pll.v | 337 ++ Arcade_MiST/Mappy Hardware/rtl/regs.v | 110 + Arcade_MiST/Mappy Hardware/rtl/sdram.sv | 323 ++ Arcade_MiST/Mappy Hardware/rtl/wsg.v | 102 + 26 files changed, 7213 insertions(+) delete mode 100644 Arcade_MiST/Mappy Hardware/DigDugII_MiST/Release/DIGDUG2.ROM delete mode 100644 Arcade_MiST/Mappy Hardware/Mappy_MiST/Release/MAPPY.ROM delete mode 100644 Arcade_MiST/Mappy Hardware/Motos_MiST/Release/MOTOS.ROM create mode 100644 Arcade_MiST/Mappy Hardware/README.txt create mode 100644 Arcade_MiST/Mappy Hardware/TheTowerofDruaga.qpf create mode 100644 Arcade_MiST/Mappy Hardware/TheTowerofDruaga.qsf create mode 100644 Arcade_MiST/Mappy Hardware/TheTowerofDruaga.sdc delete mode 100644 Arcade_MiST/Mappy Hardware/TheTowerofDruaga_MiST/Release/DRUAGA.ROM create mode 100644 Arcade_MiST/Mappy Hardware/rtl/TheTowerofDruaga_mist.sv create mode 100644 Arcade_MiST/Mappy Hardware/rtl/build_id.tcl create mode 100644 Arcade_MiST/Mappy Hardware/rtl/dpram.vhd create mode 100644 Arcade_MiST/Mappy Hardware/rtl/druaga_sprite.v create mode 100644 Arcade_MiST/Mappy Hardware/rtl/druaga_video.v create mode 100644 Arcade_MiST/Mappy Hardware/rtl/fpga_druaga.v create mode 100644 Arcade_MiST/Mappy Hardware/rtl/hvgen.v create mode 100644 Arcade_MiST/Mappy Hardware/rtl/ioctrl.v create mode 100644 Arcade_MiST/Mappy Hardware/rtl/ioctrl_0.v create mode 100644 Arcade_MiST/Mappy Hardware/rtl/ioctrl_1.v create mode 100644 Arcade_MiST/Mappy Hardware/rtl/mc6809/cpucore.v create mode 100644 Arcade_MiST/Mappy Hardware/rtl/mc6809/mc6809.v create mode 100644 Arcade_MiST/Mappy Hardware/rtl/mc6809/mc6809i.v create mode 100644 Arcade_MiST/Mappy Hardware/rtl/mems.v create mode 100644 Arcade_MiST/Mappy Hardware/rtl/pll.v create mode 100644 Arcade_MiST/Mappy Hardware/rtl/regs.v create mode 100644 Arcade_MiST/Mappy Hardware/rtl/sdram.sv create mode 100644 Arcade_MiST/Mappy Hardware/rtl/wsg.v diff --git a/Arcade_MiST/Mappy Hardware/DigDugII_MiST/Release/DIGDUG2.ROM b/Arcade_MiST/Mappy Hardware/DigDugII_MiST/Release/DIGDUG2.ROM deleted file mode 100644 index 06cb655320c2859fa0019e34f172c7cfaf1d4920..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32768 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 LkSI{-@6!JQEei#b diff --git a/Arcade_MiST/Mappy Hardware/Motos_MiST/Release/MOTOS.ROM b/Arcade_MiST/Mappy Hardware/Motos_MiST/Release/MOTOS.ROM deleted file mode 100644 index e81bfdc713c1bb5cd4a7039b02c93216777c5f20..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32768 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 diff --git a/Arcade_MiST/Mappy Hardware/README.txt b/Arcade_MiST/Mappy Hardware/README.txt new file mode 100644 index 00000000..165be9a0 --- /dev/null +++ b/Arcade_MiST/Mappy Hardware/README.txt @@ -0,0 +1,77 @@ +The Tower of Druaga/Mappy/Motos/DigDug II to Mist FPGA by Slingshot + +Appropriate ROMs are required at the root of the SD Card: +DRUAGA.ROM +MAPPY.ROM +MOTOS.ROM +DIGDUG2.ROM + + + +--------------------------------------------------------------------------------- +-- +-- Arcade: The Tower of Druaga port to MiSTer by MiSTer-X +-- 25 September 2019 +-- +--------------------------------------------------------------------------------- +-- FPGA Druaga for XILINX Spartan-3 +-------------------------------------- +-- Copyright (c) 2007 MiSTer-X +--------------------------------------------------------------------------------- +-- Cycle-Accurate 6809 Core +-- Revision 1.0 - 13th August 2016 +--------------------------------------------------- +-- Copyright (c) 2016, Greg Miller +--------------------------------------------------------------------------------- +-- +-- +-- Keyboard inputs : +-- +-- F2 : Coin + Start 2 players +-- F1 : Coin + Start 1 player +-- UP,DOWN,LEFT,RIGHT arrows : Movements +-- SPACE : Trig1 +-- CTRL : Trig2 +-- +-- MAME/IPAC/JPAC Style Keyboard inputs: +-- 5 : Coin 1 +-- 6 : Coin 2 +-- 1 : Start 1 Player +-- 2 : Start 2 Players +-- R,F,D,G : Player 2 Movements +-- A : Player 2 Trig1 +-- S : Player 2 Trig2 +-- +-- Joystick support. +-- +-- +-- FIXED: Video timing. +-- +--------------------------------------------------------------------------------- + + *** Attention *** + +ROM is not included. In order to use this arcade, you need to provide a correct ROM file. + +Find this zip file somewhere. You need to find the file exactly as required. +Do not rename other zip files even if they also represent the same game - they are not compatible! +The name of zip is taken from M.A.M.E. project, so you can get more info about +hashes and contained files there. + +To generate the ROM using Windows: +1) Copy the zip into "releases" directory +2) Execute bat file - it will show the name of zip file containing required files. +3) Put required zip into the same directory and execute the bat again. +4) If everything will go without errors or warnings, then you will get the a.*.rom file. +5) Copy generated a.*.rom into root of SD card along with the Arcade-*.rbf file + +To generate the ROM using Linux/MacOS: +1) Copy the zip into "releases" directory +2) Execute build_rom.sh +3) Copy generated a.*.rom into root of SD card along with the Arcade-*.rbf file + +To generate the ROM using MiSTer: +1) scp "releases" directory along with the zip file onto MiSTer:/media/fat/ +2) Using OSD execute build_rom.sh +3) Copy generated a.*.rom into root of SD card along with the Arcade-*.rbf file + diff --git a/Arcade_MiST/Mappy Hardware/TheTowerofDruaga.qpf b/Arcade_MiST/Mappy Hardware/TheTowerofDruaga.qpf new file mode 100644 index 00000000..b68cd1ff --- /dev/null +++ b/Arcade_MiST/Mappy Hardware/TheTowerofDruaga.qpf @@ -0,0 +1,6 @@ +DATE = "19:48:06 May 24, 2017" +QUARTUS_VERSION = "16.0.2" + +# Revisions + +PROJECT_REVISION = "TheTowerofDruaga" diff --git a/Arcade_MiST/Mappy Hardware/TheTowerofDruaga.qsf b/Arcade_MiST/Mappy Hardware/TheTowerofDruaga.qsf new file mode 100644 index 00000000..72b9f6ca --- /dev/null +++ b/Arcade_MiST/Mappy Hardware/TheTowerofDruaga.qsf @@ -0,0 +1,236 @@ +# -------------------------------------------------------------------------- # +# +# Copyright (C) 1991-2014 Altera Corporation +# Your use of Altera Corporation's design tools, logic functions +# and other software and tools, and its AMPP partner logic +# functions, and any output files from any of the foregoing +# (including device programming or simulation files), and any +# associated documentation or information are expressly subject +# to the terms and conditions of the Altera Program License +# Subscription Agreement, Altera MegaCore Function License +# Agreement, or other applicable license agreement, including, +# without limitation, that your use is for the sole purpose of +# programming logic devices manufactured by Altera and sold by +# Altera or its authorized distributors. Please refer to the +# applicable agreement for further details. +# +# -------------------------------------------------------------------------- # +# +# Quartus II 64-Bit +# Version 13.1.4 Build 182 03/12/2014 SJ Web Edition +# Date created = 19:13:36 October 04, 2019 +# +# -------------------------------------------------------------------------- # +# +# Notes: +# +# 1) The default values for assignments are stored in the file: +# TheTowerofDruaga_assignment_defaults.qdf +# If this file doesn't exist, see file: +# assignment_defaults.qdf +# +# 2) Altera recommends that you do not modify this file. This +# file is updated automatically by the Quartus II software +# and any changes you make may be lost or overwritten. +# +# -------------------------------------------------------------------------- # + + + +# Project-Wide Assignments +# ======================== +set_global_assignment -name ORIGINAL_QUARTUS_VERSION 16.0.2 +set_global_assignment -name LAST_QUARTUS_VERSION "13.1 SP4.26" +set_global_assignment -name PROJECT_CREATION_TIME_DATE "19:48:06 MAY 24,2017" +set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:rtl/build_id.tcl" +set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files + +# 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 +set_location_assignment PLL_1 -to "pll:pll|altpll:altpll_component" + +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[*] + +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 + +# 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_DO_CCPP_REMOVAL ON +set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS ON + +# Analysis & Synthesis Assignments +# ================================ +set_global_assignment -name FAMILY "Cyclone III" +set_global_assignment -name DEVICE_FILTER_PIN_COUNT 144 +set_global_assignment -name DEVICE_FILTER_SPEED_GRADE 8 +set_global_assignment -name TOP_LEVEL_ENTITY TheTowerofDruaga_mist +set_global_assignment -name VERILOG_INPUT_VERSION SYSTEMVERILOG_2005 +set_global_assignment -name VERILOG_SHOW_LMF_MAPPING_MESSAGES OFF + +# Fitter Assignments +# ================== +set_global_assignment -name DEVICE EP3C25E144C8 +set_global_assignment -name CYCLONEIII_CONFIGURATION_SCHEME "PASSIVE SERIAL" +set_global_assignment -name CRC_ERROR_OPEN_DRAIN OFF +set_global_assignment -name FORCE_CONFIGURATION_VCCIO ON +set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "3.3-V LVTTL" +set_global_assignment -name CYCLONEII_RESERVE_NCEO_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_global_assignment -name RESERVE_DATA0_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_global_assignment -name RESERVE_DATA1_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_global_assignment -name RESERVE_FLASH_NCE_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_global_assignment -name RESERVE_DCLK_AFTER_CONFIGURATION "USE AS REGULAR IO" + +# Assembler Assignments +# ===================== +set_global_assignment -name USE_CONFIGURATION_DEVICE OFF +set_global_assignment -name GENERATE_RBF_FILE ON + +# SignalTap II Assignments +# ======================== +set_global_assignment -name ENABLE_SIGNALTAP OFF +set_global_assignment -name USE_SIGNALTAP_FILE output_files/druaga.stp + +# Power Estimation Assignments +# ============================ +set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW" +set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)" + +# Advanced I/O Timing Assignments +# =============================== +set_global_assignment -name OUTPUT_IO_TIMING_NEAR_END_VMEAS "HALF VCCIO" -rise +set_global_assignment -name OUTPUT_IO_TIMING_NEAR_END_VMEAS "HALF VCCIO" -fall +set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -rise +set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -fall + +# ----------------------------------- +# start ENTITY(TheTowerofDruaga_mist) + + # 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(TheTowerofDruaga_mist) +# --------------------------------- +set_global_assignment -name SYSTEMVERILOG_FILE rtl/TheTowerofDruaga_mist.sv +set_global_assignment -name VERILOG_FILE rtl/fpga_druaga.v +set_global_assignment -name VERILOG_FILE rtl/druaga_video.v +set_global_assignment -name VERILOG_FILE rtl/druaga_sprite.v +set_global_assignment -name VERILOG_FILE rtl/wsg.v +set_global_assignment -name VERILOG_FILE rtl/ioctrl.v +set_global_assignment -name VERILOG_FILE rtl/hvgen.v +set_global_assignment -name VHDL_FILE rtl/dpram.vhd +set_global_assignment -name VERILOG_FILE rtl/mc6809/mc6809i.v +set_global_assignment -name VERILOG_FILE rtl/mc6809/mc6809.v +set_global_assignment -name VERILOG_FILE rtl/pll.v +set_global_assignment -name SYSTEMVERILOG_FILE rtl/sdram.sv +set_global_assignment -name QIP_FILE ../../common/mist/mist.qip +set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/Arcade_MiST/Mappy Hardware/TheTowerofDruaga.sdc b/Arcade_MiST/Mappy Hardware/TheTowerofDruaga.sdc new file mode 100644 index 00000000..80fe5371 --- /dev/null +++ b/Arcade_MiST/Mappy Hardware/TheTowerofDruaga.sdc @@ -0,0 +1,134 @@ +## Generated SDC file "vectrex_MiST.out.sdc" + +## Copyright (C) 1991-2013 Altera Corporation +## Your use of Altera Corporation's design tools, logic functions +## and other software and tools, and its AMPP partner logic +## functions, and any output files from any of the foregoing +## (including device programming or simulation files), and any +## associated documentation or information are expressly subject +## to the terms and conditions of the Altera Program License +## Subscription Agreement, Altera MegaCore Function License +## Agreement, or other applicable license agreement, including, +## without limitation, that your use is for the sole purpose of +## programming logic devices manufactured by Altera and sold by +## Altera or its authorized distributors. Please refer to the +## applicable agreement for further details. + + +## VENDOR "Altera" +## PROGRAM "Quartus II" +## VERSION "Version 13.1.0 Build 162 10/23/2013 SJ Web Edition" + +## DATE "Sun Jun 24 12:53:00 2018" + +## +## DEVICE "EP3C25E144C8" +## + +# Clock constraints + +# Automatically constrain PLL and other generated clocks +derive_pll_clocks -create_base_clocks + +# Automatically calculate clock uncertainty to jitter and other effects. +derive_clock_uncertainty + +# tsu/th constraints + +# tco constraints + +# tpd constraints + +#************************************************************** +# Time Information +#************************************************************** + +set_time_format -unit ns -decimal_places 3 + + + +#************************************************************** +# Create Clock +#************************************************************** + +create_clock -name {SPI_SCK} -period 41.666 -waveform { 20.8 41.666 } [get_ports {SPI_SCK}] + +set sys_clk "pll|altpll_component|auto_generated|pll1|clk[0]" +set sdram_clk "pll|altpll_component|auto_generated|pll1|clk[0]" +#************************************************************** +# Create Generated Clock +#************************************************************** + + +#************************************************************** +# Set Clock Latency +#************************************************************** + + + +#************************************************************** +# Set Clock Uncertainty +#************************************************************** + +#************************************************************** +# Set Input Delay +#************************************************************** + +set_input_delay -add_delay -clock_fall -clock [get_clocks {CLOCK_27}] 1.000 [get_ports {CLOCK_27}] +set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {CONF_DATA0}] +set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_DI}] +set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_SCK}] +set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_SS2}] +set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_SS3}] + +set_input_delay -clock [get_clocks $sdram_clk] -reference_pin [get_ports {SDRAM_CLK}] -max 6.6 [get_ports SDRAM_DQ[*]] +set_input_delay -clock [get_clocks $sdram_clk] -reference_pin [get_ports {SDRAM_CLK}] -min 3.5 [get_ports SDRAM_DQ[*]] + +#************************************************************** +# Set Output Delay +#************************************************************** + +set_output_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_DO}] +set_output_delay -add_delay -clock_fall -clock [get_clocks $sys_clk] 1.000 [get_ports {AUDIO_L}] +set_output_delay -add_delay -clock_fall -clock [get_clocks $sys_clk] 1.000 [get_ports {AUDIO_R}] +set_output_delay -add_delay -clock_fall -clock [get_clocks $sys_clk] 1.000 [get_ports {LED}] +set_output_delay -add_delay -clock_fall -clock [get_clocks $sys_clk] 1.000 [get_ports {VGA_*}] + +set_output_delay -clock [get_clocks $sdram_clk] -reference_pin [get_ports {SDRAM_CLK}] -max 1.5 [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}] +set_output_delay -clock [get_clocks $sdram_clk] -reference_pin [get_ports {SDRAM_CLK}] -min -0.8 [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}] + +#************************************************************** +# Set Clock Groups +#************************************************************** + +set_clock_groups -asynchronous -group [get_clocks {SPI_SCK}] -group [get_clocks {pll|altpll_component|auto_generated|pll1|clk[*]}] + +#************************************************************** +# Set False Path +#************************************************************** + + + +#************************************************************** +# Set Multicycle Path +#************************************************************** + +set_multicycle_path -to {VGA_*[*]} -setup 2 +set_multicycle_path -to {VGA_*[*]} -hold 1 + +#************************************************************** +# Set Maximum Delay +#************************************************************** + + + +#************************************************************** +# Set Minimum Delay +#************************************************************** + + + +#************************************************************** +# Set Input Transition +#************************************************************** + diff --git a/Arcade_MiST/Mappy Hardware/TheTowerofDruaga_MiST/Release/DRUAGA.ROM b/Arcade_MiST/Mappy Hardware/TheTowerofDruaga_MiST/Release/DRUAGA.ROM deleted file mode 100644 index 988a5c83ca89c6712086a3f196de5e0de0c8cb3e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32768 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 E17{j{761SM diff --git a/Arcade_MiST/Mappy Hardware/rtl/TheTowerofDruaga_mist.sv b/Arcade_MiST/Mappy Hardware/rtl/TheTowerofDruaga_mist.sv new file mode 100644 index 00000000..89c7e83c --- /dev/null +++ b/Arcade_MiST/Mappy Hardware/rtl/TheTowerofDruaga_mist.sv @@ -0,0 +1,299 @@ +module TheTowerofDruaga_mist ( + output LED, + output [5:0] VGA_R, + output [5:0] VGA_G, + output [5:0] VGA_B, + output VGA_HS, + output VGA_VS, + output AUDIO_L, + output AUDIO_R, + input SPI_SCK, + output SPI_DO, + input SPI_DI, + input SPI_SS2, + input SPI_SS3, + input CONF_DATA0, + input CLOCK_27, + output [12:0] SDRAM_A, + inout [15:0] SDRAM_DQ, + output SDRAM_DQML, + output SDRAM_DQMH, + output SDRAM_nWE, + output SDRAM_nCAS, + output SDRAM_nRAS, + output SDRAM_nCS, + output [1:0] SDRAM_BA, + output SDRAM_CLK, + output SDRAM_CKE + +); + +// Uncomment one of these to load the default ROM: + +`define CORE_NAME "DRUAGA" +//`define CORE_NAME "MAPPY" +//`define CORE_NAME "MOTOS" +//`define CORE_NAME "DIGDUG2" + +`include "rtl\build_id.v" + +localparam CONF_STR = { + `CORE_NAME,";ROM;", + "O2,Rotate Controls,Off,On;", + "O34,Scanlines,Off,25%,50%,75%;", + "O5,Blend,Off,On;", + "T0,Reset;", + "V,v1.00.",`BUILD_DATE +}; + +assign LED = ~ioctl_downl; +assign AUDIO_R = AUDIO_L; +assign SDRAM_CLK = clock_48; +assign SDRAM_CKE = 1; + +wire clock_48, clock_6, pll_locked; +pll pll( + .inclk0(CLOCK_27), + .c0(clock_48),//49.147727 + .c1(clock_6), + .locked(pll_locked) + ); + +wire [31:0] status; +wire [1:0] buttons; +wire [1:0] switches; +wire [7:0] joystick_0; +wire [7:0] joystick_1; +wire scandoublerD; +wire ypbpr; +wire [7:0] audio; +wire hs, vs; +wire hb, vb; +wire blankn = ~(hb | vb); +wire [2:0] r, g; +wire [1:0] b; +wire [14:0] rom_addr; +wire [15:0] rom_do; +wire [12:0] snd_addr; +wire [15:0] snd_do; +wire ioctl_downl; +wire [7:0] ioctl_index; +wire ioctl_wr; +wire [24:0] ioctl_addr; +wire [7:0] ioctl_dout; +wire key_strobe; +wire key_pressed; +wire [7:0] key_code; + +/* +ROM map +00000-07FFF cpu0 32k 3.1d+1.1b (+2.1c in Mappy) +08000-0BFFF spchip0 16k 6.3m +0C000-0FFFF spchip1 16k 7.3m +10000-11FFF cpu1 8k 4.1k +12000-12FFF bgchip 4k 5.3b +13000-133FF spclut 1k 7.5k +13400-134FF bgclut 256b 6.4c +13500-135FF wave 256b 3.3m +13600-1361F palet 32b 5.5b +*/ + +data_io data_io( + .clk_sys ( clock_48 ), + .SPI_SCK ( SPI_SCK ), + .SPI_SS2 ( SPI_SS2 ), + .SPI_DI ( SPI_DI ), + .ioctl_download( ioctl_downl ), + .ioctl_index ( ioctl_index ), + .ioctl_wr ( ioctl_wr ), + .ioctl_addr ( ioctl_addr ), + .ioctl_dout ( ioctl_dout ) +); + +reg port1_req, port2_req; +sdram sdram( + .*, + .init_n ( pll_locked ), + .clk ( clock_48 ), + + // port1 used for main CPU + .port1_req ( port1_req ), + .port1_ack ( ), + .port1_a ( ioctl_addr[23:1] ), + .port1_ds ( {ioctl_addr[0], ~ioctl_addr[0]} ), + .port1_we ( ioctl_downl ), + .port1_d ( {ioctl_dout, ioctl_dout} ), + .port1_q ( ), + + .cpu1_addr ( ioctl_downl ? 15'h7fff : {1'b0, rom_addr[14:1]} ), + .cpu1_q ( rom_do ), + + // port2 for sound CPU + .port2_req ( port2_req ), + .port2_ack ( ), + .port2_a ( ioctl_addr[23:1] - 16'h8000 ), + .port2_ds ( {ioctl_addr[0], ~ioctl_addr[0]} ), + .port2_we ( ioctl_downl ), + .port2_d ( {ioctl_dout, ioctl_dout} ), + .port2_q ( ), + + .snd_addr ( ioctl_downl ? 15'h7fff : {3'b000, snd_addr[12:1]} ), + .snd_q ( snd_do ) +); + +always @(posedge clock_48) begin + reg ioctl_wr_last = 0; + + ioctl_wr_last <= ioctl_wr; + if (ioctl_downl) begin + if (~ioctl_wr_last && ioctl_wr) begin + port1_req <= ~port1_req; + port2_req <= ~port2_req; + end + end +end + +reg reset = 1; +reg rom_loaded = 0; +always @(posedge clock_48) begin + reg ioctl_downlD; + ioctl_downlD <= ioctl_downl; + + if (ioctl_downlD & ~ioctl_downl) rom_loaded <= 1; + reset <= status[0] | buttons[1] | ioctl_downl | ~rom_loaded; +end + +wire [7:0] DSW0 = 0;//{2'h0,status[7:6],4'h0}; +wire [7:0] DSW1 = 0; +wire [7:0] DSW2 = 0;//{4'h0,status[8],3'h0}; + +wire [5:0] INP0 = { m_bomb, m_fire, m_left, m_down, m_right, m_up}; +wire [5:0] INP1 = { m_bomb, m_fire, m_left, m_down, m_right, m_up}; +wire [2:0] INP2 = { btn_coin, btn_two_players, btn_one_player }; + +wire PCLK, PCLK_EN; +wire [8:0] HPOS,VPOS; + +fpga_druaga fpga_druaga( + .MCLK(clock_48), + .CLKCPUx2(clock_6), + .RESET(reset), + .SOUT(audio), + .rom_addr(rom_addr), + .rom_data(rom_addr[0] ? rom_do[15:8] : rom_do[7:0]), + .snd_addr(snd_addr), + .snd_data(snd_addr[0] ? snd_do[15:8] : snd_do[7:0]), + .PH(HPOS), + .PV(VPOS), + .PCLK(PCLK), + .PCLK_EN(PCLK_EN), + .POUT({b,g,r}), + .INP0(INP0), + .INP1(INP1), + .INP2(INP2), + .DSW0(DSW0), + .DSW1(DSW1), + .DSW2(DSW2), + + .ROMAD(ioctl_addr[16:0]), + .ROMDT(ioctl_dout), + .ROMEN(ioctl_wr) + ); + +hvgen hvgen( + .MCLK(clock_48), + .HPOS(HPOS), + .VPOS(VPOS), + .PCLK(PCLK), + .PCLK_EN(PCLK_EN), + .HBLK(hb), + .VBLK(vb), + .HSYN(hs), + .VSYN(vs) +); + +mist_video #(.COLOR_DEPTH(3), .SD_HCNT_WIDTH(10)) mist_video( + .clk_sys ( clock_48 ), + .SPI_SCK ( SPI_SCK ), + .SPI_SS3 ( SPI_SS3 ), + .SPI_DI ( SPI_DI ), + .R ( blankn ? r : 0 ), + .G ( blankn ? g : 0 ), + .B ( blankn ? {b,b[1]} : 0 ), + .HSync ( hs ), + .VSync ( vs ), + .VGA_R ( VGA_R ), + .VGA_G ( VGA_G ), + .VGA_B ( VGA_B ), + .VGA_VS ( VGA_VS ), + .VGA_HS ( VGA_HS ), + .rotate ( {1'b1,status[2]} ), + .scandoubler_disable( scandoublerD ), + .scanlines ( status[4:3] ), + .blend ( status[5] ), + .ypbpr ( ypbpr ) + ); + +user_io #(.STRLEN(($size(CONF_STR)>>3)))user_io( + .clk_sys (clock_48 ), + .conf_str (CONF_STR ), + .SPI_CLK (SPI_SCK ), + .SPI_SS_IO (CONF_DATA0 ), + .SPI_MISO (SPI_DO ), + .SPI_MOSI (SPI_DI ), + .buttons (buttons ), + .switches (switches ), + .scandoubler_disable (scandoublerD ), + .ypbpr (ypbpr ), + .key_strobe (key_strobe ), + .key_pressed (key_pressed ), + .key_code (key_code ), + .joystick_0 (joystick_0 ), + .joystick_1 (joystick_1 ), + .status (status ) + ); + +dac #(.C_bits(16))dac( + .clk_i(clock_48), + .res_n_i(1), + .dac_i({audio,audio}), + .dac_o(AUDIO_L) + ); + +// Rotated Normal +wire m_up = ~status[2] ? btn_left | joystick_0[1] | joystick_1[1] : btn_up | joystick_0[3] | joystick_1[3]; +wire m_down = ~status[2] ? btn_right | joystick_0[0] | joystick_1[0] : btn_down | joystick_0[2] | joystick_1[2]; +wire m_left = ~status[2] ? btn_down | joystick_0[2] | joystick_1[2] : btn_left | joystick_0[1] | joystick_1[1]; +wire m_right = ~status[2] ? btn_up | joystick_0[3] | joystick_1[3] : btn_right | joystick_0[0] | joystick_1[0]; +wire m_fire = btn_fire1 | joystick_0[4] | joystick_1[4]; +wire m_bomb = btn_fire2 | joystick_0[5] | joystick_1[5]; + +reg btn_one_player = 0; +reg btn_two_players = 0; +reg btn_left = 0; +reg btn_right = 0; +reg btn_down = 0; +reg btn_up = 0; +reg btn_fire1 = 0; +reg btn_fire2 = 0; +//reg btn_fire3 = 0; +reg btn_coin = 0; + +always @(posedge clock_48) begin + if(key_strobe) begin + case(key_code) + 'h75: btn_up <= key_pressed; // up + 'h72: btn_down <= key_pressed; // down + 'h6B: btn_left <= key_pressed; // left + 'h74: btn_right <= key_pressed; // right + 'h76: btn_coin <= key_pressed; // ESC + 'h05: btn_one_player <= key_pressed; // F1 + 'h06: btn_two_players <= key_pressed; // F2 +// 'h14: btn_fire3 <= key_pressed; // ctrl + 'h11: btn_fire2 <= key_pressed; // alt + 'h29: btn_fire1 <= key_pressed; // Space + endcase + end +end + +endmodule diff --git a/Arcade_MiST/Mappy Hardware/rtl/build_id.tcl b/Arcade_MiST/Mappy Hardware/rtl/build_id.tcl new file mode 100644 index 00000000..938515d8 --- /dev/null +++ b/Arcade_MiST/Mappy Hardware/rtl/build_id.tcl @@ -0,0 +1,35 @@ +# ================================================================================ +# +# Build ID Verilog Module Script +# Jeff Wiencrot - 8/1/2011 +# +# Generates a Verilog module that contains a timestamp, +# from the current build. These values are available from the build_date, build_time, +# physical_address, and host_name output ports of the build_id module in the build_id.v +# Verilog source file. +# +# ================================================================================ + +proc generateBuildID_Verilog {} { + + # Get the timestamp (see: http://www.altera.com/support/examples/tcl/tcl-date-time-stamp.html) + set buildDate [ clock format [ clock seconds ] -format %y%m%d ] + set buildTime [ clock format [ clock seconds ] -format %H%M%S ] + + # Create a Verilog file for output + set outputFileName "rtl/build_id.v" + set outputFile [open $outputFileName "w"] + + # Output the Verilog source + puts $outputFile "`define BUILD_DATE \"$buildDate\"" + puts $outputFile "`define BUILD_TIME \"$buildTime\"" + close $outputFile + + # Send confirmation message to the Messages window + post_message "Generated build identification Verilog module: [pwd]/$outputFileName" + post_message "Date: $buildDate" + post_message "Time: $buildTime" +} + +# Comment out this line to prevent the process from automatically executing when the file is sourced: +generateBuildID_Verilog \ No newline at end of file diff --git a/Arcade_MiST/Mappy Hardware/rtl/dpram.vhd b/Arcade_MiST/Mappy Hardware/rtl/dpram.vhd new file mode 100644 index 00000000..284194c5 --- /dev/null +++ b/Arcade_MiST/Mappy Hardware/rtl/dpram.vhd @@ -0,0 +1,81 @@ +-- ----------------------------------------------------------------------- +-- +-- Syntiac's generic VHDL support files. +-- +-- ----------------------------------------------------------------------- +-- Copyright 2005-2008 by Peter Wendrich (pwsoft@syntiac.com) +-- http://www.syntiac.com/fpga64.html +-- +-- Modified April 2016 by Dar (darfpga@aol.fr) +-- http://darfpga.blogspot.fr +-- Remove address register when writing +-- +-- ----------------------------------------------------------------------- +-- +-- dpram.vhd +-- +-- ----------------------------------------------------------------------- +-- +-- generic ram. +-- +-- ----------------------------------------------------------------------- + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.numeric_std.ALL; + +-- ----------------------------------------------------------------------- + +entity dpram is + generic ( + dWidth : integer := 8; + aWidth : integer := 10 + ); + port ( + clk_a : in std_logic; + we_a : in std_logic := '0'; + addr_a : in std_logic_vector((aWidth-1) downto 0); + d_a : in std_logic_vector((dWidth-1) downto 0) := (others => '0'); + q_a : out std_logic_vector((dWidth-1) downto 0); + + clk_b : in std_logic; + we_b : in std_logic := '0'; + addr_b : in std_logic_vector((aWidth-1) downto 0); + d_b : in std_logic_vector((dWidth-1) downto 0) := (others => '0'); + q_b : out std_logic_vector((dWidth-1) downto 0) + ); +end entity; + +-- ----------------------------------------------------------------------- + +architecture rtl of dpram is + subtype addressRange is integer range 0 to ((2**aWidth)-1); + type ramDef is array(addressRange) of std_logic_vector((dWidth-1) downto 0); + signal ram: ramDef; + signal addr_a_reg: std_logic_vector((aWidth-1) downto 0); + signal addr_b_reg: std_logic_vector((aWidth-1) downto 0); +begin + +-- ----------------------------------------------------------------------- + process(clk_a) + begin + if rising_edge(clk_a) then + if we_a = '1' then + ram(to_integer(unsigned(addr_a))) <= d_a; + end if; + q_a <= ram(to_integer(unsigned(addr_a))); + end if; + end process; + + process(clk_b) + begin + if rising_edge(clk_b) then + if we_b = '1' then + ram(to_integer(unsigned(addr_b))) <= d_b; + end if; + q_b <= ram(to_integer(unsigned(addr_b))); + end if; + end process; + +end architecture; + diff --git a/Arcade_MiST/Mappy Hardware/rtl/druaga_sprite.v b/Arcade_MiST/Mappy Hardware/rtl/druaga_sprite.v new file mode 100644 index 00000000..d913eefa --- /dev/null +++ b/Arcade_MiST/Mappy Hardware/rtl/druaga_sprite.v @@ -0,0 +1,181 @@ +/*********************************** + FPGA Druaga ( Sprite Part ) + + Copyright (c) 2007 MiSTer-X +************************************/ +module DRUAGA_SPRITE +( + input VCLKx8, + input VCLK_EN, + + input [8:0] HPOS, + input [8:0] VPOS, + input oHB, + + output [6:0] SPRA_A, + input [23:0] SPRA_D, + + output [4:0] SPCOL, + + input [16:0] ROMAD, + input [7:0] ROMDT, + input ROMEN +); + +wire [9:0] CLT1_A; +wire [3:0] CLT1_D; + +dpram #(4,10) clut1(.clk_a(VCLKx8), .addr_a(CLT1_A), .q_a(CLT1_D), + .clk_b(VCLKx8), .addr_b(ROMAD[9:0]), .we_b(ROMEN & (ROMAD[16:10]=={1'b1,4'h3,2'b00})), .d_b(ROMDT[3:0])); + +wire [13:0] SPCH_A; +wire [15:0] SPCH_D; + +dpram #(8,14) spch0(.clk_a(VCLKx8), .addr_a(SPCH_A), .q_a(SPCH_D[15:8]), + .clk_b(VCLKx8), .addr_b(ROMAD[13:0]), .we_b(ROMEN & (ROMAD[16:14]==3'b010)), .d_b(ROMDT)); + +dpram #(8,14) spch1(.clk_a(VCLKx8), .addr_a(SPCH_A), .q_a(SPCH_D[7:0]), + .clk_b(VCLKx8), .addr_b(ROMAD[13:0]), .we_b(ROMEN & (ROMAD[16:14]==3'b011)), .d_b(ROMDT)); + +reg lbufr = 1'b0; // 0/1 + +reg [5:0] loop = 6'h0; // 0~32 +reg [4:0] lpcn = 5'h0; // 0~31 +reg [4:0] xf, yf; // 0~31 +reg [8:0] sx; // 0~511 +reg [4:0] sy; // 0~31 +reg [5:0] pn; // 0x00~0x3F +reg [8:0] vposl; // 0~511 + +reg [6:0] nProc = 7'h0; // 0~64 + + +// sprite registers access +reg bLoad = 1'b0; // 0/1 +wire [7:0] spriteram = SPRA_D[7:0]; +wire [7:0] spriteram_2 = SPRA_D[15:8]; +wire [7:0] spriteram_3 = SPRA_D[23:16]; +assign SPRA_A = {nProc[5:0],bLoad}; + +// laster hit check +wire [8:0] y = spriteram_2 + 8'h10 + vposl; +wire [8:0] m = { 1'b1, ( 8'hF0 ^ { 3'b000, spriteram_3[3], 4'b0000 } )}; +wire bHit = ( ( y & m ) == { 1'b0, m[7:0] } ); + +reg _sizx; +wire sizx = spriteram_3[2]; +wire sizy = spriteram_3[3]; +wire [4:0] mskx = { sizx, 4'b1111 }; +wire [4:0] msky = { sizy, 4'b1111 }; +reg [4:0] _msky = 5'b01111; + +reg bKick = 1'b0; + +reg [7:0] cno; +wire [4:0] ox = { lpcn ^ xf }; +assign SPCH_A = { cno[7:2], (cno[1]|sy[4]), (cno[0]|ox[4]), sy[3], ox[3:2], sy[2:0] }; + +wire [15:0] SPCO = SPCH_D; +assign CLT1_A = (ox[1:0]==2'b00) ? { pn, SPCO[15], SPCO[11], SPCO[7], SPCO[3] } : + (ox[1:0]==2'b01) ? { pn, SPCO[14], SPCO[10], SPCO[6], SPCO[2] } : + (ox[1:0]==2'b10) ? { pn, SPCO[13], SPCO[ 9], SPCO[5], SPCO[1] } : + { pn, SPCO[12], SPCO[ 8], SPCO[4], SPCO[0] } ; + +wire [3:0] SPCL; +assign SPCOL = {1'b0,SPCL}; +LINEBUF_DOUBLE linebuf( VCLKx8, ~oHB & VCLK_EN, lbufr, ~VCLKx8 & VCLK_EN, (loop!=0), sx, CLT1_D, HPOS, SPCL ); + +always @( posedge VCLKx8 ) begin + if (VCLK_EN) begin + if (~oHB) begin // Horizontal display time + bKick <= 1'b1; + if (loop!=0) begin // rend sprite scanline + sx <= sx+1'd1; + lpcn <= lpcn+1'd1; + loop <= loop-1'd1; + end + else begin // rend sprite scanline init. + if (~nProc[6]) begin + if (~bLoad) begin + if (bHit) begin + cno <= spriteram & { 6'b111111, ~sizy, ~sizx }; + xf <= spriteram_3[0] ? mskx : 5'h0; + yf <= spriteram_3[1] ? msky : 5'h0; + sy <= ( 9'h10 + vposl + { 1'b0, spriteram_2 } ); + _msky <= msky; + _sizx <= sizx; + bLoad <= 1'b1; + end + else begin + nProc <= nProc+1; + bLoad <= 1'b0; + end + end + else begin + pn <= spriteram[5:0]; + sx <= { spriteram_3[0], spriteram_2[7:0] } - 9'h38; + sy <= ( sy & _msky ) ^ yf; + loop <= spriteram_3[1] ? 6'h0 : { _sizx, ~_sizx, 4'h0 }; + lpcn <= 6'h0; + nProc <= nProc+1; + bLoad <= 1'b0; + end + end + end + end + else begin // Horizontal blanking time + if (bKick) begin + lbufr <= ~VPOS[0]; + vposl <= VPOS+1; + nProc <= 0; + bKick <= 1'b0; + end + end + end +end + +endmodule + +//---------------------------------------- +// Line Buffer ( for Sprite ) +//---------------------------------------- +module LINEBUF_DOUBLE( CLK, EN, SIDE1, CLK2, WEN, ADRSW, IN, ADRSR, OUT ); + +input CLK; +input EN; +input SIDE1; +input CLK2; +input WEN; +input [8:0] ADRSW; +input [3:0] IN; +input [8:0] ADRSR; +output [3:0] OUT; + +wire [3:0] OUT0, OUT1; + +wire SIDE0 = ~SIDE1; +wire OPAQUE = ~( IN[0] & IN[1] & IN[2] & IN[3] ); + +assign OUT = SIDE1 ? OUT1 : OUT0; + +LBUF512 buf0( CLK, SIDE0 ? EN : ( EN & WEN & OPAQUE ), SIDE0 ? ADRSR : ADRSW, SIDE0 ? 4'b1111 : IN, CLK2, EN & SIDE0, ADRSR, OUT0 ); +LBUF512 buf1( CLK, SIDE1 ? EN : ( EN & WEN & OPAQUE ), SIDE1 ? ADRSR : ADRSW, SIDE1 ? 4'b1111 : IN, CLK2, EN & SIDE1, ADRSR, OUT1 ); + +endmodule + +module LBUF512 +( + input CLKW, + input WEN, + input [8:0] ADRSW, + input [3:0] IN, + input CLKR, + input REN, + input [8:0] ADRSR, + output [3:0] OUT +); + +dpram #(4,9) lbuf(.clk_a(CLKW), .we_a(WEN), .addr_a(ADRSW), .d_a(IN), + .clk_b(CLKR), .addr_b(ADRSR), .q_b(OUT)); + +endmodule diff --git a/Arcade_MiST/Mappy Hardware/rtl/druaga_video.v b/Arcade_MiST/Mappy Hardware/rtl/druaga_video.v new file mode 100644 index 00000000..a9a52b84 --- /dev/null +++ b/Arcade_MiST/Mappy Hardware/rtl/druaga_video.v @@ -0,0 +1,127 @@ +/*********************************** + FPGA Druaga ( Video Part ) + + Copyright (c) 2007 MiSTer-X +************************************/ +module DRUAGA_VIDEO +( + input VCLKx8, + input VCLK, + input VCLK_EN, + + input [8:0] PH, + input [8:0] PV, + output PCLK, + output PCLK_EN, + output [7:0] POUT, + output VB, + + output [10:0] VRAM_A, + input [15:0] VRAM_D, + + output [6:0] SPRA_A, + input [23:0] SPRA_D, + + input [8:0] SCROLL, + + input [16:0] ROMAD, + input [7:0] ROMDT, + input ROMEN +); + +wire [8:0] HPOS = PH-8'd16; +wire [8:0] VPOS = PV; + +wire oHB = (PH>=290) & (PH<492); + +assign VB = (PV==224); + + +reg [4:0] PALT_A; +wire [7:0] PALT_D; + +wire [7:0] CLT0_A; +wire [3:0] CLT0_D; + +wire [11:0] BGCH_A; +wire [7:0] BGCH_D; + + +// +// BG scroll registers +// +reg [8:0] BGVSCR; +wire [8:0] BGVPOS = BGVSCR + VPOS; +always @(posedge VCLKx8) if (PH == 290) BGVSCR <= SCROLL; + + +//---------------------------------------- +// BG scanline generator +//---------------------------------------- +reg [7:0] BGPN; +reg BGH; + +wire [5:0] COL = HPOS[8:3]; +wire [5:0] ROW = VPOS[8:3]; +wire [5:0] ROW2 = ROW + 6'h02; + +wire [7:0] CHRC = VRAM_D[7:0]; +wire [5:0] BGPL = VRAM_D[13:8]; + +wire [8:0] HP = HPOS; +wire [8:0] VP = COL[5] ? VPOS : BGVPOS; +wire [11:0] CHRA = { CHRC, ~HP[2], VP[2:0] }; +wire [7:0] CHRO = BGCH_D; + +always @ ( posedge VCLKx8 ) begin + if (VCLK_EN) + case ( HP[1:0] ) + 2'b00: begin BGPN <= { BGPL, CHRO[7], CHRO[3] }; BGH <= VRAM_D[14]; end + 2'b01: begin BGPN <= { BGPL, CHRO[6], CHRO[2] }; BGH <= VRAM_D[14]; end + 2'b10: begin BGPN <= { BGPL, CHRO[5], CHRO[1] }; BGH <= VRAM_D[14]; end + 2'b11: begin BGPN <= { BGPL, CHRO[4], CHRO[0] }; BGH <= VRAM_D[14]; end + endcase +end + +wire [10:0] VRAMADRS = COL[5] ? { 4'b1111, COL[1:0], ROW[4], ROW2[3:0] } : { VP[8:3], HP[7:3] }; + +assign CLT0_A = BGPN; +assign BGCH_A = CHRA; +assign VRAM_A = VRAMADRS; + +wire BGHI = BGH & (CLT0_D!=4'd15); +wire [4:0] BGCOL = { 1'b1, CLT0_D }; + + +//---------------------------------------- +// Sprite scanline generator +//---------------------------------------- +wire [4:0] SPCOL; + +DRUAGA_SPRITE spr +( + VCLKx8, VCLK_EN, + HPOS, VPOS, oHB, + SPRA_A, SPRA_D, + SPCOL, + ROMAD,ROMDT,ROMEN +); + +//---------------------------------------- +// Color mixer & Final output +//---------------------------------------- +always @(posedge VCLKx8) if (VCLK_EN) PALT_A <= BGHI ? BGCOL : ((SPCOL[3:0]==4'd15) ? BGCOL : SPCOL ); +assign POUT = oHB ? 8'd0 : PALT_D; +assign PCLK = VCLK; +assign PCLK_EN = VCLK_EN; + +//---------------------------------------- +// ROMs +//---------------------------------------- +dpram #(8,12) bgchr(.clk_a(VCLKx8), .addr_a(BGCH_A), .q_a(BGCH_D), + .clk_b(VCLKx8), .addr_b(ROMAD[11:0]), .we_b(ROMEN & (ROMAD[16:12]=={1'b1,4'h2})), .d_b(ROMDT)); +dpram #(4,8) clut0(.clk_a(VCLKx8), .addr_a(CLT0_A^8'h03), .q_a(CLT0_D), + .clk_b(VCLKx8), .addr_b(ROMAD[7:0]), .we_b(ROMEN & (ROMAD[16:8]=={1'b1,8'h34})), .d_b(ROMDT[3:0])); +dpram #(8,5) pelet(.clk_a(VCLKx8), .addr_a(PALT_A), .q_a(PALT_D), + .clk_b(VCLKx8), .addr_b(ROMAD[4:0]), .we_b(ROMEN & (ROMAD[16:5]=={1'b1,8'h36,3'b000})), .d_b(ROMDT)); +endmodule diff --git a/Arcade_MiST/Mappy Hardware/rtl/fpga_druaga.v b/Arcade_MiST/Mappy Hardware/rtl/fpga_druaga.v new file mode 100644 index 00000000..6de29060 --- /dev/null +++ b/Arcade_MiST/Mappy Hardware/rtl/fpga_druaga.v @@ -0,0 +1,442 @@ +/*********************************** + FPGA Druaga ( Top module ) + + Copyright (c) 2007 MiSTer-X + + Conversion to clock-enable: + (c) 2019 Slingshot +************************************/ +module fpga_druaga +( + input RESET, // RESET + input MCLK, // MasterClock: 49.125MHz + input CLKCPUx2, // CPU clock x 2: MCLK/8 + + input [8:0] PH, // Screen H + input [8:0] PV, // Screen V + output PCLK, // Pixel Clock + output PCLK_EN, + output [7:0] POUT, // Pixel Color + + output [7:0] SOUT, // Sound Out + output [14:0] rom_addr, + input [7:0] rom_data, + output [12:0] snd_addr, + input [7:0] snd_data, + input [5:0] INP0, // 1P {B2,B1,L,D,R,U} + input [5:0] INP1, // 2P {B2,B1,L,D,R,U} + input [2:0] INP2, // {Coin,Start2P,Start1P} + + input [7:0] DSW0, // DIPSWs (Active Logic) + input [7:0] DSW1, + input [7:0] DSW2, + + input [16:0] ROMAD, + input [7:0] ROMDT, + input ROMEN +); + +// Clock Generator +reg [4:0] CLKS; + +wire VCLK_x8 = MCLK; +wire VCLK_x1 = CLKS[2]; + +wire VCLK_EN = CLKS[2:0] == 3'b011; +always @( posedge MCLK ) CLKS <= CLKS+1'd1; + +// Main-CPU Interface +wire MCPU_CLK = CLKCPUx2; +wire [15:0] MCPU_ADRS; +wire MCPU_VMA; +wire MCPU_RW; +wire MCPU_WE = ( ~MCPU_RW ); +//wire MCPU_RE = ( MCPU_RW ); +wire [7:0] MCPU_DO; +wire [7:0] MCPU_DI; + +// Sub-CPU Interface +wire SCPU_CLK = CLKCPUx2; +wire [15:0] SCPU_ADRS; +wire SCPU_VMA; +wire SCPU_RW; +wire SCPU_WE = ( ~SCPU_RW ); +//wire SCPU_RE = ( SCPU_RW ); +wire [7:0] SCPU_DO; +wire [7:0] SCPU_DI; + +// I/O Interface +wire MCPU_CS_IO, SCPU_WE_WSG; +wire [7:0] IO_O; +wire [10:0] vram_a; +wire [15:0] vram_d; +wire [6:0] spra_a; +wire [23:0] spra_d; +MEMS mems +( + MCLK, + CLKCPUx2, + rom_addr, rom_data, + snd_addr, snd_data, + MCPU_ADRS, MCPU_VMA, MCPU_WE, MCPU_DO, MCPU_DI, MCPU_CS_IO, IO_O, + SCPU_ADRS, SCPU_VMA, SCPU_WE, SCPU_DO, SCPU_DI, SCPU_WE_WSG, + vram_a,vram_d, + spra_a,spra_d, + ROMAD,ROMDT,ROMEN +); + +// Control Registers +wire oVB; +wire [7:0] SCROLL; +wire MCPU_IRQ, MCPU_IRQEN; +wire SCPU_IRQ, SCPU_IRQEN; +wire SCPU_RESET, IO_RESET; +wire PSG_ENABLE; +REGS regs +( + CLKCPUx2, RESET, oVB, + MCPU_ADRS, MCPU_VMA, MCPU_WE, + SCPU_ADRS, SCPU_VMA, SCPU_WE, + SCROLL, + MCPU_IRQ, MCPU_IRQEN, + SCPU_IRQ, SCPU_IRQEN, + SCPU_RESET, IO_RESET, + PSG_ENABLE +); + + +// I/O Controler +wire IsMOTOS; +IOCTRL ioctrl( + CLKCPUx2, oVB, IO_RESET, MCPU_CS_IO, MCPU_WE, MCPU_ADRS[5:0], + MCPU_DO, + IO_O, + {INP1,INP0},INP2, + {DSW2,DSW1,DSW0}, + IsMOTOS +); + + +// Video Core +wire [7:0] oPOUT; +DRUAGA_VIDEO video +( + .VCLKx8(VCLK_x8),.VCLK(VCLK_x1), + .VCLK_EN(VCLK_EN), + .PH(PH),.PV(PV), + .PCLK(PCLK),.PCLK_EN(PCLK_EN),.POUT(oPOUT),.VB(oVB), + .VRAM_A(vram_a), .VRAM_D(vram_d), + .SPRA_A(spra_a), .SPRA_D(spra_d), + .SCROLL({1'b0,SCROLL}), + .ROMAD(ROMAD),.ROMDT(ROMDT),.ROMEN(ROMEN) +); +assign POUT = (IsMOTOS & (PV==0)) ? 8'h0 : oPOUT; + + +// MainCPU +cpucore main_cpu +( + .clk(MCPU_CLK), + .rst(RESET), + .rw(MCPU_RW), + .vma(MCPU_VMA), + .address(MCPU_ADRS), + .data_in(MCPU_DI), + .data_out(MCPU_DO), + .halt(1'b0), + .hold(1'b0), + .irq(MCPU_IRQ), + .firq(1'b0), + .nmi(1'b0) +); + + +// SubCPU +cpucore sub_cpu +( + .clk(SCPU_CLK), + .rst(SCPU_RESET), + .rw(SCPU_RW), + .vma(SCPU_VMA), + .address(SCPU_ADRS), + .data_in(SCPU_DI), + .data_out(SCPU_DO), + .halt(1'b0), + .hold(1'b0), + .irq(SCPU_IRQ), + .firq(1'b0), + .nmi(1'b0) +); + + +// SOUND +wire WAVE_CLK; +wire [7:0] WAVE_AD; +wire [3:0] WAVE_DT; + +dpram #(4,8) wsgwv(.clk_a(MCLK), .addr_a(WAVE_AD), .q_a(WAVE_DT), + .clk_b(MCLK), .addr_b(ROMAD[7:0]), .we_b(ROMEN & (ROMAD[16:8]=={1'b1,8'h35})), .d_b(ROMDT[3:0])); + +WSG_8CH wsg( + .MCLK(MCLK), + .ADDR(SCPU_ADRS[5:0]), + .DATA(SCPU_DO), + .WE(SCPU_WE_WSG), + .SND_ENABLE(PSG_ENABLE), + .WAVE_CLK(WAVE_CLK), + .WAVE_AD(WAVE_AD), + .WAVE_DT(WAVE_DT), + .SOUT(SOUT) +); + +endmodule + +module MEMS +( + input MCLK, + input CPUCLKx2, + output [14:0] rom_addr, + input [7:0] rom_data, + output [12:0] snd_addr, + input [7:0] snd_data, + input [15:0] MCPU_ADRS, + input MCPU_VMA, + input MCPU_WE, + input [7:0] MCPU_DO, + output [7:0] MCPU_DI, + output IO_CS, + input [7:0] IO_O, + + input [15:0] SCPU_ADRS, + input SCPU_VMA, + input SCPU_WE, + input [7:0] SCPU_DO, + output [7:0] SCPU_DI, + output SCPU_WSG_WE, + + input [10:0] vram_a, + output [15:0] vram_d, + input [6:0] spra_a, + output [23:0] spra_d, + + input [16:0] ROMAD, + input [7:0] ROMDT, + input ROMEN +); + +wire [7:0] mrom_d, srom_d; +//DLROM #(15,8) mcpui( CPUCLKx2, MCPU_ADRS[14:0], mrom_d, ROMCL,ROMAD[14:0],ROMDT,ROMEN & (ROMAD[16:15]==2'b0_0)); +assign rom_addr = MCPU_ADRS[14:0]; +assign mrom_d = rom_data; +assign snd_addr = SCPU_ADRS[12:0]; +assign srom_d = snd_data; + +//dpram #(8,13) scpui(.clk_a(CPUCLKx2), .addr_a(SCPU_ADRS[12:0]), .q_a(srom_d), +// .clk_b(MCLK), .addr_b(ROMAD[12:0]), .we_b(ROMEN & (ROMAD[16:13]==4'b1_000)), .d_b(ROMDT)); + +wire mram_cs0 = ( MCPU_ADRS[15:11] == 5'b00000 ) & MCPU_VMA; // $0000-$07FF +wire mram_cs1 = ( MCPU_ADRS[15:11] == 5'b00001 ) & MCPU_VMA; // $0800-$0FFF +wire mram_cs2 = ( MCPU_ADRS[15:11] == 5'b00010 ) & MCPU_VMA; // $1000-$17FF +wire mram_cs3 = ( MCPU_ADRS[15:11] == 5'b00011 ) & MCPU_VMA; // $1800-$1FFF +wire mram_cs4 = ( MCPU_ADRS[15:11] == 5'b00100 ) & MCPU_VMA; // $2000-$27FF +wire mram_cs5 = ( MCPU_ADRS[15:10] == 6'b010000 ) & MCPU_VMA; // $4000-$43FF +assign IO_CS = ( MCPU_ADRS[15:11] == 5'b01001 ) & MCPU_VMA; // $4800-$4FFF +wire mrom_cs = ( MCPU_ADRS[15] ) & MCPU_VMA; // $8000-$FFFF + +wire mram_w0 = ( mram_cs0 & MCPU_WE ); +wire mram_w1 = ( mram_cs1 & MCPU_WE ); +wire mram_w2 = ( mram_cs2 & MCPU_WE ); +wire mram_w3 = ( mram_cs3 & MCPU_WE ); +wire mram_w4 = ( mram_cs4 & MCPU_WE ); +wire mram_w5 = ( mram_cs5 & MCPU_WE ); + +wire [7:0] mram_o0, mram_o1, mram_o2, mram_o3, mram_o4, mram_o5; + +assign MCPU_DI = mram_cs0 ? mram_o0 : + mram_cs1 ? mram_o1 : + mram_cs2 ? mram_o2 : + mram_cs3 ? mram_o3 : + mram_cs4 ? mram_o4 : + mram_cs5 ? mram_o5 : + mrom_cs ? mrom_d : + IO_CS ? IO_O : + 8'h0; + +wire [10:0] mram_ad = MCPU_ADRS[10:0]; + +dpram #(8,11) main_ram0( .clk_a(CPUCLKx2), .addr_a(mram_ad), .d_a(MCPU_DO), .q_a(mram_o0), .we_a(mram_w0), .clk_b(MCLK), .addr_b(vram_a), .q_b(vram_d[ 7:0])); +dpram #(8,11) main_ram1( .clk_a(CPUCLKx2), .addr_a(mram_ad), .d_a(MCPU_DO), .q_a(mram_o1), .we_a(mram_w1), .clk_b(MCLK), .addr_b(vram_a), .q_b(vram_d[15:8])); + +dpram #(8,11) main_ram2( .clk_a(CPUCLKx2), .addr_a(mram_ad), .d_a(MCPU_DO), .q_a(mram_o2), .we_a(mram_w2), .clk_b(MCLK), .addr_b({ 4'b1111, spra_a }), .q_b(spra_d[ 7: 0])); +dpram #(8,11) main_ram3( .clk_a(CPUCLKx2), .addr_a(mram_ad), .d_a(MCPU_DO), .q_a(mram_o3), .we_a(mram_w3), .clk_b(MCLK), .addr_b({ 4'b1111, spra_a }), .q_b(spra_d[15: 8])); +dpram #(8,11) main_ram4( .clk_a(CPUCLKx2), .addr_a(mram_ad), .d_a(MCPU_DO), .q_a(mram_o4), .we_a(mram_w4), .clk_b(MCLK), .addr_b({ 4'b1111, spra_a }), .q_b(spra_d[23:16])); + + // (SCPU ADRS) +wire SCPU_CS_SREG = ( ( SCPU_ADRS[15:13] == 3'b000 ) & ( SCPU_ADRS[9:6] == 4'b0000 ) ) & SCPU_VMA; +wire srom_cs = ( SCPU_ADRS[15:13] == 3'b111 ) & SCPU_VMA; // $E000-$FFFF +wire sram_cs0 = (~SCPU_CS_SREG) & (~srom_cs) & SCPU_VMA; // $0000-$03FF +wire [7:0] sram_o0; + +assign SCPU_DI = sram_cs0 ? sram_o0 : + srom_cs ? srom_d : + 8'h0; + +assign SCPU_WSG_WE = SCPU_CS_SREG & SCPU_WE; + +dpram #(8,11) share_ram( .clk_a(CPUCLKx2), .addr_a(mram_ad), .d_a(MCPU_DO), .q_a(mram_o5), .we_a(mram_w5), + .clk_b(CPUCLKx2), .addr_b(SCPU_ADRS[9:0]), .d_b(SCPU_DO), .q_b(sram_o0), .we_b(sram_cs0 & SCPU_WE) ); + + +endmodule + +module REGS +( + input MCPU_CLK, + input RESET, + input VBLANK, + + input [15:0] MCPU_ADRS, + input MCPU_VMA, + input MCPU_WE, + + input [15:0] SCPU_ADRS, + input SCPU_VMA, + input SCPU_WE, + + output reg [7:0] SCROLL, + output MCPU_IRQ, + output reg MCPU_IRQEN, + output SCPU_IRQ, + output reg SCPU_IRQEN, + output SCPU_RESET, + output IO_RESET, + output reg PSG_ENABLE +); + +// BG Scroll Register +wire MCPU_SCRWE = ( ( MCPU_ADRS[15:11] == 5'b00111 ) & MCPU_VMA & MCPU_WE ); +always @ ( negedge MCPU_CLK or posedge RESET ) begin + if ( RESET ) SCROLL <= 8'h0; + else if ( MCPU_SCRWE ) SCROLL <= MCPU_ADRS[10:3]; +end + +// MainCPU IRQ Generator +wire MCPU_IRQWE = ( ( MCPU_ADRS[15:1] == 15'b010100000000001 ) & MCPU_VMA & MCPU_WE ); +//wire MCPU_IRQWES = ( ( SCPU_ADRS[15:1] == 15'b001000000000001 ) & SCPU_VMA & SCPU_WE ); +assign MCPU_IRQ = MCPU_IRQEN & VBLANK; + +always @( negedge MCPU_CLK or posedge RESET ) begin + if ( RESET ) begin + MCPU_IRQEN <= 1'b0; + end + else begin + if ( MCPU_IRQWE ) MCPU_IRQEN <= MCPU_ADRS[0]; +// if ( MCPU_IRQWES ) MCPU_IRQEN <= SCPU_ADRS[0]; + end +end + + +// SubCPU IRQ Generator +wire SCPU_IRQWE = ( ( MCPU_ADRS[15:1] == 15'b010100000000000 ) & MCPU_VMA & MCPU_WE ); +wire SCPU_IRQWES = ( ( SCPU_ADRS[15:1] == 15'b001000000000000 ) & SCPU_VMA & SCPU_WE ); +assign SCPU_IRQ = SCPU_IRQEN & VBLANK; + +always @( negedge MCPU_CLK or posedge RESET ) begin + if ( RESET ) begin + SCPU_IRQEN <= 1'b0; + end + else begin + if ( SCPU_IRQWE ) SCPU_IRQEN <= MCPU_ADRS[0]; + if ( SCPU_IRQWES ) SCPU_IRQEN <= SCPU_ADRS[0]; + end +end + + +// SubCPU RESET Control +reg SCPU_RSTf = 1'b0; +wire SCPU_RSTWE = ( ( MCPU_ADRS[15:1] == 15'b010100000000101 ) & MCPU_VMA & MCPU_WE ); +wire SCPU_RSTWES = ( ( SCPU_ADRS[15:1] == 15'b001000000000101 ) & SCPU_VMA & SCPU_WE ); +assign SCPU_RESET = ~SCPU_RSTf; + +always @( negedge MCPU_CLK or posedge RESET ) begin + if ( RESET ) begin + SCPU_RSTf <= 1'b0; + end + else begin + if ( SCPU_RSTWE ) SCPU_RSTf <= MCPU_ADRS[0]; + if ( SCPU_RSTWES ) SCPU_RSTf <= SCPU_ADRS[0]; + end +end + + +// I/O CHIP RESET Control +reg IOCHIP_RSTf = 1'b0; +wire IOCHIP_RSTWE = ( ( MCPU_ADRS[15:1] == 15'b010100000000100 ) & MCPU_VMA & MCPU_WE ); +assign IO_RESET = ~IOCHIP_RSTf; + +always @( negedge MCPU_CLK or posedge RESET ) begin + if ( RESET ) begin + IOCHIP_RSTf <= 1'b0; + end + else begin + if ( IOCHIP_RSTWE ) IOCHIP_RSTf <= MCPU_ADRS[0]; + end +end + + +// Sound Enable Control +wire PSG_ENAWE = ( ( MCPU_ADRS[15:1] == 15'b010100000000011 ) & MCPU_VMA & MCPU_WE ); +wire PSG_ENAWES = ( ( SCPU_ADRS[15:1] == 15'b001000000000011 ) & SCPU_VMA & SCPU_WE ); + +always @( negedge MCPU_CLK or posedge RESET ) begin + if ( RESET ) begin + PSG_ENABLE <= 1'b0; + end + else begin + if ( PSG_ENAWE ) PSG_ENABLE <= MCPU_ADRS[0]; + if ( PSG_ENAWES ) PSG_ENABLE <= SCPU_ADRS[0]; + end +end + +endmodule + + +module cpucore +( + input clk, + input rst, + output rw, + output vma, + output [15:0] address, + input [7:0] data_in, + output [7:0] data_out, + input halt, + input hold, + input irq, + input firq, + input nmi +); + + +mc6809 cpu +( + .D(data_in), + .DOut(data_out), + .ADDR(address), + .RnW(rw), +// .E(vma), + .nIRQ(~irq), + .nFIRQ(~firq), + .nNMI(~nmi), + .EXTAL(clk), + .nHALT(~halt), + .nRESET(~rst), + + .XTAL(1'b0), + .MRDY(1'b1), + .nDMABREQ(1'b1) +); +assign vma = 1; + +endmodule + diff --git a/Arcade_MiST/Mappy Hardware/rtl/hvgen.v b/Arcade_MiST/Mappy Hardware/rtl/hvgen.v new file mode 100644 index 00000000..e3dc0905 --- /dev/null +++ b/Arcade_MiST/Mappy Hardware/rtl/hvgen.v @@ -0,0 +1,40 @@ +module hvgen +( + input MCLK, + output [8:0] HPOS, + output [8:0] VPOS, + input PCLK, + input PCLK_EN, + output reg HBLK = 1, + output reg VBLK = 1, + output reg HSYN = 1, + output reg VSYN = 1 +); + +reg [8:0] hcnt = 0; +reg [8:0] vcnt = 0; + +assign HPOS = hcnt; +assign VPOS = vcnt; + +always @(posedge MCLK) begin + if (PCLK_EN) + case (hcnt) + 1: begin HBLK <= 0; hcnt <= hcnt+1'd1; end + 290: begin HBLK <= 1; hcnt <= hcnt+1'd1; end + 311: begin HSYN <= 0; hcnt <= hcnt+1'd1; end + 342: begin HSYN <= 1; hcnt <= 9'd470; end + 511: begin hcnt <= 0; + case (vcnt) + 223: begin VBLK <= 1; vcnt <= vcnt+1'd1; end + 226: begin VSYN <= 0; vcnt <= vcnt+1'd1; end + 233: begin VSYN <= 1; vcnt <= 9'd483; end + 511: begin VBLK <= 0; vcnt <= 0; end + default: vcnt <= vcnt+1'd1; + endcase + end + default: hcnt <= hcnt+1'd1; + endcase +end + +endmodule \ No newline at end of file diff --git a/Arcade_MiST/Mappy Hardware/rtl/ioctrl.v b/Arcade_MiST/Mappy Hardware/rtl/ioctrl.v new file mode 100644 index 00000000..ce3d9600 --- /dev/null +++ b/Arcade_MiST/Mappy Hardware/rtl/ioctrl.v @@ -0,0 +1,142 @@ +/**************************************************** + FPGA Druaga ( Custom I/O chip emulation part ) + + Copyright (c) 2007 MiSTer-X +*****************************************************/ +module IOCTRL( CLK, UPDATE, RESET, ENABLE, WR, ADRS, IN, OUT, STKTRG12, CSTART12, DIPSW, IsMOTOS ); + input CLK; + input UPDATE; + input RESET; + input ENABLE; + input WR; + input [5:0] ADRS; + input [7:0] IN; + output [7:0] OUT; + + input [11:0] STKTRG12; // { STKTRG2[5:0], STKSTG1[5:0] } + input [2:0] CSTART12; // { COIN, START2P, START1P } + input [23:0] DIPSW; // { DSW5[3:0] DSW4[3:0] DSW3[3:0], DSW2[3:0], DSW1[3:0], DSW0[3:0] } + + output IsMOTOS; + + +reg [3:0] mema[0:15]; +reg [3:0] memb[0:15]; +reg [3:0] memc[0:31]; +reg [3:0] outr; + +reg [7:0] credits; +reg [7:0] credit_add, credit_sub; + +reg [9:0] pSTKTRG12; +reg [2:0] pCSTART12; + +reg bUpdate; +reg bIOMode = 0; + +assign OUT = { 4'b1111, outr }; +assign IsMOTOS = bIOMode; + +wire [11:0] iSTKTRG12 = ( STKTRG12 ^ pSTKTRG12 ) & STKTRG12; +wire [2:0] iCSTART12 = ( CSTART12 ^ pCSTART12 ) & CSTART12; + +wire [3:0] CREDIT_ONES, CREDIT_TENS; +BCDCONV creditsBCD( credits, CREDIT_ONES, CREDIT_TENS ); + +always @ ( posedge CLK ) begin + + if ( ENABLE ) begin + if ( ADRS[5] ) begin + if ( WR ) memc[ADRS[4:0]] <= IN; + outr <= memc[ADRS[4:0]]; + end else if ( ADRS[4] ) begin + if ( WR ) memb[ADRS[3:0]] <= IN; + outr <= memb[ADRS[3:0]]; + end else begin + if ( WR ) mema[ADRS[3:0]] <= IN; + outr <= mema[ADRS[3:0]]; + end + end + + if ( RESET ) begin + pCSTART12 <= 0; + pSTKTRG12 <= 0; + bUpdate <= 0; + bIOMode = 0; + credits = 0; + end + else begin + if ( UPDATE & (~bUpdate) ) begin + if ( mema[4'h8] == 4'h8 ) bIOMode = 1'b1; // Is running "Motos" ? + + if ( bIOMode ) begin + `include "ioctrl_1.v" + end + else begin + `include "ioctrl_0.v" + end + + pCSTART12 <= CSTART12; + pSTKTRG12 <= STKTRG12; + end + bUpdate <= UPDATE; + end + +end + +endmodule + + + +module add3(in,out); + +input [3:0] in; +output [3:0] out; +reg [3:0] out; + +always @ (in) + case (in) + 4'b0000: out <= 4'b0000; + 4'b0001: out <= 4'b0001; + 4'b0010: out <= 4'b0010; + 4'b0011: out <= 4'b0011; + 4'b0100: out <= 4'b0100; + 4'b0101: out <= 4'b1000; + 4'b0110: out <= 4'b1001; + 4'b0111: out <= 4'b1010; + 4'b1000: out <= 4'b1011; + 4'b1001: out <= 4'b1100; + default: out <= 4'b0000; + endcase + +endmodule + + +module BCDCONV(A,ONES,TENS); + +input [7:0] A; +output [3:0] ONES, TENS; +wire [3:0] c1,c2,c3,c4,c5,c6,c7; +wire [3:0] d1,d2,d3,d4,d5,d6,d7; + +assign d1 = {1'b0,A[7:5]}; +assign d2 = {c1[2:0],A[4]}; +assign d3 = {c2[2:0],A[3]}; +assign d4 = {c3[2:0],A[2]}; +assign d5 = {c4[2:0],A[1]}; +assign d6 = {1'b0,c1[3],c2[3],c3[3]}; +assign d7 = {c6[2:0],c4[3]}; + +add3 m1(d1,c1); +add3 m2(d2,c2); +add3 m3(d3,c3); +add3 m4(d4,c4); +add3 m5(d5,c5); +add3 m6(d6,c6); +add3 m7(d7,c7); + +assign ONES = {c5[2:0],A[0]}; +assign TENS = {c7[2:0],c5[3]}; + +endmodule + diff --git a/Arcade_MiST/Mappy Hardware/rtl/ioctrl_0.v b/Arcade_MiST/Mappy Hardware/rtl/ioctrl_0.v new file mode 100644 index 00000000..9bed2f27 --- /dev/null +++ b/Arcade_MiST/Mappy Hardware/rtl/ioctrl_0.v @@ -0,0 +1,119 @@ +//------------------------------------------ +// I/O Chip for "Mappy/Druaga/DigDug2" +// +// Copyright (c) 2007 MiSTer-X +//------------------------------------------ +// TODO: DSW2 = DIPSW[23:16] + + case ( mema[4'h8] ) + + 4'h1: begin + mema[4'h0] <= 0; + mema[4'h1] <= 0; + mema[4'h2] <= 0; + mema[4'h3] <= 0; + end + + 4'h3: begin + credit_add = 0; + credit_sub = 0; + + if ( iCSTART12[2] & ( credits < 99 ) ) begin + credit_add = 8'h01; + credits = credits + 1'd1; + end + + if ( mema[4'h9] == 0 ) begin + if ( ( credits >= 2 ) & iCSTART12[1] ) begin + credit_sub = 8'h02; + credits = credits - 2'd1; + end else if ( ( credits >= 1 ) & iCSTART12[0] ) begin + credit_sub = 8'h01; + credits = credits - 1'd1; + end + end + + mema[4'h0] <= credit_add; + mema[4'h1] <= credit_sub; + mema[4'h2] <= CREDIT_TENS; + mema[4'h3] <= CREDIT_ONES; + mema[4'h4] <= STKTRG12[3:0]; + mema[4'h5] <= { CSTART12[0], iCSTART12[0], STKTRG12[4], iSTKTRG12[4] }; + mema[4'h6] <= STKTRG12[9:6]; + mema[4'h7] <= { CSTART12[1], iCSTART12[1], STKTRG12[10], iSTKTRG12[10] }; + end + + 4'h4: begin + mema[4'h0] <= 0; + mema[4'h1] <= 0; + mema[4'h2] <= 0; + mema[4'h3] <= 0; + mema[4'h4] <= 0; + mema[4'h5] <= 0; + mema[4'h6] <= { CSTART12[1], CSTART12[0], 2'b00 }; + mema[4'h7] <= { CSTART12[1], CSTART12[0], 2'b00 }; + end + + 4'h5: begin + mema[4'h0] <= 4'h0; + mema[4'h1] <= 4'h8; + mema[4'h2] <= 4'h4; + mema[4'h3] <= 4'h6; + mema[4'h4] <= 4'hE; + mema[4'h5] <= 4'hD; + mema[4'h6] <= 4'h9; + mema[4'h7] <= 4'hD; + end + + default: begin end + + endcase + + + case ( memb[4'h8] ) + + 4'h1: begin + memb[4'h0] <= 0; + memb[4'h1] <= 0; + memb[4'h2] <= 0; + memb[4'h3] <= 0; + end + + 4'h3: begin + memb[4'h0] <= 0; + memb[4'h1] <= 0; + memb[4'h2] <= 0; + memb[4'h3] <= 0; + memb[4'h4] <= 0; + memb[4'h5] <= 0; + memb[4'h6] <= 0; + memb[4'h7] <= 0; + end + + 4'h4: begin + memb[4'h0] <= DIPSW[11:8]; + memb[4'h1] <= DIPSW[3:0]; + memb[4'h2] <= DIPSW[7:4]; + memb[4'h4] <= DIPSW[15:12]; + memb[4'h6] <= DIPSW[7:4]; + + memb[4'h3] <= 0; + memb[4'h5] <= { DIPSW[3:2], STKTRG12[ 5], iSTKTRG12[ 5] }; + memb[4'h7] <= { 2'b00, STKTRG12[11], iSTKTRG12[11] }; + end + + 4'h5: begin + memb[4'h0] <= 4'h0; + memb[4'h1] <= 4'h8; + memb[4'h2] <= 4'h4; + memb[4'h3] <= 4'h6; + memb[4'h4] <= 4'hE; + memb[4'h5] <= 4'hD; + memb[4'h6] <= 4'h9; + memb[4'h7] <= 4'hD; + end + + default: begin end + + endcase + diff --git a/Arcade_MiST/Mappy Hardware/rtl/ioctrl_1.v b/Arcade_MiST/Mappy Hardware/rtl/ioctrl_1.v new file mode 100644 index 00000000..cab08e36 --- /dev/null +++ b/Arcade_MiST/Mappy Hardware/rtl/ioctrl_1.v @@ -0,0 +1,48 @@ +//------------------------------------------ +// I/O Chip for "Motos" +// +// Copyright (c) 2007 MiSTer-X +//------------------------------------------ +// TODO: DSW2 = DIPSW[23:16] + + case ( mema[4'h8] ) + + 4'h1: begin + mema[4'h0] <= { 3'b00, CSTART12[2] }; + mema[4'h1] <= STKTRG12[3:0]; + mema[4'h2] <= STKTRG12[9:6]; + mema[4'h3] <= { CSTART12[1], CSTART12[0], STKTRG12[10], STKTRG12[4] }; + end + + 4'h8: begin + mema[4'h0] <= 4'h6; + mema[4'h1] <= 4'h9; + end + + default: begin end + + endcase + + + case ( memb[4'h8] ) + + 4'h8: begin + memb[4'h0] <= 4'h6; + memb[4'h1] <= 4'h9; + end + + 4'h9: begin + memb[4'h0] <= 0; + memb[4'h1] <= 0; + memb[4'h2] <= 0; + memb[4'h3] <= 0; + memb[4'h4] <= 0; + memb[4'h5] <= 0; + memb[4'h6] <= 0; + memb[4'h7] <= 0; + end + + default: begin end + + endcase + diff --git a/Arcade_MiST/Mappy Hardware/rtl/mc6809/cpucore.v b/Arcade_MiST/Mappy Hardware/rtl/mc6809/cpucore.v new file mode 100644 index 00000000..e17d80a7 --- /dev/null +++ b/Arcade_MiST/Mappy Hardware/rtl/mc6809/cpucore.v @@ -0,0 +1,36 @@ +module cpucore +( + input clk, + input rst, + output rw, + output vma, + output [15:0] address, + input [7:0] data_in, + output [7:0] data_out, + input halt, + input hold, + input irq, + input firq, + input nmi +); + + +mc6809 cpu +( + .D(data_in), + .DOut(data_out), + .ADDR(address), + .RnW(rw), + .E(vma), + .nIRQ(~irq), + .nFIRQ(~firq), + .nNMI(~nmi), + .EXTAL(clk), + .nHALT(~halt), + .nRESET(~rst), + .XTAL(1'b0), + .MRDY(1'b1), + .nDMABREQ(1'b1) +); + +endmodule \ No newline at end of file diff --git a/Arcade_MiST/Mappy Hardware/rtl/mc6809/mc6809.v b/Arcade_MiST/Mappy Hardware/rtl/mc6809/mc6809.v new file mode 100644 index 00000000..b19d1552 --- /dev/null +++ b/Arcade_MiST/Mappy Hardware/rtl/mc6809/mc6809.v @@ -0,0 +1,80 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 08:11:34 09/23/2016 +// Design Name: +// Module Name: mc6809e +// Project Name: +// Target Devices: +// Tool versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// +module mc6809( + input [7:0] D, + output [7:0] DOut, + output [15:0] ADDR, + output RnW, + output E, + output Q, + output BS, + output BA, + input nIRQ, + input nFIRQ, + input nNMI, + input EXTAL, + input XTAL, + input nHALT, + input nRESET, + input MRDY, + input nDMABREQ + + , output [111:0] RegData + + ); + +reg [1:0] clk_phase=2'b00; + +wire CLK; +assign CLK=EXTAL; + +wire LIC; +wire BUSY; +wire AVMA; +reg rE; +reg rQ; +assign E = rE; +assign Q = rQ; + +mc6809i cpucore(.D(D), .DOut(DOut), .ADDR(ADDR), .RnW(RnW), .E(E), .Q(Q), .BS(BS), .BA(BA), .nIRQ(nIRQ), .nFIRQ(nFIRQ), + .nNMI(nNMI), .AVMA(AVMA), .BUSY(BUSY), .LIC(LIC), .nHALT(nHALT), .nRESET(nRESET), .nDMABREQ(nDMABREQ) + ,.RegData(RegData) + ); + +always @(negedge CLK) +begin + case (clk_phase) + 2'b00: + rE <= 0; + 2'b01: + rQ <= 1; + 2'b10: + rE <= 1; + 2'b11: + rQ <= 0; + endcase + + if (MRDY == 1'b1) + clk_phase <= clk_phase + 2'b01; +end + + +endmodule diff --git a/Arcade_MiST/Mappy Hardware/rtl/mc6809/mc6809i.v b/Arcade_MiST/Mappy Hardware/rtl/mc6809/mc6809i.v new file mode 100644 index 00000000..5725aab4 --- /dev/null +++ b/Arcade_MiST/Mappy Hardware/rtl/mc6809/mc6809i.v @@ -0,0 +1,4156 @@ +`timescale 1ns / 1ns +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: Greg Miller +// Copyright (c) 2016, Greg Miller +// +// Create Date: 14:26:59 08/13/2016 +// Design Name: +// Module Name: mc6809 +// Project Name: Cycle-Accurate 6809 Core +// Target Devices: +// Tool versions: +// Description: +// +// Dependencies: Intended to be standalone Vanilla Verilog. +// +// Revision: +// Revision 1.0 - Initial Release +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// + + +// +// The 6809 has incomplete instruction decoding. A collection of instructions, if met, end up actually behaving like +// a binary-adjacent neighbor. +// +// The soft core permits three different behaviors for this situation, controlled by the instantiation parameter +// ILLEGAL_INSTRUCTIONS +// +// "GHOST" - Mimic the 6809's incomplete decoding. This is as similar to a hard 6809 as is practical. [DEFAULT] +// +// "STOP" - Cause the soft core to cease execution, placing $DEAD on the address bus and R/W to 'read'. Interrupts, +// bus control (/HALT, /DMABREQ), etc. are ignored. The core intentionally seizes in this instance. +// (Frankly, this is useful when making changes to the core and you have a logic analyzer connected.) +// +// "IGNORE"- Cause the soft core to merely ignore illegal instructions. It will consider them 1-byte instructions and +// attempt to fetch and run an exception 1 byte later. +// + +module mc6809i +#( + parameter ILLEGAL_INSTRUCTIONS="GHOST" +) +( + + input [7:0] D, + output [7:0] DOut, + output [15:0] ADDR, + output RnW, + input E, + input Q, + output BS, + output BA, + input nIRQ, + input nFIRQ, + input nNMI, + output AVMA, + output BUSY, + output LIC, + input nHALT, + input nRESET, + input nDMABREQ, + output [111:0] RegData +); + +reg [7:0] DOutput; + +assign DOut = DOutput; + +reg RnWOut; // Combinatorial + +reg rLIC; +assign LIC = rLIC; + +reg rAVMA; +assign AVMA = rAVMA; + +reg rBUSY; +assign BUSY = rBUSY; + +// Bus control +// BS BA +// 0 0 normal (CPU running, CPU is master) +// 0 1 Interrupt Ack +// 1 0 Sync Ack +// 1 1 CPU has gone high-Z on A, D, R/W +// + +assign RnW = RnWOut; + + +///////////////////////////////////////////////// +// Vectors +`define RESET_VECTOR 16'HFFFE +`define NMI_VECTOR 16'HFFFC +`define SWI_VECTOR 16'HFFFA +`define IRQ_VECTOR 16'HFFF8 +`define FIRQ_VECTOR 16'HFFF6 +`define SWI2_VECTOR 16'HFFF4 +`define SWI3_VECTOR 16'HFFF2 +`define Reserved_VECTOR 16'HFFF0 + +////////////////////////////////////////////////////// +// Latched registers +// + +// The last-latched copy. +reg [7:0] a; +reg [7:0] b; +reg [15:0] x; +reg [15:0] y; +reg [15:0] u; +reg [15:0] s; +reg [15:0] pc; +reg [7:0] dp; +reg [7:0] cc; +reg [15:0] tmp; +reg [15:0] addr; +reg [15:0] ea; + + +// Debug ability to export register contents +assign RegData[7:0] = a; +assign RegData[15:8] = b; +assign RegData[31:16] = x; +assign RegData[47:32] = y; +assign RegData[63:48] = s; +assign RegData[79:64] = u; +assign RegData[87:80] = cc; +assign RegData[95:88] = dp; +assign RegData[111:96] = pc; + + + +// The values as being calculated +reg [7:0] a_nxt; +reg [7:0] b_nxt; +reg [15:0] x_nxt; +reg [15:0] y_nxt; +reg [15:0] u_nxt; +reg [15:0] s_nxt; +reg [15:0] pc_nxt; +reg [7:0] dp_nxt; +reg [7:0] cc_nxt; +reg [15:0] addr_nxt; +reg [15:0] ea_nxt; +reg [15:0] tmp_nxt; + +reg BS_nxt; +reg BA_nxt; + +// for ADDR, BS/BA, assign them to the flops +assign BS = BS_nxt; +assign BA = BA_nxt; +assign ADDR=addr_nxt; + +localparam CC_E= 8'H80; +localparam CC_F= 8'H40; +localparam CC_H= 8'H20; +localparam CC_I= 8'H10; +localparam CC_N= 8'H08; +localparam CC_Z= 8'H04; +localparam CC_V= 8'H02; +localparam CC_C= 8'H01; + +localparam CC_E_BIT= 3'd7; +localparam CC_F_BIT= 3'd6; +localparam CC_H_BIT= 3'd5; +localparam CC_I_BIT= 3'd4; +localparam CC_N_BIT= 3'd3; +localparam CC_Z_BIT= 3'd2; +localparam CC_V_BIT= 3'd1; +localparam CC_C_BIT= 3'd0; + +// Convenience calculations +reg [15:0] pc_p1; +reg [15:0] pc_p2; +reg [15:0] pc_p3; +reg [15:0] s_p1; +reg [15:0] s_m1; +reg [15:0] u_p1; +reg [15:0] u_m1; +reg [15:0] addr_p1; +reg [15:0] ea_p1; + +////////////////////////////////////////////////////// +// NMI Mask +// +// NMI is supposed to be masked - despite the name - until the 6809 loads a value into S. +// Frankly, I'm cheating slightly. If someone does a LDS #$0, it won't disable the mask. Pretty much anything else +// that changes the value of S from the default (which is currently $0) will clear the mask. A reset will set the mask again. +reg NMIMask; + +reg NMILatched; +reg NMISample; +reg NMISample2; +reg NMIClear; +reg NMIClear_nxt; +wire wNMIClear = NMIClear; + +reg IRQLatched; + +reg IRQSample; +reg IRQSample2; +reg FIRQLatched; +reg FIRQSample; +reg FIRQSample2; +reg HALTLatched; +reg HALTSample; +reg HALTSample2; +reg DMABREQLatched; +reg DMABREQSample; +reg DMABREQSample2; + +// Interrupt types +localparam INTTYPE_NMI = 3'H0 ; +localparam INTTYPE_IRQ = 3'H1 ; +localparam INTTYPE_FIRQ = 3'H2 ; +localparam INTTYPE_SWI = 3'H3 ; +localparam INTTYPE_SWI2 = 3'H4 ; +localparam INTTYPE_SWI3 = 3'H5 ; + +reg [2:0] IntType; +reg [2:0] IntType_nxt; + +////////////////////////////////////////////////////// +// Instruction Fetch Details +// +reg InstPage2; +reg InstPage3; +reg InstPage2_nxt; +reg InstPage3_nxt; + +reg [7:0] Inst1; +reg [7:0] Inst2; +reg [7:0] Inst3; +reg [7:0] Inst1_nxt; +reg [7:0] Inst2_nxt; +reg [7:0] Inst3_nxt; + + +localparam CPUSTATE_RESET = 7'd0; +localparam CPUSTATE_RESET0 = 7'd1; + +localparam CPUSTATE_RESET2 = 7'd3; +localparam CPUSTATE_FETCH_I1 = 7'd4; +localparam CPUSTATE_FETCH_I1V2 = 7'd5; +localparam CPUSTATE_FETCH_I2 = 7'd8; + +localparam CPUSTATE_LBRA_OFFSETLOW = 7'd17; +localparam CPUSTATE_LBRA_DONTCARE = 7'd18; +localparam CPUSTATE_LBRA_DONTCARE2 = 7'd19; + + + +localparam CPUSTATE_BRA_DONTCARE = 7'd20; + +localparam CPUSTATE_BSR_DONTCARE1 = 7'd21; +localparam CPUSTATE_BSR_DONTCARE2 = 7'd22; +localparam CPUSTATE_BSR_RETURNLOW = 7'd23; +localparam CPUSTATE_BSR_RETURNHIGH = 7'd24; + +localparam CPUSTATE_TFR_DONTCARE1 = 7'd26; +localparam CPUSTATE_TFR_DONTCARE2 = 7'd27; +localparam CPUSTATE_TFR_DONTCARE3 = 7'd28; +localparam CPUSTATE_TFR_DONTCARE4 = 7'd29; + +localparam CPUSTATE_EXG_DONTCARE1 = 7'd30; +localparam CPUSTATE_EXG_DONTCARE2 = 7'd31; +localparam CPUSTATE_EXG_DONTCARE3 = 7'd32; +localparam CPUSTATE_EXG_DONTCARE4 = 7'd33; +localparam CPUSTATE_EXG_DONTCARE5 = 7'd34; +localparam CPUSTATE_EXG_DONTCARE6 = 7'd35; + +localparam CPUSTATE_ABX_DONTCARE = 7'd36; + +localparam CPUSTATE_RTS_HI = 7'd38; +localparam CPUSTATE_RTS_LO = 7'd39; +localparam CPUSTATE_RTS_DONTCARE2 = 7'd40; + +localparam CPUSTATE_16IMM_LO = 7'd41; +localparam CPUSTATE_ALU16_DONTCARE = 7'd42; +localparam CPUSTATE_DIRECT_DONTCARE = 7'd43; + +localparam CPUSTATE_ALU_EA = 7'd44; + +localparam CPUSTATE_ALU_DONTCARE = 7'd46; +localparam CPUSTATE_ALU_WRITEBACK = 7'd47; + +localparam CPUSTATE_LD16_LO = 7'd48; + +localparam CPUSTATE_ST16_LO = 7'd49; +localparam CPUSTATE_ALU16_LO = 7'd50; + + + + +localparam CPUSTATE_JSR_DONTCARE = 7'd53; +localparam CPUSTATE_JSR_RETLO = 7'd54; +localparam CPUSTATE_JSR_RETHI = 7'd55; +localparam CPUSTATE_EXTENDED_ADDRLO = 7'd56; +localparam CPUSTATE_EXTENDED_DONTCARE = 7'd57; +localparam CPUSTATE_INDEXED_BASE = 7'd58; + + +localparam CPUSTATE_IDX_DONTCARE3 = 7'd60; + +localparam CPUSTATE_IDX_OFFSET_LO = 7'd61; +localparam CPUSTATE_IDX_16OFFSET_LO = 7'd62; + +localparam CPUSTATE_IDX_16OFF_DONTCARE0= 7'd63; +localparam CPUSTATE_IDX_16OFF_DONTCARE1= 7'd64; +localparam CPUSTATE_IDX_16OFF_DONTCARE2= 7'd65; +localparam CPUSTATE_IDX_16OFF_DONTCARE3= 7'd66; + +localparam CPUSTATE_IDX_DOFF_DONTCARE1 = 7'd68; +localparam CPUSTATE_IDX_DOFF_DONTCARE2 = 7'd69; +localparam CPUSTATE_IDX_DOFF_DONTCARE3 = 7'd70; +localparam CPUSTATE_IDX_PC16OFF_DONTCARE = 7'd71; + +localparam CPUSTATE_IDX_EXTIND_LO = 7'd72; +localparam CPUSTATE_IDX_EXTIND_DONTCARE = 7'd73; + +localparam CPUSTATE_INDIRECT_HI = 7'd74; +localparam CPUSTATE_INDIRECT_LO = 7'd75; +localparam CPUSTATE_INDIRECT_DONTCARE = 7'd76; +localparam CPUSTATE_MUL_ACTION = 7'd77; + +localparam CPUSTATE_PSH_DONTCARE1 = 7'd80; +localparam CPUSTATE_PSH_DONTCARE2 = 7'd81; +localparam CPUSTATE_PSH_DONTCARE3 = 7'd82; +localparam CPUSTATE_PSH_ACTION = 7'd83; + +localparam CPUSTATE_PUL_DONTCARE1 = 7'd84; +localparam CPUSTATE_PUL_DONTCARE2 = 7'd85; +localparam CPUSTATE_PUL_ACTION = 7'd86; + +localparam CPUSTATE_NMI_START = 7'd87; +localparam CPUSTATE_IRQ_DONTCARE = 7'd88; +localparam CPUSTATE_IRQ_START = 7'd89; +localparam CPUSTATE_IRQ_DONTCARE2 = 7'd90; +localparam CPUSTATE_IRQ_VECTOR_HI = 7'd91; +localparam CPUSTATE_IRQ_VECTOR_LO = 7'd92; +localparam CPUSTATE_FIRQ_START = 7'd93; +localparam CPUSTATE_CC_DONTCARE = 7'd94; +localparam CPUSTATE_SWI_START = 7'd95; + +localparam CPUSTATE_TST_DONTCARE1 = 7'd96; +localparam CPUSTATE_TST_DONTCARE2 = 7'd97; + +localparam CPUSTATE_DEBUG = 7'd98; + +localparam CPUSTATE_16IMM_DONTCARE = 7'd99; + +localparam CPUSTATE_HALTED = 7'd100; + +localparam CPUSTATE_HALT_EXIT2 = 7'd102; +localparam CPUSTATE_STOP = 7'd105; +localparam CPUSTATE_STOP2 = 7'd106; +localparam CPUSTATE_STOP3 = 7'd107; + + +localparam CPUSTATE_CWAI = 7'd108; +localparam CPUSTATE_CWAI_DONTCARE1 = 7'd109; +localparam CPUSTATE_CWAI_POST = 7'd110; + +localparam CPUSTATE_DMABREQ = 7'd111; +localparam CPUSTATE_DMABREQ_EXIT = 7'd112; +localparam CPUSTATE_SYNC = 7'd113; +localparam CPUSTATE_SYNC_EXIT = 7'd114; + +localparam CPUSTATE_INT_DONTCARE = 7'd115; + + +reg [6:0] CpuState = CPUSTATE_RESET; +reg [6:0] CpuState_nxt = CPUSTATE_RESET; + +reg [6:0] NextState = CPUSTATE_RESET; +reg [6:0] NextState_nxt = CPUSTATE_RESET; + +wire [6:0] PostIllegalState; + +// If we encounter something like an illegal addressing mode (an index mode that's illegal for instance) +// What state should we go to? +generate +if (ILLEGAL_INSTRUCTIONS=="STOP") +begin : postillegal + assign PostIllegalState = CPUSTATE_STOP; +end +else +begin + assign PostIllegalState = CPUSTATE_FETCH_I1; +end +endgenerate + + + +/////////////////////////////////////////////////////////////////////// + +// +// MapInstruction - Considering how the core was instantiated, this +// will either directly return D[7:0] *or* remap values from D[7:0] +// that relate to undefined instructions in the 6809 to the instructions +// that the 6809 actually executed when these were encountered, due to +// incomplete decoding. +// +// NEG, COM, LSR, DEC - these four instructions, in Direct, Inherent (A or B) +// Indexed, or Extended addressing do not actually decode bit 0 on the instruction. +// Thus, for instance, a $51 encountered will be executed as a $50, which is a NEGB. +// + +// Specifically, the input is an instruction; if it matches an unknown instruction that the +// 6809 is known to ghost to another instruction, the output of the function +// is the the instruction that actually gets executed. Otherwise, the output is the +// input. + +function [7:0] MapInstruction(input [7:0] i); +reg [3:0] topnyb; +reg [3:0] btmnyb; +reg [7:0] newinst; +begin + newinst = i; + + topnyb = i[7:4]; + btmnyb = i[3:0]; + + if ( (topnyb == 4'H0) || + (topnyb == 4'H4) || + (topnyb == 4'H5) || + (topnyb == 4'H6) || + (topnyb == 4'H7) + ) + begin + if (btmnyb == 4'H1) + newinst = {topnyb, 4'H0}; + if (btmnyb == 4'H2) + newinst = {topnyb, 4'H3}; + if (btmnyb == 4'H5) + newinst = {topnyb, 4'H4}; + if (btmnyb == 4'HB) + newinst = {topnyb, 4'HA}; + end + MapInstruction = newinst; +end +endfunction + + +wire [7:0] MappedInstruction; +generate +if (ILLEGAL_INSTRUCTIONS=="GHOST") +begin : ghost + assign MappedInstruction = MapInstruction(D); +end +else +begin + assign MappedInstruction = D; +end +endgenerate + + + +/////////////////////////////////////////////////////////////////////// + +function IllegalInstruction(input [7:0] i); +reg [3:0] hi; +reg [3:0] lo; +reg illegal; +begin + illegal = 1'b0; + hi = i[7:4]; + lo = i[3:0]; + if ( (hi == 4'H0) || (hi == 4'H4) || (hi == 4'H5) || (hi == 4'H6) || (hi == 4'H7) ) + begin + if ( (lo == 4'H1) || (lo == 4'H2) || (lo == 4'H5) || (lo == 4'HB) ) + illegal = 1'b1; + if (lo == 4'HE) + if ( (hi == 4'H4) || (hi == 4'H5) ) + illegal = 1'b1; + end + if (hi == 4'H3) + begin + if ( (lo == 4'H8) || (lo == 4'HE) ) + illegal = 1'b1; + end + if (hi == 4'H1) + begin + if ( (lo == 4'H4) || (lo == 4'H5) || (lo == 4'H8) || (lo == 4'HB) ) + illegal = 1'b1; + end + if ( (hi == 4'H8) || (hi == 4'HC) ) + begin + if ( (lo == 4'H7) || (lo == 4'HF) ) + illegal = 1'b1; + if ( lo == 4'HD ) + if (hi == 4'HC) + illegal = 1'b1; + end + IllegalInstruction = illegal; +end +endfunction + +wire IsIllegalInstruction; + +generate +if (ILLEGAL_INSTRUCTIONS=="GHOST") +begin : never_illegal + assign IsIllegalInstruction = 1'b0; +end +else +begin + assign IsIllegalInstruction = IllegalInstruction(Inst1); +end +endgenerate + +wire [6:0] IllegalInstructionState; +generate +if (ILLEGAL_INSTRUCTIONS=="IGNORE") +begin : illegal_state + assign IllegalInstructionState = CPUSTATE_FETCH_I1; +end +else if (ILLEGAL_INSTRUCTIONS=="STOP") +begin + assign IllegalInstructionState = CPUSTATE_STOP; +end +else +begin + assign IllegalInstructionState = 7'd0; +end +endgenerate + + +/////////////////////////////////////////////////////////////////////// + + +always @(negedge NMISample2 or posedge wNMIClear) +begin + if (wNMIClear == 1) + NMILatched <= 1; + else if (NMIMask == 0) + NMILatched <= 0; + else + NMILatched <= 1; +end + +// +// The 6809 specs say that the CPU control signals are sampled on the falling edge of Q. +// It also says that the interrupts require 1 cycle of synchronization time. +// That's vague, as it doesn't say where "1 cycle" starts or ends. Starting from the +// falling edge of Q, the next cycle notices an assertion. From checking a hard 6809 on +// an analyzer, what they really mean is that it's sampled on the falling edge of Q, +// but there's a one cycle delay from the falling edge of E (0.25 clocks from the falling edge of Q +// where the signals were sampled) before it can be noticed. +// So, SIGNALSample is the latched value at the falling edge of Q +// SIGNALSample2 is the latched value at the falling edge of E (0.25 clocks after the line above) +// SIGNALLatched is the latched value at the falling edge of E (1 cycle after the line above) +// +// /HALT and /DMABREQ are delayed one cycle less than interrupts. The 6809 specs infer these details, +// but don't list the point-of-reference they're written from (for instance, they say that an interrupt requires +// a cycle for synchronization; however, it isn't clear whether that's from the falling Q to the next falling Q, +// a complete intermediate cycle, the falling E to the next falling E, etc.) - which, in the end, required an +// analyzer on the 6809 to determine how many cycles before a new instruction an interrupt (or /HALT & /DMABREQ) +// had to be asserted to be noted instead of the next instruction running start to finish. +// +always @(negedge Q) +begin + NMISample <= nNMI; + + IRQSample <= nIRQ; + + FIRQSample <= nFIRQ; + + HALTSample <= nHALT; + + DMABREQSample <= nDMABREQ; + + +end + + +reg rnRESET=0; // The latched version of /RESET, useful 1 clock after it's latched +always @(negedge E) +begin + rnRESET <= nRESET; + + NMISample2 <= NMISample; + + IRQSample2 <= IRQSample; + IRQLatched <= IRQSample2; + + FIRQSample2 <= FIRQSample; + FIRQLatched <= FIRQSample2; + + HALTSample2 <= HALTSample; + HALTLatched <= HALTSample2; + + DMABREQSample2 <= DMABREQSample; + DMABREQLatched <= DMABREQSample2; + + + if (rnRESET == 1) + begin + CpuState <= CpuState_nxt; + + // Don't interpret this next item as "The Next State"; it's a special case 'after this + // generic state, go to this programmable state', so that a single state + // can be shared for many tasks. [Specifically, the stack push/pull code, which is used + // for PSH, PUL, Interrupts, RTI, etc. + NextState <= NextState_nxt; + + // CPU registers latch from the combinatorial circuit + a <= a_nxt; + b <= b_nxt; + x <= x_nxt; + y <= y_nxt; + s <= s_nxt; + u <= u_nxt; + cc <= cc_nxt; + dp <= dp_nxt; + pc <= pc_nxt; + tmp <= tmp_nxt; + addr <= addr_nxt; + ea <= ea_nxt; + + InstPage2 <= InstPage2_nxt; + InstPage3 <= InstPage3_nxt; + Inst1 <= Inst1_nxt; + Inst2 <= Inst2_nxt; + Inst3 <= Inst3_nxt; + NMIClear <= NMIClear_nxt; + + IntType <= IntType_nxt; + + if (s != s_nxt) // Once S changes at all (default is '0'), release the NMI Mask. + NMIMask <= 1'b0; + end + else + begin + CpuState <= CPUSTATE_RESET; + NMIMask <= 1'b1; // Mask NMI until S is loaded. + NMIClear <= 1'b0; // Mark us as not having serviced NMI + end +end + + +///////////////////////////////////////////////////////////////// +// Decode the Index byte + +localparam IDX_REG_X = 3'd0; +localparam IDX_REG_Y = 3'd1; +localparam IDX_REG_U = 3'd2; +localparam IDX_REG_S = 3'd3; +localparam IDX_REG_PC = 3'd4; + +localparam IDX_MODE_POSTINC1 = 4'd0; +localparam IDX_MODE_POSTINC2 = 4'd1; +localparam IDX_MODE_PREDEC1 = 4'd2; +localparam IDX_MODE_PREDEC2 = 4'd3; +localparam IDX_MODE_NOOFFSET = 4'd4; +localparam IDX_MODE_B_OFFSET = 4'd5; +localparam IDX_MODE_A_OFFSET = 4'd6; +localparam IDX_MODE_5BIT_OFFSET= 4'd7; // Special case, not bit pattern 7; the offset sits in the bit pattern +localparam IDX_MODE_8BIT_OFFSET= 4'd8; +localparam IDX_MODE_16BIT_OFFSET = 4'd9; +localparam IDX_MODE_D_OFFSET = 4'd11; +localparam IDX_MODE_8BIT_OFFSET_PC = 4'd12; +localparam IDX_MODE_16BIT_OFFSET_PC= 4'd13; +localparam IDX_MODE_EXTENDED_INDIRECT = 4'd15; + +// Return: +// Register base [3 bits] +// Indirect [1 bit] +// Mode [4 bits] + +function [7:0] IndexDecode(input [7:0] postbyte); +reg [2:0] regnum; +reg indirect; +reg [3:0] mode; +begin + indirect = 0; + mode = 0; + + if (postbyte[7] == 0) // 5-bit + begin + mode = IDX_MODE_5BIT_OFFSET; + end + else + begin + mode = postbyte[3:0]; + indirect = postbyte[4]; + end + if ((mode != IDX_MODE_8BIT_OFFSET_PC) && (mode != IDX_MODE_16BIT_OFFSET_PC)) + regnum[2:0] = postbyte[6:5]; + else + regnum[2:0] = IDX_REG_PC; + + IndexDecode = {indirect, mode, regnum}; +end +endfunction + +wire [3:0] IndexedMode; +wire IndexedIndirect; +wire [2:0] IndexedRegister; + +assign {IndexedIndirect, IndexedMode, IndexedRegister} = IndexDecode(Inst2); + +///////////////////////////////////////////////////////////////// +// Is this a JMP instruction? (irrespective of addressing mode) +function IsJMP(input [7:0] inst); +reg [3:0] hi; +reg [3:0] lo; +begin + hi = inst[7:4]; + lo = inst[3:0]; + + IsJMP = 0; + if ((hi == 4'H0) || (hi == 4'H6) || (hi == 4'H7)) + if (lo == 4'HE) + IsJMP = 1; +end +endfunction + +/////////////////////////////////////////////////////////////////// +// Is this an 8-bit Store? + +localparam ST8_REG_A = 1'b0; +localparam ST8_REG_B = 1'b1; + +function [1:0] IsST8(input [7:0] inst); +reg regnum; +reg IsStore; +begin + + IsStore = 1'b0; + regnum = 1'b1; + + if ( (Inst1 == 8'H97) || (Inst1 == 8'HA7) || (Inst1 == 8'HB7) ) + begin + IsStore = 1'b1; + regnum = 1'b0; + end + else if ( (Inst1 == 8'HD7) || (Inst1 == 8'HE7) || (Inst1 == 8'HF7) ) + begin + IsStore = 1'b1; + regnum = 1'b1; + end + IsST8 = {IsStore, regnum}; +end +endfunction + +wire IsStore8; +wire Store8RegisterNum; + +assign {IsStore8, Store8RegisterNum} = IsST8(Inst1); + + +///////////////////////////////////////////////////////////////// +// Is this a 16-bit Store? + +localparam ST16_REG_X = 3'd0; +localparam ST16_REG_Y = 3'd1; +localparam ST16_REG_U = 3'd2; +localparam ST16_REG_S = 3'd3; +localparam ST16_REG_D = 3'd4; + + +function [3:0] IsST16(input [7:0] inst); +reg [3:0] hi; +reg [3:0] lo; +reg [2:0] regnum; +reg IsStore; +begin + hi = inst[7:4]; + lo = inst[3:0]; + IsStore = 1'b0; + regnum = 3'b111; + + if ((inst == 8'H9F) || (inst == 8'HAF) || (inst == 8'HBF)) + begin + IsStore = 1; + if (~InstPage2) + regnum = ST16_REG_X; + else + regnum = ST16_REG_Y; + end + else if ((inst == 8'HDF) || (inst == 8'HEF) || (inst == 8'HFF)) + begin + IsStore = 1; + if (~InstPage2) + regnum = ST16_REG_U; + else + regnum = ST16_REG_S; + end + else if ((inst == 8'HDD) || (inst == 8'HED) || (inst == 8'HFD)) + begin + IsStore = 1; + regnum = ST16_REG_D; + end + + IsST16 = {IsStore, regnum}; +end +endfunction + +wire IsStore16; +wire [2:0] StoreRegisterNum; + +assign {IsStore16, StoreRegisterNum} = IsST16(Inst1); + +///////////////////////////////////////////////////////////////// +// Is this a special Immediate mode instruction, ala +// PSH, PUL, EXG, TFR, ANDCC, ORCC +function IsSpecialImm(input [7:0] inst); +reg is; +reg [3:0] hi; +reg [3:0] lo; +begin + hi = inst[7:4]; + lo = inst[3:0]; + is = 0; + + if (hi == 4'H1) + begin + if ( (lo == 4'HA) || (lo == 4'HC) || (lo == 4'HE) || (lo == 4'HF) ) // ORCC, ANDCC, EXG, TFR + is = 1; + end + else if (hi == 4'H3) + begin + if ( (lo >= 4'H3) && (lo <= 4'H7) ) // PSHS, PULS, PSHU, PULU + is = 1; + end + else + is = 0; + + IsSpecialImm = is; +end +endfunction +wire IsSpecialImmediate = IsSpecialImm(Inst1); + +///////////////////////////////////////////////////////////////// +// Is this a one-byte instruction? [The 6809 reads 2 bytes for every instruction, minimum (it can read more). On a one-byte, we have to ensure that we haven't skipped the PC ahead. +function IsOneByteInstruction(input [7:0] inst); +reg is; +reg [3:0] hi; +reg [3:0] lo; +begin + hi = inst[7:4]; + lo = inst[3:0]; + is = 1'b0; + + if ( (hi == 4'H4) || (hi == 4'H5) ) + is = 1'b1; + else if ( hi == 4'H1) + begin + if ( (lo == 4'H2) || (lo == 4'H3) || (lo == 4'H9) || (lo == 4'HD) ) + is = 1'b1; + end + else if (hi == 4'H3) + begin + if ( (lo >= 4'H9) && (lo != 4'HC) ) + is = 1'b1; + end + else + is = 1'b0; + + IsOneByteInstruction = is; +end +endfunction + +///////////////////////////////////////////////////////////////// +// ALU16 - Simpler than the 8 bit ALU + +localparam ALU16_REG_X = 3'd0; +localparam ALU16_REG_Y = 3'd1; +localparam ALU16_REG_U = 3'd2; +localparam ALU16_REG_S = 3'd3; +localparam ALU16_REG_D = 3'd4; + +function [2:0] ALU16RegFromInst(input Page2, input Page3, input [7:0] inst); +reg [2:0] srcreg; +begin + srcreg = 3'b111; // default + casex ({Page2, Page3, inst}) // Note pattern for the matching below + 10'b1010xx0011: // 1083, 1093, 10A3, 10B3 CMPD + srcreg = ALU16_REG_D; + 10'b1010xx1100: // 108C, 109C, 10AC, 10BC CMPY + srcreg = ALU16_REG_Y; + 10'b0110xx0011: // 1183, 1193, 11A3, 11B3 CMPU + srcreg = ALU16_REG_U; + 10'b0110xx1100: // 118C, 119C, 11AC, 11BC CMPS + srcreg = ALU16_REG_S; + 10'b0010xx1100: // 8C,9C,AC,BC CMPX + srcreg = ALU16_REG_X; + + 10'b0011xx0011: // C3, D3, E3, F3 ADDD + srcreg = ALU16_REG_D; + + 10'b0011xx1100: // CC, DC, EC, FC LDD + srcreg = ALU16_REG_D; + 10'b0010xx1110: // 8E LDX, 9E LDX, AE LDX, BE LDX + srcreg = ALU16_REG_X; + 10'b0011xx1110: // CE LDU, DE LDU, EE LDU, FE LDU + srcreg = ALU16_REG_U; + 10'b1010xx1110: // 108E LDY, 109E LDY, 10AE LDY, 10BE LDY + srcreg = ALU16_REG_Y; + 10'b1011xx1110: // 10CE LDS, 10DE LDS, 10EE LDS, 10FE LDS + srcreg = ALU16_REG_S; + 10'b0010xx0011: // 83, 93, A3, B3 SUBD + srcreg = ALU16_REG_D; + + 10'H03A: // 3A ABX + srcreg = ALU16_REG_X; + 10'H030: // 30 LEAX + srcreg = ALU16_REG_X; + 10'H031: // 31 LEAY + srcreg = ALU16_REG_Y; + 10'H032: // 32 LEAS + srcreg = ALU16_REG_S; + 10'H033: // 32 LEAU + srcreg = ALU16_REG_U; + default: + srcreg = 3'b111; + endcase + ALU16RegFromInst = srcreg; +end +endfunction + +wire [2:0] ALU16Reg = ALU16RegFromInst(InstPage2, InstPage3, Inst1); + +localparam ALUOP16_SUB = 3'H0; +localparam ALUOP16_ADD = 3'H1; +localparam ALUOP16_LD = 3'H2; +localparam ALUOP16_CMP = 3'H3; +localparam ALUOP16_LEA = 3'H4; +localparam ALUOP16_INVALID = 3'H7; + +function [3:0] ALU16OpFromInst(input Page2, input Page3, input [7:0] inst); +reg [2:0] aluop; +reg writeback; +begin + aluop = 3'b111; + writeback = 1'b1; + casex ({Page2, Page3, inst}) + 10'b1010xx0011: // 1083, 1093, 10A3, 10B3 CMPD + begin + aluop = ALUOP16_CMP; + writeback = 1'b0; + end + 10'b1010xx1100: // 108C, 109C, 10AC, 10BC CMPY + begin + aluop = ALUOP16_CMP; + writeback = 1'b0; + end + 10'b0110xx0011: // 1183, 1193, 11A3, 11B3 CMPU + begin + aluop = ALUOP16_CMP; + writeback = 1'b0; + end + 10'b0110xx1100: // 118C, 119C, 11AC, 11BC CMPS + begin + aluop = ALUOP16_CMP; + writeback = 1'b0; + end + 10'b0010xx1100: // 8C,9C,AC,BC CMPX + begin + aluop = ALUOP16_CMP; + writeback = 1'b0; + end + + 10'b0011xx0011: // C3, D3, E3, F3 ADDD + aluop = ALUOP16_ADD; + + 10'b0011xx1100: // CC, DC, EC, FC LDD + aluop = ALUOP16_LD; + 10'b001xxx1110: // 8E LDX, 9E LDX, AE LDX, BE LDX, CE LDU, DE LDU, EE LDU, FE LDU + aluop = ALUOP16_LD; + 10'b101xxx1110: // 108E LDY, 109E LDY, 10AE LDY, 10BE LDY, 10CE LDS, 10DE LDS, 10EE LDS, 10FE LDS + aluop = ALUOP16_LD; + + 10'b0010xx0011: // 83, 93, A3, B3 SUBD + aluop = ALUOP16_SUB; + + 10'H03A: // 3A ABX + aluop = ALUOP16_ADD; + + 10'b00001100xx: // $30-$33, LEAX, LEAY, LEAS, LEAU + aluop = ALUOP16_LEA; + + default: + aluop = ALUOP16_INVALID; + endcase + ALU16OpFromInst = {writeback, aluop}; +end +endfunction + +wire ALU16OpWriteback; +wire [2:0] ALU16Opcode; + +assign {ALU16OpWriteback, ALU16Opcode} = ALU16OpFromInst(InstPage2, InstPage3, Inst1); + +wire IsALU16Opcode = (ALU16Opcode != 3'b111); + +function [23:0] ALU16Inst(input [2:0] operation16, input [15:0] a_arg, input [15:0] b_arg, input [7:0] cc_arg); +reg [7:0] cc_out; +reg [15:0] ALUFn; +reg carry; +reg borrow; +begin + cc_out = cc_arg; + case (operation16) + ALUOP16_ADD: + begin + {cc_out[CC_C_BIT], ALUFn} = {1'b0, a_arg} + b_arg; + cc_out[CC_V_BIT] = (a_arg[15] & b_arg[15] & ~ALUFn[15]) | (~a_arg[15] & ~b_arg[15] & ALUFn[15]); + end + + ALUOP16_SUB: + begin + {cc_out[CC_C_BIT], ALUFn} = {1'b0, a_arg} - {1'b0, b_arg}; + cc_out[CC_V_BIT] = (a_arg[15] & ~b_arg[15] & ~ALUFn[15]) | (~a_arg[15] & b_arg[15] & ALUFn[15]); + end + + ALUOP16_LD: + begin + ALUFn = b_arg; + cc_out[CC_V_BIT] = 1'b0; + end + + ALUOP16_CMP: + begin + {cc_out[CC_C_BIT], ALUFn} = {1'b0, a_arg} - {1'b0, b_arg}; + cc_out[CC_V_BIT] = (a_arg[15] & ~b_arg[15] & ~ALUFn[15]) | (~a_arg[15] & b_arg[15] & ALUFn[15]); + end + + ALUOP16_LEA: + begin + ALUFn = a_arg; + end + + default: + ALUFn = 16'H0000; + + endcase + cc_out[CC_Z_BIT] = (ALUFn[15:0] == 16'H0000); + if (operation16 != ALUOP16_LEA) + cc_out[CC_N_BIT] = ALUFn[15]; + ALU16Inst = {cc_out, ALUFn}; +end +endfunction + +reg [2:0] ALU16_OP; +reg [15:0] ALU16_A; +reg [15:0] ALU16_B; +reg [7:0] ALU16_CC; + +// Top 8 bits == CC, bottom 8 bits = output value +wire [23:0] ALU16 = ALU16Inst(ALU16_OP, ALU16_A, ALU16_B, ALU16_CC); + + +///////////////////////////////////////////////////////////////// +// ALU + +// The ops are organized from the 4 low-order bits of the instructions for the first set of ops, then 16-31 are the second set - even though bit 4 isn't representative. +localparam ALUOP_NEG = 5'd0; +localparam ALUOP_COM = 5'd3; +localparam ALUOP_LSR = 5'd4; +localparam ALUOP_ROR = 5'd6; +localparam ALUOP_ASR = 5'd7; +localparam ALUOP_ASL = 5'd8; +localparam ALUOP_LSL = 5'd8; +localparam ALUOP_ROL = 5'd9; +localparam ALUOP_DEC = 5'd10; +localparam ALUOP_INC = 5'd12; +localparam ALUOP_TST = 5'd13; +localparam ALUOP_CLR = 5'd15; + +localparam ALUOP_SUB = 5'd16; +localparam ALUOP_CMP = 5'd17; +localparam ALUOP_SBC = 5'd18; +localparam ALUOP_AND = 5'd20; +localparam ALUOP_BIT = 5'd21; +localparam ALUOP_LD = 5'd22; +localparam ALUOP_EOR = 5'd24; +localparam ALUOP_ADC = 5'd25; +localparam ALUOP_OR = 5'd26; +localparam ALUOP_ADD = 5'd27; + +function [5:0] ALUOpFromInst(input [7:0] inst); +reg [4:0] op; +reg writeback; +begin + // Okay, this turned out to be simpler than I expected ... + op = {inst[7], inst[3:0]}; + case (op) + ALUOP_CMP: + writeback = 0; + ALUOP_TST: + writeback = 0; + ALUOP_BIT: + writeback = 0; + default: + writeback = 1; + endcase + ALUOpFromInst = {writeback, op}; +end +endfunction + +wire [4:0] ALU8Op; +wire ALU8Writeback; + +assign {ALU8Writeback, ALU8Op} = ALUOpFromInst(Inst1); + +reg [7:0] ALU_A; +reg [7:0] ALU_B; +reg [7:0] ALU_CC; +reg [4:0] ALU_OP; + + +function [15:0] ALUInst(input [4:0] operation, input [7:0] a_arg, input [7:0] b_arg, input [7:0] cc_arg); +reg [7:0] cc_out; +reg [7:0] ALUFn; +reg carry; +reg borrow; +begin + cc_out = cc_arg; + case (operation) + ALUOP_NEG: + begin + ALUFn[7:0] = ~a_arg + 1'b1; + cc_out[CC_C_BIT] = (ALUFn[7:0] != 8'H00); + cc_out[CC_V_BIT] = (a_arg == 8'H80); + end + + ALUOP_LSL: + begin + {cc_out[CC_C_BIT], ALUFn} = {a_arg, 1'b0}; + cc_out[CC_V_BIT] = a_arg[7] ^ a_arg[6]; + end + + ALUOP_LSR: + begin + {ALUFn, cc_out[CC_C_BIT]} = {1'b0, a_arg}; + end + + ALUOP_ASR: + begin + {ALUFn, cc_out[CC_C_BIT]} = {a_arg[7], a_arg}; + end + + ALUOP_ROL: + begin + {cc_out[CC_C_BIT], ALUFn} = {a_arg, cc_arg[CC_C_BIT]}; + cc_out[CC_V_BIT] = a_arg[7] ^ a_arg[6]; + end + + ALUOP_ROR: + begin + {ALUFn, cc_out[CC_C_BIT]} = {cc_arg[CC_C_BIT], a_arg}; + end + + ALUOP_OR: + begin + ALUFn[7:0] = (a_arg | b_arg); + cc_out[CC_V_BIT] = 1'b0; + end + + ALUOP_ADD: + begin + {cc_out[CC_C_BIT], ALUFn[7:0]} = {1'b0, a_arg} + {1'b0, b_arg}; + cc_out[CC_V_BIT] = (a_arg[7] & b_arg[7] & ~ALUFn[7]) | (~a_arg[7] & ~b_arg[7] & ALUFn[7]); + cc_out[CC_H_BIT] = a_arg[4] ^ b_arg[4] ^ ALUFn[4]; + end + + ALUOP_SUB: + begin + {cc_out[CC_C_BIT], ALUFn[7:0]} = {1'b0, a_arg} - {1'b0, b_arg}; + cc_out[CC_V_BIT] = (a_arg[7] & ~b_arg[7] & ~ALUFn[7]) | (~a_arg[7] & b_arg[7] & ALUFn[7]); + end + + ALUOP_AND: + begin + ALUFn[7:0] = (a_arg & b_arg); + cc_out[CC_V_BIT] = 1'b0; + end + + ALUOP_BIT: + begin + ALUFn[7:0] = (a_arg & b_arg); + cc_out[CC_V_BIT] = 1'b0; + end + + ALUOP_EOR: + begin + ALUFn[7:0] = (a_arg ^ b_arg); + cc_out[CC_V_BIT] = 1'b0; + end + + ALUOP_CMP: + begin + {cc_out[CC_C_BIT], ALUFn[7:0]} = {1'b0, a_arg} - {1'b0, b_arg}; + cc_out[CC_V_BIT] = (a_arg[7] & ~b_arg[7] & ~ALUFn[7]) | (~a_arg[7] & b_arg[7] & ALUFn[7]); + end + + ALUOP_COM: + begin + ALUFn[7:0] = ~a_arg; + cc_out[CC_V_BIT] = 1'b0; + cc_out[CC_C_BIT] = 1'b1; + end + + ALUOP_ADC: + begin + {cc_out[CC_C_BIT], ALUFn[7:0]} = {1'b0, a_arg} + {1'b0, b_arg} + cc_arg[CC_C_BIT]; + cc_out[CC_V_BIT] = (a_arg[7] & b_arg[7] & ~ALUFn[7]) | (~a_arg[7] & ~b_arg[7] & ALUFn[7]); + cc_out[CC_H_BIT] = a_arg[4] ^ b_arg[4] ^ ALUFn[4]; + end + + ALUOP_LD: + begin + ALUFn[7:0] = b_arg; + cc_out[CC_V_BIT] = 1'b0; + end + + ALUOP_INC: + begin + {carry, ALUFn} = {1'b0, a_arg} + 1'b1; + cc_out[CC_V_BIT] = (~a_arg[7] & ALUFn[7]); + end + + ALUOP_DEC: + begin + {carry, ALUFn[7:0]} = {1'b0, a_arg} - 1'b1; + cc_out[CC_V_BIT] = (a_arg[7] & ~ALUFn[7]); + end + + ALUOP_CLR: + begin + ALUFn[7:0] = 8'H00; + cc_out[CC_V_BIT] = 1'b0; + cc_out[CC_C_BIT] = 1'b0; + end + + ALUOP_TST: + begin + ALUFn[7:0] = a_arg; + cc_out[CC_V_BIT] = 1'b0; + end + + ALUOP_SBC: + begin + {cc_out[CC_C_BIT], ALUFn[7:0]} = {1'b0, a_arg} - {1'b0, b_arg} - cc_arg[CC_C_BIT]; + cc_out[CC_V_BIT] = (a_arg[7] & ~b_arg[7] & ~ALUFn[7]) | (~a_arg[7] & b_arg[7] & ALUFn[7]); + end + + default: + ALUFn = 8'H00; + + endcase + + cc_out[CC_N_BIT] = ALUFn[7]; + cc_out[CC_Z_BIT] = (ALUFn == 8'H00); + ALUInst = {cc_out[7:0], ALUFn[7:0]}; +end +endfunction + + +// Top 8 bits == CC, bottom 8 bits = output value +wire [15:0] ALU = ALUInst(ALU_OP, ALU_A, ALU_B, ALU_CC); + +//////////////////////////////////////////////////////////// + +localparam TYPE_INHERENT = 3'd0; +localparam TYPE_IMMEDIATE = 3'd1; +localparam TYPE_DIRECT = 3'd2; +localparam TYPE_RELATIVE = 3'd3; +localparam TYPE_INDEXED = 3'd4; +localparam TYPE_EXTENDED = 3'd5; + +localparam TYPE_INVALID = 3'd7; + +// Function to decode the addressing mode the instruction uses +function [2:0] addressing_mode_type(input [7:0] inst); +begin + casex (inst) + 8'b0000???? : addressing_mode_type = TYPE_DIRECT; + 8'b0001???? : + begin + casex (inst[3:0]) + 4'b0010: + addressing_mode_type = TYPE_INHERENT; + + 4'b0011: + addressing_mode_type = TYPE_INHERENT; + + 4'b1001: + addressing_mode_type = TYPE_INHERENT; + + 4'b1101: + addressing_mode_type = TYPE_INHERENT; + + 4'b0110: + addressing_mode_type = TYPE_RELATIVE; + + 4'b0111: + addressing_mode_type = TYPE_RELATIVE; + + 4'b1010: + addressing_mode_type = TYPE_IMMEDIATE; + + 4'b1100: + addressing_mode_type = TYPE_IMMEDIATE; + + 4'b1110: + addressing_mode_type = TYPE_IMMEDIATE; + + 4'b1111: + addressing_mode_type = TYPE_IMMEDIATE; + + default: + addressing_mode_type = TYPE_INVALID; + endcase + end + + 8'b0010????: addressing_mode_type = TYPE_RELATIVE; + 8'b0011????: + begin + casex(inst[3:0]) + 4'b00??: + addressing_mode_type = TYPE_INDEXED; + + 4'b01??: + addressing_mode_type = TYPE_IMMEDIATE; + + 4'b1001: + addressing_mode_type = TYPE_INHERENT; + + 4'b101?: + addressing_mode_type = TYPE_INHERENT; + + 4'b1100: + addressing_mode_type = TYPE_INHERENT; + + 4'b1101: + addressing_mode_type = TYPE_INHERENT; + + 4'b1111: + addressing_mode_type = TYPE_INHERENT; + + default: + addressing_mode_type = TYPE_INVALID; + endcase + end + + 8'b010?????: addressing_mode_type = TYPE_INHERENT; + + 8'b0110????: addressing_mode_type = TYPE_INDEXED; + + 8'b0111????: addressing_mode_type = TYPE_EXTENDED; + + 8'b1000????: + begin + casex (inst[3:0]) + 4'b0111: addressing_mode_type = TYPE_INVALID; + 4'b1111: addressing_mode_type = TYPE_INVALID; + 4'b1101: addressing_mode_type = TYPE_RELATIVE; + default: addressing_mode_type = TYPE_IMMEDIATE; + endcase + end + + 8'b1001????: addressing_mode_type = TYPE_DIRECT; + 8'b1010????: addressing_mode_type = TYPE_INDEXED; + 8'b1011????: addressing_mode_type = TYPE_EXTENDED; + 8'b1100????: addressing_mode_type = TYPE_IMMEDIATE; + 8'b1101????: addressing_mode_type = TYPE_DIRECT; + 8'b1110????: addressing_mode_type = TYPE_INDEXED; + 8'b1111????: addressing_mode_type = TYPE_EXTENDED; + + endcase +end +endfunction + +wire [2:0] AddrModeType = addressing_mode_type(Inst1); + +////////////////////////////////////////////////// + +// Individual opcodes that are the top of a column of states. + +localparam OPCODE_INH_ABX = 8'H3A; +localparam OPCODE_INH_RTS = 8'H39; +localparam OPCODE_INH_RTI = 8'H3B; +localparam OPCODE_INH_CWAI = 8'H3C; +localparam OPCODE_INH_MUL = 8'H3D; +localparam OPCODE_INH_SWI = 8'H3F; +localparam OPCODE_INH_SEX = 8'H1D; +localparam OPCODE_INH_NOP = 8'H12; +localparam OPCODE_INH_SYNC = 8'H13; +localparam OPCODE_INH_DAA = 8'H19; + +localparam OPCODE_IMM_ORCC = 8'H1A; +localparam OPCODE_IMM_ANDCC = 8'H1C; +localparam OPCODE_IMM_EXG = 8'H1E; +localparam OPCODE_IMM_TFR = 8'H1F; +localparam OPCODE_IMM_PSHS = 8'H34; +localparam OPCODE_IMM_PULS = 8'H35; +localparam OPCODE_IMM_PSHU = 8'H36; +localparam OPCODE_IMM_PULU = 8'H37; + +localparam OPCODE_IMM_SUBD = 8'H83; +localparam OPCODE_IMM_CMPX = 8'H8C; +localparam OPCODE_IMM_LDX = 8'H8E; +localparam OPCODE_IMM_ADDD = 8'HC3; +localparam OPCODE_IMM_LDD = 8'HCC; +localparam OPCODE_IMM_LDU = 8'HCE; +localparam OPCODE_IMM_CMPD = 8'H83; // Page2 +localparam OPCODE_IMM_CMPY = 8'H8C; // Page2 +localparam OPCODE_IMM_LDY = 8'H8E; // Page2 +localparam OPCODE_IMM_LDS = 8'HCE; // Page2 +localparam OPCODE_IMM_CMPU = 8'H83; // Page3 +localparam OPCODE_IMM_CMPS = 8'H8C; // Page3 + +localparam EXGTFR_REG_D = 4'H0; +localparam EXGTFR_REG_X = 4'H1; +localparam EXGTFR_REG_Y = 4'H2; +localparam EXGTFR_REG_U = 4'H3; +localparam EXGTFR_REG_S = 4'H4; +localparam EXGTFR_REG_PC = 4'H5; +localparam EXGTFR_REG_A = 4'H8; +localparam EXGTFR_REG_B = 4'H9; +localparam EXGTFR_REG_CC = 4'HA; +localparam EXGTFR_REG_DP = 4'HB; + +function IsALU8Set0(input [7:0] instr); +reg result; +reg [3:0] hi; +reg [3:0] lo; +begin + hi = instr[7:4]; + lo = instr[3:0]; + if ( (hi == 4'H0) || (hi == 4'H4) || (hi == 4'H5) || (hi == 4'H6) || (hi == 4'H7) ) + begin + if ( (lo != 4'H1) && (lo != 4'H2) && (lo != 4'H5) && (lo != 4'HB) && (lo != 4'HE) ) // permit NEG, COM, LSR, ROR, ASR, ASL/LSL, ROL, DEC, INC, TST, CLR + result = 1; + else + result = 0; + end + else + result = 0; + IsALU8Set0 = result; +end +endfunction + +function IsALU8Set1(input [7:0] instr); +reg result; +reg [3:0] hi; +reg [3:0] lo; +begin + hi = instr[7:4]; + lo = instr[3:0]; + if ( (hi >= 4'H8) ) + begin + if ( (lo <= 4'HB) && (lo != 4'H3) && (lo != 4'H7) ) // 8-bit SUB, CMP, SBC, AND, BIT, LD, EOR, ADC, OR, ADD + result = 1; + else + result = 0; + end + else + result = 0; + IsALU8Set1 = result; +end +endfunction + +// Determine if the instruction is performing an 8-bit op (ALU only) +function ALU8BitOp(input [7:0] instr); +begin + ALU8BitOp = IsALU8Set0(instr) | IsALU8Set1(instr); +end +endfunction + +wire Is8BitInst = ALU8BitOp(Inst1); + +function IsRegA(input [7:0] instr); +reg result; +reg [3:0] hi; +begin + hi = instr[7:4]; + if ((hi == 4'H4) || (hi == 4'H8) || (hi == 4'H9) || (hi == 4'HA) || (hi == 4'HB) ) + result = 1; + else + result = 0; + IsRegA = result; +end +endfunction + +wire IsTargetRegA = IsRegA(Inst1); + +// +// +// Decode +// 00-0F = DIRECT +// 10-1F = INHERENT, RELATIVE, IMMEDIATE +// 20-2F = RELATIVE +// 30-3F = INDEXED, IMMEDIATE (pus, pul), INHERENT +// 40-4F = INHERENT +// 50-5F = INHERENT +// 60-6F = INDEXED +// 70-7F = EXTENDED +// 80-8F = IMMEDIATE, RELATIVE (BSR) +// 90-9F = DIRECT +// A0-AF = INDEXED +// B0-BF = EXTENDED +// C0-CF = IMMEDIATE +// D0-DF = DIRECT +// E0-EF = INDEXED +// F0-FF = EXTENDED + +// DIRECT; 00-0F, 90-9F, D0-DF +// INHERENT; 10-1F (12, 13, 19, 1D), 30-3F (39-3F), 40-4F, 50-5F, +// RELATIVE: 10-1F (16, 17), 20-2F, 80-8F (8D) +// IMMEDIATE: 10-1F (1A, 1C, 1E, 1F), 30-3F (34-37), 80-8F (80-8C, 8E), C0-CF +// INDEXED: 60-6F, A0-AF, E0-EF +// EXTENDED: 70-7F, B0-Bf, F0-FF + +localparam INST_LBRA = 8'H16; // always -- shitty numbering, damnit +localparam INST_LBSR = 8'H17; // + +localparam INST_BRA = 8'H20; // always +localparam INST_BRN = 8'H21; // never +localparam INST_BHI = 8'H22; // CC.Z = 0 && CC.C = 0 +localparam INST_BLS = 8'H23; // CC.Z != 0 && CC.C != 0 +localparam INST_BCC = 8'H24; // CC.C = 0 +localparam INST_BHS = 8'H24; // same as BCC +localparam INST_BCS = 8'H25; // CC.C = 1 +localparam INST_BLO = 8'H25; // same as BCS +localparam INST_BNE = 8'H26; // CC.Z = 0 +localparam INST_BEQ = 8'H27; // CC.Z = 1 +localparam INST_BVC = 8'H28; // V = 1 +localparam INST_BVS = 8'H29; // V = 0 +localparam INST_BPL = 8'H2A; // CC.N = 0 +localparam INST_BMI = 8'H2B; // CC.N = 1 +localparam INST_BGE = 8'H2C; // CC.N = CC.V +localparam INST_BLT = 8'H2D; // CC.N != CC.V +localparam INST_BGT = 8'H2E; // CC.N = CC.V && CC.Z = 0 +localparam INST_BLE = 8'H2F; // CC.N != CC.V && CC.Z = 1 +localparam INST_BSR = 8'H8D; // always + +localparam NYB_BRA = 4'H0; // always +localparam NYB_BRN = 4'H1; // never +localparam NYB_BHI = 4'H2; // CC.Z = 0 && CC.C = 0 +localparam NYB_BLS = 4'H3; // CC.Z != 0 && CC.C != 0 +localparam NYB_BCC = 4'H4; // CC.C = 0 +localparam NYB_BHS = 4'H4; // same as BCC +localparam NYB_BCS = 4'H5; // CC.C = 1 +localparam NYB_BLO = 4'H5; // same as BCS +localparam NYB_BNE = 4'H6; // CC.Z = 0 +localparam NYB_BEQ = 4'H7; // CC.Z = 1 +localparam NYB_BVC = 4'H8; // V = 0 +localparam NYB_BVS = 4'H9; // V = 1 +localparam NYB_BPL = 4'HA; // CC.N = 0 +localparam NYB_BMI = 4'HB; // CC.N = 1 +localparam NYB_BGE = 4'HC; // CC.N = CC.V +localparam NYB_BLT = 4'HD; // CC.N != CC.V +localparam NYB_BGT = 4'HE; // CC.N = CC.V && CC.Z = 0 +localparam NYB_BLE = 4'HF; // CC.N != CC.V && CC.Z = 1 + + + +function take_branch(input [7:0] Inst1, input [7:0] cc); +begin + take_branch = 0; //default + if ( (Inst1 == INST_BSR) || (Inst1 == INST_LBSR) || (Inst1 == INST_LBRA) ) + take_branch = 1; + else + case (Inst1[3:0]) + NYB_BRA: + take_branch = 1; + NYB_BRN: + take_branch = 0; + NYB_BHI: + if ( ( cc[CC_Z_BIT] | cc[CC_C_BIT] ) == 0) + take_branch = 1; + NYB_BLS: + if ( cc[CC_Z_BIT] | cc[CC_C_BIT] ) + take_branch = 1; + NYB_BCC: + if ( cc[CC_C_BIT] == 0 ) + take_branch = 1; + NYB_BCS: + if ( cc[CC_C_BIT] == 1 ) + take_branch = 1; + NYB_BNE: + if ( cc[CC_Z_BIT] == 0 ) + take_branch = 1; + NYB_BEQ: + if ( cc[CC_Z_BIT] == 1 ) + take_branch = 1; + NYB_BVC: + if ( cc[CC_V_BIT] == 0) + take_branch = 1; + NYB_BVS: + if ( cc[CC_V_BIT] == 1) + take_branch = 1; + NYB_BPL: + if ( cc[CC_N_BIT] == 0 ) + take_branch = 1; + NYB_BMI: + if (cc[CC_N_BIT] == 1) + take_branch = 1; + NYB_BGE: + if ((cc[CC_N_BIT] ^ cc[CC_V_BIT]) == 0) + take_branch = 1; + NYB_BLT: + if ((cc[CC_N_BIT] ^ cc[CC_V_BIT]) == 1) + take_branch = 1; + NYB_BGT: + if ( ((cc[CC_N_BIT] ^ cc[CC_V_BIT]) == 0) & (cc[CC_Z_BIT] == 0) ) + take_branch = 1; + NYB_BLE: + if ( ((cc[CC_N_BIT] ^ cc[CC_V_BIT]) == 1) | (cc[CC_Z_BIT] == 1) ) + take_branch = 1; + endcase +end +endfunction + +wire TakeBranch = take_branch(Inst1, cc); + +///////////////////////////////////////////////////////////////////// +// Convenience function for knowing the contents for TFR, EXG +function [15:0] EXGTFRRegister(input [3:0] regid); +begin + case (regid) + EXGTFR_REG_D: + EXGTFRRegister = {a, b}; + EXGTFR_REG_X: + EXGTFRRegister = x; + EXGTFR_REG_Y: + EXGTFRRegister = y; + EXGTFR_REG_U: + EXGTFRRegister = u; + EXGTFR_REG_S: + EXGTFRRegister = s; + EXGTFR_REG_PC: + EXGTFRRegister = pc_p1; // For both EXG and TFR, this is used on the 2nd byte in the instruction's cycle. The PC intended to transfer is actually the next byte. + EXGTFR_REG_DP: + EXGTFRRegister = {8'HFF, dp}; + EXGTFR_REG_A: + EXGTFRRegister = {8'HFF, a}; + EXGTFR_REG_B: + EXGTFRRegister = {8'HFF, b}; + EXGTFR_REG_CC: + EXGTFRRegister = {8'HFF, cc}; + default: + EXGTFRRegister = 16'H0; + endcase +end +endfunction +wire [15:0] EXGTFRRegA = EXGTFRRegister(D[7:4]); +wire [15:0] EXGTFRRegB = EXGTFRRegister(D[3:0]); + +// CPU state machine +always @(*) +begin + rLIC = 1'b0; + rAVMA = 1'b1; + rBUSY = 1'b0; + + addr_nxt = 16'HFFFF; + pc_p1 = (pc+16'H1); + pc_p2 = (pc+16'H2); + pc_p3 = (pc+16'H3); + s_p1 = (s+16'H1); + s_m1 = (s-16'H1); + u_p1 = (u+16'H1); + u_m1 = (u-16'H1); + addr_p1 = (addr+16'H1); + ea_p1 = (ea+16'H1); + BS_nxt = 1'b0; + BA_nxt = 1'b0; + + // These may be overridden below, but the "next" version by default should be + // the last latched version. + IntType_nxt = IntType; + NMIClear_nxt = NMIClear; + NextState_nxt = NextState; + a_nxt = a; + b_nxt = b; + x_nxt = x; + y_nxt = y; + s_nxt = s; + u_nxt = u; + cc_nxt = cc; + dp_nxt = dp; + pc_nxt = pc; + tmp_nxt = tmp; + ea_nxt = ea; + + ALU_A = 8'H00; + ALU_B = 8'H00; + ALU_CC = 8'H00; + ALU_OP = 5'H00; + + ALU16_OP = 3'H0; + ALU16_A = 16'H0000; + ALU16_B = 16'H0000; + ALU16_CC = 8'H00; + + DOutput = 8'H00; + RnWOut = 1'b1; // read + + Inst1_nxt = Inst1; + Inst2_nxt = Inst2; + Inst3_nxt = Inst3; + InstPage2_nxt = InstPage2; + InstPage3_nxt = InstPage3; + + CpuState_nxt = CpuState; + + case (CpuState) + CPUSTATE_RESET: + begin + addr_nxt = 16'HFFFF; + a_nxt = 0; + b_nxt = 0; + x_nxt = 0; + y_nxt = 0; + s_nxt = 16'HFFFD; // Take care about removing the reset of S. There's logic depending on the delta between s and s_nxt to clear NMIMask. + u_nxt = 0; + cc_nxt = CC_F | CC_I; // reset disables interrupts + dp_nxt = 0; + ea_nxt = 16'HFFFF; + + RnWOut = 1; // read + rLIC = 1'b0; // Instruction incomplete + NMIClear_nxt= 1'b0; + IntType_nxt = 3'b111; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_RESET0; + end + + CPUSTATE_RESET0: + begin + addr_nxt = `RESET_VECTOR; + rBUSY = 1'b1; + pc_nxt[15:8] = D[7:0]; + BS_nxt = 1'b1; // ACK RESET + rAVMA = 1'b1; + rLIC = 1'b1; + CpuState_nxt = CPUSTATE_RESET2; + end + + CPUSTATE_RESET2: + begin + addr_nxt = addr_p1; + BS_nxt = 1'b1; // ACK RESET + pc_nxt[7:0] = D[7:0]; + rAVMA = 1'b1; + rLIC = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I1; + end + + CPUSTATE_FETCH_I1: + begin + if (~DMABREQLatched) + begin + addr_nxt = pc; + RnWOut = 1'b1; + rAVMA = 1'b0; + tmp_nxt = {tmp[15:4], 4'b1111}; + BS_nxt = 1'b1; + BA_nxt = 1'b1; + rLIC = 1'b1; + CpuState_nxt = CPUSTATE_DMABREQ; + end + else if (~HALTLatched) + begin + addr_nxt = pc; + RnWOut = 1'b1; + rAVMA = 1'b0; + BS_nxt = 1'b1; + BA_nxt = 1'b1; + rLIC = 1'b1; + CpuState_nxt = CPUSTATE_HALTED; + end + else // not halting, run the inst byte fetch + begin + addr_nxt = pc; // Set the address bus for the next instruction, first byte + pc_nxt = pc_p1; + RnWOut = 1; // Set for a READ + Inst1_nxt = MappedInstruction; + InstPage2_nxt = 0; + InstPage3_nxt = 0; + + // New instruction fetch; service interrupts pending + if (NMILatched == 0) + begin + pc_nxt = pc; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_NMI_START; + end + else if ((FIRQLatched == 0) && (cc[CC_F_BIT] == 0)) + begin + pc_nxt = pc; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FIRQ_START; + end + else if ((IRQLatched == 0) && (cc[CC_I_BIT] == 0)) + begin + pc_nxt = pc; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_IRQ_START; + end + + // The actual 1st byte checks + else if (Inst1_nxt == 8'H10) // Page 2 Note, like the 6809, $10 $10 $10 $10 has the same effect as a single $10. + begin + InstPage2_nxt = 1; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I1V2; + end + else if (Inst1_nxt == 8'H11) // Page 3 + begin + InstPage3_nxt = 1; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I1V2; + end + else + begin + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I2; + end + end // if not halting + end + + CPUSTATE_FETCH_I1V2: + begin + addr_nxt = pc; // Set the address bus for the next instruction, first byte + pc_nxt = pc_p1; + RnWOut = 1; // Set for a READ + Inst1_nxt = MappedInstruction; + + if (Inst1_nxt == 8'H10) // Page 2 Note, like the 6809, $10 $10 $10 $10 has the same effect as a single $10. + begin + if (InstPage3 == 0) // $11 $11 $11 $11 ... $11 $10 still = Page 3 + InstPage2_nxt = 1; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I1V2; + end + else if (Inst1_nxt == 8'H11) // Page 3 + begin + if (InstPage2 == 0) // $10 $10 ... $10 $11 still = Page 2 + InstPage3_nxt = 1; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I1V2; + end + else + begin + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I2; + end + end + + + CPUSTATE_FETCH_I2: // We've fetched the first byte. If a $10 or $11 (page select), mark those flags and fetch the next byte as instruction byte 1. + begin + addr_nxt = addr_p1; // Address bus++ + pc_nxt = pc_p1; + Inst2_nxt = D[7:0]; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I1; + + if (IsIllegalInstruction) // Skip illegal instructions + begin + + rAVMA = 1'b1; + CpuState_nxt = IllegalInstructionState; + rLIC = 1'b1; + end + else + begin + // First byte Decode for this stage + case (AddrModeType) + TYPE_INDEXED: + begin + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_INDEXED_BASE; + end + + + TYPE_EXTENDED: + begin + ea_nxt[15:8] = Inst2_nxt; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_EXTENDED_ADDRLO; + end + TYPE_DIRECT: + begin + ea_nxt = {dp, Inst2_nxt}; + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_DIRECT_DONTCARE; + end + + TYPE_INHERENT: + begin + if (Inst1 == OPCODE_INH_NOP) + begin + rLIC = 1'b1; // Instruction done! + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I1; + end + else if (Inst1 == OPCODE_INH_DAA) // Bcd lunacy + begin + if ( ((cc[CC_C_BIT]) || (a[7:4] > 4'H9)) || + ((a[7:4] > 4'H8) && (a[3:0] > 4'H9)) ) + tmp_nxt[7:4] = 4'H6; + else + tmp_nxt[7:4] = 4'H0; + + if ((cc[CC_H_BIT]) || (a[3:0] > 4'H9)) + tmp_nxt[3:0] = 4'H6; + else + tmp_nxt[3:0] = 4'H0; + + // DAA handles carry in the weirdest way. + // If it's already set, it remains set, even if carry-out is 0. + // If it wasn't set, but the output of the operation is set, carry-out gets set. + {tmp_nxt[8], a_nxt} = {1'b0, a} + tmp_nxt[7:0]; + + cc_nxt[CC_C_BIT] = cc_nxt[CC_C_BIT] | tmp_nxt[8]; + + cc_nxt[CC_N_BIT] = a_nxt[7]; + cc_nxt[CC_Z_BIT] = (a_nxt == 8'H00); + rLIC = 1'b1; // Instruction done! + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I1; + end + else if (Inst1 == OPCODE_INH_SYNC) + begin + CpuState_nxt = CPUSTATE_SYNC; + rLIC = 1'b1; + rAVMA = 1'b0; + end + else if (Inst1 == OPCODE_INH_MUL) + begin + tmp_nxt = 16'H0000; + ea_nxt[15:8] = 8'H00; + ea_nxt[7:0] = a; + a_nxt = 8; + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_MUL_ACTION; + end + else if (Inst1 == OPCODE_INH_RTS) + begin + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_RTS_HI; + end + else if (Inst1 == OPCODE_INH_RTI) + begin + rAVMA = 1'b1; + tmp_nxt = 16'H1001; // Set tmp[12] to indicate an RTI being processed, and at least pull CC. + CpuState_nxt = CPUSTATE_PUL_ACTION; + NextState_nxt = CPUSTATE_FETCH_I1; + end + else if (Inst1 == OPCODE_INH_SWI) + begin + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_SWI_START; + end + else if (Inst1 == OPCODE_INH_CWAI) + begin + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_CWAI; + end + else if (Inst1 == OPCODE_INH_SEX) + begin + a_nxt = {8{b[7]}}; + rLIC = 1'b1; // Instruction done! + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I1; + end + else if (Inst1 == OPCODE_INH_ABX) + begin + x_nxt = x + b; + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_ABX_DONTCARE; + end + else + begin + ALU_OP = ALU8Op; + if (IsTargetRegA) + ALU_A = a; + else + ALU_A = b; + + ALU_B = 0; + ALU_CC = cc; + cc_nxt = ALU[15:8]; + + if (ALU8Writeback) + begin + if (IsTargetRegA) + a_nxt = ALU[7:0]; + else + b_nxt = ALU[7:0]; + end + rLIC = 1'b1; // Instruction done! + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I1; + end + if (IsOneByteInstruction(Inst1)) // This check is probably superfluous. Every inherent instruction is 1 byte on the 6809. + pc_nxt = pc; // The 6809 auto-reads 2 bytes for every instruction. :( Adjust by not incrementing PC on the 2nd byte read. + end + + TYPE_IMMEDIATE: + begin + if (IsSpecialImmediate) + begin + if (Inst1 == OPCODE_IMM_ANDCC) + begin + pc_nxt = pc_p1; + cc_nxt = cc & D; //cc_nxt & Inst2_nxt; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_CC_DONTCARE; + end + else if (Inst1 == OPCODE_IMM_ORCC) + begin + pc_nxt = pc_p1; + cc_nxt = cc | D; //cc_nxt | Inst2_nxt; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_CC_DONTCARE; + end + else if ( (Inst1 == OPCODE_IMM_PSHS) | (Inst1 == OPCODE_IMM_PSHU) ) + begin + pc_nxt = pc_p1; + tmp_nxt[15] = 1'b0; + tmp_nxt[14] = Inst1[1]; // Mark whether to save to U or S. + tmp_nxt[13] = 1'b0; // Not pushing due to an interrupt. + tmp_nxt[13:8] = 6'H00; + tmp_nxt[7:0] = Inst2_nxt; + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_PSH_DONTCARE1; + NextState_nxt = CPUSTATE_FETCH_I1; + end + else if ( (Inst1 == OPCODE_IMM_PULS) | (Inst1 == OPCODE_IMM_PULU) ) + begin + pc_nxt = pc_p1; + tmp_nxt[15] = 1'b0; + tmp_nxt[14] = Inst1[1]; // S (0) or U (1) stack in use. + tmp_nxt[13:8] = 6'H00; + tmp_nxt[7:0] = Inst2_nxt; + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_PUL_DONTCARE1; + NextState_nxt = CPUSTATE_FETCH_I1; + end + else if (Inst1 == OPCODE_IMM_TFR) + begin + // The second byte lists the registers; Top nybble is reg #1, bottom is reg #2. + + case (Inst2_nxt[3:0]) + EXGTFR_REG_D: + {a_nxt,b_nxt} = EXGTFRRegA; + EXGTFR_REG_X: + x_nxt = EXGTFRRegA; + EXGTFR_REG_Y: + y_nxt = EXGTFRRegA; + EXGTFR_REG_U: + u_nxt = EXGTFRRegA; + EXGTFR_REG_S: + s_nxt = EXGTFRRegA; + EXGTFR_REG_PC: + pc_nxt = EXGTFRRegA; + EXGTFR_REG_DP: + dp_nxt = EXGTFRRegA[7:0]; + EXGTFR_REG_A: + a_nxt = EXGTFRRegA[7:0]; + EXGTFR_REG_B: + b_nxt = EXGTFRRegA[7:0]; + EXGTFR_REG_CC: + cc_nxt = EXGTFRRegA[7:0]; + default: + begin + end + endcase + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_TFR_DONTCARE1; + + end + else if (Inst1 == OPCODE_IMM_EXG) + begin + // The second byte lists the registers; Top nybble is reg #1, bottom is reg #2. + + case (Inst2_nxt[7:4]) + EXGTFR_REG_D: + {a_nxt,b_nxt} = EXGTFRRegB; + EXGTFR_REG_X: + x_nxt = EXGTFRRegB; + EXGTFR_REG_Y: + y_nxt = EXGTFRRegB; + EXGTFR_REG_U: + u_nxt = EXGTFRRegB; + EXGTFR_REG_S: + s_nxt = EXGTFRRegB; + EXGTFR_REG_PC: + pc_nxt = EXGTFRRegB; + EXGTFR_REG_DP: + dp_nxt = EXGTFRRegB[7:0]; + EXGTFR_REG_A: + a_nxt = EXGTFRRegB[7:0]; + EXGTFR_REG_B: + b_nxt = EXGTFRRegB[7:0]; + EXGTFR_REG_CC: + cc_nxt = EXGTFRRegB[7:0]; + default: + begin + end + endcase + case (Inst2_nxt[3:0]) + EXGTFR_REG_D: + {a_nxt,b_nxt} = EXGTFRRegA; + EXGTFR_REG_X: + x_nxt = EXGTFRRegA; + EXGTFR_REG_Y: + y_nxt = EXGTFRRegA; + EXGTFR_REG_U: + u_nxt = EXGTFRRegA; + EXGTFR_REG_S: + s_nxt = EXGTFRRegA; + EXGTFR_REG_PC: + pc_nxt = EXGTFRRegA; + EXGTFR_REG_DP: + dp_nxt = EXGTFRRegA[7:0]; + EXGTFR_REG_A: + a_nxt = EXGTFRRegA[7:0]; + EXGTFR_REG_B: + b_nxt = EXGTFRRegA[7:0]; + EXGTFR_REG_CC: + cc_nxt = EXGTFRRegA[7:0]; + default: + begin + end + endcase + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_EXG_DONTCARE1; + end + end + // Determine if this is an 8-bit ALU operation. + else if (Is8BitInst) + begin + ALU_OP = ALU8Op; + if (IsTargetRegA) + ALU_A = a; + else + ALU_A = b; + + ALU_B = Inst2_nxt; + ALU_CC = cc; + cc_nxt = ALU[15:8]; + + if (ALU8Writeback) + begin + if (IsTargetRegA) + a_nxt = ALU[7:0]; + else + b_nxt = ALU[7:0]; + end + rLIC = 1'b1; // Instruction done! + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I1; + end + else // Then it must be a 16 bit instruction + begin + // 83 SUBD + // 8C CMPX + // 8E LDX + // C3 ADDD + // CC LDD + // CE LDU + // 108E CMPD + // 108C CMPY + // 108E LDY + // 10CE LDS + // 1183 CMPU + // 118C CMPS + // Wow, they were just stuffing them in willy-nilly ... + + // LD* 16 bit immediate + if (IsALU16Opcode) + begin + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_16IMM_LO; + end + // there's a dead zone here; I need an else to take us back to CPUSTATE_FETCHI1 if we want to ignore illegal instructions, to CPUSTATE_DEAD if we want to catch them. + + end + + end + + TYPE_RELATIVE: + begin + // Is this a LB** or a B**? + // If InstPage2 is set, it's a long branch; if clear, a normal branch. + if ( (InstPage2) || (Inst1 == INST_LBRA) || (Inst1 == INST_LBSR) ) + begin + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_LBRA_OFFSETLOW; + end + else + begin + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_BRA_DONTCARE; + end + + end + default: + begin + CpuState_nxt = CPUSTATE_FETCH_I1; + end + endcase + end + end + + + CPUSTATE_LBRA_OFFSETLOW: + begin + addr_nxt = pc; + pc_nxt = pc_p1; + Inst3_nxt = D[7:0]; + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_LBRA_DONTCARE; + end + + CPUSTATE_LBRA_DONTCARE: + begin + addr_nxt = 16'HFFFF; + if ( TakeBranch ) + begin + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_LBRA_DONTCARE2; + end + else + begin + rLIC = 1'b1; // Instruction done! + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I1; + end + end + + CPUSTATE_BRA_DONTCARE: + begin + addr_nxt = 16'HFFFF; + tmp_nxt = pc; + if (TakeBranch) + begin + pc_nxt = pc + { {8{Inst2[7]}}, Inst2[7:0]}; // Sign-extend the 8 bit offset to 16. + + if (Inst1 == INST_BSR) + begin + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_BSR_DONTCARE1; + end + else + begin + rLIC = 1'b1; // Instruction done! + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I1; + end + end + else + begin + rLIC = 1'b1; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I1; + end + + end + + CPUSTATE_LBRA_DONTCARE2: + begin + tmp_nxt= pc; + addr_nxt = 16'HFFFF; + + // Take branch + pc_nxt = pc + {Inst2[7:0], Inst3[7:0]}; + if (Inst1 == INST_LBSR) + begin + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_BSR_DONTCARE1; + end + else + begin + rLIC = 1'b1; // Instruction done! + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I1; + end + end + + CPUSTATE_BSR_DONTCARE1: + begin + addr_nxt = pc; + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_BSR_DONTCARE2; + end + + CPUSTATE_BSR_DONTCARE2: + begin + addr_nxt = 16'HFFFF; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_BSR_RETURNLOW; + end + + CPUSTATE_BSR_RETURNLOW: + begin + addr_nxt = s_m1; + s_nxt = s_m1; + DOutput[7:0] = tmp[7:0]; + RnWOut = 0; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_BSR_RETURNHIGH; + end + + CPUSTATE_BSR_RETURNHIGH: + begin + addr_nxt = s_m1; + s_nxt = s_m1; + DOutput[7:0] = tmp[15:8]; + RnWOut = 0; + rLIC = 1'b1; // Instruction done! + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I1; // after this, RnWOut must go to 1, and the bus needs the PC placed on it. + end + + CPUSTATE_TFR_DONTCARE1: + begin + addr_nxt = 16'HFFFF; + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_TFR_DONTCARE2; + end + + CPUSTATE_TFR_DONTCARE2: + begin + addr_nxt = 16'HFFFF; + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_TFR_DONTCARE3; + end + + CPUSTATE_TFR_DONTCARE3: + begin + addr_nxt = 16'HFFFF; + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_TFR_DONTCARE4; + end + + CPUSTATE_TFR_DONTCARE4: + begin + addr_nxt = 16'HFFFF; + rAVMA = 1'b1; + rLIC = 1'b1; // Instruction done! + CpuState_nxt = CPUSTATE_FETCH_I1; + end + + CPUSTATE_EXG_DONTCARE1: + begin + addr_nxt = 16'HFFFF; + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_EXG_DONTCARE2; + end + + CPUSTATE_EXG_DONTCARE2: + begin + addr_nxt = 16'HFFFF; + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_EXG_DONTCARE3; + end + + CPUSTATE_EXG_DONTCARE3: + begin + addr_nxt = 16'HFFFF; + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_EXG_DONTCARE4; + end + + CPUSTATE_EXG_DONTCARE4: + begin + addr_nxt = 16'HFFFF; + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_EXG_DONTCARE5; + end + + CPUSTATE_EXG_DONTCARE5: + begin + rAVMA = 1'b0; + addr_nxt = 16'HFFFF; + CpuState_nxt = CPUSTATE_EXG_DONTCARE6; + end + + CPUSTATE_EXG_DONTCARE6: + begin + addr_nxt = 16'HFFFF; + rAVMA = 1'b1; + rLIC = 1'b1; // Instruction done! + CpuState_nxt = CPUSTATE_FETCH_I1; + end + + CPUSTATE_ABX_DONTCARE: + begin + addr_nxt = 16'HFFFF; + rAVMA = 1'b1; + rLIC = 1'b1; // Instruction done! + CpuState_nxt = CPUSTATE_FETCH_I1; + end + + CPUSTATE_RTS_HI: + begin + addr_nxt = s; + s_nxt = s_p1; + pc_nxt[15:8] = D[7:0]; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_RTS_LO; + end + + CPUSTATE_RTS_LO: + begin + addr_nxt = s; + s_nxt = s_p1; + pc_nxt[7:0] = D[7:0]; + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_RTS_DONTCARE2; + end + + CPUSTATE_RTS_DONTCARE2: + begin + addr_nxt = 16'HFFFF; + rLIC = 1'b1; // Instruction done! + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I1; + end + + CPUSTATE_16IMM_LO: + begin + addr_nxt = pc; + pc_nxt = pc_p1; + + ALU16_OP = ALU16Opcode; + ALU16_CC = cc; + ALU16_B = {Inst2, D[7:0]}; + + case (ALU16Reg) + ALU16_REG_X: + ALU16_A = x; + ALU16_REG_D: + ALU16_A = {a, b}; + ALU16_REG_Y: + ALU16_A = y; + ALU16_REG_U: + ALU16_A = u; + ALU16_REG_S: + ALU16_A = s; + default: + ALU16_A = 16'H0; + endcase + + if (ALU16OpWriteback) + begin + case (ALU16Reg) + ALU16_REG_X: + {cc_nxt, x_nxt} = ALU16; + ALU16_REG_D: + {cc_nxt, a_nxt, b_nxt} = ALU16; + ALU16_REG_Y: + {cc_nxt, y_nxt} = ALU16; + ALU16_REG_U: + {cc_nxt, u_nxt} = ALU16; + ALU16_REG_S: + {cc_nxt, s_nxt} = ALU16; + default: + begin + end + endcase + end + else + cc_nxt = ALU16[23:16]; + + if (ALU16_OP == ALUOP16_LD) + begin + rLIC = 1'b1; // Instruction done! + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I1; + end + else + begin + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_16IMM_DONTCARE; + end + end + + CPUSTATE_DIRECT_DONTCARE: + begin + addr_nxt = 16'HFFFF; + + if (IsJMP(Inst1)) + begin + pc_nxt = ea; + rLIC = 1'b1; // Instruction done! + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I1; + end + else + begin + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_ALU_EA; + end + end + + CPUSTATE_ALU_EA: + begin + + // Is Figure 18/5 Column 2? JMP (not Immediate Mode) + // This actually isn't done here. All checks passing in to ALU_EA should check for a JMP; FIXME EVERYWHERE + + // Is Figure 18/5 Column 8? TST (not immediate mode) + // THIS IS BURIED IN THE COLUMN 3 section with comparisons to ALUOP_TST. + + // Is Figure 18/5 Column 3? + if (IsALU8Set1(Inst1)) + begin + addr_nxt = ea; + + ALU_OP = ALU8Op; + ALU_B = D[7:0]; + ALU_CC = cc; + + if (IsTargetRegA) + ALU_A = a; + else + ALU_A = b; + + cc_nxt = ALU[15:8]; + + if ( (ALU8Writeback) ) + begin + if (IsTargetRegA) + a_nxt = ALU[7:0]; + else + b_nxt = ALU[7:0]; + end + + rLIC = 1'b1; // Instruction done! + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I1; + end + + // Is Figure 18/5 Column 4? (Store, 8 bits) + else if (IsStore8) + begin + addr_nxt = ea; + RnWOut = 0; // write + + ALU_OP = ALUOP_LD; // load has the same CC characteristics as store + ALU_A = 8'H00; + ALU_CC = cc; + + case (Store8RegisterNum) + ST8_REG_A: + begin + DOutput = a; + ALU_B = a; + end + ST8_REG_B: + begin + DOutput = b; + ALU_B = b; + end + + + endcase + + cc_nxt = ALU[15:8]; + + rLIC = 1'b1; // Instruction done! + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I1; + end + + // Is Figure 18/5 Column 5? (Load, 16 bits) + else if (IsALU16Opcode & (ALU16Opcode == ALUOP16_LD)) + begin + addr_nxt = ea; + ea_nxt = ea_p1; + + case (ALU16Reg) + ALU16_REG_X: + x_nxt[15:8] = D[7:0]; + ALU16_REG_D: + a_nxt = D[7:0]; + ALU16_REG_Y: + y_nxt[15:8] = D[7:0]; + ALU16_REG_S: + s_nxt[15:8] = D[7:0]; + ALU16_REG_U: + u_nxt[15:8] = D[7:0]; + default: + begin + end + endcase + rAVMA = 1'b1; + rBUSY = 1'b1; + CpuState_nxt = CPUSTATE_LD16_LO; + + end + + // Is Figure 18/5 Column 6? (Store, 16 bits) + else if (IsStore16) + begin + addr_nxt = ea; + ea_nxt = ea_p1; + + ALU16_OP = ALUOP16_LD; // LD and ST have the same CC characteristics + ALU16_CC = cc; + ALU16_A = 8'H00; + + case (StoreRegisterNum) + ST16_REG_X: + begin + DOutput[7:0] = x[15:8]; + ALU16_B = x; + end + ST16_REG_Y: + begin + DOutput[7:0] = y[15:8]; + ALU16_B = y; + end + ST16_REG_U: + begin + DOutput[7:0] = u[15:8]; + ALU16_B = u; + end + ST16_REG_S: + begin + DOutput[7:0] = s[15:8]; + ALU16_B = s; + end + ST16_REG_D: + begin + DOutput[7:0] = a[7:0]; + ALU16_B = {a,b}; + end + default: + begin + end + endcase + + cc_nxt = ALU16[23:16]; + + RnWOut = 0; // Write + rAVMA = 1'b1; + rBUSY = 1'b1; + CpuState_nxt = CPUSTATE_ST16_LO; + end + + // Is Figure 18/5 Column 7? + else if (IsALU8Set0(Inst1)) + begin + // These are registerless instructions, ala + // ASL, ASR, CLR, COM, DEC, INC, (LSL), LSR, NEG, ROL, ROR + // and TST (special!) + // They require READ, Modify (the operation above), WRITE. Between the Read and the Write cycles, there's actually a /VMA + // cycle where the 6809 likely did the operation. We'll include a /VMA cycle for accuracy, but we'll do the work primarily in the first cycle. + addr_nxt = ea; + + ALU_OP = ALU8Op; + ALU_A = D[7:0]; + ALU_CC = cc; + tmp_nxt[15:8] = cc; // for debug only + tmp_nxt[7:0] = ALU[7:0]; + cc_nxt = ALU[15:8]; + if (ALU8Op == ALUOP_TST) + begin + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_TST_DONTCARE1; + end + else + begin + rAVMA = 1'b0; + rBUSY = 1'b1; + CpuState_nxt = CPUSTATE_ALU_DONTCARE; + end + + end + + // Is Figure 18/5 Column 8? TST + // NOTE: + // THIS IS BURIED IN THE COLUMN 3 section with comparisons to ALUOP_TST. [Directly above.] + + + // Is Figure 18/5 Column 9? (16-bit ALU ops, non-load) + else if (IsALU16Opcode && (ALU16Opcode != ALUOP16_LD) && ((Inst1 < 8'H30) || (Inst1 > 8'H33)) ) // 30-33 = LEAX, LEAY, LEAS, LEAU; don't include them here. + begin + addr_nxt = ea; + ea_nxt = ea_p1; + + tmp_nxt[15:8] = D[7:0]; + rAVMA = 1'b1; + rBUSY = 1'b1; + CpuState_nxt = CPUSTATE_ALU16_LO; + + end + + // Is Figure 18/5 Column 10? JSR (not Immediate Mode) + else if ((Inst1 == 8'H9D) || (Inst1 == 8'HAD) || (Inst1 == 8'HBD)) // JSR + begin + pc_nxt = ea; + addr_nxt = ea; + tmp_nxt = pc; + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_JSR_DONTCARE; + end + // Is Figure 18/5 Column 11? LEA(X,Y,S,U) + else if ((Inst1 >= 8'H30) && (Inst1<= 8'H33)) + begin + addr_nxt = 16'HFFFF; // Ack, actually a valid cycle, this isn't a dontcare (/VMA) cycle! + + ALU16_OP = ALU16Opcode; + ALU16_CC = cc; + ALU16_A = ea; + + case (ALU16Reg) + ALU16_REG_X: + {cc_nxt, x_nxt} = ALU16; + ALU16_REG_Y: + {cc_nxt, y_nxt} = ALU16; + ALU16_REG_U: + u_nxt = ALU16[15:0]; + ALU16_REG_S: + s_nxt = ALU16[15:0]; + default: + begin + end + endcase + + rLIC = 1'b1; // Instruction done! + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I1; + + end + + end + + + CPUSTATE_ALU_DONTCARE: + begin + addr_nxt = 16'HFFFF; + rAVMA = 1'b1; + rBUSY = 1'b1; // We do nothing here, but on the real 6809, they did the modify phase here. :| + CpuState_nxt = CPUSTATE_ALU_WRITEBACK; + end + + CPUSTATE_ALU_WRITEBACK: + begin + addr_nxt = ea; + RnWOut = 0; // Write + DOutput = tmp[7:0]; + rLIC = 1'b1; // Instruction done! + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I1; + end + + CPUSTATE_LD16_LO: + begin + addr_nxt = ea; + + case (ALU16Reg) + ALU16_REG_X: + begin + x_nxt[7:0] = D[7:0]; + ALU16_B[15:8] = x[15:8]; + end + ALU16_REG_D: + begin + b_nxt = D[7:0]; + ALU16_B[15:8] = a; + end + ALU16_REG_Y: + begin + y_nxt[7:0] = D[7:0]; + ALU16_B[15:8] = y[15:8]; + end + ALU16_REG_S: + begin + s_nxt[7:0] = D[7:0]; + ALU16_B[15:8] = s[15:8]; + end + ALU16_REG_U: + begin + u_nxt[7:0] = D[7:0]; + ALU16_B[15:8] = u[15:8]; + end + default: + begin + end + + endcase + + ALU16_OP = ALU16Opcode; + ALU16_CC = cc; + ALU16_A = 8'H00; + ALU16_B[7:0] = D[7:0]; + cc_nxt = ALU16[23:16]; + + rLIC = 1'b1; // Instruction done! + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I1; + end + + CPUSTATE_ST16_LO: + begin + addr_nxt = ea; + ea_nxt = ea_p1; + case (StoreRegisterNum) + ST16_REG_X: + DOutput[7:0] = x[7:0]; + ST16_REG_Y: + DOutput[7:0] = y[7:0]; + ST16_REG_U: + DOutput[7:0] = u[7:0]; + ST16_REG_S: + DOutput[7:0] = s[7:0]; + ST16_REG_D: + DOutput[7:0] = b[7:0]; + default: + begin + end + endcase + RnWOut = 0; // write + + rLIC = 1'b1; // Instruction done! + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I1; + end + + CPUSTATE_ALU16_LO: + begin + addr_nxt = ea; + + ALU16_OP = ALU16Opcode; + ALU16_CC = cc; + + ALU16_B = {tmp[15:8], D[7:0]}; + + case (ALU16Reg) + ALU16_REG_X: + ALU16_A = x; + ALU16_REG_D: + ALU16_A = {a, b}; + ALU16_REG_Y: + ALU16_A = y; + ALU16_REG_S: + ALU16_A = s; + ALU16_REG_U: + ALU16_A = u; + default: + ALU16_A = 16'H0; + + endcase + + if (ALU16OpWriteback) + begin + case (ALU16Reg) + ALU16_REG_X: + {cc_nxt, x_nxt} = ALU16; + ALU16_REG_D: + {cc_nxt, a_nxt, b_nxt} = ALU16; + ALU16_REG_Y: + {cc_nxt, y_nxt} = ALU16; + ALU16_REG_U: + {cc_nxt, u_nxt} = ALU16; + ALU16_REG_S: + {cc_nxt, s_nxt} = ALU16; + default: + begin + end + endcase + end + else + cc_nxt = ALU16[23:16]; + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_ALU16_DONTCARE; + end + + CPUSTATE_ALU16_DONTCARE: + begin + addr_nxt = 16'HFFFF; + rLIC = 1'b1; // Instruction done! + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I1; + end + + + CPUSTATE_JSR_DONTCARE: + begin + addr_nxt = 16'HFFFF; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_JSR_RETLO; + end + + CPUSTATE_JSR_RETLO: + begin + addr_nxt = s_m1; + s_nxt = s_m1; + RnWOut = 0; + DOutput = tmp[7:0]; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_JSR_RETHI; + end + + CPUSTATE_JSR_RETHI: + begin + addr_nxt = s_m1; + s_nxt = s_m1; + RnWOut = 0; + DOutput = tmp[15:8]; + rLIC = 1'b1; // Instruction done! + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I1; + end + + CPUSTATE_EXTENDED_ADDRLO: + begin + addr_nxt = pc; + pc_nxt = pc_p1; + ea_nxt[7:0] = D[7:0]; + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_EXTENDED_DONTCARE; + end + + CPUSTATE_EXTENDED_DONTCARE: + begin + addr_nxt = 16'HFFFF; + if (IsJMP(Inst1)) + begin + pc_nxt = ea; + rLIC = 1'b1; // Instruction done! + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I1; + end + else + begin + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_ALU_EA; + end + end + + CPUSTATE_INDEXED_BASE: + begin + addr_nxt = pc; + + Inst3_nxt = D[7:0]; + + case (IndexedRegister) + IDX_REG_X: + ALU16_A = x; + IDX_REG_Y: + ALU16_A = y; + IDX_REG_U: + ALU16_A = u; + IDX_REG_S: + ALU16_A = s; + IDX_REG_PC: + ALU16_A = pc_p1; + default: + ALU16_A = 16'H0; + endcase + ALU16_OP = ALUOP16_ADD; + + case (IndexedMode) + IDX_MODE_NOOFFSET: + begin + case (IndexedRegister) + IDX_REG_X: + ea_nxt = x; + IDX_REG_Y: + ea_nxt = y; + IDX_REG_U: + ea_nxt = u; + IDX_REG_S: + ea_nxt = s; + default: + ea_nxt = 16'H0; + endcase + + if (IndexedIndirect) + begin + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_INDIRECT_HI; + end + else + begin + if (IsJMP(Inst1)) + begin + pc_nxt = ea_nxt; + rLIC = 1'b1; // Instruction done! + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I1; + end + else + begin + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_ALU_EA; + end + end + end + + IDX_MODE_5BIT_OFFSET: + begin + // The offset is the bottom 5 bits of the Index Postbyte, which is Inst2 here. + // We'll sign-extend it to 16 bits. + ALU16_B = { {11{Inst2[4]}}, Inst2[4:0] }; + ea_nxt = ALU16[15:0]; + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_IDX_DONTCARE3; + end + + + IDX_MODE_8BIT_OFFSET_PC: + begin + ALU16_B = { {8{D[7]}}, D[7:0] }; + pc_nxt = pc_p1; + ea_nxt = ALU16[15:0]; + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_IDX_DONTCARE3; + end + + IDX_MODE_8BIT_OFFSET: + begin + ALU16_B = { {8{D[7]}}, D[7:0] }; + pc_nxt = pc_p1; + ea_nxt = ALU16[15:0]; + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_IDX_DONTCARE3; + end + + IDX_MODE_A_OFFSET: + begin + ALU16_B = { {8{a[7]}}, a[7:0] }; + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_IDX_DONTCARE3; + ea_nxt = ALU16[15:0]; + end + + IDX_MODE_B_OFFSET: + begin + ALU16_B = { {8{b[7]}}, b[7:0] }; + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_IDX_DONTCARE3; + ea_nxt = ALU16[15:0]; + end + + IDX_MODE_D_OFFSET: + begin + ALU16_B = {a, b}; + + ea_nxt = ALU16[15:0]; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_IDX_DOFF_DONTCARE1; + end + + IDX_MODE_POSTINC1: + begin + ALU16_B = 16'H1; + ea_nxt = ALU16_A; + case (IndexedRegister) + IDX_REG_X: + x_nxt = ALU16[15:0]; + IDX_REG_Y: + y_nxt = ALU16[15:0]; + IDX_REG_U: + u_nxt = ALU16[15:0]; + IDX_REG_S: + s_nxt = ALU16[15:0]; + default: + begin + end + endcase + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_IDX_16OFF_DONTCARE2; + end + + IDX_MODE_POSTINC2: + begin + ALU16_B = 16'H2; + ea_nxt = ALU16_A; + case (IndexedRegister) + IDX_REG_X: + x_nxt = ALU16[15:0]; + IDX_REG_Y: + y_nxt = ALU16[15:0]; + IDX_REG_U: + u_nxt = ALU16[15:0]; + IDX_REG_S: + s_nxt = ALU16[15:0]; + default: + begin + end + endcase + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_IDX_16OFF_DONTCARE0; + end + + IDX_MODE_PREDEC1: + begin + ALU16_B = 16'HFFFF; // -1 + case (IndexedRegister) + IDX_REG_X: + x_nxt = ALU16[15:0]; + IDX_REG_Y: + y_nxt = ALU16[15:0]; + IDX_REG_U: + u_nxt = ALU16[15:0]; + IDX_REG_S: + s_nxt = ALU16[15:0]; + default: + begin + end + endcase + ea_nxt = ALU16[15:0]; + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_IDX_16OFF_DONTCARE2; + end + + IDX_MODE_PREDEC2: + begin + ALU16_B = 16'HFFFE; // -2 + case (IndexedRegister) + IDX_REG_X: + x_nxt = ALU16[15:0]; + IDX_REG_Y: + y_nxt = ALU16[15:0]; + IDX_REG_U: + u_nxt = ALU16[15:0]; + IDX_REG_S: + s_nxt = ALU16[15:0]; + default: + begin + end + endcase + ea_nxt = ALU16[15:0]; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_IDX_16OFF_DONTCARE0; + end + + IDX_MODE_16BIT_OFFSET_PC: + begin + tmp_nxt[15:8] = D[7:0]; + pc_nxt = pc_p1; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_IDX_16OFFSET_LO; + end + + IDX_MODE_16BIT_OFFSET: + begin + tmp_nxt[15:8] = D[7:0]; + pc_nxt = pc_p1; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_IDX_16OFFSET_LO; + end + + IDX_MODE_EXTENDED_INDIRECT: + begin + ea_nxt[15:8] = D[7:0]; + pc_nxt = pc_p1; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_IDX_EXTIND_LO; + end + + default: + begin + rLIC = 1'b1; + CpuState_nxt = PostIllegalState; + end + + endcase + end + + CPUSTATE_IDX_OFFSET_LO: + begin + tmp_nxt[7:0] = D[7:0]; + addr_nxt = pc; + pc_nxt = pc_p1; + ALU16_B = tmp_nxt; + + case (IndexedRegister) + IDX_REG_X: + ALU16_A = x; + IDX_REG_Y: + ALU16_A = y; + IDX_REG_U: + ALU16_A = u; + IDX_REG_S: + ALU16_A = s; + IDX_REG_PC: + ALU16_A = pc; + default: + ALU16_A = 16'H0; + endcase + ALU16_OP = ALUOP16_ADD; + + ea_nxt = ALU16[15:0]; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_IDX_16OFF_DONTCARE1; + end + + + CPUSTATE_IDX_DONTCARE3: + begin + addr_nxt = 16'HFFFF; + if (IndexedIndirect) + begin + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_INDIRECT_HI; + end + else + begin + if (IsJMP(Inst1)) + begin + pc_nxt = ea; + rLIC = 1'b1; // Instruction done! + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I1; + end + else + begin + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_ALU_EA; + end + end + + end + + CPUSTATE_IDX_16OFFSET_LO: + begin + addr_nxt = pc; + pc_nxt = pc_p1; + + case (IndexedRegister) + IDX_REG_X: + ALU16_A = x; + IDX_REG_Y: + ALU16_A = y; + IDX_REG_U: + ALU16_A = u; + IDX_REG_S: + ALU16_A = s; + IDX_REG_PC: + ALU16_A = pc_nxt; // Whups; tricky; not part of the actual pattern + default: + ALU16_A = x; // Default to something + endcase + + ALU16_OP = ALUOP16_ADD; + + ALU16_B = {tmp[15:8], D[7:0]}; + + ea_nxt = ALU16[15:0]; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_IDX_16OFF_DONTCARE1; + end + + CPUSTATE_IDX_16OFF_DONTCARE1: + begin + addr_nxt = pc; + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_IDX_16OFF_DONTCARE2; + end + + CPUSTATE_IDX_16OFF_DONTCARE0: + begin + addr_nxt = 16'HFFFF; + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_IDX_16OFF_DONTCARE2; + end + + CPUSTATE_IDX_16OFF_DONTCARE2: + begin + addr_nxt = 16'HFFFF; + if (IndexedRegister == IDX_REG_PC) + begin + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_IDX_PC16OFF_DONTCARE; + end + else + begin + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_IDX_16OFF_DONTCARE3; + end + end + + CPUSTATE_IDX_PC16OFF_DONTCARE: + begin + addr_nxt = 16'HFFFF; + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_IDX_16OFF_DONTCARE3; + end + + + CPUSTATE_IDX_16OFF_DONTCARE3: + begin + addr_nxt = 16'HFFFF; + if (IndexedIndirect) + begin + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_INDIRECT_HI; + end + else + begin + if (IsJMP(Inst1)) + begin + pc_nxt = ea; + rLIC = 1'b1; // Instruction done! + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I1; + end + else + begin + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_ALU_EA; + end + end + end + + CPUSTATE_IDX_DOFF_DONTCARE1: + begin + addr_nxt = pc_p1; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_IDX_DOFF_DONTCARE2; + end + + CPUSTATE_IDX_DOFF_DONTCARE2: + begin + addr_nxt = pc_p2; + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_IDX_16OFF_DONTCARE2; + end + + CPUSTATE_IDX_DOFF_DONTCARE3: + begin + addr_nxt = pc_p3; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_IDX_DOFF_DONTCARE2; + end + + CPUSTATE_IDX_EXTIND_LO: + begin + ea_nxt[7:0] = D[7:0]; + addr_nxt = pc; + pc_nxt = pc_p1; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_IDX_EXTIND_DONTCARE; + end + + CPUSTATE_IDX_EXTIND_DONTCARE: + begin + addr_nxt = pc; + if (IndexedIndirect) + begin + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_INDIRECT_HI; + end + else + begin + if (IsJMP(Inst1)) + begin + pc_nxt = ea; + rLIC = 1'b1; // Instruction done! + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I1; + end + else + begin + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_ALU_EA; + end + end + end + + CPUSTATE_INDIRECT_HI: + begin + addr_nxt = ea; + tmp_nxt[15:8] = D[7:0]; + rAVMA = 1'b1; + rBUSY = 1'b1; + CpuState_nxt = CPUSTATE_INDIRECT_LO; + end + + CPUSTATE_INDIRECT_LO: + begin + addr_nxt = ea_p1; + ea_nxt[15:8] = tmp_nxt[15:8]; + ea_nxt[7:0] = D[7:0]; + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_INDIRECT_DONTCARE; + end + + CPUSTATE_INDIRECT_DONTCARE: + begin + addr_nxt = 16'HFFFF; + if (IsJMP(Inst1)) + begin + pc_nxt = ea; + rLIC = 1'b1; // Instruction done! + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I1; + end + else + begin + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_ALU_EA; + end + end + + CPUSTATE_MUL_ACTION: + begin + addr_nxt = 16'HFFFF; + rAVMA = 1'b0; + // tmp = result + // ea = additor (the shifted multiplicand) + // a = counter + // b is the multiplier (which gets shifted right) + if (a != 8'H00) + begin + if (b[0]) + begin + tmp_nxt = tmp + ea; + end + ea_nxt = {ea[14:0], 1'b0}; + b_nxt = {1'b0, b[7:1]}; + a_nxt = a - 8'H1; + end + else + begin + {a_nxt, b_nxt} = tmp; + + cc_nxt[CC_Z_BIT] = (tmp == 0); + cc_nxt[CC_C_BIT] = tmp[7]; + rLIC = 1'b1; // Instruction done! + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I1; + end + end + + CPUSTATE_PSH_DONTCARE1: + begin + addr_nxt = 16'HFFFF; + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_PSH_DONTCARE2; + end + + CPUSTATE_PSH_DONTCARE2: + begin + addr_nxt = 16'HFFFF; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_PSH_DONTCARE3; + end + + CPUSTATE_PSH_DONTCARE3: + begin + addr_nxt = (Inst1[1]) ? u : s; + + CpuState_nxt = CPUSTATE_PSH_ACTION; + end + + CPUSTATE_PSH_ACTION: + begin + rAVMA = 1'b1; + if (tmp[7] & ~(tmp[15])) // PC_LO + begin + addr_nxt = (tmp[14]) ? u_m1 : s_m1; + if (tmp[14]) + u_nxt = u_m1; + else + s_nxt = s_m1; + DOutput = pc[7:0]; + RnWOut = 1'b0; // write + tmp_nxt[15] = 1'b1; + end + else if (tmp[7] & (tmp[15])) // PC_HI + begin + addr_nxt = (tmp[14]) ? u_m1 : s_m1; + if (tmp[14]) + u_nxt = u_m1; + else + s_nxt = s_m1; + DOutput = pc[15:8]; + RnWOut = 1'b0; // write + tmp_nxt[7] = 1'b0; + tmp_nxt[15] = 1'b0; + end + else if (tmp[6] & ~(tmp[15])) // U/S_LO + begin + addr_nxt = (tmp[14]) ? u_m1 : s_m1; + if (tmp[14]) + u_nxt = u_m1; + else + s_nxt = s_m1; + DOutput = (tmp[14]) ? s[7:0] : u[7:0]; + RnWOut = 1'b0; // write + tmp_nxt[15] = 1'b1; + end + else if (tmp[6] & (tmp[15])) // U/S_HI + begin + addr_nxt = (tmp[14]) ? u_m1 : s_m1; + if (tmp[14]) + u_nxt = u_m1; + else + s_nxt = s_m1; + DOutput = (tmp[14]) ? s[15:8] : u[15:8]; + RnWOut = 1'b0; // write + tmp_nxt[6] = 1'b0; + tmp_nxt[15] = 1'b0; + end + else if (tmp[5] & ~(tmp[15])) // Y_LO + begin + addr_nxt = (tmp[14]) ? u_m1 : s_m1; + if (tmp[14]) + u_nxt = u_m1; + else + s_nxt = s_m1; + DOutput = y[7:0]; + RnWOut = 1'b0; // write + tmp_nxt[15] = 1'b1; + end + else if (tmp[5] & (tmp[15])) // Y_HI + begin + addr_nxt = (tmp[14]) ? u_m1 : s_m1; + if (tmp[14]) + u_nxt = u_m1; + else + s_nxt = s_m1; + DOutput = y[15:8]; + RnWOut = 1'b0; // write + tmp_nxt[5] = 1'b0; + tmp_nxt[15] = 1'b0; + end + else if (tmp[4] & ~(tmp[15])) // X_LO + begin + addr_nxt = (tmp[14]) ? u_m1 : s_m1; + if (tmp[14]) + u_nxt = u_m1; + else + s_nxt = s_m1; + DOutput = x[7:0]; + RnWOut = 1'b0; // write + tmp_nxt[15] = 1'b1; + end + else if (tmp[4] & (tmp[15])) // X_HI + begin + addr_nxt = (tmp[14]) ? u_m1 : s_m1; + if (tmp[14]) + u_nxt = u_m1; + else + s_nxt = s_m1; + DOutput = x[15:8]; + RnWOut = 1'b0; // write + tmp_nxt[4] = 1'b0; + tmp_nxt[15] = 1'b0; + end + else if (tmp[3]) // DP + begin + addr_nxt = (tmp[14]) ? u_m1 : s_m1; + if (tmp[14]) + u_nxt = u_m1; + else + s_nxt = s_m1; + DOutput = dp; + RnWOut = 1'b0; // write + tmp_nxt[3] = 1'b0; + end + else if (tmp[2]) // B + begin + addr_nxt = (tmp[14]) ? u_m1 : s_m1; + if (tmp[14]) + u_nxt = u_m1; + else + s_nxt = s_m1; + DOutput = b; + RnWOut = 1'b0; // write + tmp_nxt[2] = 1'b0; + end + else if (tmp[1]) // A + begin + addr_nxt = (tmp[14]) ? u_m1 : s_m1; + if (tmp[14]) + u_nxt = u_m1; + else + s_nxt = s_m1; + DOutput = a; + RnWOut = 1'b0; // write + tmp_nxt[1] = 1'b0; + end + else if (tmp[0]) // CC + begin + addr_nxt = (tmp[14]) ? u_m1 : s_m1; + if (tmp[14]) + u_nxt = u_m1; + else + s_nxt = s_m1; + DOutput = cc; + RnWOut = 1'b0; // write + tmp_nxt[0] = 1'b0; + end + if (tmp[13]) // Then we're pushing for an IRQ, and LIC is supposed to be set. + rLIC = 1'b1; + if (tmp_nxt[7:0] == 8'H00) + begin + if (NextState == CPUSTATE_FETCH_I1) + begin + rAVMA = 1'b1; + rLIC = 1'b1; + end + else + rAVMA = 1'b0; + CpuState_nxt = NextState; + end + end + + CPUSTATE_PUL_DONTCARE1: + begin + addr_nxt = 16'HFFFF; + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_PUL_DONTCARE2; + end + + CPUSTATE_PUL_DONTCARE2: + begin + addr_nxt = 16'HFFFF; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_PUL_ACTION; + end + + CPUSTATE_PUL_ACTION: + begin + rAVMA = 1'b1; + if (tmp[0]) // CC + begin + addr_nxt = (tmp[14]) ? u : s; + if (tmp[14]) + u_nxt = u_p1; + else + s_nxt = s_p1; + cc_nxt = D[7:0]; + if (tmp[12] == 1'b1) // This pull is from an RTI, the E flag comes from the retrieved CC, and set the tmp_nxt accordingly, indicating what other registers to retrieve + begin + if (D[CC_E_BIT]) + tmp_nxt[7:0] = 8'HFE; // Retrieve all registers (ENTIRE) [CC is already retrieved] + else + tmp_nxt[7:0] = 8'H80; // Retrieve PC and CC [CC is already retrieved] + end + else + tmp_nxt[0] = 1'b0; + end + else if (tmp[1]) // A + begin + addr_nxt = (tmp[14]) ? u : s; + if (tmp[14]) + u_nxt = u_p1; + else + s_nxt = s_p1; + a_nxt = D[7:0]; + tmp_nxt[1] = 1'b0; + end + else if (tmp[2]) // B + begin + addr_nxt = (tmp[14]) ? u : s; + if (tmp[14]) + u_nxt = u_p1; + else + s_nxt = s_p1; + b_nxt = D[7:0]; + tmp_nxt[2] = 1'b0; + end + else if (tmp[3]) // DP + begin + addr_nxt = (tmp[14]) ? u : s; + if (tmp[14]) + u_nxt = u_p1; + else + s_nxt = s_p1; + dp_nxt = D[7:0]; + tmp_nxt[3] = 1'b0; + end + else if (tmp[4] & (~tmp[15])) // X_HI + begin + addr_nxt = (tmp[14]) ? u : s; + if (tmp[14]) + u_nxt = u_p1; + else + s_nxt = s_p1; + x_nxt[15:8] = D[7:0]; + tmp_nxt[15] = 1'b1; + end + else if (tmp[4] & tmp[15]) // X_LO + begin + addr_nxt = (tmp[14]) ? u : s; + if (tmp[14]) + u_nxt = u_p1; + else + s_nxt = s_p1; + x_nxt[7:0] = D[7:0]; + tmp_nxt[4] = 1'b0; + tmp_nxt[15] = 1'b0; + end + else if (tmp[5] & (~tmp[15])) // Y_HI + begin + addr_nxt = (tmp[14]) ? u : s; + if (tmp[14]) + u_nxt = u_p1; + else + s_nxt = s_p1; + y_nxt[15:8] = D[7:0]; + tmp_nxt[15] = 1'b1; + end + else if (tmp[5] & tmp[15]) // Y_LO + begin + addr_nxt = (tmp[14]) ? u : s; + if (tmp[14]) + u_nxt = u_p1; + else + s_nxt = s_p1; + y_nxt[7:0] = D[7:0]; + tmp_nxt[5] = 1'b0; + tmp_nxt[15] = 1'b0; + end + else if (tmp[6] & (~tmp[15])) // U/S_HI + begin + addr_nxt = (tmp[14]) ? u : s; + if (tmp[14]) + u_nxt = u_p1; + else + s_nxt = s_p1; + if (tmp[14]) + s_nxt[15:8] = D[7:0]; + else + u_nxt[15:8] = D[7:0]; + tmp_nxt[15] = 1'b1; + end + else if (tmp[6] & tmp[15]) // U/S_LO + begin + addr_nxt = (tmp[14]) ? u : s; + if (tmp[14]) + u_nxt = u_p1; + else + s_nxt = s_p1; + if (tmp[14]) + s_nxt[7:0] = D[7:0]; + else + u_nxt[7:0] = D[7:0]; + tmp_nxt[6] = 1'b0; + tmp_nxt[15] = 1'b0; + end + else if (tmp[7] & (~tmp[15])) // PC_HI + begin + addr_nxt = (tmp[14]) ? u : s; + if (tmp[14]) + u_nxt = u_p1; + else + s_nxt = s_p1; + pc_nxt[15:8] = D[7:0]; + tmp_nxt[15] = 1'b1; + end + else if (tmp[7] & tmp[15]) // PC_LO + begin + addr_nxt = (tmp[14]) ? u : s; + if (tmp[14]) + u_nxt = u_p1; + else + s_nxt = s_p1; + pc_nxt[7:0] = D[7:0]; + tmp_nxt[7] = 1'b0; + tmp_nxt[15] = 1'b0; + end + else + begin + addr_nxt = (tmp[14]) ? u : s; + if (NextState == CPUSTATE_FETCH_I1) + begin + rAVMA = 1'b1; + rLIC = 1'b1; + end + else + rAVMA = 1'b0; + CpuState_nxt = NextState; + end + end + + CPUSTATE_NMI_START: + begin + NMIClear_nxt = 1'b1; + addr_nxt = pc; + // tmp stands as the bits to push to the stack + tmp_nxt = 16'H20FF; // Save to the S stack, PC, U, Y, X, DP, B, A, CC; set LIC on every push + NextState_nxt = CPUSTATE_IRQ_DONTCARE2; + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_IRQ_DONTCARE; + IntType_nxt = INTTYPE_NMI; + cc_nxt[CC_E_BIT] = 1'b1; + end + + CPUSTATE_IRQ_START: + begin + addr_nxt = pc; + tmp_nxt = 16'H20FF; // Save to the S stack, PC, U, Y, X, DP, B, A, CC; set LIC on every push + NextState_nxt = CPUSTATE_IRQ_DONTCARE2; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_IRQ_DONTCARE; + IntType_nxt = INTTYPE_IRQ; + cc_nxt[CC_E_BIT] = 1'b1; + end + + CPUSTATE_FIRQ_START: + begin + addr_nxt = pc; + tmp_nxt = 16'H2081; // Save to the S stack, PC, CC; set LIC on every push + NextState_nxt = CPUSTATE_IRQ_DONTCARE2; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_IRQ_DONTCARE; + IntType_nxt = INTTYPE_FIRQ; + cc_nxt[CC_E_BIT] = 1'b0; + end + + CPUSTATE_SWI_START: + begin + addr_nxt = pc; + tmp_nxt = 16'H00FF; // Save to the S stack, PC, U, Y, X, DP, B, A, CC + + NextState_nxt = CPUSTATE_IRQ_DONTCARE2; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_IRQ_DONTCARE; + if (InstPage3) + IntType_nxt = INTTYPE_SWI3; + if (InstPage2) + IntType_nxt = INTTYPE_SWI2; + else + IntType_nxt = INTTYPE_SWI; + + cc_nxt[CC_E_BIT] = 1'b1; + end + + CPUSTATE_IRQ_DONTCARE: + begin + NMIClear_nxt = 1'b0; + addr_nxt = 16'HFFFF; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_PSH_ACTION; + end + + + CPUSTATE_IRQ_DONTCARE2: + begin + addr_nxt = 16'HFFFF; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_IRQ_VECTOR_HI; + rLIC = 1'b1; + end + + CPUSTATE_IRQ_VECTOR_HI: + begin + case (IntType) + INTTYPE_NMI: + begin + addr_nxt = `NMI_VECTOR; + BS_nxt = 1'b1; // ACK Interrupt + end + INTTYPE_IRQ: + begin + addr_nxt = `IRQ_VECTOR; + BS_nxt = 1'b1; // ACK Interrupt + end + INTTYPE_SWI: + begin + addr_nxt = `SWI_VECTOR; + end + INTTYPE_FIRQ: + begin + addr_nxt = `FIRQ_VECTOR; + BS_nxt = 1'b1; // ACK Interrupt + end + INTTYPE_SWI2: + begin + addr_nxt = `SWI2_VECTOR; + end + INTTYPE_SWI3: + begin + addr_nxt = `SWI3_VECTOR; + end + default: // make the default an IRQ, even though it really should never happen + begin + addr_nxt = `IRQ_VECTOR; + BS_nxt = 1'b1; // ACK Interrupt + end + endcase + + pc_nxt[15:8] = D[7:0]; + rAVMA = 1'b1; + rBUSY = 1'b1; + rLIC = 1'b1; + CpuState_nxt = CPUSTATE_IRQ_VECTOR_LO; + + + end + + CPUSTATE_IRQ_VECTOR_LO: + begin + case (IntType) + INTTYPE_NMI: + begin + addr_nxt = `NMI_VECTOR+16'H1; + cc_nxt[CC_I_BIT] = 1'b1; + cc_nxt[CC_F_BIT] = 1'b1; + BS_nxt = 1'b1; // ACK Interrupt + end + INTTYPE_IRQ: + begin + addr_nxt = `IRQ_VECTOR+16'H1; + cc_nxt[CC_I_BIT] = 1'b1; + BS_nxt = 1'b1; // ACK Interrupt + end + INTTYPE_SWI: + begin + addr_nxt = `SWI_VECTOR+16'H1; + cc_nxt[CC_F_BIT] = 1'b1; + cc_nxt[CC_I_BIT] = 1'b1; + rLIC = 1'b1; + end + INTTYPE_FIRQ: + begin + addr_nxt = `FIRQ_VECTOR+16'H1; + cc_nxt[CC_F_BIT] = 1'b1; + cc_nxt[CC_I_BIT] = 1'b1; + BS_nxt = 1'b1; // ACK Interrupt + end + INTTYPE_SWI2: + begin + addr_nxt = `SWI2_VECTOR+16'H1; + rLIC = 1'b1; + end + INTTYPE_SWI3: + begin + addr_nxt = `SWI3_VECTOR+16'H1; + rLIC = 1'b1; + end + default: + begin + end + endcase + + pc_nxt[7:0] = D[7:0]; + rAVMA = 1'b1; + rLIC = 1'b1; + CpuState_nxt = CPUSTATE_INT_DONTCARE; + end + + CPUSTATE_INT_DONTCARE: + begin + addr_nxt = 16'HFFFF; + rAVMA = 1'b1; + rLIC = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I1; + end + + CPUSTATE_CC_DONTCARE: + begin + addr_nxt = pc; + rLIC = 1'b1; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I1; + end + + CPUSTATE_TST_DONTCARE1: + begin + addr_nxt = 16'HFFFF; + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_TST_DONTCARE2; + end + + CPUSTATE_TST_DONTCARE2: + begin + addr_nxt = 16'HFFFF; + rLIC = 1'b1; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I1; + end + + CPUSTATE_DEBUG: + begin + addr_nxt = tmp; + rLIC = 1'b1; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I1; + end + + CPUSTATE_16IMM_DONTCARE: + begin + addr_nxt = 16'HFFFF; + rLIC = 1'b1; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I1; + end + + CPUSTATE_SYNC: + begin + addr_nxt = 16'HFFFF; + BA_nxt = 1'b1; + rLIC = 1'b1; + rAVMA = 1'b0; + + if (~(NMILatched & FIRQLatched & IRQLatched)) + begin + CpuState_nxt = CPUSTATE_SYNC_EXIT; + end + end + + CPUSTATE_SYNC_EXIT: + begin + addr_nxt = 16'HFFFF; + BA_nxt = 1'b1; + rLIC = 1'b1; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I1; + end + + + CPUSTATE_DMABREQ: + begin + rAVMA = 1'b0; + addr_nxt = 16'HFFFF; + BS_nxt = 1'b1; + BA_nxt = 1'b1; + rLIC = 1'b1; + tmp_nxt[3:0] = tmp[3:0] - 1'b1; + if ( (tmp[3:0] == 4'H0) | (DMABREQSample2) ) + begin + CpuState_nxt = CPUSTATE_DMABREQ_EXIT; + end + end + + CPUSTATE_DMABREQ_EXIT: + begin + addr_nxt = 16'HFFFF; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I1; + end + + CPUSTATE_HALTED: + begin + rAVMA = 1'b0; + addr_nxt = 16'HFFFF; + BS_nxt = 1'b1; + BA_nxt = 1'b1; + rLIC = 1'b1; + if (HALTSample2) + begin + CpuState_nxt = CPUSTATE_HALT_EXIT2; + end + end + + + CPUSTATE_HALT_EXIT2: + begin + addr_nxt = 16'HFFFF; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_FETCH_I1; + end + + CPUSTATE_STOP: + begin + addr_nxt = 16'HDEAD; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_STOP2; + end + + CPUSTATE_STOP2: + begin + addr_nxt = pc; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_STOP3; + end + + CPUSTATE_STOP3: + begin + addr_nxt = 16'H0000; //{Inst1, Inst2}; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_STOP; + end + + // The otherwise critically useful Figure 18 in the 6809 datasheet contains an error; + // it lists that CWAI has a tri-stated bus while it waits for an interrupt. + // That is not true. SYNC tristates the bus, as do things like /HALT and /DMABREQ. + // CWAI does not. It waits with /VMA cycles on the bus until an interrupt occurs. + // The implementation here fits with the 6809 Programming Manual and other Motorola + // sources, not with that typo in Figure 18. + CPUSTATE_CWAI: + begin + addr_nxt = pc; + cc_nxt = {1'b1, (cc[6:0] & Inst2[6:0])}; // Set E flag, AND CC with CWAI argument + tmp_nxt = 16'H00FF; // Save to the S stack, PC, U, Y, X, DP, B, A, CC + + NextState_nxt = CPUSTATE_CWAI_POST; + rAVMA = 1'b0; + CpuState_nxt = CPUSTATE_CWAI_DONTCARE1; + end + + CPUSTATE_CWAI_DONTCARE1: + begin + addr_nxt = 16'HFFFF; + rAVMA = 1'b1; + CpuState_nxt = CPUSTATE_PSH_ACTION; + end + + CPUSTATE_CWAI_POST: + begin + addr_nxt = 16'HFFFF; + rAVMA = 1'b0; + + CpuState_nxt = CPUSTATE_CWAI_POST; + + // Wait for an interrupt + if (NMILatched == 0) + begin + rAVMA = 1'b1; + IntType_nxt = INTTYPE_NMI; + cc_nxt[CC_F_BIT] = 1'b1; + cc_nxt[CC_I_BIT] = 1'b1; + CpuState_nxt = CPUSTATE_IRQ_VECTOR_HI; + end + else if ((FIRQLatched == 0) && (cc[CC_F_BIT] == 0)) + begin + rAVMA = 1'b1; + cc_nxt[CC_F_BIT] = 1'b1; + cc_nxt[CC_I_BIT] = 1'b1; + IntType_nxt = INTTYPE_FIRQ; + CpuState_nxt = CPUSTATE_IRQ_VECTOR_HI; + end + else if ((IRQLatched == 0) && (cc[CC_I_BIT] == 0)) + begin + rAVMA = 1'b1; + cc_nxt[CC_I_BIT] = 1'b1; + IntType_nxt = INTTYPE_IRQ; + CpuState_nxt = CPUSTATE_IRQ_VECTOR_HI; + end + end + + default: // Picky darned Verilog. + begin + CpuState_nxt = PostIllegalState; + end + + endcase +end + +endmodule + diff --git a/Arcade_MiST/Mappy Hardware/rtl/mems.v b/Arcade_MiST/Mappy Hardware/rtl/mems.v new file mode 100644 index 00000000..ccde3726 --- /dev/null +++ b/Arcade_MiST/Mappy Hardware/rtl/mems.v @@ -0,0 +1,102 @@ +module mems +( + input CPUCLKx2, + output [14:0] rom_addr, + input [7:0] rom_data, + input [15:0] MCPU_ADRS, + input MCPU_VMA, + input MCPU_WE, + input [7:0] MCPU_DO, + output [7:0] MCPU_DI, + output IO_CS, + input [7:0] IO_O, + + input [15:0] SCPU_ADRS, + input SCPU_VMA, + input SCPU_WE, + input [7:0] SCPU_DO, + output [7:0] SCPU_DI, + output SCPU_WSG_WE, + + input VCLKx4, + input [10:0] vram_a, + output [15:0] vram_d, + input [6:0] spra_a, + output [23:0] spra_d, + + + input ROMCL, // Downloaded ROM image + input [16:0] ROMAD, + input [7:0] ROMDT, + input ROMEN +); + +//wire [7:0] mrom_d; +wire [7:0] srom_d; +assign rom_addr = MCPU_ADRS[14:0]; +//assign mrom_d = rom_data; + +scpui_rom scpui_rom( + .clk(CPUCLKx2), + .addr(SCPU_ADRS[12:0]), + .data(srom_d) +); + + +wire mram_cs0 = ( MCPU_ADRS[15:11] == 5'b00000 ) & MCPU_VMA; // $0000-$07FF +wire mram_cs1 = ( MCPU_ADRS[15:11] == 5'b00001 ) & MCPU_VMA; // $0800-$0FFF +wire mram_cs2 = ( MCPU_ADRS[15:11] == 5'b00010 ) & MCPU_VMA; // $1000-$17FF +wire mram_cs3 = ( MCPU_ADRS[15:11] == 5'b00011 ) & MCPU_VMA; // $1800-$1FFF +wire mram_cs4 = ( MCPU_ADRS[15:11] == 5'b00100 ) & MCPU_VMA; // $2000-$27FF +wire mram_cs5 = ( MCPU_ADRS[15:10] == 6'b010000 ) & MCPU_VMA; // $4000-$43FF +assign IO_CS = ( MCPU_ADRS[15:11] == 5'b01001 ) & MCPU_VMA; // $4800-$4FFF +wire mrom_cs = ( MCPU_ADRS[15] ) & MCPU_VMA; // $8000-$FFFF + +wire mram_w0 = ( mram_cs0 & MCPU_WE ); +wire mram_w1 = ( mram_cs1 & MCPU_WE ); +wire mram_w2 = ( mram_cs2 & MCPU_WE ); +wire mram_w3 = ( mram_cs3 & MCPU_WE ); +wire mram_w4 = ( mram_cs4 & MCPU_WE ); +wire mram_w5 = ( mram_cs5 & MCPU_WE ); + +wire [7:0] mram_o0, mram_o1, mram_o2, mram_o3, mram_o4, mram_o5; + +assign MCPU_DI = mram_cs0 ? mram_o0 : + mram_cs1 ? mram_o1 : + mram_cs2 ? mram_o2 : + mram_cs3 ? mram_o3 : + mram_cs4 ? mram_o4 : + mram_cs5 ? mram_o5 : + mrom_cs ? rom_data ://mrom_d : + IO_CS ? IO_O : + 8'h0; + +wire [10:0] mram_ad = MCPU_ADRS[10:0]; + +DPRAM_2048V main_ram0( CPUCLKx2, mram_ad, MCPU_DO, mram_o0, mram_w0, VCLKx4, vram_a, vram_d[7:0] ); +DPRAM_2048V main_ram1( CPUCLKx2, mram_ad, MCPU_DO, mram_o1, mram_w1, VCLKx4, vram_a, vram_d[15:8] ); + +DPRAM_2048V main_ram2( CPUCLKx2, mram_ad, MCPU_DO, mram_o2, mram_w2, VCLKx4, { 4'b1111, spra_a }, spra_d[7:0] ); +DPRAM_2048V main_ram3( CPUCLKx2, mram_ad, MCPU_DO, mram_o3, mram_w3, VCLKx4, { 4'b1111, spra_a }, spra_d[15:8] ); +DPRAM_2048V main_ram4( CPUCLKx2, mram_ad, MCPU_DO, mram_o4, mram_w4, VCLKx4, { 4'b1111, spra_a }, spra_d[23:16] ); + + + // (SCPU ADRS) +wire SCPU_CS_SREG = ( ( SCPU_ADRS[15:13] == 3'b000 ) & ( SCPU_ADRS[9:6] == 4'b0000 ) ) & SCPU_VMA; +wire srom_cs = ( SCPU_ADRS[15:13] == 3'b111 ) & SCPU_VMA; // $E000-$FFFF +wire sram_cs0 = (~SCPU_CS_SREG) & (~srom_cs) & SCPU_VMA; // $0000-$03FF +wire [7:0] sram_o0; + +assign SCPU_DI = sram_cs0 ? sram_o0 : + srom_cs ? srom_d : + 8'h0; + +assign SCPU_WSG_WE = SCPU_CS_SREG & SCPU_WE; + +DPRAM_2048 share_ram +( + CPUCLKx2, mram_ad, MCPU_DO, mram_o5, mram_w5, + CPUCLKx2, { 1'b0, SCPU_ADRS[9:0] }, SCPU_DO, sram_o0, sram_cs0 & SCPU_WE +); + +endmodule \ No newline at end of file diff --git a/Arcade_MiST/Mappy Hardware/rtl/pll.v b/Arcade_MiST/Mappy Hardware/rtl/pll.v new file mode 100644 index 00000000..d8ab4161 --- /dev/null +++ b/Arcade_MiST/Mappy Hardware/rtl/pll.v @@ -0,0 +1,337 @@ +// megafunction wizard: %ALTPLL% +// GENERATION: STANDARD +// VERSION: WM1.0 +// MODULE: altpll + +// ============================================================ +// File Name: pll.v +// Megafunction Name(s): +// altpll +// +// Simulation Library Files(s): +// altera_mf +// ============================================================ +// ************************************************************ +// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! +// +// 13.1.4 Build 182 03/12/2014 Patches 4.26 SJ Web Edition +// ************************************************************ + + +//Copyright (C) 1991-2014 Altera Corporation +//Your use of Altera Corporation's design tools, logic functions +//and other software and tools, and its AMPP partner logic +//functions, and any output files from any of the foregoing +//(including device programming or simulation files), and any +//associated documentation or information are expressly subject +//to the terms and conditions of the Altera Program License +//Subscription Agreement, Altera MegaCore Function License +//Agreement, or other applicable license agreement, including, +//without limitation, that your use is for the sole purpose of +//programming logic devices manufactured by Altera and sold by +//Altera or its authorized distributors. Please refer to the +//applicable agreement for further details. + + +// synopsys translate_off +`timescale 1 ps / 1 ps +// synopsys translate_on +module pll ( + inclk0, + c0, + c1, + locked); + + input inclk0; + output c0; + output c1; + output locked; + + wire [4:0] sub_wire0; + wire sub_wire2; + wire [0:0] sub_wire6 = 1'h0; + wire [0:0] sub_wire3 = sub_wire0[0:0]; + wire [1:1] sub_wire1 = sub_wire0[1:1]; + wire c1 = sub_wire1; + wire locked = sub_wire2; + wire c0 = sub_wire3; + wire sub_wire4 = inclk0; + wire [1:0] sub_wire5 = {sub_wire6, sub_wire4}; + + altpll altpll_component ( + .inclk (sub_wire5), + .clk (sub_wire0), + .locked (sub_wire2), + .activeclock (), + .areset (1'b0), + .clkbad (), + .clkena ({6{1'b1}}), + .clkloss (), + .clkswitch (1'b0), + .configupdate (1'b0), + .enable0 (), + .enable1 (), + .extclk (), + .extclkena ({4{1'b1}}), + .fbin (1'b1), + .fbmimicbidir (), + .fbout (), + .fref (), + .icdrclk (), + .pfdena (1'b1), + .phasecounterselect ({4{1'b1}}), + .phasedone (), + .phasestep (1'b1), + .phaseupdown (1'b1), + .pllena (1'b1), + .scanaclr (1'b0), + .scanclk (1'b0), + .scanclkena (1'b1), + .scandata (1'b0), + .scandataout (), + .scandone (), + .scanread (1'b0), + .scanwrite (1'b0), + .sclkout0 (), + .sclkout1 (), + .vcooverrange (), + .vcounderrange ()); + defparam + altpll_component.bandwidth_type = "AUTO", + altpll_component.clk0_divide_by = 9, + altpll_component.clk0_duty_cycle = 50, + altpll_component.clk0_multiply_by = 16, + altpll_component.clk0_phase_shift = "0", + altpll_component.clk1_divide_by = 9, + altpll_component.clk1_duty_cycle = 50, + altpll_component.clk1_multiply_by = 2, + altpll_component.clk1_phase_shift = "0", + altpll_component.compensate_clock = "CLK0", + altpll_component.inclk0_input_frequency = 37037, + altpll_component.intended_device_family = "Cyclone III", + altpll_component.lpm_hint = "CBX_MODULE_PREFIX=pll", + altpll_component.lpm_type = "altpll", + altpll_component.operation_mode = "NORMAL", + altpll_component.pll_type = "AUTO", + altpll_component.port_activeclock = "PORT_UNUSED", + altpll_component.port_areset = "PORT_UNUSED", + altpll_component.port_clkbad0 = "PORT_UNUSED", + altpll_component.port_clkbad1 = "PORT_UNUSED", + altpll_component.port_clkloss = "PORT_UNUSED", + altpll_component.port_clkswitch = "PORT_UNUSED", + altpll_component.port_configupdate = "PORT_UNUSED", + altpll_component.port_fbin = "PORT_UNUSED", + altpll_component.port_inclk0 = "PORT_USED", + altpll_component.port_inclk1 = "PORT_UNUSED", + altpll_component.port_locked = "PORT_USED", + altpll_component.port_pfdena = "PORT_UNUSED", + altpll_component.port_phasecounterselect = "PORT_UNUSED", + altpll_component.port_phasedone = "PORT_UNUSED", + altpll_component.port_phasestep = "PORT_UNUSED", + altpll_component.port_phaseupdown = "PORT_UNUSED", + altpll_component.port_pllena = "PORT_UNUSED", + altpll_component.port_scanaclr = "PORT_UNUSED", + altpll_component.port_scanclk = "PORT_UNUSED", + altpll_component.port_scanclkena = "PORT_UNUSED", + altpll_component.port_scandata = "PORT_UNUSED", + altpll_component.port_scandataout = "PORT_UNUSED", + altpll_component.port_scandone = "PORT_UNUSED", + altpll_component.port_scanread = "PORT_UNUSED", + altpll_component.port_scanwrite = "PORT_UNUSED", + altpll_component.port_clk0 = "PORT_USED", + altpll_component.port_clk1 = "PORT_USED", + altpll_component.port_clk2 = "PORT_UNUSED", + altpll_component.port_clk3 = "PORT_UNUSED", + altpll_component.port_clk4 = "PORT_UNUSED", + altpll_component.port_clk5 = "PORT_UNUSED", + altpll_component.port_clkena0 = "PORT_UNUSED", + altpll_component.port_clkena1 = "PORT_UNUSED", + altpll_component.port_clkena2 = "PORT_UNUSED", + altpll_component.port_clkena3 = "PORT_UNUSED", + altpll_component.port_clkena4 = "PORT_UNUSED", + altpll_component.port_clkena5 = "PORT_UNUSED", + altpll_component.port_extclk0 = "PORT_UNUSED", + altpll_component.port_extclk1 = "PORT_UNUSED", + altpll_component.port_extclk2 = "PORT_UNUSED", + altpll_component.port_extclk3 = "PORT_UNUSED", + altpll_component.self_reset_on_loss_lock = "OFF", + altpll_component.width_clock = 5; + + +endmodule + +// ============================================================ +// CNX file retrieval info +// ============================================================ +// Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0" +// Retrieval info: PRIVATE: BANDWIDTH STRING "1.000" +// Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "1" +// Retrieval info: PRIVATE: BANDWIDTH_FREQ_UNIT STRING "MHz" +// Retrieval info: PRIVATE: BANDWIDTH_PRESET STRING "Low" +// Retrieval info: PRIVATE: BANDWIDTH_USE_AUTO STRING "1" +// Retrieval info: PRIVATE: BANDWIDTH_USE_PRESET STRING "0" +// Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0" +// Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0" +// Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "0" +// Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "0" +// Retrieval info: PRIVATE: CREATE_CLKBAD_CHECK STRING "0" +// Retrieval info: PRIVATE: CREATE_INCLK1_CHECK STRING "0" +// Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0" +// Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "c0" +// Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "8" +// Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "1" +// Retrieval info: PRIVATE: DIV_FACTOR1 NUMERIC "1" +// Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000" +// Retrieval info: PRIVATE: DUTY_CYCLE1 STRING "50.00000000" +// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "48.000000" +// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "6.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: MIG_DEVICE_SPEED_GRADE STRING "Any" +// Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0" +// Retrieval info: PRIVATE: MIRROR_CLK1 STRING "0" +// Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "1" +// Retrieval info: PRIVATE: MULT_FACTOR1 NUMERIC "1" +// Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1" +// Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "48.00000000" +// Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "6.00000000" +// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "1" +// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE1 STRING "1" +// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz" +// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT1 STRING "MHz" +// Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "1" +// Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0" +// Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000" +// Retrieval info: PRIVATE: PHASE_SHIFT1 STRING "0.00000000" +// Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0" +// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg" +// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT1 STRING "deg" +// Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0" +// Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "0" +// Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1" +// Retrieval info: PRIVATE: PLL_ENHPLL_CHECK NUMERIC "0" +// Retrieval info: PRIVATE: PLL_FASTPLL_CHECK NUMERIC "0" +// Retrieval info: PRIVATE: PLL_FBMIMIC_CHECK STRING "0" +// Retrieval info: PRIVATE: PLL_LVDS_PLL_CHECK NUMERIC "0" +// Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0" +// Retrieval info: PRIVATE: PLL_TARGET_HARCOPY_CHECK NUMERIC "0" +// Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0" +// Retrieval info: PRIVATE: RECONFIG_FILE STRING "pll.mif" +// Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0" +// Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "1" +// Retrieval info: PRIVATE: SELF_RESET_LOCK_LOSS STRING "0" +// Retrieval info: PRIVATE: SHORT_SCAN_RADIO STRING "0" +// Retrieval info: PRIVATE: SPREAD_FEATURE_ENABLED STRING "0" +// Retrieval info: PRIVATE: SPREAD_FREQ STRING "50.000" +// Retrieval info: PRIVATE: SPREAD_FREQ_UNIT STRING "KHz" +// Retrieval info: PRIVATE: SPREAD_PERCENT STRING "0.500" +// Retrieval info: PRIVATE: SPREAD_USE STRING "0" +// Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "0" +// Retrieval info: PRIVATE: STICKY_CLK0 STRING "1" +// Retrieval info: PRIVATE: STICKY_CLK1 STRING "1" +// Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1" +// Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "1" +// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0" +// Retrieval info: PRIVATE: USE_CLK0 STRING "1" +// Retrieval info: PRIVATE: USE_CLK1 STRING "1" +// Retrieval info: PRIVATE: USE_CLKENA0 STRING "0" +// Retrieval info: PRIVATE: USE_CLKENA1 STRING "0" +// Retrieval info: PRIVATE: USE_MIL_SPEED_GRADE NUMERIC "0" +// Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0" +// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all +// Retrieval info: CONSTANT: BANDWIDTH_TYPE STRING "AUTO" +// Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "9" +// Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50" +// Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "16" +// Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0" +// Retrieval info: CONSTANT: CLK1_DIVIDE_BY NUMERIC "9" +// Retrieval info: CONSTANT: CLK1_DUTY_CYCLE NUMERIC "50" +// Retrieval info: CONSTANT: CLK1_MULTIPLY_BY NUMERIC "2" +// Retrieval info: CONSTANT: CLK1_PHASE_SHIFT STRING "0" +// Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0" +// Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "37037" +// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III" +// Retrieval info: CONSTANT: LPM_TYPE STRING "altpll" +// Retrieval info: CONSTANT: OPERATION_MODE STRING "NORMAL" +// Retrieval info: CONSTANT: PLL_TYPE STRING "AUTO" +// Retrieval info: CONSTANT: PORT_ACTIVECLOCK STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_ARESET STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_CLKBAD0 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_CLKBAD1 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_CLKLOSS STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_CLKSWITCH STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_CONFIGUPDATE STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_FBIN STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_INCLK0 STRING "PORT_USED" +// Retrieval info: CONSTANT: PORT_INCLK1 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_LOCKED STRING "PORT_USED" +// Retrieval info: CONSTANT: PORT_PFDENA STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_PHASECOUNTERSELECT STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_PHASEDONE STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_PHASESTEP STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_PHASEUPDOWN STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_PLLENA STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANACLR STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANCLK STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANCLKENA STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANDATA STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANDATAOUT STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANDONE STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANREAD STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANWRITE STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clk0 STRING "PORT_USED" +// Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_USED" +// Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clk5 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena0 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena1 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena2 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena3 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena4 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena5 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_extclk0 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_extclk1 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_extclk2 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_extclk3 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: SELF_RESET_ON_LOSS_LOCK STRING "OFF" +// Retrieval info: CONSTANT: WIDTH_CLOCK NUMERIC "5" +// Retrieval info: USED_PORT: @clk 0 0 5 0 OUTPUT_CLK_EXT VCC "@clk[4..0]" +// Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT_CLK_EXT VCC "c0" +// Retrieval info: USED_PORT: c1 0 0 0 0 OUTPUT_CLK_EXT VCC "c1" +// Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0" +// Retrieval info: USED_PORT: locked 0 0 0 0 OUTPUT GND "locked" +// Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0 +// Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0 +// Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0 +// Retrieval info: CONNECT: c1 0 0 0 0 @clk 0 0 1 1 +// Retrieval info: CONNECT: locked 0 0 0 0 @locked 0 0 0 0 +// Retrieval info: GEN_FILE: TYPE_NORMAL pll.v TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll.ppf TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll.inc FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll.cmp FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll.bsf FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll_inst.v FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll_bb.v FALSE +// Retrieval info: LIB_FILE: altera_mf +// Retrieval info: CBX_MODULE_PREFIX: ON diff --git a/Arcade_MiST/Mappy Hardware/rtl/regs.v b/Arcade_MiST/Mappy Hardware/rtl/regs.v new file mode 100644 index 00000000..b7e11f62 --- /dev/null +++ b/Arcade_MiST/Mappy Hardware/rtl/regs.v @@ -0,0 +1,110 @@ +module regs +( + input MCPU_CLK, + input RESET, + input VBLANK, + + input [15:0] MCPU_ADRS, + input MCPU_VMA, + input MCPU_WE, + + input [15:0] SCPU_ADRS, + input SCPU_VMA, + input SCPU_WE, + + output reg [7:0] SCROLL, + output MCPU_IRQ, + output reg MCPU_IRQEN, + output SCPU_IRQ, + output reg SCPU_IRQEN, + output SCPU_RESET, + output IO_RESET, + output reg PSG_ENABLE +); + +// BG Scroll Register +wire MCPU_SCRWE = ( ( MCPU_ADRS[15:11] == 5'b00111 ) & MCPU_VMA & MCPU_WE ); +always @ ( negedge MCPU_CLK or posedge RESET ) begin + if ( RESET ) SCROLL <= 8'h0; + else if ( MCPU_SCRWE ) SCROLL <= MCPU_ADRS[10:3]; +end + +// MainCPU IRQ Generator +wire MCPU_IRQWE = ( ( MCPU_ADRS[15:1] == 15'b010100000000001 ) & MCPU_VMA & MCPU_WE ); +//wire MCPU_IRQWES = ( ( SCPU_ADRS[15:1] == 15'b001000000000001 ) & SCPU_VMA & SCPU_WE ); +assign MCPU_IRQ = MCPU_IRQEN & VBLANK; + +always @( negedge MCPU_CLK or posedge RESET ) begin + if ( RESET ) begin + MCPU_IRQEN <= 1'b0; + end + else begin + if ( MCPU_IRQWE ) MCPU_IRQEN <= MCPU_ADRS[0]; +// if ( MCPU_IRQWES ) MCPU_IRQEN <= SCPU_ADRS[0]; + end +end + + +// SubCPU IRQ Generator +wire SCPU_IRQWE = ( ( MCPU_ADRS[15:1] == 15'b010100000000000 ) & MCPU_VMA & MCPU_WE ); +wire SCPU_IRQWES = ( ( SCPU_ADRS[15:1] == 15'b001000000000000 ) & SCPU_VMA & SCPU_WE ); +assign SCPU_IRQ = SCPU_IRQEN & VBLANK; + +always @( negedge MCPU_CLK or posedge RESET ) begin + if ( RESET ) begin + SCPU_IRQEN <= 1'b0; + end + else begin + if ( SCPU_IRQWE ) SCPU_IRQEN <= MCPU_ADRS[0]; + if ( SCPU_IRQWES ) SCPU_IRQEN <= SCPU_ADRS[0]; + end +end + + +// SubCPU RESET Control +reg SCPU_RSTf = 1'b0; +wire SCPU_RSTWE = ( ( MCPU_ADRS[15:1] == 15'b010100000000101 ) & MCPU_VMA & MCPU_WE ); +wire SCPU_RSTWES = ( ( SCPU_ADRS[15:1] == 15'b001000000000101 ) & SCPU_VMA & SCPU_WE ); +assign SCPU_RESET = ~SCPU_RSTf; + +always @( negedge MCPU_CLK or posedge RESET ) begin + if ( RESET ) begin + SCPU_RSTf <= 1'b0; + end + else begin + if ( SCPU_RSTWE ) SCPU_RSTf <= MCPU_ADRS[0]; + if ( SCPU_RSTWES ) SCPU_RSTf <= SCPU_ADRS[0]; + end +end + + +// I/O CHIP RESET Control +reg IOCHIP_RSTf = 1'b0; +wire IOCHIP_RSTWE = ( ( MCPU_ADRS[15:1] == 15'b010100000000100 ) & MCPU_VMA & MCPU_WE ); +assign IO_RESET = ~IOCHIP_RSTf; + +always @( negedge MCPU_CLK or posedge RESET ) begin + if ( RESET ) begin + IOCHIP_RSTf <= 1'b0; + end + else begin + if ( IOCHIP_RSTWE ) IOCHIP_RSTf <= MCPU_ADRS[0]; + end +end + + +// Sound Enable Control +wire PSG_ENAWE = ( ( MCPU_ADRS[15:1] == 15'b010100000000011 ) & MCPU_VMA & MCPU_WE ); +wire PSG_ENAWES = ( ( SCPU_ADRS[15:1] == 15'b001000000000011 ) & SCPU_VMA & SCPU_WE ); + +always @( negedge MCPU_CLK or posedge RESET ) begin + if ( RESET ) begin + PSG_ENABLE <= 1'b0; + end + else begin + if ( PSG_ENAWE ) PSG_ENABLE <= MCPU_ADRS[0]; + if ( PSG_ENAWES ) PSG_ENABLE <= SCPU_ADRS[0]; + end +end + +endmodule \ No newline at end of file diff --git a/Arcade_MiST/Mappy Hardware/rtl/sdram.sv b/Arcade_MiST/Mappy Hardware/rtl/sdram.sv new file mode 100644 index 00000000..bc78584d --- /dev/null +++ b/Arcade_MiST/Mappy Hardware/rtl/sdram.sv @@ -0,0 +1,323 @@ +// +// sdram.v +// +// sdram controller implementation for the MiST board +// https://github.com/mist-devel/mist-board +// +// Copyright (c) 2013 Till Harbaum +// Copyright (c) 2019 Gyorgy Szombathelyi +// +// This source file is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This source file is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +module sdram ( + + // interface to the MT48LC16M16 chip + inout reg [15:0] SDRAM_DQ, // 16 bit bidirectional data bus + output reg [12:0] SDRAM_A, // 13 bit multiplexed address bus + output reg SDRAM_DQML, // two byte masks + output reg SDRAM_DQMH, // two byte masks + output reg [1:0] SDRAM_BA, // two banks + output SDRAM_nCS, // a single chip select + output SDRAM_nWE, // write enable + output SDRAM_nRAS, // row address select + output SDRAM_nCAS, // columns address select + + // cpu/chipset interface + input init_n, // init signal after FPGA config to initialize RAM + input clk, // sdram clock + + input port1_req, + output reg port1_ack, + input port1_we, + input [23:1] port1_a, + input [1:0] port1_ds, + input [15:0] port1_d, + output [15:0] port1_q, + + input [15:1] cpu1_addr, + output reg [15:0] cpu1_q, + + input port2_req, + output reg port2_ack, + input port2_we, + input [23:1] port2_a, + input [1:0] port2_ds, + input [15:0] port2_d, + output [15:0] port2_q, + + input [15:1] snd_addr, + output reg [15:0] snd_q +); + +localparam RASCAS_DELAY = 3'd2; // tRCD=20ns -> 2 cycles@<100MHz +localparam BURST_LENGTH = 3'b000; // 000=1, 001=2, 010=4, 011=8 +localparam ACCESS_TYPE = 1'b0; // 0=sequential, 1=interleaved +localparam CAS_LATENCY = 3'd2; // 2/3 allowed +localparam OP_MODE = 2'b00; // only 00 (standard operation) allowed +localparam NO_WRITE_BURST = 1'b1; // 0= write burst enabled, 1=only single access write + +localparam MODE = { 3'b000, NO_WRITE_BURST, OP_MODE, CAS_LATENCY, ACCESS_TYPE, BURST_LENGTH}; + +// 64ms/8192 rows = 7.8us -> 842 cycles@108MHz +localparam RFRSH_CYCLES = 10'd842; + +// --------------------------------------------------------------------- +// ------------------------ cycle state machine ------------------------ +// --------------------------------------------------------------------- + +/* + SDRAM state machine for 2 bank interleaved access + 1 word burst, CL2 +cmd issued registered + 0 RAS0 cas1 + 1 ras0 + 2 CAS0 data1 returned + 3 RAS1 cas0 + 4 ras1 + 5 CAS1 data0 returned +*/ + +localparam STATE_RAS0 = 3'd0; // first state in cycle +localparam STATE_RAS1 = 3'd3; // Second ACTIVE command after RAS0 + tRRD (15ns) +localparam STATE_CAS0 = STATE_RAS0 + RASCAS_DELAY; // CAS phase - 3 +localparam STATE_CAS1 = STATE_RAS1 + RASCAS_DELAY; // CAS phase - 5 +localparam STATE_READ0 = 3'd0; //STATE_CAS0 + CAS_LATENCY + 1'd1; // 7 +localparam STATE_READ1 = 3'd3; +localparam STATE_LAST = 3'd5; + +reg [2:0] t; + +always @(posedge clk) begin + t <= t + 1'd1; + if (t == STATE_LAST) t <= STATE_RAS0; +end + +// --------------------------------------------------------------------- +// --------------------------- startup/reset --------------------------- +// --------------------------------------------------------------------- + +// wait 1ms (32 8Mhz cycles) after FPGA config is done before going +// into normal operation. Initialize the ram in the last 16 reset cycles (cycles 15-0) +reg [4:0] reset; +reg init = 1'b1; +always @(posedge clk, negedge init_n) begin + if(!init_n) begin + reset <= 5'h1f; + init <= 1'b1; + end else begin + if((t == STATE_LAST) && (reset != 0)) reset <= reset - 5'd1; + init <= !(reset == 0); + end +end + +// --------------------------------------------------------------------- +// ------------------ generate ram control signals --------------------- +// --------------------------------------------------------------------- + +// all possible commands +localparam CMD_INHIBIT = 4'b1111; +localparam CMD_NOP = 4'b0111; +localparam CMD_ACTIVE = 4'b0011; +localparam CMD_READ = 4'b0101; +localparam CMD_WRITE = 4'b0100; +localparam CMD_BURST_TERMINATE = 4'b0110; +localparam CMD_PRECHARGE = 4'b0010; +localparam CMD_AUTO_REFRESH = 4'b0001; +localparam CMD_LOAD_MODE = 4'b0000; + +reg [3:0] sd_cmd; // current command sent to sd ram +reg [15:0] sd_din; +// drive control signals according to current command +assign SDRAM_nCS = sd_cmd[3]; +assign SDRAM_nRAS = sd_cmd[2]; +assign SDRAM_nCAS = sd_cmd[1]; +assign SDRAM_nWE = sd_cmd[0]; + +reg [24:1] addr_latch[2]; +reg [24:1] addr_latch_next[2]; +reg [15:1] addr_last[2]; +reg [15:1] addr_last2[2]; +reg [15:0] din_latch[2]; +reg [1:0] oe_latch; +reg [1:0] we_latch; +reg [1:0] ds[2]; + +localparam PORT_NONE = 2'd0; +localparam PORT_CPU1 = 2'd1; +localparam PORT_REQ = 2'd2; + +localparam PORT_SND = 2'd1; + +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 + if (refresh) begin + next_port[0] = PORT_NONE; + addr_latch_next[0] = addr_latch[0]; + end else if (port1_req ^ port1_ack) begin + next_port[0] = PORT_REQ; + addr_latch_next[0] = { 1'b0, port1_a }; + end else if (cpu1_addr != addr_last[PORT_CPU1]) begin + next_port[0] = PORT_CPU1; + addr_latch_next[0] = { 9'd0, cpu1_addr }; + end else begin + next_port[0] = PORT_NONE; + addr_latch_next[0] = addr_latch[0]; + end +end + +// PORT2: bank 2,3 +always @(*) begin + if (port2_req ^ port2_ack) begin + next_port[1] = PORT_REQ; + addr_latch_next[1] = { 1'b1, port2_a }; + end else if (snd_addr != addr_last2[PORT_SND]) begin + next_port[1] = PORT_SND; + addr_latch_next[1] = { 1'b1, 8'd0, snd_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 + // initialization takes place at the end of the reset phase + if(t == STATE_RAS0) begin + + if(reset == 15) begin + sd_cmd <= CMD_PRECHARGE; + SDRAM_A[10] <= 1'b1; // precharge all banks + end + + if(reset == 10 || reset == 8) begin + sd_cmd <= CMD_AUTO_REFRESH; + end + + if(reset == 2) begin + sd_cmd <= CMD_LOAD_MODE; + SDRAM_A <= MODE; + SDRAM_BA <= 2'b00; + end + end + end else begin + // RAS phase + // bank 0,1 + if(t == STATE_RAS0) begin + addr_latch[0] <= addr_latch_next[0]; + port[0] <= next_port[0]; + { oe_latch[0], we_latch[0] } <= 2'b00; + + if (next_port[0] != PORT_NONE) begin + sd_cmd <= CMD_ACTIVE; + SDRAM_A <= addr_latch_next[0][22:10]; + SDRAM_BA <= addr_latch_next[0][24:23]; + addr_last[next_port[0]] <= addr_latch_next[0][15:1]; + if (next_port[0] == PORT_REQ) begin + { oe_latch[0], we_latch[0] } <= { ~port1_we, port1_we }; + ds[0] <= port1_ds; + din_latch[0] <= port1_d; + end else begin + { oe_latch[0], we_latch[0] } <= 2'b10; + ds[0] <= 2'b11; + end + end + end + + // bank 2,3 + if(t == STATE_RAS1) begin + refresh <= 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]; + addr_last2[next_port[1]] <= addr_latch_next[1][15:1]; + if (next_port[1] == PORT_REQ) begin + { oe_latch[1], we_latch[1] } <= { ~port2_we, port2_we }; + ds[1] <= port2_ds; + din_latch[1] <= port2_d; + end else begin + { oe_latch[1], we_latch[1] } <= 2'b10; + ds[1] <= 2'b11; + end + end + + 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; + { SDRAM_DQMH, SDRAM_DQML } <= ~ds[0]; + if (we_latch[0]) begin + SDRAM_DQ <= din_latch[0]; + port1_ack <= port1_req; + end + SDRAM_A <= { 4'b0010, addr_latch[0][9:1] }; // auto precharge + SDRAM_BA <= addr_latch[0][24:23]; + end + + if(t == STATE_CAS1 && (we_latch[1] || oe_latch[1])) begin + sd_cmd <= we_latch[1]?CMD_WRITE:CMD_READ; + { SDRAM_DQMH, SDRAM_DQML } <= ~ds[1]; + if (we_latch[1]) begin + SDRAM_DQ <= din_latch[1]; + port2_ack <= port2_req; + end + SDRAM_A <= { 4'b0010, addr_latch[1][9:1] }; // auto precharge + SDRAM_BA <= addr_latch[1][24:23]; + end + + // Data returned + if(t == STATE_READ0 && oe_latch[0]) begin + case(port[0]) + PORT_REQ: begin port1_q <= sd_din; port1_ack <= port1_req; end + PORT_CPU1: begin cpu1_q <= sd_din; end + default: ; + endcase; + end + if(t == STATE_READ1 && oe_latch[1]) begin + case(port[1]) + PORT_REQ: begin port2_q <= sd_din; port2_ack <= port2_req; end + PORT_SND: begin snd_q <= sd_din; end + default: ; + endcase; + end + end +end + +endmodule diff --git a/Arcade_MiST/Mappy Hardware/rtl/wsg.v b/Arcade_MiST/Mappy Hardware/rtl/wsg.v new file mode 100644 index 00000000..0e03e6d6 --- /dev/null +++ b/Arcade_MiST/Mappy Hardware/rtl/wsg.v @@ -0,0 +1,102 @@ +/******************************************* + Wave-base Sound Generator (8CH) + + Copyright (c) 2007 MiSTer-X +********************************************/ +module WSG_8CH +( + input MCLK, + + input [5:0] ADDR, + input [7:0] DATA, + input WE, + + input SND_ENABLE, + + output WAVE_CLK, + output [7:0] WAVE_AD, + input [3:0] WAVE_DT, + + output reg [7:0] SOUT +); + +//------------------------------------------- +// Clock Generator & Ctrl Registers +//------------------------------------------- +reg [10:0] clk24k_cnt = 0; + +wire CLK_WSGx8 = clk24k_cnt[7]; // 24KHz*8 +wire CLK_WSG = clk24k_cnt[10]; // 24KHz +wire CLK24M_EN = clk24k_cnt[0]; +wire CLK_WSGx8_EN = clk24k_cnt[6:0] == 7'b1111111; +wire CLK_WSG_EN = clk24k_cnt[9:0] == 10'b1111111111; + +reg [7:0] fl [0:7]; +reg [7:0] fm [0:7]; +reg [3:0] fh [0:7]; +reg [2:0] fv [0:7]; +reg [3:0] v [0:7]; + +wire [2:0] ra = ADDR[5:3]; + +always @( posedge MCLK ) begin + if ( CLK24M_EN & WE ) begin + case ( ADDR[2:0] ) + 3'h3: v[ra] <= DATA[3:0]; + 3'h4: fl[ra] <= DATA; + 3'h5: fm[ra] <= DATA; + 3'h6: begin + fh[ra] <= DATA[3:0]; + fv[ra] <= DATA[6:4]; + end + + default: ; + endcase + end + clk24k_cnt <= clk24k_cnt+1'd1; +end + +//------------------------------------------- +// WSG core (8ch) +//------------------------------------------- +reg [2:0] phase = 0; + +reg [7:0] o, ot; +reg [19:0] c [0:7]; +reg [7:0] wa; +reg [3:0] wm; +reg en; + +wire [7:0] va = WAVE_DT * wm; + +wire [19:0] cx = c[phase]; +wire [19:0] fq = { fh[phase], fm[phase], fl[phase] }; + +assign WAVE_CLK = CLK_WSGx8; +assign WAVE_AD = wa; + +always @ ( posedge MCLK ) begin + if (CLK_WSGx8_EN) begin + if ( phase ) begin + ot <= ot + (en ? { 4'h0, va[7:4] } : 8'd0); + end + else begin + o <= ot; + ot <= (en ? { 4'h0, va[7:4] } : 8'd0); + end + c[phase] <= cx + fq; + en <= (fq!=0); + wm <= v[phase]; + wa <= { fv[phase], cx[19:15] }; + phase <= phase + 1'd1; + end +end + +wire [6:0] wsgmix = ( o[6:0] | {7{o[7]}} ); + +always @ ( posedge MCLK ) begin + if (CLK_WSG_EN) SOUT <= SND_ENABLE ? { wsgmix, 1'b0 } : 8'd0; +end + +endmodule +