diff --git a/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/Mayday.qpf b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/Mayday.qpf
new file mode 100644
index 00000000..7676d539
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/Mayday.qpf
@@ -0,0 +1,31 @@
+# -------------------------------------------------------------------------- #
+#
+# Copyright (C) 1991-2014 Altera Corporation
+# Your use of Altera Corporation's design tools, logic functions
+# and other software and tools, and its AMPP partner logic
+# functions, and any output files from any of the foregoing
+# (including device programming or simulation files), and any
+# associated documentation or information are expressly subject
+# to the terms and conditions of the Altera Program License
+# Subscription Agreement, Altera MegaCore Function License
+# Agreement, or other applicable license agreement, including,
+# without limitation, that your use is for the sole purpose of
+# programming logic devices manufactured by Altera and sold by
+# Altera or its authorized distributors. Please refer to the
+# applicable agreement for further details.
+#
+# -------------------------------------------------------------------------- #
+#
+# Quartus II 64-Bit
+# Version 13.1.4 Build 182 03/12/2014 SJ Web Edition
+# Date created = 19:06:48 June 09, 2019
+#
+# -------------------------------------------------------------------------- #
+
+QUARTUS_VERSION = "13.1"
+DATE = "19:06:48 June 09, 2019"
+
+# Revisions
+
+PROJECT_REVISION = "Mayday"
+
diff --git a/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/Mayday.qsf b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/Mayday.qsf
new file mode 100644
index 00000000..a4bb174b
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/Mayday.qsf
@@ -0,0 +1,203 @@
+# -------------------------------------------------------------------------- #
+#
+# Copyright (C) 1991-2014 Altera Corporation
+# Your use of Altera Corporation's design tools, logic functions
+# and other software and tools, and its AMPP partner logic
+# functions, and any output files from any of the foregoing
+# (including device programming or simulation files), and any
+# associated documentation or information are expressly subject
+# to the terms and conditions of the Altera Program License
+# Subscription Agreement, Altera MegaCore Function License
+# Agreement, or other applicable license agreement, including,
+# without limitation, that your use is for the sole purpose of
+# programming logic devices manufactured by Altera and sold by
+# Altera or its authorized distributors. Please refer to the
+# applicable agreement for further details.
+#
+# -------------------------------------------------------------------------- #
+#
+# Quartus II 64-Bit
+# Version 13.1.4 Build 182 03/12/2014 SJ Web Edition
+# Date created = 18:04:04 June 09, 2019
+#
+# -------------------------------------------------------------------------- #
+#
+# Notes:
+#
+# 1) The default values for assignments are stored in the file:
+# Defender_MiST_assignment_defaults.qdf
+# If this file doesn't exist, see file:
+# assignment_defaults.qdf
+#
+# 2) Altera recommends that you do not modify this file. This
+# file is updated automatically by the Quartus II software
+# and any changes you make may be lost or overwritten.
+#
+# -------------------------------------------------------------------------- #
+
+
+
+# Project-Wide Assignments
+# ========================
+set_global_assignment -name PROJECT_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
+set_global_assignment -name SMART_RECOMPILE ON
+set_global_assignment -name SYSTEMVERILOG_FILE rtl/Mayday_MiST.sv
+set_global_assignment -name VHDL_FILE rtl/defender.vhd
+set_global_assignment -name VHDL_FILE rtl/defender_sound_board.vhd
+set_global_assignment -name VHDL_FILE rtl/defender_sound.vhd
+set_global_assignment -name VHDL_FILE rtl/defender_decoder_3.vhd
+set_global_assignment -name VHDL_FILE rtl/defender_decoder_2.vhd
+set_global_assignment -name VHDL_FILE rtl/defender_cmos_ram.vhd
+set_global_assignment -name SYSTEMVERILOG_FILE rtl/YM2149.sv
+set_global_assignment -name VHDL_FILE rtl/pia6821.vhd
+set_global_assignment -name VHDL_FILE rtl/cpu68.vhd
+set_global_assignment -name VHDL_FILE rtl/cpu09l_128.vhd
+set_global_assignment -name QIP_FILE rtl/pll_mist.qip
+set_global_assignment -name VERILOG_FILE rtl/data_io.v
+set_global_assignment -name SYSTEMVERILOG_FILE rtl/sdram.sv
+set_global_assignment -name VHDL_FILE rtl/gen_ram.vhd
+set_global_assignment -name VHDL_FILE rtl/dac.vhd
+set_global_assignment -name QIP_FILE ../../../common/mist/mist.qip
+
+# 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 TOP_LEVEL_ENTITY Mayday_MiST
+set_global_assignment -name DEVICE_FILTER_PIN_COUNT 144
+set_global_assignment -name DEVICE_FILTER_SPEED_GRADE 8
+
+# 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
+
+# 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)
+
+ # start DESIGN_PARTITION(Top)
+ # ---------------------------
+
+ # Incremental Compilation Assignments
+ # ===================================
+ set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
+ set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
+ set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
+
+ # end DESIGN_PARTITION(Top)
+ # -------------------------
+
+# end ENTITY(Defender_MiST)
+# -------------------------
+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/Mayday/Mayday.sdc b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/Mayday.sdc
new file mode 100644
index 00000000..fca44902
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/Mayday.sdc
@@ -0,0 +1,137 @@
+## 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}]
+
+#**************************************************************
+# 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 {pll|altpll_component|auto_generated|pll1|clk[0]}] -max 6.4 [get_ports SDRAM_DQ[*]]
+set_input_delay -clock [get_clocks {pll|altpll_component|auto_generated|pll1|clk[0]}] -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 {pll|altpll_component|auto_generated|pll1|clk[1]}] 1.000 [get_ports {AUDIO_L}]
+set_output_delay -add_delay -clock_fall -clock [get_clocks {pll|altpll_component|auto_generated|pll1|clk[1]}] 1.000 [get_ports {AUDIO_R}]
+set_output_delay -add_delay -clock_fall -clock [get_clocks {pll|altpll_component|auto_generated|pll1|clk[0]}] 1.000 [get_ports {LED}]
+set_output_delay -add_delay -clock_fall -clock [get_clocks {pll|altpll_component|auto_generated|pll1|clk[0]}] 1.000 [get_ports {VGA_*}]
+
+set_output_delay -clock [get_clocks {pll|altpll_component|auto_generated|pll1|clk[0]}] -max 1.5 [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}]
+set_output_delay -clock [get_clocks {pll|altpll_component|auto_generated|pll1|clk[0]}] -min -0.8 [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}]
+set_output_delay -clock [get_clocks {pll|altpll_component|auto_generated|pll1|clk[0]}] -max 1.5 [get_ports {SDRAM_CLK}]
+set_output_delay -clock [get_clocks {pll|altpll_component|auto_generated|pll1|clk[0]}] -min -0.8 [get_ports {SDRAM_CLK}]
+
+#**************************************************************
+# Set Clock Groups
+#**************************************************************
+
+set_clock_groups -asynchronous -group [get_clocks {SPI_SCK}] -group [get_clocks {pll|altpll_component|auto_generated|pll1|clk[*]}]
+
+#**************************************************************
+# Set False Path
+#**************************************************************
+
+
+
+#**************************************************************
+# Set Multicycle Path
+#**************************************************************
+
+set_multicycle_path -to {VGA_*[*]} -setup 2
+set_multicycle_path -to {VGA_*[*]} -hold 1
+
+set_multicycle_path -from [get_clocks {pll|altpll_component|auto_generated|pll1|clk[0]}] -to [get_clocks {pll|altpll_component|auto_generated|pll1|clk[1]}] -setup 2
+set_multicycle_path -from [get_clocks {pll|altpll_component|auto_generated|pll1|clk[0]}] -to [get_clocks {pll|altpll_component|auto_generated|pll1|clk[1]}] -hold 1
+
+#**************************************************************
+# Set Maximum Delay
+#**************************************************************
+
+
+
+#**************************************************************
+# Set Minimum Delay
+#**************************************************************
+
+
+
+#**************************************************************
+# Set Input Transition
+#**************************************************************
+
diff --git a/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/ReadMe.txt b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/ReadMe.txt
new file mode 100644
index 00000000..622794a7
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/ReadMe.txt
@@ -0,0 +1,17 @@
+Williams Mayday
+
+Port to MiST
+
+MAYDAY.ROM is required at the root of the SD-Card.
+
+ Fire Forward = Fire or Space
+ Mayday = Fire2 or ALT
+ Fire Backward = Fire3 or CTRL
+
+ Change Direction = Left or Right
+ Up = Up
+ Down = Down
+
+ Advance = A
+ Auto up = U
+ Service = H
\ No newline at end of file
diff --git a/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/Release/MAYDAY.ROM b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/Release/MAYDAY.ROM
new file mode 100644
index 00000000..0508ad5a
Binary files /dev/null and b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/Release/MAYDAY.ROM differ
diff --git a/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/Release/Mayday.rbf b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/Release/Mayday.rbf
new file mode 100644
index 00000000..bd95edb0
Binary files /dev/null and b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/Release/Mayday.rbf differ
diff --git a/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/clean.bat b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/clean.bat
new file mode 100644
index 00000000..c9a2cb06
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/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/Mayday/rtl/Mayday_MiST.sv b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/rtl/Mayday_MiST.sv
new file mode 100644
index 00000000..85905811
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/rtl/Mayday_MiST.sv
@@ -0,0 +1,260 @@
+//============================================================================
+// Arcade: Mayday
+//
+
+module Mayday_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"
+
+localparam CONF_STR = {
+ "MAYDAY;;",
+ "O34,Scanlines,Off,25%,50%,75%;",
+ "T6,Reset;",
+ "V,v1.0.0",`BUILD_DATE
+};
+
+assign LED = 1;
+
+wire clk_sys, clock_6, clock_1p79, clock_0p89;
+wire pll_locked;
+pll_mist pll(
+ .inclk0(CLOCK_27),
+ .areset(0),
+ .c0(clk_sys),//36
+ .c1(clock_6),//6
+ .c2(clock_1p79),//1.79
+ .c3(clock_0p89),//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 [10:0] ps2_key;
+wire [7:0] audio;
+wire hs, vs;
+wire blankn;
+wire [2:0] g,b;
+wire [1:0] r;
+
+wire [14:0] cart_addr;
+wire [15:0] sdram_do;
+wire cart_rd;
+wire ioctl_downl;
+wire [7:0] ioctl_index;
+wire ioctl_wr;
+wire [24:0] ioctl_addr;
+wire [7:0] ioctl_dout;
+
+data_io data_io (
+ .clk_sys ( clk_sys ),
+ .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 )
+);
+
+assign SDRAM_CLK = clk_sys;
+
+sdram cart
+(
+ .*,
+ .init ( ~pll_locked ),
+ .clk ( clk_sys ),
+ .wtbt ( 2'b00 ),
+ .dout ( sdram_do ),
+ .din ( {ioctl_dout, ioctl_dout} ),
+ .addr ( ioctl_downl ? ioctl_addr : cart_addr ),
+ .we ( ioctl_downl & ioctl_wr ),
+ .rd ( !ioctl_downl),
+ .ready()
+);
+
+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] | status[6] | ~rom_loaded;
+end
+
+defender defender (
+ .clock_6 (clock_6),
+ .clk_1p79 (clock_1p79),
+ .clk_0p89 (clock_0p89),
+ .reset (reset),
+
+ .video_r ( r ),
+ .video_g ( g ),
+ .video_b ( b ),
+ .video_hs ( hs ),
+ .video_vs ( vs ),
+ .video_blankn ( blankn ),
+
+ .audio_out ( audio ),
+
+ .roms_addr ( cart_addr ),
+ .roms_do ( sdram_do[7:0] ),
+
+ .btn_two_players ( btn_two_players ),//
+ .btn_one_player ( btn_one_player ),//
+ .btn_left_coin ( btn_coin ),//
+
+ .btn_auto_up(btn_auto_up),//
+ .btn_advance(btn_advance),//
+ .btn_service(btn_service),//
+
+
+ .btn_ffire(m_fire1),//SPACE
+ .btn_bfire(m_fire3),//CTRL
+ .btn_mayday(m_fire3),//ALT
+
+ .btn_right(m_left | m_right),
+ .btn_down(m_down),
+ .btn_up(m_up),
+
+ .sw_coktail_table(1)
+);
+
+mist_video #(.COLOR_DEPTH(3), .SD_HCNT_WIDTH(10)) mist_video(
+ .clk_sys ( clk_sys ),
+ .SPI_SCK ( SPI_SCK ),
+ .SPI_SS3 ( SPI_SS3 ),
+ .SPI_DI ( SPI_DI ),
+ .R ( blankn ? {r, r[1] } : 0 ),
+ .G ( blankn ? g : 0 ),
+ .B ( blankn ? b : 0 ),
+ .HSync ( hs ),
+ .VSync ( vs ),
+ .VGA_R ( VGA_R ),
+ .VGA_G ( VGA_G ),
+ .VGA_B ( VGA_B ),
+ .VGA_VS ( VGA_VS ),
+ .VGA_HS ( VGA_HS ),
+ .rotate ( {1'b1,status[2]} ),
+ .scandoubler_disable( scandoublerD ),
+ .scanlines ( status[4:3] ),
+ .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(15))
+dac(
+ .clk_i(clk_sys),
+ .res_n_i(1),
+ .dac_i({audio,audio}),
+ .dac_o(dac_o)
+ );
+
+wire m_up = btn_up | joystick_0[3] | joystick_1[3];
+wire m_down = btn_down | joystick_0[2] | joystick_1[2];
+wire m_left = btn_left | joystick_0[1] | joystick_1[1];
+wire m_right = btn_right | joystick_0[0] | joystick_1[0];
+wire m_fire1 = btn_fire1 | joystick_0[4] | joystick_1[4];
+wire m_fire2 = btn_fire2 | joystick_0[5] | joystick_1[5];
+wire m_fire3 = btn_fire3 | joystick_0[6] | joystick_1[6];
+wire m_fire4 = btn_fire4 | joystick_0[7] | joystick_1[7];
+
+reg btn_one_player = 0;
+reg btn_two_players = 0;
+reg btn_left = 0;
+reg btn_right = 0;
+reg btn_down = 0;
+reg btn_up = 0;
+reg btn_fire1 = 0;
+reg btn_fire2 = 0;
+reg btn_fire3 = 0;
+reg btn_fire4 = 0;
+reg btn_coin = 0;
+reg btn_advance = 0;
+reg btn_auto_up = 0;
+reg btn_service = 0;
+wire key_pressed;
+wire [7:0] key_code;
+wire key_strobe;
+
+always @(posedge clk_sys) begin
+ if(key_strobe) begin
+ case(key_code)
+ 'h75: btn_up <= key_pressed; // up
+ 'h72: btn_down <= key_pressed; // down
+ 'h6B: btn_left <= key_pressed; // left
+ 'h74: btn_right <= key_pressed; // right
+ 'h76: btn_coin <= key_pressed; // ESC
+ 'h05: btn_one_player <= key_pressed; // F1
+ 'h06: btn_two_players <= key_pressed; // F2
+ 'h12: btn_fire4 <= key_pressed; // l shift
+ 'h14: btn_fire3 <= key_pressed; // ctrl
+ 'h11: btn_fire2 <= key_pressed; // alt
+ 'h29: btn_fire1 <= key_pressed; // Space
+ 'h1C: btn_advance <= key_pressed; // A
+ 'h3C: btn_auto_up <= key_pressed; // U
+ 'h33: btn_service <= key_pressed; // H
+ endcase
+ end
+end
+
+endmodule
diff --git a/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/rtl/build_id.tcl b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/rtl/build_id.tcl
new file mode 100644
index 00000000..938515d8
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/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/Mayday/rtl/cpu09l_128.vhd b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/rtl/cpu09l_128.vhd
new file mode 100644
index 00000000..12039bde
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/rtl/cpu09l_128.vhd
@@ -0,0 +1,5906 @@
+--===========================================================================--
+-- --
+-- Synthesizable 6809 instruction compatible VHDL CPU core --
+-- --
+--===========================================================================--
+--
+-- File name : cpu09l.vhd
+--
+-- Entity name : cpu09
+--
+-- Purpose : 6809 instruction compatible CPU core written in VHDL
+-- with Last Instruction Cycle, bus available, bus status,
+-- and instruction fetch signals.
+-- Not cycle compatible with the original 6809 CPU
+--
+-- Dependencies : ieee.std_logic_1164
+-- ieee.std_logic_unsigned
+--
+-- Author : John E. Kent
+--
+-- Email : dilbert57@opencores.org
+--
+-- Web : http://opencores.org/project,system09
+--
+-- Description : VMA (valid memory address) is hight whenever a valid memory
+-- access is made by an instruction fetch, interrupt vector fetch
+-- or a data read or write otherwise it is low indicating an idle
+-- bus cycle.
+-- IFETCH (instruction fetch output) is high whenever an
+-- instruction byte is read i.e. the program counter is applied
+-- to the address bus.
+-- LIC (last instruction cycle output) is normally low
+-- but goes high on the last cycle of an instruction.
+-- BA (bus available output) is normally low but goes high while
+-- waiting in a Sync instruction state or the CPU is halted
+-- i.e. a DMA grant.
+-- BS (bus status output) is normally low but goes high during an
+-- interrupt or reset vector fetch or the processor is halted
+-- i.e. a DMA grant.
+--
+-- Copyright (C) 2003 - 2010 John Kent
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program. If not, see .
+--
+--===========================================================================--
+-- --
+-- Revision History --
+-- --
+--===========================================================================--
+--
+-- Version 0.1 - 26 June 2003 - John Kent
+-- Added extra level in state stack
+-- fixed some calls to the extended addressing state
+--
+-- Version 0.2 - 5 Sept 2003 - John Kent
+-- Fixed 16 bit indexed offset (was doing read rather than fetch)
+-- Added/Fixed STY and STS instructions.
+-- ORCC_STATE ANDed CC state rather than ORed it - Now fixed
+-- CMPX Loaded ACCA and ACCB - Now fixed
+--
+-- Version 1.0 - 6 Sep 2003 - John Kent
+-- Initial release to Open Cores
+-- reversed clock edge
+--
+-- Version 1.1 - 29 November 2003 John kent
+-- ACCA and ACCB indexed offsets are 2's complement.
+-- ALU Right Mux now sign extends ACCA & ACCB offsets
+-- Absolute Indirect addressing performed a read on the
+-- second byte of the address rather than a fetch
+-- so it formed an incorrect address. Now fixed.
+--
+-- Version 1.2 - 29 November 2003 John Kent
+-- LEAX and LEAY affect the Z bit only
+-- LEAS and LEAU do not affect any condition codes
+-- added an extra ALU control for LEA.
+--
+-- Version 1.3 - 12 December 2003 John Kent
+-- CWAI did not work, was missed a PUSH_ST on calling
+-- the ANDCC_STATE. Thanks go to Ghassan Kraidy for
+-- finding this fault.
+--
+-- Version 1.4 - 12 December 2003 John Kent
+-- Missing cc_ctrl assignment in otherwise case of
+-- lea_state resulted in cc_ctrl being latched in
+-- that state.
+-- The otherwise statement should never be reached,
+-- and has been fixed simply to resolve synthesis warnings.
+--
+-- Version 1.5 - 17 january 2004 John kent
+-- The clear instruction used "alu_ld8" to control the ALU
+-- rather than "alu_clr". This mean the Carry was not being
+-- cleared correctly.
+--
+-- Version 1.6 - 24 January 2004 John Kent
+-- Fixed problems in PSHU instruction
+--
+-- Version 1.7 - 25 January 2004 John Kent
+-- removed redundant "alu_inx" and "alu_dex'
+-- Removed "test_alu" and "test_cc"
+-- STD instruction did not set condition codes
+-- JMP direct was not decoded properly
+-- CLR direct performed an unwanted read cycle
+-- Bogus "latch_md" in Page2 indexed addressing
+--
+-- Version 1.8 - 27 January 2004 John Kent
+-- CWAI in decode1_state should increment the PC.
+-- ABX is supposed to be an unsigned addition.
+-- Added extra ALU function
+-- ASR8 slightly changed in the ALU.
+--
+-- Version 1.9 - 20 August 2005
+-- LSR8 is now handled in ASR8 and ROR8 case in the ALU,
+-- rather than LSR16. There was a problem with single
+-- operand instructions using the MD register which is
+-- sign extended on the first 8 bit fetch.
+--
+-- Version 1.10 - 13 September 2005
+-- TFR & EXG instructions did not work for the Condition Code Register
+-- An extra case has been added to the ALU for the alu_tfr control
+-- to assign the left ALU input (alu_left) to the condition code
+-- outputs (cc_out).
+--
+-- Version 1.11 - 16 September 2005
+-- JSR ,X should not predecrement S before calculating the jump address.
+-- The reason is that JSR [0,S] needs S to point to the top of the stack
+-- to fetch a valid vector address. The solution is to have the addressing
+-- mode microcode called before decrementing S and then decrementing S in
+-- JSR_STATE. JSR_STATE in turn calls PUSH_RETURN_LO_STATE rather than
+-- PUSH_RETURN_HI_STATE so that both the High & Low halves of the PC are
+-- pushed on the stack. This adds one extra bus cycle, but resolves the
+-- addressing conflict. I've also removed the pre-decement S in
+-- JSR EXTENDED as it also calls JSR_STATE.
+--
+-- Version 1.12 - 6th June 2006
+-- 6809 Programming reference manual says V is not affected by ASR, LSR and ROR
+-- This is different to the 6800. CLR should reset the V bit.
+--
+-- Version 1.13 - 7th July 2006
+-- Disable NMI on reset until S Stack pointer has been loaded.
+-- Added nmi_enable signal in sp_reg process and nmi_handler process.
+--
+-- Version 1.14 - 11th July 2006
+-- 1. Added new state to RTI called rti_entire_state.
+-- This state tests the CC register after it has been loaded
+-- from the stack. Previously the current CC was tested which
+-- was incorrect. The Entire Flag should be set before the
+-- interrupt stacks the CC.
+-- 2. On bogus Interrupts, int_cc_state went to rti_state,
+-- which was an enumerated state, but not defined anywhere.
+-- rti_state has been changed to rti_cc_state so that bogus interrupt
+-- will perform an RTI after entering that state.
+-- 3. Sync should generate an interrupt if the interrupt masks
+-- are cleared. If the interrupt masks are set, then an interrupt
+-- will cause the the PC to advance to the next instruction.
+-- Note that I don't wait for an interrupt to be asserted for
+-- three clock cycles.
+-- 4. Added new ALU control state "alu_mul". "alu_mul" is used in
+-- the Multiply instruction replacing "alu_add16". This is similar
+-- to "alu_add16" except it sets the Carry bit to B7 of the result
+-- in ACCB, sets the Zero bit if the 16 bit result is zero, but
+-- does not affect The Half carry (H), Negative (N) or Overflow (V)
+-- flags. The logic was re-arranged so that it adds md or zero so
+-- that the Carry condition code is set on zero multiplicands.
+-- 5. DAA (Decimal Adjust Accumulator) should set the Negative (N)
+-- and Zero Flags. It will also affect the Overflow (V) flag although
+-- the operation is undefined. It's anyones guess what DAA does to V.
+--
+-- Version 1.15 - 25th Feb 2007 - John Kent
+-- line 9672 changed "if Halt <= '1' then" to "if Halt = '1' then"
+-- Changed sensitivity lists.
+--
+-- Version 1.16 - 5th February 2008 - John Kent
+-- FIRQ interrupts should take priority over IRQ Interrupts.
+-- This presumably means they should be tested for before IRQ
+-- when they happen concurrently.
+--
+-- Version 1.17 - 18th February 2008 - John Kent
+-- NMI in CWAI should mask IRQ and FIRQ interrupts
+--
+-- Version 1.18 - 21st February 2008 - John Kent
+-- Removed default register settings in each case statement
+-- and placed them at the beginning of the state sequencer.
+-- Modified the SYNC instruction so that the interrupt vector(iv)
+-- is not set unless an unmasked FIRQ or IRQ is received.
+--
+-- Version 1.19 - 25th February 2008 - John Kent
+-- Enumerated separate states for FIRQ/FAST and NMIIRQ/ENTIRE
+-- Enumerated separate states for MASKI and MASKIF states
+-- Removed code on BSR/JSR in fetch cycle
+--
+-- Version 1.20 - 8th October 2011 - John Kent
+-- added fetch output which should go high during the fetch cycle
+--
+-- Version 1.21 - 8th October 2011 - John Kent
+-- added Last Instruction Cycle signal
+-- replaced fetch with ifetch (instruction fetch) signal
+-- added ba & bs (bus available & bus status) signals
+--
+-- Version 1.22 - 2011-10-29 John Kent
+-- The halt state isn't correct.
+-- The halt state is entered into from the fetch_state
+-- It returned to the fetch state which may re-run an execute cycle
+-- on the accumulator and it won't necessarily be the last instruction cycle
+-- I've changed the halt state to return to the decode1_state
+--
+-- Version 1.23 - 2011-10-30 John Kent
+-- sample halt in the change_state process if lic is high (last instruction cycle)
+--
+-- Version 1.24 - 2011-11-01 John Kent
+-- Handle interrupts in change_state process
+-- Sample interrupt inputs on last instruction cycle
+-- Remove iv_ctrl and implement iv (interrupt vector) in change_state process.
+-- Generate fic (first instruction cycle) from lic (last instruction cycle)
+-- and use it to complete the dual operand execute cycle before servicing
+-- halt or interrupts requests.
+-- rename lic to lic_out on the entity declaration so that lic can be tested internally.
+-- add int_firq1_state and int_nmirq1_state to allow for the dual operand execute cycle
+-- integrated nmi_ctrl into change_state process
+-- Reduces the microcode state stack to one entry (saved_state)
+-- imm16_state jumps directly to the fetch_state
+-- pull_return_lo states jumps directly to the fetch_state
+-- duplicate andcc_state as cwai_state
+-- rename exg1_state as exg2 state and duplicate tfr_state as exg1_state
+--
+-- Version 1.25 - 2011-11-27 John Kent
+-- Changed the microcode for saving registers on an interrupt into a microcode subroutine.
+-- Removed SWI servicing from the change state process and made SWI, SWI2 & SWI3
+-- call the interrupt microcode subroutine.
+-- Added additional states for nmi, and irq for interrupt servicing.
+-- Added additional states for nmi/irq, firq, and swi interrupts to mask I & F flags.
+--
+-- Version 1.26 - 2013-03-18 John Kent
+-- pre-initialized cond_true variable to true in state sequencer
+-- re-arranged change_state process slightly
+--
+-- Version 1.27 - 2015-05-30 John Kent
+-- Added test in state machine for masked IRQ and FIRQ in Sync_state.
+--
+-- Version 1.28 - 2015-05-30 John Kent.
+-- Moved IRQ and FIRQ test from state machine to the state sequencer Sync_state.
+--
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_unsigned.all;
+
+entity cpu09 is
+ port (
+ clk : in std_logic; -- E clock input (falling edge)
+ rst : in std_logic; -- reset input (active high)
+ vma : out std_logic; -- valid memory address (active high)
+ lic_out : out std_logic; -- last instruction cycle (active high)
+ ifetch : out std_logic; -- instruction fetch cycle (active high)
+ opfetch : out std_logic; -- opcode fetch (active high)
+ ba : out std_logic; -- bus available (high on sync wait or DMA grant)
+ bs : out std_logic; -- bus status (high on interrupt or reset vector fetch or DMA grant)
+ addr : out std_logic_vector(15 downto 0); -- address bus output
+ rw : out std_logic; -- read not write output
+ data_out : out std_logic_vector(7 downto 0); -- data bus output
+ data_in : in std_logic_vector(7 downto 0); -- data bus input
+ irq : in std_logic; -- interrupt request input (active high)
+ firq : in std_logic; -- fast interrupt request input (active high)
+ nmi : in std_logic; -- non maskable interrupt request input (active high)
+ halt : in std_logic; -- halt input (active high) grants DMA
+ hold : in std_logic -- hold input (active high) extend bus cycle
+ );
+end cpu09;
+
+architecture rtl of cpu09 is
+
+ constant EBIT : integer := 7;
+ constant FBIT : 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;
+
+ --
+ -- Interrupt vector modifiers
+ --
+ constant RST_VEC : std_logic_vector(2 downto 0) := "111";
+ constant NMI_VEC : std_logic_vector(2 downto 0) := "110";
+ constant SWI_VEC : std_logic_vector(2 downto 0) := "101";
+ constant IRQ_VEC : std_logic_vector(2 downto 0) := "100";
+ constant FIRQ_VEC : std_logic_vector(2 downto 0) := "011";
+ constant SWI2_VEC : std_logic_vector(2 downto 0) := "010";
+ constant SWI3_VEC : std_logic_vector(2 downto 0) := "001";
+ constant RESV_VEC : std_logic_vector(2 downto 0) := "000";
+
+ type state_type is (-- Start off in Reset
+ reset_state,
+ -- Fetch Interrupt Vectors (including reset)
+ vect_lo_state, vect_hi_state, vect_idle_state,
+ -- Fetch Instruction Cycle
+ fetch_state,
+ -- Decode Instruction Cycles
+ decode1_state, decode2_state, decode3_state,
+ -- Calculate Effective Address
+ imm16_state,
+ indexed_state, index8_state, index16_state, index16_2_state,
+ pcrel8_state, pcrel16_state, pcrel16_2_state,
+ indexaddr_state, indexaddr2_state,
+ postincr1_state, postincr2_state,
+ indirect_state, indirect2_state, indirect3_state,
+ extended_state,
+ -- single ops
+ single_op_read_state,
+ single_op_exec_state,
+ single_op_write_state,
+ -- Dual op states
+ dual_op_read8_state, dual_op_read16_state, dual_op_read16_2_state,
+ dual_op_write8_state, dual_op_write16_state,
+ --
+ sync_state, halt_state, cwai_state,
+ --
+ andcc_state, orcc_state,
+ tfr_state,
+ exg_state, exg1_state, exg2_state,
+ lea_state,
+ -- Multiplication
+ mul_state, mulea_state, muld_state,
+ mul0_state, mul1_state, mul2_state, mul3_state,
+ mul4_state, mul5_state, mul6_state, mul7_state,
+ -- Branches
+ lbranch_state, sbranch_state,
+ -- Jumps, Subroutine Calls and Returns
+ jsr_state, jmp_state,
+ push_return_hi_state, push_return_lo_state,
+ pull_return_hi_state, pull_return_lo_state,
+ -- Interrupt cycles
+ int_nmi_state, int_nmi1_state,
+ int_irq_state, int_irq1_state,
+ int_firq_state, int_firq1_state,
+ int_entire_state, int_fast_state,
+ int_pcl_state, int_pch_state,
+ int_upl_state, int_uph_state,
+ int_iyl_state, int_iyh_state,
+ int_ixl_state, int_ixh_state,
+ int_dp_state,
+ int_accb_state, int_acca_state,
+ int_cc_state,
+ int_cwai_state,
+ int_nmimask_state, int_firqmask_state, int_swimask_state, int_irqmask_state,
+ -- Return From Interrupt
+ rti_cc_state, rti_entire_state,
+ rti_acca_state, rti_accb_state,
+ rti_dp_state,
+ rti_ixl_state, rti_ixh_state,
+ rti_iyl_state, rti_iyh_state,
+ rti_upl_state, rti_uph_state,
+ rti_pcl_state, rti_pch_state,
+ -- Push Registers using SP
+ pshs_state,
+ pshs_pcl_state, pshs_pch_state,
+ pshs_upl_state, pshs_uph_state,
+ pshs_iyl_state, pshs_iyh_state,
+ pshs_ixl_state, pshs_ixh_state,
+ pshs_dp_state,
+ pshs_acca_state, pshs_accb_state,
+ pshs_cc_state,
+ -- Pull Registers using SP
+ puls_state,
+ puls_cc_state,
+ puls_acca_state, puls_accb_state,
+ puls_dp_state,
+ puls_ixl_state, puls_ixh_state,
+ puls_iyl_state, puls_iyh_state,
+ puls_upl_state, puls_uph_state,
+ puls_pcl_state, puls_pch_state,
+ -- Push Registers using UP
+ pshu_state,
+ pshu_pcl_state, pshu_pch_state,
+ pshu_spl_state, pshu_sph_state,
+ pshu_iyl_state, pshu_iyh_state,
+ pshu_ixl_state, pshu_ixh_state,
+ pshu_dp_state,
+ pshu_acca_state, pshu_accb_state,
+ pshu_cc_state,
+ -- Pull Registers using UP
+ pulu_state,
+ pulu_cc_state,
+ pulu_acca_state, pulu_accb_state,
+ pulu_dp_state,
+ pulu_ixl_state, pulu_ixh_state,
+ pulu_iyl_state, pulu_iyh_state,
+ pulu_spl_state, pulu_sph_state,
+ pulu_pcl_state, pulu_pch_state );
+
+ type st_type is (reset_st, push_st, idle_st );
+ type iv_type is (latch_iv, swi3_iv, swi2_iv, firq_iv, irq_iv, swi_iv, nmi_iv, reset_iv);
+ type addr_type is (idle_ad, fetch_ad, read_ad, write_ad, pushu_ad, pullu_ad, pushs_ad, pulls_ad, int_hi_ad, int_lo_ad );
+ type dout_type is (cc_dout, acca_dout, accb_dout, dp_dout,
+ ix_lo_dout, ix_hi_dout, iy_lo_dout, iy_hi_dout,
+ up_lo_dout, up_hi_dout, sp_lo_dout, sp_hi_dout,
+ pc_lo_dout, pc_hi_dout, md_lo_dout, md_hi_dout );
+ type op_type is (reset_op, fetch_op, latch_op );
+ type pre_type is (reset_pre, fetch_pre, latch_pre );
+ type cc_type is (reset_cc, load_cc, pull_cc, latch_cc );
+ 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 dp_type is (reset_dp, load_dp, pull_dp, latch_dp );
+ type ix_type is (reset_ix, load_ix, pull_lo_ix, pull_hi_ix, latch_ix );
+ type iy_type is (reset_iy, load_iy, pull_lo_iy, pull_hi_iy, latch_iy );
+ type sp_type is (reset_sp, latch_sp, load_sp, pull_hi_sp, pull_lo_sp );
+ type up_type is (reset_up, latch_up, load_up, pull_hi_up, pull_lo_up );
+ type pc_type is (reset_pc, latch_pc, load_pc, pull_lo_pc, pull_hi_pc, incr_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, load_ea, fetch_first_ea, fetch_next_ea );
+ type left_type is (cc_left, acca_left, accb_left, dp_left,
+ ix_left, iy_left, up_left, sp_left,
+ accd_left, md_left, pc_left, ea_left );
+ type right_type is (ea_right, zero_right, one_right, two_right,
+ acca_right, accb_right, accd_right,
+ md_right, md_sign5_right, md_sign8_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_lsr16, alu_lsl16,
+ alu_ror8, alu_rol8, alu_mul,
+ alu_asr8, alu_asl8, alu_lsr8,
+ alu_andcc, alu_orcc, alu_sex, alu_tfr, alu_abx,
+ alu_seif, alu_sei, alu_see, alu_cle,
+ alu_ld8, alu_st8, alu_ld16, alu_st16, alu_lea, alu_nop, alu_daa );
+
+ signal op_code: std_logic_vector(7 downto 0);
+ signal pre_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 dp: std_logic_vector(7 downto 0);
+ signal xreg: std_logic_vector(15 downto 0);
+ signal yreg: std_logic_vector(15 downto 0);
+ signal sp: std_logic_vector(15 downto 0);
+ signal up: 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(2 downto 0);
+ signal nmi_req: std_logic;
+ signal nmi_ack: std_logic;
+ signal nmi_enable: std_logic;
+ signal fic: std_logic; -- first instruction cycle
+ signal lic: std_logic; -- last instruction cycle
+
+ signal state: state_type;
+ signal next_state: state_type;
+ signal return_state: state_type;
+ signal saved_state: state_type;
+ signal st_ctrl: st_type;
+ signal iv_ctrl: iv_type;
+ signal pc_ctrl: pc_type;
+ signal ea_ctrl: ea_type;
+ signal op_ctrl: op_type;
+ signal pre_ctrl: pre_type;
+ signal md_ctrl: md_type;
+ signal acca_ctrl: acca_type;
+ signal accb_ctrl: accb_type;
+ signal ix_ctrl: ix_type;
+ signal iy_ctrl: iy_type;
+ signal cc_ctrl: cc_type;
+ signal dp_ctrl: dp_type;
+ signal sp_ctrl: sp_type;
+ signal up_ctrl: up_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;
+
+
+begin
+
+----------------------------------
+--
+-- State machine stack
+--
+----------------------------------
+--state_stack_proc: process( clk, hold, state_stack, st_ctrl,
+-- return_state, fetch_state )
+state_stack_proc: process( clk, st_ctrl, return_state )
+begin
+ if clk'event and clk = '0' then
+ if hold = '0' then
+ case st_ctrl is
+ when reset_st =>
+ saved_state <= fetch_state;
+ when push_st =>
+ saved_state <= return_state;
+ when others =>
+ null;
+ end case;
+ end if;
+ end if;
+end process;
+
+----------------------------------
+--
+-- Interrupt Vector control
+--
+----------------------------------
+--
+int_vec_proc: process( clk, iv_ctrl )
+begin
+ if clk'event and clk = '0' then
+ if hold = '0' then
+ case iv_ctrl is
+ when reset_iv =>
+ iv <= RST_VEC;
+ when nmi_iv =>
+ iv <= NMI_VEC;
+ when swi_iv =>
+ iv <= SWI_VEC;
+ when irq_iv =>
+ iv <= IRQ_VEC;
+ when firq_iv =>
+ iv <= FIRQ_VEC;
+ when swi2_iv =>
+ iv <= SWI2_VEC;
+ when swi3_iv =>
+ iv <= SWI3_VEC;
+ when others =>
+ null;
+ end case;
+ end if; -- hold
+ end if; -- clk
+end process;
+
+----------------------------------
+--
+-- Program Counter Control
+--
+----------------------------------
+
+--pc_reg: process( clk, pc_ctrl, hold, pc, out_alu, data_in )
+pc_reg: process( clk )
+begin
+ if clk'event and clk = '0' then
+ if hold = '0' then
+ case pc_ctrl is
+ when reset_pc =>
+ pc <= (others=>'0');
+ when load_pc =>
+ pc <= out_alu(15 downto 0);
+ when pull_lo_pc =>
+ pc(7 downto 0) <= data_in;
+ when pull_hi_pc =>
+ pc(15 downto 8) <= data_in;
+ when incr_pc =>
+ pc <= pc + 1;
+ when others =>
+ null;
+ end case;
+ end if;
+ end if;
+end process;
+
+----------------------------------
+--
+-- Effective Address Control
+--
+----------------------------------
+
+--ea_reg: process( clk, ea_ctrl, hold, ea, out_alu, data_in, dp )
+ea_reg: process( clk )
+begin
+
+ if clk'event and clk = '0' then
+ if hold= '0' then
+ case ea_ctrl is
+ when reset_ea =>
+ ea <= (others=>'0');
+ when fetch_first_ea =>
+ ea(7 downto 0) <= data_in;
+ ea(15 downto 8) <= dp;
+ when fetch_next_ea =>
+ ea(15 downto 8) <= ea(7 downto 0);
+ ea(7 downto 0) <= data_in;
+ when load_ea =>
+ ea <= out_alu(15 downto 0);
+ when others =>
+ null;
+ end case;
+ end if;
+ end if;
+end process;
+
+--------------------------------
+--
+-- Accumulator A
+--
+--------------------------------
+--acca_reg : process( clk, acca_ctrl, hold, out_alu, acca, data_in )
+acca_reg : process( clk )
+begin
+ if clk'event and clk = '0' then
+ if hold = '0' then
+ case acca_ctrl is
+ when reset_acca =>
+ acca <= (others=>'0');
+ 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 =>
+ null;
+ end case;
+ end if;
+ end if;
+end process;
+
+--------------------------------
+--
+-- Accumulator B
+--
+--------------------------------
+--accb_reg : process( clk, accb_ctrl, hold, out_alu, accb, data_in )
+accb_reg : process( clk )
+begin
+ if clk'event and clk = '0' then
+ if hold = '0' then
+ case accb_ctrl is
+ when reset_accb =>
+ accb <= (others=>'0');
+ when load_accb =>
+ accb <= out_alu(7 downto 0);
+ when pull_accb =>
+ accb <= data_in;
+ when others =>
+ null;
+ end case;
+ end if;
+ end if;
+end process;
+
+--------------------------------
+--
+-- X Index register
+--
+--------------------------------
+--ix_reg : process( clk, ix_ctrl, hold, out_alu, xreg, data_in )
+ix_reg : process( clk )
+begin
+ if clk'event and clk = '0' then
+ if hold = '0' then
+ case ix_ctrl is
+ when reset_ix =>
+ xreg <= (others=>'0');
+ 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 =>
+ null;
+ end case;
+ end if;
+ end if;
+end process;
+
+--------------------------------
+--
+-- Y Index register
+--
+--------------------------------
+--iy_reg : process( clk, iy_ctrl, hold, out_alu, yreg, data_in )
+iy_reg : process( clk )
+begin
+ if clk'event and clk = '0' then
+ if hold = '0' then
+ case iy_ctrl is
+ when reset_iy =>
+ yreg <= (others=>'0');
+ when load_iy =>
+ yreg <= out_alu(15 downto 0);
+ when pull_hi_iy =>
+ yreg(15 downto 8) <= data_in;
+ when pull_lo_iy =>
+ yreg(7 downto 0) <= data_in;
+ when others =>
+ null;
+ end case;
+ end if;
+ end if;
+end process;
+
+--------------------------------
+--
+-- S stack pointer
+--
+--------------------------------
+--sp_reg : process( clk, sp_ctrl, hold, sp, out_alu, data_in, nmi_enable )
+sp_reg : process( clk )
+begin
+ if clk'event and clk = '0' then
+ if hold = '0' then
+ case sp_ctrl is
+ when reset_sp =>
+ sp <= (others=>'0');
+ nmi_enable <= '0';
+ when load_sp =>
+ sp <= out_alu(15 downto 0);
+ nmi_enable <= '1';
+ when pull_hi_sp =>
+ sp(15 downto 8) <= data_in;
+ when pull_lo_sp =>
+ sp(7 downto 0) <= data_in;
+ nmi_enable <= '1';
+ when others =>
+ null;
+ end case;
+ end if;
+ end if;
+end process;
+
+--------------------------------
+--
+-- U stack pointer
+--
+--------------------------------
+--up_reg : process( clk, up_ctrl, hold, up, out_alu, data_in )
+up_reg : process( clk )
+begin
+ if clk'event and clk = '0' then
+ if hold = '0' then
+ case up_ctrl is
+ when reset_up =>
+ up <= (others=>'0');
+ when load_up =>
+ up <= out_alu(15 downto 0);
+ when pull_hi_up =>
+ up(15 downto 8) <= data_in;
+ when pull_lo_up =>
+ up(7 downto 0) <= data_in;
+ when others =>
+ null;
+ end case;
+ end if;
+ end if;
+end process;
+
+--------------------------------
+--
+-- Memory Data
+--
+--------------------------------
+--md_reg : process( clk, md_ctrl, hold, out_alu, data_in, md )
+md_reg : process( clk )
+begin
+ if clk'event and clk = '0' then
+ if hold = '0' then
+ case md_ctrl is
+ when reset_md =>
+ md <= (others=>'0');
+ when load_md =>
+ md <= out_alu(15 downto 0);
+ when fetch_first_md => -- sign extend md for branches
+ md(15 downto 8) <= data_in(7) & data_in(7) & data_in(7) & data_in(7) &
+ data_in(7) & data_in(7) & data_in(7) & data_in(7) ;
+ 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 =>
+ null;
+ end case;
+ end if;
+ end if;
+end process;
+
+
+----------------------------------
+--
+-- Condition Codes
+--
+----------------------------------
+
+--cc_reg: process( clk, cc_ctrl, hold, cc_out, cc, data_in )
+cc_reg: process( clk )
+begin
+ if clk'event and clk = '0' then
+ if hold = '0' then
+ case cc_ctrl is
+ when reset_cc =>
+ cc <= "11010000"; -- set EBIT, FBIT & IBIT
+ when load_cc =>
+ cc <= cc_out;
+ when pull_cc =>
+ cc <= data_in;
+ when others =>
+ null;
+ end case;
+ end if;
+ end if;
+end process;
+
+----------------------------------
+--
+-- Direct Page register
+--
+----------------------------------
+
+--dp_reg: process( clk, dp_ctrl, hold, out_alu, dp, data_in )
+dp_reg: process( clk )
+begin
+ if clk'event and clk = '0' then
+ if hold = '0' then
+ case dp_ctrl is
+ when reset_dp =>
+ dp <= (others=>'0');
+ when load_dp =>
+ dp <= out_alu(7 downto 0);
+ when pull_dp =>
+ dp <= data_in;
+ when others =>
+ null;
+ end case;
+ end if;
+ end if;
+end process;
+
+
+----------------------------------
+--
+-- op code register
+--
+----------------------------------
+
+--op_reg: process( clk, op_ctrl, hold, op_code, data_in )
+op_reg: process( clk )
+begin
+ if clk'event and clk = '0' then
+ if hold = '0' then
+ case op_ctrl is
+ when reset_op =>
+ op_code <= "00010010";
+ when fetch_op =>
+ op_code <= data_in;
+ when others =>
+ null;
+ end case;
+ end if;
+ end if;
+end process;
+
+
+----------------------------------
+--
+-- pre byte op code register
+--
+----------------------------------
+
+--pre_reg: process( clk, pre_ctrl, hold, pre_code, data_in )
+pre_reg: process( clk )
+begin
+ if clk'event and clk = '0' then
+ if hold = '0' then
+ case pre_ctrl is
+ when reset_pre =>
+ pre_code <= (others=>'0');
+ when fetch_pre =>
+ pre_code <= data_in;
+ when others =>
+ null;
+ end case;
+ end if;
+ end if;
+end process;
+
+--------------------------------
+--
+-- state machine
+--
+--------------------------------
+
+--change_state: process( clk, rst, state, hold, next_state )
+change_state: process( clk )
+begin
+ if clk'event and clk = '0' then
+ if rst = '1' then
+ fic <= '0';
+ nmi_ack <= '0';
+ state <= reset_state;
+ elsif hold = '0' then
+ fic <= lic;
+ --
+ -- nmi request is not cleared until nmi input goes low
+ --
+ if (nmi_req = '0') and (nmi_ack='1') then
+ nmi_ack <= '0';
+ end if;
+
+ if (nmi_req = '1') and (nmi_ack = '0') and (state = int_nmimask_state) then
+ nmi_ack <= '1';
+ end if;
+
+ if lic = '1' then
+ if halt = '1' then
+ state <= halt_state;
+
+ -- service non maskable interrupts
+ elsif (nmi_req = '1') and (nmi_ack = '0') then
+ state <= int_nmi_state;
+ --
+ -- FIRQ & IRQ are level sensitive
+ --
+ elsif (firq = '1') and (cc(FBIT) = '0') then
+ state <= int_firq_state;
+
+ elsif (irq = '1') and (cc(IBIT) = '0') then
+ state <= int_irq_state;
+ --
+ -- Version 1.27 2015-05-30
+ -- Exit sync_state on masked interrupt.
+ --
+ -- Version 1.28 2015-05-30
+ -- Move this code to the state sequencer
+ -- near line 5566.
+ --
+ -- elsif (state = sync_state) and ((firq = '1') or (irq = '1'))then
+ -- state <= fetch_state;
+ --
+ else
+ state <= next_state;
+ end if; -- halt, nmi, firq, irq
+ else
+ state <= next_state;
+ end if; -- lic
+ end if; -- reset/hold
+ end if; -- clk
+end process;
+
+------------------------------------
+--
+-- Detect Edge of NMI interrupt
+--
+------------------------------------
+
+--nmi_handler : process( clk, rst, nmi, nmi_ack, nmi_req, nmi_enable )
+nmi_handler : process( rst, clk )
+begin
+ if rst='1' then
+ nmi_req <= '0';
+ elsif clk'event and clk='0' then
+ if (nmi='1') and (nmi_ack='0') and (nmi_enable='1') then
+ nmi_req <= '1';
+ else
+ if (nmi='0') and (nmi_ack='1') then
+ nmi_req <= '0';
+ end if;
+ end if;
+ end if;
+end process;
+
+
+----------------------------------
+--
+-- Address output multiplexer
+--
+----------------------------------
+
+addr_mux: process( addr_ctrl, pc, ea, up, sp, iv )
+begin
+ ifetch <= '0';
+ vma <= '1';
+ case addr_ctrl is
+ when fetch_ad =>
+ addr <= pc;
+ rw <= '1';
+ ifetch <= '1';
+ when read_ad =>
+ addr <= ea;
+ rw <= '1';
+ when write_ad =>
+ addr <= ea;
+ rw <= '0';
+ when pushs_ad =>
+ addr <= sp;
+ rw <= '0';
+ when pulls_ad =>
+ addr <= sp;
+ rw <= '1';
+ when pushu_ad =>
+ addr <= up;
+ rw <= '0';
+ when pullu_ad =>
+ addr <= up;
+ rw <= '1';
+ when int_hi_ad =>
+ addr <= "111111111111" & iv & "0";
+ rw <= '1';
+ when int_lo_ad =>
+ addr <= "111111111111" & iv & "1";
+ rw <= '1';
+ when others =>
+ addr <= "1111111111111111";
+ rw <= '1';
+ vma <= '0';
+ end case;
+end process;
+
+--------------------------------
+--
+-- Data Bus output
+--
+--------------------------------
+dout_mux : process( dout_ctrl, md, acca, accb, dp, xreg, yreg, sp, up, pc, cc )
+begin
+ case dout_ctrl is
+ when cc_dout => -- condition code register
+ data_out <= cc;
+ when acca_dout => -- accumulator a
+ data_out <= acca;
+ when accb_dout => -- accumulator b
+ data_out <= accb;
+ when dp_dout => -- direct page register
+ data_out <= dp;
+ when ix_lo_dout => -- X index reg
+ data_out <= xreg(7 downto 0);
+ when ix_hi_dout => -- X index reg
+ data_out <= xreg(15 downto 8);
+ when iy_lo_dout => -- Y index reg
+ data_out <= yreg(7 downto 0);
+ when iy_hi_dout => -- Y index reg
+ data_out <= yreg(15 downto 8);
+ when up_lo_dout => -- U stack pointer
+ data_out <= up(7 downto 0);
+ when up_hi_dout => -- U stack pointer
+ data_out <= up(15 downto 8);
+ when sp_lo_dout => -- S stack pointer
+ data_out <= sp(7 downto 0);
+ when sp_hi_dout => -- S stack pointer
+ data_out <= sp(15 downto 8);
+ when md_lo_dout => -- alu output
+ data_out <= md(7 downto 0);
+ when md_hi_dout => -- alu output
+ data_out <= md(15 downto 8);
+ 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);
+ end case;
+end process;
+
+----------------------------------
+--
+-- Left Mux
+--
+----------------------------------
+
+left_mux: process( left_ctrl, acca, accb, cc, dp, xreg, yreg, up, sp, pc, ea, md )
+begin
+ case left_ctrl is
+ when cc_left =>
+ left(15 downto 8) <= "00000000";
+ left(7 downto 0) <= cc;
+ 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 dp_left =>
+ left(15 downto 8) <= "00000000";
+ left(7 downto 0) <= dp;
+ when accd_left =>
+ left(15 downto 8) <= acca;
+ left(7 downto 0) <= accb;
+ when md_left =>
+ left <= md;
+ when ix_left =>
+ left <= xreg;
+ when iy_left =>
+ left <= yreg;
+ when sp_left =>
+ left <= sp;
+ when up_left =>
+ left <= up;
+ when pc_left =>
+ left <= pc;
+ when others =>
+-- when ea_left =>
+ left <= ea;
+ end case;
+end process;
+
+----------------------------------
+--
+-- Right Mux
+--
+----------------------------------
+
+right_mux: process( right_ctrl, md, acca, accb, ea )
+begin
+ case right_ctrl is
+ when ea_right =>
+ right <= ea;
+ when zero_right =>
+ right <= "0000000000000000";
+ when one_right =>
+ right <= "0000000000000001";
+ when two_right =>
+ right <= "0000000000000010";
+ when acca_right =>
+ if acca(7) = '0' then
+ right <= "00000000" & acca(7 downto 0);
+ else
+ right <= "11111111" & acca(7 downto 0);
+ end if;
+ when accb_right =>
+ if accb(7) = '0' then
+ right <= "00000000" & accb(7 downto 0);
+ else
+ right <= "11111111" & accb(7 downto 0);
+ end if;
+ when accd_right =>
+ right <= acca & accb;
+ when md_sign5_right =>
+ if md(4) = '0' then
+ right <= "00000000000" & md(4 downto 0);
+ else
+ right <= "11111111111" & md(4 downto 0);
+ end if;
+ when md_sign8_right =>
+ if md(7) = '0' then
+ right <= "00000000" & md(7 downto 0);
+ else
+ right <= "11111111" & md(7 downto 0);
+ end if;
+ when others =>
+-- when md_right =>
+ right <= md;
+ end case;
+end process;
+
+----------------------------------
+--
+-- Arithmetic Logic Unit
+--
+----------------------------------
+
+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 alu_asr8 =>
+ carry_in := left(7);
+ when others =>
+ carry_in := '0';
+ end case;
+
+ valid_lo := left(3 downto 0) <= 9;
+ valid_hi := left(7 downto 4) <= 9;
+
+ --
+ -- CBIT HBIT VHI VLO DAA
+ -- 0 0 0 0 66 (!VHI : hi_nybble>8)
+ -- 0 0 0 1 60
+ -- 0 0 1 1 00
+ -- 0 0 1 0 06 ( VHI : hi_nybble<=8)
+ --
+ -- 0 1 1 0 06
+ -- 0 1 1 1 06
+ -- 0 1 0 1 66
+ -- 0 1 0 0 66
+ --
+ -- 1 1 0 0 66
+ -- 1 1 0 1 66
+ -- 1 1 1 1 66
+ -- 1 1 1 0 66
+ --
+ -- 1 0 1 0 66
+ -- 1 0 1 1 60
+ -- 1 0 0 1 60
+ -- 1 0 0 0 66
+ --
+ -- 66 = (!VHI & !VLO) + (CBIT & HBIT) + (HBIT & !VHI) + (CBIT & !VLO)
+ -- = (CBIT & (HBIT + !VLO)) + (!VHI & (HBIT + !VLO))
+ -- = (!VLO & (CBIT + !VHI)) + (HBIT & (CBIT + !VHI))
+ -- 60 = (CBIT & !HBIT & VLO) + (!HBIT & !VHI & VLO)
+ -- = (!HBIT & VLO & (CBIT + !VHI))
+ -- 06 = (!CBIT & VHI & (!VLO + VHI)
+ -- 00 = (!CBIT & !HBIT & VHI & VLO)
+ --
+ if (cc(CBIT) = '0') then
+ -- CBIT=0
+ if( cc(HBIT) = '0' ) then
+ -- HBIT=0
+ if valid_lo then
+ -- lo <= 9 (no overflow in low nybble)
+ if valid_hi then
+ -- hi <= 9 (no overflow in either low or high nybble)
+ daa_reg := "00000000";
+ else
+ -- hi > 9 (overflow in high nybble only)
+ daa_reg := "01100000";
+ end if;
+ else
+ -- lo > 9 (overflow in low nybble)
+ --
+ -- since there is already an overflow in the low nybble
+ -- you need to make room in the high nybble for the low nybble carry
+ -- so compare the high nybble with 8 rather than 9
+ -- if the high nybble is 9 there will be an overflow on the high nybble
+ -- after the decimal adjust which means it will roll over to an invalid BCD digit
+ --
+ if( left(7 downto 4) <= 8 ) then
+ -- hi <= 8 (overflow in low nybble only)
+ daa_reg := "00000110";
+ else
+ -- hi > 8 (overflow in low and high nybble)
+ daa_reg := "01100110";
+ end if;
+ end if;
+ else
+ -- HBIT=1 (overflow in low nybble)
+ if valid_hi then
+ -- hi <= 9 (overflow in low nybble only)
+ daa_reg := "00000110";
+ else
+ -- hi > 9 (overflow in low and high nybble)
+ daa_reg := "01100110";
+ end if;
+ end if;
+ else
+ -- CBIT=1 (carry => overflow in high nybble)
+ if ( cc(HBIT) = '0' )then
+ -- HBIT=0 (half carry clear => may or may not be an overflow in the low nybble)
+ if valid_lo then
+ -- lo <=9 (overflow in high nybble only)
+ daa_reg := "01100000";
+ else
+ -- lo >9 (overflow in low and high nybble)
+ daa_reg := "01100110";
+ end if;
+ else
+ -- HBIT=1 (overflow in low and high nybble)
+ daa_reg := "01100110";
+ end if;
+ end if;
+
+ case alu_ctrl is
+ when alu_add8 | alu_inc |
+ alu_add16 | alu_adc | alu_mul =>
+ out_alu <= left + right + ("000000000000000" & carry_in);
+ when alu_sub8 | alu_dec |
+ alu_sub16 | alu_sbc =>
+ out_alu <= left - right - ("000000000000000" & carry_in);
+ when alu_abx =>
+ out_alu <= left + ("00000000" & right(7 downto 0)) ;
+ 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 =>
+ out_alu <= carry_in & left(15 downto 1); -- lsr16
+ when alu_lsr8 | alu_asr8 | alu_ror8 =>
+ out_alu <= "00000000" & carry_in & left(7 downto 1); -- ror8/asr8/lsr8
+ when alu_neg =>
+ out_alu <= right - left; -- neg (right=0)
+ when alu_com =>
+ out_alu <= not left;
+ when alu_clr | alu_ld8 | alu_ld16 | alu_lea =>
+ out_alu <= right; -- clr, ld
+ when alu_st8 | alu_st16 | alu_andcc | alu_orcc | alu_tfr =>
+ out_alu <= left;
+ when alu_daa =>
+ out_alu <= left + ("00000000" & daa_reg);
+ when alu_sex =>
+ if left(7) = '0' then
+ out_alu <= "00000000" & left(7 downto 0);
+ else
+ out_alu <= "11111111" & left(7 downto 0);
+ end if;
+ 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_mul =>
+ cc_out(CBIT) <= out_alu(7);
+ when alu_daa =>
+ if ( daa_reg(7 downto 4) = "0110" ) then
+ cc_out(CBIT) <= '1';
+ else
+ cc_out(CBIT) <= '0';
+ end if;
+ when alu_andcc =>
+ cc_out(CBIT) <= left(CBIT) and cc(CBIT);
+ when alu_orcc =>
+ cc_out(CBIT) <= left(CBIT) or cc(CBIT);
+ when alu_tfr =>
+ cc_out(CBIT) <= left(CBIT);
+ when others =>
+ 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 | alu_sex | alu_daa =>
+ 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_mul |
+ alu_lsl16 | alu_lsr16 |
+ alu_ld16 | alu_st16 | alu_lea =>
+ 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_andcc =>
+ cc_out(ZBIT) <= left(ZBIT) and cc(ZBIT);
+ when alu_orcc =>
+ cc_out(ZBIT) <= left(ZBIT) or cc(ZBIT);
+ when alu_tfr =>
+ 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 | alu_sex | alu_daa =>
+ cc_out(NBIT) <= out_alu(7);
+ when alu_add16 | alu_sub16 |
+ alu_lsl16 | alu_lsr16 |
+ alu_ld16 | alu_st16 =>
+ cc_out(NBIT) <= out_alu(15);
+ when alu_andcc =>
+ cc_out(NBIT) <= left(NBIT) and cc(NBIT);
+ when alu_orcc =>
+ cc_out(NBIT) <= left(NBIT) or cc(NBIT);
+ when alu_tfr =>
+ cc_out(NBIT) <= left(NBIT);
+ when others =>
+ cc_out(NBIT) <= cc(NBIT);
+ end case;
+
+ --
+ -- Interrupt mask flag
+ --
+ case alu_ctrl is
+ when alu_andcc =>
+ cc_out(IBIT) <= left(IBIT) and cc(IBIT);
+ when alu_orcc =>
+ cc_out(IBIT) <= left(IBIT) or cc(IBIT);
+ when alu_tfr =>
+ cc_out(IBIT) <= left(IBIT);
+ when alu_seif | alu_sei =>
+ cc_out(IBIT) <= '1';
+ 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_andcc =>
+ cc_out(HBIT) <= left(HBIT) and cc(HBIT);
+ when alu_orcc =>
+ cc_out(HBIT) <= left(HBIT) or cc(HBIT);
+ when alu_tfr =>
+ 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 =>
+ 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)));
+-- 6809 Programming reference manual says
+-- V not affected by ASR, LSR and ROR
+-- This is different to the 6800
+-- John Kent 6th June 2006
+-- 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);
+--
+-- 11th July 2006 - John Kent
+-- What DAA does with V is anyones guess
+-- It is undefined in the 6809 programming manual
+--
+ when alu_daa =>
+ cc_out(VBIT) <= left(7) xor out_alu(7) xor cc(CBIT);
+-- CLR resets V Bit
+-- John Kent 6th June 2006
+ when alu_and | alu_ora | alu_eor | alu_com | alu_clr |
+ alu_st8 | alu_st16 | alu_ld8 | alu_ld16 | alu_sex =>
+ cc_out(VBIT) <= '0';
+ when alu_andcc =>
+ cc_out(VBIT) <= left(VBIT) and cc(VBIT);
+ when alu_orcc =>
+ cc_out(VBIT) <= left(VBIT) or cc(VBIT);
+ when alu_tfr =>
+ cc_out(VBIT) <= left(VBIT);
+ when others =>
+ cc_out(VBIT) <= cc(VBIT);
+ end case;
+
+ case alu_ctrl is
+ when alu_andcc =>
+ cc_out(FBIT) <= left(FBIT) and cc(FBIT);
+ when alu_orcc =>
+ cc_out(FBIT) <= left(FBIT) or cc(FBIT);
+ when alu_tfr =>
+ cc_out(FBIT) <= left(FBIT);
+ when alu_seif =>
+ cc_out(FBIT) <= '1';
+ when others =>
+ cc_out(FBIT) <= cc(FBIT);
+ end case;
+
+ case alu_ctrl is
+ when alu_andcc =>
+ cc_out(EBIT) <= left(EBIT) and cc(EBIT);
+ when alu_orcc =>
+ cc_out(EBIT) <= left(EBIT) or cc(EBIT);
+ when alu_tfr =>
+ cc_out(EBIT) <= left(EBIT);
+ when alu_see =>
+ cc_out(EBIT) <= '1';
+ when alu_cle =>
+ cc_out(EBIT) <= '0';
+ when others =>
+ cc_out(EBIT) <= cc(EBIT);
+ end case;
+end process;
+
+------------------------------------
+--
+-- state sequencer
+--
+------------------------------------
+process( state, saved_state,
+ op_code, pre_code,
+ cc, ea, md, iv, fic, halt,
+ nmi_req, firq, irq, lic )
+variable cond_true : boolean; -- variable used to evaluate coditional branches
+begin
+ cond_true := (1=1);
+ ba <= '0';
+ bs <= '0';
+ lic <= '0';
+ opfetch <= '0';
+ iv_ctrl <= latch_iv;
+ -- Registers preserved
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ ea_ctrl <= latch_ea;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ -- ALU Idle
+ left_ctrl <= pc_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ -- Bus idle
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= cc_dout;
+ -- Next State Fetch
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= fetch_state;
+
+ case state is
+ when reset_state => -- released from reset
+ -- reset the registers
+ iv_ctrl <= reset_iv;
+ op_ctrl <= reset_op;
+ pre_ctrl <= reset_pre;
+ cc_ctrl <= reset_cc;
+ acca_ctrl <= reset_acca;
+ accb_ctrl <= reset_accb;
+ dp_ctrl <= reset_dp;
+ ix_ctrl <= reset_ix;
+ iy_ctrl <= reset_iy;
+ up_ctrl <= reset_up;
+ sp_ctrl <= reset_sp;
+ pc_ctrl <= reset_pc;
+ ea_ctrl <= reset_ea;
+ md_ctrl <= reset_md;
+ st_ctrl <= reset_st;
+ next_state <= vect_hi_state;
+
+ --
+ -- Jump via interrupt vector
+ -- iv holds interrupt type
+ -- fetch PC hi from vector location
+ --
+ when vect_hi_state =>
+ -- fetch pc low interrupt vector
+ pc_ctrl <= pull_hi_pc;
+ addr_ctrl <= int_hi_ad;
+ bs <= '1';
+ next_state <= vect_lo_state;
+
+ --
+ -- jump via interrupt vector
+ -- iv holds vector type
+ -- fetch PC lo from vector location
+ --
+ when vect_lo_state =>
+ -- fetch the vector low byte
+ pc_ctrl <= pull_lo_pc;
+ addr_ctrl <= int_lo_ad;
+ bs <= '1';
+ next_state <= fetch_state;
+
+ when vect_idle_state =>
+ --
+ -- Last Instruction Cycle for SWI, SWI2 & SWI3
+ --
+ if op_code = "00111111" then
+ lic <= '1';
+ end if;
+ next_state <= fetch_state;
+
+ --
+ -- Here to fetch an instruction
+ -- PC points to opcode
+ --
+ when fetch_state =>
+ -- fetch the op code
+ opfetch <= '1';
+ op_ctrl <= fetch_op;
+ pre_ctrl <= fetch_pre;
+ ea_ctrl <= reset_ea;
+ -- Fetch op code
+ addr_ctrl <= fetch_ad;
+ -- Advance the PC to fetch next instruction byte
+ pc_ctrl <= incr_pc;
+ next_state <= decode1_state;
+
+ --
+ -- Here to decode instruction
+ -- and fetch next byte of intruction
+ -- whether it be necessary or not
+ --
+ when decode1_state =>
+ -- fetch first byte of address or immediate data
+ ea_ctrl <= fetch_first_ea;
+ md_ctrl <= fetch_first_md;
+ addr_ctrl <= fetch_ad;
+ case op_code(7 downto 4) is
+ --
+ -- direct single op (2 bytes)
+ -- 6809 => 6 cycles
+ -- cpu09 => 5 cycles
+ -- 1 op=(pc) / pc=pc+1
+ -- 2 ea_hi=dp / ea_lo=(pc) / pc=pc+1
+ -- 3 md_lo=(ea) / pc=pc
+ -- 4 alu_left=md / md=alu_out / pc=pc
+ -- 5 (ea)=md_lo / pc=pc
+ --
+ -- Exception is JMP
+ -- 6809 => 3 cycles
+ -- cpu09 => 3 cycles
+ -- 1 op=(pc) / pc=pc+1
+ -- 2 ea_hi=dp / ea_lo=(pc) / pc=pc+1
+ -- 3 pc=ea
+ --
+ when "0000" =>
+ -- advance the PC
+ pc_ctrl <= incr_pc;
+
+ case op_code(3 downto 0) is
+ when "1110" => -- jmp
+ next_state <= jmp_state;
+
+ when "1111" => -- clr
+ next_state <= single_op_exec_state;
+
+ when others =>
+ next_state <= single_op_read_state;
+
+ end case;
+
+ -- acca / accb inherent instructions
+ when "0001" =>
+ case op_code(3 downto 0) is
+ --
+ -- Page2 pre byte
+ -- pre=(pc) / pc=pc+1
+ -- op=(pc) / pc=pc+1
+ --
+ when "0000" => -- page2
+ opfetch <= '1';
+ op_ctrl <= fetch_op;
+ -- advance pc
+ pc_ctrl <= incr_pc;
+ next_state <= decode2_state;
+
+ --
+ -- Page3 pre byte
+ -- pre=(pc) / pc=pc+1
+ -- op=(pc) / pc=pc+1
+ --
+ when "0001" => -- page3
+ opfetch <= '1';
+ op_ctrl <= fetch_op;
+ -- advance pc
+ pc_ctrl <= incr_pc;
+ next_state <= decode3_state;
+
+ --
+ -- nop - No operation ( 1 byte )
+ -- 6809 => 2 cycles
+ -- cpu09 => 2 cycles
+ -- 1 op=(pc) / pc=pc+1
+ -- 2 decode
+ --
+ when "0010" => -- nop
+ lic <= '1';
+ next_state <= fetch_state;
+
+ --
+ -- sync - halt execution until an interrupt is received
+ -- interrupt may be NMI, IRQ or FIRQ
+ -- program execution continues if the
+ -- interrupt is asserted for 3 clock cycles
+ -- note that registers are not pushed onto the stack
+ -- CPU09 => Interrupts need only be asserted for one clock cycle
+ --
+ when "0011" => -- sync
+ next_state <= sync_state;
+
+ --
+ -- lbra -- long branch (3 bytes)
+ -- 6809 => 5 cycles
+ -- cpu09 => 4 cycles
+ -- 1 op=(pc) / pc=pc+1
+ -- 2 md_hi=sign(pc) / md_lo=(pc) / pc=pc+1
+ -- 3 md_hi=md_lo / md_lo=(pc) / pc=pc+1
+ -- 4 pc=pc+md
+ --
+ when "0110" =>
+ -- increment the pc
+ pc_ctrl <= incr_pc;
+ next_state <= lbranch_state;
+
+ --
+ -- lbsr - long branch to subroutine (3 bytes)
+ -- 6809 => 9 cycles
+ -- cpu09 => 6 cycles
+ -- 1 op=(pc) /pc=pc+1
+ -- 2 md_hi=sign(pc) / md_lo=(pc) / pc=pc+1 / sp=sp-1
+ -- 3 md_hi=md_lo / md_lo=(pc) / pc=pc+1
+ -- 4 (sp)= pc_lo / sp=sp-1 / pc=pc
+ -- 5 (sp)=pc_hi / pc=pc
+ -- 6 pc=pc+md
+ --
+ when "0111" =>
+ -- pre decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ -- increment the pc
+ pc_ctrl <= incr_pc;
+ next_state <= lbranch_state;
+
+ --
+ -- Decimal Adjust Accumulator
+ --
+ when "1001" => -- daa
+ left_ctrl <= acca_left;
+ right_ctrl <= accb_right;
+ alu_ctrl <= alu_daa;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_acca;
+ lic <= '1';
+ next_state <= fetch_state;
+
+ --
+ -- OR Condition Codes
+ --
+ when "1010" => -- orcc
+ -- increment the pc
+ pc_ctrl <= incr_pc;
+ next_state <= orcc_state;
+
+ --
+ -- AND Condition Codes
+ --
+ when "1100" => -- andcc
+ -- increment the pc
+ pc_ctrl <= incr_pc;
+ next_state <= andcc_state;
+
+ --
+ -- Sign Extend
+ --
+ when "1101" => -- sex
+ left_ctrl <= accb_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_sex;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_hi_acca;
+ lic <= '1';
+ next_state <= fetch_state;
+
+ --
+ -- Exchange Registers
+ --
+ when "1110" => -- exg
+ -- increment the pc
+ pc_ctrl <= incr_pc;
+ next_state <= exg_state;
+
+ --
+ -- Transfer Registers
+ --
+ when "1111" => -- tfr
+ -- increment the pc
+ pc_ctrl <= incr_pc;
+ next_state <= tfr_state;
+
+ when others =>
+ -- increment the pc
+ pc_ctrl <= incr_pc;
+ lic <= '1';
+ next_state <= fetch_state;
+ end case;
+
+ --
+ -- Short branch conditional
+ -- 6809 => always 3 cycles
+ -- cpu09 => always = 3 cycles
+ -- 1 op=(pc) / pc=pc+1
+ -- 2 md_hi=sign(pc) / md_lo=(pc) / pc=pc+1 / test cc
+ -- 3 if cc tru pc=pc+md else pc=pc
+ --
+ when "0010" => -- branch conditional
+ -- increment the pc
+ pc_ctrl <= incr_pc;
+ next_state <= sbranch_state;
+
+ --
+ -- Single byte stack operators
+ -- Do not advance PC
+ --
+ when "0011" =>
+ --
+ -- lea - load effective address (2+ bytes)
+ -- 6809 => 4 cycles + addressing mode
+ -- cpu09 => 4 cycles + addressing mode
+ -- 1 op=(pc) / pc=pc+1
+ -- 2 md_lo=(pc) / pc=pc+1
+ -- 3 calculate ea
+ -- 4 ix/iy/sp/up = ea
+ --
+ case op_code(3 downto 0) is
+ when "0000" | -- leax
+ "0001" | -- leay
+ "0010" | -- leas
+ "0011" => -- leau
+ -- advance PC
+ pc_ctrl <= incr_pc;
+ st_ctrl <= push_st;
+ return_state <= lea_state;
+ next_state <= indexed_state;
+
+ --
+ -- pshs - push registers onto sp stack
+ -- 6809 => 5 cycles + registers
+ -- cpu09 => 3 cycles + registers
+ -- 1 op=(pc) / pc=pc+1
+ -- 2 ea_lo=(pc) / pc=pc+1
+ -- 3 if ea(7 downto 0) != "00000000" then sp=sp-1
+ -- 4 if ea(7) = 1 (sp)=pcl, sp=sp-1
+ -- 5 if ea(7) = 1 (sp)=pch
+ -- if ea(6 downto 0) != "0000000" then sp=sp-1
+ -- 6 if ea(6) = 1 (sp)=upl, sp=sp-1
+ -- 7 if ea(6) = 1 (sp)=uph
+ -- if ea(5 downto 0) != "000000" then sp=sp-1
+ -- 8 if ea(5) = 1 (sp)=iyl, sp=sp-1
+ -- 9 if ea(5) = 1 (sp)=iyh
+ -- if ea(4 downto 0) != "00000" then sp=sp-1
+ -- 10 if ea(4) = 1 (sp)=ixl, sp=sp-1
+ -- 11 if ea(4) = 1 (sp)=ixh
+ -- if ea(3 downto 0) != "0000" then sp=sp-1
+ -- 12 if ea(3) = 1 (sp)=dp
+ -- if ea(2 downto 0) != "000" then sp=sp-1
+ -- 13 if ea(2) = 1 (sp)=accb
+ -- if ea(1 downto 0) != "00" then sp=sp-1
+ -- 14 if ea(1) = 1 (sp)=acca
+ -- if ea(0 downto 0) != "0" then sp=sp-1
+ -- 15 if ea(0) = 1 (sp)=cc
+ --
+ when "0100" => -- pshs
+ -- advance PC
+ pc_ctrl <= incr_pc;
+ next_state <= pshs_state;
+
+ --
+ -- puls - pull registers of sp stack
+ -- 6809 => 5 cycles + registers
+ -- cpu09 => 3 cycles + registers
+ --
+ when "0101" => -- puls
+ -- advance PC
+ pc_ctrl <= incr_pc;
+ next_state <= puls_state;
+
+ --
+ -- pshu - push registers onto up stack
+ -- 6809 => 5 cycles + registers
+ -- cpu09 => 3 cycles + registers
+ --
+ when "0110" => -- pshu
+ -- advance PC
+ pc_ctrl <= incr_pc;
+ next_state <= pshu_state;
+
+ --
+ -- pulu - pull registers of up stack
+ -- 6809 => 5 cycles + registers
+ -- cpu09 => 3 cycles + registers
+ --
+ when "0111" => -- pulu
+ -- advance PC
+ pc_ctrl <= incr_pc;
+ next_state <= pulu_state;
+
+ --
+ -- rts - return from subroutine
+ -- 6809 => 5 cycles
+ -- cpu09 => 4 cycles
+ -- 1 op=(pc) / pc=pc+1
+ -- 2 decode op
+ -- 3 pc_hi = (sp) / sp=sp+1
+ -- 4 pc_lo = (sp) / sp=sp+1
+ --
+ when "1001" =>
+ next_state <= pull_return_hi_state;
+
+ --
+ -- ADD accb to index register
+ -- *** Note: this is an unsigned addition.
+ -- does not affect any condition codes
+ -- 6809 => 3 cycles
+ -- cpu09 => 2 cycles
+ -- 1 op=(pc) / pc=pc+1
+ -- 2 alu_left=ix / alu_right=accb / ix=alu_out / pc=pc
+ --
+ when "1010" => -- abx
+ lic <= '1';
+ left_ctrl <= ix_left;
+ right_ctrl <= accb_right;
+ alu_ctrl <= alu_abx;
+ ix_ctrl <= load_ix;
+ next_state <= fetch_state;
+
+ --
+ -- Return From Interrupt
+ --
+ when "1011" => -- rti
+ next_state <= rti_cc_state;
+
+ --
+ -- CWAI
+ --
+ when "1100" => -- cwai #$
+ -- pre decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ -- increment pc
+ pc_ctrl <= incr_pc;
+ next_state <= cwai_state;
+
+ --
+ -- MUL Multiply
+ --
+ when "1101" => -- mul
+ next_state <= mul_state;
+
+ --
+ -- SWI Software Interrupt
+ --
+ when "1111" => -- swi
+ -- predecrement SP
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ iv_ctrl <= swi_iv;
+ st_ctrl <= push_st;
+ return_state <= int_swimask_state;
+ next_state <= int_entire_state;
+
+ when others =>
+ lic <= '1';
+ next_state <= fetch_state;
+
+ end case;
+ --
+ -- Accumulator A Single operand
+ -- source = acca, dest = acca
+ -- Do not advance PC
+ -- Typically 2 cycles 1 bytes
+ -- 1 opcode fetch
+ -- 2 post byte fetch / instruction decode
+ -- Note that there is no post byte
+ -- so do not advance PC in decode cycle
+ -- Re-run opcode fetch cycle after decode
+ --
+ when "0100" => -- acca single op
+ 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 <= 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 <= 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 (not defined)
+ 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;
+ lic <= '1';
+ next_state <= fetch_state;
+
+ --
+ -- Single Operand accb
+ -- source = accb, dest = accb
+ -- Typically 2 cycles 1 bytes
+ -- 1 opcode fetch
+ -- 2 post byte fetch / instruction decode
+ -- Note that there is no post byte
+ -- so do not advance PC in decode cycle
+ -- Re-run opcode fetch cycle after decode
+ --
+ when "0101" =>
+ 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 <= 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 <= 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 (undefined)
+ 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;
+ lic <= '1';
+ next_state <= fetch_state;
+
+ --
+ -- Single operand indexed
+ -- Two byte instruction so advance PC
+ -- EA should hold index offset
+ --
+ when "0110" => -- indexed single op
+ -- increment the pc
+ pc_ctrl <= incr_pc;
+ st_ctrl <= push_st;
+
+ case op_code(3 downto 0) is
+ when "1110" => -- jmp
+ return_state <= jmp_state;
+
+ when "1111" => -- clr
+ return_state <= single_op_exec_state;
+
+ when others =>
+ return_state <= single_op_read_state;
+
+ end case;
+ 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
+ -- increment PC
+ pc_ctrl <= incr_pc;
+ st_ctrl <= push_st;
+
+ case op_code(3 downto 0) is
+ when "1110" => -- jmp
+ return_state <= jmp_state;
+
+ when "1111" => -- clr
+ return_state <= single_op_exec_state;
+
+ when others =>
+ return_state <= single_op_read_state;
+
+ end case;
+ next_state <= extended_state;
+
+ when "1000" => -- acca immediate
+ -- increment the pc
+ pc_ctrl <= incr_pc;
+
+ case op_code(3 downto 0) is
+ when "0011" | -- subd #
+ "1100" | -- cmpx #
+ "1110" => -- ldx #
+ next_state <= imm16_state;
+
+ --
+ -- bsr offset - Branch to subroutine (2 bytes)
+ -- 6809 => 7 cycles
+ -- cpu09 => 5 cycles
+ -- 1 op=(pc) / pc=pc+1
+ -- 2 md_hi=sign(pc) / md_lo=(pc) / sp=sp-1 / pc=pc+1
+ -- 3 (sp)=pc_lo / sp=sp-1
+ -- 4 (sp)=pc_hi
+ -- 5 pc=pc+md
+ --
+ when "1101" => -- bsr
+ -- pre decrement SP
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ --
+ st_ctrl <= push_st;
+ return_state <= sbranch_state;
+ next_state <= push_return_lo_state;
+
+ when others =>
+ lic <= '1';
+ next_state <= fetch_state;
+
+ end case;
+
+ when "1001" => -- acca direct
+ -- increment the pc
+ pc_ctrl <= incr_pc;
+ case op_code(3 downto 0) is
+ when "0011" | -- subd
+ "1100" | -- cmpx
+ "1110" => -- ldx
+ next_state <= dual_op_read16_state;
+
+ when "0111" => -- sta direct
+ next_state <= dual_op_write8_state;
+
+ --
+ -- jsr direct - Jump to subroutine in direct page (2 bytes)
+ -- 6809 => 7 cycles
+ -- cpu09 => 5 cycles
+ -- 1 op=(pc) / pc=pc+1
+ -- 2 ea_hi=0 / ea_lo=(pc) / sp=sp-1 / pc=pc+1
+ -- 3 (sp)=pc_lo / sp=sp-1
+ -- 4 (sp)=pc_hi
+ -- 5 pc=ea
+ --
+ when "1101" => -- jsr direct
+ -- pre decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ --
+ st_ctrl <= push_st;
+ return_state <= jmp_state;
+ next_state <= push_return_lo_state;
+
+
+ when "1111" => -- stx direct
+ -- idle ALU
+ left_ctrl <= ix_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ sp_ctrl <= latch_sp;
+ next_state <= dual_op_write16_state;
+
+ when others =>
+ next_state <= dual_op_read8_state;
+
+ end case;
+
+ when "1010" => -- acca indexed
+ -- increment the pc
+ pc_ctrl <= incr_pc;
+ case op_code(3 downto 0) is
+ when "0011" | -- subd
+ "1100" | -- cmpx
+ "1110" => -- ldx
+ st_ctrl <= push_st;
+ return_state <= dual_op_read16_state;
+ next_state <= indexed_state;
+
+ when "0111" => -- staa ,x
+ st_ctrl <= push_st;
+ return_state <= dual_op_write8_state;
+ next_state <= indexed_state;
+
+ when "1101" => -- jsr ,x
+ -- DO NOT pre decrement SP
+ st_ctrl <= push_st;
+ return_state <= jsr_state;
+ next_state <= indexed_state;
+
+ when "1111" => -- stx ,x
+ st_ctrl <= push_st;
+ return_state <= dual_op_write16_state;
+ next_state <= indexed_state;
+
+ when others =>
+ st_ctrl <= push_st;
+ return_state <= dual_op_read8_state;
+ next_state <= indexed_state;
+
+ end case;
+
+ when "1011" => -- acca extended
+ -- increment the pc
+ pc_ctrl <= incr_pc;
+ case op_code(3 downto 0) is
+ when "0011" | -- subd
+ "1100" | -- cmpx
+ "1110" => -- ldx
+ st_ctrl <= push_st;
+ return_state <= dual_op_read16_state;
+ next_state <= extended_state;
+
+ when "0111" => -- staa >
+ st_ctrl <= push_st;
+ return_state <= dual_op_write8_state;
+ next_state <= extended_state;
+
+ when "1101" => -- jsr >extended
+ -- DO NOT pre decrement sp
+ st_ctrl <= push_st;
+ return_state <= jsr_state;
+ next_state <= extended_state;
+
+ when "1111" => -- stx >
+ st_ctrl <= push_st;
+ return_state <= dual_op_write16_state;
+ next_state <= extended_state;
+
+ when others =>
+ st_ctrl <= push_st;
+ return_state <= dual_op_read8_state;
+ next_state <= extended_state;
+
+ end case;
+
+ when "1100" => -- accb immediate
+ -- increment the pc
+ pc_ctrl <= incr_pc;
+ case op_code(3 downto 0) is
+ when "0011" | -- addd #
+ "1100" | -- ldd #
+ "1110" => -- ldu #
+ next_state <= imm16_state;
+
+ when others =>
+ lic <= '1';
+ next_state <= fetch_state;
+
+ end case;
+
+ when "1101" => -- accb direct
+ -- increment the pc
+ pc_ctrl <= incr_pc;
+ case op_code(3 downto 0) is
+ when "0011" | -- addd
+ "1100" | -- ldd
+ "1110" => -- ldu
+ next_state <= dual_op_read16_state;
+
+ when "0111" => -- stab direct
+ next_state <= dual_op_write8_state;
+
+ when "1101" => -- std direct
+ next_state <= dual_op_write16_state;
+
+ when "1111" => -- stu direct
+ next_state <= dual_op_write16_state;
+
+ when others =>
+ next_state <= dual_op_read8_state;
+
+ end case;
+
+ when "1110" => -- accb indexed
+ -- increment the pc
+ pc_ctrl <= incr_pc;
+ case op_code(3 downto 0) is
+ when "0011" | -- addd
+ "1100" | -- ldd
+ "1110" => -- ldu
+ st_ctrl <= push_st;
+ return_state <= dual_op_read16_state;
+ next_state <= indexed_state;
+
+ when "0111" => -- stab indexed
+ st_ctrl <= push_st;
+ return_state <= dual_op_write8_state;
+ next_state <= indexed_state;
+
+ when "1101" => -- std indexed
+ st_ctrl <= push_st;
+ return_state <= dual_op_write16_state;
+ next_state <= indexed_state;
+
+ when "1111" => -- stu indexed
+ st_ctrl <= push_st;
+ return_state <= dual_op_write16_state;
+ next_state <= indexed_state;
+
+ when others =>
+ st_ctrl <= push_st;
+ return_state <= dual_op_read8_state;
+ next_state <= indexed_state;
+
+ end case;
+
+ when "1111" => -- accb extended
+ -- increment the pc
+ pc_ctrl <= incr_pc;
+ case op_code(3 downto 0) is
+ when "0011" | -- addd
+ "1100" | -- ldd
+ "1110" => -- ldu
+ st_ctrl <= push_st;
+ return_state <= dual_op_read16_state;
+ next_state <= extended_state;
+
+ when "0111" => -- stab extended
+ st_ctrl <= push_st;
+ return_state <= dual_op_write8_state;
+ next_state <= extended_state;
+
+ when "1101" => -- std extended
+ st_ctrl <= push_st;
+ return_state <= dual_op_write16_state;
+ next_state <= extended_state;
+
+ when "1111" => -- stu extended
+ st_ctrl <= push_st;
+ return_state <= dual_op_write16_state;
+ next_state <= extended_state;
+
+ when others =>
+ st_ctrl <= push_st;
+ return_state <= dual_op_read8_state;
+ next_state <= extended_state;
+ end case;
+ --
+ -- not sure why I need this
+ --
+ when others =>
+ lic <= '1';
+ next_state <= fetch_state;
+ end case;
+
+ --
+ -- Here to decode prefix 2 instruction
+ -- and fetch next byte of intruction
+ -- whether it be necessary or not
+ --
+ when decode2_state =>
+ -- fetch first byte of address or immediate data
+ ea_ctrl <= fetch_first_ea;
+ md_ctrl <= fetch_first_md;
+ addr_ctrl <= fetch_ad;
+ case op_code(7 downto 4) is
+ --
+ -- lbcc -- long branch conditional
+ -- 6809 => branch 6 cycles, no branch 5 cycles
+ -- cpu09 => always 5 cycles
+ -- 1 pre=(pc) / pc=pc+1
+ -- 2 op=(pc) / pc=pc+1
+ -- 3 md_hi=sign(pc) / md_lo=(pc) / pc=pc+1
+ -- 4 md_hi=md_lo / md_lo=(pc) / pc=pc+1
+ -- 5 if cond pc=pc+md else pc=pc
+ --
+ when "0010" =>
+ -- increment the pc
+ pc_ctrl <= incr_pc;
+ next_state <= lbranch_state;
+
+ --
+ -- Single byte stack operators
+ -- Do not advance PC
+ --
+ when "0011" =>
+ case op_code(3 downto 0) is
+ when "1111" => -- swi 2
+ -- predecrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ iv_ctrl <= swi2_iv;
+ st_ctrl <= push_st;
+ return_state <= vect_hi_state;
+ next_state <= int_entire_state;
+
+ when others =>
+ lic <= '1';
+ next_state <= fetch_state;
+ end case;
+
+ when "1000" => -- acca immediate
+ -- increment the pc
+ pc_ctrl <= incr_pc;
+ case op_code(3 downto 0) is
+ when "0011" | -- cmpd #
+ "1100" | -- cmpy #
+ "1110" => -- ldy #
+ next_state <= imm16_state;
+
+ when others =>
+ lic <= '1';
+ next_state <= fetch_state;
+
+ end case;
+
+ when "1001" => -- acca direct
+ -- increment the pc
+ pc_ctrl <= incr_pc;
+ case op_code(3 downto 0) is
+ when "0011" | -- cmpd <
+ "1100" | -- cmpy <
+ "1110" => -- ldy <
+ next_state <= dual_op_read16_state;
+
+ when "1111" => -- sty <
+ next_state <= dual_op_write16_state;
+
+ when others =>
+ lic <= '1';
+ next_state <= fetch_state;
+
+ end case;
+
+ when "1010" => -- acca indexed
+ -- increment the pc
+ pc_ctrl <= incr_pc;
+ case op_code(3 downto 0) is
+ when "0011" | -- cmpd ,ind
+ "1100" | -- cmpy ,ind
+ "1110" => -- ldy ,ind
+ st_ctrl <= push_st;
+ return_state <= dual_op_read16_state;
+ next_state <= indexed_state;
+
+ when "1111" => -- sty ,ind
+ st_ctrl <= push_st;
+ return_state <= dual_op_write16_state;
+ next_state <= indexed_state;
+
+ when others =>
+ lic <= '1';
+ next_state <= fetch_state;
+ end case;
+
+ when "1011" => -- acca extended
+ -- increment the pc
+ pc_ctrl <= incr_pc;
+ case op_code(3 downto 0) is
+ when "0011" | -- cmpd <
+ "1100" | -- cmpy <
+ "1110" => -- ldy <
+ st_ctrl <= push_st;
+ return_state <= dual_op_read16_state;
+ next_state <= extended_state;
+
+ when "1111" => -- sty >
+ st_ctrl <= push_st;
+ return_state <= dual_op_write16_state;
+ next_state <= extended_state;
+
+ when others =>
+ lic <= '1';
+ next_state <= fetch_state;
+
+ end case;
+
+ when "1100" => -- accb immediate
+ -- increment the pc
+ pc_ctrl <= incr_pc;
+ case op_code(3 downto 0) is
+ when "0011" | -- undef #
+ "1100" | -- undef #
+ "1110" => -- lds #
+ next_state <= imm16_state;
+
+ when others =>
+ next_state <= fetch_state;
+
+ end case;
+
+ when "1101" => -- accb direct
+ -- increment the pc
+ pc_ctrl <= incr_pc;
+ case op_code(3 downto 0) is
+ when "0011" | -- undef <
+ "1100" | -- undef <
+ "1110" => -- lds <
+ next_state <= dual_op_read16_state;
+
+ when "1111" => -- sts <
+ next_state <= dual_op_write16_state;
+
+ when others =>
+ lic <= '1';
+ next_state <= fetch_state;
+
+ end case;
+
+ when "1110" => -- accb indexed
+ -- increment the pc
+ pc_ctrl <= incr_pc;
+ case op_code(3 downto 0) is
+ when "0011" | -- undef ,ind
+ "1100" | -- undef ,ind
+ "1110" => -- lds ,ind
+ st_ctrl <= push_st;
+ return_state <= dual_op_read16_state;
+ next_state <= indexed_state;
+
+ when "1111" => -- sts ,ind
+ st_ctrl <= push_st;
+ return_state <= dual_op_write16_state;
+ next_state <= indexed_state;
+
+ when others =>
+ lic <= '1';
+ next_state <= fetch_state;
+
+ end case;
+
+ when "1111" => -- accb extended
+ -- increment the pc
+ pc_ctrl <= incr_pc;
+ case op_code(3 downto 0) is
+ when "0011" | -- undef >
+ "1100" | -- undef >
+ "1110" => -- lds >
+ st_ctrl <= push_st;
+ return_state <= dual_op_read16_state;
+ next_state <= extended_state;
+
+ when "1111" => -- sts >
+ st_ctrl <= push_st;
+ return_state <= dual_op_write16_state;
+ next_state <= extended_state;
+
+ when others =>
+ lic <= '1';
+ next_state <= fetch_state;
+ end case;
+
+ when others =>
+ lic <= '1';
+ next_state <= fetch_state;
+ end case;
+ --
+ -- Here to decode instruction
+ -- and fetch next byte of intruction
+ -- whether it be necessary or not
+ --
+ when decode3_state =>
+ ea_ctrl <= fetch_first_ea;
+ md_ctrl <= fetch_first_md;
+ addr_ctrl <= fetch_ad;
+ dout_ctrl <= md_lo_dout;
+ case op_code(7 downto 4) is
+ --
+ -- Single byte stack operators
+ -- Do not advance PC
+ --
+ when "0011" =>
+ case op_code(3 downto 0) is
+ when "1111" => -- swi3
+ -- predecrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ iv_ctrl <= swi3_iv;
+ st_ctrl <= push_st;
+ return_state <= vect_hi_state;
+ next_state <= int_entire_state;
+ when others =>
+ lic <= '1';
+ next_state <= fetch_state;
+ end case;
+
+ when "1000" => -- acca immediate
+ -- increment the pc
+ pc_ctrl <= incr_pc;
+ case op_code(3 downto 0) is
+ when "0011" | -- cmpu #
+ "1100" | -- cmps #
+ "1110" => -- undef #
+ next_state <= imm16_state;
+ when others =>
+ lic <= '1';
+ next_state <= fetch_state;
+ end case;
+
+ when "1001" => -- acca direct
+ -- increment the pc
+ pc_ctrl <= incr_pc;
+ case op_code(3 downto 0) is
+ when "0011" | -- cmpu <
+ "1100" | -- cmps <
+ "1110" => -- undef <
+ next_state <= dual_op_read16_state;
+
+ when others =>
+ lic <= '1';
+ next_state <= fetch_state;
+
+ end case;
+
+ when "1010" => -- acca indexed
+ -- increment the pc
+ pc_ctrl <= incr_pc;
+ case op_code(3 downto 0) is
+ when "0011" | -- cmpu ,X
+ "1100" | -- cmps ,X
+ "1110" => -- undef ,X
+ st_ctrl <= push_st;
+ return_state <= dual_op_read16_state;
+ next_state <= indexed_state;
+
+ when others =>
+ lic <= '1';
+ next_state <= fetch_state;
+
+ end case;
+
+ when "1011" => -- acca extended
+ -- increment the pc
+ pc_ctrl <= incr_pc;
+ case op_code(3 downto 0) is
+ when "0011" | -- cmpu >
+ "1100" | -- cmps >
+ "1110" => -- undef >
+ st_ctrl <= push_st;
+ return_state <= dual_op_read16_state;
+ next_state <= extended_state;
+ when others =>
+ lic <= '1';
+ next_state <= fetch_state;
+ end case;
+
+ when others =>
+ lic <= '1';
+ next_state <= fetch_state;
+ end case;
+
+ --
+ -- here if ea holds low byte
+ -- Direct
+ -- Extended
+ -- Indexed
+ -- read memory location
+ --
+ when single_op_read_state =>
+ -- read memory into md
+ md_ctrl <= fetch_first_md;
+ addr_ctrl <= read_ad;
+ dout_ctrl <= md_lo_dout;
+ next_state <= single_op_exec_state;
+
+ when single_op_exec_state =>
+ case op_code(3 downto 0) is
+ when "0000" => -- neg
+ left_ctrl <= md_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_neg;
+ cc_ctrl <= load_cc;
+ md_ctrl <= load_md;
+ next_state <= single_op_write_state;
+ when "0011" => -- com
+ left_ctrl <= md_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_com;
+ cc_ctrl <= load_cc;
+ md_ctrl <= load_md;
+ next_state <= single_op_write_state;
+ when "0100" => -- lsr
+ left_ctrl <= md_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_lsr8;
+ cc_ctrl <= load_cc;
+ md_ctrl <= load_md;
+ next_state <= single_op_write_state;
+ when "0110" => -- ror
+ left_ctrl <= md_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_ror8;
+ cc_ctrl <= load_cc;
+ md_ctrl <= load_md;
+ next_state <= single_op_write_state;
+ when "0111" => -- asr
+ left_ctrl <= md_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_asr8;
+ cc_ctrl <= load_cc;
+ md_ctrl <= load_md;
+ next_state <= single_op_write_state;
+ when "1000" => -- asl
+ left_ctrl <= md_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_asl8;
+ cc_ctrl <= load_cc;
+ md_ctrl <= load_md;
+ next_state <= single_op_write_state;
+ when "1001" => -- rol
+ left_ctrl <= md_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_rol8;
+ cc_ctrl <= load_cc;
+ md_ctrl <= load_md;
+ next_state <= single_op_write_state;
+ when "1010" => -- dec
+ left_ctrl <= md_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_dec;
+ cc_ctrl <= load_cc;
+ md_ctrl <= load_md;
+ next_state <= single_op_write_state;
+ when "1011" => -- undefined
+ lic <= '1';
+ next_state <= fetch_state;
+ when "1100" => -- inc
+ left_ctrl <= md_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_inc;
+ cc_ctrl <= load_cc;
+ md_ctrl <= load_md;
+ next_state <= single_op_write_state;
+ when "1101" => -- tst
+ left_ctrl <= md_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_st8;
+ cc_ctrl <= load_cc;
+ lic <= '1';
+ next_state <= fetch_state;
+ when "1110" => -- jmp
+ left_ctrl <= md_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_ld16;
+ pc_ctrl <= load_pc;
+ lic <= '1';
+ next_state <= fetch_state;
+ when "1111" => -- clr
+ left_ctrl <= md_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_clr;
+ cc_ctrl <= load_cc;
+ md_ctrl <= load_md;
+ next_state <= single_op_write_state;
+ when others =>
+ lic <= '1';
+ next_state <= fetch_state;
+ end case;
+ --
+ -- single operand 8 bit write
+ -- Write low 8 bits of ALU output
+ -- EA holds address
+ -- MD holds data
+ --
+ when single_op_write_state =>
+ -- write ALU low byte output
+ addr_ctrl <= write_ad;
+ dout_ctrl <= md_lo_dout;
+ lic <= '1';
+ next_state <= fetch_state;
+
+ --
+ -- here if ea holds address of low byte
+ -- read memory location
+ --
+ when dual_op_read8_state =>
+ -- read first data byte from ea
+ md_ctrl <= fetch_first_md;
+ addr_ctrl <= read_ad;
+ lic <= '1';
+ next_state <= fetch_state;
+
+ --
+ -- Here to read a 16 bit value into MD
+ -- pointed to by the EA register
+ -- The first byte is read
+ -- and the EA is incremented
+ --
+ when dual_op_read16_state =>
+ -- increment the effective address
+ left_ctrl <= ea_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ ea_ctrl <= load_ea;
+ -- read the high byte of the 16 bit data
+ md_ctrl <= fetch_first_md;
+ addr_ctrl <= read_ad;
+ next_state <= dual_op_read16_2_state;
+
+ --
+ -- here to read the second byte
+ -- pointed to by EA into MD
+ --
+ when dual_op_read16_2_state =>
+ -- read the low byte of the 16 bit data
+ md_ctrl <= fetch_next_md;
+ addr_ctrl <= read_ad;
+ lic <= '1';
+ next_state <= fetch_state;
+
+ --
+ -- 16 bit Write state
+ -- EA hold address of memory to write to
+ -- Advance the effective address in ALU
+ -- decode op_code to determine which
+ -- register to write
+ --
+ when dual_op_write16_state =>
+ -- increment the effective address
+ left_ctrl <= ea_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ ea_ctrl <= load_ea;
+ -- write the ALU hi byte at ea
+ addr_ctrl <= write_ad;
+ if op_code(6) = '0' then
+ case op_code(3 downto 0) is
+ when "1111" => -- stx / sty
+ case pre_code is
+ when "00010000" => -- page 2 -- sty
+ dout_ctrl <= iy_hi_dout;
+ when others => -- page 1 -- stx
+ dout_ctrl <= ix_hi_dout;
+ end case;
+ when others =>
+ dout_ctrl <= md_hi_dout;
+ end case;
+ else
+ case op_code(3 downto 0) is
+ when "1101" => -- std
+ dout_ctrl <= acca_dout; -- acca is high byte of ACCD
+ when "1111" => -- stu / sts
+ case pre_code is
+ when "00010000" => -- page 2 -- sts
+ dout_ctrl <= sp_hi_dout;
+ when others => -- page 1 -- stu
+ dout_ctrl <= up_hi_dout;
+ end case;
+ when others =>
+ dout_ctrl <= md_hi_dout;
+ end case;
+ end if;
+ next_state <= dual_op_write8_state;
+
+ --
+ -- Dual operand 8 bit write
+ -- Write 8 bit accumulator
+ -- or low byte of 16 bit register
+ -- EA holds address
+ -- decode opcode to determine
+ -- which register to apply to the bus
+ -- Also set the condition codes here
+ --
+ when dual_op_write8_state =>
+ if op_code(6) = '0' then
+ case op_code(3 downto 0) is
+ when "0111" => -- sta
+ dout_ctrl <= acca_dout;
+ when "1111" => -- stx / sty
+ case pre_code is
+ when "00010000" => -- page 2 -- sty
+ dout_ctrl <= iy_lo_dout;
+ when others => -- page 1 -- stx
+ dout_ctrl <= ix_lo_dout;
+ end case;
+ when others =>
+ dout_ctrl <= md_lo_dout;
+ end case;
+ else
+ case op_code(3 downto 0) is
+ when "0111" => -- stb
+ dout_ctrl <= accb_dout;
+ when "1101" => -- std
+ dout_ctrl <= accb_dout; -- accb is low byte of accd
+ when "1111" => -- stu / sts
+ case pre_code is
+ when "00010000" => -- page 2 -- sts
+ dout_ctrl <= sp_lo_dout;
+ when others => -- page 1 -- stu
+ dout_ctrl <= up_lo_dout;
+ end case;
+ when others =>
+ dout_ctrl <= md_lo_dout;
+ end case;
+ end if;
+ -- write ALU low byte output
+ addr_ctrl <= write_ad;
+ lic <= '1';
+ next_state <= fetch_state;
+
+ --
+ -- 16 bit immediate addressing mode
+ --
+ when imm16_state =>
+ -- increment pc
+ pc_ctrl <= incr_pc;
+ -- fetch next immediate byte
+ md_ctrl <= fetch_next_md;
+ addr_ctrl <= fetch_ad;
+ lic <= '1';
+ next_state <= fetch_state;
+
+ --
+ -- md & ea holds 8 bit index offset
+ -- calculate the effective memory address
+ -- using the alu
+ --
+ when indexed_state =>
+ --
+ -- decode indexing mode
+ --
+ if md(7) = '0' then
+ case md(6 downto 5) is
+ when "00" =>
+ left_ctrl <= ix_left;
+ when "01" =>
+ left_ctrl <= iy_left;
+ when "10" =>
+ left_ctrl <= up_left;
+ when others =>
+ -- when "11" =>
+ left_ctrl <= sp_left;
+ end case;
+ right_ctrl <= md_sign5_right;
+ alu_ctrl <= alu_add16;
+ ea_ctrl <= load_ea;
+ next_state <= saved_state;
+
+ else
+ case md(3 downto 0) is
+ when "0000" => -- ,R+
+ case md(6 downto 5) is
+ when "00" =>
+ left_ctrl <= ix_left;
+ when "01" =>
+ left_ctrl <= iy_left;
+ when "10" =>
+ left_ctrl <= up_left;
+ when others =>
+ left_ctrl <= sp_left;
+ end case;
+ --
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_add16;
+ ea_ctrl <= load_ea;
+ next_state <= postincr1_state;
+
+ when "0001" => -- ,R++
+ case md(6 downto 5) is
+ when "00" =>
+ left_ctrl <= ix_left;
+ when "01" =>
+ left_ctrl <= iy_left;
+ when "10" =>
+ left_ctrl <= up_left;
+ when others =>
+ -- when "11" =>
+ left_ctrl <= sp_left;
+ end case;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_add16;
+ ea_ctrl <= load_ea;
+ next_state <= postincr2_state;
+
+ when "0010" => -- ,-R
+ case md(6 downto 5) is
+ when "00" =>
+ left_ctrl <= ix_left;
+ ix_ctrl <= load_ix;
+ when "01" =>
+ left_ctrl <= iy_left;
+ iy_ctrl <= load_iy;
+ when "10" =>
+ left_ctrl <= up_left;
+ up_ctrl <= load_up;
+ when others =>
+ -- when "11" =>
+ left_ctrl <= sp_left;
+ sp_ctrl <= load_sp;
+ end case;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ ea_ctrl <= load_ea;
+ next_state <= saved_state;
+
+ when "0011" => -- ,--R
+ case md(6 downto 5) is
+ when "00" =>
+ left_ctrl <= ix_left;
+ ix_ctrl <= load_ix;
+ when "01" =>
+ left_ctrl <= iy_left;
+ iy_ctrl <= load_iy;
+ when "10" =>
+ left_ctrl <= up_left;
+ up_ctrl <= load_up;
+ when others =>
+ -- when "11" =>
+ left_ctrl <= sp_left;
+ sp_ctrl <= load_sp;
+ end case;
+ right_ctrl <= two_right;
+ alu_ctrl <= alu_sub16;
+ ea_ctrl <= load_ea;
+ if md(4) = '0' then
+ next_state <= saved_state;
+ else
+ next_state <= indirect_state;
+ end if;
+
+ when "0100" => -- ,R (zero offset)
+ case md(6 downto 5) is
+ when "00" =>
+ left_ctrl <= ix_left;
+ when "01" =>
+ left_ctrl <= iy_left;
+ when "10" =>
+ left_ctrl <= up_left;
+ when others =>
+ -- when "11" =>
+ left_ctrl <= sp_left;
+ end case;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_add16;
+ ea_ctrl <= load_ea;
+ if md(4) = '0' then
+ next_state <= saved_state;
+ else
+ next_state <= indirect_state;
+ end if;
+
+ when "0101" => -- ACCB,R
+ case md(6 downto 5) is
+ when "00" =>
+ left_ctrl <= ix_left;
+ when "01" =>
+ left_ctrl <= iy_left;
+ when "10" =>
+ left_ctrl <= up_left;
+ when others =>
+ -- when "11" =>
+ left_ctrl <= sp_left;
+ end case;
+ right_ctrl <= accb_right;
+ alu_ctrl <= alu_add16;
+ ea_ctrl <= load_ea;
+ if md(4) = '0' then
+ next_state <= saved_state;
+ else
+ next_state <= indirect_state;
+ end if;
+
+ when "0110" => -- ACCA,R
+ case md(6 downto 5) is
+ when "00" =>
+ left_ctrl <= ix_left;
+ when "01" =>
+ left_ctrl <= iy_left;
+ when "10" =>
+ left_ctrl <= up_left;
+ when others =>
+ -- when "11" =>
+ left_ctrl <= sp_left;
+ end case;
+ right_ctrl <= acca_right;
+ alu_ctrl <= alu_add16;
+ ea_ctrl <= load_ea;
+ if md(4) = '0' then
+ next_state <= saved_state;
+ else
+ next_state <= indirect_state;
+ end if;
+
+ when "0111" => -- undefined
+ case md(6 downto 5) is
+ when "00" =>
+ left_ctrl <= ix_left;
+ when "01" =>
+ left_ctrl <= iy_left;
+ when "10" =>
+ left_ctrl <= up_left;
+ when others =>
+ -- when "11" =>
+ left_ctrl <= sp_left;
+ end case;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_add16;
+ ea_ctrl <= load_ea;
+ if md(4) = '0' then
+ next_state <= saved_state;
+ else
+ next_state <= indirect_state;
+ end if;
+
+ when "1000" => -- offset8,R
+ md_ctrl <= fetch_first_md; -- pick up 8 bit offset
+ addr_ctrl <= fetch_ad;
+ pc_ctrl <= incr_pc;
+ next_state <= index8_state;
+
+ when "1001" => -- offset16,R
+ md_ctrl <= fetch_first_md; -- pick up first byte of 16 bit offset
+ addr_ctrl <= fetch_ad;
+ pc_ctrl <= incr_pc;
+ next_state <= index16_state;
+
+ when "1010" => -- undefined
+ case md(6 downto 5) is
+ when "00" =>
+ left_ctrl <= ix_left;
+ when "01" =>
+ left_ctrl <= iy_left;
+ when "10" =>
+ left_ctrl <= up_left;
+ when others =>
+ -- when "11" =>
+ left_ctrl <= sp_left;
+ end case;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_add16;
+ ea_ctrl <= load_ea;
+ --
+ if md(4) = '0' then
+ next_state <= saved_state;
+ else
+ next_state <= indirect_state;
+ end if;
+
+ when "1011" => -- ACCD,R
+ case md(6 downto 5) is
+ when "00" =>
+ left_ctrl <= ix_left;
+ when "01" =>
+ left_ctrl <= iy_left;
+ when "10" =>
+ left_ctrl <= up_left;
+ when others =>
+ -- when "11" =>
+ left_ctrl <= sp_left;
+ end case;
+ right_ctrl <= accd_right;
+ alu_ctrl <= alu_add16;
+ ea_ctrl <= load_ea;
+ if md(4) = '0' then
+ next_state <= saved_state;
+ else
+ next_state <= indirect_state;
+ end if;
+
+ when "1100" => -- offset8,PC
+ -- fetch 8 bit offset
+ md_ctrl <= fetch_first_md;
+ addr_ctrl <= fetch_ad;
+ pc_ctrl <= incr_pc;
+ next_state <= pcrel8_state;
+
+ when "1101" => -- offset16,PC
+ -- fetch offset
+ md_ctrl <= fetch_first_md;
+ addr_ctrl <= fetch_ad;
+ pc_ctrl <= incr_pc;
+ next_state <= pcrel16_state;
+
+ when "1110" => -- undefined
+ case md(6 downto 5) is
+ when "00" =>
+ left_ctrl <= ix_left;
+ when "01" =>
+ left_ctrl <= iy_left;
+ when "10" =>
+ left_ctrl <= up_left;
+ when others =>
+ -- when "11" =>
+ left_ctrl <= sp_left;
+ end case;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_add16;
+ ea_ctrl <= load_ea;
+ if md(4) = '0' then
+ next_state <= saved_state;
+ else
+ next_state <= indirect_state;
+ end if;
+
+ when others =>
+-- when "1111" => -- [,address]
+ -- advance PC to pick up address
+ md_ctrl <= fetch_first_md;
+ addr_ctrl <= fetch_ad;
+ pc_ctrl <= incr_pc;
+ next_state <= indexaddr_state;
+ end case;
+ end if;
+
+ -- load index register with ea plus one
+ when postincr1_state =>
+ left_ctrl <= ea_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ case md(6 downto 5) is
+ when "00" =>
+ ix_ctrl <= load_ix;
+ when "01" =>
+ iy_ctrl <= load_iy;
+ when "10" =>
+ up_ctrl <= load_up;
+ when others =>
+ -- when "11" =>
+ sp_ctrl <= load_sp;
+ end case;
+ -- return to previous state
+ if md(4) = '0' then
+ next_state <= saved_state;
+ else
+ next_state <= indirect_state;
+ end if;
+
+ -- load index register with ea plus two
+ when postincr2_state =>
+ -- increment register by two (address)
+ left_ctrl <= ea_left;
+ right_ctrl <= two_right;
+ alu_ctrl <= alu_add16;
+ case md(6 downto 5) is
+ when "00" =>
+ ix_ctrl <= load_ix;
+ when "01" =>
+ iy_ctrl <= load_iy;
+ when "10" =>
+ up_ctrl <= load_up;
+ when others =>
+ -- when "11" =>
+ sp_ctrl <= load_sp;
+ end case;
+ -- return to previous state
+ if md(4) = '0' then
+ next_state <= saved_state;
+ else
+ next_state <= indirect_state;
+ end if;
+ --
+ -- ea = index register + md (8 bit signed offset)
+ -- ea holds post byte
+ --
+ when index8_state =>
+ case ea(6 downto 5) is
+ when "00" =>
+ left_ctrl <= ix_left;
+ when "01" =>
+ left_ctrl <= iy_left;
+ when "10" =>
+ left_ctrl <= up_left;
+ when others =>
+ -- when "11" =>
+ left_ctrl <= sp_left;
+ end case;
+ -- ea = index reg + md
+ right_ctrl <= md_sign8_right;
+ alu_ctrl <= alu_add16;
+ ea_ctrl <= load_ea;
+ -- return to previous state
+ if ea(4) = '0' then
+ next_state <= saved_state;
+ else
+ next_state <= indirect_state;
+ end if;
+
+ -- fetch low byte of 16 bit indexed offset
+ when index16_state =>
+ -- advance pc
+ pc_ctrl <= incr_pc;
+ -- fetch low byte
+ md_ctrl <= fetch_next_md;
+ addr_ctrl <= fetch_ad;
+ next_state <= index16_2_state;
+
+ -- ea = index register + md (16 bit offset)
+ -- ea holds post byte
+ when index16_2_state =>
+ case ea(6 downto 5) is
+ when "00" =>
+ left_ctrl <= ix_left;
+ when "01" =>
+ left_ctrl <= iy_left;
+ when "10" =>
+ left_ctrl <= up_left;
+ when others =>
+ -- when "11" =>
+ left_ctrl <= sp_left;
+ end case;
+ -- ea = index reg + md
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_add16;
+ ea_ctrl <= load_ea;
+ -- return to previous state
+ if ea(4) = '0' then
+ next_state <= saved_state;
+ else
+ next_state <= indirect_state;
+ end if;
+ --
+ -- pc relative with 8 bit signed offest
+ -- md holds signed offset
+ --
+ when pcrel8_state =>
+ -- ea = pc + signed md
+ left_ctrl <= pc_left;
+ right_ctrl <= md_sign8_right;
+ alu_ctrl <= alu_add16;
+ ea_ctrl <= load_ea;
+ -- return to previous state
+ if ea(4) = '0' then
+ next_state <= saved_state;
+ else
+ next_state <= indirect_state;
+ end if;
+
+ -- pc relative addressing with 16 bit offset
+ -- pick up the low byte of the offset in md
+ -- advance the pc
+ when pcrel16_state =>
+ -- advance pc
+ pc_ctrl <= incr_pc;
+ -- fetch low byte
+ md_ctrl <= fetch_next_md;
+ addr_ctrl <= fetch_ad;
+ next_state <= pcrel16_2_state;
+
+ -- pc relative with16 bit signed offest
+ -- md holds signed offset
+ when pcrel16_2_state =>
+ -- ea = pc + md
+ left_ctrl <= pc_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_add16;
+ ea_ctrl <= load_ea;
+ -- return to previous state
+ if ea(4) = '0' then
+ next_state <= saved_state;
+ else
+ next_state <= indirect_state;
+ end if;
+
+ -- indexed to address
+ -- pick up the low byte of the address
+ -- advance the pc
+ when indexaddr_state =>
+ -- advance pc
+ pc_ctrl <= incr_pc;
+ -- fetch low byte
+ md_ctrl <= fetch_next_md;
+ addr_ctrl <= fetch_ad;
+ next_state <= indexaddr2_state;
+
+ -- indexed to absolute address
+ -- md holds address
+ -- ea hold indexing mode byte
+ when indexaddr2_state =>
+ -- ea = md
+ left_ctrl <= pc_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_ld16;
+ ea_ctrl <= load_ea;
+ -- return to previous state
+ if ea(4) = '0' then
+ next_state <= saved_state;
+ else
+ next_state <= indirect_state;
+ end if;
+
+ --
+ -- load md with high byte of indirect address
+ -- pointed to by ea
+ -- increment ea
+ --
+ when indirect_state =>
+ -- increment ea
+ left_ctrl <= ea_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ ea_ctrl <= load_ea;
+ -- fetch high byte
+ md_ctrl <= fetch_first_md;
+ addr_ctrl <= read_ad;
+ next_state <= indirect2_state;
+ --
+ -- load md with low byte of indirect address
+ -- pointed to by ea
+ -- ea has previously been incremented
+ --
+ when indirect2_state =>
+ -- fetch high byte
+ md_ctrl <= fetch_next_md;
+ addr_ctrl <= read_ad;
+ dout_ctrl <= md_lo_dout;
+ next_state <= indirect3_state;
+ --
+ -- complete idirect addressing
+ -- by loading ea with md
+ --
+ when indirect3_state =>
+ -- load ea with md
+ left_ctrl <= ea_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_ld16;
+ ea_ctrl <= load_ea;
+ -- return to previous state
+ next_state <= saved_state;
+
+ --
+ -- 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
+ -- increment pc
+ pc_ctrl <= incr_pc;
+ -- fetch next effective address bytes
+ ea_ctrl <= fetch_next_ea;
+ addr_ctrl <= fetch_ad;
+ -- return to previous state
+ next_state <= saved_state;
+
+ when lea_state => -- here on load effective address
+ -- load index register with effective address
+ left_ctrl <= pc_left;
+ right_ctrl <= ea_right;
+ alu_ctrl <= alu_lea;
+ case op_code(3 downto 0) is
+ when "0000" => -- leax
+ cc_ctrl <= load_cc;
+ ix_ctrl <= load_ix;
+ when "0001" => -- leay
+ cc_ctrl <= load_cc;
+ iy_ctrl <= load_iy;
+ when "0010" => -- leas
+ sp_ctrl <= load_sp;
+ when "0011" => -- leau
+ up_ctrl <= load_up;
+ when others =>
+ null;
+ end case;
+ lic <= '1';
+ next_state <= fetch_state;
+
+ --
+ -- jump to subroutine
+ -- sp=sp-1
+ -- call push_return_lo_state to save pc
+ -- return to jmp_state
+ --
+ when jsr_state =>
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ -- call push_return_state
+ st_ctrl <= push_st;
+ return_state <= jmp_state;
+ next_state <= push_return_lo_state;
+
+ --
+ -- Load pc with ea
+ -- (JMP)
+ --
+ when jmp_state =>
+ -- load PC with effective address
+ left_ctrl <= pc_left;
+ right_ctrl <= ea_right;
+ alu_ctrl <= alu_ld16;
+ pc_ctrl <= load_pc;
+ lic <= '1';
+ next_state <= fetch_state;
+
+ --
+ -- long branch or branch to subroutine
+ -- pick up next md byte
+ -- md_hi = md_lo
+ -- md_lo = (pc)
+ -- pc=pc+1
+ -- if a lbsr push return address
+ -- continue to sbranch_state
+ -- to evaluate conditional branches
+ --
+ when lbranch_state =>
+ pc_ctrl <= incr_pc;
+ -- fetch the next byte into md_lo
+ md_ctrl <= fetch_next_md;
+ addr_ctrl <= fetch_ad;
+ -- if lbsr - push return address
+ -- then continue on to short branch
+ if op_code = "00010111" then
+ st_ctrl <= push_st;
+ return_state <= sbranch_state;
+ next_state <= push_return_lo_state;
+ else
+ next_state <= sbranch_state;
+ end if;
+
+ --
+ -- here to execute conditional branch
+ -- short conditional branch md = signed 8 bit offset
+ -- long branch md = 16 bit offset
+ --
+ when sbranch_state =>
+ left_ctrl <= pc_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_add16;
+ -- Test condition for branch
+ if op_code(7 downto 4) = "0010" then -- conditional branch
+ case op_code(3 downto 0) is
+ when "0000" => -- bra
+ cond_true := (1 = 1);
+ when "0001" => -- brn
+ cond_true := (1 = 0);
+ when "0010" => -- bhi
+ cond_true := ((cc(CBIT) or cc(ZBIT)) = '0');
+ when "0011" => -- bls
+ cond_true := ((cc(CBIT) or cc(ZBIT)) = '1');
+ when "0100" => -- bcc/bhs
+ cond_true := (cc(CBIT) = '0');
+ when "0101" => -- bcs/blo
+ cond_true := (cc(CBIT) = '1');
+ when "0110" => -- bne
+ cond_true := (cc(ZBIT) = '0');
+ when "0111" => -- beq
+ cond_true := (cc(ZBIT) = '1');
+ when "1000" => -- bvc
+ cond_true := (cc(VBIT) = '0');
+ when "1001" => -- bvs
+ cond_true := (cc(VBIT) = '1');
+ when "1010" => -- bpl
+ cond_true := (cc(NBIT) = '0');
+ when "1011" => -- bmi
+ cond_true := (cc(NBIT) = '1');
+ when "1100" => -- bge
+ cond_true := ((cc(NBIT) xor cc(VBIT)) = '0');
+ when "1101" => -- blt
+ cond_true := ((cc(NBIT) xor cc(VBIT)) = '1');
+ when "1110" => -- bgt
+ cond_true := ((cc(ZBIT) or (cc(NBIT) xor cc(VBIT))) = '0');
+ when "1111" => -- ble
+ cond_true := ((cc(ZBIT) or (cc(NBIT) xor cc(VBIT))) = '1');
+ when others =>
+ null;
+ end case;
+ end if;
+ if cond_true then
+ pc_ctrl <= load_pc;
+ end if;
+ lic <= '1';
+ next_state <= fetch_state;
+
+ --
+ -- push return address onto the S stack
+ --
+ -- (sp) = pc_lo
+ -- sp = sp - 1
+ --
+ when push_return_lo_state =>
+ -- decrement the sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ -- write PC low
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= pc_lo_dout;
+ next_state <= push_return_hi_state;
+
+ --
+ -- push program counter hi byte onto the stack
+ -- (sp) = pc_hi
+ -- sp = sp
+ -- return to originating state
+ --
+ when push_return_hi_state =>
+ -- write pc hi bytes
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= pc_hi_dout;
+ next_state <= saved_state;
+
+ --
+ -- RTS pull return address from stack
+ --
+ when pull_return_hi_state =>
+ -- increment the sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- read pc hi
+ pc_ctrl <= pull_hi_pc;
+ addr_ctrl <= pulls_ad;
+ next_state <= pull_return_lo_state;
+
+ when pull_return_lo_state =>
+ -- increment the SP
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- read pc low
+ pc_ctrl <= pull_lo_pc;
+ addr_ctrl <= pulls_ad;
+ dout_ctrl <= pc_lo_dout;
+ --
+ lic <= '1';
+ next_state <= fetch_state;
+
+ when andcc_state =>
+ -- AND CC with md
+ left_ctrl <= md_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_andcc;
+ cc_ctrl <= load_cc;
+ --
+ lic <= '1';
+ next_state <= fetch_state;
+
+ when orcc_state =>
+ -- OR CC with md
+ left_ctrl <= md_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_orcc;
+ cc_ctrl <= load_cc;
+ --
+ lic <= '1';
+ next_state <= fetch_state;
+
+ when tfr_state =>
+ -- select source register
+ case md(7 downto 4) is
+ when "0000" =>
+ left_ctrl <= accd_left;
+ when "0001" =>
+ left_ctrl <= ix_left;
+ when "0010" =>
+ left_ctrl <= iy_left;
+ when "0011" =>
+ left_ctrl <= up_left;
+ when "0100" =>
+ left_ctrl <= sp_left;
+ when "0101" =>
+ left_ctrl <= pc_left;
+ when "1000" =>
+ left_ctrl <= acca_left;
+ when "1001" =>
+ left_ctrl <= accb_left;
+ when "1010" =>
+ left_ctrl <= cc_left;
+ when "1011" =>
+ left_ctrl <= dp_left;
+ when others =>
+ left_ctrl <= md_left;
+ end case;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_tfr;
+ -- select destination register
+ case md(3 downto 0) is
+ when "0000" => -- accd
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
+ when "0001" => -- ix
+ ix_ctrl <= load_ix;
+ when "0010" => -- iy
+ iy_ctrl <= load_iy;
+ when "0011" => -- up
+ up_ctrl <= load_up;
+ when "0100" => -- sp
+ sp_ctrl <= load_sp;
+ when "0101" => -- pc
+ pc_ctrl <= load_pc;
+ when "1000" => -- acca
+ acca_ctrl <= load_acca;
+ when "1001" => -- accb
+ accb_ctrl <= load_accb;
+ when "1010" => -- cc
+ cc_ctrl <= load_cc;
+ when "1011" => --dp
+ dp_ctrl <= load_dp;
+ when others =>
+ null;
+ end case;
+ --
+ lic <= '1';
+ next_state <= fetch_state;
+
+ when exg_state =>
+ -- save destination register
+ case md(3 downto 0) is
+ when "0000" =>
+ left_ctrl <= accd_left;
+ when "0001" =>
+ left_ctrl <= ix_left;
+ when "0010" =>
+ left_ctrl <= iy_left;
+ when "0011" =>
+ left_ctrl <= up_left;
+ when "0100" =>
+ left_ctrl <= sp_left;
+ when "0101" =>
+ left_ctrl <= pc_left;
+ when "1000" =>
+ left_ctrl <= acca_left;
+ when "1001" =>
+ left_ctrl <= accb_left;
+ when "1010" =>
+ left_ctrl <= cc_left;
+ when "1011" =>
+ left_ctrl <= dp_left;
+ when others =>
+ left_ctrl <= md_left;
+ end case;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_tfr;
+ ea_ctrl <= load_ea;
+ -- call tranfer microcode
+ next_state <= exg1_state;
+
+ when exg1_state =>
+ -- select source register
+ case md(7 downto 4) is
+ when "0000" =>
+ left_ctrl <= accd_left;
+ when "0001" =>
+ left_ctrl <= ix_left;
+ when "0010" =>
+ left_ctrl <= iy_left;
+ when "0011" =>
+ left_ctrl <= up_left;
+ when "0100" =>
+ left_ctrl <= sp_left;
+ when "0101" =>
+ left_ctrl <= pc_left;
+ when "1000" =>
+ left_ctrl <= acca_left;
+ when "1001" =>
+ left_ctrl <= accb_left;
+ when "1010" =>
+ left_ctrl <= cc_left;
+ when "1011" =>
+ left_ctrl <= dp_left;
+ when others =>
+ left_ctrl <= md_left;
+ end case;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_tfr;
+ -- select destination register
+ case md(3 downto 0) is
+ when "0000" => -- accd
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
+ when "0001" => -- ix
+ ix_ctrl <= load_ix;
+ when "0010" => -- iy
+ iy_ctrl <= load_iy;
+ when "0011" => -- up
+ up_ctrl <= load_up;
+ when "0100" => -- sp
+ sp_ctrl <= load_sp;
+ when "0101" => -- pc
+ pc_ctrl <= load_pc;
+ when "1000" => -- acca
+ acca_ctrl <= load_acca;
+ when "1001" => -- accb
+ accb_ctrl <= load_accb;
+ when "1010" => -- cc
+ cc_ctrl <= load_cc;
+ when "1011" => --dp
+ dp_ctrl <= load_dp;
+ when others =>
+ null;
+ end case;
+ next_state <= exg2_state;
+
+ when exg2_state =>
+ -- restore destination
+ left_ctrl <= ea_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_tfr;
+ -- save as source register
+ case md(7 downto 4) is
+ when "0000" => -- accd
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
+ when "0001" => -- ix
+ ix_ctrl <= load_ix;
+ when "0010" => -- iy
+ iy_ctrl <= load_iy;
+ when "0011" => -- up
+ up_ctrl <= load_up;
+ when "0100" => -- sp
+ sp_ctrl <= load_sp;
+ when "0101" => -- pc
+ pc_ctrl <= load_pc;
+ when "1000" => -- acca
+ acca_ctrl <= load_acca;
+ when "1001" => -- accb
+ accb_ctrl <= load_accb;
+ when "1010" => -- cc
+ cc_ctrl <= load_cc;
+ when "1011" => --dp
+ dp_ctrl <= load_dp;
+ when others =>
+ null;
+ end case;
+ lic <= '1';
+ next_state <= fetch_state;
+
+ when mul_state =>
+ -- move acca to md
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_st16;
+ md_ctrl <= load_md;
+ next_state <= mulea_state;
+
+ when mulea_state =>
+ -- move accb to ea
+ left_ctrl <= accb_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_st16;
+ ea_ctrl <= load_ea;
+ next_state <= muld_state;
+
+ when muld_state =>
+ -- clear accd
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_ld8;
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
+ next_state <= mul0_state;
+
+ when mul0_state =>
+ -- if bit 0 of ea set, add accd to md
+ left_ctrl <= accd_left;
+ if ea(0) = '1' then
+ right_ctrl <= md_right;
+ else
+ right_ctrl <= zero_right;
+ end if;
+ alu_ctrl <= alu_mul;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
+ md_ctrl <= shiftl_md;
+ next_state <= mul1_state;
+
+ when mul1_state =>
+ -- if bit 1 of ea set, add accd to md
+ left_ctrl <= accd_left;
+ if ea(1) = '1' then
+ right_ctrl <= md_right;
+ else
+ right_ctrl <= zero_right;
+ end if;
+ alu_ctrl <= alu_mul;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
+ md_ctrl <= shiftl_md;
+ next_state <= mul2_state;
+
+ when mul2_state =>
+ -- if bit 2 of ea set, add accd to md
+ left_ctrl <= accd_left;
+ if ea(2) = '1' then
+ right_ctrl <= md_right;
+ else
+ right_ctrl <= zero_right;
+ end if;
+ alu_ctrl <= alu_mul;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
+ md_ctrl <= shiftl_md;
+ next_state <= mul3_state;
+
+ when mul3_state =>
+ -- if bit 3 of ea set, add accd to md
+ left_ctrl <= accd_left;
+ if ea(3) = '1' then
+ right_ctrl <= md_right;
+ else
+ right_ctrl <= zero_right;
+ end if;
+ alu_ctrl <= alu_mul;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
+ md_ctrl <= shiftl_md;
+ next_state <= mul4_state;
+
+ when mul4_state =>
+ -- if bit 4 of ea set, add accd to md
+ left_ctrl <= accd_left;
+ if ea(4) = '1' then
+ right_ctrl <= md_right;
+ else
+ right_ctrl <= zero_right;
+ end if;
+ alu_ctrl <= alu_mul;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
+ md_ctrl <= shiftl_md;
+ next_state <= mul5_state;
+
+ when mul5_state =>
+ -- if bit 5 of ea set, add accd to md
+ left_ctrl <= accd_left;
+ if ea(5) = '1' then
+ right_ctrl <= md_right;
+ else
+ right_ctrl <= zero_right;
+ end if;
+ alu_ctrl <= alu_mul;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
+ md_ctrl <= shiftl_md;
+ next_state <= mul6_state;
+
+ when mul6_state =>
+ -- if bit 6 of ea set, add accd to md
+ left_ctrl <= accd_left;
+ if ea(6) = '1' then
+ right_ctrl <= md_right;
+ else
+ right_ctrl <= zero_right;
+ end if;
+ alu_ctrl <= alu_mul;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
+ md_ctrl <= shiftl_md;
+ next_state <= mul7_state;
+
+ when mul7_state =>
+ -- if bit 7 of ea set, add accd to md
+ left_ctrl <= accd_left;
+ if ea(7) = '1' then
+ right_ctrl <= md_right;
+ else
+ right_ctrl <= zero_right;
+ end if;
+ alu_ctrl <= alu_mul;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
+ md_ctrl <= shiftl_md;
+ lic <= '1';
+ next_state <= fetch_state;
+
+ --
+ -- Enter here on pushs
+ -- ea holds post byte
+ --
+ when pshs_state =>
+ -- decrement sp if any registers to be pushed
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ -- idle address
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= cc_dout;
+ if ea(7 downto 0) = "00000000" then
+ sp_ctrl <= latch_sp;
+ else
+ sp_ctrl <= load_sp;
+ end if;
+ if ea(7) = '1' then
+ next_state <= pshs_pcl_state;
+ elsif ea(6) = '1' then
+ next_state <= pshs_upl_state;
+ elsif ea(5) = '1' then
+ next_state <= pshs_iyl_state;
+ elsif ea(4) = '1' then
+ next_state <= pshs_ixl_state;
+ elsif ea(3) = '1' then
+ next_state <= pshs_dp_state;
+ elsif ea(2) = '1' then
+ next_state <= pshs_accb_state;
+ elsif ea(1) = '1' then
+ next_state <= pshs_acca_state;
+ elsif ea(0) = '1' then
+ next_state <= pshs_cc_state;
+ else
+ lic <= '1';
+ next_state <= fetch_state;
+ end if;
+
+ when pshs_pcl_state =>
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ -- write pc low
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= pc_lo_dout;
+ next_state <= pshs_pch_state;
+
+ when pshs_pch_state =>
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ if ea(6 downto 0) = "0000000" then
+ sp_ctrl <= latch_sp;
+ else
+ sp_ctrl <= load_sp;
+ end if;
+ -- write pc hi
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= pc_hi_dout;
+ if ea(6) = '1' then
+ next_state <= pshs_upl_state;
+ elsif ea(5) = '1' then
+ next_state <= pshs_iyl_state;
+ elsif ea(4) = '1' then
+ next_state <= pshs_ixl_state;
+ elsif ea(3) = '1' then
+ next_state <= pshs_dp_state;
+ elsif ea(2) = '1' then
+ next_state <= pshs_accb_state;
+ elsif ea(1) = '1' then
+ next_state <= pshs_acca_state;
+ elsif ea(0) = '1' then
+ next_state <= pshs_cc_state;
+ else
+ lic <= '1';
+ next_state <= fetch_state;
+ end if;
+
+
+ when pshs_upl_state =>
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ -- write pc low
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= up_lo_dout;
+ next_state <= pshs_uph_state;
+
+ when pshs_uph_state =>
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ if ea(5 downto 0) = "000000" then
+ sp_ctrl <= latch_sp;
+ else
+ sp_ctrl <= load_sp;
+ end if;
+ -- write pc hi
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= up_hi_dout;
+ if ea(5) = '1' then
+ next_state <= pshs_iyl_state;
+ elsif ea(4) = '1' then
+ next_state <= pshs_ixl_state;
+ elsif ea(3) = '1' then
+ next_state <= pshs_dp_state;
+ elsif ea(2) = '1' then
+ next_state <= pshs_accb_state;
+ elsif ea(1) = '1' then
+ next_state <= pshs_acca_state;
+ elsif ea(0) = '1' then
+ next_state <= pshs_cc_state;
+ else
+ lic <= '1';
+ next_state <= fetch_state;
+ end if;
+
+ when pshs_iyl_state =>
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ -- write iy low
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= iy_lo_dout;
+ next_state <= pshs_iyh_state;
+
+ when pshs_iyh_state =>
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ if ea(4 downto 0) = "00000" then
+ sp_ctrl <= latch_sp;
+ else
+ sp_ctrl <= load_sp;
+ end if;
+ -- write iy hi
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= iy_hi_dout;
+ if ea(4) = '1' then
+ next_state <= pshs_ixl_state;
+ elsif ea(3) = '1' then
+ next_state <= pshs_dp_state;
+ elsif ea(2) = '1' then
+ next_state <= pshs_accb_state;
+ elsif ea(1) = '1' then
+ next_state <= pshs_acca_state;
+ elsif ea(0) = '1' then
+ next_state <= pshs_cc_state;
+ else
+ lic <= '1';
+ next_state <= fetch_state;
+ end if;
+
+ when pshs_ixl_state =>
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ -- write ix low
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= ix_lo_dout;
+ next_state <= pshs_ixh_state;
+
+ when pshs_ixh_state =>
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ if ea(3 downto 0) = "0000" then
+ sp_ctrl <= latch_sp;
+ else
+ sp_ctrl <= load_sp;
+ end if;
+ -- write ix hi
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= ix_hi_dout;
+ if ea(3) = '1' then
+ next_state <= pshs_dp_state;
+ elsif ea(2) = '1' then
+ next_state <= pshs_accb_state;
+ elsif ea(1) = '1' then
+ next_state <= pshs_acca_state;
+ elsif ea(0) = '1' then
+ next_state <= pshs_cc_state;
+ else
+ lic <= '1';
+ next_state <= fetch_state;
+ end if;
+
+ when pshs_dp_state =>
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ if ea(2 downto 0) = "000" then
+ sp_ctrl <= latch_sp;
+ else
+ sp_ctrl <= load_sp;
+ end if;
+ -- write dp
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= dp_dout;
+ if ea(2) = '1' then
+ next_state <= pshs_accb_state;
+ elsif ea(1) = '1' then
+ next_state <= pshs_acca_state;
+ elsif ea(0) = '1' then
+ next_state <= pshs_cc_state;
+ else
+ lic <= '1';
+ next_state <= fetch_state;
+ end if;
+
+ when pshs_accb_state =>
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ if ea(1 downto 0) = "00" then
+ sp_ctrl <= latch_sp;
+ else
+ sp_ctrl <= load_sp;
+ end if;
+ -- write accb
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= accb_dout;
+ if ea(1) = '1' then
+ next_state <= pshs_acca_state;
+ elsif ea(0) = '1' then
+ next_state <= pshs_cc_state;
+ else
+ lic <= '1';
+ next_state <= fetch_state;
+ end if;
+
+ when pshs_acca_state =>
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ if ea(0) = '1' then
+ sp_ctrl <= load_sp;
+ else
+ sp_ctrl <= latch_sp;
+ end if;
+ -- write acca
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= acca_dout;
+ if ea(0) = '1' then
+ next_state <= pshs_cc_state;
+ else
+ lic <= '1';
+ next_state <= fetch_state;
+ end if;
+
+ when pshs_cc_state =>
+ -- idle sp
+ -- write cc
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= cc_dout;
+ lic <= '1';
+ next_state <= fetch_state;
+
+ --
+ -- enter here on PULS
+ -- ea hold register mask
+ --
+ when puls_state =>
+ if ea(0) = '1' then
+ next_state <= puls_cc_state;
+ elsif ea(1) = '1' then
+ next_state <= puls_acca_state;
+ elsif ea(2) = '1' then
+ next_state <= puls_accb_state;
+ elsif ea(3) = '1' then
+ next_state <= puls_dp_state;
+ elsif ea(4) = '1' then
+ next_state <= puls_ixh_state;
+ elsif ea(5) = '1' then
+ next_state <= puls_iyh_state;
+ elsif ea(6) = '1' then
+ next_state <= puls_uph_state;
+ elsif ea(7) = '1' then
+ next_state <= puls_pch_state;
+ else
+ lic <= '1';
+ next_state <= fetch_state;
+ end if;
+
+ when puls_cc_state =>
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- read cc
+ cc_ctrl <= pull_cc;
+ addr_ctrl <= pulls_ad;
+ if ea(1) = '1' then
+ next_state <= puls_acca_state;
+ elsif ea(2) = '1' then
+ next_state <= puls_accb_state;
+ elsif ea(3) = '1' then
+ next_state <= puls_dp_state;
+ elsif ea(4) = '1' then
+ next_state <= puls_ixh_state;
+ elsif ea(5) = '1' then
+ next_state <= puls_iyh_state;
+ elsif ea(6) = '1' then
+ next_state <= puls_uph_state;
+ elsif ea(7) = '1' then
+ next_state <= puls_pch_state;
+ else
+ lic <= '1';
+ next_state <= fetch_state;
+ end if;
+
+ when puls_acca_state =>
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- read acca
+ acca_ctrl <= pull_acca;
+ addr_ctrl <= pulls_ad;
+ if ea(2) = '1' then
+ next_state <= puls_accb_state;
+ elsif ea(3) = '1' then
+ next_state <= puls_dp_state;
+ elsif ea(4) = '1' then
+ next_state <= puls_ixh_state;
+ elsif ea(5) = '1' then
+ next_state <= puls_iyh_state;
+ elsif ea(6) = '1' then
+ next_state <= puls_uph_state;
+ elsif ea(7) = '1' then
+ next_state <= puls_pch_state;
+ else
+ lic <= '1';
+ next_state <= fetch_state;
+ end if;
+
+ when puls_accb_state =>
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- read accb
+ accb_ctrl <= pull_accb;
+ addr_ctrl <= pulls_ad;
+ if ea(3) = '1' then
+ next_state <= puls_dp_state;
+ elsif ea(4) = '1' then
+ next_state <= puls_ixh_state;
+ elsif ea(5) = '1' then
+ next_state <= puls_iyh_state;
+ elsif ea(6) = '1' then
+ next_state <= puls_uph_state;
+ elsif ea(7) = '1' then
+ next_state <= puls_pch_state;
+ else
+ lic <= '1';
+ next_state <= fetch_state;
+ end if;
+
+ when puls_dp_state =>
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- read dp
+ dp_ctrl <= pull_dp;
+ addr_ctrl <= pulls_ad;
+ if ea(4) = '1' then
+ next_state <= puls_ixh_state;
+ elsif ea(5) = '1' then
+ next_state <= puls_iyh_state;
+ elsif ea(6) = '1' then
+ next_state <= puls_uph_state;
+ elsif ea(7) = '1' then
+ next_state <= puls_pch_state;
+ else
+ lic <= '1';
+ next_state <= fetch_state;
+ end if;
+
+ when puls_ixh_state =>
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- pull ix hi
+ ix_ctrl <= pull_hi_ix;
+ addr_ctrl <= pulls_ad;
+ next_state <= puls_ixl_state;
+
+ when puls_ixl_state =>
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- read ix low
+ ix_ctrl <= pull_lo_ix;
+ addr_ctrl <= pulls_ad;
+ if ea(5) = '1' then
+ next_state <= puls_iyh_state;
+ elsif ea(6) = '1' then
+ next_state <= puls_uph_state;
+ elsif ea(7) = '1' then
+ next_state <= puls_pch_state;
+ else
+ lic <= '1';
+ next_state <= fetch_state;
+ end if;
+
+ when puls_iyh_state =>
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- pull iy hi
+ iy_ctrl <= pull_hi_iy;
+ addr_ctrl <= pulls_ad;
+ next_state <= puls_iyl_state;
+
+ when puls_iyl_state =>
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- read iy low
+ iy_ctrl <= pull_lo_iy;
+ addr_ctrl <= pulls_ad;
+ if ea(6) = '1' then
+ next_state <= puls_uph_state;
+ elsif ea(7) = '1' then
+ next_state <= puls_pch_state;
+ else
+ lic <= '1';
+ next_state <= fetch_state;
+ end if;
+
+ when puls_uph_state =>
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- pull up hi
+ up_ctrl <= pull_hi_up;
+ addr_ctrl <= pulls_ad;
+ next_state <= puls_upl_state;
+
+ when puls_upl_state =>
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- read up low
+ up_ctrl <= pull_lo_up;
+ addr_ctrl <= pulls_ad;
+ if ea(7) = '1' then
+ next_state <= puls_pch_state;
+ else
+ lic <= '1';
+ next_state <= fetch_state;
+ end if;
+
+ when puls_pch_state =>
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- pull pc hi
+ pc_ctrl <= pull_hi_pc;
+ addr_ctrl <= pulls_ad;
+ next_state <= puls_pcl_state;
+
+ when puls_pcl_state =>
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- read pc low
+ pc_ctrl <= pull_lo_pc;
+ addr_ctrl <= pulls_ad;
+ lic <= '1';
+ next_state <= fetch_state;
+
+ --
+ -- Enter here on pshu
+ -- ea holds post byte
+ --
+ when pshu_state =>
+ -- decrement up if any registers to be pushed
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ if ea(7 downto 0) = "00000000" then
+ up_ctrl <= latch_up;
+ else
+ up_ctrl <= load_up;
+ end if;
+ -- write idle bus
+ if ea(7) = '1' then
+ next_state <= pshu_pcl_state;
+ elsif ea(6) = '1' then
+ next_state <= pshu_spl_state;
+ elsif ea(5) = '1' then
+ next_state <= pshu_iyl_state;
+ elsif ea(4) = '1' then
+ next_state <= pshu_ixl_state;
+ elsif ea(3) = '1' then
+ next_state <= pshu_dp_state;
+ elsif ea(2) = '1' then
+ next_state <= pshu_accb_state;
+ elsif ea(1) = '1' then
+ next_state <= pshu_acca_state;
+ elsif ea(0) = '1' then
+ next_state <= pshu_cc_state;
+ else
+ lic <= '1';
+ next_state <= fetch_state;
+ end if;
+ --
+ -- push PC onto U stack
+ --
+ when pshu_pcl_state =>
+ -- decrement up
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ up_ctrl <= load_up;
+ -- write pc low
+ addr_ctrl <= pushu_ad;
+ dout_ctrl <= pc_lo_dout;
+ next_state <= pshu_pch_state;
+
+ when pshu_pch_state =>
+ -- decrement up
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ if ea(6 downto 0) = "0000000" then
+ up_ctrl <= latch_up;
+ else
+ up_ctrl <= load_up;
+ end if;
+ -- write pc hi
+ addr_ctrl <= pushu_ad;
+ dout_ctrl <= pc_hi_dout;
+ if ea(6) = '1' then
+ next_state <= pshu_spl_state;
+ elsif ea(5) = '1' then
+ next_state <= pshu_iyl_state;
+ elsif ea(4) = '1' then
+ next_state <= pshu_ixl_state;
+ elsif ea(3) = '1' then
+ next_state <= pshu_dp_state;
+ elsif ea(2) = '1' then
+ next_state <= pshu_accb_state;
+ elsif ea(1) = '1' then
+ next_state <= pshu_acca_state;
+ elsif ea(0) = '1' then
+ next_state <= pshu_cc_state;
+ else
+ lic <= '1';
+ next_state <= fetch_state;
+ end if;
+
+ when pshu_spl_state =>
+ -- decrement up
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ up_ctrl <= load_up;
+ -- write sp low
+ addr_ctrl <= pushu_ad;
+ dout_ctrl <= sp_lo_dout;
+ next_state <= pshu_sph_state;
+
+ when pshu_sph_state =>
+ -- decrement up
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ if ea(5 downto 0) = "000000" then
+ up_ctrl <= latch_up;
+ else
+ up_ctrl <= load_up;
+ end if;
+ -- write sp hi
+ addr_ctrl <= pushu_ad;
+ dout_ctrl <= sp_hi_dout;
+ if ea(5) = '1' then
+ next_state <= pshu_iyl_state;
+ elsif ea(4) = '1' then
+ next_state <= pshu_ixl_state;
+ elsif ea(3) = '1' then
+ next_state <= pshu_dp_state;
+ elsif ea(2) = '1' then
+ next_state <= pshu_accb_state;
+ elsif ea(1) = '1' then
+ next_state <= pshu_acca_state;
+ elsif ea(0) = '1' then
+ next_state <= pshu_cc_state;
+ else
+ lic <= '1';
+ next_state <= fetch_state;
+ end if;
+
+ when pshu_iyl_state =>
+ -- decrement up
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ up_ctrl <= load_up;
+ -- write iy low
+ addr_ctrl <= pushu_ad;
+ dout_ctrl <= iy_lo_dout;
+ next_state <= pshu_iyh_state;
+
+ when pshu_iyh_state =>
+ -- decrement up
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ if ea(4 downto 0) = "00000" then
+ up_ctrl <= latch_up;
+ else
+ up_ctrl <= load_up;
+ end if;
+ -- write iy hi
+ addr_ctrl <= pushu_ad;
+ dout_ctrl <= iy_hi_dout;
+ if ea(4) = '1' then
+ next_state <= pshu_ixl_state;
+ elsif ea(3) = '1' then
+ next_state <= pshu_dp_state;
+ elsif ea(2) = '1' then
+ next_state <= pshu_accb_state;
+ elsif ea(1) = '1' then
+ next_state <= pshu_acca_state;
+ elsif ea(0) = '1' then
+ next_state <= pshu_cc_state;
+ else
+ lic <= '1';
+ next_state <= fetch_state;
+ end if;
+
+ when pshu_ixl_state =>
+ -- decrement up
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ up_ctrl <= load_up;
+ -- write ix low
+ addr_ctrl <= pushu_ad;
+ dout_ctrl <= ix_lo_dout;
+ next_state <= pshu_ixh_state;
+
+ when pshu_ixh_state =>
+ -- decrement up
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ if ea(3 downto 0) = "0000" then
+ up_ctrl <= latch_up;
+ else
+ up_ctrl <= load_up;
+ end if;
+ -- write ix hi
+ addr_ctrl <= pushu_ad;
+ dout_ctrl <= ix_hi_dout;
+ if ea(3) = '1' then
+ next_state <= pshu_dp_state;
+ elsif ea(2) = '1' then
+ next_state <= pshu_accb_state;
+ elsif ea(1) = '1' then
+ next_state <= pshu_acca_state;
+ elsif ea(0) = '1' then
+ next_state <= pshu_cc_state;
+ else
+ lic <= '1';
+ next_state <= fetch_state;
+ end if;
+
+ when pshu_dp_state =>
+ -- decrement up
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ if ea(2 downto 0) = "000" then
+ up_ctrl <= latch_up;
+ else
+ up_ctrl <= load_up;
+ end if;
+ -- write dp
+ addr_ctrl <= pushu_ad;
+ dout_ctrl <= dp_dout;
+ if ea(2) = '1' then
+ next_state <= pshu_accb_state;
+ elsif ea(1) = '1' then
+ next_state <= pshu_acca_state;
+ elsif ea(0) = '1' then
+ next_state <= pshu_cc_state;
+ else
+ lic <= '1';
+ next_state <= fetch_state;
+ end if;
+
+ when pshu_accb_state =>
+ -- decrement up
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ if ea(1 downto 0) = "00" then
+ up_ctrl <= latch_up;
+ else
+ up_ctrl <= load_up;
+ end if;
+ -- write accb
+ addr_ctrl <= pushu_ad;
+ dout_ctrl <= accb_dout;
+ if ea(1) = '1' then
+ next_state <= pshu_acca_state;
+ elsif ea(0) = '1' then
+ next_state <= pshu_cc_state;
+ else
+ lic <= '1';
+ next_state <= fetch_state;
+ end if;
+
+ when pshu_acca_state =>
+ -- decrement up
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ if ea(0) = '0' then
+ up_ctrl <= latch_up;
+ else
+ up_ctrl <= load_up;
+ end if;
+ -- write acca
+ addr_ctrl <= pushu_ad;
+ dout_ctrl <= acca_dout;
+ if ea(0) = '1' then
+ next_state <= pshu_cc_state;
+ else
+ lic <= '1';
+ next_state <= fetch_state;
+ end if;
+
+ when pshu_cc_state =>
+ -- idle up
+ -- write cc
+ addr_ctrl <= pushu_ad;
+ dout_ctrl <= cc_dout;
+ lic <= '1';
+ next_state <= fetch_state;
+
+ --
+ -- enter here on PULU
+ -- ea hold register mask
+ --
+ when pulu_state =>
+ -- idle UP
+ -- idle bus
+ if ea(0) = '1' then
+ next_state <= pulu_cc_state;
+ elsif ea(1) = '1' then
+ next_state <= pulu_acca_state;
+ elsif ea(2) = '1' then
+ next_state <= pulu_accb_state;
+ elsif ea(3) = '1' then
+ next_state <= pulu_dp_state;
+ elsif ea(4) = '1' then
+ next_state <= pulu_ixh_state;
+ elsif ea(5) = '1' then
+ next_state <= pulu_iyh_state;
+ elsif ea(6) = '1' then
+ next_state <= pulu_sph_state;
+ elsif ea(7) = '1' then
+ next_state <= pulu_pch_state;
+ else
+ lic <= '1';
+ next_state <= fetch_state;
+ end if;
+
+ when pulu_cc_state =>
+ -- increment up
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ up_ctrl <= load_up;
+ -- read cc
+ cc_ctrl <= pull_cc;
+ addr_ctrl <= pullu_ad;
+ if ea(1) = '1' then
+ next_state <= pulu_acca_state;
+ elsif ea(2) = '1' then
+ next_state <= pulu_accb_state;
+ elsif ea(3) = '1' then
+ next_state <= pulu_dp_state;
+ elsif ea(4) = '1' then
+ next_state <= pulu_ixh_state;
+ elsif ea(5) = '1' then
+ next_state <= pulu_iyh_state;
+ elsif ea(6) = '1' then
+ next_state <= pulu_sph_state;
+ elsif ea(7) = '1' then
+ next_state <= pulu_pch_state;
+ else
+ lic <= '1';
+ next_state <= fetch_state;
+ end if;
+
+ when pulu_acca_state =>
+ -- increment up
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ up_ctrl <= load_up;
+ -- read acca
+ acca_ctrl <= pull_acca;
+ addr_ctrl <= pullu_ad;
+ if ea(2) = '1' then
+ next_state <= pulu_accb_state;
+ elsif ea(3) = '1' then
+ next_state <= pulu_dp_state;
+ elsif ea(4) = '1' then
+ next_state <= pulu_ixh_state;
+ elsif ea(5) = '1' then
+ next_state <= pulu_iyh_state;
+ elsif ea(6) = '1' then
+ next_state <= pulu_sph_state;
+ elsif ea(7) = '1' then
+ next_state <= pulu_pch_state;
+ else
+ lic <= '1';
+ next_state <= fetch_state;
+ end if;
+
+ when pulu_accb_state =>
+ -- increment up
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ up_ctrl <= load_up;
+ -- read accb
+ accb_ctrl <= pull_accb;
+ addr_ctrl <= pullu_ad;
+ if ea(3) = '1' then
+ next_state <= pulu_dp_state;
+ elsif ea(4) = '1' then
+ next_state <= pulu_ixh_state;
+ elsif ea(5) = '1' then
+ next_state <= pulu_iyh_state;
+ elsif ea(6) = '1' then
+ next_state <= pulu_sph_state;
+ elsif ea(7) = '1' then
+ next_state <= pulu_pch_state;
+ else
+ lic <= '1';
+ next_state <= fetch_state;
+ end if;
+
+ when pulu_dp_state =>
+ -- increment up
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ up_ctrl <= load_up;
+ -- read dp
+ dp_ctrl <= pull_dp;
+ addr_ctrl <= pullu_ad;
+ if ea(4) = '1' then
+ next_state <= pulu_ixh_state;
+ elsif ea(5) = '1' then
+ next_state <= pulu_iyh_state;
+ elsif ea(6) = '1' then
+ next_state <= pulu_sph_state;
+ elsif ea(7) = '1' then
+ next_state <= pulu_pch_state;
+ else
+ lic <= '1';
+ next_state <= fetch_state;
+ end if;
+
+ when pulu_ixh_state =>
+ -- increment up
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ up_ctrl <= load_up;
+ -- read ix hi
+ ix_ctrl <= pull_hi_ix;
+ addr_ctrl <= pullu_ad;
+ next_state <= pulu_ixl_state;
+
+ when pulu_ixl_state =>
+ -- increment up
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ up_ctrl <= load_up;
+ -- read ix low
+ ix_ctrl <= pull_lo_ix;
+ addr_ctrl <= pullu_ad;
+ if ea(5) = '1' then
+ next_state <= pulu_iyh_state;
+ elsif ea(6) = '1' then
+ next_state <= pulu_sph_state;
+ elsif ea(7) = '1' then
+ next_state <= pulu_pch_state;
+ else
+ lic <= '1';
+ next_state <= fetch_state;
+ end if;
+
+ when pulu_iyh_state =>
+ -- increment up
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ up_ctrl <= load_up;
+ -- read iy hi
+ iy_ctrl <= pull_hi_iy;
+ addr_ctrl <= pullu_ad;
+ next_state <= pulu_iyl_state;
+
+ when pulu_iyl_state =>
+ -- increment up
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ up_ctrl <= load_up;
+ -- read iy low
+ iy_ctrl <= pull_lo_iy;
+ addr_ctrl <= pullu_ad;
+ if ea(6) = '1' then
+ next_state <= pulu_sph_state;
+ elsif ea(7) = '1' then
+ next_state <= pulu_pch_state;
+ else
+ lic <= '1';
+ next_state <= fetch_state;
+ end if;
+
+ when pulu_sph_state =>
+ -- increment up
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ up_ctrl <= load_up;
+ -- read sp hi
+ sp_ctrl <= pull_hi_sp;
+ addr_ctrl <= pullu_ad;
+ next_state <= pulu_spl_state;
+
+ when pulu_spl_state =>
+ -- increment up
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ up_ctrl <= load_up;
+ -- read sp low
+ sp_ctrl <= pull_lo_sp;
+ addr_ctrl <= pullu_ad;
+ if ea(7) = '1' then
+ next_state <= pulu_pch_state;
+ else
+ lic <= '1';
+ next_state <= fetch_state;
+ end if;
+
+ when pulu_pch_state =>
+ -- increment up
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ up_ctrl <= load_up;
+ -- pull pc hi
+ pc_ctrl <= pull_hi_pc;
+ addr_ctrl <= pullu_ad;
+ next_state <= pulu_pcl_state;
+
+ when pulu_pcl_state =>
+ -- increment up
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ up_ctrl <= load_up;
+ -- read pc low
+ pc_ctrl <= pull_lo_pc;
+ addr_ctrl <= pullu_ad;
+ lic <= '1';
+ next_state <= fetch_state;
+
+ --
+ -- pop the Condition codes
+ --
+ when rti_cc_state =>
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- read cc
+ cc_ctrl <= pull_cc;
+ addr_ctrl <= pulls_ad;
+ next_state <= rti_entire_state;
+
+ --
+ -- Added RTI cycle 11th July 2006 John Kent.
+ -- test the "Entire" Flag
+ -- that has just been popped off the stack
+ --
+ when rti_entire_state =>
+ --
+ -- The Entire flag must be recovered from the stack
+ -- before testing.
+ --
+ if cc(EBIT) = '1' then
+ next_state <= rti_acca_state;
+ else
+ next_state <= rti_pch_state;
+ end if;
+
+ when rti_acca_state =>
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- read acca
+ acca_ctrl <= pull_acca;
+ addr_ctrl <= pulls_ad;
+ next_state <= rti_accb_state;
+
+ when rti_accb_state =>
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- read accb
+ accb_ctrl <= pull_accb;
+ addr_ctrl <= pulls_ad;
+ next_state <= rti_dp_state;
+
+ when rti_dp_state =>
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- read dp
+ dp_ctrl <= pull_dp;
+ addr_ctrl <= pulls_ad;
+ next_state <= rti_ixh_state;
+
+ when rti_ixh_state =>
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- read ix hi
+ ix_ctrl <= pull_hi_ix;
+ addr_ctrl <= pulls_ad;
+ next_state <= rti_ixl_state;
+
+ when rti_ixl_state =>
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- read ix low
+ ix_ctrl <= pull_lo_ix;
+ addr_ctrl <= pulls_ad;
+ next_state <= rti_iyh_state;
+
+ when rti_iyh_state =>
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- read iy hi
+ iy_ctrl <= pull_hi_iy;
+ addr_ctrl <= pulls_ad;
+ next_state <= rti_iyl_state;
+
+ when rti_iyl_state =>
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- read iy low
+ iy_ctrl <= pull_lo_iy;
+ addr_ctrl <= pulls_ad;
+ next_state <= rti_uph_state;
+
+
+ when rti_uph_state =>
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- read up hi
+ up_ctrl <= pull_hi_up;
+ addr_ctrl <= pulls_ad;
+ next_state <= rti_upl_state;
+
+ when rti_upl_state =>
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- read up low
+ up_ctrl <= pull_lo_up;
+ addr_ctrl <= pulls_ad;
+ next_state <= rti_pch_state;
+
+ when rti_pch_state =>
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- pull pc hi
+ pc_ctrl <= pull_hi_pc;
+ addr_ctrl <= pulls_ad;
+ next_state <= rti_pcl_state;
+
+ when rti_pcl_state =>
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- pull pc low
+ pc_ctrl <= pull_lo_pc;
+ addr_ctrl <= pulls_ad;
+ lic <= '1';
+ next_state <= fetch_state;
+
+ --
+ -- here on NMI interrupt
+ -- Complete execute cycle of the last instruction.
+ -- If it was a dual operand instruction
+ --
+ when int_nmi_state =>
+ next_state <= int_nmi1_state;
+
+ -- Idle bus cycle
+ when int_nmi1_state =>
+ -- pre decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ iv_ctrl <= nmi_iv;
+ st_ctrl <= push_st;
+ return_state <= int_nmimask_state;
+ next_state <= int_entire_state;
+
+ --
+ -- here on IRQ interrupt
+ -- Complete execute cycle of the last instruction.
+ -- If it was a dual operand instruction
+ --
+ when int_irq_state =>
+ next_state <= int_irq1_state;
+
+ -- pre decrement the sp
+ -- Idle bus cycle
+ when int_irq1_state =>
+ -- pre decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ iv_ctrl <= irq_iv;
+ st_ctrl <= push_st;
+ return_state <= int_irqmask_state;
+ next_state <= int_entire_state;
+
+ --
+ -- here on FIRQ interrupt
+ -- Complete execution cycle of the last instruction
+ -- if it was a dual operand instruction
+ --
+ when int_firq_state =>
+ next_state <= int_firq1_state;
+
+ -- Idle bus cycle
+ when int_firq1_state =>
+ -- pre decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ iv_ctrl <= firq_iv;
+ st_ctrl <= push_st;
+ return_state <= int_firqmask_state;
+ next_state <= int_fast_state;
+
+ --
+ -- CWAI entry point
+ -- stack pointer already pre-decremented
+ -- mask condition codes
+ --
+ when cwai_state =>
+ -- AND CC with md
+ left_ctrl <= md_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_andcc;
+ cc_ctrl <= load_cc;
+ st_ctrl <= push_st;
+ return_state <= int_cwai_state;
+ next_state <= int_entire_state;
+
+ --
+ -- wait here for an interrupt
+ --
+ when int_cwai_state =>
+ if (nmi_req = '1') then
+ iv_ctrl <= nmi_iv;
+ next_state <= int_nmimask_state;
+ --
+ -- FIRQ & IRQ are level sensitive
+ --
+ elsif (firq = '1') and (cc(FBIT) = '0') then
+ iv_ctrl <= firq_iv;
+ next_state <= int_firqmask_state;
+
+ elsif (irq = '1') and (cc(IBIT) = '0') then
+ iv_ctrl <= irq_iv;
+ next_state <= int_irqmask_state;
+ else
+ next_state <= int_cwai_state;
+ end if;
+
+ --
+ -- State to mask I Flag and F Flag (NMI)
+ --
+ when int_nmimask_state =>
+ alu_ctrl <= alu_seif;
+ cc_ctrl <= load_cc;
+ next_state <= vect_hi_state;
+
+ --
+ -- State to mask I Flag and F Flag (FIRQ)
+ --
+ when int_firqmask_state =>
+ alu_ctrl <= alu_seif;
+ cc_ctrl <= load_cc;
+ next_state <= vect_hi_state;
+
+
+ --
+ -- State to mask I Flag and F Flag (SWI)
+ --
+ when int_swimask_state =>
+ alu_ctrl <= alu_seif;
+ cc_ctrl <= load_cc;
+ next_state <= vect_hi_state;
+
+ --
+ -- State to mask I Flag only (IRQ)
+ --
+ when int_irqmask_state =>
+ alu_ctrl <= alu_sei;
+ cc_ctrl <= load_cc;
+ next_state <= vect_hi_state;
+
+ --
+ -- set Entire Flag on SWI, SWI2, SWI3 and CWAI, IRQ and NMI
+ -- before stacking all registers
+ --
+ when int_entire_state =>
+ -- set entire flag
+ alu_ctrl <= alu_see;
+ cc_ctrl <= load_cc;
+ next_state <= int_pcl_state;
+
+ --
+ -- clear Entire Flag on FIRQ
+ -- before stacking all registers
+ --
+ when int_fast_state =>
+ -- clear entire flag
+ alu_ctrl <= alu_cle;
+ cc_ctrl <= load_cc;
+ next_state <= int_pcl_state;
+
+ when int_pcl_state =>
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ -- write pc low
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= pc_lo_dout;
+ next_state <= int_pch_state;
+
+ when int_pch_state =>
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ -- write pc hi
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= pc_hi_dout;
+ if cc(EBIT) = '1' then
+ next_state <= int_upl_state;
+ else
+ next_state <= int_cc_state;
+ end if;
+
+ when int_upl_state =>
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ -- write up low
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= up_lo_dout;
+ next_state <= int_uph_state;
+
+ when int_uph_state =>
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ -- write ix hi
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= up_hi_dout;
+ next_state <= int_iyl_state;
+
+ when int_iyl_state =>
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ -- write ix low
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= iy_lo_dout;
+ next_state <= int_iyh_state;
+
+ when int_iyh_state =>
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ -- write ix hi
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= iy_hi_dout;
+ next_state <= int_ixl_state;
+
+ when int_ixl_state =>
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ -- write ix low
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= ix_lo_dout;
+ next_state <= int_ixh_state;
+
+ when int_ixh_state =>
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ -- write ix hi
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= ix_hi_dout;
+ next_state <= int_dp_state;
+
+ when int_dp_state =>
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ -- write accb
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= dp_dout;
+ next_state <= int_accb_state;
+
+ when int_accb_state =>
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ -- write accb
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= accb_dout;
+ next_state <= int_acca_state;
+
+ when int_acca_state =>
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ -- write acca
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= acca_dout;
+ next_state <= int_cc_state;
+
+ when int_cc_state =>
+ -- write cc
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= cc_dout;
+ next_state <= saved_state;
+
+ --
+ -- According to the 6809 programming manual:
+ -- If an interrupt is received and is masked
+ -- or lasts for less than three cycles, the PC
+ -- will advance to the next instruction.
+ -- If an interrupt is unmasked and lasts
+ -- for more than three cycles, an interrupt
+ -- will be generated.
+ -- Note that I don't wait 3 clock cycles.
+ -- John Kent 11th July 2006
+ --
+ when sync_state =>
+ lic <= '1';
+ ba <= '1';
+ --
+ -- Version 1.28 2015-05-30
+ -- Exit sync_state on interrupt.
+ -- If the interrupts are active
+ -- they will be caught in the state_machine process
+ -- and the interrupt service routine microcode will be executed.
+ -- Masked interrupts will exit the sync_state.
+ -- Moved from the state_machine process to the state_sequencer process
+ --
+ if (firq = '1') or (irq = '1') then
+ next_state <= fetch_state;
+ else
+ next_state <= sync_state;
+ end if;
+
+ when halt_state =>
+ --
+ -- 2011-10-30 John Kent
+ -- ba & bs should be high
+ ba <= '1';
+ bs <= '1';
+ if halt = '1' then
+ next_state <= halt_state;
+ else
+ next_state <= fetch_state;
+ end if;
+
+ end case;
+
+--
+-- Ver 1.23 2011-10-30 John Kent
+-- First instruction cycle might be
+-- fetch_state
+-- halt_state
+-- int_nmirq_state
+-- int_firq_state
+--
+ if fic = '1' then
+ --
+ case op_code(7 downto 6) is
+ when "10" => -- acca
+ 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;
+ when "0001" => -- cmpa
+ left_ctrl <= acca_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_sub8;
+ cc_ctrl <= load_cc;
+ when "0010" => -- sbca
+ left_ctrl <= acca_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_sbc;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_acca;
+ when "0011" =>
+ case pre_code is
+ when "00010000" => -- page 2 -- cmpd
+ left_ctrl <= accd_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_sub16;
+ cc_ctrl <= load_cc;
+ when "00010001" => -- page 3 -- cmpu
+ left_ctrl <= up_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_sub16;
+ cc_ctrl <= load_cc;
+ when others => -- page 1 -- 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;
+ end case;
+ when "0100" => -- anda
+ left_ctrl <= acca_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_and;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_acca;
+ when "0101" => -- bita
+ left_ctrl <= acca_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_and;
+ cc_ctrl <= load_cc;
+ when "0110" => -- ldaa
+ left_ctrl <= acca_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_ld8;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_acca;
+ when "0111" => -- staa
+ left_ctrl <= acca_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_st8;
+ cc_ctrl <= load_cc;
+ when "1000" => -- eora
+ left_ctrl <= acca_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_eor;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_acca;
+ when "1001" => -- adca
+ left_ctrl <= acca_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_adc;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_acca;
+ when "1010" => -- oraa
+ left_ctrl <= acca_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_ora;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_acca;
+ when "1011" => -- adda
+ left_ctrl <= acca_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_add8;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_acca;
+ when "1100" =>
+ case pre_code is
+ when "00010000" => -- page 2 -- cmpy
+ left_ctrl <= iy_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_sub16;
+ cc_ctrl <= load_cc;
+ when "00010001" => -- page 3 -- cmps
+ left_ctrl <= sp_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_sub16;
+ cc_ctrl <= load_cc;
+ when others => -- page 1 -- cmpx
+ left_ctrl <= ix_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_sub16;
+ cc_ctrl <= load_cc;
+ end case;
+ when "1101" => -- bsr / jsr
+ null;
+ when "1110" => -- ldx
+ case pre_code is
+ when "00010000" => -- page 2 -- ldy
+ left_ctrl <= iy_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_ld16;
+ cc_ctrl <= load_cc;
+ iy_ctrl <= load_iy;
+ when others => -- page 1 -- ldx
+ left_ctrl <= ix_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_ld16;
+ cc_ctrl <= load_cc;
+ ix_ctrl <= load_ix;
+ end case;
+ when "1111" => -- stx
+ case pre_code is
+ when "00010000" => -- page 2 -- sty
+ left_ctrl <= iy_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_st16;
+ cc_ctrl <= load_cc;
+ when others => -- page 1 -- stx
+ left_ctrl <= ix_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_st16;
+ cc_ctrl <= load_cc;
+ end case;
+ when others =>
+ null;
+ end case;
+ when "11" => -- accb dual op
+ 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;
+ accb_ctrl <= load_accb;
+ when "0001" => -- cmpb
+ left_ctrl <= accb_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_sub8;
+ cc_ctrl <= load_cc;
+ when "0010" => -- sbcb
+ left_ctrl <= accb_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_sbc;
+ cc_ctrl <= load_cc;
+ accb_ctrl <= load_accb;
+ 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;
+ when "0100" => -- andb
+ left_ctrl <= accb_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_and;
+ cc_ctrl <= load_cc;
+ accb_ctrl <= load_accb;
+ when "0101" => -- bitb
+ left_ctrl <= accb_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_and;
+ cc_ctrl <= load_cc;
+ when "0110" => -- ldab
+ left_ctrl <= accb_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_ld8;
+ cc_ctrl <= load_cc;
+ accb_ctrl <= load_accb;
+ when "0111" => -- stab
+ left_ctrl <= accb_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_st8;
+ cc_ctrl <= load_cc;
+ when "1000" => -- eorb
+ left_ctrl <= accb_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_eor;
+ cc_ctrl <= load_cc;
+ accb_ctrl <= load_accb;
+ when "1001" => -- adcb
+ left_ctrl <= accb_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_adc;
+ cc_ctrl <= load_cc;
+ accb_ctrl <= load_accb;
+ when "1010" => -- orab
+ left_ctrl <= accb_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_ora;
+ cc_ctrl <= load_cc;
+ accb_ctrl <= load_accb;
+ when "1011" => -- addb
+ left_ctrl <= accb_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_add8;
+ cc_ctrl <= load_cc;
+ accb_ctrl <= load_accb;
+ 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;
+ when "1101" => -- std
+ left_ctrl <= accd_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_st16;
+ cc_ctrl <= load_cc;
+ when "1110" => -- ldu
+ case pre_code is
+ when "00010000" => -- page 2 -- lds
+ left_ctrl <= sp_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_ld16;
+ cc_ctrl <= load_cc;
+ sp_ctrl <= load_sp;
+ when others => -- page 1 -- ldu
+ left_ctrl <= up_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_ld16;
+ cc_ctrl <= load_cc;
+ up_ctrl <= load_up;
+ end case;
+ when "1111" =>
+ case pre_code is
+ when "00010000" => -- page 2 -- sts
+ left_ctrl <= sp_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_st16;
+ cc_ctrl <= load_cc;
+ when others => -- page 1 -- stu
+ left_ctrl <= up_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_st16;
+ cc_ctrl <= load_cc;
+ end case;
+ when others =>
+ null;
+ end case;
+ when others =>
+ null;
+ end case;
+
+ end if; -- first instruction cycle (fic)
+ lic_out <= lic;
+end process;
+
+end rtl;
+
diff --git a/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/rtl/cpu68.vhd b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/rtl/cpu68.vhd
new file mode 100644
index 00000000..016bd9a9
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/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/Mayday/rtl/dac.vhd b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/rtl/dac.vhd
new file mode 100644
index 00000000..47b2185e
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/rtl/dac.vhd
@@ -0,0 +1,48 @@
+-------------------------------------------------------------------------------
+--
+-- Delta-Sigma DAC
+--
+-- Refer to Xilinx Application Note XAPP154.
+--
+-- This DAC requires an external RC low-pass filter:
+--
+-- dac_o 0---XXXXX---+---0 analog audio
+-- 3k3 |
+-- === 4n7
+-- |
+-- GND
+--
+-------------------------------------------------------------------------------
+
+library ieee;
+ use ieee.std_logic_1164.all;
+ use ieee.numeric_std.all;
+
+entity dac is
+ generic (
+ C_bits : integer := 10
+ );
+ port (
+ clk_i : in std_logic;
+ res_n_i : in std_logic;
+ dac_i : in std_logic_vector(C_bits-1 downto 0);
+ dac_o : out std_logic
+ );
+end dac;
+
+architecture rtl of dac is
+ signal sig_in: unsigned(C_bits downto 0);
+begin
+ seq: process(clk_i, res_n_i)
+ begin
+ if res_n_i = '0' then
+ sig_in <= to_unsigned(2**C_bits, sig_in'length);
+ dac_o <= '0';
+ elsif rising_edge(clk_i) then
+ -- not dac_i(C_bits-1) effectively adds 0x8..0 to dac_i
+ --sig_in <= sig_in + unsigned(sig_in(C_bits) & (not dac_i(C_bits-1)) & dac_i(C_bits-2 downto 0));
+ sig_in <= sig_in + unsigned(sig_in(C_bits) & dac_i);
+ dac_o <= sig_in(C_bits);
+ end if;
+ end process seq;
+end rtl;
diff --git a/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/rtl/data_io.v b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/rtl/data_io.v
new file mode 100644
index 00000000..4ca9518c
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/rtl/data_io.v
@@ -0,0 +1,115 @@
+//
+// data_io.v
+//
+// data_io for the MiST board
+// http://code.google.com/p/mist-board/
+//
+// Copyright (c) 2014 Till Harbaum
+//
+// 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 data_io
+(
+ input clk_sys,
+ input SPI_SCK,
+ input SPI_SS2,
+ input SPI_DI,
+
+ // ARM -> FPGA download
+ output reg ioctl_download = 0, // signal indicating an active download
+ output reg [7:0] ioctl_index, // menu index used to upload the file
+ output ioctl_wr,
+ output reg [24:0] ioctl_addr,
+ output reg [7:0] ioctl_dout
+);
+
+/////////////////////////////// DOWNLOADING ///////////////////////////////
+
+reg [7:0] data_w;
+reg [24:0] addr_w;
+reg rclk = 0;
+
+localparam UIO_FILE_TX = 8'h53;
+localparam UIO_FILE_TX_DAT = 8'h54;
+localparam UIO_FILE_INDEX = 8'h55;
+
+// data_io has its own SPI interface to the io controller
+always@(posedge SPI_SCK, posedge SPI_SS2) begin
+ reg [6:0] sbuf;
+ reg [7:0] cmd;
+ reg [4:0] cnt;
+ reg [24:0] addr;
+
+ if(SPI_SS2) cnt <= 0;
+ else begin
+ rclk <= 0;
+
+ // don't shift in last bit. It is evaluated directly
+ // when writing to ram
+ if(cnt != 15) sbuf <= { sbuf[5:0], SPI_DI};
+
+ // increase target address after write
+ if(rclk) addr <= addr + 1'd1;
+
+ // count 0-7 8-15 8-15 ...
+ if(cnt < 15) cnt <= cnt + 1'd1;
+ else cnt <= 8;
+
+ // finished command byte
+ if(cnt == 7) cmd <= {sbuf, SPI_DI};
+
+ // prepare/end transmission
+ if((cmd == UIO_FILE_TX) && (cnt == 15)) begin
+ // prepare
+ if(SPI_DI) begin
+ addr <= 0;
+ ioctl_download <= 1;
+ end else begin
+ addr_w <= addr;
+ ioctl_download <= 0;
+ end
+ end
+
+ // command 0x54: UIO_FILE_TX
+ if((cmd == UIO_FILE_TX_DAT) && (cnt == 15)) begin
+ addr_w <= addr;
+ data_w <= {sbuf, SPI_DI};
+ rclk <= 1;
+ end
+
+ // expose file (menu) index
+ if((cmd == UIO_FILE_INDEX) && (cnt == 15)) ioctl_index <= {sbuf, SPI_DI};
+ end
+end
+
+assign ioctl_wr = |ioctl_wrd;
+reg [1:0] ioctl_wrd;
+
+always@(negedge clk_sys) begin
+ reg rclkD, rclkD2;
+
+ rclkD <= rclk;
+ rclkD2 <= rclkD;
+ ioctl_wrd<= {ioctl_wrd[0],1'b0};
+
+ if(rclkD & ~rclkD2) begin
+ ioctl_dout <= data_w;
+ ioctl_addr <= addr_w;
+ ioctl_wrd <= 2'b11;
+ end
+end
+
+endmodule
diff --git a/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/rtl/defender.vhd b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/rtl/defender.vhd
new file mode 100644
index 00000000..847e141a
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/rtl/defender.vhd
@@ -0,0 +1,797 @@
+---------------------------------------------------------------------------------
+-- Defender by Dar (darfpga@aol.fr)
+-- http://darfpga.blogspot.fr
+---------------------------------------------------------------------------------
+-- gen_ram.vhd & io_ps2_keyboard
+--------------------------------
+-- Copyright 2005-2008 by Peter Wendrich (pwsoft@syntiac.com)
+-- http://www.syntiac.com/fpga64.html
+---------------------------------------------------------------------------------
+-- cpu09l - Version : 0128
+-- Synthesizable 6809 instruction compatible VHDL CPU core
+-- Copyright (C) 2003 - 2010 John Kent
+---------------------------------------------------------------------------------
+-- 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
+---------------------------------------------------------------------------------
+-- Features :
+-- TV 15KHz mode only (atm)
+-- Cocktail mode : OK
+--
+-- Use with MAME roms from defender.zip
+--
+-- Use make_defender_proms.bat to build vhd file and bin from binaries
+--
+-- Defender Hardware caracteristics :
+--
+-- 1x6809 CPU accessing program rom and shared ram/devices
+-- 3x16Ko video and working ram
+-- 26Ko program roms
+-- 1 pia for player I/O
+-- 1 pia service switches, irq and sound selection to sound board
+--
+-- 384 pixels x 260 line video scan, 16 colors per pixel
+-- Ram palette 16 colors among 256 colors (3 red bits,3 green bits, 2 blue bits)
+--
+-- 2 decoder proms for video scan and cocktail/upright flip
+--
+-- No sprites, no char tiles
+--
+-- 128x4 cmos ram (see defender_cmos_ram.vhd for initial values)
+-- No save when power off (see also defender_cmos_ram.vhd)
+--
+-- 1x6808/02
+-- 128x8 working ram
+-- 4k program rom
+-- 1 pia for sound selection cmd input and audio samples output
+
+---------------------------------------------------------------------------------
+
+---------------------------------------------------------------------------------
+-- defender cmos data (see also defender_cmos_ram.vhd)
+-- (ram is 128x4 => only 4 bits/address, that is only 1 hex digit/address)
+--
+-- @ values - (fonction) meaning
+
+-- 0 0 - ?
+-- 1 0005 - (01) coins left
+-- 5 0000 - (02) coins center
+-- 9 0000 - (03) coins right
+-- 13 0005 - (04) total paid
+-- 17 0000 - (05) ships won
+---21 0000 - (06) total time
+-- 25 0003 - (07) total ships
+
+-- -- 8 entries of 6 digits highscore + 3 ascii letters
+
+-- 29 021270 44 52 4A
+-- 41 018315 53 41 4D
+-- 53 015920 4C 45 44
+-- 65 014285 50 47 44
+-- 77 012520 43 52 42
+-- 89 011035 4D 52 53
+-- 101 008265 53 53 52
+-- 113 006010 54 4D 48
+
+-- 125 00 - credits
+-- 127 5 - ?
+
+-- -- protected data writeable only with coin door opened
+
+-- 128 A - ?
+-- 129 0100 - (08) bonus ship level
+-- 133 03 - (09) nb ships
+-- 135 03 - (10) coinage select
+-- 137 01 - (11) left coin mult
+-- 139 04 - (12) center coin mult
+-- 141 01 - (13) right coin mult
+-- 143 01 - (14) coins for credit
+-- 145 00 - (15) coins for bonus
+-- 147 00 - (16) minimum coins
+-- 149 00 - (17) free play
+-- 151 05 - (18) game adjust 1 Stating difficulty 0=lib; 1=mod; 2=cons
+-- 153 15 - (19) game adjust 2 Progessive wave diff. limit > 4-25
+-- 155 01 - (20) game adjust 3 Background sound 0=off; 1=on
+-- 157 05 - (21) game adjust 4 Planet restore wave number
+-- 159 00 - (22) game adjust 5
+-- 161 00 - (23) game adjust 6
+-- 163 00 - (24) game adjust 7
+-- 165 00 - (25) game adjust 8
+-- 167 00 - (26) game adjust 9
+-- 169 00 - (27) game adjust 10
+
+-- 171 00000 - ?
+-- 176 0000000000000000 - ?
+-- 192 0000000000000000 - ?
+-- 208 0000000000000000 - ?
+-- 224 0000000000000000 - ?
+-- 240 0000000000000000 - ?
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_unsigned.all;
+use ieee.numeric_std.all;
+
+entity defender is
+port(
+ clk_sys : in std_logic;
+ clock_6 : in std_logic;
+ clk_1p79 : in std_logic;
+ clk_0p89 : in std_logic;
+ reset : in std_logic;
+
+ dbg_cpu_addr : out std_logic_vector(15 downto 0);
+-- tv15Khz_mode : in std_logic;
+ video_r : out std_logic_vector(2 downto 0);
+ video_g : out std_logic_vector(2 downto 0);
+ video_b : out std_logic_vector(1 downto 0);
+-- video_clk : out std_logic;
+ video_csync : out std_logic;
+ video_blankn : out std_logic;
+ video_hs : out std_logic;
+ video_vs : out std_logic;
+
+ audio_out : out std_logic_vector(7 downto 0);
+
+ roms_addr : out std_logic_vector(14 downto 0);
+ roms_do : in std_logic_vector( 7 downto 0);
+
+
+
+ btn_auto_up : in std_logic;
+ btn_advance : in std_logic;
+ btn_service : in std_logic;
+
+ btn_left_coin : in std_logic;
+ btn_one_player : in std_logic;
+ btn_two_players: in std_logic;
+
+ btn_ffire : in std_logic;
+ btn_bfire : in std_logic;
+ btn_mayday : in std_logic;
+
+ btn_right : in std_logic;
+ btn_down : in std_logic;
+ btn_up : in std_logic;
+
+ sw_coktail_table : in std_logic;
+
+ cmd_select_players_btn : out std_logic
+
+);
+end defender;
+
+architecture struct of defender is
+
+ signal reset_n: std_logic;
+ signal clock_div : std_logic_vector(1 downto 0);
+
+ signal clock_6n : std_logic;
+
+ signal cpu_clock : std_logic;
+ signal cpu_a : std_logic_vector(15 downto 0);
+ 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 wram_addr : std_logic_vector(13 downto 0);
+ signal wram_we : std_logic;
+ signal wram0_do : std_logic_vector( 7 downto 0);
+ signal wram0_we : std_logic;
+ signal wram1_do : std_logic_vector( 7 downto 0);
+ signal wram1_we : std_logic;
+ signal wram2_do : std_logic_vector( 7 downto 0);
+ signal wram2_we : std_logic;
+
+ --signal roms_addr : std_logic_vector(14 downto 0);
+ --signal roms_do : std_logic_vector( 7 downto 0);
+
+ signal roms_io_do : std_logic_vector( 7 downto 0);
+
+ signal io_we : std_logic;
+ signal io_CS : std_logic;
+
+ signal rom_page : std_logic_vector( 2 downto 0);
+ signal rom_page_we : std_logic;
+
+ signal screen_ctrl : std_logic;
+ signal screen_ctrl_we : std_logic;
+
+ signal cmos_do : std_logic_vector(3 downto 0);
+ signal cmos_we : std_logic;
+
+ signal palette_addr : std_logic_vector(3 downto 0);
+ signal palette_we : std_logic;
+ signal palette_di : std_logic_vector( 7 downto 0);
+ signal palette_do : std_logic_vector( 7 downto 0);
+
+ signal pias_clock : std_logic;
+
+-- pia io port a
+-- bit 0 Fire
+-- bit 1 Thrust
+-- bit 2 Smart Bomb
+-- bit 3 HyperSpace
+-- bit 4 2 Players
+-- bit 5 1 Player
+-- bit 6 Reverse
+-- bit 7 Down
+
+-- pia io port b
+-- bit 0 Up
+-- bit 7 1 for coktail table, 0 for upright cabinet
+-- other <= GND
+
+-- pia io ca/cb
+-- ca1, ca2, cb1 <= GND
+-- cb2 ouput + w2_jumper => select player 1/2 buttons for COCktail table
+
+ signal pia_io_CS : std_logic;
+ signal pia_io_rw_n : std_logic;
+ signal pia_io_do : std_logic_vector( 7 downto 0);
+ signal pia_io_pa_i : std_logic_vector( 7 downto 0);
+ signal pia_io_pb_i : std_logic_vector( 7 downto 0);
+ signal pia_io_cb2_o : std_logic;
+
+ -- pia rom board port a
+ -- bit 0 Auto Up / manual Down
+ -- bit 1 Advance
+ -- bit 2 Right Coin (nc)
+ -- bit 3 High Score Reset
+ -- bit 4 Left Coin
+ -- bit 5 Center Coin (nc)
+ -- bit 6 led 2 (output)
+ -- bit 7 led 1 (output)
+
+ -- pia rom board port b
+ -- bit 0-5 to sound board (output)
+ -- bit 6 led 4 (output)
+ -- bit 7 led 3 (output)
+
+ -- pia rom board ca/cb
+ -- ca1 count 240
+ -- ca2 coin door pin 7 (nc)
+ -- cb1 4ms
+ -- cb2 sound board pin 8 (H5-nc)
+
+ signal pia_ROM_CS : std_logic;
+ signal pia_rom_rw_n : std_logic;
+ signal pia_rom_do : std_logic_vector( 7 downto 0);
+ signal pia_rom_irqa : std_logic;
+ signal pia_rom_irqb : std_logic;
+ signal pia_rom_pa_i : std_logic_vector( 7 downto 0);
+ signal pia_rom_pa_o : std_logic_vector( 7 downto 0);
+ signal pia_rom_pb_o : std_logic_vector( 7 downto 0);
+
+ signal vcnt_240 : std_logic;
+ signal cnt_4ms : std_logic;
+
+ signal cpu_to_video_addr : std_logic_vector(8 downto 0);
+ signal cpu_to_video_do : std_logic_vector(7 downto 0);
+
+ signal video_scan_addr : std_logic_vector(8 downto 0);
+ signal video_scan_do : std_logic_vector(7 downto 0);
+
+ signal pixel_cnt : std_logic_vector(2 downto 0);
+ signal hcnt : std_logic_vector(5 downto 0);
+ signal vcnt : std_logic_vector(8 downto 0);
+
+ signal pixels : std_logic_vector(23 downto 0);
+
+ signal hsync0,hsync1,hsync2,csync,hblank,vblank : std_logic;
+
+ signal select_sound : std_logic_vector(5 downto 0);
+
+begin
+
+clock_6n <= not clock_6;
+reset_n <= not reset;
+
+-- for debug
+dbg_cpu_addr <= cpu_addr;
+
+
+-- make pixels counters and cpu clock
+-- in original hardware cpu clock = 1us = 6pixels
+-- here one make 2 cpu clock within 1us
+process (reset, clock_6n)
+begin
+ if reset='1' then
+ pixel_cnt <= "000";
+ cpu_clock <= '0';
+ else
+ if rising_edge(clock_6n) then
+
+ if pixel_cnt = "101" then
+ pixel_cnt <= "000";
+ cpu_clock <= '0';
+ else
+ pixel_cnt <= pixel_cnt + '1';
+ end if;
+
+ if pixel_cnt = "010" then
+ cpu_clock <= '1';
+ end if;
+
+ if pixel_cnt = "011" then -- speed up processor (two clocks / 1us)
+ cpu_clock <= '0';
+ end if;
+
+ if pixel_cnt = "100" then
+ cpu_clock <= '1';
+ end if;
+
+
+ end if;
+ end if;
+end process;
+
+-- make hcnt and vcnt video scanner from pixel clocks and counts
+--
+-- pixels |0|1|2|3|4|5|0|1|2|3|4|5|
+-- hcnt | N | N+1 |
+--
+-- hcnt [0..63] => 64 x 6 = 384 pixels, 1 pixel is 1us => 1 line is 64us (15.625KHz)
+-- vcnt [252..255,256..511] => 260 lines, 1 frame is 260 x 64us = 16.640ms (60.1Hz)
+--
+process (reset, clock_6n)
+begin
+ if reset='1' then
+ hcnt <= "000000";
+ vcnt <= '0'&X"FC";
+ else
+ if rising_edge(clock_6n) then
+
+ if pixel_cnt = "101" then
+ hcnt <= hcnt + '1';
+ if hcnt = "111111" then
+ if vcnt = '1'&X"FF" then
+ vcnt <= '0'&X"FC";
+ else
+ vcnt <= vcnt + '1';
+ end if;
+ end if;
+ end if;
+
+ end if;
+ end if;
+end process;
+
+-- rom address multiplexer
+-- should reflect content of defender_prog.bin
+--
+-- 4k 0000-0FFF cpu_space D000-DFFF defend.1 + defend.4
+-- 4k 1000-1FFF E000-EFFF defend.2
+-- 4k 2000-2FFF F000-FFFF defend.3
+-- 4k 3000-3FFF page=1 C000-CFFF defend.9 + defend.12
+-- 4k 4000-4FFF page=2 C000-CFFF defend.8 + defend.11
+-- 4k 5000-5FFF page=3 C000-CFFF defend.7 + defend.10
+-- 4k 6000-6FFF page=7 C000-C7FF defend.6 + 2k empty
+-- 4k 7000-7FFF N.A 4k empty
+
+roms_addr <=
+ "011" & cpu_addr(11 downto 0) when cpu_addr(15 downto 12) = X"C" and rom_page = "001" else
+ "100" & cpu_addr(11 downto 0) when cpu_addr(15 downto 12) = X"C" and rom_page = "010" else
+ "101" & cpu_addr(11 downto 0) when cpu_addr(15 downto 12) = X"C" and rom_page = "011" else
+ "110" & cpu_addr(11 downto 0) when cpu_addr(15 downto 12) = X"C" and rom_page = "111" else
+ "000" & cpu_addr(11 downto 0) when cpu_addr(15 downto 12) = X"D" else
+ "001" & cpu_addr(11 downto 0) when cpu_addr(15 downto 12) = X"E" else
+ "010" & cpu_addr(11 downto 0) ;--when cpu_addr(15 downto 12) = X"F";
+
+-- encoded cpu addr (decoder.2) and encoded scan addr (decoder.3)
+-- and screen control for cocktail table flip
+cpu_to_video_addr <= screen_ctrl & cpu_addr(15 downto 8);
+video_scan_addr <= screen_ctrl & vcnt(7 downto 0);
+
+-- mux cpu addr/scan addr to wram
+wram_addr <=
+ cpu_addr(7 downto 0) & cpu_to_video_do(5 downto 0) when cpu_clock = '1' else
+ video_scan_do & hcnt;
+
+-- mux cpu addr/pixels data to palette addr
+palette_addr <=
+ cpu_addr(3 downto 0) when palette_we = '1' else
+ pixels(23 downto 20) when screen_ctrl = '0' else pixels(3 downto 0);
+
+-- only cpu can write to palette
+palette_di <= cpu_do;
+
+-- palette output to colors bits
+video_r <= palette_do(2 downto 0);
+video_g <= palette_do(5 downto 3);
+video_b <= palette_do(7 downto 6);
+
+
+-- 24 bits pixels shift register
+-- 6 pixels of 4 bits
+process (clock_6)
+begin
+ if rising_edge(clock_6) then
+ if screen_ctrl = '0' then
+ if pixel_cnt = "001" then
+ pixels <= wram0_do & wram1_do & wram2_do;
+ else
+ pixels <= pixels(19 downto 0) & X"0" ;
+ end if;
+ else
+ if pixel_cnt = "001" then
+ pixels <= wram2_do & wram1_do & wram0_do;
+ else
+ pixels <= X"0" & pixels(23 downto 4);
+ end if;
+ end if;
+ end if;
+end process;
+
+-- pias cs
+io_cs <= '1' when cpu_clock = '1' and cpu_addr(15 downto 12) = X"C" and rom_page ="000" else '0';
+pia_rom_cs <= '1' when io_cs = '1' and cpu_addr(11 downto 10) = "11" and cpu_addr(2) = '0' else '0'; -- CC00-CC03
+pia_io_cs <= '1' when io_cs = '1' and cpu_addr(11 downto 10) = "11" and cpu_addr(2) = '1' else '0'; -- CC04-CC07
+
+-- write enables
+wram_we <= '1' when cpu_rw = '0' and cpu_clock = '1' and cpu_addr(15 downto 12) < X"C" else '0';
+io_we <= '1' when cpu_rw = '0' and cpu_clock = '1' and cpu_addr(15 downto 12) = X"C" and rom_page ="000" else '0';
+rom_page_we <= '1' when cpu_rw = '0' and cpu_clock = '1' and cpu_addr(15 downto 12) = X"D" else '0';
+
+palette_we <= '1' when io_we = '1' and cpu_addr(11 downto 10) = "00" and cpu_addr(4) = '0' else '0'; -- C000-C00F
+screen_ctrl_we <= '1' when io_we = '1' and cpu_addr(11 downto 10) = "00" and cpu_addr(4) = '1' else '0'; -- C010-C01F
+cmos_we <= '1' when io_we = '1' and cpu_addr(11 downto 10) = "01" else '0'; -- C400-C7FF
+pia_rom_rw_n <= '0' when io_we = '1' and cpu_addr(11 downto 10) = "11" and cpu_addr(2) = '0' else '1'; -- CC00-CC03
+pia_io_rw_n <= '0' when io_we = '1' and cpu_addr(11 downto 10) = "11" and cpu_addr(2) = '1' else '1'; -- CC04-CC07
+
+-- mux io data between cmos/video register/pias/c000_rom_page
+roms_io_do <=
+ X"0"&cmos_do when rom_page = "000" and cpu_addr(11 downto 10) = "01" else -- C400-C7FF
+ vcnt(7 downto 2)&"00" when rom_page = "000" and cpu_addr(11 downto 10) = "10" else -- C800-cBFF
+ pia_rom_do when rom_page = "000" and cpu_addr(11 downto 10) = "11" and cpu_addr(2) = '0' else -- CC00-CC03 (A2n.A3n.A4n)
+ pia_io_do when rom_page = "000" and cpu_addr(11 downto 10) = "11" and cpu_addr(2) = '1' else -- CC04-CC07 (A2.A3n)
+ roms_do;
+
+-- mux cpu in data between roms/io/wram
+cpu_di <=
+ roms_do when cpu_addr(15 downto 12) >= X"D" else
+ roms_io_do when cpu_addr(15 downto 12) >= X"C" else
+ wram0_do when cpu_to_video_do(7 downto 6) = "00" else
+ wram1_do when cpu_to_video_do(7 downto 6) = "01" else
+ wram2_do when cpu_to_video_do(7 downto 6) = "10" else X"00";
+
+
+-- dispatch cpu we to devices with respect to decoder2 bits 7-6
+wram0_we <= '1' when wram_we = '1' and cpu_to_video_do(7 downto 6) = "00" else '0';
+wram1_we <= '1' when wram_we = '1' and cpu_to_video_do(7 downto 6) = "01" else '0';
+wram2_we <= '1' when wram_we = '1' and cpu_to_video_do(7 downto 6) = "10" else '0';
+
+
+-- rom bank page (and IO) select register
+-- screen control register
+process (reset, clock_6)
+begin
+ if reset='1' then
+ rom_page <= "000";
+ screen_ctrl <= '0';
+ else
+ if rising_edge(clock_6) then
+ if rom_page_we = '1' then rom_page <= cpu_do(2 downto 0); end if;
+ if screen_ctrl_we = '1' then screen_ctrl <= cpu_do(0); end if;
+ end if;
+ end if;
+end process;
+
+-- pia rom board port a
+-- bit 0 Auto Up / manual Down
+-- bit 1 Advance
+-- bit 2 Right Coin (nc)
+-- bit 3 High Score Reset
+-- bit 4 Left Coin
+-- bit 5 Center Coin (nc)
+-- bit 6 led 2 (output)
+-- bit 7 led 1 (output)
+
+pias_clock <= clock_6; --not cpu_clock;
+
+pia_rom_pa_i(0) <= btn_auto_up;
+pia_rom_pa_i(1) <= btn_advance;
+pia_rom_pa_i(2) <= btn_service;
+pia_rom_pa_i(3) <= '0';
+pia_rom_pa_i(4) <= btn_left_coin;
+pia_rom_pa_i(5) <= '0';
+pia_rom_pa_i(6) <= '0';
+pia_rom_pa_i(7) <= '0';
+
+-- pia io port a
+-- bit 0 Fire
+-- bit 1 Thrust
+-- bit 2 Smart Bomb
+-- bit 3 HyperSpace
+-- bit 4 2 Players
+-- bit 5 1 Player
+-- bit 6 Reverse
+-- bit 7 Down
+--IN0
+pia_io_pa_i(0) <= btn_ffire;
+pia_io_pa_i(1) <= btn_right;
+pia_io_pa_i(2) <= btn_mayday;
+pia_io_pa_i(3) <= btn_bfire;
+pia_io_pa_i(4) <= btn_two_players;
+pia_io_pa_i(5) <= btn_one_player;
+pia_io_pa_i(6) <= '0';
+pia_io_pa_i(7) <= btn_down;
+
+-- pia io port b
+-- bit 0 Up
+-- bit 7 1 for coktail table, 0 for upright cabinet
+-- other <= GND
+pia_io_pb_i(0) <= btn_up;
+pia_io_pb_i(6 downto 1) <= "000000";
+pia_io_pb_i(7) <= '0';
+
+-- pia io ca/cb
+--IN2
+cmd_select_players_btn <= pia_io_cb2_o;
+
+-- pia rom ca1/Cb1
+vcnt_240 <= '1' when vcnt(7 downto 4) = X"F" else '0';
+cnt_4ms <= vcnt(5);
+
+-- pia rom irqs to cpu
+cpu_irq <= pia_rom_irqa or pia_rom_irqb;
+
+-- pia rom to sound board
+select_sound <= pia_rom_pb_o(5 downto 0);
+
+
+-- microprocessor 6809
+main_cpu : entity work.cpu09
+port map(
+ clk => cpu_clock,-- E clock input (falling edge)
+ rst => reset, -- reset input (active high)
+ vma => open, -- valid memory address (active high)
+ lic_out => open, -- last instruction cycle (active high)
+ ifetch => open, -- instruction fetch cycle (active high)
+ opfetch => open, -- opcode fetch (active high)
+ ba => open, -- bus available (high on sync wait or DMA grant)
+ bs => open, -- bus status (high on interrupt or reset vector fetch or DMA grant)
+ addr => cpu_a, -- address bus output
+ rw => cpu_rw, -- read not write output
+ data_out => cpu_do, -- data bus output
+ data_in => cpu_di, -- data bus input
+ irq => cpu_irq, -- interrupt request input (active high)
+ firq => '0', -- fast interrupt request input (active high)
+ nmi => '0', -- non maskable interrupt request input (active high)
+ halt => '0', -- halt input (active high) grants DMA
+ hold => '0' -- hold input (active high) extend bus cycle
+);
+
+-- Mayday protection.
+cpu_addr <= x"A193" when cpu_rw = '1' and cpu_a = x"A190" else
+ x"A194" when cpu_rw = '1' and cpu_a = x"A191" else
+ cpu_a;
+
+-- cpu program rom
+-- 4k D000-DFFF
+-- 4k E000-EFFF
+-- 4k F000-FFFF
+-- 4K C000-CFFF page=1
+-- 4K C000-CFFF page=2
+-- 4K C000-CFFF page=3
+-- 2K C000-C7FF page=7
+-- 6K N.A.
+
+
+-- cpu/video wram 0
+cpu_video_ram0 : entity work.gen_ram
+generic map( dWidth => 8, aWidth => 14)
+port map(
+ clk => clock_6,
+ we => wram0_we,
+ addr => wram_addr(13 downto 0),
+ d => cpu_do,
+ q => wram0_do
+);
+
+-- cpu/video wram 1
+cpu_video_ram1 : entity work.gen_ram
+generic map( dWidth => 8, aWidth => 14)
+port map(
+ clk => clock_6,
+ we => wram1_we,
+ addr => wram_addr(13 downto 0),
+ d => cpu_do,
+ q => wram1_do
+);
+
+-- cpu/video wram 2
+cpu_video_ram2 : entity work.gen_ram
+generic map( dWidth => 8, aWidth => 14)
+port map(
+ clk => clock_6,
+ we => wram2_we,
+ addr => wram_addr(13 downto 0),
+ d => cpu_do,
+ q => wram2_do
+);
+
+-- palette ram
+palette_ram : entity work.gen_ram
+generic map( dWidth => 8, aWidth => 4)
+port map(
+ clk => clock_6,
+ we => palette_we,
+ addr => palette_addr,
+ d => palette_di,
+ q => palette_do
+);
+
+-- cmos ram
+cmos_ram : entity work.defender_cmos_ram
+generic map( dWidth => 4, aWidth => 8)
+port map(
+ clk => clock_6,
+ we => cmos_we,
+ addr => cpu_addr(7 downto 0),
+ d => cpu_do(3 downto 0),
+ q => cmos_do
+);
+
+-- cpu to video addr decoder
+cpu_video_addr_decoder : entity work.defender_decoder_2
+port map(
+ clk => clock_6,
+ addr => cpu_to_video_addr,
+ data => cpu_to_video_do
+);
+
+-- video scan addr decoder
+video_scan_addr_decoder : entity work.defender_decoder_3
+port map(
+ clk => clock_6,
+ addr => video_scan_addr,
+ data => video_scan_do
+);
+
+-- pia i/O board
+pia_io : entity work.pia6821
+port map
+(
+ clk => pias_clock, -- rising edge
+ rst => reset, -- active high
+ cs => pia_io_cs,
+ rw => pia_io_rw_n, -- write low
+ addr => cpu_addr(1 downto 0),
+ data_in => cpu_do,
+ data_out => pia_io_do,
+ irqa => open, -- active high
+ irqb => open, -- active high
+ pa_i => pia_io_pa_i,
+ pa_o => open,
+ pa_oe => open,
+ ca1 => '0',
+ ca2_i => '0',
+ ca2_o => open,
+ ca2_oe => open,
+ pb_i => pia_io_pb_i,
+ pb_o => open,
+ pb_oe => open,
+ cb1 => '0',
+ cb2_i => '0',
+ cb2_o => pia_io_cb2_o,
+ cb2_oe => open
+);
+
+-- pia rom board
+pia_rom : entity work.pia6821
+port map
+(
+ clk => pias_clock,
+ rst => reset,
+ cs => pia_rom_cs,
+ rw => pia_rom_rw_n,
+ addr => cpu_addr(1 downto 0),
+ data_in => cpu_do,
+ data_out => pia_rom_do,
+ irqa => pia_rom_irqa,
+ irqb => pia_rom_irqb,
+ pa_i => pia_rom_pa_i,
+ pa_o => open,
+ pa_oe => open,
+ ca1 => vcnt_240,
+ ca2_i => '0',
+ ca2_o => open,
+ ca2_oe => open,
+ pb_i => (others => '0'),
+ pb_o => pia_rom_pb_o,
+ pb_oe => open,
+ cb1 => cnt_4ms,
+ cb2_i => '0',
+ cb2_o => open,
+ cb2_oe => open
+);
+
+-- video syncs and blanks
+video_csync <= csync;
+
+process(clock_6n)
+ constant hcnt_base : integer := 54;
+ variable vsync_cnt : std_logic_vector(3 downto 0);
+begin
+
+if rising_edge(clock_6n) then
+
+ if hcnt = hcnt_base+0 then hsync0 <= '0';
+ elsif hcnt = hcnt_base+6 then hsync0 <= '1';
+ end if;
+
+ if hcnt = hcnt_base+0 then hsync1 <= '0';
+ elsif hcnt = hcnt_base+3 then hsync1 <= '1';
+ elsif hcnt = hcnt_base+32-64 then hsync1 <= '0';
+ elsif hcnt = hcnt_base+35-64 then hsync1 <= '1';
+ end if;
+
+ if hcnt = hcnt_base+0 then hsync2 <= '0';
+ elsif hcnt = hcnt_base+32-3-64 then hsync2 <= '1';
+ elsif hcnt = hcnt_base+32-64 then hsync2 <= '0';
+ elsif hcnt = hcnt_base+64-3-128 then hsync2 <= '1';
+ end if;
+
+ if hcnt = 63 and pixel_cnt = 5 then
+ if vcnt = 495 then -- 503 with vcnt max = F4
+ vsync_cnt := X"0"; -- 499 with F8, 495 with FC
+ else
+ if vsync_cnt < X"F" then vsync_cnt := vsync_cnt + '1'; end if;
+ end if;
+ end if;
+
+ if vsync_cnt = 0 then csync <= hsync1;
+ elsif vsync_cnt = 1 then csync <= hsync1;
+ elsif vsync_cnt = 2 then csync <= hsync1;
+ elsif vsync_cnt = 3 then csync <= hsync2;
+ elsif vsync_cnt = 4 then csync <= hsync2;
+ elsif vsync_cnt = 5 then csync <= hsync2;
+ elsif vsync_cnt = 6 then csync <= hsync1;
+ elsif vsync_cnt = 7 then csync <= hsync1;
+ elsif vsync_cnt = 8 then csync <= hsync1;
+ else csync <= hsync0;
+ end if;
+
+ if hcnt = hcnt_base-2 then hblank <= '1';
+ elsif hcnt = hcnt_base+11-64 then hblank <= '0';
+ end if;
+
+ if vcnt = 492 then vblank <= '1'; -- 492 ok
+ elsif vcnt = 262 then vblank <= '0'; -- 262 ok
+ end if;
+
+ -- external sync and blank outputs
+ video_blankn <= not (hblank or vblank);
+
+ video_hs <= hsync0;
+
+ if vsync_cnt = 0 then video_vs <= '0';
+ elsif vsync_cnt = 8 then video_vs <= '1';
+ end if;
+
+end if;
+end process;
+
+-- sound board
+defender_sound_board : entity work.defender_sound_board
+port map(
+ clk_1p79 => clk_1p79,
+ clk_0p89 => clk_0p89,
+ reset => reset,
+ select_sound => select_sound,
+ audio_out => audio_out
+);
+
+end struct;
\ No newline at end of file
diff --git a/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/rtl/defender_cmos_ram.vhd b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/rtl/defender_cmos_ram.vhd
new file mode 100644
index 00000000..f74b9b02
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/rtl/defender_cmos_ram.vhd
@@ -0,0 +1,163 @@
+-- -----------------------------------------------------------------------
+--
+-- 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
+--
+-- Modifies Octiber 2017 by Dar
+-- Add init data with defender cmos value
+-- -----------------------------------------------------------------------
+--
+-- gen_rwram.vhd init with defender cmos value
+--
+-- -----------------------------------------------------------------------
+--
+-- generic ram.
+--
+-- -----------------------------------------------------------------------
+
+library IEEE;
+use IEEE.STD_LOGIC_1164.ALL;
+use IEEE.numeric_std.ALL;
+
+-- -----------------------------------------------------------------------
+
+entity defender_cmos_ram is
+ generic (
+ dWidth : integer := 8; -- must be 4 for defender_cmos_ram
+ aWidth : integer := 10 -- must be 8 for defender_cmos_ram
+ );
+ 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;
+
+-- -----------------------------------------------------------------------
+-- defender cmos data
+-- (ram is 128x4 => only 4 bits/address, that is only 1 hex digit/address)
+--
+-- @ values - (fonction) meaning
+
+-- 0 0 - ?
+-- 1 0005 - (01) coins left
+-- 5 0000 - (02) coins center
+-- 9 0000 - (03) coins right
+-- 13 0005 - (04) total paid
+-- 17 0000 - (05) ships won
+---21 0000 - (06) total time
+-- 25 0003 - (07) total ships
+
+-- -- 8 entries of 6 digits highscore + 3 ascii letters
+
+-- 29 021270 44 52 4A
+-- 41 018315 53 41 4D
+-- 53 015920 4C 45 44
+-- 65 014285 50 47 44
+-- 77 012520 43 52 42
+-- 89 011035 4D 52 53
+-- 101 008265 53 53 52
+-- 113 006010 54 4D 48
+
+-- 125 00 - credits
+-- 127 5 - ?
+
+-- -- protected data writeable only with coin door opened
+
+-- 128 A - ?
+-- 129 0100 - (08) bonus ship level
+-- 133 03 - (09) nb ships
+-- 135 03 - (10) coinage select
+-- 137 01 - (11) left coin mult
+-- 139 04 - (12) center coin mult
+-- 141 01 - (13) right coin mult
+-- 143 01 - (14) coins for credit
+-- 145 00 - (15) coins for bonus
+-- 147 00 - (16) minimum coins
+-- 149 00 - (17) free play
+-- 151 05 - (18) game adjust 1 Stating difficulty 0=lib; 1=mod; 2=cons
+-- 153 15 - (19) game adjust 2 Progessive wave diff. limit > 4-25
+-- 155 01 - (20) game adjust 3 Background sound 0=off; 1=on
+-- 157 05 - (21) game adjust 4 Planet restore wave number
+-- 159 00 - (22) game adjust 5
+-- 161 00 - (23) game adjust 6
+-- 163 00 - (24) game adjust 7
+-- 165 00 - (25) game adjust 8
+-- 167 00 - (26) game adjust 9
+-- 169 00 - (27) game adjust 10
+
+-- 171 00000 - ?
+-- 176 0000000000000000 - ?
+-- 192 0000000000000000 - ?
+-- 208 0000000000000000 - ?
+-- 224 0000000000000000 - ?
+-- 240 0000000000000000 - ?
+
+
+architecture rtl of defender_cmos_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 := (
+ X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",
+ X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"2",X"1",
+ X"2",X"7",X"0",X"4",X"4",X"5",X"2",X"4",X"A",X"0",X"1",X"8",X"3",X"1",X"5",X"5",
+ X"3",X"4",X"1",X"4",X"D",X"0",X"1",X"5",X"9",X"2",X"0",X"4",X"C",X"4",X"5",X"4",
+ X"4",X"0",X"1",X"4",X"2",X"8",X"5",X"5",X"0",X"4",X"7",X"4",X"4",X"0",X"1",X"2",
+ X"5",X"2",X"0",X"4",X"3",X"5",X"2",X"4",X"2",X"0",X"1",X"1",X"0",X"3",X"5",X"4",
+ X"D",X"5",X"2",X"5",X"3",X"0",X"0",X"8",X"2",X"6",X"5",X"5",X"3",X"5",X"3",X"5",
+ X"2",X"0",X"0",X"6",X"0",X"1",X"0",X"5",X"4",X"4",X"D",X"4",X"8",X"0",X"0",X"5",
+ X"A",X"0",X"1",X"0",X"0",X"0",X"3",X"0",X"3",X"0",X"1",X"0",X"4",X"0",X"1",X"0",
+ X"1",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"5",X"1",X"5",X"0",X"1",X"0",X"5",X"0",
+ X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",
+ X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",
+ X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",
+ X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",
+ X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",
+ X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0",X"0");
+
+
+ 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/Mayday/rtl/defender_decoder_2.vhd b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/rtl/defender_decoder_2.vhd
new file mode 100644
index 00000000..db3514d9
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/rtl/defender_decoder_2.vhd
@@ -0,0 +1,54 @@
+library ieee;
+use ieee.std_logic_1164.all,ieee.numeric_std.all;
+
+entity defender_decoder_2 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 defender_decoder_2 is
+ type rom is array(0 to 511) of std_logic_vector(7 downto 0);
+ signal rom_data: rom := (
+ X"00",X"40",X"80",X"01",X"41",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"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"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"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"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"00",X"00",X"00",X"00",X"00",X"00",X"00",
+ X"00",X"40",X"80",X"01",X"41",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"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"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"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"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"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"00",X"00",X"00",X"00",X"00",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/Mayday/rtl/defender_decoder_3.vhd b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/rtl/defender_decoder_3.vhd
new file mode 100644
index 00000000..d5751938
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/rtl/defender_decoder_3.vhd
@@ -0,0 +1,54 @@
+library ieee;
+use ieee.std_logic_1164.all,ieee.numeric_std.all;
+
+entity defender_decoder_3 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 defender_decoder_3 is
+ type rom is array(0 to 511) of std_logic_vector(7 downto 0);
+ signal rom_data: rom := (
+ 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"F8",X"F9",X"FA",X"FB",X"FC",X"FD",X"FE",X"FF",
+ X"FB",X"FA",X"F9",X"F8",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"FC",X"FD",X"FE",X"FF");
+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/Mayday/rtl/defender_sound.vhd b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/rtl/defender_sound.vhd
new file mode 100644
index 00000000..fc2af25c
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/rtl/defender_sound.vhd
@@ -0,0 +1,150 @@
+library ieee;
+use ieee.std_logic_1164.all,ieee.numeric_std.all;
+
+entity defender_sound is
+port (
+ clk : in std_logic;
+ addr : in std_logic_vector(10 downto 0);
+ data : out std_logic_vector(7 downto 0)
+);
+end entity;
+
+architecture prom of defender_sound is
+ type rom is array(0 to 2047) of std_logic_vector(7 downto 0);
+ signal rom_data: rom := (
+ X"FF",X"0F",X"8E",X"00",X"7F",X"CE",X"04",X"00",X"6F",X"01",X"6F",X"03",X"86",X"FF",X"A7",X"00",
+ X"6F",X"02",X"86",X"37",X"A7",X"03",X"86",X"3C",X"A7",X"01",X"97",X"09",X"4F",X"97",X"07",X"97",
+ X"04",X"97",X"05",X"97",X"06",X"97",X"08",X"0E",X"20",X"FE",X"16",X"48",X"48",X"48",X"1B",X"CE",
+ X"00",X"13",X"DF",X"0F",X"CE",X"FD",X"76",X"BD",X"FD",X"21",X"C6",X"09",X"7E",X"FB",X"0A",X"96",
+ X"1B",X"B7",X"04",X"00",X"96",X"13",X"97",X"1C",X"96",X"14",X"97",X"1D",X"DE",X"18",X"96",X"1C",
+ X"73",X"04",X"00",X"09",X"27",X"10",X"4A",X"26",X"FA",X"73",X"04",X"00",X"96",X"1D",X"09",X"27",
+ X"05",X"4A",X"26",X"FA",X"20",X"E8",X"B6",X"04",X"00",X"2B",X"01",X"43",X"8B",X"00",X"B7",X"04",
+ X"00",X"96",X"1C",X"9B",X"15",X"97",X"1C",X"96",X"1D",X"9B",X"16",X"97",X"1D",X"91",X"17",X"26",
+ X"CB",X"96",X"1A",X"27",X"06",X"9B",X"13",X"97",X"13",X"26",X"B9",X"39",X"86",X"01",X"97",X"1A",
+ X"C6",X"03",X"20",X"0A",X"86",X"FE",X"97",X"1A",X"86",X"C0",X"C6",X"10",X"20",X"00",X"97",X"19",
+ X"86",X"FF",X"B7",X"04",X"00",X"D7",X"15",X"D6",X"15",X"96",X"0A",X"44",X"44",X"44",X"98",X"0A",
+ X"44",X"76",X"00",X"09",X"76",X"00",X"0A",X"24",X"03",X"73",X"04",X"00",X"96",X"19",X"4A",X"26",
+ X"FD",X"5A",X"26",X"E5",X"96",X"19",X"9B",X"1A",X"97",X"19",X"26",X"DB",X"39",X"86",X"20",X"97",
+ X"15",X"97",X"18",X"86",X"01",X"CE",X"00",X"01",X"C6",X"FF",X"20",X"00",X"97",X"13",X"DF",X"16",
+ X"D7",X"14",X"D6",X"15",X"96",X"0A",X"44",X"44",X"44",X"98",X"0A",X"44",X"76",X"00",X"09",X"76",
+ X"00",X"0A",X"86",X"00",X"24",X"02",X"96",X"14",X"B7",X"04",X"00",X"DE",X"16",X"09",X"26",X"FD",
+ X"5A",X"26",X"E1",X"D6",X"14",X"D0",X"13",X"27",X"09",X"DE",X"16",X"08",X"96",X"18",X"27",X"D0",
+ X"20",X"CC",X"39",X"C6",X"01",X"D7",X"04",X"4F",X"97",X"19",X"20",X"14",X"4F",X"97",X"19",X"C6",
+ X"03",X"20",X"0D",X"86",X"01",X"97",X"19",X"CE",X"03",X"E8",X"86",X"01",X"C6",X"FF",X"20",X"00",
+ X"97",X"18",X"D7",X"13",X"DF",X"16",X"7F",X"00",X"15",X"DE",X"16",X"B6",X"04",X"00",X"16",X"54",
+ X"54",X"54",X"D8",X"0A",X"54",X"76",X"00",X"09",X"76",X"00",X"0A",X"D6",X"13",X"7D",X"00",X"19",
+ X"27",X"02",X"D4",X"09",X"D7",X"14",X"D6",X"15",X"91",X"0A",X"22",X"12",X"09",X"27",X"26",X"B7",
+ X"04",X"00",X"DB",X"15",X"99",X"14",X"25",X"16",X"91",X"0A",X"23",X"F0",X"20",X"10",X"09",X"27",
+ X"14",X"B7",X"04",X"00",X"D0",X"15",X"92",X"14",X"25",X"04",X"91",X"0A",X"22",X"F0",X"96",X"0A",
+ X"B7",X"04",X"00",X"20",X"B9",X"D6",X"18",X"27",X"B5",X"96",X"13",X"D6",X"15",X"44",X"56",X"44",
+ X"56",X"44",X"56",X"43",X"50",X"82",X"FF",X"DB",X"15",X"99",X"13",X"D7",X"15",X"97",X"13",X"26",
+ X"98",X"C1",X"07",X"26",X"94",X"39",X"86",X"FD",X"97",X"0F",X"CE",X"00",X"64",X"DF",X"0B",X"DB",
+ X"0C",X"96",X"11",X"99",X"0B",X"97",X"11",X"DE",X"0B",X"25",X"04",X"20",X"00",X"20",X"03",X"08",
+ X"27",X"11",X"DF",X"0B",X"84",X"0F",X"8B",X"9A",X"97",X"10",X"DE",X"0F",X"A6",X"00",X"B7",X"04",
+ X"00",X"20",X"DC",X"39",X"4F",X"B7",X"04",X"00",X"97",X"11",X"4F",X"91",X"11",X"26",X"03",X"73",
+ X"04",X"00",X"C6",X"12",X"5A",X"26",X"FD",X"4C",X"2A",X"F1",X"73",X"04",X"00",X"7C",X"00",X"11",
+ X"2A",X"E8",X"39",X"CE",X"00",X"13",X"6F",X"00",X"08",X"8C",X"00",X"1B",X"26",X"F8",X"86",X"40",
+ X"97",X"13",X"CE",X"00",X"13",X"86",X"80",X"97",X"11",X"5F",X"A6",X"01",X"AB",X"00",X"A7",X"01",
+ X"2A",X"02",X"DB",X"11",X"74",X"00",X"11",X"08",X"08",X"8C",X"00",X"1B",X"26",X"EC",X"F7",X"04",
+ X"00",X"7C",X"00",X"12",X"26",X"DC",X"CE",X"00",X"13",X"5F",X"A6",X"00",X"27",X"0B",X"81",X"37",
+ X"26",X"04",X"C6",X"41",X"E7",X"02",X"6A",X"00",X"5C",X"08",X"08",X"8C",X"00",X"1B",X"26",X"EA",
+ X"5D",X"26",X"BF",X"39",X"7A",X"00",X"08",X"39",X"7F",X"00",X"08",X"97",X"11",X"CE",X"FD",X"AA",
+ X"A6",X"00",X"27",X"2D",X"7A",X"00",X"11",X"27",X"06",X"4C",X"BD",X"FD",X"21",X"20",X"F1",X"08",
+ X"DF",X"0F",X"BD",X"FD",X"21",X"DF",X"0D",X"DE",X"0F",X"A6",X"00",X"97",X"15",X"A6",X"01",X"EE",
+ X"02",X"DF",X"13",X"8D",X"3E",X"DE",X"0F",X"08",X"08",X"08",X"08",X"DF",X"0F",X"9C",X"0D",X"26",
+ X"E8",X"7E",X"FD",X"0E",X"86",X"03",X"97",X"08",X"39",X"7A",X"00",X"08",X"27",X"0C",X"D6",X"15",
+ X"58",X"58",X"58",X"58",X"1B",X"97",X"15",X"4F",X"20",X"FE",X"4A",X"81",X"0B",X"23",X"01",X"4F",
+ X"CE",X"FE",X"41",X"BD",X"FD",X"21",X"A6",X"00",X"CE",X"FF",X"FF",X"DF",X"13",X"8D",X"04",X"8D",
+ X"2A",X"20",X"FC",X"CE",X"00",X"16",X"81",X"00",X"27",X"15",X"81",X"03",X"27",X"09",X"C6",X"01",
+ X"E7",X"00",X"08",X"80",X"02",X"20",X"EF",X"C6",X"91",X"E7",X"00",X"6F",X"01",X"08",X"08",X"C6",
+ X"7E",X"E7",X"00",X"C6",X"FA",X"E7",X"01",X"C6",X"DD",X"E7",X"02",X"DE",X"13",X"4F",X"F6",X"00",
+ X"12",X"5C",X"D7",X"12",X"D4",X"15",X"54",X"89",X"00",X"54",X"89",X"00",X"54",X"89",X"00",X"54",
+ X"89",X"00",X"54",X"89",X"00",X"54",X"89",X"00",X"54",X"89",X"00",X"1B",X"48",X"48",X"48",X"48",
+ X"B7",X"04",X"00",X"09",X"27",X"03",X"7E",X"00",X"16",X"39",X"36",X"A6",X"00",X"DF",X"0D",X"DE",
+ X"0F",X"A7",X"00",X"08",X"DF",X"0F",X"DE",X"0D",X"08",X"5A",X"26",X"EF",X"32",X"39",X"4F",X"97",
+ X"04",X"97",X"05",X"39",X"7F",X"00",X"04",X"96",X"05",X"84",X"7F",X"81",X"1D",X"26",X"01",X"4F",
+ X"4C",X"97",X"05",X"39",X"86",X"0E",X"BD",X"FB",X"81",X"96",X"05",X"48",X"48",X"43",X"BD",X"FC",
+ X"39",X"7C",X"00",X"17",X"BD",X"FC",X"3B",X"20",X"F8",X"86",X"03",X"BD",X"F8",X"2A",X"D6",X"06",
+ X"C1",X"1F",X"26",X"01",X"5F",X"5C",X"D7",X"06",X"86",X"20",X"10",X"5F",X"81",X"14",X"23",X"05",
+ X"CB",X"0E",X"4A",X"20",X"F7",X"CB",X"05",X"4A",X"26",X"FB",X"D7",X"13",X"BD",X"F8",X"3F",X"20",
+ X"FB",X"96",X"07",X"26",X"09",X"7C",X"00",X"07",X"86",X"0D",X"8D",X"05",X"20",X"69",X"7E",X"FC",
+ X"2E",X"16",X"58",X"1B",X"1B",X"1B",X"CE",X"FE",X"EC",X"BD",X"FD",X"21",X"A6",X"00",X"16",X"84",
+ X"0F",X"97",X"14",X"54",X"54",X"54",X"54",X"D7",X"13",X"A6",X"01",X"16",X"54",X"54",X"54",X"54",
+ X"D7",X"15",X"84",X"0F",X"97",X"11",X"DF",X"0B",X"CE",X"FE",X"4D",X"7A",X"00",X"11",X"2B",X"08",
+ X"A6",X"00",X"4C",X"BD",X"FD",X"21",X"20",X"F3",X"DF",X"18",X"BD",X"FC",X"75",X"DE",X"0B",X"A6",
+ X"02",X"97",X"1A",X"BD",X"FC",X"87",X"DE",X"0B",X"A6",X"03",X"97",X"16",X"A6",X"04",X"97",X"17",
+ X"A6",X"05",X"16",X"A6",X"06",X"CE",X"FF",X"55",X"BD",X"FD",X"21",X"17",X"DF",X"1B",X"7F",X"00",
+ X"23",X"BD",X"FD",X"21",X"DF",X"1D",X"39",X"96",X"13",X"97",X"22",X"DE",X"1B",X"DF",X"0D",X"DE",
+ X"0D",X"A6",X"00",X"9B",X"23",X"97",X"21",X"9C",X"1D",X"27",X"26",X"D6",X"14",X"08",X"DF",X"0D",
+ X"CE",X"00",X"24",X"96",X"21",X"4A",X"26",X"FD",X"A6",X"00",X"B7",X"04",X"00",X"08",X"9C",X"1F",
+ X"26",X"F1",X"5A",X"27",X"DA",X"08",X"09",X"08",X"09",X"08",X"09",X"08",X"09",X"01",X"01",X"20",
+ X"DF",X"96",X"15",X"8D",X"62",X"7A",X"00",X"22",X"26",X"C1",X"96",X"07",X"26",X"46",X"96",X"16",
+ X"27",X"42",X"7A",X"00",X"17",X"27",X"3D",X"9B",X"23",X"97",X"23",X"DE",X"1B",X"5F",X"96",X"23",
+ X"7D",X"00",X"16",X"2B",X"06",X"AB",X"00",X"25",X"08",X"20",X"0B",X"AB",X"00",X"27",X"02",X"25",
+ X"05",X"5D",X"27",X"08",X"20",X"0F",X"5D",X"26",X"03",X"DF",X"1B",X"5C",X"08",X"9C",X"1D",X"26",
+ X"DD",X"5D",X"26",X"01",X"39",X"DF",X"1D",X"96",X"15",X"27",X"06",X"8D",X"08",X"96",X"1A",X"8D",
+ X"16",X"7E",X"FB",X"E7",X"39",X"CE",X"00",X"24",X"DF",X"0F",X"DE",X"18",X"E6",X"00",X"08",X"BD",
+ X"FB",X"0A",X"DE",X"0F",X"DF",X"1F",X"39",X"4D",X"27",X"2B",X"DE",X"18",X"DF",X"0D",X"CE",X"00",
+ X"24",X"97",X"12",X"DF",X"0F",X"DE",X"0D",X"D6",X"12",X"D7",X"11",X"E6",X"01",X"54",X"54",X"54",
+ X"54",X"08",X"DF",X"0D",X"DE",X"0F",X"A6",X"00",X"10",X"7A",X"00",X"11",X"26",X"FA",X"A7",X"00",
+ X"08",X"9C",X"1F",X"26",X"DE",X"39",X"8E",X"00",X"7F",X"B6",X"04",X"02",X"0E",X"43",X"84",X"1F",
+ X"D6",X"08",X"27",X"09",X"2A",X"03",X"BD",X"FA",X"48",X"4A",X"BD",X"FA",X"89",X"5F",X"81",X"0E",
+ X"27",X"02",X"D7",X"06",X"81",X"12",X"27",X"02",X"D7",X"07",X"F6",X"EF",X"FD",X"C1",X"7E",X"26",
+ X"03",X"BD",X"EF",X"FD",X"4D",X"27",X"27",X"4A",X"81",X"0C",X"22",X"08",X"BD",X"FB",X"81",X"BD",
+ X"FB",X"E7",X"20",X"1A",X"81",X"1B",X"22",X"0E",X"80",X"0D",X"48",X"CE",X"FD",X"58",X"8D",X"21",
+ X"EE",X"00",X"AD",X"00",X"20",X"08",X"80",X"1C",X"BD",X"F8",X"2A",X"BD",X"F8",X"3F",X"96",X"04",
+ X"9A",X"05",X"27",X"FE",X"4F",X"97",X"07",X"96",X"04",X"27",X"03",X"7E",X"F9",X"13",X"7E",X"FB",
+ X"34",X"DF",X"0D",X"9B",X"0E",X"97",X"0E",X"24",X"03",X"7C",X"00",X"0D",X"DE",X"0D",X"39",X"0F",
+ X"8E",X"00",X"7F",X"CE",X"FF",X"FF",X"5F",X"E9",X"00",X"09",X"8C",X"F8",X"00",X"26",X"F8",X"E1",
+ X"00",X"27",X"01",X"3E",X"86",X"01",X"BD",X"F8",X"2A",X"BD",X"F8",X"3F",X"F6",X"EF",X"FA",X"C1",
+ X"7E",X"26",X"DC",X"BD",X"EF",X"FA",X"20",X"D7",X"FB",X"49",X"F9",X"13",X"FB",X"24",X"F8",X"8C",
+ X"FB",X"71",X"FB",X"1E",X"F8",X"CD",X"F8",X"94",X"F9",X"1C",X"F9",X"23",X"F9",X"A6",X"F9",X"D4",
+ X"F9",X"F3",X"FA",X"44",X"FA",X"84",X"40",X"01",X"00",X"10",X"E1",X"00",X"80",X"FF",X"FF",X"28",
+ X"01",X"00",X"08",X"81",X"02",X"00",X"FF",X"FF",X"28",X"81",X"00",X"FC",X"01",X"02",X"00",X"FC",
+ X"FF",X"FF",X"01",X"00",X"18",X"41",X"04",X"80",X"00",X"FF",X"8C",X"5B",X"B6",X"40",X"BF",X"49",
+ X"A4",X"73",X"73",X"A4",X"49",X"BF",X"40",X"B6",X"5B",X"8C",X"0C",X"7F",X"1D",X"0F",X"FB",X"7F",
+ X"23",X"0F",X"15",X"FE",X"08",X"50",X"8B",X"88",X"3E",X"3F",X"02",X"3E",X"7C",X"04",X"03",X"FF",
+ X"3E",X"3F",X"2C",X"E2",X"7C",X"12",X"0D",X"74",X"7C",X"0D",X"0E",X"41",X"7C",X"23",X"0B",X"50",
+ X"7C",X"1D",X"29",X"F2",X"7C",X"3F",X"02",X"3E",X"F8",X"04",X"03",X"FF",X"7C",X"3F",X"2C",X"E2",
+ X"F8",X"12",X"0D",X"74",X"F8",X"0D",X"0E",X"41",X"F8",X"23",X"0B",X"50",X"F8",X"1D",X"2F",X"F2",
+ X"F8",X"23",X"05",X"A8",X"F8",X"12",X"06",X"BA",X"F8",X"04",X"07",X"FF",X"7C",X"37",X"04",X"C1",
+ X"7C",X"23",X"05",X"A8",X"7C",X"12",X"06",X"BA",X"3E",X"04",X"07",X"FF",X"3E",X"37",X"04",X"C1",
+ X"3E",X"23",X"05",X"A8",X"1F",X"12",X"06",X"BA",X"1F",X"04",X"07",X"FF",X"1F",X"37",X"04",X"C1",
+ X"1F",X"23",X"16",X"A0",X"FE",X"1D",X"17",X"F9",X"7F",X"37",X"13",X"06",X"7F",X"3F",X"08",X"FA",
+ X"FE",X"04",X"0F",X"FF",X"FE",X"0D",X"0E",X"41",X"FE",X"23",X"0B",X"50",X"FE",X"1D",X"5F",X"E4",
+ X"00",X"47",X"3F",X"37",X"30",X"29",X"23",X"1D",X"17",X"12",X"0D",X"08",X"04",X"08",X"7F",X"D9",
+ X"FF",X"D9",X"7F",X"24",X"00",X"24",X"08",X"00",X"40",X"80",X"00",X"FF",X"00",X"80",X"40",X"10",
+ X"7F",X"B0",X"D9",X"F5",X"FF",X"F5",X"D9",X"B0",X"7F",X"4E",X"24",X"09",X"00",X"09",X"24",X"4E",
+ X"10",X"7F",X"C5",X"EC",X"E7",X"BF",X"8D",X"6D",X"6A",X"7F",X"94",X"92",X"71",X"40",X"17",X"12",
+ X"39",X"10",X"FF",X"FF",X"FF",X"FF",X"00",X"00",X"00",X"00",X"FF",X"FF",X"FF",X"FF",X"00",X"00",
+ X"00",X"00",X"48",X"8A",X"95",X"A0",X"AB",X"B5",X"BF",X"C8",X"D1",X"DA",X"E1",X"E8",X"EE",X"F3",
+ X"F7",X"FB",X"FD",X"FE",X"FF",X"FE",X"FD",X"FB",X"F7",X"F3",X"EE",X"E8",X"E1",X"DA",X"D1",X"C8",
+ X"BF",X"B5",X"AB",X"A0",X"95",X"8A",X"7F",X"75",X"6A",X"5F",X"54",X"4A",X"40",X"37",X"2E",X"25",
+ X"1E",X"17",X"11",X"0C",X"08",X"04",X"02",X"01",X"00",X"01",X"02",X"04",X"08",X"0C",X"11",X"17",
+ X"1E",X"25",X"2E",X"37",X"40",X"4A",X"54",X"5F",X"6A",X"75",X"7F",X"10",X"59",X"7B",X"98",X"AC",
+ X"B3",X"AC",X"98",X"7B",X"59",X"37",X"19",X"06",X"00",X"06",X"19",X"37",X"81",X"24",X"00",X"00",
+ X"00",X"16",X"31",X"12",X"05",X"1A",X"FF",X"00",X"27",X"6D",X"11",X"05",X"11",X"01",X"0F",X"01",
+ X"47",X"11",X"31",X"00",X"01",X"00",X"0D",X"1B",X"F4",X"12",X"00",X"00",X"00",X"14",X"47",X"41",
+ X"45",X"00",X"00",X"00",X"0F",X"5B",X"21",X"35",X"11",X"FF",X"00",X"0D",X"1B",X"15",X"00",X"00",
+ X"FD",X"00",X"01",X"69",X"31",X"11",X"00",X"01",X"00",X"03",X"6A",X"01",X"15",X"01",X"01",X"01",
+ X"01",X"47",X"F6",X"53",X"03",X"00",X"02",X"06",X"94",X"6A",X"10",X"02",X"00",X"02",X"06",X"9A",
+ X"1F",X"12",X"00",X"FF",X"10",X"04",X"69",X"31",X"11",X"00",X"FF",X"00",X"0D",X"00",X"12",X"06",
+ X"00",X"FF",X"01",X"09",X"28",X"A0",X"98",X"90",X"88",X"80",X"78",X"70",X"68",X"60",X"58",X"50",
+ X"44",X"40",X"01",X"01",X"02",X"02",X"04",X"04",X"08",X"08",X"10",X"10",X"30",X"60",X"C0",X"E0",
+ X"01",X"01",X"02",X"02",X"03",X"04",X"05",X"06",X"07",X"08",X"09",X"0A",X"0C",X"80",X"7C",X"78",
+ X"74",X"70",X"74",X"78",X"7C",X"80",X"01",X"01",X"02",X"02",X"04",X"04",X"08",X"08",X"10",X"20",
+ X"28",X"30",X"38",X"40",X"48",X"50",X"60",X"70",X"80",X"A0",X"B0",X"C0",X"08",X"40",X"08",X"40",
+ X"08",X"40",X"08",X"40",X"08",X"40",X"08",X"40",X"08",X"40",X"08",X"40",X"08",X"40",X"08",X"40",
+ X"01",X"02",X"04",X"08",X"09",X"0A",X"0B",X"0C",X"0E",X"0F",X"10",X"12",X"14",X"16",X"40",X"10",
+ X"08",X"01",X"01",X"01",X"01",X"01",X"02",X"02",X"03",X"03",X"04",X"04",X"05",X"06",X"08",X"0A",
+ X"0C",X"10",X"14",X"18",X"20",X"30",X"40",X"50",X"40",X"30",X"20",X"10",X"0C",X"0A",X"08",X"07",
+ X"06",X"05",X"04",X"03",X"02",X"02",X"01",X"01",X"01",X"07",X"08",X"09",X"0A",X"0C",X"08",X"17",
+ X"18",X"19",X"1A",X"1B",X"1C",X"00",X"00",X"00",X"FC",X"B6",X"F8",X"01",X"FD",X"2F",X"F8",X"01");
+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/Mayday/rtl/defender_sound_board.vhd b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/rtl/defender_sound_board.vhd
new file mode 100644
index 00000000..5fdd8293
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/rtl/defender_sound_board.vhd
@@ -0,0 +1,186 @@
+---------------------------------------------------------------------------------
+-- 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_1p79 : in std_logic;
+ clk_0p89 : in std_logic;
+ reset : in std_logic;
+
+ select_sound : in std_logic_vector(5 downto 0);
+ audio_out : out std_logic_vector( 7 downto 0);
+
+ dbg_cpu_addr : out std_logic_vector(15 downto 0)
+);
+end defender_sound_board;
+
+architecture struct of defender_sound_board is
+
+ signal reset_n : std_logic;
+
+ signal cpu_clock : 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 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_clock : std_logic;
+ 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;
+
+dbg_cpu_addr <= cpu_addr;
+cpu_clock <= clk_0p89;
+
+
+-- pia cs
+wram_cs <= '1' when cpu_addr(15 downto 8) = X"00" else '0'; -- 0000-007F
+pia_cs <= '1' when cpu_addr(15 downto 12) = X"0" 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 cpu_clock = '1' and wram_cs = '1' else '0';
+pia_rw_n <= '0' when cpu_rw = '0' and cpu_clock = '1' 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
+pia_clock <= clk_1p79; -- 3p58/2
+audio_out <= pia_pa_o;
+
+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(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 => cpu_clock,-- E clock input (falling edge)
+ rst => reset, -- reset input (active high)
+ rw => cpu_rw, -- read not write output
+ vma => open, -- 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_1p79,
+ addr => cpu_addr(10 downto 0),
+ data => rom_do
+);
+
+-- cpu wram
+cpu_ram : entity work.gen_ram
+generic map( dWidth => 8, aWidth => 7)
+port map(
+ clk => clk_1p79,
+ we => wram_we,
+ addr => cpu_addr(6 downto 0),
+ d => cpu_do,
+ q => wram_do
+);
+
+-- pia
+pia : entity work.pia6821
+port map
+(
+ clk => clk_1p79,
+ 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/Mayday/rtl/gen_ram.vhd b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/rtl/gen_ram.vhd
new file mode 100644
index 00000000..f1a95608
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/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/Mayday/rtl/pia6821.vhd b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/rtl/pia6821.vhd
new file mode 100644
index 00000000..d565ae36
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/rtl/pia6821.vhd
@@ -0,0 +1,553 @@
+--===========================================================================--
+--
+-- S Y N T H E Z I A B L E I/O Port C O R E
+--
+-- www.OpenCores.Org - May 2004
+-- This core adheres to the GNU public license
+--
+-- File name : pia6821.vhd
+--
+-- Purpose : Implements 2 x 8 bit parallel I/O ports
+-- with programmable data direction registers
+--
+-- Dependencies : ieee.Std_Logic_1164
+-- ieee.std_logic_unsigned
+--
+-- Author : John E. Kent
+--
+--===========================================================================----
+--
+-- Revision History:
+--
+-- Date: Revision Author
+-- 1 May 2004 0.0 John Kent
+-- Initial version developed from ioport.vhd
+--
+--
+-- Unkown date 0.0.1 found at Pacedev repository
+-- remove High Z output and and oe signal
+--
+-- 18 October 2017 0.0.2 DarFpga
+-- Set output to low level when in data is in input mode
+-- (to avoid infered latch warning)
+--
+--===========================================================================----
+--
+-- Memory Map
+--
+-- IO + $00 - Port A Data & Direction register
+-- IO + $01 - Port A Control register
+-- IO + $02 - Port B Data & Direction Direction Register
+-- IO + $03 - Port B Control Register
+--
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_unsigned.all;
+
+entity pia6821 is
+ port (
+ clk : in std_logic;
+ rst : in std_logic;
+ cs : in std_logic;
+ rw : in std_logic;
+ addr : in std_logic_vector(1 downto 0);
+ data_in : in std_logic_vector(7 downto 0);
+ data_out : out std_logic_vector(7 downto 0);
+ irqa : out std_logic;
+ irqb : out std_logic;
+ pa_i : in std_logic_vector(7 downto 0);
+ pa_o : out std_logic_vector(7 downto 0);
+ pa_oe : out std_logic_vector(7 downto 0);
+ ca1 : in std_logic;
+ ca2_i : in std_logic;
+ ca2_o : out std_logic;
+ ca2_oe : out std_logic;
+ pb_i : in std_logic_vector(7 downto 0);
+ pb_o : out std_logic_vector(7 downto 0);
+ pb_oe : out std_logic_vector(7 downto 0);
+ cb1 : in std_logic;
+ cb2_i : in std_logic;
+ cb2_o : out std_logic;
+ cb2_oe : out std_logic
+ );
+end;
+
+architecture pia_arch of pia6821 is
+
+signal porta_ddr : std_logic_vector(7 downto 0);
+signal porta_data : std_logic_vector(7 downto 0);
+signal porta_ctrl : std_logic_vector(5 downto 0);
+signal porta_read : std_logic;
+
+signal portb_ddr : std_logic_vector(7 downto 0);
+signal portb_data : std_logic_vector(7 downto 0);
+signal portb_ctrl : std_logic_vector(5 downto 0);
+signal portb_read : std_logic;
+signal portb_write : std_logic;
+
+signal ca1_del : std_logic;
+signal ca1_rise : std_logic;
+signal ca1_fall : std_logic;
+signal ca1_edge : std_logic;
+signal irqa1 : std_logic;
+
+signal ca2_del : std_logic;
+signal ca2_rise : std_logic;
+signal ca2_fall : std_logic;
+signal ca2_edge : std_logic;
+signal irqa2 : std_logic;
+signal ca2_out : std_logic;
+
+signal cb1_del : std_logic;
+signal cb1_rise : std_logic;
+signal cb1_fall : std_logic;
+signal cb1_edge : std_logic;
+signal irqb1 : std_logic;
+
+signal cb2_del : std_logic;
+signal cb2_rise : std_logic;
+signal cb2_fall : std_logic;
+signal cb2_edge : std_logic;
+signal irqb2 : std_logic;
+signal cb2_out : std_logic;
+
+begin
+
+--------------------------------
+--
+-- read I/O port
+--
+--------------------------------
+
+pia_read : process( addr, cs,
+ irqa1, irqa2, irqb1, irqb2,
+ porta_ddr, portb_ddr,
+ porta_data, portb_data,
+ porta_ctrl, portb_ctrl,
+ pa_i, pb_i )
+variable count : integer;
+begin
+ case addr is
+ when "00" =>
+ for count in 0 to 7 loop
+ if porta_ctrl(2) = '0' then
+ data_out(count) <= porta_ddr(count);
+ porta_read <= '0';
+ else
+ if porta_ddr(count) = '1' then
+ data_out(count) <= porta_data(count);
+ else
+ data_out(count) <= pa_i(count);
+ end if;
+ porta_read <= cs;
+ end if;
+ end loop;
+ portb_read <= '0';
+
+ when "01" =>
+ data_out <= irqa1 & irqa2 & porta_ctrl;
+ porta_read <= '0';
+ portb_read <= '0';
+
+ when "10" =>
+ for count in 0 to 7 loop
+ if portb_ctrl(2) = '0' then
+ data_out(count) <= portb_ddr(count);
+ portb_read <= '0';
+ else
+ if portb_ddr(count) = '1' then
+ data_out(count) <= portb_data(count);
+ else
+ data_out(count) <= pb_i(count);
+ end if;
+ portb_read <= cs;
+ end if;
+ end loop;
+ porta_read <= '0';
+
+ when "11" =>
+ data_out <= irqb1 & irqb2 & portb_ctrl;
+ porta_read <= '0';
+ portb_read <= '0';
+
+ when others =>
+ data_out <= "00000000";
+ porta_read <= '0';
+ portb_read <= '0';
+
+ end case;
+end process;
+
+---------------------------------
+--
+-- Write I/O ports
+--
+---------------------------------
+
+pia_write : process( clk, rst, addr, cs, rw, data_in,
+ porta_ctrl, portb_ctrl,
+ porta_data, portb_data,
+ porta_ddr, portb_ddr )
+begin
+ if rst = '1' then
+ porta_ddr <= "00000000";
+ porta_data <= "00000000";
+ porta_ctrl <= "000000";
+ portb_ddr <= "00000000";
+ portb_data <= "00000000";
+ portb_ctrl <= "000000";
+ portb_write <= '0';
+ elsif clk'event and clk = '1' then
+ if cs = '1' and rw = '0' then
+ case addr is
+ when "00" =>
+ if porta_ctrl(2) = '0' then
+ porta_ddr <= data_in;
+ porta_data <= porta_data;
+ else
+ porta_ddr <= porta_ddr;
+ porta_data <= data_in;
+ end if;
+ porta_ctrl <= porta_ctrl;
+ portb_ddr <= portb_ddr;
+ portb_data <= portb_data;
+ portb_ctrl <= portb_ctrl;
+ portb_write <= '0';
+ when "01" =>
+ porta_ddr <= porta_ddr;
+ porta_data <= porta_data;
+ porta_ctrl <= data_in(5 downto 0);
+ portb_ddr <= portb_ddr;
+ portb_data <= portb_data;
+ portb_ctrl <= portb_ctrl;
+ portb_write <= '0';
+ when "10" =>
+ porta_ddr <= porta_ddr;
+ porta_data <= porta_data;
+ porta_ctrl <= porta_ctrl;
+ if portb_ctrl(2) = '0' then
+ portb_ddr <= data_in;
+ portb_data <= portb_data;
+ portb_write <= '0';
+ else
+ portb_ddr <= portb_ddr;
+ portb_data <= data_in;
+ portb_write <= '1';
+ end if;
+ portb_ctrl <= portb_ctrl;
+ when "11" =>
+ porta_ddr <= porta_ddr;
+ porta_data <= porta_data;
+ porta_ctrl <= porta_ctrl;
+ portb_ddr <= portb_ddr;
+ portb_data <= portb_data;
+ portb_ctrl <= data_in(5 downto 0);
+ portb_write <= '0';
+ when others =>
+ porta_ddr <= porta_ddr;
+ porta_data <= porta_data;
+ porta_ctrl <= porta_ctrl;
+ portb_ddr <= portb_ddr;
+ portb_data <= portb_data;
+ portb_ctrl <= portb_ctrl;
+ portb_write <= '0';
+ end case;
+ else
+ porta_ddr <= porta_ddr;
+ porta_data <= porta_data;
+ porta_ctrl <= porta_ctrl;
+ portb_data <= portb_data;
+ portb_ddr <= portb_ddr;
+ portb_ctrl <= portb_ctrl;
+ portb_write <= '0';
+ end if;
+ end if;
+end process;
+
+---------------------------------
+--
+-- direction control port a
+--
+---------------------------------
+porta_direction : process ( porta_data, porta_ddr )
+variable count : integer;
+begin
+ for count in 0 to 7 loop
+ if porta_ddr(count) = '1' then
+ pa_o(count) <= porta_data(count);
+ pa_oe(count) <= '1';
+ else
+ pa_o(count) <= '0';
+ pa_oe(count) <= '0';
+ end if;
+ end loop;
+end process;
+
+---------------------------------
+--
+-- CA1 Edge detect
+--
+---------------------------------
+ca1_input : process( clk, rst, ca1, ca1_del,
+ ca1_rise, ca1_fall, ca1_edge,
+ irqa1, porta_ctrl, porta_read )
+begin
+ if rst = '1' then
+ ca1_del <= '0';
+ ca1_rise <= '0';
+ ca1_fall <= '0';
+ ca1_edge <= '0';
+ irqa1 <= '0';
+ elsif clk'event and clk = '0' then
+ ca1_del <= ca1;
+ ca1_rise <= (not ca1_del) and ca1;
+ ca1_fall <= ca1_del and (not ca1);
+ if ca1_edge = '1' then
+ irqa1 <= '1';
+ elsif porta_read = '1' then
+ irqa1 <= '0';
+ else
+ irqa1 <= irqa1;
+ end if;
+ end if;
+
+ if porta_ctrl(1) = '0' then
+ ca1_edge <= ca1_fall;
+ else
+ ca1_edge <= ca1_rise;
+ end if;
+end process;
+
+---------------------------------
+--
+-- CA2 Edge detect
+--
+---------------------------------
+ca2_input : process( clk, rst, ca2_i, ca2_del,
+ ca2_rise, ca2_fall, ca2_edge,
+ irqa2, porta_ctrl, porta_read )
+begin
+ if rst = '1' then
+ ca2_del <= '0';
+ ca2_rise <= '0';
+ ca2_fall <= '0';
+ ca2_edge <= '0';
+ irqa2 <= '0';
+ elsif clk'event and clk = '0' then
+ ca2_del <= ca2_i;
+ ca2_rise <= (not ca2_del) and ca2_i;
+ ca2_fall <= ca2_del and (not ca2_i);
+ if porta_ctrl(5) = '0' and ca2_edge = '1' then
+ irqa2 <= '1';
+ elsif porta_read = '1' then
+ irqa2 <= '0';
+ else
+ irqa2 <= irqa2;
+ end if;
+ end if;
+
+ if porta_ctrl(4) = '0' then
+ ca2_edge <= ca2_fall;
+ else
+ ca2_edge <= ca2_rise;
+ end if;
+end process;
+
+---------------------------------
+--
+-- CA2 output control
+--
+---------------------------------
+ca2_output : process( clk, rst, porta_ctrl, porta_read, ca1_edge, ca2_out )
+begin
+ if rst='1' then
+ ca2_out <= '0';
+ elsif clk'event and clk='0' then
+ case porta_ctrl(5 downto 3) is
+ when "100" => -- read PA clears, CA1 edge sets
+ if porta_read = '1' then
+ ca2_out <= '0';
+ elsif ca1_edge = '1' then
+ ca2_out <= '1';
+ else
+ ca2_out <= ca2_out;
+ end if;
+ when "101" => -- read PA clears, E sets
+ ca2_out <= not porta_read;
+ when "110" => -- set low
+ ca2_out <= '0';
+ when "111" => -- set high
+ ca2_out <= '1';
+ when others => -- no change
+ ca2_out <= ca2_out;
+ end case;
+ end if;
+end process;
+
+---------------------------------
+--
+-- CA2 direction control
+--
+---------------------------------
+ca2_direction : process( porta_ctrl, ca2_out )
+begin
+ if porta_ctrl(5) = '0' then
+ ca2_oe <= '0';
+ ca2_o <= '0';
+ else
+ ca2_o <= ca2_out;
+ ca2_oe <= '1';
+ end if;
+end process;
+
+---------------------------------
+--
+-- direction control port b
+--
+---------------------------------
+portb_direction : process ( portb_data, portb_ddr )
+variable count : integer;
+begin
+ for count in 0 to 7 loop
+ if portb_ddr(count) = '1' then
+ pb_o(count) <= portb_data(count);
+ pb_oe(count) <= '1';
+ else
+ pb_o(count) <= '0';
+ pb_oe(count) <= '0';
+ end if;
+ end loop;
+end process;
+
+---------------------------------
+--
+-- CB1 Edge detect
+--
+---------------------------------
+cb1_input : process( clk, rst, cb1, cb1_del,
+ cb1_rise, cb1_fall, cb1_edge,
+ irqb1, portb_ctrl, portb_read )
+begin
+ if rst = '1' then
+ cb1_del <= '0';
+ cb1_rise <= '0';
+ cb1_fall <= '0';
+ cb1_edge <= '0';
+ irqb1 <= '0';
+ elsif clk'event and clk = '0' then
+ cb1_del <= cb1;
+ cb1_rise <= (not cb1_del) and cb1;
+ cb1_fall <= cb1_del and (not cb1);
+ if cb1_edge = '1' then
+ irqb1 <= '1';
+ elsif portb_read = '1' then
+ irqb1 <= '0';
+ else
+ irqb1 <= irqb1;
+ end if;
+ end if;
+
+ if portb_ctrl(1) = '0' then
+ cb1_edge <= cb1_fall;
+ else
+ cb1_edge <= cb1_rise;
+ end if;
+end process;
+
+---------------------------------
+--
+-- CB2 Edge detect
+--
+---------------------------------
+cb2_input : process( clk, rst, cb2_i, cb2_del,
+ cb2_rise, cb2_fall, cb2_edge,
+ irqb2, portb_ctrl, portb_read )
+begin
+ if rst = '1' then
+ cb2_del <= '0';
+ cb2_rise <= '0';
+ cb2_fall <= '0';
+ cb2_edge <= '0';
+ irqb2 <= '0';
+ elsif clk'event and clk = '0' then
+ cb2_del <= cb2_i;
+ cb2_rise <= (not cb2_del) and cb2_i;
+ cb2_fall <= cb2_del and (not cb2_i);
+ if portb_ctrl(5) = '0' and cb2_edge = '1' then
+ irqb2 <= '1';
+ elsif portb_read = '1' then
+ irqb2 <= '0';
+ else
+ irqb2 <= irqb2;
+ end if;
+ end if;
+
+ if portb_ctrl(4) = '0' then
+ cb2_edge <= cb2_fall;
+ else
+ cb2_edge <= cb2_rise;
+ end if;
+
+end process;
+
+---------------------------------
+--
+-- CB2 output control
+--
+---------------------------------
+cb2_output : process( clk, rst, portb_ctrl, portb_write, cb1_edge, cb2_out )
+begin
+ if rst='1' then
+ cb2_out <= '0';
+ elsif clk'event and clk='0' then
+ case portb_ctrl(5 downto 3) is
+ when "100" => -- write PB clears, CA1 edge sets
+ if portb_write = '1' then
+ cb2_out <= '0';
+ elsif cb1_edge = '1' then
+ cb2_out <= '1';
+ else
+ cb2_out <= cb2_out;
+ end if;
+ when "101" => -- write PB clears, E sets
+ cb2_out <= not portb_write;
+ when "110" => -- set low
+ cb2_out <= '0';
+ when "111" => -- set high
+ cb2_out <= '1';
+ when others => -- no change
+ cb2_out <= cb2_out;
+ end case;
+ end if;
+end process;
+
+---------------------------------
+--
+-- CB2 direction control
+--
+---------------------------------
+cb2_direction : process( portb_ctrl, cb2_out )
+begin
+ if portb_ctrl(5) = '0' then
+ cb2_oe <= '0';
+ cb2_o <= '0';
+ else
+ cb2_o <= cb2_out;
+ cb2_oe <= '1';
+ end if;
+end process;
+
+---------------------------------
+--
+-- IRQ control
+--
+---------------------------------
+pia_irq : process( irqa1, irqa2, irqb1, irqb2, porta_ctrl, portb_ctrl )
+begin
+ irqa <= (irqa1 and porta_ctrl(0)) or (irqa2 and porta_ctrl(3));
+ irqb <= (irqb1 and portb_ctrl(0)) or (irqb2 and portb_ctrl(3));
+end process;
+
+end pia_arch;
+
diff --git a/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/rtl/pll_mist.ppf b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/rtl/pll_mist.ppf
new file mode 100644
index 00000000..db79bfc9
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/rtl/pll_mist.ppf
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/rtl/pll_mist.qip b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/rtl/pll_mist.qip
new file mode 100644
index 00000000..d4720390
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/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/Mayday/rtl/pll_mist.vhd b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/rtl/pll_mist.vhd
new file mode 100644
index 00000000..b54b7a75
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/rtl/pll_mist.vhd
@@ -0,0 +1,461 @@
+-- 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 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 ;
+ c3 : 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 ;
+ SIGNAL sub_wire7 : STD_LOGIC_VECTOR (1 DOWNTO 0);
+ SIGNAL sub_wire8_bv : BIT_VECTOR (0 DOWNTO 0);
+ SIGNAL sub_wire8 : 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;
+ clk3_divide_by : NATURAL;
+ clk3_duty_cycle : NATURAL;
+ clk3_multiply_by : NATURAL;
+ clk3_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_wire8_bv(0 DOWNTO 0) <= "0";
+ sub_wire8 <= To_stdlogicvector(sub_wire8_bv);
+ sub_wire5 <= sub_wire0(2);
+ sub_wire4 <= sub_wire0(0);
+ sub_wire2 <= sub_wire0(3);
+ sub_wire1 <= sub_wire0(1);
+ c1 <= sub_wire1;
+ c3 <= sub_wire2;
+ locked <= sub_wire3;
+ c0 <= sub_wire4;
+ c2 <= sub_wire5;
+ sub_wire6 <= inclk0;
+ sub_wire7 <= sub_wire8(0 DOWNTO 0) & sub_wire6;
+
+ altpll_component : altpll
+ GENERIC MAP (
+ bandwidth_type => "AUTO",
+ clk0_divide_by => 3,
+ clk0_duty_cycle => 50,
+ clk0_multiply_by => 4,
+ clk0_phase_shift => "0",
+ clk1_divide_by => 9,
+ clk1_duty_cycle => 50,
+ clk1_multiply_by => 2,
+ clk1_phase_shift => "0",
+ clk2_divide_by => 181,
+ clk2_duty_cycle => 50,
+ clk2_multiply_by => 12,
+ clk2_phase_shift => "0",
+ clk3_divide_by => 91,
+ clk3_duty_cycle => 50,
+ clk3_multiply_by => 3,
+ clk3_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_USED",
+ 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_wire7,
+ clk => sub_wire0,
+ locked => sub_wire3
+ );
+
+
+
+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 "181"
+-- Retrieval info: PRIVATE: DIV_FACTOR3 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: DUTY_CYCLE3 STRING "50.00000000"
+-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "36.000000"
+-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "6.000000"
+-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE2 STRING "1.790055"
+-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE3 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: LVDS_PHASE_SHIFT_UNIT3 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: MIRROR_CLK3 STRING "0"
+-- Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "4"
+-- Retrieval info: PRIVATE: MULT_FACTOR1 NUMERIC "2"
+-- Retrieval info: PRIVATE: MULT_FACTOR2 NUMERIC "12"
+-- Retrieval info: PRIVATE: MULT_FACTOR3 NUMERIC "3"
+-- Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1"
+-- Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "36.00000000"
+-- Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "6.00000000"
+-- Retrieval info: PRIVATE: OUTPUT_FREQ2 STRING "1.79000000"
+-- Retrieval info: PRIVATE: OUTPUT_FREQ3 STRING "0.89000000"
+-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "0"
+-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE1 STRING "0"
+-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE2 STRING "0"
+-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE3 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: OUTPUT_FREQ_UNIT3 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_SHIFT3 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: PHASE_SHIFT_UNIT3 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: STICKY_CLK3 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_CLK3 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_CLKENA3 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 "3"
+-- Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50"
+-- Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "4"
+-- Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0"
+-- Retrieval info: CONSTANT: CLK1_DIVIDE_BY NUMERIC "9"
+-- Retrieval info: CONSTANT: CLK1_DUTY_CYCLE NUMERIC "50"
+-- Retrieval info: CONSTANT: CLK1_MULTIPLY_BY NUMERIC "2"
+-- Retrieval info: CONSTANT: CLK1_PHASE_SHIFT STRING "0"
+-- Retrieval info: CONSTANT: CLK2_DIVIDE_BY NUMERIC "181"
+-- Retrieval info: CONSTANT: CLK2_DUTY_CYCLE NUMERIC "50"
+-- Retrieval info: CONSTANT: CLK2_MULTIPLY_BY NUMERIC "12"
+-- Retrieval info: CONSTANT: CLK2_PHASE_SHIFT STRING "0"
+-- Retrieval info: CONSTANT: CLK3_DIVIDE_BY NUMERIC "91"
+-- Retrieval info: CONSTANT: CLK3_DUTY_CYCLE NUMERIC "50"
+-- Retrieval info: CONSTANT: CLK3_MULTIPLY_BY NUMERIC "3"
+-- Retrieval info: CONSTANT: CLK3_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_USED"
+-- 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: c3 0 0 0 0 OUTPUT_CLK_EXT VCC "c3"
+-- 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: c3 0 0 0 0 @clk 0 0 1 3
+-- 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/Mayday/rtl/sdram.sv b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/rtl/sdram.sv
new file mode 100644
index 00000000..8f927d05
--- /dev/null
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Mayday/rtl/sdram.sv
@@ -0,0 +1,254 @@
+//
+// sdram.v
+//
+// Static RAM controller implementation using SDRAM MT48LC16M16A2
+//
+// Copyright (c) 2015,2016 Sorgelig
+//
+// Some parts of SDRAM code used from project:
+// http://hamsterworks.co.nz/mediawiki/index.php/Simple_SDRAM_Controller
+//
+// 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 .
+//
+// ------------------------------------------
+//
+// v2.1 - Add universal 8/16 bit mode.
+//
+
+module sdram
+(
+ input init, // reset to initialize RAM
+ input clk, // clock ~100MHz
+ //
+ // SDRAM_* - signals 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, //
+ 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
+ output SDRAM_CKE, // clock enable
+ //
+ input [1:0] wtbt, // 16bit mode: bit1 - write high byte, bit0 - write low byte,
+ // 8bit mode: 2'b00 - use addr[0] to decide which byte to write
+ // Ignored while reading.
+ //
+ input [24:0] addr, // 25 bit address for 8bit mode. addr[0] = 0 for 16bit mode for correct operations.
+ output [15:0] dout, // data output to cpu
+ input [15:0] din, // data input from cpu
+ input we, // cpu requests write
+ input rd, // cpu requests read
+ output reg ready // dout is valid. Ready to accept new read/write.
+);
+
+assign SDRAM_nCS = command[3];
+assign SDRAM_nRAS = command[2];
+assign SDRAM_nCAS = command[1];
+assign SDRAM_nWE = command[0];
+assign SDRAM_CKE = cke;
+
+// no burst configured
+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 for < 100MHz, 3 for >100MHz
+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};
+
+localparam sdram_startup_cycles= 14'd12100;// 100us, plus a little more, @ 100MHz
+localparam cycles_per_refresh = 14'd186; // (64000*36)/8192-1 Calc'd as (64ms @ 36MHz)/8192 rose
+localparam startup_refresh_max = 14'b11111111111111;
+
+// SDRAM 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 [13:0] refresh_count = startup_refresh_max - sdram_startup_cycles;
+reg [3:0] command = CMD_INHIBIT;
+reg cke = 0;
+reg [24:0] save_addr;
+reg [15:0] data;
+
+assign dout = save_addr[0] ? {data[7:0], data[15:8]} : {data[15:8], data[7:0]};
+typedef enum
+{
+ STATE_STARTUP,
+ STATE_OPEN_1,
+ STATE_WRITE,
+ STATE_READ,
+ STATE_IDLE, STATE_IDLE_1, STATE_IDLE_2, STATE_IDLE_3,
+ STATE_IDLE_4, STATE_IDLE_5, STATE_IDLE_6, STATE_IDLE_7
+} state_t;
+
+state_t state = STATE_STARTUP;
+
+always @(posedge clk) begin
+ reg old_we, old_rd;
+ reg [CAS_LATENCY:0] data_ready_delay;
+
+ reg [15:0] new_data;
+ reg [1:0] new_wtbt;
+ reg new_we;
+ reg new_rd;
+ reg save_we = 1;
+
+
+ command <= CMD_NOP;
+ refresh_count <= refresh_count+1'b1;
+
+ data_ready_delay <= {1'b0, data_ready_delay[CAS_LATENCY:1]};
+
+ if(data_ready_delay[0]) data <= SDRAM_DQ;
+
+ case(state)
+ STATE_STARTUP: begin
+ //------------------------------------------------------------------------
+ //-- This is the initial startup state, where we wait for at least 100us
+ //-- before starting the start sequence
+ //--
+ //-- The initialisation is sequence is
+ //-- * de-assert SDRAM_CKE
+ //-- * 100us wait,
+ //-- * assert SDRAM_CKE
+ //-- * wait at least one cycle,
+ //-- * PRECHARGE
+ //-- * wait 2 cycles
+ //-- * REFRESH,
+ //-- * tREF wait
+ //-- * REFRESH,
+ //-- * tREF wait
+ //-- * LOAD_MODE_REG
+ //-- * 2 cycles wait
+ //------------------------------------------------------------------------
+ cke <= 1;
+ SDRAM_DQ <= 16'bZZZZZZZZZZZZZZZZ;
+ SDRAM_DQML <= 1;
+ SDRAM_DQMH <= 1;
+ SDRAM_A <= 0;
+ SDRAM_BA <= 0;
+
+ // All the commands during the startup are NOPS, except these
+ if(refresh_count == startup_refresh_max-31) begin
+ // ensure all rows are closed
+ command <= CMD_PRECHARGE;
+ SDRAM_A[10] <= 1; // all banks
+ SDRAM_BA <= 2'b00;
+ end else if (refresh_count == startup_refresh_max-23) begin
+ // these refreshes need to be at least tREF (66ns) apart
+ command <= CMD_AUTO_REFRESH;
+ end else if (refresh_count == startup_refresh_max-15)
+ command <= CMD_AUTO_REFRESH;
+ else if (refresh_count == startup_refresh_max-7) begin
+ // Now load the mode register
+ command <= CMD_LOAD_MODE;
+ SDRAM_A <= MODE;
+ end
+
+ //------------------------------------------------------
+ //-- if startup is complete then go into idle mode,
+ //-- get prepared to accept a new command, and schedule
+ //-- the first refresh cycle
+ //------------------------------------------------------
+ if(!refresh_count) begin
+ state <= STATE_IDLE;
+ ready <= 1;
+ refresh_count <= 0;
+ end
+ end
+
+ STATE_IDLE_7: state <= STATE_IDLE_6;
+ STATE_IDLE_6: state <= STATE_IDLE_5;
+ STATE_IDLE_5: state <= STATE_IDLE_4;
+ STATE_IDLE_4: state <= STATE_IDLE_3;
+ STATE_IDLE_3: state <= STATE_IDLE_2;
+ STATE_IDLE_2: state <= STATE_IDLE_1;
+ STATE_IDLE_1: begin
+ SDRAM_DQ <= 16'bZZZZZZZZZZZZZZZZ;
+ state <= STATE_IDLE;
+ // mask possible refresh to reduce colliding.
+ if(refresh_count > cycles_per_refresh) begin
+ //------------------------------------------------------------------------
+ //-- Start the refresh cycle.
+ //-- This tasks tRFC (66ns), so 2 idle cycles are needed @ 36MHz
+ //------------------------------------------------------------------------
+ state <= STATE_IDLE_2;
+ command <= CMD_AUTO_REFRESH;
+ refresh_count <= refresh_count - cycles_per_refresh + 1'd1;
+ end
+ end
+
+ STATE_IDLE: begin
+ // Priority is to issue a refresh if one is outstanding
+ if(refresh_count > (cycles_per_refresh<<1)) state <= STATE_IDLE_1;
+ else if(new_rd | new_we) begin
+ new_we <= 0;
+ new_rd <= 0;
+ save_addr<= addr;
+ save_we <= new_we;
+ state <= STATE_OPEN_1;
+ command <= CMD_ACTIVE;
+ SDRAM_A <= addr[13:1];
+ SDRAM_BA <= addr[24:23];
+ end
+ end
+
+ // ACTIVE-to-READ or WRITE delay >20ns (1 cycle @ 36 MHz)(-75)
+ STATE_OPEN_1: begin
+ SDRAM_A <= {4'b0010, save_addr[22:14]};
+ SDRAM_DQML <= save_we & (new_wtbt ? ~new_wtbt[0] : save_addr[0]);
+ SDRAM_DQMH <= save_we & (new_wtbt ? ~new_wtbt[1] : ~save_addr[0]);
+ state <= save_we ? STATE_WRITE : STATE_READ;
+ end
+
+ STATE_READ: begin
+ state <= STATE_IDLE_5;
+ command <= CMD_READ;
+ SDRAM_DQ <= 16'bZZZZZZZZZZZZZZZZ;
+
+ // Schedule reading the data values off the bus
+ data_ready_delay[CAS_LATENCY] <= 1;
+ end
+
+ STATE_WRITE: begin
+ state <= STATE_IDLE_5;
+ command <= CMD_WRITE;
+ SDRAM_DQ <= new_wtbt ? new_data : {new_data[7:0], new_data[7:0]};
+ ready <= 1;
+ end
+ endcase
+
+ if(init) begin
+ state <= STATE_STARTUP;
+ refresh_count <= startup_refresh_max - sdram_startup_cycles;
+ end
+
+ old_we <= we;
+ old_rd <= rd;
+ if(we & ~old_we) {ready, new_we, new_data, new_wtbt} <= {1'b0, 1'b1, din, wtbt};
+ else
+ if((rd & ~old_rd) || (rd & old_rd & (save_addr != addr))) {ready, new_rd} <= {1'b0, 1'b1};
+
+end
+
+endmodule