diff --git a/Arcade_MiST/Konami Timepilot Hardware/rtl/power_surge.vhd b/Arcade_MiST/Konami Timepilot Hardware/rtl/power_surge.vhd
deleted file mode 100644
index 8426d71b..00000000
--- a/Arcade_MiST/Konami Timepilot Hardware/rtl/power_surge.vhd
+++ /dev/null
@@ -1,779 +0,0 @@
----------------------------------------------------------------------------------
--- Time pilot by Dar (darfpga@aol.fr) (29/10/2017)
--- http://darfpga.blogspot.fr
----------------------------------------------------------------------------------
--- gen_ram.vhd & io_ps2_keyboard
---------------------------------
--- Copyright 2005-2008 by Peter Wendrich (pwsoft@syntiac.com)
--- http://www.syntiac.com/fpga64.html
----------------------------------------------------------------------------------
--- T80/T80se - Version : 0247
------------------------------
--- Z80 compatible microprocessor core
--- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
----------------------------------------------------------------------------------
--- YM2149 (AY-3-8910)
--- Copyright (c) MikeJ - Jan 2005
----------------------------------------------------------------------------------
--- Educational use only
--- Do not redistribute synthetized file with roms
--- Do not redistribute roms whatever the form
--- Use at your own risk
----------------------------------------------------------------------------------
-
--- Features :
--- TV 15KHz mode only (atm)
--- Coctail mode ok
--- Sound ok
-
--- Use with MAME roms from timeplt.zip
---
--- Use make_time_pilot_proms.bat to build vhd file from binaries
-
--- time_pilot_prog.vhd : tm1, tm2,tm3
--- time_pilot_sprite_grphx.vhd : tm4, tm5
--- time_pilot_char_grphx.vhd : tm6
--- time_pilot_sound_prog.vhd : tm7
--- time_pilot_palette_blue_green.vhd : timeplt.b4
--- time_pilot_palette_green_red.vhd : timeplt.b5
--- time_pilot_sprite_color_lut.vhd : timeplt.e9
--- time_pilot_char_color_lut.vhd : timeplt.e12
-
--- Time Pilot Hardware caracteristics :
---
--- VIDEO : 1xZ80@3MHz CPU accessing its program rom, working ram,
--- sprite data ram, I/O, sound board register and trigger.
--- 24Kx8bits program rom
---
--- One char tile map 32x28
--- 8Kx8bits graphics rom 2bits/pixel
--- 4 colors/32sets among 16 colors
---
--- 24 sprites with priorities and flip H/V
--- 16Kx8bits graphics rom 2bits/pixel
--- 3 colors/64sets among 16 colors (different of char colors).
---
--- Char/sprites color palette 2x16 colors among 32768 colors
--- 15bits 5red/5green/5blue
---
--- Working ram : 4Kx8bits
--- Sprites data ram : 256x16bits
--- Sprites line buffer rams : 1 scan line delay flip/flop 2x256x4bits
-
--- SOUND : 1xZ80@1.79MHz CPU accessing its program rom, working ram, 2x-AY3-8910
--- 8Kx8bits program rom
---
--- 1xAY-3-8910
--- I/O noise input and command/trigger from video board.
--- 3 sound channels
---
--- 1xAY-3-8910
--- 3 sound channels
---
--- 6 RC filters with 4 states : transparent or cut 600Hz, 700Hz, 3.4KHz
---
----------------------------------------------------------------------------------
-
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.std_logic_unsigned.all;
-use ieee.numeric_std.all;
-
-entity power_surge is
-port(
- clock_6 : in std_logic;
- clock_12 : in std_logic;
- clock_14 : in std_logic;
- reset : in std_logic;
- video_r : out std_logic_vector(4 downto 0);
- video_g : out std_logic_vector(4 downto 0);
- video_b : out std_logic_vector(4 downto 0);
- video_clk : out std_logic;
- video_hblank : out std_logic;
- video_vblank : out std_logic;
- video_hs : out std_logic;
- video_vs : out std_logic;
- audio_out : out std_logic_vector(10 downto 0);
- roms_addr : out std_logic_vector(14 downto 0);
- roms_do : in std_logic_vector(7 downto 0);
- roms_rd : out std_logic;
- dip_switch_1 : in std_logic_vector(7 downto 0);--Cabinet Unknown Lives Lives Initial_Energy Unknown Unknown Unknown
- dip_switch_2 : in std_logic_vector(7 downto 0);--Stop_at_Junctions, Unknown, Unknown, Cheat, Coin_B Coin_B Coin_A Coin_A
-
- start2 : in std_logic;
- start1 : in std_logic;
- coin1 : in std_logic;
-
- fire1 : in std_logic;
- right1 : in std_logic;
- left1 : in std_logic;
- down1 : in std_logic;
- up1 : in std_logic;
-
- fire2 : in std_logic;
- right2 : in std_logic;
- left2 : in std_logic;
- down2 : in std_logic;
- up2 : in std_logic
-);
-end power_surge;
-
-architecture struct of power_surge is
-
- signal reset_n: std_logic;
- signal clock_12n : std_logic;
- signal clock_6n : std_logic;
- signal clock_div : std_logic_vector(1 downto 0) := "00";
-
- signal hcnt : std_logic_vector(5 downto 0); -- horizontal counter
- signal vcnt : std_logic_vector(8 downto 0); -- vertical counter
- signal pxcnt : std_logic_vector(2 downto 0); -- pixel counter
- signal spcnt : std_logic_vector(4 downto 0); -- sprite counter
-
- signal hsync0 : std_logic;
-
- signal hblank : std_logic;
- signal vblank : std_logic;
-
- signal cpu_ena : 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_wr_n : std_logic;
- signal cpu_mreq_n : std_logic;
- signal cpu_nmi_n : std_logic;
- signal cpu_int_n : std_logic;
-
- signal cpu_rom_do : std_logic_vector( 7 downto 0);
-
- signal wram_addr : std_logic_vector(11 downto 0);
- signal wram_we : std_logic;
- signal wram_do : std_logic_vector( 7 downto 0);
-
- signal ch_graphx_addr_f: std_logic_vector(12 downto 0);
- signal ch_graphx_addr : std_logic_vector(12 downto 0);
- signal ch_graphx_do : std_logic_vector( 7 downto 0);
- signal ch_pixels : std_logic_vector( 7 downto 0);
- signal ch_data1 : std_logic_vector( 7 downto 0);
- signal ch_pixel_bit1 : std_logic;
- signal ch_pixel_bit2 : std_logic;
- signal ch_color_set : std_logic_vector(4 downto 0);
- signal ch_palette_addr : std_logic_vector(7 downto 0);
- signal ch_palette_do : std_logic_vector(7 downto 0);
-
- signal spram_addr : std_logic_vector(7 downto 0);
- signal spram1_we : std_logic;
- signal spram1_do : std_logic_vector(7 downto 0);
- signal spram2_we : std_logic;
- signal spram2_do : std_logic_vector(7 downto 0);
-
- signal sp_graphx_addr : std_logic_vector(13 downto 0);
- signal sp_graphx_do : std_logic_vector(7 downto 0);
- signal vcnt_r : std_logic_vector(8 downto 0);
- signal sp_line : std_logic_vector(7 downto 0);
- signal sp_on_line : std_logic;
- signal sp_attr : std_logic_vector(7 downto 0);
- signal sp_posh : std_logic_vector(7 downto 0);
- signal sp_pixels : std_logic_vector(7 downto 0);
- signal sp_color_set : std_logic_vector(5 downto 0);
- signal sp_palette_addr : std_logic_vector(7 downto 0);
- signal sp_palette_do : std_logic_vector(7 downto 0);
- signal sp_read_out : std_logic_vector(3 downto 0);
- signal sp_blank : std_logic;
-
- signal rgb_palette_addr : std_logic_vector(4 downto 0);
- signal rgb_palette_bg_do : std_logic_vector(7 downto 0);
- signal rgb_palette_gr_do : std_logic_vector(7 downto 0);
-
- signal sp_buffer_write_addr : std_logic_vector(7 downto 0);
- signal sp_buffer_write_we : std_logic;
- signal sp_buffer_read_addr : std_logic_vector(7 downto 0);
-
- signal sp_buffer_ram1_addr : std_logic_vector(7 downto 0);
- signal sp_buffer_ram1_we : std_logic;
- signal sp_buffer_ram1_di : std_logic_vector(3 downto 0);
- signal sp_buffer_ram1_do : std_logic_vector(3 downto 0);
-
- signal sp_buffer_ram2_addr : std_logic_vector(7 downto 0);
- signal sp_buffer_ram2_we : std_logic;
- signal sp_buffer_ram2_di : std_logic_vector(3 downto 0);
- signal sp_buffer_ram2_do : std_logic_vector(3 downto 0);
-
- signal sp_buffer_sel : std_logic;
-
- signal itt_n : std_logic_vector(7 downto 0);
- signal flip : std_logic;
- signal C0xx_we : std_logic;
- signal C3xx_we : std_logic;
- signal sound_cmd : std_logic_vector(7 downto 0);
- signal sound_trig : std_logic;
-
- signal input_0 : std_logic_vector(7 downto 0);
- signal input_1 : std_logic_vector(7 downto 0);
- signal input_2 : std_logic_vector(7 downto 0);
-
-begin
-
-video_clk <= clock_6n;
-clock_12n <= not clock_12;
-clock_6n <= not clock_6;
-reset_n <= not reset;
-
---------------------------
--- Video/sprite scanner --
---------------------------
-
--- make hcnt and vcnt video scanner from pixel clocks and counts
---
--- pxcnt |0|1|2|3|4|5|6|7|0|1|2|3|4|5|6|7|
--- hcnt | N | N+1 |
--- cpu_adr/do | |
-
---
--- hcnt [0..47] => 48 x 8 = 384 pixels, 384/6.144Mhz => 1 line is 62.5us (16.000KHz)
--- vcnt [252..255,256..511] => 260 lines, 1 frame is 260 x 62.5us = 16.250ms (61.54Hz)
-
-process (reset, clock_6)
-begin
- if reset='1' then
- pxcnt <= "000";
- hcnt <= "000000";
- vcnt <= '0'&X"FC";
- spcnt <= "00000";
- else
- if rising_edge(clock_6) then
- pxcnt <= pxcnt + '1';
- if pxcnt = "111" then
- hcnt <= hcnt + '1';
-
- if hcnt = "101111" then -- char from #0 to #47 (one line)
- hcnt <= "000000";
- if vcnt = '1'&X"FF" then
- vcnt <= '0'&X"FC";
- else
- vcnt <= vcnt + '1';
- end if;
- end if;
-
- -- sprite down counter
- if hcnt(0) = '1' then -- every is 16 bits (2 char)
- if hcnt = "101111" then
- spcnt <= "11111"; -- start with sprite #31
- else
- spcnt <= spcnt - '1'; -- downto sprite #8
- end if;
- end if;
-
- end if;
- end if;
- end if;
-end process;
-
-cpu_ena <= not pxcnt(0);
-
--- inputs
-input_0 <= "111" & not start2 & not start1 & '1' & '1' & not coin1; -- ?/ ?/ ?/ 2S/ 1S/SVC/ C2/ C1
-input_1 <= "111" & not fire1 & not down1 & not up1 & not right1 & not left1; -- ?/1FL/1SR/1SL/1DW/1UP/1RI/1LE
-input_2 <= "111" & not fire2 & not down2 & not up2 & not right2 & not left2; -- ?/2FL/2SR/2SL/2DW/2UP/2RI/2LE
-
--- cpu input address decoding (mirror mostly from Mame)
-cpu_di <= cpu_rom_do when cpu_addr(15 downto 12) < X"6" else -- 0000-5FFF
-
-
- X"80" when cpu_addr(15 downto 0) = "0110000000000100" else -- 6004 Protection
-
- wram_do when cpu_addr(15 downto 12) = X"A" else -- A000-AFFF
-
- spram1_do when cpu_addr(15 downto 12) = X"B" and
- cpu_addr(10) = '0' else -- B000-B3FF
-
- spram2_do when cpu_addr(15 downto 12) = X"B" and
- cpu_addr(10) = '1' else -- B400-B7FF
-
- vcnt(7 downto 0) when cpu_addr(15 downto 12) = X"C" and
- cpu_addr( 9 downto 8) = "00" else -- C000-C0FF
-
- X"FF" when cpu_addr(15 downto 12) = X"C" and
- cpu_addr( 9 downto 8) = "01" else -- C100-C1FF
-
- dip_switch_2 when cpu_addr(15 downto 12) = X"C" and
- cpu_addr( 9 downto 8) = "10" else -- C200-C2FF
-
- input_0 when cpu_addr(15 downto 12) = X"C" and
- cpu_addr( 9 downto 8) = "11" and
- cpu_addr( 6 downto 5) = "00" else -- C300-C31F
-
- input_1 when cpu_addr(15 downto 12) = X"C" and
- cpu_addr( 9 downto 8) = "11" and
- cpu_addr( 6 downto 5) = "01" else -- C320-C32F
-
- input_2 when cpu_addr(15 downto 12) = X"C" and
- cpu_addr( 9 downto 8) = "11" and
- cpu_addr( 6 downto 5) = "10" else -- C340-C34F
-
- dip_switch_1 when cpu_addr(15 downto 12) = X"C" and
- cpu_addr( 9 downto 8) = "11" and
- cpu_addr( 6 downto 5) = "11" else -- C360-C36F
-
- X"FF";
-
--- working ram address multiplexer cpu/video scanner
-wram_addr <= cpu_addr(11 downto 0) when cpu_ena = '1' else
- '0' & pxcnt(1) & vcnt(7 downto 3) & hcnt(4 downto 0) when flip = '0' else
- '0' & pxcnt(1) & not vcnt(7 downto 3) & not hcnt(4 downto 0);
-
--- sprite data ram address multiplexer cpu/sprite scanner
-spram_addr <= cpu_addr(7 downto 0) when cpu_ena = '1' else "00" & spcnt & pxcnt(1);
-
--- write enable to working ram, sprite data ram and misc registers
-wram_we <= '1' when cpu_wr_n = '0' and cpu_ena = '1' and cpu_addr(15 downto 12) = X"A" else '0';
-spram1_we <= '1' when cpu_wr_n = '0' and cpu_ena = '1' and cpu_addr(15 downto 12) = X"B" and cpu_addr(10) = '0' else '0';
-spram2_we <= '1' when cpu_wr_n = '0' and cpu_ena = '1' and cpu_addr(15 downto 12) = X"B" and cpu_addr(10) = '1' else '0';
-C0xx_we <= '1' when cpu_wr_n = '0' and cpu_ena = '1' and cpu_addr(15 downto 8) = "11000000" else '0';--
-C3xx_we <= '1' when cpu_wr_n = '0' and cpu_ena = '1' and cpu_addr(15 downto 12) = X"C" and cpu_addr(9 downto 8) = "11" else '0';
-
-process (clock_6)
-begin
- if rising_edge(clock_6) then
- if C0xx_we = '1' then
- sound_cmd <= cpu_do;
- end if;
-
- if C3xx_we = '1' then
- if cpu_addr(3 downto 1) = "000" then itt_n <= cpu_do; end if;
- if cpu_addr(3 downto 1) = "001" then flip <= not cpu_do(0); end if;
- if cpu_addr(3 downto 1) = "010" then sound_trig <= cpu_do(0); end if;
- end if;
- cpu_nmi_n <= vblank;
-cpu_int_n <= '1';
--- if itt_n(0) = '0' then
--- cpu_nmi_n <= '1';
--- else -- lauch nmi and end of frame
--- if (vcnt = 493) and (hcnt = "000000") and (pxcnt = "000") then
--- cpu_nmi_n <= '0';
--- else
--- cpu_nmi_n <= '1';
--- end if;
--- end if;
- end if;
-end process;
-
-
-----------------------
---- sprite machine ---
-----------------------
--- sprite data rams are scanned from sprites addresse 31 to 8 at each line
-
--- latch current sprite data with respect to pixel and hcnt in relation
--- with sprite data ram addressing
-process (clock_6)
-begin
- if rising_edge(clock_6) then
-
- if (hcnt(0) = '0') and (pxcnt = "001") then
- sp_posh <= spram1_do ; -- a.k.a. X
- sp_attr <= spram2_do ; -- color and flip x/y
- vcnt_r <= vcnt;
- end if;
-
- -- sprite is on current line if sp_line is below 16
- -- and if sprite vertical position (a.k.a. Y) is below xF0
- if (hcnt(0) = '0') and (pxcnt = "011") then
- if sp_line(7 downto 4) = "0000" and spram2_do < X"F0" then
- sp_on_line <= '1';
- else
- sp_on_line <= '0';
- end if;
- end if;
-
- -- delay sp_color_set
- if (hcnt(0) = '0') and (pxcnt = "100") then
- sp_color_set <= sp_attr(5 downto 0);
- end if;
-
- end if;
-end process;
-
--- sp_line (valid only when pxcnt = "011")
-sp_line <= not(vcnt_r(7 downto 0)) - spram2_do;
-
--- address sprite graphics rom with sprite code and tile number and sprite line counter
--- with respect to sprite flip x/y controls
-with sp_attr(7 downto 6) select
- sp_graphx_addr <= spram1_do & sp_line(3) & hcnt(0) & pxcnt(2) & sp_line(2 downto 0) when "11",
- spram1_do & sp_line(3) & not hcnt(0) & not pxcnt(2) & sp_line(2 downto 0) when "10",
- spram1_do & not sp_line(3) & hcnt(0) & pxcnt(2) & not sp_line(2 downto 0) when "01",
- spram1_do & not sp_line(3) & not hcnt(0) & not pxcnt(2) & not sp_line(2 downto 0) when others;
-
--- latch and shift sprite graphics data with respect to flipx control
--- 8bits => 4x2bits = 4pixels / 4colors (3colors + transparent)
-process (clock_6)
-begin
- if rising_edge(clock_6) then
-
- if pxcnt(1 downto 0) = "00" then
- if sp_on_line = '1' then
- if sp_attr(6) = '1' then
- sp_pixels <= sp_graphx_do;
- else
- sp_pixels(3 downto 0) <= sp_graphx_do(0) & sp_graphx_do(1) & sp_graphx_do(2) & sp_graphx_do(3);
- sp_pixels(7 downto 4) <= sp_graphx_do(4) & sp_graphx_do(5) & sp_graphx_do(6) & sp_graphx_do(7);
- end if;
- else
- sp_pixels <= (others => '0');
- end if;
- else
- sp_pixels(3 downto 0) <= sp_pixels(2 downto 0) & '0';
- sp_pixels(7 downto 4) <= sp_pixels(6 downto 4) & '0';
- end if;
-
- end if;
-
-end process;
-
--- address sprite color palette 4 colors, 64 sets => 16 colors
-sp_palette_addr <= sp_color_set & sp_pixels(3) & sp_pixels(7);
-
--- write sprite to line buffer at posh position
-process (clock_6)
-begin
- if rising_edge(clock_6) then
- if hcnt(0) = '0' and pxcnt = "101" then
- sp_buffer_write_addr <= sp_posh;
- else
- sp_buffer_write_addr <= sp_buffer_write_addr + '1';
- end if;
- end if;
-end process;
-
--- write colors to buffer when not transparent
-sp_buffer_write_we <= '0' when sp_palette_do(3 downto 0) = "0000" else '1';
-
--- read sprite line buffer and erase after read
-process (clock_12)
-begin
- if rising_edge(clock_12) then
- if hcnt = "101111" and pxcnt = "111" then
- sp_buffer_read_addr <= "11111010"; -- tune horizontal position of sprites
- else
- if clock_6 = '0' then
- sp_buffer_read_addr <= sp_buffer_read_addr + '1';
- else
- if vcnt(0) = '0' then
- sp_read_out <= sp_buffer_ram1_do;
- else
- sp_read_out <= sp_buffer_ram2_do;
- end if;
- end if;
- end if;
- end if;
-end process;
-
--- toggle read/write sprite line buffer every other line
-
--- wait pxcnt = "101" to allow last sprite (#8) to be written to line buffer
-process (clock_6)
-begin
- if rising_edge(clock_6) then
- if pxcnt = "101" then sp_buffer_sel <= vcnt(0); end if;
- end if;
-end process;
-
-sp_buffer_ram1_addr <= sp_buffer_read_addr when sp_buffer_sel = '0' else sp_buffer_write_addr;
-sp_buffer_ram2_addr <= sp_buffer_read_addr when sp_buffer_sel = '1' else sp_buffer_write_addr;
-
-sp_buffer_ram1_di <= "0000" when sp_buffer_sel = '0' else sp_palette_do(3 downto 0);
-sp_buffer_ram2_di <= "0000" when sp_buffer_sel = '1' else sp_palette_do(3 downto 0);
-
-sp_buffer_ram1_we <= not clock_6 when sp_buffer_sel = '0' else sp_buffer_write_we;
-sp_buffer_ram2_we <= not clock_6 when sp_buffer_sel = '1' else sp_buffer_write_we;
-
---------------------
---- char machine ---
---------------------
-
--- latch current char data with respect to vcnt and hcnt in relation
--- with wram ram addressing
-process (clock_6)
-begin
- if rising_edge(clock_6) and pxcnt = "001" then
- ch_data1 <= wram_do ;
- end if;
-
- if rising_edge(clock_6) and pxcnt = "100" then
- ch_color_set <= ch_data1(4 downto 0) ;
- end if;
-
-end process;
-
--- address char graphics rom with char code, pixel count and vertical line counter
--- with respect to char flip x/y controls
-with ch_data1(7 downto 6) select
- ch_graphx_addr_f <= ch_data1(5) & wram_do & pxcnt(2) & vcnt(2 downto 0) when "00",
- ch_data1(5) & wram_do & not pxcnt(2) & vcnt(2 downto 0) when "01",
- ch_data1(5) & wram_do & pxcnt(2) & not(vcnt(2 downto 0)) when "10",
- ch_data1(5) & wram_do & not pxcnt(2) & not(vcnt(2 downto 0)) when others;
-
--- in cocktail flip mode negate h/v counters
-ch_graphx_addr <= ch_graphx_addr_f when flip ='0' else ch_graphx_addr_f xor "0000000001111";
-
--- latch and shift char graphics data with respect to flipx control and cocktail flip control
--- 8bits => 4x2bits = 4pixels / 4colors
-process (clock_6)
-begin
- if rising_edge(clock_6) then
- if pxcnt(1 downto 0) = "00" then
- if (ch_data1(6) xor flip) = '0' then
- ch_pixels <= ch_graphx_do;
- else
- ch_pixels(3 downto 0) <= ch_graphx_do(0) & ch_graphx_do(1) &ch_graphx_do(2) &ch_graphx_do(3);
- ch_pixels(7 downto 4) <= ch_graphx_do(4) & ch_graphx_do(5) &ch_graphx_do(6) &ch_graphx_do(7);
- end if;
- else
- ch_pixels(3 downto 0) <= ch_pixels(2 downto 0) & '0';
- ch_pixels(7 downto 4) <= ch_pixels(6 downto 4) & '0';
- end if;
- end if;
-
-end process;
-
--- address char color palette 4 colors, 64 sets => 16 colors
-ch_palette_addr <= '0' & ch_color_set & ch_pixels(3) & ch_pixels(7);
-
----------------------
--- mux char/sprite --
----------------------
-
--- char data controls sprite display/hide
-process (clock_6)
-begin
- if rising_edge(clock_6) then
- sp_blank <= ch_color_set(4);
- end if;
-end process;
-
--- select rbg color and bank with respect to char/sprite selection
-rgb_palette_addr <=
- '1' & ch_palette_do(3 downto 0) when (sp_read_out = "0000" or sp_blank = '1') else
- '0' & sp_read_out;
-
--- register and assign rbg palette output
-process (clock_6)
-begin
- if rising_edge(clock_6) then
- if hblank = '1' or vblank = '1' then
- video_r <= "00000";
- video_g <= "00000";
- video_b <= "00000";
- else
- video_r <= rgb_palette_gr_do(5 downto 1);
- video_g <= rgb_palette_bg_do(2 downto 0) & rgb_palette_gr_do(7 downto 6);
- video_b <= rgb_palette_bg_do(7 downto 3);
- end if;
- end if;
-end process;
-
-video_hblank <= hblank;
-video_vblank <= vblank;
-
-----------------------------
--- video syncs and blanks --
-----------------------------
-
-process(clock_6)
- constant hcnt_base : integer := 36;
- variable vsync_cnt : std_logic_vector(3 downto 0);
-begin
- if rising_edge(clock_6) and pxcnt = "110" then
-
- if hcnt = hcnt_base+0 then hsync0 <= '0';
- elsif hcnt = hcnt_base+3 then hsync0 <= '1';
- end if;
-
- if hcnt = hcnt_base then
- if vcnt = 500 then
- vsync_cnt := X"0";
- else
- if vsync_cnt < X"F" then vsync_cnt := vsync_cnt + '1'; end if;
- end if;
- end if;
-
- if hcnt = hcnt_base-4 then
- hblank <= '1';
- if vcnt = 495 then
- vblank <= '1'; -- 492 ok
- elsif vcnt = 262 then
- vblank <= '0'; -- 262 ok
- end if;
- elsif hcnt = 0 then
- hblank <= '0';
- end if;
-
- video_hs <= hsync0;
-
- if vsync_cnt = 0 then video_vs <= '0';
- elsif vsync_cnt = 8 then video_vs <= '1';
- end if;
-
- end if;
-end process;
-
-------------------------------
--- components & sound board --
-------------------------------
-
--- microprocessor Z80
-cpu : entity work.T80se
-generic map(Mode => 0, T2Write => 1, IOWait => 1)
-port map(
- RESET_n => reset_n,
- CLK_n => clock_6,
- CLKEN => cpu_ena,
- WAIT_n => '1',
- INT_n => cpu_int_n,
- NMI_n => cpu_nmi_n,
- BUSRQ_n => '1',
- M1_n => open,
- MREQ_n => cpu_mreq_n,
- IORQ_n => open,
- RD_n => open,
- WR_n => cpu_wr_n,
- RFSH_n => open,
- HALT_n => open,
- BUSAK_n => open,
- A => cpu_addr,
- DI => cpu_di,
- DO => cpu_do
-);
-
-roms_addr <= cpu_addr(14 downto 0);
-cpu_rom_do <= roms_do;
-roms_rd <= '1';
-
-
--- cpu1 program ROM
---rom_cpu1 : entity work.power_surge_prog
---port map(
--- clk => clock_6n,
--- addr => cpu_addr(14 downto 0),
--- data => cpu_rom_do
---);
-
-
--- working/char RAM 0xA000-0xAFFF
-wram : entity work.gen_ram
-generic map( dWidth => 8, aWidth => 12)
-port map(
- clk => clock_6n,
- we => wram_we,
- addr => wram_addr,
- d => cpu_do,
- q => wram_do
-);
-
--- sprite RAM1 0xB000-0xB0FF
-spram1 : entity work.gen_ram
-generic map( dWidth => 8, aWidth => 8)
-port map(
- clk => clock_6n,
- we => spram1_we,
- addr => spram_addr,
- d => cpu_do,
- q => spram1_do
-);
-
--- sprite RAM2 0xB400-0xB4FF
-spram2 : entity work.gen_ram
-generic map( dWidth => 8, aWidth => 8)
-port map(
- clk => clock_6n,
- we => spram2_we,
- addr => spram_addr,
- d => cpu_do,
- q => spram2_do
-);
-
--- sprite line buffer 1
-splinebuf1 : entity work.gen_ram
-generic map( dWidth => 4, aWidth => 8)
-port map(
- clk => clock_12n,
- we => sp_buffer_ram1_we,
- addr => sp_buffer_ram1_addr,
- d => sp_buffer_ram1_di,
- q => sp_buffer_ram1_do
-);
-
--- sprite line buffer 2
-splinebuf2 : entity work.gen_ram
-generic map( dWidth => 4, aWidth => 8)
-port map(
- clk => clock_12n,
- we => sp_buffer_ram2_we,
- addr => sp_buffer_ram2_addr,
- d => sp_buffer_ram2_di,
- q => sp_buffer_ram2_do
-);
-
--- char graphics ROM
-char_graphics : entity work.power_surge_char_grphx
-port map(
- clk => clock_6,
- addr => ch_graphx_addr,
- data => ch_graphx_do
-);
-
--- char palette ROM
-ch_palette : entity work.power_surge_char_color_lut
-port map(
- clk => clock_6,
- addr => ch_palette_addr,
- data => ch_palette_do
-);
-
--- sprite graphics ROM
-sp_graphics : entity work.power_surge_sprite_grphx
-port map(
- clk => clock_6,
- addr => sp_graphx_addr,
- data => sp_graphx_do
-);
-
--- sprite palette ROM
-sp_palette : entity work.power_surge_sprite_color_lut
-port map(
- clk => clock_6,
- addr => sp_palette_addr,
- data => sp_palette_do
-);
-
--- rgb palette ROM 1
-rgb_palette_gb : entity work.power_surge_palette_blue_green
-port map(
- clk => clock_6,
- addr => rgb_palette_addr,
- data => rgb_palette_bg_do
-);
-
--- rgb palette ROM 2
-rgb_palette_br : entity work.power_surge_palette_green_red
-port map(
- clk => clock_6,
- addr => rgb_palette_addr,
- data => rgb_palette_gr_do
-);
-
--- sound board
-time_pilot_sound_board : entity work.time_pilot_sound_board
-port map(
-clock_14 => clock_14,
-reset => reset,
-
-sound_trig => sound_trig,
-sound_cmd => sound_cmd,
-
-audio_out => audio_out
-);
-
-end struct;
\ No newline at end of file
diff --git a/Arcade_MiST/Namco Super Pacman Hardware/rtl/TheTowerofDruaga_mist.sv b/Arcade_MiST/Namco Super Pacman Hardware/rtl/TheTowerofDruaga_mist.sv
index 3bef470e..f515b416 100644
--- a/Arcade_MiST/Namco Super Pacman Hardware/rtl/TheTowerofDruaga_mist.sv
+++ b/Arcade_MiST/Namco Super Pacman Hardware/rtl/TheTowerofDruaga_mist.sv
@@ -34,7 +34,7 @@ module TheTowerofDruaga_mist (
wire [6:0] core_mod;
localparam CONF_STR = {
- `CORE_NAME, ";ROM;",
+ `CORE_NAME, ";;",
"O2,Rotate Controls,Off,On;",
"O34,Scanlines,Off,25%,50%,75%;",
"O5,Blend,Off,On;",
@@ -49,31 +49,6 @@ wire [1:0] scanlines = status[4:3];
wire blend = status[5];
wire flip = status[7];
-wire dcFreeze = status[29];
-wire dcService = status[30];
-wire dcCabinet = 1'b0; // (upright only)
-
-// The Tower of Druaga [t]
-wire [1:0] dtLives = status[9:8];
-
-// Mappy [m]
-wire dmRoundP = status[6];
-wire [2:0] dmRank = status[12:10];
-wire dmDemoSnd = status[13];
-wire [2:0] dmExtend = status[16:14];
-wire [1:0] dmLives = status[18:17];
-
-// DigDug2 [d]
-wire ddLives = status[19];
-wire [1:0] ddExtend = status[21:20];
-wire ddLevelSel = status[22];
-
-// Motos [o]
-wire doLives = status[23];
-wire doRank = status[24];
-wire [1:0] doExtend = status[26:25];
-wire doDemoSnd = status[27];
-
reg [7:0] DSW0;
reg [7:0] DSW1;
reg [7:0] DSW2;
diff --git a/Arcade_MiST/Williams 6809 rev.1 Hardware/Defender Hardware/rtl/Defender_MiST.sv b/Arcade_MiST/Williams 6809 rev.1 Hardware/Defender Hardware/rtl/Defender_MiST.sv
index f76e7444..a41a9fff 100644
--- a/Arcade_MiST/Williams 6809 rev.1 Hardware/Defender Hardware/rtl/Defender_MiST.sv
+++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Defender Hardware/rtl/Defender_MiST.sv
@@ -205,7 +205,7 @@ ROM Structure:
7400-7BFF snd cpu 2k
*/
data_io data_io (
- .clk_sys ( clk_sys ),
+ .clk_sys ( clk_mem ),
.SPI_SCK ( SPI_SCK ),
.SPI_SS2 ( SPI_SS2 ),
.SPI_DI ( SPI_DI ),
@@ -228,7 +228,7 @@ wire [11:0] snd_rom_addr;
wire snd_vma;
wire [15:0] snd_do;
-sdram #(.MHZ(54)) sdram(
+sdram #(.MHZ(72)) sdram(
.*,
.init_n ( pll_locked ),
.clk ( clk_mem ),
@@ -258,9 +258,8 @@ sdram #(.MHZ(54)) sdram(
.snd_q ( snd_do )
);
-always @(posedge clk_sys) begin
+always @(posedge clk_mem) begin
reg ioctl_wr_last = 0;
- reg snd_vma_r, snd_vma_r2;
ioctl_wr_last <= ioctl_wr;
if (ioctl_downl && ioctl_index == 0) begin
@@ -269,6 +268,11 @@ always @(posedge clk_sys) begin
port2_req <= ~port2_req;
end
end
+end
+
+always @(posedge clk_sys) begin
+ reg snd_vma_r, snd_vma_r2;
+
snd_vma_r <= snd_vma; snd_vma_r2 <= snd_vma_r;
if (snd_vma_r2) snd_addr <= snd_rom_addr;
end
@@ -314,7 +318,7 @@ defender defender (
.snd_do ( snd_addr[0] ? snd_do[15:8] : snd_do[7:0] ),
.snd_vma ( snd_vma ),
- .dl_clock ( clk_sys ),
+ .dl_clock ( clk_mem ),
.dl_addr ( ioctl_addr[15:0] ),
.dl_data ( ioctl_dout ),
.dl_wr ( ioctl_wr && ioctl_index == 0 ),
diff --git a/Console_MiST/GCE - Vectrex_MiST/rtl/YM2149.sv b/Console_MiST/GCE - Vectrex_MiST/rtl/YM2149.sv
deleted file mode 100644
index e4cf9525..00000000
--- a/Console_MiST/GCE - Vectrex_MiST/rtl/YM2149.sv
+++ /dev/null
@@ -1,326 +0,0 @@
-//
-// Copyright (c) MikeJ - Jan 2005
-// Copyright (c) 2016-2018 Sorgelig
-//
-// All rights reserved
-//
-// Redistribution and use in source and synthezised forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-// Redistributions of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.
-//
-// Redistributions in synthesized form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-//
-// Neither the name of the author nor the names of other contributors may
-// be used to endorse or promote products derived from this software without
-// specific prior written permission.
-//
-// THIS CODE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
-// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-// POSSIBILITY OF SUCH DAMAGE.
-//
-
-
-// BDIR BC MODE
-// 0 0 inactive
-// 0 1 read value
-// 1 0 write value
-// 1 1 set address
-//
-
-module YM2149
-(
- input CLK, // Global clock
- input CE, // PSG Clock enable
- input RESET, // Chip RESET (set all Registers to '0', active hi)
- input BDIR, // Bus Direction (0 - read , 1 - write)
- input BC, // Bus control
- input [7:0] DI, // Data In
- output [7:0] DO, // Data Out
- output [7:0] CHANNEL_A, // PSG Output channel A
- output [7:0] CHANNEL_B, // PSG Output channel B
- output [7:0] CHANNEL_C, // PSG Output channel C
-
- input SEL,
- input MODE,
-
- output [5:0] ACTIVE,
-
- input [7:0] IOA_in,
- output [7:0] IOA_out,
-
- input [7:0] IOB_in,
- output [7:0] IOB_out
-);
-
-assign ACTIVE = ~ymreg[7][5:0];
-assign IOA_out = ymreg[7][6] ? ymreg[14] : 8'hff;
-assign IOB_out = ymreg[7][7] ? ymreg[15] : 8'hff;
-
-reg [7:0] addr;
-reg [7:0] ymreg[16];
-
-// Write to PSG
-reg env_reset;
-always @(posedge CLK) begin
- if(RESET) begin
- ymreg <= '{default:0};
- ymreg[7] <= '1;
- addr <= '0;
- env_reset <= 0;
- end else begin
- env_reset <= 0;
- if(BDIR) begin
- if(BC) addr <= DI;
- else if(!addr[7:4]) begin
- ymreg[addr[3:0]] <= DI;
- env_reset <= (addr == 13);
- end
- end
- end
-end
-
-// Read from PSG
-assign DO = dout;
-reg [7:0] dout;
-always_comb begin
- dout = 8'hFF;
- if(~BDIR & BC & !addr[7:4]) begin
- case(addr[3:0])
- 0: dout = ymreg[0];
- 1: dout = ymreg[1][3:0];
- 2: dout = ymreg[2];
- 3: dout = ymreg[3][3:0];
- 4: dout = ymreg[4];
- 5: dout = ymreg[5][3:0];
- 6: dout = ymreg[6][4:0];
- 7: dout = ymreg[7];
- 8: dout = ymreg[8][4:0];
- 9: dout = ymreg[9][4:0];
- 10: dout = ymreg[10][4:0];
- 11: dout = ymreg[11];
- 12: dout = ymreg[12];
- 13: dout = ymreg[13][3:0];
- 14: dout = ymreg[7][6] ? ymreg[14] : IOA_in;
- 15: dout = ymreg[7][7] ? ymreg[15] : IOB_in;
- endcase
- end
-end
-
-reg ena_div;
-reg ena_div_noise;
-
-// p_divider
-always @(posedge CLK) begin
- reg [3:0] cnt_div;
- reg noise_div;
-
- if(CE) begin
- ena_div <= 0;
- ena_div_noise <= 0;
- if(!cnt_div) begin
- cnt_div <= {SEL, 3'b111};
- ena_div <= 1;
-
- noise_div <= (~noise_div);
- if (noise_div) ena_div_noise <= 1;
- end else begin
- cnt_div <= cnt_div - 1'b1;
- end
- end
-end
-
-
-reg [2:0] noise_gen_op;
-
-// p_noise_gen
-always @(posedge CLK) begin
- reg [16:0] poly17;
- reg [4:0] noise_gen_cnt;
-
- if(CE) begin
- if (ena_div_noise) begin
- if (!ymreg[6][4:0] || noise_gen_cnt >= ymreg[6][4:0] - 1'd1) begin
- noise_gen_cnt <= 0;
- poly17 <= {(poly17[0] ^ poly17[2] ^ !poly17), poly17[16:1]};
- end else begin
- noise_gen_cnt <= noise_gen_cnt + 1'd1;
- end
- noise_gen_op <= {3{poly17[0]}};
- end
- end
-end
-
-wire [11:0] tone_gen_freq[1:3];
-assign tone_gen_freq[1] = {ymreg[1][3:0], ymreg[0]};
-assign tone_gen_freq[2] = {ymreg[3][3:0], ymreg[2]};
-assign tone_gen_freq[3] = {ymreg[5][3:0], ymreg[4]};
-
-reg [3:1] tone_gen_op;
-
-//p_tone_gens
-always @(posedge CLK) begin
- integer i;
- reg [11:0] tone_gen_cnt[1:3];
-
- if(CE) begin
- // looks like real chips count up - we need to get the Exact behaviour ..
-
- for (i = 1; i <= 3; i = i + 1) begin
- if(ena_div) begin
- if (tone_gen_freq[i]) begin
- if (tone_gen_cnt[i] >= (tone_gen_freq[i] - 1'd1)) begin
- tone_gen_cnt[i] <= 0;
- tone_gen_op[i] <= ~tone_gen_op[i];
- end else begin
- tone_gen_cnt[i] <= tone_gen_cnt[i] + 1'd1;
- end
- end else begin
- tone_gen_op[i] <= ymreg[7][i];
- tone_gen_cnt[i] <= 0;
- end
- end
- end
- end
-end
-
-reg env_ena;
-wire [15:0] env_gen_comp = {ymreg[12], ymreg[11]} ? {ymreg[12], ymreg[11]} - 1'd1 : 16'd0;
-
-//p_envelope_freq
-always @(posedge CLK) begin
- reg [15:0] env_gen_cnt;
-
- if(CE) begin
- env_ena <= 0;
- if(ena_div) begin
- if (env_gen_cnt >= env_gen_comp) begin
- env_gen_cnt <= 0;
- env_ena <= 1;
- end else begin
- env_gen_cnt <= (env_gen_cnt + 1'd1);
- end
- end
- end
-end
-
-reg [4:0] env_vol;
-
-wire is_bot = (env_vol == 5'b00000);
-wire is_bot_p1 = (env_vol == 5'b00001);
-wire is_top_m1 = (env_vol == 5'b11110);
-wire is_top = (env_vol == 5'b11111);
-
-always @(posedge CLK) begin
- reg env_hold;
- reg env_inc;
-
- // envelope shapes
- // C AtAlH
- // 0 0 x x \___
- //
- // 0 1 x x /___
- //
- // 1 0 0 0 \\\\
- //
- // 1 0 0 1 \___
- //
- // 1 0 1 0 \/\/
- // ___
- // 1 0 1 1 \
- //
- // 1 1 0 0 ////
- // ___
- // 1 1 0 1 /
- //
- // 1 1 1 0 /\/\
- //
- // 1 1 1 1 /___
-
- if(env_reset | RESET) begin
- // load initial state
- if(!ymreg[13][2]) begin // attack
- env_vol <= 5'b11111;
- env_inc <= 0; // -1
- end else begin
- env_vol <= 5'b00000;
- env_inc <= 1; // +1
- end
- env_hold <= 0;
- end
- else if(CE) begin
- if (env_ena) begin
- if (!env_hold) begin
- if (env_inc) env_vol <= (env_vol + 5'b00001);
- else env_vol <= (env_vol + 5'b11111);
- end
-
- // envelope shape control.
- if(!ymreg[13][3]) begin
- if(!env_inc) begin // down
- if(is_bot_p1) env_hold <= 1;
- end else if (is_top) env_hold <= 1;
- end else if(ymreg[13][0]) begin // hold = 1
- if(!env_inc) begin // down
- if(ymreg[13][1]) begin // alt
- if(is_bot) env_hold <= 1;
- end else if(is_bot_p1) env_hold <= 1;
- end else if(ymreg[13][1]) begin // alt
- if(is_top) env_hold <= 1;
- end else if(is_top_m1) env_hold <= 1;
- end else if(ymreg[13][1]) begin // alternate
- if(env_inc == 1'b0) begin // down
- if(is_bot_p1) env_hold <= 1;
- if(is_bot) begin
- env_hold <= 0;
- env_inc <= 1;
- end
- end else begin
- if(is_top_m1) env_hold <= 1;
- if(is_top) begin
- env_hold <= 0;
- env_inc <= 0;
- end
- end
- end
- end
- end
-end
-
-reg [5:0] A,B,C;
-always @(posedge CLK) begin
- A <= {MODE, ~((ymreg[7][0] | tone_gen_op[1]) & (ymreg[7][3] | noise_gen_op[0])) ? 5'd0 : ymreg[8][4] ? env_vol[4:0] : { ymreg[8][3:0], ymreg[8][3]}};
- B <= {MODE, ~((ymreg[7][1] | tone_gen_op[2]) & (ymreg[7][4] | noise_gen_op[1])) ? 5'd0 : ymreg[9][4] ? env_vol[4:0] : { ymreg[9][3:0], ymreg[9][3]}};
- C <= {MODE, ~((ymreg[7][2] | tone_gen_op[3]) & (ymreg[7][5] | noise_gen_op[2])) ? 5'd0 : ymreg[10][4] ? env_vol[4:0] : {ymreg[10][3:0], ymreg[10][3]}};
-end
-
-wire [7:0] volTable[64] = '{
- //YM2149
- 8'h00, 8'h01, 8'h01, 8'h02, 8'h02, 8'h03, 8'h03, 8'h04,
- 8'h06, 8'h07, 8'h09, 8'h0a, 8'h0c, 8'h0e, 8'h11, 8'h13,
- 8'h17, 8'h1b, 8'h20, 8'h25, 8'h2c, 8'h35, 8'h3e, 8'h47,
- 8'h54, 8'h66, 8'h77, 8'h88, 8'ha1, 8'hc0, 8'he0, 8'hff,
-
- //AY8910
- 8'h00, 8'h00, 8'h03, 8'h03, 8'h04, 8'h04, 8'h06, 8'h06,
- 8'h0a, 8'h0a, 8'h0f, 8'h0f, 8'h15, 8'h15, 8'h22, 8'h22,
- 8'h28, 8'h28, 8'h41, 8'h41, 8'h5b, 8'h5b, 8'h72, 8'h72,
- 8'h90, 8'h90, 8'hb5, 8'hb5, 8'hd7, 8'hd7, 8'hff, 8'hff
-};
-
-assign CHANNEL_A = volTable[A];
-assign CHANNEL_B = volTable[B];
-assign CHANNEL_C = volTable[C];
-
-endmodule
diff --git a/Console_MiST/GCE - Vectrex_MiST/rtl/cpu09l_128a.vhd b/Console_MiST/GCE - Vectrex_MiST/rtl/cpu09l_128a.vhd
deleted file mode 100644
index 6a07aacb..00000000
--- a/Console_MiST/GCE - Vectrex_MiST/rtl/cpu09l_128a.vhd
+++ /dev/null
@@ -1,5978 +0,0 @@
---===========================================================================--
--- --
--- Synthesizable 6809 instruction compatible VHDL CPU core --
--- --
---===========================================================================--
---
--- File name : cpu09l.vhd
---
--- Entity name : cpu09
---
--- Purpose : 6809 instruction compatible CPU core written in VHDL
--- with Last Instruction Cycle, bus available, bus status,
--- and instruction fetch signals.
--- Not cycle compatible with the original 6809 CPU
---
--- Dependencies : ieee.std_logic_1164
--- ieee.std_logic_unsigned
---
--- Author : John E. Kent
---
--- Email : dilbert57@opencores.org
---
--- Web : http://opencores.org/project,system09
---
--- Description : VMA (valid memory address) is hight whenever a valid memory
--- access is made by an instruction fetch, interrupt vector fetch
--- or a data read or write otherwise it is low indicating an idle
--- bus cycle.
--- IFETCH (instruction fetch output) is high whenever an
--- instruction byte is read i.e. the program counter is applied
--- to the address bus.
--- LIC (last instruction cycle output) is normally low
--- but goes high on the last cycle of an instruction.
--- BA (bus available output) is normally low but goes high while
--- waiting in a Sync instruction state or the CPU is halted
--- i.e. a DMA grant.
--- BS (bus status output) is normally low but goes high during an
--- interrupt or reset vector fetch or the processor is halted
--- i.e. a DMA grant.
---
--- Copyright (C) 2003 - 2010 John Kent
---
--- This program is free software: you can redistribute it and/or modify
--- it under the terms of the GNU General Public License as published by
--- the Free Software Foundation, either version 3 of the License, or
--- (at your option) any later version.
---
--- This program is distributed in the hope that it will be useful,
--- but WITHOUT ANY WARRANTY; without even the implied warranty of
--- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--- GNU General Public License for more details.
---
--- You should have received a copy of the GNU General Public License
--- along with this program. If not, see .
---
---===========================================================================--
--- --
--- Revision History --
--- --
---===========================================================================--
---
--- Version 0.1 - 26 June 2003 - John Kent
--- Added extra level in state stack
--- fixed some calls to the extended addressing state
---
--- Version 0.2 - 5 Sept 2003 - John Kent
--- Fixed 16 bit indexed offset (was doing read rather than fetch)
--- Added/Fixed STY and STS instructions.
--- ORCC_STATE ANDed CC state rather than ORed it - Now fixed
--- CMPX Loaded ACCA and ACCB - Now fixed
---
--- Version 1.0 - 6 Sep 2003 - John Kent
--- Initial release to Open Cores
--- reversed clock edge
---
--- Version 1.1 - 29 November 2003 John kent
--- ACCA and ACCB indexed offsets are 2's complement.
--- ALU Right Mux now sign extends ACCA & ACCB offsets
--- Absolute Indirect addressing performed a read on the
--- second byte of the address rather than a fetch
--- so it formed an incorrect address. Now fixed.
---
--- Version 1.2 - 29 November 2003 John Kent
--- LEAX and LEAY affect the Z bit only
--- LEAS and LEAU do not affect any condition codes
--- added an extra ALU control for LEA.
---
--- Version 1.3 - 12 December 2003 John Kent
--- CWAI did not work, was missed a PUSH_ST on calling
--- the ANDCC_STATE. Thanks go to Ghassan Kraidy for
--- finding this fault.
---
--- Version 1.4 - 12 December 2003 John Kent
--- Missing cc_ctrl assignment in otherwise case of
--- lea_state resulted in cc_ctrl being latched in
--- that state.
--- The otherwise statement should never be reached,
--- and has been fixed simply to resolve synthesis warnings.
---
--- Version 1.5 - 17 january 2004 John kent
--- The clear instruction used "alu_ld8" to control the ALU
--- rather than "alu_clr". This mean the Carry was not being
--- cleared correctly.
---
--- Version 1.6 - 24 January 2004 John Kent
--- Fixed problems in PSHU instruction
---
--- Version 1.7 - 25 January 2004 John Kent
--- removed redundant "alu_inx" and "alu_dex'
--- Removed "test_alu" and "test_cc"
--- STD instruction did not set condition codes
--- JMP direct was not decoded properly
--- CLR direct performed an unwanted read cycle
--- Bogus "latch_md" in Page2 indexed addressing
---
--- Version 1.8 - 27 January 2004 John Kent
--- CWAI in decode1_state should increment the PC.
--- ABX is supposed to be an unsigned addition.
--- Added extra ALU function
--- ASR8 slightly changed in the ALU.
---
--- Version 1.9 - 20 August 2005
--- LSR8 is now handled in ASR8 and ROR8 case in the ALU,
--- rather than LSR16. There was a problem with single
--- operand instructions using the MD register which is
--- sign extended on the first 8 bit fetch.
---
--- Version 1.10 - 13 September 2005
--- TFR & EXG instructions did not work for the Condition Code Register
--- An extra case has been added to the ALU for the alu_tfr control
--- to assign the left ALU input (alu_left) to the condition code
--- outputs (cc_out).
---
--- Version 1.11 - 16 September 2005
--- JSR ,X should not predecrement S before calculating the jump address.
--- The reason is that JSR [0,S] needs S to point to the top of the stack
--- to fetch a valid vector address. The solution is to have the addressing
--- mode microcode called before decrementing S and then decrementing S in
--- JSR_STATE. JSR_STATE in turn calls PUSH_RETURN_LO_STATE rather than
--- PUSH_RETURN_HI_STATE so that both the High & Low halves of the PC are
--- pushed on the stack. This adds one extra bus cycle, but resolves the
--- addressing conflict. I've also removed the pre-decement S in
--- JSR EXTENDED as it also calls JSR_STATE.
---
--- Version 1.12 - 6th June 2006
--- 6809 Programming reference manual says V is not affected by ASR, LSR and ROR
--- This is different to the 6800. CLR should reset the V bit.
---
--- Version 1.13 - 7th July 2006
--- Disable NMI on reset until S Stack pointer has been loaded.
--- Added nmi_enable signal in sp_reg process and nmi_handler process.
---
--- Version 1.14 - 11th July 2006
--- 1. Added new state to RTI called rti_entire_state.
--- This state tests the CC register after it has been loaded
--- from the stack. Previously the current CC was tested which
--- was incorrect. The Entire Flag should be set before the
--- interrupt stacks the CC.
--- 2. On bogus Interrupts, int_cc_state went to rti_state,
--- which was an enumerated state, but not defined anywhere.
--- rti_state has been changed to rti_cc_state so that bogus interrupt
--- will perform an RTI after entering that state.
--- 3. Sync should generate an interrupt if the interrupt masks
--- are cleared. If the interrupt masks are set, then an interrupt
--- will cause the the PC to advance to the next instruction.
--- Note that I don't wait for an interrupt to be asserted for
--- three clock cycles.
--- 4. Added new ALU control state "alu_mul". "alu_mul" is used in
--- the Multiply instruction replacing "alu_add16". This is similar
--- to "alu_add16" except it sets the Carry bit to B7 of the result
--- in ACCB, sets the Zero bit if the 16 bit result is zero, but
--- does not affect The Half carry (H), Negative (N) or Overflow (V)
--- flags. The logic was re-arranged so that it adds md or zero so
--- that the Carry condition code is set on zero multiplicands.
--- 5. DAA (Decimal Adjust Accumulator) should set the Negative (N)
--- and Zero Flags. It will also affect the Overflow (V) flag although
--- the operation is undefined. It's anyones guess what DAA does to V.
---
--- Version 1.15 - 25th Feb 2007 - John Kent
--- line 9672 changed "if Halt <= '1' then" to "if Halt = '1' then"
--- Changed sensitivity lists.
---
--- Version 1.16 - 5th February 2008 - John Kent
--- FIRQ interrupts should take priority over IRQ Interrupts.
--- This presumably means they should be tested for before IRQ
--- when they happen concurrently.
---
--- Version 1.17 - 18th February 2008 - John Kent
--- NMI in CWAI should mask IRQ and FIRQ interrupts
---
--- Version 1.18 - 21st February 2008 - John Kent
--- Removed default register settings in each case statement
--- and placed them at the beginning of the state sequencer.
--- Modified the SYNC instruction so that the interrupt vector(iv)
--- is not set unless an unmasked FIRQ or IRQ is received.
---
--- Version 1.19 - 25th February 2008 - John Kent
--- Enumerated separate states for FIRQ/FAST and NMIIRQ/ENTIRE
--- Enumerated separate states for MASKI and MASKIF states
--- Removed code on BSR/JSR in fetch cycle
---
--- Version 1.20 - 8th October 2011 - John Kent
--- added fetch output which should go high during the fetch cycle
---
--- Version 1.21 - 8th October 2011 - John Kent
--- added Last Instruction Cycle signal
--- replaced fetch with ifetch (instruction fetch) signal
--- added ba & bs (bus available & bus status) signals
---
--- Version 1.22 - 2011-10-29 John Kent
--- The halt state isn't correct.
--- The halt state is entered into from the fetch_state
--- It returned to the fetch state which may re-run an execute cycle
--- on the accumulator and it won't necessarily be the last instruction cycle
--- I've changed the halt state to return to the decode1_state
---
--- Version 1.23 - 2011-10-30 John Kent
--- sample halt in the change_state process if lic is high (last instruction cycle)
---
--- Version 1.24 - 2011-11-01 John Kent
--- Handle interrupts in change_state process
--- Sample interrupt inputs on last instruction cycle
--- Remove iv_ctrl and implement iv (interrupt vector) in change_state process.
--- Generate fic (first instruction cycle) from lic (last instruction cycle)
--- and use it to complete the dual operand execute cycle before servicing
--- halt or interrupts requests.
--- rename lic to lic_out on the entity declaration so that lic can be tested internally.
--- add int_firq1_state and int_nmirq1_state to allow for the dual operand execute cycle
--- integrated nmi_ctrl into change_state process
--- Reduces the microcode state stack to one entry (saved_state)
--- imm16_state jumps directly to the fetch_state
--- pull_return_lo states jumps directly to the fetch_state
--- duplicate andcc_state as cwai_state
--- rename exg1_state as exg2 state and duplicate tfr_state as exg1_state
---
--- Version 1.25 - 2011-11-27 John Kent
--- Changed the microcode for saving registers on an interrupt into a microcode subroutine.
--- Removed SWI servicing from the change state process and made SWI, SWI2 & SWI3
--- call the interrupt microcode subroutine.
--- Added additional states for nmi, and irq for interrupt servicing.
--- Added additional states for nmi/irq, firq, and swi interrupts to mask I & F flags.
---
--- Version 1.26 - 2013-03-18 John Kent
--- pre-initialized cond_true variable to true in state sequencer
--- re-arranged change_state process slightly
---
--- Version 1.27 - 2015-05-30 John Kent
--- Added test in state machine for masked IRQ and FIRQ in Sync_state.
---
--- Version 1.28 - 2015-05-30 John Kent.
--- Moved IRQ and FIRQ test from state machine to the state sequencer Sync_state.
---
--- Version 1.28a - Temporary tweaked release - 2018-02-08 DarFPGA
--- Add wait_cycles process to retrieve original cycle count for some (few) instructions.
--- Only those used by vectrex exec_rom (and spike rom) during drawing.
--- Beware that external hold (hold_in) is no more active.
---
---
-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)
- ce : in std_logic;
- 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
- );
-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;
-
-
- signal cnt_cycles : std_logic_vector(3 downto 0) := "0000" ;
- signal hold : std_logic;
-
-begin
-
-wait_cycles: process(clk)
-begin
- if clk'event and clk = '0' then
- if ce = '1' then
- if lic = '1' then
- case op_code is
- when X"A6" => hold <= '1'; cnt_cycles <= X"1"; -- additional cycles for vectrex tuning
- when X"97" => hold <= '1'; cnt_cycles <= X"1";
- when X"8C" => hold <= '1'; cnt_cycles <= X"1";
- when X"D7" => hold <= '1'; cnt_cycles <= X"1";
- when X"1F" => hold <= '1'; cnt_cycles <= X"3";
- when X"B3" => hold <= '1'; cnt_cycles <= X"2";
- when X"0A" => hold <= '1'; cnt_cycles <= X"2";
- when X"0C" => hold <= '1'; cnt_cycles <= X"2";
- when X"1E" => hold <= '1'; cnt_cycles <= X"3"; -- exg @117A/7C spike (allow time enough for timer to end before pc=11A4)
- when others=> null;
- end case;
- end if;
-
- if hold = '1' then
- if cnt_cycles = X"1" then
- hold <= '0';
- end if;
- cnt_cycles <= cnt_cycles - '1';
- end if;
- end if;
- end if;
-end process;
-
-----------------------------------
---
--- 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 ce = '1' 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 if;
-end process;
-
-----------------------------------
---
--- Interrupt Vector control
---
-----------------------------------
---
-int_vec_proc: process( clk, iv_ctrl )
-begin
- if clk'event and clk = '0' then
- if ce = '1' 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;
- 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 ce = '1' 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 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 ce = '1' 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 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 ce = '1' 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 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 ce = '1' 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 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 ce = '1' 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 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 ce = '1' 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 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 ce = '1' 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 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 ce = '1' 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 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 ce = '1' 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 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 ce = '1' 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 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 ce = '1' 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 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 ce = '1' 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 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 ce = '1' 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 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 ce = '1' and 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 ce = '1' 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 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/Console_MiST/GCE - Vectrex_MiST/rtl/mc6809is.v b/Console_MiST/GCE - Vectrex_MiST/rtl/mc6809is.v
deleted file mode 100644
index ebdc88be..00000000
--- a/Console_MiST/GCE - Vectrex_MiST/rtl/mc6809is.v
+++ /dev/null
@@ -1,4154 +0,0 @@
-`timescale 1ns / 1ns
-//////////////////////////////////////////////////////////////////////////////////
-// Company:
-// Engineer: Greg Miller
-// Copyright (c) 2016, Greg Miller
-//
-// Create Date: 14:26:59 08/13/2016
-// Design Name:
-// Module Name: mc6809
-// Project Name: Cycle-Accurate 6809 Core
-// Target Devices:
-// Tool versions:
-// Description:
-//
-// Dependencies: Intended to be standalone Vanilla Verilog.
-//
-// Revision:
-// Revision 1.0 - Initial Release
-// Revision 1.0s - Sinchronous version (by Sorgelig)
-// Additional Comments:
-//
-//////////////////////////////////////////////////////////////////////////////////
-
-
-//
-// The 6809 has incomplete instruction decoding. A collection of instructions, if met, end up actually behaving like
-// a binary-adjacent neighbor.
-//
-// The soft core permits three different behaviors for this situation, controlled by the instantiation parameter
-// ILLEGAL_INSTRUCTIONS
-//
-// "GHOST" - Mimic the 6809's incomplete decoding. This is as similar to a hard 6809 as is practical. [DEFAULT]
-//
-// "STOP" - Cause the soft core to cease execution, placing $DEAD on the address bus and R/W to 'read'. Interrupts,
-// bus control (/HALT, /DMABREQ), etc. are ignored. The core intentionally seizes in this instance.
-// (Frankly, this is useful when making changes to the core and you have a logic analyzer connected.)
-//
-// "IGNORE"- Cause the soft core to merely ignore illegal instructions. It will consider them 1-byte instructions and
-// attempt to fetch and run an exception 1 byte later.
-//
-
-module mc6809is
-#(
- parameter ILLEGAL_INSTRUCTIONS="GHOST"
-)
-(
- input CLK,
- input fallE_en,
- input fallQ_en,
-
- input [7:0] D,
- output [7:0] DOut,
- output [15:0] ADDR,
- output RnW,
- output BS,
- output BA,
- input nIRQ,
- input nFIRQ,
- input nNMI,
- output AVMA,
- output BUSY,
- output LIC,
- input nHALT,
- input nRESET,
- input nDMABREQ,
- output [111:0] RegData
-);
-
-reg [7:0] DOutput;
-
-assign DOut = DOutput;
-
-reg RnWOut; // Combinatorial
-
-reg rLIC;
-assign LIC = rLIC;
-
-reg rAVMA;
-assign AVMA = rAVMA;
-
-reg rBUSY;
-assign BUSY = rBUSY;
-
-// Bus control
-// BS BA
-// 0 0 normal (CPU running, CPU is master)
-// 0 1 Interrupt Ack
-// 1 0 Sync Ack
-// 1 1 CPU has gone high-Z on A, D, R/W
-//
-
-assign RnW = RnWOut;
-
-
-/////////////////////////////////////////////////
-// Vectors
-`define RESET_VECTOR 16'HFFFE
-`define NMI_VECTOR 16'HFFFC
-`define SWI_VECTOR 16'HFFFA
-`define IRQ_VECTOR 16'HFFF8
-`define FIRQ_VECTOR 16'HFFF6
-`define SWI2_VECTOR 16'HFFF4
-`define SWI3_VECTOR 16'HFFF2
-`define Reserved_VECTOR 16'HFFF0
-
-//////////////////////////////////////////////////////
-// Latched registers
-//
-
-// The last-latched copy.
-reg [7:0] a;
-reg [7:0] b;
-reg [15:0] x;
-reg [15:0] y;
-reg [15:0] u;
-reg [15:0] s;
-reg [15:0] pc;
-reg [7:0] dp;
-reg [7:0] cc;
-reg [15:0] tmp;
-reg [15:0] addr;
-reg [15:0] ea;
-
-
-// Debug ability to export register contents
-assign RegData[7:0] = a;
-assign RegData[15:8] = b;
-assign RegData[31:16] = x;
-assign RegData[47:32] = y;
-assign RegData[63:48] = s;
-assign RegData[79:64] = u;
-assign RegData[87:80] = cc;
-assign RegData[95:88] = dp;
-assign RegData[111:96] = pc;
-
-
-
-// The values as being calculated
-reg [7:0] a_nxt;
-reg [7:0] b_nxt;
-reg [15:0] x_nxt;
-reg [15:0] y_nxt;
-reg [15:0] u_nxt;
-reg [15:0] s_nxt;
-reg [15:0] pc_nxt;
-reg [7:0] dp_nxt;
-reg [7:0] cc_nxt;
-reg [15:0] addr_nxt;
-reg [15:0] ea_nxt;
-reg [15:0] tmp_nxt;
-
-reg BS_nxt;
-reg BA_nxt;
-
-// for ADDR, BS/BA, assign them to the flops
-assign BS = BS_nxt;
-assign BA = BA_nxt;
-assign ADDR=addr_nxt;
-
-localparam CC_E= 8'H80;
-localparam CC_F= 8'H40;
-localparam CC_H= 8'H20;
-localparam CC_I= 8'H10;
-localparam CC_N= 8'H08;
-localparam CC_Z= 8'H04;
-localparam CC_V= 8'H02;
-localparam CC_C= 8'H01;
-
-localparam CC_E_BIT= 3'd7;
-localparam CC_F_BIT= 3'd6;
-localparam CC_H_BIT= 3'd5;
-localparam CC_I_BIT= 3'd4;
-localparam CC_N_BIT= 3'd3;
-localparam CC_Z_BIT= 3'd2;
-localparam CC_V_BIT= 3'd1;
-localparam CC_C_BIT= 3'd0;
-
-// Convenience calculations
-reg [15:0] pc_p1;
-reg [15:0] pc_p2;
-reg [15:0] pc_p3;
-reg [15:0] s_p1;
-reg [15:0] s_m1;
-reg [15:0] u_p1;
-reg [15:0] u_m1;
-reg [15:0] addr_p1;
-reg [15:0] ea_p1;
-
-//////////////////////////////////////////////////////
-// NMI Mask
-//
-// NMI is supposed to be masked - despite the name - until the 6809 loads a value into S.
-// Frankly, I'm cheating slightly. If someone does a LDS #$0, it won't disable the mask. Pretty much anything else
-// that changes the value of S from the default (which is currently $0) will clear the mask. A reset will set the mask again.
-reg NMIMask;
-
-reg NMILatched;
-reg NMISample;
-reg NMISample2;
-reg NMIClear;
-reg NMIClear_nxt;
-wire wNMIClear = NMIClear;
-
-reg IRQLatched;
-
-reg IRQSample;
-reg IRQSample2;
-reg FIRQLatched;
-reg FIRQSample;
-reg FIRQSample2;
-reg HALTLatched;
-reg HALTSample;
-reg HALTSample2;
-reg DMABREQLatched;
-reg DMABREQSample;
-reg DMABREQSample2;
-
-// Interrupt types
-localparam INTTYPE_NMI = 3'H0 ;
-localparam INTTYPE_IRQ = 3'H1 ;
-localparam INTTYPE_FIRQ = 3'H2 ;
-localparam INTTYPE_SWI = 3'H3 ;
-localparam INTTYPE_SWI2 = 3'H4 ;
-localparam INTTYPE_SWI3 = 3'H5 ;
-
-reg [2:0] IntType;
-reg [2:0] IntType_nxt;
-
-//////////////////////////////////////////////////////
-// Instruction Fetch Details
-//
-reg InstPage2;
-reg InstPage3;
-reg InstPage2_nxt;
-reg InstPage3_nxt;
-
-reg [7:0] Inst1;
-reg [7:0] Inst2;
-reg [7:0] Inst3;
-reg [7:0] Inst1_nxt;
-reg [7:0] Inst2_nxt;
-reg [7:0] Inst3_nxt;
-
-
-localparam CPUSTATE_RESET = 7'd0;
-localparam CPUSTATE_RESET0 = 7'd1;
-
-localparam CPUSTATE_RESET2 = 7'd3;
-localparam CPUSTATE_FETCH_I1 = 7'd4;
-localparam CPUSTATE_FETCH_I1V2 = 7'd5;
-localparam CPUSTATE_FETCH_I2 = 7'd8;
-
-localparam CPUSTATE_LBRA_OFFSETLOW = 7'd17;
-localparam CPUSTATE_LBRA_DONTCARE = 7'd18;
-localparam CPUSTATE_LBRA_DONTCARE2 = 7'd19;
-
-
-
-localparam CPUSTATE_BRA_DONTCARE = 7'd20;
-
-localparam CPUSTATE_BSR_DONTCARE1 = 7'd21;
-localparam CPUSTATE_BSR_DONTCARE2 = 7'd22;
-localparam CPUSTATE_BSR_RETURNLOW = 7'd23;
-localparam CPUSTATE_BSR_RETURNHIGH = 7'd24;
-
-localparam CPUSTATE_TFR_DONTCARE1 = 7'd26;
-localparam CPUSTATE_TFR_DONTCARE2 = 7'd27;
-localparam CPUSTATE_TFR_DONTCARE3 = 7'd28;
-localparam CPUSTATE_TFR_DONTCARE4 = 7'd29;
-
-localparam CPUSTATE_EXG_DONTCARE1 = 7'd30;
-localparam CPUSTATE_EXG_DONTCARE2 = 7'd31;
-localparam CPUSTATE_EXG_DONTCARE3 = 7'd32;
-localparam CPUSTATE_EXG_DONTCARE4 = 7'd33;
-localparam CPUSTATE_EXG_DONTCARE5 = 7'd34;
-localparam CPUSTATE_EXG_DONTCARE6 = 7'd35;
-
-localparam CPUSTATE_ABX_DONTCARE = 7'd36;
-
-localparam CPUSTATE_RTS_HI = 7'd38;
-localparam CPUSTATE_RTS_LO = 7'd39;
-localparam CPUSTATE_RTS_DONTCARE2 = 7'd40;
-
-localparam CPUSTATE_16IMM_LO = 7'd41;
-localparam CPUSTATE_ALU16_DONTCARE = 7'd42;
-localparam CPUSTATE_DIRECT_DONTCARE = 7'd43;
-
-localparam CPUSTATE_ALU_EA = 7'd44;
-
-localparam CPUSTATE_ALU_DONTCARE = 7'd46;
-localparam CPUSTATE_ALU_WRITEBACK = 7'd47;
-
-localparam CPUSTATE_LD16_LO = 7'd48;
-
-localparam CPUSTATE_ST16_LO = 7'd49;
-localparam CPUSTATE_ALU16_LO = 7'd50;
-
-
-
-
-localparam CPUSTATE_JSR_DONTCARE = 7'd53;
-localparam CPUSTATE_JSR_RETLO = 7'd54;
-localparam CPUSTATE_JSR_RETHI = 7'd55;
-localparam CPUSTATE_EXTENDED_ADDRLO = 7'd56;
-localparam CPUSTATE_EXTENDED_DONTCARE = 7'd57;
-localparam CPUSTATE_INDEXED_BASE = 7'd58;
-
-
-localparam CPUSTATE_IDX_DONTCARE3 = 7'd60;
-
-localparam CPUSTATE_IDX_OFFSET_LO = 7'd61;
-localparam CPUSTATE_IDX_16OFFSET_LO = 7'd62;
-
-localparam CPUSTATE_IDX_16OFF_DONTCARE0= 7'd63;
-localparam CPUSTATE_IDX_16OFF_DONTCARE1= 7'd64;
-localparam CPUSTATE_IDX_16OFF_DONTCARE2= 7'd65;
-localparam CPUSTATE_IDX_16OFF_DONTCARE3= 7'd66;
-
-localparam CPUSTATE_IDX_DOFF_DONTCARE1 = 7'd68;
-localparam CPUSTATE_IDX_DOFF_DONTCARE2 = 7'd69;
-localparam CPUSTATE_IDX_DOFF_DONTCARE3 = 7'd70;
-localparam CPUSTATE_IDX_PC16OFF_DONTCARE = 7'd71;
-
-localparam CPUSTATE_IDX_EXTIND_LO = 7'd72;
-localparam CPUSTATE_IDX_EXTIND_DONTCARE = 7'd73;
-
-localparam CPUSTATE_INDIRECT_HI = 7'd74;
-localparam CPUSTATE_INDIRECT_LO = 7'd75;
-localparam CPUSTATE_INDIRECT_DONTCARE = 7'd76;
-localparam CPUSTATE_MUL_ACTION = 7'd77;
-
-localparam CPUSTATE_PSH_DONTCARE1 = 7'd80;
-localparam CPUSTATE_PSH_DONTCARE2 = 7'd81;
-localparam CPUSTATE_PSH_DONTCARE3 = 7'd82;
-localparam CPUSTATE_PSH_ACTION = 7'd83;
-
-localparam CPUSTATE_PUL_DONTCARE1 = 7'd84;
-localparam CPUSTATE_PUL_DONTCARE2 = 7'd85;
-localparam CPUSTATE_PUL_ACTION = 7'd86;
-
-localparam CPUSTATE_NMI_START = 7'd87;
-localparam CPUSTATE_IRQ_DONTCARE = 7'd88;
-localparam CPUSTATE_IRQ_START = 7'd89;
-localparam CPUSTATE_IRQ_DONTCARE2 = 7'd90;
-localparam CPUSTATE_IRQ_VECTOR_HI = 7'd91;
-localparam CPUSTATE_IRQ_VECTOR_LO = 7'd92;
-localparam CPUSTATE_FIRQ_START = 7'd93;
-localparam CPUSTATE_CC_DONTCARE = 7'd94;
-localparam CPUSTATE_SWI_START = 7'd95;
-
-localparam CPUSTATE_TST_DONTCARE1 = 7'd96;
-localparam CPUSTATE_TST_DONTCARE2 = 7'd97;
-
-localparam CPUSTATE_DEBUG = 7'd98;
-
-localparam CPUSTATE_16IMM_DONTCARE = 7'd99;
-
-localparam CPUSTATE_HALTED = 7'd100;
-
-localparam CPUSTATE_HALT_EXIT2 = 7'd102;
-localparam CPUSTATE_STOP = 7'd105;
-localparam CPUSTATE_STOP2 = 7'd106;
-localparam CPUSTATE_STOP3 = 7'd107;
-
-
-localparam CPUSTATE_CWAI = 7'd108;
-localparam CPUSTATE_CWAI_DONTCARE1 = 7'd109;
-localparam CPUSTATE_CWAI_POST = 7'd110;
-
-localparam CPUSTATE_DMABREQ = 7'd111;
-localparam CPUSTATE_DMABREQ_EXIT = 7'd112;
-localparam CPUSTATE_SYNC = 7'd113;
-localparam CPUSTATE_SYNC_EXIT = 7'd114;
-
-localparam CPUSTATE_INT_DONTCARE = 7'd115;
-
-
-reg [6:0] CpuState = CPUSTATE_RESET;
-reg [6:0] CpuState_nxt = CPUSTATE_RESET;
-
-reg [6:0] NextState = CPUSTATE_RESET;
-reg [6:0] NextState_nxt = CPUSTATE_RESET;
-
-wire [6:0] PostIllegalState;
-
-// If we encounter something like an illegal addressing mode (an index mode that's illegal for instance)
-// What state should we go to?
-generate
-if (ILLEGAL_INSTRUCTIONS=="STOP")
-begin : postillegal
- assign PostIllegalState = CPUSTATE_STOP;
-end
-else
-begin
- assign PostIllegalState = CPUSTATE_FETCH_I1;
-end
-endgenerate
-
-
-
-///////////////////////////////////////////////////////////////////////
-
-//
-// MapInstruction - Considering how the core was instantiated, this
-// will either directly return D[7:0] *or* remap values from D[7:0]
-// that relate to undefined instructions in the 6809 to the instructions
-// that the 6809 actually executed when these were encountered, due to
-// incomplete decoding.
-//
-// NEG, COM, LSR, DEC - these four instructions, in Direct, Inherent (A or B)
-// Indexed, or Extended addressing do not actually decode bit 0 on the instruction.
-// Thus, for instance, a $51 encountered will be executed as a $50, which is a NEGB.
-//
-
-// Specifically, the input is an instruction; if it matches an unknown instruction that the
-// 6809 is known to ghost to another instruction, the output of the function
-// is the the instruction that actually gets executed. Otherwise, the output is the
-// input.
-
-function [7:0] MapInstruction(input [7:0] i);
-reg [3:0] topnyb;
-reg [3:0] btmnyb;
-reg [7:0] newinst;
-begin
- newinst = i;
-
- topnyb = i[7:4];
- btmnyb = i[3:0];
-
- if ( (topnyb == 4'H0) ||
- (topnyb == 4'H4) ||
- (topnyb == 4'H5) ||
- (topnyb == 4'H6) ||
- (topnyb == 4'H7)
- )
- begin
- if (btmnyb == 4'H1)
- newinst = {topnyb, 4'H0};
- if (btmnyb == 4'H2)
- newinst = {topnyb, 4'H3};
- if (btmnyb == 4'H5)
- newinst = {topnyb, 4'H4};
- if (btmnyb == 4'HB)
- newinst = {topnyb, 4'HA};
- end
- MapInstruction = newinst;
-end
-endfunction
-
-
-wire [7:0] MappedInstruction;
-generate
-if (ILLEGAL_INSTRUCTIONS=="GHOST")
-begin : ghost
- assign MappedInstruction = MapInstruction(D);
-end
-else
-begin
- assign MappedInstruction = D;
-end
-endgenerate
-
-
-
-///////////////////////////////////////////////////////////////////////
-
-function IllegalInstruction(input [7:0] i);
-reg [3:0] hi;
-reg [3:0] lo;
-reg illegal;
-begin
- illegal = 1'b0;
- hi = i[7:4];
- lo = i[3:0];
- if ( (hi == 4'H0) || (hi == 4'H4) || (hi == 4'H5) || (hi == 4'H6) || (hi == 4'H7) )
- begin
- if ( (lo == 4'H1) || (lo == 4'H2) || (lo == 4'H5) || (lo == 4'HB) )
- illegal = 1'b1;
- if (lo == 4'HE)
- if ( (hi == 4'H4) || (hi == 4'H5) )
- illegal = 1'b1;
- end
- if (hi == 4'H3)
- begin
- if ( (lo == 4'H8) || (lo == 4'HE) )
- illegal = 1'b1;
- end
- if (hi == 4'H1)
- begin
- if ( (lo == 4'H4) || (lo == 4'H5) || (lo == 4'H8) || (lo == 4'HB) )
- illegal = 1'b1;
- end
- if ( (hi == 4'H8) || (hi == 4'HC) )
- begin
- if ( (lo == 4'H7) || (lo == 4'HF) )
- illegal = 1'b1;
- if ( lo == 4'HD )
- if (hi == 4'HC)
- illegal = 1'b1;
- end
- IllegalInstruction = illegal;
-end
-endfunction
-
-wire IsIllegalInstruction;
-
-generate
-if (ILLEGAL_INSTRUCTIONS=="GHOST")
-begin : never_illegal
- assign IsIllegalInstruction = 1'b0;
-end
-else
-begin
- assign IsIllegalInstruction = IllegalInstruction(Inst1);
-end
-endgenerate
-
-wire [6:0] IllegalInstructionState;
-generate
-if (ILLEGAL_INSTRUCTIONS=="IGNORE")
-begin : illegal_state
- assign IllegalInstructionState = CPUSTATE_FETCH_I1;
-end
-else if (ILLEGAL_INSTRUCTIONS=="STOP")
-begin
- assign IllegalInstructionState = CPUSTATE_STOP;
-end
-else
-begin
- assign IllegalInstructionState = 7'd0;
-end
-endgenerate
-
-
-///////////////////////////////////////////////////////////////////////
-
-
-always @(posedge CLK)
-begin
- reg old_sample;
- old_sample <= NMISample2;
-
- if (wNMIClear == 1) NMILatched <= 1;
- else if(old_sample & ~NMISample2) NMILatched <= NMIMask;
-end
-
-//
-// The 6809 specs say that the CPU control signals are sampled on the falling edge of Q.
-// It also says that the interrupts require 1 cycle of synchronization time.
-// That's vague, as it doesn't say where "1 cycle" starts or ends. Starting from the
-// falling edge of Q, the next cycle notices an assertion. From checking a hard 6809 on
-// an analyzer, what they really mean is that it's sampled on the falling edge of Q,
-// but there's a one cycle delay from the falling edge of E (0.25 clocks from the falling edge of Q
-// where the signals were sampled) before it can be noticed.
-// So, SIGNALSample is the latched value at the falling edge of Q
-// SIGNALSample2 is the latched value at the falling edge of E (0.25 clocks after the line above)
-// SIGNALLatched is the latched value at the falling edge of E (1 cycle after the line above)
-//
-// /HALT and /DMABREQ are delayed one cycle less than interrupts. The 6809 specs infer these details,
-// but don't list the point-of-reference they're written from (for instance, they say that an interrupt requires
-// a cycle for synchronization; however, it isn't clear whether that's from the falling Q to the next falling Q,
-// a complete intermediate cycle, the falling E to the next falling E, etc.) - which, in the end, required an
-// analyzer on the 6809 to determine how many cycles before a new instruction an interrupt (or /HALT & /DMABREQ)
-// had to be asserted to be noted instead of the next instruction running start to finish.
-//
-always @(posedge CLK)
-begin
- if(fallQ_en) begin
- NMISample <= nNMI;
- IRQSample <= nIRQ;
- FIRQSample <= nFIRQ;
- HALTSample <= nHALT;
- DMABREQSample <= nDMABREQ;
- end
-end
-
-
-reg rnRESET=0; // The latched version of /RESET, useful 1 clock after it's latched
-always @(posedge CLK)
-begin
- if(fallE_en) begin
- rnRESET <= nRESET;
-
- NMISample2 <= NMISample;
-
- IRQSample2 <= IRQSample;
- IRQLatched <= IRQSample2;
-
- FIRQSample2 <= FIRQSample;
- FIRQLatched <= FIRQSample2;
-
- HALTSample2 <= HALTSample;
- HALTLatched <= HALTSample2;
-
- DMABREQSample2 <= DMABREQSample;
- DMABREQLatched <= DMABREQSample2;
-
-
- if (rnRESET == 1)
- begin
- CpuState <= CpuState_nxt;
-
- // Don't interpret this next item as "The Next State"; it's a special case 'after this
- // generic state, go to this programmable state', so that a single state
- // can be shared for many tasks. [Specifically, the stack push/pull code, which is used
- // for PSH, PUL, Interrupts, RTI, etc.
- NextState <= NextState_nxt;
-
- // CPU registers latch from the combinatorial circuit
- a <= a_nxt;
- b <= b_nxt;
- x <= x_nxt;
- y <= y_nxt;
- s <= s_nxt;
- u <= u_nxt;
- cc <= cc_nxt;
- dp <= dp_nxt;
- pc <= pc_nxt;
- tmp <= tmp_nxt;
- addr <= addr_nxt;
- ea <= ea_nxt;
-
- InstPage2 <= InstPage2_nxt;
- InstPage3 <= InstPage3_nxt;
- Inst1 <= Inst1_nxt;
- Inst2 <= Inst2_nxt;
- Inst3 <= Inst3_nxt;
- NMIClear <= NMIClear_nxt;
-
- IntType <= IntType_nxt;
-
- // Once S changes at all (default is '0'), release the NMI Mask.
- if (s != s_nxt) NMIMask <= 1'b0;
- end
- else
- begin
- CpuState <= CPUSTATE_RESET;
- NMIMask <= 1'b1; // Mask NMI until S is loaded.
- NMIClear <= 1'b0; // Mark us as not having serviced NMI
- end
- end
-end
-
-
-/////////////////////////////////////////////////////////////////
-// Decode the Index byte
-
-localparam IDX_REG_X = 3'd0;
-localparam IDX_REG_Y = 3'd1;
-localparam IDX_REG_U = 3'd2;
-localparam IDX_REG_S = 3'd3;
-localparam IDX_REG_PC = 3'd4;
-
-localparam IDX_MODE_POSTINC1 = 4'd0;
-localparam IDX_MODE_POSTINC2 = 4'd1;
-localparam IDX_MODE_PREDEC1 = 4'd2;
-localparam IDX_MODE_PREDEC2 = 4'd3;
-localparam IDX_MODE_NOOFFSET = 4'd4;
-localparam IDX_MODE_B_OFFSET = 4'd5;
-localparam IDX_MODE_A_OFFSET = 4'd6;
-localparam IDX_MODE_5BIT_OFFSET= 4'd7; // Special case, not bit pattern 7; the offset sits in the bit pattern
-localparam IDX_MODE_8BIT_OFFSET= 4'd8;
-localparam IDX_MODE_16BIT_OFFSET = 4'd9;
-localparam IDX_MODE_D_OFFSET = 4'd11;
-localparam IDX_MODE_8BIT_OFFSET_PC = 4'd12;
-localparam IDX_MODE_16BIT_OFFSET_PC= 4'd13;
-localparam IDX_MODE_EXTENDED_INDIRECT = 4'd15;
-
-// Return:
-// Register base [3 bits]
-// Indirect [1 bit]
-// Mode [4 bits]
-
-function [7:0] IndexDecode(input [7:0] postbyte);
-reg [2:0] regnum;
-reg indirect;
-reg [3:0] mode;
-begin
- indirect = 0;
- mode = 0;
-
- if (postbyte[7] == 0) // 5-bit
- begin
- mode = IDX_MODE_5BIT_OFFSET;
- end
- else
- begin
- mode = postbyte[3:0];
- indirect = postbyte[4];
- end
- if ((mode != IDX_MODE_8BIT_OFFSET_PC) && (mode != IDX_MODE_16BIT_OFFSET_PC))
- regnum[2:0] = postbyte[6:5];
- else
- regnum[2:0] = IDX_REG_PC;
-
- IndexDecode = {indirect, mode, regnum};
-end
-endfunction
-
-wire [3:0] IndexedMode;
-wire IndexedIndirect;
-wire [2:0] IndexedRegister;
-
-assign {IndexedIndirect, IndexedMode, IndexedRegister} = IndexDecode(Inst2);
-
-/////////////////////////////////////////////////////////////////
-// Is this a JMP instruction? (irrespective of addressing mode)
-function IsJMP(input [7:0] inst);
-reg [3:0] hi;
-reg [3:0] lo;
-begin
- hi = inst[7:4];
- lo = inst[3:0];
-
- IsJMP = 0;
- if ((hi == 4'H0) || (hi == 4'H6) || (hi == 4'H7))
- if (lo == 4'HE)
- IsJMP = 1;
-end
-endfunction
-
-///////////////////////////////////////////////////////////////////
-// Is this an 8-bit Store?
-
-localparam ST8_REG_A = 1'b0;
-localparam ST8_REG_B = 1'b1;
-
-function [1:0] IsST8(input [7:0] inst);
-reg regnum;
-reg IsStore;
-begin
-
- IsStore = 1'b0;
- regnum = 1'b1;
-
- if ( (Inst1 == 8'H97) || (Inst1 == 8'HA7) || (Inst1 == 8'HB7) )
- begin
- IsStore = 1'b1;
- regnum = 1'b0;
- end
- else if ( (Inst1 == 8'HD7) || (Inst1 == 8'HE7) || (Inst1 == 8'HF7) )
- begin
- IsStore = 1'b1;
- regnum = 1'b1;
- end
- IsST8 = {IsStore, regnum};
-end
-endfunction
-
-wire IsStore8;
-wire Store8RegisterNum;
-
-assign {IsStore8, Store8RegisterNum} = IsST8(Inst1);
-
-
-/////////////////////////////////////////////////////////////////
-// Is this a 16-bit Store?
-
-localparam ST16_REG_X = 3'd0;
-localparam ST16_REG_Y = 3'd1;
-localparam ST16_REG_U = 3'd2;
-localparam ST16_REG_S = 3'd3;
-localparam ST16_REG_D = 3'd4;
-
-
-function [3:0] IsST16(input [7:0] inst);
-reg [3:0] hi;
-reg [3:0] lo;
-reg [2:0] regnum;
-reg IsStore;
-begin
- hi = inst[7:4];
- lo = inst[3:0];
- IsStore = 1'b0;
- regnum = 3'b111;
-
- if ((inst == 8'H9F) || (inst == 8'HAF) || (inst == 8'HBF))
- begin
- IsStore = 1;
- if (~InstPage2)
- regnum = ST16_REG_X;
- else
- regnum = ST16_REG_Y;
- end
- else if ((inst == 8'HDF) || (inst == 8'HEF) || (inst == 8'HFF))
- begin
- IsStore = 1;
- if (~InstPage2)
- regnum = ST16_REG_U;
- else
- regnum = ST16_REG_S;
- end
- else if ((inst == 8'HDD) || (inst == 8'HED) || (inst == 8'HFD))
- begin
- IsStore = 1;
- regnum = ST16_REG_D;
- end
-
- IsST16 = {IsStore, regnum};
-end
-endfunction
-
-wire IsStore16;
-wire [2:0] StoreRegisterNum;
-
-assign {IsStore16, StoreRegisterNum} = IsST16(Inst1);
-
-/////////////////////////////////////////////////////////////////
-// Is this a special Immediate mode instruction, ala
-// PSH, PUL, EXG, TFR, ANDCC, ORCC
-function IsSpecialImm(input [7:0] inst);
-reg is;
-reg [3:0] hi;
-reg [3:0] lo;
-begin
- hi = inst[7:4];
- lo = inst[3:0];
- is = 0;
-
- if (hi == 4'H1)
- begin
- if ( (lo == 4'HA) || (lo == 4'HC) || (lo == 4'HE) || (lo == 4'HF) ) // ORCC, ANDCC, EXG, TFR
- is = 1;
- end
- else if (hi == 4'H3)
- begin
- if ( (lo >= 4'H3) && (lo <= 4'H7) ) // PSHS, PULS, PSHU, PULU
- is = 1;
- end
- else
- is = 0;
-
- IsSpecialImm = is;
-end
-endfunction
-wire IsSpecialImmediate = IsSpecialImm(Inst1);
-
-/////////////////////////////////////////////////////////////////
-// Is this a one-byte instruction? [The 6809 reads 2 bytes for every instruction, minimum (it can read more). On a one-byte, we have to ensure that we haven't skipped the PC ahead.
-function IsOneByteInstruction(input [7:0] inst);
-reg is;
-reg [3:0] hi;
-reg [3:0] lo;
-begin
- hi = inst[7:4];
- lo = inst[3:0];
- is = 1'b0;
-
- if ( (hi == 4'H4) || (hi == 4'H5) )
- is = 1'b1;
- else if ( hi == 4'H1)
- begin
- if ( (lo == 4'H2) || (lo == 4'H3) || (lo == 4'H9) || (lo == 4'HD) )
- is = 1'b1;
- end
- else if (hi == 4'H3)
- begin
- if ( (lo >= 4'H9) && (lo != 4'HC) )
- is = 1'b1;
- end
- else
- is = 1'b0;
-
- IsOneByteInstruction = is;
-end
-endfunction
-
-/////////////////////////////////////////////////////////////////
-// ALU16 - Simpler than the 8 bit ALU
-
-localparam ALU16_REG_X = 3'd0;
-localparam ALU16_REG_Y = 3'd1;
-localparam ALU16_REG_U = 3'd2;
-localparam ALU16_REG_S = 3'd3;
-localparam ALU16_REG_D = 3'd4;
-
-function [2:0] ALU16RegFromInst(input Page2, input Page3, input [7:0] inst);
-reg [2:0] srcreg;
-begin
- srcreg = 3'b111; // default
- casex ({Page2, Page3, inst}) // Note pattern for the matching below
- 10'b1010xx0011: // 1083, 1093, 10A3, 10B3 CMPD
- srcreg = ALU16_REG_D;
- 10'b1010xx1100: // 108C, 109C, 10AC, 10BC CMPY
- srcreg = ALU16_REG_Y;
- 10'b0110xx0011: // 1183, 1193, 11A3, 11B3 CMPU
- srcreg = ALU16_REG_U;
- 10'b0110xx1100: // 118C, 119C, 11AC, 11BC CMPS
- srcreg = ALU16_REG_S;
- 10'b0010xx1100: // 8C,9C,AC,BC CMPX
- srcreg = ALU16_REG_X;
-
- 10'b0011xx0011: // C3, D3, E3, F3 ADDD
- srcreg = ALU16_REG_D;
-
- 10'b0011xx1100: // CC, DC, EC, FC LDD
- srcreg = ALU16_REG_D;
- 10'b0010xx1110: // 8E LDX, 9E LDX, AE LDX, BE LDX
- srcreg = ALU16_REG_X;
- 10'b0011xx1110: // CE LDU, DE LDU, EE LDU, FE LDU
- srcreg = ALU16_REG_U;
- 10'b1010xx1110: // 108E LDY, 109E LDY, 10AE LDY, 10BE LDY
- srcreg = ALU16_REG_Y;
- 10'b1011xx1110: // 10CE LDS, 10DE LDS, 10EE LDS, 10FE LDS
- srcreg = ALU16_REG_S;
- 10'b0010xx0011: // 83, 93, A3, B3 SUBD
- srcreg = ALU16_REG_D;
-
- 10'H03A: // 3A ABX
- srcreg = ALU16_REG_X;
- 10'H030: // 30 LEAX
- srcreg = ALU16_REG_X;
- 10'H031: // 31 LEAY
- srcreg = ALU16_REG_Y;
- 10'H032: // 32 LEAS
- srcreg = ALU16_REG_S;
- 10'H033: // 32 LEAU
- srcreg = ALU16_REG_U;
- default:
- srcreg = 3'b111;
- endcase
- ALU16RegFromInst = srcreg;
-end
-endfunction
-
-wire [2:0] ALU16Reg = ALU16RegFromInst(InstPage2, InstPage3, Inst1);
-
-localparam ALUOP16_SUB = 3'H0;
-localparam ALUOP16_ADD = 3'H1;
-localparam ALUOP16_LD = 3'H2;
-localparam ALUOP16_CMP = 3'H3;
-localparam ALUOP16_LEA = 3'H4;
-localparam ALUOP16_INVALID = 3'H7;
-
-function [3:0] ALU16OpFromInst(input Page2, input Page3, input [7:0] inst);
-reg [2:0] aluop;
-reg writeback;
-begin
- aluop = 3'b111;
- writeback = 1'b1;
- casex ({Page2, Page3, inst})
- 10'b1010xx0011: // 1083, 1093, 10A3, 10B3 CMPD
- begin
- aluop = ALUOP16_CMP;
- writeback = 1'b0;
- end
- 10'b1010xx1100: // 108C, 109C, 10AC, 10BC CMPY
- begin
- aluop = ALUOP16_CMP;
- writeback = 1'b0;
- end
- 10'b0110xx0011: // 1183, 1193, 11A3, 11B3 CMPU
- begin
- aluop = ALUOP16_CMP;
- writeback = 1'b0;
- end
- 10'b0110xx1100: // 118C, 119C, 11AC, 11BC CMPS
- begin
- aluop = ALUOP16_CMP;
- writeback = 1'b0;
- end
- 10'b0010xx1100: // 8C,9C,AC,BC CMPX
- begin
- aluop = ALUOP16_CMP;
- writeback = 1'b0;
- end
-
- 10'b0011xx0011: // C3, D3, E3, F3 ADDD
- aluop = ALUOP16_ADD;
-
- 10'b0011xx1100: // CC, DC, EC, FC LDD
- aluop = ALUOP16_LD;
- 10'b001xxx1110: // 8E LDX, 9E LDX, AE LDX, BE LDX, CE LDU, DE LDU, EE LDU, FE LDU
- aluop = ALUOP16_LD;
- 10'b101xxx1110: // 108E LDY, 109E LDY, 10AE LDY, 10BE LDY, 10CE LDS, 10DE LDS, 10EE LDS, 10FE LDS
- aluop = ALUOP16_LD;
-
- 10'b0010xx0011: // 83, 93, A3, B3 SUBD
- aluop = ALUOP16_SUB;
-
- 10'H03A: // 3A ABX
- aluop = ALUOP16_ADD;
-
- 10'b00001100xx: // $30-$33, LEAX, LEAY, LEAS, LEAU
- aluop = ALUOP16_LEA;
-
- default:
- aluop = ALUOP16_INVALID;
- endcase
- ALU16OpFromInst = {writeback, aluop};
-end
-endfunction
-
-wire ALU16OpWriteback;
-wire [2:0] ALU16Opcode;
-
-assign {ALU16OpWriteback, ALU16Opcode} = ALU16OpFromInst(InstPage2, InstPage3, Inst1);
-
-wire IsALU16Opcode = (ALU16Opcode != 3'b111);
-
-function [23:0] ALU16Inst(input [2:0] operation16, input [15:0] a_arg, input [15:0] b_arg, input [7:0] cc_arg);
-reg [7:0] cc_out;
-reg [15:0] ALUFn;
-reg carry;
-reg borrow;
-begin
- cc_out = cc_arg;
- case (operation16)
- ALUOP16_ADD:
- begin
- {cc_out[CC_C_BIT], ALUFn} = {1'b0, a_arg} + b_arg;
- cc_out[CC_V_BIT] = (a_arg[15] & b_arg[15] & ~ALUFn[15]) | (~a_arg[15] & ~b_arg[15] & ALUFn[15]);
- end
-
- ALUOP16_SUB:
- begin
- {cc_out[CC_C_BIT], ALUFn} = {1'b0, a_arg} - {1'b0, b_arg};
- cc_out[CC_V_BIT] = (a_arg[15] & ~b_arg[15] & ~ALUFn[15]) | (~a_arg[15] & b_arg[15] & ALUFn[15]);
- end
-
- ALUOP16_LD:
- begin
- ALUFn = b_arg;
- cc_out[CC_V_BIT] = 1'b0;
- end
-
- ALUOP16_CMP:
- begin
- {cc_out[CC_C_BIT], ALUFn} = {1'b0, a_arg} - {1'b0, b_arg};
- cc_out[CC_V_BIT] = (a_arg[15] & ~b_arg[15] & ~ALUFn[15]) | (~a_arg[15] & b_arg[15] & ALUFn[15]);
- end
-
- ALUOP16_LEA:
- begin
- ALUFn = a_arg;
- end
-
- default:
- ALUFn = 16'H0000;
-
- endcase
- cc_out[CC_Z_BIT] = (ALUFn[15:0] == 16'H0000);
- if (operation16 != ALUOP16_LEA)
- cc_out[CC_N_BIT] = ALUFn[15];
- ALU16Inst = {cc_out, ALUFn};
-end
-endfunction
-
-reg [2:0] ALU16_OP;
-reg [15:0] ALU16_A;
-reg [15:0] ALU16_B;
-reg [7:0] ALU16_CC;
-
-// Top 8 bits == CC, bottom 8 bits = output value
-wire [23:0] ALU16 = ALU16Inst(ALU16_OP, ALU16_A, ALU16_B, ALU16_CC);
-
-
-/////////////////////////////////////////////////////////////////
-// ALU
-
-// The ops are organized from the 4 low-order bits of the instructions for the first set of ops, then 16-31 are the second set - even though bit 4 isn't representative.
-localparam ALUOP_NEG = 5'd0;
-localparam ALUOP_COM = 5'd3;
-localparam ALUOP_LSR = 5'd4;
-localparam ALUOP_ROR = 5'd6;
-localparam ALUOP_ASR = 5'd7;
-localparam ALUOP_ASL = 5'd8;
-localparam ALUOP_LSL = 5'd8;
-localparam ALUOP_ROL = 5'd9;
-localparam ALUOP_DEC = 5'd10;
-localparam ALUOP_INC = 5'd12;
-localparam ALUOP_TST = 5'd13;
-localparam ALUOP_CLR = 5'd15;
-
-localparam ALUOP_SUB = 5'd16;
-localparam ALUOP_CMP = 5'd17;
-localparam ALUOP_SBC = 5'd18;
-localparam ALUOP_AND = 5'd20;
-localparam ALUOP_BIT = 5'd21;
-localparam ALUOP_LD = 5'd22;
-localparam ALUOP_EOR = 5'd24;
-localparam ALUOP_ADC = 5'd25;
-localparam ALUOP_OR = 5'd26;
-localparam ALUOP_ADD = 5'd27;
-
-function [5:0] ALUOpFromInst(input [7:0] inst);
-reg [4:0] op;
-reg writeback;
-begin
- // Okay, this turned out to be simpler than I expected ...
- op = {inst[7], inst[3:0]};
- case (op)
- ALUOP_CMP:
- writeback = 0;
- ALUOP_TST:
- writeback = 0;
- ALUOP_BIT:
- writeback = 0;
- default:
- writeback = 1;
- endcase
- ALUOpFromInst = {writeback, op};
-end
-endfunction
-
-wire [4:0] ALU8Op;
-wire ALU8Writeback;
-
-assign {ALU8Writeback, ALU8Op} = ALUOpFromInst(Inst1);
-
-reg [7:0] ALU_A;
-reg [7:0] ALU_B;
-reg [7:0] ALU_CC;
-reg [4:0] ALU_OP;
-
-
-function [15:0] ALUInst(input [4:0] operation, input [7:0] a_arg, input [7:0] b_arg, input [7:0] cc_arg);
-reg [7:0] cc_out;
-reg [7:0] ALUFn;
-reg borrow;
-begin
- cc_out = cc_arg;
- case (operation)
- ALUOP_NEG:
- begin
- ALUFn = ~a_arg + 1'b1;
- cc_out[CC_C_BIT] = (ALUFn != 8'H00);
- cc_out[CC_V_BIT] = (a_arg == 8'H80);
- end
-
- ALUOP_LSL:
- begin
- {cc_out[CC_C_BIT], ALUFn} = {a_arg, 1'b0};
- cc_out[CC_V_BIT] = a_arg[7] ^ a_arg[6];
- end
-
- ALUOP_LSR:
- begin
- {ALUFn, cc_out[CC_C_BIT]} = {1'b0, a_arg};
- end
-
- ALUOP_ASR:
- begin
- {ALUFn, cc_out[CC_C_BIT]} = {a_arg[7], a_arg};
- end
-
- ALUOP_ROL:
- begin
- {cc_out[CC_C_BIT], ALUFn} = {a_arg, cc_arg[CC_C_BIT]};
- cc_out[CC_V_BIT] = a_arg[7] ^ a_arg[6];
- end
-
- ALUOP_ROR:
- begin
- {ALUFn, cc_out[CC_C_BIT]} = {cc_arg[CC_C_BIT], a_arg};
- end
-
- ALUOP_OR:
- begin
- ALUFn = (a_arg | b_arg);
- cc_out[CC_V_BIT] = 0;
- end
-
- ALUOP_ADD:
- begin
- {cc_out[CC_C_BIT], ALUFn} = {1'b0, a_arg} + {1'b0, b_arg};
- cc_out[CC_V_BIT] = (a_arg[7] & b_arg[7] & ~ALUFn[7]) | (~a_arg[7] & ~b_arg[7] & ALUFn[7]);
- cc_out[CC_H_BIT] = a_arg[4] ^ b_arg[4] ^ ALUFn[4];
- end
-
- ALUOP_SUB:
- begin
- {cc_out[CC_C_BIT], ALUFn} = {1'b0, a_arg} - {1'b0, b_arg};
- cc_out[CC_V_BIT] = (a_arg[7] & ~b_arg[7] & ~ALUFn[7]) | (~a_arg[7] & b_arg[7] & ALUFn[7]);
- end
-
- ALUOP_AND:
- begin
- ALUFn = (a_arg & b_arg);
- cc_out[CC_V_BIT] = 0;
- end
-
- ALUOP_BIT:
- begin
- ALUFn = (a_arg & b_arg);
- cc_out[CC_V_BIT] = 0;
- end
-
- ALUOP_EOR:
- begin
- ALUFn = (a_arg ^ b_arg);
- cc_out[CC_V_BIT] = 0;
- end
-
- ALUOP_CMP:
- begin
- {cc_out[CC_C_BIT], ALUFn} = {1'b0, a_arg} - {1'b0, b_arg};
- cc_out[CC_V_BIT] = (a_arg[7] & ~b_arg[7] & ~ALUFn[7]) | (~a_arg[7] & b_arg[7] & ALUFn[7]);
- end
-
- ALUOP_COM:
- begin
- ALUFn = ~a_arg;
- cc_out[CC_V_BIT] = 0;
- cc_out[CC_C_BIT] = 1;
- end
-
- ALUOP_ADC:
- begin
- {cc_out[CC_C_BIT], ALUFn} = {1'b0, a_arg} + {1'b0, b_arg} + cc_arg[CC_C_BIT];
- cc_out[CC_V_BIT] = (a_arg[7] & b_arg[7] & ~ALUFn[7]) | (~a_arg[7] & ~b_arg[7] & ALUFn[7]);
- cc_out[CC_H_BIT] = a_arg[4] ^ b_arg[4] ^ ALUFn[4];
- end
-
- ALUOP_LD:
- begin
- ALUFn = b_arg;
- cc_out[CC_V_BIT] = 0;
- end
-
- ALUOP_INC:
- begin
- ALUFn = a_arg + 1'b1;
- cc_out[CC_V_BIT] = (~a_arg[7] & ALUFn[7]);
- end
-
- ALUOP_DEC:
- begin
- ALUFn = a_arg - 1'b1;
- cc_out[CC_V_BIT] = (a_arg[7] & ~ALUFn[7]);
- end
-
- ALUOP_CLR:
- begin
- ALUFn = 0;
- cc_out[CC_V_BIT] = 0;
- cc_out[CC_C_BIT] = 0;
- end
-
- ALUOP_TST:
- begin
- ALUFn = a_arg;
- cc_out[CC_V_BIT] = 0;
- end
-
- ALUOP_SBC:
- begin
- {cc_out[CC_C_BIT], ALUFn} = {1'b0, a_arg} - {1'b0, b_arg} - cc_arg[CC_C_BIT];
- cc_out[CC_V_BIT] = (a_arg[7] & ~b_arg[7] & ~ALUFn[7]) | (~a_arg[7] & b_arg[7] & ALUFn[7]);
- end
-
- default:
- ALUFn = 0;
-
- endcase
-
- cc_out[CC_N_BIT] = ALUFn[7];
- cc_out[CC_Z_BIT] = !ALUFn;
- ALUInst = {cc_out[7:0], ALUFn};
-end
-endfunction
-
-
-// Top 8 bits == CC, bottom 8 bits = output value
-wire [15:0] ALU = ALUInst(ALU_OP, ALU_A, ALU_B, ALU_CC);
-
-////////////////////////////////////////////////////////////
-
-localparam TYPE_INHERENT = 3'd0;
-localparam TYPE_IMMEDIATE = 3'd1;
-localparam TYPE_DIRECT = 3'd2;
-localparam TYPE_RELATIVE = 3'd3;
-localparam TYPE_INDEXED = 3'd4;
-localparam TYPE_EXTENDED = 3'd5;
-
-localparam TYPE_INVALID = 3'd7;
-
-// Function to decode the addressing mode the instruction uses
-function [2:0] addressing_mode_type(input [7:0] inst);
-begin
- casex (inst)
- 8'b0000???? : addressing_mode_type = TYPE_DIRECT;
- 8'b0001???? :
- begin
- casex (inst[3:0])
- 4'b0010:
- addressing_mode_type = TYPE_INHERENT;
-
- 4'b0011:
- addressing_mode_type = TYPE_INHERENT;
-
- 4'b1001:
- addressing_mode_type = TYPE_INHERENT;
-
- 4'b1101:
- addressing_mode_type = TYPE_INHERENT;
-
- 4'b0110:
- addressing_mode_type = TYPE_RELATIVE;
-
- 4'b0111:
- addressing_mode_type = TYPE_RELATIVE;
-
- 4'b1010:
- addressing_mode_type = TYPE_IMMEDIATE;
-
- 4'b1100:
- addressing_mode_type = TYPE_IMMEDIATE;
-
- 4'b1110:
- addressing_mode_type = TYPE_IMMEDIATE;
-
- 4'b1111:
- addressing_mode_type = TYPE_IMMEDIATE;
-
- default:
- addressing_mode_type = TYPE_INVALID;
- endcase
- end
-
- 8'b0010????: addressing_mode_type = TYPE_RELATIVE;
- 8'b0011????:
- begin
- casex(inst[3:0])
- 4'b00??:
- addressing_mode_type = TYPE_INDEXED;
-
- 4'b01??:
- addressing_mode_type = TYPE_IMMEDIATE;
-
- 4'b1001:
- addressing_mode_type = TYPE_INHERENT;
-
- 4'b101?:
- addressing_mode_type = TYPE_INHERENT;
-
- 4'b1100:
- addressing_mode_type = TYPE_INHERENT;
-
- 4'b1101:
- addressing_mode_type = TYPE_INHERENT;
-
- 4'b1111:
- addressing_mode_type = TYPE_INHERENT;
-
- default:
- addressing_mode_type = TYPE_INVALID;
- endcase
- end
-
- 8'b010?????: addressing_mode_type = TYPE_INHERENT;
-
- 8'b0110????: addressing_mode_type = TYPE_INDEXED;
-
- 8'b0111????: addressing_mode_type = TYPE_EXTENDED;
-
- 8'b1000????:
- begin
- casex (inst[3:0])
- 4'b0111: addressing_mode_type = TYPE_INVALID;
- 4'b1111: addressing_mode_type = TYPE_INVALID;
- 4'b1101: addressing_mode_type = TYPE_RELATIVE;
- default: addressing_mode_type = TYPE_IMMEDIATE;
- endcase
- end
-
- 8'b1001????: addressing_mode_type = TYPE_DIRECT;
- 8'b1010????: addressing_mode_type = TYPE_INDEXED;
- 8'b1011????: addressing_mode_type = TYPE_EXTENDED;
- 8'b1100????: addressing_mode_type = TYPE_IMMEDIATE;
- 8'b1101????: addressing_mode_type = TYPE_DIRECT;
- 8'b1110????: addressing_mode_type = TYPE_INDEXED;
- 8'b1111????: addressing_mode_type = TYPE_EXTENDED;
-
- endcase
-end
-endfunction
-
-wire [2:0] AddrModeType = addressing_mode_type(Inst1);
-
-//////////////////////////////////////////////////
-
-// Individual opcodes that are the top of a column of states.
-
-localparam OPCODE_INH_ABX = 8'H3A;
-localparam OPCODE_INH_RTS = 8'H39;
-localparam OPCODE_INH_RTI = 8'H3B;
-localparam OPCODE_INH_CWAI = 8'H3C;
-localparam OPCODE_INH_MUL = 8'H3D;
-localparam OPCODE_INH_SWI = 8'H3F;
-localparam OPCODE_INH_SEX = 8'H1D;
-localparam OPCODE_INH_NOP = 8'H12;
-localparam OPCODE_INH_SYNC = 8'H13;
-localparam OPCODE_INH_DAA = 8'H19;
-
-localparam OPCODE_IMM_ORCC = 8'H1A;
-localparam OPCODE_IMM_ANDCC = 8'H1C;
-localparam OPCODE_IMM_EXG = 8'H1E;
-localparam OPCODE_IMM_TFR = 8'H1F;
-localparam OPCODE_IMM_PSHS = 8'H34;
-localparam OPCODE_IMM_PULS = 8'H35;
-localparam OPCODE_IMM_PSHU = 8'H36;
-localparam OPCODE_IMM_PULU = 8'H37;
-
-localparam OPCODE_IMM_SUBD = 8'H83;
-localparam OPCODE_IMM_CMPX = 8'H8C;
-localparam OPCODE_IMM_LDX = 8'H8E;
-localparam OPCODE_IMM_ADDD = 8'HC3;
-localparam OPCODE_IMM_LDD = 8'HCC;
-localparam OPCODE_IMM_LDU = 8'HCE;
-localparam OPCODE_IMM_CMPD = 8'H83; // Page2
-localparam OPCODE_IMM_CMPY = 8'H8C; // Page2
-localparam OPCODE_IMM_LDY = 8'H8E; // Page2
-localparam OPCODE_IMM_LDS = 8'HCE; // Page2
-localparam OPCODE_IMM_CMPU = 8'H83; // Page3
-localparam OPCODE_IMM_CMPS = 8'H8C; // Page3
-
-localparam EXGTFR_REG_D = 4'H0;
-localparam EXGTFR_REG_X = 4'H1;
-localparam EXGTFR_REG_Y = 4'H2;
-localparam EXGTFR_REG_U = 4'H3;
-localparam EXGTFR_REG_S = 4'H4;
-localparam EXGTFR_REG_PC = 4'H5;
-localparam EXGTFR_REG_A = 4'H8;
-localparam EXGTFR_REG_B = 4'H9;
-localparam EXGTFR_REG_CC = 4'HA;
-localparam EXGTFR_REG_DP = 4'HB;
-
-function IsALU8Set0(input [7:0] instr);
-reg result;
-reg [3:0] hi;
-reg [3:0] lo;
-begin
- hi = instr[7:4];
- lo = instr[3:0];
- if ( (hi == 4'H0) || (hi == 4'H4) || (hi == 4'H5) || (hi == 4'H6) || (hi == 4'H7) )
- begin
- if ( (lo != 4'H1) && (lo != 4'H2) && (lo != 4'H5) && (lo != 4'HB) && (lo != 4'HE) ) // permit NEG, COM, LSR, ROR, ASR, ASL/LSL, ROL, DEC, INC, TST, CLR
- result = 1;
- else
- result = 0;
- end
- else
- result = 0;
- IsALU8Set0 = result;
-end
-endfunction
-
-function IsALU8Set1(input [7:0] instr);
-reg result;
-reg [3:0] hi;
-reg [3:0] lo;
-begin
- hi = instr[7:4];
- lo = instr[3:0];
- if ( (hi >= 4'H8) )
- begin
- if ( (lo <= 4'HB) && (lo != 4'H3) && (lo != 4'H7) ) // 8-bit SUB, CMP, SBC, AND, BIT, LD, EOR, ADC, OR, ADD
- result = 1;
- else
- result = 0;
- end
- else
- result = 0;
- IsALU8Set1 = result;
-end
-endfunction
-
-// Determine if the instruction is performing an 8-bit op (ALU only)
-function ALU8BitOp(input [7:0] instr);
-begin
- ALU8BitOp = IsALU8Set0(instr) | IsALU8Set1(instr);
-end
-endfunction
-
-wire Is8BitInst = ALU8BitOp(Inst1);
-
-function IsRegA(input [7:0] instr);
-reg result;
-reg [3:0] hi;
-begin
- hi = instr[7:4];
- if ((hi == 4'H4) || (hi == 4'H8) || (hi == 4'H9) || (hi == 4'HA) || (hi == 4'HB) )
- result = 1;
- else
- result = 0;
- IsRegA = result;
-end
-endfunction
-
-wire IsTargetRegA = IsRegA(Inst1);
-
-//
-//
-// Decode
-// 00-0F = DIRECT
-// 10-1F = INHERENT, RELATIVE, IMMEDIATE
-// 20-2F = RELATIVE
-// 30-3F = INDEXED, IMMEDIATE (pus, pul), INHERENT
-// 40-4F = INHERENT
-// 50-5F = INHERENT
-// 60-6F = INDEXED
-// 70-7F = EXTENDED
-// 80-8F = IMMEDIATE, RELATIVE (BSR)
-// 90-9F = DIRECT
-// A0-AF = INDEXED
-// B0-BF = EXTENDED
-// C0-CF = IMMEDIATE
-// D0-DF = DIRECT
-// E0-EF = INDEXED
-// F0-FF = EXTENDED
-
-// DIRECT; 00-0F, 90-9F, D0-DF
-// INHERENT; 10-1F (12, 13, 19, 1D), 30-3F (39-3F), 40-4F, 50-5F,
-// RELATIVE: 10-1F (16, 17), 20-2F, 80-8F (8D)
-// IMMEDIATE: 10-1F (1A, 1C, 1E, 1F), 30-3F (34-37), 80-8F (80-8C, 8E), C0-CF
-// INDEXED: 60-6F, A0-AF, E0-EF
-// EXTENDED: 70-7F, B0-Bf, F0-FF
-
-localparam INST_LBRA = 8'H16; // always -- shitty numbering, damnit
-localparam INST_LBSR = 8'H17; //
-
-localparam INST_BRA = 8'H20; // always
-localparam INST_BRN = 8'H21; // never
-localparam INST_BHI = 8'H22; // CC.Z = 0 && CC.C = 0
-localparam INST_BLS = 8'H23; // CC.Z != 0 && CC.C != 0
-localparam INST_BCC = 8'H24; // CC.C = 0
-localparam INST_BHS = 8'H24; // same as BCC
-localparam INST_BCS = 8'H25; // CC.C = 1
-localparam INST_BLO = 8'H25; // same as BCS
-localparam INST_BNE = 8'H26; // CC.Z = 0
-localparam INST_BEQ = 8'H27; // CC.Z = 1
-localparam INST_BVC = 8'H28; // V = 1
-localparam INST_BVS = 8'H29; // V = 0
-localparam INST_BPL = 8'H2A; // CC.N = 0
-localparam INST_BMI = 8'H2B; // CC.N = 1
-localparam INST_BGE = 8'H2C; // CC.N = CC.V
-localparam INST_BLT = 8'H2D; // CC.N != CC.V
-localparam INST_BGT = 8'H2E; // CC.N = CC.V && CC.Z = 0
-localparam INST_BLE = 8'H2F; // CC.N != CC.V && CC.Z = 1
-localparam INST_BSR = 8'H8D; // always
-
-localparam NYB_BRA = 4'H0; // always
-localparam NYB_BRN = 4'H1; // never
-localparam NYB_BHI = 4'H2; // CC.Z = 0 && CC.C = 0
-localparam NYB_BLS = 4'H3; // CC.Z != 0 && CC.C != 0
-localparam NYB_BCC = 4'H4; // CC.C = 0
-localparam NYB_BHS = 4'H4; // same as BCC
-localparam NYB_BCS = 4'H5; // CC.C = 1
-localparam NYB_BLO = 4'H5; // same as BCS
-localparam NYB_BNE = 4'H6; // CC.Z = 0
-localparam NYB_BEQ = 4'H7; // CC.Z = 1
-localparam NYB_BVC = 4'H8; // V = 0
-localparam NYB_BVS = 4'H9; // V = 1
-localparam NYB_BPL = 4'HA; // CC.N = 0
-localparam NYB_BMI = 4'HB; // CC.N = 1
-localparam NYB_BGE = 4'HC; // CC.N = CC.V
-localparam NYB_BLT = 4'HD; // CC.N != CC.V
-localparam NYB_BGT = 4'HE; // CC.N = CC.V && CC.Z = 0
-localparam NYB_BLE = 4'HF; // CC.N != CC.V && CC.Z = 1
-
-
-
-function take_branch(input [7:0] Inst1, input [7:0] cc);
-begin
- take_branch = 0; //default
- if ( (Inst1 == INST_BSR) || (Inst1 == INST_LBSR) || (Inst1 == INST_LBRA) )
- take_branch = 1;
- else
- case (Inst1[3:0])
- NYB_BRA:
- take_branch = 1;
- NYB_BRN:
- take_branch = 0;
- NYB_BHI:
- if ( ( cc[CC_Z_BIT] | cc[CC_C_BIT] ) == 0)
- take_branch = 1;
- NYB_BLS:
- if ( cc[CC_Z_BIT] | cc[CC_C_BIT] )
- take_branch = 1;
- NYB_BCC:
- if ( cc[CC_C_BIT] == 0 )
- take_branch = 1;
- NYB_BCS:
- if ( cc[CC_C_BIT] == 1 )
- take_branch = 1;
- NYB_BNE:
- if ( cc[CC_Z_BIT] == 0 )
- take_branch = 1;
- NYB_BEQ:
- if ( cc[CC_Z_BIT] == 1 )
- take_branch = 1;
- NYB_BVC:
- if ( cc[CC_V_BIT] == 0)
- take_branch = 1;
- NYB_BVS:
- if ( cc[CC_V_BIT] == 1)
- take_branch = 1;
- NYB_BPL:
- if ( cc[CC_N_BIT] == 0 )
- take_branch = 1;
- NYB_BMI:
- if (cc[CC_N_BIT] == 1)
- take_branch = 1;
- NYB_BGE:
- if ((cc[CC_N_BIT] ^ cc[CC_V_BIT]) == 0)
- take_branch = 1;
- NYB_BLT:
- if ((cc[CC_N_BIT] ^ cc[CC_V_BIT]) == 1)
- take_branch = 1;
- NYB_BGT:
- if ( ((cc[CC_N_BIT] ^ cc[CC_V_BIT]) == 0) & (cc[CC_Z_BIT] == 0) )
- take_branch = 1;
- NYB_BLE:
- if ( ((cc[CC_N_BIT] ^ cc[CC_V_BIT]) == 1) | (cc[CC_Z_BIT] == 1) )
- take_branch = 1;
- endcase
-end
-endfunction
-
-wire TakeBranch = take_branch(Inst1, cc);
-
-/////////////////////////////////////////////////////////////////////
-// Convenience function for knowing the contents for TFR, EXG
-function [15:0] EXGTFRRegister(input [3:0] regid);
-begin
- case (regid)
- EXGTFR_REG_D:
- EXGTFRRegister = {a, b};
- EXGTFR_REG_X:
- EXGTFRRegister = x;
- EXGTFR_REG_Y:
- EXGTFRRegister = y;
- EXGTFR_REG_U:
- EXGTFRRegister = u;
- EXGTFR_REG_S:
- EXGTFRRegister = s;
- EXGTFR_REG_PC:
- EXGTFRRegister = pc_p1; // For both EXG and TFR, this is used on the 2nd byte in the instruction's cycle. The PC intended to transfer is actually the next byte.
- EXGTFR_REG_DP:
- EXGTFRRegister = {8'HFF, dp};
- EXGTFR_REG_A:
- EXGTFRRegister = {8'HFF, a};
- EXGTFR_REG_B:
- EXGTFRRegister = {8'HFF, b};
- EXGTFR_REG_CC:
- EXGTFRRegister = {8'HFF, cc};
- default:
- EXGTFRRegister = 16'H0;
- endcase
-end
-endfunction
-wire [15:0] EXGTFRRegA = EXGTFRRegister(D[7:4]);
-wire [15:0] EXGTFRRegB = EXGTFRRegister(D[3:0]);
-
-// CPU state machine
-always @(*)
-begin
- rLIC = 1'b0;
- rAVMA = 1'b1;
- rBUSY = 1'b0;
-
- addr_nxt = 16'HFFFF;
- pc_p1 = (pc+16'H1);
- pc_p2 = (pc+16'H2);
- pc_p3 = (pc+16'H3);
- s_p1 = (s+16'H1);
- s_m1 = (s-16'H1);
- u_p1 = (u+16'H1);
- u_m1 = (u-16'H1);
- addr_p1 = (addr+16'H1);
- ea_p1 = (ea+16'H1);
- BS_nxt = 1'b0;
- BA_nxt = 1'b0;
-
- // These may be overridden below, but the "next" version by default should be
- // the last latched version.
- IntType_nxt = IntType;
- NMIClear_nxt = NMIClear;
- NextState_nxt = NextState;
- a_nxt = a;
- b_nxt = b;
- x_nxt = x;
- y_nxt = y;
- s_nxt = s;
- u_nxt = u;
- cc_nxt = cc;
- dp_nxt = dp;
- pc_nxt = pc;
- tmp_nxt = tmp;
- ea_nxt = ea;
-
- ALU_A = 8'H00;
- ALU_B = 8'H00;
- ALU_CC = 8'H00;
- ALU_OP = 5'H00;
-
- ALU16_OP = 3'H0;
- ALU16_A = 16'H0000;
- ALU16_B = 16'H0000;
- ALU16_CC = 8'H00;
-
- DOutput = 8'H00;
- RnWOut = 1'b1; // read
-
- Inst1_nxt = Inst1;
- Inst2_nxt = Inst2;
- Inst3_nxt = Inst3;
- InstPage2_nxt = InstPage2;
- InstPage3_nxt = InstPage3;
-
- CpuState_nxt = CpuState;
-
- case (CpuState)
- CPUSTATE_RESET:
- begin
- addr_nxt = 16'HFFFF;
- a_nxt = 0;
- b_nxt = 0;
- x_nxt = 0;
- y_nxt = 0;
- s_nxt = 16'HFFFD; // Take care about removing the reset of S. There's logic depending on the delta between s and s_nxt to clear NMIMask.
- u_nxt = 0;
- cc_nxt = CC_F | CC_I; // reset disables interrupts
- dp_nxt = 0;
- ea_nxt = 16'HFFFF;
-
- RnWOut = 1; // read
- rLIC = 1'b0; // Instruction incomplete
- NMIClear_nxt= 1'b0;
- IntType_nxt = 3'b111;
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_RESET0;
- end
-
- CPUSTATE_RESET0:
- begin
- addr_nxt = `RESET_VECTOR;
- rBUSY = 1'b1;
- pc_nxt[15:8] = D[7:0];
- BS_nxt = 1'b1; // ACK RESET
- rAVMA = 1'b1;
- rLIC = 1'b1;
- CpuState_nxt = CPUSTATE_RESET2;
- end
-
- CPUSTATE_RESET2:
- begin
- addr_nxt = addr_p1;
- BS_nxt = 1'b1; // ACK RESET
- pc_nxt[7:0] = D[7:0];
- rAVMA = 1'b1;
- rLIC = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I1;
- end
-
- CPUSTATE_FETCH_I1:
- begin
- if (~DMABREQLatched)
- begin
- addr_nxt = pc;
- RnWOut = 1'b1;
- rAVMA = 1'b0;
- tmp_nxt = {tmp[15:4], 4'b1111};
- BS_nxt = 1'b1;
- BA_nxt = 1'b1;
- rLIC = 1'b1;
- CpuState_nxt = CPUSTATE_DMABREQ;
- end
- else if (~HALTLatched)
- begin
- addr_nxt = pc;
- RnWOut = 1'b1;
- rAVMA = 1'b0;
- BS_nxt = 1'b1;
- BA_nxt = 1'b1;
- rLIC = 1'b1;
- CpuState_nxt = CPUSTATE_HALTED;
- end
- else // not halting, run the inst byte fetch
- begin
- addr_nxt = pc; // Set the address bus for the next instruction, first byte
- pc_nxt = pc_p1;
- RnWOut = 1; // Set for a READ
- Inst1_nxt = MappedInstruction;
- InstPage2_nxt = 0;
- InstPage3_nxt = 0;
-
- // New instruction fetch; service interrupts pending
- if (NMILatched == 0)
- begin
- pc_nxt = pc;
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_NMI_START;
- end
- else if ((FIRQLatched == 0) && (cc[CC_F_BIT] == 0))
- begin
- pc_nxt = pc;
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FIRQ_START;
- end
- else if ((IRQLatched == 0) && (cc[CC_I_BIT] == 0))
- begin
- pc_nxt = pc;
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_IRQ_START;
- end
-
- // The actual 1st byte checks
- else if (Inst1_nxt == 8'H10) // Page 2 Note, like the 6809, $10 $10 $10 $10 has the same effect as a single $10.
- begin
- InstPage2_nxt = 1;
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I1V2;
- end
- else if (Inst1_nxt == 8'H11) // Page 3
- begin
- InstPage3_nxt = 1;
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I1V2;
- end
- else
- begin
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I2;
- end
- end // if not halting
- end
-
- CPUSTATE_FETCH_I1V2:
- begin
- addr_nxt = pc; // Set the address bus for the next instruction, first byte
- pc_nxt = pc_p1;
- RnWOut = 1; // Set for a READ
- Inst1_nxt = MappedInstruction;
-
- if (Inst1_nxt == 8'H10) // Page 2 Note, like the 6809, $10 $10 $10 $10 has the same effect as a single $10.
- begin
- if (InstPage3 == 0) // $11 $11 $11 $11 ... $11 $10 still = Page 3
- InstPage2_nxt = 1;
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I1V2;
- end
- else if (Inst1_nxt == 8'H11) // Page 3
- begin
- if (InstPage2 == 0) // $10 $10 ... $10 $11 still = Page 2
- InstPage3_nxt = 1;
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I1V2;
- end
- else
- begin
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I2;
- end
- end
-
-
- CPUSTATE_FETCH_I2: // We've fetched the first byte. If a $10 or $11 (page select), mark those flags and fetch the next byte as instruction byte 1.
- begin
- addr_nxt = addr_p1; // Address bus++
- pc_nxt = pc_p1;
- Inst2_nxt = D[7:0];
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I1;
-
- if (IsIllegalInstruction) // Skip illegal instructions
- begin
-
- rAVMA = 1'b1;
- CpuState_nxt = IllegalInstructionState;
- rLIC = 1'b1;
- end
- else
- begin
- // First byte Decode for this stage
- case (AddrModeType)
- TYPE_INDEXED:
- begin
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_INDEXED_BASE;
- end
-
-
- TYPE_EXTENDED:
- begin
- ea_nxt[15:8] = Inst2_nxt;
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_EXTENDED_ADDRLO;
- end
- TYPE_DIRECT:
- begin
- ea_nxt = {dp, Inst2_nxt};
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_DIRECT_DONTCARE;
- end
-
- TYPE_INHERENT:
- begin
- if (Inst1 == OPCODE_INH_NOP)
- begin
- rLIC = 1'b1; // Instruction done!
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I1;
- end
- else if (Inst1 == OPCODE_INH_DAA) // Bcd lunacy
- begin
- if ( ((cc[CC_C_BIT]) || (a[7:4] > 4'H9)) ||
- ((a[7:4] > 4'H8) && (a[3:0] > 4'H9)) )
- tmp_nxt[7:4] = 4'H6;
- else
- tmp_nxt[7:4] = 4'H0;
-
- if ((cc[CC_H_BIT]) || (a[3:0] > 4'H9))
- tmp_nxt[3:0] = 4'H6;
- else
- tmp_nxt[3:0] = 4'H0;
-
- // DAA handles carry in the weirdest way.
- // If it's already set, it remains set, even if carry-out is 0.
- // If it wasn't set, but the output of the operation is set, carry-out gets set.
- {tmp_nxt[8], a_nxt} = {1'b0, a} + tmp_nxt[7:0];
-
- cc_nxt[CC_C_BIT] = cc_nxt[CC_C_BIT] | tmp_nxt[8];
-
- cc_nxt[CC_N_BIT] = a_nxt[7];
- cc_nxt[CC_Z_BIT] = (a_nxt == 8'H00);
- rLIC = 1'b1; // Instruction done!
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I1;
- end
- else if (Inst1 == OPCODE_INH_SYNC)
- begin
- CpuState_nxt = CPUSTATE_SYNC;
- rLIC = 1'b1;
- rAVMA = 1'b0;
- end
- else if (Inst1 == OPCODE_INH_MUL)
- begin
- tmp_nxt = 16'H0000;
- ea_nxt[15:8] = 8'H00;
- ea_nxt[7:0] = a;
- a_nxt = 8;
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_MUL_ACTION;
- end
- else if (Inst1 == OPCODE_INH_RTS)
- begin
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_RTS_HI;
- end
- else if (Inst1 == OPCODE_INH_RTI)
- begin
- rAVMA = 1'b1;
- tmp_nxt = 16'H1001; // Set tmp[12] to indicate an RTI being processed, and at least pull CC.
- CpuState_nxt = CPUSTATE_PUL_ACTION;
- NextState_nxt = CPUSTATE_FETCH_I1;
- end
- else if (Inst1 == OPCODE_INH_SWI)
- begin
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_SWI_START;
- end
- else if (Inst1 == OPCODE_INH_CWAI)
- begin
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_CWAI;
- end
- else if (Inst1 == OPCODE_INH_SEX)
- begin
- a_nxt = {8{b[7]}};
- rLIC = 1'b1; // Instruction done!
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I1;
- end
- else if (Inst1 == OPCODE_INH_ABX)
- begin
- x_nxt = x + b;
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_ABX_DONTCARE;
- end
- else
- begin
- ALU_OP = ALU8Op;
- if (IsTargetRegA)
- ALU_A = a;
- else
- ALU_A = b;
-
- ALU_B = 0;
- ALU_CC = cc;
- cc_nxt = ALU[15:8];
-
- if (ALU8Writeback)
- begin
- if (IsTargetRegA)
- a_nxt = ALU[7:0];
- else
- b_nxt = ALU[7:0];
- end
- rLIC = 1'b1; // Instruction done!
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I1;
- end
- if (IsOneByteInstruction(Inst1)) // This check is probably superfluous. Every inherent instruction is 1 byte on the 6809.
- pc_nxt = pc; // The 6809 auto-reads 2 bytes for every instruction. :( Adjust by not incrementing PC on the 2nd byte read.
- end
-
- TYPE_IMMEDIATE:
- begin
- if (IsSpecialImmediate)
- begin
- if (Inst1 == OPCODE_IMM_ANDCC)
- begin
- pc_nxt = pc_p1;
- cc_nxt = cc & D; //cc_nxt & Inst2_nxt;
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_CC_DONTCARE;
- end
- else if (Inst1 == OPCODE_IMM_ORCC)
- begin
- pc_nxt = pc_p1;
- cc_nxt = cc | D; //cc_nxt | Inst2_nxt;
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_CC_DONTCARE;
- end
- else if ( (Inst1 == OPCODE_IMM_PSHS) | (Inst1 == OPCODE_IMM_PSHU) )
- begin
- pc_nxt = pc_p1;
- tmp_nxt[15] = 1'b0;
- tmp_nxt[14] = Inst1[1]; // Mark whether to save to U or S.
- tmp_nxt[13] = 1'b0; // Not pushing due to an interrupt.
- tmp_nxt[13:8] = 6'H00;
- tmp_nxt[7:0] = Inst2_nxt;
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_PSH_DONTCARE1;
- NextState_nxt = CPUSTATE_FETCH_I1;
- end
- else if ( (Inst1 == OPCODE_IMM_PULS) | (Inst1 == OPCODE_IMM_PULU) )
- begin
- pc_nxt = pc_p1;
- tmp_nxt[15] = 1'b0;
- tmp_nxt[14] = Inst1[1]; // S (0) or U (1) stack in use.
- tmp_nxt[13:8] = 6'H00;
- tmp_nxt[7:0] = Inst2_nxt;
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_PUL_DONTCARE1;
- NextState_nxt = CPUSTATE_FETCH_I1;
- end
- else if (Inst1 == OPCODE_IMM_TFR)
- begin
- // The second byte lists the registers; Top nybble is reg #1, bottom is reg #2.
-
- case (Inst2_nxt[3:0])
- EXGTFR_REG_D:
- {a_nxt,b_nxt} = EXGTFRRegA;
- EXGTFR_REG_X:
- x_nxt = EXGTFRRegA;
- EXGTFR_REG_Y:
- y_nxt = EXGTFRRegA;
- EXGTFR_REG_U:
- u_nxt = EXGTFRRegA;
- EXGTFR_REG_S:
- s_nxt = EXGTFRRegA;
- EXGTFR_REG_PC:
- pc_nxt = EXGTFRRegA;
- EXGTFR_REG_DP:
- dp_nxt = EXGTFRRegA[7:0];
- EXGTFR_REG_A:
- a_nxt = EXGTFRRegA[7:0];
- EXGTFR_REG_B:
- b_nxt = EXGTFRRegA[7:0];
- EXGTFR_REG_CC:
- cc_nxt = EXGTFRRegA[7:0];
- default:
- begin
- end
- endcase
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_TFR_DONTCARE1;
-
- end
- else if (Inst1 == OPCODE_IMM_EXG)
- begin
- // The second byte lists the registers; Top nybble is reg #1, bottom is reg #2.
-
- case (Inst2_nxt[7:4])
- EXGTFR_REG_D:
- {a_nxt,b_nxt} = EXGTFRRegB;
- EXGTFR_REG_X:
- x_nxt = EXGTFRRegB;
- EXGTFR_REG_Y:
- y_nxt = EXGTFRRegB;
- EXGTFR_REG_U:
- u_nxt = EXGTFRRegB;
- EXGTFR_REG_S:
- s_nxt = EXGTFRRegB;
- EXGTFR_REG_PC:
- pc_nxt = EXGTFRRegB;
- EXGTFR_REG_DP:
- dp_nxt = EXGTFRRegB[7:0];
- EXGTFR_REG_A:
- a_nxt = EXGTFRRegB[7:0];
- EXGTFR_REG_B:
- b_nxt = EXGTFRRegB[7:0];
- EXGTFR_REG_CC:
- cc_nxt = EXGTFRRegB[7:0];
- default:
- begin
- end
- endcase
- case (Inst2_nxt[3:0])
- EXGTFR_REG_D:
- {a_nxt,b_nxt} = EXGTFRRegA;
- EXGTFR_REG_X:
- x_nxt = EXGTFRRegA;
- EXGTFR_REG_Y:
- y_nxt = EXGTFRRegA;
- EXGTFR_REG_U:
- u_nxt = EXGTFRRegA;
- EXGTFR_REG_S:
- s_nxt = EXGTFRRegA;
- EXGTFR_REG_PC:
- pc_nxt = EXGTFRRegA;
- EXGTFR_REG_DP:
- dp_nxt = EXGTFRRegA[7:0];
- EXGTFR_REG_A:
- a_nxt = EXGTFRRegA[7:0];
- EXGTFR_REG_B:
- b_nxt = EXGTFRRegA[7:0];
- EXGTFR_REG_CC:
- cc_nxt = EXGTFRRegA[7:0];
- default:
- begin
- end
- endcase
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_EXG_DONTCARE1;
- end
- end
- // Determine if this is an 8-bit ALU operation.
- else if (Is8BitInst)
- begin
- ALU_OP = ALU8Op;
- if (IsTargetRegA)
- ALU_A = a;
- else
- ALU_A = b;
-
- ALU_B = Inst2_nxt;
- ALU_CC = cc;
- cc_nxt = ALU[15:8];
-
- if (ALU8Writeback)
- begin
- if (IsTargetRegA)
- a_nxt = ALU[7:0];
- else
- b_nxt = ALU[7:0];
- end
- rLIC = 1'b1; // Instruction done!
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I1;
- end
- else // Then it must be a 16 bit instruction
- begin
- // 83 SUBD
- // 8C CMPX
- // 8E LDX
- // C3 ADDD
- // CC LDD
- // CE LDU
- // 108E CMPD
- // 108C CMPY
- // 108E LDY
- // 10CE LDS
- // 1183 CMPU
- // 118C CMPS
- // Wow, they were just stuffing them in willy-nilly ...
-
- // LD* 16 bit immediate
- if (IsALU16Opcode)
- begin
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_16IMM_LO;
- end
- // there's a dead zone here; I need an else to take us back to CPUSTATE_FETCHI1 if we want to ignore illegal instructions, to CPUSTATE_DEAD if we want to catch them.
-
- end
-
- end
-
- TYPE_RELATIVE:
- begin
- // Is this a LB** or a B**?
- // If InstPage2 is set, it's a long branch; if clear, a normal branch.
- if ( (InstPage2) || (Inst1 == INST_LBRA) || (Inst1 == INST_LBSR) )
- begin
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_LBRA_OFFSETLOW;
- end
- else
- begin
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_BRA_DONTCARE;
- end
-
- end
- default:
- begin
- CpuState_nxt = CPUSTATE_FETCH_I1;
- end
- endcase
- end
- end
-
-
- CPUSTATE_LBRA_OFFSETLOW:
- begin
- addr_nxt = pc;
- pc_nxt = pc_p1;
- Inst3_nxt = D[7:0];
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_LBRA_DONTCARE;
- end
-
- CPUSTATE_LBRA_DONTCARE:
- begin
- addr_nxt = 16'HFFFF;
- if ( TakeBranch )
- begin
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_LBRA_DONTCARE2;
- end
- else
- begin
- rLIC = 1'b1; // Instruction done!
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I1;
- end
- end
-
- CPUSTATE_BRA_DONTCARE:
- begin
- addr_nxt = 16'HFFFF;
- tmp_nxt = pc;
- if (TakeBranch)
- begin
- pc_nxt = pc + { {8{Inst2[7]}}, Inst2[7:0]}; // Sign-extend the 8 bit offset to 16.
-
- if (Inst1 == INST_BSR)
- begin
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_BSR_DONTCARE1;
- end
- else
- begin
- rLIC = 1'b1; // Instruction done!
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I1;
- end
- end
- else
- begin
- rLIC = 1'b1;
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I1;
- end
-
- end
-
- CPUSTATE_LBRA_DONTCARE2:
- begin
- tmp_nxt= pc;
- addr_nxt = 16'HFFFF;
-
- // Take branch
- pc_nxt = pc + {Inst2[7:0], Inst3[7:0]};
- if (Inst1 == INST_LBSR)
- begin
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_BSR_DONTCARE1;
- end
- else
- begin
- rLIC = 1'b1; // Instruction done!
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I1;
- end
- end
-
- CPUSTATE_BSR_DONTCARE1:
- begin
- addr_nxt = pc;
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_BSR_DONTCARE2;
- end
-
- CPUSTATE_BSR_DONTCARE2:
- begin
- addr_nxt = 16'HFFFF;
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_BSR_RETURNLOW;
- end
-
- CPUSTATE_BSR_RETURNLOW:
- begin
- addr_nxt = s_m1;
- s_nxt = s_m1;
- DOutput[7:0] = tmp[7:0];
- RnWOut = 0;
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_BSR_RETURNHIGH;
- end
-
- CPUSTATE_BSR_RETURNHIGH:
- begin
- addr_nxt = s_m1;
- s_nxt = s_m1;
- DOutput[7:0] = tmp[15:8];
- RnWOut = 0;
- rLIC = 1'b1; // Instruction done!
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I1; // after this, RnWOut must go to 1, and the bus needs the PC placed on it.
- end
-
- CPUSTATE_TFR_DONTCARE1:
- begin
- addr_nxt = 16'HFFFF;
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_TFR_DONTCARE2;
- end
-
- CPUSTATE_TFR_DONTCARE2:
- begin
- addr_nxt = 16'HFFFF;
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_TFR_DONTCARE3;
- end
-
- CPUSTATE_TFR_DONTCARE3:
- begin
- addr_nxt = 16'HFFFF;
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_TFR_DONTCARE4;
- end
-
- CPUSTATE_TFR_DONTCARE4:
- begin
- addr_nxt = 16'HFFFF;
- rAVMA = 1'b1;
- rLIC = 1'b1; // Instruction done!
- CpuState_nxt = CPUSTATE_FETCH_I1;
- end
-
- CPUSTATE_EXG_DONTCARE1:
- begin
- addr_nxt = 16'HFFFF;
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_EXG_DONTCARE2;
- end
-
- CPUSTATE_EXG_DONTCARE2:
- begin
- addr_nxt = 16'HFFFF;
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_EXG_DONTCARE3;
- end
-
- CPUSTATE_EXG_DONTCARE3:
- begin
- addr_nxt = 16'HFFFF;
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_EXG_DONTCARE4;
- end
-
- CPUSTATE_EXG_DONTCARE4:
- begin
- addr_nxt = 16'HFFFF;
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_EXG_DONTCARE5;
- end
-
- CPUSTATE_EXG_DONTCARE5:
- begin
- rAVMA = 1'b0;
- addr_nxt = 16'HFFFF;
- CpuState_nxt = CPUSTATE_EXG_DONTCARE6;
- end
-
- CPUSTATE_EXG_DONTCARE6:
- begin
- addr_nxt = 16'HFFFF;
- rAVMA = 1'b1;
- rLIC = 1'b1; // Instruction done!
- CpuState_nxt = CPUSTATE_FETCH_I1;
- end
-
- CPUSTATE_ABX_DONTCARE:
- begin
- addr_nxt = 16'HFFFF;
- rAVMA = 1'b1;
- rLIC = 1'b1; // Instruction done!
- CpuState_nxt = CPUSTATE_FETCH_I1;
- end
-
- CPUSTATE_RTS_HI:
- begin
- addr_nxt = s;
- s_nxt = s_p1;
- pc_nxt[15:8] = D[7:0];
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_RTS_LO;
- end
-
- CPUSTATE_RTS_LO:
- begin
- addr_nxt = s;
- s_nxt = s_p1;
- pc_nxt[7:0] = D[7:0];
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_RTS_DONTCARE2;
- end
-
- CPUSTATE_RTS_DONTCARE2:
- begin
- addr_nxt = 16'HFFFF;
- rLIC = 1'b1; // Instruction done!
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I1;
- end
-
- CPUSTATE_16IMM_LO:
- begin
- addr_nxt = pc;
- pc_nxt = pc_p1;
-
- ALU16_OP = ALU16Opcode;
- ALU16_CC = cc;
- ALU16_B = {Inst2, D[7:0]};
-
- case (ALU16Reg)
- ALU16_REG_X:
- ALU16_A = x;
- ALU16_REG_D:
- ALU16_A = {a, b};
- ALU16_REG_Y:
- ALU16_A = y;
- ALU16_REG_U:
- ALU16_A = u;
- ALU16_REG_S:
- ALU16_A = s;
- default:
- ALU16_A = 16'H0;
- endcase
-
- if (ALU16OpWriteback)
- begin
- case (ALU16Reg)
- ALU16_REG_X:
- {cc_nxt, x_nxt} = ALU16;
- ALU16_REG_D:
- {cc_nxt, a_nxt, b_nxt} = ALU16;
- ALU16_REG_Y:
- {cc_nxt, y_nxt} = ALU16;
- ALU16_REG_U:
- {cc_nxt, u_nxt} = ALU16;
- ALU16_REG_S:
- {cc_nxt, s_nxt} = ALU16;
- default:
- begin
- end
- endcase
- end
- else
- cc_nxt = ALU16[23:16];
-
- if (ALU16_OP == ALUOP16_LD)
- begin
- rLIC = 1'b1; // Instruction done!
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I1;
- end
- else
- begin
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_16IMM_DONTCARE;
- end
- end
-
- CPUSTATE_DIRECT_DONTCARE:
- begin
- addr_nxt = 16'HFFFF;
-
- if (IsJMP(Inst1))
- begin
- pc_nxt = ea;
- rLIC = 1'b1; // Instruction done!
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I1;
- end
- else
- begin
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_ALU_EA;
- end
- end
-
- CPUSTATE_ALU_EA:
- begin
-
- // Is Figure 18/5 Column 2? JMP (not Immediate Mode)
- // This actually isn't done here. All checks passing in to ALU_EA should check for a JMP; FIXME EVERYWHERE
-
- // Is Figure 18/5 Column 8? TST (not immediate mode)
- // THIS IS BURIED IN THE COLUMN 3 section with comparisons to ALUOP_TST.
-
- // Is Figure 18/5 Column 3?
- if (IsALU8Set1(Inst1))
- begin
- addr_nxt = ea;
-
- ALU_OP = ALU8Op;
- ALU_B = D[7:0];
- ALU_CC = cc;
-
- if (IsTargetRegA)
- ALU_A = a;
- else
- ALU_A = b;
-
- cc_nxt = ALU[15:8];
-
- if ( (ALU8Writeback) )
- begin
- if (IsTargetRegA)
- a_nxt = ALU[7:0];
- else
- b_nxt = ALU[7:0];
- end
-
- rLIC = 1'b1; // Instruction done!
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I1;
- end
-
- // Is Figure 18/5 Column 4? (Store, 8 bits)
- else if (IsStore8)
- begin
- addr_nxt = ea;
- RnWOut = 0; // write
-
- ALU_OP = ALUOP_LD; // load has the same CC characteristics as store
- ALU_A = 8'H00;
- ALU_CC = cc;
-
- case (Store8RegisterNum)
- ST8_REG_A:
- begin
- DOutput = a;
- ALU_B = a;
- end
- ST8_REG_B:
- begin
- DOutput = b;
- ALU_B = b;
- end
-
-
- endcase
-
- cc_nxt = ALU[15:8];
-
- rLIC = 1'b1; // Instruction done!
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I1;
- end
-
- // Is Figure 18/5 Column 5? (Load, 16 bits)
- else if (IsALU16Opcode & (ALU16Opcode == ALUOP16_LD))
- begin
- addr_nxt = ea;
- ea_nxt = ea_p1;
-
- case (ALU16Reg)
- ALU16_REG_X:
- x_nxt[15:8] = D[7:0];
- ALU16_REG_D:
- a_nxt = D[7:0];
- ALU16_REG_Y:
- y_nxt[15:8] = D[7:0];
- ALU16_REG_S:
- s_nxt[15:8] = D[7:0];
- ALU16_REG_U:
- u_nxt[15:8] = D[7:0];
- default:
- begin
- end
- endcase
- rAVMA = 1'b1;
- rBUSY = 1'b1;
- CpuState_nxt = CPUSTATE_LD16_LO;
-
- end
-
- // Is Figure 18/5 Column 6? (Store, 16 bits)
- else if (IsStore16)
- begin
- addr_nxt = ea;
- ea_nxt = ea_p1;
-
- ALU16_OP = ALUOP16_LD; // LD and ST have the same CC characteristics
- ALU16_CC = cc;
- ALU16_A = 8'H00;
-
- case (StoreRegisterNum)
- ST16_REG_X:
- begin
- DOutput[7:0] = x[15:8];
- ALU16_B = x;
- end
- ST16_REG_Y:
- begin
- DOutput[7:0] = y[15:8];
- ALU16_B = y;
- end
- ST16_REG_U:
- begin
- DOutput[7:0] = u[15:8];
- ALU16_B = u;
- end
- ST16_REG_S:
- begin
- DOutput[7:0] = s[15:8];
- ALU16_B = s;
- end
- ST16_REG_D:
- begin
- DOutput[7:0] = a[7:0];
- ALU16_B = {a,b};
- end
- default:
- begin
- end
- endcase
-
- cc_nxt = ALU16[23:16];
-
- RnWOut = 0; // Write
- rAVMA = 1'b1;
- rBUSY = 1'b1;
- CpuState_nxt = CPUSTATE_ST16_LO;
- end
-
- // Is Figure 18/5 Column 7?
- else if (IsALU8Set0(Inst1))
- begin
- // These are registerless instructions, ala
- // ASL, ASR, CLR, COM, DEC, INC, (LSL), LSR, NEG, ROL, ROR
- // and TST (special!)
- // They require READ, Modify (the operation above), WRITE. Between the Read and the Write cycles, there's actually a /VMA
- // cycle where the 6809 likely did the operation. We'll include a /VMA cycle for accuracy, but we'll do the work primarily in the first cycle.
- addr_nxt = ea;
-
- ALU_OP = ALU8Op;
- ALU_A = D[7:0];
- ALU_CC = cc;
- tmp_nxt[15:8] = cc; // for debug only
- tmp_nxt[7:0] = ALU[7:0];
- cc_nxt = ALU[15:8];
- if (ALU8Op == ALUOP_TST)
- begin
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_TST_DONTCARE1;
- end
- else
- begin
- rAVMA = 1'b0;
- rBUSY = 1'b1;
- CpuState_nxt = CPUSTATE_ALU_DONTCARE;
- end
-
- end
-
- // Is Figure 18/5 Column 8? TST
- // NOTE:
- // THIS IS BURIED IN THE COLUMN 3 section with comparisons to ALUOP_TST. [Directly above.]
-
-
- // Is Figure 18/5 Column 9? (16-bit ALU ops, non-load)
- else if (IsALU16Opcode && (ALU16Opcode != ALUOP16_LD) && ((Inst1 < 8'H30) || (Inst1 > 8'H33)) ) // 30-33 = LEAX, LEAY, LEAS, LEAU; don't include them here.
- begin
- addr_nxt = ea;
- ea_nxt = ea_p1;
-
- tmp_nxt[15:8] = D[7:0];
- rAVMA = 1'b1;
- rBUSY = 1'b1;
- CpuState_nxt = CPUSTATE_ALU16_LO;
-
- end
-
- // Is Figure 18/5 Column 10? JSR (not Immediate Mode)
- else if ((Inst1 == 8'H9D) || (Inst1 == 8'HAD) || (Inst1 == 8'HBD)) // JSR
- begin
- pc_nxt = ea;
- addr_nxt = ea;
- tmp_nxt = pc;
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_JSR_DONTCARE;
- end
- // Is Figure 18/5 Column 11? LEA(X,Y,S,U)
- else if ((Inst1 >= 8'H30) && (Inst1<= 8'H33))
- begin
- addr_nxt = 16'HFFFF; // Ack, actually a valid cycle, this isn't a dontcare (/VMA) cycle!
-
- ALU16_OP = ALU16Opcode;
- ALU16_CC = cc;
- ALU16_A = ea;
-
- case (ALU16Reg)
- ALU16_REG_X:
- {cc_nxt, x_nxt} = ALU16;
- ALU16_REG_Y:
- {cc_nxt, y_nxt} = ALU16;
- ALU16_REG_U:
- u_nxt = ALU16[15:0];
- ALU16_REG_S:
- s_nxt = ALU16[15:0];
- default:
- begin
- end
- endcase
-
- rLIC = 1'b1; // Instruction done!
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I1;
-
- end
-
- end
-
-
- CPUSTATE_ALU_DONTCARE:
- begin
- addr_nxt = 16'HFFFF;
- rAVMA = 1'b1;
- rBUSY = 1'b1; // We do nothing here, but on the real 6809, they did the modify phase here. :|
- CpuState_nxt = CPUSTATE_ALU_WRITEBACK;
- end
-
- CPUSTATE_ALU_WRITEBACK:
- begin
- addr_nxt = ea;
- RnWOut = 0; // Write
- DOutput = tmp[7:0];
- rLIC = 1'b1; // Instruction done!
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I1;
- end
-
- CPUSTATE_LD16_LO:
- begin
- addr_nxt = ea;
-
- case (ALU16Reg)
- ALU16_REG_X:
- begin
- x_nxt[7:0] = D[7:0];
- ALU16_B[15:8] = x[15:8];
- end
- ALU16_REG_D:
- begin
- b_nxt = D[7:0];
- ALU16_B[15:8] = a;
- end
- ALU16_REG_Y:
- begin
- y_nxt[7:0] = D[7:0];
- ALU16_B[15:8] = y[15:8];
- end
- ALU16_REG_S:
- begin
- s_nxt[7:0] = D[7:0];
- ALU16_B[15:8] = s[15:8];
- end
- ALU16_REG_U:
- begin
- u_nxt[7:0] = D[7:0];
- ALU16_B[15:8] = u[15:8];
- end
- default:
- begin
- end
-
- endcase
-
- ALU16_OP = ALU16Opcode;
- ALU16_CC = cc;
- ALU16_A = 8'H00;
- ALU16_B[7:0] = D[7:0];
- cc_nxt = ALU16[23:16];
-
- rLIC = 1'b1; // Instruction done!
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I1;
- end
-
- CPUSTATE_ST16_LO:
- begin
- addr_nxt = ea;
- ea_nxt = ea_p1;
- case (StoreRegisterNum)
- ST16_REG_X:
- DOutput[7:0] = x[7:0];
- ST16_REG_Y:
- DOutput[7:0] = y[7:0];
- ST16_REG_U:
- DOutput[7:0] = u[7:0];
- ST16_REG_S:
- DOutput[7:0] = s[7:0];
- ST16_REG_D:
- DOutput[7:0] = b[7:0];
- default:
- begin
- end
- endcase
- RnWOut = 0; // write
-
- rLIC = 1'b1; // Instruction done!
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I1;
- end
-
- CPUSTATE_ALU16_LO:
- begin
- addr_nxt = ea;
-
- ALU16_OP = ALU16Opcode;
- ALU16_CC = cc;
-
- ALU16_B = {tmp[15:8], D[7:0]};
-
- case (ALU16Reg)
- ALU16_REG_X:
- ALU16_A = x;
- ALU16_REG_D:
- ALU16_A = {a, b};
- ALU16_REG_Y:
- ALU16_A = y;
- ALU16_REG_S:
- ALU16_A = s;
- ALU16_REG_U:
- ALU16_A = u;
- default:
- ALU16_A = 16'H0;
-
- endcase
-
- if (ALU16OpWriteback)
- begin
- case (ALU16Reg)
- ALU16_REG_X:
- {cc_nxt, x_nxt} = ALU16;
- ALU16_REG_D:
- {cc_nxt, a_nxt, b_nxt} = ALU16;
- ALU16_REG_Y:
- {cc_nxt, y_nxt} = ALU16;
- ALU16_REG_U:
- {cc_nxt, u_nxt} = ALU16;
- ALU16_REG_S:
- {cc_nxt, s_nxt} = ALU16;
- default:
- begin
- end
- endcase
- end
- else
- cc_nxt = ALU16[23:16];
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_ALU16_DONTCARE;
- end
-
- CPUSTATE_ALU16_DONTCARE:
- begin
- addr_nxt = 16'HFFFF;
- rLIC = 1'b1; // Instruction done!
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I1;
- end
-
-
- CPUSTATE_JSR_DONTCARE:
- begin
- addr_nxt = 16'HFFFF;
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_JSR_RETLO;
- end
-
- CPUSTATE_JSR_RETLO:
- begin
- addr_nxt = s_m1;
- s_nxt = s_m1;
- RnWOut = 0;
- DOutput = tmp[7:0];
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_JSR_RETHI;
- end
-
- CPUSTATE_JSR_RETHI:
- begin
- addr_nxt = s_m1;
- s_nxt = s_m1;
- RnWOut = 0;
- DOutput = tmp[15:8];
- rLIC = 1'b1; // Instruction done!
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I1;
- end
-
- CPUSTATE_EXTENDED_ADDRLO:
- begin
- addr_nxt = pc;
- pc_nxt = pc_p1;
- ea_nxt[7:0] = D[7:0];
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_EXTENDED_DONTCARE;
- end
-
- CPUSTATE_EXTENDED_DONTCARE:
- begin
- addr_nxt = 16'HFFFF;
- if (IsJMP(Inst1))
- begin
- pc_nxt = ea;
- rLIC = 1'b1; // Instruction done!
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I1;
- end
- else
- begin
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_ALU_EA;
- end
- end
-
- CPUSTATE_INDEXED_BASE:
- begin
- addr_nxt = pc;
-
- Inst3_nxt = D[7:0];
-
- case (IndexedRegister)
- IDX_REG_X:
- ALU16_A = x;
- IDX_REG_Y:
- ALU16_A = y;
- IDX_REG_U:
- ALU16_A = u;
- IDX_REG_S:
- ALU16_A = s;
- IDX_REG_PC:
- ALU16_A = pc_p1;
- default:
- ALU16_A = 16'H0;
- endcase
- ALU16_OP = ALUOP16_ADD;
-
- case (IndexedMode)
- IDX_MODE_NOOFFSET:
- begin
- case (IndexedRegister)
- IDX_REG_X:
- ea_nxt = x;
- IDX_REG_Y:
- ea_nxt = y;
- IDX_REG_U:
- ea_nxt = u;
- IDX_REG_S:
- ea_nxt = s;
- default:
- ea_nxt = 16'H0;
- endcase
-
- if (IndexedIndirect)
- begin
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_INDIRECT_HI;
- end
- else
- begin
- if (IsJMP(Inst1))
- begin
- pc_nxt = ea_nxt;
- rLIC = 1'b1; // Instruction done!
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I1;
- end
- else
- begin
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_ALU_EA;
- end
- end
- end
-
- IDX_MODE_5BIT_OFFSET:
- begin
- // The offset is the bottom 5 bits of the Index Postbyte, which is Inst2 here.
- // We'll sign-extend it to 16 bits.
- ALU16_B = { {11{Inst2[4]}}, Inst2[4:0] };
- ea_nxt = ALU16[15:0];
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_IDX_DONTCARE3;
- end
-
-
- IDX_MODE_8BIT_OFFSET_PC:
- begin
- ALU16_B = { {8{D[7]}}, D[7:0] };
- pc_nxt = pc_p1;
- ea_nxt = ALU16[15:0];
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_IDX_DONTCARE3;
- end
-
- IDX_MODE_8BIT_OFFSET:
- begin
- ALU16_B = { {8{D[7]}}, D[7:0] };
- pc_nxt = pc_p1;
- ea_nxt = ALU16[15:0];
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_IDX_DONTCARE3;
- end
-
- IDX_MODE_A_OFFSET:
- begin
- ALU16_B = { {8{a[7]}}, a[7:0] };
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_IDX_DONTCARE3;
- ea_nxt = ALU16[15:0];
- end
-
- IDX_MODE_B_OFFSET:
- begin
- ALU16_B = { {8{b[7]}}, b[7:0] };
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_IDX_DONTCARE3;
- ea_nxt = ALU16[15:0];
- end
-
- IDX_MODE_D_OFFSET:
- begin
- ALU16_B = {a, b};
-
- ea_nxt = ALU16[15:0];
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_IDX_DOFF_DONTCARE1;
- end
-
- IDX_MODE_POSTINC1:
- begin
- ALU16_B = 16'H1;
- ea_nxt = ALU16_A;
- case (IndexedRegister)
- IDX_REG_X:
- x_nxt = ALU16[15:0];
- IDX_REG_Y:
- y_nxt = ALU16[15:0];
- IDX_REG_U:
- u_nxt = ALU16[15:0];
- IDX_REG_S:
- s_nxt = ALU16[15:0];
- default:
- begin
- end
- endcase
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_IDX_16OFF_DONTCARE2;
- end
-
- IDX_MODE_POSTINC2:
- begin
- ALU16_B = 16'H2;
- ea_nxt = ALU16_A;
- case (IndexedRegister)
- IDX_REG_X:
- x_nxt = ALU16[15:0];
- IDX_REG_Y:
- y_nxt = ALU16[15:0];
- IDX_REG_U:
- u_nxt = ALU16[15:0];
- IDX_REG_S:
- s_nxt = ALU16[15:0];
- default:
- begin
- end
- endcase
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_IDX_16OFF_DONTCARE0;
- end
-
- IDX_MODE_PREDEC1:
- begin
- ALU16_B = 16'HFFFF; // -1
- case (IndexedRegister)
- IDX_REG_X:
- x_nxt = ALU16[15:0];
- IDX_REG_Y:
- y_nxt = ALU16[15:0];
- IDX_REG_U:
- u_nxt = ALU16[15:0];
- IDX_REG_S:
- s_nxt = ALU16[15:0];
- default:
- begin
- end
- endcase
- ea_nxt = ALU16[15:0];
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_IDX_16OFF_DONTCARE2;
- end
-
- IDX_MODE_PREDEC2:
- begin
- ALU16_B = 16'HFFFE; // -2
- case (IndexedRegister)
- IDX_REG_X:
- x_nxt = ALU16[15:0];
- IDX_REG_Y:
- y_nxt = ALU16[15:0];
- IDX_REG_U:
- u_nxt = ALU16[15:0];
- IDX_REG_S:
- s_nxt = ALU16[15:0];
- default:
- begin
- end
- endcase
- ea_nxt = ALU16[15:0];
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_IDX_16OFF_DONTCARE0;
- end
-
- IDX_MODE_16BIT_OFFSET_PC:
- begin
- tmp_nxt[15:8] = D[7:0];
- pc_nxt = pc_p1;
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_IDX_16OFFSET_LO;
- end
-
- IDX_MODE_16BIT_OFFSET:
- begin
- tmp_nxt[15:8] = D[7:0];
- pc_nxt = pc_p1;
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_IDX_16OFFSET_LO;
- end
-
- IDX_MODE_EXTENDED_INDIRECT:
- begin
- ea_nxt[15:8] = D[7:0];
- pc_nxt = pc_p1;
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_IDX_EXTIND_LO;
- end
-
- default:
- begin
- rLIC = 1'b1;
- CpuState_nxt = PostIllegalState;
- end
-
- endcase
- end
-
- CPUSTATE_IDX_OFFSET_LO:
- begin
- tmp_nxt[7:0] = D[7:0];
- addr_nxt = pc;
- pc_nxt = pc_p1;
- ALU16_B = tmp_nxt;
-
- case (IndexedRegister)
- IDX_REG_X:
- ALU16_A = x;
- IDX_REG_Y:
- ALU16_A = y;
- IDX_REG_U:
- ALU16_A = u;
- IDX_REG_S:
- ALU16_A = s;
- IDX_REG_PC:
- ALU16_A = pc;
- default:
- ALU16_A = 16'H0;
- endcase
- ALU16_OP = ALUOP16_ADD;
-
- ea_nxt = ALU16[15:0];
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_IDX_16OFF_DONTCARE1;
- end
-
-
- CPUSTATE_IDX_DONTCARE3:
- begin
- addr_nxt = 16'HFFFF;
- if (IndexedIndirect)
- begin
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_INDIRECT_HI;
- end
- else
- begin
- if (IsJMP(Inst1))
- begin
- pc_nxt = ea;
- rLIC = 1'b1; // Instruction done!
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I1;
- end
- else
- begin
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_ALU_EA;
- end
- end
-
- end
-
- CPUSTATE_IDX_16OFFSET_LO:
- begin
- addr_nxt = pc;
- pc_nxt = pc_p1;
-
- case (IndexedRegister)
- IDX_REG_X:
- ALU16_A = x;
- IDX_REG_Y:
- ALU16_A = y;
- IDX_REG_U:
- ALU16_A = u;
- IDX_REG_S:
- ALU16_A = s;
- IDX_REG_PC:
- ALU16_A = pc_nxt; // Whups; tricky; not part of the actual pattern
- default:
- ALU16_A = x; // Default to something
- endcase
-
- ALU16_OP = ALUOP16_ADD;
-
- ALU16_B = {tmp[15:8], D[7:0]};
-
- ea_nxt = ALU16[15:0];
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_IDX_16OFF_DONTCARE1;
- end
-
- CPUSTATE_IDX_16OFF_DONTCARE1:
- begin
- addr_nxt = pc;
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_IDX_16OFF_DONTCARE2;
- end
-
- CPUSTATE_IDX_16OFF_DONTCARE0:
- begin
- addr_nxt = 16'HFFFF;
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_IDX_16OFF_DONTCARE2;
- end
-
- CPUSTATE_IDX_16OFF_DONTCARE2:
- begin
- addr_nxt = 16'HFFFF;
- if (IndexedRegister == IDX_REG_PC)
- begin
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_IDX_PC16OFF_DONTCARE;
- end
- else
- begin
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_IDX_16OFF_DONTCARE3;
- end
- end
-
- CPUSTATE_IDX_PC16OFF_DONTCARE:
- begin
- addr_nxt = 16'HFFFF;
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_IDX_16OFF_DONTCARE3;
- end
-
-
- CPUSTATE_IDX_16OFF_DONTCARE3:
- begin
- addr_nxt = 16'HFFFF;
- if (IndexedIndirect)
- begin
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_INDIRECT_HI;
- end
- else
- begin
- if (IsJMP(Inst1))
- begin
- pc_nxt = ea;
- rLIC = 1'b1; // Instruction done!
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I1;
- end
- else
- begin
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_ALU_EA;
- end
- end
- end
-
- CPUSTATE_IDX_DOFF_DONTCARE1:
- begin
- addr_nxt = pc_p1;
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_IDX_DOFF_DONTCARE2;
- end
-
- CPUSTATE_IDX_DOFF_DONTCARE2:
- begin
- addr_nxt = pc_p2;
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_IDX_16OFF_DONTCARE2;
- end
-
- CPUSTATE_IDX_DOFF_DONTCARE3:
- begin
- addr_nxt = pc_p3;
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_IDX_DOFF_DONTCARE2;
- end
-
- CPUSTATE_IDX_EXTIND_LO:
- begin
- ea_nxt[7:0] = D[7:0];
- addr_nxt = pc;
- pc_nxt = pc_p1;
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_IDX_EXTIND_DONTCARE;
- end
-
- CPUSTATE_IDX_EXTIND_DONTCARE:
- begin
- addr_nxt = pc;
- if (IndexedIndirect)
- begin
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_INDIRECT_HI;
- end
- else
- begin
- if (IsJMP(Inst1))
- begin
- pc_nxt = ea;
- rLIC = 1'b1; // Instruction done!
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I1;
- end
- else
- begin
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_ALU_EA;
- end
- end
- end
-
- CPUSTATE_INDIRECT_HI:
- begin
- addr_nxt = ea;
- tmp_nxt[15:8] = D[7:0];
- rAVMA = 1'b1;
- rBUSY = 1'b1;
- CpuState_nxt = CPUSTATE_INDIRECT_LO;
- end
-
- CPUSTATE_INDIRECT_LO:
- begin
- addr_nxt = ea_p1;
- ea_nxt[15:8] = tmp_nxt[15:8];
- ea_nxt[7:0] = D[7:0];
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_INDIRECT_DONTCARE;
- end
-
- CPUSTATE_INDIRECT_DONTCARE:
- begin
- addr_nxt = 16'HFFFF;
- if (IsJMP(Inst1))
- begin
- pc_nxt = ea;
- rLIC = 1'b1; // Instruction done!
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I1;
- end
- else
- begin
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_ALU_EA;
- end
- end
-
- CPUSTATE_MUL_ACTION:
- begin
- addr_nxt = 16'HFFFF;
- rAVMA = 1'b0;
- // tmp = result
- // ea = additor (the shifted multiplicand)
- // a = counter
- // b is the multiplier (which gets shifted right)
- if (a != 8'H00)
- begin
- if (b[0])
- begin
- tmp_nxt = tmp + ea;
- end
- ea_nxt = {ea[14:0], 1'b0};
- b_nxt = {1'b0, b[7:1]};
- a_nxt = a - 8'H1;
- end
- else
- begin
- {a_nxt, b_nxt} = tmp;
-
- cc_nxt[CC_Z_BIT] = (tmp == 0);
- cc_nxt[CC_C_BIT] = tmp[7];
- rLIC = 1'b1; // Instruction done!
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I1;
- end
- end
-
- CPUSTATE_PSH_DONTCARE1:
- begin
- addr_nxt = 16'HFFFF;
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_PSH_DONTCARE2;
- end
-
- CPUSTATE_PSH_DONTCARE2:
- begin
- addr_nxt = 16'HFFFF;
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_PSH_DONTCARE3;
- end
-
- CPUSTATE_PSH_DONTCARE3:
- begin
- addr_nxt = (Inst1[1]) ? u : s;
-
- CpuState_nxt = CPUSTATE_PSH_ACTION;
- end
-
- CPUSTATE_PSH_ACTION:
- begin
- rAVMA = 1'b1;
- if (tmp[7] & ~(tmp[15])) // PC_LO
- begin
- addr_nxt = (tmp[14]) ? u_m1 : s_m1;
- if (tmp[14])
- u_nxt = u_m1;
- else
- s_nxt = s_m1;
- DOutput = pc[7:0];
- RnWOut = 1'b0; // write
- tmp_nxt[15] = 1'b1;
- end
- else if (tmp[7] & (tmp[15])) // PC_HI
- begin
- addr_nxt = (tmp[14]) ? u_m1 : s_m1;
- if (tmp[14])
- u_nxt = u_m1;
- else
- s_nxt = s_m1;
- DOutput = pc[15:8];
- RnWOut = 1'b0; // write
- tmp_nxt[7] = 1'b0;
- tmp_nxt[15] = 1'b0;
- end
- else if (tmp[6] & ~(tmp[15])) // U/S_LO
- begin
- addr_nxt = (tmp[14]) ? u_m1 : s_m1;
- if (tmp[14])
- u_nxt = u_m1;
- else
- s_nxt = s_m1;
- DOutput = (tmp[14]) ? s[7:0] : u[7:0];
- RnWOut = 1'b0; // write
- tmp_nxt[15] = 1'b1;
- end
- else if (tmp[6] & (tmp[15])) // U/S_HI
- begin
- addr_nxt = (tmp[14]) ? u_m1 : s_m1;
- if (tmp[14])
- u_nxt = u_m1;
- else
- s_nxt = s_m1;
- DOutput = (tmp[14]) ? s[15:8] : u[15:8];
- RnWOut = 1'b0; // write
- tmp_nxt[6] = 1'b0;
- tmp_nxt[15] = 1'b0;
- end
- else if (tmp[5] & ~(tmp[15])) // Y_LO
- begin
- addr_nxt = (tmp[14]) ? u_m1 : s_m1;
- if (tmp[14])
- u_nxt = u_m1;
- else
- s_nxt = s_m1;
- DOutput = y[7:0];
- RnWOut = 1'b0; // write
- tmp_nxt[15] = 1'b1;
- end
- else if (tmp[5] & (tmp[15])) // Y_HI
- begin
- addr_nxt = (tmp[14]) ? u_m1 : s_m1;
- if (tmp[14])
- u_nxt = u_m1;
- else
- s_nxt = s_m1;
- DOutput = y[15:8];
- RnWOut = 1'b0; // write
- tmp_nxt[5] = 1'b0;
- tmp_nxt[15] = 1'b0;
- end
- else if (tmp[4] & ~(tmp[15])) // X_LO
- begin
- addr_nxt = (tmp[14]) ? u_m1 : s_m1;
- if (tmp[14])
- u_nxt = u_m1;
- else
- s_nxt = s_m1;
- DOutput = x[7:0];
- RnWOut = 1'b0; // write
- tmp_nxt[15] = 1'b1;
- end
- else if (tmp[4] & (tmp[15])) // X_HI
- begin
- addr_nxt = (tmp[14]) ? u_m1 : s_m1;
- if (tmp[14])
- u_nxt = u_m1;
- else
- s_nxt = s_m1;
- DOutput = x[15:8];
- RnWOut = 1'b0; // write
- tmp_nxt[4] = 1'b0;
- tmp_nxt[15] = 1'b0;
- end
- else if (tmp[3]) // DP
- begin
- addr_nxt = (tmp[14]) ? u_m1 : s_m1;
- if (tmp[14])
- u_nxt = u_m1;
- else
- s_nxt = s_m1;
- DOutput = dp;
- RnWOut = 1'b0; // write
- tmp_nxt[3] = 1'b0;
- end
- else if (tmp[2]) // B
- begin
- addr_nxt = (tmp[14]) ? u_m1 : s_m1;
- if (tmp[14])
- u_nxt = u_m1;
- else
- s_nxt = s_m1;
- DOutput = b;
- RnWOut = 1'b0; // write
- tmp_nxt[2] = 1'b0;
- end
- else if (tmp[1]) // A
- begin
- addr_nxt = (tmp[14]) ? u_m1 : s_m1;
- if (tmp[14])
- u_nxt = u_m1;
- else
- s_nxt = s_m1;
- DOutput = a;
- RnWOut = 1'b0; // write
- tmp_nxt[1] = 1'b0;
- end
- else if (tmp[0]) // CC
- begin
- addr_nxt = (tmp[14]) ? u_m1 : s_m1;
- if (tmp[14])
- u_nxt = u_m1;
- else
- s_nxt = s_m1;
- DOutput = cc;
- RnWOut = 1'b0; // write
- tmp_nxt[0] = 1'b0;
- end
- if (tmp[13]) // Then we're pushing for an IRQ, and LIC is supposed to be set.
- rLIC = 1'b1;
- if (tmp_nxt[7:0] == 8'H00)
- begin
- if (NextState == CPUSTATE_FETCH_I1)
- begin
- rAVMA = 1'b1;
- rLIC = 1'b1;
- end
- else
- rAVMA = 1'b0;
- CpuState_nxt = NextState;
- end
- end
-
- CPUSTATE_PUL_DONTCARE1:
- begin
- addr_nxt = 16'HFFFF;
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_PUL_DONTCARE2;
- end
-
- CPUSTATE_PUL_DONTCARE2:
- begin
- addr_nxt = 16'HFFFF;
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_PUL_ACTION;
- end
-
- CPUSTATE_PUL_ACTION:
- begin
- rAVMA = 1'b1;
- if (tmp[0]) // CC
- begin
- addr_nxt = (tmp[14]) ? u : s;
- if (tmp[14])
- u_nxt = u_p1;
- else
- s_nxt = s_p1;
- cc_nxt = D[7:0];
- if (tmp[12] == 1'b1) // This pull is from an RTI, the E flag comes from the retrieved CC, and set the tmp_nxt accordingly, indicating what other registers to retrieve
- begin
- if (D[CC_E_BIT])
- tmp_nxt[7:0] = 8'HFE; // Retrieve all registers (ENTIRE) [CC is already retrieved]
- else
- tmp_nxt[7:0] = 8'H80; // Retrieve PC and CC [CC is already retrieved]
- end
- else
- tmp_nxt[0] = 1'b0;
- end
- else if (tmp[1]) // A
- begin
- addr_nxt = (tmp[14]) ? u : s;
- if (tmp[14])
- u_nxt = u_p1;
- else
- s_nxt = s_p1;
- a_nxt = D[7:0];
- tmp_nxt[1] = 1'b0;
- end
- else if (tmp[2]) // B
- begin
- addr_nxt = (tmp[14]) ? u : s;
- if (tmp[14])
- u_nxt = u_p1;
- else
- s_nxt = s_p1;
- b_nxt = D[7:0];
- tmp_nxt[2] = 1'b0;
- end
- else if (tmp[3]) // DP
- begin
- addr_nxt = (tmp[14]) ? u : s;
- if (tmp[14])
- u_nxt = u_p1;
- else
- s_nxt = s_p1;
- dp_nxt = D[7:0];
- tmp_nxt[3] = 1'b0;
- end
- else if (tmp[4] & (~tmp[15])) // X_HI
- begin
- addr_nxt = (tmp[14]) ? u : s;
- if (tmp[14])
- u_nxt = u_p1;
- else
- s_nxt = s_p1;
- x_nxt[15:8] = D[7:0];
- tmp_nxt[15] = 1'b1;
- end
- else if (tmp[4] & tmp[15]) // X_LO
- begin
- addr_nxt = (tmp[14]) ? u : s;
- if (tmp[14])
- u_nxt = u_p1;
- else
- s_nxt = s_p1;
- x_nxt[7:0] = D[7:0];
- tmp_nxt[4] = 1'b0;
- tmp_nxt[15] = 1'b0;
- end
- else if (tmp[5] & (~tmp[15])) // Y_HI
- begin
- addr_nxt = (tmp[14]) ? u : s;
- if (tmp[14])
- u_nxt = u_p1;
- else
- s_nxt = s_p1;
- y_nxt[15:8] = D[7:0];
- tmp_nxt[15] = 1'b1;
- end
- else if (tmp[5] & tmp[15]) // Y_LO
- begin
- addr_nxt = (tmp[14]) ? u : s;
- if (tmp[14])
- u_nxt = u_p1;
- else
- s_nxt = s_p1;
- y_nxt[7:0] = D[7:0];
- tmp_nxt[5] = 1'b0;
- tmp_nxt[15] = 1'b0;
- end
- else if (tmp[6] & (~tmp[15])) // U/S_HI
- begin
- addr_nxt = (tmp[14]) ? u : s;
- if (tmp[14])
- u_nxt = u_p1;
- else
- s_nxt = s_p1;
- if (tmp[14])
- s_nxt[15:8] = D[7:0];
- else
- u_nxt[15:8] = D[7:0];
- tmp_nxt[15] = 1'b1;
- end
- else if (tmp[6] & tmp[15]) // U/S_LO
- begin
- addr_nxt = (tmp[14]) ? u : s;
- if (tmp[14])
- u_nxt = u_p1;
- else
- s_nxt = s_p1;
- if (tmp[14])
- s_nxt[7:0] = D[7:0];
- else
- u_nxt[7:0] = D[7:0];
- tmp_nxt[6] = 1'b0;
- tmp_nxt[15] = 1'b0;
- end
- else if (tmp[7] & (~tmp[15])) // PC_HI
- begin
- addr_nxt = (tmp[14]) ? u : s;
- if (tmp[14])
- u_nxt = u_p1;
- else
- s_nxt = s_p1;
- pc_nxt[15:8] = D[7:0];
- tmp_nxt[15] = 1'b1;
- end
- else if (tmp[7] & tmp[15]) // PC_LO
- begin
- addr_nxt = (tmp[14]) ? u : s;
- if (tmp[14])
- u_nxt = u_p1;
- else
- s_nxt = s_p1;
- pc_nxt[7:0] = D[7:0];
- tmp_nxt[7] = 1'b0;
- tmp_nxt[15] = 1'b0;
- end
- else
- begin
- addr_nxt = (tmp[14]) ? u : s;
- if (NextState == CPUSTATE_FETCH_I1)
- begin
- rAVMA = 1'b1;
- rLIC = 1'b1;
- end
- else
- rAVMA = 1'b0;
- CpuState_nxt = NextState;
- end
- end
-
- CPUSTATE_NMI_START:
- begin
- NMIClear_nxt = 1'b1;
- addr_nxt = pc;
- // tmp stands as the bits to push to the stack
- tmp_nxt = 16'H20FF; // Save to the S stack, PC, U, Y, X, DP, B, A, CC; set LIC on every push
- NextState_nxt = CPUSTATE_IRQ_DONTCARE2;
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_IRQ_DONTCARE;
- IntType_nxt = INTTYPE_NMI;
- cc_nxt[CC_E_BIT] = 1'b1;
- end
-
- CPUSTATE_IRQ_START:
- begin
- addr_nxt = pc;
- tmp_nxt = 16'H20FF; // Save to the S stack, PC, U, Y, X, DP, B, A, CC; set LIC on every push
- NextState_nxt = CPUSTATE_IRQ_DONTCARE2;
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_IRQ_DONTCARE;
- IntType_nxt = INTTYPE_IRQ;
- cc_nxt[CC_E_BIT] = 1'b1;
- end
-
- CPUSTATE_FIRQ_START:
- begin
- addr_nxt = pc;
- tmp_nxt = 16'H2081; // Save to the S stack, PC, CC; set LIC on every push
- NextState_nxt = CPUSTATE_IRQ_DONTCARE2;
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_IRQ_DONTCARE;
- IntType_nxt = INTTYPE_FIRQ;
- cc_nxt[CC_E_BIT] = 1'b0;
- end
-
- CPUSTATE_SWI_START:
- begin
- addr_nxt = pc;
- tmp_nxt = 16'H00FF; // Save to the S stack, PC, U, Y, X, DP, B, A, CC
-
- NextState_nxt = CPUSTATE_IRQ_DONTCARE2;
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_IRQ_DONTCARE;
- if (InstPage3)
- IntType_nxt = INTTYPE_SWI3;
- if (InstPage2)
- IntType_nxt = INTTYPE_SWI2;
- else
- IntType_nxt = INTTYPE_SWI;
-
- cc_nxt[CC_E_BIT] = 1'b1;
- end
-
- CPUSTATE_IRQ_DONTCARE:
- begin
- NMIClear_nxt = 1'b0;
- addr_nxt = 16'HFFFF;
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_PSH_ACTION;
- end
-
-
- CPUSTATE_IRQ_DONTCARE2:
- begin
- addr_nxt = 16'HFFFF;
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_IRQ_VECTOR_HI;
- rLIC = 1'b1;
- end
-
- CPUSTATE_IRQ_VECTOR_HI:
- begin
- case (IntType)
- INTTYPE_NMI:
- begin
- addr_nxt = `NMI_VECTOR;
- BS_nxt = 1'b1; // ACK Interrupt
- end
- INTTYPE_IRQ:
- begin
- addr_nxt = `IRQ_VECTOR;
- BS_nxt = 1'b1; // ACK Interrupt
- end
- INTTYPE_SWI:
- begin
- addr_nxt = `SWI_VECTOR;
- end
- INTTYPE_FIRQ:
- begin
- addr_nxt = `FIRQ_VECTOR;
- BS_nxt = 1'b1; // ACK Interrupt
- end
- INTTYPE_SWI2:
- begin
- addr_nxt = `SWI2_VECTOR;
- end
- INTTYPE_SWI3:
- begin
- addr_nxt = `SWI3_VECTOR;
- end
- default: // make the default an IRQ, even though it really should never happen
- begin
- addr_nxt = `IRQ_VECTOR;
- BS_nxt = 1'b1; // ACK Interrupt
- end
- endcase
-
- pc_nxt[15:8] = D[7:0];
- rAVMA = 1'b1;
- rBUSY = 1'b1;
- rLIC = 1'b1;
- CpuState_nxt = CPUSTATE_IRQ_VECTOR_LO;
-
-
- end
-
- CPUSTATE_IRQ_VECTOR_LO:
- begin
- case (IntType)
- INTTYPE_NMI:
- begin
- addr_nxt = `NMI_VECTOR+16'H1;
- cc_nxt[CC_I_BIT] = 1'b1;
- cc_nxt[CC_F_BIT] = 1'b1;
- BS_nxt = 1'b1; // ACK Interrupt
- end
- INTTYPE_IRQ:
- begin
- addr_nxt = `IRQ_VECTOR+16'H1;
- cc_nxt[CC_I_BIT] = 1'b1;
- BS_nxt = 1'b1; // ACK Interrupt
- end
- INTTYPE_SWI:
- begin
- addr_nxt = `SWI_VECTOR+16'H1;
- cc_nxt[CC_F_BIT] = 1'b1;
- cc_nxt[CC_I_BIT] = 1'b1;
- rLIC = 1'b1;
- end
- INTTYPE_FIRQ:
- begin
- addr_nxt = `FIRQ_VECTOR+16'H1;
- cc_nxt[CC_F_BIT] = 1'b1;
- cc_nxt[CC_I_BIT] = 1'b1;
- BS_nxt = 1'b1; // ACK Interrupt
- end
- INTTYPE_SWI2:
- begin
- addr_nxt = `SWI2_VECTOR+16'H1;
- rLIC = 1'b1;
- end
- INTTYPE_SWI3:
- begin
- addr_nxt = `SWI3_VECTOR+16'H1;
- rLIC = 1'b1;
- end
- default:
- begin
- end
- endcase
-
- pc_nxt[7:0] = D[7:0];
- rAVMA = 1'b1;
- rLIC = 1'b1;
- CpuState_nxt = CPUSTATE_INT_DONTCARE;
- end
-
- CPUSTATE_INT_DONTCARE:
- begin
- addr_nxt = 16'HFFFF;
- rAVMA = 1'b1;
- rLIC = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I1;
- end
-
- CPUSTATE_CC_DONTCARE:
- begin
- addr_nxt = pc;
- rLIC = 1'b1;
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I1;
- end
-
- CPUSTATE_TST_DONTCARE1:
- begin
- addr_nxt = 16'HFFFF;
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_TST_DONTCARE2;
- end
-
- CPUSTATE_TST_DONTCARE2:
- begin
- addr_nxt = 16'HFFFF;
- rLIC = 1'b1;
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I1;
- end
-
- CPUSTATE_DEBUG:
- begin
- addr_nxt = tmp;
- rLIC = 1'b1;
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I1;
- end
-
- CPUSTATE_16IMM_DONTCARE:
- begin
- addr_nxt = 16'HFFFF;
- rLIC = 1'b1;
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I1;
- end
-
- CPUSTATE_SYNC:
- begin
- addr_nxt = 16'HFFFF;
- BA_nxt = 1'b1;
- rLIC = 1'b1;
- rAVMA = 1'b0;
-
- if (~(NMILatched & FIRQLatched & IRQLatched))
- begin
- CpuState_nxt = CPUSTATE_SYNC_EXIT;
- end
- end
-
- CPUSTATE_SYNC_EXIT:
- begin
- addr_nxt = 16'HFFFF;
- BA_nxt = 1'b1;
- rLIC = 1'b1;
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I1;
- end
-
-
- CPUSTATE_DMABREQ:
- begin
- rAVMA = 1'b0;
- addr_nxt = 16'HFFFF;
- BS_nxt = 1'b1;
- BA_nxt = 1'b1;
- rLIC = 1'b1;
- tmp_nxt[3:0] = tmp[3:0] - 1'b1;
- if ( (tmp[3:0] == 4'H0) | (DMABREQSample2) )
- begin
- CpuState_nxt = CPUSTATE_DMABREQ_EXIT;
- end
- end
-
- CPUSTATE_DMABREQ_EXIT:
- begin
- addr_nxt = 16'HFFFF;
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I1;
- end
-
- CPUSTATE_HALTED:
- begin
- rAVMA = 1'b0;
- addr_nxt = 16'HFFFF;
- BS_nxt = 1'b1;
- BA_nxt = 1'b1;
- rLIC = 1'b1;
- if (HALTSample2)
- begin
- CpuState_nxt = CPUSTATE_HALT_EXIT2;
- end
- end
-
-
- CPUSTATE_HALT_EXIT2:
- begin
- addr_nxt = 16'HFFFF;
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_FETCH_I1;
- end
-
- CPUSTATE_STOP:
- begin
- addr_nxt = 16'HDEAD;
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_STOP2;
- end
-
- CPUSTATE_STOP2:
- begin
- addr_nxt = pc;
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_STOP3;
- end
-
- CPUSTATE_STOP3:
- begin
- addr_nxt = 16'H0000; //{Inst1, Inst2};
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_STOP;
- end
-
- // The otherwise critically useful Figure 18 in the 6809 datasheet contains an error;
- // it lists that CWAI has a tri-stated bus while it waits for an interrupt.
- // That is not true. SYNC tristates the bus, as do things like /HALT and /DMABREQ.
- // CWAI does not. It waits with /VMA cycles on the bus until an interrupt occurs.
- // The implementation here fits with the 6809 Programming Manual and other Motorola
- // sources, not with that typo in Figure 18.
- CPUSTATE_CWAI:
- begin
- addr_nxt = pc;
- cc_nxt = {1'b1, (cc[6:0] & Inst2[6:0])}; // Set E flag, AND CC with CWAI argument
- tmp_nxt = 16'H00FF; // Save to the S stack, PC, U, Y, X, DP, B, A, CC
-
- NextState_nxt = CPUSTATE_CWAI_POST;
- rAVMA = 1'b0;
- CpuState_nxt = CPUSTATE_CWAI_DONTCARE1;
- end
-
- CPUSTATE_CWAI_DONTCARE1:
- begin
- addr_nxt = 16'HFFFF;
- rAVMA = 1'b1;
- CpuState_nxt = CPUSTATE_PSH_ACTION;
- end
-
- CPUSTATE_CWAI_POST:
- begin
- addr_nxt = 16'HFFFF;
- rAVMA = 1'b0;
-
- CpuState_nxt = CPUSTATE_CWAI_POST;
-
- // Wait for an interrupt
- if (NMILatched == 0)
- begin
- rAVMA = 1'b1;
- IntType_nxt = INTTYPE_NMI;
- cc_nxt[CC_F_BIT] = 1'b1;
- cc_nxt[CC_I_BIT] = 1'b1;
- CpuState_nxt = CPUSTATE_IRQ_VECTOR_HI;
- end
- else if ((FIRQLatched == 0) && (cc[CC_F_BIT] == 0))
- begin
- rAVMA = 1'b1;
- cc_nxt[CC_F_BIT] = 1'b1;
- cc_nxt[CC_I_BIT] = 1'b1;
- IntType_nxt = INTTYPE_FIRQ;
- CpuState_nxt = CPUSTATE_IRQ_VECTOR_HI;
- end
- else if ((IRQLatched == 0) && (cc[CC_I_BIT] == 0))
- begin
- rAVMA = 1'b1;
- cc_nxt[CC_I_BIT] = 1'b1;
- IntType_nxt = INTTYPE_IRQ;
- CpuState_nxt = CPUSTATE_IRQ_VECTOR_HI;
- end
- end
-
- default: // Picky darned Verilog.
- begin
- CpuState_nxt = PostIllegalState;
- end
-
- endcase
-end
-
-endmodule
-
diff --git a/Console_MiST/GCE - Vectrex_MiST/rtl/sdram.sv b/Console_MiST/GCE - Vectrex_MiST/rtl/sdram.sv
index 53a14e5e..66fa4abc 100644
--- a/Console_MiST/GCE - Vectrex_MiST/rtl/sdram.sv
+++ b/Console_MiST/GCE - Vectrex_MiST/rtl/sdram.sv
@@ -1,79 +1,117 @@
//
// sdram.v
//
-// Static RAM controller implementation using SDRAM MT48LC16M16A2
+// sdram controller implementation for the MiST board
+// https://github.com/mist-devel/mist-board
+//
+// Copyright (c) 2013 Till Harbaum
+// Copyright (c) 2019 Gyorgy Szombathelyi
//
-// Copyright (c) 2015,2016 Sorgelig
-//
-// Some parts of SDRAM code used from project:
-// http://hamsterworks.co.nz/mediawiki/index.php/Simple_SDRAM_Controller
-//
-// This source file is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published
-// by the Free Software Foundation, either version 3 of the License, or
+// This source file is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published
+// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
-//
+//
// This source file is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
-//
+//
// You should have received a copy of the GNU General Public License
-// along with this program. If not, see .
-//
-// ------------------------------------------
-//
-// v2.1 - Add universal 8/16 bit mode.
+// along with this program. If not, see .
//
-module sdram
-(
- input init, // reset to initialize RAM
- input clk, // clock ~100MHz
- //
- // SDRAM_* - signals to the MT48LC16M16 chip
- inout reg [15:0] SDRAM_DQ, // 16 bit bidirectional data bus
- output reg [12:0] SDRAM_A, // 13 bit multiplexed address bus
- output reg SDRAM_DQML, // two byte masks
- output reg SDRAM_DQMH, //
- output reg [1:0] SDRAM_BA, // two banks
- output SDRAM_nCS, // a single chip select
- output SDRAM_nWE, // write enable
- output SDRAM_nRAS, // row address select
- output SDRAM_nCAS, // columns address select
- output SDRAM_CKE, // clock enable
- //
- input [1:0] wtbt, // 16bit mode: bit1 - write high byte, bit0 - write low byte,
- // 8bit mode: 2'b00 - use addr[0] to decide which byte to write
- // Ignored while reading.
- //
- input [24:0] addr, // 25 bit address for 8bit mode. addr[0] = 0 for 16bit mode for correct operations.
- output [15:0] dout, // data output to cpu
- input [15:0] din, // data input from cpu
- input we, // cpu requests write
- input rd, // cpu requests read
- output reg ready // dout is valid. Ready to accept new read/write.
+module sdram (
+
+ // interface to the MT48LC16M16 chip
+ inout reg [15:0] SDRAM_DQ, // 16 bit bidirectional data bus
+ output reg [12:0] SDRAM_A, // 13 bit multiplexed address bus
+ output reg SDRAM_DQML, // two byte masks
+ output reg SDRAM_DQMH, // two byte masks
+ output reg [1:0] SDRAM_BA, // two banks
+ output SDRAM_nCS, // a single chip select
+ output SDRAM_nWE, // write enable
+ output SDRAM_nRAS, // row address select
+ output SDRAM_nCAS, // columns address select
+
+ // cpu/chipset interface
+ input init_n, // init signal after FPGA config to initialize RAM
+ input clk, // sdram clock
+
+ input port1_req,
+ output reg port1_ack,
+ input port1_we,
+ input [24:1] port1_a,
+ input [1:0] port1_ds,
+ input [15:0] port1_d,
+ output reg [15:0] port1_q
);
-assign SDRAM_nCS = command[3];
-assign SDRAM_nRAS = command[2];
-assign SDRAM_nCAS = command[1];
-assign SDRAM_nWE = command[0];
-assign SDRAM_CKE = cke;
+parameter MHZ = 16'd80; // 80 MHz default clock, set it to proper value to calculate refresh rate
-// no burst configured
-localparam BURST_LENGTH = 3'b000; // 000=1, 001=2, 010=4, 011=8
-localparam ACCESS_TYPE = 1'b0; // 0=sequential, 1=interleaved
-localparam CAS_LATENCY = 3'd2; // 2 for < 100MHz, 3 for >100MHz
-localparam OP_MODE = 2'b00; // only 00 (standard operation) allowed
-localparam NO_WRITE_BURST = 1'b1; // 0= write burst enabled, 1=only single access write
-localparam MODE = {3'b000, NO_WRITE_BURST, OP_MODE, CAS_LATENCY, ACCESS_TYPE, BURST_LENGTH};
+localparam RASCAS_DELAY = 3'd1; // tRCD=20ns -> 1 cycle@<50MHz
+localparam BURST_LENGTH = 3'b000; // 000=1, 001=2, 010=4, 011=8
+localparam ACCESS_TYPE = 1'b0; // 0=sequential, 1=interleaved
+localparam CAS_LATENCY = 3'd2; // 2/3 allowed
+localparam OP_MODE = 2'b00; // only 00 (standard operation) allowed
+localparam NO_WRITE_BURST = 1'b1; // 0= write burst enabled, 1=only single access write
-localparam sdram_startup_cycles= 14'd12100;// 100us, plus a little more, @ 100MHz
-localparam cycles_per_refresh = 14'd186; // (64000*24)/8192-1 Calc'd as (64ms @ 24MHz)/8192 rose
-localparam startup_refresh_max = 14'b11111111111111;
+localparam MODE = { 3'b000, NO_WRITE_BURST, OP_MODE, CAS_LATENCY, ACCESS_TYPE, BURST_LENGTH};
-// SDRAM commands
+// 64ms/8192 rows = 7.8us
+localparam RFRSH_CYCLES = 16'd78*MHZ/4'd10;
+// ---------------------------------------------------------------------
+// ------------------------ cycle state machine ------------------------
+// ---------------------------------------------------------------------
+
+/*
+ Simple SDRAM state machine
+ 1 word burst, CL2
+cmd issued registered
+ 0 RAS0
+ 1 ras0
+ 2 CAS0
+ 3 cas0
+ 4
+ 5 data0 returned
+*/
+
+localparam STATE_RAS0 = 3'd0; // first state in cycle
+localparam STATE_CAS0 = STATE_RAS0 + RASCAS_DELAY + 1'd1; // CAS phase - 3
+localparam STATE_READ0 = STATE_CAS0 + CAS_LATENCY + 1'd1; // 6
+localparam STATE_LAST = 3'd5;
+
+reg [2:0] t;
+
+always @(posedge clk) begin
+ t <= t + 1'd1;
+ if (t == STATE_LAST) t <= STATE_RAS0;
+ if (t == STATE_RAS0 && !init && !port1_active && !need_refresh) t <= STATE_RAS0;
+end
+
+// ---------------------------------------------------------------------
+// --------------------------- startup/reset ---------------------------
+// ---------------------------------------------------------------------
+
+// wait 1ms (32 8Mhz cycles) after FPGA config is done before going
+// into normal operation. Initialize the ram in the last 16 reset cycles (cycles 15-0)
+reg [4:0] reset;
+reg init = 1'b1;
+always @(posedge clk, negedge init_n) begin
+ if(!init_n) begin
+ reset <= 5'h1f;
+ init <= 1'b1;
+ end else begin
+ if((t == STATE_LAST) && (reset != 0)) reset <= reset - 5'd1;
+ init <= !(reset == 0);
+ end
+end
+
+// ---------------------------------------------------------------------
+// ------------------ generate ram control signals ---------------------
+// ---------------------------------------------------------------------
+
+// all possible commands
localparam CMD_INHIBIT = 4'b1111;
localparam CMD_NOP = 4'b0111;
localparam CMD_ACTIVE = 4'b0011;
@@ -84,171 +122,94 @@ localparam CMD_PRECHARGE = 4'b0010;
localparam CMD_AUTO_REFRESH = 4'b0001;
localparam CMD_LOAD_MODE = 4'b0000;
-reg [13:0] refresh_count = startup_refresh_max - sdram_startup_cycles;
-reg [3:0] command = CMD_INHIBIT;
-reg cke = 0;
-reg [24:0] save_addr;
-reg [15:0] data;
+reg [3:0] sd_cmd; // current command sent to sd ram
-assign dout = save_addr[0] ? {data[7:0], data[15:8]} : {data[15:8], data[7:0]};
-typedef enum
-{
- STATE_STARTUP,
- STATE_OPEN_1,
- STATE_WRITE,
- STATE_READ,
- STATE_IDLE, STATE_IDLE_1, STATE_IDLE_2, STATE_IDLE_3,
- STATE_IDLE_4, STATE_IDLE_5, STATE_IDLE_6, STATE_IDLE_7
-} state_t;
+// 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];
-state_t state = STATE_STARTUP;
+reg [24:1] addr_latch;
+reg [15:0] din_latch;
+reg oe_latch;
+reg we_latch;
+reg [1:0] ds;
+
+reg [10:0] refresh_cnt;
+wire need_refresh = (refresh_cnt >= RFRSH_CYCLES);
+reg refresh /* synthesis noprune */;
+wire port1_active = port1_req ^ port1_ack /* synthesis keep */;
always @(posedge clk) begin
- reg old_we, old_rd;
- reg [CAS_LATENCY:0] data_ready_delay;
- reg [15:0] new_data;
- reg [1:0] new_wtbt;
- reg new_we;
- reg new_rd;
- reg save_we = 1;
-
-
- command <= CMD_NOP;
- refresh_count <= refresh_count+1'b1;
-
- data_ready_delay <= {1'b0, data_ready_delay[CAS_LATENCY:1]};
-
- if(data_ready_delay[0]) data <= SDRAM_DQ;
-
- case(state)
- STATE_STARTUP: begin
- //------------------------------------------------------------------------
- //-- This is the initial startup state, where we wait for at least 100us
- //-- before starting the start sequence
- //--
- //-- The initialisation is sequence is
- //-- * de-assert SDRAM_CKE
- //-- * 100us wait,
- //-- * assert SDRAM_CKE
- //-- * wait at least one cycle,
- //-- * PRECHARGE
- //-- * wait 2 cycles
- //-- * REFRESH,
- //-- * tREF wait
- //-- * REFRESH,
- //-- * tREF wait
- //-- * LOAD_MODE_REG
- //-- * 2 cycles wait
- //------------------------------------------------------------------------
- cke <= 1;
- SDRAM_DQ <= 16'bZZZZZZZZZZZZZZZZ;
- SDRAM_DQML <= 1;
- SDRAM_DQMH <= 1;
- SDRAM_A <= 0;
- SDRAM_BA <= 0;
-
- // All the commands during the startup are NOPS, except these
- if(refresh_count == startup_refresh_max-31) begin
- // ensure all rows are closed
- command <= CMD_PRECHARGE;
- SDRAM_A[10] <= 1; // all banks
- SDRAM_BA <= 2'b00;
- end else if (refresh_count == startup_refresh_max-23) begin
- // these refreshes need to be at least tREF (66ns) apart
- command <= CMD_AUTO_REFRESH;
- end else if (refresh_count == startup_refresh_max-15)
- command <= CMD_AUTO_REFRESH;
- else if (refresh_count == startup_refresh_max-7) begin
- // Now load the mode register
- command <= CMD_LOAD_MODE;
- SDRAM_A <= MODE;
- end
-
- //------------------------------------------------------
- //-- if startup is complete then go into idle mode,
- //-- get prepared to accept a new command, and schedule
- //-- the first refresh cycle
- //------------------------------------------------------
- if(!refresh_count) begin
- state <= STATE_IDLE;
- ready <= 1;
- refresh_count <= 0;
- end
- end
-
- STATE_IDLE_7: state <= STATE_IDLE_6;
- STATE_IDLE_6: state <= STATE_IDLE_5;
- STATE_IDLE_5: state <= STATE_IDLE_4;
- STATE_IDLE_4: state <= STATE_IDLE_3;
- STATE_IDLE_3: state <= STATE_IDLE_2;
- STATE_IDLE_2: state <= STATE_IDLE_1;
- STATE_IDLE_1: begin
- SDRAM_DQ <= 16'bZZZZZZZZZZZZZZZZ;
- state <= STATE_IDLE;
- // mask possible refresh to reduce colliding.
- if(refresh_count > cycles_per_refresh) begin
- //------------------------------------------------------------------------
- //-- Start the refresh cycle.
- //-- This tasks tRFC (66ns), so 2 idle cycles are needed @ 24MHz
- //------------------------------------------------------------------------
- state <= STATE_IDLE_2;
- command <= CMD_AUTO_REFRESH;
- refresh_count <= refresh_count - cycles_per_refresh + 1'd1;
- end
- end
-
- STATE_IDLE: begin
- // Priority is to issue a refresh if one is outstanding
- if(refresh_count > (cycles_per_refresh<<1)) state <= STATE_IDLE_1;
- else if(new_rd | new_we) begin
- new_we <= 0;
- new_rd <= 0;
- save_addr<= addr;
- save_we <= new_we;
- state <= STATE_OPEN_1;
- command <= CMD_ACTIVE;
- SDRAM_A <= addr[13:1];
- SDRAM_BA <= addr[24:23];
- end
- end
-
- // ACTIVE-to-READ or WRITE delay >20ns (1 cycle @ 24 MHz)(-75)
- STATE_OPEN_1: begin
- SDRAM_A <= {4'b0010, save_addr[22:14]};
- SDRAM_DQML <= save_we & (new_wtbt ? ~new_wtbt[0] : save_addr[0]);
- SDRAM_DQMH <= save_we & (new_wtbt ? ~new_wtbt[1] : ~save_addr[0]);
- state <= save_we ? STATE_WRITE : STATE_READ;
- end
-
- STATE_READ: begin
- state <= STATE_IDLE_5;
- command <= CMD_READ;
- SDRAM_DQ <= 16'bZZZZZZZZZZZZZZZZ;
-
- // Schedule reading the data values off the bus
- data_ready_delay[CAS_LATENCY] <= 1;
- end
-
- STATE_WRITE: begin
- state <= STATE_IDLE_5;
- command <= CMD_WRITE;
- SDRAM_DQ <= new_wtbt ? new_data : {new_data[7:0], new_data[7:0]};
- ready <= 1;
- end
- endcase
+ SDRAM_DQ <= 16'bZZZZZZZZZZZZZZZZ;
+ { SDRAM_DQMH, SDRAM_DQML } <= 2'b11;
+ sd_cmd <= CMD_NOP; // default: idle
+ refresh_cnt <= refresh_cnt + 1'd1;
if(init) begin
- state <= STATE_STARTUP;
- refresh_count <= startup_refresh_max - sdram_startup_cycles;
+ // initialization takes place at the end of the reset phase
+ refresh_cnt <= 0;
+ refresh <= 0;
+ if(t == STATE_RAS0) begin
+
+ if(reset == 15) begin
+ sd_cmd <= CMD_PRECHARGE;
+ SDRAM_A[10] <= 1'b1; // precharge all banks
+ end
+
+ if(reset == 10 || reset == 8) begin
+ sd_cmd <= CMD_AUTO_REFRESH;
+ end
+
+ if(reset == 2) begin
+ sd_cmd <= CMD_LOAD_MODE;
+ SDRAM_A <= MODE;
+ SDRAM_BA <= 2'b00;
+ end
+ end
+ end else begin
+ // RAS phase
+ // bank 0,1
+ if(t == STATE_RAS0) begin
+ { oe_latch, we_latch } <= 2'b00;
+ refresh <= 0;
+
+ if (port1_active) begin
+ sd_cmd <= CMD_ACTIVE;
+ SDRAM_A <= port1_a[22:10];
+ SDRAM_BA <= port1_a[24:23];
+ addr_latch <= port1_a;
+ { oe_latch, we_latch } <= { ~port1_we, port1_we };
+ ds <= port1_ds;
+ din_latch <= port1_d;
+ end else if (need_refresh) begin
+ sd_cmd <= CMD_AUTO_REFRESH;
+ refresh_cnt <= 0;
+ refresh <= 1;
+ end
+ end
+
+ // CAS phase
+ if(t == STATE_CAS0 && (we_latch || oe_latch)) begin
+ sd_cmd <= we_latch?CMD_WRITE:CMD_READ;
+ { SDRAM_DQMH, SDRAM_DQML } <= ~ds;
+ if (we_latch) begin
+ SDRAM_DQ <= din_latch;
+ port1_ack <= port1_req;
+ end
+ SDRAM_A <= { 4'b0010, addr_latch[9:1] }; // auto precharge
+ SDRAM_BA <= addr_latch[24:23];
+ end
+
+ // Data returned
+ if(t == STATE_READ0 && oe_latch) begin
+ port1_q <= SDRAM_DQ;
+ port1_ack <= port1_req;
+ end
+
end
-
- old_we <= we;
- old_rd <= rd;
- if(we & ~old_we) {ready, new_we, new_data, new_wtbt} <= {1'b0, 1'b1, din, wtbt};
- else
- if((rd & ~old_rd) || (rd & old_rd & (save_addr != addr))) {ready, new_rd} <= {1'b0, 1'b1};
-
end
endmodule
diff --git a/Console_MiST/GCE - Vectrex_MiST/rtl/vectrex.vhd b/Console_MiST/GCE - Vectrex_MiST/rtl/vectrex.vhd
index 8f471b26..b632def4 100644
--- a/Console_MiST/GCE - Vectrex_MiST/rtl/vectrex.vhd
+++ b/Console_MiST/GCE - Vectrex_MiST/rtl/vectrex.vhd
@@ -180,32 +180,6 @@ end vectrex;
architecture syn of vectrex is
- component YM2149
- port (
- CLK : in std_logic;
- CE : in std_logic;
- RESET : in std_logic;
- BDIR : in std_logic; -- Bus Direction (0 - read , 1 - write)
- BC : in std_logic; -- Bus control
- DI : in std_logic_vector(7 downto 0);
- DO : out std_logic_vector(7 downto 0);
- CHANNEL_A : out std_logic_vector(7 downto 0);
- CHANNEL_B : out std_logic_vector(7 downto 0);
- CHANNEL_C : out std_logic_vector(7 downto 0);
-
- SEL : in std_logic;
- MODE : in std_logic;
-
- ACTIVE : out std_logic_vector(5 downto 0);
-
- IOA_in : in std_logic_vector(7 downto 0);
- IOA_out : out std_logic_vector(7 downto 0);
-
- IOB_in : in std_logic_vector(7 downto 0);
- IOB_out : out std_logic_vector(7 downto 0)
- );
- end component;
-
component mc6809 is port
(
CPU : in std_logic;
@@ -787,20 +761,29 @@ video_vblank <= vblank;
scan_video_addr <= vcnt_video * std_logic_vector(to_unsigned(max_h,10)) + hcnt_video;
-- sound
-audio_1 <= ("00"&ay_chan_a) +
- ("00"&ay_chan_b) +
- ("00"&ay_chan_c) +
- ("00"&dac_sound);
+process (clock_24)
+begin
+ if rising_edge(clock_24) then
+ if ay_audio_chan = "00" then ay_chan_a <= ay_audio_muxed; end if;
+ if ay_audio_chan = "01" then ay_chan_b <= ay_audio_muxed; end if;
+ if ay_audio_chan = "10" then ay_chan_c <= ay_audio_muxed; end if;
+ end if;
+end process;
+
+audio_1 <= ("00"&ay_chan_a) +
+ ("00"&ay_chan_b) +
+ ("00"&ay_chan_c) +
+ ("00"&dac_sound);
audio_out <= "000"&audio_1(9 downto 3) + audio_speech;
-- vectrex just toggle port A forced/high Z to produce serial data
-- when in high Z vectrex sense port A to get speech chip ready for new byte
-vectrex_serial_bit_in <= ay_ioa_out(4) and speech_mode;
+vectrex_serial_bit_in <= (ay_ioa_oe or ay_ioa_out(4)) and speech_mode;
-- get serial data from vectrex joystick port
-process (cpu_clock, reset)
+process (clock_24, reset)
begin
if reset='1' then
vectrex_bd_rate_div <= X"00";
@@ -963,34 +946,37 @@ port map(
ENA_4 => via_en_4 -- 4x system clock (4HZ) _-_-_-_-_-
);
-
-
-- AY-3-8910
+ay_3_8910_2 : entity work.YM2149
+port map(
+ -- data bus
+ I_DA => via_pa_o, -- in std_logic_vector(7 downto 0);
+ O_DA => ay_do, -- out std_logic_vector(7 downto 0);
+ O_DA_OE_L => open, -- out std_logic;
+ -- control
+ I_A9_L => '0', -- in std_logic;
+ I_A8 => '1', -- in std_logic;
+ I_BDIR => via_pb_o(4), -- in std_logic;
+ I_BC2 => '1', -- in std_logic;
+ I_BC1 => via_pb_o(3), -- in std_logic;
+ I_SEL_L => '1', -- in std_logic;
- ym2149_inst: YM2149
- port map (
- CLK => clock_24,
- CE => cpu_clock_en,
- RESET => not reset_n,
- BDIR => via_pb_o(4),
- BC => via_pb_o(3),
- DI => via_pa_o,
- DO => ay_do,
- CHANNEL_A => ay_chan_a,
- CHANNEL_B => ay_chan_b,
- CHANNEL_C => ay_chan_c,
+ O_AUDIO => ay_audio_muxed, -- out std_logic_vector(7 downto 0);
+ O_CHAN => ay_audio_chan, -- out std_logic_vector(1 downto 0);
- SEL => '0',
- MODE => '0',
+ -- port a
+ I_IOA => players_switches, -- in std_logic_vector(7 downto 0);
+ O_IOA => ay_ioa_out, -- out std_logic_vector(7 downto 0);
+ O_IOA_OE_L => ay_ioa_oe, -- out std_logic;
+ -- port b
+ I_IOB => (others => '0'), -- in std_logic_vector(7 downto 0);
+ O_IOB => open, -- out std_logic_vector(7 downto 0);
+ O_IOB_OE_L => open, -- out std_logic;
- ACTIVE => open,
-
- IOA_in => players_switches,
- IOA_out => ay_ioa_out,
-
- IOB_in => (others => '0'),
- IOB_out => open
- );
+ ENA => cpu_clock_en, -- in std_logic; -- clock enable for higher speed operation
+ RESET_L => reset_n, -- in std_logic;
+ CLK => clock_24 -- in std_logic
+);
-- select hardware speakjet or VHDL sp0256
diff --git a/Console_MiST/GCE - Vectrex_MiST/rtl/vectrex_mist.sv b/Console_MiST/GCE - Vectrex_MiST/rtl/vectrex_mist.sv
index 5df1877a..6d9e4340 100644
--- a/Console_MiST/GCE - Vectrex_MiST/rtl/vectrex_mist.sv
+++ b/Console_MiST/GCE - Vectrex_MiST/rtl/vectrex_mist.sv
@@ -47,7 +47,6 @@ localparam CONF_STR = {
wire [31:0] status;
wire [1:0] buttons;
wire [1:0] switches;
-wire [15:0] kbjoy;
wire [7:0] joystick_0;
wire [7:0] joystick_1;
wire [15:0] joy_ana_0;
@@ -85,23 +84,40 @@ pll pll (
);
assign SDRAM_CLK = clk_24;
-wire [15:0] sdram_do;
-assign cart_do = sdram_do[7:0];
+assign SDRAM_CKE = 1;
-sdram cart
+reg sdram_req;
+wire [24:1] sdram_a = ioctl_downl ? ioctl_addr[24:1] : cart_addr[14:1];
+wire [1:0] sdram_ds = ioctl_downl ? {ioctl_addr[0], ~ioctl_addr[0]} : 2'b11;
+wire [15:0] sdram_q;
+assign cart_do = cart_addr[0] ? sdram_q[15:8] : sdram_q[7:0];
+
+sdram #(24) cart
(
- .*,
- .init(~pll_locked),
- .clk(clk_24),
- .wtbt(2'b00),
- .dout(sdram_do),
- .din ({ioctl_dout, ioctl_dout}),
- .addr(ioctl_downl ? ioctl_addr : cart_addr),
- .we(ioctl_downl & ioctl_wr),
- .rd(!ioctl_downl & cart_rd),
- .ready()
+ .*,
+ .clk(clk_24),
+ .init_n(pll_locked),
+ .port1_req(sdram_req),
+ .port1_ack(),
+ .port1_a(sdram_a),
+ .port1_we(ioctl_downl),
+ .port1_ds(sdram_ds),
+ .port1_d({ioctl_dout, ioctl_dout}),
+ .port1_q(sdram_q)
);
+always @(posedge clk_24) begin
+ reg [14:1] cart_addrD;
+
+ if (ioctl_downl) begin
+ if (ioctl_wr) sdram_req <= !sdram_req;
+ end
+ else begin
+ cart_addrD <= cart_addr[14:1];
+ if (cart_rd & cart_addr[14:1] != cart_addrD) sdram_req <= !sdram_req;
+ end
+end
+
reg reset = 0;
reg second_reset = 0;