diff --git a/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/README.md b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/README.md
new file mode 100644
index 00000000..f0291cc6
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/README.md
@@ -0,0 +1,192 @@
+robotron-fpga MiST port
+=======================
+
+Supported games: Robotron 2048, Joust, Sinistar, Bubbles, Splat, Stargate
+
+After loading the RBF, a CMOS clearing will happen. Reset the core to start
+the game.
+
+Sinistar has some graphics issues, and the speech chip is not implemented.
+
+robotron-fpga
+=============
+
+An implementation of the classic Robotron: 2084 video arcade game from 1982.
+Both the sound board and CPU/interface boards are implemented, but are in
+separate sub-projects at the moment. The CPU/interface implementation relies
+on a Motorola MC6809E processor attached to the FPGA board via an adapter
+board design that is part of this project.
+
+
+
+The goal is to have a complete Robotron: 2084 game implemented in a single,
+compact, inexpensive FPGA board which includes the necessary peripherals:
+video and sound outputs, joysticks interface, and coin/player buttons.
+
+Status
+======
+
+The CPU/interface and sound boards are implemented as separate projects.
+Both appear to function well.
+
+The MC6809E breakout board has been fabricated, but has some design issues
+that need to be addressed. The primary issue is the lack of pull-up/-down
+resistors on key MC6809E signals, to keep the processor in a RESET state
+until the FPGA board is ready to work with the MC6809E. I also screwed up
+and put the NEXYS2 connector on the "bottom side" of the board. Smooth!
+
+Documentation
+=============
+
+These documents served me well during development of this project.
+
+[Sean Riddle](http://seanriddle.com/) - Williams arcade machine information,
+including Robotron: 2084.
+
+* [Hardware overview](http://seanriddle.com/willhard.html)
+* [Memory map](http://seanriddle.com/memmap.gif)
+* [Processor and video timing](http://seanriddle.com/timing.html)
+* [BLTter description and test code](http://seanriddle.com/blittest.html)
+
+[Robotron-2084](http://www.robotron-2084.co.uk/) - Williams arcade machine
+official documentation.
+
+* [Robotron schematics and instruction manuals](http://www.robotron-2084.co.uk/manualsrobotron.html)
+* [Defender "later series" theory of operation](http://www.robotron-2084.co.uk/manualsdefender.html),
+ interesting because the Robotron and Defender hardware is quite
+ similar.
+
+Documentation for various ICs in the original Robotron: 2084 machine.
+
+* [MC6809E microprocessor datasheet](http://www.classiccmp.org/dunfield/r/6809e.pdf)
+* [MC6809E microprocessor programming manual](http://www.classiccmp.org/dunfield/r/6809prog.pdf)
+* [DM9316 Synchronous 4-Bit Binary Counter](http://www.ti.com/product/dm9316)
+* National Semiconductor(?) DM7489 64-bit random access read/write memory
+ (no good reference)
+* [Harris HM-7641 512 x 8 PROM](http://www.bitsavers.org/pdf/harris/_dataBooks/1978_Harris_Memory_Vol1.pdf) (page 2-35)
+* [Harris HM-6514 1024 x 4 CMOS RAM](http://www.bitsavers.org/pdf/harris/_dataBooks/1978_Harris_Memory_Vol1.pdf) (page 3-49)
+* [Mostek MK4116 16,384 x 1 bit dynamic RAM](http://hardware.speccy.org/datasheet/MK4116.pdf)
+* [Signetics 8T97 hex buffer](http://www.bitsavers.org/pdf/signetics/_dataBooks/1977_Bipolar_Microprocessor.pdf) (page 96)
+* [Various 74-series logic ICs](http://www.ti.com/lsds/ti/logic/home_overview.page)
+
+[Digilent](http://www.digilentinc.com/) - FPGA development boards and
+accessories.
+
+* [NEXYS2 FPGA development board](http://digilentinc.com/Products/Detail.cfm?NavPath=2,400,789&Prod=NEXYS2)
+
+[Xilinx](http://www.xilinx.com/) - FPGA silicon and tools vendor.
+
+* [Spartan-3E documentation](http://www.xilinx.com/support/documentation/spartan-3e.htm)
+
+Requirements
+============
+
+* Digilent NEXYS2 Spartan-3E FPGA development board.
+
+ This is the board I've done my development on, and is a good choice
+ because it has plenty of inputs, a VGA output connector, many switches
+ and LEDs, and enough onboard RAM and flash to meet the game's memory
+ needs.
+
+* Williams Robotron: 2084 ROM binary files:
+
+ These files are often used with MAME, the arcade emulator. CPU board
+ ROM files are named "robotron.sb?", where "?" is "1" through "9" and
+ "a" through "c". The sound board ROM file is named "robotron.snd".
+
+* Python 2.7:
+
+ Used to transform ROM and PROM files into VHDL files.
+
+* Xilinx ISE WebPack 13.4:
+
+ For compiling VHDL and generating the bit file for the FPGA.
+
+* Digilent Adept or other JTAG tool:
+
+ For loading the bit file into FPGA board.
+
+* VGA monitor:
+
+ Video output is 31.25 kHz horizontal sync and 60 Hz vertical sync,
+ which is compatible with VGA monitors. The output is line-doubled
+ from the arcade game's original 15.625 kHz horizontal sync.
+
+* RC lowpass filter:
+
+ The PWM audio output from the FPGA needs filtering to sound reasonable,
+ or an eight-bit DAC can be attached to the 8-bit audio output pins of
+ the FPGA board.
+
+Tools
+=====
+
+* make_rom_file.py:
+
+ Translates a set of Robotron ROM board ROM files
+ (like those you would use with the MAME arcade emulator) into a
+ binary file that can be loaded into the flash device on the Digilent
+ FPGA board.
+
+* make_decoder_vhdl.py:
+
+ Translates a decoder.4 or decoder.6 file (data
+ dumped from decoder PROMs on the Robotron CPU board) into a VHDL
+ file used by the robotron_cpu project.
+
+* dac_out_wave.py:
+
+ Translates the text file output of robotron_test.vhd
+ into a WAV file that can be played.
+
+* make_sound_rom.py:
+
+ Produces rom_snd_blocks.vhd, containing VHDL ROM
+ blocks, from the contents of a robotron.snd ROM file. The
+ robotron.snd file is not provided due to copyright on the original
+ ROM binaries produced by Williams. I happen to have a physical
+ instance of the ROM board, so I'm in the clear. :-)
+
+Contributing
+============
+
+Contributions are welcome!
+
+Please respect Williams Electronics' copyright and do not post any VHDL
+or .bit files containing their binary code.
+
+License
+=======
+
+This hardware design is licensed under a
+[Creative Commons Attribution-ShareAlike 3.0 Unported License]
+(http://creativecommons.org/licenses/by-sa/3.0/).
+
+The associated software is provided under the GNU Public License,
+version 3:
+
+This project 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 project 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 project. If not, see .
+
+Contact
+=======
+
+Jared Boone
+
+ShareBrained Technology, Inc.
+
+
+
+
+The latest version of this repository can be found at
+https://github.com/sharebrained/robotron-fpga
diff --git a/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/RobotronFPGA.qpf b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/RobotronFPGA.qpf
new file mode 100644
index 00000000..df002df5
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/RobotronFPGA.qpf
@@ -0,0 +1,31 @@
+# -------------------------------------------------------------------------- #
+#
+# Copyright (C) 2017 Intel Corporation. All rights reserved.
+# Your use of Intel Corporation's design tools, logic functions
+# and other software and tools, and its AMPP partner logic
+# functions, and any output files from any of the foregoing
+# (including device programming or simulation files), and any
+# associated documentation or information are expressly subject
+# to the terms and conditions of the Intel Program License
+# Subscription Agreement, the Intel Quartus Prime License Agreement,
+# the Intel MegaCore Function License Agreement, or other
+# applicable license agreement, including, without limitation,
+# that your use is for the sole purpose of programming logic
+# devices manufactured by Intel and sold by Intel or its
+# authorized distributors. Please refer to the applicable
+# agreement for further details.
+#
+# -------------------------------------------------------------------------- #
+#
+# Quartus Prime
+# Version 17.0.1 Build 598 06/07/2017 SJ Standard Edition
+# Date created = 04:04:47 October 16, 2017
+#
+# -------------------------------------------------------------------------- #
+
+QUARTUS_VERSION = "17.0"
+DATE = "04:04:47 October 16, 2017"
+
+# Revisions
+
+PROJECT_REVISION = "RobotronFPGA"
diff --git a/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/RobotronFPGA.qsf b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/RobotronFPGA.qsf
new file mode 100644
index 00000000..bd44a02d
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/RobotronFPGA.qsf
@@ -0,0 +1,231 @@
+# -------------------------------------------------------------------------- #
+#
+# Copyright (C) 1991-2013 Altera Corporation
+# Your use of Altera Corporation's design tools, logic functions
+# and other software and tools, and its AMPP partner logic
+# functions, and any output files from any of the foregoing
+# (including device programming or simulation files), and any
+# associated documentation or information are expressly subject
+# to the terms and conditions of the Altera Program License
+# Subscription Agreement, Altera MegaCore Function License
+# Agreement, or other applicable license agreement, including,
+# without limitation, that your use is for the sole purpose of
+# programming logic devices manufactured by Altera and sold by
+# Altera or its authorized distributors. Please refer to the
+# applicable agreement for further details.
+#
+# -------------------------------------------------------------------------- #
+#
+# Quartus II 64-Bit
+# Version 13.1.0 Build 162 10/23/2013 SJ Web Edition
+# Date created = 16:34:25 January 07, 2020
+#
+# -------------------------------------------------------------------------- #
+#
+# Notes:
+#
+# 1) The default values for assignments are stored in the file:
+# RobotronFPGA_assignment_defaults.qdf
+# If this file doesn't exist, see file:
+# assignment_defaults.qdf
+#
+# 2) Altera recommends that you do not modify this file. This
+# file is updated automatically by the Quartus II software
+# and any changes you make may be lost or overwritten.
+#
+# -------------------------------------------------------------------------- #
+
+
+
+# Project-Wide Assignments
+# ========================
+set_global_assignment -name PROJECT_CREATION_TIME_DATE "21:22:13 JUNE 04, 2019"
+set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
+set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:rtl/build_id.tcl"
+set_global_assignment -name ORIGINAL_QUARTUS_VERSION 13.1
+set_global_assignment -name LAST_QUARTUS_VERSION "13.1 SP4.26"
+set_global_assignment -name SMART_RECOMPILE ON
+
+# Pin & Location Assignments
+# ==========================
+set_location_assignment PIN_7 -to LED
+set_location_assignment PIN_54 -to CLOCK_27
+set_location_assignment PIN_144 -to VGA_R[5]
+set_location_assignment PIN_143 -to VGA_R[4]
+set_location_assignment PIN_142 -to VGA_R[3]
+set_location_assignment PIN_141 -to VGA_R[2]
+set_location_assignment PIN_137 -to VGA_R[1]
+set_location_assignment PIN_135 -to VGA_R[0]
+set_location_assignment PIN_133 -to VGA_B[5]
+set_location_assignment PIN_132 -to VGA_B[4]
+set_location_assignment PIN_125 -to VGA_B[3]
+set_location_assignment PIN_121 -to VGA_B[2]
+set_location_assignment PIN_120 -to VGA_B[1]
+set_location_assignment PIN_115 -to VGA_B[0]
+set_location_assignment PIN_114 -to VGA_G[5]
+set_location_assignment PIN_113 -to VGA_G[4]
+set_location_assignment PIN_112 -to VGA_G[3]
+set_location_assignment PIN_111 -to VGA_G[2]
+set_location_assignment PIN_110 -to VGA_G[1]
+set_location_assignment PIN_106 -to VGA_G[0]
+set_location_assignment PIN_136 -to VGA_VS
+set_location_assignment PIN_119 -to VGA_HS
+set_location_assignment PIN_65 -to AUDIO_L
+set_location_assignment PIN_80 -to AUDIO_R
+set_location_assignment PIN_105 -to SPI_DO
+set_location_assignment PIN_88 -to SPI_DI
+set_location_assignment PIN_126 -to SPI_SCK
+set_location_assignment PIN_127 -to SPI_SS2
+set_location_assignment PIN_91 -to SPI_SS3
+set_location_assignment PIN_13 -to CONF_DATA0
+set_location_assignment PLL_1 -to "pll:pll|altpll:altpll_component"
+set_location_assignment PIN_49 -to SDRAM_A[0]
+set_location_assignment PIN_44 -to SDRAM_A[1]
+set_location_assignment PIN_42 -to SDRAM_A[2]
+set_location_assignment PIN_39 -to SDRAM_A[3]
+set_location_assignment PIN_4 -to SDRAM_A[4]
+set_location_assignment PIN_6 -to SDRAM_A[5]
+set_location_assignment PIN_8 -to SDRAM_A[6]
+set_location_assignment PIN_10 -to SDRAM_A[7]
+set_location_assignment PIN_11 -to SDRAM_A[8]
+set_location_assignment PIN_28 -to SDRAM_A[9]
+set_location_assignment PIN_50 -to SDRAM_A[10]
+set_location_assignment PIN_30 -to SDRAM_A[11]
+set_location_assignment PIN_32 -to SDRAM_A[12]
+set_location_assignment PIN_83 -to SDRAM_DQ[0]
+set_location_assignment PIN_79 -to SDRAM_DQ[1]
+set_location_assignment PIN_77 -to SDRAM_DQ[2]
+set_location_assignment PIN_76 -to SDRAM_DQ[3]
+set_location_assignment PIN_72 -to SDRAM_DQ[4]
+set_location_assignment PIN_71 -to SDRAM_DQ[5]
+set_location_assignment PIN_69 -to SDRAM_DQ[6]
+set_location_assignment PIN_68 -to SDRAM_DQ[7]
+set_location_assignment PIN_86 -to SDRAM_DQ[8]
+set_location_assignment PIN_87 -to SDRAM_DQ[9]
+set_location_assignment PIN_98 -to SDRAM_DQ[10]
+set_location_assignment PIN_99 -to SDRAM_DQ[11]
+set_location_assignment PIN_100 -to SDRAM_DQ[12]
+set_location_assignment PIN_101 -to SDRAM_DQ[13]
+set_location_assignment PIN_103 -to SDRAM_DQ[14]
+set_location_assignment PIN_104 -to SDRAM_DQ[15]
+set_location_assignment PIN_58 -to SDRAM_BA[0]
+set_location_assignment PIN_51 -to SDRAM_BA[1]
+set_location_assignment PIN_85 -to SDRAM_DQMH
+set_location_assignment PIN_67 -to SDRAM_DQML
+set_location_assignment PIN_60 -to SDRAM_nRAS
+set_location_assignment PIN_64 -to SDRAM_nCAS
+set_location_assignment PIN_66 -to SDRAM_nWE
+set_location_assignment PIN_59 -to SDRAM_nCS
+set_location_assignment PIN_33 -to SDRAM_CKE
+set_location_assignment PIN_43 -to SDRAM_CLK
+
+# Classic Timing Assignments
+# ==========================
+set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0
+set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85
+set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS ON
+set_global_assignment -name TIMEQUEST_DO_CCPP_REMOVAL 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 RobotronFPGA_MiST
+
+# Fitter Assignments
+# ==================
+set_global_assignment -name DEVICE EP3C25E144C8
+set_global_assignment -name ENABLE_CONFIGURATION_PINS OFF
+set_global_assignment -name ENABLE_NCE_PIN OFF
+set_global_assignment -name ENABLE_BOOT_SEL_PIN OFF
+set_global_assignment -name CYCLONEIII_CONFIGURATION_SCHEME "PASSIVE SERIAL"
+set_global_assignment -name CRC_ERROR_OPEN_DRAIN OFF
+set_global_assignment -name FORCE_CONFIGURATION_VCCIO ON
+set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "3.3-V LVTTL"
+set_global_assignment -name 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 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_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/cpu1.stp
+
+# Power Estimation Assignments
+# ============================
+set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "NO HEAT SINK WITH STILL AIR"
+set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)"
+
+# Advanced I/O Timing Assignments
+# ===============================
+set_global_assignment -name OUTPUT_IO_TIMING_NEAR_END_VMEAS "HALF VCCIO" -rise
+set_global_assignment -name OUTPUT_IO_TIMING_NEAR_END_VMEAS "HALF VCCIO" -fall
+set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -rise
+set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -fall
+
+# ---------------------------
+# start ENTITY(Defender_MiST)
+
+ # Pin & Location Assignments
+ # ==========================
+
+ # Fitter Assignments
+ # ==================
+
+ # start DESIGN_PARTITION(Top)
+ # ---------------------------
+
+ # Incremental Compilation Assignments
+ # ===================================
+
+ # end DESIGN_PARTITION(Top)
+ # -------------------------
+
+# end ENTITY(Defender_MiST)
+# -------------------------
+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
+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_*
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_*
+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
+set_global_assignment -name SYSTEMVERILOG_FILE rtl/RobotronFPGA_MiST.sv
+set_global_assignment -name VHDL_FILE rtl/defender_sound_board.vhd
+set_global_assignment -name SYSTEMVERILOG_FILE rtl/sdram.sv
+set_global_assignment -name VHDL_FILE rtl/pll_mist.vhd
+set_global_assignment -name VHDL_FILE rtl/gen_ram.vhd
+set_global_assignment -name VHDL_FILE rtl/dpram.vhd
+set_global_assignment -name VHDL_FILE rtl/cpu68.vhd
+set_global_assignment -name VHDL_FILE rtl/robotron_soc.vhd
+set_global_assignment -name VHDL_FILE rtl/robotron_cpu/sc1.vhd
+set_global_assignment -name VHDL_FILE rtl/robotron_cpu/robotron_cpu.vhd
+set_global_assignment -name VHDL_FILE rtl/robotron_cpu/decoder_6.vhd
+set_global_assignment -name VHDL_FILE rtl/robotron_cpu/decoder_4.vhd
+set_global_assignment -name QIP_FILE ../../../common/mist/mist.qip
+set_global_assignment -name VHDL_FILE ../../../common/CPU/MC6809/cpu09l_128a.vhd
+set_global_assignment -name VHDL_FILE ../../../common/IO/pia6821.vhd
+set_global_assignment -name VERILOG_FILE ../../../common/CPU/MC6809/mc6809i.v
+set_global_assignment -name SIGNALTAP_FILE output_files/cpu1.stp
+set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
\ No newline at end of file
diff --git a/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/RobotronFPGA.sdc b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/RobotronFPGA.sdc
new file mode 100644
index 00000000..cad1ec42
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/RobotronFPGA.sdc
@@ -0,0 +1,138 @@
+## Generated SDC file "vectrex_MiST.out.sdc"
+
+## Copyright (C) 1991-2013 Altera Corporation
+## Your use of Altera Corporation's design tools, logic functions
+## and other software and tools, and its AMPP partner logic
+## functions, and any output files from any of the foregoing
+## (including device programming or simulation files), and any
+## associated documentation or information are expressly subject
+## to the terms and conditions of the Altera Program License
+## Subscription Agreement, Altera MegaCore Function License
+## Agreement, or other applicable license agreement, including,
+## without limitation, that your use is for the sole purpose of
+## programming logic devices manufactured by Altera and sold by
+## Altera or its authorized distributors. Please refer to the
+## applicable agreement for further details.
+
+
+## VENDOR "Altera"
+## PROGRAM "Quartus II"
+## VERSION "Version 13.1.0 Build 162 10/23/2013 SJ Web Edition"
+
+## DATE "Sun Jun 24 12:53:00 2018"
+
+##
+## DEVICE "EP3C25E144C8"
+##
+
+# Clock constraints
+
+# Automatically constrain PLL and other generated clocks
+derive_pll_clocks -create_base_clocks
+
+# Automatically calculate clock uncertainty to jitter and other effects.
+derive_clock_uncertainty
+
+# tsu/th constraints
+
+# tco constraints
+
+# tpd constraints
+
+#**************************************************************
+# Time Information
+#**************************************************************
+
+set_time_format -unit ns -decimal_places 3
+
+
+
+#**************************************************************
+# Create Clock
+#**************************************************************
+
+create_clock -name {SPI_SCK} -period 41.666 -waveform { 20.8 41.666 } [get_ports {SPI_SCK}]
+
+set sdram_clk "pll|altpll_component|auto_generated|pll1|clk[0]"
+set vid_clk "pll|altpll_component|auto_generated|pll1|clk[1]"
+set game_clk "pll|altpll_component|auto_generated|pll1|clk[1]"
+set aud_clk "pll|altpll_component|auto_generated|pll1|clk[2]"
+
+#**************************************************************
+# Create Generated Clock
+#**************************************************************
+
+
+#**************************************************************
+# Set Clock Latency
+#**************************************************************
+
+
+
+#**************************************************************
+# Set Clock Uncertainty
+#**************************************************************
+
+#**************************************************************
+# Set Input Delay
+#**************************************************************
+
+set_input_delay -add_delay -clock_fall -clock [get_clocks {CLOCK_27}] 1.000 [get_ports {CLOCK_27}]
+set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {CONF_DATA0}]
+set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_DI}]
+set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_SCK}]
+set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_SS2}]
+set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_SS3}]
+
+set_input_delay -clock [get_clocks $sdram_clk] -reference_pin [get_ports {SDRAM_CLK}] -max 6.4 [get_ports SDRAM_DQ[*]]
+set_input_delay -clock [get_clocks $sdram_clk] -reference_pin [get_ports {SDRAM_CLK}] -min 3.2 [get_ports SDRAM_DQ[*]]
+
+#**************************************************************
+# Set Output Delay
+#**************************************************************
+
+set_output_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_DO}]
+set_output_delay -add_delay -clock_fall -clock [get_clocks $aud_clk] 1.000 [get_ports {AUDIO_L}]
+set_output_delay -add_delay -clock_fall -clock [get_clocks $aud_clk] 1.000 [get_ports {AUDIO_R}]
+set_output_delay -add_delay -clock_fall -clock [get_clocks $sdram_clk] 1.000 [get_ports {LED}]
+set_output_delay -add_delay -clock_fall -clock [get_clocks $vid_clk] 1.000 [get_ports {VGA_*}]
+
+set_output_delay -clock [get_clocks $sdram_clk] -reference_pin [get_ports {SDRAM_CLK}] -max 1.5 [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}]
+set_output_delay -clock [get_clocks $sdram_clk] -reference_pin [get_ports {SDRAM_CLK}] -min -0.8 [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}]
+
+#**************************************************************
+# Set Clock Groups
+#**************************************************************
+
+set_clock_groups -asynchronous -group [get_clocks {SPI_SCK}] -group [get_clocks {pll|altpll_component|auto_generated|pll1|clk[*]}]
+set_clock_groups -asynchronous -group [get_clocks $game_clk] -group [get_clocks $aud_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/Williams 6809 rev.1 Hardware/Robotron-FPGA/buildall.sh b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/buildall.sh
new file mode 100755
index 00000000..2fa8e228
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/buildall.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+PROJECTS=" \
+ROBOTRON \
+JOUST \
+SPLAT \
+BUBBLES \
+STARGATE \
+SINISTAR"
+
+mkdir -p Releases
+for PROJECT in $PROJECTS; do
+ echo "Compiling $PROJECT"
+ sed -i "s/^.define CORE_NAME.*/\`define CORE_NAME \"$PROJECT\"/" rtl/RobotronFPGA_MiST.sv
+ quartus_sh --flow compile RobotronFPGA.qsf && cp output_files/RobotronFPGA.rbf Releases/$PROJECT.rbf
+done
\ No newline at end of file
diff --git a/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/clean.bat b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/clean.bat
new file mode 100644
index 00000000..c9a2cb06
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/clean.bat
@@ -0,0 +1,15 @@
+@echo off
+del /s *.bak
+del /s *.orig
+del /s *.rej
+rmdir /s /q db
+rmdir /s /q incremental_db
+rmdir /s /q output
+rmdir /s /q simulation
+rmdir /s /q greybox_tmp
+del PLLJ_PLLSPE_INFO.txt
+del *.qws
+del *.ppf
+del *.qip
+del *.ddb
+pause
diff --git a/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/RobotronFPGA_MiST.sv b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/RobotronFPGA_MiST.sv
new file mode 100644
index 00000000..c51b7f46
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/RobotronFPGA_MiST.sv
@@ -0,0 +1,354 @@
+//============================================================================
+// Robotron-FPGA MiST top-level
+//
+// Robotron-FPGA is Copyright 2012 ShareBrained Technology, Inc.
+//
+// Supports:
+// Robotron 2048/Joust/Stargate/Bubbles/Splat/Sinistar
+
+module RobotronFPGA_MiST(
+ output LED,
+ output [5:0] VGA_R,
+ output [5:0] VGA_G,
+ output [5:0] VGA_B,
+ output VGA_HS,
+ output VGA_VS,
+ output AUDIO_L,
+ output AUDIO_R,
+ input SPI_SCK,
+ output SPI_DO,
+ input SPI_DI,
+ input SPI_SS2,
+ input SPI_SS3,
+ input CONF_DATA0,
+ input CLOCK_27,
+
+ output [12:0] SDRAM_A,
+ inout [15:0] SDRAM_DQ,
+ output SDRAM_DQML,
+ output SDRAM_DQMH,
+ output SDRAM_nWE,
+ output SDRAM_nCAS,
+ output SDRAM_nRAS,
+ output SDRAM_nCS,
+ output [1:0] SDRAM_BA,
+ output SDRAM_CLK,
+ output SDRAM_CKE
+);
+
+`include "rtl/build_id.v"
+
+`define CORE_NAME "ROBOTRON"
+//`define CORE_NAME "JOUST"
+//`define CORE_NAME "SPLAT"
+//`define CORE_NAME "BUBBLES"
+//`define CORE_NAME "STARGATE"
+//`define CORE_NAME "SINISTAR"
+
+localparam CONF_STR = {
+ `CORE_NAME,";ROM;",
+ "O2,Rotate Controls,Off,On;",
+ "O34,Scanlines,Off,25%,50%,75%;",
+ "O5,Blend,Off,On;",
+ "O6,Swap Joysticks,Off,On;",
+ "T0,Reset;",
+ "V,v1.0.",`BUILD_DATE
+};
+
+wire rotate = status[2];
+wire [1:0] scanlines = status[4:3];
+wire blend = status[5];
+wire joyswap = status[6];
+
+reg [7:0] SW;
+reg [7:0] JA;
+reg [7:0] JB;
+reg [3:0] BTN;
+reg blitter_sc2, sinistar;
+reg [1:0] orientation; // [left/right, landscape/portrait]
+
+always @(*) begin
+ orientation = 2'b10;
+ SW = 8'h00;
+ blitter_sc2 = 0;
+ sinistar = 0;
+
+ if (`CORE_NAME == "ROBOTRON") begin
+ BTN = { m_one_player, m_two_players, m_coin1 | m_coin2, reset };
+ JA = ~{ m_right2, m_left2, m_down2, m_up2, m_right, m_left, m_down, m_up };
+ JB = ~{ m_right2, m_left2, m_down2, m_up2, m_right, m_left, m_down, m_up };
+ end else if (`CORE_NAME == "JOUST") begin
+ BTN = { m_two_players, m_one_player, m_coin1 | m_coin2, reset };
+ JA = ~{ 5'b00000, m_fireA, m_right, m_left };
+ JB = ~{ 5'b00000, m_fire2A, m_right2, m_left2 };
+ end else if (`CORE_NAME == "SPLAT") begin
+ blitter_sc2 = 1;
+ BTN = { m_one_player, m_two_players, m_coin1 | m_coin2, reset };
+ JA = ~{ m_right2, m_left2, m_down2, m_up2, m_right, m_left, m_down, m_up };
+ JB = ~{ m_right4, m_left4, m_down4, m_up4, m_right3, m_left3, m_down3, m_up3 };
+ end else if (`CORE_NAME == "BUBBLES") begin
+ BTN = { m_two_players, m_one_player, m_coin1 | m_coin2, reset };
+ JA = ~{ 4'b0000, m_right, m_left, m_down, m_up };
+ JB = ~{ 4'b0000, m_right2, m_left2, m_down2, m_up2 };
+ end else if (`CORE_NAME == "STARGATE") begin
+ BTN = { m_two_players, m_one_player, m_coin1 | m_coin2, reset };
+ JA = ~{ m_fireE, m_up, m_down, m_left | m_right, m_fireD, m_fireC, m_fireB, m_fireA };
+ JB = ~{ m_fire2E, m_up2, m_down2, m_left2 | m_right2, m_fire2D, m_fire2C, m_fire2B, m_fire2A };
+ end else if (`CORE_NAME == "SINISTAR") begin
+ sinistar = 1;
+ orientation = 2'b01;
+ BTN = { m_two_players, m_one_player, m_coin1 | m_coin2, reset };
+ JA = { sin_x, 2'b00, m_right | m_left | m_right2 | m_left2, sin_y, 2'b00, m_up | m_down | m_up2 | m_down2 };
+ JB = { sin_x, 2'b00, m_right | m_left | m_right2 | m_left2, sin_y, 2'b00, m_up | m_down | m_up2 | m_down2 };
+ end
+end
+
+assign LED = ~ioctl_downl;
+assign SDRAM_CLK = clk_mem;
+assign SDRAM_CKE = 1;
+
+wire clk_sys, clk_mem, clk_aud;
+wire pll_locked;
+pll_mist pll(
+ .inclk0(CLOCK_27),
+ .areset(0),
+ .c0(clk_mem),//96
+ .c1(clk_sys),//12
+ .c2(clk_aud),//0.89
+ .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 blankn;
+wire [2:0] r,g;
+wire [1:0] b;
+wire key_pressed;
+wire [7:0] key_code;
+wire key_strobe;
+
+wire ioctl_downl;
+wire [7:0] ioctl_index;
+wire ioctl_wr;
+wire [24:0] ioctl_addr;
+wire [7:0] ioctl_dout;
+
+/*
+ROM Structure:
+0000-BFFF main cpu 48k
+C000-CFFF snd cpu 4k
+*/
+data_io data_io (
+ .clk_sys ( clk_mem ),
+ .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;
+wire [23:1] mem_addr;
+wire [15:0] mem_do;
+wire [15:0] mem_di;
+wire mem_oe;
+wire mem_we;
+wire ramcs;
+wire romcs;
+wire ramlb;
+wire ramub;
+
+reg clkref;
+always @(posedge clk_sys) clkref <= ~clkref;
+
+sdram #(.MHZ(96)) sdram(
+ .*,
+ .init_n ( pll_locked ),
+ .clk ( clk_mem ),
+ .clkref ( clkref ),
+
+ // ROM upload
+ .port1_req ( port1_req ),
+ .port1_ack ( ),
+ .port1_a ( ioctl_addr[22:0] ),
+ .port1_ds ( 2'b11 ),
+ .port1_we ( ioctl_downl ),
+ .port1_d ( {ioctl_dout[7:4], ioctl_dout[7:4], ioctl_dout[3:0], ioctl_dout[3:0]} ),
+ .port1_q ( ),
+
+ // CPU/video access
+ .cpu1_addr ( ioctl_downl ? 17'h1ffff : sdram_addr ),
+ .cpu1_d ( mem_di ),
+ .cpu1_q ( mem_do ),
+ .cpu1_oe ( ~mem_oe & ~(ramcs & romcs) ),
+ .cpu1_we ( ~mem_we & ~(ramcs & romcs) ),
+ .cpu1_ds ( ~romcs ? 2'b11 : ~{ramub, ramlb} )
+);
+
+// ROM address to SDRAM address:
+// 0xxx-8xxx -> 0xxx-8xxx
+// DXXX-FXXX -> 9xxx-Bxxx
+wire [17:1] sdram_addr = ~romcs ? {1'b0, mem_addr[16], ~mem_addr[16] & mem_addr[15], mem_addr[14:1]} : { 1'b1, mem_addr[16:1] };
+
+always @(posedge clk_mem) 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 clk_sys) 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
+
+robotron_soc robotron_soc (
+ .clock ( clk_sys ),
+ .clock_snd ( clk_aud ),
+ .vgaRed ( r ),
+ .vgaGreen ( g ),
+ .vgaBlue ( b ),
+ .Hsync ( hs ),
+ .Vsync ( vs ),
+ .audio_out ( audio ),
+
+ .blitter_sc2 ( blitter_sc2 ),
+ .sinistar ( sinistar ),
+ .BTN ( BTN ),
+ .SIN_FIRE ( ~m_fireA & ~m_fire2A ),
+ .SIN_BOMB ( ~m_fireB & ~m_fire2B ),
+ .SW ( SW ),
+ .JA ( JA ),
+ .JB ( JB ),
+
+ .MemAdr ( mem_addr ),
+ .MemDin ( mem_di ),
+ .MemDout ( mem_do ),
+ .MemOE ( mem_oe ),
+ .MemWR ( mem_we ),
+ .RamCS ( ramcs ),
+ .RamLB ( ramlb ),
+ .RamUB ( ramub ),
+ .FlashCS ( romcs ),
+
+ .dl_clock ( clk_mem ),
+ .dl_addr ( ioctl_addr[15:0] ),
+ .dl_data ( ioctl_dout ),
+ .dl_wr ( ioctl_wr )
+);
+
+mist_video #(.COLOR_DEPTH(3), .SD_HCNT_WIDTH(11)) mist_video(
+ .clk_sys ( clk_sys ),
+ .SPI_SCK ( SPI_SCK ),
+ .SPI_SS3 ( SPI_SS3 ),
+ .SPI_DI ( SPI_DI ),
+ .R ( r ),
+ .G ( g ),
+ .B ( {b, b[1] } ),
+ .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 ( {orientation[1],rotate} ),
+ .scandoubler_disable( scandoublerD ),
+ .ce_divider ( 1'b1 ),
+ .scanlines ( scanlines ),
+ .blend ( blend ),
+ .ypbpr ( ypbpr )
+ );
+
+user_io #(
+ .STRLEN(($size(CONF_STR)>>3)))
+user_io(
+ .clk_sys ( clk_sys ),
+ .conf_str ( CONF_STR ),
+ .SPI_CLK ( SPI_SCK ),
+ .SPI_SS_IO ( CONF_DATA0 ),
+ .SPI_MISO ( SPI_DO ) ,
+ .SPI_MOSI ( SPI_DI ),
+ .buttons ( buttons ),
+ .switches ( switches ),
+ .scandoubler_disable (scandoublerD ),
+ .ypbpr ( ypbpr ),
+ .key_strobe ( key_strobe ),
+ .key_pressed ( key_pressed ),
+ .key_code ( key_code ),
+ .joystick_0 ( joystick_0 ),
+ .joystick_1 ( joystick_1 ),
+ .status ( status )
+ );
+
+wire dac_o;
+assign AUDIO_L = dac_o;
+assign AUDIO_R = dac_o;
+
+dac #(
+ .C_bits(8))
+dac(
+ .clk_i(clk_aud),
+ .res_n_i(1),
+ .dac_i(audio),
+ .dac_o(dac_o)
+ );
+
+// Sinistar controls
+reg sin_x;
+reg sin_y;
+
+always @(posedge clk_sys) begin
+ if (m_right | m_right2) sin_x <= 0;
+ else if (m_left | m_left2) sin_x <= 1;
+
+ if (m_up | m_up2) sin_y <= 0;
+ else if (m_down | m_down2) sin_y <= 1;
+end
+
+// General controls
+wire m_up, m_down, m_left, m_right, m_fireA, m_fireB, m_fireC, m_fireD, m_fireE, m_fireF;
+wire m_up2, m_down2, m_left2, m_right2, m_fire2A, m_fire2B, m_fire2C, m_fire2D, m_fire2E, m_fire2F;
+wire m_up3, m_down3, m_left3, m_right3, m_fire3A, m_fire3B, m_fire3C, m_fire3D, m_fire3E, m_fire3F;
+wire m_up4, m_down4, m_left4, m_right4, m_fire4A, m_fire4B, m_fire4C, m_fire4D, m_fire4E, m_fire4F;
+wire m_tilt, m_coin1, m_coin2, m_coin3, m_coin4, m_one_player, m_two_players, m_three_players, m_four_players;
+
+arcade_inputs inputs (
+ .clk ( clk_sys ),
+ .key_strobe ( key_strobe ),
+ .key_pressed ( key_pressed ),
+ .key_code ( key_code ),
+ .joystick_0 ( joystick_0 ),
+ .joystick_1 ( joystick_1 ),
+ .rotate ( rotate ),
+ .orientation ( orientation ),
+ .joyswap ( joyswap ),
+ .oneplayer ( 1'b0 ),
+ .controls ( {m_tilt, m_coin4, m_coin3, m_coin2, m_coin1, m_four_players, m_three_players, m_two_players, m_one_player} ),
+ .player1 ( {m_fireF, m_fireE, m_fireD, m_fireC, m_fireB, m_fireA, m_up, m_down, m_left, m_right} ),
+ .player2 ( {m_fire2F, m_fire2E, m_fire2D, m_fire2C, m_fire2B, m_fire2A, m_up2, m_down2, m_left2, m_right2} ),
+ .player3 ( {m_fire3F, m_fire3E, m_fire3D, m_fire3C, m_fire3B, m_fire3A, m_up3, m_down3, m_left3, m_right3} ),
+ .player4 ( {m_fire4F, m_fire4E, m_fire4D, m_fire4C, m_fire4B, m_fire4A, m_up4, m_down4, m_left4, m_right4} )
+);
+
+endmodule
diff --git a/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/build_id.tcl b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/build_id.tcl
new file mode 100644
index 00000000..938515d8
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/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/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/cpu68.vhd b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/cpu68.vhd
new file mode 100644
index 00000000..016bd9a9
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/cpu68.vhd
@@ -0,0 +1,3963 @@
+--===========================================================================--
+--
+-- S Y N T H E Z I A B L E CPU68 C O R E
+--
+-- www.OpenCores.Org - December 2002
+-- This core adheres to the GNU public license
+--
+-- File name : cpu68.vhd
+--
+-- Purpose : Implements a 6800 compatible CPU core with some
+-- additional instructions found in the 6801
+--
+-- Dependencies : ieee.Std_Logic_1164
+-- ieee.std_logic_unsigned
+--
+-- Author : John E. Kent
+--
+--===========================================================================----
+--
+-- Revision History:
+--
+-- Date: Revision Author
+-- 22 Sep 2002 0.1 John Kent
+--
+-- 30 Oct 2002 0.2 John Kent
+-- made NMI edge triggered
+--
+-- 30 Oct 2002 0.3 John Kent
+-- more corrections to NMI
+-- added wai_wait_state to prevent stack overflow on wai.
+--
+-- 1 Nov 2002 0.4 John Kent
+-- removed WAI states and integrated WAI with the interrupt service routine
+-- replace Data out (do) and Data in (di) register with a single Memory Data (md) reg.
+-- Added Multiply instruction states.
+-- run ALU and CC out of CPU module for timing measurements.
+--
+-- 3 Nov 2002 0.5 John Kent
+-- Memory Data Register was not loaded on Store instructions
+-- SEV and CLV were not defined in the ALU
+-- Overflow Flag on NEG was incorrect
+--
+-- 16th Feb 2003 0.6 John Kent
+-- Rearranged the execution cycle for dual operand instructions
+-- so that occurs during the following fetch cycle.
+-- This allows the reduction of one clock cycle from dual operand
+-- instruction. Note that this also necessitated re-arranging the
+-- program counter so that it is no longer incremented in the ALU.
+-- The effective address has also been re-arranged to include a
+-- separate added. The STD (store accd) now sets the condition codes.
+--
+-- 28th Jun 2003 0.7 John Kent
+-- Added Hold and Halt signals. Hold is used to steal cycles from the
+-- CPU or add wait states. Halt puts the CPU in the inactive state
+-- and is only honoured in the fetch cycle. Both signals are active high.
+--
+-- 9th Jan 2004 0.8 John Kent
+-- Clear instruction did an alu_ld8 rather than an alu_clr, so
+-- the carry bit was not cleared correctly.
+-- This error was picked up by Michael Hassenfratz.
+--
+
+library ieee;
+use IEEE.STD_LOGIC_1164.ALL;
+use IEEE.STD_LOGIC_ARITH.ALL;
+use IEEE.STD_LOGIC_UNSIGNED.ALL;
+
+entity cpu68 is
+ port (
+ clk: in std_logic;
+ rst: in std_logic;
+ rw: out std_logic;
+ vma: out std_logic;
+ address: out std_logic_vector(15 downto 0);
+ data_in: in std_logic_vector(7 downto 0);
+ data_out: out std_logic_vector(7 downto 0);
+ hold: in std_logic;
+ halt: in std_logic;
+ irq: in std_logic;
+ nmi: in std_logic;
+ test_alu: out std_logic_vector(15 downto 0);
+ test_cc: out std_logic_vector(7 downto 0)
+ );
+end;
+
+architecture CPU_ARCH of cpu68 is
+
+ constant SBIT : integer := 7;
+ constant XBIT : integer := 6;
+ constant HBIT : integer := 5;
+ constant IBIT : integer := 4;
+ constant NBIT : integer := 3;
+ constant ZBIT : integer := 2;
+ constant VBIT : integer := 1;
+ constant CBIT : integer := 0;
+
+ type state_type is (reset_state, fetch_state, decode_state,
+ extended_state, indexed_state, read8_state, read16_state, immediate16_state,
+ write8_state, write16_state,
+ execute_state, halt_state, error_state,
+ mul_state, mulea_state, muld_state,
+ mul0_state, mul1_state, mul2_state, mul3_state,
+ mul4_state, mul5_state, mul6_state, mul7_state,
+ jmp_state, jsr_state, jsr1_state,
+ branch_state, bsr_state, bsr1_state,
+ rts_hi_state, rts_lo_state,
+ int_pcl_state, int_pch_state,
+ int_ixl_state, int_ixh_state,
+ int_cc_state, int_acca_state, int_accb_state,
+ int_wai_state, int_mask_state,
+ rti_state, rti_cc_state, rti_acca_state, rti_accb_state,
+ rti_ixl_state, rti_ixh_state,
+ rti_pcl_state, rti_pch_state,
+ pula_state, psha_state, pulb_state, pshb_state,
+ pulx_lo_state, pulx_hi_state, pshx_lo_state, pshx_hi_state,
+ vect_lo_state, vect_hi_state );
+ type addr_type is (idle_ad, fetch_ad, read_ad, write_ad, push_ad, pull_ad, int_hi_ad, int_lo_ad );
+ type dout_type is (md_lo_dout, md_hi_dout, acca_dout, accb_dout, ix_lo_dout, ix_hi_dout, cc_dout, pc_lo_dout, pc_hi_dout );
+ type op_type is (reset_op, fetch_op, latch_op );
+ type acca_type is (reset_acca, load_acca, load_hi_acca, pull_acca, latch_acca );
+ type accb_type is (reset_accb, load_accb, pull_accb, latch_accb );
+ type cc_type is (reset_cc, load_cc, pull_cc, latch_cc );
+ type ix_type is (reset_ix, load_ix, pull_lo_ix, pull_hi_ix, latch_ix );
+ type sp_type is (reset_sp, latch_sp, load_sp );
+ type pc_type is (reset_pc, latch_pc, load_ea_pc, add_ea_pc, pull_lo_pc, pull_hi_pc, inc_pc );
+ type md_type is (reset_md, latch_md, load_md, fetch_first_md, fetch_next_md, shiftl_md );
+ type ea_type is (reset_ea, latch_ea, add_ix_ea, load_accb_ea, inc_ea, fetch_first_ea, fetch_next_ea );
+ type iv_type is (reset_iv, latch_iv, swi_iv, nmi_iv, irq_iv );
+ type nmi_type is (reset_nmi, set_nmi, latch_nmi );
+ type left_type is (acca_left, accb_left, accd_left, md_left, ix_left, sp_left );
+ type right_type is (md_right, zero_right, plus_one_right, accb_right );
+ type alu_type is (alu_add8, alu_sub8, alu_add16, alu_sub16, alu_adc, alu_sbc,
+ alu_and, alu_ora, alu_eor,
+ alu_tst, alu_inc, alu_dec, alu_clr, alu_neg, alu_com,
+ alu_inx, alu_dex, alu_cpx,
+ alu_lsr16, alu_lsl16,
+ alu_ror8, alu_rol8,
+ alu_asr8, alu_asl8, alu_lsr8,
+ alu_sei, alu_cli, alu_sec, alu_clc, alu_sev, alu_clv, alu_tpa, alu_tap,
+ alu_ld8, alu_st8, alu_ld16, alu_st16, alu_nop, alu_daa );
+
+ signal op_code: std_logic_vector(7 downto 0);
+ signal acca: std_logic_vector(7 downto 0);
+ signal accb: std_logic_vector(7 downto 0);
+ signal cc: std_logic_vector(7 downto 0);
+ signal cc_out: std_logic_vector(7 downto 0);
+ signal xreg: std_logic_vector(15 downto 0);
+ signal sp: std_logic_vector(15 downto 0);
+ signal ea: std_logic_vector(15 downto 0);
+ signal pc: std_logic_vector(15 downto 0);
+ signal md: std_logic_vector(15 downto 0);
+ signal left: std_logic_vector(15 downto 0);
+ signal right: std_logic_vector(15 downto 0);
+ signal out_alu: std_logic_vector(15 downto 0);
+ signal iv: std_logic_vector(1 downto 0);
+ signal nmi_req: std_logic;
+ signal nmi_ack: std_logic;
+
+ signal state: state_type;
+ signal next_state: state_type;
+ signal pc_ctrl: pc_type;
+ signal ea_ctrl: ea_type;
+ signal op_ctrl: op_type;
+ signal md_ctrl: md_type;
+ signal acca_ctrl: acca_type;
+ signal accb_ctrl: accb_type;
+ signal ix_ctrl: ix_type;
+ signal cc_ctrl: cc_type;
+ signal sp_ctrl: sp_type;
+ signal iv_ctrl: iv_type;
+ signal left_ctrl: left_type;
+ signal right_ctrl: right_type;
+ signal alu_ctrl: alu_type;
+ signal addr_ctrl: addr_type;
+ signal dout_ctrl: dout_type;
+ signal nmi_ctrl: nmi_type;
+
+
+begin
+
+----------------------------------
+--
+-- Address bus multiplexer
+--
+----------------------------------
+
+addr_mux: process( clk, addr_ctrl, pc, ea, sp, iv )
+begin
+ case addr_ctrl is
+ when idle_ad =>
+ address <= "1111111111111111";
+ vma <= '0';
+ rw <= '1';
+ when fetch_ad =>
+ address <= pc;
+ vma <= '1';
+ rw <= '1';
+ when read_ad =>
+ address <= ea;
+ vma <= '1';
+ rw <= '1';
+ when write_ad =>
+ address <= ea;
+ vma <= '1';
+ rw <= '0';
+ when push_ad =>
+ address <= sp;
+ vma <= '1';
+ rw <= '0';
+ when pull_ad =>
+ address <= sp;
+ vma <= '1';
+ rw <= '1';
+ when int_hi_ad =>
+ address <= "1111111111111" & iv & "0";
+ vma <= '1';
+ rw <= '1';
+ when int_lo_ad =>
+ address <= "1111111111111" & iv & "1";
+ vma <= '1';
+ rw <= '1';
+ when others =>
+ address <= "1111111111111111";
+ vma <= '0';
+ rw <= '1';
+ end case;
+end process;
+
+--------------------------------
+--
+-- Data Bus output
+--
+--------------------------------
+dout_mux : process( clk, dout_ctrl, md, acca, accb, xreg, pc, cc )
+begin
+ case dout_ctrl is
+ when md_hi_dout => -- alu output
+ data_out <= md(15 downto 8);
+ when md_lo_dout =>
+ data_out <= md(7 downto 0);
+ when acca_dout => -- accumulator a
+ data_out <= acca;
+ when accb_dout => -- accumulator b
+ data_out <= accb;
+ when ix_lo_dout => -- index reg
+ data_out <= xreg(7 downto 0);
+ when ix_hi_dout => -- index reg
+ data_out <= xreg(15 downto 8);
+ when cc_dout => -- condition codes
+ data_out <= cc;
+ when pc_lo_dout => -- low order pc
+ data_out <= pc(7 downto 0);
+ when pc_hi_dout => -- high order pc
+ data_out <= pc(15 downto 8);
+ when others =>
+ data_out <= "00000000";
+ end case;
+end process;
+
+
+----------------------------------
+--
+-- Program Counter Control
+--
+----------------------------------
+
+pc_mux: process( clk, pc_ctrl, pc, out_alu, data_in, ea, hold )
+variable tempof : std_logic_vector(15 downto 0);
+variable temppc : std_logic_vector(15 downto 0);
+begin
+ case pc_ctrl is
+ when add_ea_pc =>
+ if ea(7) = '0' then
+ tempof := "00000000" & ea(7 downto 0);
+ else
+ tempof := "11111111" & ea(7 downto 0);
+ end if;
+ when inc_pc =>
+ tempof := "0000000000000001";
+ when others =>
+ tempof := "0000000000000000";
+ end case;
+
+ case pc_ctrl is
+ when reset_pc =>
+ temppc := "1111111111111110";
+ when load_ea_pc =>
+ temppc := ea;
+ when pull_lo_pc =>
+ temppc(7 downto 0) := data_in;
+ temppc(15 downto 8) := pc(15 downto 8);
+ when pull_hi_pc =>
+ temppc(7 downto 0) := pc(7 downto 0);
+ temppc(15 downto 8) := data_in;
+ when others =>
+ temppc := pc;
+ end case;
+
+ if clk'event and clk = '0' then
+ if hold = '1' then
+ pc <= pc;
+ else
+ pc <= temppc + tempof;
+ end if;
+ end if;
+end process;
+
+----------------------------------
+--
+-- Effective Address Control
+--
+----------------------------------
+
+ea_mux: process( clk, ea_ctrl, ea, out_alu, data_in, accb, xreg, hold )
+variable tempind : std_logic_vector(15 downto 0);
+variable tempea : std_logic_vector(15 downto 0);
+begin
+ case ea_ctrl is
+ when add_ix_ea =>
+ tempind := "00000000" & ea(7 downto 0);
+ when inc_ea =>
+ tempind := "0000000000000001";
+ when others =>
+ tempind := "0000000000000000";
+ end case;
+
+ case ea_ctrl is
+ when reset_ea =>
+ tempea := "0000000000000000";
+ when load_accb_ea =>
+ tempea := "00000000" & accb(7 downto 0);
+ when add_ix_ea =>
+ tempea := xreg;
+ when fetch_first_ea =>
+ tempea(7 downto 0) := data_in;
+ tempea(15 downto 8) := "00000000";
+ when fetch_next_ea =>
+ tempea(7 downto 0) := data_in;
+ tempea(15 downto 8) := ea(7 downto 0);
+ when others =>
+ tempea := ea;
+ end case;
+
+ if clk'event and clk = '0' then
+ if hold = '1' then
+ ea <= ea;
+ else
+ ea <= tempea + tempind;
+ end if;
+ end if;
+end process;
+
+--------------------------------
+--
+-- Accumulator A
+--
+--------------------------------
+acca_mux : process( clk, acca_ctrl, out_alu, acca, data_in, hold )
+begin
+ if clk'event and clk = '0' then
+ if hold = '1' then
+ acca <= acca;
+ else
+ case acca_ctrl is
+ when reset_acca =>
+ acca <= "00000000";
+ when load_acca =>
+ acca <= out_alu(7 downto 0);
+ when load_hi_acca =>
+ acca <= out_alu(15 downto 8);
+ when pull_acca =>
+ acca <= data_in;
+ when others =>
+-- when latch_acca =>
+ acca <= acca;
+ end case;
+ end if;
+ end if;
+end process;
+
+--------------------------------
+--
+-- Accumulator B
+--
+--------------------------------
+accb_mux : process( clk, accb_ctrl, out_alu, accb, data_in, hold )
+begin
+ if clk'event and clk = '0' then
+ if hold = '1' then
+ accb <= accb;
+ else
+ case accb_ctrl is
+ when reset_accb =>
+ accb <= "00000000";
+ when load_accb =>
+ accb <= out_alu(7 downto 0);
+ when pull_accb =>
+ accb <= data_in;
+ when others =>
+-- when latch_accb =>
+ accb <= accb;
+ end case;
+ end if;
+ end if;
+end process;
+
+--------------------------------
+--
+-- X Index register
+--
+--------------------------------
+ix_mux : process( clk, ix_ctrl, out_alu, xreg, data_in, hold )
+begin
+ if clk'event and clk = '0' then
+ if hold = '1' then
+ xreg <= xreg;
+ else
+ case ix_ctrl is
+ when reset_ix =>
+ xreg <= "0000000000000000";
+ when load_ix =>
+ xreg <= out_alu(15 downto 0);
+ when pull_hi_ix =>
+ xreg(15 downto 8) <= data_in;
+ when pull_lo_ix =>
+ xreg(7 downto 0) <= data_in;
+ when others =>
+-- when latch_ix =>
+ xreg <= xreg;
+ end case;
+ end if;
+ end if;
+end process;
+
+--------------------------------
+--
+-- stack pointer
+--
+--------------------------------
+sp_mux : process( clk, sp_ctrl, out_alu, hold )
+begin
+ if clk'event and clk = '0' then
+ if hold = '1' then
+ sp <= sp;
+ else
+ case sp_ctrl is
+ when reset_sp =>
+ sp <= "0000000000000000";
+ when load_sp =>
+ sp <= out_alu(15 downto 0);
+ when others =>
+-- when latch_sp =>
+ sp <= sp;
+ end case;
+ end if;
+ end if;
+end process;
+
+--------------------------------
+--
+-- Memory Data
+--
+--------------------------------
+md_mux : process( clk, md_ctrl, out_alu, data_in, md, hold )
+begin
+ if clk'event and clk = '0' then
+ if hold = '1' then
+ md <= md;
+ else
+ case md_ctrl is
+ when reset_md =>
+ md <= "0000000000000000";
+ when load_md =>
+ md <= out_alu(15 downto 0);
+ when fetch_first_md =>
+ md(15 downto 8) <= "00000000";
+ md(7 downto 0) <= data_in;
+ when fetch_next_md =>
+ md(15 downto 8) <= md(7 downto 0);
+ md(7 downto 0) <= data_in;
+ when shiftl_md =>
+ md(15 downto 1) <= md(14 downto 0);
+ md(0) <= '0';
+ when others =>
+-- when latch_md =>
+ md <= md;
+ end case;
+ end if;
+ end if;
+end process;
+
+
+----------------------------------
+--
+-- Condition Codes
+--
+----------------------------------
+
+cc_mux: process( clk, cc_ctrl, cc_out, cc, data_in, hold )
+begin
+ if clk'event and clk = '0' then
+ if hold = '1' then
+ cc <= cc;
+ else
+ case cc_ctrl is
+ when reset_cc =>
+ cc <= "11000000";
+ when load_cc =>
+ cc <= cc_out;
+ when pull_cc =>
+ cc <= data_in;
+ when others =>
+-- when latch_cc =>
+ cc <= cc;
+ end case;
+ end if;
+ end if;
+end process;
+
+----------------------------------
+--
+-- interrupt vector
+--
+----------------------------------
+
+iv_mux: process( clk, iv_ctrl, hold )
+begin
+ if clk'event and clk = '0' then
+ if hold = '1' then
+ iv <= iv;
+ else
+ case iv_ctrl is
+ when reset_iv =>
+ iv <= "11";
+ when nmi_iv =>
+ iv <= "10";
+ when swi_iv =>
+ iv <= "01";
+ when irq_iv =>
+ iv <= "00";
+ when others =>
+ iv <= iv;
+ end case;
+ end if;
+ end if;
+end process;
+
+----------------------------------
+--
+-- op code fetch
+--
+----------------------------------
+
+op_fetch: process( clk, data_in, op_ctrl, op_code, hold )
+begin
+ if clk'event and clk = '0' then
+ if hold = '1' then
+ op_code <= op_code;
+ else
+ case op_ctrl is
+ when reset_op =>
+ op_code <= "00000001"; -- nop
+ when fetch_op =>
+ op_code <= data_in;
+ when others =>
+-- when latch_op =>
+ op_code <= op_code;
+ end case;
+ end if;
+ end if;
+end process;
+
+----------------------------------
+--
+-- Left Mux
+--
+----------------------------------
+
+left_mux: process( left_ctrl, acca, accb, xreg, sp, pc, ea, md )
+begin
+ case left_ctrl is
+ when acca_left =>
+ left(15 downto 8) <= "00000000";
+ left(7 downto 0) <= acca;
+ when accb_left =>
+ left(15 downto 8) <= "00000000";
+ left(7 downto 0) <= accb;
+ when accd_left =>
+ left(15 downto 8) <= acca;
+ left(7 downto 0) <= accb;
+ when ix_left =>
+ left <= xreg;
+ when sp_left =>
+ left <= sp;
+ when others =>
+-- when md_left =>
+ left <= md;
+ end case;
+end process;
+----------------------------------
+--
+-- Right Mux
+--
+----------------------------------
+
+right_mux: process( right_ctrl, data_in, md, accb, ea )
+begin
+ case right_ctrl is
+ when zero_right =>
+ right <= "0000000000000000";
+ when plus_one_right =>
+ right <= "0000000000000001";
+ when accb_right =>
+ right <= "00000000" & accb;
+ when others =>
+-- when md_right =>
+ right <= md;
+ end case;
+end process;
+
+----------------------------------
+--
+-- Arithmetic Logic Unit
+--
+----------------------------------
+
+mux_alu: process( alu_ctrl, cc, left, right, out_alu, cc_out )
+variable valid_lo, valid_hi : boolean;
+variable carry_in : std_logic;
+variable daa_reg : std_logic_vector(7 downto 0);
+begin
+
+ case alu_ctrl is
+ when alu_adc | alu_sbc |
+ alu_rol8 | alu_ror8 =>
+ carry_in := cc(CBIT);
+ when others =>
+ carry_in := '0';
+ end case;
+
+ valid_lo := left(3 downto 0) <= 9;
+ valid_hi := left(7 downto 4) <= 9;
+
+ if (cc(CBIT) = '0') then
+ if( cc(HBIT) = '1' ) then
+ if valid_hi then
+ daa_reg := "00000110";
+ else
+ daa_reg := "01100110";
+ end if;
+ else
+ if valid_lo then
+ if valid_hi then
+ daa_reg := "00000000";
+ else
+ daa_reg := "01100000";
+ end if;
+ else
+ if( left(7 downto 4) <= 8 ) then
+ daa_reg := "00000110";
+ else
+ daa_reg := "01100110";
+ end if;
+ end if;
+ end if;
+ else
+ if ( cc(HBIT) = '1' )then
+ daa_reg := "01100110";
+ else
+ if valid_lo then
+ daa_reg := "01100000";
+ else
+ daa_reg := "01100110";
+ end if;
+ end if;
+ end if;
+
+ case alu_ctrl is
+ when alu_add8 | alu_inc |
+ alu_add16 | alu_inx |
+ alu_adc =>
+ out_alu <= left + right + ("000000000000000" & carry_in);
+ when alu_sub8 | alu_dec |
+ alu_sub16 | alu_dex |
+ alu_sbc | alu_cpx =>
+ out_alu <= left - right - ("000000000000000" & carry_in);
+ when alu_and =>
+ out_alu <= left and right; -- and/bit
+ when alu_ora =>
+ out_alu <= left or right; -- or
+ when alu_eor =>
+ out_alu <= left xor right; -- eor/xor
+ when alu_lsl16 | alu_asl8 | alu_rol8 =>
+ out_alu <= left(14 downto 0) & carry_in; -- rol8/asl8/lsl16
+ when alu_lsr16 | alu_lsr8 =>
+ out_alu <= carry_in & left(15 downto 1); -- lsr
+ when alu_ror8 =>
+ out_alu <= "00000000" & carry_in & left(7 downto 1); -- ror
+ when alu_asr8 =>
+ out_alu <= "00000000" & left(7) & left(7 downto 1); -- asr
+ when alu_neg =>
+ out_alu <= right - left; -- neg (right=0)
+ when alu_com =>
+ out_alu <= not left;
+ when alu_clr | alu_ld8 | alu_ld16 =>
+ out_alu <= right; -- clr, ld
+ when alu_st8 | alu_st16 =>
+ out_alu <= left;
+ when alu_daa =>
+ out_alu <= left + ("00000000" & daa_reg);
+ when alu_tpa =>
+ out_alu <= "00000000" & cc;
+ when others =>
+ out_alu <= left; -- nop
+ end case;
+
+ --
+ -- carry bit
+ --
+ case alu_ctrl is
+ when alu_add8 | alu_adc =>
+ cc_out(CBIT) <= (left(7) and right(7)) or
+ (left(7) and not out_alu(7)) or
+ (right(7) and not out_alu(7));
+ when alu_sub8 | alu_sbc =>
+ cc_out(CBIT) <= ((not left(7)) and right(7)) or
+ ((not left(7)) and out_alu(7)) or
+ (right(7) and out_alu(7));
+ when alu_add16 =>
+ cc_out(CBIT) <= (left(15) and right(15)) or
+ (left(15) and not out_alu(15)) or
+ (right(15) and not out_alu(15));
+ when alu_sub16 =>
+ cc_out(CBIT) <= ((not left(15)) and right(15)) or
+ ((not left(15)) and out_alu(15)) or
+ (right(15) and out_alu(15));
+ when alu_ror8 | alu_lsr16 | alu_lsr8 | alu_asr8 =>
+ cc_out(CBIT) <= left(0);
+ when alu_rol8 | alu_asl8 =>
+ cc_out(CBIT) <= left(7);
+ when alu_lsl16 =>
+ cc_out(CBIT) <= left(15);
+ when alu_com =>
+ cc_out(CBIT) <= '1';
+ when alu_neg | alu_clr =>
+ cc_out(CBIT) <= out_alu(7) or out_alu(6) or out_alu(5) or out_alu(4) or
+ out_alu(3) or out_alu(2) or out_alu(1) or out_alu(0);
+ when alu_daa =>
+ if ( daa_reg(7 downto 4) = "0110" ) then
+ cc_out(CBIT) <= '1';
+ else
+ cc_out(CBIT) <= '0';
+ end if;
+ when alu_sec =>
+ cc_out(CBIT) <= '1';
+ when alu_clc =>
+ cc_out(CBIT) <= '0';
+ when alu_tap =>
+ cc_out(CBIT) <= left(CBIT);
+ when others => -- carry is not affected by cpx
+ cc_out(CBIT) <= cc(CBIT);
+ end case;
+ --
+ -- Zero flag
+ --
+ case alu_ctrl is
+ when alu_add8 | alu_sub8 |
+ alu_adc | alu_sbc |
+ alu_and | alu_ora | alu_eor |
+ alu_inc | alu_dec |
+ alu_neg | alu_com | alu_clr |
+ alu_rol8 | alu_ror8 | alu_asr8 | alu_asl8 | alu_lsr8 |
+ alu_ld8 | alu_st8 =>
+ cc_out(ZBIT) <= not( out_alu(7) or out_alu(6) or out_alu(5) or out_alu(4) or
+ out_alu(3) or out_alu(2) or out_alu(1) or out_alu(0) );
+ when alu_add16 | alu_sub16 |
+ alu_lsl16 | alu_lsr16 |
+ alu_inx | alu_dex |
+ alu_ld16 | alu_st16 | alu_cpx =>
+ cc_out(ZBIT) <= not( out_alu(15) or out_alu(14) or out_alu(13) or out_alu(12) or
+ out_alu(11) or out_alu(10) or out_alu(9) or out_alu(8) or
+ out_alu(7) or out_alu(6) or out_alu(5) or out_alu(4) or
+ out_alu(3) or out_alu(2) or out_alu(1) or out_alu(0) );
+ when alu_tap =>
+ cc_out(ZBIT) <= left(ZBIT);
+ when others =>
+ cc_out(ZBIT) <= cc(ZBIT);
+ end case;
+
+ --
+ -- negative flag
+ --
+ case alu_ctrl is
+ when alu_add8 | alu_sub8 |
+ alu_adc | alu_sbc |
+ alu_and | alu_ora | alu_eor |
+ alu_rol8 | alu_ror8 | alu_asr8 | alu_asl8 | alu_lsr8 |
+ alu_inc | alu_dec | alu_neg | alu_com | alu_clr |
+ alu_ld8 | alu_st8 =>
+ cc_out(NBIT) <= out_alu(7);
+ when alu_add16 | alu_sub16 |
+ alu_lsl16 | alu_lsr16 |
+ alu_ld16 | alu_st16 | alu_cpx =>
+ cc_out(NBIT) <= out_alu(15);
+ when alu_tap =>
+ cc_out(NBIT) <= left(NBIT);
+ when others =>
+ cc_out(NBIT) <= cc(NBIT);
+ end case;
+
+ --
+ -- Interrupt mask flag
+ --
+ case alu_ctrl is
+ when alu_sei =>
+ cc_out(IBIT) <= '1'; -- set interrupt mask
+ when alu_cli =>
+ cc_out(IBIT) <= '0'; -- clear interrupt mask
+ when alu_tap =>
+ cc_out(IBIT) <= left(IBIT);
+ when others =>
+ cc_out(IBIT) <= cc(IBIT); -- interrupt mask
+ end case;
+
+ --
+ -- Half Carry flag
+ --
+ case alu_ctrl is
+ when alu_add8 | alu_adc =>
+ cc_out(HBIT) <= (left(3) and right(3)) or
+ (right(3) and not out_alu(3)) or
+ (left(3) and not out_alu(3));
+ when alu_tap =>
+ cc_out(HBIT) <= left(HBIT);
+ when others =>
+ cc_out(HBIT) <= cc(HBIT);
+ end case;
+
+ --
+ -- Overflow flag
+ --
+ case alu_ctrl is
+ when alu_add8 | alu_adc =>
+ cc_out(VBIT) <= (left(7) and right(7) and (not out_alu(7))) or
+ ((not left(7)) and (not right(7)) and out_alu(7));
+ when alu_sub8 | alu_sbc =>
+ cc_out(VBIT) <= (left(7) and (not right(7)) and (not out_alu(7))) or
+ ((not left(7)) and right(7) and out_alu(7));
+ when alu_add16 =>
+ cc_out(VBIT) <= (left(15) and right(15) and (not out_alu(15))) or
+ ((not left(15)) and (not right(15)) and out_alu(15));
+ when alu_sub16 | alu_cpx =>
+ cc_out(VBIT) <= (left(15) and (not right(15)) and (not out_alu(15))) or
+ ((not left(15)) and right(15) and out_alu(15));
+ when alu_inc =>
+ cc_out(VBIT) <= ((not left(7)) and left(6) and left(5) and left(4) and
+ left(3) and left(2) and left(1) and left(0));
+ when alu_dec | alu_neg =>
+ cc_out(VBIT) <= (left(7) and (not left(6)) and (not left(5)) and (not left(4)) and
+ (not left(3)) and (not left(2)) and (not left(1)) and (not left(0)));
+ when alu_asr8 =>
+ cc_out(VBIT) <= left(0) xor left(7);
+ when alu_lsr8 | alu_lsr16 =>
+ cc_out(VBIT) <= left(0);
+ when alu_ror8 =>
+ cc_out(VBIT) <= left(0) xor cc(CBIT);
+ when alu_lsl16 =>
+ cc_out(VBIT) <= left(15) xor left(14);
+ when alu_rol8 | alu_asl8 =>
+ cc_out(VBIT) <= left(7) xor left(6);
+ when alu_tap =>
+ cc_out(VBIT) <= left(VBIT);
+ when alu_and | alu_ora | alu_eor | alu_com |
+ alu_st8 | alu_st16 | alu_ld8 | alu_ld16 |
+ alu_clv =>
+ cc_out(VBIT) <= '0';
+ when alu_sev =>
+ cc_out(VBIT) <= '1';
+ when others =>
+ cc_out(VBIT) <= cc(VBIT);
+ end case;
+
+ case alu_ctrl is
+ when alu_tap =>
+ cc_out(XBIT) <= cc(XBIT) and left(XBIT);
+ cc_out(SBIT) <= left(SBIT);
+ when others =>
+ cc_out(XBIT) <= cc(XBIT) and left(XBIT);
+ cc_out(SBIT) <= cc(SBIT);
+ end case;
+
+ test_alu <= out_alu;
+ test_cc <= cc_out;
+end process;
+
+------------------------------------
+--
+-- Detect Edge of NMI interrupt
+--
+------------------------------------
+
+nmi_handler : process( clk, rst, nmi, nmi_ack )
+begin
+ if clk'event and clk='0' then
+ if hold = '1' then
+ nmi_req <= nmi_req;
+ else
+ if rst='1' then
+ nmi_req <= '0';
+ else
+ if (nmi='1') and (nmi_ack='0') then
+ nmi_req <= '1';
+ else
+ if (nmi='0') and (nmi_ack='1') then
+ nmi_req <= '0';
+ else
+ nmi_req <= nmi_req;
+ end if;
+ end if;
+ end if;
+ end if;
+ end if;
+end process;
+
+------------------------------------
+--
+-- Nmi mux
+--
+------------------------------------
+
+nmi_mux: process( clk, nmi_ctrl, nmi_ack, hold )
+begin
+ if clk'event and clk='0' then
+ if hold = '1' then
+ nmi_ack <= nmi_ack;
+ else
+ case nmi_ctrl is
+ when set_nmi =>
+ nmi_ack <= '1';
+ when reset_nmi =>
+ nmi_ack <= '0';
+ when others =>
+-- when latch_nmi =>
+ nmi_ack <= nmi_ack;
+ end case;
+ end if;
+ end if;
+end process;
+
+------------------------------------
+--
+-- state sequencer
+--
+------------------------------------
+process( state, op_code, cc, ea, irq, nmi_req, nmi_ack, hold, halt )
+ begin
+ case state is
+ when reset_state => -- released from reset
+ -- reset the registers
+ op_ctrl <= reset_op;
+ acca_ctrl <= reset_acca;
+ accb_ctrl <= reset_accb;
+ ix_ctrl <= reset_ix;
+ sp_ctrl <= reset_sp;
+ pc_ctrl <= reset_pc;
+ ea_ctrl <= reset_ea;
+ md_ctrl <= reset_md;
+ iv_ctrl <= reset_iv;
+ nmi_ctrl <= reset_nmi;
+ -- idle the ALU
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= reset_cc;
+ -- idle the bus
+ dout_ctrl <= md_lo_dout;
+ addr_ctrl <= idle_ad;
+ next_state <= vect_hi_state;
+
+ --
+ -- Jump via interrupt vector
+ -- iv holds interrupt type
+ -- fetch PC hi from vector location
+ --
+ when vect_hi_state =>
+ -- default the registers
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ md_ctrl <= latch_md;
+ ea_ctrl <= latch_ea;
+ iv_ctrl <= latch_iv;
+ -- idle the ALU
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ -- fetch pc low interrupt vector
+ pc_ctrl <= pull_hi_pc;
+ addr_ctrl <= int_hi_ad;
+ dout_ctrl <= pc_hi_dout;
+ next_state <= vect_lo_state;
+ --
+ -- jump via interrupt vector
+ -- iv holds vector type
+ -- fetch PC lo from vector location
+ --
+ when vect_lo_state =>
+ -- default the registers
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ md_ctrl <= latch_md;
+ ea_ctrl <= latch_ea;
+ iv_ctrl <= latch_iv;
+ -- idle the ALU
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ -- fetch the vector low byte
+ pc_ctrl <= pull_lo_pc;
+ addr_ctrl <= int_lo_ad;
+ dout_ctrl <= pc_lo_dout;
+ next_state <= fetch_state;
+
+ --
+ -- Here to fetch an instruction
+ -- PC points to opcode
+ -- Should service interrupt requests at this point
+ -- either from the timer
+ -- or from the external input.
+ --
+ when fetch_state =>
+ case op_code(7 downto 4) is
+ when "0000" |
+ "0001" |
+ "0010" | -- branch conditional
+ "0011" |
+ "0100" | -- acca single op
+ "0101" | -- accb single op
+ "0110" | -- indexed single op
+ "0111" => -- extended single op
+ -- idle ALU
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+
+ when "1000" | -- acca immediate
+ "1001" | -- acca direct
+ "1010" | -- acca indexed
+ "1011" => -- acca extended
+ case op_code(3 downto 0) is
+ when "0000" => -- suba
+ left_ctrl <= acca_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_sub8;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ when "0001" => -- cmpa
+ left_ctrl <= acca_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_sub8;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ when "0010" => -- sbca
+ left_ctrl <= acca_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_sbc;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ when "0011" => -- subd
+ left_ctrl <= accd_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_sub16;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ when "0100" => -- anda
+ left_ctrl <= acca_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_and;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ when "0101" => -- bita
+ left_ctrl <= acca_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_and;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ when "0110" => -- ldaa
+ left_ctrl <= acca_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_ld8;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ when "0111" => -- staa
+ left_ctrl <= acca_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_st8;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ when "1000" => -- eora
+ left_ctrl <= acca_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_eor;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ when "1001" => -- adca
+ left_ctrl <= acca_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_adc;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ when "1010" => -- oraa
+ left_ctrl <= acca_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_ora;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ when "1011" => -- adda
+ left_ctrl <= acca_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_add8;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ when "1100" => -- cpx
+ left_ctrl <= ix_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_cpx;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ when "1101" => -- bsr / jsr
+ left_ctrl <= acca_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ when "1110" => -- lds
+ left_ctrl <= sp_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_ld16;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= load_sp;
+ when "1111" => -- sts
+ left_ctrl <= sp_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_st16;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ when others =>
+ left_ctrl <= acca_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ end case;
+ when "1100" | -- accb immediate
+ "1101" | -- accb direct
+ "1110" | -- accb indexed
+ "1111" => -- accb extended
+ case op_code(3 downto 0) is
+ when "0000" => -- subb
+ left_ctrl <= accb_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_sub8;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= load_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ when "0001" => -- cmpb
+ left_ctrl <= accb_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_sub8;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ when "0010" => -- sbcb
+ left_ctrl <= accb_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_sbc;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= load_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ when "0011" => -- addd
+ left_ctrl <= accd_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_add16;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ when "0100" => -- andb
+ left_ctrl <= accb_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_and;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= load_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ when "0101" => -- bitb
+ left_ctrl <= accb_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_and;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ when "0110" => -- ldab
+ left_ctrl <= accb_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_ld8;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= load_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ when "0111" => -- stab
+ left_ctrl <= accb_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_st8;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ when "1000" => -- eorb
+ left_ctrl <= accb_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_eor;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= load_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ when "1001" => -- adcb
+ left_ctrl <= accb_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_adc;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= load_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ when "1010" => -- orab
+ left_ctrl <= accb_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_ora;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= load_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ when "1011" => -- addb
+ left_ctrl <= accb_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_add8;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= load_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ when "1100" => -- ldd
+ left_ctrl <= accd_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_ld16;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ when "1101" => -- std
+ left_ctrl <= accd_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_st16;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ when "1110" => -- ldx
+ left_ctrl <= ix_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_ld16;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= load_ix;
+ sp_ctrl <= latch_sp;
+ when "1111" => -- stx
+ left_ctrl <= ix_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_st16;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ when others =>
+ left_ctrl <= accb_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ end case;
+ when others =>
+ left_ctrl <= accd_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ end case;
+ md_ctrl <= latch_md;
+ -- fetch the op code
+ op_ctrl <= fetch_op;
+ ea_ctrl <= reset_ea;
+ addr_ctrl <= fetch_ad;
+ dout_ctrl <= md_lo_dout;
+ iv_ctrl <= latch_iv;
+ if halt = '1' then
+ pc_ctrl <= latch_pc;
+ nmi_ctrl <= latch_nmi;
+ next_state <= halt_state;
+ -- service non maskable interrupts
+ elsif (nmi_req = '1') and (nmi_ack = '0') then
+ pc_ctrl <= latch_pc;
+ nmi_ctrl <= set_nmi;
+ next_state <= int_pcl_state;
+ -- service maskable interrupts
+ else
+ --
+ -- nmi request is not cleared until nmi input goes low
+ --
+ if(nmi_req = '0') and (nmi_ack='1') then
+ nmi_ctrl <= reset_nmi;
+ else
+ nmi_ctrl <= latch_nmi;
+ end if;
+ --
+ -- IRQ is level sensitive
+ --
+ if (irq = '1') and (cc(IBIT) = '0') then
+ pc_ctrl <= latch_pc;
+ next_state <= int_pcl_state;
+ else
+ -- Advance the PC to fetch next instruction byte
+ pc_ctrl <= inc_pc;
+ next_state <= decode_state;
+ end if;
+ end if;
+ --
+ -- Here to decode instruction
+ -- and fetch next byte of intruction
+ -- whether it be necessary or not
+ --
+ when decode_state =>
+ -- fetch first byte of address or immediate data
+ ea_ctrl <= fetch_first_ea;
+ addr_ctrl <= fetch_ad;
+ dout_ctrl <= md_lo_dout;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ iv_ctrl <= latch_iv;
+ case op_code(7 downto 4) is
+ when "0000" =>
+ md_ctrl <= fetch_first_md;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ case op_code(3 downto 0) is
+ when "0001" => -- nop
+ left_ctrl <= accd_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ when "0100" => -- lsrd
+ left_ctrl <= accd_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_lsr16;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
+ ix_ctrl <= latch_ix;
+ when "0101" => -- lsld
+ left_ctrl <= accd_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_lsl16;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
+ ix_ctrl <= latch_ix;
+ when "0110" => -- tap
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_tap;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ when "0111" => -- tpa
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_tpa;
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= load_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ when "1000" => -- inx
+ left_ctrl <= ix_left;
+ right_ctrl <= plus_one_right;
+ alu_ctrl <= alu_inx;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= load_ix;
+ when "1001" => -- dex
+ left_ctrl <= ix_left;
+ right_ctrl <= plus_one_right;
+ alu_ctrl <= alu_dex;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= load_ix;
+ when "1010" => -- clv
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_clv;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ when "1011" => -- sev
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_sev;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ when "1100" => -- clc
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_clc;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ when "1101" => -- sec
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_sec;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ when "1110" => -- cli
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_cli;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ when "1111" => -- sei
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_sei;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ when others =>
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ end case;
+ next_state <= fetch_state;
+ -- acca / accb inherent instructions
+ when "0001" =>
+ md_ctrl <= fetch_first_md;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ left_ctrl <= acca_left;
+ right_ctrl <= accb_right;
+ case op_code(3 downto 0) is
+ when "0000" => -- sba
+ alu_ctrl <= alu_sub8;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_acca;
+ accb_ctrl <= latch_accb;
+ when "0001" => -- cba
+ alu_ctrl <= alu_sub8;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ when "0110" => -- tab
+ alu_ctrl <= alu_st8;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= load_accb;
+ when "0111" => -- tba
+ alu_ctrl <= alu_ld8;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_acca;
+ accb_ctrl <= latch_accb;
+ when "1001" => -- daa
+ alu_ctrl <= alu_daa;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_acca;
+ accb_ctrl <= latch_accb;
+ when "1011" => -- aba
+ alu_ctrl <= alu_add8;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_acca;
+ accb_ctrl <= latch_accb;
+ when others =>
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ end case;
+ next_state <= fetch_state;
+ when "0010" => -- branch conditional
+ md_ctrl <= fetch_first_md;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ -- increment the pc
+ pc_ctrl <= inc_pc;
+ case op_code(3 downto 0) is
+ when "0000" => -- bra
+ next_state <= branch_state;
+ when "0001" => -- brn
+ next_state <= fetch_state;
+ when "0010" => -- bhi
+ if (cc(CBIT) or cc(ZBIT)) = '0' then
+ next_state <= branch_state;
+ else
+ next_state <= fetch_state;
+ end if;
+ when "0011" => -- bls
+ if (cc(CBIT) or cc(ZBIT)) = '1' then
+ next_state <= branch_state;
+ else
+ next_state <= fetch_state;
+ end if;
+ when "0100" => -- bcc/bhs
+ if cc(CBIT) = '0' then
+ next_state <= branch_state;
+ else
+ next_state <= fetch_state;
+ end if;
+ when "0101" => -- bcs/blo
+ if cc(CBIT) = '1' then
+ next_state <= branch_state;
+ else
+ next_state <= fetch_state;
+ end if;
+ when "0110" => -- bne
+ if cc(ZBIT) = '0' then
+ next_state <= branch_state;
+ else
+ next_state <= fetch_state;
+ end if;
+ when "0111" => -- beq
+ if cc(ZBIT) = '1' then
+ next_state <= branch_state;
+ else
+ next_state <= fetch_state;
+ end if;
+ when "1000" => -- bvc
+ if cc(VBIT) = '0' then
+ next_state <= branch_state;
+ else
+ next_state <= fetch_state;
+ end if;
+ when "1001" => -- bvs
+ if cc(VBIT) = '1' then
+ next_state <= branch_state;
+ else
+ next_state <= fetch_state;
+ end if;
+ when "1010" => -- bpl
+ if cc(NBIT) = '0' then
+ next_state <= branch_state;
+ else
+ next_state <= fetch_state;
+ end if;
+ when "1011" => -- bmi
+ if cc(NBIT) = '1' then
+ next_state <= branch_state;
+ else
+ next_state <= fetch_state;
+ end if;
+ when "1100" => -- bge
+ if (cc(NBIT) xor cc(VBIT)) = '0' then
+ next_state <= branch_state;
+ else
+ next_state <= fetch_state;
+ end if;
+ when "1101" => -- blt
+ if (cc(NBIT) xor cc(VBIT)) = '1' then
+ next_state <= branch_state;
+ else
+ next_state <= fetch_state;
+ end if;
+ when "1110" => -- bgt
+ if (cc(ZBIT) or (cc(NBIT) xor cc(VBIT))) = '0' then
+ next_state <= branch_state;
+ else
+ next_state <= fetch_state;
+ end if;
+ when "1111" => -- ble
+ if (cc(ZBIT) or (cc(NBIT) xor cc(VBIT))) = '1' then
+ next_state <= branch_state;
+ else
+ next_state <= fetch_state;
+ end if;
+ when others =>
+ next_state <= fetch_state;
+ end case;
+ --
+ -- Single byte stack operators
+ -- Do not advance PC
+ --
+ when "0011" =>
+ md_ctrl <= fetch_first_md;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ pc_ctrl <= latch_pc;
+ case op_code(3 downto 0) is
+ when "0000" => -- tsx
+ left_ctrl <= sp_left;
+ right_ctrl <= plus_one_right;
+ alu_ctrl <= alu_add16;
+ cc_ctrl <= latch_cc;
+ ix_ctrl <= load_ix;
+ sp_ctrl <= latch_sp;
+ next_state <= fetch_state;
+ when "0001" => -- ins
+ left_ctrl <= sp_left;
+ right_ctrl <= plus_one_right;
+ alu_ctrl <= alu_add16;
+ cc_ctrl <= latch_cc;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= load_sp;
+ next_state <= fetch_state;
+ when "0010" => -- pula
+ left_ctrl <= sp_left;
+ right_ctrl <= plus_one_right;
+ alu_ctrl <= alu_add16;
+ cc_ctrl <= latch_cc;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= load_sp;
+ next_state <= pula_state;
+ when "0011" => -- pulb
+ left_ctrl <= sp_left;
+ right_ctrl <= plus_one_right;
+ alu_ctrl <= alu_add16;
+ cc_ctrl <= latch_cc;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= load_sp;
+ next_state <= pulb_state;
+ when "0100" => -- des
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= plus_one_right;
+ alu_ctrl <= alu_sub16;
+ cc_ctrl <= latch_cc;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= load_sp;
+ next_state <= fetch_state;
+ when "0101" => -- txs
+ left_ctrl <= ix_left;
+ right_ctrl <= plus_one_right;
+ alu_ctrl <= alu_sub16;
+ cc_ctrl <= latch_cc;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= load_sp;
+ next_state <= fetch_state;
+ when "0110" => -- psha
+ left_ctrl <= sp_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ next_state <= psha_state;
+ when "0111" => -- pshb
+ left_ctrl <= sp_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ next_state <= pshb_state;
+ when "1000" => -- pulx
+ left_ctrl <= sp_left;
+ right_ctrl <= plus_one_right;
+ alu_ctrl <= alu_add16;
+ cc_ctrl <= latch_cc;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= load_sp;
+ next_state <= pulx_hi_state;
+ when "1001" => -- rts
+ left_ctrl <= sp_left;
+ right_ctrl <= plus_one_right;
+ alu_ctrl <= alu_add16;
+ cc_ctrl <= latch_cc;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= load_sp;
+ next_state <= rts_hi_state;
+ when "1010" => -- abx
+ left_ctrl <= ix_left;
+ right_ctrl <= accb_right;
+ alu_ctrl <= alu_add16;
+ cc_ctrl <= latch_cc;
+ ix_ctrl <= load_ix;
+ sp_ctrl <= latch_sp;
+ next_state <= fetch_state;
+ when "1011" => -- rti
+ left_ctrl <= sp_left;
+ right_ctrl <= plus_one_right;
+ alu_ctrl <= alu_add16;
+ cc_ctrl <= latch_cc;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= load_sp;
+ next_state <= rti_cc_state;
+ when "1100" => -- pshx
+ left_ctrl <= sp_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ next_state <= pshx_lo_state;
+ when "1101" => -- mul
+ left_ctrl <= acca_left;
+ right_ctrl <= accb_right;
+ alu_ctrl <= alu_add16;
+ cc_ctrl <= latch_cc;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ next_state <= mul_state;
+ when "1110" => -- wai
+ left_ctrl <= sp_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ next_state <= int_pcl_state;
+ when "1111" => -- swi
+ left_ctrl <= sp_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ next_state <= int_pcl_state;
+ when others =>
+ left_ctrl <= sp_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ next_state <= fetch_state;
+ end case;
+ --
+ -- Accumulator A Single operand
+ -- source = Acc A dest = Acc A
+ -- Do not advance PC
+ --
+ when "0100" => -- acca single op
+ md_ctrl <= fetch_first_md;
+ accb_ctrl <= latch_accb;
+ pc_ctrl <= latch_pc;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ left_ctrl <= acca_left;
+ case op_code(3 downto 0) is
+ when "0000" => -- neg
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_neg;
+ acca_ctrl <= load_acca;
+ cc_ctrl <= load_cc;
+ when "0011" => -- com
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_com;
+ acca_ctrl <= load_acca;
+ cc_ctrl <= load_cc;
+ when "0100" => -- lsr
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_lsr8;
+ acca_ctrl <= load_acca;
+ cc_ctrl <= load_cc;
+ when "0110" => -- ror
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_ror8;
+ acca_ctrl <= load_acca;
+ cc_ctrl <= load_cc;
+ when "0111" => -- asr
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_asr8;
+ acca_ctrl <= load_acca;
+ cc_ctrl <= load_cc;
+ when "1000" => -- asl
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_asl8;
+ acca_ctrl <= load_acca;
+ cc_ctrl <= load_cc;
+ when "1001" => -- rol
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_rol8;
+ acca_ctrl <= load_acca;
+ cc_ctrl <= load_cc;
+ when "1010" => -- dec
+ right_ctrl <= plus_one_right;
+ alu_ctrl <= alu_dec;
+ acca_ctrl <= load_acca;
+ cc_ctrl <= load_cc;
+ when "1011" => -- undefined
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ acca_ctrl <= latch_acca;
+ cc_ctrl <= latch_cc;
+ when "1100" => -- inc
+ right_ctrl <= plus_one_right;
+ alu_ctrl <= alu_inc;
+ acca_ctrl <= load_acca;
+ cc_ctrl <= load_cc;
+ when "1101" => -- tst
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_st8;
+ acca_ctrl <= latch_acca;
+ cc_ctrl <= load_cc;
+ when "1110" => -- jmp
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ acca_ctrl <= latch_acca;
+ cc_ctrl <= latch_cc;
+ when "1111" => -- clr
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_clr;
+ acca_ctrl <= load_acca;
+ cc_ctrl <= load_cc;
+ when others =>
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ acca_ctrl <= latch_acca;
+ cc_ctrl <= latch_cc;
+ end case;
+ next_state <= fetch_state;
+ --
+ -- single operand acc b
+ -- Do not advance PC
+ --
+ when "0101" =>
+ md_ctrl <= fetch_first_md;
+ acca_ctrl <= latch_acca;
+ pc_ctrl <= latch_pc;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ left_ctrl <= accb_left;
+ case op_code(3 downto 0) is
+ when "0000" => -- neg
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_neg;
+ accb_ctrl <= load_accb;
+ cc_ctrl <= load_cc;
+ when "0011" => -- com
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_com;
+ accb_ctrl <= load_accb;
+ cc_ctrl <= load_cc;
+ when "0100" => -- lsr
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_lsr8;
+ accb_ctrl <= load_accb;
+ cc_ctrl <= load_cc;
+ when "0110" => -- ror
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_ror8;
+ accb_ctrl <= load_accb;
+ cc_ctrl <= load_cc;
+ when "0111" => -- asr
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_asr8;
+ accb_ctrl <= load_accb;
+ cc_ctrl <= load_cc;
+ when "1000" => -- asl
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_asl8;
+ accb_ctrl <= load_accb;
+ cc_ctrl <= load_cc;
+ when "1001" => -- rol
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_rol8;
+ accb_ctrl <= load_accb;
+ cc_ctrl <= load_cc;
+ when "1010" => -- dec
+ right_ctrl <= plus_one_right;
+ alu_ctrl <= alu_dec;
+ accb_ctrl <= load_accb;
+ cc_ctrl <= load_cc;
+ when "1011" => -- undefined
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ accb_ctrl <= latch_accb;
+ cc_ctrl <= latch_cc;
+ when "1100" => -- inc
+ right_ctrl <= plus_one_right;
+ alu_ctrl <= alu_inc;
+ accb_ctrl <= load_accb;
+ cc_ctrl <= load_cc;
+ when "1101" => -- tst
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_st8;
+ accb_ctrl <= latch_accb;
+ cc_ctrl <= load_cc;
+ when "1110" => -- jmp
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ accb_ctrl <= latch_accb;
+ cc_ctrl <= latch_cc;
+ when "1111" => -- clr
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_clr;
+ accb_ctrl <= load_accb;
+ cc_ctrl <= load_cc;
+ when others =>
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ accb_ctrl <= latch_accb;
+ cc_ctrl <= latch_cc;
+ end case;
+ next_state <= fetch_state;
+ --
+ -- Single operand indexed
+ -- Two byte instruction so advance PC
+ -- EA should hold index offset
+ --
+ when "0110" => -- indexed single op
+ md_ctrl <= fetch_first_md;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ -- increment the pc
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ pc_ctrl <= inc_pc;
+ next_state <= indexed_state;
+ --
+ -- Single operand extended addressing
+ -- three byte instruction so advance the PC
+ -- Low order EA holds high order address
+ --
+ when "0111" => -- extended single op
+ md_ctrl <= fetch_first_md;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ -- increment the pc
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ pc_ctrl <= inc_pc;
+ next_state <= extended_state;
+
+ when "1000" => -- acca immediate
+ md_ctrl <= fetch_first_md;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ -- increment the pc
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ pc_ctrl <= inc_pc;
+ case op_code(3 downto 0) is
+ when "0011" | -- subdd #
+ "1100" | -- cpx #
+ "1110" => -- lds #
+ next_state <= immediate16_state;
+ when "1101" => -- bsr
+ next_state <= bsr_state;
+ when others =>
+ next_state <= fetch_state;
+ end case;
+
+ when "1001" => -- acca direct
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ -- increment the pc
+ pc_ctrl <= inc_pc;
+ case op_code(3 downto 0) is
+ when "0111" => -- staa direct
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_st8;
+ cc_ctrl <= latch_cc;
+ md_ctrl <= load_md;
+ next_state <= write8_state;
+ when "1111" => -- sts direct
+ left_ctrl <= sp_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_st16;
+ cc_ctrl <= latch_cc;
+ md_ctrl <= load_md;
+ next_state <= write16_state;
+ when "1101" => -- jsr direct
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ md_ctrl <= fetch_first_md;
+ next_state <= jsr_state;
+ when others =>
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ md_ctrl <= fetch_first_md;
+ next_state <= read8_state;
+ end case;
+
+ when "1010" => -- acca indexed
+ md_ctrl <= fetch_first_md;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ -- increment the pc
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ pc_ctrl <= inc_pc;
+ next_state <= indexed_state;
+
+ when "1011" => -- acca extended
+ md_ctrl <= fetch_first_md;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ -- increment the pc
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ pc_ctrl <= inc_pc;
+ next_state <= extended_state;
+
+ when "1100" => -- accb immediate
+ md_ctrl <= fetch_first_md;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ -- increment the pc
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ pc_ctrl <= inc_pc;
+ case op_code(3 downto 0) is
+ when "0011" | -- addd #
+ "1100" | -- ldd #
+ "1110" => -- ldx #
+ next_state <= immediate16_state;
+ when others =>
+ next_state <= fetch_state;
+ end case;
+
+ when "1101" => -- accb direct
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ -- increment the pc
+ pc_ctrl <= inc_pc;
+ case op_code(3 downto 0) is
+ when "0111" => -- stab direct
+ left_ctrl <= accb_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_st8;
+ cc_ctrl <= latch_cc;
+ md_ctrl <= load_md;
+ next_state <= write8_state;
+ when "1101" => -- std direct
+ left_ctrl <= accd_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_st16;
+ cc_ctrl <= latch_cc;
+ md_ctrl <= load_md;
+ next_state <= write16_state;
+ when "1111" => -- stx direct
+ left_ctrl <= ix_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_st16;
+ cc_ctrl <= latch_cc;
+ md_ctrl <= load_md;
+ next_state <= write16_state;
+ when others =>
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ md_ctrl <= fetch_first_md;
+ next_state <= read8_state;
+ end case;
+
+ when "1110" => -- accb indexed
+ md_ctrl <= fetch_first_md;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ -- increment the pc
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ pc_ctrl <= inc_pc;
+ next_state <= indexed_state;
+
+ when "1111" => -- accb extended
+ md_ctrl <= fetch_first_md;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ -- increment the pc
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ pc_ctrl <= inc_pc;
+ next_state <= extended_state;
+
+ when others =>
+ md_ctrl <= fetch_first_md;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ -- idle the pc
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ pc_ctrl <= latch_pc;
+ next_state <= fetch_state;
+ end case;
+
+ when immediate16_state =>
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ op_ctrl <= latch_op;
+ iv_ctrl <= latch_iv;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment pc
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ pc_ctrl <= inc_pc;
+ -- fetch next immediate byte
+ md_ctrl <= fetch_next_md;
+ addr_ctrl <= fetch_ad;
+ dout_ctrl <= md_lo_dout;
+ next_state <= fetch_state;
+ --
+ -- ea holds 8 bit index offet
+ -- calculate the effective memory address
+ -- using the alu
+ --
+ when indexed_state =>
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ -- calculate effective address from index reg
+ -- index offest is not sign extended
+ ea_ctrl <= add_ix_ea;
+ -- idle the bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ -- work out next state
+ case op_code(7 downto 4) is
+ when "0110" => -- single op indexed
+ md_ctrl <= latch_md;
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ case op_code(3 downto 0) is
+ when "1011" => -- undefined
+ next_state <= fetch_state;
+ when "1110" => -- jmp
+ next_state <= jmp_state;
+ when others =>
+ next_state <= read8_state;
+ end case;
+ when "1010" => -- acca indexed
+ case op_code(3 downto 0) is
+ when "0111" => -- staa
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_st8;
+ cc_ctrl <= latch_cc;
+ md_ctrl <= load_md;
+ next_state <= write8_state;
+ when "1101" => -- jsr
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ md_ctrl <= latch_md;
+ next_state <= jsr_state;
+ when "1111" => -- sts
+ left_ctrl <= sp_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_st16;
+ cc_ctrl <= latch_cc;
+ md_ctrl <= load_md;
+ next_state <= write16_state;
+ when others =>
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ md_ctrl <= latch_md;
+ next_state <= read8_state;
+ end case;
+ when "1110" => -- accb indexed
+ case op_code(3 downto 0) is
+ when "0111" => -- stab direct
+ left_ctrl <= accb_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_st8;
+ cc_ctrl <= latch_cc;
+ md_ctrl <= load_md;
+ next_state <= write8_state;
+ when "1101" => -- std direct
+ left_ctrl <= accd_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_st16;
+ cc_ctrl <= latch_cc;
+ md_ctrl <= load_md;
+ next_state <= write16_state;
+ when "1111" => -- stx direct
+ left_ctrl <= ix_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_st16;
+ cc_ctrl <= latch_cc;
+ md_ctrl <= load_md;
+ next_state <= write16_state;
+ when others =>
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ md_ctrl <= latch_md;
+ next_state <= read8_state;
+ end case;
+ when others =>
+ md_ctrl <= latch_md;
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ next_state <= fetch_state;
+ end case;
+ --
+ -- ea holds the low byte of the absolute address
+ -- Move ea low byte into ea high byte
+ -- load new ea low byte to for absolute 16 bit address
+ -- advance the program counter
+ --
+ when extended_state => -- fetch ea low byte
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ -- increment pc
+ pc_ctrl <= inc_pc;
+ -- fetch next effective address bytes
+ ea_ctrl <= fetch_next_ea;
+ addr_ctrl <= fetch_ad;
+ dout_ctrl <= md_lo_dout;
+ -- work out the next state
+ case op_code(7 downto 4) is
+ when "0111" => -- single op extended
+ md_ctrl <= latch_md;
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ case op_code(3 downto 0) is
+ when "1011" => -- undefined
+ next_state <= fetch_state;
+ when "1110" => -- jmp
+ next_state <= jmp_state;
+ when others =>
+ next_state <= read8_state;
+ end case;
+ when "1011" => -- acca extended
+ case op_code(3 downto 0) is
+ when "0111" => -- staa
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_st8;
+ cc_ctrl <= latch_cc;
+ md_ctrl <= load_md;
+ next_state <= write8_state;
+ when "1101" => -- jsr
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ md_ctrl <= latch_md;
+ next_state <= jsr_state;
+ when "1111" => -- sts
+ left_ctrl <= sp_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_st16;
+ cc_ctrl <= latch_cc;
+ md_ctrl <= load_md;
+ next_state <= write16_state;
+ when others =>
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ md_ctrl <= latch_md;
+ next_state <= read8_state;
+ end case;
+ when "1111" => -- accb extended
+ case op_code(3 downto 0) is
+ when "0111" => -- stab
+ left_ctrl <= accb_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_st8;
+ cc_ctrl <= latch_cc;
+ md_ctrl <= load_md;
+ next_state <= write8_state;
+ when "1101" => -- std
+ left_ctrl <= accd_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_st16;
+ cc_ctrl <= latch_cc;
+ md_ctrl <= load_md;
+ next_state <= write16_state;
+ when "1111" => -- stx
+ left_ctrl <= ix_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_st16;
+ cc_ctrl <= latch_cc;
+ md_ctrl <= load_md;
+ next_state <= write16_state;
+ when others =>
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ md_ctrl <= latch_md;
+ next_state <= read8_state;
+ end case;
+ when others =>
+ md_ctrl <= latch_md;
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ next_state <= fetch_state;
+ end case;
+ --
+ -- here if ea holds low byte (direct page)
+ -- can enter here from extended addressing
+ -- read memory location
+ -- note that reads may be 8 or 16 bits
+ --
+ when read8_state => -- read data
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ --
+ addr_ctrl <= read_ad;
+ dout_ctrl <= md_lo_dout;
+ case op_code(7 downto 4) is
+ when "0110" | "0111" => -- single operand
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ md_ctrl <= fetch_first_md;
+ ea_ctrl <= latch_ea;
+ next_state <= execute_state;
+
+ when "1001" | "1010" | "1011" => -- acca
+ case op_code(3 downto 0) is
+ when "0011" | -- subd
+ "1110" | -- lds
+ "1100" => -- cpx
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ md_ctrl <= fetch_first_md;
+ -- increment the effective address in case of 16 bit load
+ ea_ctrl <= inc_ea;
+ next_state <= read16_state;
+-- when "0111" => -- staa
+-- left_ctrl <= acca_left;
+-- right_ctrl <= zero_right;
+-- alu_ctrl <= alu_st8;
+-- cc_ctrl <= latch_cc;
+-- md_ctrl <= load_md;
+-- ea_ctrl <= latch_ea;
+-- next_state <= write8_state;
+-- when "1101" => -- jsr
+-- left_ctrl <= acca_left;
+-- right_ctrl <= zero_right;
+-- alu_ctrl <= alu_nop;
+-- cc_ctrl <= latch_cc;
+-- md_ctrl <= latch_md;
+-- ea_ctrl <= latch_ea;
+-- next_state <= jsr_state;
+-- when "1111" => -- sts
+-- left_ctrl <= sp_left;
+-- right_ctrl <= zero_right;
+-- alu_ctrl <= alu_st16;
+-- cc_ctrl <= latch_cc;
+-- md_ctrl <= load_md;
+-- ea_ctrl <= latch_ea;
+-- next_state <= write16_state;
+ when others =>
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ md_ctrl <= fetch_first_md;
+ ea_ctrl <= latch_ea;
+ next_state <= fetch_state;
+ end case;
+
+ when "1101" | "1110" | "1111" => -- accb
+ case op_code(3 downto 0) is
+ when "0011" | -- addd
+ "1100" | -- ldd
+ "1110" => -- ldx
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ md_ctrl <= fetch_first_md;
+ -- increment the effective address in case of 16 bit load
+ ea_ctrl <= inc_ea;
+ next_state <= read16_state;
+-- when "0111" => -- stab
+-- left_ctrl <= accb_left;
+-- right_ctrl <= zero_right;
+-- alu_ctrl <= alu_st8;
+-- cc_ctrl <= latch_cc;
+-- md_ctrl <= load_md;
+-- ea_ctrl <= latch_ea;
+-- next_state <= write8_state;
+-- when "1101" => -- std
+-- left_ctrl <= accd_left;
+-- right_ctrl <= zero_right;
+-- alu_ctrl <= alu_st16;
+-- cc_ctrl <= latch_cc;
+-- md_ctrl <= load_md;
+-- ea_ctrl <= latch_ea;
+-- next_state <= write16_state;
+-- when "1111" => -- stx
+-- left_ctrl <= ix_left;
+-- right_ctrl <= zero_right;
+-- alu_ctrl <= alu_st16;
+-- cc_ctrl <= latch_cc;
+-- md_ctrl <= load_md;
+-- ea_ctrl <= latch_ea;
+-- next_state <= write16_state;
+ when others =>
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ md_ctrl <= fetch_first_md;
+ ea_ctrl <= latch_ea;
+ next_state <= execute_state;
+ end case;
+ when others =>
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ md_ctrl <= fetch_first_md;
+ ea_ctrl <= latch_ea;
+ next_state <= fetch_state;
+ end case;
+
+ when read16_state => -- read second data byte from ea
+ -- default
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ -- idle the effective address
+ ea_ctrl <= latch_ea;
+ -- read the low byte of the 16 bit data
+ md_ctrl <= fetch_next_md;
+ addr_ctrl <= read_ad;
+ dout_ctrl <= md_lo_dout;
+ next_state <= fetch_state;
+ --
+ -- 16 bit Write state
+ -- write high byte of ALU output.
+ -- EA hold address of memory to write to
+ -- Advance the effective address in ALU
+ --
+ when write16_state =>
+ -- default
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ -- increment the effective address
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ ea_ctrl <= inc_ea;
+ -- write the ALU hi byte to ea
+ addr_ctrl <= write_ad;
+ dout_ctrl <= md_hi_dout;
+ next_state <= write8_state;
+ --
+ -- 8 bit write
+ -- Write low 8 bits of ALU output
+ --
+ when write8_state =>
+ -- default registers
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- idle the ALU
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ -- write ALU low byte output
+ addr_ctrl <= write_ad;
+ dout_ctrl <= md_lo_dout;
+ next_state <= fetch_state;
+
+ when jmp_state =>
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- load PC with effective address
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ pc_ctrl <= load_ea_pc;
+ -- idle the bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ next_state <= fetch_state;
+
+ when jsr_state => -- JSR
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= plus_one_right;
+ alu_ctrl <= alu_sub16;
+ cc_ctrl <= latch_cc;
+ sp_ctrl <= load_sp;
+ -- write pc low
+ addr_ctrl <= push_ad;
+ dout_ctrl <= pc_lo_dout;
+ next_state <= jsr1_state;
+
+ when jsr1_state => -- JSR
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= plus_one_right;
+ alu_ctrl <= alu_sub16;
+ cc_ctrl <= latch_cc;
+ sp_ctrl <= load_sp;
+ -- write pc hi
+ addr_ctrl <= push_ad;
+ dout_ctrl <= pc_hi_dout;
+ next_state <= jmp_state;
+
+ when branch_state => -- Bcc
+ -- default registers
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- calculate signed branch
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ pc_ctrl <= add_ea_pc;
+ -- idle the bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ next_state <= fetch_state;
+
+ when bsr_state => -- BSR
+ -- default
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= plus_one_right;
+ alu_ctrl <= alu_sub16;
+ cc_ctrl <= latch_cc;
+ sp_ctrl <= load_sp;
+ -- write pc low
+ addr_ctrl <= push_ad;
+ dout_ctrl <= pc_lo_dout;
+ next_state <= bsr1_state;
+
+ when bsr1_state => -- BSR
+ -- default registers
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= plus_one_right;
+ alu_ctrl <= alu_sub16;
+ cc_ctrl <= latch_cc;
+ sp_ctrl <= load_sp;
+ -- write pc hi
+ addr_ctrl <= push_ad;
+ dout_ctrl <= pc_hi_dout;
+ next_state <= branch_state;
+
+ when rts_hi_state => -- RTS
+ -- default
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment the sp
+ left_ctrl <= sp_left;
+ right_ctrl <= plus_one_right;
+ alu_ctrl <= alu_add16;
+ cc_ctrl <= latch_cc;
+ sp_ctrl <= load_sp;
+ -- read pc hi
+ pc_ctrl <= pull_hi_pc;
+ addr_ctrl <= pull_ad;
+ dout_ctrl <= pc_hi_dout;
+ next_state <= rts_lo_state;
+
+ when rts_lo_state => -- RTS1
+ -- default
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- idle the ALU
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ -- read pc low
+ pc_ctrl <= pull_lo_pc;
+ addr_ctrl <= pull_ad;
+ dout_ctrl <= pc_lo_dout;
+ next_state <= fetch_state;
+
+ when mul_state =>
+ -- default
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- move acca to md
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_st16;
+ cc_ctrl <= latch_cc;
+ md_ctrl <= load_md;
+ -- idle bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ next_state <= mulea_state;
+
+ when mulea_state =>
+ -- default
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ md_ctrl <= latch_md;
+ -- idle ALU
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ -- move accb to ea
+ ea_ctrl <= load_accb_ea;
+ -- idle bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ next_state <= muld_state;
+
+ when muld_state =>
+ -- default
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ md_ctrl <= latch_md;
+ -- clear accd
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_ld8;
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
+ -- idle bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ next_state <= mul0_state;
+
+ when mul0_state =>
+ -- default
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- if bit 0 of ea set, add accd to md
+ left_ctrl <= accd_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_add16;
+ if ea(0) = '1' then
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
+ else
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ end if;
+ md_ctrl <= shiftl_md;
+ -- idle bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ next_state <= mul1_state;
+
+ when mul1_state =>
+ -- default
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- if bit 1 of ea set, add accd to md
+ left_ctrl <= accd_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_add16;
+ if ea(1) = '1' then
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
+ else
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ end if;
+ md_ctrl <= shiftl_md;
+ -- idle bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ next_state <= mul2_state;
+
+ when mul2_state =>
+ -- default
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- if bit 2 of ea set, add accd to md
+ left_ctrl <= accd_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_add16;
+ if ea(2) = '1' then
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
+ else
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ end if;
+ md_ctrl <= shiftl_md;
+ -- idle bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ next_state <= mul3_state;
+
+ when mul3_state =>
+ -- default
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- if bit 3 of ea set, add accd to md
+ left_ctrl <= accd_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_add16;
+ if ea(3) = '1' then
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
+ else
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ end if;
+ md_ctrl <= shiftl_md;
+ -- idle bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ next_state <= mul4_state;
+
+ when mul4_state =>
+ -- default
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- if bit 4 of ea set, add accd to md
+ left_ctrl <= accd_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_add16;
+ if ea(4) = '1' then
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
+ else
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ end if;
+ md_ctrl <= shiftl_md;
+ -- idle bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ next_state <= mul5_state;
+
+ when mul5_state =>
+ -- default
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- if bit 5 of ea set, add accd to md
+ left_ctrl <= accd_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_add16;
+ if ea(5) = '1' then
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
+ else
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ end if;
+ md_ctrl <= shiftl_md;
+ -- idle bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ next_state <= mul6_state;
+
+ when mul6_state =>
+ -- default
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- if bit 6 of ea set, add accd to md
+ left_ctrl <= accd_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_add16;
+ if ea(6) = '1' then
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
+ else
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ end if;
+ md_ctrl <= shiftl_md;
+ -- idle bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ next_state <= mul7_state;
+
+ when mul7_state =>
+ -- default
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- if bit 7 of ea set, add accd to md
+ left_ctrl <= accd_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_add16;
+ if ea(7) = '1' then
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
+ else
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ end if;
+ md_ctrl <= shiftl_md;
+ -- idle bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ next_state <= fetch_state;
+
+ when execute_state => -- execute single operand instruction
+ -- default
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ case op_code(7 downto 4) is
+ when "0110" | -- indexed single op
+ "0111" => -- extended single op
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ iv_ctrl <= latch_iv;
+ ea_ctrl <= latch_ea;
+ -- idle the bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ left_ctrl <= md_left;
+ case op_code(3 downto 0) is
+ when "0000" => -- neg
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_neg;
+ cc_ctrl <= load_cc;
+ md_ctrl <= load_md;
+ next_state <= write8_state;
+ when "0011" => -- com
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_com;
+ cc_ctrl <= load_cc;
+ md_ctrl <= load_md;
+ next_state <= write8_state;
+ when "0100" => -- lsr
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_lsr8;
+ cc_ctrl <= load_cc;
+ md_ctrl <= load_md;
+ next_state <= write8_state;
+ when "0110" => -- ror
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_ror8;
+ cc_ctrl <= load_cc;
+ md_ctrl <= load_md;
+ next_state <= write8_state;
+ when "0111" => -- asr
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_asr8;
+ cc_ctrl <= load_cc;
+ md_ctrl <= load_md;
+ next_state <= write8_state;
+ when "1000" => -- asl
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_asl8;
+ cc_ctrl <= load_cc;
+ md_ctrl <= load_md;
+ next_state <= write8_state;
+ when "1001" => -- rol
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_rol8;
+ cc_ctrl <= load_cc;
+ md_ctrl <= load_md;
+ next_state <= write8_state;
+ when "1010" => -- dec
+ right_ctrl <= plus_one_right;
+ alu_ctrl <= alu_dec;
+ cc_ctrl <= load_cc;
+ md_ctrl <= load_md;
+ next_state <= write8_state;
+ when "1011" => -- undefined
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ md_ctrl <= latch_md;
+ next_state <= fetch_state;
+ when "1100" => -- inc
+ right_ctrl <= plus_one_right;
+ alu_ctrl <= alu_inc;
+ cc_ctrl <= load_cc;
+ md_ctrl <= load_md;
+ next_state <= write8_state;
+ when "1101" => -- tst
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_st8;
+ cc_ctrl <= load_cc;
+ md_ctrl <= latch_md;
+ next_state <= fetch_state;
+ when "1110" => -- jmp
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ md_ctrl <= latch_md;
+ next_state <= fetch_state;
+ when "1111" => -- clr
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_clr;
+ cc_ctrl <= load_cc;
+ md_ctrl <= load_md;
+ next_state <= write8_state;
+ when others =>
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ md_ctrl <= latch_md;
+ next_state <= fetch_state;
+ end case;
+
+ when others =>
+ left_ctrl <= accd_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ ea_ctrl <= latch_ea;
+ -- idle the bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ next_state <= fetch_state;
+ end case;
+
+ when psha_state =>
+ -- default registers
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= plus_one_right;
+ alu_ctrl <= alu_sub16;
+ cc_ctrl <= latch_cc;
+ sp_ctrl <= load_sp;
+ -- write acca
+ addr_ctrl <= push_ad;
+ dout_ctrl <= acca_dout;
+ next_state <= fetch_state;
+
+ when pula_state =>
+ -- default registers
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- idle sp
+ left_ctrl <= sp_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ sp_ctrl <= latch_sp;
+ -- read acca
+ acca_ctrl <= pull_acca;
+ addr_ctrl <= pull_ad;
+ dout_ctrl <= acca_dout;
+ next_state <= fetch_state;
+
+ when pshb_state =>
+ -- default registers
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= plus_one_right;
+ alu_ctrl <= alu_sub16;
+ cc_ctrl <= latch_cc;
+ sp_ctrl <= load_sp;
+ -- write accb
+ addr_ctrl <= push_ad;
+ dout_ctrl <= accb_dout;
+ next_state <= fetch_state;
+
+ when pulb_state =>
+ -- default
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- idle sp
+ left_ctrl <= sp_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ sp_ctrl <= latch_sp;
+ -- read accb
+ accb_ctrl <= pull_accb;
+ addr_ctrl <= pull_ad;
+ dout_ctrl <= accb_dout;
+ next_state <= fetch_state;
+
+ when pshx_lo_state =>
+ -- default
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= plus_one_right;
+ alu_ctrl <= alu_sub16;
+ cc_ctrl <= latch_cc;
+ sp_ctrl <= load_sp;
+ -- write ix low
+ addr_ctrl <= push_ad;
+ dout_ctrl <= ix_lo_dout;
+ next_state <= pshx_hi_state;
+
+ when pshx_hi_state =>
+ -- default registers
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= plus_one_right;
+ alu_ctrl <= alu_sub16;
+ cc_ctrl <= latch_cc;
+ sp_ctrl <= load_sp;
+ -- write ix hi
+ addr_ctrl <= push_ad;
+ dout_ctrl <= ix_hi_dout;
+ next_state <= fetch_state;
+
+ when pulx_hi_state =>
+ -- default
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= plus_one_right;
+ alu_ctrl <= alu_add16;
+ cc_ctrl <= latch_cc;
+ sp_ctrl <= load_sp;
+ -- pull ix hi
+ ix_ctrl <= pull_hi_ix;
+ addr_ctrl <= pull_ad;
+ dout_ctrl <= ix_hi_dout;
+ next_state <= pulx_lo_state;
+
+ when pulx_lo_state =>
+ -- default
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- idle sp
+ left_ctrl <= sp_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ sp_ctrl <= latch_sp;
+ -- read ix low
+ ix_ctrl <= pull_lo_ix;
+ addr_ctrl <= pull_ad;
+ dout_ctrl <= ix_lo_dout;
+ next_state <= fetch_state;
+
+ --
+ -- return from interrupt
+ -- enter here from bogus interrupts
+ --
+ when rti_state =>
+ -- default registers
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= plus_one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- idle address bus
+ cc_ctrl <= latch_cc;
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= cc_dout;
+ next_state <= rti_cc_state;
+
+ when rti_cc_state =>
+ -- default registers
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= plus_one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- read cc
+ cc_ctrl <= pull_cc;
+ addr_ctrl <= pull_ad;
+ dout_ctrl <= cc_dout;
+ next_state <= rti_accb_state;
+
+ when rti_accb_state =>
+ -- default registers
+ acca_ctrl <= latch_acca;
+ ix_ctrl <= latch_ix;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= plus_one_right;
+ alu_ctrl <= alu_add16;
+ cc_ctrl <= latch_cc;
+ sp_ctrl <= load_sp;
+ -- read accb
+ accb_ctrl <= pull_accb;
+ addr_ctrl <= pull_ad;
+ dout_ctrl <= accb_dout;
+ next_state <= rti_acca_state;
+
+ when rti_acca_state =>
+ -- default registers
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= plus_one_right;
+ alu_ctrl <= alu_add16;
+ cc_ctrl <= latch_cc;
+ sp_ctrl <= load_sp;
+ -- read acca
+ acca_ctrl <= pull_acca;
+ addr_ctrl <= pull_ad;
+ dout_ctrl <= acca_dout;
+ next_state <= rti_ixh_state;
+
+ when rti_ixh_state =>
+ -- default
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= plus_one_right;
+ alu_ctrl <= alu_add16;
+ cc_ctrl <= latch_cc;
+ sp_ctrl <= load_sp;
+ -- read ix hi
+ ix_ctrl <= pull_hi_ix;
+ addr_ctrl <= pull_ad;
+ dout_ctrl <= ix_hi_dout;
+ next_state <= rti_ixl_state;
+
+ when rti_ixl_state =>
+ -- default
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= plus_one_right;
+ alu_ctrl <= alu_add16;
+ cc_ctrl <= latch_cc;
+ sp_ctrl <= load_sp;
+ -- read ix low
+ ix_ctrl <= pull_lo_ix;
+ addr_ctrl <= pull_ad;
+ dout_ctrl <= ix_lo_dout;
+ next_state <= rti_pch_state;
+
+ when rti_pch_state =>
+ -- default
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= plus_one_right;
+ alu_ctrl <= alu_add16;
+ cc_ctrl <= latch_cc;
+ sp_ctrl <= load_sp;
+ -- pull pc hi
+ pc_ctrl <= pull_hi_pc;
+ addr_ctrl <= pull_ad;
+ dout_ctrl <= pc_hi_dout;
+ next_state <= rti_pcl_state;
+
+ when rti_pcl_state =>
+ -- default
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- idle sp
+ left_ctrl <= sp_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ sp_ctrl <= latch_sp;
+ -- pull pc low
+ pc_ctrl <= pull_lo_pc;
+ addr_ctrl <= pull_ad;
+ dout_ctrl <= pc_lo_dout;
+ next_state <= fetch_state;
+
+ --
+ -- here on interrupt
+ -- iv register hold interrupt type
+ --
+ when int_pcl_state =>
+ -- default
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= plus_one_right;
+ alu_ctrl <= alu_sub16;
+ cc_ctrl <= latch_cc;
+ sp_ctrl <= load_sp;
+ -- write pc low
+ addr_ctrl <= push_ad;
+ dout_ctrl <= pc_lo_dout;
+ next_state <= int_pch_state;
+
+ when int_pch_state =>
+ -- default
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= plus_one_right;
+ alu_ctrl <= alu_sub16;
+ cc_ctrl <= latch_cc;
+ sp_ctrl <= load_sp;
+ -- write pc hi
+ addr_ctrl <= push_ad;
+ dout_ctrl <= pc_hi_dout;
+ next_state <= int_ixl_state;
+
+ when int_ixl_state =>
+ -- default
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= plus_one_right;
+ alu_ctrl <= alu_sub16;
+ cc_ctrl <= latch_cc;
+ sp_ctrl <= load_sp;
+ -- write ix low
+ addr_ctrl <= push_ad;
+ dout_ctrl <= ix_lo_dout;
+ next_state <= int_ixh_state;
+
+ when int_ixh_state =>
+ -- default
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= plus_one_right;
+ alu_ctrl <= alu_sub16;
+ cc_ctrl <= latch_cc;
+ sp_ctrl <= load_sp;
+ -- write ix hi
+ addr_ctrl <= push_ad;
+ dout_ctrl <= ix_hi_dout;
+ next_state <= int_acca_state;
+
+ when int_acca_state =>
+ -- default
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= plus_one_right;
+ alu_ctrl <= alu_sub16;
+ cc_ctrl <= latch_cc;
+ sp_ctrl <= load_sp;
+ -- write acca
+ addr_ctrl <= push_ad;
+ dout_ctrl <= acca_dout;
+ next_state <= int_accb_state;
+
+
+ when int_accb_state =>
+ -- default
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= plus_one_right;
+ alu_ctrl <= alu_sub16;
+ cc_ctrl <= latch_cc;
+ sp_ctrl <= load_sp;
+ -- write accb
+ addr_ctrl <= push_ad;
+ dout_ctrl <= accb_dout;
+ next_state <= int_cc_state;
+
+ when int_cc_state =>
+ -- default
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= plus_one_right;
+ alu_ctrl <= alu_sub16;
+ cc_ctrl <= latch_cc;
+ sp_ctrl <= load_sp;
+ -- write cc
+ addr_ctrl <= push_ad;
+ dout_ctrl <= cc_dout;
+ nmi_ctrl <= latch_nmi;
+ --
+ -- nmi is edge triggered
+ -- nmi_req is cleared when nmi goes low.
+ --
+ if nmi_req = '1' then
+ iv_ctrl <= nmi_iv;
+ next_state <= vect_hi_state;
+ else
+ --
+ -- IRQ is level sensitive
+ --
+ if (irq = '1') and (cc(IBIT) = '0') then
+ iv_ctrl <= irq_iv;
+ next_state <= int_mask_state;
+ else
+ case op_code is
+ when "00111110" => -- WAI (wait for interrupt)
+ iv_ctrl <= latch_iv;
+ next_state <= int_wai_state;
+ when "00111111" => -- SWI (Software interrupt)
+ iv_ctrl <= swi_iv;
+ next_state <= vect_hi_state;
+ when others => -- bogus interrupt (return)
+ iv_ctrl <= latch_iv;
+ next_state <= rti_state;
+ end case;
+ end if;
+ end if;
+
+ when int_wai_state =>
+ -- default
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ op_ctrl <= latch_op;
+ ea_ctrl <= latch_ea;
+ -- enable interrupts
+ left_ctrl <= sp_left;
+ right_ctrl <= plus_one_right;
+ alu_ctrl <= alu_cli;
+ cc_ctrl <= load_cc;
+ sp_ctrl <= latch_sp;
+ -- idle bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= cc_dout;
+ if (nmi_req = '1') and (nmi_ack='0') then
+ iv_ctrl <= nmi_iv;
+ nmi_ctrl <= set_nmi;
+ next_state <= vect_hi_state;
+ else
+ --
+ -- nmi request is not cleared until nmi input goes low
+ --
+ if (nmi_req = '0') and (nmi_ack='1') then
+ nmi_ctrl <= reset_nmi;
+ else
+ nmi_ctrl <= latch_nmi;
+ end if;
+ --
+ -- IRQ is level sensitive
+ --
+ if (irq = '1') and (cc(IBIT) = '0') then
+ iv_ctrl <= irq_iv;
+ next_state <= int_mask_state;
+ else
+ iv_ctrl <= latch_iv;
+ next_state <= int_wai_state;
+ end if;
+ end if;
+
+ when int_mask_state =>
+ -- default
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- Mask IRQ
+ left_ctrl <= sp_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_sei;
+ cc_ctrl <= load_cc;
+ sp_ctrl <= latch_sp;
+ -- idle bus cycle
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ next_state <= vect_hi_state;
+
+ when halt_state => -- halt CPU.
+ -- default
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- do nothing in ALU
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ -- idle bus cycle
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ if halt = '1' then
+ next_state <= halt_state;
+ else
+ next_state <= fetch_state;
+ end if;
+
+ when others => -- error state halt on undefine states
+ -- default
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- do nothing in ALU
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ -- idle bus cycle
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ next_state <= error_state;
+ end case;
+end process;
+
+--------------------------------
+--
+-- state machine
+--
+--------------------------------
+
+change_state: process( clk, rst, state, hold )
+begin
+ if clk'event and clk = '0' then
+ if rst = '1' then
+ state <= reset_state;
+ elsif hold = '1' then
+ state <= state;
+ else
+ state <= next_state;
+ end if;
+ end if;
+end process;
+ -- output
+
+end CPU_ARCH;
+
diff --git a/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/defender_sound_board.vhd b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/defender_sound_board.vhd
new file mode 100644
index 00000000..7adbb321
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/defender_sound_board.vhd
@@ -0,0 +1,184 @@
+---------------------------------------------------------------------------------
+-- Defender sound board by Dar (darfpga@aol.fr)
+-- http://darfpga.blogspot.fr
+---------------------------------------------------------------------------------
+-- gen_ram.vhd
+--------------------------------
+-- Copyright 2005-2008 by Peter Wendrich (pwsoft@syntiac.com)
+-- http://www.syntiac.com/fpga64.html
+---------------------------------------------------------------------------------
+-- cpu68 - Version 9th Jan 2004 0.8
+-- 6800/01 compatible CPU core
+-- GNU public license - December 2002 : John E. Kent
+---------------------------------------------------------------------------------
+-- Educational use only
+-- Do not redistribute synthetized file with roms
+-- Do not redistribute roms whatever the form
+-- Use at your own risk
+---------------------------------------------------------------------------------
+-- Version 0.0 -- 15/10/2017 --
+-- initial version
+---------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_unsigned.all;
+use ieee.numeric_std.all;
+
+entity defender_sound_board is
+port(
+ clk_0p89 : in std_logic;
+ reset : in std_logic;
+ hand : out std_logic;
+ select_sound : in std_logic_vector( 5 downto 0);
+ audio_out : out std_logic_vector( 7 downto 0);
+ rom_addr : out std_logic_vector(11 downto 0);
+ rom_do : in std_logic_vector( 7 downto 0);
+ rom_vma : out std_logic
+);
+end defender_sound_board;
+
+architecture struct of defender_sound_board is
+
+ signal reset_n : std_logic;
+
+ signal cpu_addr : std_logic_vector(15 downto 0);
+ signal cpu_di : std_logic_vector( 7 downto 0);
+ signal cpu_do : std_logic_vector( 7 downto 0);
+ signal cpu_rw : std_logic;
+ signal cpu_irq : std_logic;
+ signal cpu_vma : std_logic;
+
+ signal wram_cs : std_logic;
+ signal wram_we : std_logic;
+ signal wram_do : std_logic_vector( 7 downto 0);
+
+ signal rom_cs : std_logic;
+-- signal rom_do : std_logic_vector( 7 downto 0);
+
+-- pia port a
+-- bit 0-7 audio output
+
+-- pia port b
+-- bit 0-4 select sound input (sel0-4)
+-- bit 5-6 switch sound/notes/speech on/off
+-- bit 7 sel5
+
+-- pia io ca/cb
+-- ca1 vdd
+-- cb1 sound trigger (sel0-5 = 1)
+-- ca2 speech data N/C
+-- cb2 speech clock N/C
+
+ signal pia_rw_n : std_logic;
+ signal pia_cs : std_logic;
+ signal pia_irqa : std_logic;
+ signal pia_irqb : std_logic;
+ signal pia_do : std_logic_vector( 7 downto 0);
+ signal pia_pa_o : std_logic_vector( 7 downto 0);
+ signal pia_pb_i : std_logic_vector( 7 downto 0);
+ signal pia_cb1_i : std_logic;
+
+begin
+
+reset_n <= not reset;
+
+-- pia cs
+wram_cs <= '1' when cpu_addr(15 downto 8) = X"00" else '0'; -- 0000-007F
+pia_cs <= '1' when cpu_addr(14 downto 12) = "000" and cpu_addr(10) = '1' else '0'; -- 8400-8403 ? => 0400-0403
+rom_cs <= '1' when cpu_addr(15 downto 12) = X"F" else '0'; -- F800-FFFF
+
+-- write enables
+wram_we <= '1' when cpu_rw = '0' and wram_cs = '1' else '0';
+pia_rw_n <= '0' when cpu_rw = '0' and pia_cs = '1' else '1';
+
+-- mux cpu in data between roms/io/wram
+cpu_di <=
+ wram_do when wram_cs = '1' else
+ pia_do when pia_cs = '1' else
+ rom_do when rom_cs = '1' else X"55";
+
+-- pia I/O
+audio_out <= pia_pa_o;
+
+pia_pb_i(5 downto 0) <= select_sound(5 downto 0);
+--pia_pb_i(4 downto 0) <= select_sound(4 downto 0);
+--pia_pb_i(6 downto 5) <= "11"; -- assume DS1-1 and DS1-2 open
+pia_pb_i(6) <= '1';
+pia_pb_i(7) <= '1'; -- Handshake to ? from rom board (drawings are confusing)
+
+-- pia Cb1
+pia_cb1_i <= '0' when select_sound = "111111" else '1';
+
+-- pia irqs to cpu
+cpu_irq <= pia_irqa or pia_irqb;
+
+-- microprocessor 6800
+main_cpu : entity work.cpu68
+port map(
+ clk => clk_0p89,-- E clock input (falling edge)
+ rst => reset, -- reset input (active high)
+ rw => cpu_rw, -- read not write output
+ vma => cpu_vma, -- valid memory address (active high)
+ address => cpu_addr, -- address bus output
+ data_in => cpu_di, -- data bus input
+ data_out => cpu_do, -- data bus output
+ hold => '0', -- hold input (active high) extend bus cycle
+ halt => '0', -- halt input (active high) grants DMA
+ irq => cpu_irq, -- interrupt request input (active high)
+ nmi => '0', -- non maskable interrupt request input (active high)
+ test_alu => open,
+ test_cc => open
+);
+
+-- cpu program rom
+--cpu_prog_rom : entity work.defender_sound
+--port map(
+-- clk => clk_0p89,
+-- addr => cpu_addr(10 downto 0),
+-- data => rom_do
+--);
+rom_vma <= rom_cs and cpu_vma;
+rom_addr <= cpu_addr(11 downto 0);
+
+-- cpu wram
+cpu_ram : entity work.gen_ram
+generic map( dWidth => 8, aWidth => 7)
+port map(
+ clk => clk_0p89,
+ we => wram_we,
+ addr => cpu_addr(6 downto 0),
+ d => cpu_do,
+ q => wram_do
+);
+
+-- pia
+pia : entity work.pia6821
+port map
+(
+ clk => clk_0p89,
+ rst => reset,
+ cs => pia_cs,
+ rw => pia_rw_n,
+ addr => cpu_addr(1 downto 0),
+ data_in => cpu_do,
+ data_out => pia_do,
+ irqa => pia_irqa,
+ irqb => pia_irqb,
+ pa_i => (others => '0'),
+ pa_o => pia_pa_o,
+ pa_oe => open,
+ ca1 => '1',
+ ca2_i => '0',
+ ca2_o => open,
+ ca2_oe => open,
+ pb_i => pia_pb_i,
+ pb_o => open,
+ pb_oe => open,
+ cb1 => pia_cb1_i,
+ cb2_i => '0',
+ cb2_o => open,
+ cb2_oe => open
+);
+
+end struct;
\ No newline at end of file
diff --git a/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/dpram.vhd b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/dpram.vhd
new file mode 100644
index 00000000..284194c5
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/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/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/gen_ram.vhd b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/gen_ram.vhd
new file mode 100644
index 00000000..f1a95608
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/gen_ram.vhd
@@ -0,0 +1,84 @@
+-- -----------------------------------------------------------------------
+--
+-- Syntiac's generic VHDL support files.
+--
+-- -----------------------------------------------------------------------
+-- Copyright 2005-2008 by Peter Wendrich (pwsoft@syntiac.com)
+-- http://www.syntiac.com/fpga64.html
+--
+-- Modified April 2016 by Dar (darfpga@aol.fr)
+-- http://darfpga.blogspot.fr
+-- Remove address register when writing
+--
+-- -----------------------------------------------------------------------
+--
+-- gen_rwram.vhd
+--
+-- -----------------------------------------------------------------------
+--
+-- generic ram.
+--
+-- -----------------------------------------------------------------------
+
+library IEEE;
+use IEEE.STD_LOGIC_1164.ALL;
+use IEEE.numeric_std.ALL;
+
+-- -----------------------------------------------------------------------
+
+entity gen_ram is
+ generic (
+ dWidth : integer := 8;
+ aWidth : integer := 10
+ );
+ port (
+ clk : in std_logic;
+ we : in std_logic;
+ addr : in std_logic_vector((aWidth-1) downto 0);
+ d : in std_logic_vector((dWidth-1) downto 0);
+ q : out std_logic_vector((dWidth-1) downto 0)
+ );
+end entity;
+
+-- -----------------------------------------------------------------------
+
+architecture rtl of gen_ram is
+ subtype addressRange is integer range 0 to ((2**aWidth)-1);
+ type ramDef is array(addressRange) of std_logic_vector((dWidth-1) downto 0);
+ signal ram: ramDef;
+
+ signal rAddrReg : std_logic_vector((aWidth-1) downto 0);
+ signal qReg : std_logic_vector((dWidth-1) downto 0);
+begin
+-- -----------------------------------------------------------------------
+-- Signals to entity interface
+-- -----------------------------------------------------------------------
+-- q <= qReg;
+
+-- -----------------------------------------------------------------------
+-- Memory write
+-- -----------------------------------------------------------------------
+ process(clk)
+ begin
+ if rising_edge(clk) then
+ if we = '1' then
+ ram(to_integer(unsigned(addr))) <= d;
+ end if;
+ end if;
+ end process;
+
+-- -----------------------------------------------------------------------
+-- Memory read
+-- -----------------------------------------------------------------------
+process(clk)
+ begin
+ if rising_edge(clk) then
+-- qReg <= ram(to_integer(unsigned(rAddrReg)));
+-- rAddrReg <= addr;
+---- qReg <= ram(to_integer(unsigned(addr)));
+ q <= ram(to_integer(unsigned(addr)));
+ end if;
+ end process;
+--q <= ram(to_integer(unsigned(addr)));
+end architecture;
+
diff --git a/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/pll_mist.qip b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/pll_mist.qip
new file mode 100644
index 00000000..d4720390
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/pll_mist.qip
@@ -0,0 +1,4 @@
+set_global_assignment -name IP_TOOL_NAME "ALTPLL"
+set_global_assignment -name IP_TOOL_VERSION "13.1"
+set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "pll_mist.vhd"]
+set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll_mist.ppf"]
diff --git a/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/pll_mist.vhd b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/pll_mist.vhd
new file mode 100644
index 00000000..981d030b
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/pll_mist.vhd
@@ -0,0 +1,429 @@
+-- megafunction wizard: %ALTPLL%
+-- GENERATION: STANDARD
+-- VERSION: WM1.0
+-- MODULE: altpll
+
+-- ============================================================
+-- File Name: pll_mist.vhd
+-- Megafunction Name(s):
+-- altpll
+--
+-- Simulation Library Files(s):
+-- altera_mf
+-- ============================================================
+-- ************************************************************
+-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
+--
+-- 13.1.4 Build 182 03/12/2014 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.
+
+
+LIBRARY ieee;
+USE ieee.std_logic_1164.all;
+
+LIBRARY altera_mf;
+USE altera_mf.all;
+
+ENTITY pll_mist IS
+ PORT
+ (
+ areset : IN STD_LOGIC := '0';
+ inclk0 : IN STD_LOGIC := '0';
+ c0 : OUT STD_LOGIC ;
+ c1 : OUT STD_LOGIC ;
+ c2 : OUT STD_LOGIC ;
+ locked : OUT STD_LOGIC
+ );
+END pll_mist;
+
+
+ARCHITECTURE SYN OF pll_mist IS
+
+ SIGNAL sub_wire0 : STD_LOGIC_VECTOR (4 DOWNTO 0);
+ SIGNAL sub_wire1 : STD_LOGIC ;
+ SIGNAL sub_wire2 : STD_LOGIC ;
+ SIGNAL sub_wire3 : STD_LOGIC ;
+ SIGNAL sub_wire4 : STD_LOGIC ;
+ SIGNAL sub_wire5 : STD_LOGIC ;
+ SIGNAL sub_wire6 : STD_LOGIC_VECTOR (1 DOWNTO 0);
+ SIGNAL sub_wire7_bv : BIT_VECTOR (0 DOWNTO 0);
+ SIGNAL sub_wire7 : STD_LOGIC_VECTOR (0 DOWNTO 0);
+
+
+
+ COMPONENT altpll
+ GENERIC (
+ bandwidth_type : STRING;
+ clk0_divide_by : NATURAL;
+ clk0_duty_cycle : NATURAL;
+ clk0_multiply_by : NATURAL;
+ clk0_phase_shift : STRING;
+ clk1_divide_by : NATURAL;
+ clk1_duty_cycle : NATURAL;
+ clk1_multiply_by : NATURAL;
+ clk1_phase_shift : STRING;
+ clk2_divide_by : NATURAL;
+ clk2_duty_cycle : NATURAL;
+ clk2_multiply_by : NATURAL;
+ clk2_phase_shift : STRING;
+ compensate_clock : STRING;
+ inclk0_input_frequency : NATURAL;
+ intended_device_family : STRING;
+ lpm_hint : STRING;
+ lpm_type : STRING;
+ operation_mode : STRING;
+ pll_type : STRING;
+ port_activeclock : STRING;
+ port_areset : STRING;
+ port_clkbad0 : STRING;
+ port_clkbad1 : STRING;
+ port_clkloss : STRING;
+ port_clkswitch : STRING;
+ port_configupdate : STRING;
+ port_fbin : STRING;
+ port_inclk0 : STRING;
+ port_inclk1 : STRING;
+ port_locked : STRING;
+ port_pfdena : STRING;
+ port_phasecounterselect : STRING;
+ port_phasedone : STRING;
+ port_phasestep : STRING;
+ port_phaseupdown : STRING;
+ port_pllena : STRING;
+ port_scanaclr : STRING;
+ port_scanclk : STRING;
+ port_scanclkena : STRING;
+ port_scandata : STRING;
+ port_scandataout : STRING;
+ port_scandone : STRING;
+ port_scanread : STRING;
+ port_scanwrite : STRING;
+ port_clk0 : STRING;
+ port_clk1 : STRING;
+ port_clk2 : STRING;
+ port_clk3 : STRING;
+ port_clk4 : STRING;
+ port_clk5 : STRING;
+ port_clkena0 : STRING;
+ port_clkena1 : STRING;
+ port_clkena2 : STRING;
+ port_clkena3 : STRING;
+ port_clkena4 : STRING;
+ port_clkena5 : STRING;
+ port_extclk0 : STRING;
+ port_extclk1 : STRING;
+ port_extclk2 : STRING;
+ port_extclk3 : STRING;
+ self_reset_on_loss_lock : STRING;
+ width_clock : NATURAL
+ );
+ PORT (
+ areset : IN STD_LOGIC ;
+ clk : OUT STD_LOGIC_VECTOR (4 DOWNTO 0);
+ inclk : IN STD_LOGIC_VECTOR (1 DOWNTO 0);
+ locked : OUT STD_LOGIC
+ );
+ END COMPONENT;
+
+BEGIN
+ sub_wire7_bv(0 DOWNTO 0) <= "0";
+ sub_wire7 <= To_stdlogicvector(sub_wire7_bv);
+ sub_wire4 <= sub_wire0(2);
+ sub_wire3 <= sub_wire0(0);
+ sub_wire1 <= sub_wire0(1);
+ c1 <= sub_wire1;
+ locked <= sub_wire2;
+ c0 <= sub_wire3;
+ c2 <= sub_wire4;
+ sub_wire5 <= inclk0;
+ sub_wire6 <= sub_wire7(0 DOWNTO 0) & sub_wire5;
+
+ altpll_component : altpll
+ GENERIC MAP (
+ bandwidth_type => "AUTO",
+ clk0_divide_by => 9,
+ clk0_duty_cycle => 50,
+ clk0_multiply_by => 32,
+ clk0_phase_shift => "0",
+ clk1_divide_by => 9,
+ clk1_duty_cycle => 50,
+ clk1_multiply_by => 4,
+ clk1_phase_shift => "0",
+ clk2_divide_by => 91,
+ clk2_duty_cycle => 50,
+ clk2_multiply_by => 3,
+ clk2_phase_shift => "0",
+ compensate_clock => "CLK0",
+ inclk0_input_frequency => 37037,
+ intended_device_family => "Cyclone III",
+ lpm_hint => "CBX_MODULE_PREFIX=pll_mist",
+ lpm_type => "altpll",
+ operation_mode => "NORMAL",
+ pll_type => "AUTO",
+ port_activeclock => "PORT_UNUSED",
+ port_areset => "PORT_USED",
+ port_clkbad0 => "PORT_UNUSED",
+ port_clkbad1 => "PORT_UNUSED",
+ port_clkloss => "PORT_UNUSED",
+ port_clkswitch => "PORT_UNUSED",
+ port_configupdate => "PORT_UNUSED",
+ port_fbin => "PORT_UNUSED",
+ port_inclk0 => "PORT_USED",
+ port_inclk1 => "PORT_UNUSED",
+ port_locked => "PORT_USED",
+ port_pfdena => "PORT_UNUSED",
+ port_phasecounterselect => "PORT_UNUSED",
+ port_phasedone => "PORT_UNUSED",
+ port_phasestep => "PORT_UNUSED",
+ port_phaseupdown => "PORT_UNUSED",
+ port_pllena => "PORT_UNUSED",
+ port_scanaclr => "PORT_UNUSED",
+ port_scanclk => "PORT_UNUSED",
+ port_scanclkena => "PORT_UNUSED",
+ port_scandata => "PORT_UNUSED",
+ port_scandataout => "PORT_UNUSED",
+ port_scandone => "PORT_UNUSED",
+ port_scanread => "PORT_UNUSED",
+ port_scanwrite => "PORT_UNUSED",
+ port_clk0 => "PORT_USED",
+ port_clk1 => "PORT_USED",
+ port_clk2 => "PORT_USED",
+ port_clk3 => "PORT_UNUSED",
+ port_clk4 => "PORT_UNUSED",
+ port_clk5 => "PORT_UNUSED",
+ port_clkena0 => "PORT_UNUSED",
+ port_clkena1 => "PORT_UNUSED",
+ port_clkena2 => "PORT_UNUSED",
+ port_clkena3 => "PORT_UNUSED",
+ port_clkena4 => "PORT_UNUSED",
+ port_clkena5 => "PORT_UNUSED",
+ port_extclk0 => "PORT_UNUSED",
+ port_extclk1 => "PORT_UNUSED",
+ port_extclk2 => "PORT_UNUSED",
+ port_extclk3 => "PORT_UNUSED",
+ self_reset_on_loss_lock => "OFF",
+ width_clock => 5
+ )
+ PORT MAP (
+ areset => areset,
+ inclk => sub_wire6,
+ clk => sub_wire0,
+ locked => sub_wire2
+ );
+
+
+
+END SYN;
+
+-- ============================================================
+-- CNX file retrieval info
+-- ============================================================
+-- Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0"
+-- Retrieval info: PRIVATE: BANDWIDTH STRING "1.000"
+-- Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "1"
+-- Retrieval info: PRIVATE: BANDWIDTH_FREQ_UNIT STRING "MHz"
+-- Retrieval info: PRIVATE: BANDWIDTH_PRESET STRING "Low"
+-- Retrieval info: PRIVATE: BANDWIDTH_USE_AUTO STRING "1"
+-- Retrieval info: PRIVATE: BANDWIDTH_USE_PRESET STRING "0"
+-- Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0"
+-- Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0"
+-- Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "0"
+-- Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "0"
+-- Retrieval info: PRIVATE: CREATE_CLKBAD_CHECK STRING "0"
+-- Retrieval info: PRIVATE: CREATE_INCLK1_CHECK STRING "0"
+-- Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0"
+-- Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "c0"
+-- Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "8"
+-- Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "3"
+-- Retrieval info: PRIVATE: DIV_FACTOR1 NUMERIC "9"
+-- Retrieval info: PRIVATE: DIV_FACTOR2 NUMERIC "91"
+-- Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"
+-- Retrieval info: PRIVATE: DUTY_CYCLE1 STRING "50.00000000"
+-- Retrieval info: PRIVATE: DUTY_CYCLE2 STRING "50.00000000"
+-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "96.000000"
+-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "12.000000"
+-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE2 STRING "0.890110"
+-- Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0"
+-- Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0"
+-- Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1"
+-- Retrieval info: PRIVATE: GLOCKED_FEATURE_ENABLED STRING "0"
+-- Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0"
+-- Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575"
+-- Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1"
+-- Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "27.000"
+-- Retrieval info: PRIVATE: INCLK0_FREQ_UNIT_COMBO STRING "MHz"
+-- Retrieval info: PRIVATE: INCLK1_FREQ_EDIT STRING "100.000"
+-- Retrieval info: PRIVATE: INCLK1_FREQ_EDIT_CHANGED STRING "1"
+-- Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_CHANGED STRING "1"
+-- Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_COMBO STRING "MHz"
+-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone III"
+-- Retrieval info: PRIVATE: INT_FEEDBACK__MODE_RADIO STRING "1"
+-- Retrieval info: PRIVATE: LOCKED_OUTPUT_CHECK STRING "1"
+-- Retrieval info: PRIVATE: LONG_SCAN_RADIO STRING "1"
+-- Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "Not Available"
+-- Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0"
+-- Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg"
+-- Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT1 STRING "deg"
+-- Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT2 STRING "ps"
+-- Retrieval info: PRIVATE: MIG_DEVICE_SPEED_GRADE STRING "Any"
+-- Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0"
+-- Retrieval info: PRIVATE: MIRROR_CLK1 STRING "0"
+-- Retrieval info: PRIVATE: MIRROR_CLK2 STRING "0"
+-- Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "6"
+-- Retrieval info: PRIVATE: MULT_FACTOR1 NUMERIC "2"
+-- Retrieval info: PRIVATE: MULT_FACTOR2 NUMERIC "3"
+-- Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1"
+-- Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "96.00000000"
+-- Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "12.00000000"
+-- Retrieval info: PRIVATE: OUTPUT_FREQ2 STRING "0.89000000"
+-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "1"
+-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE1 STRING "1"
+-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE2 STRING "0"
+-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz"
+-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT1 STRING "MHz"
+-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT2 STRING "MHz"
+-- Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "1"
+-- Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0"
+-- Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000"
+-- Retrieval info: PRIVATE: PHASE_SHIFT1 STRING "0.00000000"
+-- Retrieval info: PRIVATE: PHASE_SHIFT2 STRING "0.00000000"
+-- Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0"
+-- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg"
+-- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT1 STRING "deg"
+-- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT2 STRING "deg"
+-- Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0"
+-- Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "1"
+-- Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1"
+-- Retrieval info: PRIVATE: PLL_ENHPLL_CHECK NUMERIC "0"
+-- Retrieval info: PRIVATE: PLL_FASTPLL_CHECK NUMERIC "0"
+-- Retrieval info: PRIVATE: PLL_FBMIMIC_CHECK STRING "0"
+-- Retrieval info: PRIVATE: PLL_LVDS_PLL_CHECK NUMERIC "0"
+-- Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0"
+-- Retrieval info: PRIVATE: PLL_TARGET_HARCOPY_CHECK NUMERIC "0"
+-- Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0"
+-- Retrieval info: PRIVATE: RECONFIG_FILE STRING "pll_mist.mif"
+-- Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0"
+-- Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "1"
+-- Retrieval info: PRIVATE: SELF_RESET_LOCK_LOSS STRING "0"
+-- Retrieval info: PRIVATE: SHORT_SCAN_RADIO STRING "0"
+-- Retrieval info: PRIVATE: SPREAD_FEATURE_ENABLED STRING "0"
+-- Retrieval info: PRIVATE: SPREAD_FREQ STRING "50.000"
+-- Retrieval info: PRIVATE: SPREAD_FREQ_UNIT STRING "KHz"
+-- Retrieval info: PRIVATE: SPREAD_PERCENT STRING "0.500"
+-- Retrieval info: PRIVATE: SPREAD_USE STRING "0"
+-- Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "0"
+-- Retrieval info: PRIVATE: STICKY_CLK0 STRING "1"
+-- Retrieval info: PRIVATE: STICKY_CLK1 STRING "1"
+-- Retrieval info: PRIVATE: STICKY_CLK2 STRING "1"
+-- Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1"
+-- Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "1"
+-- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
+-- Retrieval info: PRIVATE: USE_CLK0 STRING "1"
+-- Retrieval info: PRIVATE: USE_CLK1 STRING "1"
+-- Retrieval info: PRIVATE: USE_CLK2 STRING "1"
+-- Retrieval info: PRIVATE: USE_CLKENA0 STRING "0"
+-- Retrieval info: PRIVATE: USE_CLKENA1 STRING "0"
+-- Retrieval info: PRIVATE: USE_CLKENA2 STRING "0"
+-- Retrieval info: PRIVATE: USE_MIL_SPEED_GRADE NUMERIC "0"
+-- Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0"
+-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
+-- Retrieval info: CONSTANT: BANDWIDTH_TYPE STRING "AUTO"
+-- Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "9"
+-- Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50"
+-- Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "32"
+-- 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 "4"
+-- Retrieval info: CONSTANT: CLK1_PHASE_SHIFT STRING "0"
+-- Retrieval info: CONSTANT: CLK2_DIVIDE_BY NUMERIC "91"
+-- Retrieval info: CONSTANT: CLK2_DUTY_CYCLE NUMERIC "50"
+-- Retrieval info: CONSTANT: CLK2_MULTIPLY_BY NUMERIC "3"
+-- Retrieval info: CONSTANT: CLK2_PHASE_SHIFT STRING "0"
+-- Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0"
+-- Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "37037"
+-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III"
+-- Retrieval info: CONSTANT: LPM_TYPE STRING "altpll"
+-- Retrieval info: CONSTANT: OPERATION_MODE STRING "NORMAL"
+-- Retrieval info: CONSTANT: PLL_TYPE STRING "AUTO"
+-- Retrieval info: CONSTANT: PORT_ACTIVECLOCK STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_ARESET STRING "PORT_USED"
+-- Retrieval info: CONSTANT: PORT_CLKBAD0 STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_CLKBAD1 STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_CLKLOSS STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_CLKSWITCH STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_CONFIGUPDATE STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_FBIN STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_INCLK0 STRING "PORT_USED"
+-- Retrieval info: CONSTANT: PORT_INCLK1 STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_LOCKED STRING "PORT_USED"
+-- Retrieval info: CONSTANT: PORT_PFDENA STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_PHASECOUNTERSELECT STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_PHASEDONE STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_PHASESTEP STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_PHASEUPDOWN STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_PLLENA STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_SCANACLR STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_SCANCLK STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_SCANCLKENA STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_SCANDATA STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_SCANDATAOUT STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_SCANDONE STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_SCANREAD STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_SCANWRITE STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_clk0 STRING "PORT_USED"
+-- Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_USED"
+-- Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_USED"
+-- Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_clk5 STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_clkena0 STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_clkena1 STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_clkena2 STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_clkena3 STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_clkena4 STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_clkena5 STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_extclk0 STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_extclk1 STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_extclk2 STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_extclk3 STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: SELF_RESET_ON_LOSS_LOCK STRING "OFF"
+-- Retrieval info: CONSTANT: WIDTH_CLOCK NUMERIC "5"
+-- Retrieval info: USED_PORT: @clk 0 0 5 0 OUTPUT_CLK_EXT VCC "@clk[4..0]"
+-- Retrieval info: USED_PORT: @inclk 0 0 2 0 INPUT_CLK_EXT VCC "@inclk[1..0]"
+-- Retrieval info: USED_PORT: areset 0 0 0 0 INPUT GND "areset"
+-- Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT_CLK_EXT VCC "c0"
+-- Retrieval info: USED_PORT: c1 0 0 0 0 OUTPUT_CLK_EXT VCC "c1"
+-- Retrieval info: USED_PORT: c2 0 0 0 0 OUTPUT_CLK_EXT VCC "c2"
+-- Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0"
+-- Retrieval info: USED_PORT: locked 0 0 0 0 OUTPUT GND "locked"
+-- Retrieval info: CONNECT: @areset 0 0 0 0 areset 0 0 0 0
+-- Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0
+-- Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0
+-- Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0
+-- Retrieval info: CONNECT: c1 0 0 0 0 @clk 0 0 1 1
+-- Retrieval info: CONNECT: c2 0 0 0 0 @clk 0 0 1 2
+-- Retrieval info: CONNECT: locked 0 0 0 0 @locked 0 0 0 0
+-- Retrieval info: GEN_FILE: TYPE_NORMAL pll_mist.vhd TRUE
+-- Retrieval info: GEN_FILE: TYPE_NORMAL pll_mist.ppf TRUE
+-- Retrieval info: GEN_FILE: TYPE_NORMAL pll_mist.inc FALSE
+-- Retrieval info: GEN_FILE: TYPE_NORMAL pll_mist.cmp FALSE
+-- Retrieval info: GEN_FILE: TYPE_NORMAL pll_mist.bsf FALSE
+-- Retrieval info: GEN_FILE: TYPE_NORMAL pll_mist_inst.vhd FALSE
+-- Retrieval info: LIB_FILE: altera_mf
+-- Retrieval info: CBX_MODULE_PREFIX: ON
diff --git a/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/robotron_cpu/decoder_4.vhd b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/robotron_cpu/decoder_4.vhd
new file mode 100644
index 00000000..ab4849dd
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/robotron_cpu/decoder_4.vhd
@@ -0,0 +1,54 @@
+library ieee;
+use ieee.std_logic_1164.all,ieee.numeric_std.all;
+
+entity decoder_4 is
+port (
+ clk : in std_logic;
+ addr : in std_logic_vector(8 downto 0);
+ data : out std_logic_vector(7 downto 0)
+);
+end entity;
+
+architecture prom of decoder_4 is
+ type rom is array(0 to 511) of std_logic_vector(7 downto 0);
+ signal rom_data: rom := (
+ X"81",X"02",X"42",X"82",X"03",X"43",X"83",X"04",X"44",X"84",X"05",X"45",X"85",X"06",X"46",X"86",
+ X"07",X"47",X"87",X"08",X"48",X"88",X"09",X"49",X"89",X"0A",X"4A",X"8A",X"0B",X"4B",X"8B",X"0C",
+ X"4C",X"8C",X"0D",X"4D",X"8D",X"0E",X"4E",X"8E",X"0F",X"4F",X"8F",X"10",X"50",X"90",X"11",X"51",
+ X"91",X"12",X"52",X"92",X"13",X"53",X"93",X"14",X"54",X"94",X"15",X"55",X"95",X"16",X"56",X"96",
+ X"17",X"57",X"97",X"18",X"58",X"98",X"19",X"59",X"99",X"1A",X"5A",X"9A",X"1B",X"5B",X"9B",X"1C",
+ X"5C",X"9C",X"1D",X"5D",X"9D",X"1E",X"5E",X"9E",X"1F",X"5F",X"9F",X"20",X"60",X"A0",X"21",X"61",
+ X"A1",X"22",X"62",X"A2",X"23",X"63",X"A3",X"24",X"64",X"A4",X"25",X"65",X"A5",X"26",X"66",X"A6",
+ X"27",X"67",X"A7",X"28",X"68",X"A8",X"29",X"69",X"A9",X"2A",X"6A",X"AA",X"2B",X"6B",X"AB",X"2C",
+ X"6C",X"AC",X"2D",X"6D",X"AD",X"2E",X"6E",X"AE",X"2F",X"6F",X"AF",X"30",X"70",X"B0",X"31",X"71",
+ X"B1",X"32",X"72",X"B2",X"33",X"73",X"B3",X"34",X"74",X"B4",X"35",X"75",X"B5",X"36",X"76",X"B6",
+ X"37",X"77",X"B7",X"38",X"78",X"B8",X"39",X"79",X"B9",X"3A",X"7A",X"BA",X"3B",X"7B",X"BB",X"3C",
+ X"7C",X"BC",X"3D",X"7D",X"BD",X"3E",X"7E",X"BE",X"3F",X"7F",X"BF",X"00",X"40",X"80",X"01",X"41",
+ X"C3",X"CF",X"D0",X"D9",X"D2",X"C9",X"C7",X"C8",X"D4",X"80",X"A8",X"C3",X"A9",X"80",X"B1",X"B9",
+ X"B8",X"B1",X"80",X"D7",X"C9",X"CC",X"CC",X"C9",X"C1",X"CD",X"D3",X"80",X"C5",X"CC",X"C5",X"C3",
+ X"D4",X"D2",X"CF",X"CE",X"C9",X"C3",X"D3",X"80",X"C9",X"CE",X"C3",X"AE",X"80",X"C1",X"CC",X"CC",
+ X"80",X"D2",X"C9",X"C7",X"C8",X"D4",X"D3",X"80",X"D2",X"C5",X"D3",X"C5",X"D2",X"D6",X"C5",X"C4",
+ X"34",X"B3",X"73",X"33",X"B2",X"72",X"32",X"B1",X"71",X"31",X"B0",X"70",X"30",X"AF",X"6F",X"2F",
+ X"AE",X"6E",X"2E",X"AD",X"6D",X"2D",X"AC",X"6C",X"2C",X"AB",X"6B",X"2B",X"AA",X"6A",X"2A",X"A9",
+ X"69",X"29",X"A8",X"68",X"28",X"A7",X"67",X"27",X"A6",X"66",X"26",X"A5",X"65",X"25",X"A4",X"64",
+ X"24",X"A3",X"63",X"23",X"A2",X"62",X"22",X"A1",X"61",X"21",X"A0",X"60",X"20",X"9F",X"5F",X"1F",
+ X"9E",X"5E",X"1E",X"9D",X"5D",X"1D",X"9C",X"5C",X"1C",X"9B",X"5B",X"1B",X"9A",X"5A",X"1A",X"99",
+ X"59",X"19",X"98",X"58",X"18",X"97",X"57",X"17",X"96",X"56",X"16",X"95",X"55",X"15",X"94",X"54",
+ X"14",X"93",X"53",X"13",X"92",X"52",X"12",X"91",X"51",X"11",X"90",X"50",X"10",X"8F",X"4F",X"0F",
+ X"8E",X"4E",X"0E",X"8D",X"4D",X"0D",X"8C",X"4C",X"0C",X"8B",X"4B",X"0B",X"8A",X"4A",X"0A",X"89",
+ X"49",X"09",X"88",X"48",X"08",X"87",X"47",X"07",X"86",X"46",X"06",X"85",X"45",X"05",X"84",X"44",
+ X"04",X"83",X"43",X"03",X"82",X"42",X"02",X"81",X"74",X"B4",X"35",X"75",X"B5",X"36",X"76",X"B6",
+ X"37",X"77",X"B7",X"38",X"78",X"B8",X"39",X"79",X"B9",X"3A",X"7A",X"BA",X"3B",X"7B",X"BB",X"3C",
+ X"7C",X"BC",X"3D",X"7D",X"BD",X"3E",X"7E",X"BE",X"3F",X"7F",X"BF",X"00",X"40",X"80",X"01",X"41",
+ X"C3",X"CF",X"D0",X"D9",X"D2",X"C9",X"C7",X"C8",X"D4",X"80",X"A8",X"C3",X"A9",X"80",X"B1",X"B9",
+ X"B8",X"B1",X"80",X"D7",X"C9",X"CC",X"CC",X"C9",X"C1",X"CD",X"D3",X"80",X"C5",X"CC",X"C5",X"C3",
+ X"D4",X"D2",X"CF",X"CE",X"C9",X"C3",X"D3",X"80",X"C9",X"CE",X"C3",X"AE",X"80",X"C1",X"CC",X"CC",
+ X"80",X"D2",X"C9",X"C7",X"C8",X"D4",X"D3",X"80",X"D2",X"C5",X"D3",X"C5",X"D2",X"D6",X"C5",X"C4");
+begin
+process(clk)
+begin
+ if rising_edge(clk) then
+ data <= rom_data(to_integer(unsigned(addr)));
+ end if;
+end process;
+end architecture;
diff --git a/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/robotron_cpu/decoder_6.vhd b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/robotron_cpu/decoder_6.vhd
new file mode 100644
index 00000000..0e46cdd5
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/robotron_cpu/decoder_6.vhd
@@ -0,0 +1,54 @@
+library ieee;
+use ieee.std_logic_1164.all,ieee.numeric_std.all;
+
+entity decoder_6 is
+port (
+ clk : in std_logic;
+ addr : in std_logic_vector(8 downto 0);
+ data : out std_logic_vector(7 downto 0)
+);
+end entity;
+
+architecture prom of decoder_6 is
+ type rom is array(0 to 511) of std_logic_vector(7 downto 0);
+ signal rom_data: rom := (
+ X"00",X"00",X"01",X"02",X"03",X"04",X"05",X"06",X"07",X"08",X"09",X"0A",X"0B",X"0C",X"0D",X"0E",
+ X"0F",X"10",X"11",X"12",X"13",X"14",X"15",X"16",X"17",X"18",X"19",X"1A",X"1B",X"1C",X"1D",X"1E",
+ X"1F",X"20",X"21",X"22",X"23",X"24",X"25",X"26",X"27",X"28",X"29",X"2A",X"2B",X"2C",X"2D",X"2E",
+ X"2F",X"30",X"31",X"32",X"33",X"34",X"35",X"36",X"37",X"38",X"39",X"3A",X"3B",X"3C",X"3D",X"3E",
+ X"3F",X"40",X"41",X"42",X"43",X"44",X"45",X"46",X"47",X"48",X"49",X"4A",X"4B",X"4C",X"4D",X"4E",
+ X"4F",X"50",X"51",X"52",X"53",X"54",X"55",X"56",X"57",X"58",X"59",X"5A",X"5B",X"5C",X"5D",X"5E",
+ X"5F",X"60",X"61",X"62",X"63",X"64",X"65",X"66",X"67",X"68",X"69",X"6A",X"6B",X"6C",X"6D",X"6E",
+ X"6F",X"70",X"71",X"72",X"73",X"74",X"75",X"76",X"77",X"78",X"79",X"7A",X"7B",X"7C",X"7D",X"7E",
+ X"7F",X"80",X"81",X"82",X"83",X"84",X"85",X"86",X"87",X"88",X"89",X"8A",X"8B",X"8C",X"8D",X"8E",
+ X"8F",X"90",X"91",X"92",X"93",X"94",X"95",X"96",X"97",X"98",X"99",X"9A",X"9B",X"9C",X"9D",X"9E",
+ X"9F",X"A0",X"A1",X"A2",X"A3",X"A4",X"A5",X"A6",X"A7",X"A8",X"A9",X"AA",X"AB",X"AC",X"AD",X"AE",
+ X"AF",X"B0",X"B1",X"B2",X"B3",X"B4",X"B5",X"B6",X"B7",X"B8",X"B9",X"BA",X"BB",X"BC",X"BD",X"BE",
+ X"BF",X"C0",X"C1",X"C2",X"C3",X"C4",X"C5",X"C6",X"C7",X"C8",X"C9",X"CA",X"CB",X"CC",X"CD",X"CE",
+ X"CF",X"D0",X"D1",X"D2",X"D3",X"D4",X"D5",X"D6",X"D7",X"D8",X"D9",X"DA",X"DB",X"DC",X"DD",X"DE",
+ X"DF",X"E0",X"E1",X"E2",X"E3",X"E4",X"E5",X"E6",X"E7",X"E8",X"E9",X"EA",X"EB",X"EC",X"ED",X"EE",
+ X"EF",X"F0",X"F1",X"F2",X"F3",X"F4",X"F5",X"F6",X"F7",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
+ X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"F7",X"F6",X"F5",X"F4",X"F3",X"F2",X"F1",X"F0",X"EF",
+ X"EE",X"ED",X"EC",X"EB",X"EA",X"E9",X"E8",X"E7",X"E6",X"E5",X"E4",X"E3",X"E2",X"E1",X"E0",X"DF",
+ X"DE",X"DD",X"DC",X"DB",X"DA",X"D9",X"D8",X"D7",X"D6",X"D5",X"D4",X"D3",X"D2",X"D1",X"D0",X"CF",
+ X"CE",X"CD",X"CC",X"CB",X"CA",X"C9",X"C8",X"C7",X"C6",X"C5",X"C4",X"C3",X"C2",X"C1",X"C0",X"BF",
+ X"BE",X"BD",X"BC",X"BB",X"BA",X"B9",X"B8",X"B7",X"B6",X"B5",X"B4",X"B3",X"B2",X"B1",X"B0",X"AF",
+ X"AE",X"AD",X"AC",X"AB",X"AA",X"A9",X"A8",X"A7",X"A6",X"A5",X"A4",X"A3",X"A2",X"A1",X"A0",X"9F",
+ X"9E",X"9D",X"9C",X"9B",X"9A",X"99",X"98",X"97",X"96",X"95",X"94",X"93",X"92",X"91",X"90",X"8F",
+ X"8E",X"8D",X"8C",X"8B",X"8A",X"89",X"88",X"87",X"86",X"85",X"84",X"83",X"82",X"81",X"80",X"7F",
+ X"7E",X"7D",X"7C",X"7B",X"7A",X"79",X"78",X"77",X"76",X"75",X"74",X"73",X"72",X"71",X"70",X"6F",
+ X"6E",X"6D",X"6C",X"6B",X"6A",X"69",X"68",X"67",X"66",X"65",X"64",X"63",X"62",X"61",X"60",X"5F",
+ X"5E",X"5D",X"5C",X"5B",X"5A",X"59",X"58",X"57",X"56",X"55",X"54",X"53",X"52",X"51",X"50",X"4F",
+ X"4E",X"4D",X"4C",X"4B",X"4A",X"49",X"48",X"47",X"46",X"45",X"44",X"43",X"42",X"41",X"40",X"3F",
+ X"3E",X"3D",X"3C",X"3B",X"3A",X"39",X"38",X"37",X"36",X"35",X"34",X"33",X"32",X"31",X"30",X"2F",
+ X"2E",X"2D",X"2C",X"2B",X"2A",X"29",X"28",X"27",X"26",X"25",X"24",X"23",X"22",X"21",X"20",X"1F",
+ X"1E",X"1D",X"1C",X"1B",X"1A",X"19",X"18",X"17",X"16",X"15",X"14",X"13",X"12",X"11",X"10",X"0F",
+ X"0E",X"0D",X"0C",X"0B",X"0A",X"09",X"08",X"07",X"06",X"05",X"04",X"03",X"02",X"01",X"00",X"00");
+begin
+process(clk)
+begin
+ if rising_edge(clk) then
+ data <= rom_data(to_integer(unsigned(addr)));
+ end if;
+end process;
+end architecture;
diff --git a/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/robotron_cpu/robotron_cpu.vhd b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/robotron_cpu/robotron_cpu.vhd
new file mode 100755
index 00000000..901b252a
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/robotron_cpu/robotron_cpu.vhd
@@ -0,0 +1,1096 @@
+-----------------------------------------------------------------------
+--
+-- Copyright 2012 ShareBrained Technology, Inc.
+--
+-- This file is part of robotron-fpga.
+--
+-- robotron-fpga 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.
+--
+-- robotron-fpga 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 robotron-fpga. If not, see
+-- .
+--
+-- Jan 2020:
+-- Converted from bidirectional data buses to separated buses for SOC usage
+-- Changed to orignal 15kHz display timing
+-- Replaced PIAs from System09 (the original didn't work in Joust)
+-- Added blitter SC2 selection (for Splat)
+-----------------------------------------------------------------------
+
+library ieee;
+ use ieee.std_logic_1164.all;
+ use ieee.numeric_std.all;
+
+--library unisim;
+-- use unisim.vcomponents.all;
+
+entity robotron_cpu is
+ port(
+ clock : in std_logic;
+ blitter_sc2 : in std_logic;
+ sinistar : in std_logic;
+
+ -- MC6809 signals
+ A : in std_logic_vector(15 downto 0);
+ Dout : in std_logic_vector(7 downto 0);
+ Din : out std_logic_vector(7 downto 0);
+ RESET_N : out std_logic;
+ NMI_N : out std_logic;
+ FIRQ_N : out std_logic;
+ IRQ_N : out std_logic;
+ LIC : in std_logic;
+ AVMA : in std_logic;
+ R_W_N : in std_logic;
+ TSC : out std_logic;
+ HALT_N : out std_logic;
+ BA : in std_logic;
+ BS : in std_logic;
+ BUSY : in std_logic;
+ E : out std_logic;
+ Q : out std_logic;
+
+ -- USB
+ --EppAstb : in std_logic;
+ --EppDstb : in std_logic;
+ --UsbFlag : in std_logic;
+ --EppWait : in std_logic;
+ --EppDB : in std_logic_vector(7 downto 0);
+ --UsbClk : in std_logic;
+ --UsbOE : in std_logic;
+ --UsbWR : in std_logic;
+ --UsbPktEnd : in std_logic;
+ --UsbDir : in std_logic;
+ --UsbMode : in std_logic;
+ --UsbAdr : in std_logic_vector(1 downto 0);
+
+ -- Cellular RAM / StrataFlash
+ MemOE : out std_logic;
+ MemWR : out std_logic;
+
+ RamAdv : out std_logic;
+ RamCS : out std_logic;
+ RamClk : out std_logic;
+ RamCRE : out std_logic;
+ RamLB : out std_logic;
+ RamUB : out std_logic;
+ RamWait : in std_logic;
+
+ FlashRp : out std_logic;
+ FlashCS : out std_logic;
+ FlashStSts : in std_logic;
+
+ MemAdr : out std_logic_vector(23 downto 1);
+ MemDin : out std_logic_vector(15 downto 0);
+ MemDout : in std_logic_vector(15 downto 0);
+
+ -- 7-segment display
+ SEG : out std_logic_vector(6 downto 0);
+ DP : out std_logic;
+ AN : out std_logic_vector(3 downto 0);
+
+ -- LEDs
+ LED : out std_logic_vector(7 downto 0);
+
+ -- Switches
+ SW : in std_logic_vector(7 downto 0);
+
+ -- Buttons
+ BTN : in std_logic_vector(3 downto 0);
+
+ -- VGA connector
+ vgaRed : out std_logic_vector(2 downto 0);
+ vgaGreen : out std_logic_vector(2 downto 0);
+ vgaBlue : out std_logic_vector(1 downto 0);
+ Hsync : out std_logic;
+ Vsync : out std_logic;
+
+ -- PS/2 connector
+ --PS2C : in std_logic;
+ --PS2D : in std_logic;
+
+ -- 12-pin connectors
+ JA : in std_logic_vector(7 downto 0);
+ JB : in std_logic_vector(7 downto 0);
+ SIN_FIRE : in std_logic;
+ SIN_BOMB : in std_logic;
+
+ -- To sound board
+ HAND : in std_logic := '1';
+ PB : out std_logic_vector(5 downto 0)
+ );
+end robotron_cpu;
+
+architecture Behavioral of robotron_cpu is
+
+ signal reset_request : std_logic;
+ signal reset_counter : unsigned(7 downto 0);
+ signal reset : std_logic;
+
+ signal clock_12_phase : unsigned(11 downto 0) := (0 => '1', others => '0');
+
+ signal clock_q_set : boolean;
+ signal clock_q_clear : boolean;
+ signal clock_q : std_logic := '0';
+
+ signal clock_e_set : boolean;
+ signal clock_e_clear : boolean;
+ signal clock_e : std_logic := '0';
+
+ -------------------------------------------------------------------
+
+ signal video_count : unsigned(14 downto 0) := (others => '0');
+ signal video_count_next : unsigned(14 downto 0);
+ signal video_address_or_mask : unsigned(13 downto 0);
+ signal video_address : unsigned(13 downto 0) := (others => '0');
+
+ signal count_240 : std_logic;
+ signal irq_4ms : std_logic;
+
+ signal horizontal_sync : std_logic;
+ signal vertical_sync : std_logic;
+
+ signal video_blank : boolean := true;
+
+ -------------------------------------------------------------------
+
+ signal led_bcd_in : std_logic_vector(15 downto 0);
+ signal led_bcd_in_digit : std_logic_vector(3 downto 0);
+
+ signal led_counter : unsigned(15 downto 0) := (others => '0');
+ signal led_digit_index : unsigned(1 downto 0);
+
+ signal led_segment : std_logic_vector(6 downto 0);
+ signal led_dp : std_logic;
+ signal led_anode : std_logic_vector(3 downto 0);
+
+ -------------------------------------------------------------------
+
+ signal address : std_logic_vector(15 downto 0);
+
+ signal write : boolean;
+ signal read : boolean;
+
+ -------------------------------------------------------------------
+
+ signal mpu_address : std_logic_vector(15 downto 0);
+ signal mpu_data_in : std_logic_vector(7 downto 0);
+ signal mpu_data_out : std_logic_vector(7 downto 0);
+
+ signal mpu_bus_status : std_logic;
+ signal mpu_bus_available : std_logic;
+
+ signal mpu_read : boolean;
+ signal mpu_write : boolean;
+
+ signal mpu_reset : std_logic := '1';
+ signal mpu_halt : std_logic := '0';
+ signal mpu_halted : boolean := false;
+ signal mpu_irq : std_logic := '0';
+ signal mpu_firq : std_logic := '0';
+ signal mpu_nmi : std_logic := '0';
+
+ -------------------------------------------------------------------
+
+ signal memory_address : std_logic_vector(15 downto 0);
+ signal memory_data_in : std_logic_vector(7 downto 0);
+ signal memory_data_out : std_logic_vector(7 downto 0);
+
+ signal memory_output_enable : boolean := false;
+ signal memory_write : boolean := false;
+ signal flash_enable : boolean := false;
+
+ signal ram_enable : boolean := false;
+ signal ram_lower_enable : boolean := false;
+ signal ram_upper_enable : boolean := false;
+
+ -------------------------------------------------------------------
+
+ signal e_rom : std_logic := '0';
+ signal screen_control : std_logic := '0';
+
+ signal rom_access : boolean;
+ signal ram_access : boolean;
+ signal hiram_access : boolean; -- Sinistar hiram
+ signal color_table_access : boolean;
+ signal widget_pia_access : boolean;
+ signal rom_pia_access : boolean;
+ signal blt_register_access : boolean;
+ signal video_counter_access : boolean;
+ signal watchdog_access : boolean;
+ signal control_access : boolean;
+ signal cmos_access : boolean;
+
+ signal video_counter_value : std_logic_vector(7 downto 0);
+
+ -------------------------------------------------------------------
+
+ signal SLAM : std_logic := '1';
+ signal R_COIN : std_logic := '1';
+ signal C_COIN : std_logic := '1';
+ signal L_COIN : std_logic := '1';
+ signal H_S_RESET : std_logic := '1';
+ signal ADVANCE : std_logic := '1';
+ signal AUTO_UP : std_logic := '0';
+
+ signal rom_pia_rs : std_logic_vector(1 downto 0) := (others => '0');
+ signal rom_pia_cs : std_logic := '0';
+ signal rom_pia_write : std_logic := '0';
+ signal rom_pia_data_in : std_logic_vector(7 downto 0);
+ signal rom_pia_data_out : std_logic_vector(7 downto 0);
+ signal rom_pia_ca2_out : std_logic;
+ signal rom_pia_ca2_dir : std_logic;
+ signal rom_pia_irq_a : std_logic;
+ signal rom_pia_pa_in : std_logic_vector(7 downto 0);
+ signal rom_pia_pa_out : std_logic_vector(7 downto 0);
+ signal rom_pia_pa_dir : std_logic_vector(7 downto 0);
+
+ signal rom_pia_cb2_out : std_logic;
+ signal rom_pia_cb2_dir : std_logic;
+ signal rom_pia_irq_b : std_logic;
+ signal rom_pia_pb_in : std_logic_vector(7 downto 0);
+ signal rom_pia_pb_out : std_logic_vector(7 downto 0);
+ signal rom_pia_pb_dir : std_logic_vector(7 downto 0);
+
+ signal rom_led_digit : std_logic_vector(3 downto 0);
+
+ -------------------------------------------------------------------
+
+ signal MOVE_UP_1 : std_logic := '1';
+ signal MOVE_DOWN_1 : std_logic := '1';
+ signal MOVE_LEFT_1 : std_logic := '1';
+ signal MOVE_RIGHT_1 : std_logic := '1';
+ signal PLAYER_1_START : std_logic := '1';
+ signal PLAYER_2_START : std_logic := '1';
+ signal FIRE_UP_1 : std_logic := '1';
+ signal FIRE_DOWN_1 : std_logic := '1';
+ signal FIRE_RIGHT_1 : std_logic := '1';
+ signal FIRE_LEFT_1 : std_logic := '1';
+ signal MOVE_UP_2 : std_logic := '1';
+ signal MOVE_DOWN_2 : std_logic := '1';
+ signal MOVE_LEFT_2 : std_logic := '1';
+ signal MOVE_RIGHT_2 : std_logic := '1';
+ signal FIRE_RIGHT_2 : std_logic := '1';
+ signal FIRE_UP_2 : std_logic := '1';
+ signal FIRE_DOWN_2 : std_logic := '1';
+ signal FIRE_LEFT_2 : std_logic := '1';
+
+ signal board_interface_w1 : std_logic := '1'; -- Upright application: '1' = jumper present
+
+ signal widget_pia_rs : std_logic_vector(1 downto 0) := (others => '0');
+ signal widget_pia_cs : std_logic;
+ signal widget_pia_write : std_logic := '0';
+ signal widget_pia_data_in : std_logic_vector(7 downto 0);
+ signal widget_pia_data_out : std_logic_vector(7 downto 0);
+ signal widget_pia_ca2_out : std_logic;
+ signal widget_pia_ca2_dir : std_logic;
+ signal widget_pia_irq_a : std_logic;
+ signal widget_pia_pa_in : std_logic_vector(7 downto 0);
+ signal widget_pia_pa_out : std_logic_vector(7 downto 0);
+ signal widget_pia_pa_dir : std_logic_vector(7 downto 0);
+ signal widget_pia_input_select : std_logic;
+ signal widget_pia_cb2_out : std_logic;
+ signal widget_pia_cb2_dir : std_logic;
+ signal widget_pia_irq_b : std_logic;
+ signal widget_pia_pb_in : std_logic_vector(7 downto 0);
+ signal widget_pia_pb_out : std_logic_vector(7 downto 0);
+ signal widget_pia_pb_dir : std_logic_vector(7 downto 0);
+
+ signal widget_ic3_a : std_logic_vector(4 downto 1);
+ signal widget_ic3_b : std_logic_vector(4 downto 1);
+ signal widget_ic3_y : std_logic_vector(4 downto 1);
+
+ signal widget_ic4_a : std_logic_vector(4 downto 1);
+ signal widget_ic4_b : std_logic_vector(4 downto 1);
+ signal widget_ic4_y : std_logic_vector(4 downto 1);
+
+ -------------------------------------------------------------------
+
+ signal blt_rs : std_logic_vector(2 downto 0) := (others => '0');
+ signal blt_reg_cs : std_logic := '0';
+ signal blt_reg_data_in : std_logic_vector(7 downto 0) := (others => '0');
+
+ signal blt_halt : boolean := false;
+ signal blt_halt_ack : boolean := false;
+ signal blt_read : boolean := false;
+ signal blt_write : boolean := false;
+ signal blt_blt_ack : std_logic := '0';
+ signal blt_address_out : std_logic_vector(15 downto 0);
+ signal blt_data_in : std_logic_vector(7 downto 0);
+ signal blt_data_out : std_logic_vector(7 downto 0);
+ signal blt_en_lower : boolean := false;
+ signal blt_en_upper : boolean := false;
+
+ -------------------------------------------------------------------
+
+ function to_std_logic(L: boolean) return std_logic is
+ begin
+ if L then
+ return '1';
+ else
+ return '0';
+ end if;
+ end function;
+
+ subtype pixel_color_t is std_logic_vector(7 downto 0);
+ type color_table_t is array(0 to 15) of pixel_color_t;
+ signal color_table : color_table_t;
+
+ signal pixel_nibbles : std_logic_vector(7 downto 0);
+ signal pixel_byte_l : std_logic_vector(7 downto 0);
+ signal pixel_byte_h : std_logic_vector(7 downto 0);
+
+ -------------------------------------------------------------------
+
+ signal decoder_4_in : std_logic_vector(8 downto 0);
+ signal pseudo_address : std_logic_vector(15 downto 8);
+
+ signal decoder_6_in : std_logic_vector(8 downto 0);
+ signal video_prom_address : std_logic_vector(13 downto 6);
+
+ -------------------------------------------------------------------
+
+ signal debug_blt_source_address : std_logic_vector(15 downto 0) := (others => '0');
+ signal debug_last_mpu_address : std_logic_vector(15 downto 0) := (others => '0');
+
+begin
+
+ -- clock 0 1 2 3 4 5 6 7 8 9 10 11
+ -- Q 0 0 0 1 1 1 1 1 1 0 0 0
+ -- E 0 0 0 0 0 0 1 1 1 1 1 1
+ -- Memory 0 0 1 1 2 2 3 3 4 4 5 5
+
+ -- Micro 128Mb (8M x 16) CellularRAM MT45W8MW16BGX-701 WT (marking "PW503")
+ -- MT: Micron Technology
+ -- 45: PSRAM/CellularRAM memory
+ -- W: 1.70-1.95V
+ -- 8M: 8 Meg address space
+ -- W: 1.7 - 3.6V
+ -- 16: 16-bit bus
+ -- B: asynchronous/page/burst read/write operation mode
+ -- GX: 54-ball "green" VFBGA
+ -- -70: 70ns access/cycle time
+ -- 1: 104MHz frequency
+ -- : standard standby power option
+ -- WT: -30C to +85C operating temperature
+ -------------------------------------------------------------------
+ -- Asynchronous mode:
+ -- tRC (read cycle): 70 ns
+ -- from CE#/OE#/ADDRESS/LB#/UB# asserted to DATA valid and CE#/OE#/ADDRESS/LB#/UB# de-asserted.
+ -- tWC (write cycle): 70 ns
+ -- from CE#/ADDRESS/LB#/UB# asserted to DATA valid and CE#/WE#/LB#/UB# de-asserted.
+ -- tCEM: 4 us maximum
+ -- from WE# asserted to DATA valid and CE#/WE#/LB#/UB# de-asserted.
+
+ -- Intel JS28F128J3D75
+ -------------------------------------------------------------------
+ -- Read:
+ -- 75 ns read/write cycle time
+ -- 75 ns address to output delay
+ -- 75 ns CE# to output delay
+
+ reset_request <= BTN(0);
+
+ mpu_reset <= reset;
+ mpu_halt <= to_std_logic(blt_halt);
+ mpu_irq <= rom_pia_irq_a or rom_pia_irq_b;
+ mpu_firq <= '0';
+ mpu_nmi <= '0';
+
+ address <= blt_address_out when mpu_halted else
+ mpu_address;
+ write <= blt_write when mpu_halted else
+ mpu_write;
+ read <= blt_read when mpu_halted else
+ mpu_read;
+
+ rom_access <= (address < X"9000" and read and e_rom = '1') or
+ (address >= X"D000" and read and sinistar='0') or
+ (address >= X"E000" and read and sinistar='1');
+ ram_access <= (address < X"9000" and write) or
+ (address < X"9000" and read and e_rom = '0') or
+ (address >= X"9000" and address < X"C000") or
+ hiram_access;
+ hiram_access <=
+ (address >= X"D000" and address < X"E000") and sinistar='1';
+
+ -- Color table: write: C000-C3FF
+ color_table_access <= std_match(address, "110000----------");
+
+ -- Widget PIA: read/write: C8X4 - C8X7
+ widget_pia_access <= std_match(address, "11001000----01--");
+
+ -- ROM PIA: read/write: C8XC - C8XF
+ rom_pia_access <= std_match(address, "11001000----11--");
+
+ -- Control address: write: C9XX
+ control_access <= std_match(address, "11001001--------");
+
+ -- Special chips: read/write? CAXX
+ blt_register_access <= std_match(address, "11001010--------");
+
+ -- Video counter: read: CBXX (even addresses)
+ video_counter_access <= std_match(address, "11001011-------0");
+
+ -- Watchdog register: write: CBFE or CBFF
+ watchdog_access <= std_match(address, "110010111111111-");
+
+ -- CMOS "nonvolatile" RAM: read/write: CC00 - CFFF
+ cmos_access <= std_match(address, "110011----------");
+
+ SLAM <= not SW(6);
+ H_S_RESET <= not SW(2);
+ ADVANCE <= not SW(1);
+ AUTO_UP <= not SW(0);
+
+ PLAYER_1_START <= not BTN(3);
+ PLAYER_2_START <= not BTN(2);
+ L_COIN <= not BTN(1);
+
+ MOVE_UP_1 <= JA(0);
+ MOVE_DOWN_1 <= JA(1);
+ MOVE_LEFT_1 <= JA(2);
+ MOVE_RIGHT_1 <= JA(3);
+ FIRE_UP_1 <= JA(4);
+ FIRE_DOWN_1 <= JA(5);
+ FIRE_LEFT_1 <= JA(6);
+ FIRE_RIGHT_1 <= JA(7);
+
+ MOVE_UP_2 <= JB(0);
+ MOVE_DOWN_2 <= JB(1);
+ MOVE_LEFT_2 <= JB(2);
+ MOVE_RIGHT_2 <= JB(3);
+ FIRE_UP_2 <= JB(4);
+ FIRE_DOWN_2 <= JB(5);
+ FIRE_LEFT_2 <= JB(6);
+ FIRE_RIGHT_2 <= JB(7);
+
+ video_counter_value <= std_logic_vector(video_address(13 downto 8)) & "00";
+
+ decoder_4_in <= screen_control & address(15 downto 8);
+ decoder_6_in <= screen_control & std_logic_vector(video_address(13 downto 6));
+
+ process(clock)
+ begin
+ if rising_edge(clock) then
+ ram_enable <= false;
+ ram_lower_enable <= false;
+ ram_upper_enable <= false;
+
+ flash_enable <= false;
+
+ memory_output_enable <= false;
+ memory_write <= false;
+ memory_data_out <= (others => '0');
+
+ blt_reg_cs <= '0';
+ blt_blt_ack <= '0';
+
+ rom_pia_cs <= '0';
+ rom_pia_write <= '0';
+
+ widget_pia_cs <= '0';
+ widget_pia_write <= '0';
+
+ if clock_12_phase( 0) = '1' then
+ memory_address <= "00" & video_prom_address &
+ std_logic_vector(video_address(5 downto 0));
+ end if;
+
+ if clock_12_phase( 4) = '1' then
+ memory_address <= "01" & video_prom_address &
+ std_logic_vector(video_address(5 downto 0));
+ end if;
+
+ if clock_12_phase( 8) = '1' then
+ memory_address <= "10" & video_prom_address &
+ std_logic_vector(video_address(5 downto 0));
+ end if;
+
+ if clock_12_phase(5) = '1' then
+ if std_match(video_address(5 downto 0), "11-1--") then
+ video_blank <= true;
+ elsif std_match(video_address(5 downto 0), "0---1-") then
+ video_blank <= false;
+ end if;
+ end if;
+
+ if clock_12_phase( 0) = '1' or
+ clock_12_phase( 4) = '1' or
+ clock_12_phase( 8) = '1' then
+ memory_output_enable <= true;
+ ram_enable <= true;
+ ram_lower_enable <= true;
+ ram_upper_enable <= true;
+
+ if video_blank then
+ vgaRed <= (others => '0');
+ vgaGreen <= (others => '0');
+ vgaBlue <= (others => '0');
+ else
+ vgaRed <= pixel_byte_h(2 downto 0);
+ vgaGreen <= pixel_byte_h(5 downto 3);
+ vgaBlue <= pixel_byte_h(7 downto 6);
+ end if;
+ end if;
+
+ if clock_12_phase( 1) = '1' or
+ clock_12_phase( 5) = '1' or
+ clock_12_phase( 9) = '1' then
+ pixel_nibbles <= memory_data_in;
+ end if;
+ if clock_12_phase( 2) = '1' or
+ clock_12_phase( 6) = '1' or
+ clock_12_phase(10) = '1' then
+
+ pixel_byte_l <= color_table(to_integer(unsigned(pixel_nibbles(3 downto 0))));
+ pixel_byte_h <= color_table(to_integer(unsigned(pixel_nibbles(7 downto 4))));
+
+ if video_blank then
+ vgaRed <= (others => '0');
+ vgaGreen <= (others => '0');
+ vgaBlue <= (others => '0');
+ else
+ vgaRed <= pixel_byte_l(2 downto 0);
+ vgaGreen <= pixel_byte_l(5 downto 3);
+ vgaBlue <= pixel_byte_l(7 downto 6);
+ end if;
+ end if;
+
+ -- BLT-only cycles
+ -- NOTE: the next cycle must be a read if coming from RAM, since the
+ -- RAM WE# needs to deassert for a time in order for another write to
+ -- take place.
+ if clock_12_phase(11) = '1' or clock_12_phase(1) = '1' then
+ if mpu_halted then
+ if ram_access and not hiram_access then
+ if pseudo_address(15 downto 14) = "11" then
+ memory_address <= address;
+ else
+ memory_address <= pseudo_address(15 downto 14) &
+ address(7 downto 0) &
+ pseudo_address(13 downto 8);
+ end if;
+ else
+ memory_address <= address;
+ end if;
+
+ if ram_access and write then
+ memory_data_out <= blt_data_out;
+ memory_write <= true;
+ else
+ memory_output_enable <= true;
+ end if;
+
+ if ram_access then
+ ram_enable <= true;
+ ram_lower_enable <= blt_en_lower;
+ ram_upper_enable <= blt_en_upper;
+ end if;
+
+ if rom_access then
+ flash_enable <= true;
+ end if;
+
+ blt_blt_ack <= '1';
+ end if;
+ end if;
+
+ -- MPU-only cycle
+ -- NOTE: the next cycle must be a read if coming from RAM, since the
+ -- RAM WE# needs to deassert for a time in order for another write to
+ -- take place.
+ if clock_12_phase(7) = '1' then
+ if not mpu_halted then
+ if ram_access and not hiram_access then
+ if pseudo_address(15 downto 14) = "11" then
+ memory_address <= address;
+ else
+ memory_address <= pseudo_address(15 downto 14) &
+ address(7 downto 0) &
+ pseudo_address(13 downto 8);
+ end if;
+ else
+ memory_address <= address;
+ end if;
+
+ if (ram_access or cmos_access or color_table_access) and write then
+ memory_data_out <= mpu_data_in;
+ memory_write <= true;
+ else
+ memory_output_enable <= true;
+ end if;
+
+ if ram_access or cmos_access or color_table_access then
+ ram_enable <= true;
+ ram_lower_enable <= true;
+ ram_upper_enable <= true;
+ end if;
+
+ if rom_access then
+ flash_enable <= true;
+ end if;
+
+ if blt_register_access and write then
+ blt_rs <= address(2 downto 0);
+ blt_reg_cs <= '1';
+ blt_reg_data_in <= mpu_data_in;
+
+ -- NOTE: To display BLT source address:
+ if address(2 downto 0) = "010" then
+ debug_blt_source_address(15 downto 8) <= mpu_data_in;
+ end if;
+
+ if address(2 downto 0) = "011" then
+ debug_blt_source_address(7 downto 0) <= mpu_data_in;
+ end if;
+ end if;
+
+ if rom_pia_access then
+ rom_pia_rs <= address(1 downto 0);
+ rom_pia_data_in <= mpu_data_in;
+ rom_pia_write <= to_std_logic(write);
+ rom_pia_cs <= '1';
+ end if;
+
+ if widget_pia_access then
+ widget_pia_rs <= address(1 downto 0);
+ widget_pia_data_in <= mpu_data_in;
+ widget_pia_write <= to_std_logic(write);
+ widget_pia_cs <= '1';
+ end if;
+
+ if control_access and write then
+ screen_control <= mpu_data_in(1);
+ e_rom <= mpu_data_in(0);
+ end if;
+
+ if color_table_access and write then
+ color_table(to_integer(unsigned(address(3 downto 0)))) <= mpu_data_in;
+ end if;
+ end if;
+ end if;
+
+ if clock_12_phase(8) = '1' then
+ if not mpu_halted then
+ if read then
+ if ram_access or rom_access or cmos_access then
+ mpu_data_out <= memory_data_in;
+ end if;
+
+ if widget_pia_access then
+ mpu_data_out <= widget_pia_data_out;
+ end if;
+
+ if rom_pia_access then
+ mpu_data_out <= rom_pia_data_out;
+ end if;
+
+ if video_counter_access then
+ mpu_data_out <= video_counter_value;
+ end if;
+ end if;
+ end if;
+ end if;
+ end if;
+ end process;
+
+ LED <= mpu_irq &
+ mpu_halt &
+ to_std_logic(mpu_halted) &
+ to_std_logic(ram_access) &
+ to_std_logic(rom_access) &
+ to_std_logic(rom_pia_access) &
+ to_std_logic(widget_pia_access) &
+ to_std_logic(blt_register_access);
+
+ led_bcd_in <= debug_blt_source_address;
+
+ -------------------------------------------------------------------
+
+ horizontal_decoder: entity work.decoder_4
+ port map(
+ clk => not clock,
+ addr => decoder_4_in,
+ data => pseudo_address
+ );
+
+ -------------------------------------------------------------------
+
+ vertical_decoder: entity work.decoder_6
+ port map(
+ clk => not clock,
+ addr => decoder_6_in,
+ data => video_prom_address
+ );
+
+ -------------------------------------------------------------------
+
+ blt_halt_ack <= mpu_halted;
+ blt_data_in <= memory_data_in;
+
+ blt: entity work.sc1
+ port map(
+ clk => clock,
+ sc2 => blitter_sc2,
+
+ reg_cs => blt_reg_cs,
+ reg_data_in => blt_reg_data_in,
+ rs => blt_rs,
+
+ halt => blt_halt,
+ halt_ack => blt_halt_ack,
+
+ blt_ack => blt_blt_ack,
+ blt_address_out => blt_address_out,
+
+ blt_rd => blt_read,
+ blt_wr => blt_write,
+
+ blt_data_in => blt_data_in,
+ blt_data_out => blt_data_out,
+
+ en_upper => blt_en_upper,
+ en_lower => blt_en_lower
+ );
+
+ -------------------------------------------------------------------
+
+ rom_pia_pa_in <= not HAND &
+ not SLAM &
+ not C_COIN &
+ not L_COIN &
+ not H_S_RESET &
+ not R_COIN &
+ not ADVANCE &
+ not AUTO_UP;
+ PB(5 downto 0) <= rom_pia_pb_out(5 downto 0);
+
+ rom_led_digit(0) <= rom_pia_pb_out(6);
+ rom_led_digit(1) <= rom_pia_pb_out(7);
+ rom_led_digit(2) <= rom_pia_cb2_out;
+ rom_led_digit(3) <= rom_pia_ca2_out;
+ rom_pia_pb_in <= (others => '1');
+
+ rom_pia: entity work.pia6821
+ port map(
+ rst => reset,
+ clk => clock,
+
+ addr => address(1 downto 0),
+ cs => rom_pia_cs,
+ rw => not rom_pia_write,
+
+ data_in => mpu_data_in,
+ data_out => rom_pia_data_out,
+
+ ca1 => count_240,
+ ca2_i => '1',
+ ca2_o => rom_pia_ca2_out,
+ ca2_oe => rom_pia_ca2_dir,
+ irqa => rom_pia_irq_a,
+ pa_i => rom_pia_pa_in,
+ pa_o => rom_pia_pa_out,
+ pa_oe => rom_pia_pa_dir,
+
+ cb1 => irq_4ms,
+ cb2_i => '1',
+ cb2_o => rom_pia_cb2_out,
+ cb2_oe => rom_pia_cb2_dir,
+ irqb => rom_pia_irq_b,
+ pb_i => rom_pia_pb_in,
+ pb_o => rom_pia_pb_out,
+ pb_oe => rom_pia_pb_dir
+ );
+ -------------------------------------------------------------------
+
+ widget_pia_input_select <= widget_pia_cb2_out;
+
+ widget_ic3_a <= not (MOVE_RIGHT_2 & MOVE_LEFT_2 & MOVE_DOWN_2 & MOVE_UP_2);
+ widget_ic3_b <= not (MOVE_RIGHT_1 & MOVE_LEFT_1 & MOVE_DOWN_1 & MOVE_UP_1);
+
+ widget_ic3_y <= widget_ic3_b when widget_pia_input_select = '1' else widget_ic3_a;
+
+ widget_ic4_a <= not (FIRE_RIGHT_2 & FIRE_LEFT_2 & FIRE_DOWN_2 & FIRE_UP_2);
+ widget_ic4_b <= not (FIRE_RIGHT_1 & FIRE_LEFT_1 & FIRE_DOWN_1 & FIRE_UP_1);
+
+ widget_ic4_y <= widget_ic4_b when widget_pia_input_select = '1' else widget_ic4_a;
+
+ widget_pia_pa_in <= widget_ic4_y(2) &
+ widget_ic4_y(1) &
+ not PLAYER_2_START &
+ not PLAYER_1_START &
+ widget_ic3_y(4) &
+ widget_ic3_y(3) &
+ widget_ic3_y(2) &
+ widget_ic3_y(1) when sinistar = '0' else
+ widget_ic4_y(4) &
+ widget_ic4_y(3) &
+ widget_ic4_y(2) &
+ widget_ic4_y(1) &
+ widget_ic3_y(4) &
+ widget_ic3_y(3) &
+ widget_ic3_y(2) &
+ widget_ic3_y(1);
+ widget_pia_pb_in <= not board_interface_w1 &
+ "00000" &
+ widget_ic4_y(4) &
+ widget_ic4_y(3) when sinistar = '0' else
+ not board_interface_w1 &
+ "0" &
+ not PLAYER_2_START &
+ not PLAYER_1_START &
+ "00" &
+ not SIN_BOMB &
+ not SIN_FIRE;
+
+ widget_pia: work.pia6821
+ port map(
+ rst => reset,
+ clk => clock,
+
+ addr => address(1 downto 0),
+ cs => widget_pia_cs,
+ rw => not widget_pia_write,
+
+ data_in => mpu_data_in,
+ data_out => widget_pia_data_out,
+
+ ca1 => '0',
+ ca2_i => '0',
+ ca2_o => widget_pia_ca2_out,
+ ca2_oe => widget_pia_ca2_dir,
+ irqa => widget_pia_irq_a,
+ pa_i => widget_pia_pa_in,
+ pa_o => widget_pia_pa_out,
+ pa_oe => widget_pia_pa_dir,
+
+ cb1 => '0',
+ cb2_i => '1',
+ cb2_o => widget_pia_cb2_out,
+ cb2_oe => widget_pia_cb2_dir,
+ irqb => widget_pia_irq_b,
+ pb_i => widget_pia_pb_in,
+ pb_o => widget_pia_pb_out,
+ pb_oe => widget_pia_pb_dir
+ );
+
+ -------------------------------------------------------------------
+
+ E <= clock_e;
+ Q <= clock_q;
+
+ Din <= mpu_data_out;
+
+ TSC <= '0';
+
+ process(clock, clock_q_set)
+ begin
+ if rising_edge(clock) and clock_q_set then
+ -- RESET, HALT, interrupts are captured by microprocessor
+ -- on Q falling edge. Present once per processor clock,
+ -- on Q rising edge -- just because.
+ RESET_N <= not mpu_reset;
+ HALT_N <= not mpu_halt;
+ IRQ_N <= not mpu_irq;
+ FIRQ_N <= not mpu_firq;
+ NMI_N <= not mpu_nmi;
+ end if;
+ end process;
+--
+ process(clock, clock_q_set)
+ begin
+ if rising_edge(clock) and clock_q_set then
+ mpu_address <= A;
+ mpu_bus_status <= BS;
+ mpu_bus_available <= BA;
+ mpu_halted <= BS = '1' and BA = '1';
+ mpu_write <= R_W_N = '0' and BA = '0';
+ mpu_read <= R_W_N = '1' and BA = '0';
+
+ if BA = '0' then
+ debug_last_mpu_address <= A;
+ end if;
+ end if;
+ end process;
+
+ process(clock, clock_e_set)
+ begin
+ if rising_edge(clock) and clock_e_set then
+ mpu_data_in <= Dout;
+ end if;
+ end process;
+
+ -------------------------------------------------------------------
+
+ MemOE <= '0' when memory_output_enable else '1';
+ MemWR <= '0' when memory_write else '1';
+
+ RamAdv <= '0';
+ RamCS <= '0' when ram_enable else '1';
+ RamClk <= '0';
+ RamCRE <= '0';
+ RamLB <= '0' when ram_lower_enable else '1';
+ RamUB <= '0' when ram_upper_enable else '1';
+
+ FlashRp <= '1';
+ FlashCS <= '0' when flash_enable else '1';
+
+ MemAdr <= "0000000" & memory_address;
+
+ MemDin <= memory_data_out(7 downto 4) &
+ memory_data_out(7 downto 4) &
+ memory_data_out(3 downto 0) &
+ memory_data_out(3 downto 0);
+ memory_data_in <= MemDout(11 downto 8) & MemDout(3 downto 0);
+
+ -------------------------------------------------------------------
+ -- Video output
+
+ Hsync <= not horizontal_sync;
+ Vsync <= not vertical_sync;
+
+ -------------------------------------------------------------------
+
+ DP <= led_dp;
+ SEG <= led_segment;
+ AN <= led_anode;
+
+ -------------------------------------------------------------------
+ -- 1MHz, 12-phase counter.
+
+ process(clock)
+ begin
+ if rising_edge(clock) then
+ clock_12_phase <= clock_12_phase rol 1;
+ end if;
+ end process;
+
+ -------------------------------------------------------------------
+ -- Q clock
+
+ clock_q_set <= clock_12_phase(2) = '1';
+ clock_q_clear <= clock_12_phase(8) = '1';
+
+ process(clock)
+ begin
+ if rising_edge(clock) then
+ if clock_q_set then
+ clock_q <= '1';
+ elsif clock_q_clear then
+ clock_q <= '0';
+ end if;
+ end if;
+ end process;
+
+ -------------------------------------------------------------------
+ -- E clock
+
+ clock_e_set <= clock_12_phase(5) = '1';
+ clock_e_clear <= clock_12_phase(11) = '1';
+
+ process(clock)
+ begin
+ if rising_edge(clock) then
+ if clock_e_set then
+ clock_e <= '1';
+ elsif clock_e_clear then
+ clock_e <= '0';
+ end if;
+ end if;
+ end process;
+
+ -------------------------------------------------------------------
+ -- Reset generator
+
+ process(clock)
+ begin
+ if rising_edge(clock) then
+ if reset_request = '1' then
+ reset_counter <= (others => '0');
+ reset <= '1';
+ else
+ if reset_counter < 100 then
+ reset_counter <= reset_counter + 1;
+ else
+ reset <= '0';
+ end if;
+ end if;
+ end if;
+ end process;
+
+ -------------------------------------------------------------------
+ -- Video counter
+
+ video_count_next <= video_count + 1 when (video_count /= 16639)
+ else (others => '0');
+ video_address_or_mask <= "11111100000000" when video_count_next(14) = '1' else (others => '0');
+-- irq_4ms <= video_count(11);
+ irq_4ms <= video_address(11);
+
+ process(clock, clock_e_clear)
+ begin
+ -- Advance video count at end of video memory phase.
+ if rising_edge(clock) and clock_e_clear then
+ --watchdog_increment <= '0';
+ video_count <= video_count_next;
+ video_address <= video_count_next(13 downto 0) or video_address_or_mask;
+ --video_address <= video_address + 1;
+ --if video_count(14 downto 0) = "011111111111111" then
+ -- watchdog_increment <= '1';
+ --end if;
+ end if;
+ end process;
+
+ -------------------------------------------------------------------
+ -- Video generator
+
+ count_240 <= '1' when video_address(13 downto 10) = "1111" else '0';
+
+ horizontal_sync <= '1' when video_address(5 downto 2) = "1110" else '0';
+ vertical_sync <= '1' when video_address(13 downto 9) = "11111" else '0';
+
+ -------------------------------------------------------------------
+ -- LED numeric display
+
+ process(clock)
+ begin
+ if rising_edge(clock) then
+ led_counter <= led_counter + 1;
+ end if;
+ end process;
+
+ led_digit_index <= led_counter(15 downto 14);
+
+ with led_digit_index select
+ led_anode <= "1110" when "00",
+ "1101" when "01",
+ "1011" when "10",
+ "0111" when "11",
+ "1111" when others;
+
+ with led_digit_index select
+ led_bcd_in_digit <= led_bcd_in( 3 downto 0) when "00",
+ led_bcd_in( 7 downto 4) when "01",
+ led_bcd_in(11 downto 8) when "10",
+ led_bcd_in(15 downto 12) when "11",
+ "XXXX" when others;
+
+-- bcd_demux: led_decoder
+-- port map(
+-- input => led_bcd_in_digit,
+-- output => led_segment
+-- );
+
+ led_dp <= '1';
+
+end Behavioral;
diff --git a/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/robotron_cpu/robotron_cpu_test.vhd b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/robotron_cpu/robotron_cpu_test.vhd
new file mode 100755
index 00000000..cd1cabaf
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/robotron_cpu/robotron_cpu_test.vhd
@@ -0,0 +1,363 @@
+-----------------------------------------------------------------------
+--
+-- Copyright 2012 ShareBrained Technology, Inc.
+--
+-- This file is part of robotron-fpga.
+--
+-- robotron-fpga 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.
+--
+-- robotron-fpga 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 robotron-fpga. If not, see
+-- .
+--
+-----------------------------------------------------------------------
+
+library ieee;
+ use ieee.std_logic_1164.all;
+ use ieee.numeric_std.all;
+
+entity robotron_cpu_test is
+end robotron_cpu_test;
+
+architecture behavior of robotron_cpu_test is
+
+ component robotron_cpu
+ port(
+ CLK : in std_logic;
+
+ -- MC6809E interface
+ A : in std_logic_vector(15 downto 0);
+ D : inout std_logic_vector(7 downto 0);
+ RESET_N : out std_logic;
+ NMI_N : out std_logic;
+ FIRQ_N : out std_logic;
+ IRQ_N : out std_logic;
+ LIC : in std_logic;
+ AVMA : in std_logic;
+ R_W_N : in std_logic;
+ TSC : out std_logic;
+ HALT_N : out std_logic;
+ BA : in std_logic;
+ BS : in std_logic;
+ BUSY : in std_logic;
+ E : out std_logic;
+ Q : out std_logic;
+
+ -- RAM and flash memories
+ MemOE : out std_logic;
+ MemWR : out std_logic;
+
+ RamAdv : out std_logic;
+ RamCS : out std_logic;
+ RamClk : out std_logic;
+ RamCRE : out std_logic;
+ RamLB : out std_logic;
+ RamUB : out std_logic;
+ RamWait : in std_logic;
+
+ FlashRp : out std_logic;
+ FlashCS : out std_logic;
+ FlashStSts : in std_logic;
+
+ MemAdr : out std_logic_vector(23 downto 1);
+ MemDB : inout std_logic_vector(15 downto 0);
+
+ -- 7-segment display
+ SEG : out std_logic_vector(6 downto 0);
+ DP : out std_logic;
+ AN : out std_logic_vector(3 downto 0);
+
+ -- LEDs
+ LED : out std_logic_vector(7 downto 0);
+
+ -- Switches
+ SW : in std_logic_vector(7 downto 0);
+
+ -- Buttons
+ BTN : in std_logic_vector(3 downto 0);
+
+ -- VGA
+ vgaRed : out std_logic_vector(2 downto 0);
+ vgaGreen : out std_logic_vector(2 downto 0);
+ vgaBlue : out std_logic_vector(1 downto 0);
+ Hsync : out std_logic;
+ Vsync : out std_logic
+ );
+ end component;
+
+ constant CLK_frequency : real := 48.0e6;
+ constant CLK_period : time := 1 sec / CLK_frequency;
+
+ signal CLK : std_logic := '0';
+
+ signal A : std_logic_vector(15 downto 0) := (others => '0');
+ signal D : std_logic_vector(7 downto 0);
+ signal RESET_N : std_logic := '1';
+ signal NMI_N : std_logic := '1';
+ signal FIRQ_N : std_logic := '1';
+ signal IRQ_N : std_logic := '1';
+ signal LIC : std_logic := '0';
+ signal AVMA : std_logic := '0';
+ signal R_W_N : std_logic := '0';
+ signal TSC : std_logic := '0';
+ signal HALT_N : std_logic := '1';
+ signal BA : std_logic := '0';
+ signal BS : std_logic := '0';
+ signal BUSY : std_logic := '0';
+ signal E : std_logic := '0';
+ signal Q : std_logic := '0';
+
+ signal MemOE : std_logic;
+ signal MemWR : std_logic;
+
+ signal RamAdv : std_logic;
+ signal RamCS : std_logic;
+ signal RamClk : std_logic;
+ signal RamCRE : std_logic;
+ signal RamLB : std_logic;
+ signal RamUB : std_logic;
+ signal RamWait : std_logic;
+
+ signal FlashRp : std_logic;
+ signal FlashCS : std_logic;
+ signal FlashStSts : std_logic;
+
+ signal MemAdr : std_logic_vector(23 downto 1);
+ signal MemDB : std_logic_vector(15 downto 0);
+
+ signal SEG : std_logic_vector(6 downto 0);
+ signal DP : std_logic;
+ signal AN : std_logic_vector(3 downto 0);
+
+ signal LED : std_logic_vector(7 downto 0);
+
+ signal SW : std_logic_vector(7 downto 0) := (others => '0');
+
+ signal BTN : std_logic_vector(3 downto 0) := (others => '0');
+
+ signal vgaRed : std_logic_vector(2 downto 0);
+ signal vgaGreen : std_logic_vector(2 downto 0);
+ signal vgaBlue : std_logic_vector(1 downto 0);
+ signal Hsync : std_logic;
+ signal Vsync : std_logic;
+
+ -------------------------------------------------------------------
+
+ signal bus_address : std_logic_vector(15 downto 0) := (others => '1');
+ signal bus_read : std_logic := '1';
+ signal bus_data : std_logic_vector(7 downto 0) := (others => 'Z');
+ signal bus_available: std_logic := 'Z';
+ signal bus_status : std_logic := 'Z';
+
+begin
+
+ uut: robotron_cpu PORT MAP (
+ CLK => CLK,
+ A => A,
+ D => D,
+ RESET_N => RESET_N,
+ NMI_N => NMI_N,
+ FIRQ_N => FIRQ_N,
+ IRQ_N => IRQ_N,
+ LIC => LIC,
+ AVMA => AVMA,
+ R_W_N => R_W_N,
+ TSC => TSC,
+ HALT_N => HALT_N,
+ BA => BA,
+ BS => BS,
+ BUSY => BUSY,
+ E => E,
+ Q => Q,
+ MemOE => MemOE,
+ MemWR => MemWR,
+ RamAdv => RamAdv,
+ RamCS => RamCS,
+ RamClk => RamClk,
+ RamCRE => RamCRE,
+ RamLB => RamLB,
+ RamUB => RamUB,
+ RamWait => RamWait,
+ FlashRp => FlashRp,
+ FlashCS => FlashCS,
+ FlashStSts => FlashStSts,
+ MemAdr => MemAdr,
+ MemDB => MemDB,
+ SEG => SEG,
+ DP => DP,
+ AN => AN,
+ LED => LED,
+ SW => SW,
+ BTN => BTN,
+ vgaRed => vgaRed,
+ vgaGreen => vgaGreen,
+ vgaBlue => vgaBlue,
+ Hsync => Hsync,
+ Vsync => Vsync
+ );
+
+ CLK_process :process
+ begin
+ CLK <= '0';
+ wait for CLK_period/2;
+ CLK <= '1';
+ wait for CLK_period/2;
+ end process;
+
+ bus_process: process
+ begin
+ wait until falling_edge(E);
+
+ -- E=0 + 0 ns
+ wait for 20 ns;
+ R_W_N <= 'U';
+ A <= (others => 'U');
+ BA <= 'U';
+ BS <= 'U';
+
+ -- E=0 + 20 ns
+ wait for 10 ns;
+ D <= (others => 'Z');
+
+ -- E=0 + 30 ns
+ wait for 170 ns;
+
+ if bus_available = '0' then
+ R_W_N <= bus_read;
+ A <= bus_address;
+ else
+ R_W_N <= 'Z';
+ A <= (others => 'Z');
+ end if;
+
+ BA <= bus_available;
+ BS <= bus_status;
+
+ -- E=0 + 200 ns
+ wait until rising_edge(Q);
+
+ -- Q=1
+ wait for 200 ns;
+
+ -- Q=1 + 200 ns
+ if bus_available = '0' then
+ if bus_read = '0' then
+ D <= bus_data;
+ end if;
+ end if;
+ end process;
+
+ stim_proc: process
+ begin
+ BTN(0) <= '1';
+ wait for 100 ns;
+ BTN(0) <= '0';
+
+ wait until rising_edge(RESET_N);
+
+ wait until falling_edge(E);
+ bus_available <= '0';
+ bus_status <= '0';
+
+ bus_address <= X"FFFE";
+ bus_read <= '1';
+ bus_data <= (others => 'Z');
+
+ wait until falling_edge(E);
+ bus_address <= X"9000";
+ bus_read <= '1';
+ bus_data <= (others => 'Z');
+
+ wait until falling_edge(E);
+ bus_address <= X"0000";
+ bus_read <= '0';
+ bus_data <= X"69";
+
+ -- Turn on ROM PIA CA2
+ wait until falling_edge(E);
+ bus_address <= X"C80D";
+ bus_read <= '0';
+ bus_data <= X"3C";
+
+ -- IDLE
+ wait until falling_edge(E);
+ bus_address <= (others => 'Z');
+ bus_read <= '1';
+ bus_data <= (others => 'Z');
+
+ -- Turn off ROM PIA CA2
+ wait until falling_edge(E);
+ bus_address <= X"C80D";
+ bus_read <= '0';
+ bus_data <= X"34";
+
+ -- Write BLT
+ wait until falling_edge(E);
+ bus_address <= X"CA02";
+ bus_read <= '0';
+ bus_data <= X"D0";
+
+ wait until falling_edge(E);
+ bus_address <= X"CA03";
+ bus_read <= '0';
+ bus_data <= X"00";
+
+ wait until falling_edge(E);
+ bus_address <= X"CA04";
+ bus_read <= '0';
+ bus_data <= X"33";
+
+ wait until falling_edge(E);
+ bus_address <= X"CA05";
+ bus_read <= '0';
+ bus_data <= X"44";
+
+ wait until falling_edge(E);
+ bus_address <= X"CA06";
+ bus_read <= '0';
+ bus_data <= X"00";
+
+ wait until falling_edge(E);
+ bus_address <= X"CA07";
+ bus_read <= '0';
+ bus_data <= X"00";
+
+ wait until falling_edge(E);
+ bus_address <= X"CA00";
+ bus_read <= '0';
+ bus_data <= X"01";
+
+ -- IDLE
+ wait until falling_edge(E);
+ bus_address <= (others => 'Z');
+ bus_read <= '1';
+ bus_data <= (others => 'Z');
+
+ -- HALT should assert from BLT.
+ wait until falling_edge(E);
+ wait until falling_edge(E);
+
+ wait until falling_edge(E);
+ -- Release bus to BLT.
+ bus_status <= '1';
+ bus_available <= '1';
+
+ -- HALT should deassert from BLT.
+ wait until falling_edge(E);
+ wait until falling_edge(E);
+ wait until falling_edge(E);
+
+ wait;
+ end process;
+
+end;
diff --git a/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/robotron_cpu/sc1.vhd b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/robotron_cpu/sc1.vhd
new file mode 100644
index 00000000..e3269afb
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/robotron_cpu/sc1.vhd
@@ -0,0 +1,240 @@
+-----------------------------------------------------------------------
+--
+-- Copyright 2012 ShareBrained Technology, Inc.
+--
+-- This file is part of robotron-fpga.
+--
+-- robotron-fpga 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.
+--
+-- robotron-fpga 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 robotron-fpga. If not, see
+-- .
+--
+-----------------------------------------------------------------------
+
+-- This entity models a pair of Williams SC1 pixel BLTter ICs.
+-- The interface is modified to be more conducive to synchronous
+-- FPGA implementation.
+-- Dec 2018 changes for SC1 or SC2 and 0 address error (DW oldgit)
+
+library ieee;
+ use ieee.std_logic_1164.all;
+ use ieee.std_logic_unsigned.all;
+
+entity sc1 is
+port(
+ clk : in std_logic;
+ sc2 : in std_logic;
+
+ reg_cs : in std_logic;
+ reg_data_in : in std_logic_vector( 7 downto 0);
+ rs : in std_logic_vector( 2 downto 0);
+
+ halt : out boolean;
+ halt_ack : in boolean;
+
+ blt_ack : in std_logic;
+
+ blt_rd : out boolean;
+ blt_wr : out boolean;
+
+ blt_address_out : out std_logic_vector(15 downto 0);
+ blt_data_in : in std_logic_vector( 7 downto 0);
+ blt_data_out : out std_logic_vector( 7 downto 0);
+
+ en_upper : out boolean;
+ en_lower : out boolean
+);
+end sc1;
+
+architecture RTL of sc1 is
+
+ type state_t is (state_idle, state_wait_for_halt, state_src, state_dst);
+
+ -- control attributes
+ signal ctrl_span_src : std_logic := '0';
+ signal ctrl_span_dst : std_logic := '0';
+ signal ctrl_slow : std_logic := '0';
+ signal ctrl_foreground : std_logic := '0';
+ signal ctrl_solid : std_logic := '0';
+ signal ctrl_shift : std_logic := '0';
+ signal ctrl_no_lower : std_logic := '0';
+ signal ctrl_no_upper : std_logic := '0';
+
+ -- 0: Run register
+ signal reg_ctrl : std_logic_vector( 7 downto 0) := (others => '0');
+ -- 1: solid value
+ signal reg_solid : std_logic_vector( 7 downto 0) := (others => '0');
+ -- 2, 3: source address
+ signal reg_src_base : std_logic_vector(15 downto 0) := (others => '0');
+ -- 4, 5: destination address
+ signal reg_dst_base : std_logic_vector(15 downto 0) := (others => '0');
+ -- 6: width
+ signal reg_width : std_logic_vector( 7 downto 0) := (others => '0');
+ -- 7: height
+ signal reg_height : std_logic_vector( 7 downto 0) := (others => '0');
+
+ -- Internal
+ signal state : state_t := state_idle;
+
+ signal blt_src_data : std_logic_vector( 7 downto 0) := (others => '0');
+ signal blt_shift : std_logic_vector( 3 downto 0) := (others => '0');
+
+ signal src_address : std_logic_vector(15 downto 0) := (others => '0');
+ signal dst_address : std_logic_vector(15 downto 0) := (others => '0');
+
+ signal x_count : std_logic_vector( 7 downto 0) := (others => '0');
+ signal x_count_next : std_logic_vector( 7 downto 0) := (others => '0');
+ signal y_count : std_logic_vector( 7 downto 0) := (others => '0');
+ signal y_count_next : std_logic_vector( 7 downto 0) := (others => '0');
+
+ signal xorval : std_logic_vector( 7 downto 0) := (others => '0');
+
+begin
+ -- SC1 had a bug so values had to be xored with 0X04, SC2 fixed the bug so no xor required
+ xorval <= x"04" when sc2='0' else x"00";
+
+ halt <= not (state = state_idle);
+ blt_rd <= (state = state_src);
+ blt_wr <= (state = state_dst);
+
+ blt_address_out <= dst_address when (state = state_dst) else src_address;
+
+ en_upper <= (state = state_src) or (not (ctrl_no_upper = '1' or (ctrl_foreground = '1' and blt_src_data(7 downto 4) = x"0") ));
+ en_lower <= (state = state_src) or (not (ctrl_no_lower = '1' or (ctrl_foreground = '1' and blt_src_data(3 downto 0) = x"0") ));
+
+ blt_data_out <= reg_solid when ctrl_solid = '1' else blt_src_data;
+
+ x_count_next <= x_count + 1;
+ y_count_next <= y_count + 1;
+
+ -- break out control reg into individual signals
+ ctrl_no_upper <= reg_ctrl(7);
+ ctrl_no_lower <= reg_ctrl(6);
+ ctrl_shift <= reg_ctrl(5);
+ ctrl_solid <= reg_ctrl(4);
+ ctrl_foreground <= reg_ctrl(3);
+ --ctrl_slow <= reg_ctrl(2);
+ ctrl_span_dst <= reg_ctrl(1);
+ ctrl_span_src <= reg_ctrl(0);
+
+ -- register access
+ process(clk)
+ begin
+ if rising_edge(clk) then
+ if reg_cs = '1' then
+ case rs is
+ -- 0: Start BLT with control attributes
+ when "000" => reg_ctrl <= reg_data_in;
+ -- 1: mask
+ when "001" => reg_solid <= reg_data_in;
+ -- 2: source address high
+ when "010" => reg_src_base(15 downto 8) <= reg_data_in;
+ -- 3: source address low
+ when "011" => reg_src_base( 7 downto 0) <= reg_data_in;
+ -- 4: destination address high
+ when "100" => reg_dst_base(15 downto 8) <= reg_data_in;
+ -- 5: destination address low
+ when "101" => reg_dst_base( 7 downto 0) <= reg_data_in;
+ -- 6: width
+ when "110" => reg_width <= reg_data_in xor xorval;
+ -- 7: height
+ when "111" => reg_height <= reg_data_in xor xorval;
+ -- Do nothing.
+ when others => null;
+ end case;
+ end if;
+ end if;
+ end process;
+
+ -- state machine
+ process(clk)
+ begin
+ if rising_edge(clk) then
+ case state is
+ when state_idle =>
+ if reg_cs = '1' and rs = "000" then
+ state <= state_wait_for_halt;
+ end if;
+
+ when state_wait_for_halt =>
+ if halt_ack then
+ src_address <= reg_src_base;
+ dst_address <= reg_dst_base;
+
+ x_count <= (others => '0');
+ y_count <= (others => '0');
+ blt_shift <= (others => '0');
+
+ state <= state_src;
+ end if;
+
+ when state_src =>
+ if blt_ack = '1' then
+ if ctrl_shift = '0' then
+ -- unshifted
+ blt_src_data <= blt_data_in;
+ else
+ -- shifted right one pixel
+ blt_shift <= blt_data_in( 3 downto 0);
+ blt_src_data <= blt_shift & blt_data_in( 7 downto 4);
+ end if;
+ state <= state_dst;
+ end if;
+
+ when state_dst =>
+ if blt_ack = '1' then
+ state <= state_src;
+
+ if x_count_next < reg_width then
+ x_count <= x_count_next;
+
+ if ctrl_span_src = '1' then
+ src_address <= src_address + 256;
+ else
+ src_address <= src_address + 1;
+ end if;
+
+ if ctrl_span_dst = '1' then
+ dst_address <= dst_address + 256;
+ else
+ dst_address <= dst_address + 1;
+ end if;
+ else
+ x_count <= (others => '0');
+ y_count <= y_count_next;
+
+ if y_count_next = reg_height then
+ state <= state_idle;
+ end if;
+
+ if ctrl_span_src = '1' then
+ src_address <= reg_src_base + y_count_next;
+ else
+ src_address <= src_address + 1;
+ end if;
+
+ if ctrl_span_dst = '1' then
+ dst_address <= reg_dst_base + y_count_next;
+ else
+ dst_address <= dst_address + 1;
+ end if;
+
+ end if;
+ end if;
+ -- Do nothing.
+ when others => null;
+ end case;
+ end if;
+ end process;
+end RTL;
diff --git a/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/robotron_cpu/sc1_tb.vhd b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/robotron_cpu/sc1_tb.vhd
new file mode 100755
index 00000000..6433d45b
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/robotron_cpu/sc1_tb.vhd
@@ -0,0 +1,160 @@
+-----------------------------------------------------------------------
+--
+-- Copyright 2012 ShareBrained Technology, Inc.
+--
+-- This file is part of robotron-fpga.
+--
+-- robotron-fpga 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.
+--
+-- robotron-fpga 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 robotron-fpga. If not, see
+-- .
+--
+-----------------------------------------------------------------------
+
+library ieee;
+ use ieee.std_logic_1164.all;
+
+entity sc1_tb is
+end sc1_tb;
+
+architecture behavior of sc1_tb is
+
+ component sc1
+ port(
+ clk : in std_logic;
+ reset : in std_logic;
+ e_sync : in std_logic;
+ reg_cs : in std_logic;
+ reg_data_in : in std_logic_vector(7 downto 0);
+ rs : in std_logic_vector(2 downto 0);
+ halt : out boolean;
+ halt_ack : in boolean;
+ blt_ack : in std_logic;
+ blt_address_out : out std_logic_vector(15 downto 0);
+ read : out boolean;
+ write : out boolean;
+ blt_data_in : in std_logic_vector(7 downto 0);
+ blt_data_out : out std_logic_vector(7 downto 0);
+ en_upper : out boolean;
+ en_lower : out boolean
+ );
+ end component;
+
+ signal clk : std_logic := '0';
+ signal reset : std_logic := '0';
+ signal e_sync : std_logic := '0';
+ signal reg_cs : std_logic := '0';
+ signal reg_data_in : std_logic_vector(7 downto 0) := (others => '0');
+ signal rs : std_logic_vector(2 downto 0) := (others => '0');
+ signal halt : boolean := false;
+ signal halt_ack : boolean := false;
+ signal blt_ack : std_logic := '0';
+ signal blt_address_out : std_logic_vector(15 downto 0);
+ signal read : boolean := false;
+ signal write : boolean := false;
+ signal blt_data_in : std_logic_vector(7 downto 0) := (others => '0');
+ signal blt_data_out : std_logic_vector(7 downto 0);
+ signal en_upper : boolean;
+ signal en_lower : boolean;
+
+ constant clk_period : time := 83.333333 ns;
+
+begin
+
+ uut: sc1
+ port map(
+ clk => clk,
+ reset => reset,
+ e_sync => e_sync,
+ reg_cs => reg_cs,
+ reg_data_in => reg_data_in,
+ rs => rs,
+ halt => halt,
+ halt_ack => halt_ack,
+ blt_ack => blt_ack,
+ blt_address_out => blt_address_out,
+ read => read,
+ write => write,
+ blt_data_in => blt_data_in,
+ blt_data_out => blt_data_out,
+ en_upper => en_upper,
+ en_lower => en_lower
+ );
+
+ clk_process: process
+ begin
+ clk <= '0';
+ wait for clk_period/2;
+
+ clk <= '1';
+ wait for clk_period/2;
+ end process;
+
+ stim_proc: process
+ begin
+ e_sync <= '1';
+
+ wait until rising_edge(clk);
+ rs <= "010";
+ reg_data_in <= X"11";
+ reg_cs <= '1';
+
+ wait until rising_edge(clk);
+ rs <= "011";
+ reg_data_in <= X"22";
+ reg_cs <= '1';
+
+ wait until rising_edge(clk);
+ rs <= "100";
+ reg_data_in <= X"33";
+ reg_cs <= '1';
+
+ wait until rising_edge(clk);
+ rs <= "101";
+ reg_data_in <= X"44";
+ reg_cs <= '1';
+
+ wait until rising_edge(clk);
+ rs <= "110";
+ reg_data_in <= X"00";
+ reg_cs <= '1';
+
+ wait until rising_edge(clk);
+ rs <= "111";
+ reg_data_in <= X"00";
+ reg_cs <= '1';
+
+ wait until rising_edge(clk);
+ rs <= "000";
+ reg_data_in <= "00000001";
+ reg_cs <= '1';
+
+ wait until rising_edge(clk);
+ reg_cs <= '0';
+
+ wait until halt = true;
+ halt_ack <= true;
+
+ wait until rising_edge(clk);
+ blt_ack <= '1';
+ blt_data_in <= X"69";
+
+ wait until halt = false;
+ blt_ack <= '0';
+ halt_ack <= false;
+
+ wait;
+ end process;
+
+end;
diff --git a/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/robotron_soc.vhd b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/robotron_soc.vhd
new file mode 100644
index 00000000..99769a4f
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/robotron_soc.vhd
@@ -0,0 +1,262 @@
+-----------------------------------------------------------------------
+--
+-- A SOC-like top-level for robotron-fpga
+-- (C) 2020 Slingshot
+--
+-- MC6809 Cycle-Accurate 6809 Core
+-- (c) 2016, Greg Miller
+--
+-- Defender sound board by Dar (darfpga@aol.fr)
+--
+-- robotron-fpga 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.
+--
+-- robotron-fpga 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 robotron-fpga. If not, see
+-- .
+--
+-----------------------------------------------------------------------
+
+library ieee;
+ use ieee.std_logic_1164.all;
+ use ieee.numeric_std.all;
+
+entity robotron_soc is
+port (
+ clock : in std_logic; -- 12MHz
+ clock_snd : in std_logic; -- 0.89MHz
+
+ -- Cellular RAM / StrataFlash
+ MemOE : out std_logic;
+ MemWR : out std_logic;
+
+ RamAdv : out std_logic;
+ RamCS : out std_logic;
+ RamClk : out std_logic;
+ RamCRE : out std_logic;
+ RamLB : out std_logic;
+ RamUB : out std_logic;
+ RamWait : in std_logic;
+
+ FlashRp : out std_logic;
+ FlashCS : out std_logic;
+ FlashStSts : in std_logic;
+
+ MemAdr : out std_logic_vector(23 downto 1);
+ MemDin : out std_logic_vector(15 downto 0);
+ MemDout : in std_logic_vector(15 downto 0);
+
+ blitter_sc2 : in std_logic;
+ sinistar : in std_logic;
+
+ -- Switches
+ SW : in std_logic_vector(7 downto 0);
+
+ -- Buttons
+ BTN : in std_logic_vector(3 downto 0);
+ SIN_FIRE : in std_logic;
+ SIN_BOMB : in std_logic;
+
+ -- VGA connector
+ vgaRed : out std_logic_vector(2 downto 0);
+ vgaGreen : out std_logic_vector(2 downto 0);
+ vgaBlue : out std_logic_vector(1 downto 0);
+ Hsync : out std_logic;
+ Vsync : out std_logic;
+
+ -- Audio
+ audio_out : out std_logic_vector(7 downto 0);
+
+ -- 12-pin connectors
+ JA : in std_logic_vector(7 downto 0);
+ JB : in std_logic_vector(7 downto 0);
+
+ dl_clock : in std_logic;
+ dl_addr : in std_logic_vector(15 downto 0);
+ dl_data : in std_logic_vector(7 downto 0);
+ dl_wr : in std_logic
+);
+end robotron_soc;
+
+architecture Behavioral of robotron_soc is
+
+component mc6809i is
+port (
+ D : in std_logic_vector( 7 downto 0);
+ Dout : out std_logic_vector( 7 downto 0);
+ ADDR : out std_logic_vector(15 downto 0);
+ RnW : out std_logic;
+ E : in std_logic;
+ Q : in std_logic;
+ BS : out std_logic;
+ BA : out std_logic;
+ nIRQ : in std_logic := '1';
+ nFIRQ : in std_logic := '1';
+ nNMI : in std_logic := '1';
+ AVMA : out std_logic;
+ BUSY : out std_logic;
+ LIC : out std_logic;
+ nHALT : in std_logic := '1';
+ nRESET : in std_logic := '1';
+ nDMABREQ : in std_logic := '1'
+);
+end component mc6809i;
+
+signal cpu_a : std_logic_vector(15 downto 0);
+signal cpu_dout : std_logic_vector( 7 downto 0);
+signal cpu_din : std_logic_vector( 7 downto 0);
+signal cpu_reset_n : std_logic;
+signal cpu_nmi_n : std_logic;
+signal cpu_firq_n : std_logic;
+signal cpu_irq_n : std_logic;
+signal cpu_lic : std_logic;
+signal cpu_avma : std_logic;
+signal cpu_rwn : std_logic;
+signal cpu_halt_n : std_logic;
+signal cpu_ba : std_logic;
+signal cpu_bs : std_logic;
+signal cpu_busy : std_logic;
+signal cpu_e : std_logic;
+signal cpu_q : std_logic;
+
+signal hand : std_logic;
+signal select_sound : std_logic_vector( 5 downto 0);
+
+signal snd_addr : std_logic_vector(11 downto 0);
+signal snd_do : std_logic_vector( 7 downto 0);
+signal snd_rom_we : std_logic;
+
+begin
+
+mc6809: mc6809i
+port map (
+ ADDR => cpu_a,
+ Dout => cpu_dout,
+ D => cpu_din,
+ nReset => cpu_reset_n,
+ nNMI => cpu_nmi_n,
+ nFIRQ => cpu_firq_n,
+ nIRQ => cpu_irq_n,
+ LIC => cpu_lic,
+ AVMA => cpu_avma,
+ RnW => cpu_rwn,
+ nHALT => cpu_halt_n,
+ BA => cpu_ba,
+ BS => cpu_bs,
+ BUSY => cpu_busy,
+ E => cpu_e,
+ Q => cpu_q
+);
+
+cpu_board: entity work.robotron_cpu
+port map (
+ clock => clock,
+ blitter_sc2 => blitter_sc2,
+ sinistar => sinistar,
+
+ A => cpu_a,
+ Dout => cpu_dout,
+ Din => cpu_din,
+ RESET_N => cpu_reset_n,
+ NMI_N => cpu_nmi_n,
+ FIRQ_N => cpu_firq_n,
+ IRQ_N => cpu_irq_n,
+ LIC => cpu_lic,
+ AVMA => cpu_avma,
+ R_W_N => cpu_rwn,
+ TSC => open,
+ HALT_N => cpu_halt_n,
+ BA => cpu_ba,
+ BS => cpu_bs,
+ BUSY => cpu_busy,
+ E => cpu_e,
+ Q => cpu_q,
+
+ -- Cellular RAM / StrataFlash
+ MemOE => MemOE,
+ MemWR => MemWR,
+
+ RamAdv => RamAdv,
+ RamCS => RamCS,
+ RamClk => RamClk,
+ RamCRE => RamCRE,
+ RamLB => RamLB,
+ RamUB => RamUB,
+ RamWait => RamWait,
+
+ FlashRp => FlashRp,
+ FlashCS => FlashCS,
+ FlashStSts => FlashStSts,
+
+ MemAdr => MemAdr,
+ MemDin => MemDin,
+ MemDout => MemDout,
+
+ -- 7-segment display
+-- SEG => SEG,
+-- DP => DP,
+-- AN => AN,
+
+ -- LEDs
+-- LED => LED,
+
+ -- Switches
+ SW => SW,
+
+ -- Buttons
+ BTN => BTN,
+ SIN_FIRE => SIN_FIRE,
+ SIN_BOMB => SIN_BOMB,
+
+ -- VGA connector
+ vgaRed => vgaRed,
+ vgaGreen => vgaGreen,
+ vgaBlue => vgaBlue,
+ Hsync => Hsync,
+ Vsync => Vsync,
+
+ -- 12-pin connectors
+ JA => JA,
+ JB => JB,
+
+ -- Sound board
+ PB => select_sound,
+ HAND => hand
+);
+
+snd_rom : entity work.dpram
+generic map( dWidth => 8, aWidth => 12)
+port map(
+ clk_a => clock_snd,
+ addr_a => snd_addr,
+ q_a => snd_do,
+ clk_b => dl_clock,
+ we_b => snd_rom_we,
+ addr_b => dl_addr(11 downto 0),
+ d_b => dl_data
+);
+
+snd_rom_we <= '1' when dl_wr = '1' and dl_addr(15 downto 12) = x"C" else '0'; -- C000-CFFF
+
+-- sound board
+defender_sound_board : entity work.defender_sound_board
+port map(
+ clk_0p89 => clock_snd,
+ reset => not cpu_reset_n,
+ hand => hand,
+ select_sound => select_sound,
+ audio_out => audio_out,
+ rom_addr => snd_addr,
+ rom_do => snd_do
+);
+
+end Behavioral;
diff --git a/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/sdram.sv b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/sdram.sv
new file mode 100644
index 00000000..55c8b97d
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron-FPGA/rtl/sdram.sv
@@ -0,0 +1,253 @@
+//
+// 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 clkref,
+
+ 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 [17:1] cpu1_addr,
+ input [15:0] cpu1_d,
+ output reg [15:0] cpu1_q,
+ input cpu1_oe,
+ input cpu1_we,
+ input [1:0] cpu1_ds
+);
+
+parameter MHZ = 80; // 80 MHz default clock, adjust to calculate the refresh rate correctly
+
+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 = 16'd78*MHZ/10;
+
+// ---------------------------------------------------------------------
+// ------------------------ cycle state machine ------------------------
+// ---------------------------------------------------------------------
+
+/*
+ SDRAM state machine
+ 1 word burst, CL2
+cmd issued registered
+ 0 RAS0
+ 1
+ 2 CAS0
+ 3
+ 4
+ 5
+ 6 data ready
+ 7
+*/
+
+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_READ0 = STATE_CAS0 + CAS_LATENCY + 2'd2; // 6
+localparam STATE_LAST = 3'd7;
+
+reg [2:0] t;
+
+always @(posedge clk) begin
+ reg clkref_d;
+ clkref_d <= clkref;
+
+ t <= t + 1'd1;
+ if (t == STATE_LAST) t <= STATE_RAS0;
+ if (~clkref_d & clkref) t <= 3'd1;
+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;
+reg [24:1] addr_latch_next;
+reg [15:0] din_latch;
+reg oe_latch;
+reg we_latch;
+reg [1:0] ds;
+
+localparam PORT_NONE = 2'd0;
+localparam PORT_CPU1 = 2'd1;
+localparam PORT_REQ = 2'd2;
+
+reg [2:0] next_port;
+reg [2:0] port;
+reg port1_state;
+
+// PORT1
+always @(*) begin
+ if (port1_req ^ port1_state) begin
+ next_port = PORT_REQ;
+ addr_latch_next = { 1'b0, port1_a };
+ end else if (cpu1_oe | cpu1_we) begin
+ next_port = PORT_CPU1;
+ addr_latch_next = { 7'd0, cpu1_addr };
+ end else begin
+ next_port = PORT_NONE;
+ addr_latch_next = addr_latch;
+ 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
+
+ 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
+ if(t == STATE_RAS0) begin
+ addr_latch <= addr_latch_next;
+ port <= next_port;
+ { oe_latch, we_latch } <= 2'b00;
+
+ if (next_port != PORT_NONE) begin
+ sd_cmd <= CMD_ACTIVE;
+ SDRAM_A <= addr_latch_next[22:10];
+ SDRAM_BA <= addr_latch_next[24:23];
+ if (next_port == PORT_REQ) begin
+ { oe_latch, we_latch } <= { ~port1_we, port1_we };
+ ds <= port1_ds;
+ din_latch <= port1_d;
+ port1_state <= port1_req;
+ end else begin
+ { oe_latch, we_latch } <= { cpu1_oe, cpu1_we };
+ din_latch <= cpu1_d;
+ ds <= cpu1_ds;
+ end
+ end else begin
+ sd_cmd <= CMD_AUTO_REFRESH;
+ end
+ end
+
+ // CAS phase
+ if(t == STATE_CAS0 && (we_latch || oe_latch)) begin
+ sd_cmd <= we_latch?CMD_WRITE:CMD_READ;
+ { SDRAM_DQMH, SDRAM_DQML } <= ~ds;
+ if (we_latch) begin
+ SDRAM_DQ <= din_latch;
+ port1_ack <= port1_req;
+ end
+ SDRAM_A <= { 4'b0010, addr_latch[9:1] }; // auto precharge
+ SDRAM_BA <= addr_latch[24:23];
+ end
+
+ // Data returned
+ if(t == STATE_READ0 && oe_latch) begin
+ case(port)
+ PORT_REQ: begin port1_q <= sd_din; port1_ack <= port1_req; end
+ PORT_CPU1: begin cpu1_q <= sd_din; end
+ default: ;
+ endcase;
+ end
+ end
+end
+
+endmodule