From b52c8613ea9491b5bf6dffb77cc656045590bfed Mon Sep 17 00:00:00 2001 From: Gyorgy Szombathelyi Date: Sun, 27 Mar 2022 17:00:45 +0200 Subject: [PATCH] Williams rev.2 works --- .../Williams 6809 rev.2 Hardware/README | 90 +- .../Williams 6809 rev.2 Hardware/README.md | 54 + .../Williams 6809 rev.2 Hardware/ReadMe.txt | 6 - .../Williams2.qpf | 31 + .../{WilliamsHWv2.qsf => Williams2.qsf} | 142 +- .../{WilliamsHWv2.sdc => Williams2.sdc} | 24 +- .../WilliamsHWv2.qpf | 31 - .../meta/Inferno.mra | 57 + ...- Survival of the Fittest (revision 2).mra | 65 + .../meta/Mystic Marathon.mra | 60 + .../meta/Turkey Shoot.mra | 60 + .../rtl/Williams2_MiST.sv | 431 ++ .../rtl/WilliamsV2_MiST.sv | 325 - .../rtl/dpram.vhd | 81 + .../rtl/gray_code.vhd | 95 + .../rtl/hc55564.vhd | 84 + .../rtl/pll_mist.vhd | 30 +- .../rtl/rom/make..bat | 11 - .../rtl/rom/make_vhdl_prom.exe | Bin 119861 -> 0 bytes .../williams2_decoder.vhd} | 4 +- .../rtl/rtl_jkent/cpu09l_128.vhd | 5906 ----------------- .../rtl/rtl_jkent/cpu68_2.vhd | 4019 ----------- .../rtl/rtl_pace/pia6821.vhd | 553 -- .../Williams 6809 rev.2 Hardware/rtl/sdram.sv | 75 +- .../rtl/tshoot_cmos_ram.vhd | 182 - .../rtl/tshoot_sound_board.vhd | 25 +- .../rtl/williams2.vhd | 550 +- .../rtl/williams2_colormix.vhd | 91 + .../rtl/williams_cvsd_board.vhd | 495 ++ 29 files changed, 2073 insertions(+), 11504 deletions(-) create mode 100644 Arcade_MiST/Williams 6809 rev.2 Hardware/README.md delete mode 100644 Arcade_MiST/Williams 6809 rev.2 Hardware/ReadMe.txt create mode 100644 Arcade_MiST/Williams 6809 rev.2 Hardware/Williams2.qpf rename Arcade_MiST/Williams 6809 rev.2 Hardware/{WilliamsHWv2.qsf => Williams2.qsf} (65%) rename Arcade_MiST/Williams 6809 rev.2 Hardware/{WilliamsHWv2.sdc => Williams2.sdc} (83%) delete mode 100644 Arcade_MiST/Williams 6809 rev.2 Hardware/WilliamsHWv2.qpf create mode 100644 Arcade_MiST/Williams 6809 rev.2 Hardware/meta/Inferno.mra create mode 100644 Arcade_MiST/Williams 6809 rev.2 Hardware/meta/Joust 2 - Survival of the Fittest (revision 2).mra create mode 100644 Arcade_MiST/Williams 6809 rev.2 Hardware/meta/Mystic Marathon.mra create mode 100644 Arcade_MiST/Williams 6809 rev.2 Hardware/meta/Turkey Shoot.mra create mode 100644 Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/Williams2_MiST.sv delete mode 100644 Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/WilliamsV2_MiST.sv create mode 100644 Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/dpram.vhd create mode 100644 Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/gray_code.vhd create mode 100644 Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/hc55564.vhd delete mode 100644 Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/rom/make..bat delete mode 100644 Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/rom/make_vhdl_prom.exe rename Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/{rom/turkey_shoot_decoder.vhd => roms/williams2_decoder.vhd} (97%) delete mode 100644 Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/rtl_jkent/cpu09l_128.vhd delete mode 100644 Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/rtl_jkent/cpu68_2.vhd delete mode 100644 Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/rtl_pace/pia6821.vhd delete mode 100644 Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/tshoot_cmos_ram.vhd create mode 100644 Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/williams2_colormix.vhd create mode 100644 Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/williams_cvsd_board.vhd diff --git a/Arcade_MiST/Williams 6809 rev.2 Hardware/README b/Arcade_MiST/Williams 6809 rev.2 Hardware/README index 7d23b0a6..69e1b915 100644 --- a/Arcade_MiST/Williams 6809 rev.2 Hardware/README +++ b/Arcade_MiST/Williams 6809 rev.2 Hardware/README @@ -1,5 +1,5 @@ ------------------------------------------------------------------------------- --- Turkey shoot by Dar (darfpga@aol.fr) (05 March 2022) +-- Inferno by Dar (darfpga@aol.fr) (13 March 2022) -- http://darfpga.blogspot.fr -- https://sourceforge.net/projects/darfpga/files -- github.com/darfpga @@ -38,7 +38,7 @@ -- 17,18 - gnd - 8,10 -- ------------------------------------------------------------------------------- --- Version 0.0 -- 05/03/2022 -- +-- Version 0.0 -- 13/03/2022 -- -- initial version ------------------------------------------------------------------------------- -- @@ -57,12 +57,12 @@ -- F2 : Start 2 players -- F1 : Start 1 player -- SPACE : Fire --- RIGHT arrow : Move gun right --- LEFT arrow : Move gun left --- UP arrow : Move gun up --- DOWN arrow : Move gun down --- CTRL : Gobble --- W(Z) : Grenade +-- RIGHT arrow : run/aim -- must use separate controls +-- LEFT arrow : run/aim -- must use separate controls +-- UP arrow : run/aim -- must use separate controls +-- DOWN arrow : run/aim -- must use separate controls +-- CTRL : NU +-- W(Z) : NU -- -- Keyboard Service inputs French(english) : -- @@ -73,61 +73,57 @@ -- To enter service mode press 'advance' key while in game over screen -- Enter service mode to tune game parameters (difficulty ...) -- Tuning are lost at power OFF, for permanent tuning edit/set parameters --- within tshoot_cmos_ram.vhd and recompile. +-- within inferno_cmos_ram.vhd and recompile. -- ------------------------------------------------------------------------------- --- Use make_tshoot_proms.bat to build vhd file and bin from binaries +-- Use make_inferno_proms.bat to build vhd file and bin from binaries -- Load sdram with external rom bank -> use sdram_loader_de10_lite.sof + key(0) ------------------------------------------------------------------------------- --- Program sdram content with this turkey shoot rom bank loader before --- programming turkey shoot game core : +-- Program sdram content with this inferno rom bank loader before +-- programming inferno game core : -- --- 1) program DE10_lite with tshoot sdram loader +-- 1) program DE10_lite with inferno sdram loader -- 2) press key(0) at least once (digit blinks during programming) --- 3) program DE10_lite with tshoot core without switching DE10_lite OFF +-- 3) program DE10_lite with inferno core without switching DE10_lite OFF ------------------------------------------------------------------------------- --- Used ROMs by make_tshoot_proms.bat +-- Used ROMs by make_inferno_proms.bat -> turkey_shoot_prog1 - rom18.ic55 CRC(effc33f1) +> inferno_prog2 + ic9.inf CRC(1a013185) + ic10.inf CRC(dbf64a36) -> turkey_shoot_prog2 - rom2.ic9" CRC(fd982687) - rom3.ic10" CRC(9617054d) +> inferno_bank_a + None -> turkey_shoot_bank_a - rom17.ic26 CRC(b02d1ccd) - rom15.ic24 CRC(11709935) +> inferno_bank_b + ic25.inf CRC(103a5951) + ic23.inf CRC(c04749a0) + ic21.inf CRC(c405f853) + ic19.inf CRC(ade7645a) -> turkey_shoot_bank_b - rom16.ic25 CRC(69ce38f8) - rom14.ic23 CRC(769a4ae5) - rom13.ic21 CRC(ec016c9b) - rom12.ic19 CRC(98ae7afa) +> inferno_bank_c + ic18.inf CRC(95bcf7b1) + ic16.inf CRC(8bc4f935) + ic14.inf CRC(a70508a7) + ic12.inf CRC(7ffb87f9) -> turkey_shoot_bank_c - rom11.ic18 CRC(60d5fab8) - rom9.ic16 CRC(a4dd4a0e) - rom7.ic14 CRC(f25505e6) - rom5.ic12 CRC(94a7c0ed) +> inferno_bank_d + ic17.inf CRC(b4684139) + ic15.inf CRC(128a6ad6) + ic13.inf CRC(83a9e4d6) + ic11.inf CRC(c2e9c909) -> turkey_shoot_bank_d - rom10.ic17 CRC(0f32bad8) - rom8.ic15 CRC(e9b6cbf7) - rom6.ic13 CRC(a49f617f) - rom4.ic11 CRC(b026dc00) +> inferno_sound + ic8.inf CRC(4e3123b8) -> turkey_shoot_sound - rom1.ic8 CRC(011a94a7) +> inferno_graph1 + ic57.inf CRC(65a4ef79) -> turkey_shoot_graph1 - rom20.ic57 CRC(c6e1d253) +> inferno_graph2 + ic58.inf CRC(4bb1c2a0) -> turkey_shoot_graph2 - rom21.ic58 CRC(9874e90f) - -> turkey_shoot_graph3 - rom19.ic41 CRC(b9ce4d2a) +> inferno_graph3 + ic41.inf CRC(f3f7238f) ------------------------------------------------------------------------------- -- Misc. info diff --git a/Arcade_MiST/Williams 6809 rev.2 Hardware/README.md b/Arcade_MiST/Williams 6809 rev.2 Hardware/README.md new file mode 100644 index 00000000..f8e3208b --- /dev/null +++ b/Arcade_MiST/Williams 6809 rev.2 Hardware/README.md @@ -0,0 +1,54 @@ +# Williams rev.2 hardware games by darfpga + +Supported games: Turkey Shoot, Joust 2, Inferno, Mystic Marathon + +After loading the RBF (Core), a CMOS clearing happens. When the message +"Factory Settings Restored" appears, press the MiST soft RESET button (right). + +Later on you can save the CMOS RAM using the "Save NVRAM" OSD option. + +## Usage + +- Create ROM and ARC files from MAME ROM zip files using the mra utility and the MRA files. +- Example: mra -A -z /path/to/mame/roms Inferno.mra +- Copy the RBF and the ARC files to the same folder. +- Copy the ROM files to the root of the SD Card. + +- MRA utilty: https://github.com/sebdel/mra-tools-c + +## Controls + +### Turkey Shoot + +| Function | Button | +| --------------- | -------- | +| Aim | Mouse | +| Fire | Button A | +| Grenade | Button B | +| Gobble | Button C | + +### Joust2 + +| Function | Button | +| --------------- | -------- | +| Flap | Button A | +| Transform/start | Button B | +| Left | Left | +| Right | Right | + +### Inferno + +| Function | Button | +| --------------- | ---------- | +| Move | Left/Right/Down/Up | +| Aim | Left/Right/Down/Up on Right Stick (dual stick gamepad only) OR | +| | Button C/D/E/B | +| Shoot | Button A | + +### Mystic Marathon + +| Function | Button | +| --------------- | -------- | +| Jump | Button A | +| Left | Left | +| Right | Right | diff --git a/Arcade_MiST/Williams 6809 rev.2 Hardware/ReadMe.txt b/Arcade_MiST/Williams 6809 rev.2 Hardware/ReadMe.txt deleted file mode 100644 index 893a2828..00000000 --- a/Arcade_MiST/Williams 6809 rev.2 Hardware/ReadMe.txt +++ /dev/null @@ -1,6 +0,0 @@ -Games that should work on this Hardware - -Mystic Marathon -Turkey Shoot -Inferno -Joust 2 - Survival of the Fittest \ No newline at end of file diff --git a/Arcade_MiST/Williams 6809 rev.2 Hardware/Williams2.qpf b/Arcade_MiST/Williams 6809 rev.2 Hardware/Williams2.qpf new file mode 100644 index 00000000..ccc72328 --- /dev/null +++ b/Arcade_MiST/Williams 6809 rev.2 Hardware/Williams2.qpf @@ -0,0 +1,31 @@ +# -------------------------------------------------------------------------- # +# +# Copyright (C) 2017 Intel Corporation. All rights reserved. +# Your use of Intel Corporation's design tools, logic functions +# and other software and tools, and its AMPP partner logic +# functions, and any output files from any of the foregoing +# (including device programming or simulation files), and any +# associated documentation or information are expressly subject +# to the terms and conditions of the Intel Program License +# Subscription Agreement, the Intel Quartus Prime License Agreement, +# the Intel MegaCore Function License Agreement, or other +# applicable license agreement, including, without limitation, +# that your use is for the sole purpose of programming logic +# devices manufactured by Intel and sold by Intel or its +# authorized distributors. Please refer to the applicable +# agreement for further details. +# +# -------------------------------------------------------------------------- # +# +# Quartus Prime +# Version 17.0.1 Build 598 06/07/2017 SJ Standard Edition +# Date created = 04:04:47 October 16, 2017 +# +# -------------------------------------------------------------------------- # + +QUARTUS_VERSION = "17.0" +DATE = "04:04:47 October 16, 2017" + +# Revisions + +PROJECT_REVISION = "Williams2" diff --git a/Arcade_MiST/Williams 6809 rev.2 Hardware/WilliamsHWv2.qsf b/Arcade_MiST/Williams 6809 rev.2 Hardware/Williams2.qsf similarity index 65% rename from Arcade_MiST/Williams 6809 rev.2 Hardware/WilliamsHWv2.qsf rename to Arcade_MiST/Williams 6809 rev.2 Hardware/Williams2.qsf index 0de8796d..a693d952 100644 --- a/Arcade_MiST/Williams 6809 rev.2 Hardware/WilliamsHWv2.qsf +++ b/Arcade_MiST/Williams 6809 rev.2 Hardware/Williams2.qsf @@ -1,6 +1,6 @@ # -------------------------------------------------------------------------- # # -# Copyright (C) 1991-2014 Altera Corporation +# 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 @@ -17,15 +17,15 @@ # -------------------------------------------------------------------------- # # # Quartus II 64-Bit -# Version 13.1.4 Build 182 03/12/2014 SJ Full Version -# Date created = 19:39:51 March 07, 2022 +# Version 13.1.0 Build 162 10/23/2013 SJ Web Edition +# Date created = 16:34:25 January 07, 2020 # # -------------------------------------------------------------------------- # # # Notes: # # 1) The default values for assignments are stored in the file: -# WilliamsHWv2_assignment_defaults.qdf +# Williams2_assignment_defaults.qdf # If this file doesn't exist, see file: # assignment_defaults.qdf # @@ -39,24 +39,12 @@ # 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 NUM_PARALLEL_PROCESSORS ALL -set_global_assignment -name LAST_QUARTUS_VERSION 13.1 set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:rtl/build_id.tcl" +set_global_assignment -name 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/WilliamsV2_MiST.sv -set_global_assignment -name VHDL_FILE rtl/williams2.vhd -set_global_assignment -name VHDL_FILE rtl/tshoot_sound_board.vhd -set_global_assignment -name VHDL_FILE rtl/tshoot_cmos_ram.vhd -set_global_assignment -name VHDL_FILE rtl/gen_ram.vhd -set_global_assignment -name VHDL_FILE rtl/rtl_jkent/cpu09l_128.vhd -set_global_assignment -name VHDL_FILE rtl/rom/turkey_shoot_decoder.vhd -set_global_assignment -name VHDL_FILE rtl/rom/gray_code.vhd -set_global_assignment -name VHDL_FILE rtl/rtl_pace/pia6821.vhd -set_global_assignment -name VHDL_FILE rtl/rtl_jkent/cpu68_2.vhd -set_global_assignment -name SYSTEMVERILOG_FILE rtl/sdram.sv -set_global_assignment -name VHDL_FILE rtl/pll_mist.vhd -set_global_assignment -name QIP_FILE "D:/GitHub/Mist_FPGA/common/mist/mist.qip" # Pin & Location Assignments # ========================== @@ -90,6 +78,7 @@ 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] @@ -129,27 +118,20 @@ set_location_assignment PIN_66 -to SDRAM_nWE set_location_assignment PIN_59 -to SDRAM_nCS set_location_assignment PIN_33 -to SDRAM_CKE set_location_assignment PIN_43 -to SDRAM_CLK -set_location_assignment PLL_1 -to "pll:pll|altpll:altpll_component" # Classic Timing Assignments # ========================== set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0 set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85 set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS ON +set_global_assignment -name TIMEQUEST_DO_CCPP_REMOVAL ON # Analysis & Synthesis Assignments # ================================ set_global_assignment -name FAMILY "Cyclone III" set_global_assignment -name DEVICE_FILTER_PIN_COUNT 144 set_global_assignment -name DEVICE_FILTER_SPEED_GRADE 8 -set_global_assignment -name DEVICE_FILTER_PACKAGE TQFP -set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS ON -set_global_assignment -name ALLOW_POWER_UP_DONT_CARE ON -set_global_assignment -name CYCLONEII_OPTIMIZATION_TECHNIQUE SPEED -set_global_assignment -name VERILOG_SHOW_LMF_MAPPING_MESSAGES OFF -set_global_assignment -name VERILOG_MACRO "EXT_ROM=" -set_global_assignment -name FORCE_SYNCH_CLEAR ON -set_global_assignment -name TOP_LEVEL_ENTITY WilliamsV2_MiST +set_global_assignment -name TOP_LEVEL_ENTITY Williams2_MiST # Fitter Assignments # ================== @@ -161,30 +143,25 @@ set_global_assignment -name CYCLONEIII_CONFIGURATION_SCHEME "PASSIVE SERIAL" set_global_assignment -name CRC_ERROR_OPEN_DRAIN OFF set_global_assignment -name FORCE_CONFIGURATION_VCCIO ON set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "3.3-V LVTTL" -set_global_assignment -name CYCLONEII_RESERVE_NCEO_AFTER_CONFIGURATION "USE AS REGULAR IO" -set_global_assignment -name RESERVE_DATA0_AFTER_CONFIGURATION "USE AS REGULAR IO" set_global_assignment -name RESERVE_DATA1_AFTER_CONFIGURATION "USE AS REGULAR IO" set_global_assignment -name RESERVE_FLASH_NCE_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_global_assignment -name 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" -set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_RETIMING ON -set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_DUPLICATION ON -set_global_assignment -name OPTIMIZE_HOLD_TIMING "ALL PATHS" -set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING ON -set_global_assignment -name FITTER_EFFORT "STANDARD FIT" # Assembler Assignments # ===================== -set_global_assignment -name GENERATE_RBF_FILE ON set_global_assignment -name USE_CONFIGURATION_DEVICE OFF +set_global_assignment -name GENERATE_RBF_FILE ON # SignalTap II Assignments # ======================== set_global_assignment -name ENABLE_SIGNALTAP OFF -set_global_assignment -name USE_SIGNALTAP_FILE output_files/tm.stp +set_global_assignment -name USE_SIGNALTAP_FILE output_files/w2.stp # Power Estimation Assignments # ============================ -set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW" +set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "NO HEAT SINK WITH STILL AIR" set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)" # Advanced I/O Timing Assignments @@ -194,58 +171,71 @@ 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(WilliamsV2_MiST) +# --------------------------- +# start ENTITY(Williams2_MiST) # Pin & Location Assignments # ========================== - set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[*] - set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[*] - set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_BA[0] - set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_BA[1] - set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQMH - set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQML - set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nRAS - set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nCAS - set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nWE - set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nCS - set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[*] - set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[*] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[*] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[*] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_BA[0] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_BA[1] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQMH +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQML +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nRAS +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nCAS +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nWE +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nCS +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[*] +set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[*] # Fitter Assignments # ================== - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[*] - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[*] - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_BA[*] - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQML - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQMH - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nRAS - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nCAS - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nWE - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nCS - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_CKE - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_CLK - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_R[*] - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_G[*] - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_B[*] - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_HS - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_VS - set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to AUDIO_L - set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to AUDIO_R - set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SPI_DO +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_* +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_* +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to AUDIO_L +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to AUDIO_R +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SPI_DO # 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 +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(WilliamsV2_MiST) -# --------------------------- +# end ENTITY(Williams2_MiST) +# ------------------------- +set_global_assignment -name CYCLONEII_OPTIMIZATION_TECHNIQUE BALANCED +set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS ON +set_global_assignment -name ALLOW_SYNCH_CTRL_USAGE OFF +set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_DUPLICATION ON +set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_RETIMING ON +set_global_assignment -name OPTIMIZE_HOLD_TIMING "ALL PATHS" +set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING ON +set_global_assignment -name FITTER_EFFORT "AUTO FIT" +set_global_assignment -name SYSTEMVERILOG_FILE rtl/Williams2_MiST.sv +set_global_assignment -name QIP_FILE rtl/pll_mist.qip +set_global_assignment -name SYSTEMVERILOG_FILE rtl/sdram.sv +set_global_assignment -name VHDL_FILE rtl/williams2.vhd +set_global_assignment -name VHDL_FILE rtl/williams2_colormix.vhd +set_global_assignment -name VHDL_FILE rtl/gen_ram.vhd +set_global_assignment -name VHDL_FILE rtl/tshoot_sound_board.vhd +set_global_assignment -name VHDL_FILE rtl/dpram.vhd +set_global_assignment -name VHDL_FILE rtl/gray_code.vhd +set_global_assignment -name VHDL_FILE rtl/hc55564.vhd +set_global_assignment -name VHDL_FILE rtl/williams_cvsd_board.vhd +set_global_assignment -name VHDL_FILE rtl/roms/williams2_decoder.vhd +set_global_assignment -name QIP_FILE ../../common/mist/mist.qip +set_global_assignment -name VHDL_FILE ../../common/IO/pia6821.vhd +set_global_assignment -name VHDL_FILE ../../common/CPU/6800/cpu68.vhd +set_global_assignment -name VERILOG_FILE ../../common/CPU/MC6809/mc6809is.v +set_global_assignment -name QIP_FILE ../../common/Sound/jt51/jt51.qip +set_global_assignment -name SIGNALTAP_FILE output_files/w2.stp +set_global_assignment -name SIGNALTAP_FILE output_files/snd.stp set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/Arcade_MiST/Williams 6809 rev.2 Hardware/WilliamsHWv2.sdc b/Arcade_MiST/Williams 6809 rev.2 Hardware/Williams2.sdc similarity index 83% rename from Arcade_MiST/Williams 6809 rev.2 Hardware/WilliamsHWv2.sdc rename to Arcade_MiST/Williams 6809 rev.2 Hardware/Williams2.sdc index 4a373c09..b3f4f9d8 100644 --- a/Arcade_MiST/Williams 6809 rev.2 Hardware/WilliamsHWv2.sdc +++ b/Arcade_MiST/Williams 6809 rev.2 Hardware/Williams2.sdc @@ -54,7 +54,9 @@ set_time_format -unit ns -decimal_places 3 create_clock -name {SPI_SCK} -period 41.666 -waveform { 20.8 41.666 } [get_ports {SPI_SCK}] set sdram_clk "pll|altpll_component|auto_generated|pll1|clk[0]" -set sys_clk "pll|altpll_component|auto_generated|pll1|clk[1]" +set vid_clk "pll|altpll_component|auto_generated|pll1|clk[1]" +set game_clk "pll|altpll_component|auto_generated|pll1|clk[2]" + #************************************************************** # Create Generated Clock #************************************************************** @@ -81,18 +83,18 @@ set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [ge set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_SS2}] set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_SS3}] -set_input_delay -clock [get_clocks $sdram_clk] -reference_pin [get_ports {SDRAM_CLK}] -max 6.6 [get_ports SDRAM_DQ[*]] -set_input_delay -clock [get_clocks $sdram_clk] -reference_pin [get_ports {SDRAM_CLK}] -min 3.5 [get_ports SDRAM_DQ[*]] +set_input_delay -clock [get_clocks $sdram_clk] -reference_pin [get_ports {SDRAM_CLK}] -max 6.4 [get_ports SDRAM_DQ[*]] +set_input_delay -clock [get_clocks $sdram_clk] -reference_pin [get_ports {SDRAM_CLK}] -min 3.2 [get_ports SDRAM_DQ[*]] #************************************************************** # Set Output Delay #************************************************************** -set_output_delay -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_DO}] -set_output_delay -clock [get_clocks $sys_clk] 1.000 [get_ports {AUDIO_L}] -set_output_delay -clock [get_clocks $sys_clk] 1.000 [get_ports {AUDIO_R}] -set_output_delay -clock [get_clocks $sys_clk] 1.000 [get_ports {LED}] -set_output_delay -clock [get_clocks $sys_clk] 1.000 [get_ports {VGA_*}] +set_output_delay -add_delay -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_DO}] +set_output_delay -add_delay -clock [get_clocks $game_clk] 1.000 [get_ports {AUDIO_L}] +set_output_delay -add_delay -clock [get_clocks $game_clk] 1.000 [get_ports {AUDIO_R}] +set_output_delay -add_delay -clock [get_clocks $sdram_clk] 1.000 [get_ports {LED}] +set_output_delay -add_delay -clock [get_clocks $vid_clk] 1.000 [get_ports {VGA_*}] set_output_delay -clock [get_clocks $sdram_clk] -reference_pin [get_ports {SDRAM_CLK}] -max 1.5 [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}] set_output_delay -clock [get_clocks $sdram_clk] -reference_pin [get_ports {SDRAM_CLK}] -min -0.8 [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}] @@ -113,8 +115,10 @@ set_clock_groups -asynchronous -group [get_clocks {SPI_SCK}] -group [get_clocks # Set Multicycle Path #************************************************************** -set_multicycle_path -to {VGA_*[*]} -setup 2 -set_multicycle_path -to {VGA_*[*]} -hold 1 +set_multicycle_path -from [get_clocks $sdram_clk] -to [get_clocks $game_clk] -setup 2 +set_multicycle_path -from [get_clocks $sdram_clk] -to [get_clocks $game_clk] -hold 1 +#set_multicycle_path -to {VGA_*[*]} -setup 3 +#set_multicycle_path -to {VGA_*[*]} -hold 2 #************************************************************** # Set Maximum Delay diff --git a/Arcade_MiST/Williams 6809 rev.2 Hardware/WilliamsHWv2.qpf b/Arcade_MiST/Williams 6809 rev.2 Hardware/WilliamsHWv2.qpf deleted file mode 100644 index 39c1d7bf..00000000 --- a/Arcade_MiST/Williams 6809 rev.2 Hardware/WilliamsHWv2.qpf +++ /dev/null @@ -1,31 +0,0 @@ -# -------------------------------------------------------------------------- # -# -# Copyright (C) 1991-2013 Altera Corporation -# Your use of Altera Corporation's design tools, logic functions -# and other software and tools, and its AMPP partner logic -# functions, and any output files from any of the foregoing -# (including device programming or simulation files), and any -# associated documentation or information are expressly subject -# to the terms and conditions of the Altera Program License -# Subscription Agreement, Altera MegaCore Function License -# Agreement, or other applicable license agreement, including, -# without limitation, that your use is for the sole purpose of -# programming logic devices manufactured by Altera and sold by -# Altera or its authorized distributors. Please refer to the -# applicable agreement for further details. -# -# -------------------------------------------------------------------------- # -# -# Quartus II 64-Bit -# Version 13.1.0 Build 162 10/23/2013 SJ Web Edition -# Date created = 00:21:03 December 03, 2019 -# -# -------------------------------------------------------------------------- # - -QUARTUS_VERSION = "13.1" -DATE = "00:21:03 December 03, 2019" - -# Revisions - -PROJECT_REVISION = "WilliamsHWv2" - diff --git a/Arcade_MiST/Williams 6809 rev.2 Hardware/meta/Inferno.mra b/Arcade_MiST/Williams 6809 rev.2 Hardware/meta/Inferno.mra new file mode 100644 index 00000000..36aaddbe --- /dev/null +++ b/Arcade_MiST/Williams 6809 rev.2 Hardware/meta/Inferno.mra @@ -0,0 +1,57 @@ + + Inferno (Williams) + 0216 + 201911270000 + 1980 + Williams + inferno + william2 + + 2 + + + + 00 + + + + + + + + + + + + + + + + + + + + + + + + + + + 00 + + + + + + + + + + + + + + + + diff --git a/Arcade_MiST/Williams 6809 rev.2 Hardware/meta/Joust 2 - Survival of the Fittest (revision 2).mra b/Arcade_MiST/Williams 6809 rev.2 Hardware/meta/Joust 2 - Survival of the Fittest (revision 2).mra new file mode 100644 index 00000000..0544f3cd --- /dev/null +++ b/Arcade_MiST/Williams 6809 rev.2 Hardware/meta/Joust 2 - Survival of the Fittest (revision 2).mra @@ -0,0 +1,65 @@ + + Joust 2 - Survival of the Fittest (revision 2) + 0216 + 201911270000 + 1980 + Williams + joust2 + william2 + + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Arcade_MiST/Williams 6809 rev.2 Hardware/meta/Mystic Marathon.mra b/Arcade_MiST/Williams 6809 rev.2 Hardware/meta/Mystic Marathon.mra new file mode 100644 index 00000000..c2006444 --- /dev/null +++ b/Arcade_MiST/Williams 6809 rev.2 Hardware/meta/Mystic Marathon.mra @@ -0,0 +1,60 @@ + + Mystic Marathon + 0216 + 201911270000 + 1980 + Williams + mysticm + william2 + + 3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 00 + + + + + + + + + + + + + + + + diff --git a/Arcade_MiST/Williams 6809 rev.2 Hardware/meta/Turkey Shoot.mra b/Arcade_MiST/Williams 6809 rev.2 Hardware/meta/Turkey Shoot.mra new file mode 100644 index 00000000..a32e12ff --- /dev/null +++ b/Arcade_MiST/Williams 6809 rev.2 Hardware/meta/Turkey Shoot.mra @@ -0,0 +1,60 @@ + + Turkey Shoot + 0216 + 201911270000 + 1980 + Williams + tshoot + william2 + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/Williams2_MiST.sv b/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/Williams2_MiST.sv new file mode 100644 index 00000000..5cb15a0e --- /dev/null +++ b/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/Williams2_MiST.sv @@ -0,0 +1,431 @@ +//============================================================================ +// Arcade: Williams rev.2 +// + +module Williams2_MiST( + output LED, + output [5:0] VGA_R, + output [5:0] VGA_G, + output [5:0] VGA_B, + output VGA_HS, + output VGA_VS, + output AUDIO_L, + output AUDIO_R, + input SPI_SCK, + output SPI_DO, + input SPI_DI, + input SPI_SS2, + input SPI_SS3, + input CONF_DATA0, + input CLOCK_27, + + output [12:0] SDRAM_A, + inout [15:0] SDRAM_DQ, + output SDRAM_DQML, + output SDRAM_DQMH, + output SDRAM_nWE, + output SDRAM_nCAS, + output SDRAM_nRAS, + output SDRAM_nCS, + output [1:0] SDRAM_BA, + output SDRAM_CLK, + output SDRAM_CKE +); + +`include "rtl/build_id.v" + +`define CORE_NAME "TSHOOT" +//`define CORE_NAME "JOUST2" +//`define CORE_NAME "INFERNO" +//`define CORE_NAME "MYSTICM" + +localparam CONF_STR = { + `CORE_NAME,";;", + "O2,Rotate Controls,Off,On;", + "O34,Scanlines,Off,25%,50%,75%;", + "O5,Blend,Off,On;", + "O6,Joystick Swap,Off,On;", + "O7,Auto up,Off,On;", + "T8,Advance;", + "T9,HS Reset;", + "R1024,Save NVRAM;", + "T0,Reset;", + "V,v1.2.",`BUILD_DATE +}; + +wire rotate = status[2]; +wire [1:0] scanlines = status[4:3]; +wire blend = status[5]; +wire joyswap = status[6]; +wire autoup = status[7]; +wire adv = status[8]; +wire hsr = status[9]; + +wire advance, hsreset; +trigger adv_button(clk_sys, adv, advance); +trigger hsr_button(clk_sys, hsr, hsreset); + +wire [6:0] core_mod; +reg [7:0] input1; +reg [7:0] input2; +wire input_sel; +reg [1:0] orientation; // [left/right, landscape/portrait] +wire [5:0] gun_gray_code; +reg oneplayer; // only one joystick + +always @(*) begin + input1 = 0; + input2 = 0; + orientation = 2'b10; + oneplayer = 1; + + case (core_mod) + 7'h0: // Turkey Shoot + begin + input1 = {~(m_fireA | m_fire2A | mouse_flags[0]), 1'b0, gun_gray_code}; + input2 = { m_two_players, m_one_player, 4'd0, m_fireC | m_fire2C | mouse_flags[2], m_fireB | m_fire2B | mouse_flags[1] }; + end + 7'h1: // Joust 2 + begin + oneplayer = 0; + orientation = 2'b01; + input1[7:4] = { 2'b11, ~m_fireB, ~m_fire2B }; + input1[3:0] = input_sel ? ~{1'b0, m_fire2A, m_right2, m_left2} : ~{1'b0, m_fireA, m_right, m_left}; + end + 7'h2: // Inferno + begin + oneplayer = 0; + input1 = input_sel ? ~{m_down2B | m_fire2E, m_right2B | m_fire2D, m_left2B | m_fire2C, m_up2B | m_fire2B, m_down2, m_right2, m_left2, m_up2} : + ~{m_downB | m_fireE, m_rightB | m_fireD, m_leftB | m_fireC, m_upB | m_fireB, m_down, m_right, m_left, m_up}; + input2 = { m_two_players, m_one_player, 4'd0, m_fire2A, m_fireA }; + end + 7'h3: // Mystic Marathon + begin + input1 = { m_fireA, 1'b0, m_two_players, m_one_player, m_left, m_down, m_right, m_up }; + end + default: ; + endcase + +end + +assign LED = ~ioctl_downl; +assign SDRAM_CLK = clk_mem; +assign SDRAM_CKE = 1; + +wire clk_sys, clk_vid, clk_mem; +wire pll_locked; +pll_mist pll( + .inclk0(CLOCK_27), + .areset(0), + .c0(clk_mem),//96 + .c1(clk_vid),//48 + .c2(clk_sys),//12 + .locked(pll_locked) + ); + +wire [31:0] status; +wire [1:0] buttons; +wire [1:0] switches; +wire [19:0] joystick_0; +wire [19:0] joystick_1; +wire scandoublerD; +wire ypbpr; +wire no_csync; +wire key_pressed; +wire [7:0] key_code; +wire key_strobe; +wire mouse_strobe; +wire signed [8:0] mouse_x; +wire signed [8:0] mouse_y; +wire [7:0] mouse_flags; + +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 ), + .no_csync (no_csync ), + .core_mod (core_mod ), + .key_strobe (key_strobe ), + .key_pressed (key_pressed ), + .key_code (key_code ), + .mouse_strobe (mouse_strobe ), + .mouse_flags (mouse_flags ), + .mouse_x (mouse_x ), + .mouse_y (mouse_y ), + .joystick_0 (joystick_0 ), + .joystick_1 (joystick_1 ), + .status (status ) + ); + +wire ioctl_downl; +wire ioctl_upl; +wire [7:0] ioctl_index; +wire ioctl_wr; +wire [24:0] ioctl_addr; +wire [7:0] ioctl_dout; +wire [7:0] ioctl_din; +wire rom_downl = ioctl_downl & ioctl_index == 0; + +data_io data_io ( + .clk_sys ( clk_mem ), + .SPI_SCK ( SPI_SCK ), + .SPI_SS2 ( SPI_SS2 ), + .SPI_DI ( SPI_DI ), + .SPI_DO ( SPI_DO ), + .ioctl_download( ioctl_downl ), + .ioctl_upload ( ioctl_upl ), + .ioctl_index ( ioctl_index ), + .ioctl_wr ( ioctl_wr ), + .ioctl_addr ( ioctl_addr ), + .ioctl_dout ( ioctl_dout ), + .ioctl_din ( ioctl_din ) +); + +reg port1_req, port2_req; +wire [17:0] rom_addr; +reg [17:0] rom_addr_r; +wire [15:0] rom_do; +wire [13:0] gfx_addr; +wire [31:0] gfx_do; +wire [12:0] snd_addr; +reg [19:0] snd_addr_r; +wire [15:0] snd_do; +wire [16:0] snd2_addr; +reg [19:0] snd2_addr_r; +wire [15:0] snd2_do; + +wire [24:0] gfx_ioctl_addr = ioctl_addr - 20'h25000; + +always @(posedge clk_mem) begin + rom_addr_r <= rom_downl ? 18'd0 : rom_addr; + snd_addr_r <= rom_downl ? 20'd0 : snd_addr + 20'h23000; + snd2_addr_r <= rom_downl ? 20'd0 : snd2_addr + 20'h35000; +end + +sdram #(.MHZ(96)) sdram( + .*, + .init_n ( pll_locked ), + .clk ( clk_mem ), + + // port1 used for main and sound CPUs + .port1_req ( port1_req ), + .port1_ack ( ), + .port1_a ( ioctl_addr[23:1] ), + .port1_ds ( {ioctl_addr[0], ~ioctl_addr[0]} ), + .port1_we ( ioctl_downl ), + .port1_d ( {ioctl_dout, ioctl_dout} ), + .port1_q ( ), + + .cpu1_addr ( rom_addr_r[17:1] ), + .cpu1_q ( rom_do ), + .cpu2_addr ( snd_addr_r[19:1] ), + .cpu2_q ( snd_do ), + .cpu3_addr ( snd2_addr_r[19:1] ), + .cpu3_q ( snd2_do ), + + // port2 for background graphics + .port2_req ( port2_req ), + .port2_ack ( ), + .port2_a ( gfx_ioctl_addr[23:1] ), + .port2_ds ( {gfx_ioctl_addr[0], ~gfx_ioctl_addr[0]} ), + .port2_we ( ioctl_downl ), + .port2_d ( {ioctl_dout, ioctl_dout} ), + .port2_q ( ), + + .sp_addr ( gfx_addr ), + .sp_q ( gfx_do ) +); + +always @(posedge clk_mem) begin + reg ioctl_wr_last = 0; + + ioctl_wr_last <= ioctl_wr; + if (rom_downl) begin + if (~ioctl_wr_last && ioctl_wr) begin + port1_req <= ~port1_req; + port2_req <= ~port2_req; + end + end +end + +reg reset = 1; +reg rom_loaded = 0; +always @(posedge clk_sys) begin + reg ioctl_downlD; + ioctl_downlD <= ioctl_downl; + + if (ioctl_downlD & ~ioctl_downl) rom_loaded <= 1; + reset <= status[0] | buttons[1] | ioctl_downl | ~rom_loaded; +end + +wire [16:0] audio_left; +wire [16:0] audio_right; +wire hs, vs; +wire blankn; +wire [3:0] r,g,b,i; + +williams2 williams2 ( + .clock_12 ( clk_sys ), + .reset ( reset ), + .hwsel ( core_mod[1:0] ), + + .rom_addr ( rom_addr ), + .rom_do ( rom_addr[0] ? rom_do[15:8] : rom_do[7:0] ), + .gfx_rom_addr ( gfx_addr ), + .gfx_rom_do ( gfx_do ), + .snd_rom_addr ( snd_addr ), + .snd_rom_do ( snd_addr[0] ? snd_do[15:8] : snd_do[7:0] ), + .snd2_rom_addr ( snd2_addr ), + .snd2_rom_do ( snd2_addr[0] ? snd2_do[15:8] : snd2_do[7:0] ), + + .video_r ( r ), + .video_g ( g ), + .video_b ( b ), + .video_i ( i ), + .video_hs ( hs ), + .video_vs ( vs ), + .video_blankn ( blankn ), + .audio_left ( audio_left ), + .audio_right ( audio_right ), + + .btn_auto_up ( autoup ), + .btn_advance ( advance ), + .btn_high_score_reset ( hsreset ), + .btn_coin ( m_coin1 | m_coin2 ), + + .input1 ( input1 ), + .input2 ( input2 ), + .input_sel ( input_sel ), + + .dl_clock ( clk_mem ), + .dl_addr ( ioctl_addr[15:0] ), + .dl_data ( ioctl_dout ), + .dl_wr ( ioctl_wr && ioctl_index == 0 ), + .up_data ( ioctl_din ), + .cmos_wr ( ioctl_wr && ioctl_index == 8'hff ) +); + +wire [7:0] red; +wire [7:0] green; +wire [7:0] blue; + +williams2_colormix williams2_colormix ( + .mysticm ( core_mod[1:0] == 3 ), + .r ( r ), + .g ( g ), + .b ( b ), + .intensity ( i ), + .vga_r ( red ), + .vga_g ( green ), + .vga_b ( blue ) +); + +mist_video #(.COLOR_DEPTH(6), .SD_HCNT_WIDTH(10)) mist_video( + .clk_sys ( clk_vid ), + .SPI_SCK ( SPI_SCK ), + .SPI_SS3 ( SPI_SS3 ), + .SPI_DI ( SPI_DI ), + .R ( blankn ? red[7:2] : 0 ), + .G ( blankn ? green[7:2] : 0 ), + .B ( blankn ? blue[7:2] : 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 ( {orientation[1],rotate} ), + .scandoubler_disable( scandoublerD ), + .no_csync ( no_csync ), + .scanlines ( scanlines ), + .blend ( blend ), + .ypbpr ( ypbpr ) + ); + +dac #( + .C_bits(17)) +dacl( + .clk_i(clk_sys), + .res_n_i(1), + .dac_i(audio_left), + .dac_o(AUDIO_L) + ); + +dac #( + .C_bits(17)) +dacr( + .clk_i(clk_sys), + .res_n_i(1), + .dac_i(audio_right), + .dac_o(AUDIO_R) + ); + +// Turkey shot guns +reg signed [8:0] x, y; +wire [5:0] gun_v = x[8:3], gun_h = y[8:3]; +wire [5:0] gun_bin_code = input_sel ? gun_v : gun_h; + +always @(posedge clk_sys) begin + if (mouse_strobe) begin + x <= x + mouse_x; + y <= y - mouse_y; + end +end + +gray_code gun_gray_encoder ( + .clk(clk_sys), + .addr(gun_bin_code), + .data(gun_gray_code) +); + +// Common inputs +wire m_up, m_down, m_left, m_right, m_fireA, m_fireB, m_fireC, m_fireD, m_fireE, m_fireF, m_upB, m_downB, m_leftB, m_rightB; +wire m_up2, m_down2, m_left2, m_right2, m_fire2A, m_fire2B, m_fire2C, m_fire2D, m_fire2E, m_fire2F, m_up2B, m_down2B, m_left2B, m_right2B; +wire m_tilt, m_coin1, m_coin2, m_coin3, m_coin4, m_one_player, m_two_players, m_three_players, m_four_players; + +arcade_inputs inputs ( + .clk ( clk_sys ), + .key_strobe ( key_strobe ), + .key_pressed ( key_pressed ), + .key_code ( key_code ), + .joystick_0 ( joystick_0 ), + .joystick_1 ( joystick_1 ), + .rotate ( rotate ), + .orientation ( orientation ), + .joyswap ( joyswap ), + .oneplayer ( oneplayer ), + .controls ( {m_tilt, m_coin4, m_coin3, m_coin2, m_coin1, m_four_players, m_three_players, m_two_players, m_one_player} ), + .player1 ( {m_upB, m_downB, m_leftB, m_rightB, 6'd0, m_fireF, m_fireE, m_fireD, m_fireC, m_fireB, m_fireA, m_up, m_down, m_left, m_right} ), + .player2 ( {m_up2B, m_down2B, m_left2B, m_right2B, 6'd0, m_fire2F, m_fire2E, m_fire2D, m_fire2C, m_fire2B, m_fire2A, m_up2, m_down2, m_left2, m_right2} ) +); + +endmodule + +module trigger ( + input clk, + input btn, + output trigger +); + +reg [23:0] counter; +assign trigger = (counter != 0); + +always @(posedge clk) begin + reg btn_d; + + btn_d <= btn; + if (~btn_d & btn) counter <= 24'hfffff; + if (counter != 0) counter <= counter - 1'd1; +end + +endmodule diff --git a/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/WilliamsV2_MiST.sv b/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/WilliamsV2_MiST.sv deleted file mode 100644 index 962dd280..00000000 --- a/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/WilliamsV2_MiST.sv +++ /dev/null @@ -1,325 +0,0 @@ -//============================================================================ -// Arcade: Williams V2 Hardware by DarFPGA -// -// This program is free software; you can redistribute it and/or modify it -// under the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 2 of the License, or (at your option) -// any later version. -// -// This program is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -// more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, write to the Free Software Foundation, Inc., -// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -//============================================================================ - -module WilliamsV2_MiST( - output LED, - output [5:0] VGA_R, - output [5:0] VGA_G, - output [5:0] VGA_B, - output VGA_HS, - output VGA_VS, - output AUDIO_L, - output AUDIO_R, - input SPI_SCK, - inout SPI_DO, - input SPI_DI, - input SPI_SS2, - input SPI_SS3, - input SPI_SS4, - input CONF_DATA0, - input CLOCK_27, - output [12:0] SDRAM_A, - inout [15:0] SDRAM_DQ, - output SDRAM_DQML, - output SDRAM_DQMH, - output SDRAM_nWE, - output SDRAM_nCAS, - output SDRAM_nRAS, - output SDRAM_nCS, - output [1:0] SDRAM_BA, - output SDRAM_CLK, - output SDRAM_CKE -); - -`include "rtl/build_id.v" - -localparam CONF_STR = { - "TurkeyS;rom;", - "O2,Rotate Controls,Off,On;", - "O5,Blend,Off,On;", - "O6,Autoup,Off,On;", - "O8,Advance,Off,On;", - "T9,Reset Highscores,Off,On;", - "T0,Reset;", - "V,v0.0.",`BUILD_DATE -}; - -wire rotate = status[2]; -wire blend = status[5]; -wire autoup = status[6]; -wire advance = status[8]; -wire Hreset = status[9]; - -assign LED = ~ioctl_downl; -assign SDRAM_CLK = clk48; -assign SDRAM_CKE = 1; -assign AUDIO_R = AUDIO_L; - -wire clk48, clk_sys, clk12; -wire pll_locked; -pll_mist pll( - .inclk0(CLOCK_27), - .areset(0), - .c0(clk48), - .c1(clk_sys),//24 - .c2(clk12), - .locked(pll_locked) - ); - -wire [63:0] status; -wire [1:0] buttons; -wire [1:0] switches; -wire [31:0] joystick_0; -wire [31:0] joystick_1; -wire scandoublerD; -wire ypbpr; -wire no_csync; -wire key_pressed; -wire [7:0] key_code; -wire key_strobe; - -user_io #( - .STRLEN(($size(CONF_STR)>>3)), - .ROM_DIRECT_UPLOAD(1'b1)) -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 ), - .no_csync (no_csync ), - .key_strobe (key_strobe ), - .key_pressed (key_pressed ), - .key_code (key_code ), - .joystick_0 (joystick_0 ), - .joystick_1 (joystick_1 ), - .status (status ) - ); - -wire ioctl_downl; -wire ioctl_upl; -wire [7:0] ioctl_index; -wire ioctl_wr; -wire [24:0] ioctl_addr; -wire [7:0] ioctl_dout; -wire [7:0] ioctl_din; - -data_io #( - .ROM_DIRECT_UPLOAD(1'b1)) -data_io( - .clk_sys ( clk_sys ), - .SPI_SCK ( SPI_SCK ), - .SPI_SS2 ( SPI_SS2 ), - .SPI_SS4 ( SPI_SS4 ), - .SPI_DI ( SPI_DI ), - .SPI_DO ( SPI_DO ), - .ioctl_download( ioctl_downl ), - .ioctl_upload ( ioctl_upl ), - .ioctl_index ( ioctl_index ), - .ioctl_wr ( ioctl_wr ), - .ioctl_addr ( ioctl_addr ), - .ioctl_dout ( ioctl_dout ), - .ioctl_din ( ioctl_din ) -); - -wire [24:0] sp_ioctl_addr = ioctl_addr - 18'h22000;//check - -wire [13:0] prg_rom_addr; -wire [7:0] prg_rom_do; -wire [12:0] snd_rom_addr; -wire [7:0] snd_rom_do; -wire [16:0] bank_rom_addr; -wire [7:0] bank_rom_do; -wire [12:0] gfx_rom_addr; -wire [23:0] gfx_rom_do; -reg port1_req, port2_req; -sdram sdram( - .*, - .init_n ( pll_locked ), - .clk ( clk48 ), - - // port1 used for main + sound CPUs - .port1_req ( port1_req ), - .port1_ack ( ), - .port1_a ( ioctl_addr ), - .port1_ds ( {ioctl_addr[0], ~ioctl_addr[0]} ), - .port1_we ( ioctl_downl ), - .port1_d ( {ioctl_dout, ioctl_dout} ), - .port1_q ( ), - - .cpu1_addr ( ioctl_downl ? 16'hffff : {1'b0, prg_rom_addr[13:1]} ), - .cpu1_q ( prg_rom_do ), - - .cpu2_addr ( ioctl_downl ? 16'hffff : (16'h2000 + bank_rom_addr[16:1]) ), - .cpu2_q ( bank_rom_do ), - .cpu3_addr ( ioctl_downl ? 16'hffff : (16'hE000 + snd_rom_addr[12:1]) ), - .cpu3_q ( snd_rom_do ), - - // port2 for sprite graphics - .port2_req ( port2_req ), - .port2_ack ( ), - .port2_a ( {sp_ioctl_addr[23:17], sp_ioctl_addr[14:0], sp_ioctl_addr[16]} ), // merge sprite roms to 32-bit wide words - .port2_ds ( {sp_ioctl_addr[15], ~sp_ioctl_addr[15]} ), - .port2_we ( ioctl_downl ), - .port2_d ( {ioctl_dout, ioctl_dout} ), - .port2_q ( ), - - .sp_addr ( ioctl_downl ? 15'h7fff : gfx_rom_addr ),//todo - .sp_q ( gfx_rom_do ) -); - -// ROM download controller -always @(posedge clk_sys) begin - reg ioctl_wr_last = 0; - - ioctl_wr_last <= ioctl_wr; - if (ioctl_downl) begin - if (~ioctl_wr_last && ioctl_wr && ioctl_index == 0) begin - port1_req <= ~port1_req; - port2_req <= ~port2_req; - end - end -end - -reg reset = 1; -reg rom_loaded = 0; -always @(posedge clk_sys) begin - reg ioctl_downlD; - ioctl_downlD <= ioctl_downl; - - if (ioctl_downlD & ~ioctl_downl) rom_loaded <= 1; - reset <= status[0] | buttons[1] | ~rom_loaded; -end - - -wire [7:0] audio; -wire hs, vs, cs; -wire blankn; -wire [3:0] g, r, b, intensity; - -williams2 williams2( - .clock_12 (clk12), - .reset (reset), -//prg low - .prg_rom_addr (prg_rom_addr),//(13 downto 0); - .prg_rom_do (prg_rom_do),//(7 downto 0); -//banks - .rom_addr (bank_rom_addr),//(16 downto 0); - .rom_do (bank_rom_do),//( 7 downto 0); - .rom_rd (),// -//snd - .snd_rom_addr (snd_rom_addr),//(12 downto 0); - .snd_rom_do (snd_rom_do),//(7 downto 0); -//gfx - .gfx_rom_addr (gfx_rom_addr),//(12 downto 0); - .gfx_rom_do (gfx_rom_do),//(23 downto 0); -//dec hardcoded for now - .dec_rom_addr (),//(8 downto 0); - .dec_rom_do (),//(7 downto 0); - - .video_r (r), - .video_g (g), - .video_b (b), - .video_i (intensity), - .video_csync (cs), - .video_blankn (blankn), - .video_hs (hs), - .video_vs (vs), - - .audio_out (audio), - - .btn_auto_up (autoup), - .btn_advance (advance), - .btn_high_score_reset (Hreset), - - .btn_gobble (m_fireC), - .btn_grenade (m_fireB), - .btn_coin (m_coin1), - .btn_start_2 (m_two_players), - .btn_start_1 (m_one_player), - .btn_trigger (m_fireA), - .btn_left (m_left), - .btn_right (m_right), - .btn_up (m_up), - .btn_down (m_down), - - .sw_coktail_table (1'b0) -); - -wire [7:0]ri = r*intensity; -wire [7:0]gi = g*intensity; -wire [7:0]bi = b*intensity; - -mist_video #(.COLOR_DEPTH(4), .SD_HCNT_WIDTH(10)) mist_video( - .clk_sys ( clk_sys ), - .SPI_SCK ( SPI_SCK ), - .SPI_SS3 ( SPI_SS3 ), - .SPI_DI ( SPI_DI ), - .R ( blankn ? ri[7:4] : 0 ), - .G ( blankn ? gi[7:4] : 0 ), - .B ( blankn ? bi[7:4] : 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, rotate } ), - .ce_divider ( 1 ), - .blend ( blend ), - .scandoubler_disable(scandoublerD ), - .no_csync ( 1'b1 ),//todo - .ypbpr ( ypbpr ) - ); - -dac #( - .C_bits(8)) -dac_( - .clk_i(clk_sys), - .res_n_i(1), - .dac_i(audio), - .dac_o(AUDIO_L) - ); - -wire m_up, m_down, m_left, m_right, m_fireA, m_fireB, m_fireC, m_fireD, m_fireE, m_fireF; -wire m_up2, m_down2, m_left2, m_right2, m_fire2A, m_fire2B, m_fire2C, m_fire2D, m_fire2E, m_fire2F; -wire m_tilt, m_coin1, m_coin2, m_coin3, m_coin4, m_one_player, m_two_players, m_three_players, m_four_players; - -arcade_inputs inputs ( - .clk ( clk_sys ), - .key_strobe ( key_strobe ), - .key_pressed ( key_pressed ), - .key_code ( key_code ), - .joystick_0 ( joystick_0 ), - .joystick_1 ( joystick_1 ), - .rotate ( rotate ), - .orientation ( 2'b11 ),//check - .joyswap ( 1'b0 ), - .oneplayer ( 1'b1 ), - .controls ( {m_tilt, m_coin4, m_coin3, m_coin2, m_coin1, m_four_players, m_three_players, m_two_players, m_one_player} ), - .player1 ( {m_fireF, m_fireE, m_fireD, m_fireC, m_fireB, m_fireA, m_up, m_down, m_left, m_right} ), - .player2 ( {m_fire2F, m_fire2E, m_fire2D, m_fire2C, m_fire2B, m_fire2A, m_up2, m_down2, m_left2, m_right2} ) -); - -endmodule diff --git a/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/dpram.vhd b/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/dpram.vhd new file mode 100644 index 00000000..284194c5 --- /dev/null +++ b/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/dpram.vhd @@ -0,0 +1,81 @@ +-- ----------------------------------------------------------------------- +-- +-- Syntiac's generic VHDL support files. +-- +-- ----------------------------------------------------------------------- +-- Copyright 2005-2008 by Peter Wendrich (pwsoft@syntiac.com) +-- http://www.syntiac.com/fpga64.html +-- +-- Modified April 2016 by Dar (darfpga@aol.fr) +-- http://darfpga.blogspot.fr +-- Remove address register when writing +-- +-- ----------------------------------------------------------------------- +-- +-- dpram.vhd +-- +-- ----------------------------------------------------------------------- +-- +-- generic ram. +-- +-- ----------------------------------------------------------------------- + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.numeric_std.ALL; + +-- ----------------------------------------------------------------------- + +entity dpram is + generic ( + dWidth : integer := 8; + aWidth : integer := 10 + ); + port ( + clk_a : in std_logic; + we_a : in std_logic := '0'; + addr_a : in std_logic_vector((aWidth-1) downto 0); + d_a : in std_logic_vector((dWidth-1) downto 0) := (others => '0'); + q_a : out std_logic_vector((dWidth-1) downto 0); + + clk_b : in std_logic; + we_b : in std_logic := '0'; + addr_b : in std_logic_vector((aWidth-1) downto 0); + d_b : in std_logic_vector((dWidth-1) downto 0) := (others => '0'); + q_b : out std_logic_vector((dWidth-1) downto 0) + ); +end entity; + +-- ----------------------------------------------------------------------- + +architecture rtl of dpram is + subtype addressRange is integer range 0 to ((2**aWidth)-1); + type ramDef is array(addressRange) of std_logic_vector((dWidth-1) downto 0); + signal ram: ramDef; + signal addr_a_reg: std_logic_vector((aWidth-1) downto 0); + signal addr_b_reg: std_logic_vector((aWidth-1) downto 0); +begin + +-- ----------------------------------------------------------------------- + process(clk_a) + begin + if rising_edge(clk_a) then + if we_a = '1' then + ram(to_integer(unsigned(addr_a))) <= d_a; + end if; + q_a <= ram(to_integer(unsigned(addr_a))); + end if; + end process; + + process(clk_b) + begin + if rising_edge(clk_b) then + if we_b = '1' then + ram(to_integer(unsigned(addr_b))) <= d_b; + end if; + q_b <= ram(to_integer(unsigned(addr_b))); + end if; + end process; + +end architecture; + diff --git a/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/gray_code.vhd b/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/gray_code.vhd new file mode 100644 index 00000000..3dcf639a --- /dev/null +++ b/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/gray_code.vhd @@ -0,0 +1,95 @@ +library ieee; +use ieee.std_logic_1164.all,ieee.numeric_std.all; + +entity gray_code is +port ( + clk : in std_logic; + addr : in std_logic_vector(5 downto 0); + data : out std_logic_vector(5 downto 0) +); +end entity; + +architecture prom of gray_code is + type rom is array(0 to 63) of std_logic_vector(5 downto 0); + signal rom_data: rom := ( + "000000", + "000001", + "000011", + "000010", + "000110", + "000111", + "000101", + "000100", + + "001100", + "001101", + "001111", + "001110", + "001010", + "001011", + "001001", + "001000", + + "011000", + "011001", + "011011", + "011010", + "011110", + "011111", + "011101", + "011100", + + "010100", + "010101", + "010111", + "010110", + "010010", + "010011", + "010001", + "010000", + + "110000", + "110001", + "110011", + "110010", + "110110", + "110111", + "110101", + "110100", + + "111100", + "111101", + "111111", + "111110", + "111010", + "111011", + "111001", + "111000", + + "101000", + "101001", + "101011", + "101010", + "101110", + "101111", + "101101", + "101100", + + "100100", + "100101", + "100111", + "100110", + "100010", + "100011", + "100001", + "100000" + + ); +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.2 Hardware/rtl/hc55564.vhd b/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/hc55564.vhd new file mode 100644 index 00000000..ce584677 --- /dev/null +++ b/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/hc55564.vhd @@ -0,0 +1,84 @@ +-- HC55516/HC55564 Continuously Variable Slope Delta decoder +-- (c)2015 vlait +-- +-- This 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 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. + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity hc55564 is +port +( + clk : in std_logic; + cen : in std_logic; + rst : in std_logic; + bit_in : in std_logic; + sample_out : out std_logic_vector(15 downto 0) +); + +end hc55564; + +architecture hdl of hc55564 is + constant h : integer := (1 - 1/8) *256; --integrator decay (1 - 1/8) * 256 = 224 + constant b : integer := (1 - 1/256)*256; --syllabic decay (1 - 1/256) * 256 = 255 + + constant s_min : unsigned(15 downto 0) := to_unsigned(40, 16); + constant s_max : unsigned(15 downto 0) := to_unsigned(5120, 16); + + signal runofn_new : std_logic_vector(2 downto 0); + signal runofn : std_logic_vector(2 downto 0); + signal res1 : unsigned(31 downto 0); + signal res2 : unsigned(31 downto 0); + signal x_new : unsigned(16 downto 0); + signal x : unsigned(15 downto 0); --integrator + signal s : unsigned(15 downto 0); --syllabic + signal old_cen : std_logic; +begin + +res1 <= x * h; +res2 <= s * b; +runofn_new <= runofn(1 downto 0) & bit_in; +x_new <= ('0'&res1(23 downto 8)) + s when bit_in = '1' else ('0'&res1(23 downto 8)) - s; + +process(clk, rst, bit_in) +begin + -- reset ?? + if rising_edge(clk) then + old_cen <= cen; + if old_cen = '0' and cen = '1' then + runofn <= runofn_new; + if runofn_new = "000" or runofn_new = "111" then + s <= s + 40; + if (s + 40) > s_max then + s <= s_max; + end if; + else + s <= res2(23 downto 8); + if res2(23 downto 8) < s_min then + s <= s_min; + end if; + end if; + + if x_new(16) = '1' then + x <= (others => bit_in); + else + x <= x_new(15 downto 0); + end if; + end if; + end if; +end process; + +sample_out <= std_logic_vector(x); + +end architecture hdl; \ No newline at end of file diff --git a/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/pll_mist.vhd b/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/pll_mist.vhd index a1ee3351..3f69b67d 100644 --- a/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/pll_mist.vhd +++ b/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/pll_mist.vhd @@ -14,7 +14,7 @@ -- ************************************************************ -- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! -- --- 13.1.4 Build 182 03/12/2014 SJ Full Version +-- 13.1.4 Build 182 03/12/2014 SJ Web Edition -- ************************************************************ @@ -162,7 +162,7 @@ BEGIN clk0_phase_shift => "0", clk1_divide_by => 9, clk1_duty_cycle => 50, - clk1_multiply_by => 8, + clk1_multiply_by => 16, clk1_phase_shift => "0", clk2_divide_by => 9, clk2_duty_cycle => 50, @@ -249,14 +249,14 @@ END SYN; -- 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 "9" +-- Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "3" -- Retrieval info: PRIVATE: DIV_FACTOR1 NUMERIC "9" --- Retrieval info: PRIVATE: DIV_FACTOR2 NUMERIC "9" +-- Retrieval info: PRIVATE: DIV_FACTOR2 NUMERIC "1" -- Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000" -- Retrieval info: PRIVATE: DUTY_CYCLE1 STRING "50.00000000" -- Retrieval info: PRIVATE: DUTY_CYCLE2 STRING "50.00000000" -- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "96.000000" --- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "24.000000" +-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "48.000000" -- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE2 STRING "12.000000" -- Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0" -- Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0" @@ -278,22 +278,22 @@ END SYN; -- 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 "ps" +-- Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT1 STRING "deg" -- Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT2 STRING "ps" -- Retrieval info: PRIVATE: MIG_DEVICE_SPEED_GRADE STRING "Any" -- Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0" -- Retrieval info: PRIVATE: MIRROR_CLK1 STRING "0" -- Retrieval info: PRIVATE: MIRROR_CLK2 STRING "0" --- Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "32" --- Retrieval info: PRIVATE: MULT_FACTOR1 NUMERIC "8" --- Retrieval info: PRIVATE: MULT_FACTOR2 NUMERIC "4" +-- Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "4" +-- Retrieval info: PRIVATE: MULT_FACTOR1 NUMERIC "2" +-- Retrieval info: PRIVATE: MULT_FACTOR2 NUMERIC "1" -- Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1" -- Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "96.00000000" --- Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "24.00000000" +-- Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "48.00000000" -- Retrieval info: PRIVATE: OUTPUT_FREQ2 STRING "12.00000000" --- 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_MODE0 STRING "1" +-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE1 STRING "1" +-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE2 STRING "1" -- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz" -- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT1 STRING "MHz" -- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT2 STRING "MHz" @@ -305,7 +305,7 @@ END SYN; -- 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_UNIT2 STRING "ps" -- 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" @@ -349,7 +349,7 @@ END SYN; -- 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 "8" +-- Retrieval info: CONSTANT: CLK1_MULTIPLY_BY NUMERIC "16" -- Retrieval info: CONSTANT: CLK1_PHASE_SHIFT STRING "0" -- Retrieval info: CONSTANT: CLK2_DIVIDE_BY NUMERIC "9" -- Retrieval info: CONSTANT: CLK2_DUTY_CYCLE NUMERIC "50" diff --git a/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/rom/make..bat b/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/rom/make..bat deleted file mode 100644 index 2bffe72b..00000000 --- a/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/rom/make..bat +++ /dev/null @@ -1,11 +0,0 @@ -make_vhdl_prom.exe 7649.ic60 turkey_shoot_decoder.vhd - -copy /B rom17.ic26 + rom15.ic24 turkey_shoot_bank_a.bin -copy /B rom16.ic25 + rom14.ic23 + rom13.ic21 + rom12.ic19 turkey_shoot_bank_b.bin -copy /B rom11.ic18 + rom9.ic16 + rom7.ic14 + rom5.ic12 turkey_shoot_bank_c.bin -copy /B rom10.ic17 + rom8.ic15 + rom6.ic13 + rom4.ic11 turkey_shoot_bank_d.bin -copy /B rom20.ic57 + rom21.ic58 + rom19.ic41 gfx.bin - -copy /b rom18.ic55 + rom2.ic9 + rom3.ic10 + rom3.ic10 + turkey_shoot_bank_a.bin + turkey_shoot_bank_b.bin + turkey_shoot_bank_c.bin + turkey_shoot_bank_d.bin + rom1.ic8 + gfx.bin turkeys.rom - -pause \ No newline at end of file diff --git a/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/rom/make_vhdl_prom.exe b/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/rom/make_vhdl_prom.exe deleted file mode 100644 index 1e5618bf9417eaeb90556e3021a78e9860a815e8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 119861 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 H%=`ZUgl. --- ---===========================================================================-- --- -- --- 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.2 Hardware/rtl/rtl_jkent/cpu68_2.vhd b/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/rtl_jkent/cpu68_2.vhd deleted file mode 100644 index 12e0f935..00000000 --- a/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/rtl_jkent/cpu68_2.vhd +++ /dev/null @@ -1,4019 +0,0 @@ ---===========================================================================-- --- --- 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. --- --- 2019 Jared Boone --- Stall1_State1 & Stall2|_State added for better cycle accuracy. --- --- March 2020 Gyorgy Szombathelyi --- Runned through VHDLFormatter --- Set I bit at reset --- Set I bit on NMI --- Fixes many Irem sound board issues, where NMI is constantly --- issued by the ADPCM chip, and interrupted by normal IRQ - -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, - stall1_state, stall2_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 <= "11010000"; - 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; - next_state <= fetch_state; - 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; - next_state <= fetch_state; - 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; - next_state <= fetch_state; - 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; - next_state <= fetch_state; - 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; - next_state <= fetch_state; - 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; - next_state <= fetch_state; - 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; - next_state <= stall2_state; - 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; - next_state <= fetch_state; - 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; - next_state <= fetch_state; - 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; - next_state <= fetch_state; - 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; - next_state <= fetch_state; - 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; - next_state <= fetch_state; - 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; - next_state <= fetch_state; - 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; - next_state <= fetch_state; - end case; - -- 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 <= stall2_state; - when "0010" => -- bhi - if (cc(CBIT) or cc(ZBIT)) = '0' then - next_state <= branch_state; - else - next_state <= stall2_state; - end if; - when "0011" => -- bls - if (cc(CBIT) or cc(ZBIT)) = '1' then - next_state <= branch_state; - else - next_state <= stall2_state; - end if; - when "0100" => -- bcc/bhs - if cc(CBIT) = '0' then - next_state <= branch_state; - else - next_state <= stall2_state; - end if; - when "0101" => -- bcs/blo - if cc(CBIT) = '1' then - next_state <= branch_state; - else - next_state <= stall2_state; - end if; - when "0110" => -- bne - if cc(ZBIT) = '0' then - next_state <= branch_state; - else - next_state <= stall2_state; - end if; - when "0111" => -- beq - if cc(ZBIT) = '1' then - next_state <= branch_state; - else - next_state <= stall2_state; - end if; - when "1000" => -- bvc - if cc(VBIT) = '0' then - next_state <= branch_state; - else - next_state <= stall2_state; - end if; - when "1001" => -- bvs - if cc(VBIT) = '1' then - next_state <= branch_state; - else - next_state <= stall2_state; - end if; - when "1010" => -- bpl - if cc(NBIT) = '0' then - next_state <= branch_state; - else - next_state <= stall2_state; - end if; - when "1011" => -- bmi - if cc(NBIT) = '1' then - next_state <= branch_state; - else - next_state <= stall2_state; - end if; - when "1100" => -- bge - if (cc(NBIT) xor cc(VBIT)) = '0' then - next_state <= branch_state; - else - next_state <= stall2_state; - end if; - when "1101" => -- blt - if (cc(NBIT) xor cc(VBIT)) = '1' then - next_state <= branch_state; - else - next_state <= stall2_state; - end if; - when "1110" => -- bgt - if (cc(ZBIT) or (cc(NBIT) xor cc(VBIT))) = '0' then - next_state <= branch_state; - else - next_state <= stall2_state; - end if; - when "1111" => -- ble - if (cc(ZBIT) or (cc(NBIT) xor cc(VBIT))) = '1' then - next_state <= branch_state; - else - next_state <= stall2_state; - end if; - when others => - next_state <= stall2_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 <= stall1_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 <= int_mask_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 stall2_state => -- Do nothing for two cycles - -- 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 <= stall1_state; - - when stall1_state => -- Do nothing for one cycle - -- 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 <= fetch_state; - - 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.2 Hardware/rtl/rtl_pace/pia6821.vhd b/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/rtl_pace/pia6821.vhd deleted file mode 100644 index d565ae36..00000000 --- a/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/rtl_pace/pia6821.vhd +++ /dev/null @@ -1,553 +0,0 @@ ---===========================================================================-- --- --- 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.2 Hardware/rtl/sdram.sv b/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/sdram.sv index 9f78c393..cec8382d 100644 --- a/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/sdram.sv +++ b/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/sdram.sv @@ -4,21 +4,21 @@ // sdram controller implementation for the MiST board // https://github.com/mist-devel/mist-board // -// Copyright (c) 2013 Till Harbaum +// Copyright (c) 2013 Till Harbaum // Copyright (c) 2019 Gyorgy Szombathelyi // -// This source file is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published -// by the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// +// This source file is 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 +// 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 . +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . // module sdram ( @@ -46,11 +46,11 @@ module sdram ( input [15:0] port1_d, output reg [15:0] port1_q, - input [16:1] cpu1_addr, + input [19:1] cpu1_addr, output reg [15:0] cpu1_q, - input [16:1] cpu2_addr, + input [19:1] cpu2_addr, output reg [15:0] cpu2_q, - input [16:1] cpu3_addr, + input [19:1] cpu3_addr, output reg [15:0] cpu3_q, input port2_req, @@ -60,11 +60,13 @@ module sdram ( input [1:0] port2_ds, input [15:0] port2_d, output reg [31:0] port2_q, - - input [16:2] sp_addr, + + input [17:2] sp_addr, output reg [31:0] sp_q ); +parameter MHZ = 16'd80; // 80 MHz default clock, set it to proper value to calculate refresh rate + localparam RASCAS_DELAY = 3'd2; // tRCD=20ns -> 2 cycles@<100MHz localparam BURST_LENGTH = 3'b001; // 000=1, 001=2, 010=4, 011=8 localparam ACCESS_TYPE = 1'b0; // 0=sequential, 1=interleaved @@ -74,8 +76,8 @@ localparam NO_WRITE_BURST = 1'b1; // 0= write burst enabled, 1=only single acc localparam MODE = { 3'b000, NO_WRITE_BURST, OP_MODE, CAS_LATENCY, ACCESS_TYPE, BURST_LENGTH}; -// 64ms/8192 rows = 7.8us -> 842 cycles@108MHz -localparam RFRSH_CYCLES = 10'd842; +// 64ms/8192 rows = 7.8us +localparam RFRSH_CYCLES = 16'd78*MHZ/4'd10; // --------------------------------------------------------------------- // ------------------------ cycle state machine ------------------------ @@ -144,18 +146,19 @@ localparam CMD_PRECHARGE = 4'b0010; localparam CMD_AUTO_REFRESH = 4'b0001; localparam CMD_LOAD_MODE = 4'b0000; -reg [3:0] sd_cmd; // current command sent to sd ram -reg [15:0] sd_din; +reg [3:0] sd_cmd; // current command sent to sd ram +reg [15:0] sd_din; // Fast Input register latching incoming SDRAM data + // drive control signals according to current command assign SDRAM_nCS = sd_cmd[3]; assign SDRAM_nRAS = sd_cmd[2]; assign SDRAM_nCAS = sd_cmd[1]; assign SDRAM_nWE = sd_cmd[0]; -reg [24:1] addr_latch[3]; +reg [24:1] addr_latch[2]; reg [24:1] addr_latch_next[2]; -reg [16:1] addr_last[4]; -reg [16:2] addr_last2[2]; +reg [19:1] addr_last[3:1]; +reg [17:2] addr_last2[2]; reg [15:0] din_latch[2]; reg [1:0] oe_latch; reg [1:0] we_latch; @@ -175,26 +178,26 @@ reg [2:0] next_port[2]; reg [2:0] port[2]; reg refresh; -reg [10:0] refresh_cnt; -wire need_refresh = (refresh_cnt >= RFRSH_CYCLES); +reg [11:0] refresh_cnt; +reg need_refresh; // PORT1: bank 0,1 always @(*) begin if (refresh) begin next_port[0] = PORT_NONE; - addr_latch_next[0] = addr_latch[0]; + addr_latch_next[0] = addr_latch[1]; end else if (port1_req ^ port1_state) begin next_port[0] = PORT_REQ; addr_latch_next[0] = { 1'b0, port1_a }; end else if (cpu1_addr != addr_last[PORT_CPU1]) begin next_port[0] = PORT_CPU1; - addr_latch_next[0] = { 8'd0, cpu1_addr }; + addr_latch_next[0] = { 5'd0, cpu1_addr }; end else if (cpu2_addr != addr_last[PORT_CPU2]) begin next_port[0] = PORT_CPU2; - addr_latch_next[0] = { 8'd0, cpu2_addr }; + addr_latch_next[0] = { 5'd0, cpu2_addr }; end else if (cpu3_addr != addr_last[PORT_CPU3]) begin next_port[0] = PORT_CPU3; - addr_latch_next[0] = { 8'd0, cpu3_addr }; + addr_latch_next[0] = { 5'd0, cpu3_addr }; end else begin next_port[0] = PORT_NONE; addr_latch_next[0] = addr_latch[0]; @@ -208,7 +211,7 @@ always @(*) begin addr_latch_next[1] = { 1'b1, port2_a }; end else if (sp_addr != addr_last2[PORT_SP]) begin next_port[1] = PORT_SP; - addr_latch_next[1] = { 1'b1, 7'd0, sp_addr, 1'b0 }; + addr_latch_next[1] = { 1'b1, 6'd0, sp_addr, 1'b0 }; end else begin next_port[1] = PORT_NONE; addr_latch_next[1] = addr_latch[1]; @@ -223,6 +226,7 @@ always @(posedge clk) begin { SDRAM_DQMH, SDRAM_DQML } <= 2'b11; sd_cmd <= CMD_NOP; // default: idle refresh_cnt <= refresh_cnt + 1'd1; + need_refresh <= (refresh_cnt >= RFRSH_CYCLES); if(init) begin // initialization takes place at the end of the reset phase @@ -255,7 +259,7 @@ always @(posedge clk) begin sd_cmd <= CMD_ACTIVE; SDRAM_A <= addr_latch_next[0][22:10]; SDRAM_BA <= addr_latch_next[0][24:23]; - addr_last[next_port[0]] <= addr_latch_next[0][16:1]; + addr_last[next_port[0]] <= addr_latch_next[0][19:1]; if (next_port[0] == PORT_REQ) begin { oe_latch[0], we_latch[0] } <= { ~port1_we, port1_we }; ds[0] <= port1_ds; @@ -270,7 +274,7 @@ always @(posedge clk) begin // bank 2,3 if(t == STATE_RAS1) begin - refresh <= 1'b0; + refresh <= 0; addr_latch[1] <= addr_latch_next[1]; { oe_latch[1], we_latch[1] } <= 2'b00; port[1] <= next_port[1]; @@ -289,10 +293,8 @@ always @(posedge clk) begin { oe_latch[1], we_latch[1] } <= 2'b10; ds[1] <= 2'b11; end - end - - if (next_port[1] == PORT_NONE && need_refresh && !we_latch[0] && !oe_latch[0]) begin - refresh <= 1'b1; + end else if (need_refresh && !oe_latch[0] & !we_latch[0]) begin + refresh <= 1; refresh_cnt <= 0; sd_cmd <= CMD_AUTO_REFRESH; end @@ -340,6 +342,7 @@ always @(posedge clk) begin endcase; end + //set DQM two cycles before the 2nd word in the burst if(t == STATE_DS1b && oe_latch[1]) { SDRAM_DQMH, SDRAM_DQML } <= ~ds[1]; if(t == STATE_READ1b && oe_latch[1]) begin diff --git a/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/tshoot_cmos_ram.vhd b/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/tshoot_cmos_ram.vhd deleted file mode 100644 index 05ebe32a..00000000 --- a/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/tshoot_cmos_ram.vhd +++ /dev/null @@ -1,182 +0,0 @@ --- ----------------------------------------------------------------------- --- --- Syntiac's generic VHDL support",x"iles. --- --- ----------------------------------------------------------------------- --- 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 March 2022 by Dar --- Add init data with tshoot cmos value --- ----------------------------------------------------------------------- --- --- gen_rwram.vhd init with tshoot cmos value --- --- ----------------------------------------------------------------------- --- --- generic ram. --- --- ----------------------------------------------------------------------- --- tshoot cmos settings -- --- ---@00-03:Extra fowl every (XXYY XX=value*1000 YY=index default 320A) --- 0000/0501/0A02/0F03/1404/1905/1E06/2307 --- 2808/2D09/320A/370B/3C0C/410D/460E/4B0F --- 5010/5511/5A12/5F13 --- ---@04-07: Missions for 1 credit (XXYY XX=value YY=index default 0301) --- 0200/0301/0402/0503 --- ---@08-0B: attract mode no/yes (XXYY XX=value YY=index default 0101) --- 0000/0101 --- ---@0C-0F: pricing selection (XXYY XX=value YY=index [0000 custom, 0909 free play] default 0303) --- 0000/0101/.../0909 --- ---@10-13 -> CC1C-CC1F: coin slot units (XXYY XX=value YY=index, index is used only when custom) --- 0000/0101/.../6262 --- ---@20-23 -> CC24-CC27: unit for credit/bonus credit (XXYY XX=value YY=index) --- 0000/0101/.../6262 --- ---@28-2B: difficulty (XXYY XX=value YY=index default 0505) --- 0000/0101/../0909 --- ---@2C-2F: ? --- 0300 --- ---@30-33: gun recoil no/yes (XXYY XX=value YY=index default 0101) --- 0000/0101 --- ---@34-35: control sum : sum of nibbles from @00 to @33 + 3 --- ----------------------------------------------------------------------- - -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.numeric_std.ALL; --- ----------------------------------------------------------------------- -entity t_shoot_cmos_ram is - generic ( - dWidth : integer := 8; -- must be 4",x"or tshoot_cmos_ram - aWidth : integer := 10 -- must be 10",x"or tshoot_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; --- ----------------------------------------------------------------------- --- tshoot cmos data --- (ram is 128x4 => only 4 bits/address, that is only 1 hex digit/address) - -architecture rtl of t_shoot_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"3",x"2",x"0",x"A",x"0",x"3",x"0",x"1",x"0",x"1",x"0",x"1",x"0",x"3",x"0",x"3", - x"0",x"1",x"0",x"0",x"0",x"4",x"0",x"0",x"0",x"1",x"0",x"0",x"0",x"1",x"0",x"0", - x"0",x"0",x"0",x"0",x"0",x"0",x"0",x"0",x"0",x"5",x"0",x"5",x"0",x"3",x"0",x"0", - x"0",x"1",x"0",x"1",x"5",x"F",x"A",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",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",X"0",X"0",X"0",X"0",X"0",X"0",X"0", - x"0",x"7",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"7",x"0",x"0",x"0",x"0",x"0",x"0",x"0",x"0",x"0",x"0",x"0",x"6", - x"0",x"0",x"0",x"0",x"1",x"5",x"0",x"0",x"0",x"0",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"5",x"0",x"0",x"0",x"0",x"1",x"7",x"0",x"1", - x"0",x"0",x"0",x"0",x"0",x"0",x"0",x"1",x"8",x"1",x"0",x"0",x"0",x"0",x"0",x"5", - x"0",x"2",x"D",x"5",x"5",x"7",x"4",x"9",x"4",x"C",x"0",x"0",x"4",x"0",x"3",x"5", - x"4",x"D",x"5",x"2",x"5",x"3",x"0",x"0",x"4",x"0",x"2",x"0",x"5",x"2",x"4",x"F", - x"4",x"E",x"0",x"0",x"3",x"9",x"1",x"5",x"4",x"A",x"5",x"2",x"4",x"E",x"0",x"0", - x"3",x"8",x"3",x"4",x"5",x"4",x"4",x"E",x"4",x"4",x"0",x"0",x"3",x"7",x"2",x"5", - x"5",x"7",x"5",x"0",x"4",x"2",x"0",x"0",x"3",x"6",x"1",x"0",x"4",x"3",x"4",x"C", - x"5",x"3",x"0",x"0",x"3",x"5",x"0",x"3",x"4",x"C",x"4",x"5",x"4",x"F",x"0",x"0", - x"3",x"4",x"7",x"8",x"4",x"4",x"5",x"2",x"5",x"9",x"0",x"0",x"3",x"3",x"2",x"1", - x"4",x"A",x"5",x"3",x"4",x"3",x"0",x"0",x"3",x"2",x"5",x"0",x"4",x"A",x"4",x"5", - x"4",x"8",x"0",x"0",x"3",x"1",x"3",x"6",x"5",x"2",x"4",x"D",x"4",x"9",x"0",x"0", - x"3",x"0",x"1",x"8",x"4",x"B",x"4",x"5",x"4",x"E",x"0",x"0",x"2",x"9",x"1",x"0", - x"5",x"0",x"4",x"7",x"4",x"4",x"0",x"0",x"2",x"8",x"0",x"0",x"5",x"0",x"4",x"1", - x"4",x"8",x"0",x"0",x"2",x"7",x"9",x"8",x"4",x"E",x"5",x"6",x"4",x"2",x"0",x"0", - x"2",x"6",x"7",x"2",x"4",x"1",x"4",x"7",x"5",x"2",x"0",x"0",x"2",x"5",x"2",x"9", - x"5",x"6",x"4",x"C",x"4",x"7",x"0",x"0",x"2",x"4",x"7",x"3",x"4",x"4",x"4",x"F", - x"4",x"E",x"0",x"0",x"2",x"3",x"9",x"0",x"5",x"7",x"4",x"5",x"5",x"3",x"0",x"0", - x"2",x"2",x"6",x"2",x"4",x"A",x"5",x"0",x"4",x"4",x"0",x"0",x"2",x"1",x"8",x"3", - x"5",x"0",x"4",x"6",x"5",x"A",x"0",x"0",x"2",x"0",x"2",x"1",x"4",x"B",x"4",x"7", - x"4",x"D",x"0",x"0",x"1",x"9",x"1",x"8",x"4",x"B",x"5",x"2",x"4",x"4",x"0",x"0", - x"1",x"8",x"9",x"9",x"5",x"3",x"4",x"3",x"4",x"C",x"0",x"0",x"1",x"7",x"2",x"1", - x"5",x"2",x"4",x"1",x"5",x"7",x"0",x"0",x"1",x"6",x"7",x"8",x"4",x"2",x"4",x"1", - x"4",x"E",x"0",x"0",x"1",x"5",x"2",x"1",x"5",x"0",x"5",x"6",x"4",x"1",x"0",x"0", - x"1",x"4",x"5",x"2",x"4",x"A",x"4",x"3",x"2",x"0",x"0",x"0",x"1",x"3",x"7",x"8", - x"2",x"0",x"4",x"5",x"5",x"3",x"0",x"0",x"1",x"2",x"6",x"4",x"4",x"8",x"4",x"5", - x"4",x"3",x"0",x"0",x"1",x"1",x"3",x"7",x"4",x"D",x"4",x"2",x"5",x"3",x"0",x"0", - x"1",x"0",x"6",x"2",x"5",x"2",x"4",x"3",x"4",x"2",x"0",x"0",x"0",x"9",x"3",x"5", - x"5",x"0",x"4",x"A",x"4",x"5",x"0",x"0",x"0",x"8",x"2",x"8",x"4",x"2",x"4",x"6", - x"4",x"4",x"0",x"0",x"0",x"7",x"9",x"0",x"4",x"4",x"4",x"1",x"5",x"2",x"0",x"0", - x"0",x"7",x"5",x"0",x"5",x"3",x"4",x"4",x"5",x"7",x"0",x"0",x"0",x"6",x"7",x"8", - x"A",x"D",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",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",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.2 Hardware/rtl/tshoot_sound_board.vhd b/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/tshoot_sound_board.vhd index bd47945a..2b7b722a 100644 --- a/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/tshoot_sound_board.vhd +++ b/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/tshoot_sound_board.vhd @@ -38,11 +38,9 @@ port( sound_trig : in std_logic; sound_ack : out std_logic; audio_out : out std_logic_vector( 7 downto 0); - - snd_rom_addr : out std_logic_vector(12 downto 0); - snd_rom_do : in std_logic_vector(7 downto 0); - - dbg_cpu_addr : out std_logic_vector(15 downto 0) + + snd_rom_addr : buffer std_logic_vector(12 downto 0); + snd_rom_do : in std_logic_vector( 7 downto 0) ); end tshoot_sound_board; @@ -65,6 +63,8 @@ architecture struct of tshoot_sound_board is signal rom_cs : std_logic; signal rom_do : std_logic_vector( 7 downto 0); + signal snd_rom_addr_r : std_logic_vector(12 downto 0); + -- pia port a -- bit 0-7 audio output @@ -86,8 +86,6 @@ architecture struct of tshoot_sound_board is begin -dbg_cpu_addr <= cpu_addr; - -- clock divider process (reset, clock_12) begin @@ -116,7 +114,16 @@ end process; wram_cs <= '1' when cpu_addr(15 downto 13) = "000" else '0'; pia_cs <= '1' when cpu_addr(15 downto 13) = "001" else '0'; rom_cs <= '1' when cpu_addr(15 downto 13) = "111" else '0'; - + +snd_rom_addr <= cpu_addr(12 downto 0) when rom_cs = '1' else snd_rom_addr_r; + +process (reset, clock_12) +begin + if rising_edge(clock_12) then + snd_rom_addr_r <= snd_rom_addr; + end if; +end process; + -- write enables wram_we <= '1' when cpu_rw_n = '0' and cpu_clock = '1' and wram_cs = '1' else '0'; pia_rw_n <= '0' when cpu_rw_n = '0' and pia_cs = '1' else '1'; @@ -155,8 +162,6 @@ port map( -- addr => cpu_addr(12 downto 0), -- data => rom_do --); - -snd_rom_addr <= cpu_addr(12 downto 0); rom_do <= snd_rom_do; -- cpu wram diff --git a/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/williams2.vhd b/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/williams2.vhd index eafc3db1..382b4afa 100644 --- a/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/williams2.vhd +++ b/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/williams2.vhd @@ -9,9 +9,9 @@ -- 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 +-- mc6809 +-- Cycle-Accurate 6809 Core +-- Copyright (c) 2016, Greg Miller --------------------------------------------------------------------------------- -- cpu68 - Version 9th Jan 2004 0.8 -- 6800/01 compatible CPU core @@ -46,64 +46,83 @@ use ieee.numeric_std.all; entity williams2 is port( - clock_12 : in std_logic; - reset : in std_logic; ---prg low - prg_rom_addr : out std_logic_vector(13 downto 0); - prg_rom_do : in std_logic_vector(7 downto 0); ---banks - rom_addr : out std_logic_vector(16 downto 0); - rom_do : in std_logic_vector( 7 downto 0); - rom_rd : out std_logic; ---snd - snd_rom_addr : out std_logic_vector(12 downto 0); - snd_rom_do : in std_logic_vector(7 downto 0); ---gfx - gfx_rom_addr : out std_logic_vector(12 downto 0); - gfx_rom_do : in std_logic_vector(23 downto 0); ---dec - dec_rom_addr : out std_logic_vector(8 downto 0); - dec_rom_do : in std_logic_vector(7 downto 0); --- tv15Khz_mode : in std_logic; - video_r : out std_logic_vector(3 downto 0); - video_g : out std_logic_vector(3 downto 0); - video_b : out std_logic_vector(3 downto 0); - video_i : out std_logic_vector(3 downto 0); - 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); - + clock_12 : in std_logic; + reset : in std_logic; + hwsel : in std_logic_vector(1 downto 0); + + rom_addr : buffer std_logic_vector(17 downto 0); + rom_do : in std_logic_vector( 7 downto 0); + rom_rd : out std_logic; + gfx_rom_addr : out std_logic_vector(13 downto 0); + gfx_rom_do : in std_logic_vector(31 downto 0); + snd_rom_addr : out std_logic_vector(12 downto 0); + snd_rom_do : in std_logic_vector( 7 downto 0); + snd2_rom_addr : out std_logic_vector(16 downto 0); + snd2_rom_do : in std_logic_vector( 7 downto 0); + + video_r : out std_logic_vector(3 downto 0); + video_g : out std_logic_vector(3 downto 0); + video_b : out std_logic_vector(3 downto 0); + video_i : out std_logic_vector(3 downto 0); + video_csync : out std_logic; + video_blankn : out std_logic; + video_hs : out std_logic; + video_vs : out std_logic; + + audio_left : out unsigned(16 downto 0); + audio_right : out unsigned(16 downto 0); + + input1 : in std_logic_vector(7 downto 0); + input2 : in std_logic_vector(7 downto 0); + input_sel : out std_logic; + btn_auto_up : in std_logic; btn_advance : in std_logic; btn_high_score_reset : in std_logic; + btn_coin : in std_logic; + + cnt_4ms_o : out std_logic; - btn_gobble : in std_logic; - btn_grenade : in std_logic; - btn_coin : in std_logic; - btn_start_2 : in std_logic; - btn_start_1 : in std_logic; - btn_trigger : in std_logic; - --- gun_h : in std_logic_vector(5 downto 0); --- gun_v : in std_logic_vector(5 downto 0); - --- cnt_4ms_o : out std_logic; - btn_left : in std_logic; - btn_right : in std_logic; - btn_up : in std_logic; - btn_down : in std_logic; - sw_coktail_table : in std_logic; seven_seg : out std_logic_vector( 7 downto 0); - - dbg_out : out std_logic_vector(31 downto 0) + + dl_clock : in std_logic; + dl_addr : in std_logic_vector(15 downto 0); + dl_data : in std_logic_vector( 7 downto 0); + dl_wr : in std_logic; + up_data : out std_logic_vector(7 downto 0); + cmos_wr : in std_logic ); end williams2; architecture struct of williams2 is + component mc6809is is + port ( + CLK : in std_logic; + fallE_en : in std_logic; + fallQ_en : in std_logic; + D : in std_logic_vector( 7 downto 0); + Dout : out std_logic_vector( 7 downto 0); + ADDR : out std_logic_vector(15 downto 0); + RnW : out std_logic; + BS : out std_logic; + BA : out std_logic; + nIRQ : in std_logic := '1'; + nFIRQ : in std_logic := '1'; + nNMI : in std_logic := '1'; + AVMA : out std_logic; + BUSY : out std_logic; + LIC : out std_logic; + nHALT : in std_logic := '1'; + nRESET : in std_logic := '1'; + nDMABREQ : in std_logic := '1' + ); + end component mc6809is; + + constant HW_TSHOOT : std_logic_vector(1 downto 0) := "00"; + constant HW_JOUST2 : std_logic_vector(1 downto 0) := "01"; + constant HW_INFERNO : std_logic_vector(1 downto 0) := "10"; + constant HW_MYSTICM : std_logic_vector(1 downto 0) := "11"; signal en_pixel : std_logic := '0'; signal video_access : std_logic; @@ -118,6 +137,7 @@ architecture struct of williams2 is signal cpu_do : std_logic_vector( 7 downto 0); signal cpu_rw_n : std_logic; signal cpu_irq : std_logic; + signal cpu_firq : std_logic; signal addr_bus : std_logic_vector(15 downto 0); signal data_bus_high : std_logic_vector( 7 downto 0); @@ -127,7 +147,7 @@ architecture struct of williams2 is signal decod_addr : std_logic_vector( 8 downto 0); signal decod_do : std_logic_vector( 7 downto 0); - + signal vram_addr : std_logic_vector(13 downto 0); signal vram_cs : std_logic; signal vram_we : std_logic; @@ -143,7 +163,8 @@ architecture struct of williams2 is signal vram_l2_we : std_logic; signal vram_h2_do : std_logic_vector( 3 downto 0); signal vram_h2_we : std_logic; - + + signal rom_addr_r : std_logic_vector(17 downto 0); signal rom_bank_a_do : std_logic_vector( 7 downto 0); signal rom_bank_b_do : std_logic_vector( 7 downto 0); signal rom_bank_c_do : std_logic_vector( 7 downto 0); @@ -152,8 +173,9 @@ architecture struct of williams2 is signal rom_prog1_do : std_logic_vector( 7 downto 0); signal rom_prog2_do : std_logic_vector( 7 downto 0); --- signal sram0_we : std_logic; --- signal sram0_do : std_logic_vector( 7 downto 0); + signal sram_cs : std_logic; + signal sram_we : std_logic; + signal sram_do : std_logic_vector( 7 downto 0); signal page : std_logic_vector( 2 downto 0); signal page_cs : std_logic; @@ -189,8 +211,9 @@ architecture struct of williams2 is signal xscroll_high_cs : std_logic; signal xscroll_low_cs : std_logic; signal xscroll : std_logic_vector(11 downto 0); - - signal graph_addr : std_logic_vector(12 downto 0); + signal xscroll_adj : std_logic_vector( 2 downto 0); + + signal graph_addr : std_logic_vector(13 downto 0); signal graph1_do : std_logic_vector( 7 downto 0); signal graph2_do : std_logic_vector( 7 downto 0); signal graph3_do : std_logic_vector( 7 downto 0); @@ -229,7 +252,6 @@ architecture struct of williams2 is signal bg_pixels_5 : std_logic_vector( 3 downto 0); signal bg_pixels_6 : std_logic_vector( 3 downto 0); signal bg_pixels_7 : std_logic_vector( 3 downto 0); - signal bg_pixels_8 : std_logic_vector( 3 downto 0); signal bg_pixels_shifted : std_logic_vector(3 downto 0); signal hsync0,hsync1,hsync2,csync,hblank,vblank : std_logic; @@ -264,35 +286,22 @@ architecture struct of williams2 is signal cpu_ba : std_logic; signal cpu_bs : std_logic; - signal gun_bin_code : std_logic_vector(5 downto 0); - signal gun_gray_code : std_logic_vector(5 downto 0); - signal sound_select : std_logic_vector(7 downto 0); signal sound_trig : std_logic; + signal sound_trig2 : std_logic; signal sound_ack : std_logic; - - signal left_r : std_logic; - signal right_r : std_logic; - signal up_r : std_logic; - signal down_r : std_logic; - signal gun_update_r : std_logic; - signal div_h ,div_v : std_logic_vector(4 downto 0); - signal gun_h, gun_v : std_logic_vector(5 downto 0); - - signal sound_cpu_addr : std_logic_vector(15 downto 0); + signal audio : std_logic_vector( 7 downto 0); + signal pia_audio : std_logic_vector( 7 downto 0); + signal speech_out : std_logic_vector(15 downto 0); + signal fm_left : unsigned(15 downto 0); + signal fm_right : unsigned(15 downto 0); + signal ic79_a : std_logic_vector(3 downto 0); + signal ic79_b : std_logic_vector(3 downto 0); + signal ic79_out : std_logic; begin --- for debug -process (clock_12) -begin - if rising_edge(clock_12) then --- dbg_out(15 downto 0) <= cpu_addr; - dbg_out(15 downto 0) <= sound_cpu_addr; - end if; -end process; - -- make pixels counters and cpu clock -- in original hardware cpu clock = 1us = 6pixels -- here one make 2 cpu clock within 1us @@ -305,21 +314,21 @@ begin video_access <= '0'; graph_access <= '0'; rom_rd <= '0'; - + if pixel_cnt = "000" then en_cpu <= '1'; end if; if pixel_cnt = "001" then rom_rd <= '1'; end if; if pixel_cnt = "011" then video_access <= '1'; end if; if pixel_cnt = "100" then graph_access <= '1'; end if; - + if en_pixel = '1' then if pixel_cnt = "101" then pixel_cnt <= "000"; else pixel_cnt <= pixel_cnt + '1'; end if; - + end if; - + end if; end process; @@ -341,7 +350,7 @@ begin if (pixel_cnt = "101") and (en_pixel = '1' ) then hcnt <= hcnt + '1'; - if hcnt = "111111" then + if hcnt = "111101" then if vcnt = '1'&X"FF" then vcnt <= '0'&X"FC"; else @@ -389,7 +398,6 @@ begin bg_pixels_5 <= bg_pixels_4; bg_pixels_6 <= bg_pixels_5; bg_pixels_7 <= bg_pixels_6; - bg_pixels_8 <= bg_pixels_7; if flip = '0' then fg_pixels_0 <= fg_pixels(23 downto 20); @@ -401,7 +409,8 @@ begin end if; end process; -with xscroll(2 downto 0) select +xscroll_adj <= xscroll(2 downto 0) when hwsel = HW_TSHOOT else xscroll(2 downto 0) xor "111"; +with xscroll_adj(2 downto 0) select bg_pixels_shifted <= bg_pixels_0 when "000", bg_pixels_1 when "001", @@ -411,13 +420,20 @@ bg_pixels_shifted <= bg_pixels_5 when "101", bg_pixels_6 when "110", bg_pixels_7 when others; - + +-- ic79 74LS85 controls low background color bank bit w.r.t ligne number (vcnt) +ic79_a <= bg_color_bank(0) & bg_color_bank(0) & "01"; +ic79_b <= "00"&vcnt(7)&vcnt(6); +ic79_out <= '1' when (ic79_a > ic79_b) or ((ic79_a = ic79_b) and (vcnt(5)='0')) else '0'; + -- mux bus addr and pixels data to palette addr palette_addr <= addr_bus(10 downto 1) when color_cs = '1' else fg_color_bank & fg_pixels_0 when fg_pixels_0 /= x"0" else + bg_color_bank(5 downto 0) & bg_pixels_shifted when hwsel = HW_JOUST2 else + bg_color_bank(5 downto 3) & bg_color_bank(1) & bg_color_bank(2) & ic79_out & bg_pixels_shifted when hwsel = HW_MYSTICM else bg_color_bank(5 downto 3) & vcnt(7 downto 5) & bg_pixels_shifted; - + -- palette output to colors bits video_r <= palette_lo_do(3 downto 0); video_g <= palette_lo_do(7 downto 4); @@ -440,20 +456,23 @@ begin if video_access = '1' then fg_pixels <= vram_h0_do & vram_l0_do & vram_h1_do & vram_l1_do & vram_h2_do & vram_l2_do; -- map graphics address - flip_bg_a <= map_do(7); - if map_do(7) = '0' then - graph_addr <= map_do(6 downto 0) & vcnt(3 downto 0) & map_x(1) & map_x(0); + if hwsel = HW_JOUST2 then + graph_addr <= map_do(7 downto 0) & vcnt(3 downto 0) & map_x(1) & map_x(0); -- /!\ bit supplementaire else - graph_addr <= map_do(6 downto 0) & vcnt(3 downto 0) & not map_x(1) & not map_x(0); + flip_bg_a <= map_do(7); + if map_do(7) = '0' then + graph_addr <= '0' & map_do(6 downto 0) & vcnt(3 downto 0) & map_x(1) & map_x(0); + else + graph_addr <= '0' & map_do(6 downto 0) & vcnt(3 downto 0) & not map_x(1) & not map_x(0); + end if; end if; else fg_pixels <= fg_pixels(19 downto 0) & X"0" ; end if; - + if graph_access = '1' then flip_bg <= flip_bg_a; --- bg_pixels <= graph1_do & graph2_do & graph3_do; - bg_pixels <= gfx_rom_do; + bg_pixels <= graph1_do & graph2_do & graph3_do; else if flip_bg = '0' then bg_pixels <= bg_pixels(19 downto 0) & X"0"; @@ -461,34 +480,35 @@ begin bg_pixels <= X"0" & bg_pixels(23 downto 4); end if; end if; --- else --- end if; + else + --end if; end if; end if; end process; - - -gun_bin_code <= gun_v when pia_io1_ca2_o = '0' else gun_h; pias_clock <= not clock_12; -pia_io1_pa_i <= not btn_trigger & '0'& gun_gray_code; -pia_io1_pb_i <= btn_start_2 & btn_start_1 & "1111" & btn_gobble & btn_grenade; -pia_io2_pa_i <= sw_coktail_table & "000" & btn_coin & btn_high_score_reset & btn_advance & btn_auto_up; +pia_io1_pa_i <= input1; +pia_io1_pb_i <= input2; +pia_io2_pa_i <= sw_coktail_table & "000" & btn_coin & btn_high_score_reset & btn_advance & btn_auto_up; +input_sel <= pia_io1_ca2_o; -- video syncs to pia -vcnt_240 <= '0' when vcnt = '1'&X"F0" else '1'; +vcnt_240 <= '1' when vcnt = '1'&X"F0" else '0'; cnt_4ms <= vcnt(5); ---cnt_4ms_o <= vcnt(5); +cnt_4ms_o <= vcnt(5); -- pia rom irqs to cpu -cpu_irq <= pia_io1_irqa or pia_io1_irqb or pia_io2_irqa or pia_io2_irqb; +cpu_irq <= pia_io1_irqa or pia_io1_irqb or pia_io2_irqa or pia_io2_irqb when hwsel = HW_TSHOOT else + pia_io1_irqb or pia_io2_irqa or pia_io2_irqb when hwsel = HW_MYSTICM else + pia_io2_irqa or pia_io2_irqb; +cpu_firq <= pia_io1_irqa when hwsel = HW_MYSTICM else '0'; -- chip select/we we_bus <= '1' when (cpu_rw_n = '0' or blit_rw_n = '0') and en_pixel = '1' and en_cpu = '1' else '0'; vram_cs <= '1' when color_cs = '0' and - ( (blit_has_bus = '0' and addr_bus < x"C000") or - (blit_has_bus = '1' and (addr_bus < x"9000" or addr_bus >= x"C000" or dma_inh_n = '0'))) else '0'; + ( (blit_has_bus = '0' and (addr_bus < x"C000" or hwsel = HW_JOUST2)) or + (blit_has_bus = '1' and (addr_bus < x"9000" or (addr_bus >= x"C000" and hwsel = HW_TSHOOT) or dma_inh_n = '0'))) else '0'; color_cs <= '1' when addr_bus(15 downto 12) = X"8" and page(1 downto 0) = "11" else '0'; -- 8000-8FFF & page 3 rom_bank_cs <= '1' when addr_bus(15) = '0' and (page /= "000" and page /= "111") else '0'; -- 0000-7000 @@ -504,12 +524,14 @@ flip_cs <= '1' when cpu_addr(15 downto 5) = X"CB"&"100" else '0'; -- C dma_inh_cs <= '1' when cpu_addr(15 downto 5) = X"CB"&"101" else '0'; -- CBA0-CBBF pia_io2_cs <= '1' when addr_bus(15 downto 7) = X"C9"&"1" and addr_bus(3 downto 2) = "00" else '0'; -- C980-C983 pia_io1_cs <= '1' when addr_bus(15 downto 7) = X"C9"&"1" and addr_bus(3 downto 2) = "01" else '0'; -- C984-C987 +sram_cs <= '1' when addr_bus(15 downto 12) = X"D" and (hwsel = HW_INFERNO or hwsel = HW_MYSTICM) else '0'; -- D000-DFFF palette_lo_we <= '1' when we_bus = '1' and color_cs = '1' and addr_bus(0) = '0' else '0'; palette_hi_we <= '1' when we_bus = '1' and color_cs = '1' and addr_bus(0) = '1' else '0'; map_we <= '1' when we_bus = '1' and addr_bus(15 downto 11) = X"C"&'0' else '0'; -- C000-C7FF cmos_we <= '1' when we_bus = '1' and addr_bus(15 downto 10) = x"C"&"11" else '0'; -- CC00-CFFF vram_we <= '1' when we_bus = '1' and vram_cs = '1' else '0'; +sram_we <= '1' when we_bus = '1' and sram_cs = '1' else '0'; -- dispatch we to devices with respect to decoder bits 7-6 and blitter inhibit vram_l0_we <= '1' when vram_we = '1' and blit_wr_inh_l = '0' and decod_do(7 downto 6) = "00" else '0'; @@ -520,17 +542,28 @@ vram_h1_we <= '1' when vram_we = '1' and blit_wr_inh_h = '0' and decod_do(7 dow vram_h2_we <= '1' when vram_we = '1' and blit_wr_inh_h = '0' and decod_do(7 downto 6) = "10" else '0'; -- mux banked rom address to external (d)ram -rom_addr <= "00"&addr_bus(14 downto 0) when (page = "010" ) else - "01"&addr_bus(14 downto 0) when (page = "110" ) else - "10"&addr_bus(14 downto 0) when (page = "001" or page = "011") else - "11"&addr_bus(14 downto 0) when (page = "100" or page = "101") else - "00"&addr_bus(14 downto 0); +rom_addr <= rom_addr_r when (cpu_rw_n = '0' or blit_rw_n = '0') else + "10000"&addr_bus(12 downto 0) when addr_bus(15 downto 13) = "111" else -- 8K + "100010"&addr_bus(11 downto 0) when addr_bus(15 downto 12) = X"D" else -- 4K + "000"&addr_bus(14 downto 0) when (page = "010" ) else + "001"&addr_bus(14 downto 0) when (page = "110" ) else + "010"&addr_bus(14 downto 0) when (page = "001" or page = "011") else + "011"&addr_bus(14 downto 0) when (page = "100" or page = "101") else + rom_addr_r; + +process (clock_12) +begin + if rising_edge(clock_12) then + rom_addr_r <= rom_addr; + end if; +end process; -- mux data bus between cpu/blitter/roms/io/vram data_bus_high <= --- rom_prog2_do when addr_bus(15 downto 12) >= X"E" else -- 8K --- rom_prog1_do when addr_bus(15 downto 12) >= X"D" else -- 4K - prg_rom_do when addr_bus(15 downto 12) >= X"D" else -- 12K + sram_do when sram_cs = '1' else -- 4K- D000-DFFF + rom_do when addr_bus(15 downto 12) >= X"D" else + --rom_prog2_do when addr_bus(15 downto 12) >= X"E" else -- 8K + --rom_prog1_do when addr_bus(15 downto 12) >= X"D" else -- 4K vcnt(7 downto 0) when addr_bus(15 downto 4) = X"CBE" else map_do when addr_bus(15 downto 11) = X"C"&'0' else x"0"&cmos_do when addr_bus(15 downto 10) = X"C"&"11" else @@ -651,13 +684,13 @@ if reset='1' then blit_wr_inh_h <= '0'; blit_wr_inh_l <= '0'; else - if rising_edge(clock_12) then + if rising_edge(clock_12) then -- sync cpu_halt in the middle of cpu cycle if video_access = '1' then cpu_halt <= blit_halt; end if; - + -- intialize blit if blit_start = '1' and blit_halt = '0' and video_access = '1' then blit_halt <= '1'; @@ -673,67 +706,67 @@ else blit_addr <= blit_src; blit_rw_n <= '1'; end if; - + -- do blit if blit_has_bus = '1' then - - -- read step (use graph access) - if graph_access = '1' and en_pixel = '0' and blit_go = '1' then - + + -- read step (use graph access) + if graph_access = '1' and en_pixel = '0' and blit_go = '1' then + -- next step will be write blit_addr <= blit_cur_dst; blit_rw_n <= '0'; - + -- also prepare next source address w.r.t source stride if blit_cmd(0) = '0' then - blit_cur_src <= blit_cur_src + 1; - else + blit_cur_src <= blit_cur_src + 1; + else if blit_cur_width = 0 then - blit_cur_src <= blit_src_ori + 1; - blit_src_ori <= blit_src_ori + 1; - else - blit_cur_src <= blit_cur_src + 256; + blit_cur_src <= blit_src_ori + 1; + blit_src_ori <= blit_src_ori + 1; + else + blit_cur_src <= blit_cur_src + 256; end if; end if; -- get data from source and prepare data to be written blit_h := not blit_cmd(7); blit_l := not blit_cmd(6); - + -- right shift mode if blit_cmd(5) = '0' then data := data_bus; else - data := right_nibble & data_bus(7 downto 4); - right_nibble <= data_bus(3 downto 0); + data := right_nibble & data_bus(7 downto 4); + right_nibble <= data_bus(3 downto 0); end if; - + -- transparent mode : don't write pixel if src = 0 - if blit_cmd(3) = '1' then + if blit_cmd(3) = '1' then if data(7 downto 4) = x"0" then blit_h := '0'; end if; - if data(3 downto 0) = x"0" then blit_l := '0'; end if; - end if; - + if data(3 downto 0) = x"0" then blit_l := '0'; end if; + end if; + -- solid mode : write color instead of src data if blit_cmd(4) = '1' then data := blit_color; - else + else data := data; end if; - + -- put data to written on bus with write inhibits blit_data <= data; - blit_wr_inh_h <= not blit_h; + blit_wr_inh_h <= not blit_h; blit_wr_inh_l <= not blit_l; - + end if; - + -- write step (use cpu access) if en_cpu = '1' and en_pixel = '0' and blit_go = '1' then -- next step will be read blit_addr <= blit_cur_src; blit_rw_n <= '1'; - + -- also prepare next destination address w.r.t destination stride -- or stop blit if blit_cur_width = 0 then @@ -745,56 +778,57 @@ else else blit_cur_width <= blit_width; blit_cur_height <= blit_cur_height - 1; - + if blit_cmd(1) = '0' then blit_cur_dst <= blit_cur_dst + 1; - else + else blit_cur_dst <= blit_dst_ori + 1; - blit_dst_ori <= blit_dst_ori + 1; + blit_dst_ori <= blit_dst_ori + 1; end if; - + end if; else blit_cur_width <= blit_cur_width - 1; - + if blit_cmd(1) = '0' then blit_cur_dst <= blit_cur_dst + 1; else blit_cur_dst <= blit_cur_dst + 256; - end if; - end if; + end if; + end if; end if; - + -- slow mode if en_cpu = '1' and en_pixel = '0' and blit_cmd(2) = '1' then blit_go <= not blit_go; end if; - - end if; -- cpu halted + + end if; -- cpu halted end if; end if; end process; -- microprocessor 6809 -IC28 -main_cpu : entity work.cpu09 -port map( - clk => en_cpu, -- 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 => cpu_ba, -- bus available (high on sync wait or DMA grant) - bs => cpu_bs, -- bus status (high on interrupt or reset vector fetch or DMA grant) - addr => cpu_addr, -- address bus output - rw => cpu_rw_n, -- 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 => cpu_halt, -- halt input (active high) grants DMA - hold => '0' -- hold input (active high) extend bus cycle +main_cpu : mc6809is +port map( + CLK => clock_12, + fallE_en => en_cpu and not en_pixel, + fallQ_en => en_cpu and en_pixel, + D => cpu_di, + Dout => cpu_do, + ADDR => cpu_addr, + RnW => cpu_rw_n, + BS => cpu_bs, + BA => cpu_ba, + nIRQ => not cpu_irq, + nFIRQ => not cpu_firq, + nNMI => '1', + AVMA => open, + BUSY => open, + LIC => open, + nHALT => not cpu_halt, + nRESET => not reset, + nDMABREQ => '1' ); -- cpu program roms - IC9-10-54 @@ -804,7 +838,7 @@ port map( -- addr => addr_bus(11 downto 0), -- data => rom_prog1_do --); - +-- --prog2_rom : entity work.turkey_shoot_prog2 --port map( -- clk => clock_12, @@ -812,7 +846,6 @@ port map( -- data => rom_prog2_do --); -prg_rom_addr <= addr_bus(13 downto 0); -- rom17.ic26 + rom15.ic24 --bank_a_rom : entity work.turkey_shoot_bank_a @@ -821,8 +854,8 @@ prg_rom_addr <= addr_bus(13 downto 0); -- addr => addr_bus(13 downto 0), -- data => rom_bank_a_do --); - --- rom16.ic25 + rom14.ic23 + rom13.ic21 + rom12.ic19 +-- +---- rom16.ic25 + rom14.ic23 + rom13.ic21 + rom12.ic19 --bank_b_rom : entity work.turkey_shoot_bank_b --port map( -- clk => clock_12, @@ -846,6 +879,11 @@ prg_rom_addr <= addr_bus(13 downto 0); -- data => rom_bank_d_do --); +gfx_rom_addr <= graph_addr(13 downto 0); +graph1_do <= gfx_rom_do(7 downto 0); +graph2_do <= gfx_rom_do(15 downto 8); +graph3_do <= gfx_rom_do(23 downto 16); + -- rom20.ic57 --graph1_rom : entity work.turkey_shoot_graph1 --port map( @@ -854,15 +892,15 @@ prg_rom_addr <= addr_bus(13 downto 0); -- data => graph1_do --); --- rom20.ic58 +---- rom20.ic58 --graph2_rom : entity work.turkey_shoot_graph2 --port map( -- clk => clock_12, -- addr => graph_addr(12 downto 0), -- data => graph2_do --); - --- rom20.ic41 +-- +------ rom20.ic41 --graph3_rom : entity work.turkey_shoot_graph3 --port map( -- clk => clock_12, @@ -870,15 +908,13 @@ prg_rom_addr <= addr_bus(13 downto 0); -- data => graph3_do --); -gfx_rom_addr <= graph_addr(12 downto 0); - -- cpu/video wram low 0 - IC102-105 cpu_video_ram_l0 : entity work.gen_ram generic map( dWidth => 4, aWidth => 14) port map( clk => clock_12, we => vram_l0_we, - addr => vram_addr(13 downto 0), + addr => vram_addr, d => data_bus(3 downto 0), q => vram_l0_do ); @@ -889,7 +925,7 @@ generic map( dWidth => 4, aWidth => 14) port map( clk => clock_12, we => vram_h0_we, - addr => vram_addr(13 downto 0), + addr => vram_addr, d => data_bus(7 downto 4), q => vram_h0_do ); @@ -900,7 +936,7 @@ generic map( dWidth => 4, aWidth => 14) port map( clk => clock_12, we => vram_l1_we, - addr => vram_addr(13 downto 0), + addr => vram_addr, d => data_bus(3 downto 0), q => vram_l1_do ); @@ -911,7 +947,7 @@ generic map( dWidth => 4, aWidth => 14) port map( clk => clock_12, we => vram_h1_we, - addr => vram_addr(13 downto 0), + addr => vram_addr, d => data_bus(7 downto 4), q => vram_h1_do ); @@ -922,7 +958,7 @@ generic map( dWidth => 4, aWidth => 14) port map( clk => clock_12, we => vram_l2_we, - addr => vram_addr(13 downto 0), + addr => vram_addr, d => data_bus(3 downto 0), q => vram_l2_do ); @@ -933,12 +969,11 @@ generic map( dWidth => 4, aWidth => 14) port map( clk => clock_12, we => vram_h2_we, - addr => vram_addr(13 downto 0), + addr => vram_addr, d => data_bus(7 downto 4), q => vram_h2_do ); - -- palette rams - IC78-77 palette_ram_lo : entity work.gen_ram generic map( dWidth => 8, aWidth => 10) @@ -961,7 +996,6 @@ port map( q => palette_hi_do ); - -- map ram - IC40 map_ram : entity work.gen_ram generic map( dWidth => 8, aWidth => 11) @@ -973,51 +1007,45 @@ port map( q => map_do ); ---sram0 : entity work.gen_ram ---generic map( dWidth => 8, aWidth => 11) ---port map( --- clk => clock_12, --- we => sram0_we, --- addr => addr_bus(10 downto 0), --- d => data_bus, --- q => sram0_do ---); - --- cmos ram - IC59 -cmos_ram : entity work.t_shoot_cmos_ram -generic map( dWidth => 4, aWidth => 10) +-- sram 0 & 1 +sram : entity work.gen_ram +generic map( dWidth => 8, aWidth => 12) port map( clk => clock_12, - we => cmos_we, - addr => cpu_addr(9 downto 0), - d => data_bus(3 downto 0), - q => cmos_do + we => sram_we, + addr => addr_bus(11 downto 0), + d => data_bus, + q => sram_do +); + +-- cmos ram - IC59 +cmos_ram : entity work.dpram +generic map( dWidth => 4, aWidth => 10) +port map( + clk_a => clock_12, + we_a => cmos_we, + addr_a => addr_bus(9 downto 0), + d_a => data_bus(3 downto 0), + q_a => cmos_do, + clk_b => dl_clock, + we_b => cmos_wr, + addr_b => dl_addr(9 downto 0), + d_b => dl_data(3 downto 0), + q_b => up_data(3 downto 0) ); -- addr bus to video addr decoder - IC60 -video_addr_decoder : entity work.turkey_shoot_decoder +video_addr_decoder : entity work.williams2_decoder port map( clk => clock_12, addr => decod_addr, data => decod_do ); ---dec_rom_addr <= decod_addr; ---decod_do <= dec_rom_do; - --- gun gray code encoder -gun_gray_encoder : entity work.gray_code -port map( - clk => clock_12, - addr => gun_bin_code, - data => gun_gray_code -); - - -- pia iO1 : ic6 (5C) pia_io1 : entity work.pia6821 port map -( +( clk => pias_clock, -- rising edge rst => reset, -- active high cs => pia_io1_cs, @@ -1046,7 +1074,7 @@ port map -- pia iO2 : ic5 (2C) pia_rom : entity work.pia6821 port map -( +( clk => pias_clock, rst => reset, cs => pia_io2_cs, @@ -1059,9 +1087,9 @@ port map pa_i => pia_io2_pa_i, pa_o => open, pa_oe => open, - ca1 => '0', + ca1 => cnt_4ms, --'0', ca2_i => '0', - ca2_o => open, + ca2_o => sound_trig2, ca2_oe => open, pb_i => (others => '0'), pb_o => sound_select, @@ -1097,7 +1125,7 @@ if rising_edge(clock_12) then 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 = 502 then vsync_cnt := X"0"; @@ -1130,7 +1158,7 @@ if rising_edge(clock_12) then 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; @@ -1143,62 +1171,34 @@ tshoot_sound_board : entity work.tshoot_sound_board port map( clock_12 => clock_12, reset => reset, + sound_select => sound_select, sound_trig => sound_trig, sound_ack => sound_ack, - audio_out => audio_out, + audio_out => audio, + snd_rom_addr => snd_rom_addr, - snd_rom_do => snd_rom_do, - dbg_cpu_addr => sound_cpu_addr + snd_rom_do => snd_rom_do ); -process (reset, clock_12) -begin -if reset='1' then -else - if rising_edge(clock_12) then - - gun_update_r <= cnt_4ms; - - if gun_update_r = '0' and cnt_4ms = '1' then - - left_r <= btn_left; - right_r <= btn_right; - up_r <= btn_up; - down_r <= btn_down; - +williams_cvsd_board : entity work.williams_cvsd_board +port map( + clock_12 => clock_12, + reset => reset, - if ((btn_left = '1' and left_r = '1') or (btn_right = '1' and right_r = '1')) and div_h < 3 then - div_h <= div_h + '1'; - else - div_h <= (others => '0'); - end if; - - if btn_left = '1' and div_h = 1 and gun_h > 0 then - gun_h <= gun_h - '1'; - end if; - if btn_right = '1' and div_h = 1 and gun_h < 63 then - gun_h <= gun_h + '1'; - end if; + sound_select => sound_select, + sound_trig => sound_trig2, - if ((btn_up = '1' and up_r = '1') or (btn_down = '1' and down_r = '1')) and div_v < 3 then - div_v <= div_v + '1'; - else - div_v <= (others => '0'); - end if; - - if btn_up = '1' and div_v = 1 and gun_v > 0 then - gun_v <= gun_v - '1'; - end if; - if btn_down = '1' and div_v = 1 and gun_v < 63 then - gun_v <= gun_v + '1'; - end if; - - end if; + pia_audio => pia_audio, + speech_out => speech_out, + ym2151_left => fm_left, + ym2151_right => fm_right, - end if; - -end if; -end process; + snd_rom_addr => snd2_rom_addr, + snd_rom_do => snd2_rom_do +); + +audio_left <= "00000000000000000" + unsigned(audio&"00000") + unsigned(pia_audio&"00000") + unsigned(speech_out(15 downto 1)) + fm_left; +audio_right <= "00000000000000000" + unsigned(audio&"00000") + unsigned(pia_audio&"00000") + unsigned(speech_out(15 downto 1)) + fm_right; end struct; \ No newline at end of file diff --git a/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/williams2_colormix.vhd b/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/williams2_colormix.vhd new file mode 100644 index 00000000..633eb187 --- /dev/null +++ b/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/williams2_colormix.vhd @@ -0,0 +1,91 @@ + ------------------------------------- +-- Color palette Mame Informations -- +------------------------------------- +-- +-- Normal values (turkey shoot, inferno, joust2) + +-- red green blue +-- gain( { 0.25f, 0.25f, 0.25f }), +-- offset({ 0.00f, 0.00f, 0.00f }) + +-- Modified value (mystic marathon) + +-- gain = { 0.8f, 0.73f, 0.81f }; +-- offset = { -0.27f, 0.00f, -0.22f }; + +-- Computation (video/williams.cpp) +-- color_1 = max(color_in + offset , 0) +-- color_2 = min(color_1 * gain/0.25, 1) +-- with color_in max value = 1 + +-- because of gain/0.25 is ~3 output value may be much higher than 1 +-- applying min(x, 1) will strangely saturate/limit result + +-- Here by, color_in max value = 15 (before intensity) +-- => red offset = -0.27*15 = 4.050 let's assume value 5 +-- => green offset = -0.00*15 = 0.000 let's assume value 0 +-- => blue offset = -0.22*15 = 3.300 let's assume value 3 + +-- red gain = 3.20 rescaled to 127/3.24 => 125.4 let's assume value 125 +-- green gain = 2.92 rescaled to 127/3.24 => 114.5 let's assume value 114 +-- blue gain = 3.24 rescaled to 127/3.24 => 127.0 let's assume value 127 + +-- After intensity and gain, limit should be 256*128/3.24 = 10922 +-- limiting to this value gives wrong results so I choose not to +-- apply limitation (limit to 256*128 = 32768). + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; +use ieee.numeric_std.all; + +entity williams2_colormix is +port( + mysticm : in std_logic; + r : in std_logic_vector(3 downto 0); + g : in std_logic_vector(3 downto 0); + b : in std_logic_vector(3 downto 0); + intensity : in std_logic_vector(3 downto 0); + vga_r : out std_logic_vector(7 downto 0); + vga_g : out std_logic_vector(7 downto 0); + vga_b : out std_logic_vector(7 downto 0) +); +end williams2_colormix; + +architecture struct of williams2_colormix is + + signal ri : std_logic_vector( 7 downto 0); + signal gi : std_logic_vector( 7 downto 0); + signal bi : std_logic_vector( 7 downto 0); + signal ro : std_logic_vector( 7 downto 0); + signal go : std_logic_vector( 7 downto 0); + signal bo : std_logic_vector( 7 downto 0); + signal rg : std_logic_vector(15 downto 0); + signal gg : std_logic_vector(15 downto 0); + signal bg : std_logic_vector(15 downto 0); + +begin + +-- apply intensity +ri <= r*intensity; +gi <= g*intensity; +bi <= b*intensity; + +-- apply offset and max(x, 0) +ro <= ri-x"50" when ri > x"50" else x"00"; +go <= gi-x"00" when gi > x"00" else x"00"; +bo <= bi-x"30" when bi > x"30" else x"00"; + +-- apply gain and limit +-- in fact limit cannot be reached, anyway I keep the limiting function +-- here for whos who want to try it +rg <= ro*x"7D" when ro*x"7D" < x"7FFF" else x"7FFF"; +gg <= go*x"72" when go*x"72" < x"7FFF" else x"7FFF"; +bg <= bo*x"7F" when bo*x"7F" < x"7FFF" else x"7FFF"; + +-- allow selection to real_time compare results with/without modification +vga_r <= rg(14 downto 7) when mysticm = '1' else ri; +vga_g <= gg(14 downto 7) when mysticm = '1' else gi; +vga_b <= bg(14 downto 7) when mysticm = '1' else bi; + +end struct; \ No newline at end of file diff --git a/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/williams_cvsd_board.vhd b/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/williams_cvsd_board.vhd new file mode 100644 index 00000000..9928ae0d --- /dev/null +++ b/Arcade_MiST/Williams 6809 rev.2 Hardware/rtl/williams_cvsd_board.vhd @@ -0,0 +1,495 @@ +--------------------------------------------------------------------------------- +-- Williams cvsd board by Dar (darfpga@aol.fr) +-- +-- Background sound and speech (D-11298) model +-- +-- http://darfpga.blogspot.fr +-- https://sourceforge.net/projects/darfpga/files +-- github.com/darfpga +--------------------------------------------------------------------------------- +-- gen_ram.vhd +-- Copyright 2005-2008 by Peter Wendrich (pwsoft@syntiac.com) +-- http://www.syntiac.com/fpga64.html +--------------------------------------------------------------------------------- +-- MC6809 +-- Copyright (c) 2016, Greg Miller +--------------------------------------------------------------------------------- +-- HC55516/HC55564 Continuously Variable Slope Delta decoder +-- (c)2015 vlait +--------------------------------------------------------------------------------- +-- JT51 (YM2151). . +-- Author: Jose Tejada Gomez. Twitter: @topapate +--------------------------------------------------------------------------------- +-- 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 -- 25/03/2022 -- +-- initial version +--------------------------------------------------------------------------------- +-- Features : +-- +-- Use with MAME roms from joust2.zip +-- +-- Connexions : +-- +-- main board cvsd board +-- pia_io2 pb_o (IC5/2C - port B) => sound_select +-- pia_io2 ca2_o (IC5/2C - ca2) => sound_trig +-- +--------------------------------------------------------------------------------- +-- Use make_joust2_proms.bat to build vhd file and bin from binaries +--------------------------------------------------------------------------------- +--------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; +use ieee.numeric_std.all; + +entity williams_cvsd_board is +port( + clock_12 : in std_logic; + reset : in std_logic; + + sound_select : in std_logic_vector(7 downto 0); + sound_trig : in std_logic; + + pia_audio : out std_logic_vector( 7 downto 0); + speech_out : out std_logic_vector(15 downto 0); + ym2151_left : out unsigned (15 downto 0); + ym2151_right : out unsigned (15 downto 0); + + snd_rom_addr : buffer std_logic_vector(16 downto 0); + snd_rom_do : in std_logic_vector( 7 downto 0); + + dbg_out : out std_logic_vector(31 downto 0) + +); +end williams_cvsd_board; + +architecture struct of williams_cvsd_board is + +component jt51 is +port ( + + rst : in std_logic; -- reset + clk : in std_logic; -- main clock + cen : in std_logic; -- clock enable (* direct_enable *) + cen_p1: in std_logic; -- clock enable at half the speed (* direct_enable *) + cs_n : in std_logic; -- chip select + wr_n : in std_logic; -- write + a0 : in std_logic; + din : in std_logic_vector(7 downto 0); -- data in + dout : out std_logic_vector(7 downto 0); -- data out + -- peripheral control + ct1 : out std_logic; + ct2 : out std_logic; + irq_n : out std_logic; -- I do not synchronize this signal + + -- Low resolution output (same as real chip) + sample: out std_logic; -- marks new output sample + left : out signed (15 downto 0); + right : out signed (15 downto 0); + -- Full resolution output + xleft : out signed (15 downto 0); + xright : out signed (15 downto 0); + -- unsigned outputs for sigma delta converters, full resolution + dacleft : out unsigned (15 downto 0); + dacright : out unsigned (15 downto 0) +); end component jt51; + + +component mc6809is is +port ( + CLK : in std_logic; + fallE_en : in std_logic; + fallQ_en : in std_logic; + + D : in std_logic_vector(7 downto 0); + DOut : out std_logic_vector(7 downto 0); + ADDR : out std_logic_vector(15 downto 0); + RnW : out std_logic; + BS : out std_logic; + BA : out std_logic; + + nIRQ : in std_logic := '1'; + nFIRQ : in std_logic := '1'; + nNMI : in std_logic := '1'; + + AVMA : out std_logic; + BUSY : out std_logic; + LIC : out std_logic; + + nHALT : in std_logic := '1'; + nRESET : in std_logic := '1'; + + nDMABREQ: in std_logic := '1'; + RegData : out std_logic_vector(111 downto 0) +); +end component mc6809is; + + signal en_cnt : std_logic := '0'; + signal div_cnt : std_logic_vector(1 downto 0) := "00"; + + signal rom_bank_cs : 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_n : std_logic; + signal write_n : std_logic; + + signal reset_n : std_logic; + signal cpu_firq_n : std_logic; + signal cpu_nmi_n : std_logic; + signal cpu_e_en : std_logic; + signal cpu_q_en : std_logic; + + signal page_cs : std_logic; + signal page : std_logic_vector( 2 downto 0); + signal rom_cs : std_logic; + signal rom_bank_a_do : std_logic_vector( 7 downto 0); + signal rom_bank_b_do : std_logic_vector( 7 downto 0); + signal rom_bank_c_do : std_logic_vector( 7 downto 0); + + signal sram_cs : std_logic; + signal sram_we : std_logic; + signal sram_do : std_logic_vector( 7 downto 0); + + signal cvsd1_cs : std_logic; + signal cvsd2_cs : std_logic; + signal cvsd_data : std_logic; + signal cvsd_clk : std_logic; + signal cvsd_cnt : std_logic_vector(15 downto 0); + + signal pia_clock : std_logic; + + signal pia_cs : std_logic; + signal pia_we_n : std_logic; + signal pia_do : std_logic_vector( 7 downto 0); +-- signal pia_pa_o : std_logic_vector( 7 downto 0); + signal pia_irqa : std_logic; + signal pia_irqb : std_logic; + + signal ym2151_irq_n : std_logic := '0'; + signal ym2151_cs_n : std_logic; + signal ym2151_do : std_logic_vector( 7 downto 0); + signal ym2151_we_n : std_logic; + + signal lim : unsigned(9 downto 0); + signal cnt_max : unsigned(9 downto 0); + signal next_cnt : unsigned(9 downto 0); + signal next_cnt2 : unsigned(9 downto 0); + signal cen_cnt : unsigned(9 downto 0) := "0000000000"; + signal alt : std_logic := '0'; + signal cen_1p78 : std_logic := '0'; + signal cen_3p57 : std_logic := '0'; + + signal snd_rom_addr_r : std_logic_vector(16 downto 0); + +begin + +-- for debug +process (clock_12) +begin + if rising_edge(clock_12) then + dbg_out(15 downto 0) <= cpu_addr; + dbg_out(23 downto 16) <= cpu_di; + end if; +end process; + +-- +reset_n <= not reset; + +-- make cpu clocks 2MHz (12MHz/6) +-- in original hardware 2MHz from 8MHz/4 +-- _ _ _ _ _ +-- en_cnt |_| |_| |_| |_| |_| | ... (6MHz) +-- +-- div_cnt | 0 | 1 | 2 | 0 | 1 | ... +-- _ _ +-- cpu_e_en ___| |_________| |__ ... +-- _ _ +-- cpu_q_en | |_________| |______ ... +-- ______ ___________ __ +-- cpu_do ______|___________|__ ... +-- __________ ______ +-- write_n |___| ... + +process (reset, clock_12) +begin + if rising_edge(clock_12) then + + en_cnt <= not en_cnt; + write_n <= '1'; + cpu_e_en <= '0'; + cpu_q_en <= '0'; + + if en_cnt = '1' then + if div_cnt = "10" then + div_cnt <= "00"; + else + div_cnt <= div_cnt + '1'; + end if; + + -- place E and Q falling edge for MC6809 + if div_cnt = "00" then cpu_e_en <= '1'; end if; + if div_cnt = "10" then cpu_q_en <= '1'; end if; + + end if; + + -- center cpu write pulse + if div_cnt = "10" then write_n <= cpu_rw_n; end if; + + -- synchronize interruptions + if div_cnt = "01" then + cpu_nmi_n <= not pia_irqb; + cpu_firq_n <= not pia_irqa; + end if; + + end if; +end process; + +pia_clock <= not clock_12; + +-- chip select/we +sram_cs <= '1' when cpu_addr(15 downto 13) = "000" else '0'; -- 0000-1FFF +ym2151_cs_n <= '0' when cpu_addr(15 downto 13) = "001" else '1'; -- 2000-3FFF +pia_cs <= '1' when cpu_addr(15 downto 13) = "010" else '0'; -- 4000-5FFF +cvsd1_cs <= '1' when cpu_addr(15 downto 11) = "01100" else '0'; -- 6000-67FF +cvsd2_cs <= '1' when cpu_addr(15 downto 11) = "01101" else '0'; -- 6800-6FFF +page_cs <= '1' when cpu_addr(15 downto 11) = "01111" else '0'; -- 7800-7FFF +rom_cs <= '1' when cpu_addr(15) = '1'; -- 8000-FFFF + +sram_we <= '1' when write_n = '0' and sram_cs = '1' else '0'; +pia_we_n <= '0' when write_n = '0' and pia_cs = '1' else '1'; +ym2151_we_n <= '0' when write_n = '0' and ym2151_cs_n = '0' else '1'; + +-- mux data to cpu di +cpu_di <= + cpu_do when cpu_rw_n = '0' else + sram_do when sram_cs = '1' else + ym2151_do when ym2151_cs_n = '0' else + pia_do when pia_cs = '1' else + snd_rom_do when rom_cs = '1' else + --rom_bank_a_do when rom_cs = '1' and page(1 downto 0) = "00" else + --rom_bank_b_do when rom_cs = '1' and page(1 downto 0) = "01" else + --rom_bank_c_do when rom_cs = '1' and page(1 downto 0) = "10" else + X"00"; + +-- page register, cvsd clock and data +process (reset, clock_12) +begin + if reset='1' then + page <= "000"; + cvsd_data <= '0'; + cvsd_clk <= '0'; + else + if rising_edge(clock_12) then + if page_cs = '1' and write_n = '0' then page <= cpu_do(2 downto 0); end if; + if cvsd1_cs = '1' then cvsd_data <= cpu_do(0); end if; + if cvsd1_cs = '1' then cvsd_clk <= '0'; end if; + if cvsd2_cs = '1' then cvsd_clk <= '1'; end if; + end if; + end if; +end process; + +-- microprocessor 6809 -IC28 +--main_cpu : entity work.cpu09 +--port map( +-- clk => en_cpu, -- 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_addr, -- address bus output +-- rw => cpu_rw_n, -- read not write output +-- data_out => cpu_do, -- data bus output +-- data_in => cpu_di, -- data bus input +-- irq => '0', -- interrupt request input (active high) +-- firq => cpu_firq, -- fast interrupt request input (active high) +-- nmi => cpu_nmi, -- non maskable interrupt request input (active high) +-- halt => '0', -- halt input (active high) grants DMA +-- hold => '0' -- hold input (active high) extend bus cycle +--); + +-- microprocessor 6809 - IC28 +main_cpu : mc6809is +port map ( + CLK => clock_12, -- : in std_logic; + fallE_en => cpu_e_en, -- : in std_logic; + fallQ_en => cpu_q_en, -- : in std_logic; + + D => cpu_di, -- : in std_logic_vector(7 downto 0); + DOut => cpu_do, -- : out std_logic_vector(7 downto 0); + ADDR => cpu_addr, -- : out std_logic_vector(15 downto 0); + RnW => cpu_rw_n, -- : out std_logic; + BS => open, -- : out std_logic; + BA => open, -- : out std_logic; + + nIRQ => '1', -- : in std_logic := '1'; + nFIRQ => cpu_firq_n, -- : in std_logic := '1'; + nNMI => cpu_nmi_n, -- : in std_logic := '1'; + + AVMA => open, -- : out std_logic; + BUSY => open, -- : out std_logic; + LIC => open, -- : out std_logic; + + nHALT => '1', -- : in std_logic := '1' + nRESET => reset_n,-- : in std_logic := '1'; + + nDMABREQ => '1', -- : in std_logic := '1'; + RegData => open -- : out std_logic_vector(111 downto 0); +); + +snd_rom_addr <= page(1 downto 0)&cpu_addr(14 downto 0) when rom_cs = '1' else snd_rom_addr_r; + +process (reset, clock_12) +begin + if rising_edge(clock_12) then + snd_rom_addr_r <= snd_rom_addr; + end if; +end process; + +-- rom0 IC_U4 +--bank_a_rom : entity work.joust2_bg_sound_bank_a +--port map( +-- clk => clock_12, +-- addr => cpu_addr(14 downto 0), +-- data => rom_bank_a_do +--); +-- +---- rom1 IC_U19 +--bank_b_rom : entity work.joust2_bg_sound_bank_b +--port map( +-- clk => clock_12, +-- addr => cpu_addr(14 downto 0), +-- data => rom_bank_b_do +--); +-- +---- rom2 IC_U20 +--bank_c_rom : entity work.joust2_bg_sound_bank_c +--port map( +-- clk => clock_12, +-- addr => cpu_addr(14 downto 0), +-- data => rom_bank_c_do +--); + +-- sram IC U3 +sram : entity work.gen_ram +generic map( dWidth => 8, aWidth => 11) +port map( + clk => clock_12, + we => sram_we, + addr => cpu_addr(10 downto 0), + d => cpu_do, + q => sram_do +); + +-- pia IC_U2 +pia : entity work.pia6821 +port map +( + clk => pia_clock, -- rising edge + rst => reset, -- active high + cs => pia_cs, + rw => pia_we_n, -- write low + addr => cpu_addr(1 downto 0), + data_in => cpu_do, + data_out => pia_do, + irqa => pia_irqa, -- active high + irqb => pia_irqb, -- active high + pa_i => x"00", + pa_o => pia_audio, + pa_oe => open, + ca1 => ym2151_irq_n, + ca2_i => '0', + ca2_o => open, + ca2_oe => open, + pb_i => sound_select, + pb_o => open, + pb_oe => open, + cb1 => sound_trig, + cb2_i => '0', + cb2_o => open, + cb2_oe => open +); + +-- CVSD speech decoder +cvsd : entity work.HC55564 +port map( + clk => clock_12, + cen => cvsd_clk, + rst => '0', -- Reset is not currently implemented + bit_in => cvsd_data, + sample_out(15 downto 0) => speech_out +); + +-- YM2151 : FM Clocks +-- make 3.57 and 1.78MHz from 12MHz +lim <= to_unsigned(512,10); +cnt_max <= to_unsigned(512+152,10); + +next_cnt <= cen_cnt + to_unsigned(152,10); +next_cnt2 <= cen_cnt + to_unsigned(152,10) - to_unsigned(512,10); + +process (clock_12) +begin + if rising_edge(clock_12) then + cen_3p57 <= '0'; + cen_1p78 <= '0'; + + if cen_cnt >= cnt_max then + cen_cnt <= (others => '0'); + alt <= '0'; + else + if next_cnt >= lim then + cen_cnt <= next_cnt2; + cen_3p57 <= '1'; + alt <= not alt; + cen_1p78 <= alt; + else + cen_cnt <= next_cnt; + end if; + end if; + + end if; +end process; + + +-- YM2151 +jt51_if : jt51 +port map ( + + rst => reset, -- reset + clk => clock_12, -- main clock + cen => cen_3p57, -- clock enable (* direct_enable *) + cen_p1 => cen_1p78, -- clock enable at half the speed (* direct_enable *) + cs_n => ym2151_cs_n, -- chip select + wr_n => ym2151_we_n, -- write + a0 => cpu_addr(0), + din => cpu_do, -- data in + dout => ym2151_do, -- data out + -- peripheral control + ct1 => open, + ct2 => open, + irq_n => ym2151_irq_n, -- I do not synchronize this signal + + -- Low resolution output (same as real chip) + sample => open, -- marks new output sample + left => open, + right => open, + -- Full resolution output + xleft => open, + xright => open, + -- unsigned outputs for sigma delta converters, full resolution + dacleft => ym2151_left, + dacright => ym2151_right +); + +end struct;